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 0000000000..4f8d41e798 Binary files /dev/null and b/InOsEmuPkg/CpuRuntimeDxe/Strings.uni differ 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 0000000000..669654ece4 Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBaseBoardManufacturer.uni differ 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 0000000000..dda02d2970 Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscBiosVendor.uni differ 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 0000000000..177ff38925 Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscChassisManufacturer.uni differ 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 0000000000..782a83bf89 Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscOemString.uni differ 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 0000000000..87c5a8112b Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscPortInternalConnectorDesignator.uni differ 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 0000000000..7a4e8a2cbc Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubClassDriver.uni differ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubclassDriverDataTable.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubclassDriverDataTable.c new file mode 100644 index 0000000000..cb71f7db50 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSubclassDriverDataTable.c @@ -0,0 +1,78 @@ +/*++ + +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: + + 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 0000000000..709c53a660 Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageString.uni differ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageStringData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageStringData.c new file mode 100644 index 0000000000..0dc706e659 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemLanguageStringData.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: + + 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 0000000000..3ff890b83d Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemManufacturer.uni differ 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 0000000000..abf2da762c Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionString.uni differ diff --git a/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionStringData.c b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionStringData.c new file mode 100644 index 0000000000..581586b857 --- /dev/null +++ b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemOptionStringData.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: + + 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 0000000000..45e9ce3c00 Binary files /dev/null and b/InOsEmuPkg/MiscSubClassPlatformDxe/MiscSystemSlotDesignation.uni differ 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 +