summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c16
-rw-r--r--InOsEmuPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf2
-rw-r--r--InOsEmuPkg/InOsEmuPkg.dec1
-rw-r--r--InOsEmuPkg/Include/Protocol/EmuBlockIo.h6
-rw-r--r--InOsEmuPkg/Unix/Sec/BlockIo.c1119
-rw-r--r--InOsEmuPkg/Unix/Sec/Gasket.h50
-rw-r--r--InOsEmuPkg/Unix/Sec/PosixFileSystem.c2
-rw-r--r--InOsEmuPkg/Unix/Sec/SecMain.c3
-rw-r--r--InOsEmuPkg/Unix/Sec/SecMain.h3
-rw-r--r--InOsEmuPkg/Unix/Sec/SecMain.inf3
-rw-r--r--InOsEmuPkg/Unix/Sec/X64/Gasket.S134
-rw-r--r--InOsEmuPkg/Unix/UnixX64.dsc14
-rw-r--r--InOsEmuPkg/Unix/UnixX64.fdf5
-rwxr-xr-xInOsEmuPkg/Unix/build64.sh4
14 files changed, 597 insertions, 765 deletions
diff --git a/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c b/InOsEmuPkg/EmuBlockIoDxe/EmuBlockIo.c
index 999445b..9f3aa28 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 24f4759..82460e4 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 3a7417f..7cbed7f 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 f31124d..26d6bb8 100644
--- a/InOsEmuPkg/Include/Protocol/EmuBlockIo.h
+++ b/InOsEmuPkg/Include/Protocol/EmuBlockIo.h
@@ -23,7 +23,7 @@
#include <Protocol/BlockIo2.h>
#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 3fc1d3f..1636d95 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.
-
- <F>ixed - Fixed disk like a hard drive.
- <R>emovable - Removable media like a floppy or CD-ROM.
- Read <O>nly - Write protected device.
- Read <W>rite - Read write device.
- <block count> - Decimal number of blocks a device supports.
- <block size> - 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 =
- <F | R><O | W>;<block count>;<block size>[!...]
-
- EFI_EMU_PHYSICAL_DISKS =
- <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
-
- 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 <fcntl.h>
-#include <unistd.h>
-#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 <fcntl.h>
+//#include <unistd.h>
+#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 61297b5..e506e77 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 8558256..720f102 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 9c0990b..ff5eff0 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 19e5f17..f2487b9 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 <Protocol/EmuIoThunk.h>
#include <Protocol/EmuGraphicsWindow.h>
#include <Protocol/EmuThread.h>
+#include <Protocol/EmuBlockIo.h>
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
@@ -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 7939fbf..763fd1e 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 3dc0fa1..e5515e2 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 06b7b34..b58f601 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 14e5b60..d369692 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 a9294be..8742b3f 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 ;;