From 033d0e5ff6324045ffbb1c95cbecb2215e2d6716 Mon Sep 17 00:00:00 2001 From: andrewfish Date: Fri, 3 Jun 2011 03:31:32 +0000 Subject: Get BlockIo mapping interfaces working. Still need to work on detecting block size of devices, but you can map a .dmg file no problem at this point. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11724 6f19259b-4bc3-4df7-8a09-765794883524 --- InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c | 16 +- InOsEmuPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf | 2 +- InOsEmuPkg/InOsEmuPkg.dec | 1 + InOsEmuPkg/Include/Protocol/EmuBlockIo.h | 6 +- InOsEmuPkg/Unix/Sec/BlockIo.c | 1119 ++++++++++------------------ InOsEmuPkg/Unix/Sec/Gasket.h | 50 ++ InOsEmuPkg/Unix/Sec/PosixFileSystem.c | 2 +- InOsEmuPkg/Unix/Sec/SecMain.c | 3 + InOsEmuPkg/Unix/Sec/SecMain.h | 3 +- InOsEmuPkg/Unix/Sec/SecMain.inf | 3 +- InOsEmuPkg/Unix/Sec/X64/Gasket.S | 134 ++++ InOsEmuPkg/Unix/UnixX64.dsc | 14 +- InOsEmuPkg/Unix/UnixX64.fdf | 5 +- InOsEmuPkg/Unix/build64.sh | 4 +- 14 files changed, 597 insertions(+), 765 deletions(-) (limited to 'InOsEmuPkg') diff --git a/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c b/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c index 999445bae2..9f3aa28b9e 100644 --- a/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c +++ b/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c @@ -232,7 +232,7 @@ EmuBlockIoReset ( EMU_BLOCK_IO_PRIVATE *Private; EFI_TPL OldTpl; - Private = EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS (This); + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); OldTpl = gBS->RaiseTPL (TPL_CALLBACK); @@ -264,8 +264,7 @@ EmuBlockIoReset ( **/ EFI_STATUS EFIAPI -EmuBlockIoReadBlocks -( +EmuBlockIoReadBlocks ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, @@ -278,7 +277,7 @@ EmuBlockIoReadBlocks EFI_TPL OldTpl; EFI_BLOCK_IO2_TOKEN Token; - Private = EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS (This); + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); OldTpl = gBS->RaiseTPL (TPL_CALLBACK); @@ -325,7 +324,7 @@ EmuBlockIoWriteBlocks ( EFI_TPL OldTpl; EFI_BLOCK_IO2_TOKEN Token; - Private = EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS (This); + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); OldTpl = gBS->RaiseTPL (TPL_CALLBACK); @@ -357,7 +356,7 @@ EmuBlockIoFlushBlocks ( EFI_TPL OldTpl; EFI_BLOCK_IO2_TOKEN Token; - Private = EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS (This); + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); OldTpl = gBS->RaiseTPL (TPL_CALLBACK); @@ -442,7 +441,7 @@ EmuBlockIoDriverBindingSupported ( // Make sure GUID is for a File System handle. // Status = EFI_UNSUPPORTED; - if (CompareGuid (EmuIoThunk->Protocol, &gEmuVirtualDisksGuid)) { + if (CompareGuid (EmuIoThunk->Protocol, &gEmuBlockIoProtocolGuid)) { Status = EFI_SUCCESS; } @@ -524,7 +523,7 @@ EmuBlockIoDriverBindingStart ( // // Set DiskType // - if (!CompareGuid (EmuIoThunk->Protocol, &gEmuVirtualDisksGuid)) { + if (!CompareGuid (EmuIoThunk->Protocol, &gEmuBlockIoProtocolGuid)) { Status = EFI_UNSUPPORTED; goto Done; } @@ -542,6 +541,7 @@ EmuBlockIoDriverBindingStart ( Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE; Private->IoThunk = EmuIoThunk; Private->Io = EmuIoThunk->Interface; + Private->EfiHandle = Handle; Private->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2; Private->BlockIo.Media = &Private->Media; diff --git a/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf b/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf index 24f4759d66..82460e40ec 100644 --- a/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf +++ b/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf @@ -66,4 +66,4 @@ gEfiBlockIoProtocolGuid # PROTOCOL BY_START gEfiBlockIo2ProtocolGuid # PROTOCOL BY_START gEmuIoThunkProtocolGuid # PROTOCOL TO_START - + gEmuBlockIoProtocolGuid # PROTOCOL BY_START diff --git a/InOsEmuPkg/InOsEmuPkg.dec b/InOsEmuPkg/InOsEmuPkg.dec index 3a7417fd97..7cbed7f573 100644 --- a/InOsEmuPkg/InOsEmuPkg.dec +++ b/InOsEmuPkg/InOsEmuPkg.dec @@ -36,6 +36,7 @@ gEmuIoThunkProtocolGuid = { 0x453368F6, 0x7C85, 0x434A, { 0xA9, 0x8A, 0x72, 0xD1, 0xB7, 0xFF, 0xA9, 0x26 } } gEmuGraphicsWindowProtocolGuid = { 0x30FD316A, 0x6728, 0x2E41, { 0xA6, 0x90, 0x0D, 0x13, 0x33, 0xD8, 0xCA, 0xC1 } } gEmuThreadThunkProtocolGuid = { 0x3B1E4B7C, 0x09D8, 0x944F, { 0xA4, 0x08, 0x13, 0x09, 0xEB, 0x8B, 0x44, 0x27 } } + gEmuBlockIoProtocolGuid = { 0x6888A4AE, 0xAFCE, 0xE84B, { 0x91, 0x02, 0xF7, 0xB9, 0xDA, 0xE6, 0xA0, 0x30 } } [Ppis] gEmuThunkPpiGuid = { 0xE113F896, 0x75CF, 0xF640, { 0x81, 0x7F, 0xC8, 0x5A, 0x79, 0xE8, 0xAE, 0x67 } } diff --git a/InOsEmuPkg/Include/Protocol/EmuBlockIo.h b/InOsEmuPkg/Include/Protocol/EmuBlockIo.h index f31124dc01..26d6bb8518 100644 --- a/InOsEmuPkg/Include/Protocol/EmuBlockIo.h +++ b/InOsEmuPkg/Include/Protocol/EmuBlockIo.h @@ -23,7 +23,7 @@ #include #define EMU_BLOCK_IO_PROTOCOL_GUID \ - { 0x3EC5F7E0, 0x1124, 0xDF45, { 0x9F, 0x96, 0x7D, 0xD6, 0x63, 0xC0, 0xAF, 0xE7 } } +{ 0x6888A4AE, 0xAFCE, 0xE84B, { 0x91, 0x02, 0xF7, 0xB9, 0xDA, 0xE6, 0xA0, 0x30 } } typedef struct _EMU_BLOCK_IO_PROTOCOL EMU_BLOCK_IO_PROTOCOL; @@ -90,7 +90,7 @@ EFI_STATUS IN EFI_LBA LBA, IN OUT EFI_BLOCK_IO2_TOKEN *Token, IN UINTN BufferSize, - OUT VOID *Buffer + OUT VOID *Buffer ); /** @@ -127,7 +127,7 @@ EFI_STATUS typedef EFI_STATUS (EFIAPI *EMU_BLOCK_WRITE) ( - IN EMU_BLOCK_IO_PROTOCOL *This, + IN EMU_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA LBA, IN OUT EFI_BLOCK_IO2_TOKEN *Token, diff --git a/InOsEmuPkg/Unix/Sec/BlockIo.c b/InOsEmuPkg/Unix/Sec/BlockIo.c index 3fc1d3f9aa..1636d9508c 100644 --- a/InOsEmuPkg/Unix/Sec/BlockIo.c +++ b/InOsEmuPkg/Unix/Sec/BlockIo.c @@ -9,598 +9,111 @@ http://opensource.org/licenses/bsd-license.php 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: - - UnixBlockIo.c - -Abstract: - - Produce block IO abstractions for real devices 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. - - ixed - Fixed disk like a hard drive. - emovable - Removable media like a floppy or CD-ROM. - Read nly - Write protected device. - Read rite - Read write device. - - Decimal number of blocks a device supports. - - Decimal number of bytes per block. - - UNIX envirnonment variable contents. '<' and '>' are not part of the variable, - they are just used to make this help more readable. There should be no - spaces between the ';'. Extra spaces will break the variable. A '!' is - used to seperate multiple devices in a variable. - - EFI_EMU_VIRTUAL_DISKS = - ;;[!...] - - EFI_EMU_PHYSICAL_DISKS = - :;;[!...] - - Virtual Disks: These devices use a file to emulate a hard disk or removable - media device. - - Thus a 20 MB emulated hard drive would look like: - EFI_EMU_VIRTUAL_DISKS=FW;40960;512 - - A 1.44MB emulated floppy with a block size of 1024 would look like: - EFI_EMU_VIRTUAL_DISKS=RW;1440;1024 - - Physical Disks: These devices use UNIX to open a real device in your system - - Thus a 120 MB floppy would look like: - EFI_EMU_PHYSICAL_DISKS=B:RW;245760;512 - - Thus a standard CD-ROM floppy would look like: - EFI_EMU_PHYSICAL_DISKS=Z:RO;307200;2048 - - - * Other names and brands may be claimed as the property of others. - **/ -#include -#include -#include "UnixBlockIo.h" - -// -// Block IO protocol member functions -// -EFI_STATUS -EFIAPI -UnixBlockIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -EFI_STATUS -EFIAPI -UnixBlockIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -EFI_STATUS -EFIAPI -UnixBlockIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ); - -EFI_STATUS -EFIAPI -UnixBlockIoResetBlock ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -// -// Private Worker functions -// -EFI_STATUS -UnixBlockIoCreateMapping ( - IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk, - IN EFI_HANDLE EfiDeviceHandle, - IN CHAR16 *Filename, - IN BOOLEAN ReadOnly, - IN BOOLEAN RemovableMedia, - IN UINTN NumberOfBlocks, - IN UINTN BlockSize - ); - -EFI_STATUS -UnixBlockIoReadWriteCommon ( - IN EMU_BLOCK_IO_PRIVATE *Private, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer, - IN CHAR8 *CallerName - ); +//#include +//#include +#include "SecMain.h" -EFI_STATUS -UnixBlockIoError ( - IN EMU_BLOCK_IO_PRIVATE *Private - ); +#define EMU_BLOCK_IO_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'M', 'b', 'k') +typedef struct { + UINTN Signature; -EFI_STATUS -UnixBlockIoOpenDevice ( - EMU_BLOCK_IO_PRIVATE *Private - ); + EMU_IO_THUNK_PROTOCOL *Thunk; -CHAR16 * -GetNextElementPastTerminator ( - IN CHAR16 *EnvironmentVariable, - IN CHAR16 Terminator - ); + char *Filename; + UINTN ReadMode; + UINTN Mode; + int fd; - -EFI_DRIVER_BINDING_PROTOCOL gUnixBlockIoDriverBinding = { - UnixBlockIoDriverBindingSupported, - UnixBlockIoDriverBindingStart, - UnixBlockIoDriverBindingStop, - 0xa, - NULL, - NULL -}; - -/** - The user Entry Point for module UnixBlockIo. 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 -InitializeUnixBlockIo( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = EfiLibInstallAllDriverProtocols2 ( - ImageHandle, - SystemTable, - &gUnixBlockIoDriverBinding, - ImageHandle, - &gUnixBlockIoComponentName, - &gUnixBlockIoComponentName2, - NULL, - &gUnixBlockIoDriverDiagnostics, - &gUnixBlockIoDriverDiagnostics2 - ); - ASSERT_EFI_ERROR (Status); - - - return Status; -} - -EFI_STATUS -EFIAPI -UnixBlockIoDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Handle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - -**/ -{ - 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; - } - - // - // Make sure the UnixThunkProtocol is valid - // - Status = EFI_UNSUPPORTED; - if (EmuIoThunk->UnixThunk->Signature == EFI_EMU_THUNK_PROTOCOL_SIGNATURE) { - - // - // Check the GUID to see if this is a handle type the driver supports - // - if (CompareGuid (EmuIoThunk->TypeGuid, &gEfiUnixVirtualDisksGuid) ) { - Status = EFI_SUCCESS; - } - } - - // - // Close the I/O Abstraction(s) used to perform the supported test - // - gBS->CloseProtocol ( - Handle, - &gEmuIoThunkProtocolGuid, - This->DriverBindingHandle, - Handle - ); - return Status; -} - -EFI_STATUS -EFIAPI -UnixBlockIoDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Handle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -/*++ - -Routine Description: - -Arguments: - -Returns: - - None - -**/ -{ - EFI_STATUS Status; - EMU_IO_THUNK_PROTOCOL *EmuIoThunk; - CHAR16 Buffer[FILENAME_BUFFER_SIZE]; - CHAR16 *Str; BOOLEAN RemovableMedia; BOOLEAN WriteProtected; - UINTN NumberOfBlocks; - UINTN BlockSize; - INTN i; - // - // 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 Status; - } - // - // Set DiskType - // - if (!CompareGuid (EmuIoThunk->TypeGuid, &gEfiUnixVirtualDisksGuid)) { - Status = EFI_UNSUPPORTED; - goto Done; - } + UINTN BlockSize; + UINT64 NumberOfBlocks; + UINT64 LastBlock; - Status = EFI_NOT_FOUND; - // Extract filename. - Str = EmuIoThunk->EnvString; - i = 0; - while (*Str && *Str != ':') - Buffer[i++] = *Str++; - Buffer[i] = 0; - if (*Str != ':') { - goto Done; - } + EMU_BLOCK_IO_PROTOCOL EmuBlockIo; + EFI_BLOCK_IO_MEDIA *Media; - Str++; +} EMU_BLOCK_IO_PRIVATE; - RemovableMedia = FALSE; - WriteProtected = TRUE; - NumberOfBlocks = 0; - BlockSize = 512; - do { - if (*Str == 'R' || *Str == 'F') { - RemovableMedia = (BOOLEAN) (*Str == 'R'); - Str++; - } - if (*Str == 'O' || *Str == 'W') { - WriteProtected = (BOOLEAN) (*Str == 'O'); - Str++; - } - if (*Str == 0) - break; - if (*Str != ';') - goto Done; - Str++; - - NumberOfBlocks = Atoi (Str); - Str = GetNextElementPastTerminator (Str, ';'); - if (NumberOfBlocks == 0) - break; - - BlockSize = Atoi (Str); - if (BlockSize != 0) - Str = GetNextElementPastTerminator (Str, ';'); - } while (0); +#define EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, EMU_BLOCK_IO_PRIVATE, EmuBlockIo, EMU_BLOCK_IO_PRIVATE_SIGNATURE) - // - // If we get here the variable is valid so do the work. - // - Status = UnixBlockIoCreateMapping ( - EmuIoThunk, - Handle, - Buffer, - WriteProtected, - RemovableMedia, - NumberOfBlocks, - BlockSize - ); -Done: - if (EFI_ERROR (Status)) { - gBS->CloseProtocol ( - Handle, - &gEmuIoThunkProtocolGuid, - This->DriverBindingHandle, - Handle - ); - } - - return Status; -} EFI_STATUS -EFIAPI -UnixBlockIoDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Handle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_STATUS Status; - EMU_BLOCK_IO_PRIVATE *Private; - - // - // Get our context back - // - Status = gBS->OpenProtocol ( - Handle, - &gEfiBlockIoProtocolGuid, - (void *)&BlockIo, - This->DriverBindingHandle, - Handle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo); - - // - // BugBug: If we need to kick people off, we need to make Uninstall Close the handles. - // We could pass in our image handle or FLAG our open to be closed via - // Unistall (== to saying any CloseProtocol will close our open) - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - Private->EfiHandle, - &gEfiBlockIoProtocolGuid, - &Private->BlockIo, - NULL - ); - if (!EFI_ERROR (Status)) { - - Status = gBS->CloseProtocol ( - Handle, - &gEmuIoThunkProtocolGuid, - This->DriverBindingHandle, - Handle - ); - - // - // Shut down our device - // - Private->UnixThunk->Close (Private->fd); - - // - // Free our instance data - // - FreeUnicodeStringTable (Private->ControllerNameTable); +EmuBlockIoReset ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); - gBS->FreePool (Private); - } - return Status; -} - -CHAR16 * -GetNextElementPastTerminator ( - IN CHAR16 *EnvironmentVariable, - IN CHAR16 Terminator - ) /*++ -Routine Description: - - Worker function to parse environment variables. - -Arguments: - EnvironmentVariable - Envirnment variable to parse. - - Terminator - Terminator to parse for. - -Returns: - - Pointer to next eliment past the first occurence of Terminator or the '\0' - at the end of the string. +This function extends the capability of SetFilePointer to accept 64 bit parameters **/ -{ - CHAR16 *Ptr; - - for (Ptr = EnvironmentVariable; *Ptr != '\0'; Ptr++) { - if (*Ptr == Terminator) { - Ptr++; - break; - } - } - - return Ptr; -} - EFI_STATUS -UnixBlockIoCreateMapping ( - IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk, - IN EFI_HANDLE EfiDeviceHandle, - IN CHAR16 *Filename, - IN BOOLEAN ReadOnly, - IN BOOLEAN RemovableMedia, - IN UINTN NumberOfBlocks, - IN UINTN BlockSize +SetFilePointer64 ( + IN EMU_BLOCK_IO_PRIVATE *Private, + IN INT64 DistanceToMove, + OUT UINT64 *NewFilePointer, + IN INT32 MoveMethod ) { - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EMU_BLOCK_IO_PRIVATE *Private; - UINTN Index; - - Status = gBS->AllocatePool ( - EfiBootServicesData, - sizeof (EMU_BLOCK_IO_PRIVATE), - (void *)&Private - ); - ASSERT_EFI_ERROR (Status); - - EfiInitializeLock (&Private->Lock, TPL_NOTIFY); - - Private->UnixThunk = EmuIoThunk->UnixThunk; - - Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE; - Private->LastBlock = NumberOfBlocks - 1; - Private->BlockSize = BlockSize; + EFI_STATUS Status; + off_t res; - for (Index = 0; Filename[Index] != 0; Index++) { - Private->Filename[Index] = Filename[Index]; + Status = EFI_SUCCESS; + res = lseek (Private->fd, DistanceToMove, MoveMethod); + if (res == -1) { + Status = EFI_INVALID_PARAMETER; } - Private->Filename[Index] = 0; - - Private->Mode = (ReadOnly ? O_RDONLY : O_RDWR); - - Private->NumberOfBlocks = NumberOfBlocks; - Private->fd = -1; - - Private->ControllerNameTable = NULL; - - AddUnicodeString ( - "eng", - gUnixBlockIoComponentName.SupportedLanguages, - &Private->ControllerNameTable, - Filename - ); - - BlockIo = &Private->BlockIo; - BlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION; - BlockIo->Media = &Private->Media; - BlockIo->Media->BlockSize = Private->BlockSize; - BlockIo->Media->LastBlock = Private->NumberOfBlocks - 1; - BlockIo->Media->MediaId = 0;; - - BlockIo->Reset = UnixBlockIoResetBlock; - BlockIo->ReadBlocks = UnixBlockIoReadBlocks; - BlockIo->WriteBlocks = UnixBlockIoWriteBlocks; - BlockIo->FlushBlocks = UnixBlockIoFlushBlocks; - - BlockIo->Media->ReadOnly = ReadOnly; - BlockIo->Media->RemovableMedia = RemovableMedia; - BlockIo->Media->LogicalPartition = FALSE; - BlockIo->Media->MediaPresent = TRUE; - BlockIo->Media->WriteCaching = FALSE; - - BlockIo->Media->IoAlign = 1; - - Private->EfiHandle = EfiDeviceHandle; - Status = UnixBlockIoOpenDevice (Private); - if (!EFI_ERROR (Status)) { - - Status = gBS->InstallMultipleProtocolInterfaces ( - &Private->EfiHandle, - &gEfiBlockIoProtocolGuid, - &Private->BlockIo, - NULL - ); - if (EFI_ERROR (Status)) { - FreeUnicodeStringTable (Private->ControllerNameTable); - gBS->FreePool (Private); - } - - DEBUG ((EFI_D_ERROR, "BlockDevice added: %s\n", Filename)); + if (NewFilePointer != NULL) { + *NewFilePointer = res; } return Status; } + EFI_STATUS -UnixBlockIoOpenDevice ( - EMU_BLOCK_IO_PRIVATE *Private +EmuBlockIoOpenDevice ( + IN EMU_BLOCK_IO_PRIVATE *Private ) { EFI_STATUS Status; UINT64 FileSize; UINT64 EndOfFile; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - BlockIo = &Private->BlockIo; - EfiAcquireLock (&Private->Lock); // // If the device is already opened, close it // if (Private->fd >= 0) { - BlockIo->Reset (BlockIo, FALSE); + EmuBlockIoReset (&Private->EmuBlockIo, FALSE); } // // Open the device // - Private->fd = Private->UnixThunk->Open (Private->Filename, Private->Mode, 0644); + Private->fd = open (Private->Filename, Private->Mode, 0644); if (Private->fd < 0) { - DEBUG ((EFI_D_INFO, "PlOpenBlock: Could not open %a\n", Private->Filename)); - BlockIo->Media->MediaPresent = FALSE; - Status = EFI_NO_MEDIA; + DEBUG ((EFI_D_INFO, "EmuOpenBlock: Could not open %a\n", Private->Filename)); + Private->Media->MediaPresent = FALSE; + Status = EFI_NO_MEDIA; goto Done; } - if (!BlockIo->Media->MediaPresent) { + if (!Private->Media->MediaPresent) { // // BugBug: try to emulate if a CD appears - notify drivers to check it out // - BlockIo->Media->MediaPresent = TRUE; - EfiReleaseLock (&Private->Lock); - EfiAcquireLock (&Private->Lock); + Private->Media->MediaPresent = TRUE; } // @@ -609,7 +122,7 @@ UnixBlockIoOpenDevice ( Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END); if (EFI_ERROR (Status)) { FileSize = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize); - DEBUG ((EFI_D_ERROR, "PlOpenBlock: Could not get filesize of %a\n", Private->Filename)); + DEBUG ((EFI_D_ERROR, "EmuOpenBlock: Could not get filesize of %a\n", Private->Filename)); Status = EFI_UNSUPPORTED; goto Done; } @@ -617,7 +130,7 @@ UnixBlockIoOpenDevice ( if (Private->NumberOfBlocks == 0) { Private->NumberOfBlocks = DivU64x32 (FileSize, Private->BlockSize); Private->LastBlock = Private->NumberOfBlocks - 1; - Private->Media.LastBlock = Private->LastBlock; + Private->Media->LastBlock = Private->LastBlock; } EndOfFile = MultU64x32 (Private->NumberOfBlocks, Private->BlockSize); @@ -626,67 +139,97 @@ UnixBlockIoOpenDevice ( // // file is not the proper size, change it // - DEBUG ((EFI_D_INIT, "PlOpenBlock: Initializing block device: %a\n", Private->Filename)); + DEBUG ((EFI_D_INIT, "EmuOpenBlock: Initializing block device: %a\n", Private->Filename)); // // first set it to 0 // - Private->UnixThunk->FTruncate (Private->fd, 0); + ftruncate (Private->fd, 0); // // then set it to the needed file size (OS will zero fill it) // - Private->UnixThunk->FTruncate (Private->fd, EndOfFile); + ftruncate (Private->fd, EndOfFile); } - DEBUG ((EFI_D_INIT, "%HPlOpenBlock: opened %a%N\n", Private->Filename)); + DEBUG ((EFI_D_INIT, "%HEmuOpenBlock: opened %a%N\n", Private->Filename)); Status = EFI_SUCCESS; Done: if (EFI_ERROR (Status)) { if (Private->fd >= 0) { - BlockIo->Reset (BlockIo, FALSE); + EmuBlockIoReset (&Private->EmuBlockIo, FALSE); } } - EfiReleaseLock (&Private->Lock); return Status; } + EFI_STATUS -UnixBlockIoError ( - IN EMU_BLOCK_IO_PRIVATE *Private +EmuBlockIoCreateMapping ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN EFI_BLOCK_IO_MEDIA *Media ) { - return EFI_DEVICE_ERROR; + EFI_STATUS Status; + EMU_BLOCK_IO_PRIVATE *Private; + + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + Private->Media = Media; + + Media->MediaId = 0; + Media->RemovableMedia = Private->RemovableMedia; + Media->MediaPresent = TRUE; + Media->LogicalPartition = FALSE; + Media->ReadOnly = Private->WriteProtected; + Media->WriteCaching = FALSE; + Media->BlockSize = Private->BlockSize; + Media->IoAlign = 1; + Media->LastBlock = 0; // Filled in by OpenDevice + + // EFI_BLOCK_IO_PROTOCOL_REVISION2 + Media->LowestAlignedLba = 0; + Media->LogicalBlocksPerPhysicalBlock = 0; + + // EFI_BLOCK_IO_PROTOCOL_REVISION3 + Media->OptimalTransferLengthGranularity = 0; + + Status = EmuBlockIoOpenDevice (Private); + + return Status; +} + -#if 0 - EFI_BLOCK_IO_PROTOCOL *BlockIo; +EFI_STATUS +EmuBlockIoError ( + IN EMU_BLOCK_IO_PRIVATE *Private + ) +{ EFI_STATUS Status; BOOLEAN ReinstallBlockIoFlag; - BlockIo = &Private->BlockIo; - - switch (Private->UnixThunk->GetLastError ()) { + switch (errno) { - case ERROR_NOT_READY: + case EAGAIN: Status = EFI_NO_MEDIA; - BlockIo->Media->ReadOnly = FALSE; - BlockIo->Media->MediaPresent = FALSE; + Private->Media->ReadOnly = FALSE; + Private->Media->MediaPresent = FALSE; ReinstallBlockIoFlag = FALSE; break; - case ERROR_WRONG_DISK: - BlockIo->Media->ReadOnly = FALSE; - BlockIo->Media->MediaPresent = TRUE; - BlockIo->Media->MediaId += 1; + case EACCES: + Private->Media->ReadOnly = FALSE; + Private->Media->MediaPresent = TRUE; + Private->Media->MediaId += 1; ReinstallBlockIoFlag = TRUE; Status = EFI_MEDIA_CHANGED; break; - case ERROR_WRITE_PROTECT: - BlockIo->Media->ReadOnly = TRUE; + case EROFS: + Private->Media->ReadOnly = TRUE; ReinstallBlockIoFlag = FALSE; Status = EFI_WRITE_PROTECTED; break; @@ -696,9 +239,9 @@ UnixBlockIoError ( Status = EFI_DEVICE_ERROR; break; } - +/* if (ReinstallBlockIoFlag) { - BlockIo->Reset (BlockIo, FALSE); + Private->EmuBlockIo->Reset (&Private->EmuBlockIo, FALSE); gBS->ReinstallProtocolInterface ( Private->EfiHandle, @@ -707,14 +250,13 @@ UnixBlockIoError ( BlockIo ); } - +*/ return Status; -#endif } EFI_STATUS -UnixBlockIoReadWriteCommon ( - IN EMU_BLOCK_IO_PRIVATE *Private, +EmuBlockIoReadWriteCommon ( + IN EMU_BLOCK_IO_PRIVATE *Private, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, @@ -729,22 +271,22 @@ UnixBlockIoReadWriteCommon ( UINT64 DistanceMoved; if (Private->fd < 0) { - Status = UnixBlockIoOpenDevice (Private); + Status = EmuBlockIoOpenDevice (Private); if (EFI_ERROR (Status)) { return Status; } } - if (!Private->Media.MediaPresent) { + if (!Private->Media->MediaPresent) { DEBUG ((EFI_D_INIT, "%s: No Media\n", CallerName)); return EFI_NO_MEDIA; } - if (Private->Media.MediaId != MediaId) { + if (Private->Media->MediaId != MediaId) { return EFI_MEDIA_CHANGED; } - if ((UINTN) Buffer % Private->Media.IoAlign != 0) { + if ((UINTN) Buffer % Private->Media->IoAlign != 0) { return EFI_INVALID_PARAMETER; } @@ -775,172 +317,238 @@ UnixBlockIoReadWriteCommon ( if (EFI_ERROR (Status)) { DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n")); - return UnixBlockIoError (Private); + return EmuBlockIoError (Private); } return EFI_SUCCESS; } -EFI_STATUS -EFIAPI -UnixBlockIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -/*++ - - Routine Description: - Read BufferSize bytes from Lba into Buffer. - - Arguments: - This - Protocol instance pointer. - MediaId - Id of the media, changes every time the media is replaced. - Lba - The starting Logical Block Address to read from - BufferSize - Size of Buffer, must be a multiple of device block size. - Buffer - Buffer containing read data - - Returns: - EFI_SUCCESS - The data was read correctly from the device. - EFI_DEVICE_ERROR - The device reported an error while performing the read. - EFI_NO_MEDIA - There is no media in the device. - EFI_MEDIA_CHANGED - The MediaId does not matched the current device. - EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the - device. - EFI_INVALID_PARAMETER - The read request contains device addresses that are not - valid for the device. +/** + Read BufferSize bytes from Lba into Buffer. + + This function reads the requested number of blocks from the device. All the + blocks are read, or an error is returned. + If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and + non-blocking I/O is being used, the Event associated with this request will + not be signaled. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId Id of the media, changes every time the media is + replaced. + @param[in] Lba The starting Logical Block Address to read from. + @param[in, out] Token A pointer to the token associated with the transaction. + @param[in] BufferSize Size of Buffer, must be a multiple of device block size. + @param[out] Buffer A pointer to the destination buffer for the data. The + caller is responsible for either having implicit or + explicit ownership of the buffer. + + @retval EFI_SUCCESS The read request was queued if Token->Event is + not NULL.The data was read correctly from the + device if the Token->Event is NULL. + @retval EFI_DEVICE_ERROR The device reported an error while performing + the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. + @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the + intrinsic block size of the device. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, + or the buffer is not on proper alignment. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack + of resources. **/ +EFI_STATUS +EmuBlockIoReadBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN UINTN BufferSize, + OUT VOID *Buffer + ) { - EMU_BLOCK_IO_PRIVATE *Private; - ssize_t len; EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + EMU_BLOCK_IO_PRIVATE *Private; + ssize_t len; Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); - Status = UnixBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "UnixReadBlocks"); + Status = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixReadBlocks"); if (EFI_ERROR (Status)) { goto Done; } - len = Private->UnixThunk->Read (Private->fd, Buffer, BufferSize); + len = read (Private->fd, Buffer, BufferSize); if (len != BufferSize) { DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed.\n")); - Status = UnixBlockIoError (Private); + Status = EmuBlockIoError (Private); goto Done; } // - // If we wrote then media is present. + // If we read then media is present. // - This->Media->MediaPresent = TRUE; + Private->Media->MediaPresent = TRUE; Status = EFI_SUCCESS; Done: - gBS->RestoreTPL (OldTpl); + if (Token != NULL) { + if (Token->Event != NULL) { + // Caller is responcible for signaling EFI Event + Token->TransactionStatus = Status; + return EFI_SUCCESS; + } + } return Status; } -EFI_STATUS -EFIAPI -UnixBlockIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -/*++ - Routine Description: - Write BufferSize bytes from Lba into Buffer. - - Arguments: - This - Protocol instance pointer. - MediaId - Id of the media, changes every time the media is replaced. - Lba - The starting Logical Block Address to read from - BufferSize - Size of Buffer, must be a multiple of device block size. - Buffer - Buffer containing read data - - Returns: - EFI_SUCCESS - The data was written correctly to the device. - EFI_WRITE_PROTECTED - The device can not be written to. - EFI_DEVICE_ERROR - The device reported an error while performing the write. - EFI_NO_MEDIA - There is no media in the device. - EFI_MEDIA_CHNAGED - The MediaId does not matched the current device. - EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the - device. - EFI_INVALID_PARAMETER - The write request contains a LBA that is not - valid for the device. +/** + Write BufferSize bytes from Lba into Buffer. + + This function writes the requested number of blocks to the device. All blocks + are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA, + EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is + being used, the Event associated with this request will not be signaled. + + @param[in] This Indicates a pointer to the calling context. + @param[in] MediaId The media ID that the write request is for. + @param[in] Lba The starting logical block address to be written. The + caller is responsible for writing to only legitimate + locations. + @param[in, out] Token A pointer to the token associated with the transaction. + @param[in] BufferSize Size of Buffer, must be a multiple of device block size. + @param[in] Buffer A pointer to the source buffer for the data. + + @retval EFI_SUCCESS The write request was queued if Event is not NULL. + The data was written correctly to the device if + the Event is NULL. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, + or the buffer is not on proper alignment. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack + of resources. **/ +EFI_STATUS +EmuBlockIoWriteBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN UINTN BufferSize, + IN VOID *Buffer + ) { - EMU_BLOCK_IO_PRIVATE *Private; + EMU_BLOCK_IO_PRIVATE *Private; ssize_t len; EFI_STATUS Status; - EFI_TPL OldTpl; - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); - Status = UnixBlockIoReadWriteCommon (Private, MediaId, Lba, BufferSize, Buffer, "UnixWriteBlocks"); + Status = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixWriteBlocks"); if (EFI_ERROR (Status)) { goto Done; } - len = Private->UnixThunk->Write (Private->fd, Buffer, BufferSize); + len = write (Private->fd, Buffer, BufferSize); if (len != BufferSize) { DEBUG ((EFI_D_INIT, "ReadBlocks: WriteFile failed.\n")); - Status = UnixBlockIoError (Private); + Status = EmuBlockIoError (Private); goto Done; } // // If the write succeeded, we are not write protected and media is present. // - This->Media->MediaPresent = TRUE; - This->Media->ReadOnly = FALSE; + Private->Media->MediaPresent = TRUE; + Private->Media->ReadOnly = FALSE; Status = EFI_SUCCESS; Done: - gBS->RestoreTPL (OldTpl); + if (Token != NULL) { + if (Token->Event != NULL) { + // Caller is responcible for signaling EFI Event + Token->TransactionStatus = Status; + return EFI_SUCCESS; + } + } + return Status; } -EFI_STATUS -EFIAPI -UnixBlockIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -/*++ - - Routine Description: - Flush the Block Device. - Arguments: - This - Protocol instance pointer. - - Returns: - EFI_SUCCESS - All outstanding data was written to the device - EFI_DEVICE_ERROR - The device reported an error while writting back the data - EFI_NO_MEDIA - There is no media in the device. +/** + Flush the Block Device. + + If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED + is returned and non-blocking I/O is being used, the Event associated with + this request will not be signaled. + + @param[in] This Indicates a pointer to the calling context. + @param[in,out] Token A pointer to the token associated with the transaction + + @retval EFI_SUCCESS The flush request was queued if Event is not NULL. + All outstanding data was written correctly to the + device if the Event is NULL. + @retval EFI_DEVICE_ERROR The device reported an error while writting back + the data. + @retval EFI_WRITE_PROTECTED The device cannot be written to. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack + of resources. **/ +EFI_STATUS +EmuBlockIoFlushBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN OUT EFI_BLOCK_IO2_TOKEN *Token + ) { + EMU_BLOCK_IO_PRIVATE *Private; + + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + if (Private->fd >= 0) { + close (Private->fd); + Private->fd = open (Private->Filename, Private->Mode, 0644); + } + + if (Token != NULL) { + if (Token->Event != NULL) { + // Caller is responcible for signaling EFI Event + Token->TransactionStatus = EFI_SUCCESS; + return EFI_SUCCESS; + } + } + return EFI_SUCCESS; } + +/** + Reset the block device hardware. + + @param[in] This Indicates a pointer to the calling context. + @param[in] ExtendedVerification Indicates that the driver may perform a more + exhausive verfication operation of the device + during 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 -UnixBlockIoResetBlock ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification +EmuBlockIoReset ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification ) /*++ @@ -959,95 +567,138 @@ UnixBlockIoResetBlock ( **/ { EMU_BLOCK_IO_PRIVATE *Private; - EFI_TPL OldTpl; - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); if (Private->fd >= 0) { - Private->UnixThunk->Close (Private->fd); + close (Private->fd); Private->fd = -1; } - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; } -UINTN -Atoi ( - CHAR16 *String - ) -/*++ - -Routine Description: - Convert a unicode string to a UINTN - -Arguments: - - String - Unicode string. +char * +StdDupUnicodeToAscii ( + IN CHAR16 *Str + ) +{ + UINTN Size; + char *Ascii; + char *Ptr; + + Size = StrLen (Str) + 1; + Ascii = malloc (Size); + if (Ascii == NULL) { + return NULL; + } + + for (Ptr = Ascii; *Str != '\0'; Ptr++, Str++) { + *Ptr = *Str; + } + *Ptr = 0; + + return Ascii; +} -Returns: - UINTN of the number represented by String. +EMU_BLOCK_IO_PROTOCOL gEmuBlockIoProtocol = { + GasketEmuBlockIoReset, + GasketEmuBlockIoReadBlocks, + GasketEmuBlockIoWriteBlocks, + GasketEmuBlockIoFlushBlocks, + GasketEmuBlockIoCreateMapping +}; -**/ +EFI_STATUS +EmuBlockIoThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) { - UINTN Number; - CHAR16 *Str; - - // - // skip preceeding white space - // - Str = String; - while ((*Str) && (*Str == ' ')) { - Str++; + EMU_BLOCK_IO_PRIVATE *Private; + char *Str; + + if (This->Private != NULL) { + return EFI_ALREADY_STARTED; } - // - // Convert ot a Number - // - Number = 0; - while (*Str != '\0') { - if ((*Str >= '0') && (*Str <= '9')) { - Number = (Number * 10) +*Str - '0'; - } else { - break; - } - - Str++; + + if (!CompareGuid (This->Protocol, &gEmuBlockIoProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = malloc (sizeof (EMU_BLOCK_IO_PRIVATE)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; } - return Number; + + Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->EmuBlockIo, &gEmuBlockIoProtocol, sizeof (gEmuBlockIoProtocol)); + Private->fd = -1; + + Private->Filename = StdDupUnicodeToAscii (This->ConfigString); + if (Private->Filename == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Str = strstr (Private->Filename, ":"); + if (Str == NULL) { + Private->RemovableMedia = FALSE; + Private->WriteProtected = FALSE; + } else { + for (*Str++ = '\0'; *Str != 0; Str++) { + if (*Str == 'R' || *Str == 'F') { + Private->RemovableMedia = (BOOLEAN) (*Str == 'R'); + } + if (*Str == 'O' || *Str == 'W') { + Private->WriteProtected = (BOOLEAN) (*Str == 'O'); + } + } + } + + Private->BlockSize = 512; + + This->Interface = &Private->EmuBlockIo; + This->Private = Private; + return EFI_SUCCESS; } -/*++ - -This function extends the capability of SetFilePointer to accept 64 bit parameters - -**/ EFI_STATUS -SetFilePointer64 ( - IN EMU_BLOCK_IO_PRIVATE *Private, - IN INT64 DistanceToMove, - OUT UINT64 *NewFilePointer, - IN INT32 MoveMethod +EmuBlockIoThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This ) { - EFI_STATUS Status; - off_t res; + EMU_BLOCK_IO_PRIVATE *Private; - Status = EFI_SUCCESS; - res = Private->UnixThunk->Lseek(Private->fd, DistanceToMove, MoveMethod); - if (res == -1) { - Status = EFI_INVALID_PARAMETER; + if (!CompareGuid (This->Protocol, &gEmuBlockIoProtocolGuid)) { + return EFI_UNSUPPORTED; } - - if (NewFilePointer != NULL) { - *NewFilePointer = res; + + Private = This->Private; + + if (This->Private != NULL) { + if (Private->Filename != NULL) { + free (Private->Filename); + } + free (This->Private); } - - return Status; + + return EFI_SUCCESS; } + + + +EMU_IO_THUNK_PROTOCOL gBlockIoThunkIo = { + &gEmuBlockIoProtocolGuid, + NULL, + NULL, + 0, + GasketBlockIoThunkOpen, + GasketBlockIoThunkClose, + NULL +}; + + diff --git a/InOsEmuPkg/Unix/Sec/Gasket.h b/InOsEmuPkg/Unix/Sec/Gasket.h index 61297b575a..e506e774b6 100644 --- a/InOsEmuPkg/Unix/Sec/Gasket.h +++ b/InOsEmuPkg/Unix/Sec/Gasket.h @@ -405,8 +405,58 @@ GasketPosixFileSystmeThunkClose ( IN EMU_IO_THUNK_PROTOCOL *This ); +EFI_STATUS +EFIAPI +GasketEmuBlockIoReset ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); +EFI_STATUS +GasketEmuBlockIoReadBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN UINTN BufferSize, + OUT VOID *Buffer + ); +EFI_STATUS +EFIAPI +GasketEmuBlockIoWriteBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +EFI_STATUS +GasketEmuBlockIoFlushBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN OUT EFI_BLOCK_IO2_TOKEN *Token + ); + +EFI_STATUS +GasketEmuBlockIoCreateMapping ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN EFI_BLOCK_IO_MEDIA *Media + ); + +EFI_STATUS +EFIAPI +GasketBlockIoThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketBlockIoThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + #endif diff --git a/InOsEmuPkg/Unix/Sec/PosixFileSystem.c b/InOsEmuPkg/Unix/Sec/PosixFileSystem.c index 855825627f..720f10218a 100644 --- a/InOsEmuPkg/Unix/Sec/PosixFileSystem.c +++ b/InOsEmuPkg/Unix/Sec/PosixFileSystem.c @@ -1533,7 +1533,7 @@ PosixFileSystmeThunkClose ( } if (This->Private != NULL) { - if (Private->VolumeLabel == NULL) { + if (Private->VolumeLabel != NULL) { free (Private->VolumeLabel); } free (This->Private); diff --git a/InOsEmuPkg/Unix/Sec/SecMain.c b/InOsEmuPkg/Unix/Sec/SecMain.c index 9c0990b2cd..ff5eff0c07 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.c +++ b/InOsEmuPkg/Unix/Sec/SecMain.c @@ -116,7 +116,10 @@ main ( // AddThunkProtocol (&gX11ThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE); AddThunkProtocol (&gPosixFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE); + AddThunkProtocol (&gBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE); + + // // Emulator other Thunks // diff --git a/InOsEmuPkg/Unix/Sec/SecMain.h b/InOsEmuPkg/Unix/Sec/SecMain.h index 19e5f17147..f2487b9133 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.h +++ b/InOsEmuPkg/Unix/Sec/SecMain.h @@ -46,6 +46,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include #include @@ -318,6 +319,6 @@ extern EMU_THUNK_PROTOCOL gEmuThunkProtocol; extern EMU_IO_THUNK_PROTOCOL gX11ThunkIo; extern EMU_IO_THUNK_PROTOCOL gPosixFileSystemThunkIo; extern EMU_IO_THUNK_PROTOCOL gPthreadThunkIo; - +extern EMU_IO_THUNK_PROTOCOL gBlockIoThunkIo; #endif diff --git a/InOsEmuPkg/Unix/Sec/SecMain.inf b/InOsEmuPkg/Unix/Sec/SecMain.inf index 7939fbfa83..763fd1e6a1 100644 --- a/InOsEmuPkg/Unix/Sec/SecMain.inf +++ b/InOsEmuPkg/Unix/Sec/SecMain.inf @@ -35,6 +35,7 @@ X11GraphicsWindow.c Pthreads.c PosixFileSystem.c + BlockIo.c [Sources.X64] X64/Gasket.S # convert between Emu x86_64 ABI and EFI X64 ABI @@ -68,8 +69,8 @@ gEmuIoThunkProtocolGuid gEmuGraphicsWindowProtocolGuid gEmuThreadThunkProtocolGuid + gEmuBlockIoProtocolGuid gEfiSimpleFileSystemProtocolGuid - [Guids] gEfiFileSystemVolumeLabelInfoIdGuid # SOMETIMES_CONSUMED diff --git a/InOsEmuPkg/Unix/Sec/X64/Gasket.S b/InOsEmuPkg/Unix/Sec/X64/Gasket.S index 3dc0fa1f28..e5515e259b 100644 --- a/InOsEmuPkg/Unix/Sec/X64/Gasket.S +++ b/InOsEmuPkg/Unix/Sec/X64/Gasket.S @@ -1022,9 +1022,143 @@ ASM_PFX(GasketPosixFileSystmeThunkClose): popq %rbp ret +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoReset) +ASM_PFX(GasketEmuBlockIoReset): + 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(EmuBlockIoReset) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoReadBlocks) +ASM_PFX(GasketEmuBlockIoReadBlocks): + 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 + movq 0x38(%rbp), %r9 + + call ASM_PFX(EmuBlockIoReadBlocks) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoWriteBlocks) +ASM_PFX(GasketEmuBlockIoWriteBlocks): + 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 + movq 0x38(%rbp), %r9 + + call ASM_PFX(EmuBlockIoWriteBlocks) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoFlushBlocks) +ASM_PFX(GasketEmuBlockIoFlushBlocks): + 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(EmuBlockIoFlushBlocks) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoCreateMapping) +ASM_PFX(GasketEmuBlockIoCreateMapping): + 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(EmuBlockIoCreateMapping) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret +ASM_GLOBAL ASM_PFX(GasketBlockIoThunkOpen) +ASM_PFX(GasketBlockIoThunkOpen): + 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(EmuBlockIoThunkOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketBlockIoThunkClose) +ASM_PFX(GasketBlockIoThunkClose): + 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(EmuBlockIoThunkClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret diff --git a/InOsEmuPkg/Unix/UnixX64.dsc b/InOsEmuPkg/Unix/UnixX64.dsc index 06b7b34322..b58f6011f2 100644 --- a/InOsEmuPkg/Unix/UnixX64.dsc +++ b/InOsEmuPkg/Unix/UnixX64.dsc @@ -220,8 +220,7 @@ gInOsEmuPkgTokenSpaceGuid.PcdEmuApCount|L"1" - gInOsEmuPkgTokenSpaceGuid.PcdEmuPhysicalDisk|L"E:RW;245760;512" - gInOsEmuPkgTokenSpaceGuid.PcdEmuVirtualDisk|L"FW;40960;512" + gInOsEmuPkgTokenSpaceGuid.PcdEmuVirtualDisk|L"disk.dmg:FW" gInOsEmuPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window" gInOsEmuPkgTokenSpaceGuid.PcdEmuFileSystem|L".!../../../../EdkShellBinPkg/Bin" gInOsEmuPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0" @@ -358,20 +357,13 @@ InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf InOsEmuPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf -!if $(0) - 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 +!if $(NETWORK_SUPPORT) + InOsEmuPkg/EmuSnpDxe/EmuSnpDxe.inf !endif MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf diff --git a/InOsEmuPkg/Unix/UnixX64.fdf b/InOsEmuPkg/Unix/UnixX64.fdf index 14e5b6022a..d3696927ee 100644 --- a/InOsEmuPkg/Unix/UnixX64.fdf +++ b/InOsEmuPkg/Unix/UnixX64.fdf @@ -221,9 +221,8 @@ INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf INF InOsEmuPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf INF InOsEmuPkg/EmuGopDxe/EmuGopDxe.inf INF InOsEmuPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf +INF InOsEmuPkg/EmuBlockIoDxe/EmuBlockIoDxe.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 @@ -235,7 +234,7 @@ INF MdeModulePkg/Application/HelloWorld/HelloWorld.inf # Network stack drivers # !if $(NETWORK_SUPPORT) -#INF UnixPkg/UnixSnpDxe/UnixSnpDxe.inf +INF InOsEmuPkg/EmuSnpDxe/EmuSnpDxe.inf !endif INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf diff --git a/InOsEmuPkg/Unix/build64.sh b/InOsEmuPkg/Unix/build64.sh index a9294be02e..8742b3f7f4 100755 --- a/InOsEmuPkg/Unix/build64.sh +++ b/InOsEmuPkg/Unix/build64.sh @@ -58,8 +58,8 @@ case `uname` in UNIXPKG_TOOLS=XCLANG fi # NETWORK_SUPPORT="-D NETWORK_SUPPORT" -# BUILD_NEW_SHELL="-D BUILD_NEW_SHELL" -# BUILD_FAT="-D BUILD_FAT" + BUILD_NEW_SHELL="-D BUILD_NEW_SHELL" + BUILD_FAT="-D BUILD_FAT" ;; Linux*) TARGET_TOOLS=ELFGCC ;; -- cgit v1.2.3