From 2ef2b01e07c02db339f34004445734a2dbdd80e1 Mon Sep 17 00:00:00 2001 From: AJFISH Date: Sun, 6 Dec 2009 01:57:05 +0000 Subject: Adding support for BeagleBoard. ArmPkg - Supoprt for ARM specific things that can change as the architecture changes. Plus semihosting JTAG drivers. EmbeddedPkg - Generic support for an embeddded platform. Including a light weight command line shell. BeagleBoardPkg - Platform specifics for BeagleBoard. SD Card works, but USB has issues. Looks like a bug in the open source USB stack (Our internal stack works fine). git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9518 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c | 526 ++++++++++++++++++++++++++ ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h | 114 ++++++ ArmPkg/Filesystem/SemihostFs/SemihostFs.inf | 48 +++ 3 files changed, 688 insertions(+) create mode 100644 ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c create mode 100644 ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h create mode 100644 ArmPkg/Filesystem/SemihostFs/SemihostFs.inf (limited to 'ArmPkg/Filesystem') diff --git a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c new file mode 100644 index 0000000000..0f1da65ba0 --- /dev/null +++ b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c @@ -0,0 +1,526 @@ +/** @file + Support a Semi Host file system over a debuggers JTAG + + Copyright (c) 2008-2009, Apple Inc. All rights reserved. + + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "SemihostFs.h" + + +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gSemihostFs = { + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, + VolumeOpen +}; + +EFI_FILE gSemihostFsFile = { + EFI_FILE_PROTOCOL_REVISION, + FileOpen, + FileClose, + FileDelete, + FileRead, + FileWrite, + FileGetPosition, + FileSetPosition, + FileGetInfo, + FileSetInfo, + FileFlush +}; + +// +// Device path for SemiHosting. It contains our autogened Caller ID GUID. +// +typedef struct { + VENDOR_DEVICE_PATH Guid; + EFI_DEVICE_PATH_PROTOCOL End; +} SEMIHOST_DEVICE_PATH; + +SEMIHOST_DEVICE_PATH gDevicePath = { + { + { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof (VENDOR_DEVICE_PATH), 0 }, + EFI_CALLER_ID_GUID + }, + { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} +}; + +typedef struct { + LIST_ENTRY Link; + UINT64 Signature; + EFI_FILE File; + CHAR8 *FileName; + UINT32 Position; + UINT32 SemihostHandle; + BOOLEAN IsRoot; +} SEMIHOST_FCB; + +#define SEMIHOST_FCB_SIGNATURE SIGNATURE_32( 'S', 'H', 'F', 'C' ) +#define SEMIHOST_FCB_FROM_THIS(a) CR(a, SEMIHOST_FCB, File, SEMIHOST_FCB_SIGNATURE) +#define SEMIHOST_FCB_FROM_LINK(a) CR(a, SEMIHOST_FCB, Link, SEMIHOST_FCB_SIGNATURE); + +EFI_HANDLE gInstallHandle = NULL; +LIST_ENTRY gFileList = INITIALIZE_LIST_HEAD_VARIABLE (gFileList); + +SEMIHOST_FCB * +AllocateFCB ( + VOID + ) +{ + SEMIHOST_FCB *Fcb = AllocateZeroPool (sizeof (SEMIHOST_FCB)); + + if (Fcb != NULL) { + CopyMem (&Fcb->File, &gSemihostFsFile, sizeof (gSemihostFsFile)); + Fcb->Signature = SEMIHOST_FCB_SIGNATURE; + } + + return Fcb; +} + +VOID +FreeFCB ( + IN SEMIHOST_FCB *Fcb + ) +{ + // Remove Fcb from gFileList. + RemoveEntryList (&Fcb->Link); + + // To help debugging... + Fcb->Signature = 0; + + FreePool (Fcb); +} + + + +EFI_STATUS +VolumeOpen ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE **Root + ) +{ + SEMIHOST_FCB *RootFcb = NULL; + + if (Root == NULL) { + return EFI_INVALID_PARAMETER; + } + + RootFcb = AllocateFCB (); + if (RootFcb == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + RootFcb->IsRoot = TRUE; + + InsertTailList (&gFileList, &RootFcb->Link); + + *Root = &RootFcb->File; + + return EFI_SUCCESS; +} + +EFI_STATUS +FileOpen ( + IN EFI_FILE *File, + OUT EFI_FILE **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + SEMIHOST_FCB *FileFcb = NULL; + EFI_STATUS Status = EFI_SUCCESS; + UINT32 SemihostHandle; + CHAR8 *AsciiFileName; + CHAR8 *AsciiPtr; + UINTN Length; + UINT32 SemihostMode; + BOOLEAN IsRoot; + + if ((FileName == NULL) || (NewHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // Semihost interface requires ASCII filesnames + Length = StrSize (FileName); + + AsciiFileName = AllocatePool (Length); + if (AsciiFileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + AsciiPtr = AsciiFileName; + + while (Length--) { + *AsciiPtr++ = *FileName++ & 0xFF; + } + + if ((AsciiStrCmp (AsciiFileName, "\\") == 0) || (AsciiStrCmp (AsciiFileName, "/") == 0) || (AsciiStrCmp (AsciiFileName, "") == 0)) { + // Opening '/', '\', or the NULL pathname is trying to open the root directory + IsRoot = TRUE; + + // Root directory node doesn't have a name. + FreePool (AsciiFileName); + AsciiFileName = NULL; + } else { + // Translate EFI_FILE_MODE into Semihosting mode + if (OpenMode & EFI_FILE_MODE_WRITE) { + SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY; + } else if (OpenMode & EFI_FILE_MODE_READ) { + SemihostMode = SEMIHOST_FILE_MODE_READ | SEMIHOST_FILE_MODE_BINARY; + } else { + return EFI_UNSUPPORTED; + } + + // Add the creation flag if necessary + if (OpenMode & EFI_FILE_MODE_CREATE) { + SemihostMode |= SEMIHOST_FILE_MODE_CREATE; + } + + // Call the semihosting interface to open the file. + Status = SemihostFileOpen (AsciiFileName, SemihostMode, &SemihostHandle); + if (EFI_ERROR(Status)) { + return Status; + } + + IsRoot = FALSE; + } + + // Allocate a control block and fill it + FileFcb = AllocateFCB (); + if (FileFcb == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + FileFcb->FileName = AsciiFileName; + FileFcb->SemihostHandle = SemihostHandle; + FileFcb->Position = 0; + FileFcb->IsRoot = IsRoot; + + InsertTailList (&gFileList, &FileFcb->Link); + + *NewHandle = &FileFcb->File; + + return Status; +} + + +EFI_STATUS +FileClose ( + IN EFI_FILE *File + ) +{ + SEMIHOST_FCB *Fcb = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + Fcb = SEMIHOST_FCB_FROM_THIS(File); + + if (Fcb->IsRoot == TRUE) { + FreeFCB (Fcb); + Status = EFI_SUCCESS; + } else { + Status = SemihostFileClose (Fcb->SemihostHandle); + if (!EFI_ERROR(Status)) { + FreePool (Fcb->FileName); + FreeFCB (Fcb); + } + } + + return Status; +} + +EFI_STATUS +FileDelete ( + IN EFI_FILE *File + ) +{ + SEMIHOST_FCB *Fcb = NULL; + EFI_STATUS Status; + CHAR8 *FileName; + UINTN NameSize; + + Fcb = SEMIHOST_FCB_FROM_THIS(File); + + // Get the filename from the Fcb + NameSize = AsciiStrLen (Fcb->FileName); + FileName = AllocatePool (NameSize + 1); + + AsciiStrCpy (FileName, Fcb->FileName); + + // Close the file if it's open. Disregard return status, + // since it might give an error if the file isn't open. + File->Close (File); + + // Call the semihost interface to delete the file. + Status = SemihostFileRemove (FileName); + + return Status; +} + +EFI_STATUS +FileRead ( + IN EFI_FILE *File, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + SEMIHOST_FCB *Fcb = NULL; + EFI_STATUS Status; + + Fcb = SEMIHOST_FCB_FROM_THIS(File); + + if (Fcb->IsRoot == TRUE) { + Status = EFI_UNSUPPORTED; + } else { + Status = SemihostFileRead (Fcb->SemihostHandle, BufferSize, Buffer); + if (!EFI_ERROR (Status)) { + Fcb->Position += *BufferSize; + } + } + + return Status; +} + +EFI_STATUS +FileWrite ( + IN EFI_FILE *File, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + SEMIHOST_FCB *Fcb = NULL; + EFI_STATUS Status; + UINTN WriteSize = *BufferSize; + + Fcb = SEMIHOST_FCB_FROM_THIS(File); + + Status = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, Buffer); + + if (!EFI_ERROR(Status)) { + // Semihost write return the number of bytes *NOT* written. + *BufferSize -= WriteSize; + Fcb->Position += *BufferSize; + } + + return Status; +} + +EFI_STATUS +FileGetPosition ( + IN EFI_FILE *File, + OUT UINT64 *Position + ) +{ + SEMIHOST_FCB *Fcb = NULL; + + if (Position == NULL) { + return EFI_INVALID_PARAMETER; + } + + Fcb = SEMIHOST_FCB_FROM_THIS(File); + + *Position = Fcb->Position; + + return EFI_SUCCESS; +} + +EFI_STATUS +FileSetPosition ( + IN EFI_FILE *File, + IN UINT64 Position + ) +{ + SEMIHOST_FCB *Fcb = NULL; + UINT32 Length; + EFI_STATUS Status; + + Fcb = SEMIHOST_FCB_FROM_THIS(File); + + Status = SemihostFileLength (Fcb->SemihostHandle, &Length); + if (!EFI_ERROR(Status) && (Length < Position)) { + Position = Length; + } + + Status = SemihostFileSeek (Fcb->SemihostHandle, (UINT32)Position); + if (!EFI_ERROR(Status)) { + Fcb->Position = Position; + } + + return Status; +} + +STATIC +EFI_STATUS +GetFileInfo ( + IN SEMIHOST_FCB *Fcb, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_FILE_INFO *Info = NULL; + UINTN NameSize = 0; + UINTN ResultSize; + UINTN Index; + UINT32 Length; + EFI_STATUS Status; + + if (Fcb->IsRoot == TRUE) { + ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16); + } else { + NameSize = AsciiStrLen (Fcb->FileName) + 1; + ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16); + } + + if (*BufferSize < ResultSize) { + *BufferSize = ResultSize; + return EFI_BUFFER_TOO_SMALL; + } + + Info = Buffer; + + // Zero out the structure + ZeroMem (Info, SIZE_OF_EFI_FILE_INFO); + + // Fill in the structure + Info->Size = ResultSize; + + if (Fcb->IsRoot == TRUE) { + Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY; + Info->FileName[0] = L'\0'; + } else { + Status = SemihostFileLength (Fcb->SemihostHandle, &Length); + if (EFI_ERROR(Status)) { + return Status; + } + + Info->FileSize = Length; + Info->PhysicalSize = Length; + + for (Index = 0; Index < NameSize; Index++) { + Info->FileName[Index] = Fcb->FileName[Index]; + } + } + + + *BufferSize = ResultSize; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +GetFilesystemInfo ( + IN SEMIHOST_FCB *Fcb, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_FILE_SYSTEM_INFO *Info = NULL; + EFI_STATUS Status; + STATIC CHAR16 Label[] = L"SemihostFs"; + UINTN ResultSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize(Label); + + if(*BufferSize >= ResultSize) { + ZeroMem (Buffer, ResultSize); + Status = EFI_SUCCESS; + + Info = Buffer; + + Info->Size = ResultSize; + Info->ReadOnly = FALSE; + Info->VolumeSize = 0; + Info->FreeSpace = 0; + Info->BlockSize = 0; + + StrCpy (Info->VolumeLabel, Label); + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + + *BufferSize = ResultSize; + return Status; +} + +EFI_STATUS +FileGetInfo ( + IN EFI_FILE *File, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + SEMIHOST_FCB *Fcb = NULL; + EFI_STATUS Status = EFI_UNSUPPORTED; + + Fcb = SEMIHOST_FCB_FROM_THIS(File); + + if (CompareGuid(InformationType, &gEfiFileSystemInfoGuid) != 0) { + Status = GetFilesystemInfo(Fcb, BufferSize, Buffer); + } else if (CompareGuid(InformationType, &gEfiFileInfoGuid) != 0) { + Status = GetFileInfo(Fcb, BufferSize, Buffer); + } + + return Status; +} + +EFI_STATUS +FileSetInfo ( + IN EFI_FILE *File, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +FileFlush ( + IN EFI_FILE *File + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +SemihostFsEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status = EFI_NOT_FOUND; + + if (SemihostConnectionSupported ()) { + Status = gBS->InstallMultipleProtocolInterfaces ( + &gInstallHandle, + &gEfiSimpleFileSystemProtocolGuid, &gSemihostFs, + &gEfiDevicePathProtocolGuid, &gDevicePath, + NULL + ); + } + + return Status; +} + diff --git a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h new file mode 100644 index 0000000000..f058d92e29 --- /dev/null +++ b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.h @@ -0,0 +1,114 @@ +/** @file + Support a Semi Host file system over a debuggers JTAG + + Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+ + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __SEMIHOST_FS_H__ +#define __SEMIHOST_FS_H__ + +EFI_STATUS +SemihostFsSupported( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +SemihostFsStart( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +EFI_STATUS +SemihostFsStop( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +EFI_STATUS +VolumeOpen( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE **Root + ); + +EFI_STATUS +FileOpen( + IN EFI_FILE *File, + OUT EFI_FILE **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +EFI_STATUS +FileClose( + IN EFI_FILE *File + ); + +EFI_STATUS +FileDelete( + IN EFI_FILE *File + ); + +EFI_STATUS +FileRead( + IN EFI_FILE *File, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +FileWrite( + IN EFI_FILE *File, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +EFI_STATUS +FileGetPosition( + IN EFI_FILE *File, + OUT UINT64 *Position + ); + +EFI_STATUS +FileSetPosition( + IN EFI_FILE *File, + IN UINT64 Position + ); + +EFI_STATUS +FileGetInfo( + IN EFI_FILE *File, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +FileSetInfo( + IN EFI_FILE *File, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +EFI_STATUS +FileFlush( + IN EFI_FILE *File + ); + +#endif // __SEMIHOST_FS_H__ + diff --git a/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf b/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf new file mode 100644 index 0000000000..7fca293d6f --- /dev/null +++ b/ArmPkg/Filesystem/SemihostFs/SemihostFs.inf @@ -0,0 +1,48 @@ +#%HEADER% +#/** @file +# Support a Semi Host file system over a debuggers JTAG +# +# Copyright (c) 2009, Apple, Inc. +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SemihostFs + FILE_GUID = C5B9C74A-6D72-4719-99AB-C59F199091EB + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = SemihostFsEntryPoint + + +[Sources.ARM] + Arm/SemihostFs.c + +[Packages] + MdePkg/MdePkg.dec + ArmPkg/ArmPkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + SemihostLib + UefiDriverEntryPoint + UefiLib + +[Guids] + gEfiFileSystemInfoGuid + gEfiFileInfoGuid + gEfiFileSystemVolumeLabelInfoIdGuid + +[Protocols] + gEfiSimpleFileSystemProtocolGuid + gEfiDevicePathProtocolGuid + -- cgit v1.2.3