ArmPkg/SemihostFs: Make the driver more compliant with the UEFI specification
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14262 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
Support a Semi Host file system over a debuggers JTAG
|
Support a Semi Host file system over a debuggers JTAG
|
||||||
|
|
||||||
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||||
Portions copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
|
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <Guid/FileInfo.h>
|
#include <Guid/FileInfo.h>
|
||||||
#include <Guid/FileSystemInfo.h>
|
#include <Guid/FileSystemInfo.h>
|
||||||
|
#include <Guid/FileSystemVolumeLabelInfo.h>
|
||||||
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
@@ -32,6 +33,9 @@
|
|||||||
|
|
||||||
#include "SemihostFs.h"
|
#include "SemihostFs.h"
|
||||||
|
|
||||||
|
#define DEFAULT_SEMIHOST_FS_LABEL L"SemihostFs"
|
||||||
|
|
||||||
|
STATIC CHAR16 *mSemihostFsLabel;
|
||||||
|
|
||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = {
|
||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
|
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
|
||||||
@@ -69,13 +73,15 @@ SEMIHOST_DEVICE_PATH gDevicePath = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
LIST_ENTRY Link;
|
LIST_ENTRY Link;
|
||||||
UINT64 Signature;
|
UINT64 Signature;
|
||||||
EFI_FILE File;
|
EFI_FILE File;
|
||||||
CHAR8 *FileName;
|
CHAR8 *FileName;
|
||||||
UINT32 Position;
|
UINT64 OpenMode;
|
||||||
UINTN SemihostHandle;
|
UINT32 Position;
|
||||||
BOOLEAN IsRoot;
|
UINTN SemihostHandle;
|
||||||
|
BOOLEAN IsRoot;
|
||||||
|
EFI_FILE_INFO Info;
|
||||||
} SEMIHOST_FCB;
|
} SEMIHOST_FCB;
|
||||||
|
|
||||||
#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )
|
#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' )
|
||||||
@@ -134,6 +140,7 @@ VolumeOpen (
|
|||||||
}
|
}
|
||||||
|
|
||||||
RootFcb->IsRoot = TRUE;
|
RootFcb->IsRoot = TRUE;
|
||||||
|
RootFcb->Info.Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
|
||||||
|
|
||||||
InsertTailList (&gFileList, &RootFcb->Link);
|
InsertTailList (&gFileList, &RootFcb->Link);
|
||||||
|
|
||||||
@@ -157,11 +164,17 @@ FileOpen (
|
|||||||
CHAR8 *AsciiFileName;
|
CHAR8 *AsciiFileName;
|
||||||
UINT32 SemihostMode;
|
UINT32 SemihostMode;
|
||||||
BOOLEAN IsRoot;
|
BOOLEAN IsRoot;
|
||||||
|
UINTN Length;
|
||||||
|
|
||||||
if ((FileName == NULL) || (NewHandle == NULL)) {
|
if ((FileName == NULL) || (NewHandle == NULL)) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Semihosting does not support directories
|
||||||
|
if (Attributes & EFI_FILE_DIRECTORY) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
// Semihost interface requires ASCII filenames
|
// Semihost interface requires ASCII filenames
|
||||||
AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8));
|
AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8));
|
||||||
if (AsciiFileName == NULL) {
|
if (AsciiFileName == NULL) {
|
||||||
@@ -213,6 +226,18 @@ FileOpen (
|
|||||||
FileFcb->SemihostHandle = SemihostHandle;
|
FileFcb->SemihostHandle = SemihostHandle;
|
||||||
FileFcb->Position = 0;
|
FileFcb->Position = 0;
|
||||||
FileFcb->IsRoot = IsRoot;
|
FileFcb->IsRoot = IsRoot;
|
||||||
|
FileFcb->OpenMode = OpenMode;
|
||||||
|
|
||||||
|
if (!IsRoot) {
|
||||||
|
Status = SemihostFileLength (SemihostHandle, &Length);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileFcb->Info.FileSize = Length;
|
||||||
|
FileFcb->Info.PhysicalSize = Length;
|
||||||
|
FileFcb->Info.Attribute = Attributes;
|
||||||
|
}
|
||||||
|
|
||||||
InsertTailList (&gFileList, &FileFcb->Link);
|
InsertTailList (&gFileList, &FileFcb->Link);
|
||||||
|
|
||||||
@@ -271,8 +296,11 @@ FileDelete (
|
|||||||
|
|
||||||
// Call the semihost interface to delete the file.
|
// Call the semihost interface to delete the file.
|
||||||
Status = SemihostFileRemove (FileName);
|
Status = SemihostFileRemove (FileName);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
Status = EFI_WARN_DELETE_FAILURE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_WARN_DELETE_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
@@ -316,6 +344,11 @@ FileWrite (
|
|||||||
|
|
||||||
Fcb = SEMIHOST_FCB_FROM_THIS(File);
|
Fcb = SEMIHOST_FCB_FROM_THIS(File);
|
||||||
|
|
||||||
|
// We cannot write a read-only file
|
||||||
|
if (Fcb->OpenMode & EFI_FILE_READ_ONLY) {
|
||||||
|
return EFI_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
Status = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
|
Status = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer);
|
||||||
|
|
||||||
if (!EFI_ERROR(Status)) {
|
if (!EFI_ERROR(Status)) {
|
||||||
@@ -388,8 +421,6 @@ GetFileInfo (
|
|||||||
UINTN NameSize = 0;
|
UINTN NameSize = 0;
|
||||||
UINTN ResultSize;
|
UINTN ResultSize;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
UINTN Length;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
if (Fcb->IsRoot == TRUE) {
|
if (Fcb->IsRoot == TRUE) {
|
||||||
ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
|
ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16);
|
||||||
@@ -405,30 +436,20 @@ GetFileInfo (
|
|||||||
|
|
||||||
Info = Buffer;
|
Info = Buffer;
|
||||||
|
|
||||||
// Zero out the structure
|
// Copy the current file info
|
||||||
ZeroMem (Info, SIZE_OF_EFI_FILE_INFO);
|
CopyMem (Info, &Fcb->Info, SIZE_OF_EFI_FILE_INFO);
|
||||||
|
|
||||||
// Fill in the structure
|
// Fill in the structure
|
||||||
Info->Size = ResultSize;
|
Info->Size = ResultSize;
|
||||||
|
|
||||||
if (Fcb->IsRoot == TRUE) {
|
if (Fcb->IsRoot == TRUE) {
|
||||||
Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
|
|
||||||
Info->FileName[0] = L'\0';
|
Info->FileName[0] = L'\0';
|
||||||
} else {
|
} else {
|
||||||
Status = SemihostFileLength (Fcb->SemihostHandle, &Length);
|
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Info->FileSize = Length;
|
|
||||||
Info->PhysicalSize = Length;
|
|
||||||
|
|
||||||
for (Index = 0; Index < NameSize; Index++) {
|
for (Index = 0; Index < NameSize; Index++) {
|
||||||
Info->FileName[Index] = Fcb->FileName[Index];
|
Info->FileName[Index] = Fcb->FileName[Index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*BufferSize = ResultSize;
|
*BufferSize = ResultSize;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
@@ -444,10 +465,9 @@ GetFilesystemInfo (
|
|||||||
{
|
{
|
||||||
EFI_FILE_SYSTEM_INFO *Info = NULL;
|
EFI_FILE_SYSTEM_INFO *Info = NULL;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
STATIC CHAR16 Label[] = L"SemihostFs";
|
UINTN ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (mSemihostFsLabel);
|
||||||
UINTN ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize(Label);
|
|
||||||
|
|
||||||
if(*BufferSize >= ResultSize) {
|
if (*BufferSize >= ResultSize) {
|
||||||
ZeroMem (Buffer, ResultSize);
|
ZeroMem (Buffer, ResultSize);
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
@@ -459,7 +479,7 @@ GetFilesystemInfo (
|
|||||||
Info->FreeSpace = 0;
|
Info->FreeSpace = 0;
|
||||||
Info->BlockSize = 0;
|
Info->BlockSize = 0;
|
||||||
|
|
||||||
StrCpy (Info->VolumeLabel, Label);
|
StrCpy (Info->VolumeLabel, mSemihostFsLabel);
|
||||||
} else {
|
} else {
|
||||||
Status = EFI_BUFFER_TOO_SMALL;
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
@@ -476,17 +496,31 @@ FileGetInfo (
|
|||||||
OUT VOID *Buffer
|
OUT VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SEMIHOST_FCB *Fcb = NULL;
|
SEMIHOST_FCB *Fcb;
|
||||||
EFI_STATUS Status = EFI_UNSUPPORTED;
|
EFI_STATUS Status;
|
||||||
|
UINTN ResultSize;
|
||||||
|
|
||||||
Fcb = SEMIHOST_FCB_FROM_THIS(File);
|
Fcb = SEMIHOST_FCB_FROM_THIS(File);
|
||||||
|
|
||||||
if (CompareGuid(InformationType, &gEfiFileSystemInfoGuid) != 0) {
|
if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {
|
||||||
Status = GetFilesystemInfo(Fcb, BufferSize, Buffer);
|
Status = GetFilesystemInfo (Fcb, BufferSize, Buffer);
|
||||||
} else if (CompareGuid(InformationType, &gEfiFileInfoGuid) != 0) {
|
} else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {
|
||||||
Status = GetFileInfo(Fcb, BufferSize, Buffer);
|
Status = GetFileInfo (Fcb, BufferSize, Buffer);
|
||||||
|
} else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid) != 0) {
|
||||||
|
ResultSize = StrSize (mSemihostFsLabel);
|
||||||
|
|
||||||
|
if (*BufferSize >= ResultSize) {
|
||||||
|
StrCpy (Buffer, mSemihostFsLabel);
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
} else {
|
||||||
|
Status = EFI_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*BufferSize = ResultSize;
|
||||||
|
} else {
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,7 +532,27 @@ FileSetInfo (
|
|||||||
IN VOID *Buffer
|
IN VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return EFI_UNSUPPORTED;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
if (Buffer == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
|
||||||
|
if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {
|
||||||
|
//Status = SetFilesystemInfo (Fcb, BufferSize, Buffer);
|
||||||
|
} else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {
|
||||||
|
//Status = SetFileInfo (Fcb, BufferSize, Buffer);
|
||||||
|
} else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid) != 0) {
|
||||||
|
if (StrSize (Buffer) > 0) {
|
||||||
|
FreePool (mSemihostFsLabel);
|
||||||
|
mSemihostFsLabel = AllocateCopyPool (StrSize (Buffer), Buffer);
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
@@ -506,7 +560,19 @@ FileFlush (
|
|||||||
IN EFI_FILE *File
|
IN EFI_FILE *File
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return EFI_SUCCESS;
|
SEMIHOST_FCB *Fcb;
|
||||||
|
|
||||||
|
Fcb = SEMIHOST_FCB_FROM_THIS(File);
|
||||||
|
|
||||||
|
if (Fcb->IsRoot) {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
} else {
|
||||||
|
if (Fcb->Info.Attribute & EFI_FILE_READ_ONLY) {
|
||||||
|
return EFI_ACCESS_DENIED;
|
||||||
|
} else {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
@@ -515,17 +581,27 @@ SemihostFsEntryPoint (
|
|||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status = EFI_NOT_FOUND;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Status = EFI_NOT_FOUND;
|
||||||
|
|
||||||
if (SemihostConnectionSupported ()) {
|
if (SemihostConnectionSupported ()) {
|
||||||
|
mSemihostFsLabel = AllocateCopyPool (StrSize (DEFAULT_SEMIHOST_FS_LABEL), DEFAULT_SEMIHOST_FS_LABEL);
|
||||||
|
if (mSemihostFsLabel == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
&gInstallHandle,
|
&gInstallHandle,
|
||||||
&gEfiSimpleFileSystemProtocolGuid, &gSemihostFs,
|
&gEfiSimpleFileSystemProtocolGuid, &gSemihostFs,
|
||||||
&gEfiDevicePathProtocolGuid, &gDevicePath,
|
&gEfiDevicePathProtocolGuid, &gDevicePath,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
FreePool (mSemihostFsLabel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user