From 949f388f5fa361e3be374f59edc09b92296abe03 Mon Sep 17 00:00:00 2001 From: andrewfish Date: Wed, 11 May 2011 18:31:20 +0000 Subject: [PATCH] Add InOsEmuPkg. Like UnixPkg and Nt32Pkg, but EFI code can be common and does not require including system include files. Currently only Unix 64-bit is supported and it has only been tested on Mac OS X. Not all features are ported over, but GOP, via X11, and access to local file systems are supported and you can boot to the shell. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11641 6f19259b-4bc3-4df7-8a09-765794883524 --- InOsEmuPkg/AutoScanPei/AutoScanPei.c | 109 ++ InOsEmuPkg/AutoScanPei/AutoScanPei.inf | 58 + InOsEmuPkg/BootModePei/BootModePei.c | 94 + InOsEmuPkg/BootModePei/BootModePei.inf | 59 + InOsEmuPkg/CpuRuntimeDxe/Cpu.c | 339 ++++ InOsEmuPkg/CpuRuntimeDxe/Cpu.inf | 65 + InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h | 172 ++ InOsEmuPkg/CpuRuntimeDxe/CpuIo.c | 333 ++++ InOsEmuPkg/CpuRuntimeDxe/Strings.uni | Bin 0 -> 2184 bytes InOsEmuPkg/EmuBusDriverDxe/ComponentName.c | 247 +++ InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.c | 537 ++++++ InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.h | 116 ++ .../EmuBusDriverDxe/EmuBusDriverDxe.inf | 63 + InOsEmuPkg/EmuGopDxe/ComponentName.c | 250 +++ InOsEmuPkg/EmuGopDxe/EmuGopDxe.inf | 69 + InOsEmuPkg/EmuGopDxe/Gop.h | 195 +++ InOsEmuPkg/EmuGopDxe/GopDriver.c | 443 +++++ InOsEmuPkg/EmuGopDxe/GopInput.c | 899 ++++++++++ InOsEmuPkg/EmuGopDxe/GopScreen.c | 420 +++++ .../EmuSimpleFileSystemDxe/ComponentName.c | 244 +++ .../EmuSimpleFileSystem.c | 914 ++++++++++ .../EmuSimpleFileSystem.h | 80 + .../EmuSimpleFileSystemDxe.inf | 55 + InOsEmuPkg/EmuThunkDxe/EmuThunk.c | 89 + InOsEmuPkg/EmuThunkDxe/EmuThunk.inf | 59 + .../FirmwareVolumePei/FirmwareVolumePei.c | 130 ++ .../FirmwareVolumePei/FirmwareVolumePei.inf | 60 + InOsEmuPkg/FlashMapPei/FlashMapPei.c | 83 + InOsEmuPkg/FlashMapPei/FlashMapPei.inf | 68 + .../FvbServicesRuntimeDxe/FWBlockService.c | 1360 ++++++++++++++ InOsEmuPkg/FvbServicesRuntimeDxe/FvbInfo.c | 154 ++ .../FvbServicesRuntimeDxe.inf | 80 + .../FvbServicesRuntimeDxe/FwBlockService.h | 219 +++ InOsEmuPkg/InOsEmuPkg.dec | 85 + InOsEmuPkg/Include/Guid/EmuSystemConfig.h | 36 + InOsEmuPkg/Include/Library/EmuThunkLib.h | 22 + InOsEmuPkg/Include/Library/KeyMapLib.h | 43 + InOsEmuPkg/Include/Library/ThunkPpiList.h | 33 + .../Include/Library/ThunkProtocolList.h | 35 + .../Include/Ppi/EmuPeiServicesTableUpdate.h | 27 + InOsEmuPkg/Include/Ppi/EmuThunk.h | 128 ++ InOsEmuPkg/Include/Protocol/EmuFileSystem.h | 140 ++ .../Include/Protocol/EmuGraphicsWindow.h | 134 ++ InOsEmuPkg/Include/Protocol/EmuIoThunk.h | 51 + InOsEmuPkg/Include/Protocol/EmuPthreadThunk.h | 105 ++ InOsEmuPkg/Include/Protocol/EmuThunk.h | 199 +++ InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.c | 52 + InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.inf | 45 + .../DxeEmuPeCoffExtraActionLib.c | 103 ++ .../DxeEmuPeCoffExtraActionLib.inf | 48 + .../DxeEmuSerialPortLib/DxeEmuSerialPortLib.c | 119 ++ .../DxeEmuSerialPortLib.inf | 40 + InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.c | 557 ++++++ InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.h | 97 + InOsEmuPkg/Library/EmuBdsLib/EmuBdsLib.inf | 66 + InOsEmuPkg/Library/EmuBdsLib/PlatformData.c | 69 + .../Library/KeyMapLibNull/KeyMapLibNull.c | 50 + .../Library/KeyMapLibNull/KeyMapLibNull.inf | 39 + .../PeiCoreServicesTablePointerLib.inf | 45 + .../PeiServicesTablePointer.c | 102 ++ .../PeiEmuPeCoffExtraActionLib.c | 106 ++ .../PeiEmuPeCoffExtraActionLib.inf | 46 + .../PeiEmuPeCoffGetEntryPointLib.c | 297 ++++ .../PeiEmuPeCoffGetEntryPointLib.inf | 49 + .../PeiEmuSerialPortLib/PeiEmuSerialPortLib.c | 140 ++ .../PeiEmuSerialPortLib.inf | 45 + .../PeiServicesTablePointer.c | 134 ++ .../PeiServicesTablePointerLib.inf | 47 + .../Library/ThunkPpiList/ThunkPpiList.c | 72 + .../Library/ThunkPpiList/ThunkPpiList.inf | 38 + .../ThunkProtocolList/ThunkProtocolList.c | 138 ++ .../ThunkProtocolList/ThunkProtocolList.inf | 36 + InOsEmuPkg/MetronomeDxe/Metronome.c | 125 ++ InOsEmuPkg/MetronomeDxe/Metronome.h | 56 + InOsEmuPkg/MetronomeDxe/Metronome.inf | 59 + .../MiscBaseBoardManufacturer.uni | Bin 0 -> 2214 bytes .../MiscBaseBoardManufacturerData.c | 57 + .../MiscBaseBoardManufacturerFunction.c | 167 ++ .../MiscBiosVendor.uni | Bin 0 -> 1588 bytes .../MiscBiosVendorData.c | 88 + .../MiscBiosVendorFunction.c | 202 +++ .../MiscBootInformationData.c | 33 + .../MiscBootInformationFunction.c | 73 + .../MiscChassisManufacturer.uni | Bin 0 -> 1774 bytes .../MiscChassisManufacturerData.c | 45 + .../MiscChassisManufacturerFunction.c | 137 ++ .../MiscSubClassPlatformDxe/MiscDevicePath.h | 175 ++ .../MiscNumberOfInstallableLanguagesData.c | 38 + ...MiscNumberOfInstallableLanguagesFunction.c | 238 +++ .../MiscSubClassPlatformDxe/MiscOemString.uni | Bin 0 -> 1312 bytes .../MiscOemStringData.c | 32 + .../MiscOemStringFunction.c | 80 + .../MiscPortInternalConnectorDesignator.uni | Bin 0 -> 8914 bytes .../MiscPortInternalConnectorDesignatorData.c | 99 ++ ...cPortInternalConnectorDesignatorFunction.c | 177 ++ .../MiscResetCapabilitiesData.c | 42 + .../MiscResetCapabilitiesFunction.c | 76 + .../MiscSubClassDriver.h | 122 ++ .../MiscSubClassDriver.inf | 103 ++ .../MiscSubClassDriver.uni | Bin 0 -> 2004 bytes .../MiscSubclassDriverDataTable.c | 78 + .../MiscSubclassDriverEntryPoint.c | 170 ++ .../MiscSystemLanguageString.uni | Bin 0 -> 1314 bytes .../MiscSystemLanguageStringData.c | 33 + .../MiscSystemLanguageStringFunction.c | 85 + .../MiscSystemManufacturer.uni | Bin 0 -> 1772 bytes .../MiscSystemManufacturerData.c | 57 + .../MiscSystemManufacturerFunction.c | 140 ++ .../MiscSystemOptionString.uni | Bin 0 -> 1308 bytes .../MiscSystemOptionStringData.c | 32 + .../MiscSystemOptionStringFunction.c | 83 + .../MiscSystemSlotDesignation.uni | Bin 0 -> 1322 bytes .../MiscSystemSlotDesignationData.c | 52 + .../MiscSystemSlotDesignationFunction.c | 97 + .../RealTimeClockRuntimeDxe/RealTimeClock.c | 305 ++++ .../RealTimeClockRuntimeDxe/RealTimeClock.inf | 57 + InOsEmuPkg/ResetRuntimeDxe/Reset.c | 114 ++ InOsEmuPkg/ResetRuntimeDxe/Reset.inf | 57 + .../ThunkPpiToProtocolPei.c | 74 + .../ThunkPpiToProtocolPei.inf | 55 + InOsEmuPkg/TimerDxe/Timer.c | 351 ++++ InOsEmuPkg/TimerDxe/Timer.h | 73 + InOsEmuPkg/TimerDxe/Timer.inf | 59 + InOsEmuPkg/Unix/.gdbinit | 8 + InOsEmuPkg/Unix/Sec/EmuThunk.c | 314 ++++ InOsEmuPkg/Unix/Sec/FwVol.c | 309 ++++ InOsEmuPkg/Unix/Sec/Gasket.h | 420 +++++ InOsEmuPkg/Unix/Sec/PosixFileSystem.c | 1556 +++++++++++++++++ InOsEmuPkg/Unix/Sec/Pthreads.c | 233 +++ InOsEmuPkg/Unix/Sec/SecMain.c | 1148 ++++++++++++ InOsEmuPkg/Unix/Sec/SecMain.h | 306 ++++ InOsEmuPkg/Unix/Sec/SecMain.inf | 118 ++ InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c | 976 +++++++++++ InOsEmuPkg/Unix/Sec/X64/Gasket.S | 1054 +++++++++++ InOsEmuPkg/Unix/Sec/X64/SwitchStack.S | 112 ++ InOsEmuPkg/Unix/UnixX64.dsc | 377 ++++ InOsEmuPkg/Unix/UnixX64.fdf | 382 ++++ .../Unix/Xcode/xcode_project64/XcodeBuild.sh | 24 + .../xcode_project.xcodeproj/default.pbxuser | 191 ++ .../xcode_project.xcodeproj/project.pbxproj | 124 ++ InOsEmuPkg/Unix/build64.sh | 132 ++ InOsEmuPkg/build64.sh | 16 + 142 files changed, 23677 insertions(+) create mode 100644 InOsEmuPkg/AutoScanPei/AutoScanPei.c create mode 100644 InOsEmuPkg/AutoScanPei/AutoScanPei.inf create mode 100644 InOsEmuPkg/BootModePei/BootModePei.c create mode 100644 InOsEmuPkg/BootModePei/BootModePei.inf create mode 100644 InOsEmuPkg/CpuRuntimeDxe/Cpu.c create mode 100644 InOsEmuPkg/CpuRuntimeDxe/Cpu.inf create mode 100644 InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h create mode 100644 InOsEmuPkg/CpuRuntimeDxe/CpuIo.c create mode 100644 InOsEmuPkg/CpuRuntimeDxe/Strings.uni create mode 100644 InOsEmuPkg/EmuBusDriverDxe/ComponentName.c create mode 100644 InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.c create mode 100644 InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.h create mode 100644 InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf create mode 100644 InOsEmuPkg/EmuGopDxe/ComponentName.c create mode 100644 InOsEmuPkg/EmuGopDxe/EmuGopDxe.inf create mode 100644 InOsEmuPkg/EmuGopDxe/Gop.h create mode 100644 InOsEmuPkg/EmuGopDxe/GopDriver.c create mode 100644 InOsEmuPkg/EmuGopDxe/GopInput.c create mode 100644 InOsEmuPkg/EmuGopDxe/GopScreen.c create mode 100644 InOsEmuPkg/EmuSimpleFileSystemDxe/ComponentName.c create mode 100644 InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c create mode 100644 InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.h create mode 100644 InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf create mode 100644 InOsEmuPkg/EmuThunkDxe/EmuThunk.c create mode 100644 InOsEmuPkg/EmuThunkDxe/EmuThunk.inf create mode 100644 InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.c create mode 100644 InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.inf create mode 100644 InOsEmuPkg/FlashMapPei/FlashMapPei.c create mode 100644 InOsEmuPkg/FlashMapPei/FlashMapPei.inf create mode 100644 InOsEmuPkg/FvbServicesRuntimeDxe/FWBlockService.c create mode 100644 InOsEmuPkg/FvbServicesRuntimeDxe/FvbInfo.c create mode 100644 InOsEmuPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf create mode 100644 InOsEmuPkg/FvbServicesRuntimeDxe/FwBlockService.h create mode 100644 InOsEmuPkg/InOsEmuPkg.dec create mode 100644 InOsEmuPkg/Include/Guid/EmuSystemConfig.h create mode 100644 InOsEmuPkg/Include/Library/EmuThunkLib.h create mode 100644 InOsEmuPkg/Include/Library/KeyMapLib.h create mode 100644 InOsEmuPkg/Include/Library/ThunkPpiList.h create mode 100644 InOsEmuPkg/Include/Library/ThunkProtocolList.h create mode 100644 InOsEmuPkg/Include/Ppi/EmuPeiServicesTableUpdate.h create mode 100644 InOsEmuPkg/Include/Ppi/EmuThunk.h create mode 100644 InOsEmuPkg/Include/Protocol/EmuFileSystem.h create mode 100644 InOsEmuPkg/Include/Protocol/EmuGraphicsWindow.h create mode 100644 InOsEmuPkg/Include/Protocol/EmuIoThunk.h create mode 100644 InOsEmuPkg/Include/Protocol/EmuPthreadThunk.h create mode 100644 InOsEmuPkg/Include/Protocol/EmuThunk.h create mode 100644 InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.c create mode 100644 InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.inf create mode 100644 InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c create mode 100644 InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf create mode 100644 InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c create mode 100644 InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf create mode 100644 InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.c create mode 100644 InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.h create mode 100644 InOsEmuPkg/Library/EmuBdsLib/EmuBdsLib.inf create mode 100644 InOsEmuPkg/Library/EmuBdsLib/PlatformData.c create mode 100644 InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.c create mode 100644 InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.inf create mode 100644 InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf create mode 100644 InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiServicesTablePointer.c create mode 100644 InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c create mode 100644 InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf create mode 100644 InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c create mode 100644 InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf create mode 100644 InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c create mode 100644 InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf create mode 100644 InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c create mode 100644 InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf create mode 100644 InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.c create mode 100644 InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.inf create mode 100644 InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.c create mode 100644 InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.inf create mode 100644 InOsEmuPkg/MetronomeDxe/Metronome.c create mode 100644 InOsEmuPkg/MetronomeDxe/Metronome.h create mode 100644 InOsEmuPkg/MetronomeDxe/Metronome.inf create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturer.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturerData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturerFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendor.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendorData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendorFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscBootInformationData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscBootInformationFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturer.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturerData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturerFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscDevicePath.h create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscNumberOfInstallableLanguagesData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscNumberOfInstallableLanguagesFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemString.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemStringData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemStringFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignator.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignatorData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignatorFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscResetCapabilitiesData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscResetCapabilitiesFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.h create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.inf create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubclassDriverDataTable.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubclassDriverEntryPoint.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageString.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageStringData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageStringFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturer.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturerData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturerFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionString.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionStringData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionStringFunction.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignation.uni create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignationData.c create mode 100644 InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignationFunction.c create mode 100644 InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.c create mode 100644 InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf create mode 100644 InOsEmuPkg/ResetRuntimeDxe/Reset.c create mode 100644 InOsEmuPkg/ResetRuntimeDxe/Reset.inf create mode 100644 InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.c create mode 100644 InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf create mode 100644 InOsEmuPkg/TimerDxe/Timer.c create mode 100644 InOsEmuPkg/TimerDxe/Timer.h create mode 100644 InOsEmuPkg/TimerDxe/Timer.inf create mode 100644 InOsEmuPkg/Unix/.gdbinit create mode 100644 InOsEmuPkg/Unix/Sec/EmuThunk.c create mode 100644 InOsEmuPkg/Unix/Sec/FwVol.c create mode 100644 InOsEmuPkg/Unix/Sec/Gasket.h create mode 100644 InOsEmuPkg/Unix/Sec/PosixFileSystem.c create mode 100644 InOsEmuPkg/Unix/Sec/Pthreads.c create mode 100644 InOsEmuPkg/Unix/Sec/SecMain.c create mode 100644 InOsEmuPkg/Unix/Sec/SecMain.h create mode 100644 InOsEmuPkg/Unix/Sec/SecMain.inf create mode 100644 InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c create mode 100644 InOsEmuPkg/Unix/Sec/X64/Gasket.S create mode 100644 InOsEmuPkg/Unix/Sec/X64/SwitchStack.S create mode 100644 InOsEmuPkg/Unix/UnixX64.dsc create mode 100644 InOsEmuPkg/Unix/UnixX64.fdf create mode 100755 InOsEmuPkg/Unix/Xcode/xcode_project64/XcodeBuild.sh create mode 100644 InOsEmuPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/default.pbxuser create mode 100644 InOsEmuPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/project.pbxproj create mode 100755 InOsEmuPkg/Unix/build64.sh create mode 100755 InOsEmuPkg/build64.sh diff --git a/InOsEmuPkg/AutoScanPei/AutoScanPei.c b/InOsEmuPkg/AutoScanPei/AutoScanPei.c new file mode 100644 index 0000000000..78cdd34965 --- /dev/null +++ b/InOsEmuPkg/AutoScanPei/AutoScanPei.c @@ -0,0 +1,109 @@ +/*++ @file + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "PiPei.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +PeimInitializeAutoScanPei ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +/*++ + +Routine Description: + Perform a call-back into the SEC simulator to get a memory value + +Arguments: + FfsHeader - General purpose data available to every PEIM + PeiServices - General purpose services available to every PEIM. + +Returns: + None + +**/ +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; + EMU_THUNK_PPI *Thunk; + UINT64 MemorySize; + EFI_PHYSICAL_ADDRESS MemoryBase; + UINTN Index; + EFI_RESOURCE_ATTRIBUTE_TYPE Attributes; + + + DEBUG ((EFI_D_ERROR, "Emu Autoscan PEIM Loaded\n")); + + // + // Get the PEI UNIX Autoscan PPI + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, // GUID + 0, // INSTANCE + &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR + (VOID **)&Thunk // PPI + ); + ASSERT_EFI_ERROR (Status); + + Index = 0; + do { + Status = Thunk->MemoryAutoScan (Index, &MemoryBase, &MemorySize); + if (!EFI_ERROR (Status)) { + Attributes = + ( + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | + EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE + ); + + if (Index == 0) { + // + // Register the memory with the PEI Core + // + Status = PeiServicesInstallPeiMemory (MemoryBase, MemorySize); + ASSERT_EFI_ERROR (Status); + + Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED; + } + + BuildResourceDescriptorHob ( + EFI_RESOURCE_SYSTEM_MEMORY, + Attributes, + MemoryBase, + MemorySize + ); + } + Index++; + } while (!EFI_ERROR (Status)); + + // + // Build the CPU hob with 36-bit addressing and 16-bits of IO space. + // + BuildCpuHob (36, 16); + + return Status; +} diff --git a/InOsEmuPkg/AutoScanPei/AutoScanPei.inf b/InOsEmuPkg/AutoScanPei/AutoScanPei.inf new file mode 100644 index 0000000000..b8692ca3d9 --- /dev/null +++ b/InOsEmuPkg/AutoScanPei/AutoScanPei.inf @@ -0,0 +1,58 @@ +## @file +# Component description file for EmuAutoScan module +# +# This module abstracts memory auto-scan in a Emu environment. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = AutoScanPei + FILE_GUID = 2D6F6BCC-9681-8E42-8579-B57DCD0060F0 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + + ENTRY_POINT = PeimInitializeAutoScanPei + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + AutoScanPei.c + +[Packages] + MdePkg/MdePkg.dec +# MdeModulePkg/MdeModulePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + PeiServicesTablePointerLib + PeiServicesLib + HobLib + BaseMemoryLib + BaseLib + PeimEntryPoint + DebugLib + + +[Ppis] + gEfiPeiMemoryDiscoveredPpiGuid # PPI ALWAYS_PRODUCED + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + + +[Depex] + gEmuThunkPpiGuid AND gEfiPeiMasterBootModePpiGuid + diff --git a/InOsEmuPkg/BootModePei/BootModePei.c b/InOsEmuPkg/BootModePei/BootModePei.c new file mode 100644 index 0000000000..e26e929f07 --- /dev/null +++ b/InOsEmuPkg/BootModePei/BootModePei.c @@ -0,0 +1,94 @@ +/** @file + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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. + +**/ + + + +// +// The package level header files this module uses +// +#include + +#include +#include + + +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +// +// The Library classes this module consumes +// +#include +#include + + +// +// Module globals +// +EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMasterBootModePpiGuid, + NULL +}; + +EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiBootInRecoveryModePpiGuid, + NULL +}; + +EFI_STATUS +EFIAPI +InitializeBootMode ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +/*++ + +Routine Description: + + Peform the boot mode determination logic + +Arguments: + + PeiServices - General purpose services available to every PEIM. + +Returns: + + Status - EFI_SUCCESS if the boot mode could be set + +**/ +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + + DEBUG ((EFI_D_ERROR, "Emu Boot Mode PEIM Loaded\n")); + + BootMode = FixedPcdGet32 (PcdEmuBootMode); + + Status = PeiServicesSetBootMode (BootMode); + ASSERT_EFI_ERROR (Status); + + Status = PeiServicesInstallPpi (&mPpiListBootMode); + ASSERT_EFI_ERROR (Status); + + if (BootMode == BOOT_IN_RECOVERY_MODE) { + Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode); + ASSERT_EFI_ERROR (Status); + } + + return Status; +} diff --git a/InOsEmuPkg/BootModePei/BootModePei.inf b/InOsEmuPkg/BootModePei/BootModePei.inf new file mode 100644 index 0000000000..d162552eb1 --- /dev/null +++ b/InOsEmuPkg/BootModePei/BootModePei.inf @@ -0,0 +1,59 @@ +## @file +# Component description file for BootMode module +# +# This module provides platform specific function to detect boot mode. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BootModePei + FILE_GUID = 64196C76-58E3-0B4D-9484-B54F7C4349CA + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeBootMode + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + BootModePei.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + PeiServicesTablePointerLib + PeiServicesLib + BaseLib + PeimEntryPoint + DebugLib + + +[Ppis] + gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED + gEfiPeiBootInRecoveryModePpiGuid # PPI SOMETIMES_PRODUCED + +[FixedPcd] + gInOsEmuPkgTokenSpaceGuid.PcdEmuBootMode + +[Depex] + TRUE + diff --git a/InOsEmuPkg/CpuRuntimeDxe/Cpu.c b/InOsEmuPkg/CpuRuntimeDxe/Cpu.c new file mode 100644 index 0000000000..2b1e1d1cda --- /dev/null +++ b/InOsEmuPkg/CpuRuntimeDxe/Cpu.c @@ -0,0 +1,339 @@ +/*++ @file + Emu driver to produce CPU Architectural Protocol. + +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "CpuDriver.h" + +UINT64 mTimerPeriod; + +CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate = { + CPU_ARCH_PROT_PRIVATE_SIGNATURE, + NULL, + { + EmuFlushCpuDataCache, + EmuEnableInterrupt, + EmuDisableInterrupt, + EmuGetInterruptState, + EmuInit, + EmuRegisterInterruptHandler, + EmuGetTimerValue, + EmuSetMemoryAttributes, + 0, + 4 + }, + { + { + CpuMemoryServiceRead, + CpuMemoryServiceWrite + }, + { + CpuIoServiceRead, + CpuIoServiceWrite + } + }, + TRUE +}; + +#define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100 + + + +// +// Service routines for the driver +// +EFI_STATUS +EFIAPI +EmuFlushCpuDataCache ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Start, + IN UINT64 Length, + IN EFI_CPU_FLUSH_TYPE FlushType + ) +{ + if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) { + // + // Only WB flush is supported. We actually need do nothing on Emu emulator + // environment. Classify this to follow EFI spec + // + return EFI_SUCCESS; + } + // + // Other flush types are not supported by Emu emulator + // + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuEnableInterrupt ( + IN EFI_CPU_ARCH_PROTOCOL *This + ) +{ + CPU_ARCH_PROTOCOL_PRIVATE *Private; + + Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This); + Private->InterruptState = TRUE; + gEmuThunk->EnableInterrupt (); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuDisableInterrupt ( + IN EFI_CPU_ARCH_PROTOCOL *This + ) +{ + CPU_ARCH_PROTOCOL_PRIVATE *Private; + + Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This); + Private->InterruptState = FALSE; + gEmuThunk->DisableInterrupt (); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuGetInterruptState ( + IN EFI_CPU_ARCH_PROTOCOL *This, + OUT BOOLEAN *State + ) +{ + CPU_ARCH_PROTOCOL_PRIVATE *Private; + + if (State == NULL) { + return EFI_INVALID_PARAMETER; + } + + Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This); + *State = Private->InterruptState; + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuInit ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_CPU_INIT_TYPE InitType + ) +{ + CPU_ARCH_PROTOCOL_PRIVATE *Private; + + Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This); + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuRegisterInterruptHandler ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ) +{ + CPU_ARCH_PROTOCOL_PRIVATE *Private; + + // + // Do parameter checking for EFI spec conformance + // + if (InterruptType < 0 || InterruptType > 0xff) { + return EFI_UNSUPPORTED; + } + // + // Do nothing for Emu emulation + // + Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This); + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuGetTimerValue ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINT32 TimerIndex, + OUT UINT64 *TimerValue, + OUT UINT64 *TimerPeriod OPTIONAL + ) +{ + if (TimerValue == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (TimerIndex != 0) { + return EFI_INVALID_PARAMETER; + } + + *TimerValue = gEmuThunk->QueryPerformanceCounter (); + + if (TimerPeriod != NULL) { + *TimerPeriod = mTimerPeriod; + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +EmuSetMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + CPU_ARCH_PROTOCOL_PRIVATE *Private; + + // + // Check for invalid parameter for Spec conformance + // + if (Length == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Do nothing for Nt32 emulation + // + Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This); + return EFI_UNSUPPORTED; +} + + + +/** + Logs SMBIOS record. + + @param Smbios Pointer to SMBIOS protocol instance. + @param Buffer Pointer to the data buffer. + +**/ +VOID +LogSmbiosData ( + IN EFI_SMBIOS_PROTOCOL *Smbios, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + + SmbiosHandle = 0; + Status = Smbios->Add ( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER*)Buffer + ); + ASSERT_EFI_ERROR (Status); +} + +VOID +CpuUpdateSmbios ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 TotalSize; + EFI_SMBIOS_PROTOCOL *Smbios; + EFI_HII_HANDLE HiiHandle; + STRING_REF Token; + UINTN CpuVerStrLen; + EFI_STRING CpuVerStr; + SMBIOS_TABLE_TYPE4 *SmbiosRecord; + CHAR8 *OptionalStrStart; + + // + // Locate Smbios protocol. + // + Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios); + + if (EFI_ERROR (Status)) { + return; + } + + // + // Initialize strings to HII database + // + HiiHandle = HiiAddPackages ( + &gEfiCallerIdGuid, + NULL, + CpuStrings, + NULL + ); + ASSERT (HiiHandle != NULL); + + Token = STRING_TOKEN (STR_PROCESSOR_VERSION); + CpuVerStr = HiiGetPackageString(&gEfiCallerIdGuid, Token, NULL); + CpuVerStrLen = StrLen(CpuVerStr); + ASSERT (CpuVerStrLen <= SMBIOS_STRING_MAX_LENGTH); + + TotalSize = sizeof(SMBIOS_TABLE_TYPE4) + CpuVerStrLen + 1 + 1; + SmbiosRecord = AllocatePool(TotalSize); + ZeroMem(SmbiosRecord, TotalSize); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + // + // Processor version is the 1st string. + // + SmbiosRecord->ProcessorVersion = 1; + // + // Store CPU frequency data record to data hub - It's an emulator so make up a value + // + SmbiosRecord->CurrentSpeed = 1234; + + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + UnicodeStrToAsciiStr(CpuVerStr, OptionalStrStart); + + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + LogSmbiosData(Smbios, (UINT8 *) SmbiosRecord); + FreePool (SmbiosRecord); +} + +EFI_STATUS +EFIAPI +InitializeCpu ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT64 Frequency; + + // + // Retrieve the frequency of the performance counter in Hz. + // + Frequency = gEmuThunk->QueryPerformanceFrequency (); + + // + // Convert frequency in Hz to a clock period in femtoseconds. + // + mTimerPeriod = DivU64x64Remainder (1000000000000000, Frequency, NULL); + + CpuUpdateSmbios (); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &mCpuTemplate.Handle, + &gEfiCpuArchProtocolGuid, &mCpuTemplate.Cpu, + &gEfiCpuIo2ProtocolGuid, &mCpuTemplate.CpuIo, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/InOsEmuPkg/CpuRuntimeDxe/Cpu.inf b/InOsEmuPkg/CpuRuntimeDxe/Cpu.inf new file mode 100644 index 0000000000..44e651f2c8 --- /dev/null +++ b/InOsEmuPkg/CpuRuntimeDxe/Cpu.inf @@ -0,0 +1,65 @@ +## @file +# Component description file for Cpu module. +# +# This CPU module abstracts the interrupt subsystem of a platform and the CPU-specific setjump-long pair. +# Copyright (c) 2006 - 2010, 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Cpu + FILE_GUID = f3794b60-8985-11db-8e53-0040d02b1835 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeCpu + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + CpuIo.c + Cpu.c + CpuDriver.h + Strings.uni + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + UefiDriverEntryPoint + UefiLib + HiiLib + DebugLib + BaseLib + EmuThunkLib + +[Protocols] + gEmuIoThunkProtocolGuid # PROTOCOL_NOTIFY SOMETIMES_CONSUMED + gEfiSmbiosProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + gEfiHiiProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + gEfiCpuIo2ProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiCpuArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + +[Depex] + gEfiSmbiosProtocolGuid diff --git a/InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h b/InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h new file mode 100644 index 0000000000..a836f631d1 --- /dev/null +++ b/InOsEmuPkg/CpuRuntimeDxe/CpuDriver.h @@ -0,0 +1,172 @@ +/*++ @file + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 _CPU_ARCHITECTURAL_PROTOCOL_DRIVER_H_ +#define _CPU_ARCHITECTURAL_PROTOCOL_DRIVER_H_ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +extern UINT8 CpuStrings[]; + +// +// Internal Data Structures +// +#define CPU_ARCH_PROT_PRIVATE_SIGNATURE SIGNATURE_32 ('c', 'a', 'p', 'd') + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + + EFI_CPU_ARCH_PROTOCOL Cpu; + EFI_CPU_IO2_PROTOCOL CpuIo; + + // + // Local Data for CPU interface goes here + // + BOOLEAN InterruptState; + +} CPU_ARCH_PROTOCOL_PRIVATE; + +#define CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + CPU_ARCH_PROTOCOL_PRIVATE, \ + Cpu, \ + CPU_ARCH_PROT_PRIVATE_SIGNATURE \ + ) + +EFI_STATUS +EFIAPI +CpuMemoryServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +EFI_STATUS +EFIAPI +CpuMemoryServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ); + +EFI_STATUS +EFIAPI +CpuIoServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 UserAddress, + IN UINTN Count, + IN OUT VOID *UserBuffer + ); + +EFI_STATUS +EFIAPI +CpuIoServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 UserAddress, + IN UINTN Count, + IN OUT VOID *UserBuffer + ); + +EFI_STATUS +EFIAPI +InitializeCpu ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +EmuFlushCpuDataCache ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Start, + IN UINT64 Length, + IN EFI_CPU_FLUSH_TYPE FlushType + ); + +EFI_STATUS +EFIAPI +EmuEnableInterrupt ( + IN EFI_CPU_ARCH_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +EmuDisableInterrupt ( + IN EFI_CPU_ARCH_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +EmuGetInterruptState ( + IN EFI_CPU_ARCH_PROTOCOL *This, + OUT BOOLEAN *State + ); + +EFI_STATUS +EFIAPI +EmuInit ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_CPU_INIT_TYPE InitType + ); + +EFI_STATUS +EFIAPI +EmuRegisterInterruptHandler ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler + ); + +EFI_STATUS +EFIAPI +EmuGetTimerValue ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINT32 TimerIndex, + OUT UINT64 *TimerValue, + OUT UINT64 *TimerPeriod OPTIONAL + ); + +EFI_STATUS +EFIAPI +EmuSetMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +#endif diff --git a/InOsEmuPkg/CpuRuntimeDxe/CpuIo.c b/InOsEmuPkg/CpuRuntimeDxe/CpuIo.c new file mode 100644 index 0000000000..6f63375f4f --- /dev/null +++ b/InOsEmuPkg/CpuRuntimeDxe/CpuIo.c @@ -0,0 +1,333 @@ +/*++ @file + This is the code that publishes the CPU I/O Protocol. + The intent herein is to have a single I/O service that can load + as early as possible, extend into runtime, and be layered upon by + the implementations of architectural protocols and the PCI Root + Bridge I/O Protocol. + + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IA32_MAX_IO_ADDRESS 0xFFFF +#define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF + +EFI_STATUS +CpuIoCheckAddressRange ( + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer, + IN UINT64 Limit + ); + +EFI_STATUS +EFIAPI +CpuMemoryServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Perform the Memory Access Read service for the CPU I/O Protocol + +Arguments: + + Pointer to an instance of the CPU I/O Protocol + Width of the Memory Access + Address of the Memory access + Count of the number of accesses to perform + Pointer to the buffer to read or write from memory + +Returns: + + Status + + EFI_SUCCESS - The data was read from or written to the EFI + System. + EFI_INVALID_PARAMETER - Width is invalid for this EFI System. + EFI_INVALID_PARAMETER - Buffer is NULL. + EFI_UNSUPPORTED - The Buffer is not aligned for the given Width. + EFI_UNSUPPORTED - The address range specified by Address, Width, + and Count is not valid for this EFI System. + +**/ +{ + EFI_STATUS Status; + + if (!Buffer) { + return EFI_INVALID_PARAMETER; + } + + Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Do nothing for Nt32 version + // + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CpuMemoryServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Perform the Memory Access Read service for the CPU I/O Protocol + +Arguments: + + Pointer to an instance of the CPU I/O Protocol + Width of the Memory Access + Address of the Memory access + Count of the number of accesses to perform + Pointer to the buffer to read or write from memory + +Returns: + + Status + + EFI_SUCCESS - The data was read from or written to the EFI System. + EFI_INVALID_PARAMETER - Width is invalid for this EFI System. + EFI_INVALID_PARAMETER - Buffer is NULL. + EFI_UNSUPPORTED - The Buffer is not aligned for the given Width. + EFI_UNSUPPORTED - The address range specified by Address, Width, and + Count is not valid for this EFI System. + +**/ +{ + EFI_STATUS Status; + + if (!Buffer) { + return EFI_INVALID_PARAMETER; + } + + Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Do nothing for Nt32 version + // + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CpuIoServiceRead ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 UserAddress, + IN UINTN Count, + IN OUT VOID *UserBuffer + ) +/*++ + +Routine Description: + + This is the service that implements the I/O read + +Arguments: + + Pointer to an instance of the CPU I/O Protocol + Width of the Memory Access + Address of the I/O access + Count of the number of accesses to perform + Pointer to the buffer to read or write from I/O space + +Returns: + + Status + EFI_SUCCESS - The data was read from or written to the EFI System. + EFI_INVALID_PARAMETER - Width is invalid for this EFI System. + EFI_INVALID_PARAMETER - Buffer is NULL. + EFI_UNSUPPORTED - The Buffer is not aligned for the given Width. + EFI_UNSUPPORTED - The address range specified by Address, Width, and + Count is not valid for this EFI System. +**/ +{ + UINTN Address; + EFI_STATUS Status; + + if (!UserBuffer) { + return EFI_INVALID_PARAMETER; + } + + Address = (UINTN) UserAddress; + + if (Width >= EfiCpuIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Do nothing for Nt32 version + // + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +CpuIoServiceWrite ( + IN EFI_CPU_IO2_PROTOCOL *This, + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 UserAddress, + IN UINTN Count, + IN OUT VOID *UserBuffer + ) +/*++ + +Routine Description: + + + This is the service that implements the I/O Write + +Arguments: + + Pointer to an instance of the CPU I/O Protocol + Width of the Memory Access + Address of the I/O access + Count of the number of accesses to perform + Pointer to the buffer to read or write from I/O space + +Returns: + + Status + + Status + EFI_SUCCESS - The data was read from or written to the EFI System. + EFI_INVALID_PARAMETER - Width is invalid for this EFI System. + EFI_INVALID_PARAMETER - Buffer is NULL. + EFI_UNSUPPORTED - The Buffer is not aligned for the given Width. + EFI_UNSUPPORTED - The address range specified by Address, Width, and + Count is not valid for this EFI System. + +**/ +{ + UINTN Address; + EFI_STATUS Status; + + if (!UserBuffer) { + return EFI_INVALID_PARAMETER; + } + + Address = (UINTN) UserAddress; + + if (Width >= EfiCpuIoWidthMaximum) { + return EFI_INVALID_PARAMETER; + } + + Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Do nothing for Nt32 version + // + return EFI_SUCCESS; +} + + +/*++ + +Routine Description: + +Arguments: + + Width - TODO: add argument description + Address - TODO: add argument description + Count - TODO: add argument description + Buffer - TODO: add argument description + Limit - TODO: add argument description + +Returns: + + EFI_UNSUPPORTED - TODO: Add description for return value + EFI_UNSUPPORTED - TODO: Add description for return value + EFI_UNSUPPORTED - TODO: Add description for return value + EFI_SUCCESS - TODO: Add description for return value + +**/ +EFI_STATUS +CpuIoCheckAddressRange ( + IN EFI_CPU_IO_PROTOCOL_WIDTH Width, + IN UINT64 Address, + IN UINTN Count, + IN VOID *Buffer, + IN UINT64 Limit + ) +{ + UINTN AlignMask; + + if (Address > Limit) { + return EFI_UNSUPPORTED; + } + + // + // For FiFo type, the target address won't increase during the access, so treat count as 1 + // + if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) { + Count = 1; + } + + Width = Width & 0x03; + if (Address - 1 + (1 << Width) * Count > Limit) { + return EFI_UNSUPPORTED; + } + + AlignMask = (1 << Width) - 1; + if ((UINTN) Buffer & AlignMask) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + + diff --git a/InOsEmuPkg/CpuRuntimeDxe/Strings.uni b/InOsEmuPkg/CpuRuntimeDxe/Strings.uni new file mode 100644 index 0000000000000000000000000000000000000000..4f8d41e798d16b2d978a6e1646a11e4a61c62cf9 GIT binary patch literal 2184 zcmchYOKuZE5Qb|D5_cGx4Fnt`7Azt_N{9m%B#vx{z$%KL8OaaiaRNRfCqY~S`2Om# zdnPy%pa_koyQ{mp>aS=2{86)-CAMXc`0m+VsM>l??3K;zlPzs-sg3Ny7Vti>o;_rK zYESr{*<;oXn{qa=F>BqKb4%knyD6)wZF92Axj3S<%&CE8+@0GMV;|1vwr4GSS-{aj zcM4a6+&S__E_(ufj_f}30*-;xJ@CzJ0;kTF+?&Fmup>0mld>ASw1oY?`&K@Z=DBMe zBd^D5>Q)HL3X?SUb5vKXQ?#C2mr+PB9l7vC^a0<*v8|-Y8rhhxeJMZ8Y*@IrXKmYu zepkZsyJZpmXZL82QFzNfOTi}{@@eq8v}e%rT^HoVs3xZ9$f6-9A;Plb3tZQ6mVFgs zvV^Of-=F1P5hmR(e-XVhaY2N4JYSWg!T-8H_h@Y6p*eA{fv6atjGZpF^sRdBWE&|L z{AHcDM@96vC-eVFis(D`#_D+Km>O-`YsOtWgl>?730bJQ!)}8rK4De&%sjCp<~sYz zmmnc#ZG)~+hokM1o2=9=G**};S5hm?drpf|-}%!oqCZ8F^fw(_VyDP!xeZ6`H_$I_ zO~=`Sl9k#Mx(>YJ5x&560IzU)<1xA~Mk zXZ9Yd1r_pTQ*0xeOSFx^U$#M3=w)q!qfUG;IS;dJSC7?ea}45{_q+@~c{E_&r19VP fHeoG#PFTxG2HuMk`|8NY_8qKxll9(}t*Y2B+L|8k literal 0 HcmV?d00001 diff --git a/InOsEmuPkg/EmuBusDriverDxe/ComponentName.c b/InOsEmuPkg/EmuBusDriverDxe/ComponentName.c new file mode 100644 index 0000000000..e8be214b3c --- /dev/null +++ b/InOsEmuPkg/EmuBusDriverDxe/ComponentName.c @@ -0,0 +1,247 @@ +/** @file + +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 + +**/ + +#include "EmuBusDriverDxe.h" + +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +EmuBusDriverComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +EmuBusDriverComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEmuBusDriverComponentName = { + EmuBusDriverComponentNameGetDriverName, + EmuBusDriverComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuBusDriverComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmuBusDriverComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmuBusDriverComponentNameGetControllerName, + "en" +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mEmuBusDriverNameTable[] = { + { "eng", L"Emu Bus Driver" }, + { NULL , NULL } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] 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. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +EmuBusDriverComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mEmuBusDriverNameTable, + DriverName, + (BOOLEAN)(This == &gEmuBusDriverComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] 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. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] 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. + + @retval 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. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +EmuBusDriverComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + EMU_IO_THUNK_PROTOCOL *EmuIo; + EMU_IO_DEVICE *Private; + + // + // Make sure this driver is currently managing ControllHandle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + gEmuBusDriverBinding.DriverBindingHandle, + &gEmuThunkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // This is a bus driver, so ChildHandle can not be NULL. + // + if (ChildHandle == NULL) { + return EFI_UNSUPPORTED; + } + + Status = EfiTestChildHandle ( + ControllerHandle, + ChildHandle, + &gEmuThunkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get our context back + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEmuIoThunkProtocolGuid, + (VOID**)&EmuIo, + gEmuBusDriverBinding.DriverBindingHandle, + ChildHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Private = EMU_IO_DEVICE_FROM_THIS (EmuIo); + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + Private->ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gEmuBusDriverComponentName) + ); +} diff --git a/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.c b/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.c new file mode 100644 index 0000000000..b76236f325 --- /dev/null +++ b/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.c @@ -0,0 +1,537 @@ +/** @file + Emu Bus driver + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "EmuBusDriverDxe.h" + + + +// +// DriverBinding protocol global +// +EFI_DRIVER_BINDING_PROTOCOL gEmuBusDriverBinding = { + EmuBusDriverBindingSupported, + EmuBusDriverBindingStart, + EmuBusDriverBindingStop, + 0xa, + NULL, + NULL +}; + + + +EFI_STATUS +EFIAPI +EmuBusDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EMU_THUNK_PROTOCOL *EmuThunk; + UINTN Index; + + // + // Check the contents of the first Device Path Node of RemainingDevicePath to make sure + // it is a legal Device Path Node for this bus driver's children. + // + if (RemainingDevicePath != NULL) { + // + // Check if RemainingDevicePath is the End of Device Path Node, + // if yes, go on checking other conditions + // + if (!IsDevicePathEnd (RemainingDevicePath)) { + // + // If RemainingDevicePath isn't the End of Device Path Node, + // check its validation + // + if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH || + RemainingDevicePath->SubType != HW_VENDOR_DP || + DevicePathNodeLength(RemainingDevicePath) != sizeof(EMU_VENDOR_DEVICE_PATH_NODE)) { + return EFI_UNSUPPORTED; + } + } + } + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEmuThunkProtocolGuid, + (VOID **)&EmuThunk , + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Close the I/O Abstraction(s) used to perform the supported test + // + gBS->CloseProtocol ( + ControllerHandle, + &gEmuThunkProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + // + // Open the EFI Device Path protocol needed to perform the supported test + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + (VOID **)&ParentDevicePath, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + + // + // Close protocol, don't use device path protocol in the Support() function + // + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + return Status; +} + + +EFI_STATUS +EFIAPI +EmuBusDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_STATUS InstallStatus; + EMU_THUNK_PROTOCOL *EmuThunk; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EMU_IO_DEVICE *EmuDevice; + EMU_BUS_DEVICE *EmuBusDevice; + EMU_IO_THUNK_PROTOCOL *EmuIoThunk; + UINTN Index; + CHAR16 *StartString; + CHAR16 *SubString; + UINTN StringSize; + UINT16 ComponentName[512]; + EMU_VENDOR_DEVICE_PATH_NODE *Node; + BOOLEAN CreateDevice; + CHAR16 *TempStr; + CHAR16 *PcdTempStr; + UINTN TempStrSize; + + + Status = EFI_UNSUPPORTED; + + // + // Grab the protocols we need + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + (VOID **)&ParentDevicePath, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + return Status; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEmuThunkProtocolGuid, + (VOID **)&EmuThunk, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + return Status; + } + + if (Status != EFI_ALREADY_STARTED) { + EmuBusDevice = AllocatePool (sizeof (EMU_BUS_DEVICE)); + if (EmuBusDevice == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + EmuBusDevice->Signature = EMU_BUS_DEVICE_SIGNATURE; + EmuBusDevice->ControllerNameTable = NULL; + + AddUnicodeString2 ( + "eng", + gEmuBusDriverComponentName.SupportedLanguages, + &EmuBusDevice->ControllerNameTable, + L"InOsEmu Bus Controller", + TRUE + ); + AddUnicodeString2 ( + "en", + gEmuBusDriverComponentName2.SupportedLanguages, + &EmuBusDevice->ControllerNameTable, + L"InOsEmu Bus Controller", + FALSE + ); + + + Status = gBS->InstallMultipleProtocolInterfaces ( + &ControllerHandle, + &gEfiCallerIdGuid, EmuBusDevice, + NULL + ); + if (EFI_ERROR (Status)) { + FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable); + gBS->FreePool (EmuBusDevice); + return Status; + } + } + + + for (Status = EFI_SUCCESS, EmuIoThunk = NULL; !EFI_ERROR (Status); ) { + Status = EmuThunk->GetNextProtocol (TRUE, &EmuIoThunk); + if (EFI_ERROR (Status)) { + break; + } + + CreateDevice = TRUE; + if (RemainingDevicePath != NULL) { + CreateDevice = FALSE; + // + // Check if RemainingDevicePath is the End of Device Path Node, + // if yes, don't create any child device + // + if (!IsDevicePathEnd (RemainingDevicePath)) { + // + // If RemainingDevicePath isn't the End of Device Path Node, + // check its validation + // + Node = (EMU_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath; + if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH && + Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP && + DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (EMU_VENDOR_DEVICE_PATH_NODE) + ) { + if (CompareGuid (&Node->VendorDevicePath.Guid, EmuIoThunk->Protocol) && Node->Instance == EmuIoThunk->Instance) { + CreateDevice = TRUE; + } + } + } + } + + if (CreateDevice) { + // + // Allocate instance structure, and fill in parent information. + // + EmuDevice = AllocatePool (sizeof (EMU_IO_DEVICE)); + if (EmuDevice == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + EmuDevice->Handle = NULL; + EmuDevice->ControllerHandle = ControllerHandle; + EmuDevice->ParentDevicePath = ParentDevicePath; + CopyMem (&EmuDevice->EmuIoThunk, EmuIoThunk, sizeof (EMU_IO_THUNK_PROTOCOL)); + + EmuDevice->ControllerNameTable = NULL; + + StrnCpy (ComponentName, EmuIoThunk->ConfigString, sizeof (ComponentName)/sizeof (CHAR16)); + + EmuDevice->DevicePath = EmuBusCreateDevicePath ( + ParentDevicePath, + EmuIoThunk->Protocol, + EmuIoThunk->Instance + ); + if (EmuDevice->DevicePath == NULL) { + gBS->FreePool (EmuDevice); + return EFI_OUT_OF_RESOURCES; + } + + AddUnicodeString ( + "eng", + gEmuBusDriverComponentName.SupportedLanguages, + &EmuDevice->ControllerNameTable, + ComponentName + ); + + EmuDevice->Signature = EMU_IO_DEVICE_SIGNATURE; + + InstallStatus = gBS->InstallMultipleProtocolInterfaces ( + &EmuDevice->Handle, + &gEfiDevicePathProtocolGuid, EmuDevice->DevicePath, + &gEmuIoThunkProtocolGuid, &EmuDevice->EmuIoThunk, + NULL + ); + if (EFI_ERROR (InstallStatus)) { + FreeUnicodeStringTable (EmuDevice->ControllerNameTable); + gBS->FreePool (EmuDevice); + } else { + // + // Open For Child Device + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEmuThunkProtocolGuid, + (VOID **)&EmuThunk , + This->DriverBindingHandle, + EmuDevice->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (!EFI_ERROR (Status)) { + InstallStatus = EFI_SUCCESS; + } + } + } + } + + return InstallStatus; +} + + +EFI_STATUS +EFIAPI +EmuBusDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + UINTN Index; + BOOLEAN AllChildrenStopped; + EMU_IO_THUNK_PROTOCOL *EmuIoThunk; + EMU_BUS_DEVICE *EmuBusDevice; + EMU_IO_DEVICE *EmuDevice; + EMU_THUNK_PROTOCOL *EmuThunk; + + // + // Complete all outstanding transactions to Controller. + // Don't allow any new transaction to Controller to be started. + // + + if (NumberOfChildren == 0) { + // + // Close the bus driver + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiCallerIdGuid, + (VOID **)&EmuBusDevice, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->UninstallMultipleProtocolInterfaces ( + ControllerHandle, + &gEfiCallerIdGuid, EmuBusDevice, + NULL + ); + + FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable); + + gBS->FreePool (EmuBusDevice); + + gBS->CloseProtocol ( + ControllerHandle, + &gEmuThunkProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + return EFI_SUCCESS; + } + + AllChildrenStopped = TRUE; + + for (Index = 0; Index < NumberOfChildren; Index++) { + + Status = gBS->OpenProtocol ( + ChildHandleBuffer[Index], + &gEmuIoThunkProtocolGuid, + (VOID **)&EmuIoThunk, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + EmuDevice = EMU_IO_DEVICE_FROM_THIS (EmuIoThunk); + + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEmuThunkProtocolGuid, + This->DriverBindingHandle, + EmuDevice->Handle + ); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + EmuDevice->Handle, + &gEfiDevicePathProtocolGuid, EmuDevice->DevicePath, + &gEmuIoThunkProtocolGuid, EmuDevice->EmuIoThunk, + NULL + ); + + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + ControllerHandle, + &gEmuThunkProtocolGuid, + (VOID **) &EmuThunk , + This->DriverBindingHandle, + EmuDevice->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + } else { + // + // Close the child handle + // + FreeUnicodeStringTable (EmuDevice->ControllerNameTable); + FreePool (EmuDevice); + } + } + + if (EFI_ERROR (Status)) { + AllChildrenStopped = FALSE; + } + } + + if (!AllChildrenStopped) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + + +/*++ + +Routine Description: + Create a device path node using Guid and InstanceNumber and append it to + the passed in RootDevicePath + +Arguments: + RootDevicePath - Root of the device path to return. + + Guid - GUID to use in vendor device path node. + + InstanceNumber - Instance number to use in the vendor device path. This + argument is needed to make sure each device path is unique. + +Returns: + + EFI_DEVICE_PATH_PROTOCOL + +**/ +EFI_DEVICE_PATH_PROTOCOL * +EmuBusCreateDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath, + IN EFI_GUID *Guid, + IN UINT16 InstanceNumber + ) +{ + EMU_VENDOR_DEVICE_PATH_NODE DevicePath; + + DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH; + DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP; + SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (EMU_VENDOR_DEVICE_PATH_NODE)); + + // + // The GUID defines the Class + // + CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID)); + + // + // Add an instance number so we can make sure there are no Device Path + // duplication. + // + DevicePath.Instance = InstanceNumber; + + return AppendDevicePathNode ( + RootDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath + ); +} + + + +/** + The user Entry Point for module EmuBusDriver. The user code starts with this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InitializeEmuBusDriver ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = EfiLibInstallAllDriverProtocols ( + ImageHandle, + SystemTable, + &gEmuBusDriverBinding, + ImageHandle, + &gEmuBusDriverComponentName, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + + return Status; +} + + + + diff --git a/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.h b/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.h new file mode 100644 index 0000000000..e5eee56254 --- /dev/null +++ b/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.h @@ -0,0 +1,116 @@ +/*++ @file + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 __EMU_BUS_DRIVER_H__ +#define __EMU_BUS_DRIVER_H__ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern EFI_DRIVER_BINDING_PROTOCOL gEmuBusDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gEmuBusDriverComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gEmuBusDriverComponentName2; + + +// +// Unix Bus Controller Structure +// +#define EMU_BUS_DEVICE_SIGNATURE SIGNATURE_32 ('L', 'X', 'B', 'D') + +typedef struct { + UINT64 Signature; + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} EMU_BUS_DEVICE; + +// +// Unix Child Device Controller Structure +// +#define EMU_IO_DEVICE_SIGNATURE SIGNATURE_32 ('L', 'X', 'V', 'D') + +typedef struct { + UINT64 Signature; + EFI_HANDLE Handle; + EMU_IO_THUNK_PROTOCOL EmuIoThunk; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + // + // Private data about the parent + // + EFI_HANDLE ControllerHandle; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + + EFI_UNICODE_STRING_TABLE *ControllerNameTable; + +} EMU_IO_DEVICE; + +#define EMU_IO_DEVICE_FROM_THIS(a) \ + CR(a, EMU_IO_DEVICE, EmuIoThunk, EMU_IO_DEVICE_SIGNATURE) + + + +// +// Driver Binding Protocol function prototypes +// +EFI_STATUS +EFIAPI +EmuBusDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + + +EFI_STATUS +EFIAPI +EmuBusDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ParentHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + + +EFI_STATUS +EFIAPI +EmuBusDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +// +// Unix Bus Driver private worker functions +// +EFI_DEVICE_PATH_PROTOCOL * +EmuBusCreateDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath, + IN EFI_GUID *Guid, + IN UINT16 InstanceNumber + ); + + +#endif diff --git a/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf b/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf new file mode 100644 index 0000000000..88c2764beb --- /dev/null +++ b/InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf @@ -0,0 +1,63 @@ +## @file +# Emu Bus driver +# +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuBusDriver + FILE_GUID = 9842073D-95D9-9F49-BD3F-2E29525125DF + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeEmuBusDriver + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# +# DRIVER_BINDING = gEmuBusDriverBinding +# COMPONENT_NAME = gEmuBusDriverComponentName +# + +[Sources] + ComponentName.c + EmuBusDriverDxe.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + DevicePathLib + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + PcdLib + UefiLib + UefiDriverEntryPoint + BaseLib + DebugLib + + +[Protocols] + gEfiDevicePathProtocolGuid # PROTOCOL TO_START + gEmuThunkProtocolGuid # PROTOCOL TO_START + gEmuIoThunkProtocolGuid # PROTOCOL BY_START + + + diff --git a/InOsEmuPkg/EmuGopDxe/ComponentName.c b/InOsEmuPkg/EmuGopDxe/ComponentName.c new file mode 100644 index 0000000000..9360fa1738 --- /dev/null +++ b/InOsEmuPkg/EmuGopDxe/ComponentName.c @@ -0,0 +1,250 @@ +/** @file + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010,Apple Inc. 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: + + ComponentName.c + +Abstract: + +**/ + +#include "Gop.h" + +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +EmuGopComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +EmuGopComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL gEmuGopComponentName = { + EmuGopComponentNameGetDriverName, + EmuGopComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuGopComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmuGopComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmuGopComponentNameGetControllerName, + "en" +}; + + +EFI_UNICODE_STRING_TABLE mEmuGopDriverNameTable[] = { + { "eng", L"InOsEmu GOP Driver" }, + { NULL , NULL } +}; + + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] 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. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +EmuGopComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mEmuGopDriverNameTable, + DriverName, + (BOOLEAN)(This == &gEmuGopComponentName) + ); +} + + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] 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. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] 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. + + @retval 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. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +EmuGopComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + GOP_PRIVATE_DATA *Private; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing ControllerHandle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + gEmuGopDriverBinding.DriverBindingHandle, + &gEmuIoThunkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + // + // Get our context back + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiGraphicsOutputProtocolGuid, + (VOID **)&GraphicsOutput, + gEmuGopDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput); + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + Private->ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gEmuGopComponentName) + ); +} diff --git a/InOsEmuPkg/EmuGopDxe/EmuGopDxe.inf b/InOsEmuPkg/EmuGopDxe/EmuGopDxe.inf new file mode 100644 index 0000000000..2a988c9e5b --- /dev/null +++ b/InOsEmuPkg/EmuGopDxe/EmuGopDxe.inf @@ -0,0 +1,69 @@ +## @file +# GOP driver +# +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuGopDxe + FILE_GUID = BCC87E0D-86D6-4D4D-8040-2D983D368BD1 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeEmuGop + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# +# DRIVER_BINDING = gEmuGopDriverBinding +# COMPONENT_NAME = gEmuGopComponentName +# + +[Sources] + ComponentName.c + GopScreen.c + GopDriver.c + GopInput.c + Gop.h + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + UefiLib + UefiDriverEntryPoint + BaseLib + DebugLib + KeyMapLib + + +[Guids] + gEfiEventExitBootServicesGuid # SOMETIMES_CONSUMED Create Event: EVENT_GROUP_GUID + + +[Protocols] + gEfiGraphicsOutputProtocolGuid + gEfiSimpleTextInProtocolGuid # PROTOCOL BY_START + gEfiSimpleTextInputExProtocolGuid # PROTOCOL BY_START + gEfiSimplePointerProtocolGuid # PROTOCOL BY_START + gEmuIoThunkProtocolGuid # PROTOCOL TO_START + gEmuGraphicsWindowProtocolGuid # PROTOCOL TO_START diff --git a/InOsEmuPkg/EmuGopDxe/Gop.h b/InOsEmuPkg/EmuGopDxe/Gop.h new file mode 100644 index 0000000000..03e33ea636 --- /dev/null +++ b/InOsEmuPkg/EmuGopDxe/Gop.h @@ -0,0 +1,195 @@ +/*++ @file + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010,Apple Inc. 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 __UGA_H_ +#define __UGA_H_ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define MAX_Q 256 + +typedef struct { + UINTN Front; + UINTN Rear; + UINTN Count; + EFI_INPUT_KEY Q[MAX_Q]; +} GOP_QUEUE_FIXED; + +#define EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('U', 'g', 'S', 'n') +typedef struct _EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY { + UINTN Signature; + EFI_HANDLE NotifyHandle; + EFI_KEY_DATA KeyData; + EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn; + EFI_EVENT Event; + LIST_ENTRY NotifyEntry; +} EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY; + +#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff + +typedef struct { + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + UINT32 ColorDepth; + UINT32 RefreshRate; +} GOP_MODE_DATA; + + + +extern EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gEmuGopComponentName; + +#define EMU_UGA_CLASS_NAME L"EmuGopWindow" + +#define GOP_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('G', 'o', 'p', 'N') +typedef struct { + UINT64 Signature; + + EFI_HANDLE Handle; + EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn; + EFI_SIMPLE_POINTER_PROTOCOL SimplePointer; + + EMU_IO_THUNK_PROTOCOL *EmuIoThunk; + EMU_GRAPHICS_WINDOW_PROTOCOL *EmuGraphicsWindow; + + EFI_UNICODE_STRING_TABLE *ControllerNameTable; + + EFI_SIMPLE_POINTER_MODE PointerMode; + // + // GOP Private Data for QueryMode () + // + GOP_MODE_DATA *ModeData; + + + // + // UGA Private Data knowing when to start hardware + // + BOOLEAN HardwareNeedsStarting; + + CHAR16 *WindowName; + + GOP_QUEUE_FIXED Queue; + + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInEx; + EFI_KEY_STATE KeyState; + LIST_ENTRY NotifyList; +} GOP_PRIVATE_DATA; + + +#define GOP_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, GOP_PRIVATE_DATA, GraphicsOutput, GOP_PRIVATE_DATA_SIGNATURE) + +#define GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS(a) \ + CR(a, GOP_PRIVATE_DATA, SimpleTextIn, GOP_PRIVATE_DATA_SIGNATURE) + +#define GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS(a) \ + CR(a, GOP_PRIVATE_DATA, SimpleTextInEx, GOP_PRIVATE_DATA_SIGNATURE) + +#define GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS(a) \ + CR(a, GOP_PRIVATE_DATA, SimplePointer, GOP_PRIVATE_DATA_SIGNATURE) + + +// +// Global Protocol Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gEmuGopComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gEmuGopComponentName2; + +// +// Gop Hardware abstraction internal worker functions +// +EFI_STATUS +EmuGopSupported ( + IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk + ); + +EFI_STATUS +EmuGopConstructor ( + IN GOP_PRIVATE_DATA *Private + ); + +EFI_STATUS +EmuGopDestructor ( + IN GOP_PRIVATE_DATA *Private + ); + + +EFI_STATUS +GopPrivateAddQ ( + IN GOP_PRIVATE_DATA *Private, + IN EFI_INPUT_KEY Key + ); + +EFI_STATUS +EmuGopInitializeSimpleTextInForWindow ( + IN GOP_PRIVATE_DATA *Private + ); + +EFI_STATUS +EmuGopInitializeSimplePointerForWindow ( + IN GOP_PRIVATE_DATA *Private + ); + +EFI_STATUS +EmuGopStartWindow ( + IN GOP_PRIVATE_DATA *Private, + IN UINT32 HorizontalResolution, + IN UINT32 VerticalResolution, + IN UINT32 ColorDepth, + IN UINT32 RefreshRate + ); + +VOID +EFIAPI +ShutdownGopEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +VOID +EFIAPI +GopPrivateMakeCallbackFunction ( + IN VOID *Context, + IN EFI_KEY_DATA *KeyData + ); + +VOID +EFIAPI +GopPrivateBreakCallbackFunction ( + IN VOID *Context, + IN EFI_KEY_DATA *KeyData + ); + +#endif diff --git a/InOsEmuPkg/EmuGopDxe/GopDriver.c b/InOsEmuPkg/EmuGopDxe/GopDriver.c new file mode 100644 index 0000000000..8ddaa86cfa --- /dev/null +++ b/InOsEmuPkg/EmuGopDxe/GopDriver.c @@ -0,0 +1,443 @@ +/*++ @file + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010,Apple Inc. 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 "Gop.h" + + +EFI_STATUS +FreeNotifyList ( + IN OUT LIST_ENTRY *ListHead + ) +/*++ + +Routine Description: + +Arguments: + + ListHead - The list head + +Returns: + + EFI_SUCCESS - Free the notify list successfully + EFI_INVALID_PARAMETER - ListHead is invalid. + +**/ +{ + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NotifyNode; + + if (ListHead == NULL) { + return EFI_INVALID_PARAMETER; + } + while (!IsListEmpty (ListHead)) { + NotifyNode = CR ( + ListHead->ForwardLink, + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, + NotifyEntry, + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE + ); + RemoveEntryList (ListHead->ForwardLink); + gBS->FreePool (NotifyNode); + } + + return EFI_SUCCESS; +} + + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. +**/ +EFI_STATUS +EFIAPI +EmuGopDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EMU_IO_THUNK_PROTOCOL *EmuIoThunk; + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + Handle, + &gEmuIoThunkProtocolGuid, + (VOID **)&EmuIoThunk, + This->DriverBindingHandle, + Handle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = EmuGopSupported (EmuIoThunk); + + // + // Close the I/O Abstraction(s) used to perform the supported test + // + gBS->CloseProtocol ( + Handle, + &gEmuIoThunkProtocolGuid, + This->DriverBindingHandle, + Handle + ); + + return Status; +} + + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +EmuGopDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EMU_IO_THUNK_PROTOCOL *EmuIoThunk; + EFI_STATUS Status; + GOP_PRIVATE_DATA *Private; + + // + // Grab the protocols we need + // + Status = gBS->OpenProtocol ( + Handle, + &gEmuIoThunkProtocolGuid, + (VOID **)&EmuIoThunk, + This->DriverBindingHandle, + Handle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Allocate Private context data for SGO inteface. + // + Private = NULL; + Status = gBS->AllocatePool ( + EfiBootServicesData, + sizeof (GOP_PRIVATE_DATA), + (VOID **)&Private + ); + if (EFI_ERROR (Status)) { + goto Done; + } + // + // Set up context record + // + Private->Signature = GOP_PRIVATE_DATA_SIGNATURE; + Private->Handle = Handle; + Private->EmuIoThunk = EmuIoThunk; + Private->WindowName = EmuIoThunk->ConfigString; + Private->ControllerNameTable = NULL; + + AddUnicodeString ( + "eng", + gEmuGopComponentName.SupportedLanguages, + &Private->ControllerNameTable, + EmuIoThunk->ConfigString + ); + AddUnicodeString2 ( + "en", + gEmuGopComponentName2.SupportedLanguages, + &Private->ControllerNameTable, + EmuIoThunk->ConfigString, + FALSE + ); + + Status = EmuGopConstructor (Private); + if (EFI_ERROR (Status)) { + goto Done; + } + // + // Publish the Gop interface to the world + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput, + &gEfiSimpleTextInProtocolGuid, &Private->SimpleTextIn, + &gEfiSimplePointerProtocolGuid, &Private->SimplePointer, + &gEfiSimpleTextInputExProtocolGuid, &Private->SimpleTextInEx, + NULL + ); + +Done: + if (EFI_ERROR (Status)) { + + gBS->CloseProtocol ( + Handle, + &gEmuIoThunkProtocolGuid, + This->DriverBindingHandle, + Handle + ); + + if (Private != NULL) { + // + // On Error Free back private data + // + if (Private->ControllerNameTable != NULL) { + FreeUnicodeStringTable (Private->ControllerNameTable); + } + if (Private->SimpleTextIn.WaitForKey != NULL) { + gBS->CloseEvent (Private->SimpleTextIn.WaitForKey); + } + if (Private->SimpleTextInEx.WaitForKeyEx != NULL) { + gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx); + } + FreeNotifyList (&Private->NotifyList); + + gBS->FreePool (Private); + } + } + + return Status; +} + + + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +EmuGopDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Handle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_STATUS Status; + GOP_PRIVATE_DATA *Private; + + Status = gBS->OpenProtocol ( + Handle, + &gEfiGraphicsOutputProtocolGuid, + (VOID **)&GraphicsOutput, + This->DriverBindingHandle, + Handle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + // + // If the GOP interface does not exist the driver is not started + // + return EFI_NOT_STARTED; + } + + // + // Get our private context information + // + Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput); + + // + // Remove the SGO interface from the system + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + Private->Handle, + &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput, + &gEfiSimpleTextInProtocolGuid, &Private->SimpleTextIn, + &gEfiSimplePointerProtocolGuid, &Private->SimplePointer, + &gEfiSimpleTextInputExProtocolGuid, &Private->SimpleTextInEx, + NULL + ); + if (!EFI_ERROR (Status)) { + // + // Shutdown the hardware + // + Status = EmuGopDestructor (Private); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + gBS->CloseProtocol ( + Handle, + &gEmuIoThunkProtocolGuid, + This->DriverBindingHandle, + Handle + ); + + // + // Free our instance data + // + FreeUnicodeStringTable (Private->ControllerNameTable); + + Status = gBS->CloseEvent (Private->SimpleTextIn.WaitForKey); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx); + ASSERT_EFI_ERROR (Status); + + FreeNotifyList (&Private->NotifyList); + + gBS->FreePool (Private); + + } + + return Status; +} + + +/// +/// This protocol provides the services required to determine if a driver supports a given controller. +/// If a controller is supported, then it also provides routines to start and stop the controller. +/// +EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding = { + EmuGopDriverBindingSupported, + EmuGopDriverBindingStart, + EmuGopDriverBindingStop, + 0xa, + NULL, + NULL +}; + + + +/** + The user Entry Point for module EmuGop. The user code starts with this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InitializeEmuGop ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gEmuGopDriverBinding, + ImageHandle, + &gEmuGopComponentName, + &gEmuGopComponentName2 + ); + ASSERT_EFI_ERROR (Status); + + + return Status; +} + diff --git a/InOsEmuPkg/EmuGopDxe/GopInput.c b/InOsEmuPkg/EmuGopDxe/GopInput.c new file mode 100644 index 0000000000..f6c7959bcf --- /dev/null +++ b/InOsEmuPkg/EmuGopDxe/GopInput.c @@ -0,0 +1,899 @@ +/*++ @file + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 0 2011,Apple Inc. 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 "Gop.h" + + +BOOLEAN +GopPrivateIsKeyRegistered ( + IN EFI_KEY_DATA *RegsiteredData, + IN EFI_KEY_DATA *InputData + ) +/*++ + +Routine Description: + +Arguments: + + RegsiteredData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was registered. + InputData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was pressed. + +Returns: + TRUE - Key be pressed matches a registered key. + FLASE - Match failed. + +**/ +{ + ASSERT (RegsiteredData != NULL && InputData != NULL); + + if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) || + (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) { + return FALSE; + } + + // + // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored. + // + if (RegsiteredData->KeyState.KeyShiftState != 0 && + RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) { + return FALSE; + } + if (RegsiteredData->KeyState.KeyToggleState != 0 && + RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) { + return FALSE; + } + + return TRUE; + +} + + +VOID +EFIAPI +GopPrivateMakeCallbackFunction ( + IN VOID *Context, + IN EFI_KEY_DATA *KeyData + ) +{ + LIST_ENTRY *Link; + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; + GOP_PRIVATE_DATA *Private = (GOP_PRIVATE_DATA *)Context; + + KeyMapMake (KeyData); + + for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { + CurrentNotify = CR ( + Link, + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, + NotifyEntry, + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE + ); + if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { + // We could be called at a high TPL so signal an event to call the registered function + // at a lower TPL. + gBS->SignalEvent (CurrentNotify->Event); + } + } +} + + +VOID +EFIAPI +GopPrivateBreakCallbackFunction ( + IN VOID *Context, + IN EFI_KEY_DATA *KeyData + ) +{ + GOP_PRIVATE_DATA *Private = (GOP_PRIVATE_DATA *)Context; + + KeyMapBreak (KeyData); +} + + + +// +// Simple Text In implementation. +// + +/** + Reset the input device and optionally run diagnostics + + @param This Protocol instance pointer. + @param ExtendedVerification Driver may perform diagnostics on reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. + +**/ +EFI_STATUS +EFIAPI +EmuGopSimpleTextInReset ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + GOP_PRIVATE_DATA *Private; + EFI_KEY_DATA KeyData; + EFI_TPL OldTpl; + + Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); + if (Private->EmuGraphicsWindow == NULL) { + return EFI_SUCCESS; + } + + // + // Enter critical section + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + // + // A reset is draining the Queue + // + while (Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData) == EFI_SUCCESS) + ; + + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); + return EFI_SUCCESS; +} + + +/** + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existence of a keystroke via WaitForEvent () call. + + @param This Protocol instance pointer. + @param Key A pointer to a buffer that is filled in with the keystroke + information for the key that was pressed. + + @retval EFI_SUCCESS The keystroke information was returned. + @retval EFI_NOT_READY There was no keystroke data available. + @retval EFI_DEVICE_ERROR The keystroke information was not returned due to + hardware errors. + +**/ +EFI_STATUS +EFIAPI +EmuGopSimpleTextInReadKeyStroke ( + IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, + OUT EFI_INPUT_KEY *Key + ) +{ + GOP_PRIVATE_DATA *Private; + EFI_STATUS Status; + EFI_TPL OldTpl; + EFI_KEY_DATA KeyData; + + Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); + if (Private->EmuGraphicsWindow == NULL) { + return EFI_NOT_READY; + } + + // + // Enter critical section + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData); + CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); + + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); + + return Status; +} + + + +/** + SimpleTextIn and SimpleTextInEx Notify Wait Event + + @param Event Event whose notification function is being invoked. + @param Context Pointer to GOP_PRIVATE_DATA. + +**/ +VOID +EFIAPI +EmuGopSimpleTextInWaitForKey ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + GOP_PRIVATE_DATA *Private; + EFI_STATUS Status; + EFI_TPL OldTpl; + + Private = (GOP_PRIVATE_DATA *) Context; + if (Private->EmuGraphicsWindow == NULL) { + return; + } + + // + // Enter critical section + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + Status = Private->EmuGraphicsWindow->CheckKey (Private->EmuGraphicsWindow); + if (!EFI_ERROR (Status)) { + // + // If a there is a key in the queue signal our event. + // + gBS->SignalEvent (Event); + } + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); +} + + +// +// Simple Text Input Ex protocol functions +// + + +/** + The Reset() function resets the input device hardware. 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. The hardware verification process is not defined by + this specification and is left up to the platform firmware or + driver to implement. + + @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. + + @param ExtendedVerification Indicates that the driver may + perform a more exhaustive + verification operation of the + device during reset. + + + @retval EFI_SUCCESS The device was reset. + + @retval EFI_DEVICE_ERROR The device is not functioning + correctly and could not be reset. + +**/ +EFI_STATUS +EFIAPI +EmuGopSimpleTextInExResetEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +/*++ + + Routine Description: + Reset the input device and optionaly run diagnostics + + Arguments: + This - Protocol instance pointer. + ExtendedVerification - Driver may perform diagnostics on reset. + + Returns: + EFI_SUCCESS - The device was reset. + +**/ +{ + GOP_PRIVATE_DATA *Private; + + Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); + + return EFI_SUCCESS; +} + + + +/** + The function reads the next keystroke from the input device. If + there is no pending keystroke the function returns + EFI_NOT_READY. If there is a pending keystroke, then + KeyData.Key.ScanCode is the EFI scan code defined in Error! + Reference source not found. The KeyData.Key.UnicodeChar is the + actual printable character or is zero if the key does not + represent a printable character (control key, function key, + etc.). The KeyData.KeyState is shift state for the character + reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode . + When interpreting the data from this function, it should be + noted that if a class of printable characters that are + normally adjusted by shift modifiers (e.g. Shift Key + "f" + key) would be presented solely as a KeyData.Key.UnicodeChar + without the associated shift state. So in the previous example + of a Shift Key + "f" key being pressed, the only pertinent + data returned would be KeyData.Key.UnicodeChar with the value + of "F". This of course would not typically be the case for + non-printable characters such as the pressing of the Right + Shift Key + F10 key since the corresponding returned data + would be reflected both in the KeyData.KeyState.KeyShiftState + and KeyData.Key.ScanCode values. UEFI drivers which implement + the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return + KeyData.Key and KeyData.KeyState values. These drivers must + always return the most current state of + KeyData.KeyState.KeyShiftState and + KeyData.KeyState.KeyToggleState. It should also be noted that + certain input devices may not be able to produce shift or toggle + state information, and in those cases the high order bit in the + respective Toggle and Shift state fields should not be active. + + + @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. + + @param KeyData A pointer to a buffer that is filled in with + the keystroke state data for the key that was + pressed. + + + @retval EFI_SUCCESS The keystroke information was + returned. + + @retval EFI_NOT_READY There was no keystroke data available. + EFI_DEVICE_ERROR The keystroke + information was not returned due to + hardware errors. + + +**/ +EFI_STATUS +EFIAPI +EmuGopSimpleTextInExReadKeyStrokeEx ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ) +/*++ + + Routine Description: + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existance of a keystroke via WaitForEvent () call. + + Arguments: + This - Protocol instance pointer. + KeyData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was pressed. + + Returns: + EFI_SUCCESS - The keystroke information was returned. + EFI_NOT_READY - There was no keystroke data availiable. + EFI_DEVICE_ERROR - The keystroke information was not returned due to + hardware errors. + EFI_INVALID_PARAMETER - KeyData is NULL. + +**/ +{ + EFI_STATUS Status; + GOP_PRIVATE_DATA *Private; + EFI_TPL OldTpl; + + + if (KeyData == NULL) { + return EFI_INVALID_PARAMETER; + } + + Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); + if (Private->EmuGraphicsWindow == NULL) { + return EFI_NOT_READY; + } + + // + // Enter critical section + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + Status = Private->EmuGraphicsWindow->GetKey(Private->EmuGraphicsWindow, KeyData); + + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); + + return Status; +} + + + +/** + The SetState() function allows the input device hardware to + have state settings adjusted. + + @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. + + @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to + set the state for the input device. + + + @retval EFI_SUCCESS The device state was set appropriately. + + @retval EFI_DEVICE_ERROR The device is not functioning + correctly and could not have the + setting adjusted. + + @retval EFI_UNSUPPORTED The device does not support the + ability to have its state set. + +**/ +EFI_STATUS +EFIAPI +EmuGopSimpleTextInExSetState ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ) +{ + GOP_PRIVATE_DATA *Private; + EFI_STATUS Status; + EFI_TPL OldTpl; + + Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This); + if (Private->EmuGraphicsWindow == NULL) { + return EFI_NOT_READY; + } + + // + // Enter critical section + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + Status = Private->EmuGraphicsWindow->KeySetState (Private->EmuGraphicsWindow, KeyToggleState); + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); + + return Status; +} + + +/** + SimpleTextIn and SimpleTextInEx Notify Wait Event + + @param Event Event whose notification function is being invoked. + @param Context Pointer to GOP_PRIVATE_DATA. + +**/ +VOID +EFIAPI +EmuGopRegisterKeyCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *ExNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)Context; + + ExNotify->KeyNotificationFn (&ExNotify->KeyData); +} + + + +/** + The RegisterKeystrokeNotify() function registers a function + which will be called when a specified keystroke will occur. + + @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. + + @param KeyData A pointer to a buffer that is filled in with + the keystroke information for the key that was + pressed. + + @param KeyNotificationFunction Points to the function to be + called when the key sequence + is typed specified by KeyData. + + + @param NotifyHandle Points to the unique handle assigned to + the registered notification. + + @retval EFI_SUCCESS The device state was set + appropriately. + + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary + data structures. + +**/ +EFI_STATUS +EFIAPI +EmuGopSimpleTextInExRegisterKeyNotify ( + 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; + GOP_PRIVATE_DATA *Private; + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; + LIST_ENTRY *Link; + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify; + + if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); + + // + // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. + // + for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { + CurrentNotify = CR ( + Link, + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, + NotifyEntry, + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE + ); + if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { + if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { + *NotifyHandle = CurrentNotify->NotifyHandle; + return EFI_SUCCESS; + } + } + } + + // + // Allocate resource to save the notification function + // + NewNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY)); + if (NewNotify == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewNotify->Signature = EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE; + NewNotify->KeyNotificationFn = KeyNotificationFunction; + NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify; + CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData)); + InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry); + + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + EmuGopRegisterKeyCallback, + NewNotify, + &NewNotify->Event + ); + ASSERT_EFI_ERROR (Status); + + + *NotifyHandle = NewNotify->NotifyHandle; + + return EFI_SUCCESS; + +} + + +/** + The UnregisterKeystrokeNotify() function removes the + notification which was previously registered. + + @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. + + @param NotificationHandle The handle of the notification + function being unregistered. + + @retval EFI_SUCCESS The device state was set appropriately. + + @retval EFI_INVALID_PARAMETER The NotificationHandle is + invalid. + +**/ +EFI_STATUS +EFIAPI +EmuGopSimpleTextInExUnregisterKeyNotify ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_HANDLE NotificationHandle + ) +/*++ + + Routine Description: + Remove a registered notification function from a particular keystroke. + + Arguments: + This - Protocol instance pointer. + NotificationHandle - The handle of the notification function being unregistered. + + Returns: + EFI_SUCCESS - The notification function was unregistered successfully. + EFI_INVALID_PARAMETER - The NotificationHandle is invalid. + +**/ +{ + GOP_PRIVATE_DATA *Private; + LIST_ENTRY *Link; + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; + + if (NotificationHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (((EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) NotificationHandle)->Signature != EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) { + return EFI_INVALID_PARAMETER; + } + + Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); + + for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { + CurrentNotify = CR ( + Link, + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, + NotifyEntry, + EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE + ); + if (CurrentNotify->NotifyHandle == NotificationHandle) { + // + // Remove the notification function from NotifyList and free resources + // + RemoveEntryList (&CurrentNotify->NotifyEntry); + + gBS->CloseEvent (CurrentNotify->Event); + + gBS->FreePool (CurrentNotify); + return EFI_SUCCESS; + } + } + + // + // Can not find the specified Notification Handle + // + return EFI_INVALID_PARAMETER; +} + + + +/** + Initialize SimplelTextIn and SimpleTextInEx protocols in the Private + context structure. + + @param Private Context structure to fill in. + + @return EFI_SUCCESS Initialization was a success + +**/ +EFI_STATUS +EmuGopInitializeSimpleTextInForWindow ( + IN GOP_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + + // + // Initialize Simple Text In protoocol + // + Private->SimpleTextIn.Reset = EmuGopSimpleTextInReset; + Private->SimpleTextIn.ReadKeyStroke = EmuGopSimpleTextInReadKeyStroke; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + EmuGopSimpleTextInWaitForKey, + Private, + &Private->SimpleTextIn.WaitForKey + ); + ASSERT_EFI_ERROR (Status); + + + // + // Initialize Simple Text In Ex + // + + Private->SimpleTextInEx.Reset = EmuGopSimpleTextInExResetEx; + Private->SimpleTextInEx.ReadKeyStrokeEx = EmuGopSimpleTextInExReadKeyStrokeEx; + Private->SimpleTextInEx.SetState = EmuGopSimpleTextInExSetState; + Private->SimpleTextInEx.RegisterKeyNotify = EmuGopSimpleTextInExRegisterKeyNotify; + Private->SimpleTextInEx.UnregisterKeyNotify = EmuGopSimpleTextInExUnregisterKeyNotify; + + Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE); + + InitializeListHead (&Private->NotifyList); + + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + EmuGopSimpleTextInWaitForKey, + Private, + &Private->SimpleTextInEx.WaitForKeyEx + ); + ASSERT_EFI_ERROR (Status); + + + return Status; +} + + + + + + + +// +// Simple Pointer implementation. +// + + +/** + Resets the pointer device hardware. + + @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL + instance. + @param ExtendedVerification Indicates that the driver may perform a more exhaustive + verification operation of the device during reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset. + +**/ +EFI_STATUS +EFIAPI +EmuGopSimplePointerReset ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + GOP_PRIVATE_DATA *Private; + EFI_SIMPLE_POINTER_STATE State; + EFI_TPL OldTpl; + + Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This); + if (Private->EmuGraphicsWindow == NULL) { + return EFI_SUCCESS; + } + + // + // Enter critical section + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + // + // A reset is draining the Queue + // + while (Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, &State) == EFI_SUCCESS) + ; + + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); + return EFI_SUCCESS; +} + + +/** + Retrieves the current state of a pointer device. + + @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL + instance. + @param State A pointer to the state information on the pointer device. + + @retval EFI_SUCCESS The state of the pointer device was returned in State. + @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to + GetState(). + @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's + current state. + +**/ +EFI_STATUS +EFIAPI +EmuGopSimplePointerGetState ( + IN EFI_SIMPLE_POINTER_PROTOCOL *This, + IN OUT EFI_SIMPLE_POINTER_STATE *State + ) +{ + GOP_PRIVATE_DATA *Private; + EFI_STATUS Status; + EFI_TPL OldTpl; + + Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This); + if (Private->EmuGraphicsWindow == NULL) { + return EFI_NOT_READY; + } + + // + // Enter critical section + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + Status = Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, State); + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); + + return Status; +} + + +/** + SimplePointer Notify Wait Event + + @param Event Event whose notification function is being invoked. + @param Context Pointer to GOP_PRIVATE_DATA. + +**/ +VOID +EFIAPI +EmuGopSimplePointerWaitForInput ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + GOP_PRIVATE_DATA *Private; + EFI_STATUS Status; + EFI_TPL OldTpl; + + Private = (GOP_PRIVATE_DATA *) Context; + if (Private->EmuGraphicsWindow == NULL) { + return; + } + + // + // Enter critical section + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + + Status = Private->EmuGraphicsWindow->CheckPointer (Private->EmuGraphicsWindow); + if (!EFI_ERROR (Status)) { + // + // If the pointer state has changed, signal our event. + // + gBS->SignalEvent (Event); + } + // + // Leave critical section and return + // + gBS->RestoreTPL (OldTpl); +} + + +/** + SimplePointer constructor + + @param Private Context structure to fill in. + + @retval EFI_SUCCESS Constructor had success + +**/ +EFI_STATUS +EmuGopInitializeSimplePointerForWindow ( + IN GOP_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + + // + // Initialize Simple Pointer protoocol + // + Private->PointerMode.ResolutionX = 1; + Private->PointerMode.ResolutionY = 1; + Private->PointerMode.ResolutionZ = 1; + Private->PointerMode.LeftButton = TRUE; + Private->PointerMode.RightButton = TRUE; + + Private->SimplePointer.Reset = EmuGopSimplePointerReset; + Private->SimplePointer.GetState = EmuGopSimplePointerGetState; + Private->SimplePointer.Mode = &Private->PointerMode; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_WAIT, + TPL_NOTIFY, + EmuGopSimplePointerWaitForInput, + Private, + &Private->SimplePointer.WaitForInput + ); + + return Status; +} diff --git a/InOsEmuPkg/EmuGopDxe/GopScreen.c b/InOsEmuPkg/EmuGopDxe/GopScreen.c new file mode 100644 index 0000000000..e7e58adf80 --- /dev/null +++ b/InOsEmuPkg/EmuGopDxe/GopScreen.c @@ -0,0 +1,420 @@ +/*++ @file + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. 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: + + EmuGopScreen.c + +Abstract: + + This file produces the graphics abstration of UGA. It is called by + EmuGopDriver.c file which deals with the EFI 1.1 driver model. + This file just does graphics. + +**/ + +#include "Gop.h" + + +EFI_EVENT mGopScreenExitBootServicesEvent; + +GOP_MODE_DATA mGopModeData[] = { + { 800, 600, 0, 0 }, + { 640, 480, 0, 0 }, + { 720, 400, 0, 0 }, + {1024, 768, 0, 0 }, + {1280, 1024, 0, 0 } + }; + + +/** + Returns information for an available graphics mode that the graphics device + and the set of active video output devices supports. + + @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance. + @param ModeNumber The mode number to return information on. + @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer. + @param Info A pointer to callee allocated buffer that returns information about ModeNumber. + + @retval EFI_SUCCESS Mode information returned. + @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode. + @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () + @retval EFI_INVALID_PARAMETER One of the input args was NULL. + +**/ +EFI_STATUS +EFIAPI +EmuGopQuerytMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +{ + GOP_PRIVATE_DATA *Private; + + Private = GOP_PRIVATE_DATA_FROM_THIS (This); + + if (Info == NULL || SizeOfInfo == NULL || (UINTN) ModeNumber >= This->Mode->MaxMode) { + return EFI_INVALID_PARAMETER; + } + + *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); + if (*Info == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + + (*Info)->Version = 0; + (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution; + (*Info)->VerticalResolution = Private->ModeData[ModeNumber].VerticalResolution; + (*Info)->PixelFormat = PixelBltOnly; + (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution; + + return EFI_SUCCESS; +} + + + +/** + Set the video device into the specified mode and clears the visible portions of + the output display to black. + + @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance. + @param ModeNumber Abstraction that defines the current video mode. + + @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected. + @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. + @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. + +**/ +EFI_STATUS +EFIAPI +EmuGopSetMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ) +{ + EFI_STATUS Status; + GOP_PRIVATE_DATA *Private; + GOP_MODE_DATA *ModeData; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill; + + Private = GOP_PRIVATE_DATA_FROM_THIS (This); + + if (ModeNumber >= This->Mode->MaxMode) { + return EFI_UNSUPPORTED; + } + + ModeData = &Private->ModeData[ModeNumber]; + This->Mode->Mode = ModeNumber; + Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution; + Private->GraphicsOutput.Mode->Info->VerticalResolution = ModeData->VerticalResolution; + Private->GraphicsOutput.Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution; + + if (Private->HardwareNeedsStarting) { + Status = EmuGopStartWindow ( + Private, + ModeData->HorizontalResolution, + ModeData->VerticalResolution, + ModeData->ColorDepth, + ModeData->RefreshRate + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Private->HardwareNeedsStarting = FALSE; + } + + + Status = Private->EmuGraphicsWindow->Size( + Private->EmuGraphicsWindow, + ModeData->HorizontalResolution, + ModeData->VerticalResolution + ); + + + Fill.Red = 0x7f; + Fill.Green = 0x7F; + Fill.Blue = 0x7f; + This->Blt ( + This, + &Fill, + EfiBltVideoFill, + 0, + 0, + 0, + 0, + ModeData->HorizontalResolution, + ModeData->VerticalResolution, + ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + return EFI_SUCCESS; +} + + + +/** + Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer. + + @param This Protocol instance pointer. + @param BltBuffer Buffer containing data to blit into video buffer. This + buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + @param BltOperation Operation to perform on BlitBuffer and video memory + @param SourceX X coordinate of source for the BltBuffer. + @param SourceY Y coordinate of source for the BltBuffer. + @param DestinationX X coordinate of destination for the BltBuffer. + @param DestinationY Y coordinate of destination for the BltBuffer. + @param Width Width of rectangle in BltBuffer in pixels. + @param Height Hight of rectangle in BltBuffer in pixels. + @param Delta OPTIONAL + + @retval EFI_SUCCESS The Blt operation completed. + @retval EFI_INVALID_PARAMETER BltOperation is not valid. + @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer. + +**/ +EFI_STATUS +EFIAPI +EmuGopBlt ( + 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 OPTIONAL + ) +{ + GOP_PRIVATE_DATA *Private; + EFI_TPL OriginalTPL; + EFI_STATUS Status; + EMU_GRAPHICS_WINDOWS__BLT_ARGS GopBltArgs; + + Private = GOP_PRIVATE_DATA_FROM_THIS (This); + + if ((BltOperation < 0) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) { + return EFI_INVALID_PARAMETER; + } + + if (Width == 0 || Height == 0) { + 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_UGA_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 (TPL_NOTIFY); + + // + // Pack UGA Draw protocol parameters to EMU_GRAPHICS_WINDOWS__BLT_ARGS structure to adapt to + // GopBlt() API of Unix UGA IO protocol. + // + GopBltArgs.DestinationX = DestinationX; + GopBltArgs.DestinationY = DestinationY; + GopBltArgs.Height = Height; + GopBltArgs.Width = Width; + GopBltArgs.SourceX = SourceX; + GopBltArgs.SourceY = SourceY; + GopBltArgs.Delta = Delta; + Status = Private->EmuGraphicsWindow->Blt ( + Private->EmuGraphicsWindow, + (EFI_UGA_PIXEL *)BltBuffer, + (EFI_UGA_BLT_OPERATION)BltOperation, + &GopBltArgs + ); + + gBS->RestoreTPL (OriginalTPL); + + return Status; +} + + +// +// Construction and Destruction functions +// + +EFI_STATUS +EmuGopSupported ( + IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk + ) +{ + // + // Check to see if the IO abstraction represents a device type we support. + // + // This would be replaced a check of PCI subsystem ID, etc. + // + if (!CompareGuid (EmuIoThunk->Protocol, &gEmuGraphicsWindowProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +EmuGopStartWindow ( + IN GOP_PRIVATE_DATA *Private, + IN UINT32 HorizontalResolution, + IN UINT32 VerticalResolution, + IN UINT32 ColorDepth, + IN UINT32 RefreshRate + ) +{ + EFI_STATUS Status; + + // + // Register to be notified on exit boot services so we can destroy the window. + // + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_CALLBACK, + ShutdownGopEvent, + Private, + &mGopScreenExitBootServicesEvent + ); + + Status = Private->EmuIoThunk->Open (Private->EmuIoThunk); + if (!EFI_ERROR (Status)) { + Private->EmuGraphicsWindow = Private->EmuIoThunk->Interface; + + // Register callback to support RegisterKeyNotify() + Status = Private->EmuGraphicsWindow->RegisterKeyNotify ( + Private->EmuGraphicsWindow, + GopPrivateMakeCallbackFunction, + GopPrivateBreakCallbackFunction, + Private + ); + ASSERT_EFI_ERROR (Status); + } + return Status; +} + +EFI_STATUS +EmuGopConstructor ( + GOP_PRIVATE_DATA *Private + ) +{ + Private->ModeData = mGopModeData; + + Private->GraphicsOutput.QueryMode = EmuGopQuerytMode; + Private->GraphicsOutput.SetMode = EmuGopSetMode; + Private->GraphicsOutput.Blt = EmuGopBlt; + + // + // Allocate buffer for Graphics Output Protocol mode information + // + Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE)); + if (Private->GraphicsOutput.Mode == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); + if (Private->GraphicsOutput.Mode->Info == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Private->GraphicsOutput.Mode->MaxMode = sizeof(mGopModeData) / sizeof(GOP_MODE_DATA); + // + // Till now, we have no idea about the window size. + // + Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; + Private->GraphicsOutput.Mode->Info->Version = 0; + Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0; + Private->GraphicsOutput.Mode->Info->VerticalResolution = 0; + Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly; + Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); + Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL; + Private->GraphicsOutput.Mode->FrameBufferSize = 0; + + Private->HardwareNeedsStarting = TRUE; + Private->EmuGraphicsWindow = NULL; + + EmuGopInitializeSimpleTextInForWindow (Private); + + EmuGopInitializeSimplePointerForWindow (Private); + + return EFI_SUCCESS; +} + + + +EFI_STATUS +EmuGopDestructor ( + GOP_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + if (!Private->HardwareNeedsStarting) { + Status = Private->EmuIoThunk->Open (Private->EmuIoThunk); + Private->EmuGraphicsWindow = NULL; + } + + // + // Free graphics output protocol occupied resource + // + if (Private->GraphicsOutput.Mode != NULL) { + if (Private->GraphicsOutput.Mode->Info != NULL) { + FreePool (Private->GraphicsOutput.Mode->Info); + } + FreePool (Private->GraphicsOutput.Mode); + } + + return EFI_SUCCESS; +} + + +VOID +EFIAPI +ShutdownGopEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + This is the UGA screen's callback notification function for exit-boot-services. + All we do here is call EmuGopDestructor(). + +Arguments: + + Event - not used + Context - pointer to the Private structure. + +Returns: + + None. + +**/ +{ + EFI_STATUS Status; + Status = EmuGopDestructor (Context); +} + diff --git a/InOsEmuPkg/EmuSimpleFileSystemDxe/ComponentName.c b/InOsEmuPkg/EmuSimpleFileSystemDxe/ComponentName.c new file mode 100644 index 0000000000..fa6404a81a --- /dev/null +++ b/InOsEmuPkg/EmuSimpleFileSystemDxe/ComponentName.c @@ -0,0 +1,244 @@ +/** @file + +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. + +**/ + +#include "EmuSimpleFileSystem.h" + +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +EmuSimpleFileSystemComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +EmuSimpleFileSystemComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEmuSimpleFileSystemComponentName = { + EmuSimpleFileSystemComponentNameGetDriverName, + EmuSimpleFileSystemComponentNameGetControllerName, + "eng" +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuSimpleFileSystemComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)EmuSimpleFileSystemComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)EmuSimpleFileSystemComponentNameGetControllerName, + "en" +}; + +EFI_UNICODE_STRING_TABLE mEmuSimpleFileSystemDriverNameTable[] = { + { + "eng;en", + L"Emu Simple File System Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] 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. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mEmuSimpleFileSystemDriverNameTable, + DriverName, + (BOOLEAN)(This == &gEmuSimpleFileSystemComponentName) + ); +} + + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] 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. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name 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. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] 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. + + @retval 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. + + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing ControllerHandle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + gEmuSimpleFileSystemDriverBinding.DriverBindingHandle, + &gEmuIoThunkProtocolGuid + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + // + // Get our context back + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID**)&SimpleFileSystem, + gEmuSimpleFileSystemDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem); + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + Private->ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gEmuSimpleFileSystemComponentName) + ); +} diff --git a/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c b/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c new file mode 100644 index 0000000000..b7181fd255 --- /dev/null +++ b/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c @@ -0,0 +1,914 @@ +/*++ @file + Produce Simple File System abstractions for directories on your PC using Posix APIs. + The configuration of what devices to mount or emulate comes from UNIX + environment variables. The variables must be visible to the Microsoft* + Developer Studio for them to work. + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "EmuSimpleFileSystem.h" + + + + +/** + Opens a new file relative to the source file's location. + + @param This The protocol instance pointer. + @param NewHandle Returns File Handle for FileName. + @param FileName Null terminated string. "\", ".", and ".." are supported. + @param OpenMode Open mode for file. + @param Attributes Only used for EFI_FILE_MODE_CREATE. + + @retval EFI_SUCCESS The device was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_MEDIA_CHANGED The media has changed. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + + // + // Check for obvious invalid parameters. + // + if (This == NULL || NewHandle == NULL || FileName == NULL) { + return EFI_INVALID_PARAMETER; + } + + switch (OpenMode) { + case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE: + if (Attributes &~EFI_FILE_VALID_ATTR) { + return EFI_INVALID_PARAMETER; + } + + if (Attributes & EFI_FILE_READ_ONLY) { + return EFI_INVALID_PARAMETER; + } + + // + // fall through + // + case EFI_FILE_MODE_READ: + case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE: + break; + + default: + return EFI_INVALID_PARAMETER; + } + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + return PrivateFile->Io->Open (PrivateFile->Io, NewHandle, FileName, OpenMode, Attributes); +} + + + +/** + Close the file handle + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The file was closed. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemClose ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Status = PrivateFile->Io->Close (PrivateFile->Io); + if (!EFI_ERROR (Status)) { + gBS->FreePool (PrivateFile); + } + + gBS->RestoreTPL (OldTpl); + + return Status; +} + + +/** + Close and delete the file handle. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The file was closed and deleted. + @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = PrivateFile->Io->Delete (PrivateFile->Io); + if (!EFI_ERROR (Status)) { + gBS->FreePool (PrivateFile); + } + + gBS->RestoreTPL (OldTpl); + + return Status; +} + + +/** + Read data from the file. + + @param This Protocol instance pointer. + @param BufferSize On input size of buffer, on output amount of data in buffer. + @param Buffer The buffer in which data is read. + + @retval EFI_SUCCESS Data was read. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL || BufferSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((*BufferSize != 0) && (Buffer == NULL)) { + // Buffer can be NULL if *BufferSize is zero + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = PrivateFile->Io->Read (PrivateFile->Io, BufferSize, Buffer); + + gBS->RestoreTPL (OldTpl); + return Status; +} + + +/** + Write data to a file. + + @param This Protocol instance pointer. + @param BufferSize On input size of buffer, on output amount of data in buffer. + @param Buffer The buffer in which data to write. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to Open directory are not supported. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The device is write protected. + @retval EFI_ACCESS_DENIED The file was open for read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL || BufferSize == NULL || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = PrivateFile->Io->Write (PrivateFile->Io, BufferSize, Buffer); + + gBS->RestoreTPL (OldTpl); + return Status; +} + + +/** + Set a files current position + + @param This Protocol instance pointer. + @param Position Byte position from the start of the file. + + @retval EFI_SUCCESS Position was updated. + @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL || Position == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = PrivateFile->Io->GetPosition (PrivateFile->Io, Position); + + gBS->RestoreTPL (OldTpl); + return Status; +} + + + +/** + Get a file's current position + + @param This Protocol instance pointer. + @param Position Byte position from the start of the file. + + @retval EFI_SUCCESS Position was updated. + @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = PrivateFile->Io->SetPosition (PrivateFile->Io, Position); + + gBS->RestoreTPL (OldTpl); + return Status; +} + + +/** + Get information about a file. + + @param This Protocol instance pointer. + @param InformationType Type of information to return in Buffer. + @param BufferSize On input size of buffer, on output amount of data in buffer. + @param Buffer The buffer to return data. + + @retval EFI_SUCCESS Data was returned. + @retval EFI_UNSUPPORTED InformationType is not supported. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The device is write protected. + @retval EFI_ACCESS_DENIED The file was open for read only. + @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL || InformationType == NULL || BufferSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = PrivateFile->Io->GetInfo (PrivateFile->Io, InformationType, BufferSize, Buffer); + + gBS->RestoreTPL (OldTpl); + return Status; +} + + +/** + Set information about a file + + @param File Protocol instance pointer. + @param InformationType Type of information in Buffer. + @param BufferSize Size of buffer. + @param Buffer The data to write. + + @retval EFI_SUCCESS Data was set. + @retval EFI_UNSUPPORTED InformationType is not supported. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The device is write protected. + @retval EFI_ACCESS_DENIED The file was open for read only. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemSetInfo ( + IN EFI_FILE_PROTOCOL*This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + // + // Check for invalid parameters. + // + if (This == NULL || InformationType == NULL || BufferSize == 0 || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = PrivateFile->Io->SetInfo (PrivateFile->Io, InformationType, BufferSize, Buffer); + + gBS->RestoreTPL (OldTpl); + return Status; +} + + +/** + Flush data back for the file handle. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS Data was flushed. + @retval EFI_UNSUPPORTED Writes to Open directory are not supported. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The device is write protected. + @retval EFI_ACCESS_DENIED The file was open for read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemFlush ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = PrivateFile->Io->Flush (PrivateFile->Io); + + gBS->RestoreTPL (OldTpl); + return Status; +} + + + +/** + Open the root directory on a volume. + + @param This Protocol instance pointer. + @param Root Returns an Open file handle for the root directory + + @retval EFI_SUCCESS The device was opened. + @retval EFI_UNSUPPORTED This volume does not support the file system. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +{ + EFI_STATUS Status; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_TPL OldTpl; + + if (This == NULL || Root == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This); + + PrivateFile = AllocatePool (sizeof (EMU_EFI_FILE_PRIVATE)); + if (PrivateFile == NULL) { + goto Done; + } + + PrivateFile->Signature = EMU_EFI_FILE_PRIVATE_SIGNATURE; + PrivateFile->IoThunk = Private->IoThunk; + PrivateFile->SimpleFileSystem = This; + PrivateFile->EfiFile.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + PrivateFile->EfiFile.Open = EmuSimpleFileSystemOpen; + PrivateFile->EfiFile.Close = EmuSimpleFileSystemClose; + PrivateFile->EfiFile.Delete = EmuSimpleFileSystemDelete; + PrivateFile->EfiFile.Read = EmuSimpleFileSystemRead; + PrivateFile->EfiFile.Write = EmuSimpleFileSystemWrite; + PrivateFile->EfiFile.GetPosition = EmuSimpleFileSystemGetPosition; + PrivateFile->EfiFile.SetPosition = EmuSimpleFileSystemSetPosition; + PrivateFile->EfiFile.GetInfo = EmuSimpleFileSystemGetInfo; + PrivateFile->EfiFile.SetInfo = EmuSimpleFileSystemSetInfo; + PrivateFile->EfiFile.Flush = EmuSimpleFileSystemFlush; + + *Root = &PrivateFile->EfiFile; + + Status = Private->Io->OpenVolume (Private->Io, &PrivateFile->Io); + if (EFI_ERROR (Status)) { + goto Done; + } + + AddUnicodeString2 ( + "eng", + gEmuSimpleFileSystemComponentName.SupportedLanguages, + &Private->ControllerNameTable, + Private->IoThunk->ConfigString, + TRUE + ); + + AddUnicodeString2 ( + "en", + gEmuSimpleFileSystemComponentName.SupportedLanguages, + &Private->ControllerNameTable, + Private->IoThunk->ConfigString, + FALSE + ); + + +Done: + if (EFI_ERROR (Status)) { + if (PrivateFile) { + gBS->FreePool (PrivateFile); + } + + *Root = NULL; + } + + gBS->RestoreTPL (OldTpl); + + return Status; +} + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EMU_IO_THUNK_PROTOCOL *EmuIoThunk; + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEmuIoThunkProtocolGuid, + (VOID **)&EmuIoThunk, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Make sure GUID is for a File System handle. + // + Status = EFI_UNSUPPORTED; + if (CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) { + Status = EFI_SUCCESS; + } + + // + // Close the I/O Abstraction(s) used to perform the supported test + // + gBS->CloseProtocol ( + ControllerHandle, + &gEmuIoThunkProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + return Status; +} + + + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EMU_IO_THUNK_PROTOCOL *EmuIoThunk; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + INTN i; + + Private = NULL; + + // + // Open the IO Abstraction(s) needed + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEmuIoThunkProtocolGuid, + (VOID **)&EmuIoThunk, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Validate GUID + // + if (!CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + Private = AllocatePool (sizeof (EMU_SIMPLE_FILE_SYSTEM_PRIVATE)); + if (Private == NULL) { + goto Done; + } + + Status = EmuIoThunk->Open (EmuIoThunk); + if (EFI_ERROR (Status)) { + goto Done; + } + + Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE; + Private->IoThunk = EmuIoThunk; + Private->Io = EmuIoThunk->Interface; + + Private->SimpleFileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + Private->SimpleFileSystem.OpenVolume = EmuSimpleFileSystemOpenVolume; + + Private->ControllerNameTable = NULL; + + AddUnicodeString2 ( + "eng", + gEmuSimpleFileSystemComponentName.SupportedLanguages, + &Private->ControllerNameTable, + EmuIoThunk->ConfigString, + TRUE + ); + + AddUnicodeString2 ( + "en", + gEmuSimpleFileSystemComponentName2.SupportedLanguages, + &Private->ControllerNameTable, + EmuIoThunk->ConfigString, + FALSE + ); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, &Private->SimpleFileSystem, + NULL + ); + +Done: + if (EFI_ERROR (Status)) { + if (Private != NULL) { + if (Private->ControllerNameTable != NULL) { + FreeUnicodeStringTable (Private->ControllerNameTable); + } + + gBS->FreePool (Private); + + } + + gBS->CloseProtocol ( + ControllerHandle, + &gEmuIoThunkProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + return Status; +} + + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +EmuSimpleFileSystemDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + // + // Get our context back + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID **)&SimpleFileSystem, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem); + Status = Private->IoThunk->Close (Private->IoThunk); + + // + // Uninstall the Simple File System Protocol from ControllerHandle + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, &Private->SimpleFileSystem, + NULL + ); + if (!EFI_ERROR (Status)) { + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEmuIoThunkProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + if (!EFI_ERROR (Status)) { + // + // Free our instance data + // + FreeUnicodeStringTable (Private->ControllerNameTable); + gBS->FreePool (Private); + } + + return Status; +} + + +EFI_DRIVER_BINDING_PROTOCOL gEmuSimpleFileSystemDriverBinding = { + EmuSimpleFileSystemDriverBindingSupported, + EmuSimpleFileSystemDriverBindingStart, + EmuSimpleFileSystemDriverBindingStop, + 0xa, + NULL, + NULL +}; + + + + +/** + The user Entry Point for module EmuSimpleFileSystem. The user code starts with this function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InitializeEmuSimpleFileSystem( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gEmuSimpleFileSystemDriverBinding, + ImageHandle, + &gEmuSimpleFileSystemComponentName, + &gEmuSimpleFileSystemComponentName2 + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.h b/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.h new file mode 100644 index 0000000000..5a1182c2ad --- /dev/null +++ b/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.h @@ -0,0 +1,80 @@ +/*++ @file + Produce Simple File System abstractions for a directory on your PC using Unix APIs. + The configuration of what devices to mount or emulate comes from + environment variables. + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 _EMU_SIMPLE_FILE_SYSTEM_H_ +#define _EMU_SIMPLE_FILE_SYSTEM_H_ + +#include "PiDxe.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +extern EFI_DRIVER_BINDING_PROTOCOL gEmuSimpleFileSystemDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gEmuSimpleFileSystemComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gEmuSimpleFileSystemComponentName2; + +#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'M', 'f', 's') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *IoThunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Io; + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} EMU_SIMPLE_FILE_SYSTEM_PRIVATE; + +#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE, \ + SimpleFileSystem, \ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \ + ) + +#define EMU_EFI_FILE_PRIVATE_SIGNATURE SIGNATURE_32 ('e', 'm', 'f', 's') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *IoThunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + EFI_FILE_PROTOCOL EfiFile; + EFI_FILE_PROTOCOL *Io; +} EMU_EFI_FILE_PRIVATE; + +#define EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + EMU_EFI_FILE_PRIVATE, \ + EfiFile, \ + EMU_EFI_FILE_PRIVATE_SIGNATURE \ + ) + + + +#endif diff --git a/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf b/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf new file mode 100644 index 0000000000..f05f156dc1 --- /dev/null +++ b/InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf @@ -0,0 +1,55 @@ +## @file +# Simple filesystem driver +# +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuSimpleFileSystem + FILE_GUID = 35B72237-3926-CF4A-A7F3-1449F9E0E4BD + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeEmuSimpleFileSystem + + +[Sources] + ComponentName.c + EmuSimpleFileSystem.c + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + UefiLib + UefiDriverEntryPoint + BaseLib + DebugLib + + +[Guids] + gEfiFileSystemVolumeLabelInfoIdGuid # SOMETIMES_CONSUMED + gEfiFileInfoGuid # SOMETIMES_CONSUMED + gEfiFileSystemInfoGuid # SOMETIMES_CONSUMED + + +[Protocols] + gEfiSimpleFileSystemProtocolGuid # PROTOCOL BY_START + gEmuIoThunkProtocolGuid # PROTOCOL TO_START + diff --git a/InOsEmuPkg/EmuThunkDxe/EmuThunk.c b/InOsEmuPkg/EmuThunkDxe/EmuThunk.c new file mode 100644 index 0000000000..a0661c8726 --- /dev/null +++ b/InOsEmuPkg/EmuThunkDxe/EmuThunk.c @@ -0,0 +1,89 @@ +/*++ @file + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +// +// EmuThunk Device Path Protocol Instance +// +EMU_THUNK_DEVICE_PATH mEmuThunkDevicePath = { + { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (EMU_VENDOR_DEVICE_PATH_NODE)), + (UINT8) ((sizeof (EMU_VENDOR_DEVICE_PATH_NODE)) >> 8) + } + }, + EMU_THUNK_PROTOCOL_GUID + }, + 0 + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + + +EFI_STATUS +EFIAPI +InitializeEmuThunk ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + Install UnixThunk Protocol and it's associated Device Path protocol + +Arguments: + (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) + +Returns: + EFI_SUCEESS - UnixThunk protocol is added or error status from + gBS->InstallMultiProtocolInterfaces(). + +**/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEmuThunkProtocolGuid, gEmuThunk, + &gEfiDevicePathProtocolGuid, &mEmuThunkDevicePath, + NULL + ); + + return Status; +} diff --git a/InOsEmuPkg/EmuThunkDxe/EmuThunk.inf b/InOsEmuPkg/EmuThunkDxe/EmuThunk.inf new file mode 100644 index 0000000000..314a6f38ef --- /dev/null +++ b/InOsEmuPkg/EmuThunkDxe/EmuThunk.inf @@ -0,0 +1,59 @@ +## @file +# A DXE driver to produce EMU_THUNK_PROTOCOL +# +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuThunk + FILE_GUID = 2F62A818-4A72-CD40-90B9-FF00DAABEE7B + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeEmuThunk + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + EmuThunk.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + EmuThunkLib + UefiDriverEntryPoint + UefiLib + DebugLib + DevicePathLib + + + +[Protocols] + gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEmuThunkProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +[Depex] + TRUE + diff --git a/InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.c b/InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.c new file mode 100644 index 0000000000..ec9fe5c0b7 --- /dev/null +++ b/InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.c @@ -0,0 +1,130 @@ +/*++ @file + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "PiPei.h" +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +PeimInitializeFirmwareVolumePei ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +/*++ + +Routine Description: + Perform a call-back into the SEC simulator to get address of the Firmware Hub + +Arguments: + FfsHeader - Ffs Header availible to every PEIM + PeiServices - General purpose services available to every PEIM. + +Returns: + None + +**/ +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; + EMU_THUNK_PPI *Thunk; + EFI_PHYSICAL_ADDRESS FdBase; + EFI_PHYSICAL_ADDRESS FdFixUp; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + UINT64 FdSize; + UINTN Index; + + DEBUG ((EFI_D_ERROR, "Unix Firmware Volume PEIM Loaded\n")); + + // + // Get the Fwh Information PPI + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, // GUID + 0, // INSTANCE + &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR + (VOID **)&Thunk // PPI + ); + ASSERT_EFI_ERROR (Status); + + Index = 0; + do { + // + // Get information about all the FD's in the system + // + Status = Thunk->FirmwareDevices (Index, &FdBase, &FdSize, &FdFixUp); + if (!EFI_ERROR (Status)) { + // + // Assume the FD starts with an FV header + // + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FdBase; + + // + // Make an FV Hob for the first FV in the FD + // + BuildFvHob (FdBase, FvHeader->FvLength); + + if (Index == 0) { + // + // Assume the first FD was produced by the NT32.DSC + // All these strange offests are needed to keep in + // sync with the FlashMap and NT32.dsc file + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_FIRMWARE_DEVICE, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + FdBase, + ( + FvHeader->FvLength + + PcdGet32 (PcdFlashNvStorageVariableSize) + + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + PcdGet32 (PcdFlashNvStorageFtwSpareSize) + + PcdGet32 (PcdEmuFlashNvStorageEventLogSize) + ) + ); + + // + // Hard code the address of the spare block and variable services. + // Assume it's a hard coded offset from FV0 in FD0. + // + FdSize = + PcdGet32 (PcdFlashNvStorageVariableSize) + + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + PcdGet32 (PcdFlashNvStorageFtwSpareSize) + + PcdGet32 (PcdEmuFlashNvStorageEventLogSize); + + BuildFvHob (FdFixUp + PcdGet64 (PcdEmuFlashNvStorageVariableBase), FdSize); + } else { + // + // For other FD's just map them in. + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_FIRMWARE_DEVICE, + (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE), + FdBase, + FdSize + ); + } + } + + Index++; + } while (!EFI_ERROR (Status)); + + return Status; +} diff --git a/InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.inf b/InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.inf new file mode 100644 index 0000000000..02a4474c29 --- /dev/null +++ b/InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.inf @@ -0,0 +1,60 @@ +## @file +# Component description file for EmuFwh module +# +# This PEIM will produce the HOB to describe Firmware Volume, Firmware Devices +# on the Emu emulator. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FirmwareVolumePei + FILE_GUID = 6DB075DE-449E-2644-96D0-CC5A1B4C3B2A + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = PeimInitializeFirmwareVolumePei + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + FirmwareVolumePei.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + PeiServicesTablePointerLib + PeiServicesLib + HobLib + PeimEntryPoint + DebugLib + +[Pcd] + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + +[Depex] + gEmuThunkPpiGuid AND gEfiPeiMemoryDiscoveredPpiGuid + diff --git a/InOsEmuPkg/FlashMapPei/FlashMapPei.c b/InOsEmuPkg/FlashMapPei/FlashMapPei.c new file mode 100644 index 0000000000..955c46227e --- /dev/null +++ b/InOsEmuPkg/FlashMapPei/FlashMapPei.c @@ -0,0 +1,83 @@ +/*++ @file + PEIM to build GUIDed HOBs for platform specific flash map + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "PiPei.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +PeimInitializeFlashMap ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +/*++ + +Routine Description: + Build GUIDed HOBs for platform specific flash map + +Arguments: + FfsHeader - A pointer to the EFI_FFS_FILE_HEADER structure. + PeiServices - General purpose services available to every PEIM. + +Returns: + EFI_STATUS + +**/ +{ + EFI_STATUS Status; + EMU_THUNK_PPI *Thunk; + EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; + EFI_PHYSICAL_ADDRESS FdBase; + EFI_PHYSICAL_ADDRESS FdFixUp; + UINT64 FdSize; + + DEBUG ((EFI_D_ERROR, "InOsEmuPkg Flash Map PEIM Loaded\n")); + + // + // Get the Fwh Information PPI + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, // GUID + 0, // INSTANCE + &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR + (VOID **)&Thunk // PPI + ); + ASSERT_EFI_ERROR (Status); + + // + // Assume that FD0 contains the Flash map. + // + Status = Thunk->FirmwareDevices (0, &FdBase, &FdSize, &FdFixUp); + if (EFI_ERROR (Status)) { + return Status; + } + + PcdSet64 (PcdFlashNvStorageVariableBase64, PcdGet64 (PcdEmuFlashNvStorageVariableBase) + FdFixUp); + PcdSet64 (PcdFlashNvStorageFtwWorkingBase64, PcdGet64 (PcdEmuFlashNvStorageFtwWorkingBase) + FdFixUp); + PcdSet64 (PcdFlashNvStorageFtwSpareBase64, PcdGet64 (PcdEmuFlashNvStorageFtwSpareBase) + FdFixUp); + + return EFI_SUCCESS; +} diff --git a/InOsEmuPkg/FlashMapPei/FlashMapPei.inf b/InOsEmuPkg/FlashMapPei/FlashMapPei.inf new file mode 100644 index 0000000000..ed5bc3baab --- /dev/null +++ b/InOsEmuPkg/FlashMapPei/FlashMapPei.inf @@ -0,0 +1,68 @@ +## @file +# Component description file for FlashMap PEI module +# +# This module installs FlashMap PPI which is used to get flash layout information. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FlashMapPei + FILE_GUID = C9FAF091-57F8-A64C-A07A-445B124F0D93 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + + ENTRY_POINT = PeimInitializeFlashMap + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + FlashMapPei.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + PcdLib + BaseMemoryLib + PeiServicesTablePointerLib + PeiServicesLib + HobLib + PeimEntryPoint + DebugLib + + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 + + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase + +[Depex] + gEmuThunkPpiGuid + diff --git a/InOsEmuPkg/FvbServicesRuntimeDxe/FWBlockService.c b/InOsEmuPkg/FvbServicesRuntimeDxe/FWBlockService.c new file mode 100644 index 0000000000..a95b180adb --- /dev/null +++ b/InOsEmuPkg/FvbServicesRuntimeDxe/FWBlockService.c @@ -0,0 +1,1360 @@ +/*++ @file + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "PiDxe.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FwBlockService.h" + +ESAL_FWB_GLOBAL *mFvbModuleGlobal; + +#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS) + +EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = { + FVB_DEVICE_SIGNATURE, + { + { + { + HARDWARE_DEVICE_PATH, + HW_MEMMAP_DP, + { + sizeof (MEMMAP_DEVICE_PATH), + 0 + } + }, + EfiMemoryMappedIO, + 0, + 0, + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + sizeof (EFI_DEVICE_PATH_PROTOCOL), + 0 + } + } + }, + 0, + { + FvbProtocolGetAttributes, + FvbProtocolSetAttributes, + FvbProtocolGetPhysicalAddress, + FvbProtocolGetBlockSize, + FvbProtocolRead, + FvbProtocolWrite, + FvbProtocolEraseBlocks, + NULL + } +}; + + + +VOID +EFIAPI +FvbVirtualddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + Fixup internal data so that EFI and SAL can be call in virtual mode. + Call the passed in Child Notify event and convert the mFvbModuleGlobal + date items to there virtual address. + + mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] - Physical copy of instance data + mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] - Virtual pointer to common + instance data. + +Arguments: + + (Standard EFI notify event - EFI_EVENT_NOTIFY) + +Returns: + + None + +**/ +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + UINTN Index; + + EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]); + + // + // Convert the base address of all the instances + // + Index = 0; + FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]; + while (Index < mFvbModuleGlobal->NumFv) { + EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]); + FwhInstance = (EFI_FW_VOL_INSTANCE *) + ( + (UINTN) ((UINT8 *) FwhInstance) + FwhInstance->VolumeHeader.HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) + ); + Index++; + } + + EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal); +} + +EFI_STATUS +GetFvbInstance ( + IN UINTN Instance, + IN ESAL_FWB_GLOBAL *Global, + OUT EFI_FW_VOL_INSTANCE **FwhInstance, + IN BOOLEAN Virtual + ) +/*++ + +Routine Description: + Retrieves the physical address of a memory mapped FV + +Arguments: + Instance - The FV instance whose base address is going to be + returned + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance structure + Virtual - Whether CPU is in virtual or physical mode + +Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +**/ +{ + EFI_FW_VOL_INSTANCE *FwhRecord; + + if (Instance >= Global->NumFv) { + return EFI_INVALID_PARAMETER; + } + // + // Find the right instance of the FVB private data + // + FwhRecord = Global->FvInstance[Virtual]; + while (Instance > 0) { + FwhRecord = (EFI_FW_VOL_INSTANCE *) + ( + (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) + ); + Instance--; + } + + *FwhInstance = FwhRecord; + + return EFI_SUCCESS; +} + +EFI_STATUS +FvbGetPhysicalAddress ( + IN UINTN Instance, + OUT EFI_PHYSICAL_ADDRESS *Address, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +/*++ + +Routine Description: + Retrieves the physical address of a memory mapped FV + +Arguments: + Instance - The FV instance whose base address is going to be + returned + Address - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS + that on successful return, contains the base address + of the firmware volume. + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + Virtual - Whether CPU is in virtual or physical mode + +Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +**/ +{ + EFI_FW_VOL_INSTANCE *FwhInstance = NULL; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual); + ASSERT_EFI_ERROR (Status); + *Address = FwhInstance->FvBase[Virtual]; + + return EFI_SUCCESS; +} + +EFI_STATUS +FvbGetVolumeAttributes ( + IN UINTN Instance, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +/*++ + +Routine Description: + Retrieves attributes, insures positive polarity of attribute bits, returns + resulting attributes in output parameter + +Arguments: + Instance - The FV instance whose attributes is going to be + returned + Attributes - Output buffer which contains attributes + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + Virtual - Whether CPU is in virtual or physical mode + +Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +**/ +{ + EFI_FW_VOL_INSTANCE *FwhInstance = NULL; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual); + ASSERT_EFI_ERROR (Status); + *Attributes = FwhInstance->VolumeHeader.Attributes; + + return EFI_SUCCESS; +} + +EFI_STATUS +FvbGetLbaAddress ( + IN UINTN Instance, + IN EFI_LBA Lba, + OUT UINTN *LbaAddress, + OUT UINTN *LbaLength, + OUT UINTN *NumOfBlocks, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +/*++ + +Routine Description: + Retrieves the starting address of an LBA in an FV + +Arguments: + Instance - The FV instance which the Lba belongs to + Lba - The logical block address + LbaAddress - On output, contains the physical starting address + of the Lba + LbaLength - On output, contains the length of the block + NumOfBlocks - A 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 + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + Virtual - Whether CPU is in virtual or physical mode + +Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +**/ +{ + UINT32 NumBlocks; + UINT32 BlockLength; + UINTN Offset; + EFI_LBA StartLba; + EFI_LBA NextLba; + EFI_FW_VOL_INSTANCE *FwhInstance = NULL; + EFI_FV_BLOCK_MAP_ENTRY *BlockMap; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual); + ASSERT_EFI_ERROR (Status); + + StartLba = 0; + Offset = 0; + BlockMap = &(FwhInstance->VolumeHeader.BlockMap[0]); + + // + // Parse the blockmap of the FV to find which map entry the Lba belongs to + // + while (TRUE) { + NumBlocks = BlockMap->NumBlocks; + BlockLength = BlockMap->Length; + + if (NumBlocks == 0 || BlockLength == 0) { + return EFI_INVALID_PARAMETER; + } + + NextLba = StartLba + NumBlocks; + + // + // The map entry found + // + if (Lba >= StartLba && Lba < NextLba) { + Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength); + if (LbaAddress != NULL) { + *LbaAddress = FwhInstance->FvBase[Virtual] + Offset; + } + + if (LbaLength != NULL) { + *LbaLength = BlockLength; + } + + if (NumOfBlocks != NULL) { + *NumOfBlocks = (UINTN) (NextLba - Lba); + } + + return EFI_SUCCESS; + } + + StartLba = NextLba; + Offset = Offset + NumBlocks * BlockLength; + BlockMap++; + } +} + +EFI_STATUS +FvbReadBlock ( + IN UINTN Instance, + IN EFI_LBA Lba, + IN UINTN BlockOffset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +/*++ + +Routine Description: + Reads specified number of bytes into a buffer from the specified block + +Arguments: + Instance - The FV instance to be read from + Lba - The logical block address to be read from + BlockOffset - Offset into the block at which to begin reading + NumBytes - Pointer that on input contains the total size of + the buffer. On output, it contains the total number + of bytes read + Buffer - Pointer to a caller allocated buffer that will be + used to hold the data read + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + Virtual - Whether CPU is in virtual or physical mode + +Returns: + EFI_SUCCESS - The firmware volume was read successfully and + contents are in Buffer + EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes returned + in Buffer + EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state + EFI_DEVICE_ERROR - The block device is not functioning correctly and + could not be read + EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL + +**/ +{ + EFI_FVB_ATTRIBUTES_2 Attributes; + UINTN LbaAddress; + UINTN LbaLength; + EFI_STATUS Status; + + // + // Check for invalid conditions + // + if ((NumBytes == NULL) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (*NumBytes == 0) { + return EFI_INVALID_PARAMETER; + } + + Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Check if the FV is read enabled + // + FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual); + + if ((Attributes & EFI_FVB2_READ_STATUS) == 0) { + return EFI_ACCESS_DENIED; + } + // + // Perform boundary checks and adjust NumBytes + // + if (BlockOffset > LbaLength) { + return EFI_INVALID_PARAMETER; + } + + if (LbaLength < (*NumBytes + BlockOffset)) { + *NumBytes = (UINT32) (LbaLength - BlockOffset); + Status = EFI_BAD_BUFFER_SIZE; + } + + CopyMem (Buffer, (UINT8 *) (LbaAddress + BlockOffset), (UINTN) (*NumBytes)); + + return Status; +} + +EFI_STATUS +FvbWriteBlock ( + IN UINTN Instance, + IN EFI_LBA Lba, + IN UINTN BlockOffset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +/*++ + +Routine Description: + Writes specified number of bytes from the input buffer to the block + +Arguments: + Instance - The FV instance to be written to + Lba - The starting logical block index to write to + BlockOffset - Offset into the block at which to begin writing + NumBytes - Pointer that on input contains the total size of + the buffer. On output, it contains the total number + of bytes actually written + Buffer - Pointer to a caller allocated buffer that contains + the source for the write + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + Virtual - Whether CPU is in virtual or physical mode + +Returns: + EFI_SUCCESS - The firmware volume was written successfully + EFI_BAD_BUFFER_SIZE - Write attempted across a 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 not functioning correctly and + could not be written + EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL + +**/ +{ + EFI_FVB_ATTRIBUTES_2 Attributes; + UINTN LbaAddress; + UINTN LbaLength; + EFI_STATUS Status; + + // + // Check for invalid conditions + // + if ((NumBytes == NULL) || (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (*NumBytes == 0) { + return EFI_INVALID_PARAMETER; + } + + Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Check if the FV is write enabled + // + FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual); + + if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) { + return EFI_ACCESS_DENIED; + } + // + // Perform boundary checks and adjust NumBytes + // + if (BlockOffset > LbaLength) { + return EFI_INVALID_PARAMETER; + } + + if (LbaLength < (*NumBytes + BlockOffset)) { + *NumBytes = (UINT32) (LbaLength - BlockOffset); + Status = EFI_BAD_BUFFER_SIZE; + } + // + // Write data + // + CopyMem ((UINT8 *) (LbaAddress + BlockOffset), Buffer, (UINTN) (*NumBytes)); + + return Status; +} + +EFI_STATUS +FvbEraseBlock ( + IN UINTN Instance, + IN EFI_LBA Lba, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +/*++ + +Routine Description: + Erases and initializes a firmware volume block + +Arguments: + Instance - The FV instance to be erased + Lba - The logical block index to be erased + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + Virtual - Whether CPU is in virtual or physical mode + +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. Firmware device may have been + partially erased + EFI_INVALID_PARAMETER - Instance not found + +**/ +{ + + EFI_FVB_ATTRIBUTES_2 Attributes; + UINTN LbaAddress; + UINTN LbaLength; + EFI_STATUS Status; + UINT8 Data; + + // + // Check if the FV is write enabled + // + FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual); + + if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) { + return EFI_ACCESS_DENIED; + } + // + // Get the starting address of the block for erase. + // + Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual); + + if (EFI_ERROR (Status)) { + return Status; + } + + if ((Attributes & EFI_FVB2_ERASE_POLARITY) != 0) { + Data = 0xFF; + } else { + Data = 0x0; + } + + SetMem ((UINT8 *) LbaAddress, LbaLength, Data); + + return EFI_SUCCESS; +} + +EFI_STATUS +FvbSetVolumeAttributes ( + IN UINTN Instance, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +/*++ + +Routine Description: + Modifies the current settings of the firmware volume according to the + input parameter, and returns the new setting of the volume + +Arguments: + Instance - The FV instance whose attributes is going to be + modified + Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES_2 + containing the desired firmware volume settings. + On successful return, it contains the new settings + of the firmware volume + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + Virtual - Whether CPU is in virtual or physical mode + +Returns: + EFI_SUCCESS - Successfully returns + EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified + EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are + in conflict with the capabilities as declared in the + firmware volume header + +**/ +{ + EFI_FW_VOL_INSTANCE *FwhInstance = NULL; + EFI_FVB_ATTRIBUTES_2 OldAttributes; + EFI_FVB_ATTRIBUTES_2 *AttribPtr; + UINT32 Capabilities; + UINT32 OldStatus; + UINT32 NewStatus; + EFI_STATUS Status; + EFI_FVB_ATTRIBUTES_2 UnchangedAttributes; + + + // + // Find the right instance of the FVB private data + // + Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual); + ASSERT_EFI_ERROR (Status); + + AttribPtr = (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes); + OldAttributes = *AttribPtr; + Capabilities = OldAttributes & (EFI_FVB2_READ_DISABLED_CAP | \ + EFI_FVB2_READ_ENABLED_CAP | \ + EFI_FVB2_WRITE_DISABLED_CAP | \ + EFI_FVB2_WRITE_ENABLED_CAP | \ + EFI_FVB2_LOCK_CAP \ + ); + + OldStatus = OldAttributes & EFI_FVB2_STATUS; + NewStatus = *Attributes & EFI_FVB2_STATUS; + UnchangedAttributes = 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_STICKY_WRITE | \ + EFI_FVB2_MEMORY_MAPPED | \ + EFI_FVB2_ERASE_POLARITY | \ + EFI_FVB2_READ_LOCK_CAP | \ + EFI_FVB2_WRITE_LOCK_CAP | \ + EFI_FVB2_ALIGNMENT; + + // + // Some attributes of FV is read only can *not* be set + // + if ((OldAttributes & UnchangedAttributes) ^ (*Attributes & UnchangedAttributes)) { + return EFI_INVALID_PARAMETER; + } + + // + // If firmware volume is locked, no status bit can be updated + // + if (OldAttributes & EFI_FVB2_LOCK_STATUS) { + if (OldStatus ^ NewStatus) { + return EFI_ACCESS_DENIED; + } + } + // + // Test read disable + // + if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) { + if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) { + return EFI_INVALID_PARAMETER; + } + } + // + // Test read enable + // + if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) { + if (NewStatus & EFI_FVB2_READ_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + // + // Test write disable + // + if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) { + if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) { + return EFI_INVALID_PARAMETER; + } + } + // + // Test write enable + // + if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) { + if (NewStatus & EFI_FVB2_WRITE_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + // + // Test lock + // + if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) { + if (NewStatus & EFI_FVB2_LOCK_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + + *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS)); + *AttribPtr = (*AttribPtr) | NewStatus; + *Attributes = *AttribPtr; + + return EFI_SUCCESS; +} +// +// FVB protocol APIs +// +EFI_STATUS +EFIAPI +FvbProtocolGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +/*++ + +Routine Description: + + Retrieves the physical address of the device. + +Arguments: + + This - Calling context + Address - Output buffer containing the address. + +Returns: + +Returns: + EFI_SUCCESS - Successfully returns + +**/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ()); +} + +EFI_STATUS +EFIAPI +FvbProtocolGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ) +/*++ + +Routine Description: + Retrieve the size of a logical block + +Arguments: + This - Calling context + Lba - Indicates which block to return the size for. + BlockSize - A pointer to a caller allocated UINTN in which + the size of the block is returned + NumOfBlocks - a 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 was read successfully and + contents are in Buffer + +**/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbGetLbaAddress ( + FvbDevice->Instance, + Lba, + NULL, + BlockSize, + NumOfBlocks, + mFvbModuleGlobal, + EfiGoneVirtual () + ); +} + +EFI_STATUS +EFIAPI +FvbProtocolGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +/*++ + +Routine Description: + Retrieves Volume attributes. No polarity translations are done. + +Arguments: + This - Calling context + Attributes - output buffer which contains attributes + +Returns: + EFI_SUCCESS - Successfully returns + +**/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ()); +} + +EFI_STATUS +EFIAPI +FvbProtocolSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +/*++ + +Routine Description: + Sets Volume attributes. No polarity translations are done. + +Arguments: + This - Calling context + Attributes - output buffer which contains attributes + +Returns: + EFI_SUCCESS - Successfully returns + +**/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ()); +} + +EFI_STATUS +EFIAPI +FvbProtocolEraseBlocks ( + IN CONST 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. Firmware device may have been + partially erased + +**/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + EFI_FW_VOL_INSTANCE *FwhInstance = NULL; + UINTN NumOfBlocks; + VA_LIST args; + EFI_LBA StartingLba; + UINTN NumOfLba; + EFI_STATUS Status; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + Status = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ()); + ASSERT_EFI_ERROR (Status); + + NumOfBlocks = FwhInstance->NumOfBlocks; + + VA_START (args, This); + + do { + StartingLba = VA_ARG (args, EFI_LBA); + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + break; + } + + NumOfLba = VA_ARG (args, UINT32); + + // + // Check input parameters + // + if (NumOfLba == 0) { + VA_END (args); + return EFI_INVALID_PARAMETER; + } + + if ((StartingLba + NumOfLba) > NumOfBlocks) { + return EFI_INVALID_PARAMETER; + } + } while (1); + + VA_END (args); + + VA_START (args, This); + do { + StartingLba = VA_ARG (args, EFI_LBA); + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + break; + } + + NumOfLba = VA_ARG (args, UINT32); + + while (NumOfLba > 0) { + Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ()); + if (EFI_ERROR (Status)) { + VA_END (args); + return Status; + } + + StartingLba++; + NumOfLba--; + } + + } while (1); + + VA_END (args); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +FvbProtocolWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +/*++ + +Routine Description: + + Writes data beginning at Lba:Offset from FV. The write terminates either + when *NumBytes of data have been written, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + +Arguments: + This - Calling context + Lba - Block in which to begin write + Offset - Offset in the block at which to begin write + NumBytes - On input, indicates the requested write size. On + output, indicates the actual number of bytes written + Buffer - Buffer containing source data for the write. + +Returns: + EFI_SUCCESS - The firmware volume was written successfully + EFI_BAD_BUFFER_SIZE - Write attempted across a 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 not functioning correctly and + could not be written + EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL + +**/ +{ + + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ()); +} + +EFI_STATUS +EFIAPI +FvbProtocolRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +/*++ + +Routine Description: + + Reads data beginning at Lba:Offset from FV. The Read terminates either + when *NumBytes of data have been read, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + +Arguments: + This - Calling context + Lba - Block in which to begin Read + Offset - Offset in the block at which to begin Read + NumBytes - On input, indicates the requested write size. On + output, indicates the actual number of bytes Read + Buffer - Buffer containing source data for the Read. + +Returns: + EFI_SUCCESS - The firmware volume was read successfully and + contents are in Buffer + EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes returned + in Buffer + EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state + EFI_DEVICE_ERROR - The block device is not functioning correctly and + could not be read + EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL + +**/ +{ + + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ()); +} +EFI_STATUS +ValidateFvHeader ( + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader + ) +/*++ + +Routine Description: + Check the integrity of firmware volume header + +Arguments: + FwVolHeader - A pointer to a firmware volume header + +Returns: + EFI_SUCCESS - The firmware volume is consistent + EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an FV + +**/ +{ + UINT16 *Ptr; + UINT16 HeaderLength; + UINT16 Checksum; + + // + // Verify the header revision, header signature, length + // Length of FvBlock cannot be 2**64-1 + // HeaderLength cannot be an odd number + // + if ((FwVolHeader->Revision != EFI_FVH_REVISION) || + (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || + (FwVolHeader->FvLength == ((UINTN) -1)) || + ((FwVolHeader->HeaderLength & 0x01) != 0) + ) { + return EFI_NOT_FOUND; + } + // + // Verify the header checksum + // + HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2); + Ptr = (UINT16 *) FwVolHeader; + Checksum = 0; + while (HeaderLength > 0) { + Checksum = Checksum + (*Ptr); + HeaderLength--; + Ptr++; + } + + if (Checksum != 0) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +FvbInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + This function does common initialization for FVB services + +Arguments: + +Returns: + +**/ +{ + EFI_STATUS Status; + EFI_FW_VOL_INSTANCE *FwhInstance = NULL; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_DXE_SERVICES *DxeServices; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; + UINT32 BufferSize; + EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; + EFI_HANDLE FwbHandle; + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface; + EFI_DEVICE_PATH_PROTOCOL *TempFwbDevicePath; + FV_DEVICE_PATH TempFvbDevicePathData; + UINT32 MaxLbaSize; + EFI_PHYSICAL_ADDRESS BaseAddress; + UINT64 Length; + UINTN NumOfBlocks; + EFI_PEI_HOB_POINTERS FvHob; + + // + // Get the DXE services table + // + DxeServices = gDS; + + // + // Allocate runtime services data for global variable, which contains + // the private data of all firmware volume block instances + // + Status = gBS->AllocatePool ( + EfiRuntimeServicesData, + sizeof (ESAL_FWB_GLOBAL), + (VOID**) &mFvbModuleGlobal + ); + ASSERT_EFI_ERROR (Status); + + // + // Calculate the total size for all firmware volume block instances + // + BufferSize = 0; + + FvHob.Raw = GetHobList (); + while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) { + BaseAddress = FvHob.FirmwareVolume->BaseAddress; + Length = FvHob.FirmwareVolume->Length; + // + // Check if it is a "real" flash + // + Status = DxeServices->GetMemorySpaceDescriptor ( + BaseAddress, + &Descriptor + ); + if (EFI_ERROR (Status)) { + break; + } + + if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) { + FvHob.Raw = GET_NEXT_HOB (FvHob); + continue; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; + Status = ValidateFvHeader (FwVolHeader); + if (EFI_ERROR (Status)) { + // + // Get FvbInfo + // + Status = GetFvbInfo (Length, &FwVolHeader); + if (EFI_ERROR (Status)) { + FvHob.Raw = GET_NEXT_HOB (FvHob); + continue; + } + } + + BufferSize += (sizeof (EFI_FW_VOL_INSTANCE) + FwVolHeader->HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER)); + FvHob.Raw = GET_NEXT_HOB (FvHob); + } + + // + // Only need to allocate once. There is only one copy of physical memory for + // the private data of each FV instance. But in virtual mode or in physical + // mode, the address of the the physical memory may be different. + // + Status = gBS->AllocatePool ( + EfiRuntimeServicesData, + BufferSize, + (VOID**) &mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] + ); + ASSERT_EFI_ERROR (Status); + + // + // Make a virtual copy of the FvInstance pointer. + // + FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]; + mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance; + + mFvbModuleGlobal->NumFv = 0; + MaxLbaSize = 0; + + FvHob.Raw = GetHobList (); + while (NULL != (FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw))) { + BaseAddress = FvHob.FirmwareVolume->BaseAddress; + Length = FvHob.FirmwareVolume->Length; + // + // Check if it is a "real" flash + // + Status = DxeServices->GetMemorySpaceDescriptor ( + BaseAddress, + &Descriptor + ); + if (EFI_ERROR (Status)) { + break; + } + + if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) { + FvHob.Raw = GET_NEXT_HOB (FvHob); + continue; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; + Status = ValidateFvHeader (FwVolHeader); + if (EFI_ERROR (Status)) { + // + // Get FvbInfo to provide in FwhInstance. + // + Status = GetFvbInfo (Length, &FwVolHeader); + if (EFI_ERROR (Status)) { + FvHob.Raw = GET_NEXT_HOB (FvHob); + continue; + } + // + // Write healthy FV header back. + // + CopyMem ( + (VOID *) (UINTN) BaseAddress, + (VOID *) FwVolHeader, + FwVolHeader->HeaderLength + ); + } + + FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress; + FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress; + + CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength); + FwVolHeader = &(FwhInstance->VolumeHeader); + EfiInitializeLock (&(FwhInstance->FvbDevLock), TPL_HIGH_LEVEL); + + NumOfBlocks = 0; + + for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) { + // + // Get the maximum size of a block. The size will be used to allocate + // buffer for Scratch space, the intermediate buffer for FVB extension + // protocol + // + if (MaxLbaSize < PtrBlockMapEntry->Length) { + MaxLbaSize = PtrBlockMapEntry->Length; + } + + NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks; + } + // + // The total number of blocks in the FV. + // + FwhInstance->NumOfBlocks = NumOfBlocks; + + // + // Add a FVB Protocol Instance + // + Status = gBS->AllocatePool ( + EfiRuntimeServicesData, + sizeof (EFI_FW_VOL_BLOCK_DEVICE), + (VOID**) &FvbDevice + ); + ASSERT_EFI_ERROR (Status); + + CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE)); + + FvbDevice->Instance = mFvbModuleGlobal->NumFv; + mFvbModuleGlobal->NumFv++; + + // + // Set up the devicepath + // + FvbDevice->DevicePath.MemMapDevPath.StartingAddress = BaseAddress; + FvbDevice->DevicePath.MemMapDevPath.EndingAddress = BaseAddress + (FwVolHeader->FvLength - 1); + + // + // Find a handle with a matching device path that has supports FW Block protocol + // + TempFwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &TempFvbDevicePathData; + CopyMem (TempFwbDevicePath, &FvbDevice->DevicePath, sizeof (FV_DEVICE_PATH)); + Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle); + if (EFI_ERROR (Status)) { + // + // LocateDevicePath fails so install a new interface and device path + // + FwbHandle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + &FvbDevice->FwVolBlockInstance, + &gEfiDevicePathProtocolGuid, + &FvbDevice->DevicePath, + NULL + ); + ASSERT_EFI_ERROR (Status); + } else if (IsDevicePathEnd (TempFwbDevicePath)) { + // + // Device allready exists, so reinstall the FVB protocol + // + Status = gBS->HandleProtocol ( + FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID**)&OldFwbInterface + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->ReinstallProtocolInterface ( + FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + OldFwbInterface, + &FvbDevice->FwVolBlockInstance + ); + ASSERT_EFI_ERROR (Status); + + } else { + // + // There was a FVB protocol on an End Device Path node + // + ASSERT (FALSE); + } + + FwhInstance = (EFI_FW_VOL_INSTANCE *) + ( + (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) + ); + + FvHob.Raw = GET_NEXT_HOB (FvHob); + } + + return EFI_SUCCESS; +} diff --git a/InOsEmuPkg/FvbServicesRuntimeDxe/FvbInfo.c b/InOsEmuPkg/FvbServicesRuntimeDxe/FvbInfo.c new file mode 100644 index 0000000000..34f2910643 --- /dev/null +++ b/InOsEmuPkg/FvbServicesRuntimeDxe/FvbInfo.c @@ -0,0 +1,154 @@ +/*++ @file + Defines data structure that is the volume header found.These data is intent + to decouple FVB driver with FV header. + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef struct { + UINT64 FvLength; + EFI_FIRMWARE_VOLUME_HEADER FvbInfo; + // + // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0 + // + EFI_FV_BLOCK_MAP_ENTRY End[1]; +} EFI_FVB_MEDIA_INFO; + +EFI_FVB_MEDIA_INFO mPlatformFvbMediaInfo[] = { + // + // Recovery BOIS FVB + // + { + FixedPcdGet32 (PcdEmuFlashFvRecoverySize), + { + { + 0, + }, // ZeroVector[16] + EFI_FIRMWARE_FILE_SYSTEM2_GUID, + FixedPcdGet32 (PcdEmuFlashFvRecoverySize), + EFI_FVH_SIGNATURE, + EFI_FVB2_READ_ENABLED_CAP | + EFI_FVB2_READ_STATUS | + EFI_FVB2_WRITE_ENABLED_CAP | + EFI_FVB2_WRITE_STATUS | + EFI_FVB2_ERASE_POLARITY, + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, // CheckSum + 0, // ExtHeaderOffset + { + 0, + }, // Reserved[1] + 2, // Revision + { + { + FixedPcdGet32 (PcdEmuFlashFvRecoverySize)/FixedPcdGet32 (PcdEmuFirmwareBlockSize), + FixedPcdGet32 (PcdEmuFirmwareBlockSize), + } + } + }, + { + { + 0, + 0 + } + } + }, + // + // Systen NvStorage FVB + // + { + FixedPcdGet32 (PcdFlashNvStorageVariableSize) + \ + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + \ + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) + \ + FixedPcdGet32 (PcdEmuFlashNvStorageEventLogSize), + { + { + 0, + }, // ZeroVector[16] + EFI_SYSTEM_NV_DATA_FV_GUID, + FixedPcdGet32 (PcdFlashNvStorageVariableSize) + \ + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + \ + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) + \ + FixedPcdGet32 (PcdEmuFlashNvStorageEventLogSize), + EFI_FVH_SIGNATURE, + EFI_FVB2_READ_ENABLED_CAP | + EFI_FVB2_READ_STATUS | + EFI_FVB2_WRITE_ENABLED_CAP | + EFI_FVB2_WRITE_STATUS | + EFI_FVB2_ERASE_POLARITY, + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, // CheckSum + 0, // ExtHeaderOffset + { + 0, + }, // Reserved[1] + 2, // Revision + { + { + (FixedPcdGet32 (PcdFlashNvStorageVariableSize) + \ + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + \ + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) + \ + FixedPcdGet32 (PcdEmuFlashNvStorageEventLogSize)) / FixedPcdGet32 (PcdEmuFirmwareBlockSize), + FixedPcdGet32 (PcdEmuFirmwareBlockSize), + } + } + }, + { + { + 0, + 0 + } + } + } +}; + +EFI_STATUS +GetFvbInfo ( + IN UINT64 FvLength, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ) +{ + UINTN Index; + + for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) { + if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) { + *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} diff --git a/InOsEmuPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf b/InOsEmuPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf new file mode 100644 index 0000000000..d34386779b --- /dev/null +++ b/InOsEmuPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf @@ -0,0 +1,80 @@ +## @file +# Component description file for Emu Fimware Volume Block DXE driver module. +# +# This DXE runtime driver implements and produces the Fimware Volue Block Protocol on +# Emu emulator. +# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FwBlockService + FILE_GUID = A01E498C-96E8-2A4C-95F4-85248F989753 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FvbInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + FvbInfo.c + FWBlockService.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + HobLib + DebugLib + UefiRuntimeLib + DxeServicesTableLib + BaseLib + UefiDriverEntryPoint + UefiLib + DevicePathLib + +[Guids] + gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED Create Event: EVENT_GROUP_GUID + +[Protocols] + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL ALWAYS_PRODUCED + gEfiDevicePathProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + +[FixedPcd] + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareFdSize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + +[Depex] + TRUE + diff --git a/InOsEmuPkg/FvbServicesRuntimeDxe/FwBlockService.h b/InOsEmuPkg/FvbServicesRuntimeDxe/FwBlockService.h new file mode 100644 index 0000000000..e4984515a4 --- /dev/null +++ b/InOsEmuPkg/FvbServicesRuntimeDxe/FwBlockService.h @@ -0,0 +1,219 @@ +/*++ @file + Firmware volume block driver for Intel Firmware Hub (FWH) device + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 _FW_BLOCK_SERVICE_H +#define _FW_BLOCK_SERVICE_H + +// +// BugBug: Add documentation here for data structure!!!! +// +#define FVB_PHYSICAL 0 +#define FVB_VIRTUAL 1 + +typedef struct { + EFI_LOCK FvbDevLock; + UINTN FvBase[2]; + UINTN NumOfBlocks; + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; +} EFI_FW_VOL_INSTANCE; + +typedef struct { + UINT32 NumFv; + EFI_FW_VOL_INSTANCE *FvInstance[2]; +} ESAL_FWB_GLOBAL; + +// +// Fvb Protocol instance data +// +#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE) +#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE) +#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'N') + +typedef struct { + MEMMAP_DEVICE_PATH MemMapDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_DEVICE_PATH; + +typedef struct { + UINTN Signature; + FV_DEVICE_PATH DevicePath; + UINTN Instance; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance; +} EFI_FW_VOL_BLOCK_DEVICE; + +EFI_STATUS +GetFvbInfo ( + IN UINT64 FvLength, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ) +; + +EFI_STATUS +FvbReadBlock ( + IN UINTN Instance, + IN EFI_LBA Lba, + IN UINTN BlockOffset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +; + +EFI_STATUS +FvbWriteBlock ( + IN UINTN Instance, + IN EFI_LBA Lba, + IN UINTN BlockOffset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +; + +EFI_STATUS +FvbEraseBlock ( + IN UINTN Instance, + IN EFI_LBA Lba, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +; + +EFI_STATUS +FvbSetVolumeAttributes ( + IN UINTN Instance, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +; + +EFI_STATUS +FvbGetVolumeAttributes ( + IN UINTN Instance, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +; + +EFI_STATUS +FvbGetPhysicalAddress ( + IN UINTN Instance, + OUT EFI_PHYSICAL_ADDRESS *Address, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +; + +EFI_STATUS +EFIAPI +FvbInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + + +VOID +EFIAPI +FvbClassAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +; + +EFI_STATUS +FvbGetLbaAddress ( + IN UINTN Instance, + IN EFI_LBA Lba, + OUT UINTN *LbaAddress, + OUT UINTN *LbaLength, + OUT UINTN *NumOfBlocks, + IN ESAL_FWB_GLOBAL *Global, + IN BOOLEAN Virtual + ) +; + +// +// Protocol APIs +// +EFI_STATUS +EFIAPI +FvbProtocolGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +; + +EFI_STATUS +EFIAPI +FvbProtocolSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +; + +EFI_STATUS +EFIAPI +FvbProtocolGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +; + +EFI_STATUS +EFIAPI +FvbProtocolGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ) +; + +EFI_STATUS +EFIAPI +FvbProtocolRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +; + +EFI_STATUS +EFIAPI +FvbProtocolWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +; + +EFI_STATUS +EFIAPI +FvbProtocolEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ) +; + +#endif diff --git a/InOsEmuPkg/InOsEmuPkg.dec b/InOsEmuPkg/InOsEmuPkg.dec new file mode 100644 index 0000000000..14f1040a7c --- /dev/null +++ b/InOsEmuPkg/InOsEmuPkg.dec @@ -0,0 +1,85 @@ +## @file +# +# This is the Emu Emulation Environment Platform +# +# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +## + +[Defines] + DEC_VERSION = 0x00010005 + PACKAGE_NAME = InOsEmuPkg + PACKAGE_GUID = 36E48BD7-7D92-5A47-A2CD-513F072E3300 + PACKAGE_VERSION = 0.1 + + +[Includes] + Include + + +[LibraryClasses] + ThunkPpiList|Include/Library/ThunkPpiList.h + ThunkProtocolList|Include/Library/ThunkProtocolList.h + EmuThunkLib|Include/Library/EmuThunkLib.h + KeyMap|Include/Library/KeyMapLib.h + +[Protocols] + gEmuThunkProtocolGuid = { 0x398DCA31, 0x3505, 0xDB47, { 0xBD, 0x93, 0x1D, 0x38, 0x5F, 0x79, 0x13, 0x15 } } + gEmuIoThunkProtocolGuid = { 0x453368F6, 0x7C85, 0x434A, { 0xA9, 0x8A, 0x72, 0xD1, 0xB7, 0xFF, 0xA9, 0x26 } } + gEmuGraphicsWindowProtocolGuid = { 0x30FD316A, 0x6728, 0x2E41, { 0xA6, 0x90, 0x0D, 0x13, 0x33, 0xD8, 0xCA, 0xC1 } } + gEmuPthreadThunkProtocolGuid = { 0x3B1E4B7C, 0x09D8, 0x944F, { 0xA4, 0x08, 0x13, 0x09, 0xEB, 0x8B, 0x44, 0x27 } } + +[Ppis] + gEmuThunkPpiGuid = { 0xE113F896, 0x75CF, 0xF640, { 0x81, 0x7F, 0xC8, 0x5A, 0x79, 0xE8, 0xAE, 0x67 } } + gEmuPeiServicesTableUpdatePpiGuid = { 0xFA93020C, 0x6CDF, 0x1946, { 0x86, 0x35, 0x72, 0xCB, 0x51, 0x9E, 0xCF, 0xFD } } + + +[Guids] + gInOsEmuPkgTokenSpaceGuid = { 0x4F792E68, 0xE8C8, 0x794E, { 0xB1, 0xD8, 0x37, 0x03, 0xF3, 0xF2, 0xD5, 0xA5 } } + gEmuSystemConfigGuid = { 0xF8626165, 0x6CEB, 0x924A, { 0xBA, 0xFC, 0xF1, 0x3A, 0xB9, 0xD6, 0x57, 0x28 } } + +# gEmuVirtualDisksGuid = {0xf2ba331a, 0x8985, 0x11db, {0xa4, 0x06, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35}} +# gEmuPhysicalDisksGuid = {0xf2bdcc96, 0x8985, 0x11db, {0x87, 0x19, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35}} +# gEmuFileSystemGuid = {0xf2c16b9e, 0x8985, 0x11db, {0x92, 0xc8, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35}} +# gEmuSerialPortGuid = {0x6d3a727d, 0x66c8, 0x4d19, {0x87, 0xe6, 0x02, 0x15, 0x86, 0x14, 0x90, 0xf3}} +# gEmuNetworkGuid = {0x081603B4, 0x0F1D, 0x4022, {0xB6, 0xFD, 0x4C, 0xE3, 0x5E, 0x09, 0xA1, 0xA6}} + +[PcdsFixedAtBuild] + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase|0x0|UINT64|0x00001014 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase|0x0|UINT64|0x00001015 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase|0x0|UINT64|0x00001016 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFdBaseAddress|0x0|UINT64|0x00001017 + + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase|0x0|UINT64|0x0000100e + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize|0x0|UINT32|0x0000100f + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase|0x0|UINT64|0x00001010 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize|0x0|UINT32|0x00001011 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareFdSize|0x0|UINT32|0x00001012 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize|0|UINT32|0x00001013 + + gInOsEmuPkgTokenSpaceGuid.PcdEmuApCount|L"0"|VOID*|0x00001019 + +[PcdsFixedAtBuild, PcdsPatchableInModule] + gInOsEmuPkgTokenSpaceGuid.PcdEmuBootMode|1|UINT32|0x00001006 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"..\\Fv\\Fv_Recovery.fd"|VOID*|0x00001009 + gInOsEmuPkgTokenSpaceGuid.PcdEmuMemorySize|L"64!64"|VOID*|0x0000100c + + + gInOsEmuPkgTokenSpaceGuid.PcdEmuPhysicalDisk|L"E:RW;245760;512"|VOID*|0x00001000 + gInOsEmuPkgTokenSpaceGuid.PcdEmuVirtualDisk|L"FW;40960;512"|VOID*|0x00001001 + gInOsEmuPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window"|VOID*|0x00001018 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFileSystem|L".!../../../../../EdkShellBinPkg/bin/ia32/Apps"|VOID*|0x00001004 + gInOsEmuPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0"|VOID*|0x00001002 + gInOsEmuPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"en0"|VOID*|0x0000100d + + gInOsEmuPkgTokenSpaceGuid.PcdEmuCpuModel|L"Intel(R) Processor Model"|VOID*|0x00001007 + gInOsEmuPkgTokenSpaceGuid.PcdEmuCpuSpeed|L"3000"|VOID*|0x00001008 + + diff --git a/InOsEmuPkg/Include/Guid/EmuSystemConfig.h b/InOsEmuPkg/Include/Guid/EmuSystemConfig.h new file mode 100644 index 0000000000..b3a7d9b09f --- /dev/null +++ b/InOsEmuPkg/Include/Guid/EmuSystemConfig.h @@ -0,0 +1,36 @@ +/** @file + Setup Variable data structure for Emu platform. + +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. + + +**/ + +#ifndef __EMU_SYSTEM_CONFIG_H__ +#define __EMU_SYSTEM_CONFIG_H__ + +#define EFI_EMU_SYSTEM_CONFIG_GUID \ + { 0x9C4FB516, 0x3A1E, 0xD847, { 0xA1, 0xA1, 0x70, 0x58, 0xB6, 0x98, 0x67, 0x32 } } + + +#pragma pack(1) +typedef struct { + // + // Console output mode + // + UINT32 ConOutColumn; + UINT32 ConOutRow; +} EMU_SYSTEM_CONFIGURATION; +#pragma pack() + + +extern EFI_GUID gEmuSystemConfigGuid; + +#endif diff --git a/InOsEmuPkg/Include/Library/EmuThunkLib.h b/InOsEmuPkg/Include/Library/EmuThunkLib.h new file mode 100644 index 0000000000..d8f55b862e --- /dev/null +++ b/InOsEmuPkg/Include/Library/EmuThunkLib.h @@ -0,0 +1,22 @@ +/*++ @file + +Copyright (c) 2011, Apple Inc. 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 __EMU_THUNK_LIB_H__ +#define __EMU_THUNK_LIB_H__ + +#include + + +extern EMU_THUNK_PROTOCOL *gEmuThunk; + +#endif diff --git a/InOsEmuPkg/Include/Library/KeyMapLib.h b/InOsEmuPkg/Include/Library/KeyMapLib.h new file mode 100644 index 0000000000..7bd29a7230 --- /dev/null +++ b/InOsEmuPkg/Include/Library/KeyMapLib.h @@ -0,0 +1,43 @@ +/*++ @file + +Copyright (c) 2011, Apple Inc. 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 + + +/** + KeyMapMake gets called on key presses. + + @param KeyData Key that was pressed. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +KeyMapMake ( + IN EFI_KEY_DATA *KeyData + ); + +/** + KeyMapBreak gets called on key releases. + + @param KeyData Key that was pressed. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +KeyMapBreak ( + IN EFI_KEY_DATA *KeyData + ); diff --git a/InOsEmuPkg/Include/Library/ThunkPpiList.h b/InOsEmuPkg/Include/Library/ThunkPpiList.h new file mode 100644 index 0000000000..febc972e20 --- /dev/null +++ b/InOsEmuPkg/Include/Library/ThunkPpiList.h @@ -0,0 +1,33 @@ +/** @file + All 3rd parties to register the PPIs passed into PEI Core + + Copyright (c) 2008 - 2011, Apple Inc. 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 + + +EFI_PEI_PPI_DESCRIPTOR * +GetThunkPpiList ( + VOID + ); + + +EFI_STATUS +EFIAPI +AddThunkPpi ( + IN UINTN Flags, + IN EFI_GUID *Guid, + IN VOID *Ppi + ); + + diff --git a/InOsEmuPkg/Include/Library/ThunkProtocolList.h b/InOsEmuPkg/Include/Library/ThunkProtocolList.h new file mode 100644 index 0000000000..5b25f9cc86 --- /dev/null +++ b/InOsEmuPkg/Include/Library/ThunkProtocolList.h @@ -0,0 +1,35 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2008 - 2011, Apple Inc. 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 +#include + + +EFI_STATUS +EFIAPI +AddThunkProtocol ( + IN EMU_IO_THUNK_PROTOCOL *ThunkIo, + IN CHAR16 *ConfigString, + IN BOOLEAN EmuBusDriver + ); + +EFI_STATUS +EFIAPI +GetNextThunkProtocol ( + IN BOOLEAN EmuBusDriver, + OUT EMU_IO_THUNK_PROTOCOL **Instance + ); + + diff --git a/InOsEmuPkg/Include/Ppi/EmuPeiServicesTableUpdate.h b/InOsEmuPkg/Include/Ppi/EmuPeiServicesTableUpdate.h new file mode 100644 index 0000000000..f706eac5c0 --- /dev/null +++ b/InOsEmuPkg/Include/Ppi/EmuPeiServicesTableUpdate.h @@ -0,0 +1,27 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2008 - 2011, Apple Inc. 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 __EMU_PEI_SERVICE_TABLE_UPDATE_PPI_H__ +#define __EMU_PEI_SERVICE_TABLE_UPDATE_PPI_H__ + +#define _EMU_PEI_SERVICE_TABLE_UPDATE_PPI_GUID \ + { 0xFA93020C, 0x6CDF, 0x1946, { 0x86, 0x35, 0x72, 0xCB, 0x51, 0x9E, 0xCF, 0xFD } } + + + + +extern EFI_GUID gEmuPeiServicesTableUpdatePpiGuid; + +#endif diff --git a/InOsEmuPkg/Include/Ppi/EmuThunk.h b/InOsEmuPkg/Include/Ppi/EmuThunk.h new file mode 100644 index 0000000000..61047e3bfd --- /dev/null +++ b/InOsEmuPkg/Include/Ppi/EmuThunk.h @@ -0,0 +1,128 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2008 - 2011, Apple Inc. 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 __EMU_THUNK_PPI_H__ +#define __EMU_THUNK_PPI_H__ + +#define EMU_THUNK_PPI_GUID \ + { 0xB958B78C, 0x1D3E, 0xEE40, { 0x8B, 0xF4, 0xF0, 0x63, 0x2D, 0x06, 0x39, 0x16 } } + + + +/*++ + +Routine Description: + This service is called from Index == 0 until it returns EFI_UNSUPPORTED. + It allows discontiguous memory regions to be supported by the emulator. + +Arguments: + Index - Which memory region to use + MemoryBase - Return Base address of memory region + MemorySize - Return size in bytes of the memory region + +Returns: + EFI_SUCCESS - If memory region was mapped + EFI_UNSUPPORTED - If Index is not supported + +**/ +typedef +EFI_STATUS +(EFIAPI *EMU_PEI_AUTOSCAN) ( + IN UINTN Index, + OUT EFI_PHYSICAL_ADDRESS *MemoryBase, + OUT UINT64 *MemorySize + ); + + +/*++ + +Routine Description: + Return the FD Size and base address. Since the FD is loaded from a + file into host memory only the SEC will know it's address. + +Arguments: + Index - Which FD, starts at zero. + FdSize - Size of the FD in bytes + FdBase - Start address of the FD. Assume it points to an FV Header + FixUp - Difference between actual FD address and build address + +Returns: + EFI_SUCCESS - Return the Base address and size of the FV + EFI_UNSUPPORTED - Index does nto map to an FD in the system + +**/ +typedef +EFI_STATUS +(EFIAPI *EMU_PEI_FD_INFORMATION) ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ); + + +/*++ + +Routine Description: + Export of EMU_THUNK_PROTOCOL from the SEC. + +Returns: + EFI_SUCCESS - Data returned + +**/ +typedef +VOID * +(EFIAPI *EMU_PEI_THUNK_INTERFACE) ( + VOID + ); + + + +/*++ + +Routine Description: + Loads and relocates a PE/COFF image into memory. + +Arguments: + Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated + ImageAddress - The base address of the relocated PE/COFF image + ImageSize - The size of the relocated PE/COFF image + EntryPoint - The entry point of the relocated PE/COFF image + +Returns: + EFI_SUCCESS - The file was loaded and relocated + EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file + +**/ +typedef +EFI_STATUS +(EFIAPI *EMU_PEI_LOAD_FILE) ( + VOID *Pe32Data, + EFI_PHYSICAL_ADDRESS *ImageAddress, + UINT64 *ImageSize, + EFI_PHYSICAL_ADDRESS *EntryPoint + ); + + +typedef struct { + EMU_PEI_AUTOSCAN MemoryAutoScan; + EMU_PEI_FD_INFORMATION FirmwareDevices; + EMU_PEI_THUNK_INTERFACE Thunk; + EMU_PEI_LOAD_FILE LoadFile; +} EMU_THUNK_PPI; + +extern EFI_GUID gEmuThunkPpiGuid; + +#endif diff --git a/InOsEmuPkg/Include/Protocol/EmuFileSystem.h b/InOsEmuPkg/Include/Protocol/EmuFileSystem.h new file mode 100644 index 0000000000..3713acfdc1 --- /dev/null +++ b/InOsEmuPkg/Include/Protocol/EmuFileSystem.h @@ -0,0 +1,140 @@ +/** @file + SimpleFileSystem protocol as defined in the UEFI 2.0 specification. + + The SimpleFileSystem protocol is the programmatic access to the FAT (12,16,32) + file system specified in UEFI 2.0. It can also be used to abstract a file + system other than FAT. + + UEFI 2.0 can boot from any valid EFI image contained in a SimpleFileSystem. + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved. +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. + +**/ + +#ifndef _EMU_UGA_IO_H_ +#define _EMU_UGA_IO_H_ + +#include +#include +#include +#include + +#define EMU_GRAPHICS_WINDOW_PROTOCOL_GUID \ + { 0x30FD316A, 0x6728, 0x2E41, { 0xA6, 0x90, 0x0D, 0x13, 0x33, 0xD8, 0xCA, 0xC1 } } + +typedef struct _EMU_GRAPHICS_WINDOW_PROTOCOL EMU_GRAPHICS_WINDOW_PROTOCOL; + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_CLOSE)( + EMU_GRAPHICS_WINDOW_PROTOCOL *Uga + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_SIZE)( + EMU_GRAPHICS_WINDOW_PROTOCOL *Uga, + UINT32 Width, + UINT32 Height + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_CHECK_KEY)( + EMU_GRAPHICS_WINDOW_PROTOCOL *Uga + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_GET_KEY)( + EMU_GRAPHICS_WINDOW_PROTOCOL *Uga, + EFI_KEY_DATA *key + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_KEY_SET_STATE) ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ); + + +typedef +VOID +(EFIAPI *EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK) ( + IN VOID *Context, + IN EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_REGISTER_KEY_NOTIFY) ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK CallBack, + IN VOID *Context + ); + + +typedef struct { + UINTN SourceX; + UINTN SourceY; + UINTN DestinationX; + UINTN DestinationY; + UINTN Width; + UINTN Height; + UINTN Delta; +} EMU_GRAPHICS_WINDOWS__BLT_ARGS; + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_BLT)( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, + IN EFI_UGA_BLT_OPERATION BltOperation, + IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args + ); + +typedef +BOOLEAN +(EFIAPI *EMU_GRAPHICS_WINDOWS_IS_KEY_PRESSED) ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_CHECK_POINTER)( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_GET_POINTER_STATE)( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + EFI_SIMPLE_POINTER_STATE *state + ); + +struct _EMU_GRAPHICS_WINDOW_PROTOCOL { + EMU_GRAPHICS_WINDOWS_SIZE Size; + EMU_GRAPHICS_WINDOWS_CHECK_KEY CheckKey; + EMU_GRAPHICS_WINDOWS_KEY_SET_STATE KeySetState; + EMU_GRAPHICS_WINDOWS_GET_KEY GetKey; + EMU_GRAPHICS_WINDOWS_REGISTER_KEY_NOTIFY RegisterKeyNotify; + EMU_GRAPHICS_WINDOWS_BLT Blt; + EMU_GRAPHICS_WINDOWS_IS_KEY_PRESSED IsKeyPressed; + EMU_GRAPHICS_WINDOWS_CHECK_POINTER CheckPointer; + EMU_GRAPHICS_WINDOWS_GET_POINTER_STATE GetPointerState; +}; + + +extern EFI_GUID gEmuGraphicsWindowProtocolGuid; + +#endif diff --git a/InOsEmuPkg/Include/Protocol/EmuGraphicsWindow.h b/InOsEmuPkg/Include/Protocol/EmuGraphicsWindow.h new file mode 100644 index 0000000000..e1afa0ef5a --- /dev/null +++ b/InOsEmuPkg/Include/Protocol/EmuGraphicsWindow.h @@ -0,0 +1,134 @@ +/*++ @file + +Copyright (c) 2006, Tristan Gingold. All rights reserved.
+Portitions copyright (c) 2010 - 2011, Apple Inc. 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 _EMU_UGA_IO_H_ +#define _EMU_UGA_IO_H_ + +#include +#include +#include +#include + +#define EMU_GRAPHICS_WINDOW_PROTOCOL_GUID \ + { 0x30FD316A, 0x6728, 0x2E41, { 0xA6, 0x90, 0x0D, 0x13, 0x33, 0xD8, 0xCA, 0xC1 } } + +typedef struct _EMU_GRAPHICS_WINDOW_PROTOCOL EMU_GRAPHICS_WINDOW_PROTOCOL; + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_CLOSE)( + EMU_GRAPHICS_WINDOW_PROTOCOL *Uga + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_SIZE)( + EMU_GRAPHICS_WINDOW_PROTOCOL *Uga, + UINT32 Width, + UINT32 Height + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_CHECK_KEY)( + EMU_GRAPHICS_WINDOW_PROTOCOL *Uga + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_GET_KEY)( + EMU_GRAPHICS_WINDOW_PROTOCOL *Uga, + EFI_KEY_DATA *key + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_KEY_SET_STATE) ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ); + + +typedef +VOID +(EFIAPI *EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK) ( + IN VOID *Context, + IN EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_REGISTER_KEY_NOTIFY) ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack, + IN VOID *Context + ); + + +typedef struct { + UINTN SourceX; + UINTN SourceY; + UINTN DestinationX; + UINTN DestinationY; + UINTN Width; + UINTN Height; + UINTN Delta; +} EMU_GRAPHICS_WINDOWS__BLT_ARGS; + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_BLT)( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, + IN EFI_UGA_BLT_OPERATION BltOperation, + IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args + ); + +typedef +BOOLEAN +(EFIAPI *EMU_GRAPHICS_WINDOWS_IS_KEY_PRESSED) ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_CHECK_POINTER)( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_GRAPHICS_WINDOWS_GET_POINTER_STATE)( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + EFI_SIMPLE_POINTER_STATE *state + ); + +struct _EMU_GRAPHICS_WINDOW_PROTOCOL { + EMU_GRAPHICS_WINDOWS_SIZE Size; + EMU_GRAPHICS_WINDOWS_CHECK_KEY CheckKey; + EMU_GRAPHICS_WINDOWS_KEY_SET_STATE KeySetState; + EMU_GRAPHICS_WINDOWS_GET_KEY GetKey; + EMU_GRAPHICS_WINDOWS_REGISTER_KEY_NOTIFY RegisterKeyNotify; + EMU_GRAPHICS_WINDOWS_BLT Blt; + EMU_GRAPHICS_WINDOWS_IS_KEY_PRESSED IsKeyPressed; + EMU_GRAPHICS_WINDOWS_CHECK_POINTER CheckPointer; + EMU_GRAPHICS_WINDOWS_GET_POINTER_STATE GetPointerState; +}; + + +extern EFI_GUID gEmuGraphicsWindowProtocolGuid; + +#endif diff --git a/InOsEmuPkg/Include/Protocol/EmuIoThunk.h b/InOsEmuPkg/Include/Protocol/EmuIoThunk.h new file mode 100644 index 0000000000..af132bea7e --- /dev/null +++ b/InOsEmuPkg/Include/Protocol/EmuIoThunk.h @@ -0,0 +1,51 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2010 - 2011, Apple Inc. 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 __EMU_IO_THUNK__ +#define __EMU_IO_THUNK__ + + +#define EMU_IO_THUNK_PROTOCO_GUID \ + { 0x453368F6, 0x7C85, 0x434A, { 0xA9, 0x8A, 0x72, 0xD1, 0xB7, 0xFF, 0xA9, 0x26 } } + + +typedef struct _EMU_IO_THUNK_PROTOCOL EMU_IO_THUNK_PROTOCOL; + + +typedef +EFI_STATUS +(EFIAPI *EMU_IO_THUNK_PROTOCOL_CLOSE_OPEN) ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_IO_THUNK_PROTOCOL_CLOSE_CLOSE) ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +struct _EMU_IO_THUNK_PROTOCOL { + EFI_GUID *Protocol; + VOID *Interface; /// Only be valid after Open() is called + CHAR16 *ConfigString; + UINT16 Instance; + EMU_IO_THUNK_PROTOCOL_CLOSE_OPEN Open; + EMU_IO_THUNK_PROTOCOL_CLOSE_CLOSE Close; + VOID *Private; /// Used by implementation +}; + +extern EFI_GUID gEmuIoThunkProtocolGuid; + +#endif diff --git a/InOsEmuPkg/Include/Protocol/EmuPthreadThunk.h b/InOsEmuPkg/Include/Protocol/EmuPthreadThunk.h new file mode 100644 index 0000000000..80325f4305 --- /dev/null +++ b/InOsEmuPkg/Include/Protocol/EmuPthreadThunk.h @@ -0,0 +1,105 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2010 - 2011, Apple Inc. 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 __EMU_PTHREAD_THUNK__ +#define __EMU_PTHREAD_THUNK__ + +#define EMU_PTHREAD_THUNK_PROTOCO_GUID \ + { 0x3B1E4B7C, 0x09D8, 0x944F, { 0xA4, 0x08, 0x13, 0x09, 0xEB, 0x8B, 0x44, 0x27 } } + + +typedef struct _EMU_PTREAD_THUNK_PROTOCOL EMU_PTREAD_THUNK_PROTOCOL; + + +typedef +UINTN +(EFIAPI *PTREAD_THUNK_MUTEXT_LOCK) ( + IN VOID *Mutex + ); + + +typedef +UINTN +(EFIAPI *PTREAD_THUNK_MUTEXT_UNLOCK) ( + IN VOID *Mutex + ); + + +typedef +UINTN +(EFIAPI *PTREAD_THUNK_MUTEX_TRY_LOCK) ( + IN VOID *Mutex + ); + + +typedef +VOID * +(EFIAPI *PTREAD_THUNK_MUTEX_INIT) ( + IN VOID + ); + + +typedef +UINTN +(EFIAPI *PTREAD_THUNK_MUTEX_DISTROY) ( + IN VOID *Mutex + ); + + + +typedef +VOID * +(*PTREAD_THUNK_THEAD_ENTRY) ( + IN VOID *Context + ); + +typedef +UINTN +(EFIAPI *PTREAD_THUNK_CREATE_THREAD) ( + IN VOID *Thread, + IN VOID *Attribute, + IN PTREAD_THUNK_THEAD_ENTRY Start, + IN VOID *Context + ); + +typedef +VOID +(EFIAPI *PTREAD_THUNK_EXIT_THREAD) ( + IN VOID *ValuePtr + ); + + +typedef +UINTN +(EFIAPI *PTREAD_THUNK_SELF) ( + VOID + ); + + +struct _EMU_PTREAD_THUNK_PROTOCOL { + PTREAD_THUNK_MUTEXT_LOCK MutextLock; + PTREAD_THUNK_MUTEXT_UNLOCK MutexUnlock; + PTREAD_THUNK_MUTEX_TRY_LOCK MutexTryLock; + PTREAD_THUNK_MUTEX_INIT MutexInit; + PTREAD_THUNK_MUTEX_DISTROY MutexDistroy; + PTREAD_THUNK_CREATE_THREAD CreateThread; + PTREAD_THUNK_EXIT_THREAD ExitThread; + PTREAD_THUNK_SELF Self; +}; + +extern EFI_GUID gEmuPthreadThunkProtocolGuid; + +#endif + diff --git a/InOsEmuPkg/Include/Protocol/EmuThunk.h b/InOsEmuPkg/Include/Protocol/EmuThunk.h new file mode 100644 index 0000000000..411cd3e625 --- /dev/null +++ b/InOsEmuPkg/Include/Protocol/EmuThunk.h @@ -0,0 +1,199 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2008 - 2011, Apple Inc. 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 __EMU_THUNK_PROTOCOL_H__ +#define __EMU_THUNK_PROTOCOL_H__ + +#define EMU_THUNK_PROTOCOL_GUID \ + { 0xA37D7CCD, 0x8E91, 0xFB48, { 0xA0, 0xBD, 0x64, 0xC1, 0x83, 0xA3, 0xB4, 0x3F } } + +// neded for things like EFI_TIME_CAPABILITIES +#include + +#include + +#include +#include + + +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + UINT32 Instance; +} EMU_VENDOR_DEVICE_PATH_NODE; + +typedef struct { + EMU_VENDOR_DEVICE_PATH_NODE Vendor; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} EMU_THUNK_DEVICE_PATH; + + + +typedef struct _EMU_THUNK_PROTOCOL EMU_THUNK_PROTOCOL; + + + +typedef +EFI_STATUS +(EFIAPI *EMU_WRITE_STD_ERROR) ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ); + +typedef +EFI_STATUS +(EFIAPI *EMU_PE_COFF_GET_ENTRY_POINT) ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ); + +typedef +VOID +(EFIAPI *EMU_PE_COFF_RELOCATE_EXTRA_ACTION) ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +typedef +VOID +(EFIAPI *EMU_PE_COFF_UNLOAD_EXTRA_ACTION) ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +typedef +VOID +(EFIAPI *EMU_ENABLE_INERRUPTS) ( + VOID + ); + +typedef +VOID +(EFIAPI *EMU_DISABLE_INERRUPTS) ( + VOID + ); + +typedef +UINT64 +(EFIAPI *EMU_QUERY_PERFORMANCE_FREQENCY) ( + VOID + ); + +typedef +UINT64 +(EFIAPI *EMU_QUERY_PERFORMANCE_COUNTER) ( + VOID + ); + +typedef +VOID +(EFIAPI *EMU_SLEEP) ( + IN UINT64 Milliseconds + ); + +typedef +VOID +(EFIAPI *EMU_EXIT) ( + IN UINTN Status + ); + +typedef +VOID +(EFIAPI *EMU_GET_TIME) ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +typedef +VOID +(EFIAPI *EMU_SET_TIME) ( + IN EFI_TIME *Time + ); + + +typedef +VOID +(EFIAPI EMU_SET_TIMER_CALLBACK) ( + IN UINT64 DeltaMs + ); + +typedef +VOID +(EFIAPI *EMU_SET_TIMER) ( + IN UINT64 PeriodMs, + IN EMU_SET_TIMER_CALLBACK CallBack + ); + + + +/** + Enumerates the current set of protocol instances that abstract OS services from EFI. + + A given protocol can have multiple instances. Usually a protocol is configured via a + single PCD string. The data associated for each instance is seperated via a ! in the string. + EMU_IO_THUNK_PROTOCOL_CLOSE.ConfigString will contain the information in the PCD string up to the next !. + Thus each instance has a unique ConfigString. + + @param EmuBusDriver TRUE means only return protocol instances that need to be produced + by the EmuBusDriver. FALSE means return all possible protocols + @param Instance On input the protocol to search for, or NULL to start a search + of all the supported protocol instances. + @param NextProtocol On output it represents the next value to be passed into Protocol. + @param Interface A pointer to the EMU_IO_THUNK_PROTOCOL_CLOSE interface. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The next protocol instance was not found. + @retval EFI_INVALID_PARAMETER Instance is NULL. + +**/ +typedef +EFI_STATUS +(EFIAPI *EMU_GET_NEXT_PROTOCOL) ( + IN BOOLEAN EmuBusDriver, + OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL + ); + + +struct _EMU_THUNK_PROTOCOL { + // Used for early debug printing + EMU_WRITE_STD_ERROR WriteStdErr; + + /// + /// PE/COFF loader hooks to get symbols loaded + /// + EMU_PE_COFF_GET_ENTRY_POINT PeCoffGetEntryPoint; + EMU_PE_COFF_RELOCATE_EXTRA_ACTION PeCoffRelocateImageExtraAction; + EMU_PE_COFF_UNLOAD_EXTRA_ACTION PeCoffUnloadImageExtraAction; + + /// + /// DXE Architecture Protocol Services + /// + EMU_ENABLE_INERRUPTS EnableInterrupt; + EMU_DISABLE_INERRUPTS DisableInterrupt; + EMU_QUERY_PERFORMANCE_FREQENCY QueryPerformanceFrequency; + EMU_QUERY_PERFORMANCE_COUNTER QueryPerformanceCounter; + + EMU_SLEEP Sleep; + EMU_EXIT Exit; + EMU_GET_TIME GetTime; + EMU_SET_TIME SetTime; + EMU_SET_TIMER SetTimer; + + /// + /// Generic System Services + /// + EMU_GET_NEXT_PROTOCOL GetNextProtocol; +}; + +extern EFI_GUID gEmuThunkProtocolGuid; + +#endif diff --git a/InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.c b/InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.c new file mode 100644 index 0000000000..79e9fbc1ee --- /dev/null +++ b/InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.c @@ -0,0 +1,52 @@ +/*++ @file + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 + +#include +#include +#include + +#include + + +EMU_THUNK_PROTOCOL *gEmuThunk = NULL; + + +/** + The constructor function caches the pointer of EMU Thunk protocol. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeEmuLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = GetFirstGuidHob (&gEmuThunkProtocolGuid); + ASSERT (GuidHob != NULL); + + gEmuThunk = (EMU_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); + ASSERT (gEmuThunk != NULL); + + return EFI_SUCCESS; +} diff --git a/InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.inf b/InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.inf new file mode 100644 index 0000000000..de395d6272 --- /dev/null +++ b/InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.inf @@ -0,0 +1,45 @@ +## @file +# A library to produce the global variable 'gEmuThunk' +# +# This library contains a single global variable 'gEmuThunk' along with a constructor to +# initialize that global. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeEmuLib + FILE_GUID = 31479AFD-B06F-4E4A-863B-A8F7E7710778 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = EmuThunkLib + + CONSTRUCTOR = DxeEmuLibConstructor + + +[Sources] + DxeEmuLib.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + HobLib + DebugLib + + +[Protocols] + gEmuThunkProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c b/InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c new file mode 100644 index 0000000000..fdb8d5334d --- /dev/null +++ b/InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c @@ -0,0 +1,103 @@ +/** @file + Provides services to perform additional actions to relocate and unload + PE/Coff image for Emu environment specific purpose such as souce level debug. + This version only works for DXE phase + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. 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 + +#include + +#include +#include +#include +#include +#include +#include + +// +// Cache of UnixThunk protocol +// +EMU_THUNK_PROTOCOL *mThunk = NULL; + + +/** + The constructor function gets the pointer of the WinNT thunk functions + It will ASSERT() if Unix thunk protocol is not installed. + + @retval EFI_SUCCESS Unix thunk protocol is found and cached. + +**/ +EFI_STATUS +EFIAPI +DxeEmuPeCoffLibExtraActionConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + // + // Retrieve EmuThunkProtocol from GUID'ed HOB + // + GuidHob = GetFirstGuidHob (&gEmuThunkProtocolGuid); + ASSERT (GuidHob != NULL); + mThunk = (EMU_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); + ASSERT (mThunk != NULL); + + return EFI_SUCCESS; +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +PeCoffLoaderRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mThunk != NULL) { + mThunk->PeCoffRelocateImageExtraAction (ImageContext); + } +} + + + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +PeCoffLoaderUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mThunk != NULL) { + mThunk->PeCoffUnloadImageExtraAction (ImageContext); + } +} diff --git a/InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf b/InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf new file mode 100644 index 0000000000..7c1b4ca8e0 --- /dev/null +++ b/InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf @@ -0,0 +1,48 @@ +## @file +# PeCoff extra action libary for DXE phase that run Emu emulator. +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. + +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeEmuPeCoffExtraActionLib + FILE_GUID = 68FCD487-D230-6846-95B1-5E1F2EF942C4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffExtraActionLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER + + CONSTRUCTOR = DxeEmuPeCoffLibExtraActionConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + DxeEmuPeCoffExtraActionLib.c + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + DebugLib + HobLib + BaseMemoryLib + +[Protocols] + gEmuThunkProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c b/InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c new file mode 100644 index 0000000000..b4ef86e128 --- /dev/null +++ b/InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c @@ -0,0 +1,119 @@ +/** @file + Serial Port Lib that thunks back to Emulator services to write to StdErr. + All read functions are stubed out. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2011, Apple Inc. 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 +#include +#include + + + + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + return RETURN_SUCCESS; +} + +/** + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to be written. + @param NumberOfBytes The number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return gEmuThunk->WriteStdErr (Buffer, NumberOfBytes); +} + + +/** + Read data from serial device and save the datas in buffer. + + Reads NumberOfBytes data bytes from a serial device into the buffer + specified by Buffer. The number of bytes actually read is returned. + If the return value is less than NumberOfBytes, then the rest operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes The number of bytes which will be read. + + @retval 0 Read data failed; No data is to be read. + @retval >0 The actual number of bytes read from serial device. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return 0; +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + return FALSE; +} + + diff --git a/InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf b/InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf new file mode 100644 index 0000000000..115ad28483 --- /dev/null +++ b/InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf @@ -0,0 +1,40 @@ +## @file +# Write only instance of Serial Port Library with empty functions. +# +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeEmuSerialPortLibNull + FILE_GUID = DF08A29A-F60B-E649-AA79-A1490E863A5D + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SerialPortLib| DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVE + + +[Sources] + DxeEmuSerialPortLib.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + EmuThunkLib + + + + + diff --git a/InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.c b/InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.c new file mode 100644 index 0000000000..8f47ef9125 --- /dev/null +++ b/InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.c @@ -0,0 +1,557 @@ +/*++ @file + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "BdsPlatform.h" + +EMU_SYSTEM_CONFIGURATION mSystemConfigData; + +VOID +SetupVariableInit ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Size; + + Size = sizeof (mSystemConfigData); + Status = gRT->GetVariable ( + L"Setup", + &gEmuSystemConfigGuid, + NULL, + &Size, + (VOID *) &mSystemConfigData + ); + + if (EFI_ERROR (Status)) { + // + // SetupVariable is corrupt + // + mSystemConfigData.ConOutRow = PcdGet32 (PcdConOutColumn); + mSystemConfigData.ConOutColumn = PcdGet32 (PcdConOutRow); + + Status = gRT->SetVariable ( + L"Setup", + &gEmuSystemConfigGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (mSystemConfigData), + (VOID *) &mSystemConfigData + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status)); + } + } +} + +// +// BDS Platform Functions +// +VOID +EFIAPI +PlatformBdsInit ( + VOID + ) +/*++ + +Routine Description: + + Platform Bds init. Include the platform firmware vendor, revision + and so crc check. + +Arguments: + +Returns: + + None. + +**/ +{ + SetupVariableInit (); +} + +EFI_STATUS +PlatformBdsConnectConsole ( + IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole + ) +/*++ + +Routine Description: + + Connect the predefined platform default console device. Always try to find + and enable the vga device if have. + +Arguments: + + PlatformConsole - Predfined platform default console device array. + +Returns: + + EFI_SUCCESS - Success connect at least one ConIn and ConOut + device, there must have one ConOut device is + active vga device. + + EFI_STATUS - Return the status of + BdsLibConnectAllDefaultConsoles () + +**/ +{ + EFI_STATUS Status; + UINTN Index; + + Index = 0; + Status = EFI_SUCCESS; + + // + // Have chance to connect the platform default console, + // the platform default console is the minimue device group + // the platform should support + // + while (PlatformConsole[Index].DevicePath != NULL) { + // + // Update the console variable with the connect type + // + if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { + BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL); + } + + if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { + BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL); + } + + if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { + BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL); + } + + Index++; + } + // + // Connect the all the default console with current cosole variable + // + Status = BdsLibConnectAllDefaultConsoles (); + return Status; +} + +VOID +PlatformBdsConnectSequence ( + VOID + ) +/*++ + +Routine Description: + + Connect with predeined platform connect sequence, + the OEM/IBV can customize with their own connect sequence. + +Arguments: + + None. + +Returns: + + None. + +**/ +{ + UINTN Index; + + Index = 0; + + // + // Here we can get the customized platform connect sequence + // Notes: we can connect with new variable which record the + // last time boots connect device path sequence + // + while (gPlatformConnectSequence[Index] != NULL) { + // + // Build the platform boot option + // + BdsLibConnectDevicePath (gPlatformConnectSequence[Index]); + Index++; + } + + // + // Just use the simple policy to connect all devices + // + BdsLibConnectAll (); +} + +VOID +PlatformBdsGetDriverOption ( + IN OUT LIST_ENTRY *BdsDriverLists + ) +/*++ + +Routine Description: + + Load the predefined driver option, OEM/IBV can customize this + to load their own drivers + +Arguments: + + BdsDriverLists - The header of the driver option link list. + +Returns: + + None. + +**/ +{ + UINTN Index; + + Index = 0; + + // + // Here we can get the customized platform driver option + // + while (gPlatformDriverOption[Index] != NULL) { + // + // Build the platform boot option + // + BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder"); + Index++; + } + +} + +VOID +PlatformBdsDiagnostics ( + IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, + IN BOOLEAN QuietBoot, + IN BASEM_MEMORY_TEST BaseMemoryTest + ) +/*++ + +Routine Description: + + Perform the platform diagnostic, such like test memory. OEM/IBV also + can customize this fuction to support specific platform diagnostic. + +Arguments: + + MemoryTestLevel - The memory test intensive level + + QuietBoot - Indicate if need to enable the quiet boot + + BaseMemoryTest - A pointer to BdsMemoryTest() + +Returns: + + None. + +**/ +{ + EFI_STATUS Status; + + // + // Here we can decide if we need to show + // the diagnostics screen + // Notes: this quiet boot code should be remove + // from the graphic lib + // + if (QuietBoot) { + EnableQuietBoot (PcdGetPtr(PcdLogoFile)); + // + // Perform system diagnostic + // + Status = BaseMemoryTest (MemoryTestLevel); + if (EFI_ERROR (Status)) { + DisableQuietBoot (); + } + + return ; + } + // + // Perform system diagnostic + // + Status = BaseMemoryTest (MemoryTestLevel); +} + +VOID +EFIAPI +PlatformBdsPolicyBehavior ( + IN OUT LIST_ENTRY *DriverOptionList, + IN OUT LIST_ENTRY *BootOptionList, + IN PROCESS_CAPSULES ProcessCapsules, + IN BASEM_MEMORY_TEST BaseMemoryTest + ) +/*++ + +Routine Description: + + The function will excute with as the platform policy, current policy + is driven by boot mode. IBV/OEM can customize this code for their specific + policy action. + +Arguments: + + DriverOptionList - The header of the driver option link list + + BootOptionList - The header of the boot option link list + + ProcessCapsules - A pointer to ProcessCapsules() + + BaseMemoryTest - A pointer to BaseMemoryTest() + +Returns: + + None. + +**/ +{ + EFI_STATUS Status; + UINT16 Timeout; + EFI_BOOT_MODE BootMode; + + // + // Init the time out value + // + Timeout = PcdGet16 (PcdPlatformBootTimeOut); + + // + // Load the driver option as the driver option list + // + PlatformBdsGetDriverOption (DriverOptionList); + + // + // Get current Boot Mode + // + Status = BdsLibGetBootMode (&BootMode); + + // + // Go the different platform policy with different boot mode + // Notes: this part code can be change with the table policy + // + switch (BootMode) { + + case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES: + case BOOT_WITH_MINIMAL_CONFIGURATION: + // + // In no-configuration boot mode, we can connect the + // console directly. + // + BdsLibConnectAllDefaultConsoles (); + PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest); + + // + // Perform some platform specific connect sequence + // + PlatformBdsConnectSequence (); + + // + // Notes: current time out = 0 can not enter the + // front page + // + PlatformBdsEnterFrontPage (Timeout, FALSE); + + // + // Check the boot option with the boot option list + // + BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder"); + break; + + case BOOT_ON_FLASH_UPDATE: + // + // Boot with the specific configuration + // + PlatformBdsConnectConsole (gPlatformConsole); + PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest); + BdsLibConnectAll (); + ProcessCapsules (BOOT_ON_FLASH_UPDATE); + break; + + case BOOT_IN_RECOVERY_MODE: + // + // In recovery mode, just connect platform console + // and show up the front page + // + PlatformBdsConnectConsole (gPlatformConsole); + PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest); + + // + // In recovery boot mode, we still enter to the + // frong page now + // + PlatformBdsEnterFrontPage (Timeout, FALSE); + break; + + case BOOT_WITH_FULL_CONFIGURATION: + case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS: + case BOOT_WITH_DEFAULT_SETTINGS: + default: + // + // Connect platform console + // + Status = PlatformBdsConnectConsole (gPlatformConsole); + if (EFI_ERROR (Status)) { + // + // Here OEM/IBV can customize with defined action + // + PlatformBdsNoConsoleAction (); + } + + PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest); + + // + // Perform some platform specific connect sequence + // + PlatformBdsConnectSequence (); + + // + // Give one chance to enter the setup if we + // have the time out + // + PlatformBdsEnterFrontPage (Timeout, FALSE); + + // + // Here we have enough time to do the enumeration of boot device + // + BdsLibEnumerateAllBootOption (BootOptionList); + break; + } + + return ; + +} + +VOID +EFIAPI +PlatformBdsBootSuccess ( + IN BDS_COMMON_OPTION *Option + ) +/*++ + +Routine Description: + + Hook point after a boot attempt succeeds. We don't expect a boot option to + return, so the EFI 1.0 specification defines that you will default to an + interactive mode and stop processing the BootOrder list in this case. This + is alos a platform implementation and can be customized by IBV/OEM. + +Arguments: + + Option - Pointer to Boot Option that succeeded to boot. + +Returns: + + None. + +**/ +{ + CHAR16 *TmpStr; + + // + // If Boot returned with EFI_SUCCESS and there is not in the boot device + // select loop then we need to pop up a UI and wait for user input. + // + TmpStr = Option->StatusString; + if (TmpStr != NULL) { + BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL); + FreePool (TmpStr); + } +} + +VOID +EFIAPI +PlatformBdsBootFail ( + IN BDS_COMMON_OPTION *Option, + IN EFI_STATUS Status, + IN CHAR16 *ExitData, + IN UINTN ExitDataSize + ) +/*++ + +Routine Description: + + Hook point after a boot attempt fails. + +Arguments: + + Option - Pointer to Boot Option that failed to boot. + + Status - Status returned from failed boot. + + ExitData - Exit data returned from failed boot. + + ExitDataSize - Exit data size returned from failed boot. + +Returns: + + None. + +**/ +{ + CHAR16 *TmpStr; + + // + // If Boot returned with failed status then we need to pop up a UI and wait + // for user input. + // + TmpStr = Option->StatusString; + if (TmpStr != NULL) { + BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL); + FreePool (TmpStr); + } +} + +EFI_STATUS +PlatformBdsNoConsoleAction ( + VOID + ) +/*++ + +Routine Description: + + This function is remained for IBV/OEM to do some platform action, + if there no console device can be connected. + +Arguments: + + None. + +Returns: + + EFI_SUCCESS - Direct return success now. + +**/ +{ + return EFI_SUCCESS; +} + +VOID +EFIAPI +PlatformBdsLockNonUpdatableFlash ( + VOID + ) +{ + return; +} + +/** + Lock the ConsoleIn device in system table. All key + presses will be ignored until the Password is typed in. The only way to + disable the password is to type it in to a ConIn device. + + @param Password Password used to lock ConIn device. + + @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully. + @retval EFI_UNSUPPORTED Password not found + +**/ +EFI_STATUS +EFIAPI +LockKeyboards ( + IN CHAR16 *Password + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.h b/InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.h new file mode 100644 index 0000000000..a76ec2e4bd --- /dev/null +++ b/InOsEmuPkg/Library/EmuBdsLib/BdsPlatform.h @@ -0,0 +1,97 @@ +/*++ @file + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 _BDS_PLATFORM_H +#define _BDS_PLATFORM_H + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +extern BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[]; +extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[]; +extern EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption[]; + +#define gEndEntire \ + { \ + END_DEVICE_PATH_TYPE,\ + END_ENTIRE_DEVICE_PATH_SUBTYPE,\ + END_DEVICE_PATH_LENGTH,\ + 0\ + } + + +typedef struct { + EMU_VENDOR_DEVICE_PATH_NODE EmuBus; + EMU_VENDOR_DEVICE_PATH_NODE EmuGraphicsWindow; + EFI_DEVICE_PATH_PROTOCOL End; +} EMU_PLATFORM_UGA_DEVICE_PATH; + + +// +// Platform BDS Functions +// +VOID +PlatformBdsGetDriverOption ( + IN LIST_ENTRY *BdsDriverLists + ); + +EFI_STATUS +BdsMemoryTest ( + EXTENDMEM_COVERAGE_LEVEL Level + ); + + +VOID +PlatformBdsConnectSequence ( + VOID + ); + +EFI_STATUS +ProcessCapsules ( + EFI_BOOT_MODE BootMode + ); + +EFI_STATUS +PlatformBdsConnectConsole ( + IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole + ); + +EFI_STATUS +PlatformBdsNoConsoleAction ( + VOID + ); + +VOID +PlatformBdsEnterFrontPage ( + IN UINT16 TimeoutDefault, + IN BOOLEAN ConnectAllHappened + ); + +#endif // _BDS_PLATFORM_H diff --git a/InOsEmuPkg/Library/EmuBdsLib/EmuBdsLib.inf b/InOsEmuPkg/Library/EmuBdsLib/EmuBdsLib.inf new file mode 100644 index 0000000000..27f6337bb5 --- /dev/null +++ b/InOsEmuPkg/Library/EmuBdsLib/EmuBdsLib.inf @@ -0,0 +1,66 @@ +## @file +# Platfrom BDS driver +# +# Do platform action customized by IBV/OEM. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuBdsLib + FILE_GUID = 59569181-CBF8-2E44-9C3E-C2AB2F5608E1 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformBdsLib|DXE_DRIVER + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + BdsPlatform.c + PlatformData.c + BdsPlatform.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + PcdLib + GenericBdsLib + DevicePathLib + + +[Guids] + gEmuSystemConfigGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile + +[Depex] + gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid diff --git a/InOsEmuPkg/Library/EmuBdsLib/PlatformData.c b/InOsEmuPkg/Library/EmuBdsLib/PlatformData.c new file mode 100644 index 0000000000..e20099b9f0 --- /dev/null +++ b/InOsEmuPkg/Library/EmuBdsLib/PlatformData.c @@ -0,0 +1,69 @@ +/*++ @file + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. 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 "BdsPlatform.h" + + + +EMU_PLATFORM_UGA_DEVICE_PATH gGopDevicePath = { + { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (EMU_VENDOR_DEVICE_PATH_NODE)), + (UINT8) ((sizeof (EMU_VENDOR_DEVICE_PATH_NODE)) >> 8) + } + }, + EMU_THUNK_PROTOCOL_GUID + }, + 0 + }, + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (EMU_VENDOR_DEVICE_PATH_NODE)), + (UINT8) ((sizeof (EMU_VENDOR_DEVICE_PATH_NODE)) >> 8) + }, + EMU_GRAPHICS_WINDOW_PROTOCOL_GUID, + 0 + }, + gEndEntire +}; + +// +// Predefined platform default console device path +// +BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = { + { + (EFI_DEVICE_PATH_PROTOCOL *) &gGopDevicePath, + (CONSOLE_OUT | CONSOLE_IN) + }, + { + NULL, + 0 + } +}; + +// +// Predefined platform specific driver option +// +EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption[] = { NULL }; + +// +// Predefined platform connect sequence +// +EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] = { NULL }; diff --git a/InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.c b/InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.c new file mode 100644 index 0000000000..5a80870f0f --- /dev/null +++ b/InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.c @@ -0,0 +1,50 @@ +/*++ @file + +Copyright (c) 2011, Apple Inc. 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 +#include + + +/** + KeyMapMake gets called on key presses. + + @param KeyData Key that was pressed. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +KeyMapMake ( + IN EFI_KEY_DATA *KeyData + ) +{ + return EFI_SUCCESS; +} + +/** + KeyMapBreak gets called on key releases. + + @param KeyData Key that was pressed. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +KeyMapBreak ( + IN EFI_KEY_DATA *KeyData + ) +{ + return EFI_SUCCESS; +} \ No newline at end of file diff --git a/InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.inf b/InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.inf new file mode 100644 index 0000000000..46483df341 --- /dev/null +++ b/InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.inf @@ -0,0 +1,39 @@ +## @file +# A library to produce the global variable 'gEmuThunk' +# +# This library contains a single global variable 'gEmuThunk' along with a constructor to +# initialize that global. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = KeyMapLibNull + FILE_GUID = 6B7067C7-A843-A34C-9530-48446963B740 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = KeyMapLib + +[Sources] + KeyMapLibNull.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + HobLib + DebugLib + + diff --git a/InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf b/InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf new file mode 100644 index 0000000000..2510d690e2 --- /dev/null +++ b/InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf @@ -0,0 +1,45 @@ +## @file +# Instance of PEI Services Table Pointer Library using global variable for the table pointer. +# +# PEI Services Table Pointer Library implementation that retrieves a pointer to the +# PEI Services Table from a global variable. Not available to modules that execute from +# read-only memory. +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = InOsEmuPkgPeiCoreServicesTablePointerLib + FILE_GUID = E9A22529-44FA-3E4A-A66B-1E918E7AB26A + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeiServicesTablePointerLib|PEI_CORE + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only) +# + +[Sources] + PeiServicesTablePointer.c + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + DebugLib + +[Ppis] + gEmuPeiServicesTableUpdatePpiGuid + diff --git a/InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiServicesTablePointer.c b/InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiServicesTablePointer.c new file mode 100644 index 0000000000..1c689390f8 --- /dev/null +++ b/InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiServicesTablePointer.c @@ -0,0 +1,102 @@ +/** @file + PEI Services Table Pointer Library for PEI Core. + + This library is used for PEI Core which does executed from flash device directly but + executed in memory. When the PEI Core does a Set of the PEI Service table pointer + a PPI is reinstalled so that PEIMs can update the copy of the PEI Services table + they have cached. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Portiions copyrigth (c) 2011, Apple Inc. 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 +#include +#include + +#include + + +CONST EFI_PEI_SERVICES **gPeiServices = NULL; + +/** + Caches a pointer PEI Services Table. + + Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer + in a CPU specific manner as specified in the CPU binding section of the Platform Initialization + Pre-EFI Initialization Core Interface Specification. + + If PeiServicesTablePointer is NULL, then ASSERT(). + + @param PeiServicesTablePointer The address of PeiServices pointer. +**/ +VOID +EFIAPI +SetPeiServicesTablePointer ( + IN CONST EFI_PEI_SERVICES **PeiServicesTablePointer + ) +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; + VOID *NotUsed; + + gPeiServices = PeiServicesTablePointer; + + Status = (*PeiServicesTablePointer)->LocatePpi ( + PeiServicesTablePointer, + &gEmuPeiServicesTableUpdatePpiGuid, // GUID + 0, // INSTANCE + &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR + &NotUsed // PPI + ); + if (!EFI_ERROR (Status)) { + // + // Standard PI Mechanism is to use negative offset from IDT. + // We can't do that in the emulator, so we make up a constant location + // that every one can use. The first try may fail as the PEI Core is still + // initializing its self, but that is OK. + // + + // Reinstall PPI to consumers know to update PEI Services pointer + Status = (*PeiServicesTablePointer)->ReInstallPpi ( + PeiServicesTablePointer, + PpiDescriptor, + PpiDescriptor + ); + + } + +} + +/** + Retrieves the cached value of the PEI Services Table pointer. + + Returns the cached value of the PEI Services Table pointer in a CPU specific manner + as specified in the CPU binding section of the Platform Initialization Pre-EFI + Initialization Core Interface Specification. + + If the cached PEI Services Table pointer is NULL, then ASSERT(). + + @return The pointer to PeiServices. + +**/ +CONST EFI_PEI_SERVICES ** +EFIAPI +GetPeiServicesTablePointer ( + VOID + ) +{ + ASSERT (gPeiServices != NULL); + ASSERT (*gPeiServices != NULL); + return gPeiServices; +} + + diff --git a/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c b/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c new file mode 100644 index 0000000000..b88bd009fe --- /dev/null +++ b/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c @@ -0,0 +1,106 @@ +/** @file + Provides services to perform additional actions to relocate and unload + PE/Coff image for Emu environment specific purpose such as souce level debug. + This version only works for PEI phase + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. 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 +#include +#include + +#include +#include +#include +#include +#include + +// +// Cache of UnixThunk protocol +// +EMU_THUNK_PROTOCOL *mThunk = NULL; + +/** + The function caches the pointer of the Unix thunk functions + It will ASSERT() if Unix thunk ppi is not installed. + + @retval EFI_SUCCESS WinNT thunk protocol is found and cached. + +**/ +EFI_STATUS +EFIAPI +EmuPeCoffGetThunkStucture ( + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + + + // + // Locate Unix ThunkPpi for retrieving standard output handle + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + ASSERT_EFI_ERROR (Status); + + mThunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk (); + + return EFI_SUCCESS; +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +PeCoffLoaderRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mThunk == NULL) { + EmuPeCoffGetThunkStucture (); + } + mThunk->PeCoffRelocateImageExtraAction (ImageContext); + } + + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +PeCoffLoaderUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mThunk == NULL) { + EmuPeCoffGetThunkStucture (); + } + mThunk->PeCoffUnloadImageExtraAction (ImageContext); +} diff --git a/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf b/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf new file mode 100644 index 0000000000..3fd4a8aefe --- /dev/null +++ b/InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf @@ -0,0 +1,46 @@ +## @file +# PeCoff extra action libary for Pei phase that run Emu emulator. +# +# Lib to provide memory journal status code reporting Routines +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. + +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiEmuPeCoffExtraActionLib + FILE_GUID = 79C4E72A-730B-F040-8129-95877B3A97A8 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffExtraActionLib|PEI_CORE PEIM + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + PeiEmuPeCoffExtraActionLib.c + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + BaseLib + PeiServicesLib + DebugLib + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED diff --git a/InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c b/InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c new file mode 100644 index 0000000000..0b4be07ce6 --- /dev/null +++ b/InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c @@ -0,0 +1,297 @@ +/*++ @file + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. 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 "PiPei.h" +#include +#include +#include +#include + +#include +#include + + + +/** + Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded + into system memory with the PE/COFF Loader Library functions. + + Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry + point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then + return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. + If Pe32Data is NULL, then ASSERT(). + If EntryPoint is NULL, then ASSERT(). + + @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. + @param EntryPoint The pointer to entry point to the PE/COFF image to return. + + @retval RETURN_SUCCESS EntryPoint was returned. + @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + EMU_THUNK_PROTOCOL *Thunk; + + // + // Locate EmuThunkPpi for retrieving standard output handle + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + ASSERT_EFI_ERROR (Status); + + Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + + return Thunk->PeCoffGetEntryPoint (Pe32Data, EntryPoint); +} + +/** + Returns the machine type of PE/COFF image. + This is copied from MDE BasePeCoffGetEntryPointLib, the code should be sync with it. + The reason is Emu package needs to load the image to memory to support source + level debug. + + + @param Pe32Data Pointer to a PE/COFF header + + @return Machine type or zero if not a valid iamge + +**/ +UINT16 +EFIAPI +PeCoffLoaderGetMachineType ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + EFI_IMAGE_DOS_HEADER *DosHdr; + + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + + } else { + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data); + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + return Hdr.Te->Machine; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + return Hdr.Pe32->FileHeader.Machine; + } + + return 0x0000; +} + +/** + Returns a pointer to the PDB file name for a PE/COFF image that has been + loaded into system memory with the PE/COFF Loader Library functions. + + Returns the PDB file name for the PE/COFF image specified by Pe32Data. If + the PE/COFF image specified by Pe32Data is not a valid, then NULL is + returned. If the PE/COFF image specified by Pe32Data does not contain a + debug directory entry, then NULL is returned. If the debug directory entry + in the PE/COFF image specified by Pe32Data does not contain a PDB file name, + then NULL is returned. + If Pe32Data is NULL, then ASSERT(). + + @param Pe32Data Pointer to the PE/COFF image that is loaded in system + memory. + + @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL + if it cannot be retrieved. + +**/ +VOID * +EFIAPI +PeCoffLoaderGetPdbPointer ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; + UINTN DirCount; + VOID *CodeViewEntryPointer; + INTN TEImageAdjust; + UINT32 NumberOfRvaAndSizes; + UINT16 Magic; + + ASSERT (Pe32Data != NULL); + + TEImageAdjust = 0; + DirectoryEntry = NULL; + DebugEntry = NULL; + NumberOfRvaAndSizes = 0; + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) { + DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG]; + TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize; + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te + + Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress + + TEImageAdjust); + } + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + // + // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic. + // It is due to backward-compatibility, for some system might + // generate PE32+ image with PE32 Magic. + // + switch (Hdr.Pe32->FileHeader.Machine) { + case EFI_IMAGE_MACHINE_IA32: + // + // Assume PE32 image with IA32 Machine field. + // + Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; + break; + case EFI_IMAGE_MACHINE_X64: + case EFI_IMAGE_MACHINE_IA64: + // + // Assume PE32+ image with X64 or IA64 Machine field + // + Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + break; + default: + // + // For unknow Machine field, use Magic in optional Header + // + Magic = Hdr.Pe32->OptionalHeader.Magic; + } + + if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + // + // Use PE32 offset get Debug Directory Entry + // + NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress); + } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + // + // Use PE32+ offset get Debug Directory Entry + // + NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress); + } + + if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + DirectoryEntry = NULL; + DebugEntry = NULL; + } + } else { + return NULL; + } + + if (DebugEntry == NULL || DirectoryEntry == NULL) { + return NULL; + } + + for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) { + if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { + if (DebugEntry->SizeOfData > 0) { + CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust); + switch (* (UINT32 *) CodeViewEntryPointer) { + case CODEVIEW_SIGNATURE_NB10: + return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)); + case CODEVIEW_SIGNATURE_RSDS: + return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)); + case CODEVIEW_SIGNATURE_MTOC: + return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)); + default: + break; + } + } + } + } + + return NULL; +} + + +/** + Returns the size of the PE/COFF headers + + Returns the size of the PE/COFF header specified by Pe32Data. + If Pe32Data is NULL, then ASSERT(). + + @param Pe32Data Pointer to the PE/COFF image that is loaded in system + memory. + + @return Size of PE/COFF header in bytes or zero if not a valid image. + +**/ +UINT32 +EFIAPI +PeCoffGetSizeOfHeaders ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + UINTN SizeOfHeaders; + + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders; + } else { + SizeOfHeaders = 0; + } + + return SizeOfHeaders; +} + diff --git a/InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf b/InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf new file mode 100644 index 0000000000..d09fd22df8 --- /dev/null +++ b/InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf @@ -0,0 +1,49 @@ +## @file +# Component description file for the EdkNt32PeiPeCoffGetEntryPointLib library. +# +# PeCoffGetEntryPointLib library class for NT32 instance implemented by use NTPeiLoadFile PPI. +# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiEmuPeCoffGetEntryPointLib + FILE_GUID = 1CBED347-7DE6-BC48-AC68-3758598124D2 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffGetEntryPointLib + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + PeiEmuPeCoffGetEntryPointLib.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + PeiServicesLib + DebugLib + + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + diff --git a/InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c b/InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c new file mode 100644 index 0000000000..aa4e80cf01 --- /dev/null +++ b/InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c @@ -0,0 +1,140 @@ +/** @file + Serial Port Lib that thunks back to Emulator services to write to StdErr. + All read functions are stubed out. There is no constructor so this lib can + be linked with PEI Core. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2011, Apple Inc. 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 +#include +#include + +#include +#include + + + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + return RETURN_SUCCESS; +} + +/** + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to be written. + @param NumberOfBytes The number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + EMU_THUNK_PROTOCOL *Thunk; + + // + // Locate EmuThunkPpi for retrieving standard output handle + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + if (!EFI_ERROR (Status)) { + Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + return Thunk->WriteStdErr (Buffer, NumberOfBytes); + } + + return 0; +} + + +/** + Read data from serial device and save the datas in buffer. + + Reads NumberOfBytes data bytes from a serial device into the buffer + specified by Buffer. The number of bytes actually read is returned. + If the return value is less than NumberOfBytes, then the rest operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes The number of bytes which will be read. + + @retval 0 Read data failed; No data is to be read. + @retval >0 The actual number of bytes read from serial device. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return 0; +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + return FALSE; +} + + diff --git a/InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf b/InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf new file mode 100644 index 0000000000..663967ddd9 --- /dev/null +++ b/InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf @@ -0,0 +1,45 @@ +## @file +# Write only instance of Serial Port Library with empty functions. +# +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiEmuSerialPortLibNull + FILE_GUID = E4541241-8897-411a-91F8-7D7E45837146 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SerialPortLib| PEI_CORE PEIM + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + PeiEmuSerialPortLib.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + PeiServicesLib + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + + + + diff --git a/InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c b/InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c new file mode 100644 index 0000000000..6a58a74f87 --- /dev/null +++ b/InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c @@ -0,0 +1,134 @@ +/** @file + PEI Services Table Pointer Library. + + This library is used for PEIM which does executed from flash device directly but + executed in memory. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Portiions copyrigth (c) 2011, Apple Inc. 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 +#include +#include + +#include + + +CONST EFI_PEI_SERVICES **gPeiServices = NULL; + +/** + Caches a pointer PEI Services Table. + + Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer + in a CPU specific manner as specified in the CPU binding section of the Platform Initialization + Pre-EFI Initialization Core Interface Specification. + + If PeiServicesTablePointer is NULL, then ASSERT(). + + @param PeiServicesTablePointer The address of PeiServices pointer. +**/ +VOID +EFIAPI +SetPeiServicesTablePointer ( + IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer + ) +{ + ASSERT (PeiServicesTablePointer != NULL); + ASSERT (*PeiServicesTablePointer != NULL); + gPeiServices = PeiServicesTablePointer; +} + +/** + Retrieves the cached value of the PEI Services Table pointer. + + Returns the cached value of the PEI Services Table pointer in a CPU specific manner + as specified in the CPU binding section of the Platform Initialization Pre-EFI + Initialization Core Interface Specification. + + If the cached PEI Services Table pointer is NULL, then ASSERT(). + + @return The pointer to PeiServices. + +**/ +CONST EFI_PEI_SERVICES ** +EFIAPI +GetPeiServicesTablePointer ( + VOID + ) +{ + ASSERT (gPeiServices != NULL); + ASSERT (*gPeiServices != NULL); + return gPeiServices; +} + + + +/** + Notification service to be called when gEmuThunkPpiGuid is installed. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. Type + EFI_PEI_NOTIFY_DESCRIPTOR is defined above. + @param Ppi Address of the PPI that was installed. + + @retval EFI_STATUS This function will install a PPI to PPI database. The status + code will be the code for (*PeiServices)->InstallPpi. + +**/ +EFI_STATUS +EFIAPI +PeiServicesTablePointerNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + gPeiServices = (CONST EFI_PEI_SERVICES **)PeiServices; + + return EFI_SUCCESS; +} + + +EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnThunkList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEmuPeiServicesTableUpdatePpiGuid, + PeiServicesTablePointerNotifyCallback +}; + + +/** + Constructor register notification on when PPI updates. If PPI is + alreay installed registering the notify will cause the handle to + run. + + @param FileHandle The handle of FFS header the loaded driver. + @param PeiServices The pointer to the PEI services. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +PeiServicesTablePointerLibConstructor ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + // register to be told when PeiServices pointer is updated + Status = (*PeiServices)->NotifyPpi (PeiServices, &mNotifyOnThunkList); + ASSERT_EFI_ERROR (Status); + return Status; +} + + diff --git a/InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf b/InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf new file mode 100644 index 0000000000..29d790a32a --- /dev/null +++ b/InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf @@ -0,0 +1,47 @@ +## @file +# Instance of PEI Services Table Pointer Library using global variable for the table pointer. +# +# PEI Services Table Pointer Library implementation that retrieves a pointer to the +# PEI Services Table from a global variable. Not available to modules that execute from +# read-only memory. +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = InOsEmuPkgPeiServicesTablePointerLib + FILE_GUID = 5FD8B4ED-D66F-C144-9953-AC557C649925 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeiServicesTablePointerLib|PEIM + + CONSTRUCTOR = PeiServicesTablePointerLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only) +# + +[Sources] + PeiServicesTablePointer.c + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + DebugLib + +[Ppis] + gEmuPeiServicesTableUpdatePpiGuid + diff --git a/InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.c b/InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.c new file mode 100644 index 0000000000..3531b84bf5 --- /dev/null +++ b/InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.c @@ -0,0 +1,72 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2008 - 2011, Apple Inc. 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 +#include + +#include + + +UINTN gThunkPpiListSize = 0; +EFI_PEI_PPI_DESCRIPTOR *gThunkPpiList = NULL; + + + +EFI_PEI_PPI_DESCRIPTOR * +GetThunkPpiList ( + VOID + ) +{ + UINTN Index; + + if (gThunkPpiList == NULL) { + return NULL; + } + + Index = (gThunkPpiListSize/sizeof (EFI_PEI_PPI_DESCRIPTOR)) - 1; + gThunkPpiList[Index].Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + + return gThunkPpiList; +} + + +EFI_STATUS +EFIAPI +AddThunkPpi ( + IN UINTN Flags, + IN EFI_GUID *Guid, + IN VOID *Ppi + ) +{ + UINTN Index; + + gThunkPpiList = realloc (gThunkPpiList, gThunkPpiListSize + sizeof (EFI_PEI_PPI_DESCRIPTOR)); + if (gThunkPpiList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Index = (gThunkPpiListSize/sizeof (EFI_PEI_PPI_DESCRIPTOR)); + gThunkPpiList[Index].Flags = Flags; + gThunkPpiList[Index].Guid = Guid; + gThunkPpiList[Index].Ppi = Ppi; + gThunkPpiListSize += sizeof (EFI_PEI_PPI_DESCRIPTOR); + + return EFI_SUCCESS; +} + + + + + diff --git a/InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.inf b/InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.inf new file mode 100644 index 0000000000..aa4bb5a48e --- /dev/null +++ b/InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.inf @@ -0,0 +1,38 @@ +## @file +# Place thunk PPI in HOB. +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ThunkPpiList + FILE_GUID = 465FDE84-E8B0-B04B-A843-A03F68F617A9 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryAllocationLib|SEC BASE USER_DEFINED + +[Sources] + ThunkPpiList.c + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + +[BuildOptions] + XCODE:*_*_*_DLINK_PATH == gcc + diff --git a/InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.c b/InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.c new file mode 100644 index 0000000000..3c53716765 --- /dev/null +++ b/InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.c @@ -0,0 +1,138 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2008 - 2011, Apple Inc. 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 +#include +#include +#include + +#include + +#include + + +#define EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('E','m','u','T') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL Data; + BOOLEAN EmuBusDriver; + LIST_ENTRY Link; +} EMU_IO_THUNK_PROTOCOL_DATA; + +LIST_ENTRY mThunkList = INITIALIZE_LIST_HEAD_VARIABLE (mThunkList); + + +EFI_STATUS +EFIAPI +AddThunkProtocol ( + IN EMU_IO_THUNK_PROTOCOL *ThunkIo, + IN CHAR16 *ConfigString, + IN BOOLEAN EmuBusDriver + ) +{ + CHAR16 *StartString; + CHAR16 *SubString; + UINTN Instance; + EMU_IO_THUNK_PROTOCOL_DATA *Private; + + if (ThunkIo == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = 0; + StartString = malloc (StrSize (ConfigString)); + StrCpy (StartString, ConfigString); + while (*StartString != '\0') { + + // + // Find the end of the sub string + // + SubString = StartString; + while (*SubString != '\0' && *SubString != '!') { + SubString++; + } + + if (*SubString == '!') { + // + // Replace token with '\0' to make sub strings. If this is the end + // of the string SubString will already point to NULL. + // + *SubString = '\0'; + SubString++; + } + + Private = malloc (sizeof (EMU_IO_THUNK_PROTOCOL_DATA)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Private->Signature = EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE; + Private->EmuBusDriver = EmuBusDriver; + + CopyMem (&Private->Data, ThunkIo, sizeof (EMU_IO_THUNK_PROTOCOL)); + Private->Data.Instance = Instance++; + Private->Data.ConfigString = StartString; + + InsertTailList (&mThunkList, &Private->Link); + + // + // Parse Next sub string. This will point to '\0' if we are at the end. + // + StartString = SubString; + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +GetNextThunkProtocol ( + IN BOOLEAN EmuBusDriver, + OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL + ) +{ + LIST_ENTRY *Link; + EMU_IO_THUNK_PROTOCOL_DATA *Private; + + if (mThunkList.ForwardLink == &mThunkList) { + // Skip parsing an empty list + return EFI_NOT_FOUND; + } + + for (Link = mThunkList.ForwardLink; Link != &mThunkList; Link = Link->ForwardLink) { + Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE); + if (EmuBusDriver & !Private->EmuBusDriver) { + continue; + } else if (*Instance == NULL) { + // Find 1st match in list + *Instance = &Private->Data; + return EFI_SUCCESS; + } else if (*Instance == &Private->Data) { + // Matched previous call so look for valid next entry + Link = Link->ForwardLink; + if (Link == &mThunkList) { + return EFI_NOT_FOUND; + } + Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE); + *Instance = &Private->Data; + return EFI_SUCCESS; + } + } + + + return EFI_NOT_FOUND; +} + diff --git a/InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.inf b/InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.inf new file mode 100644 index 0000000000..387a650fd7 --- /dev/null +++ b/InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.inf @@ -0,0 +1,36 @@ +## @file +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ThunkProtocolList + FILE_GUID = 7833616E-AE0D-594F-870C-80E68682D587 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryAllocationLib|BASE SEC USER_DEFINED + +[Sources] + ThunkProtocolList.c + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + + + diff --git a/InOsEmuPkg/MetronomeDxe/Metronome.c b/InOsEmuPkg/MetronomeDxe/Metronome.c new file mode 100644 index 0000000000..34f946984f --- /dev/null +++ b/InOsEmuPkg/MetronomeDxe/Metronome.c @@ -0,0 +1,125 @@ +/*++ @file + Emu Emulation Metronome Architectural Protocol Driver as defined in DXE CIS + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. 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 "Metronome.h" + + +// +// Global Variables +// +EFI_METRONOME_ARCH_PROTOCOL mMetronome = { + EmuMetronomeDriverWaitForTick, + TICK_PERIOD +}; + +// +// Worker Functions +// + +EFI_STATUS +EFIAPI +EmuMetronomeDriverWaitForTick ( + IN EFI_METRONOME_ARCH_PROTOCOL *This, + IN UINT32 TickNumber + ) +/*++ + +Routine Description: + + The WaitForTick() function waits for the number of ticks specified by + TickNumber from a known time source in the platform. If TickNumber of + ticks are detected, then EFI_SUCCESS is returned. The actual time passed + between entry of this function and the first tick is between 0 and + TickPeriod 100 nS units. If you want to guarantee that at least TickPeriod + time has elapsed, wait for two ticks. This function waits for a hardware + event to determine when a tick occurs. It is possible for interrupt + processing, or exception processing to interrupt the execution of the + WaitForTick() function. Depending on the hardware source for the ticks, it + is possible for a tick to be missed. This function cannot guarantee that + ticks will not be missed. If a timeout occurs waiting for the specified + number of ticks, then EFI_TIMEOUT is returned. + +Arguments: + + This - The EFI_METRONOME_ARCH_PROTOCOL instance. + TickNumber - Number of ticks to wait. + +Returns: + + EFI_SUCCESS - The wait for the number of ticks specified by TickNumber + succeeded. + +**/ +{ + UINT64 SleepTime; + + // + // Calculate the time to sleep. Emu smallest unit to sleep is 1 millisec + // Tick Period is in 100ns units, divide by 10000 to convert to ms + // + SleepTime = DivU64x32 (MultU64x32 ((UINT64) TickNumber, TICK_PERIOD) + 9999, 10000); + gEmuThunk->Sleep (SleepTime); + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +EmuMetronomeDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Initialize the Metronome Architectural Protocol driver + +Arguments: + + ImageHandle - ImageHandle of the loaded driver + + + SystemTable - Pointer to the System Table + +Returns: + + EFI_SUCCESS - Metronome Architectural Protocol created + + EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver. + + EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver. + +**/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + + // + // Install the Metronome Architectural Protocol onto a new handle + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiMetronomeArchProtocolGuid, + EFI_NATIVE_INTERFACE, + &mMetronome + ); + + return Status; +} diff --git a/InOsEmuPkg/MetronomeDxe/Metronome.h b/InOsEmuPkg/MetronomeDxe/Metronome.h new file mode 100644 index 0000000000..5115e0b55b --- /dev/null +++ b/InOsEmuPkg/MetronomeDxe/Metronome.h @@ -0,0 +1,56 @@ +/*++ @file + Emu Emulation Metronome Architectural Protocol Driver as defined in DXE CIS + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. 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 _EMU_THUNK_METRONOME_H_ +#define _EMU_THUNK_METRONOME_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + + + +// +// Period of on tick in 100 nanosecond units +// +#define TICK_PERIOD 2000 + +// +// Function Prototypes +// + +EFI_STATUS +EFIAPI +EmuMetronomeDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +EmuMetronomeDriverWaitForTick ( + IN EFI_METRONOME_ARCH_PROTOCOL *This, + IN UINT32 TickNumber + ); + +#endif diff --git a/InOsEmuPkg/MetronomeDxe/Metronome.inf b/InOsEmuPkg/MetronomeDxe/Metronome.inf new file mode 100644 index 0000000000..4befdf3d61 --- /dev/null +++ b/InOsEmuPkg/MetronomeDxe/Metronome.inf @@ -0,0 +1,59 @@ +## @file +# Emu Emulation Metronome Architectural Protocol Driver as defined in DXE CIS +# +# This metronome module simulates metronome by Sleep WinAPI. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Metronome + FILE_GUID = f348f6fe-8985-11db-b4c3-0040d02b1835 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = EmuMetronomeDriverInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + Metronome.h + Metronome.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + EmuThunkLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + + +[Protocols] + gEfiMetronomeArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +[Depex] + TRUE + diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturer.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturer.uni new file mode 100644 index 0000000000000000000000000000000000000000..669654ece436d1f97a103b2987ec3487e5f77be2 GIT binary patch literal 2214 zcmbuANpBND5QXcE#D5q$7nURj4jd35d6|Gk5=V(0;ADA=Gg4xsu^q^t2fkPBo*Czs zSR?mZUG@6atM9eUVIh)%Z?F7q@*0gi`T%d|5 z6YGH}!#cr#j^CNbxMe;h#)N)_#nk6xP%rEjOYPlrZjODzicl$D#^?rbrT-zTI(@_5 zn9jii;xL#R`8=cE$pgtu4xz6W`4Yd zrNsK%xfs(5-S%xW(8#0M2z)8llDTd@0%tWZfmh+bVkhKCsQ+N~5Y;v_fz5lYMt=V* z?hrT-rd5SmDQQJ6KDgebvB0kEbLaYyvpE^6KVW~!$_VTeRJR@d5HHvKA}6ueeZE=> zsxx%dwJ)>{J7L~|(*#!4_gL+qv_7NMneN*uead?2q0B-DWv5tNxaTe-DOzofUVi1Z zM&IB=XRRykq0Sx=9M7LDwhY` zOEGGA)t+*-BtNyvxv0QUi6I9A(1@#+4K~cBKI%F@ZN?{l)4mK;m%?WltmFI2#*njFA# i7Y&!MPg1G=$JSbl*FZHWB`m>vjE={w#Q&o5rT7oAeow&w literal 0 HcmV?d00001 diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturerData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturerData.c new file mode 100644 index 0000000000..52d120429f --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturerData.c @@ -0,0 +1,57 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscBaseBoardManufacturerData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_BASE_BOARD_MANUFACTURER_DATA, MiscBaseBoardManufacturer) = { + STRING_TOKEN(STR_MISC_BASE_BOARD_MANUFACTURER), + STRING_TOKEN(STR_MISC_BASE_BOARD_PRODUCT_NAME), + STRING_TOKEN(STR_MISC_BASE_BOARD_VERSION), + STRING_TOKEN(STR_MISC_BASE_BOARD_SERIAL_NUMBER), + STRING_TOKEN(STR_MISC_BASE_BOARD_ASSET_TAG), + STRING_TOKEN(STR_MISC_BASE_BOARD_CHASSIS_LOCATION), + { // BaseBoardFeatureFlags + 1, // Motherboard + 0, // RequiresDaughterCard + 0, // Removable + 1, // Replaceable, + 0, // HotSwappable + 0, // Reserved + }, + EfiBaseBoardTypeUnknown, // BaseBoardType + { // BaseBoardChassisLink + EFI_MISC_SUBCLASS_GUID, // ProducerName + 1, // Instance + 1, // SubInstance + }, + 0, // BaseBoardNumberLinks + { // LinkN + EFI_MISC_SUBCLASS_GUID, // ProducerName + 1, // Instance + 1, // SubInstance + }, +}; + +/* eof - MiscBaseBoardManufacturerData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturerFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturerFunction.c new file mode 100644 index 0000000000..04f5a1edc5 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturerFunction.c @@ -0,0 +1,167 @@ +/** @file + BaseBoard manufacturer information boot time changes. + SMBIOS type 2. + + 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. + +**/ + +#include "MiscSubClassDriver.h" +/** + This function makes boot time changes to the contents of the + MiscBaseBoardManufacturer (Type 2). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(MiscBaseBoardManufacturer) +{ + CHAR8 *OptionalStrStart; + UINTN ManuStrLen; + UINTN ProductStrLen; + UINTN VerStrLen; + UINTN AssertTagStrLen; + UINTN SerialNumStrLen; + UINTN ChassisStrLen; + EFI_STATUS Status; + EFI_STRING Manufacturer; + EFI_STRING Product; + EFI_STRING Version; + EFI_STRING SerialNumber; + EFI_STRING AssertTag; + EFI_STRING Chassis; + STRING_REF TokenToGet; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE2 *SmbiosRecord; + EFI_MISC_BASE_BOARD_MANUFACTURER *ForType2InputData; + + ForType2InputData = (EFI_MISC_BASE_BOARD_MANUFACTURER *)RecordData; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_MANUFACTURER); + Manufacturer = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + ManuStrLen = StrLen(Manufacturer); + if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_PRODUCT_NAME); + Product = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + ProductStrLen = StrLen(Product); + if (ProductStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_VERSION); + Version = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + VerStrLen = StrLen(Version); + if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_SERIAL_NUMBER); + SerialNumber = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + SerialNumStrLen = StrLen(SerialNumber); + if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_ASSET_TAG); + AssertTag = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + AssertTagStrLen = StrLen(AssertTag); + if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_BASE_BOARD_CHASSIS_LOCATION); + Chassis = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + ChassisStrLen = StrLen(Chassis); + if (ChassisStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + ChassisStrLen +1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + ChassisStrLen +1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE2); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + // + // Manu will be the 1st optional string following the formatted structure. + // + SmbiosRecord->Manufacturer = 1; + // + // ProductName will be the 2st optional string following the formatted structure. + // + SmbiosRecord->ProductName = 2; + // + // Version will be the 3rd optional string following the formatted structure. + // + SmbiosRecord->Version = 3; + // + // SerialNumber will be the 4th optional string following the formatted structure. + // + SmbiosRecord->SerialNumber = 4; + // + // AssertTag will be the 5th optional string following the formatted structure. + // + SmbiosRecord->AssetTag = 5; + + // + // LocationInChassis will be the 6th optional string following the formatted structure. + // + SmbiosRecord->LocationInChassis = 6; + SmbiosRecord->FeatureFlag = (*(BASE_BOARD_FEATURE_FLAGS*)&(ForType2InputData->BaseBoardFeatureFlags)); + SmbiosRecord->ChassisHandle = 0; + SmbiosRecord->BoardType = (UINT8)ForType2InputData->BaseBoardType; + SmbiosRecord->NumberOfContainedObjectHandles = 0; + + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + // + // Since we fill NumberOfContainedObjectHandles = 0 for simple, just after this filed to fill string + // + OptionalStrStart -= 2; + UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart); + UnicodeStrToAsciiStr(Product, OptionalStrStart + ManuStrLen + 1); + UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1); + UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1); + UnicodeStrToAsciiStr(AssertTag, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1); + UnicodeStrToAsciiStr(Chassis, OptionalStrStart + ManuStrLen + 1 + ProductStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1); + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + + FreePool(SmbiosRecord); + return Status; +} diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendor.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendor.uni new file mode 100644 index 0000000000000000000000000000000000000000..dda02d29706e0d55aed3535fd5aa08610166ffed GIT binary patch literal 1588 zcmb7^OK%fF5QO`T#D7@X7ap+<95^6Avf~9-32|gQ0Zx(MS;-Hyb^`wMz*jxqUE3$D z)y_=M^iQW zXC~YnU%SV<2#<_YdY>!958=bGfb&hy1$SY1;` z9s5k%w6E9+nntLqzRzqzrQI-!UFjRUqK}y`5y~tiRCbI<&yhQfRMBcH^uiTtg}&vs zth0h!WZzg9uZ~BQ-6WEjT``}4DvXXt?_!C&<`lD!mwXg8czwcGJAcq$up;KViSaH< zI7MvV3!D-?L5pkZN-^8qw_LZp*Zr>XLWFlA%zm({`^l=32UYUSZ-Q!8xvX(6#i)R) zHRWneekyzW@(K($G34M5Hqz?c?odu=>@m9abGLVTMBpBOC5s2x%)I{gd5B314lBP2 zx6X0wH5M3Ei~I0@Y`X9Y88~Jl`*b!L@x$AAIv-WWCBNz}My9lc-! OIO!c|`|X|Va`z9hYVJS) literal 0 HcmV?d00001 diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendorData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendorData.c new file mode 100644 index 0000000000..b9a8cede83 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendorData.c @@ -0,0 +1,88 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscBiosVendorData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_BIOS_VENDOR_DATA, MiscBiosVendor) = { + STRING_TOKEN(STR_MISC_BIOS_VENDOR), // BiosVendor + STRING_TOKEN(STR_MISC_BIOS_VERSION), // BiosVersion + STRING_TOKEN(STR_MISC_BIOS_RELEASE_DATE), // BiosReleaseDate + 0xBABE, // BiosStartingAddress + { // BiosPhysicalDeviceSize + 2, // Value + 3, // Exponent + }, + { // BiosCharacteristics1 + 0, // Reserved1 :2 + 0, // Unknown :1 + 1, // BiosCharacteristicsNotSupported :1 + 0, // IsaIsSupported :1 + 0, // McaIsSupported :1 + 0, // EisaIsSupported :1 + 0, // PciIsSupported :1 + 0, // PcmciaIsSupported :1 + 0, // PlugAndPlayIsSupported :1 + 0, // ApmIsSupported :1 + 0, // BiosIsUpgradable :1 + 0, // BiosShadowingAllowed :1 + 0, // VlVesaIsSupported :1 + 0, // EscdSupportIsAvailable :1 + 0, // BootFromCdIsSupported :1 + 0, // SelectableBootIsSupported :1 + 0, // RomBiosIsSocketed :1 + 0, // BootFromPcmciaIsSupported :1 + 0, // EDDSpecificationIsSupported :1 + 0, // JapaneseNecFloppyIsSupported :1 + 0, // JapaneseToshibaFloppyIsSupported :1 + 0, // Floppy525_360IsSupported :1 + 0, // Floppy525_12IsSupported :1 + 0, // Floppy35_720IsSupported :1 + 0, // Floppy35_288IsSupported :1 + 0, // PrintScreenIsSupported :1 + 0, // Keyboard8042IsSupported :1 + 0, // SerialIsSupported :1 + 0, // PrinterIsSupported :1 + 0, // CgaMonoIsSupported :1 + 0, // NecPc98 :1 + 0, // AcpiIsSupported :1 + 0, // UsbLegacyIsSupported :1 + 0, // AgpIsSupported :1 + 0, // I20BootIsSupported :1 + 0, // Ls120BootIsSupported :1 + 0, // AtapiZipDriveBootIsSupported :1 + 0, // Boot1394IsSupported :1 + 0, // SmartBatteryIsSupported :1 + 0, // BiosBootSpecIsSupported :1 + 0, // FunctionKeyNetworkBootIsSupported :1 + 0 // Reserved :22 + }, + { // BiosCharacteristics2 + 0, // BiosReserved :16 + 0, // SystemReserved :16 + 0 // Reserved :32 + }, +}; + +/* eof - MiscBiosVendorData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendorFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendorFunction.c new file mode 100644 index 0000000000..6d64ef4632 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendorFunction.c @@ -0,0 +1,202 @@ +/** @file + BIOS vendor information boot time changes. + Misc. subclass type 2. + SMBIOS type 0. + + 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. + +**/ + +#include "MiscSubClassDriver.h" + +/** + This function returns the value & exponent to Base2 for a given + Hex value. This is used to calculate the BiosPhysicalDeviceSize. + + @param Value The hex value which is to be converted into value-exponent form + @param Exponent The exponent out of the conversion + + @retval EFI_SUCCESS All parameters were valid and *Value & *Exponent have been set. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +EFI_STATUS +GetValueExponentBase2( + IN OUT UINTN *Value, + OUT UINTN *Exponent + ) +{ + if ((Value == NULL) || (Exponent == NULL)) { + return EFI_INVALID_PARAMETER; + } + + while ((*Value % 2) == 0) { + *Value=*Value/2; + (*Exponent)++; + } + + return EFI_SUCCESS; +} + +/** + Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k' + as the unit. + + @param Base2Data Pointer to Base2_Data + + @retval EFI_SUCCESS Transform successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +UINT16 +Base2ToByteWith64KUnit ( + IN EFI_EXP_BASE2_DATA *Base2Data + ) +{ + UINT16 Value; + UINT16 Exponent; + + Value = Base2Data->Value; + Exponent = Base2Data->Exponent; + Exponent -= 16; + Value <<= Exponent; + + return Value; +} + + +/** + This function makes boot time changes to the contents of the + MiscBiosVendor (Type 0). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(MiscBiosVendor) +{ + CHAR8 *OptionalStrStart; + UINTN VendorStrLen; + UINTN VerStrLen; + UINTN DateStrLen; + CHAR16 *Version; + CHAR16 *ReleaseDate; + EFI_STATUS Status; + EFI_STRING Char16String; + STRING_REF TokenToGet; + STRING_REF TokenToUpdate; + SMBIOS_TABLE_TYPE0 *SmbiosRecord; + EFI_SMBIOS_HANDLE SmbiosHandle; + EFI_MISC_BIOS_VENDOR *ForType0InputData; + + ForType0InputData = (EFI_MISC_BIOS_VENDOR *)RecordData; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + Version = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString); + if (StrLen (Version) > 0) { + TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_VERSION); + HiiSetString (mHiiHandle, TokenToUpdate, Version, NULL); + } + + ReleaseDate = (CHAR16 *) PcdGetPtr (PcdFirmwareReleaseDateString); + if (StrLen(ReleaseDate) > 0) { + TokenToUpdate = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE); + HiiSetString (mHiiHandle, TokenToUpdate, ReleaseDate, NULL); + } + + TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VENDOR); + Char16String = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + VendorStrLen = StrLen(Char16String); + if (VendorStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_BIOS_VERSION); + Version = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + VerStrLen = StrLen(Version); + if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_BIOS_RELEASE_DATE); + ReleaseDate = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + DateStrLen = StrLen(ReleaseDate); + if (DateStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE0) + VendorStrLen + 1 + VerStrLen + 1 + DateStrLen + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + // + // Vendor will be the 1st optional string following the formatted structure. + // + SmbiosRecord->Vendor = 1; + // + // Version will be the 2nd optional string following the formatted structure. + // + SmbiosRecord->BiosVersion = 2; + SmbiosRecord->BiosSegment = (UINT16)ForType0InputData->BiosStartingAddress; + // + // ReleaseDate will be the 3rd optional string following the formatted structure. + // + SmbiosRecord->BiosReleaseDate = 3; + // + // Nt32 has no PCD value to indicate BIOS Size, just fill 0 for simply. + // + SmbiosRecord->BiosSize = 0; + SmbiosRecord->BiosCharacteristics = *(MISC_BIOS_CHARACTERISTICS*)(&ForType0InputData->BiosCharacteristics1); + // + // CharacterExtensionBytes also store in ForType0InputData->BiosCharacteristics1 later two bytes to save size. + // + SmbiosRecord->BIOSCharacteristicsExtensionBytes[0] = *((UINT8 *) &ForType0InputData->BiosCharacteristics1 + 4); + SmbiosRecord->BIOSCharacteristicsExtensionBytes[1] = *((UINT8 *) &ForType0InputData->BiosCharacteristics1 + 5); + + SmbiosRecord->SystemBiosMajorRelease = ForType0InputData->BiosMajorRelease; + SmbiosRecord->SystemBiosMinorRelease = ForType0InputData->BiosMinorRelease; + SmbiosRecord->EmbeddedControllerFirmwareMajorRelease = ForType0InputData->BiosEmbeddedFirmwareMajorRelease; + SmbiosRecord->EmbeddedControllerFirmwareMinorRelease = ForType0InputData->BiosEmbeddedFirmwareMinorRelease; + + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + UnicodeStrToAsciiStr(Char16String, OptionalStrStart); + UnicodeStrToAsciiStr(Version, OptionalStrStart + VendorStrLen + 1); + UnicodeStrToAsciiStr(ReleaseDate, OptionalStrStart + VendorStrLen + 1 + VerStrLen + 1); + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + + FreePool(SmbiosRecord); + return Status; +} diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBootInformationData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBootInformationData.c new file mode 100644 index 0000000000..0b7c57a8a7 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBootInformationData.c @@ -0,0 +1,33 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscBootInformationData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_BOOT_INFORMATION_STATUS_DATA, BootInformationStatus) = { + EfiBootInformationStatusNoError, // BootInformationStatus + {0} // BootInformationData +}; + +/* eof - MiscBootInformationData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBootInformationFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBootInformationFunction.c new file mode 100644 index 0000000000..65c9792a93 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBootInformationFunction.c @@ -0,0 +1,73 @@ +/** @file + boot information boot time changes. + SMBIOS type 32. + + 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. + +**/ + +#include "MiscSubClassDriver.h" + + +/** + This function makes boot time changes to the contents of the + MiscBootInformation (Type 32). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ + +MISC_SMBIOS_TABLE_FUNCTION(BootInformationStatus) +{ + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE32 *SmbiosRecord; + EFI_MISC_BOOT_INFORMATION_STATUS* ForType32InputData; + + ForType32InputData = (EFI_MISC_BOOT_INFORMATION_STATUS *)RecordData; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE32) + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE32); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + SmbiosRecord->BootStatus = (UINT8)ForType32InputData->BootInformationStatus; + + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + FreePool(SmbiosRecord); + return Status; +} diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturer.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturer.uni new file mode 100644 index 0000000000000000000000000000000000000000..177ff38925bbd52c094b8bbb07e3c165febbbae8 GIT binary patch literal 1774 zcmbW1OK%!M5QO_2DgR*wmplw4Iph!}kpQo42DsX7{$n_mz$8HRA_+$Mca{ zX=lC1K4adnC7u(TGZ#V%hQ0$<6J|>*vr}bX9y#{Pt%g_5u?z?_XdNOpxDXcoqD*P=Y@HYHIb>C0dEz~%sqJ8h}%e`u+)wSw1o=`pA JTy;ax?ms4!4`2WQ literal 0 HcmV?d00001 diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturerData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturerData.c new file mode 100644 index 0000000000..795658bac6 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturerData.c @@ -0,0 +1,45 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscChassisManufacturerData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Chassis Manufacturer data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_CHASSIS_MANUFACTURER_DATA, MiscChassisManufacturer) = { + STRING_TOKEN(STR_MISC_CHASSIS_MANUFACTURER), // ChassisManufactrurer + STRING_TOKEN(STR_MISC_CHASSIS_VERSION), // ChassisVersion + STRING_TOKEN(STR_MISC_CHASSIS_SERIAL_NUMBER), // ChassisSerialNumber + STRING_TOKEN(STR_MISC_CHASSIS_ASSET_TAG), // ChassisAssetTag + { // ChassisTypeStatus + EfiMiscChassisTypeOther, // ChassisType + 0, // ChassisLockPresent + 0 // Reserved + }, + EfiChassisStateOther, // ChassisBootupState + EfiChassisStateOther, // ChassisPowerSupplyState + EfiChassisStateOther, // ChassisThermalState + EfiChassisSecurityStatusOther, // ChassisSecurityState + 0 // ChassisOemDefined +}; + +/* eof - MiscChassisManufacaturerData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturerFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturerFunction.c new file mode 100644 index 0000000000..fd1262b190 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturerFunction.c @@ -0,0 +1,137 @@ +/** @file + Chassis manufacturer information boot time changes. + SMBIOS type 3. + + 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. + +**/ + +#include "MiscSubClassDriver.h" + +/** + This function makes boot time changes to the contents of the + MiscChassisManufacturer (Type 3). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(MiscChassisManufacturer) +{ + CHAR8 *OptionalStrStart; + UINTN ManuStrLen; + UINTN VerStrLen; + UINTN AssertTagStrLen; + UINTN SerialNumStrLen; + EFI_STATUS Status; + EFI_STRING Manufacturer; + EFI_STRING Version; + EFI_STRING SerialNumber; + EFI_STRING AssertTag; + STRING_REF TokenToGet; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE3 *SmbiosRecord; + EFI_MISC_CHASSIS_MANUFACTURER *ForType3InputData; + + ForType3InputData = (EFI_MISC_CHASSIS_MANUFACTURER *)RecordData; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_MANUFACTURER); + Manufacturer = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + ManuStrLen = StrLen(Manufacturer); + if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_VERSION); + Version = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + VerStrLen = StrLen(Version); + if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_SERIAL_NUMBER); + SerialNumber = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + SerialNumStrLen = StrLen(SerialNumber); + if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_CHASSIS_ASSET_TAG); + AssertTag = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + AssertTagStrLen = StrLen(AssertTag); + if (AssertTagStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE3) + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + AssertTagStrLen + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE3); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + // + // Manu will be the 1st optional string following the formatted structure. + // + SmbiosRecord->Manufacturer = 1; + SmbiosRecord->Type = (UINT8)ForType3InputData->ChassisType.ChassisType; + // + // Version will be the 2nd optional string following the formatted structure. + // + SmbiosRecord->Version = 2; + // + // SerialNumber will be the 3rd optional string following the formatted structure. + // + SmbiosRecord->SerialNumber = 3; + // + // AssertTag will be the 4th optional string following the formatted structure. + // + SmbiosRecord->AssetTag = 4; + SmbiosRecord->BootupState = (UINT8)ForType3InputData->ChassisBootupState; + SmbiosRecord->PowerSupplyState = (UINT8)ForType3InputData->ChassisPowerSupplyState; + SmbiosRecord->ThermalState = (UINT8)ForType3InputData->ChassisThermalState; + SmbiosRecord->SecurityStatus = (UINT8)ForType3InputData->ChassisSecurityState; + CopyMem (SmbiosRecord->OemDefined,(UINT8*)&ForType3InputData->ChassisOemDefined, 4); + + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart); + UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1); + UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1); + UnicodeStrToAsciiStr(AssertTag, OptionalStrStart + ManuStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1); + + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + + FreePool(SmbiosRecord); + return Status; +} diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscDevicePath.h b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscDevicePath.h new file mode 100644 index 0000000000..b1a9acfafd --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscDevicePath.h @@ -0,0 +1,175 @@ +/*++ + +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: + + MiscDevicePath.h + +Abstract: + + Misc class required EFI Device Path definitions (Ports, slots & + onboard devices) + +**/ + +#ifndef _MISC_DEVICE_PATH_H +#define _MISC_DEVICE_PATH_H + + +#pragma pack(1) +// +// USB +// + +/* For reference: +#define USB1_1_STR "ACPI(PNP0A03,0)/PCI(1D,0)." +#define USB1_2_STR "ACPI(PNP0A03,0)/PCI(1D,1)." +#define USB1_3_STR "ACPI(PNP0A03,0)/PCI(1D,2)." +#define USB2_1_STR "ACPI(PNP0A03,0)/PCI(1D,7)." +*/ + +// +// #define acpi { 0x02, 0x01, 0x00, 0x0C, 0x0a0341d0, 0x00000000 } +// #define pci( device,function) { 0x01, 0x01, 0x00, 0x06, device, function } +// #define end { 0xFF, 0xFF, 0x00, 0x04 } +// +#define DP_ACPI \ + { \ + {ACPI_DEVICE_PATH, ACPI_DP, {(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \ + ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)}}, EISA_PNP_ID (0x0A03), 0 \ + } +#define DP_PCI(device, function) \ + { \ + {HARDWARE_DEVICE_PATH, HW_PCI_DP, {(UINT8) (sizeof (PCI_DEVICE_PATH)), (UINT8) \ + ((sizeof (PCI_DEVICE_PATH)) >> 8)}}, function, device \ + } +#define DP_END \ + { \ + END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, {END_DEVICE_PATH_LENGTH, 0} \ + } + +#define DP_LPC(eisaid, function) \ + { \ + {ACPI_DEVICE_PATH, ACPI_DP, {(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), (UINT8) \ + ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)}}, EISA_PNP_ID (eisaid), function \ + } + +// +// Shanmu >> moved to TianoDevicePath.h +// + +/* +typedef struct _USB_PORT_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; + PCI_DEVICE_PATH PciBusDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} USB_PORT_DEVICE_PATH; + + +//IDE ??I am not sure. Should this be ATAPI_DEVICE_PATH +typedef struct _IDE_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; + PCI_DEVICE_PATH PciBusDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} IDE_DEVICE_PATH; + +//RMC Connector +typedef struct _RMC_CONN_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; + PCI_DEVICE_PATH PciBridgeDevicePath; + PCI_DEVICE_PATH PciBusDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} RMC_CONN_DEVICE_PATH; + +//static RMC_CONN_DEVICE_PATH mRmcConnDevicePath = { acpi, pci( 0x1E,0x00 ),pci( 0x0A,0x00 ), end }; + +//RIDE +typedef struct _RIDE_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; + PCI_DEVICE_PATH PciBridgeDevicePath; + PCI_DEVICE_PATH PciBusDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} RIDE_DEVICE_PATH; + +//static RIDE_DEVICE_PATH mRideDevicePath = { acpi, pci( 0x1E,0x00 ),pci( 0x02,0x00 ), end }; + +//Gigabit NIC +//typedef struct _GB_NIC_DEVICE_PATH +//{ +// ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; +// PCI_DEVICE_PATH PciBridgeDevicePath; +// PCI_DEVICE_PATH PciXBridgeDevicePath; +// PCI_DEVICE_PATH PciXBusDevicePath; +// EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +//} GB_NIC_DEVICE_PATH; + +//static GB_NIC_DEVICE_PATH mGbNicDevicePath = { acpi, pci( 0x03,0x00 ),pci( 0x1F,0x00 ),pci( 0x07,0x00 ), end }; + + +//P/S2 Connector +typedef struct _PS2_CONN_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; + PCI_DEVICE_PATH LpcBridgeDevicePath; + ACPI_HID_DEVICE_PATH LpcBusDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} PS2_CONN_DEVICE_PATH; + +//static PS2_CONN_DEVICE_PATH mPs2KeyboardDevicePath = { acpi, pci( 0x1F,0x00 ),lpc( 0x0303,0 ), end }; +//static PS2_CONN_DEVICE_PATH mPs2MouseDevicePath = { acpi, pci( 0x1F,0x00 ),lpc( 0x0303,1 ), end }; + +//Serial Port Connector +typedef struct _SERIAL_CONN_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; + PCI_DEVICE_PATH LpcBridgeDevicePath; + ACPI_HID_DEVICE_PATH LpcBusDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} SERIAL_CONN_DEVICE_PATH; + +//static SERIAL_CONN_DEVICE_PATH mCom1DevicePath = { acpi, pci( 0x1F,0x00 ),lpc( 0x0501,0 ), end }; +//static SERIAL_CONN_DEVICE_PATH mCom2DevicePath = { acpi, pci( 0x1F,0x00 ),lpc( 0x0501,1 ), end }; + +//Parallel Port Connector +typedef struct _PARALLEL_CONN_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; + PCI_DEVICE_PATH LpcBridgeDevicePath; + ACPI_HID_DEVICE_PATH LpcBusDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} PARALLEL_CONN_DEVICE_PATH; + +//static PARALLEL_CONN_DEVICE_PATH mLpt1DevicePath = { acpi, pci( 0x1F,0x00 ),lpc( 0x0401,0 ), end }; + +//Floopy Connector +typedef struct _FLOOPY_CONN_DEVICE_PATH +{ + ACPI_HID_DEVICE_PATH PciRootBridgeDevicePath; + PCI_DEVICE_PATH LpcBridgeDevicePath; + ACPI_HID_DEVICE_PATH LpcBusDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} FLOOPY_CONN_DEVICE_PATH; + +//static FLOOPY_CONN_DEVICE_PATH mFloopyADevicePath = { acpi, pci( 0x1F,0x00 ),lpc( 0x0604,0 ), end }; +//static FLOOPY_CONN_DEVICE_PATH mFloopyBDevicePath = { acpi, pci( 0x1F,0x00 ),lpc( 0x0604,1 ), end }; + +*/ + +// +// End Shanmu +// +#pragma pack() + +#endif diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscNumberOfInstallableLanguagesData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscNumberOfInstallableLanguagesData.c new file mode 100644 index 0000000000..88d9d0fb4b --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscNumberOfInstallableLanguagesData.c @@ -0,0 +1,38 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscNumberOfInstallableLanguagesData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA, NumberOfInstallableLanguages) += { + 1, // NumberOfInstallableLanguages + { // LanguageFlags + 0, // AbbreviatedLanguageFormat + 0 // Reserved + }, + 0, // CurrentLanguageNumber +}; + +/* eof - MiscNumberOfInstallableLanguagesData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscNumberOfInstallableLanguagesFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscNumberOfInstallableLanguagesFunction.c new file mode 100644 index 0000000000..9bd7f4da6a --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscNumberOfInstallableLanguagesFunction.c @@ -0,0 +1,238 @@ +/** @file + This driver parses the mSmbiosMiscDataTable structure and reports + any generated data. + + 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. + +**/ + +#include "MiscSubClassDriver.h" +/*++ + Check whether the language is supported for given HII handle + + @param HiiHandle The HII package list handle. + @param Offset The offest of current lanague in the supported languages. + @param CurrentLang The language code. + + @retval TRUE Supported. + @retval FALSE Not Supported. + +**/ +VOID +EFIAPI +CurrentLanguageMatch ( + IN EFI_HII_HANDLE HiiHandle, + OUT UINT16 *Offset, + OUT CHAR8 *CurrentLang + ) +{ + CHAR8 *DefaultLang; + CHAR8 *BestLanguage; + CHAR8 *Languages; + CHAR8 *MatchLang; + CHAR8 *EndMatchLang; + UINTN CompareLength; + + Languages = HiiGetSupportedLanguages (HiiHandle); + if (Languages == NULL) { + return; + } + + CurrentLang = GetEfiGlobalVariable (L"PlatformLang"); + DefaultLang = (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang); + BestLanguage = GetBestLanguage ( + Languages, + FALSE, + (CurrentLang != NULL) ? CurrentLang : "", + DefaultLang, + NULL + ); + if (BestLanguage != NULL) { + // + // Find the best matching RFC 4646 language, compute the offset. + // + CompareLength = AsciiStrLen (BestLanguage); + for (MatchLang = Languages, (*Offset) = 0; MatchLang != '\0'; (*Offset)++) { + // + // Seek to the end of current match language. + // + for (EndMatchLang = MatchLang; *EndMatchLang != '\0' && *EndMatchLang != ';'; EndMatchLang++); + + if ((EndMatchLang == MatchLang + CompareLength) && AsciiStrnCmp(MatchLang, BestLanguage, CompareLength) == 0) { + // + // Find the current best Language in the supported languages + // + break; + } + // + // best language match be in the supported language. + // + ASSERT (*EndMatchLang == ';'); + MatchLang = EndMatchLang + 1; + } + FreePool (BestLanguage); + } + + FreePool (Languages); + if (CurrentLang != NULL) { + FreePool (CurrentLang); + } + return ; +} + + +/** + Get next language from language code list (with separator ';'). + + @param LangCode Input: point to first language in the list. On + Otput: point to next language in the list, or + NULL if no more language in the list. + @param Lang The first language in the list. + +**/ +VOID +EFIAPI +GetNextLanguage ( + IN OUT CHAR8 **LangCode, + OUT CHAR8 *Lang + ) +{ + UINTN Index; + CHAR8 *StringPtr; + + ASSERT (LangCode != NULL); + ASSERT (*LangCode != NULL); + ASSERT (Lang != NULL); + + Index = 0; + StringPtr = *LangCode; + while (StringPtr[Index] != 0 && StringPtr[Index] != ';') { + Index++; + } + + CopyMem (Lang, StringPtr, Index); + Lang[Index] = 0; + + if (StringPtr[Index] == ';') { + Index++; + } + *LangCode = StringPtr + Index; +} + +/** + This function returns the number of supported languages on HiiHandle. + + @param HiiHandle The HII package list handle. + + @retval The number of supported languages. + +**/ +UINT16 +EFIAPI +GetSupportedLanguageNumber ( + IN EFI_HII_HANDLE HiiHandle + ) +{ + CHAR8 *Lang; + CHAR8 *Languages; + CHAR8 *LanguageString; + UINT16 LangNumber; + + Languages = HiiGetSupportedLanguages (HiiHandle); + if (Languages == NULL) { + return 0; + } + + LangNumber = 0; + Lang = AllocatePool (AsciiStrSize (Languages)); + if (Lang != NULL) { + LanguageString = Languages; + while (*LanguageString != 0) { + GetNextLanguage (&LanguageString, Lang); + LangNumber++; + } + FreePool (Lang); + } + FreePool (Languages); + return LangNumber; +} + + +/** + This function makes boot time changes to the contents of the + MiscNumberOfInstallableLanguages (Type 13). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(NumberOfInstallableLanguages) +{ + UINTN LangStrLen; + CHAR8 CurrentLang[SMBIOS_STRING_MAX_LENGTH + 1]; + CHAR8 *OptionalStrStart; + UINT16 Offset; + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE13 *SmbiosRecord; + EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *ForType13InputData; + + ForType13InputData = (EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES *)RecordData; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + ForType13InputData->NumberOfInstallableLanguages = GetSupportedLanguageNumber (mHiiHandle); + + // + // Try to check if current langcode matches with the langcodes in installed languages + // + ZeroMem(CurrentLang, SMBIOS_STRING_MAX_LENGTH + 1); + CurrentLanguageMatch (mHiiHandle, &Offset, CurrentLang); + LangStrLen = AsciiStrLen(CurrentLang); + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + LangStrLen + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + + SmbiosRecord->InstallableLanguages = (UINT8)ForType13InputData->NumberOfInstallableLanguages; + SmbiosRecord->Flags = (UINT8)ForType13InputData->LanguageFlags.AbbreviatedLanguageFormat; + SmbiosRecord->CurrentLanguages = 1; + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + AsciiStrCpy(OptionalStrStart, CurrentLang); + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + FreePool(SmbiosRecord); + return Status; +} diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemString.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemString.uni new file mode 100644 index 0000000000000000000000000000000000000000..782a83bf89b3f4cca08f715732e837981fdc8ab4 GIT binary patch literal 1312 zcmZ{kTaOY!5QWdPiT`23zIa(ceel7k3G9wKQDL*NQJ)C+orH@S*j4_#`kiiuflbVW zuCDItQ>RZ=^Y>3vO(lA!=X{U#2(Njti7vF(PwiAF*Ic*S68l7BJ;lD#3%=LP>U-}c z{yFnZD_FgHR0hQ}eRIkS}-?6lZ-M1{Qx-c%dT7P@Dg5cyVZUF-dURmn0@A4WOR z3HSxL^N?eSKP1NlyCq^8{4uQ8S`z8K9p_fWC#;y2^X1GIpjG%oR(*QG-k8}cFf(q6 z@6(fghI{5Yu|tg*eeN!>Fm}Zx=2`~UC5oAuZ+_6ncUo(9bgr$QF7dydaH+Wd3R;XA z&F=KJIc$t*HKJb5wZZqTNANtZOVri;XY9lpne}g?9rUEIi#MU)++$H)#}`5C24@Q@)O?`+hLsWACv@Fu_68`o{7Owq>-&6C3acynsH=~R zEq%q$&@@3++diuqop!@44NBjrgH2hl5UMI#&}IYK(5kevN1DUUSYqQI2ue81;czpZtOS%#NA+C8ql<@fNAR zA8;!43@xtcE9boAy_LF^*6+K{KScarh^y~(7UJxkQ3rSOJiG+=tZP~4Ud~Yi)qAeh zhWgZw&XpY)Ut+Am05;a@LIduX;tlX(bvo28`OjCexP#3+^xrWLGwJc}opZ{o_e+Yb OtN0#!ei7yqdHw^qjm8-O literal 0 HcmV?d00001 diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemStringData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemStringData.c new file mode 100644 index 0000000000..1d0781586f --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemStringData.c @@ -0,0 +1,32 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscOemStringData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_OEM_STRING_DATA, OemString) = { + { STRING_TOKEN(STR_MISC_OEM_STRING) } +}; + +/* eof - MiscOemStringData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemStringFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemStringFunction.c new file mode 100644 index 0000000000..94fc71c231 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemStringFunction.c @@ -0,0 +1,80 @@ +/** @file + boot information boot time changes. + SMBIOS type 11. + + 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. + +**/ + +#include "MiscSubClassDriver.h" +/** + This function makes boot time changes to the contents of the + MiscOemString (Type 11). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(OemString) +{ + UINTN OemStrLen; + CHAR8 *OptionalStrStart; + EFI_STATUS Status; + EFI_STRING OemStr; + STRING_REF TokenToGet; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE11 *SmbiosRecord; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + TokenToGet = STRING_TOKEN (STR_MISC_OEM_STRING); + OemStr = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + OemStrLen = StrLen(OemStr); + if (OemStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE11) + OemStrLen + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_OEM_STRINGS; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE11); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + SmbiosRecord->StringCount = 1; + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + UnicodeStrToAsciiStr(OemStr, OptionalStrStart); + + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + FreePool(SmbiosRecord); + return Status; +} diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignator.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignator.uni new file mode 100644 index 0000000000000000000000000000000000000000..87c5a8112b1a6aff05eed036ef9051522f64d6d6 GIT binary patch literal 8914 zcmc(l?Qh#Q5XSHGfc+0b@@3tcWOmb_9kv0EYp2ee4aY&-PeI;mAh8SCX_tR~?e8HY zONm!RqL~gxL{U24J$!gP9;tl&cg@x;v0v>sem~n!)YfKYVoe*{C%d)OhIVNmZHnwK zc52Tk>-Iap4enO%YBlQ5x$oEr$#c8nUK&z#=z7f4A$KENV-!oJh%ESgB8X}#bKSl4QvvE!R7#nAlQzXt^{S?$=yGBy)ZfQ3{KH-T_ z$=;B=E41bMk9n%rSG+srZsd?jZ>C?Z&+aUI=6;Cmv7K;LyBmi>x^pDn*0n>OX%RBv z9nSbspT>4kXt!wx_J;cIJuEraFOG{-u0nUew?oiKquB6#$<~CrdVK=U;<$KTh5v## zevE|rAEX|ly3dSf^A@QS*Z&Lp;5iVcX@OaJ(v-3I!}*(h%(E-`)N#E^+msPnd%*sL zCnsP(!|U!_Uq#DD{xVLoQvG>rEl~CFqpodnZP*_54xA>is&c^74xV<%UCS|jX#12c zp643!QRv{=EhG+{<}P>gXkC{mrB_;)C^ubQwdXTziM`{!aCMzU)f-q6vVER+&?+5W zXT48N*!4^{2S`aqR=rdkS+)E?xx*VF*Gz2PS@FGS+54HETzdyDdia%WzG1#)yk({4 z_X-ih#|8iNFI#qUsx31P^5jc56XdfR%N6=18%t=_JB`(Z@mVUg%RJD}L_Y>cpb=M1 zI|7yZKj2P1(zx^~8(=-+y?VdTvnFpOcjQLv0NE`k<)0=6d^g~{be>s6D2zSlZSwCd zcBPSH<2#U3ok+ZAK<%V)&*JuW5_A@=uR;06yqkHUav z;~wMc`(KuUdNf}MvG3a?LEbp;1G~hKL1hNkVW1u`0`u`C#J+D6i-8Q2)+E0+`3U~b z#qF{_@sfBRCqBf$lSNZyem-+m7BRLj%o}BOZz+8Sm{Q+geVIr8_teUHCz)qYsCdB?jc6wwVLw9zSI)1#)7*WP+s=5M;ojAS|V*epK2Sl0dOijBy zc~Crt4%}`}CoDb^%ah8*omVcmt3FCuCYzsrgkqRyDnFsqI`zrLpt$qxAy)ZTIleZY zjIXj7{tv#|WPdu_(z#cUY({JTZfVY5bNUr$CN6@b&8!>aPdZWSu|v|jud}q`ekrb( zHL-IDV{OM+Sr4ltABU|F`@W6VIx%#go$66yem7Yh!D_s`W~5#Om%bDDFA3%1 zx4bA$&a@~NeT5wHJxgCP^@S<_5}DAm8~0sMCps~FssU5_rqm6J->;(WUl+kq+@Ta_ z;`d^C4Bq@XO4yngD~g9=@a+_t9$)ujaHa2m@11{jIWMX*C+pEN^-v7H-P4|<`m_Cf z7gP4TjF(#?Cd4~YT@;INum87*;W^$@U$Al%e~-uWoS7QYElzH*C>Gz|v!XB2`uhg5 C{Xs+k literal 0 HcmV?d00001 diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignatorData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignatorData.c new file mode 100644 index 0000000000..7d511e1912 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignatorData.c @@ -0,0 +1,99 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscPortInternalConnectorDesignatorData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortInternalConnectorDesignator) = { + STRING_TOKEN(STR_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR), // PortInternalConnectorDesignator + STRING_TOKEN(STR_MISC_PORT_EXTERNAL_CONNECTOR_DESIGNATOR), // PortExternalConnectorDesignator + EfiPortConnectorTypeOther, // PortInternalConnectorType + EfiPortConnectorTypeOther, // PortExternalConnectorType + EfiPortTypeNone, // PortType + {{{{0, 0, {0, 0}}, 0, 0}, {{0, 0, {0, 0}}, 0, 0}, {0, 0, {0, 0}}}} // PortPath +}; + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortKeyboard) = { + STRING_TOKEN (STR_MISC_PORT_INTERNAL_KEYBOARD), // PortInternalConnectorDesignator + STRING_TOKEN (STR_MISC_PORT_EXTERNAL_KEYBOARD), // PortExternalConnectorDesignator + EfiPortConnectorTypeNone, // PortInternalConnectorType + EfiPortConnectorTypePS2, // PortExternalConnectorType + EfiPortTypeKeyboard, // PortType + // mPs2KbyboardDevicePath // PortPath + // + {{{{0, 0, {0, 0}}, 0, 0}, {{0, 0, {0, 0}}, 0, 0}, {0, 0, {0, 0}}}} // PortPath +}; + +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortMouse) = { + STRING_TOKEN (STR_MISC_PORT_INTERNAL_MOUSE), // PortInternalConnectorDesignator + STRING_TOKEN (STR_MISC_PORT_EXTERNAL_MOUSE), // PortExternalConnectorDesignator + EfiPortConnectorTypeNone, // PortInternalConnectorType + EfiPortConnectorTypePS2, // PortExternalConnectorType + EfiPortTypeMouse, // PortType + // mPs2MouseDevicePath // PortPath + // + {{{{0, 0, {0, 0}}, 0, 0}, {{0, 0, {0, 0}}, 0, 0}, {0, 0, {0, 0}}}} // PortPath +}; + + +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortCom1) = { + STRING_TOKEN(STR_MISC_PORT_INTERNAL_COM1), + STRING_TOKEN(STR_MISC_PORT_EXTERNAL_COM1), + EfiPortConnectorTypeNone, + EfiPortConnectorTypeDB9Female, + EfiPortTypeSerial16550ACompatible, + {{{{0, 0, {0, 0}}, 0, 0}, {{0, 0, {0, 0}}, 0, 0}, {0, 0, {0, 0}}}} // PortPath +}; + +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortCom2) = { + STRING_TOKEN(STR_MISC_PORT_INTERNAL_COM2), + STRING_TOKEN(STR_MISC_PORT_EXTERNAL_COM2), + EfiPortConnectorTypeNone, + EfiPortConnectorTypeDB9Female, + EfiPortTypeSerial16550ACompatible, + {{{{0, 0, {0, 0}}, 0, 0}, {{0, 0, {0, 0}}, 0, 0}, {0, 0, {0, 0}}}} // PortPath +}; + +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortExtensionPower) = { + STRING_TOKEN(STR_MISC_PORT_INTERNAL_EXTENSION_POWER), + STRING_TOKEN(STR_MISC_PORT_EXTERNAL_EXTENSION_POWER), + EfiPortConnectorTypeOther, + EfiPortConnectorTypeNone, + EfiPortTypeOther, + {{{{0, 0, {0, 0}}, 0, 0}, {{0, 0, {0, 0}}, 0, 0}, {0, 0, {0, 0}}}} // PortPath +}; + +MISC_SMBIOS_TABLE_DATA(EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortFloppy) = { + STRING_TOKEN(STR_MISC_PORT_INTERNAL_FLOPPY), + STRING_TOKEN(STR_MISC_PORT_EXTERNAL_FLOPPY), + EfiPortConnectorTypeOnboardFloppy, + EfiPortConnectorTypeNone, + EfiPortTypeOther, + {{{{0, 0, {0, 0}}, 0, 0}, {{0, 0, {0, 0}}, 0, 0}, {0, 0, {0, 0}}}} // PortPath +}; + +/* eof - MiscPortInternalConnectorDesignatorData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignatorFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignatorFunction.c new file mode 100644 index 0000000000..89c8815913 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignatorFunction.c @@ -0,0 +1,177 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscPortInternalConnectorDesignatorFunction.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + + +MISC_SMBIOS_TABLE_FUNCTION ( + MiscPortInternalConnectorDesignator + ) +/*++ +Description: + + This function makes boot time changes to the contents of the + MiscPortConnectorInformation (Type 8). + +Parameters: + + RecordType + Type of record to be processed from the Data Table. + mMiscSubclassDataTable[].RecordType + + RecordLen + Size of static RecordData from the Data Table. + mMiscSubclassDataTable[].RecordLen + + RecordData + Pointer to copy of RecordData from the Data Table. Changes made + to this copy will be written to the Data Hub but will not alter + the contents of the static Data Table. + + LogRecordData + Set *LogRecordData to TRUE to log RecordData to Data Hub. + Set *LogRecordData to FALSE when there is no more data to log. + +Returns: + + EFI_SUCCESS + All parameters were valid and *RecordData and *LogRecordData have + been set. + + EFI_UNSUPPORTED + Unexpected RecordType value. + + EFI_INVALID_PARAMETER + One of the following parameter conditions was true: + RecordLen was zero. + RecordData was NULL. + LogRecordData was NULL. +**/ +{ + CHAR8 *OptionalStrStart; + UINTN InternalRefStrLen; + UINTN ExternalRefStrLen; + EFI_STRING InternalRef; + EFI_STRING ExternalRef; + STRING_REF TokenForInternal; + STRING_REF TokenForExternal; + EFI_STATUS Status; + SMBIOS_TABLE_TYPE8 *SmbiosRecord; + EFI_SMBIOS_HANDLE SmbiosHandle; + EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR *ForType8InputData; + + ForType8InputData = (EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR *)RecordData; + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + TokenForInternal = 0; + TokenForExternal = 0; + + switch (ForType8InputData->PortInternalConnectorDesignator) { + + case STR_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR: + TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR); + TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_CONNECTOR_DESIGNATOR); + break; + case STR_MISC_PORT_INTERNAL_KEYBOARD: + TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_KEYBOARD); + TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_KEYBOARD); + break; + case STR_MISC_PORT_INTERNAL_MOUSE: + TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_MOUSE); + TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_MOUSE); + break; + case STR_MISC_PORT_INTERNAL_COM1: + TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_COM1); + TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_COM1); + break; + case STR_MISC_PORT_INTERNAL_COM2: + TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_COM2); + TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_COM2); + break; + case STR_MISC_PORT_INTERNAL_EXTENSION_POWER: + TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_EXTENSION_POWER); + TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_EXTENSION_POWER); + break; + case STR_MISC_PORT_INTERNAL_FLOPPY: + TokenForInternal = STRING_TOKEN (STR_MISC_PORT_INTERNAL_FLOPPY); + TokenForExternal = STRING_TOKEN(STR_MISC_PORT_EXTERNAL_FLOPPY); + break; + default: + break; + } + + InternalRef = HiiGetPackageString(&gEfiCallerIdGuid, TokenForInternal, NULL); + InternalRefStrLen = StrLen(InternalRef); + if (InternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + ExternalRef = HiiGetPackageString(&gEfiCallerIdGuid, TokenForExternal, NULL); + ExternalRefStrLen = StrLen(ExternalRef); + if (ExternalRefStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE8) + InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE8) + InternalRefStrLen + 1 + ExternalRefStrLen + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE8); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + SmbiosRecord->InternalReferenceDesignator = 1; + SmbiosRecord->InternalConnectorType = (UINT8)ForType8InputData->PortInternalConnectorType; + SmbiosRecord->ExternalReferenceDesignator = 2; + SmbiosRecord->ExternalConnectorType = (UINT8)ForType8InputData->PortExternalConnectorType; + SmbiosRecord->PortType = (UINT8)ForType8InputData->PortType; + + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + UnicodeStrToAsciiStr(InternalRef, OptionalStrStart); + UnicodeStrToAsciiStr(ExternalRef, OptionalStrStart + InternalRefStrLen + 1); + + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + FreePool(SmbiosRecord); + return Status; +} + + + +/* eof - MiscSystemManufacturerFunction.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscResetCapabilitiesData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscResetCapabilitiesData.c new file mode 100644 index 0000000000..f591a2e547 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscResetCapabilitiesData.c @@ -0,0 +1,42 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscResetCapabilitiesData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_RESET_CAPABILITIES, MiscResetCapabilities) = { + { // ResetCapabilities + 0, // Status + 0, // BootOption + 0, // BootOptionOnLimit + 0, // WatchdogTimerPresent + 0 // Reserved + }, + 0, // ResetCount + 0, // ResetLimit + 0, // ResetTimerInterval + 0 // ResetTimeout +}; + +/* eof - MiscResetCapabilities.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscResetCapabilitiesFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscResetCapabilitiesFunction.c new file mode 100644 index 0000000000..8303c5a29b --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscResetCapabilitiesFunction.c @@ -0,0 +1,76 @@ +/** @file + ResetCapabilities. + SMBIOS type 23. + + 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. + +**/ + +#include "MiscSubClassDriver.h" +/** + This function makes boot time changes to the contents of the + MiscOemString (Type 11). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(MiscResetCapabilities) +{ + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE23 *SmbiosRecord; + EFI_MISC_RESET_CAPABILITIES *ForType23InputData; + + ForType23InputData = (EFI_MISC_RESET_CAPABILITIES *)RecordData; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE23) + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE23) + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_RESET; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE23); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + SmbiosRecord->Capabilities = *(UINT8*)&(ForType23InputData->ResetCapabilities); + SmbiosRecord->ResetCount = (UINT16)ForType23InputData->ResetCount; + SmbiosRecord->ResetLimit = (UINT16)ForType23InputData->ResetLimit; + SmbiosRecord->TimerInterval = (UINT16)ForType23InputData->ResetTimerInterval; + SmbiosRecord->Timeout = (UINT16)ForType23InputData->ResetTimeout; + + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + FreePool(SmbiosRecord); + return Status; +} + diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.h b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.h new file mode 100644 index 0000000000..7e5be7ea80 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.h @@ -0,0 +1,122 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscSubclassDriver.h + +Abstract: + + Header file for MiscSubclass Driver. + +**/ + +#ifndef _MISC_SUBCLASS_DRIVER_H +#define _MISC_SUBCLASS_DRIVER_H + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +// +// Data table entry update function. +// +typedef EFI_STATUS (EFIAPI EFI_MISC_SMBIOS_DATA_FUNCTION) ( + IN VOID *RecordData, + IN EFI_SMBIOS_PROTOCOL *Smbios + ); + +// +// Data table entry definition. +// +typedef struct { + // + // intermediat input data for SMBIOS record + // + VOID *RecordData; + EFI_MISC_SMBIOS_DATA_FUNCTION *Function; +} EFI_MISC_SMBIOS_DATA_TABLE; + +// +// Data Table extern definitions. +// +#define MISC_SMBIOS_TABLE_EXTERNS(NAME1, NAME2, NAME3) \ +extern NAME1 NAME2 ## Data; \ +extern EFI_MISC_SMBIOS_DATA_FUNCTION NAME3 ## Function + + +// +// Data Table entries +// +#define MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NAME1, NAME2) \ +{ \ + & NAME1 ## Data, \ + & NAME2 ## Function \ +} + +// +// Global definition macros. +// +#define MISC_SMBIOS_TABLE_DATA(NAME1, NAME2) \ + NAME1 NAME2 ## Data + +#define MISC_SMBIOS_TABLE_FUNCTION(NAME2) \ + EFI_STATUS EFIAPI NAME2 ## Function( \ + IN VOID *RecordData, \ + IN EFI_SMBIOS_PROTOCOL *Smbios \ + ) + + +// +// Data Table Array +// +extern EFI_MISC_SMBIOS_DATA_TABLE mMiscSubclassDataTable[]; + +// +// Data Table Array Entries +// +extern UINTN mMiscSubclassDataTableEntries; +extern UINT8 MiscSubclassStrings[]; +extern EFI_HII_HANDLE mHiiHandle; + +// +// Prototypes +// +EFI_STATUS +EFIAPI +MiscSubclassDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + + +#endif /* _MISC_SUBCLASS_DRIVER_H */ + +/* eof - MiscSubclassDriver.h */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.inf b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.inf new file mode 100644 index 0000000000..aed93f5aea --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.inf @@ -0,0 +1,103 @@ +## @file +# Misc Sub class driver +# +# Parses the MiscSubclassDataTable and reports any generated data to the DataHub. +# All .uni file who tagged with "ToolCode="DUMMY"" in following file list is included by +# MiscSubclassDriver.uni file, the StrGather tool will expand MiscSubclassDriver.uni file +# and parse all .uni file. +# Copyright (c) 2006 - 2010, 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MiscSubclass + FILE_GUID = f2fbd108-8985-11db-b06a-0040d02b1835 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MiscSubclassDriverEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + MiscBaseBoardManufacturer.uni + MiscBaseBoardManufacturerData.c + MiscBaseBoardManufacturerFunction.c + MiscBiosVendor.uni + MiscBiosVendorData.c + MiscBiosVendorFunction.c + MiscBootInformationData.c + MiscBootInformationFunction.c + MiscChassisManufacturer.uni + MiscChassisManufacturerData.c + MiscChassisManufacturerFunction.c + MiscNumberOfInstallableLanguagesData.c + MiscNumberOfInstallableLanguagesFunction.c + MiscOemString.uni + MiscOemStringData.c + MiscOemStringFunction.c + MiscPortInternalConnectorDesignator.uni + MiscPortInternalConnectorDesignatorData.c + MiscPortInternalConnectorDesignatorFunction.c + MiscResetCapabilitiesData.c + MiscResetCapabilitiesFunction.c + MiscSystemLanguageString.uni + MiscSystemLanguageStringData.c + MiscSystemLanguageStringFunction.c + MiscSystemManufacturer.uni + MiscSystemManufacturerData.c + MiscSystemManufacturerFunction.c + MiscSystemOptionString.uni + MiscSystemOptionStringData.c + MiscSystemOptionStringFunction.c + MiscSystemSlotDesignation.uni + MiscSystemSlotDesignationData.c + MiscSystemSlotDesignationFunction.c + MiscDevicePath.h + MiscSubClassDriver.h + MiscSubClassDriver.uni + MiscSubclassDriverDataTable.c + MiscSubclassDriverEntryPoint.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + DevicePathLib + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + UefiDriverEntryPoint + UefiLib + HiiLib + DebugLib + BaseLib + PcdLib + +[Protocols] + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang + gInOsEmuPkgTokenSpaceGuid.PcdEmuMemorySize + + +[Depex] + gEfiSmbiosProtocolGuid diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.uni new file mode 100644 index 0000000000000000000000000000000000000000..7a4e8a2cbc92a52a94ec926d1a55ee9e2695fb92 GIT binary patch literal 2004 zcmbuANpBND5QXcE#D5q$7nZ~Z4jd35#S1XXV#^E5De@L)q}V|-<3RpA@V#n}XKV>6 z5Lub->aKqE`c-x1_pgREEV5_zoZn-6gw@!Nk+tl`zT2Ipme|6sEXVhWP3kmT@+VsEMhV^#_$jyxkFmra6Jy4h<1u%83hNtN;;Fqm&aLo|SP?75OPF1QR^pFY)#+>Y zrp#8(Ot=NUPR}+GZkZ?ej%~tM=hn_b*d>z?Yw4^D6fqOuWUG(vbYqv5b4?pq8~b#J zOUdUN{oLAm0u(4-i3pHJ3- zRgXIA+DE>}c7`3JX@sg8hpfg_+K5@ll^)qSV~6z;q0B-|Wq0rxIC7VnDq7zfqi}^< zV{E!D>u}30vM=n5SJxxTJ|>cwowFW;DvYj2?_-I())aGymwXg8czwWEC%-YCup{Pr ziJeW9aEp$8-Qtw!F8pvD=IL&#E^pv*hs6EUGN>DUJGtgbihg*6=M4gW*uH(dTF`WtX_GY z*@{yE_kh{oG1Uh%ZX%8|ul4(%ZlR+%WzO*7Y`U;mqHpL2%EtY<^qhN6CPL3o8P!MC z_gDPpu8`hxo4FV-+#~ +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: + + MiscSubclassDriverDataTable.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + + +// +// External definitions referenced by Data Table entries. +// +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_BASE_BOARD_MANUFACTURER_DATA, MiscBaseBoardManufacturer, MiscBaseBoardManufacturer); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_BIOS_VENDOR_DATA, MiscBiosVendor,MiscBiosVendor ); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_BOOT_INFORMATION_STATUS_DATA, BootInformationStatus, BootInformationStatus); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_CHASSIS_MANUFACTURER_DATA, MiscChassisManufacturer, MiscChassisManufacturer); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_NUMBER_OF_INSTALLABLE_LANGUAGES_DATA,NumberOfInstallableLanguages, NumberOfInstallableLanguages); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_OEM_STRING_DATA,OemString, OemString); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortInternalConnectorDesignator, MiscPortInternalConnectorDesignator); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortKeyboard, MiscPortInternalConnectorDesignator); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortMouse, MiscPortInternalConnectorDesignator); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortCom1, MiscPortInternalConnectorDesignator); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortCom2, MiscPortInternalConnectorDesignator); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortExtensionPower, MiscPortInternalConnectorDesignator); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_PORT_INTERNAL_CONNECTOR_DESIGNATOR_DATA, MiscPortFloppy, MiscPortInternalConnectorDesignator); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_RESET_CAPABILITIES, MiscResetCapabilities, MiscResetCapabilities); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_SYSTEM_LANGUAGE_STRING_DATA,SystemLanguageString, SystemLanguageString); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_SYSTEM_MANUFACTURER_DATA, MiscSystemManufacturer, MiscSystemManufacturer); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_SYSTEM_OPTION_STRING_DATA, SystemOptionString, SystemOptionString); +MISC_SMBIOS_TABLE_EXTERNS ( EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotDesignation, MiscSystemSlotDesignation); + + +// +// Data Table. +// +EFI_MISC_SMBIOS_DATA_TABLE mMiscSubclassDataTable[] = { + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscBaseBoardManufacturer, MiscBaseBoardManufacturer), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscBiosVendor,MiscBiosVendor ), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( BootInformationStatus, BootInformationStatus), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscChassisManufacturer, MiscChassisManufacturer), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(NumberOfInstallableLanguages, NumberOfInstallableLanguages), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(OemString, OemString), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscPortInternalConnectorDesignator, MiscPortInternalConnectorDesignator), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscPortKeyboard, MiscPortInternalConnectorDesignator), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscPortMouse, MiscPortInternalConnectorDesignator), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscPortCom1, MiscPortInternalConnectorDesignator), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscPortCom2, MiscPortInternalConnectorDesignator), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscPortExtensionPower, MiscPortInternalConnectorDesignator), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscPortFloppy, MiscPortInternalConnectorDesignator), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscResetCapabilities, MiscResetCapabilities), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION(SystemLanguageString, SystemLanguageString), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscSystemManufacturer, MiscSystemManufacturer), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( SystemOptionString, SystemOptionString), + MISC_SMBIOS_TABLE_ENTRY_DATA_AND_FUNCTION( MiscSystemSlotDesignation, MiscSystemSlotDesignation), + }; + +// +// Number of Data Table entries. +// +UINTN mMiscSubclassDataTableEntries = (sizeof mMiscSubclassDataTable) / sizeof (EFI_MISC_SMBIOS_DATA_TABLE); + +/* eof - MiscSubclassDriverDataTable.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubclassDriverEntryPoint.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubclassDriverEntryPoint.c new file mode 100644 index 0000000000..065ab6fef8 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubclassDriverEntryPoint.c @@ -0,0 +1,170 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscSubclassDriverEntryPoint.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +EFI_HII_HANDLE mHiiHandle; + +/** + This is the standard EFI driver point that detects whether there is a + MemoryConfigurationData Variable and, if so, reports memory configuration info + to the DataHub. + + @param ImageHandle Handle for the image of this driver + @param SystemTable Pointer to the EFI System Table + + @return EFI_SUCCESS if the data is successfully reported + @return EFI_NOT_FOUND if the HOB list could not be located. + +**/ +EFI_STATUS +LogMemorySmbiosRecord ( + VOID + ) +{ + EFI_STATUS Status; + UINT64 TotalMemorySize; + UINT8 NumSlots; + SMBIOS_TABLE_TYPE19 *Type19Record; + EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle; + EFI_SMBIOS_PROTOCOL *Smbios; + CHAR16 *MemString; + + Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios); + ASSERT_EFI_ERROR (Status); + + NumSlots = 1; + + // + // Process Memory String in form size!size ... + // So 64!64 is 128 MB + // + MemString = (CHAR16 *)PcdGetPtr (PcdEmuMemorySize); + for (TotalMemorySize = 0; *MemString != '\0';) { + TotalMemorySize += StrDecimalToUint64 (MemString); + while (*MemString != '\0') { + if (*MemString == '!') { + MemString++; + break; + } + MemString++; + } + } + + // + // Convert Total Memory Size to based on KiloByte + // + TotalMemorySize = LShiftU64 (TotalMemorySize, 20); + // + // Generate Memory Array Mapped Address info + // + Type19Record = AllocatePool(sizeof (SMBIOS_TABLE_TYPE19)); + ZeroMem(Type19Record, sizeof(SMBIOS_TABLE_TYPE19)); + Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS; + Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19); + Type19Record->Hdr.Handle = 0; + Type19Record->StartingAddress = 0; + Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1; + Type19Record->MemoryArrayHandle = 0; + Type19Record->PartitionWidth = (UINT8)(NumSlots); + + // + // Generate Memory Array Mapped Address info (TYPE 19) + // + MemArrayMappedAddrSmbiosHandle = 0; + Status = Smbios->Add (Smbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record); + FreePool(Type19Record); + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +EFI_STATUS +EFIAPI +MiscSubclassDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ +Description: + + Standard EFI driver point. This driver parses the mMiscSubclassDataTable + structure and reports any generated data to the DataHub. + +Arguments: + + ImageHandle + Handle for the image of this driver + + SystemTable + Pointer to the EFI System Table + +Returns: + + EFI_SUCCESS + The data was successfully reported to the Data Hub. + +**/ +{ + UINTN Index; + EFI_STATUS EfiStatus; + EFI_SMBIOS_PROTOCOL *Smbios; + + EfiStatus = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios); + + if (EFI_ERROR(EfiStatus)) { + DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol. %r\n", EfiStatus)); + return EfiStatus; + } + + mHiiHandle = HiiAddPackages ( + &gEfiCallerIdGuid, + NULL, + MiscSubclassStrings, + NULL + ); + ASSERT (mHiiHandle != NULL); + + for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) { + // + // If the entry have a function pointer, just log the data. + // + if (mMiscSubclassDataTable[Index].Function != NULL) { + EfiStatus = (*mMiscSubclassDataTable[Index].Function)( + mMiscSubclassDataTable[Index].RecordData, + Smbios + ); + + if (EFI_ERROR(EfiStatus)) { + DEBUG((EFI_D_ERROR, "Misc smbios store error. Index=%d, ReturnStatus=%r\n", Index, EfiStatus)); + return EfiStatus; + } + } + } + + // + // Log Memory SMBIOS Record + // + EfiStatus = LogMemorySmbiosRecord(); + return EfiStatus; +} diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageString.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageString.uni new file mode 100644 index 0000000000000000000000000000000000000000..709c53a6602691e3553c649a09d5a317c0c9d9d6 GIT binary patch literal 1314 zcmZ9MNpBND5QXcE#D5q$7Xq;jIdDLLWG6!yk=Rk}2y%+NXCyCZ#!2v>2fkPBSsYpJ z>guX~^}3e%_qT0ri|nnvM=a)bqRSD|2dXWBeDL2*GpE1nF-n4;WhU6&v`@0fjDhz znN=rksl_MnH}zP^uKY94b&I
7i8e$L4l?o+z%FnSA=2mVD)3aR&ew-{E}^ikg~ zSUYxwo{-astV#|!P3W{+cClyr)_Ta8^9rG=LPBT9cnlo5&rTh!wSg3_P#egu>(Wk2 zZjt@OE?#|)D7`}@G3#-jfGUi>N54T6cbzHb5HI;CYVi7ouWsHUe_#=FO=7%{5?&G8 zuM($1PsqhJeWjS^%v+JSLTbL7d?CVjA)J1(BlnYbL><)03!en_tZLchU5e2FRW{Ws zr#_9^y`lrdB!(K?!$!F}vwPM%{;J0n+NHnn0^ANYjNKlp) +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: + + MiscSystemLanguageStringData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_LANGUAGE_STRING_DATA, SystemLanguageString) = { + 0, + STRING_TOKEN(STR_MISC_SYSTEM_LANGUAGE_STRING) +}; + +/* eof - MiscSystemLanguageStringData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageStringFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageStringFunction.c new file mode 100644 index 0000000000..3e10c63caa --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageStringFunction.c @@ -0,0 +1,85 @@ +/** @file + ResetCapabilities. + SMBIOS type 23. + + 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. + +**/ + +#include "MiscSubClassDriver.h" +/** + This function makes boot time changes to the contents of the + MiscOemString (Type 11). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(SystemLanguageString) +{ + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE13 *SmbiosRecord; + UINTN StrLeng; + CHAR8 *OptionalStrStart; + EFI_STRING Str; + STRING_REF TokenToGet; + + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_LANGUAGE_STRING); + Str = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + StrLeng = StrLen(Str); + if (StrLeng > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE13) + StrLeng + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE13) + StrLeng + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE13); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + SmbiosRecord->InstallableLanguages = 1; + SmbiosRecord->Flags = 1; + SmbiosRecord->CurrentLanguages = 1; + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + UnicodeStrToAsciiStr(Str, OptionalStrStart); + + + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + FreePool(SmbiosRecord); + return Status; +} + diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturer.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturer.uni new file mode 100644 index 0000000000000000000000000000000000000000..3ff890b83dce178ffa21b45c1e6340300e9fa52f GIT binary patch literal 1772 zcmbW1OOH}P5QS@P;(xe-jgJA;g$tu5yhe#K5FVqmBE07&Jj?|~`Sa>`s<~X4l@dZ% zS9kTP)2FKMpWh`bS!6HlCBLWk1g~_okyUMNKWuM_#WuHl+YV}98_p*7z&IiDy;ZDZACIh3mXY;f z6cZhRpMX2}983HmIVRXG5mWcauwL7eNbT)8w<11bMXZ!BX0`w=!ymG$(+l>-%vR1! zxGBC)PYxL#n8(BpZN#W^J7*#6j7i9~bk-?~n2B$E)JJz(+wA0A#ky9*|9ZwHfn%02&7lho=ypREq7Hht8x zPmE=2;y2JVLRHxws|`A>&#dlB_w5E-XFWs6s?eab>qK-Nxy4K!tucocu26H>iu>}e zj@%;q#=dy9Jfr+FnZ)dd^#-WIXnFPyp15mGIeSDYMp;ADHL*H*hyB8inCm6h4_U%3 z>h}GJlc6`zqD@~ZXN~uk>Xur)?*d2^77O{ojmuKpq^DN3*1XNa-eEY zwc1dh+{wAL1H(%UH5kA~T2*bpc*kG$XyP^fhJCxnR$1-4BC3vl8H*ik=H7p&JjA5S zyI0OBuRa1#tao&|-pkfIPj59a%pc#!zp)FwRfCnd4XA*6OkH;wyEaVLD7tfQ5qLvb zPcLM53zH7_4?Pn&W#j*AcMFpQg~HeTGR4%(dUIuZPkQyytKw^yDb{sP;VUk^cIc(= HP+HNyuZ9og literal 0 HcmV?d00001 diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturerData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturerData.c new file mode 100644 index 0000000000..13befc45f6 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturerData.c @@ -0,0 +1,57 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscSystemManufacturerData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) System Manufacturer data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_MANUFACTURER_DATA, MiscSystemManufacturer) += { + STRING_TOKEN(STR_MISC_SYSTEM_MANUFACTURER), + // SystemManufactrurer + STRING_TOKEN(STR_MISC_SYSTEM_PRODUCT_NAME), + // SystemProductName + STRING_TOKEN(STR_MISC_SYSTEM_VERSION), + // SystemVersion + STRING_TOKEN(STR_MISC_SYSTEM_SERIAL_NUMBER), + // SystemSerialNumber + { + 0xbadfaced, + 0xdead, + 0xbeef, + { + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13 + } + }, + // SystemUuid + EfiSystemWakeupTypePowerSwitch // SystemWakeupType +}; + +/* eof - MiscSystemManufacturerData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturerFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturerFunction.c new file mode 100644 index 0000000000..9d2a3cbdc1 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturerFunction.c @@ -0,0 +1,140 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscSystemManufacturerFunction.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +/** + This function makes boot time changes to the contents of the + MiscSystemManufacturer (Type 1). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(MiscSystemManufacturer) +{ + CHAR8 *OptionalStrStart; + UINTN ManuStrLen; + UINTN VerStrLen; + UINTN PdNameStrLen; + UINTN SerialNumStrLen; + EFI_STATUS Status; + EFI_STRING Manufacturer; + EFI_STRING ProductName; + EFI_STRING Version; + EFI_STRING SerialNumber; + STRING_REF TokenToGet; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE1 *SmbiosRecord; + EFI_MISC_SYSTEM_MANUFACTURER *ForType1InputData; + + ForType1InputData = (EFI_MISC_SYSTEM_MANUFACTURER *)RecordData; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_MANUFACTURER); + Manufacturer = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + ManuStrLen = StrLen(Manufacturer); + if (ManuStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_PRODUCT_NAME); + ProductName = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + PdNameStrLen = StrLen(ProductName); + if (PdNameStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_VERSION); + Version = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + VerStrLen = StrLen(Version); + if (VerStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SERIAL_NUMBER); + SerialNumber = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + SerialNumStrLen = StrLen(SerialNumber); + if (SerialNumStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE1) + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1 + SerialNumStrLen + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE1); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + // + // Manu will be the 1st optional string following the formatted structure. + // + SmbiosRecord->Manufacturer = 1; + // + // ProductName will be the 2nd optional string following the formatted structure. + // + SmbiosRecord->ProductName = 2; + // + // Version will be the 3rd optional string following the formatted structure. + // + SmbiosRecord->Version = 3; + // + // Version will be the 4th optional string following the formatted structure. + // + SmbiosRecord->SerialNumber = 4; + CopyMem ((UINT8 *) (&SmbiosRecord->Uuid),&ForType1InputData->SystemUuid,16); + SmbiosRecord->WakeUpType = (UINT8)ForType1InputData->SystemWakeupType; + + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + UnicodeStrToAsciiStr(Manufacturer, OptionalStrStart); + UnicodeStrToAsciiStr(ProductName, OptionalStrStart + ManuStrLen + 1); + UnicodeStrToAsciiStr(Version, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1); + UnicodeStrToAsciiStr(SerialNumber, OptionalStrStart + ManuStrLen + 1 + PdNameStrLen + 1 + VerStrLen + 1); + + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + FreePool(SmbiosRecord); + return Status; +} + +/* eof - MiscSystemManufacturerFunction.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionString.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionString.uni new file mode 100644 index 0000000000000000000000000000000000000000..abf2da762c948a6ae3f950ac1a1a8328684ea827 GIT binary patch literal 1308 zcmZ9MOK%fF5QOWD#D7>h7ap+<95^6AvXcc?5Ic$;K~9n1S;>!R?F9Vifv;w~UOTcp z-96n?UDMsO|Nb`BRH9dU&F{IMVKw(M(V14d*H(pc&2*;?u`e{zOXNGf;rAY`zO&w9 zpQ2}45;@Tv-3SF3UI*;vXiGKlwD3Ek!d?e!qBUm=J+h98{HV6B^m)&!WSOWBqnzjj z`~uur$g#j4kYkM85HSh%2-Yhth_r9Zxh3%lJ7(p4Iocew3V*<^PtWm<(3XLjaZ7xk z9`7uUZ}Jh4Y+{fDThtd1)atGOj=816si4zUL2v^l7( zCuu`3K7@JmjK%6Yz6iB$aJHaB%_r4gvonPIn5jF?-T>u}e_4}K`aa*3!s?Pa>gp?N zOBdJ~HBG3hWuM)QNxMc%L#40PL8k0i2vrv{COajf7m&MXo@lQ%q;ZW}L$-r$>vYd8 z(NFy5)eRYKx5#8>9riO&jnNI+udvMBd(PP>$}!FwqrMR9lQ+okc+A`{G2LZ}w@CGC zk5i#%)Z&u4a?W$!TUobK`hC~=Ld5Sv-2J4J5NGRzK6sL6;U#!x-OD=na*i6P_PJMU z`cpeNS59DjiLnQ_uyL)cX +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: + + MiscSystemOptionStringData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_OPTION_STRING_DATA, SystemOptionString) = { + {STRING_TOKEN(STR_MISC_SYSTEM_OPTION_STRING)} +}; + +/* eof - MiscSystemOptionStringData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionStringFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionStringFunction.c new file mode 100644 index 0000000000..a910634f00 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionStringFunction.c @@ -0,0 +1,83 @@ +/** @file + BIOS system option string boot time changes. + SMBIOS type 12. + + 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. + +**/ + +#include "MiscSubClassDriver.h" + + +/** + This function makes boot time changes to the contents of the + MiscSystemOptionString (Type 12). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(SystemOptionString) +{ + CHAR8 *OptionalStrStart; + UINTN OptStrLen; + EFI_STRING OptionString; + EFI_STATUS Status; + STRING_REF TokenToGet; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_TABLE_TYPE12 *SmbiosRecord; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_OPTION_STRING); + OptionString = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + OptStrLen = StrLen(OptionString); + if (OptStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE12) + OptStrLen + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE12); + // + // Make handle chosen by smbios protocol.add automatically. + // + SmbiosRecord->Hdr.Handle = 0; + + SmbiosRecord->StringCount = 1; + OptionalStrStart = (CHAR8*) (SmbiosRecord + 1); + UnicodeStrToAsciiStr(OptionString, OptionalStrStart); + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + + FreePool(SmbiosRecord); + return Status; +} diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignation.uni b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignation.uni new file mode 100644 index 0000000000000000000000000000000000000000..45e9ce3c00c7af269902cedc8ef77e2054e6719c GIT binary patch literal 1322 zcmZ9MTTk0S5QXQtQvZV$UP>WJ%R?WkQYj&ZS_OhgP|Fj_)mX{}*#VkA-}XDZvDZOS zc4l^G&z!le|NU)S+amjDNBrK~JFIpkBRjLTJ=xZB%Ph4=+u-}bCU%HCu}}QIpfz{a zXY6D2#8!CDY=JI>91N`^b~ChdD^?}T$c8Y= z@Q%RG!A)I^CH9CIQ{)DZnX@ObUfU8+oo%_d!arh1tQ0RpTYwhuN9^kMg0l(Q$}tme ziLcw!U4$3(4BwHBS#|H(u@H7(;$tlx>k>uG#5b$zqny?@uifj~zn*GO%J^z-@fy4Q=j7mPAWoZF zWi?3~dhylGn`X>cSN^%Hb&I<>9csU+e!{eTdm|m!C_anW zepfgFJ)ssi%#~vHcyDFhN~!nV1zeL}I2iT}qXZFB)&tLtxa@Hjo57E?>0bUp687dLgm^{NMbu(D!A~plw azT(b!`4QHFIn!MC*eT$c!Zv)T0^9#yp2<%D literal 0 HcmV?d00001 diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignationData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignationData.c new file mode 100644 index 0000000000..11b2339331 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignationData.c @@ -0,0 +1,52 @@ +/*++ + +Copyright (c) 2006 - 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: + + MiscSystemSlotDesignationData.c + +Abstract: + + This driver parses the mMiscSubclassDataTable structure and reports + any generated data to the DataHub. + +**/ + +#include "MiscSubClassDriver.h" + +// +// Static (possibly build generated) Bios Vendor data. +// +MISC_SMBIOS_TABLE_DATA(EFI_MISC_SYSTEM_SLOT_DESIGNATION_DATA, MiscSystemSlotDesignation) = { + STRING_TOKEN(STR_MISC_SYSTEM_SLOT_DESIGNATION), // SlotDesignation + EfiSlotTypeOther, // SlotType + EfiSlotDataBusWidthOther, // SlotDataBusWidth + EfiSlotUsageOther, // SlotUsage + EfiSlotLengthOther, // SlotLength + 0, // SlotId + { // SlotCharacteristics + 0, // CharacteristicsUnknown :1; + 0, // Provides50Volts :1; + 0, // Provides33Volts :1; + 0, // SharedSlot :1; + 0, // PcCard16Supported :1; + 0, // CardBusSupported :1; + 0, // ZoomVideoSupported :1; + 0, // ModemRingResumeSupported:1; + 0, // PmeSignalSupported :1; + 0, // HotPlugDevicesSupported :1; + 0, // SmbusSignalSupported :1; + 0 // Reserved :21; + }, + {0, 0, {0, 0}} // SlotDevicePath +}; + +/* eof - MiscSystemSlotsData.c */ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignationFunction.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignationFunction.c new file mode 100644 index 0000000000..72c4137c6b --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignationFunction.c @@ -0,0 +1,97 @@ +/** @file + BIOS system slot designator information boot time changes. + SMBIOS type 9. + + 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. + +**/ + +#include "MiscSubClassDriver.h" +/** + This function makes boot time changes to the contents of the + MiscSystemSlotDesignator structure (Type 9). + + @param RecordData Pointer to copy of RecordData from the Data Table. + + @retval EFI_SUCCESS All parameters were valid. + @retval EFI_UNSUPPORTED Unexpected RecordType value. + @retval EFI_INVALID_PARAMETER Invalid parameter was found. + +**/ +MISC_SMBIOS_TABLE_FUNCTION(MiscSystemSlotDesignation) +{ + CHAR8 *OptionalStrStart; + UINTN SlotDesignationStrLen; + EFI_STATUS Status; + EFI_STRING SlotDesignation; + STRING_REF TokenToGet; + SMBIOS_TABLE_TYPE9 *SmbiosRecord; + EFI_SMBIOS_HANDLE SmbiosHandle; + EFI_MISC_SYSTEM_SLOT_DESIGNATION* ForType9InputData; + + ForType9InputData = (EFI_MISC_SYSTEM_SLOT_DESIGNATION *)RecordData; + + // + // First check for invalid parameters. + // + if (RecordData == NULL) { + return EFI_INVALID_PARAMETER; + } + + TokenToGet = 0; + switch (ForType9InputData->SlotDesignation) { + case STR_MISC_SYSTEM_SLOT_DESIGNATION: + TokenToGet = STRING_TOKEN (STR_MISC_SYSTEM_SLOT_DESIGNATION); + break; + default: + break; + } + + SlotDesignation = HiiGetPackageString(&gEfiCallerIdGuid, TokenToGet, NULL); + SlotDesignationStrLen = StrLen(SlotDesignation); + if (SlotDesignationStrLen > SMBIOS_STRING_MAX_LENGTH) { + return EFI_UNSUPPORTED; + } + + // + // Two zeros following the last string. + // + SmbiosRecord = AllocatePool(sizeof (SMBIOS_TABLE_TYPE9) + SlotDesignationStrLen + 1 + 1); + ZeroMem(SmbiosRecord, sizeof (SMBIOS_TABLE_TYPE9) +SlotDesignationStrLen + 1 + 1); + + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_SYSTEM_SLOTS; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE9); + SmbiosRecord->Hdr.Handle = 0; + SmbiosRecord->SlotDesignation = 1; + SmbiosRecord->SlotType = ForType9InputData->SlotType; + SmbiosRecord->SlotDataBusWidth = ForType9InputData->SlotDataBusWidth; + SmbiosRecord->CurrentUsage = ForType9InputData->SlotUsage; + SmbiosRecord->SlotLength = ForType9InputData->SlotLength; + SmbiosRecord->SlotID = ForType9InputData->SlotId; + + // + // Slot Characteristics + // + CopyMem ((UINT8 *) &SmbiosRecord->SlotCharacteristics1,(UINT8 *) &ForType9InputData->SlotCharacteristics,2); + OptionalStrStart = (CHAR8 *)(SmbiosRecord + 1); + UnicodeStrToAsciiStr(SlotDesignation, OptionalStrStart); + // + // Now we have got the full smbios record, call smbios protocol to add this record. + // + SmbiosHandle = 0; + Status = Smbios-> Add( + Smbios, + NULL, + &SmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecord + ); + FreePool(SmbiosRecord); + return Status; +} diff --git a/InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.c b/InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.c new file mode 100644 index 0000000000..05c34bdbb5 --- /dev/null +++ b/InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.c @@ -0,0 +1,305 @@ +/*++ + Emu RTC Architectural Protocol Driver as defined in PI + +Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. 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 + +#include +#include +#include +#include +#include +#include +#include + +#include + +BOOLEAN +DayValid ( + IN EFI_TIME *Time + ); + +BOOLEAN +IsLeapYear ( + IN EFI_TIME *Time + ); + +EFI_STATUS +RtcTimeFieldsValid ( + IN EFI_TIME *Time + ); + +EFI_STATUS +EFIAPI +InitializeRealTimeClock ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +EmuGetTime ( + OUT EFI_TIME * Time, + OUT EFI_TIME_CAPABILITIES * Capabilities OPTIONAL + ) +/*++ + +Routine Description: + Service routine for RealTimeClockInstance->GetTime + +Arguments: + + Time - A pointer to storage that will receive a snapshot of the current time. + + Capabilities - A pointer to storage that will receive the capabilities of the real time clock + in the platform. This includes the real time clock's resolution and accuracy. + All reported device capabilities are rounded up. This is an OPTIONAL argument. + +Returns: + + EFI_SUCEESS - The underlying GetSystemTime call occurred and returned + Note that in the NT32 emulation, the GetSystemTime call has no return value + thus you will always receive a EFI_SUCCESS on this. + +**/ +{ + + // + // Check parameter for null pointer + // + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + + } + + gEmuThunk->GetTime (Time, Capabilities); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuSetTime ( + IN EFI_TIME *Time + ) +/*++ + +Routine Description: + Service routine for RealTimeClockInstance->SetTime + +Arguments: + + Time - A pointer to storage containing the time and date information to + program into the real time clock. + +Returns: + + EFI_SUCEESS - The operation completed successfully. + + EFI_INVALID_PARAMETER - One of the fields in Time is out of range. + + EFI_DEVICE_ERROR - The operation could not be complete due to a device error. + +**/ +{ + EFI_STATUS Status; + + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Make sure that the time fields are valid + // + Status = RtcTimeFieldsValid (Time); + if (EFI_ERROR (Status)) { + return Status; + } + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuGetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +/*++ + +Routine Description: + Service routine for RealTimeClockInstance->GetWakeupTime + +Arguments: + This - Indicates the protocol instance structure. + + Enabled - Indicates if the alarm is currently enabled or disabled. + + Pending - Indicates if the alarm signal is pending and requires + acknowledgement. + + Time - The current alarm setting. + +Returns: + + EFI_SUCEESS - The operation completed successfully. + + EFI_DEVICE_ERROR - The operation could not be complete due to a device error. + + EFI_UNSUPPORTED - The operation is not supported on this platform. + +**/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuSetWakeupTime ( + IN BOOLEAN Enable, + OUT EFI_TIME *Time + ) +/*++ + +Routine Description: + Service routine for RealTimeClockInstance->SetWakeupTime + +Arguments: + + Enabled - Enable or disable the wakeup alarm. + + Time - If enable is TRUE, the time to set the wakup alarm for. + If enable is FALSE, then this parameter is optional, and + may be NULL. + +Returns: + + EFI_SUCEESS - The operation completed successfully. + + EFI_DEVICE_ERROR - The operation could not be complete due to a device error. + + EFI_INVALID_PARAMETER - A field in Time is out of range. + + EFI_UNSUPPORTED - The operation is not supported on this platform. + +**/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +InitializeRealTimeClock ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + Install Real Time Clock Protocol + +Arguments: + ImageHandle - Image Handle + SystemTable - Pointer to system table + +Returns: + + EFI_SUCEESS - Real Time Clock Services are installed into the Runtime Services Table + +**/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + SystemTable->RuntimeServices->GetTime = EmuGetTime; + SystemTable->RuntimeServices->SetTime = EmuSetTime; + SystemTable->RuntimeServices->GetWakeupTime = EmuGetWakeupTime; + SystemTable->RuntimeServices->SetWakeupTime = EmuSetWakeupTime; + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiRealTimeClockArchProtocolGuid, + NULL, + NULL + ); + return Status; +} + +EFI_STATUS +RtcTimeFieldsValid ( + IN EFI_TIME *Time + ) +/*++ + +Routine Description: + + Arguments: + + Returns: +**/ +{ + if (Time->Year < 1998 || + Time->Year > 2099 || + Time->Month < 1 || + Time->Month > 12 || + (!DayValid (Time)) || + Time->Hour > 23 || + Time->Minute > 59 || + Time->Second > 59 || + Time->Nanosecond > 999999999 || + (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) || + (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) + ) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +BOOLEAN +DayValid ( + IN EFI_TIME *Time + ) +{ + + STATIC const INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + if (Time->Day < 1 || + Time->Day > DayOfMonth[Time->Month - 1] || + (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28)) + ) { + return FALSE; + } + + return TRUE; +} + +BOOLEAN +IsLeapYear ( + IN EFI_TIME *Time + ) +{ + if (Time->Year % 4 == 0) { + if (Time->Year % 100 == 0) { + if (Time->Year % 400 == 0) { + return TRUE; + } else { + return FALSE; + } + } else { + return TRUE; + } + } else { + return FALSE; + } +} diff --git a/InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf b/InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf new file mode 100644 index 0000000000..8aa490353a --- /dev/null +++ b/InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf @@ -0,0 +1,57 @@ +## @file +# Emu Real time clock Architectural Protocol Driver as defined in PI +# +# This real time clock module simulates virtual device by time WinAPI. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = RealTimeClock + FILE_GUID = f3552032-8985-11db-8429-0040d02b1835 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeRealTimeClock + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + RealTimeClock.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + EmuThunkLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + + +[Protocols] + gEfiRealTimeClockArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +[Depex] + TRUE + diff --git a/InOsEmuPkg/ResetRuntimeDxe/Reset.c b/InOsEmuPkg/ResetRuntimeDxe/Reset.c new file mode 100644 index 0000000000..14594c7763 --- /dev/null +++ b/InOsEmuPkg/ResetRuntimeDxe/Reset.c @@ -0,0 +1,114 @@ +/*++ @file + Reset Architectural Protocol as defined in UEFI/PI under Emulation + +Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. 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 + +#include +#include +#include +#include +#include +#include +#include + +#include + + +VOID +EFIAPI +EmuResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + + // + // Disconnect all + // + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &HandleCount, + &HandleBuffer + ); + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); + } + + gBS->FreePool (HandleBuffer); + } + + + // + // Discard ResetType, always return 0 as exit code + // + gEmuThunk->Exit (0); + + // + // Should never go here + // + ASSERT (FALSE); + + return; +} + + + +EFI_STATUS +EFIAPI +InitializeEmuReset ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + +Arguments: + + ImageHandle of the loaded driver + Pointer to the System Table + +Returns: + + Status +**/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + SystemTable->RuntimeServices->ResetSystem = EmuResetSystem; + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiResetArchProtocolGuid, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + diff --git a/InOsEmuPkg/ResetRuntimeDxe/Reset.inf b/InOsEmuPkg/ResetRuntimeDxe/Reset.inf new file mode 100644 index 0000000000..93eb5ca51d --- /dev/null +++ b/InOsEmuPkg/ResetRuntimeDxe/Reset.inf @@ -0,0 +1,57 @@ +## @file +# Emu Emulation Reset Architectural Protocol Driver as defined in PI +# +# This Reset module simulates system reset by process exit on Emulator. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuReset + FILE_GUID = 50A18017-37AD-8743-BCF2-DF1A8FF12FAB + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeEmuReset + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + Reset.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + EmuThunkLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + + +[Protocols] + gEfiResetArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +[Depex] + TRUE + diff --git a/InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.c b/InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.c new file mode 100644 index 0000000000..b2b7801109 --- /dev/null +++ b/InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.c @@ -0,0 +1,74 @@ +/*++ @file + UEFI/PI PEIM to abstract construction of firmware volume in a Unix environment. + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. 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 + +#include +#include +#include +#include +#include + +#include +#include + + + +EFI_STATUS +EFIAPI +PeiInitialzeThunkPpiToProtocolPei ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +/*++ + +Routine Description: + + Perform a call-back into the SEC simulator to get Unix Stuff + +Arguments: + + PeiServices - General purpose services available to every PEIM. + +Returns: + + None + +**/ +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; + EMU_THUNK_PPI *Thunk; + VOID *Ptr; + + DEBUG ((EFI_D_ERROR, "Emu Thunk PEIM Loaded\n")); + + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, // GUID + 0, // INSTANCE + &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR + (VOID **)&Thunk // PPI + ); + ASSERT_EFI_ERROR (Status); + + Ptr = Thunk->Thunk (); + + BuildGuidDataHob ( + &gEmuThunkProtocolGuid, // Guid + &Ptr, // Buffer + sizeof (VOID *) // Sizeof Buffer + ); + return Status; +} diff --git a/InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf b/InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf new file mode 100644 index 0000000000..470568f166 --- /dev/null +++ b/InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf @@ -0,0 +1,55 @@ +## @file +# Stuff driver +# +# Tiano PEIM to abstract construction of firmware volume in a Emu environment. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ThunkPpiToProtocolPei + FILE_GUID = C32A66D5-D8B7-2640-B768-082C8F083C37 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + + ENTRY_POINT = PeiInitialzeThunkPpiToProtocolPei + + +[Sources] + ThunkPpiToProtocolPei.c + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + PeiServicesTablePointerLib + PeiServicesLib + HobLib + PeimEntryPoint + DebugLib + + +[Protocols] + gEmuThunkProtocolGuid # PROTOCOL ALWAYS_CONSUMED + + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + + +[Depex] + gEmuThunkPpiGuid AND gEfiPeiMemoryDiscoveredPpiGuid + diff --git a/InOsEmuPkg/TimerDxe/Timer.c b/InOsEmuPkg/TimerDxe/Timer.c new file mode 100644 index 0000000000..143591395a --- /dev/null +++ b/InOsEmuPkg/TimerDxe/Timer.c @@ -0,0 +1,351 @@ +/*++ @file + Emu Emulation Timer Architectural Protocol Driver as defined in DXE CIS + + This Timer module uses an Emu Thread to simulate the timer-tick driven + timer service. In the future, the Thread creation should possibly be + abstracted by the CPU architectural protocol + +Copyright (c) 2004, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. 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 "PiDxe.h" +#include +#include +#include "Timer.h" +#include +#include +#include +#include +#include +#include +#include + +// +// Pointer to the CPU Architectural Protocol instance +// +EFI_CPU_ARCH_PROTOCOL *mCpu; + +// +// The Timer Architectural Protocol that this driver produces +// +EFI_TIMER_ARCH_PROTOCOL mTimer = { + EmuTimerDriverRegisterHandler, + EmuTimerDriverSetTimerPeriod, + EmuTimerDriverGetTimerPeriod, + EmuTimerDriverGenerateSoftInterrupt +}; + +// +// The notification function to call on every timer interrupt +// +EFI_TIMER_NOTIFY mTimerNotifyFunction = NULL; + +// +// The current period of the timer interrupt +// +UINT64 mTimerPeriodMs; + + +VOID +EFIAPI +TimerCallback (UINT64 DeltaMs) +{ + EFI_TPL OriginalTPL; + EFI_TIMER_NOTIFY CallbackFunction; + + + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + if (OriginalTPL < TPL_HIGH_LEVEL) { + CallbackFunction = mTimerNotifyFunction; + + // + // Only invoke the callback function if a Non-NULL handler has been + // registered. Assume all other handlers are legal. + // + if (CallbackFunction != NULL) { + CallbackFunction ((UINT64) (DeltaMs * 10000)); + } + } + + gBS->RestoreTPL (OriginalTPL); + +} + +EFI_STATUS +EFIAPI +EmuTimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ) +/*++ + +Routine Description: + + This function registers the handler NotifyFunction so it is called every time + the timer interrupt fires. It also passes the amount of time since the last + handler call to the NotifyFunction. If NotifyFunction is NULL, then the + handler is unregistered. If the handler is registered, then EFI_SUCCESS is + returned. If the CPU does not support registering a timer interrupt handler, + then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler + when a handler is already registered, then EFI_ALREADY_STARTED is returned. + If an attempt is made to unregister a handler when a handler is not registered, + then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to + register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR + is returned. + +Arguments: + + This - The EFI_TIMER_ARCH_PROTOCOL instance. + + NotifyFunction - The function to call when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will + register a handler for the timer interrupt, so it can know + how much time has passed. This information is used to + signal timer based events. NULL will unregister the handler. + +Returns: + + EFI_SUCCESS - The timer handler was registered. + + EFI_UNSUPPORTED - The platform does not support timer interrupts. + + EFI_ALREADY_STARTED - NotifyFunction is not NULL, and a handler is already + registered. + + EFI_INVALID_PARAMETER - NotifyFunction is NULL, and a handler was not + previously registered. + + EFI_DEVICE_ERROR - The timer handler could not be registered. + +**/ +{ + // + // Check for invalid parameters + // + if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) { + return EFI_ALREADY_STARTED; + } + + if (NotifyFunction == NULL) { + /* Disable timer. */ + gEmuThunk->SetTimer (0, TimerCallback); + } else if (mTimerNotifyFunction == NULL) { + /* Enable Timer. */ + gEmuThunk->SetTimer (mTimerPeriodMs, TimerCallback); + } + mTimerNotifyFunction = NotifyFunction; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuTimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ) +/*++ + +Routine Description: + + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + +Arguments: + + This - The EFI_TIMER_ARCH_PROTOCOL instance. + + TimerPeriod - The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + +Returns: + + EFI_SUCCESS - The timer period was changed. + + EFI_UNSUPPORTED - The platform cannot change the period of the timer interrupt. + + EFI_DEVICE_ERROR - The timer period could not be changed due to a device error. + +**/ +{ + + // + // If TimerPeriod is 0, then the timer thread should be canceled + // If the TimerPeriod is valid, then create and/or adjust the period of the timer thread + // + if (TimerPeriod == 0 + || ((TimerPeriod > TIMER_MINIMUM_VALUE) + && (TimerPeriod < TIMER_MAXIMUM_VALUE))) { + mTimerPeriodMs = DivU64x32 (TimerPeriod + 5000, 10000); + + gEmuThunk->SetTimer (mTimerPeriodMs, TimerCallback); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuTimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +/*++ + +Routine Description: + + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + +Arguments: + + This - The EFI_TIMER_ARCH_PROTOCOL instance. + + TimerPeriod - A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + +Returns: + + EFI_SUCCESS - The timer period was returned in TimerPeriod. + + EFI_INVALID_PARAMETER - TimerPeriod is NULL. + +**/ +{ + if (TimerPeriod == NULL) { + return EFI_INVALID_PARAMETER; + } + + *TimerPeriod = mTimerPeriodMs * 10000; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuTimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ) +/*++ + +Routine Description: + + This function generates a soft timer interrupt. If the platform does not support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() + service, then a soft timer interrupt will be generated. If the timer interrupt is + enabled when this service is called, then the registered handler will be invoked. The + registered handler should not be able to distinguish a hardware-generated timer + interrupt from a software-generated timer interrupt. + +Arguments: + + This - The EFI_TIMER_ARCH_PROTOCOL instance. + +Returns: + + EFI_SUCCESS - The soft timer interrupt was generated. + + EFI_UNSUPPORTEDT - The platform does not support the generation of soft timer interrupts. + +**/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuTimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Initialize the Timer Architectural Protocol driver + +Arguments: + + ImageHandle - ImageHandle of the loaded driver + + SystemTable - Pointer to the System Table + +Returns: + + EFI_SUCCESS - Timer Architectural Protocol created + + EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver. + + EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver. + +**/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + // + // Make sure the Timer Architectural Protocol is not already installed in the system + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid); + + // + // Get the CPU Architectural Protocol instance + // + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (void *)&mCpu); + ASSERT_EFI_ERROR (Status); + + // + // Install the Timer Architectural Protocol onto a new handle + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiTimerArchProtocolGuid, + EFI_NATIVE_INTERFACE, + &mTimer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Start the timer thread at the default timer period + // + Status = mTimer.SetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} diff --git a/InOsEmuPkg/TimerDxe/Timer.h b/InOsEmuPkg/TimerDxe/Timer.h new file mode 100644 index 0000000000..27fc676b71 --- /dev/null +++ b/InOsEmuPkg/TimerDxe/Timer.h @@ -0,0 +1,73 @@ +/*++ @file + Emu Emulation Architectural Protocol Driver as defined in UEFI/PI. + This Timer module uses an UNIX Thread to simulate the timer-tick driven + timer service. + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. 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 _TIMER_H_ +#define _TIMER_H_ + + + + +// +// Legal timer value range in 100 ns units +// +#define TIMER_MINIMUM_VALUE 0 +#define TIMER_MAXIMUM_VALUE (0x100000000ULL - 1) + +// +// Default timer value in 100 ns units (50 ms) +// +#define DEFAULT_TIMER_TICK_DURATION 500000 + +// +// Function Prototypes +// +EFI_STATUS +EFIAPI +EmuTimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +EmuTimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ); + +EFI_STATUS +EFIAPI +EmuTimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ); + +EFI_STATUS +EFIAPI +EmuTimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ); + +EFI_STATUS +EFIAPI +EmuTimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ); + +#endif diff --git a/InOsEmuPkg/TimerDxe/Timer.inf b/InOsEmuPkg/TimerDxe/Timer.inf new file mode 100644 index 0000000000..9282faed89 --- /dev/null +++ b/InOsEmuPkg/TimerDxe/Timer.inf @@ -0,0 +1,59 @@ +## @file +# Emu Emulation Timer Architectural Protocol Driver as defined in DXE CIS +# +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuTimer + FILE_GUID = 87E1BB14-4D5C-7C4E-A90E-E1415687D062 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = EmuTimerDriverInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + Timer.c + Timer.h + + +[Packages] + MdePkg/MdePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + EmuThunkLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + + +[Protocols] + gEfiCpuArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiTimerArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +[Depex] + gEfiCpuArchProtocolGuid + diff --git a/InOsEmuPkg/Unix/.gdbinit b/InOsEmuPkg/Unix/.gdbinit new file mode 100644 index 0000000000..173818c0e7 --- /dev/null +++ b/InOsEmuPkg/Unix/.gdbinit @@ -0,0 +1,8 @@ +set confirm off +set output-radix 16 +b SecGdbScriptBreak +command +silent +source SecMain.gdb +c +end diff --git a/InOsEmuPkg/Unix/Sec/EmuThunk.c b/InOsEmuPkg/Unix/Sec/EmuThunk.c new file mode 100644 index 0000000000..abae70b89a --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/EmuThunk.c @@ -0,0 +1,314 @@ +/*++ @file + Since the SEC is the only program in our emulation we + must use a UEFI/PI mechanism to export APIs to other modules. + This is the role of the EFI_EMU_THUNK_PROTOCOL. + + The mUnixThunkTable exists so that a change to EFI_EMU_THUNK_PROTOCOL + will cause an error in initializing the array if all the member functions + are not added. It looks like adding a element to end and not initializing + it may cause the table to be initaliized with the members at the end being + set to zero. This is bad as jumping to zero will crash. + +Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. 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 "SecMain.h" + +#ifdef __APPLE__ +#define DebugAssert _Mangle__DebugAssert + +#include +#include +#include +#include + +#undef DebugAssert +#endif + +int settimer_initialized; +struct timeval settimer_timeval; +void (*settimer_callback)(UINT64 delta); + +BOOLEAN gEmulatorInterruptEnabled = FALSE; + + +UINTN +SecWriteStdErr ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + ssize_t Return; + + Return = write (1, (const void *)Buffer, (size_t)NumberOfBytes); + + return (Return == -1) ? 0 : Return; +} + + + +void +settimer_handler (int sig) +{ + struct timeval timeval; + UINT64 delta; + + gettimeofday (&timeval, NULL); + delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000) + - ((UINT64)settimer_timeval.tv_sec * 1000) + - (settimer_timeval.tv_usec / 1000); + settimer_timeval = timeval; + + if (settimer_callback) { + ReverseGasketUint64 (settimer_callback, delta); + } +} + +VOID +SecSetTimer ( + IN UINT64 PeriodMs, + IN EMU_SET_TIMER_CALLBACK CallBack + ) +{ + struct itimerval timerval; + UINT32 remainder; + + if (!settimer_initialized) { + struct sigaction act; + + settimer_initialized = 1; + act.sa_handler = settimer_handler; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + gEmulatorInterruptEnabled = TRUE; + if (sigaction (SIGALRM, &act, NULL) != 0) { + printf ("SetTimer: sigaction error %s\n", strerror (errno)); + } + if (gettimeofday (&settimer_timeval, NULL) != 0) { + printf ("SetTimer: gettimeofday error %s\n", strerror (errno)); + } + } + timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000); + DivU64x32Remainder(PeriodMs, 1000, &remainder); + timerval.it_value.tv_usec = remainder * 1000; + timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000); + timerval.it_interval = timerval.it_value; + + if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) { + printf ("SetTimer: setitimer error %s\n", strerror (errno)); + } + settimer_callback = CallBack; +} + + +VOID +SecEnableInterrupt ( + VOID + ) +{ + sigset_t sigset; + + gEmulatorInterruptEnabled = TRUE; + // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts + // by enabling/disabling SIGALRM. + sigemptyset (&sigset); + sigaddset (&sigset, SIGALRM); + pthread_sigmask (SIG_UNBLOCK, &sigset, NULL); +} + + +VOID +SecDisableInterrupt ( + VOID + ) +{ + sigset_t sigset; + + // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts + // by enabling/disabling SIGALRM. + sigemptyset (&sigset); + sigaddset (&sigset, SIGALRM); + pthread_sigmask (SIG_BLOCK, &sigset, NULL); + gEmulatorInterruptEnabled = FALSE; +} + + +BOOLEAN +SecInterruptEanbled (void) +{ + return gEmulatorInterruptEnabled; +} + + +UINT64 +QueryPerformanceFrequency ( + VOID + ) +{ + // Hard code to nanoseconds + return 1000000000ULL; +} + +UINT64 +QueryPerformanceCounter ( + VOID + ) +{ +#if __APPLE__ + UINT64 Start; + Nanoseconds elapsedNano; + + Start = mach_absolute_time (); + + // Convert to nanoseconds. + + // Have to do some pointer fun because AbsoluteToNanoseconds + // works in terms of UnsignedWide, which is a structure rather + // than a proper 64-bit integer. + elapsedNano = AbsoluteToNanoseconds (*(AbsoluteTime *) &Start); + + return *(uint64_t *) &elapsedNano; +#else + // Need to figure out what to do for Linux? + return 0; +#endif +} + + + +VOID +SecSleep ( + IN UINT64 Milliseconds + ) +{ + struct timespec rq, rm; + struct timeval start, end; + unsigned long MicroSec; + + rq.tv_sec = Milliseconds / 1000; + rq.tv_nsec = (Milliseconds % 1000) * 1000000; + + // + // nanosleep gets interrupted by our timer tic. + // we need to track wall clock time or we will stall for way too long + // + gettimeofday (&start, NULL); + end.tv_sec = start.tv_sec + rq.tv_sec; + MicroSec = (start.tv_usec + rq.tv_nsec/1000); + end.tv_usec = MicroSec % 1000000; + if (MicroSec > 1000000) { + end.tv_sec++; + } + + while (nanosleep (&rq, &rm) == -1) { + if (errno != EINTR) { + break; + } + gettimeofday (&start, NULL); + if (start.tv_sec > end.tv_sec) { + break; + } if ((start.tv_sec == end.tv_sec) && (start.tv_usec > end.tv_usec)) { + break; + } + rq = rm; + } +} + +VOID +SecExit ( + UINTN Status + ) +{ + exit (Status); +} + + +VOID +SecGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ) +{ + struct tm *tm; + time_t t; + + t = time (NULL); + tm = localtime (&t); + + Time->Year = 1900 + tm->tm_year; + Time->Month = tm->tm_mon + 1; + Time->Day = tm->tm_mday; + Time->Hour = tm->tm_hour; + Time->Minute = tm->tm_min; + Time->Second = tm->tm_sec; + Time->Nanosecond = 0; + Time->TimeZone = timezone; + Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0) + | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0); + + if (Capabilities != NULL) { + Capabilities->Resolution = 1; + Capabilities->Accuracy = 50000000; + Capabilities->SetsToZero = FALSE; + } +} + + + +VOID +SecSetTime ( + IN EFI_TIME *Time + ) +{ + // Don't change the time on the system + // We could save delta to localtime() and have SecGetTime adjust return values? + return; +} + + +EFI_STATUS +SecGetNextProtocol ( + IN BOOLEAN EmuBusDriver, + OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL + ) +{ + return GetNextThunkProtocol (EmuBusDriver, Instance); +} + + +EMU_THUNK_PROTOCOL gEmuThunkProtocol = { + GasketSecWriteStdErr, + GasketSecPeCoffGetEntryPoint, + GasketSecPeCoffRelocateImageExtraAction, + GasketSecPeCoffUnloadImageExtraAction, + GasketSecEnableInterrupt, + GasketSecDisableInterrupt, + GasketQueryPerformanceFrequency, + GasketQueryPerformanceCounter, + GasketSecSleep, + GasketSecExit, + GasketSecGetTime, + GasketSecSetTime, + GasketSecSetTimer, + GasketSecGetNextProtocol +}; + + +VOID +SecInitThunkProtocol ( + VOID + ) +{ + // timezone and daylight lib globals depend on tzset be called 1st. + tzset (); +} + diff --git a/InOsEmuPkg/Unix/Sec/FwVol.c b/InOsEmuPkg/Unix/Sec/FwVol.c new file mode 100644 index 0000000000..a9a09a4096 --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/FwVol.c @@ -0,0 +1,309 @@ +/*++ @file + A simple FV stack so the SEC can extract the SEC Core from an + FV. + +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. + +**/ + +#include "SecMain.h" + +#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \ + (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)) + +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_FVB2_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; +} + +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. + +**/ +{ + 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; +} + +EFI_STATUS +SecFfsFindNextFile ( + 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: + 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_FFS_FILE_HEADER *FfsFileHeader; + UINT32 FileLength; + UINT32 FileOccupiedSize; + UINT32 FileOffset; + UINT64 FvLength; + UINT8 ErasePolarity; + UINT8 FileState; + + FvLength = FwVolHeader->FvLength; + if (FwVolHeader->Attributes & EFI_FVB2_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 = GET_OCCUPIED_SIZE (FileLength, 8); + FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader + FileOccupiedSize); + } + + FileOffset = (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader); + + 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 = GET_OCCUPIED_SIZE (FileLength, 8); + + 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 { + return EFI_NOT_FOUND; + } + 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; +} + +EFI_STATUS +SecFfsFindSectionData ( + 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: + 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 = GET_OCCUPIED_SIZE (SectionLength, 4); + + ParsedLength += SectionLength; + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength); + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +SecFfsFindPeiCore ( + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, + OUT VOID **Pe32Data + ) +/*++ + +Routine Description: + Given the pointer to the Firmware Volume Header find the SEC + core and return it's PE32 image. + +Arguments: + FwVolHeader - Pointer to memory mapped FV + Pe32Data - Pointer to SEC PE32 iamge. + +Returns: + EFI_SUCCESS - Pe32Data is valid + other - Failure + +**/ +{ + EFI_STATUS Status; + EFI_FFS_FILE_HEADER *FileHeader; + EFI_FV_FILETYPE SearchType; + + SearchType = EFI_FV_FILETYPE_PEI_CORE; + FileHeader = NULL; + do { + Status = SecFfsFindNextFile (SearchType, FwVolHeader, &FileHeader); + if (!EFI_ERROR (Status)) { + Status = SecFfsFindSectionData (EFI_SECTION_PE32, FileHeader, Pe32Data); + return Status; + } + } while (!EFI_ERROR (Status)); + + return Status; +} diff --git a/InOsEmuPkg/Unix/Sec/Gasket.h b/InOsEmuPkg/Unix/Sec/Gasket.h new file mode 100644 index 0000000000..665a075e3f --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/Gasket.h @@ -0,0 +1,420 @@ +/** @file + + Copyright (c) 2008 - 2011, Apple Inc. 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 _GASKET_H_ +#define _GASKET_H_ + +// +// EMU_THUNK_PROTOCOL gaskets (EFIAPI to UNIX ABI) +// + +UINTN +GasketSecWriteStdErr ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ); + +RETURN_STATUS +EFIAPI +GasketSecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ); + +VOID +EFIAPI +GasketSecPeCoffRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +VOID +EFIAPI +GasketSecPeCoffUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +VOID +EFIAPI +GasketSecSetTimer ( + IN UINT64 PeriodMs, + IN EMU_SET_TIMER_CALLBACK CallBack + ); + +VOID +EFIAPI +GasketSecEnableInterrupt ( + VOID + ); + +VOID +EFIAPI +GasketSecDisableInterrupt ( + VOID + ); + +UINT64 +GasketQueryPerformanceFrequency ( + VOID + ); + +UINT64 +GasketQueryPerformanceCounter ( + VOID + ); + + +VOID +EFIAPI +GasketSecSleep ( + IN UINT64 Milliseconds + ); + +VOID +EFIAPI +GasketSecExit ( + UINTN Status + ); + +VOID +EFIAPI +GasketSecGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +VOID +EFIAPI +GasketSecSetTime ( + IN EFI_TIME *Time + ); + +EFI_STATUS +EFIAPI +GasketSecGetNextProtocol ( + IN BOOLEAN EmuBusDriver, + OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL + ); + + +// PPIs produced by SEC + + +EFI_STATUS +EFIAPI +GasketSecUnixPeiLoadFile ( + IN VOID *Pe32Data, + IN EFI_PHYSICAL_ADDRESS *ImageAddress, + IN UINT64 *ImageSize, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint + ); + +EFI_STATUS +EFIAPI +GasketSecUnixPeiAutoScan ( + IN UINTN Index, + OUT EFI_PHYSICAL_ADDRESS *MemoryBase, + OUT UINT64 *MemorySize + ); + +VOID * +EFIAPI +GasketSecEmuThunkAddress ( + VOID + ); + + +EFI_STATUS +EFIAPI +GasketSecUnixUnixFwhAddress ( + IN OUT UINT64 *FwhSize, + IN OUT EFI_PHYSICAL_ADDRESS *FwhBase + ); + + + +// +// Reverse (UNIX to EFIAPI) gaskets +// + +typedef +void +(*CALL_BACK) ( + UINT64 Delta + ); + +UINTN +ReverseGasketUint64 ( + CALL_BACK CallBack, + UINT64 a + ); + +UINTN +ReverseGasketUint64Uint64 ( + VOID *CallBack, + VOID *Context, + VOID *Key + ); + +// +// Gasket functions for EFI_EMU_UGA_IO_PROTOCOL +// + + +EFI_STATUS +EFIAPI +GasketX11Size ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + UINT32 Width, + UINT32 Height + ); + +EFI_STATUS +EFIAPI +GasketX11CheckKey ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo + ); + +EFI_STATUS +EFIAPI +GasketX11GetKey ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + EFI_KEY_DATA *key + ); + +EFI_STATUS +EFIAPI +GasketX11KeySetState ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + EFI_KEY_TOGGLE_STATE *KeyToggleState + ); + +EFI_STATUS +EFIAPI +GasketX11RegisterKeyNotify ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack, + IN VOID *Context + ); + + +EFI_STATUS +EFIAPI +GasketX11Blt ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows, + IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, + IN EFI_UGA_BLT_OPERATION BltOperation, + IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args + ); + +EFI_STATUS +EFIAPI +GasketX11CheckPointer ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo + ); + +EFI_STATUS +EFIAPI +GasketX11GetPointerState ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + EFI_SIMPLE_POINTER_STATE *state + ); + +EFI_STATUS +EFIAPI +GasketX11GraphicsWindowOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketX11GraphicsWindowClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +// Pthreads + +UINTN +EFIAPI +GasketPthreadMutexLock ( + IN VOID *Mutex + ); + + + +UINTN +EFIAPI +GasketPthreadMutexUnLock ( + IN VOID *Mutex + ); + + +UINTN +EFIAPI +GasketPthreadMutexTryLock ( + IN VOID *Mutex + ); + + +VOID * +EFIAPI +GasketPthreadMutexInit ( + IN VOID + ); + + +UINTN +EFIAPI +GasketPthreadMutexDestroy ( + IN VOID *Mutex + ); + + +UINTN +EFIAPI +GasketPthreadCreate ( + IN VOID *Thread, + IN VOID *Attribute, + IN PTREAD_THUNK_THEAD_ENTRY Start, + IN VOID *Context + ); + +VOID +EFIAPI +GasketPthreadExit ( + IN VOID *ValuePtr + ); + + +UINTN +EFIAPI +GasketPthreadSelf ( + VOID + ); + +EFI_STATUS +EFIAPI +GasketPthreadOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPthreadClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + + +// PosixFileSystem + +EFI_STATUS +EFIAPI +GasketPosixOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ); + +EFI_STATUS +EFIAPI +GasketPosixFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +EFI_STATUS +EFIAPI +GasketPosixFileCLose ( + IN EFI_FILE_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPosixFileDelete ( + IN EFI_FILE_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPosixFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketPosixFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketPosixFileSetPossition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ); + +EFI_STATUS +EFIAPI +GasketPosixFileGetPossition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +EFI_STATUS +EFIAPI +GasketPosixFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketPosixFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketPosixFileFlush ( + IN EFI_FILE_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPosixFileSystmeThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPosixFileSystmeThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + + + +#endif + + diff --git a/InOsEmuPkg/Unix/Sec/PosixFileSystem.c b/InOsEmuPkg/Unix/Sec/PosixFileSystem.c new file mode 100644 index 0000000000..d2d3e6da0e --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/PosixFileSystem.c @@ -0,0 +1,1556 @@ +/*++ @file + POSIX Pthreads to emulate APs and implement threads + +Copyright (c) 2011, Apple Inc. 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 "SecMain.h" + + +#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'P', 'f', 's') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *Thunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem; + CHAR8 *FilePath; + CHAR16 *VolumeLabel; + BOOLEAN FileHandlesOpen; +} EMU_SIMPLE_FILE_SYSTEM_PRIVATE; + +#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE, \ + SimpleFileSystem, \ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \ + ) + + +#define EMU_EFI_FILE_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'P', 'f', 'i') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *Thunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + EFI_FILE_PROTOCOL EfiFile; + int fd; + DIR *Dir; + BOOLEAN IsRootDirectory; + BOOLEAN IsDirectoryPath; + BOOLEAN IsOpenedByRead; + char *FileName; + struct dirent *Dirent; +} EMU_EFI_FILE_PRIVATE; + +#define EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + EMU_EFI_FILE_PRIVATE, \ + EfiFile, \ + EMU_EFI_FILE_PRIVATE_SIGNATURE \ + ) + +EFI_STATUS +PosixFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +PosixFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +EFI_FILE_PROTOCOL gPosixFileProtocol = { + EFI_FILE_REVISION, + GasketPosixFileOpen, + GasketPosixFileCLose, + GasketPosixFileDelete, + GasketPosixFileRead, + GasketPosixFileWrite, + GasketPosixFileGetPossition, + GasketPosixFileSetPossition, + GasketPosixFileGetInfo, + GasketPosixFileSetInfo, + GasketPosixFileFlush +}; + +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gPosixFileSystemProtocol = { + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, + GasketPosixOpenVolume, +}; + + +/** + Open the root directory on a volume. + + @param This Protocol instance pointer. + @param Root Returns an Open file handle for the root directory + + @retval EFI_SUCCESS The device was opened. + @retval EFI_UNSUPPORTED This volume does not support the file system. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. + +**/ +EFI_STATUS +PosixOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +{ + EFI_STATUS Status; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + EMU_EFI_FILE_PRIVATE *PrivateFile; + + Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This); + + Status = EFI_OUT_OF_RESOURCES; + PrivateFile = malloc (sizeof (EMU_EFI_FILE_PRIVATE)); + if (PrivateFile == NULL) { + goto Done; + } + + PrivateFile->FileName = malloc (AsciiStrSize (Private->FilePath)); + if (PrivateFile->FileName == NULL) { + goto Done; + } + AsciiStrCpy (PrivateFile->FileName, Private->FilePath); + + PrivateFile->Signature = EMU_EFI_FILE_PRIVATE_SIGNATURE; + PrivateFile->Thunk = Private->Thunk; + PrivateFile->SimpleFileSystem = This; + PrivateFile->IsRootDirectory = TRUE; + PrivateFile->IsDirectoryPath = TRUE; + PrivateFile->IsOpenedByRead = TRUE; + + CopyMem (&PrivateFile->EfiFile, &gPosixFileProtocol, sizeof (EFI_FILE_PROTOCOL)); + + PrivateFile->fd = -1; + PrivateFile->Dir = NULL; + PrivateFile->Dirent = NULL; + + *Root = &PrivateFile->EfiFile; + + PrivateFile->Dir = opendir (PrivateFile->FileName); + if (PrivateFile->Dir == NULL) { + Status = EFI_ACCESS_DENIED; + } else { + Status = EFI_SUCCESS; + } + +Done: + if (EFI_ERROR (Status)) { + if (PrivateFile != NULL) { + if (PrivateFile->FileName != NULL) { + free (PrivateFile->FileName); + } + + free (PrivateFile); + } + + *Root = NULL; + } + + return Status; +} + + +EFI_STATUS +ErrnoToEfiStatus () +{ + switch (errno) { + case EACCES: + return EFI_ACCESS_DENIED; + + case EDQUOT: + case ENOSPC: + return EFI_VOLUME_FULL; + + default: + return EFI_DEVICE_ERROR; + } +} + +VOID +CutPrefix ( + IN CHAR8 *Str, + IN UINTN Count + ) +{ + CHAR8 *Pointer; + + if (AsciiStrLen (Str) < Count) { + ASSERT (0); + } + + for (Pointer = Str; *(Pointer + Count); Pointer++) { + *Pointer = *(Pointer + Count); + } + + *Pointer = *(Pointer + Count); +} + + +VOID +PosixSystemTimeToEfiTime ( + IN time_t SystemTime, + OUT EFI_TIME *Time + ) +{ + struct tm *tm; + + tm = gmtime (&SystemTime); + Time->Year = tm->tm_year; + Time->Month = tm->tm_mon + 1; + Time->Day = tm->tm_mday; + Time->Hour = tm->tm_hour; + Time->Minute = tm->tm_min; + Time->Second = tm->tm_sec; + Time->Nanosecond = 0; + + Time->TimeZone = timezone; + Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0) | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0); +} + + +EFI_STATUS +UnixSimpleFileSystemFileInfo ( + EMU_EFI_FILE_PRIVATE *PrivateFile, + IN CHAR8 *FileName, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINTN Size; + UINTN NameSize; + UINTN ResultSize; + EFI_FILE_INFO *Info; + CHAR8 *RealFileName; + CHAR8 *TempPointer; + CHAR16 *BufferFileName; + struct stat buf; + + if (FileName != NULL) { + RealFileName = FileName; + } + else if (PrivateFile->IsRootDirectory) { + RealFileName = ""; + } else { + RealFileName = PrivateFile->FileName; + } + + TempPointer = RealFileName; + while (*TempPointer) { + if (*TempPointer == '/') { + RealFileName = TempPointer + 1; + } + + TempPointer++; + } + + Size = SIZE_OF_EFI_FILE_INFO; + NameSize = AsciiStrSize (RealFileName) * 2; + ResultSize = Size + NameSize; + + if (*BufferSize < ResultSize) { + *BufferSize = ResultSize; + return EFI_BUFFER_TOO_SMALL; + } + if (stat (FileName == NULL ? PrivateFile->FileName : FileName, &buf) < 0) { + return EFI_DEVICE_ERROR; + } + + Status = EFI_SUCCESS; + + Info = Buffer; + ZeroMem (Info, ResultSize); + + Info->Size = ResultSize; + Info->FileSize = buf.st_size; + Info->PhysicalSize = MultU64x32 (buf.st_blocks, buf.st_blksize); + + PosixSystemTimeToEfiTime (buf.st_ctime, &Info->CreateTime); + PosixSystemTimeToEfiTime (buf.st_atime, &Info->LastAccessTime); + PosixSystemTimeToEfiTime (buf.st_mtime, &Info->ModificationTime); + + if (!(buf.st_mode & S_IWUSR)) { + Info->Attribute |= EFI_FILE_READ_ONLY; + } + + if (S_ISDIR(buf.st_mode)) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + + BufferFileName = (CHAR16 *)((CHAR8 *) Buffer + Size); + while (*RealFileName) { + *BufferFileName++ = *RealFileName++; + } + *BufferFileName = 0; + + *BufferSize = ResultSize; + return Status; +} + +BOOLEAN +IsZero ( + IN VOID *Buffer, + IN UINTN Length + ) +{ + if (Buffer == NULL || Length == 0) { + return FALSE; + } + + if (*(UINT8 *) Buffer != 0) { + return FALSE; + } + + if (Length > 1) { + if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) { + return FALSE; + } + } + + return TRUE; +} + + + +/** + Opens a new file relative to the source file's location. + + @param This The protocol instance pointer. + @param NewHandle Returns File Handle for FileName. + @param FileName Null terminated string. "\", ".", and ".." are supported. + @param OpenMode Open mode for file. + @param Attributes Only used for EFI_FILE_MODE_CREATE. + + @retval EFI_SUCCESS The device was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_MEDIA_CHANGED The media has changed. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +PosixFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_FILE_PROTOCOL *Root; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EMU_EFI_FILE_PRIVATE *NewPrivateFile; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + EFI_STATUS Status; + CHAR16 *Src; + char *Dst; + CHAR8 *RealFileName; + char *ParseFileName; + char *GuardPointer; + CHAR8 TempChar; + UINTN Count; + BOOLEAN TrailingDash; + BOOLEAN LoopFinish; + UINTN InfoSize; + EFI_FILE_INFO *Info; + struct stat finfo; + int res; + + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + NewPrivateFile = NULL; + Status = EFI_OUT_OF_RESOURCES; + + // + // BUGBUG: assume an open of root + // if current location, return current data + // + if ((StrCmp (FileName, L"\\") == 0) || + (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) { +OpenRoot: + Status = PosixOpenVolume (PrivateFile->SimpleFileSystem, &Root); + NewPrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root); + goto Done; + } + + TrailingDash = FALSE; + if (FileName[StrLen (FileName) - 1] == L'\\') { + TrailingDash = TRUE; + FileName[StrLen (FileName) - 1] = 0; + } + + // + // Attempt to open the file + // + NewPrivateFile = malloc (sizeof (EMU_EFI_FILE_PRIVATE)); + if (NewPrivateFile == NULL) { + goto Done; + } + + CopyMem (NewPrivateFile, PrivateFile, sizeof (EMU_EFI_FILE_PRIVATE)); + + NewPrivateFile->FileName = malloc (AsciiStrSize (PrivateFile->FileName) + 1 + StrLen (FileName) + 1); + if (NewPrivateFile->FileName == NULL) { + goto Done; + } + + if (*FileName == L'\\') { + AsciiStrCpy (NewPrivateFile->FileName, PrivateRoot->FilePath); + // Skip first '\'. + Src = FileName + 1; + } else { + AsciiStrCpy (NewPrivateFile->FileName, PrivateFile->FileName); + Src = FileName; + } + Dst = NewPrivateFile->FileName + AsciiStrLen (NewPrivateFile->FileName); + GuardPointer = NewPrivateFile->FileName + AsciiStrLen (PrivateRoot->FilePath); + *Dst++ = '/'; + // Convert unicode to ascii and '\' to '/' + while (*Src) { + if (*Src == '\\') { + *Dst++ = '/'; + } else { + *Dst++ = *Src; + } + Src++; + } + *Dst = 0; + + + // + // Get rid of . and .., except leading . or .. + // + + // + // GuardPointer protect simplefilesystem root path not be destroyed + // + + LoopFinish = FALSE; + while (!LoopFinish) { + LoopFinish = TRUE; + + for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) { + if (*ParseFileName == '.' && + (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == '/') && + *(ParseFileName - 1) == '/' + ) { + + // + // cut /. + // + CutPrefix (ParseFileName - 1, 2); + LoopFinish = FALSE; + break; + } + + if (*ParseFileName == '.' && + *(ParseFileName + 1) == '.' && + (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == '/') && + *(ParseFileName - 1) == '/' + ) { + + ParseFileName--; + Count = 3; + + while (ParseFileName != GuardPointer) { + ParseFileName--; + Count++; + if (*ParseFileName == '/') { + break; + } + } + + // + // cut /.. and its left directory + // + CutPrefix (ParseFileName, Count); + LoopFinish = FALSE; + break; + } + } + } + + if (AsciiStrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) { + NewPrivateFile->IsRootDirectory = TRUE; + free (NewPrivateFile->FileName); + free (NewPrivateFile); + goto OpenRoot; + } + + RealFileName = NewPrivateFile->FileName + AsciiStrLen(NewPrivateFile->FileName) - 1; + while (RealFileName > NewPrivateFile->FileName && *RealFileName != '/') { + RealFileName--; + } + + TempChar = *(RealFileName - 1); + *(RealFileName - 1) = 0; + *(RealFileName - 1) = TempChar; + + + // + // Test whether file or directory + // + NewPrivateFile->IsRootDirectory = FALSE; + NewPrivateFile->fd = -1; + NewPrivateFile->Dir = NULL; + if (OpenMode & EFI_FILE_MODE_CREATE) { + if (Attributes & EFI_FILE_DIRECTORY) { + NewPrivateFile->IsDirectoryPath = TRUE; + } else { + NewPrivateFile->IsDirectoryPath = FALSE; + } + } else { + res = stat (NewPrivateFile->FileName, &finfo); + if (res == 0 && S_ISDIR(finfo.st_mode)) { + NewPrivateFile->IsDirectoryPath = TRUE; + } else { + NewPrivateFile->IsDirectoryPath = FALSE; + } + } + + if (OpenMode & EFI_FILE_MODE_WRITE) { + NewPrivateFile->IsOpenedByRead = FALSE; + } else { + NewPrivateFile->IsOpenedByRead = TRUE; + } + + Status = EFI_SUCCESS; + + // + // deal with directory + // + if (NewPrivateFile->IsDirectoryPath) { + if ((OpenMode & EFI_FILE_MODE_CREATE)) { + // + // Create a directory + // + if (mkdir (NewPrivateFile->FileName, 0777) != 0) { + if (errno != EEXIST) { + //free (TempFileName); + Status = EFI_ACCESS_DENIED; + goto Done; + } + } + } + + NewPrivateFile->Dir = opendir (NewPrivateFile->FileName); + if (NewPrivateFile->Dir == NULL) { + if (errno == EACCES) { + Status = EFI_ACCESS_DENIED; + } else { + Status = EFI_NOT_FOUND; + } + + goto Done; + } + + } else { + // + // deal with file + // + NewPrivateFile->fd = open ( + NewPrivateFile->FileName, + ((OpenMode & EFI_FILE_MODE_CREATE) ? O_CREAT : 0) | (NewPrivateFile->IsOpenedByRead ? O_RDONLY : O_RDWR), + 0666 + ); + if (NewPrivateFile->fd < 0) { + if (errno == ENOENT) { + Status = EFI_NOT_FOUND; + } else { + Status = EFI_ACCESS_DENIED; + } + } + } + + if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) { + // + // Set the attribute + // + InfoSize = 0; + Info = NULL; + Status = PosixFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info); + if (Status != EFI_BUFFER_TOO_SMALL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + Info = malloc (InfoSize); + if (Info == NULL) { + goto Done; + } + + Status = PosixFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info); + if (EFI_ERROR (Status)) { + goto Done; + } + + Info->Attribute = Attributes; + PosixFileSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info); + + free (Info); + } + +Done: ; + if (TrailingDash) { + FileName[StrLen (FileName) + 1] = 0; + FileName[StrLen (FileName)] = L'\\'; + } + + if (EFI_ERROR (Status)) { + if (NewPrivateFile) { + if (NewPrivateFile->FileName) { + free (NewPrivateFile->FileName); + } + + free (NewPrivateFile); + } + } else { + *NewHandle = &NewPrivateFile->EfiFile; + } + + return Status; +} + + + +/** + Close the file handle + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The device was opened. + +**/ +EFI_STATUS +PosixFileCLose ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->fd >= 0) { + close (PrivateFile->fd); + } + if (PrivateFile->Dir != NULL) { + closedir (PrivateFile->Dir); + } + + PrivateFile->fd = -1; + PrivateFile->Dir = NULL; + + if (PrivateFile->FileName) { + free (PrivateFile->FileName); + } + + free (PrivateFile); + + return EFI_SUCCESS; +} + + +/** + Close and delete the file handle. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The device was opened. + @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted. + +**/ +EFI_STATUS +PosixFileDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + Status = EFI_WARN_DELETE_FAILURE; + + if (PrivateFile->IsDirectoryPath) { + if (PrivateFile->Dir != NULL) { + closedir (PrivateFile->Dir); + PrivateFile->Dir = NULL; + } + + if (rmdir (PrivateFile->FileName) == 0) { + Status = EFI_SUCCESS; + } + } else { + close (PrivateFile->fd); + PrivateFile->fd = -1; + + if (!PrivateFile->IsOpenedByRead) { + if (!unlink (PrivateFile->FileName)) { + Status = EFI_SUCCESS; + } + } + } + + free (PrivateFile->FileName); + free (PrivateFile); + + return Status; +} + + +/** + Read data from the file. + + @param This Protocol instance pointer. + @param BufferSize On input size of buffer, on output amount of data in buffer. + @param Buffer The buffer in which data is read. + + @retval EFI_SUCCESS Data was read. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size. + +**/ +EFI_STATUS +PosixFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + int Res; + UINTN Size; + UINTN NameSize; + UINTN ResultSize; + CHAR8 *FullFileName; + + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (!PrivateFile->IsDirectoryPath) { + if (PrivateFile->fd < 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + Res = read (PrivateFile->fd, Buffer, *BufferSize); + if (Res < 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + *BufferSize = Res; + Status = EFI_SUCCESS; + goto Done; + } + + // + // Read on a directory. + // + if (PrivateFile->Dir == NULL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + if (PrivateFile->Dirent == NULL) { + PrivateFile->Dirent = readdir (PrivateFile->Dir); + if (PrivateFile->Dirent == NULL) { + *BufferSize = 0; + Status = EFI_SUCCESS; + goto Done; + } + } + + Size = SIZE_OF_EFI_FILE_INFO; + NameSize = AsciiStrLen (PrivateFile->Dirent->d_name) + 1; + ResultSize = Size + 2 * NameSize; + + if (*BufferSize < ResultSize) { + *BufferSize = ResultSize; + Status = EFI_BUFFER_TOO_SMALL; + goto Done; + } + Status = EFI_SUCCESS; + + *BufferSize = ResultSize; + + FullFileName = malloc (AsciiStrLen(PrivateFile->FileName) + 1 + NameSize); + if (FullFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + AsciiStrCpy (FullFileName, PrivateFile->FileName); + AsciiStrCat (FullFileName, "/"); + AsciiStrCat (FullFileName, PrivateFile->Dirent->d_name); + Status = UnixSimpleFileSystemFileInfo ( + PrivateFile, + FullFileName, + BufferSize, + Buffer + ); + free (FullFileName); + + PrivateFile->Dirent = NULL; + +Done: + return Status; +} + + + +/** + Write data to a file. + + @param This Protocol instance pointer. + @param BufferSize On input size of buffer, on output amount of data in buffer. + @param Buffer The buffer in which data to write. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to Open directory are not supported. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The device is write protected. + @retval EFI_ACCESS_DENIED The file was open for read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +PosixFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + int Res; + + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->fd < 0) { + return EFI_DEVICE_ERROR; + } + + if (PrivateFile->IsDirectoryPath) { + return EFI_UNSUPPORTED; + } + + if (PrivateFile->IsOpenedByRead) { + return EFI_ACCESS_DENIED; + } + + Res = write (PrivateFile->fd, Buffer, *BufferSize); + if (Res == (UINTN)-1) { + return ErrnoToEfiStatus (); + } + + *BufferSize = Res; + return EFI_SUCCESS; +} + + + +/** + Set a files current position + + @param This Protocol instance pointer. + @param Position Byte position from the start of the file. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open. + +**/ +EFI_STATUS +PosixFileSetPossition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + off_t Pos; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->IsDirectoryPath) { + if (Position != 0) { + return EFI_UNSUPPORTED; + } + + if (PrivateFile->Dir == NULL) { + return EFI_DEVICE_ERROR; + } + rewinddir (PrivateFile->Dir); + return EFI_SUCCESS; + } else { + if (Position == (UINT64) -1) { + Pos = lseek (PrivateFile->fd, 0, SEEK_END); + } else { + Pos = lseek (PrivateFile->fd, Position, SEEK_SET); + } + if (Pos == (off_t)-1) { + return ErrnoToEfiStatus (); + } + return EFI_SUCCESS; + } +} + + + +/** + Get a file's current position + + @param This Protocol instance pointer. + @param Position Byte position from the start of the file. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.. + +**/ +EFI_STATUS +PosixFileGetPossition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->IsDirectoryPath) { + Status = EFI_UNSUPPORTED; + } else { + *Position = (UINT64)lseek (PrivateFile->fd, 0, SEEK_CUR); + Status = (*Position == (UINT64) -1) ? ErrnoToEfiStatus () : EFI_SUCCESS; + } + + return Status; +} + + +/** + Get information about a file. + + @param This Protocol instance pointer. + @param InformationType Type of information to return in Buffer. + @param BufferSize On input size of buffer, on output amount of data in buffer. + @param Buffer The buffer to return data. + + @retval EFI_SUCCESS Data was returned. + @retval EFI_UNSUPPORTED InformationType is not supported. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The device is write protected. + @retval EFI_ACCESS_DENIED The file was open for read only. + @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize. + +**/ +EFI_STATUS +PosixFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer; + int UnixStatus; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + struct statfs buf; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + + Status = EFI_SUCCESS; + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { + Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, BufferSize, Buffer); + } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) { + *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + return EFI_BUFFER_TOO_SMALL; + } + + UnixStatus = statfs (PrivateFile->FileName, &buf); + if (UnixStatus < 0) { + return EFI_DEVICE_ERROR; + } + + FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *) Buffer; + FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + FileSystemInfoBuffer->ReadOnly = FALSE; + + // + // Succeeded + // + FileSystemInfoBuffer->VolumeSize = MultU64x32 (buf.f_blocks, buf.f_bsize); + FileSystemInfoBuffer->FreeSpace = MultU64x32 (buf.f_bavail, buf.f_bsize); + FileSystemInfoBuffer->BlockSize = buf.f_bsize; + + + StrCpy ((CHAR16 *) FileSystemInfoBuffer->VolumeLabel, PrivateRoot->VolumeLabel); + *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + + } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) { + *BufferSize = StrSize (PrivateRoot->VolumeLabel); + return EFI_BUFFER_TOO_SMALL; + } + + StrCpy ((CHAR16 *) Buffer, PrivateRoot->VolumeLabel); + *BufferSize = StrSize (PrivateRoot->VolumeLabel); + + } + + return Status; +} + + +/** + Set information about a file + + @param File Protocol instance pointer. + @param InformationType Type of information in Buffer. + @param BufferSize Size of buffer. + @param Buffer The data to write. + + @retval EFI_SUCCESS Data was returned. + @retval EFI_UNSUPPORTED InformationType is not supported. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The device is write protected. + @retval EFI_ACCESS_DENIED The file was open for read only. + +**/ +EFI_STATUS +PosixFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_FILE_INFO *OldFileInfo; + EFI_FILE_INFO *NewFileInfo; + EFI_STATUS Status; + UINTN OldInfoSize; + mode_t NewAttr; + struct stat OldAttr; + CHAR8 *OldFileName; + CHAR8 *NewFileName; + CHAR8 *CharPointer; + BOOLEAN AttrChangeFlag; + BOOLEAN NameChangeFlag; + BOOLEAN SizeChangeFlag; + BOOLEAN TimeChangeFlag; + struct tm NewLastAccessSystemTime; + struct tm NewLastWriteSystemTime; + EFI_FILE_SYSTEM_INFO *NewFileSystemInfo; + CHAR8 *AsciiFilePtr; + CHAR16 *UnicodeFilePtr; + int UnixStatus; + struct utimbuf Utime; + + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + errno = 0; + Status = EFI_UNSUPPORTED; + OldFileInfo = NewFileInfo = NULL; + OldFileName = NewFileName = NULL; + AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE; + + // + // Set file system information. + // + if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + if (BufferSize < (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel))) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer; + + free (PrivateRoot->VolumeLabel); + + PrivateRoot->VolumeLabel = malloc (StrSize (NewFileSystemInfo->VolumeLabel)); + if (PrivateRoot->VolumeLabel == NULL) { + goto Done; + } + + StrCpy (PrivateRoot->VolumeLabel, NewFileSystemInfo->VolumeLabel); + + Status = EFI_SUCCESS; + goto Done; + } + + // + // Set volume label information. + // + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + StrCpy (PrivateRoot->VolumeLabel, (CHAR16 *) Buffer); + + Status = EFI_SUCCESS; + goto Done; + } + + if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (BufferSize < SIZE_OF_EFI_FILE_INFO) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + // + // Set file/directory information. + // + + // + // Check for invalid set file information parameters. + // + NewFileInfo = (EFI_FILE_INFO *) Buffer; + if (NewFileInfo->Size <= sizeof (EFI_FILE_INFO) || + (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) || + (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF) + ) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + // + // Get current file information so we can determine what kind + // of change request this is. + // + OldInfoSize = 0; + Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, NULL); + if (Status != EFI_BUFFER_TOO_SMALL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + OldFileInfo = malloc (OldInfoSize); + if (OldFileInfo == NULL) { + goto Done; + } + + Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, OldFileInfo); + if (EFI_ERROR (Status)) { + goto Done; + } + + OldFileName = malloc (AsciiStrSize (PrivateFile->FileName)); + if (OldFileInfo == NULL) { + goto Done; + } + + AsciiStrCpy (OldFileName, PrivateFile->FileName); + + // + // Make full pathname from new filename and rootpath. + // + if (NewFileInfo->FileName[0] == '\\') { + NewFileName = malloc (AsciiStrLen (PrivateRoot->FilePath) + 1 + StrLen (NewFileInfo->FileName) + 1); + if (NewFileName == NULL) { + goto Done; + } + + AsciiStrCpy (NewFileName, PrivateRoot->FilePath); + AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName); + UnicodeFilePtr = NewFileInfo->FileName + 1; + *AsciiFilePtr++ ='/'; + } else { + NewFileName = malloc (AsciiStrLen (PrivateFile->FileName) + 2 + StrLen (NewFileInfo->FileName) + 1); + if (NewFileName == NULL) { + goto Done; + } + + AsciiStrCpy (NewFileName, PrivateRoot->FilePath); + AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName); + if ((AsciiFilePtr[-1] != '/') && (NewFileInfo->FileName[0] != '/')) { + // make sure there is a / between Root FilePath and NewFileInfo Filename + AsciiFilePtr[0] = '/'; + AsciiFilePtr[1] = '\0'; + AsciiFilePtr++; + } + UnicodeFilePtr = NewFileInfo->FileName; + } + // Convert to ascii. + while (*UnicodeFilePtr) { + *AsciiFilePtr++ = *UnicodeFilePtr++; + } + *AsciiFilePtr = 0; + + // + // Is there an attribute change request? + // + if (NewFileInfo->Attribute != OldFileInfo->Attribute) { + if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + AttrChangeFlag = TRUE; + } + + // + // Is there a name change request? + // bugbug: - Should really use EFI_UNICODE_COLLATION_PROTOCOL + // + if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) { + NameChangeFlag = TRUE; + } + + // + // Is there a size change request? + // + if (NewFileInfo->FileSize != OldFileInfo->FileSize) { + SizeChangeFlag = TRUE; + } + + // + // Is there a time stamp change request? + // + if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } + + // + // All done if there are no change requests being made. + // + if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) { + Status = EFI_SUCCESS; + goto Done; + } + + // + // Set file or directory information. + // + if (stat (OldFileName, &OldAttr) != 0) { + Status = ErrnoToEfiStatus (); + goto Done; + } + + // + // Name change. + // + if (NameChangeFlag) { + // + // Close the handles first + // + if (PrivateFile->IsOpenedByRead) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) { + } + + if (*CharPointer != 0) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + UnixStatus = rename (OldFileName, NewFileName); + if (UnixStatus == 0) { + // + // modify file name + // + free (PrivateFile->FileName); + + PrivateFile->FileName = malloc (AsciiStrSize (NewFileName)); + if (PrivateFile->FileName == NULL) { + goto Done; + } + + AsciiStrCpy (PrivateFile->FileName, NewFileName); + } else { + Status = EFI_DEVICE_ERROR; + goto Done; + } + } + + // + // Size change + // + if (SizeChangeFlag) { + if (PrivateFile->IsDirectoryPath) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + if (ftruncate (PrivateFile->fd, NewFileInfo->FileSize) != 0) { + Status = ErrnoToEfiStatus (); + goto Done; + } + + } + + // + // Time change + // + if (TimeChangeFlag) { + NewLastAccessSystemTime.tm_year = NewFileInfo->LastAccessTime.Year; + NewLastAccessSystemTime.tm_mon = NewFileInfo->LastAccessTime.Month; + NewLastAccessSystemTime.tm_mday = NewFileInfo->LastAccessTime.Day; + NewLastAccessSystemTime.tm_hour = NewFileInfo->LastAccessTime.Hour; + NewLastAccessSystemTime.tm_min = NewFileInfo->LastAccessTime.Minute; + NewLastAccessSystemTime.tm_sec = NewFileInfo->LastAccessTime.Second; + NewLastAccessSystemTime.tm_isdst = 0; + + Utime.actime = mktime (&NewLastAccessSystemTime); + + NewLastWriteSystemTime.tm_year = NewFileInfo->ModificationTime.Year; + NewLastWriteSystemTime.tm_mon = NewFileInfo->ModificationTime.Month; + NewLastWriteSystemTime.tm_mday = NewFileInfo->ModificationTime.Day; + NewLastWriteSystemTime.tm_hour = NewFileInfo->ModificationTime.Hour; + NewLastWriteSystemTime.tm_min = NewFileInfo->ModificationTime.Minute; + NewLastWriteSystemTime.tm_sec = NewFileInfo->ModificationTime.Second; + NewLastWriteSystemTime.tm_isdst = 0; + + Utime.modtime = mktime (&NewLastWriteSystemTime); + + if (Utime.actime == (time_t)-1 || Utime.modtime == (time_t)-1) { + goto Done; + } + + if (utime (PrivateFile->FileName, &Utime) == -1) { + Status = ErrnoToEfiStatus (); + goto Done; + } + } + + // + // No matter about AttrChangeFlag, Attribute must be set. + // Because operation before may cause attribute change. + // + NewAttr = OldAttr.st_mode; + + if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) { + NewAttr &= ~(S_IRUSR | S_IRGRP | S_IROTH); + } else { + NewAttr |= S_IRUSR; + } + + if (chmod (NewFileName, NewAttr) != 0) { + Status = ErrnoToEfiStatus (); + } + +Done: + if (OldFileInfo != NULL) { + free (OldFileInfo); + } + + if (OldFileName != NULL) { + free (OldFileName); + } + + if (NewFileName != NULL) { + free (NewFileName); + } + + return Status; +} + + +/** + Flush data back for the file handle. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to Open directory are not supported. + @retval EFI_NO_MEDIA The device has no media. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The device is write protected. + @retval EFI_ACCESS_DENIED The file was open for read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +PosixFileFlush ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->IsDirectoryPath) { + return EFI_UNSUPPORTED; + } + + if (PrivateFile->IsOpenedByRead) { + return EFI_ACCESS_DENIED; + } + + if (PrivateFile->fd < 0) { + return EFI_DEVICE_ERROR; + } + + if (fsync (PrivateFile->fd) != 0) { + return ErrnoToEfiStatus (); + } + + return EFI_SUCCESS; +} + + + +EFI_STATUS +PosixFileSystmeThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + UINTN i; + + if (This->Private != NULL) { + return EFI_ALREADY_STARTED; + } + + if (!CompareGuid (This->Protocol, &gEfiSimpleFileSystemProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = malloc (sizeof (EMU_SIMPLE_FILE_SYSTEM_PRIVATE)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Private->FilePath = malloc (StrLen (This->ConfigString) + 1); + if (Private->FilePath == NULL) { + free (Private); + return EFI_OUT_OF_RESOURCES; + } + + // Convert Unicode to Ascii + for (i = 0; This->ConfigString[i] != 0; i++) { + Private->FilePath[i] = This->ConfigString[i]; + } + Private->FilePath[i] = 0; + + + Private->VolumeLabel = malloc (StrLen (L"EFI_EMULATED")); + if (Private->VolumeLabel == NULL) { + free (Private->FilePath); + free (Private); + return EFI_OUT_OF_RESOURCES; + } + StrCpy (Private->VolumeLabel, L"EFI_EMULATED"); + + Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->SimpleFileSystem, &gPosixFileSystemProtocol, sizeof (Private->SimpleFileSystem)); + Private->FileHandlesOpen = FALSE; + + This->Interface = &Private->SimpleFileSystem; + This->Private = Private; + return EFI_SUCCESS; +} + + +EFI_STATUS +PosixFileSystmeThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + if (!CompareGuid (This->Protocol, &gEfiSimpleFileSystemProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = This->Private; + + if (Private->FileHandlesOpen) { + // + // Close only supported if all the EFI_FILE_HANDLEs have been closed. + // + return EFI_NOT_READY; + } + + if (This->Private != NULL) { + if (Private->VolumeLabel == NULL) { + free (Private->VolumeLabel); + } + free (This->Private); + } + + return EFI_SUCCESS; +} + + +EMU_IO_THUNK_PROTOCOL gPosixFileSystemThunkIo = { + &gEfiSimpleFileSystemProtocolGuid, + NULL, + NULL, + 0, + GasketPosixFileSystmeThunkOpen, + GasketPosixFileSystmeThunkClose, + NULL +}; + + diff --git a/InOsEmuPkg/Unix/Sec/Pthreads.c b/InOsEmuPkg/Unix/Sec/Pthreads.c new file mode 100644 index 0000000000..273be5dcc9 --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/Pthreads.c @@ -0,0 +1,233 @@ +/*++ @file + POSIX Pthreads to emulate APs and implement threads + +Copyright (c) 2011, Apple Inc. 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 "SecMain.h" +#include + + +UINTN +EFIAPI +PthreadMutexLock ( + IN VOID *Mutex + ) +{ + return (UINTN)pthread_mutex_lock ((pthread_mutex_t *)Mutex); +} + + + +UINTN +EFIAPI +PthreadMutexUnLock ( + IN VOID *Mutex + ) +{ + return (UINTN)pthread_mutex_unlock ((pthread_mutex_t *)Mutex); +} + + +UINTN +EFIAPI +PthreadMutexTryLock ( + IN VOID *Mutex + ) +{ + return (UINTN)pthread_mutex_trylock ((pthread_mutex_t *)Mutex); +} + + +VOID * +PthreadMutexInit ( + IN VOID + ) +{ + pthread_mutex_t *Mutex; + int err; + + Mutex = malloc (sizeof (pthread_mutex_t)); + err = pthread_mutex_init (Mutex, NULL); + if (err == 0) { + return Mutex; + } + + return NULL; +} + + +UINTN +PthreadMutexDestroy ( + IN VOID *Mutex + ) +{ + if (Mutex != NULL) { + return pthread_mutex_destroy ((pthread_mutex_t *)Mutex); + } + + return -1; +} + +// Can't store this data on PthreadCreate stack so we need a global +typedef struct { + pthread_mutex_t Mutex; + PTREAD_THUNK_THEAD_ENTRY Start; +} THREAD_MANGLE; + +THREAD_MANGLE mThreadMangle = { + PTHREAD_MUTEX_INITIALIZER, + NULL +}; + +VOID * +SecFakePthreadStart ( + VOID *Context + ) +{ + PTREAD_THUNK_THEAD_ENTRY Start; + sigset_t SigMask; + + // Save global on the stack before we unlock + Start = mThreadMangle.Start; + pthread_mutex_unlock (&mThreadMangle.Mutex); + + // Mask all signals to the APs + sigfillset (&SigMask); + pthread_sigmask (SIG_BLOCK, &SigMask, NULL); + + // + // We have to start the thread in SEC as we need to follow + // OS X calling conventions. We can then call back into + // to the callers Start. + // + // This is a great example of how all problems in computer + // science can be solved by adding another level of indirection + // + return (VOID *)ReverseGasketUint64 ((CALL_BACK)Start, (UINTN)Context); +} + +UINTN +PthreadCreate ( + IN VOID *Thread, + IN VOID *Attribute, + IN PTREAD_THUNK_THEAD_ENTRY Start, + IN VOID *Context + ) +{ + int err; + BOOLEAN EnabledOnEntry; + + // + // Threads inherit interrupt state so disable interrupts before we start thread + // + if (SecInterruptEanbled ()) { + SecDisableInterrupt (); + EnabledOnEntry = TRUE; + } else { + EnabledOnEntry = FALSE; + } + + // Aquire lock for global, SecFakePthreadStart runs in a different thread. + pthread_mutex_lock (&mThreadMangle.Mutex); + mThreadMangle.Start = Start; + + err = pthread_create (Thread, Attribute, SecFakePthreadStart, Context); + if (err != 0) { + // Thread failed to launch so release the lock; + pthread_mutex_unlock (&mThreadMangle.Mutex); + } + + if (EnabledOnEntry) { + // Restore interrupt state + SecEnableInterrupt (); + } + + return err; +} + + +VOID +PthreadExit ( + IN VOID *ValuePtr + ) +{ + pthread_exit (ValuePtr); + return; +} + + +UINTN +PthreadSelf ( + VOID + ) +{ + // POSIX currently allows pthread_t to be a structure or arithmetic type. + // Check out sys/types.h to make sure this will work if you are porting. + // On OS X (Darwin) pthread_t is a pointer to a structure so this code works. + return (UINTN)pthread_self (); +} + + +EMU_PTREAD_THUNK_PROTOCOL gPthreadThunk = { + GasketPthreadMutexLock, + GasketPthreadMutexUnLock, + GasketPthreadMutexTryLock, + GasketPthreadMutexInit, + GasketPthreadMutexDestroy, + GasketPthreadCreate, + GasketPthreadExit, + GasketPthreadSelf +}; + + +EFI_STATUS +PthreadOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + if (This->Instance != 0) { + // Only single instance is supported + return EFI_NOT_FOUND; + } + + if (This->ConfigString[0] == L'0') { + // If AP count is zero no need for threads + return EFI_NOT_FOUND; + } + + This->Interface = &gPthreadThunk; + + return EFI_SUCCESS; +} + + +EFI_STATUS +PthreadClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + return EFI_SUCCESS; +} + + +EMU_IO_THUNK_PROTOCOL gPthreadThunkIo = { + &gEmuPthreadThunkProtocolGuid, + NULL, + NULL, + 0, + GasketPthreadOpen, + GasketPthreadClose, + NULL +}; + + diff --git a/InOsEmuPkg/Unix/Sec/SecMain.c b/InOsEmuPkg/Unix/Sec/SecMain.c new file mode 100644 index 0000000000..8677ab5938 --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/SecMain.c @@ -0,0 +1,1148 @@ +/*++ @file + +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. 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 "SecMain.h" + +#ifdef __APPLE__ +#define MAP_ANONYMOUS MAP_ANON +char *gGdbWorkingFileName = NULL; +#endif + + +// +// Globals +// + +EMU_THUNK_PPI mSecEmuThunkPpi = { + GasketSecUnixPeiAutoScan, + GasketSecUnixFdAddress, + GasketSecEmuThunkAddress, + GasketSecUnixPeiLoadFile +}; + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = { + GasketSecTemporaryRamSupport +}; + + + +// +// Default information about where the FD is located. +// This array gets filled in with information from EFI_FIRMWARE_VOLUMES +// EFI_FIRMWARE_VOLUMES is a host environment variable set by system.cmd. +// The number of array elements is allocated base on parsing +// EFI_FIRMWARE_VOLUMES and the memory is never freed. +// +UINTN gFdInfoCount = 0; +EMU_FD_INFO *gFdInfo; + +// +// Array that supports seperate memory rantes. +// The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable. +// The number of array elements is allocated base on parsing +// EFI_MEMORY_SIZE and the memory is never freed. +// +UINTN gSystemMemoryCount = 0; +EMU_SYSTEM_MEMORY *gSystemMemory; + + + +UINTN mImageContextModHandleArraySize = 0; +IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL; + + + +EFI_PHYSICAL_ADDRESS * +MapMemory ( + INTN fd, + UINT64 length, + INTN prot, + INTN flags); + +EFI_STATUS +MapFile ( + IN CHAR8 *FileName, + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + OUT UINT64 *Length + ); + +EFI_STATUS +EFIAPI +SecNt32PeCoffRelocateImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + + +int +main ( + IN int Argc, + IN char **Argv, + IN char **Envp + ) +/*++ + +Routine Description: + Main entry point to SEC for Unix. This is a unix program + +Arguments: + Argc - Number of command line arguments + Argv - Array of command line argument strings + Envp - Array of environmemt variable strings + +Returns: + 0 - Normal exit + 1 - Abnormal exit + +**/ +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS InitialStackMemory; + UINT64 InitialStackMemorySize; + UINTN Index; + UINTN Index1; + UINTN Index2; + UINTN PeiIndex; + CHAR8 *FileName; + BOOLEAN Done; + VOID *PeiCoreFile; + CHAR16 *MemorySizeStr; + CHAR16 *FirmwareVolumesStr; + UINTN *StackPointer; + + setbuf(stdout, 0); + setbuf(stderr, 0); + + MemorySizeStr = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize); + FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume); + + printf ("\nEDK SEC Main UNIX Emulation Environment from edk2.sourceforge.net\n"); + + // + // PPIs pased into PEI_CORE + // + AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEfiTemporaryRamSupportPpiGuid, &mSecTemporaryRamSupportPpi); + AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi); + AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuPeiServicesTableUpdatePpiGuid, NULL); + + SecInitThunkProtocol (); + + // + // Emulator Bus Driver Thunks + // + AddThunkProtocol (&gX11ThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE); + AddThunkProtocol (&gPosixFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE); + + // + // Emulator other Thunks + // + AddThunkProtocol (&gPthreadThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuApCount), FALSE); + + // EmuSecLibConstructor (); + +#ifdef __APPLE__ + // + // We can't use dlopen on OS X, so we need a scheme to get symboles into gdb + // We need to create a temp file that contains gdb commands so we can load + // symbols when we load every PE/COFF image. + // + Index = strlen (*Argv); + gGdbWorkingFileName = malloc (Index + strlen(".gdb") + 1); + strcpy (gGdbWorkingFileName, *Argv); + strcat (gGdbWorkingFileName, ".gdb"); +#endif + + + // + // Allocate space for gSystemMemory Array + // + gSystemMemoryCount = CountSeperatorsInString (MemorySizeStr, '!') + 1; + gSystemMemory = calloc (gSystemMemoryCount, sizeof (EMU_SYSTEM_MEMORY)); + if (gSystemMemory == NULL) { + printf ("ERROR : Can not allocate memory for system. Exiting.\n"); + exit (1); + } + // + // Allocate space for gSystemMemory Array + // + gFdInfoCount = CountSeperatorsInString (FirmwareVolumesStr, '!') + 1; + gFdInfo = calloc (gFdInfoCount, sizeof (EMU_FD_INFO)); + if (gFdInfo == NULL) { + printf ("ERROR : Can not allocate memory for fd info. Exiting.\n"); + exit (1); + } + + printf (" BootMode 0x%02x\n", (unsigned int)PcdGet32 (PcdEmuBootMode)); + + // + // Open up a 128K file to emulate temp memory for PEI. + // on a real platform this would be SRAM, or using the cache as RAM. + // Set InitialStackMemory to zero so UnixOpenFile will allocate a new mapping + // + InitialStackMemorySize = STACK_SIZE; + InitialStackMemory = (UINTN)MapMemory(0, + (UINT32) InitialStackMemorySize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANONYMOUS | MAP_PRIVATE); + if (InitialStackMemory == 0) { + printf ("ERROR : Can not open SecStack Exiting\n"); + exit (1); + } + + printf (" SEC passing in %u KB of temp RAM at 0x%08lx to PEI\n", + (unsigned int)(InitialStackMemorySize / 1024), + (unsigned long)InitialStackMemory); + + for (StackPointer = (UINTN*) (UINTN) InitialStackMemory; + StackPointer < (UINTN*)(UINTN)((UINTN) InitialStackMemory + (UINT64) InitialStackMemorySize); + StackPointer ++) { + *StackPointer = 0x5AA55AA5; + } + + // + // Open All the firmware volumes and remember the info in the gFdInfo global + // + FileName = (CHAR8 *)malloc (StrLen (FirmwareVolumesStr) + 1); + if (FileName == NULL) { + printf ("ERROR : Can not allocate memory for firmware volume string\n"); + exit (1); + } + + Index2 = 0; + for (Done = FALSE, Index = 0, PeiIndex = 0, PeiCoreFile = NULL; + FirmwareVolumesStr[Index2] != 0; + Index++) { + for (Index1 = 0; (FirmwareVolumesStr[Index2] != '!') && (FirmwareVolumesStr[Index2] != 0); Index2++) + FileName[Index1++] = FirmwareVolumesStr[Index2]; + if (FirmwareVolumesStr[Index2] == '!') + Index2++; + FileName[Index1] = '\0'; + + // + // Open the FD and remmeber where it got mapped into our processes address space + // + Status = MapFile ( + FileName, + &gFdInfo[Index].Address, + &gFdInfo[Index].Size + ); + if (EFI_ERROR (Status)) { + printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName, (unsigned int)Status); + exit (1); + } + + printf (" FD loaded from %s at 0x%08lx", + FileName, (unsigned long)gFdInfo[Index].Address); + + if (PeiCoreFile == NULL) { + // + // Assume the beginning of the FD is an FV and look for the PEI Core. + // Load the first one we find. + // + Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile); + if (!EFI_ERROR (Status)) { + PeiIndex = Index; + printf (" contains SEC Core"); + } + } + + printf ("\n"); + } + // + // Calculate memory regions and store the information in the gSystemMemory + // global for later use. The autosizing code will use this data to + // map this memory into the SEC process memory space. + // + Index1 = 0; + Index = 0; + while (1) { + UINTN val = 0; + // + // Save the size of the memory. + // + while (MemorySizeStr[Index1] >= '0' && MemorySizeStr[Index1] <= '9') { + val = val * 10 + MemorySizeStr[Index1] - '0'; + Index1++; + } + gSystemMemory[Index++].Size = val * 0x100000; + if (MemorySizeStr[Index1] == 0) + break; + Index1++; + } + + printf ("\n"); + + // + // Hand off to PEI Core + // + SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile); + + // + // If we get here, then the PEI Core returned. This is an error as PEI should + // always hand off to DXE. + // + printf ("ERROR : PEI Core returned\n"); + exit (1); +} + +EFI_PHYSICAL_ADDRESS * +MapMemory ( + INTN fd, + UINT64 length, + INTN prot, + INTN flags) +{ + STATIC UINTN base = 0x40000000; + CONST UINTN align = (1 << 24); + VOID *res = NULL; + BOOLEAN isAligned = 0; + + // + // Try to get an aligned block somewhere in the address space of this + // process. + // + while((!isAligned) && (base != 0)) { + res = mmap ((void *)base, length, prot, flags, fd, 0); + if (res == MAP_FAILED) { + return NULL; + } + if ((((UINTN)res) & ~(align-1)) == (UINTN)res) { + isAligned=1; + } + else { + munmap(res, length); + base += align; + } + } + return res; +} + +EFI_STATUS +MapFile ( + IN CHAR8 *FileName, + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + OUT UINT64 *Length + ) +/*++ + +Routine Description: + Opens and memory maps a file using Unix services. If BaseAddress is non zero + the process will try and allocate the memory starting at BaseAddress. + +Arguments: + FileName - The name of the file to open and map + MapSize - The amount of the file to map in bytes + CreationDisposition - The flags to pass to CreateFile(). Use to create new files for + memory emulation, and exiting files for firmware volume emulation + BaseAddress - The base address of the mapped file in the user address space. + If passed in as NULL the a new memory region is used. + If passed in as non NULL the request memory region is used for + the mapping of the file into the process space. + Length - The size of the mapped region in bytes + +Returns: + EFI_SUCCESS - The file was opened and mapped. + EFI_NOT_FOUND - FileName was not found in the current directory + EFI_DEVICE_ERROR - An error occured attempting to map the opened file + +**/ +{ + int fd; + VOID *res; + UINTN FileSize; + + fd = open (FileName, O_RDONLY); + if (fd < 0) + return EFI_NOT_FOUND; + FileSize = lseek (fd, 0, SEEK_END); + + + res = MapMemory(fd, FileSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); + + close (fd); + + if (res == MAP_FAILED) + return EFI_DEVICE_ERROR; + + *Length = (UINT64) FileSize; + *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res; + + return EFI_SUCCESS; +} + + + +VOID +SecLoadFromCore ( + IN UINTN LargestRegion, + IN UINTN LargestRegionSize, + IN UINTN BootFirmwareVolumeBase, + IN VOID *PeiCorePe32File + ) +/*++ + +Routine Description: + This is the service to load the PEI Core from the Firmware Volume + +Arguments: + LargestRegion - Memory to use for PEI. + LargestRegionSize - Size of Memory to use for PEI + BootFirmwareVolumeBase - Start of the Boot FV + PeiCorePe32File - PEI Core PE32 + +Returns: + Success means control is transfered and thus we should never return + +**/ +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS TopOfMemory; + VOID *TopOfStack; + UINT64 PeiCoreSize; + EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint; + EFI_PHYSICAL_ADDRESS PeiImageAddress; + EFI_SEC_PEI_HAND_OFF *SecCoreData; + UINTN PeiStackSize; + + // + // Compute Top Of Memory for Stack and PEI Core Allocations + // + TopOfMemory = LargestRegion + LargestRegionSize; + PeiStackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1); + + // + // |-----------| <---- TemporaryRamBase + TemporaryRamSize + // | Heap | + // | | + // |-----------| <---- StackBase / PeiTemporaryMemoryBase + // | | + // | Stack | + // |-----------| <---- TemporaryRamBase + // + TopOfStack = (VOID *)(LargestRegion + PeiStackSize); + TopOfMemory = LargestRegion + PeiStackSize; + + // + // Reservet space for storing PeiCore's parament in stack. + // + TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + + // + // Bind this information into the SEC hand-off state + // + SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN) TopOfStack; + SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF); + SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase; + SecCoreData->BootFirmwareVolumeSize = PcdGet32 (PcdEmuFirmwareFdSize); + SecCoreData->TemporaryRamBase = (VOID*)(UINTN)LargestRegion; + SecCoreData->TemporaryRamSize = STACK_SIZE; + SecCoreData->StackBase = SecCoreData->TemporaryRamBase; + SecCoreData->StackSize = PeiStackSize; + SecCoreData->PeiTemporaryRamBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + PeiStackSize); + SecCoreData->PeiTemporaryRamSize = STACK_SIZE - PeiStackSize; + + // + // Load the PEI Core from a Firmware Volume + // + Status = SecUnixPeiLoadFile ( + PeiCorePe32File, + &PeiImageAddress, + &PeiCoreSize, + &PeiCoreEntryPoint + ); + if (EFI_ERROR (Status)) { + return ; + } + + // + // Transfer control to the PEI Core + // + PeiSwitchStacks ( + (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint, + SecCoreData, + (VOID *)GetThunkPpiList (), + NULL, + TopOfStack + ); + // + // If we get here, then the PEI Core returned. This is an error + // + return ; +} + +EFI_STATUS +EFIAPI +SecUnixPeiAutoScan ( + IN UINTN Index, + OUT EFI_PHYSICAL_ADDRESS *MemoryBase, + OUT UINT64 *MemorySize + ) +/*++ + +Routine Description: + This service is called from Index == 0 until it returns EFI_UNSUPPORTED. + It allows discontiguous memory regions to be supported by the emulator. + It uses gSystemMemory[] and gSystemMemoryCount that were created by + parsing the host environment variable EFI_MEMORY_SIZE. + The size comes from the varaible and the address comes from the call to + UnixOpenFile. + +Arguments: + Index - Which memory region to use + MemoryBase - Return Base address of memory region + MemorySize - Return size in bytes of the memory region + +Returns: + EFI_SUCCESS - If memory region was mapped + EFI_UNSUPPORTED - If Index is not supported + +**/ +{ + void *res; + + if (Index >= gSystemMemoryCount) { + return EFI_UNSUPPORTED; + } + + *MemoryBase = 0; + res = MapMemory(0, gSystemMemory[Index].Size, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS); + if (res == MAP_FAILED) + return EFI_DEVICE_ERROR; + *MemorySize = gSystemMemory[Index].Size; + *MemoryBase = (UINTN)res; + gSystemMemory[Index].Memory = *MemoryBase; + + return EFI_SUCCESS; +} + +VOID * +EFIAPI +SecEmuThunkAddress ( + VOID + ) +/*++ + +Routine Description: + Since the SEC is the only Unix program in stack it must export + an interface to do POSIX calls. gUnix is initailized in UnixThunk.c. + +Arguments: + InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL); + InterfaceBase - Address of the gUnix global + +Returns: + EFI_SUCCESS - Data returned + +**/ +{ + return &gEmuThunkProtocol; +} + + +EFI_STATUS +SecUnixPeiLoadFile ( + IN VOID *Pe32Data, + OUT EFI_PHYSICAL_ADDRESS *ImageAddress, + OUT UINT64 *ImageSize, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint + ) +/*++ + +Routine Description: + Loads and relocates a PE/COFF image into memory. + +Arguments: + Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated + ImageAddress - The base address of the relocated PE/COFF image + ImageSize - The size of the relocated PE/COFF image + EntryPoint - The entry point of the relocated PE/COFF image + +Returns: + EFI_SUCCESS - The file was loaded and relocated + EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file + +**/ +{ + EFI_STATUS Status; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle = Pe32Data; + + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecImageRead; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + + // + // Allocate space in UNIX (not emulator) memory. Extra space is for alignment + // + ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) MapMemory ( + 0, + (UINT32) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANONYMOUS | MAP_PRIVATE + ); + if (ImageContext.ImageAddress == 0) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Align buffer on section boundry + // + ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; + ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1)); + + + Status = PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + + SecPeCoffRelocateImageExtraAction (&ImageContext); + + // + // BugBug: Flush Instruction Cache Here when CPU Lib is ready + // + + *ImageAddress = ImageContext.ImageAddress; + *ImageSize = ImageContext.ImageSize; + *EntryPoint = ImageContext.EntryPoint; + + return EFI_SUCCESS; +} + + +RETURN_STATUS +EFIAPI +SecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS ImageAddress; + UINT64 ImageSize; + EFI_PHYSICAL_ADDRESS PhysEntryPoint; + + Status = SecUnixPeiLoadFile (Pe32Data, &ImageAddress, &ImageSize, &PhysEntryPoint); + + *EntryPoint = (VOID *)(UINTN)PhysEntryPoint; + return Status; +} + + + +EFI_STATUS +EFIAPI +SecUnixFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ) +/*++ + +Routine Description: + Return the FD Size and base address. Since the FD is loaded from a + file into host memory only the SEC will know it's address. + +Arguments: + Index - Which FD, starts at zero. + FdSize - Size of the FD in bytes + FdBase - Start address of the FD. Assume it points to an FV Header + FixUp - Difference between actual FD address and build address + +Returns: + EFI_SUCCESS - Return the Base address and size of the FV + EFI_UNSUPPORTED - Index does nto map to an FD in the system + +**/ +{ + if (Index >= gFdInfoCount) { + return EFI_UNSUPPORTED; + } + + *FdBase = gFdInfo[Index].Address; + *FdSize = gFdInfo[Index].Size; + *FixUp = 0; + + if (*FdBase == 0 && *FdSize == 0) { + return EFI_UNSUPPORTED; + } + + if (Index == 0) { + // + // FD 0 has XIP code and well known PCD values + // If the memory buffer could not be allocated at the FD build address + // the Fixup is the difference. + // + *FixUp = *FdBase - PcdGet64 (PcdEmuFdBaseAddress); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SecImageRead ( + 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; +} + +UINTN +CountSeperatorsInString ( + IN const CHAR16 *String, + IN CHAR16 Seperator + ) +/*++ + +Routine Description: + Count the number of seperators in String + +Arguments: + String - String to process + Seperator - Item to count + +Returns: + Number of Seperator in String + +**/ +{ + UINTN Count; + + for (Count = 0; *String != '\0'; String++) { + if (*String == Seperator) { + Count++; + } + } + + return Count; +} + + +EFI_STATUS +AddHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN VOID *ModHandle + ) +/*++ + +Routine Description: + Store the ModHandle in an array indexed by the Pdb File name. + The ModHandle is needed to unload the image. + +Arguments: + ImageContext - Input data returned from PE Laoder Library. Used to find the + .PDB file name of the PE Image. + ModHandle - Returned from LoadLibraryEx() and stored for call to + FreeLibrary(). + +Returns: + EFI_SUCCESS - ModHandle was stored. + +**/ +{ + UINTN Index; + IMAGE_CONTEXT_TO_MOD_HANDLE *Array; + UINTN PreviousSize; + + + Array = mImageContextModHandleArray; + for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) { + if (Array->ImageContext == NULL) { + // + // Make a copy of the stirng and store the ModHandle + // + Array->ImageContext = ImageContext; + Array->ModHandle = ModHandle; + return EFI_SUCCESS; + } + } + + // + // No free space in mImageContextModHandleArray so grow it by + // IMAGE_CONTEXT_TO_MOD_HANDLE entires. realloc will + // copy the old values to the new locaiton. But it does + // not zero the new memory area. + // + PreviousSize = mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE); + mImageContextModHandleArraySize += MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE; + + mImageContextModHandleArray = realloc (mImageContextModHandleArray, mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE)); + if (mImageContextModHandleArray == NULL) { + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + memset (mImageContextModHandleArray + PreviousSize, 0, MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE)); + + return AddHandle (ImageContext, ModHandle); +} + + +VOID * +RemoveHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +/*++ + +Routine Description: + Return the ModHandle and delete the entry in the array. + +Arguments: + ImageContext - Input data returned from PE Laoder Library. Used to find the + .PDB file name of the PE Image. + +Returns: + ModHandle - ModHandle assoicated with ImageContext is returned + NULL - No ModHandle associated with ImageContext + +**/ +{ + UINTN Index; + IMAGE_CONTEXT_TO_MOD_HANDLE *Array; + + if (ImageContext->PdbPointer == NULL) { + // + // If no PDB pointer there is no ModHandle so return NULL + // + return NULL; + } + + Array = mImageContextModHandleArray; + for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) { + if (Array->ImageContext == ImageContext) { + // + // If you find a match return it and delete the entry + // + Array->ImageContext = NULL; + return Array->ModHandle; + } + } + + return NULL; +} + + + +// +// Target for gdb breakpoint in a script that uses gGdbWorkingFileName to source a +// add-symbol-file command. Hey what can you say scripting in gdb is not that great.... +// +// Put .gdbinit in the CWD where you do gdb SecMain.dll for source level debug +// +// cat .gdbinit +// b SecGdbScriptBreak +// command +// silent +// source SecMain.dll.gdb +// c +// end +// +VOID +SecGdbScriptBreak ( + VOID + ) +{ +} + +VOID +SecUnixLoaderBreak ( + VOID + ) +{ +} + +BOOLEAN +IsPdbFile ( + IN CHAR8 *PdbFileName + ) +{ + UINTN Len; + + if (PdbFileName == NULL) { + return FALSE; + } + + Len = strlen (PdbFileName); + if ((Len < 5)|| (PdbFileName[Len - 4] != '.')) { + return FALSE; + } + + if ((PdbFileName[Len - 3] == 'P' || PdbFileName[Len - 3] == 'p') && + (PdbFileName[Len - 2] == 'D' || PdbFileName[Len - 2] == 'd') && + (PdbFileName[Len - 1] == 'B' || PdbFileName[Len - 1] == 'b')) { + return TRUE; + } + + return FALSE; +} + + +#define MAX_SPRINT_BUFFER_SIZE 0x200 + +void +PrintLoadAddress ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (ImageContext->PdbPointer == NULL) { + fprintf (stderr, + "0x%08lx Loading NO DEBUG with entry point 0x%08lx\n", + (unsigned long)(ImageContext->ImageAddress), + (unsigned long)ImageContext->EntryPoint + ); + } else { + fprintf (stderr, + "0x%08lx Loading %s with entry point 0x%08lx\n", + (unsigned long)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), + ImageContext->PdbPointer, + (unsigned long)ImageContext->EntryPoint + ); + } + // Keep output synced up + fflush (stderr); +} + + +VOID +EFIAPI +SecPeCoffRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + +#ifdef __APPLE__ + BOOLEAN EnabledOnEntry; + + // + // Make sure writting of the file is an atomic operation + // + if (SecInterruptEanbled ()) { + SecDisableInterrupt (); + EnabledOnEntry = TRUE; + } else { + EnabledOnEntry = FALSE; + } + + PrintLoadAddress (ImageContext); + + // + // In mach-o (OS X executable) dlopen() can only load files in the MH_DYLIB of MH_BUNDLE format. + // To convert to PE/COFF we need to construct a mach-o with the MH_PRELOAD format. We create + // .dSYM files for the PE/COFF images that can be used by gdb for source level debugging. + // + FILE *GdbTempFile; + + // + // In the Mach-O to PE/COFF conversion the size of the PE/COFF headers is not accounted for. + // Thus we need to skip over the PE/COFF header when giving load addresses for our symbol table. + // + if (ImageContext->PdbPointer != NULL && !IsPdbFile (ImageContext->PdbPointer)) { + // + // Now we have a database of the images that are currently loaded + // + + // + // 'symbol-file' will clear out currnet symbol mappings in gdb. + // you can do a 'add-symbol-file filename address' for every image we loaded to get source + // level debug in gdb. Note Sec, being a true application will work differently. + // + // We add the PE/COFF header size into the image as the mach-O does not have a header in + // loaded into system memory. + // + // This gives us a data base of gdb commands and after something is unloaded that entry will be + // removed. We don't yet have the scheme of how to comunicate with gdb, but we have the + // data base of info ready to roll. + // + // We could use qXfer:libraries:read, but OS X GDB does not currently support it. + // + // // ImageContext->PdbPointer + // // ImageContext->ImageAddress + ImageContext->SizeOfHeaders + // + // + // + + // + // Write the file we need for the gdb script + // + GdbTempFile = fopen (gGdbWorkingFileName, "w"); + if (GdbTempFile != NULL) { + fprintf (GdbTempFile, "add-symbol-file %s 0x%08lx\n", ImageContext->PdbPointer, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)); + fclose (GdbTempFile); + + // + // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint. + // Hey what can you say scripting in gdb is not that great.... + // + SecGdbScriptBreak (); + } else { + ASSERT (FALSE); + } + + AddHandle (ImageContext, ImageContext->PdbPointer); + + if (EnabledOnEntry) { + SecEnableInterrupt (); + } + + + } + +#else + + void *Handle = NULL; + void *Entry = NULL; + + if (ImageContext->PdbPointer == NULL) { + return; + } + + if (!IsPdbFile (ImageContext->PdbPointer)) { + return; + } + + fprintf (stderr, + "Loading %s 0x%08lx - entry point 0x%08lx\n", + ImageContext->PdbPointer, + (unsigned long)ImageContext->ImageAddress, + (unsigned long)ImageContext->EntryPoint); + + Handle = dlopen (ImageContext->PdbPointer, RTLD_NOW); + + if (Handle) { + Entry = dlsym (Handle, "_ModuleEntryPoint"); + } else { + printf("%s\n", dlerror()); + } + + if (Entry != NULL) { + ImageContext->EntryPoint = (UINTN)Entry; + printf("Change %s Entrypoint to :0x%08lx\n", ImageContext->PdbPointer, (unsigned long)Entry); + } + + SecUnixLoaderBreak (); + +#endif + + return; +} + + +VOID +EFIAPI +SecPeCoffUnloadImageExtraAction ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + VOID *Handle; + + Handle = RemoveHandle (ImageContext); + +#ifdef __APPLE__ + FILE *GdbTempFile; + BOOLEAN EnabledOnEntry; + + if (Handle != NULL) { + // + // Need to skip .PDB files created from VC++ + // + if (!IsPdbFile (ImageContext->PdbPointer)) { + if (SecInterruptEanbled ()) { + SecDisableInterrupt (); + EnabledOnEntry = TRUE; + } else { + EnabledOnEntry = FALSE; + } + + // + // Write the file we need for the gdb script + // + GdbTempFile = fopen (gGdbWorkingFileName, "w"); + if (GdbTempFile != NULL) { + fprintf (GdbTempFile, "remove-symbol-file %s\n", ImageContext->PdbPointer); + fclose (GdbTempFile); + + // + // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint. + // Hey what can you say scripting in gdb is not that great.... + // + SecGdbScriptBreak (); + } else { + ASSERT (FALSE); + } + + if (EnabledOnEntry) { + SecEnableInterrupt (); + } + } + } + +#else + // + // Don't want to confuse gdb with symbols for something that got unloaded + // + if (Handle != NULL) { + dlclose (Handle); + } + +#endif + return; +} + + diff --git a/InOsEmuPkg/Unix/Sec/SecMain.h b/InOsEmuPkg/Unix/Sec/SecMain.h new file mode 100644 index 0000000000..6e352b11b5 --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/SecMain.h @@ -0,0 +1,306 @@ +/*++ @file + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. 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 _SEC_MAIN_H__ +#define _SEC_MAIN_H__ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#if __CYGWIN__ +#include +#else +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#include +#include +#include +#define _XOPEN_SOURCE +#ifndef _Bool + #define _Bool char // for clang debug +#endif +#else +#include +#include +#endif + +#include + +#include "Gasket.h" + + +#define STACK_SIZE 0x20000 + +typedef struct { + EFI_PHYSICAL_ADDRESS Address; + UINT64 Size; +} EMU_FD_INFO; + +typedef struct { + EFI_PHYSICAL_ADDRESS Memory; + UINT64 Size; +} EMU_SYSTEM_MEMORY; + + +#define MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE 0x100 + +typedef struct { + PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext; + VOID *ModHandle; +} IMAGE_CONTEXT_TO_MOD_HANDLE; + + +EFI_STATUS +EFIAPI +SecUnixPeiLoadFile ( + VOID *Pe32Data, + EFI_PHYSICAL_ADDRESS *ImageAddress, + UINT64 *ImageSize, + EFI_PHYSICAL_ADDRESS *EntryPoint + ); + +int +main ( + IN int Argc, + IN char **Argv, + IN char **Envp + ); + +VOID +SecLoadFromCore ( + IN UINTN LargestRegion, + IN UINTN LargestRegionSize, + IN UINTN BootFirmwareVolumeBase, + IN VOID *PeiCoreFile + ); + +EFI_STATUS +SecLoadFile ( + IN VOID *Pe32Data, + IN EFI_PHYSICAL_ADDRESS *ImageAddress, + IN UINT64 *ImageSize, + IN EFI_PHYSICAL_ADDRESS *EntryPoint + ); + +EFI_STATUS +SecFfsFindPeiCore ( + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, + OUT VOID **Pe32Data + ); + +EFI_STATUS +SecFfsFindNextFile ( + IN EFI_FV_FILETYPE SearchType, + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, + IN OUT EFI_FFS_FILE_HEADER **FileHeader + ); + +EFI_STATUS +SecFfsFindSectionData ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT VOID **SectionData + ); + +EFI_STATUS +EFIAPI +SecUnixPeCoffLoaderLoadAsDll ( + IN CHAR8 *PdbFileName, + IN VOID **ImageEntryPoint, + OUT VOID **ModHandle + ); + +EFI_STATUS +EFIAPI +SecUnixPeCoffLoaderFreeLibrary ( + OUT VOID *ModHandle + ); + +EFI_STATUS +EFIAPI +SecUnixFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ) +; + +EFI_STATUS +EFIAPI +GasketSecUnixFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ) +; + + +EFI_STATUS +GetImageReadFunction ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN EFI_PHYSICAL_ADDRESS *TopOfMemory + ); + +EFI_STATUS +EFIAPI +SecImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ); + +CHAR16 * +AsciiToUnicode ( + IN CHAR8 *Ascii, + IN UINTN *StrLen OPTIONAL + ); + +UINTN +CountSeperatorsInString ( + IN const CHAR16 *String, + IN CHAR16 Seperator + ); + +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +EFI_STATUS +EFIAPI +GasketSecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + + +RETURN_STATUS +EFIAPI +SecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ); + +VOID +EFIAPI +SecPeCoffRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +VOID +EFIAPI +SecPeCoffLoaderUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + + +VOID +EFIAPI +PeiSwitchStacks ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *Context3, OPTIONAL + IN VOID *NewStack + ); + +VOID +SecInitThunkProtocol ( + VOID + ); + + +VOID SecSleep (UINT64 Milliseconds); +VOID SecEnableInterrupt (VOID); +VOID SecDisableInterrupt (VOID); +BOOLEAN SecInterruptEanbled (VOID); + + +extern EMU_THUNK_PROTOCOL gEmuThunkProtocol; +extern EMU_IO_THUNK_PROTOCOL gX11ThunkIo; +extern EMU_IO_THUNK_PROTOCOL gPosixFileSystemThunkIo; +extern EMU_IO_THUNK_PROTOCOL gPthreadThunkIo; + + +#endif diff --git a/InOsEmuPkg/Unix/Sec/SecMain.inf b/InOsEmuPkg/Unix/Sec/SecMain.inf new file mode 100644 index 0000000000..24a36be955 --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/SecMain.inf @@ -0,0 +1,118 @@ +## @file +# Entry Point of Emu Emulator +# +# Main executable file of Unix Emulator that loads PEI core after initialization finished. +# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2011, Apple Inc. 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecMain + FILE_GUID = 8863C0AD-7724-C84B-88E5-A33B116D1485 + MODULE_TYPE = USER_DEFINED +# MODULE_TYPE = BASE + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + SecMain.c + EmuThunk.c + FwVol.c + X11GraphicsWindow.c + Pthreads.c + PosixFileSystem.c + +[Sources.X64] + X64/Gasket.S # convert between Emu x86_64 ABI and EFI X64 ABI + X64/SwitchStack.S + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + InOsEmuPkg/InOsEmuPkg.dec + InOsEmuPkg/InOsEmuPkg.dec + +[LibraryClasses] + DebugLib + PcdLib + PrintLib + BaseMemoryLib + BaseLib + PeCoffLib + ThunkPpiList + ThunkProtocolList + + +[Ppis] + gEfiPeiStatusCodePpiGuid # PPI ALWAYS_PRODUCED + gEfiTemporaryRamSupportPpiGuid + gEmuThunkPpiGuid + gEmuPeiServicesTableUpdatePpiGuid + +[Protocols] + gEmuIoThunkProtocolGuid + gEmuIoThunkProtocolGuid + gEmuGraphicsWindowProtocolGuid + gEmuPthreadThunkProtocolGuid + gEfiSimpleFileSystemProtocolGuid + + +[Guids] + gEfiFileSystemVolumeLabelInfoIdGuid # SOMETIMES_CONSUMED + gEfiFileInfoGuid # SOMETIMES_CONSUMED + gEfiFileSystemInfoGuid # SOMETIMES_CONSUMED + +[Pcd] + gInOsEmuPkgTokenSpaceGuid.PcdEmuBootMode + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume + gInOsEmuPkgTokenSpaceGuid.PcdEmuMemorySize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFdBaseAddress + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareFdSize + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize + gInOsEmuPkgTokenSpaceGuid.PcdEmuApCount + gInOsEmuPkgTokenSpaceGuid.PcdEmuPhysicalDisk + gInOsEmuPkgTokenSpaceGuid.PcdEmuVirtualDisk + gInOsEmuPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window" + gInOsEmuPkgTokenSpaceGuid.PcdEmuFileSystem + gInOsEmuPkgTokenSpaceGuid.PcdEmuSerialPort + gInOsEmuPkgTokenSpaceGuid.PcdEmuNetworkInterface + + +[BuildOptions] + GCC:*_*_IA32_DLINK_FLAGS == -o $(BIN_DIR)/SecMain -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o -L/usr/X11R6/lib -lXext -lX11 /usr/lib/crtn.o + GCC:*_*_*_DLINK2_FLAGS == -lc + GCC:*_*_IA32_CC_FLAGS == -m32 -g -fshort-wchar -fno-strict-aliasing -Wall -malign-double -idirafter/usr/include -c -include $(DEST_DIR_DEBUG)/AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings + GCC:*_*_IA32_PP_FLAGS == -m32 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h + GCC:*_*_IA32_ASM_FLAGS == -m32 -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h + + GCC:*_*_X64_DLINK_FLAGS == -o $(BIN_DIR)/SecMain -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/crt1.o /usr/lib/crti.o -L/usr/X11R6/lib -lXext -lX11 /usr/lib/crtn.o + GCC:*_*_X64_CC_FLAGS == -m64 -g -fshort-wchar -fno-strict-aliasing -Wall -malign-double -idirafter/usr/include -c -include $(DEST_DIR_DEBUG)/AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings + GCC:*_*_X64_PP_FLAGS == -m64 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h + GCC:*_*_X64_ASM_FLAGS == -m64 -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h + +# +# Need to do this link via gcc and not ld as the pathing to libraries changes from OS version to OS version +# + XCODE:*_*_IA32_DLINK_PATH == gcc + XCODE:*_*_IA32_DLINK_FLAGS == -arch i386 -o $(BIN_DIR)/SecMain -L/usr/X11R6/lib -lXext -lX11 -framework IOKit -framework Carbon + XCODE:*_*_IA32_ASM_FLAGS == -arch i386 -g + + XCODE:*_*_X64_DLINK_PATH == gcc + XCODE:*_*_X64_DLINK_FLAGS == -o $(BIN_DIR)/SecMain -L/usr/X11R6/lib -lXext -lX11 -lIOKit -framework Carbon + XCODE:*_*_X64_ASM_FLAGS == -g diff --git a/InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c b/InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c new file mode 100644 index 0000000000..1920f33c99 --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/X11GraphicsWindow.c @@ -0,0 +1,976 @@ +/*++ @file + +Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. 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 "SecMain.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define KEYSYM_LOWER 0 +#define KEYSYM_UPPER 1 + +/* XQueryPointer */ + +struct uga_drv_shift_mask { + unsigned char shift; + unsigned char size; + unsigned char csize; +}; + +#define NBR_KEYS 32 +typedef struct { + EMU_GRAPHICS_WINDOW_PROTOCOL GraphicsIo; + + Display *display; + int screen; /* values for window_size in main */ + Window win; + GC gc; + Visual *visual; + + int depth; + unsigned int width; + unsigned int height; + unsigned int line_bytes; + unsigned int pixel_shift; + unsigned char *image_data; + + struct uga_drv_shift_mask r, g, b; + + int use_shm; + XShmSegmentInfo xshm_info; + XImage *image; + + unsigned int key_rd; + unsigned int key_wr; + unsigned int key_count; + EFI_KEY_DATA keys[NBR_KEYS]; + + EFI_KEY_STATE KeyState; + + EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeRegisterdKeyCallback; + EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakRegisterdKeyCallback; + VOID *RegisterdKeyCallbackContext; + + int previous_x; + int previous_y; + EFI_SIMPLE_POINTER_STATE pointer_state; + int pointer_state_changed; +} GRAPHICS_IO_PRIVATE; + +void +HandleEvents(GRAPHICS_IO_PRIVATE *drv); + +void +fill_shift_mask (struct uga_drv_shift_mask *sm, unsigned long mask) +{ + sm->shift = 0; + sm->size = 0; + while ((mask & 1) == 0) + { + mask >>= 1; + sm->shift++; + } + while (mask & 1) + { + sm->size++; + mask >>= 1; + } + sm->csize = 8 - sm->size; +} + +int +TryCreateShmImage ( + IN GRAPHICS_IO_PRIVATE *drv + ) +{ + drv->image = XShmCreateImage (drv->display, drv->visual, + drv->depth, ZPixmap, NULL, &drv->xshm_info, + drv->width, drv->height); + if (drv->image == NULL) + return 0; + + switch (drv->image->bitmap_unit) { + case 32: + drv->pixel_shift = 2; + break; + case 16: + drv->pixel_shift = 1; + break; + case 8: + drv->pixel_shift = 0; + break; + } + + drv->xshm_info.shmid = shmget + (IPC_PRIVATE, drv->image->bytes_per_line * drv->image->height, + IPC_CREAT | 0777); + if (drv->xshm_info.shmid < 0) { + XDestroyImage(drv->image); + return 0; + } + + drv->image_data = shmat (drv->xshm_info.shmid, NULL, 0); + if(!drv->image_data) { + shmctl (drv->xshm_info.shmid, IPC_RMID, NULL); + XDestroyImage(drv->image); + return 0; + } + +#ifndef __APPLE__ + // + // This closes shared memory in real time on OS X. Only closes after folks quit using + // it on Linux. + // + /* Can this fail ? */ + shmctl (drv->xshm_info.shmid, IPC_RMID, NULL); +#endif + + drv->xshm_info.shmaddr = (char*)drv->image_data; + drv->image->data = (char*)drv->image_data; + + if (!XShmAttach (drv->display, &drv->xshm_info)) { + shmdt (drv->image_data); + XDestroyImage(drv->image); + return 0; + } + return 1; +} + + +EFI_STATUS +X11Size( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN UINT32 Width, + IN UINT32 Height + ) +{ + GRAPHICS_IO_PRIVATE *drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + XSizeHints size_hints; + + /* Destroy current buffer if created. */ + if (drv->image != NULL) + { + /* Before destroy buffer, need to make sure the buffer available for access. */ + XDestroyImage(drv->image); + + if (drv->use_shm) + shmdt (drv->image_data); + + drv->image_data = NULL; + drv->image = NULL; + } + + drv->width = Width; + drv->height = Height; + XResizeWindow (drv->display, drv->win, Width, Height); + + /* Allocate image. */ + if (XShmQueryExtension(drv->display) && TryCreateShmImage(drv)) { + drv->use_shm = 1; + } else { + drv->use_shm = 0; + if (drv->depth > 16) + drv->pixel_shift = 2; + else if (drv->depth > 8) + drv->pixel_shift = 1; + else + drv->pixel_shift = 0; + + drv->image_data = malloc((drv->width * drv->height) << drv->pixel_shift); + drv->image = XCreateImage (drv->display, drv->visual, drv->depth, + ZPixmap, 0, (char *)drv->image_data, + drv->width, drv->height, + 8 << drv->pixel_shift, 0); + } + drv->line_bytes = drv->image->bytes_per_line; + fill_shift_mask (&drv->r, drv->image->red_mask); + fill_shift_mask (&drv->g, drv->image->green_mask); + fill_shift_mask (&drv->b, drv->image->blue_mask); + + /* Set WM hints. */ + size_hints.flags = PSize | PMinSize | PMaxSize; + size_hints.min_width = size_hints.max_width = size_hints.base_width = Width; + size_hints.min_height = size_hints.max_height = size_hints.base_height = Height; + XSetWMNormalHints (drv->display, drv->win, &size_hints); + + XMapWindow (drv->display, drv->win); + HandleEvents(drv); + return EFI_SUCCESS; +} + +void +handleKeyEvent(GRAPHICS_IO_PRIVATE *drv, XEvent *ev, BOOLEAN Make) +{ + KeySym *KeySym; + EFI_KEY_DATA KeyData; + int KeySymArraySize; + + if (Make) { + if (drv->key_count == NBR_KEYS) { + return; + } + } + + // keycode is a physical key on the keyboard + // KeySym is a mapping of a physical key + // KeyboardMapping is the array of KeySym for a given keycode. key, shifted key, option key, command key, ... + // + // Returns an array of KeySymArraySize of KeySym for the keycode. [0] is lower case, [1] is upper case, + // [2] and [3] are based on option and command modifiers. The problem we have is command V + // could be mapped to a crazy Unicode character so the old scheme of returning a string. + // + KeySym = XGetKeyboardMapping (drv->display, ev->xkey.keycode, 1, &KeySymArraySize); + + KeyData.Key.ScanCode = 0; + KeyData.Key.UnicodeChar = 0; + KeyData.KeyState.KeyShiftState = 0; + + // + // Skipping EFI_SCROLL_LOCK_ACTIVE & EFI_NUM_LOCK_ACTIVE since they are not on Macs + // + if ((ev->xkey.state & LockMask) == 0) { + drv->KeyState.KeyToggleState &= ~EFI_CAPS_LOCK_ACTIVE; + } else { + if (Make) { + drv->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; + } + } + + // Skipping EFI_MENU_KEY_PRESSED and EFI_SYS_REQ_PRESSED + + switch (*KeySym) { + case XK_Control_R: + if (Make) { + drv->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED; + } else { + drv->KeyState.KeyShiftState &= ~EFI_RIGHT_CONTROL_PRESSED; + } + break; + case XK_Control_L: + if (Make) { + drv->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED; + } else { + drv->KeyState.KeyShiftState &= ~EFI_LEFT_CONTROL_PRESSED; + } + break; + + case XK_Shift_R: + if (Make) { + drv->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; + } else { + drv->KeyState.KeyShiftState &= ~EFI_RIGHT_SHIFT_PRESSED; + } + break; + case XK_Shift_L: + if (Make) { + drv->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; + } else { + drv->KeyState.KeyShiftState &= ~EFI_LEFT_SHIFT_PRESSED; + } + break; + + case XK_Mode_switch: + if (Make) { + drv->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED; + } else { + drv->KeyState.KeyShiftState &= ~EFI_LEFT_ALT_PRESSED; + } + break; + + case XK_Meta_R: + if (Make) { + drv->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; + } else { + drv->KeyState.KeyShiftState &= ~EFI_RIGHT_LOGO_PRESSED; + } + break; + case XK_Meta_L: + if (Make) { + drv->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED; + } else { + drv->KeyState.KeyShiftState &= ~EFI_LEFT_LOGO_PRESSED; + } + break; + + case XK_KP_Home: + case XK_Home: KeyData.Key.ScanCode = SCAN_HOME; break; + + case XK_KP_End: + case XK_End: KeyData.Key.ScanCode = SCAN_END; break; + + case XK_KP_Left: + case XK_Left: KeyData.Key.ScanCode = SCAN_LEFT; break; + + case XK_KP_Right: + case XK_Right: KeyData.Key.ScanCode = SCAN_RIGHT; break; + + case XK_KP_Up: + case XK_Up: KeyData.Key.ScanCode = SCAN_UP; break; + + case XK_KP_Down: + case XK_Down: KeyData.Key.ScanCode = SCAN_DOWN; break; + + case XK_KP_Delete: + case XK_Delete: KeyData.Key.ScanCode = SCAN_DELETE; break; + + case XK_KP_Insert: + case XK_Insert: KeyData.Key.ScanCode = SCAN_INSERT; break; + + case XK_KP_Page_Up: + case XK_Page_Up: KeyData.Key.ScanCode = SCAN_PAGE_UP; break; + + case XK_KP_Page_Down: + case XK_Page_Down: KeyData.Key.ScanCode = SCAN_PAGE_DOWN; break; + + case XK_Escape: KeyData.Key.ScanCode = SCAN_ESC; break; + + + case XK_KP_F1: + case XK_F1: KeyData.Key.ScanCode = SCAN_F1; break; + + case XK_KP_F2: + case XK_F2: KeyData.Key.ScanCode = SCAN_F2; break; + + case XK_KP_F3: + case XK_F3: KeyData.Key.ScanCode = SCAN_F3; break; + + case XK_KP_F4: + case XK_F4: KeyData.Key.ScanCode = SCAN_F4; break; + + case XK_F5: KeyData.Key.ScanCode = SCAN_F5; break; + case XK_F6: KeyData.Key.ScanCode = SCAN_F6; break; + case XK_F7: KeyData.Key.ScanCode = SCAN_F7; break; + + // Don't map into X11 by default on a Mac + // System Preferences->Keyboard->Keyboard Shortcuts can be configured + // to not use higher function keys as shortcuts and the will show up + // in X11. + case XK_F8: KeyData.Key.ScanCode = SCAN_F8; break; + case XK_F9: KeyData.Key.ScanCode = SCAN_F9; break; + case XK_F10: KeyData.Key.ScanCode = SCAN_F10; break; + + case XK_F11: KeyData.Key.ScanCode = SCAN_F11; break; + case XK_F12: KeyData.Key.ScanCode = SCAN_F12; break; + + case XK_F13: KeyData.Key.ScanCode = SCAN_F13; break; + case XK_F14: KeyData.Key.ScanCode = SCAN_F14; break; + case XK_F15: KeyData.Key.ScanCode = SCAN_F15; break; + case XK_F16: KeyData.Key.ScanCode = SCAN_F16; break; + case XK_F17: KeyData.Key.ScanCode = SCAN_F17; break; + case XK_F18: KeyData.Key.ScanCode = SCAN_F18; break; + case XK_F19: KeyData.Key.ScanCode = SCAN_F19; break; + case XK_F20: KeyData.Key.ScanCode = SCAN_F20; break; + case XK_F21: KeyData.Key.ScanCode = SCAN_F21; break; + case XK_F22: KeyData.Key.ScanCode = SCAN_F22; break; + case XK_F23: KeyData.Key.ScanCode = SCAN_F23; break; + case XK_F24: KeyData.Key.ScanCode = SCAN_F24; break; + + // No mapping in X11 + //case XK_: KeyData.Key.ScanCode = SCAN_MUTE; break; + //case XK_: KeyData.Key.ScanCode = SCAN_VOLUME_UP; break; + //case XK_: KeyData.Key.ScanCode = SCAN_VOLUME_DOWN; break; + //case XK_: KeyData.Key.ScanCode = SCAN_BRIGHTNESS_UP; break; + //case XK_: KeyData.Key.ScanCode = SCAN_BRIGHTNESS_DOWN; break; + //case XK_: KeyData.Key.ScanCode = SCAN_SUSPEND; break; + //case XK_: KeyData.Key.ScanCode = SCAN_HIBERNATE; break; + //case XK_: KeyData.Key.ScanCode = SCAN_TOGGLE_DISPLAY; break; + //case XK_: KeyData.Key.ScanCode = SCAN_RECOVERY; break; + //case XK_: KeyData.Key.ScanCode = SCAN_EJECT; break; + + case XK_BackSpace: KeyData.Key.UnicodeChar = 0x0008; break; + + case XK_KP_Tab: + case XK_Tab: KeyData.Key.UnicodeChar = 0x0009; break; + + case XK_Linefeed: KeyData.Key.UnicodeChar = 0x000a; break; + + case XK_KP_Enter: + case XK_Return: KeyData.Key.UnicodeChar = 0x000d; break; + + case XK_KP_Equal : KeyData.Key.UnicodeChar = L'='; break; + case XK_KP_Multiply : KeyData.Key.UnicodeChar = L'*'; break; + case XK_KP_Add : KeyData.Key.UnicodeChar = L'+'; break; + case XK_KP_Separator : KeyData.Key.UnicodeChar = L'~'; break; + case XK_KP_Subtract : KeyData.Key.UnicodeChar = L'-'; break; + case XK_KP_Decimal : KeyData.Key.UnicodeChar = L'.'; break; + case XK_KP_Divide : KeyData.Key.UnicodeChar = L'/'; break; + + case XK_KP_0 : KeyData.Key.UnicodeChar = L'0'; break; + case XK_KP_1 : KeyData.Key.UnicodeChar = L'1'; break; + case XK_KP_2 : KeyData.Key.UnicodeChar = L'2'; break; + case XK_KP_3 : KeyData.Key.UnicodeChar = L'3'; break; + case XK_KP_4 : KeyData.Key.UnicodeChar = L'4'; break; + case XK_KP_5 : KeyData.Key.UnicodeChar = L'5'; break; + case XK_KP_6 : KeyData.Key.UnicodeChar = L'6'; break; + case XK_KP_7 : KeyData.Key.UnicodeChar = L'7'; break; + case XK_KP_8 : KeyData.Key.UnicodeChar = L'8'; break; + case XK_KP_9 : KeyData.Key.UnicodeChar = L'9'; break; + + default: + ; + } + + // The global state is our state + KeyData.KeyState.KeyShiftState = drv->KeyState.KeyShiftState; + KeyData.KeyState.KeyToggleState = drv->KeyState.KeyToggleState; + + if (*KeySym < XK_BackSpace) { + if (((drv->KeyState.KeyShiftState & (EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)) != 0) || + ((drv->KeyState.KeyToggleState & EFI_CAPS_LOCK_ACTIVE) != 0) ) { + + KeyData.Key.UnicodeChar = (CHAR16)KeySym[KEYSYM_UPPER]; + + // Per UEFI spec since we converted the Unicode clear the shift bits we pass up + KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED); + } else { + KeyData.Key.UnicodeChar = (CHAR16)KeySym[KEYSYM_LOWER]; + } + } else { + // XK_BackSpace is the start of XK_MISCELLANY. These are the XK_? keys we process in this file + ; + } + + if (Make) { + memcpy (&drv->keys[drv->key_wr], &KeyData, sizeof (EFI_KEY_DATA)); + drv->key_wr = (drv->key_wr + 1) % NBR_KEYS; + drv->key_count++; + if (drv->MakeRegisterdKeyCallback != NULL) { + ReverseGasketUint64Uint64 (drv->MakeRegisterdKeyCallback ,drv->RegisterdKeyCallbackContext, &KeyData); + } + } else { + if (drv->BreakRegisterdKeyCallback != NULL) { + ReverseGasketUint64Uint64 (drv->BreakRegisterdKeyCallback ,drv->RegisterdKeyCallbackContext, &KeyData); + } + } +} + + +void +handleMouseMoved(GRAPHICS_IO_PRIVATE *drv, XEvent *ev) +{ + if ( ev->xmotion.x != drv->previous_x ) + { + drv->pointer_state.RelativeMovementX += ( ev->xmotion.x - drv->previous_x ); + drv->previous_x = ev->xmotion.x; + drv->pointer_state_changed = 1; + } + + if ( ev->xmotion.y != drv->previous_y ) + { + drv->pointer_state.RelativeMovementY += ( ev->xmotion.y - drv->previous_y ); + drv->previous_y = ev->xmotion.y; + drv->pointer_state_changed = 1; + } + + drv->pointer_state.RelativeMovementZ = 0; +} + +void +handleMouseDown(GRAPHICS_IO_PRIVATE *drv, XEvent *ev, BOOLEAN Pressed) +{ + if ( ev->xbutton.button == Button1 ) + { + drv->pointer_state_changed = ( drv->pointer_state.LeftButton != Pressed ); + drv->pointer_state.LeftButton = Pressed; + } + if ( ev->xbutton.button == Button2 ) + { + drv->pointer_state_changed = ( drv->pointer_state.RightButton != Pressed ); + drv->pointer_state.RightButton = Pressed; + } +} + +void +Redraw(GRAPHICS_IO_PRIVATE *drv, UINTN X, UINTN Y, UINTN Width, UINTN Height) +{ + if (drv->use_shm) + XShmPutImage (drv->display, drv->win, drv->gc, drv->image, + X, Y, X, Y, Width, Height, False); + else + XPutImage (drv->display, drv->win, drv->gc, drv->image, + X, Y, X, Y, Width, Height); + XFlush(drv->display); +} + +void +HandleEvent(GRAPHICS_IO_PRIVATE *drv, XEvent *ev) +{ + switch (ev->type) + { + case Expose: + Redraw(drv, ev->xexpose.x, ev->xexpose.y, + ev->xexpose.width, ev->xexpose.height); + break; + case GraphicsExpose: + Redraw(drv, ev->xgraphicsexpose.x, ev->xgraphicsexpose.y, + ev->xgraphicsexpose.width, ev->xgraphicsexpose.height); + break; + case KeyPress: + handleKeyEvent(drv, ev, TRUE); + break; + case KeyRelease: + handleKeyEvent(drv, ev, FALSE); + break; + case MappingNotify: + XRefreshKeyboardMapping(&ev->xmapping); + break; + case MotionNotify: + handleMouseMoved(drv, ev); + break; + case ButtonPress: + handleMouseDown(drv, ev, TRUE); + break; + case ButtonRelease: + handleMouseDown(drv, ev, FALSE); + break; +#if 0 + case DestroyNotify: + XCloseDisplay (drv->display); + exit (1); + break; +#endif + case NoExpose: + default: + break; + } +} + +void +HandleEvents(GRAPHICS_IO_PRIVATE *drv) +{ + while (XPending(drv->display) != 0) + { + XEvent ev; + + XNextEvent (drv->display, &ev); + HandleEvent(drv, &ev); + } +} + +unsigned long +X11PixelToColor (GRAPHICS_IO_PRIVATE *drv, EFI_UGA_PIXEL pixel) +{ + return ((pixel.Red >> drv->r.csize) << drv->r.shift) + | ((pixel.Green >> drv->g.csize) << drv->g.shift) + | ((pixel.Blue >> drv->b.csize) << drv->b.shift); +} + +EFI_UGA_PIXEL +X11ColorToPixel (GRAPHICS_IO_PRIVATE *drv, unsigned long val) +{ + EFI_UGA_PIXEL res; + + memset (&res, 0, sizeof (EFI_UGA_PIXEL)); + /* FIXME: should round instead of truncate. */ + res.Red = (val >> drv->r.shift) << drv->r.csize; + res.Green = (val >> drv->g.shift) << drv->g.csize; + res.Blue = (val >> drv->b.shift) << drv->b.csize; + + return res; +} + +STATIC EFI_STATUS +CheckKeyInternal( GRAPHICS_IO_PRIVATE *drv, BOOLEAN delay ) +{ + HandleEvents(drv); + if (drv->key_count != 0) + return EFI_SUCCESS; + if ( delay ) + /* EFI is polling. Be CPU-friendly. */ + SecSleep (20); + return EFI_NOT_READY; + } + +EFI_STATUS +X11CheckKey(EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo) +{ + GRAPHICS_IO_PRIVATE *drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + return CheckKeyInternal(drv, TRUE); +} + +EFI_STATUS +EFIAPI +X11GetKey ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_KEY_DATA *KeyData + ) +{ + GRAPHICS_IO_PRIVATE *drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + EFI_STATUS status; + + status = CheckKeyInternal(drv, FALSE); + if (status != EFI_SUCCESS) + return status; + + CopyMem (KeyData, &drv->keys[drv->key_rd], sizeof (EFI_KEY_DATA)); + drv->key_rd = (drv->key_rd + 1) % NBR_KEYS; + drv->key_count--; + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +X11KeySetState ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ) +{ + GRAPHICS_IO_PRIVATE *drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; +// XKeyEvent event; + + if (*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) { + if ((drv->KeyState.KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == 0) { + // + // We could create an XKeyEvent and send a XK_Caps_Lock to + // the UGA/GOP Window + // + } + } + + drv->KeyState.KeyToggleState = *KeyToggleState; + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +X11RegisterKeyNotify ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack, + IN VOID *Context + ) +{ + GRAPHICS_IO_PRIVATE *drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + + drv->MakeRegisterdKeyCallback = MakeCallBack; + drv->BreakRegisterdKeyCallback = BreakCallBack; + drv->RegisterdKeyCallbackContext = Context; + + return EFI_SUCCESS; +} + + +EFI_STATUS +X11Blt ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, + IN EFI_UGA_BLT_OPERATION BltOperation, + IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args + ) +{ + GRAPHICS_IO_PRIVATE *Private = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + UINTN DstY; + UINTN SrcY; + UINTN DstX; + UINTN SrcX; + UINTN Index; + EFI_UGA_PIXEL *Blt; + UINT8 *Dst; + UINT8 *Src; + UINTN Nbr; + unsigned long Color; + + // + // Check bounds + // + if (BltOperation == EfiUgaVideoToBltBuffer + || BltOperation == EfiUgaVideoToVideo) { + // + // Source is Video. + // + if (Args->SourceY + Args->Height > Private->height) { + return EFI_INVALID_PARAMETER; + } + + if (Args->SourceX + Args->Width > Private->width) { + return EFI_INVALID_PARAMETER; + } + } + + if (BltOperation == EfiUgaBltBufferToVideo + || BltOperation == EfiUgaVideoToVideo + || BltOperation == EfiUgaVideoFill) { + // + // Destination is Video + // + if (Args->DestinationY + Args->Height > Private->height) { + return EFI_INVALID_PARAMETER; + } + + if (Args->DestinationX + Args->Width > Private->width) { + return EFI_INVALID_PARAMETER; + } + } + + switch (BltOperation) { + case EfiUgaVideoToBltBuffer: + Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (Args->DestinationY * Args->Delta) + Args->DestinationX * sizeof (EFI_UGA_PIXEL)); + Args->Delta -= Args->Width * sizeof (EFI_UGA_PIXEL); + for (SrcY = Args->SourceY; SrcY < (Args->Height + Args->SourceY); SrcY++) { + for (SrcX = Args->SourceX; SrcX < (Args->Width + Args->SourceX); SrcX++) { + *Blt++ = X11ColorToPixel(Private, + XGetPixel(Private->image, SrcX, SrcY)); + } + Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Args->Delta); + } + break; + case EfiUgaBltBufferToVideo: + Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (Args->SourceY * Args->Delta) + Args->SourceX * sizeof (EFI_UGA_PIXEL)); + Args->Delta -= Args->Width * sizeof (EFI_UGA_PIXEL); + for (DstY = Args->DestinationY; DstY < (Args->Height + Args->DestinationY); DstY++) { + for (DstX = Args->DestinationX; DstX < (Args->Width + Args->DestinationX); DstX++) { + XPutPixel(Private->image, DstX, DstY, X11PixelToColor(Private, *Blt)); + Blt++; + } + Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Args->Delta); + } + break; + case EfiUgaVideoToVideo: + Dst = Private->image_data + (Args->DestinationX << Private->pixel_shift) + + Args->DestinationY * Private->line_bytes; + Src = Private->image_data + (Args->SourceX << Private->pixel_shift) + + Args->SourceY * Private->line_bytes; + Nbr = Args->Width << Private->pixel_shift; + if (Args->DestinationY < Args->SourceY) { + for (Index = 0; Index < Args->Height; Index++) { + memcpy (Dst, Src, Nbr); + Dst += Private->line_bytes; + Src += Private->line_bytes; + } + } + else { + Dst += (Args->Height - 1) * Private->line_bytes; + Src += (Args->Height - 1) * Private->line_bytes; + for (Index = 0; Index < Args->Height; Index++) { + // + // Source and Destination Y may be equal, therefore Dst and Src may + // overlap. + // + memmove (Dst, Src, Nbr); + Dst -= Private->line_bytes; + Src -= Private->line_bytes; + } + } + break; + case EfiUgaVideoFill: + Color = X11PixelToColor(Private, *BltBuffer); + for (DstY = Args->DestinationY; DstY < (Args->Height + Args->DestinationY); DstY++) { + for (DstX = Args->DestinationX; DstX < (Args->Width + Args->DestinationX); DstX++) { + XPutPixel(Private->image, DstX, DstY, Color); + } + } + break; + default: + return EFI_INVALID_PARAMETER; + } + + // + // Refresh screen. + // + switch (BltOperation) { + case EfiUgaVideoToVideo: + XCopyArea(Private->display, Private->win, Private->win, Private->gc, + Args->SourceX, Args->SourceY, Args->Width, Args->Height, Args->DestinationX, Args->DestinationY); + while (1) { + XEvent ev; + + XNextEvent (Private->display, &ev); + HandleEvent(Private, &ev); + if (ev.type == NoExpose || ev.type == GraphicsExpose) + break; + } + break; + case EfiUgaVideoFill: + Color = X11PixelToColor(Private, *BltBuffer); + XSetForeground(Private->display, Private->gc, Color); + XFillRectangle(Private->display, Private->win, Private->gc, + Args->DestinationX, Args->DestinationY, Args->Width, Args->Height); + XFlush(Private->display); + break; + case EfiUgaBltBufferToVideo: + Redraw(Private, Args->DestinationX, Args->DestinationY, Args->Width, Args->Height); + break; + default: + break; + } + return EFI_SUCCESS; +} + +STATIC EFI_STATUS +CheckPointerInternal( GRAPHICS_IO_PRIVATE *drv, BOOLEAN delay ) +{ + HandleEvents(drv); + if (drv->pointer_state_changed != 0) + return EFI_SUCCESS; + if ( delay ) + /* EFI is polling. Be CPU-friendly. */ + SecSleep (20); + return EFI_NOT_READY; +} + +EFI_STATUS +X11CheckPointer(EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo) +{ + GRAPHICS_IO_PRIVATE *drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + return( CheckPointerInternal( drv, TRUE ) ); +} + +EFI_STATUS +X11GetPointerState (EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, EFI_SIMPLE_POINTER_STATE *state) +{ + GRAPHICS_IO_PRIVATE *drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + EFI_STATUS status; + + status = CheckPointerInternal( drv, FALSE ); + if (status != EFI_SUCCESS) + return status; + + memcpy( state, &drv->pointer_state, sizeof( EFI_SIMPLE_POINTER_STATE ) ); + + drv->pointer_state.RelativeMovementX = 0; + drv->pointer_state.RelativeMovementY = 0; + drv->pointer_state.RelativeMovementZ = 0; + drv->pointer_state_changed = 0; + return EFI_SUCCESS; +} + + + +EFI_STATUS +X11GraphicsWindowOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + GRAPHICS_IO_PRIVATE *drv; + unsigned int border_width = 0; + char *display_name = NULL; + int title_len; + + drv = (GRAPHICS_IO_PRIVATE *)calloc (1, sizeof (GRAPHICS_IO_PRIVATE)); + if (drv == NULL) + return EFI_OUT_OF_RESOURCES; + + drv->GraphicsIo.Size = GasketX11Size; + drv->GraphicsIo.CheckKey = GasketX11CheckKey; + drv->GraphicsIo.GetKey = GasketX11GetKey; + drv->GraphicsIo.KeySetState = GasketX11KeySetState; + drv->GraphicsIo.RegisterKeyNotify = GasketX11RegisterKeyNotify; + drv->GraphicsIo.Blt = GasketX11Blt; + drv->GraphicsIo.CheckPointer = GasketX11CheckPointer; + drv->GraphicsIo.GetPointerState = GasketX11GetPointerState; + + + drv->key_count = 0; + drv->key_rd = 0; + drv->key_wr = 0; + drv->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID; + drv->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID; + drv->MakeRegisterdKeyCallback = NULL; + drv->BreakRegisterdKeyCallback = NULL; + drv->RegisterdKeyCallbackContext = NULL; + + + drv->display = XOpenDisplay (display_name); + if (drv->display == NULL) { + fprintf (stderr, "uga: cannot connect to X server %s\n", XDisplayName (display_name)); + free (drv); + return EFI_DEVICE_ERROR; + } + drv->screen = DefaultScreen (drv->display); + drv->visual = DefaultVisual (drv->display, drv->screen); + drv->win = XCreateSimpleWindow + (drv->display, RootWindow (drv->display, drv->screen), + 0, 0, 4, 4, border_width, + WhitePixel (drv->display, drv->screen), + BlackPixel (drv->display, drv->screen)); + + drv->depth = DefaultDepth (drv->display, drv->screen); + XDefineCursor (drv->display, drv->win, XCreateFontCursor (drv->display, XC_pirate)); + + /* Compute title len and convert to Ascii. */ + for (title_len = 0; This->ConfigString[title_len] != 0; title_len++) + ; + { + char title[title_len + 1]; + int i; + for (i = 0; i < title_len; i++) + title[i] = This->ConfigString[i]; + title[i] = 0; + + XStoreName (drv->display, drv->win, title); + } + +// XAutoRepeatOff (drv->display); + XSelectInput (drv->display, drv->win, + ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask ); + drv->gc = DefaultGC (drv->display, drv->screen); + + This->Private = (VOID *)drv; + This->Interface = (VOID *)drv; + return EFI_SUCCESS; +} + + +EFI_STATUS +X11GraphicsWindowClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + GRAPHICS_IO_PRIVATE *drv = (GRAPHICS_IO_PRIVATE *)This->Private; + + if (drv == NULL) + return EFI_SUCCESS; + if (drv->image != NULL) + { + XDestroyImage(drv->image); + + if (drv->use_shm) + shmdt (drv->image_data); + + drv->image_data = NULL; + drv->image = NULL; + } + XDestroyWindow(drv->display, drv->win); + XCloseDisplay(drv->display); + +#ifdef __APPLE__ + // Free up the shared memory + shmctl (drv->xshm_info.shmid, IPC_RMID, NULL); +#endif + + free(drv); + return EFI_SUCCESS; +} + + +EMU_IO_THUNK_PROTOCOL gX11ThunkIo = { + &gEmuGraphicsWindowProtocolGuid, + NULL, + NULL, + 0, + GasketX11GraphicsWindowOpen, + GasketX11GraphicsWindowClose, + NULL +}; + + diff --git a/InOsEmuPkg/Unix/Sec/X64/Gasket.S b/InOsEmuPkg/Unix/Sec/X64/Gasket.S new file mode 100644 index 0000000000..fde3028da9 --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/X64/Gasket.S @@ -0,0 +1,1054 @@ +#------------------------------------------------------------------------------ +# +# Manage differenced between UNIX ABI and EFI/Windows ABI +# +# EFI Arg passing: RCX, RDX, R8, R9 +# Callee allocates 32 bytes on stack to spill registers +# UNIX Arg passing: RDI, RSI, RDX, RCX, R8, R9 +# RSI, RDI calle-save on EFI, scatch on UNIX callign +# +# Copyright (c) 2008 - 2011, Apple Inc. 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. +# +#------------------------------------------------------------------------------ + +// +// Gaskets are EFI ABI to UNIX ABI calls +// EFI ABI code will sub 40 (0x28) from %rsp before calling a function +// This is the 32 (0x20) byte to spill registers and 8 bytes to align stack on 16 byte boundry. +// + .text + +// 32 byte shadow to spill rcx-r9, 8 bytes to align stack on 16 byte boundry +// Any call with 0 - 4 arguments allocates 40 bytes on the stack. +// For more than 4 args you always have to increase in quanta of 16 so 5 or 6 args is 56, +// 7 or 8 args is 72, and 9 or 10 args is 88 + + + + .text + +// +// EMU_THUNK_PROTOCOL gaskets (EFIAPI to UNIX ABI) +// + + + + +ASM_GLOBAL ASM_PFX(GasketSecWriteStdErr) +ASM_PFX(GasketSecWriteStdErr): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecWriteStdErr) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecSetTimer) +ASM_PFX(GasketSecSetTimer): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecSetTimer) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecEnableInterrupt) +ASM_PFX(GasketSecEnableInterrupt): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecEnableInterrupt) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecDisableInterrupt) +ASM_PFX(GasketSecDisableInterrupt): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecDisableInterrupt) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketQueryPerformanceFrequency) +ASM_PFX(GasketQueryPerformanceFrequency): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(QueryPerformanceFrequency) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketQueryPerformanceCounter) +ASM_PFX(GasketQueryPerformanceCounter): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(QueryPerformanceCounter) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecSleep) +ASM_PFX(GasketSecSleep): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecSleep) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecExit) +ASM_PFX(GasketSecExit): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + movq %rcx, %rdi // Swizzle args + call ASM_PFX(SecExit) // Less to do as we will never return to EFI ABI world +LDEAD_LOOP: + jmp LDEAD_LOOP // _exit should never return + + +ASM_GLOBAL ASM_PFX(GasketSecGetTime) +ASM_PFX(GasketSecGetTime): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecGetTime) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecSetTime) +ASM_PFX(GasketSecSetTime): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecSetTime) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecGetNextProtocol) +ASM_PFX(GasketSecGetNextProtocol): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(SecGetNextProtocol) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +// PPIs produced by SEC + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffGetEntryPoint) +ASM_PFX(GasketSecPeCoffGetEntryPoint): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecPeCoffGetEntryPoint) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffRelocateImageExtraAction) +ASM_PFX(GasketSecPeCoffRelocateImageExtraAction): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecPeCoffRelocateImageExtraAction) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffUnloadImageExtraAction) +ASM_PFX(GasketSecPeCoffUnloadImageExtraAction): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecPeCoffUnloadImageExtraAction) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecEmuThunkAddress) +ASM_PFX(GasketSecEmuThunkAddress): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecEmuThunkAddress) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +// +// Gasket functions for EFI_EMU_UGA_IO_PROTOCOL +// + +ASM_GLOBAL ASM_PFX(GasketX11Size) +ASM_PFX(GasketX11Size): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(X11Size) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11CheckKey) +ASM_PFX(GasketX11CheckKey): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(X11CheckKey) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketX11GetKey) +ASM_PFX(GasketX11GetKey): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(X11GetKey) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11KeySetState) +ASM_PFX(GasketX11KeySetState): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(X11KeySetState) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11RegisterKeyNotify) +ASM_PFX(GasketX11RegisterKeyNotify): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(X11RegisterKeyNotify) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11Blt) +ASM_PFX(GasketX11Blt): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(X11Blt) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11CheckPointer) +ASM_PFX(GasketX11CheckPointer): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(X11CheckPointer) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GetPointerState) +ASM_PFX(GasketX11GetPointerState): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(X11GetPointerState) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GraphicsWindowOpen) +ASM_PFX(GasketX11GraphicsWindowOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(X11GraphicsWindowOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GraphicsWindowClose) +ASM_PFX(GasketX11GraphicsWindowClose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %r9, %rcx + + call ASM_PFX(X11GraphicsWindowClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +// Pthreads + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexLock) +ASM_PFX(GasketPthreadMutexLock): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadMutexLock) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexUnLock) +ASM_PFX(GasketPthreadMutexUnLock): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadMutexUnLock) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexTryLock) +ASM_PFX(GasketPthreadMutexTryLock): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadMutexTryLock) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexInit) +ASM_PFX(GasketPthreadMutexInit): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + + call ASM_PFX(PthreadMutexInit) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexDestroy) +ASM_PFX(GasketPthreadMutexDestroy): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadMutexDestroy) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadCreate) +ASM_PFX(GasketPthreadCreate): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(PthreadCreate) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadExit) +ASM_PFX(GasketPthreadExit): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadExit) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketPthreadSelf) +ASM_PFX(GasketPthreadSelf): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + + call ASM_PFX(PthreadSelf) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadOpen) +ASM_PFX(GasketPthreadOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadClose) +ASM_PFX(GasketPthreadClose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + + +// +// UNIX ABI to EFI ABI call +// +// UINTN +// ReverseGasketUint64 ( +// void *Api, +// UINTN Arg1 +// ); +ASM_GLOBAL ASM_PFX(ReverseGasketUint64) +ASM_PFX(ReverseGasketUint64): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + movq %rdi, %rax // Swizzle args + movq %rsi, %rcx + + subq $32, %rsp // 32-byte shadow space + call *%rax + addq $32, %rsp + + popq %rbp + ret + +// +// UNIX ABI to EFI ABI call +// +// UINTN +// ReverseGasketUint64Uint64 ( +// void *Api, +// UINTN Arg1 +// UINTN Arg2 +// ); +ASM_GLOBAL ASM_PFX(ReverseGasketUint64Uint64) +ASM_PFX(ReverseGasketUint64Uint64): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + movq %rdi, %rax // Swizzle args + movq %rsi, %rcx + + subq $32, %rsp // 32-byte shadow space + call *%rax + addq $32, %rsp + + popq %rbp + ret + + +// Sec PPI Callbacks - Check Me + +ASM_GLOBAL ASM_PFX(GasketSecUnixPeiLoadFile) +ASM_PFX(GasketSecUnixPeiLoadFile): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(SecUnixPeiLoadFile) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketSecUnixPeiAutoScan) +ASM_PFX(GasketSecUnixPeiAutoScan): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(SecUnixPeiAutoScan) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecUnixFdAddress) +ASM_PFX(GasketSecUnixFdAddress): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(SecUnixFdAddress) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +// EmuIoThunk SimpleFileSystem + +ASM_GLOBAL ASM_PFX(GasketPosixOpenVolume) +ASM_PFX(GasketPosixOpenVolume): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(PosixOpenVolume) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileOpen) +ASM_PFX(GasketPosixFileOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 0x30(%rbp), %r8 + + call ASM_PFX(PosixFileOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileCLose) +ASM_PFX(GasketPosixFileCLose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileCLose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileDelete) +ASM_PFX(GasketPosixFileDelete): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileDelete) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileRead) +ASM_PFX(GasketPosixFileRead): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(PosixFileRead) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileWrite) +ASM_PFX(GasketPosixFileWrite): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(PosixFileWrite) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSetPossition) +ASM_PFX(GasketPosixFileSetPossition): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(PosixFileSetPossition) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileGetPossition) +ASM_PFX(GasketPosixFileGetPossition): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(PosixFileGetPossition) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileGetInfo) +ASM_PFX(GasketPosixFileGetInfo): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(PosixFileGetInfo) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSetInfo) +ASM_PFX(GasketPosixFileSetInfo): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(PosixFileSetInfo) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileFlush) +ASM_PFX(GasketPosixFileFlush): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileFlush) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSystmeThunkOpen) +ASM_PFX(GasketPosixFileSystmeThunkOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileSystmeThunkOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSystmeThunkClose) +ASM_PFX(GasketPosixFileSystmeThunkClose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileSystmeThunkClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + + + + + diff --git a/InOsEmuPkg/Unix/Sec/X64/SwitchStack.S b/InOsEmuPkg/Unix/Sec/X64/SwitchStack.S new file mode 100644 index 0000000000..0d4e5029c9 --- /dev/null +++ b/InOsEmuPkg/Unix/Sec/X64/SwitchStack.S @@ -0,0 +1,112 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+# Portitions copyright (c) 2011, Apple Inc. 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. +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Routine Description: +# +# Routine for switching stacks with 3 parameters EFI ABI +# Convert UNIX to EFI ABI +# +# Arguments: +# +# (rdi) EntryPoint - Entry point with new stack. +# (rsi) Context1 - Parameter1 for entry point. (rcx) +# (rdx) Context2 - Parameter2 for entry point. (rdx) +# (rcx) Context3 - Parameter3 for entry point. (r8) +# (r8) NewStack - The pointer to new stack. +# +# Returns: +# +# None +# +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(PeiSwitchStacks) +ASM_PFX(PeiSwitchStacks): + pushq $0 // tells gdb to stop unwinding frame + movq %rsp, %rbp + + movq %r8, %rsp + + movq %rdi, %rax + movq %rsi, %rcx + movq %rcx, %r8 + + # + # Reserve space for register parameters (rcx, rdx, r8 & r9) on the stack, + # in case the callee wishes to spill them. + # + subq $32, %rsp // 32-byte shadow space plus alignment pad + call *%rax + + + +// EFI_STATUS +// EFIAPI +// SecTemporaryRamSupport ( +// IN CONST EFI_PEI_SERVICES **PeiServices, // %rcx +// IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, // %rdx +// IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, // %r8 +// IN UINTN CopySize // %r9 +// ) +// +ASM_GLOBAL ASM_PFX(GasketSecTemporaryRamSupport) +ASM_PFX(GasketSecTemporaryRamSupport): + // Adjust callers %rbp to account for stack move + subq %rdx, %rbp // Calc offset of %rbp in Temp Memory + addq %r8, %rbp // add in permanent base to offset + + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + pushq %rdx // Save TemporaryMemoryBase + pushq %r8 // Save PermanentMemoryBase + pushq %r9 // Save CopySize + + // + // Copy all of temp RAM to permanent memory, including stack + // + // CopyMem (PermanentMemoryBase, TemporaryMemoryBase, CopySize); + // %rdi, %rsi, %rdx + movq %r8, %rdi // Swizzle args + movq %rdx, %rsi + movq %r9, %rdx + call ASM_PFX(CopyMem) + // Temp mem stack now copied to permanent location. %esp still in temp memory + + popq %r9 // CopySize (old stack) + popq %r8 // PermanentMemoryBase (old stack) + popq %rdx // TemporaryMemoryBase (old stack) + + movq %rsp, %rcx // Move to new stack + subq %rdx, %rcx // Calc offset of stack in Temp Memory + addq %r8, %rcx // Calc PermanentMemoryBase address + movq %rcx, %rsp // Update stack + // Stack now points to permanent memory + + // ZeroMem (TemporaryMemoryBase /* rdi */, CopySize /* rsi */); + movq %rdx, %rdi + movq %r9, %rsi + call ASM_PFX(ZeroMem) + + // This data comes off the NEW stack + popq %rdi + popq %rsi + popq %rbp + ret + + diff --git a/InOsEmuPkg/Unix/UnixX64.dsc b/InOsEmuPkg/Unix/UnixX64.dsc new file mode 100644 index 0000000000..88c4218d2d --- /dev/null +++ b/InOsEmuPkg/Unix/UnixX64.dsc @@ -0,0 +1,377 @@ +## @file +# +# EFI/Framework Emulation Platform with UEFI HII interface supported. +# +# The Emulation Platform can be used to debug individual modules, prior to creating +# a real platform. This also provides an example for how an DSC is created. +# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2010 - 2011, Apple Inc. 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. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + PLATFORM_NAME = EmuUnix + PLATFORM_GUID = 05FD064D-1073-E844-936C-A0E16317107D + PLATFORM_VERSION = 0.3 + DSC_ SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/EmuUnixX64 + SUPPORTED_ARCHITECTURES = X64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + FLASH_DEFINITION = InOsEmuPkg/Unix/UnixX64.fdf + +################################################################################ +# +# SKU Identification section - list of all SKU IDs supported by this Platform. +# +################################################################################ +[SkuIds] + 0|DEFAULT + +################################################################################ +# +# Library Class section - list of all Library Classes needed by this Platform. +# +################################################################################ +[LibraryClasses] + # + # Entry point + # + PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + # + # Basic + # + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + + # + # UEFI & PI + # + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf + + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + # + # Generic Modules + # + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf + IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf + UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf + DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf + OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + # + # Platform + # + PlatformBdsLib|InOsEmuPkg/Library/EmuBdsLib/EmuBdsLib.inf + KeyMapLib|InOsEmuPkg/Library/KeyMapLibNull/KeyMapLibNull.inf + + # + # Misc + # + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + + +[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE] + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + + ThunkPpiList|InOsEmuPkg/Library/ThunkPpiList/ThunkPpiList.inf + ThunkProtocolList|InOsEmuPkg/Library/ThunkProtocolList/ThunkProtocolList.inf + + +[LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE] + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + PeCoffGetEntryPointLib|InOsEmuPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf + PeCoffExtraActionLib|InOsEmuPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf + ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + +[LibraryClasses.common.PEI_CORE] + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + PeiServicesTablePointerLib|InOsEmuPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf + SerialPortLib|InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf + +[LibraryClasses.common.PEIM] + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + PeiServicesTablePointerLib|InOsEmuPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf + +[LibraryClasses.common.DXE_CORE] + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + PeCoffExtraActionLib|InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + +[LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_APPLICATION] + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + EmuThunkLib|InOsEmuPkg/Library/DxeEmuLib/DxeEmuLib.inf + PeCoffExtraActionLib|InOsEmuPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf + +[LibraryClasses.common.UEFI_DRIVER] + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + +[LibraryClasses.common.UEFI_APPLICATION] + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform. +# +################################################################################ +[PcdsFeatureFlag] + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE + +[PcdsFixedAtBuild] + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x0 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule|0x0 + + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareFdSize|0x002a0000 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize|0x10000 + gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"../Fv/Fv_Recovery.fd" + + gInOsEmuPkgTokenSpaceGuid.PcdEmuMemorySizeForSecMain|L"64!64" + +#define BOOT_WITH_FULL_CONFIGURATION 0x00 +#define BOOT_WITH_MINIMAL_CONFIGURATION 0x01 +#define BOOT_ASSUMING_NO_CONFIGURATION_CHANGES 0x02 +#define BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03 +#define BOOT_WITH_DEFAULT_SETTINGS 0x04 +#define BOOT_ON_S4_RESUME 0x05 +#define BOOT_ON_S5_RESUME 0x06 +#define BOOT_ON_S2_RESUME 0x10 +#define BOOT_ON_S3_RESUME 0x11 +#define BOOT_ON_FLASH_UPDATE 0x12 +#define BOOT_IN_RECOVERY_MODE 0x20 + gInOsEmuPkgTokenSpaceGuid.PcdEmuBootMode|0 + + gInOsEmuPkgTokenSpaceGuid.PcdEmuApCount|L"0" + + gInOsEmuPkgTokenSpaceGuid.PcdEmuPhysicalDisk|L"E:RW;245760;512" + gInOsEmuPkgTokenSpaceGuid.PcdEmuVirtualDisk|L"FW;40960;512" + gInOsEmuPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window" + gInOsEmuPkgTokenSpaceGuid.PcdEmuFileSystem|L".!../../../../ShellBinPkg/UefiShell/X64!../../../../Build/Shell/DEBUG_XCLANG" + gInOsEmuPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0" + gInOsEmuPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"en0" + + gInOsEmuPkgTokenSpaceGuid.PcdEmuCpuModel|L"Intel(R) Processor Model" + gInOsEmuPkgTokenSpaceGuid.PcdEmuCpuSpeed|L"3000" + +################################################################################ +# +# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ + +[PcdsDynamicDefault.common.DEFAULT] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 + +[PcdsDynamicHii.common.DEFAULT] + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|L"Setup"|gEmuSystemConfigGuid|0x0|80 + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|L"Setup"|gEmuSystemConfigGuid|0x4|25 + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|10 + + +################################################################################################### +# +# Components Section - list of the modules and components that will be processed by compilation +# tools and the EDK II tools to generate PE32/PE32+/Coff image files. +# +# Note: The EDK II DSC file is not used to specify how compiled binary images get placed +# into firmware volume images. This section is just a list of modules to compile from +# source into UEFI-compliant binaries. +# It is the FDF file that contains information on combining binary files into firmware +# volume images, whose concept is beyond UEFI and is described in PI specification. +# Binary modules do not need to be listed in this section, as they should be +# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi), +# Logo (Logo.bmp), and etc. +# There may also be modules listed in this section that are not required in the FDF file, +# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be +# generated for it, but the binary will not be put into any firmware volume. +# +################################################################################################### +[Components] +!if $(SEC_ONLY) + ## + # SEC Phase modules + ## + InOsEmuPkg/Unix/Sec/SecMain.inf +!else + ## + # PEI Phase modules + ## + MdeModulePkg/Core/Pei/PeiMain.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf + MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf { + + SerialPortLib|InOsEmuPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf + } + + IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf + InOsEmuPkg/BootModePei/BootModePei.inf + MdeModulePkg/Universal/Variable/Pei/VariablePei.inf + InOsEmuPkg/AutoScanPei/AutoScanPei.inf + InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.inf + InOsEmuPkg/FlashMapPei/FlashMapPei.inf + InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { + + # turn off CR3 write so that DXE IPL will not crash emulator + BaseLib|UnixPkg/Library/UnixBaseLib/UnixBaseLib.inf + } + + ## + # DXE Phase modules + ## + MdeModulePkg/Core/Dxe/DxeMain.inf { + + NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf + NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + } + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + + MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf { + + SerialPortLib|InOsEmuPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf + } + + InOsEmuPkg/MetronomeDxe/Metronome.inf + InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf + InOsEmuPkg/ResetRuntimeDxe/Reset.inf + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + InOsEmuPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf + MdeModulePkg/Universal/EbcDxe/EbcDxe.inf + MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf + InOsEmuPkg/EmuThunkDxe/EmuThunk.inf + InOsEmuPkg/CpuRuntimeDxe/Cpu.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.inf + InOsEmuPkg/TimerDxe/Timer.inf + + + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf + MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf + + InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf + InOsEmuPkg/EmuGopDxe/EmuGopDxe.inf + InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf + +!if $(0) + UnixPkg/UnixBlockIoDxe/UnixBlockIo.inf + UnixPkg/UnixSerialIoDxe/UnixSerialIo.inf + UnixPkg/UnixConsoleDxe/UnixConsole.inf + UnixPkg/UnixSimpleFileSystemDxe/UnixSimpleFileSystem.inf +!endif + + MdeModulePkg/Application/HelloWorld/HelloWorld.inf + + # + # Network stack drivers + # +##!if $(NETWORK_SUPPORT) & $(0) +!if $(0) + UnixPkg/UnixSnpDxe/UnixSnpDxe.inf +!endif + MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf + MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf + MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf + MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf + MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf + MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf + MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf + MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf + MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf + MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf + + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/PrintDxe/PrintDxe.inf + MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + +!if $(COMPILE_BINS) + FatPkg/EnhancedFatDxe/Fat.inf +!endif +!endif diff --git a/InOsEmuPkg/Unix/UnixX64.fdf b/InOsEmuPkg/Unix/UnixX64.fdf new file mode 100644 index 0000000000..48d9179c9c --- /dev/null +++ b/InOsEmuPkg/Unix/UnixX64.fdf @@ -0,0 +1,382 @@ +## @file +# This is Unix FDF file with UEFI HII features enabled +# +# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2009 - 2011, Apple Inc. 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. +# + +################################################################################ +# +# FD Section +# The [FD] Section is made up of the definition statements and a +# description of what goes into the Flash Device Image. Each FD section +# defines one flash "device" image. A flash device image may be one of +# the following: Removable media bootable image (like a boot floppy +# image,) an Option ROM image (that would be "flashed" into an add-in +# card,) a System "Flash" image (that would be burned into a system's +# flash) or an Update ("Capsule") image that will be used to update and +# existing system flash. +# +################################################################################ +[FD.Fv_Recovery] +# +# In OS X PEIMs are really XIP, so we need to make this address match the malloced +# buffer for the FD (0x41000000). If this address does not match the FV will get +# relocated in place (works, but not a great idea). +# +BaseAddress = 0x102000000|gInOsEmuPkgTokenSpaceGuid.PcdEmuFdBaseAddress #The base address of the FLASH Device. +Size = 0x005a0000|gInOsEmuPkgTokenSpaceGuid.PcdEmuFirmwareFdSize #The size in bytes of the FLASH Device +ErasePolarity = 1 +BlockSize = 0x10000 +NumBlocks = 0x5a + +################################################################################ +# +# Following are lists of FD Region layout which correspond to the locations of different +# images within the flash device. +# +# Regions must be defined in ascending order and may not overlap. +# +# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by +# the pipe "|" character, followed by the size of the region, also in hex with the leading +# "0x" characters. Like: +# Offset|Size +# PcdOffsetCName|PcdSizeCName +# RegionType +# +################################################################################ +0x00000000|0x00580000 +gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase|gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize +FV = FvRecovery + +0x00580000|0x0000c000 +gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +#NV_VARIABLE_STORE +DATA = { + ## This is the EFI_FIRMWARE_VOLUME_HEADER + # ZeroVector [] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + # FileSystemGuid: gEfiSystemNvDataFvGuid = + # { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} + 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, + 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50, + # FvLength: 0x20000 + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + # Signature "_FVH" #Attributes + 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00, + # HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision + 0x48, 0x00, 0x36, 0x09, 0x00, 0x00, 0x00, 0x02, + # Blockmap[0]: 2 Blocks * 0x10000 Bytes / Block + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + # Blockmap[1]: End + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ## This is the VARIABLE_STORE_HEADER + #Signature: gEfiVariableGuid = + # { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }} + 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41, + 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d, + #Size: 0xc000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xBFB8 + # This can speed up the Variable Dispatch a bit. + 0xB8, 0xBF, 0x00, 0x00, + #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32 + 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +0x0058c000|0x00002000 +#NV_EVENT_LOG +gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase|gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize + +0x0058e000|0x00002000 +gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +#NV_FTW_WORKING +DATA = { + # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEfiSystemNvDataFvGuid = + # { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} + 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, + 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50, + # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved + 0x77, 0x13, 0x9B, 0xD7, 0xFE, 0xFF, 0xFF, 0xFF, + # WriteQueueSize: UINT64 + 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +0x00590000|0x00010000 +#NV_FTW_SPARE +gInOsEmuPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + +################################################################################ +# +# FV Section +# +# [FV] section is used to define what components or modules are placed within a flash +# device file. This section also defines order the components and modules are positioned +# within the image. The [FV] section consists of define statements, set statements and +# module statements. +# +################################################################################ +[FV.FvRecovery] +FvAlignment = 16 #FV alignment and FV attributes setting. +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +################################################################################ +# +# The INF statements point to EDK component and EDK II module INF files, which will be placed into this FV image. +# Parsing tools will scan the INF file to determine the type of component or module. +# The component or module type is used to reference the standard rules +# defined elsewhere in the FDF file. +# +# The format for INF statements is: +# INF $(PathAndInfFileName) +# +################################################################################ +## +# PEI Phase modules +## +## +# PEI Apriori file example, more PEIM module added later. +## +APRIORI PEI { + INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf + INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf + INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf + } +APRIORI DXE { + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + INF InOsEmuPkg/MetronomeDxe/Metronome.inf + } +INF MdeModulePkg/Core/Pei/PeiMain.inf +INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf +INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf +INF InOsEmuPkg/BootModePei/BootModePei.inf +INF InOsEmuPkg/AutoScanPei/AutoScanPei.inf +INF InOsEmuPkg/FirmwareVolumePei/FirmwareVolumePei.inf +INF InOsEmuPkg/FlashMapPei/FlashMapPei.inf +INF InOsEmuPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf +INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf +INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf + +## +# DXE Phase modules +## +INF MdeModulePkg/Core/Dxe/DxeMain.inf +INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf +INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf +INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf +INF InOsEmuPkg/MetronomeDxe/Metronome.inf +INF InOsEmuPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf +INF InOsEmuPkg/ResetRuntimeDxe/Reset.inf +INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +INF InOsEmuPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf +INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf +INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf +INF InOsEmuPkg/EmuThunkDxe/EmuThunk.inf +INF InOsEmuPkg/CpuRuntimeDxe/Cpu.inf +INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf +INF InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.inf +INF InOsEmuPkg/TimerDxe/Timer.inf +INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf +INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf +INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf +INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf +INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf +INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf +INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf +INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf +INF IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + +INF InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf +INF InOsEmuPkg/EmuGopDxe/EmuGopDxe.inf +INF InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf + +#INF UnixPkg/UnixBlockIoDxe/UnixBlockIo.inf +#INF UnixPkg/UnixSerialIoDxe/UnixSerialIo.inf +INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf +INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf +INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf +INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf +INF MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf +INF MdeModulePkg/Application/HelloWorld/HelloWorld.inf + +# +# Network stack drivers +# +!if $(NETWORK_SUPPORT) +#INF UnixPkg/UnixSnpDxe/UnixSnpDxe.inf +!endif +INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf +INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf +INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf +INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf +INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf +INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf +INF MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf +INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf +INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf +INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf + + +!if $(COMPILE_BINS) +INF FatPkg/EnhancedFatDxe/Fat.inf +!else +# Used checked in Visual Studio binaries +INF RuleOverride = BINARY USE = X64 FatBinPkg/EnhancedFatDxe/Fat.inf +!endif + + FILE APPLICATION = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile) { +# SECTION PE32 = ShellBinPkg/UefiShell/X64/Shell.efi + SECTION PE32 = Build/GccShellPkg/DEBUG_XCLANG/X64/ShellFull.efi + SECTION UI = "Shell" + } + +FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) { + SECTION RAW = MdeModulePkg/Logo/Logo.bmp +} + + +################################################################################ +# +# Rules are use with the [FV] section's module INF type to define +# how an FFS file is created for a given INF file. The following Rule are the default +# rules for the different module type. User can add the customized rules to define the +# content of the FFS file. +# +################################################################################ + + +############################################################################ +# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section # +############################################################################ +# +#[Rule.Common.DXE_DRIVER] +# FILE DRIVER = $(NAMED_GUID) { +# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex +# COMPRESS PI_STD { +# GUIDED { +# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi +# UI STRING="$(MODULE_NAME)" Optional +# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) +# } +# } +# } +# +############################################################################ + +[Rule.Common.PEI_CORE] + FILE PEI_CORE = $(NAMED_GUID) { + PE32 PE32 Align=32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.PEIM] + FILE PEIM = $(NAMED_GUID) { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align=32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_CORE] + FILE DXE_CORE = $(NAMED_GUID) { + COMPRESS PI_STD { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + } + +[Rule.Common.UEFI_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + COMPRESS PI_STD { + GUIDED { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + } + } + +[Rule.Common.DXE_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + COMPRESS PI_STD { + GUIDED { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + } + } + +[Rule.Common.DXE_RUNTIME_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + COMPRESS PI_STD { + GUIDED { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + } + } + +[Rule.Common.UEFI_APPLICATION] + FILE APPLICATION = $(NAMED_GUID) { + COMPRESS PI_STD { + GUIDED { + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + } + } + +[Rule.Common.UEFI_DRIVER.BINARY] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional |.depex + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_APPLICATION.BINARY] + FILE APPLICATION = $(NAMED_GUID) { + PE32 PE32 |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + diff --git a/InOsEmuPkg/Unix/Xcode/xcode_project64/XcodeBuild.sh b/InOsEmuPkg/Unix/Xcode/xcode_project64/XcodeBuild.sh new file mode 100755 index 0000000000..634b1b025c --- /dev/null +++ b/InOsEmuPkg/Unix/Xcode/xcode_project64/XcodeBuild.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# External makefile Xcode project project uses this script to build and clean from the Xcode GUI +# +# Copyright (c) 2008 - 2011, Apple Inc. 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. +# + +# force exit on error +set -e + +# +# Source the workspace and set up the environment variables we need +# +cd ../.. +echo `pwd` +./build64.sh $1 $2 $3 $4 $5 $6 $8 diff --git a/InOsEmuPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/default.pbxuser b/InOsEmuPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/default.pbxuser new file mode 100644 index 0000000000..c0d31981fd --- /dev/null +++ b/InOsEmuPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/default.pbxuser @@ -0,0 +1,191 @@ +// !$*UTF8*$! +{ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + activeBuildConfigurationName = Debug; + activeExecutable = BA11A1010FB10BCE00D06FEC /* SecMain.dll */; + activeTarget = D28A88AD04BDD90700651E21 /* xcode_project */; + breakpoints = ( + BA11A11A0FB10E0700D06FEC /* SecGdbScriptBreak */, + ); + codeSenseManager = BA11A0FE0FB10B4800D06FEC /* Code sense */; + executables = ( + BA11A1010FB10BCE00D06FEC /* SecMain.dll */, + ); + perUserDictionary = { + "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 20, + 198, + 20, + 99, + 99, + 29, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBreakpointsDataSource_ActionID, + PBXBreakpointsDataSource_TypeID, + PBXBreakpointsDataSource_BreakpointID, + PBXBreakpointsDataSource_UseID, + PBXBreakpointsDataSource_LocationID, + PBXBreakpointsDataSource_ConditionID, + PBXBreakpointsDataSource_IgnoreCountID, + PBXBreakpointsDataSource_ContinueID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 229, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 341, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 263260969; + PBXWorkspaceStateSaveDate = 263260969; + }; + sourceControlManager = BA11A0FD0FB10B4800D06FEC /* Source Control */; + userBuildSettings = { + }; + }; + BA11A0FD0FB10B4800D06FEC /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + repositoryNamesForRoots = { + }; + scmConfiguration = { + }; + }; + BA11A0FE0FB10B4800D06FEC /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + BA11A1010FB10BCE00D06FEC /* SecMain.dll */ = { + isa = PBXExecutable; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + breakpointsEnabled = 1; + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + commandLineArgs = ( + ); + displayName = "Executable Runner"; + environment = { + }; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + "PBXLSLaunchAction-1" = { + PBXLSLaunchAction = 1; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXGDB_LaunchConfig; + commandLineArgs = ( + ); + displayName = GDB; + environment = { + }; + identifier = com.apple.Xcode.launch.GDBMI_Config; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + customDataFormattersEnabled = 0; + dataTipCustomDataFormattersEnabled = 1; + dataTipShowTypeColumn = 1; + dataTipSortType = 0; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + launchableReference = BA11A1020FB10BCE00D06FEC /* SecMain.dll */; + libgmallocEnabled = 0; + name = SecMain.dll; + savedGlobals = { + }; + showTypeColumn = 0; + sourceDirectories = ( + ); + startupPath = ../../../Build/UnixX64/DEBUG_UNIXPKG/X64; + }; + BA11A1020FB10BCE00D06FEC /* SecMain.dll */ = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + name = SecMain.dll; + path = ../../../Build/UnixX64/DEBUG_UNIXPKG/X64/SecMain; + sourceTree = SOURCE_ROOT; + }; + BA11A11A0FB10E0700D06FEC /* SecGdbScriptBreak */ = { + isa = PBXSymbolicBreakpoint; + actions = ( + BA11A11E0FB10E2200D06FEC /* XCBreakpointCommandAction */, + ); + breakpointStyle = 1; + continueAfterActions = 1; + countType = 0; + delayBeforeContinue = 0; + hitCount = 0; + ignoreCount = 0; + location = SecMain; + modificationTime = 263261853.260195; + originalNumberOfMultipleMatches = 1; + state = 1; + symbolName = SecGdbScriptBreak; + }; + BA11A11E0FB10E2200D06FEC /* XCBreakpointCommandAction */ = { + isa = XCBreakpointCommandAction; + command = "source SecMain.gdb"; + fallbackIsa = XCBreakpointAction; + logCommand = 0; + useDebuggerSideImplementation = 1; + }; + D28A88AD04BDD90700651E21 /* xcode_project */ = { + activeExec = 0; + }; +} diff --git a/InOsEmuPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/project.pbxproj b/InOsEmuPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..9bd13bd63f --- /dev/null +++ b/InOsEmuPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/project.pbxproj @@ -0,0 +1,124 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* xcode_project */ = { + isa = PBXGroup; + children = ( + ); + name = xcode_project; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + D28A88AD04BDD90700651E21 /* xcode_project */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "xcode_project" */; + buildPhases = ( + ); + buildToolPath = ./XcodeBuild.sh; + buildWorkingDirectory = ""; + dependencies = ( + ); + name = xcode_project; + passBuildSettingsInEnvironment = 1; + productName = xcode_project; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "xcode_project" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* xcode_project */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D28A88AD04BDD90700651E21 /* xcode_project */, + ); + }; +/* End PBXProject section */ + +/* Begin XCBuildConfiguration section */ + 1DEB919008733D9F0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = xcode_project; + }; + name = Debug; + }; + 1DEB919108733D9F0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = xcode_project; + }; + name = Release; + }; + 1DEB919408733D9F0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Debug; + }; + 1DEB919508733D9F0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "xcode_project" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB919008733D9F0010E9CD /* Debug */, + 1DEB919108733D9F0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "xcode_project" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB919408733D9F0010E9CD /* Debug */, + 1DEB919508733D9F0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/InOsEmuPkg/Unix/build64.sh b/InOsEmuPkg/Unix/build64.sh new file mode 100755 index 0000000000..e575a9266e --- /dev/null +++ b/InOsEmuPkg/Unix/build64.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# +# Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# Copyright (c) 2010, 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. +# + +set -e +shopt -s nocasematch + + +# +# Setup workspace if it is not set +# +if [ -z "$WORKSPACE" ] +then + echo Initializing workspace + if [ ! -e `pwd`/edksetup.sh ] + then + cd ../.. + fi +# This version is for the tools in the BaseTools project. +# this assumes svn pulls have the same root dir +# export EDK_TOOLS_PATH=`pwd`/../BaseTools +# This version is for the tools source in edk2 + export EDK_TOOLS_PATH=`pwd`/BaseTools + echo $EDK_TOOLS_PATH + source edksetup.sh BaseTools +else + echo Building from: $WORKSPACE +fi + +# +# Pick a default tool type for a given OS +# +TARGET_TOOLS=MYTOOLS +UNIXPKG_TOOLS=GCC44 +NETWORK_SUPPORT= +COMPILE_BINS= +case `uname` in + CYGWIN*) echo Cygwin not fully supported yet. ;; + Darwin*) + Major=$(uname -r | cut -f 1 -d '.') + if [[ $Major == 9 ]] + then + echo UnixPkg requires Snow Leopard or later OS + exit 1 + else + TARGET_TOOLS=XCODE32 + UNIXPKG_TOOLS=XCLANG + fi + NETWORK_SUPPORT="-D NETWORK_SUPPORT" + COMPILE_BINS="-D COMPILE_BINS" + ;; + Linux*) TARGET_TOOLS=ELFGCC ;; + +esac + +BUILD_ROOT_ARCH=$WORKSPACE/Build/EmuUnixX64/DEBUG_"$UNIXPKG_TOOLS"/X64 + +if [[ ! -f `which build` || ! -f `which GenFv` ]]; +then + # build the tools if they don't yet exist. Bin scheme + echo Building tools as they are not in the path + make -C $WORKSPACE/BaseTools +elif [[ ( -f `which build` || -f `which GenFv` ) && ! -d $EDK_TOOLS_PATH/Source/C/bin ]]; +then + # build the tools if they don't yet exist. BinWrapper scheme + echo Building tools no $EDK_TOOLS_PATH/Source/C/bin directory + make -C $WORKSPACE/BaseTools +else + echo using prebuilt tools +fi + + +for arg in "$@" +do + if [[ $arg == run ]]; then + case `uname` in + Darwin*) + # + # On Darwin we can't use dlopen, so we have to load the real PE/COFF images. + # This .gdbinit script sets a breakpoint that loads symbols for the PE/COFFEE + # images that get loaded in SecMain + # + cp $WORKSPACE/InOsEmuPkg/Unix/.gdbinit $WORKSPACE/Build/EmuUnixX64/DEBUG_"$UNIXPKG_TOOLS"/X64 + ;; + esac + + /usr/bin/gdb $BUILD_ROOT_ARCH/SecMain -q -cd=$BUILD_ROOT_ARCH + exit + fi + + if [[ $arg == cleanall ]]; then + make -C $WORKSPACE/BaseTools clean + build -p $WORKSPACE/InOsEmuPkg/Unix/UnixX64.dsc -a X64 -t $TARGET_TOOLS -D SEC_ONLY -n 3 clean + build -p $WORKSPACE/InOsEmuPkg/Unix/UnixX64.dsc -a X64 -t $UNIXPKG_TOOLS -n 3 clean + build -p $WORKSPACE/ShellPkg/ShellPkg.dsc -a X64 -t $UNIXPKG_TOOLS -n 3 clean + exit $? + fi + + if [[ $arg == clean ]]; then + build -p $WORKSPACE/InOsEmuPkg/Unix/UnixX64.dsc -a X64 -t $TARGET_TOOLS -D SEC_ONLY -n 3 clean + build -p $WORKSPACE/InOsEmuPkg/Unix/UnixX64.dsc -a X64 -t $UNIXPKG_TOOLS -n 3 clean + exit $? + fi + + if [[ $arg == shell ]]; then + build -p $WORKSPACE/ShellPkg/ShellPkg.dsc -a X64 -t $UNIXPKG_TOOLS -n 3 $2 $3 $4 $5 $6 $7 $8 + cp Build/Shell/DEBUG_$UNIXPKG_TOOLS/X64/Shell.efi ShellBinPkg/UefiShell/X64/Shell.efi + exit $? + fi +done + + +# +# Build the edk2 UnixPkg +# +echo $PATH +echo `which build` +build -p $WORKSPACE/InOsEmuPkg/Unix/UnixX64.dsc -a X64 -t $TARGET_TOOLS -D SEC_ONLY -n 3 $1 $2 $3 $4 $5 $6 $7 $8 modules +build -p $WORKSPACE/InOsEmuPkg/Unix/UnixX64.dsc -a X64 -t $UNIXPKG_TOOLS $NETWORK_SUPPORT -n 3 $1 $2 $3 $4 $5 $6 $7 $8 +cp $WORKSPACE/Build/EmuUnixX64/DEBUG_"$TARGET_TOOLS"/X64/SecMain $WORKSPACE/Build/EmuUnixX64/DEBUG_"$UNIXPKG_TOOLS"/X64 +exit $? + diff --git a/InOsEmuPkg/build64.sh b/InOsEmuPkg/build64.sh new file mode 100755 index 0000000000..a1d47b7292 --- /dev/null +++ b/InOsEmuPkg/build64.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# +# Copyright (c) 2011, Apple Inc. 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. +# + +cd Unix +. build64.sh $1 $2 $3 $4 $5 $6 $7 $8 + -- 2.39.2