diff --git a/Vlv2TbltDevicePkg/CustomShellPkg/Application/Shell/Shell.c b/Vlv2TbltDevicePkg/CustomShellPkg/Application/Shell/Shell.c index 20d2e0eec25..618dda27a11 100644 --- a/Vlv2TbltDevicePkg/CustomShellPkg/Application/Shell/Shell.c +++ b/Vlv2TbltDevicePkg/CustomShellPkg/Application/Shell/Shell.c @@ -15,6 +15,9 @@ **/ #include "Shell.h" +#include +#include +#include // // Initialize the global structure @@ -315,6 +318,184 @@ InternalEfiShellStartCtrlSMonitor( return (Status); } +SHELL_STATUS +EFIAPI +TrampolineBareflank( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_GUID BareflankGuid = {0x78563412, 0x3412, 0x7856, {0x90, 0x12, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12}}; //TODO: use proper GUID + EFI_STATUS Status; + EFI_STATUS CleanupStatus; + EFI_HANDLE NewHandle; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + MEMMAP_DEVICE_PATH MemPath[2]; + UINTN FvHandleCount; + EFI_HANDLE *FvHandleBuffer; + EFI_FV_FILETYPE Type; + UINTN Size; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINT32 AuthenticationStatus; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; + VOID *Buffer; + UINTN i; + + Buffer = NULL; + + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &FvHandleCount, + &FvHandleBuffer + ); + for (i = 0; i < FvHandleCount; i++) { + gBS->HandleProtocol ( + FvHandleBuffer[i], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + + Status = Fv->ReadFile ( + Fv, + &BareflankGuid, + &Buffer, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (Status == EFI_NOT_FOUND) { + Print(L"Image not found in Fv[%d]\n", i); + continue; + } + else if (Status == EFI_SUCCESS) { + Print(L"Image found in Fv[%d]\n", i); + Print(L"\tBuffer %x\n", Buffer); + Print(L"\tSize %x\n", Size); + Print(L"\tType %x\n", Type); + Print(L"\tAttributes %x\n", Attributes); + Print(L"\tAuthenticationStatus %x\n", AuthenticationStatus); + break; + } + else { + Print(L"Error in Fv[%d]: %d\n", i, Status & ~0x80000000); + } + } + + if (Buffer == NULL) { + Print(L"Image not found in any Fv\n"); + return SHELL_NOT_FOUND; + } + + MemPath[0].Header.Type = HARDWARE_DEVICE_PATH; + MemPath[0].Header.SubType = HW_MEMMAP_DP; + MemPath[0].Header.Length[0] = (UINT8)sizeof(MEMMAP_DEVICE_PATH); + MemPath[0].Header.Length[1] = (UINT8)(sizeof(MEMMAP_DEVICE_PATH) >> 8); + MemPath[0].MemoryType = EfiLoaderCode; + + // Buffer+4 - header of PE32 **section**. TODO: is it defined anywhere in the code? + MemPath[0].StartingAddress = ((UINTN)Buffer)+4; + MemPath[0].EndingAddress = MemPath[0].StartingAddress + Size; + + MemPath[1].Header.Type = END_DEVICE_PATH_TYPE; + MemPath[1].Header.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; + MemPath[1].Header.Length[0] = (UINT8)sizeof(EFI_DEVICE_PATH); + MemPath[1].Header.Length[1] = (UINT8)(sizeof(EFI_DEVICE_PATH) >> 8); + + ImageHandle = gImageHandle; + NewHandle = NULL; + + // + // Load the image with: + // FALSE - not from boot manager, + // address and size of memory region where the image is located. + // + Status = gBS->LoadImage( + FALSE, + ImageHandle, + (EFI_DEVICE_PATH_PROTOCOL*)MemPath, + (VOID*) ((UINTN)(MemPath[0].StartingAddress)), + MemPath[0].EndingAddress - MemPath[0].StartingAddress, + &NewHandle); + + if (EFI_ERROR(Status)) { + if (NewHandle != NULL) { + gBS->UnloadImage(NewHandle); + } + return Status; + } + Status = gBS->OpenProtocol( + NewHandle, + &gEfiLoadedImageProtocolGuid, + (VOID**)&LoadedImage, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (!EFI_ERROR(Status)) { + // + // If the image is not an app abort it. + // + if (LoadedImage->ImageCodeType != EfiLoaderCode){ + ShellPrintHiiEx( + -1, + -1, + NULL, + STRING_TOKEN (STR_SHELL_IMAGE_NOT_APP), + ShellInfoObject.HiiHandle); + + gBS->UnloadImage(NewHandle); + return Status; + } + + ASSERT(LoadedImage->LoadOptionsSize == 0); + + // + // Install a shell parameters protocol on the image. + // + Status = gBS->InstallProtocolInterface( + &NewHandle, + &gEfiShellParametersProtocolGuid, + EFI_NATIVE_INTERFACE, + ShellInfoObject.NewShellParametersProtocol); + ASSERT_EFI_ERROR(Status); + + // + // Now start the image. + // + if (!EFI_ERROR(Status)) { + Status = gBS->StartImage( + NewHandle, + 0, + NULL); + + CleanupStatus = gBS->UninstallProtocolInterface( + NewHandle, + &gEfiShellParametersProtocolGuid, + ShellInfoObject.NewShellParametersProtocol); + + // Print a new line for applications that forgot to do so. + ShellPrintEx(-1, -1, L"\r\n"); + ASSERT_EFI_ERROR(CleanupStatus); + return Status; + } + + // Unload image - We should only get here if we didn't call StartImage. + gBS->UnloadImage(NewHandle); + } + + // TODO: should Buffer be deallocated? When? How? + /* + * ReadFile() will allocate an appropriately sized buffer from boot services + * pool memory, which will be returned in *Buffer. The size of the new buffer + * is returned in *BufferSize + */ + + return Status; +} + /** Internal worker function to load and run an image via memory-mapped device path. It is a modified InternalShellExecuteDevicePath() from ShellProtocol.c, tailored @@ -328,7 +509,8 @@ InternalEfiShellStartCtrlSMonitor( @retval EFI_UNSUPPORTED Nested shell invocations are not allowed. @retval other Return value of underlying application. **/ -EFI_STATUS +SHELL_STATUS +EFIAPI Trampoline( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -448,6 +630,33 @@ Trampoline( return Status; } +SHELL_STATUS +EFIAPI +TestBF( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINTN rax = 0xbf00; + + ShellPrintEx(-1, -1, L"Testing for Bareflank: "); + + asm volatile ( + "cpuid\n\t" + : "+a"(rax)); + + if (rax == 0xbf01) { + ShellPrintEx(-1, -1, L"success\r\n"); + } else { + ShellPrintEx(-1, -1, L"error (%x)\r\n\ + Trying vmcall (this will hang if Bareflank isn't started): ", rax); + asm volatile ("vmcall\n\t"); + ShellPrintEx(-1, -1, L"success\r\n"); + } + + return SHELL_SUCCESS; +} + CONST CHAR16* EFIAPI RtnicGetManFileName ( @@ -761,6 +970,26 @@ UefiMain ( ShellPrintEx(-1, -1, L"\r\nShellCommandRegisterCommandName error: %x\r\n", Status); } + ShellCommandRegisterCommandName(L"bareflank", //*CommandString, + &TrampolineBareflank, //CommandHandler, + RtnicGetManFileName, //GetManFileName, + 3, //ShellMinSupportLevel, + L"", //*ProfileName, + TRUE, //CanAffectLE, + ShellInfoObject.HiiHandle, //HiiHandle, + STRING_TOKEN(STR_SHELL_CRLF) //ManFormatHelp + ); + + ShellCommandRegisterCommandName(L"testbf", //*CommandString, + &TestBF, //CommandHandler, + RtnicGetManFileName, //GetManFileName, + 3, //ShellMinSupportLevel, + L"", //*ProfileName, + TRUE, //CanAffectLE, + ShellInfoObject.HiiHandle, //HiiHandle, + STRING_TOKEN(STR_SHELL_CRLF) //ManFormatHelp + ); + // // begin the UI waiting loop // diff --git a/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf b/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf index 0a426513c6b..63ce4300767 100644 --- a/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf +++ b/Vlv2TbltDevicePkg/PlatformPkgGcc.fdf @@ -657,6 +657,13 @@ FILE DRIVER = 961578FE-B6B7-44c3-AF35-6BC705CD2B1F { SECTION PE32 = FatBinPkg/EnhancedFatDxe/$(EDK_DXE_ARCHITECTURE)/Fat.efi } +# +# Bareflank +# +FILE APPLICATION = 78563412-3412-7856-9012-123456789012 { + SECTION PE32 = bareflank.efi + } + # # UEFI Shell # diff --git a/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc b/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc index 1daf7137ee0..8e02b8c87ac 100644 --- a/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc +++ b/Vlv2TbltDevicePkg/PlatformPkgGccX64.dsc @@ -1844,3 +1844,63 @@ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmmDxe.inf gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x00000043 } + +[PcdsFixedAtBuild] + ## This flag is used to control initialization of the shell library + # This should be FALSE for compiling the shell application itself only. + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + + # + # Shell Lib + # +[LibraryClasses] + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + +[Components.X64] + Vlv2TbltDevicePkg/CustomShellPkg/Application/Shell/Shell.inf { + + #------------------------------ + # Basic commands + #------------------------------ + + + NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf + + #------------------------------ + # Networking commands + #------------------------------ + + + NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf + + #------------------------------ + # Performance command + #------------------------------ + + + NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf + + #------------------------------ + # Support libraries + #------------------------------ + + + DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf + NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf + ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + } diff --git a/Vlv2TbltDevicePkg/bld_vlv.sh b/Vlv2TbltDevicePkg/bld_vlv.sh index 121a63abf8c..aef0120a0ce 100755 --- a/Vlv2TbltDevicePkg/bld_vlv.sh +++ b/Vlv2TbltDevicePkg/bld_vlv.sh @@ -28,7 +28,7 @@ export WORKSPACE=$(pwd) #build_threads=($NUMBER_OF_PROCESSORS)+1 Build_Flags= exitCode=0 -Arch=IA32 +Arch=X64 SpiLock=0 export CORE_PATH=$WORKSPACE/edk2