summaryrefslogtreecommitdiff
path: root/EmbeddedPkg
diff options
context:
space:
mode:
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2013-01-25 11:28:06 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2013-01-25 11:28:06 +0000
commit1e57a46299244793beb27e74be171d1540606999 (patch)
tree8644a24d6e4b4cfd080d4c40ccf2d3d9f13760f9 /EmbeddedPkg
parent5767f22fca7c337cdc113e14b411c1fd0ea7bd53 (diff)
downloadedk2-platforms-1e57a46299244793beb27e74be171d1540606999.tar.xz
ARM Packages: Fixed line endings
This large code change only modifies the line endings to be CRLF to be compliant with the EDK2 coding convention document. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14088 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EmbeddedPkg')
-rw-r--r--EmbeddedPkg/Ebl/Ebl.h414
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dsc524
-rw-r--r--EmbeddedPkg/GdbStub/GdbStub.c2526
-rw-r--r--EmbeddedPkg/GdbStub/GdbStubInternal.h1492
-rw-r--r--EmbeddedPkg/GdbStub/Ia32/Processor.c1986
-rw-r--r--EmbeddedPkg/GdbStub/SerialIo.c1102
-rwxr-xr-xEmbeddedPkg/Include/Library/DebugAgentTimerLib.h2
-rwxr-xr-xEmbeddedPkg/Include/Library/DmaLib.h144
-rw-r--r--EmbeddedPkg/Include/Library/EblAddExternalCommandLib.h244
-rw-r--r--EmbeddedPkg/Include/Library/EblCmdLib.h96
-rw-r--r--EmbeddedPkg/Include/Library/EblNetworkLib.h136
-rw-r--r--EmbeddedPkg/Include/Library/GdbSerialLib.h214
-rw-r--r--EmbeddedPkg/Include/Library/PrePiLib.h1580
-rw-r--r--EmbeddedPkg/Include/Library/SerialPortExtLib.h132
-rw-r--r--EmbeddedPkg/Include/Protocol/EblAddCommand.h10
-rw-r--r--EmbeddedPkg/Include/Protocol/EmbeddedExternalDevice.h188
-rw-r--r--EmbeddedPkg/Include/Protocol/EmbeddedGpio.h334
-rw-r--r--EmbeddedPkg/Include/fdt.h148
-rw-r--r--EmbeddedPkg/Include/libfdt.h2956
-rw-r--r--EmbeddedPkg/Include/libfdt_env.h154
-rwxr-xr-xEmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLib.c2
-rw-r--r--EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf2
-rw-r--r--EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf2
-rw-r--r--EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.c346
-rw-r--r--EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf2
-rw-r--r--EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c3556
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt.c444
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c168
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_ro.c1150
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_rw.c990
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_strerror.c192
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_sw.c512
-rw-r--r--EmbeddedPkg/Library/FdtLib/fdt_wip.c236
-rw-r--r--EmbeddedPkg/Library/FdtLib/libfdt_internal.h190
-rwxr-xr-xEmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S516
-rwxr-xr-xEmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm518
-rwxr-xr-xEmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c104
-rwxr-xr-xEmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h1398
-rwxr-xr-xEmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c1824
-rwxr-xr-xEmbeddedPkg/Library/NullDmaLib/NullDmaLib.inf2
-rw-r--r--EmbeddedPkg/Library/PrePiHobLib/Hob.c1704
-rw-r--r--EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointer.c10
-rw-r--r--EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf2
-rw-r--r--EmbeddedPkg/Library/PrePiLib/FwVol.c1684
-rw-r--r--EmbeddedPkg/Library/PrePiLib/PrePi.h92
-rw-r--r--EmbeddedPkg/Library/PrePiLib/PrePiLib.c452
-rw-r--r--EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c654
-rw-r--r--EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf2
-rw-r--r--EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf2
-rw-r--r--EmbeddedPkg/TemplateSec/TemplateSec.inf130
-rw-r--r--EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf2
51 files changed, 15635 insertions, 15635 deletions
diff --git a/EmbeddedPkg/Ebl/Ebl.h b/EmbeddedPkg/Ebl/Ebl.h
index 03b4ba29fb..44c44fb0fc 100644
--- a/EmbeddedPkg/Ebl/Ebl.h
+++ b/EmbeddedPkg/Ebl/Ebl.h
@@ -1,207 +1,207 @@
-/** @file
- Include file for basic command line parser for EBL (Embedded Boot Loader)
-
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __EBL_H__
-#define __EBL_H__
-
-#include <PiDxe.h>
-#include <Protocol/BlockIo.h>
-#include <Protocol/SimpleFileSystem.h>
-#include <Protocol/FirmwareVolume2.h>
-#include <Protocol/LoadFile.h>
-#include <Protocol/FirmwareVolumeBlock.h>
-#include <Protocol/PxeBaseCode.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/EblAddCommand.h>
-#include <Protocol/PciIo.h>
-#include <Protocol/DevicePath.h>
-
-#include <Guid/FileInfo.h>
-#include <Guid/DxeServices.h>
-#include <Guid/MemoryTypeInformation.h>
-#include <Guid/MemoryAllocationHob.h>
-#include <Library/BaseLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/PrintLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/DebugLib.h>
-#include <Library/EfiFileLib.h>
-#include <Library/HobLib.h>
-#include <Library/DebugLib.h>
-#include <Library/IoLib.h>
-#include <Library/PcdLib.h>
-#include <Library/EblCmdLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/UefiLib.h>
-#include <Library/EblNetworkLib.h>
-#include <Library/TimerLib.h>
-
-#include <IndustryStandard/Pci.h>
-
-//
-// Prompt for the command line
-//
-#define CMD_SEPARATOR ';'
-#define EBL_MAX_COMMAND_COUNT 0x100
-#define MAX_CMD_HISTORY 16
-#define MAX_CMD_LINE 256
-#define MAX_ARGS 32
-
-#define EBL_CR 0x0a
-#define EBL_LF 0x0d
-
-#define EFI_SET_TIMER_TO_SECOND 10000000
-
-
-
-EBL_COMMAND_TABLE *
-EblGetCommand (
- IN CHAR8 *CommandName
- );
-
-
-EFI_STATUS
-EblPathToDevice (
- IN CHAR8 *Path,
- OUT EFI_HANDLE *DeviceHandle,
- OUT EFI_DEVICE_PATH_PROTOCOL **PathDevicePath,
- OUT VOID **Buffer,
- OUT UINTN *BufferSize
- );
-
-BOOLEAN
-EblAnyKeyToContinueQtoQuit (
- IN UINTN *CurrentRow,
- IN BOOLEAN PrefixNewline
- );
-
-VOID
-EblUpdateDeviceLists (
- VOID
- );
-
-VOID
-EblInitializeCmdTable (
- VOID
- );
-
-VOID
-EblShutdownExternalCmdTable (
- VOID
- );
-
-VOID
-EblSetTextColor (
- UINTN Attribute
- );
-
-
-EFI_STATUS
-EblGetCharKey (
- IN OUT EFI_INPUT_KEY *Key,
- IN UINTN TimoutInSec,
- IN EBL_GET_CHAR_CALL_BACK CallBack OPTIONAL
- );
-
-// BugBug: Move me to a library
-INTN
-EFIAPI
-AsciiStrniCmp (
- IN CONST CHAR8 *FirstString,
- IN CONST CHAR8 *SecondString,
- IN UINTN Length
- );
-
-
-VOID
-EblInitializeDeviceCmd (
- VOID
- );
-
-VOID
-EblInitializemdHwDebugCmds (
- VOID
- );
-
-VOID
-EblInitializeDirCmd (
- VOID
- );
-
-VOID
-EblInitializeHobCmd (
- VOID
- );
-
-VOID
-EblInitializemdHwIoDebugCmds (
- VOID
- );
-
-VOID
-EblInitializeScriptCmd (
- VOID
- );
-
-VOID
-EblInitializeNetworkCmd (
- VOID
- );
-
-VOID
-EblInitializeVariableCmds (
- VOID
- );
-
-CHAR8 *
-ParseArguments (
- IN CHAR8 *CmdLine,
- OUT UINTN *Argc,
- OUT CHAR8 **Argv
- );
-
-EFI_STATUS
-ProcessCmdLine (
- IN CHAR8 *CmdLine,
- IN UINTN MaxCmdLineSize
- );
-
-EFI_STATUS
-OutputData (
- IN UINT8 *Address,
- IN UINTN Length,
- IN UINTN Width,
- IN UINTN Offset
- );
-
-UINTN
-WidthFromCommandName (
- IN CHAR8 *Argv,
- IN UINTN Default
- );
-
-
-extern UINTN gScreenColumns;
-extern UINTN gScreenRows;
-extern BOOLEAN gPageBreak;
-extern CHAR8 *gMemMapType[];
-
-#endif
-
+/** @file
+ Include file for basic command line parser for EBL (Embedded Boot Loader)
+
+ Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __EBL_H__
+#define __EBL_H__
+
+#include <PiDxe.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/PxeBaseCode.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/EblAddCommand.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DevicePath.h>
+
+#include <Guid/FileInfo.h>
+#include <Guid/DxeServices.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/MemoryAllocationHob.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EfiFileLib.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/EblCmdLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/EblNetworkLib.h>
+#include <Library/TimerLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+//
+// Prompt for the command line
+//
+#define CMD_SEPARATOR ';'
+#define EBL_MAX_COMMAND_COUNT 0x100
+#define MAX_CMD_HISTORY 16
+#define MAX_CMD_LINE 256
+#define MAX_ARGS 32
+
+#define EBL_CR 0x0a
+#define EBL_LF 0x0d
+
+#define EFI_SET_TIMER_TO_SECOND 10000000
+
+
+
+EBL_COMMAND_TABLE *
+EblGetCommand (
+ IN CHAR8 *CommandName
+ );
+
+
+EFI_STATUS
+EblPathToDevice (
+ IN CHAR8 *Path,
+ OUT EFI_HANDLE *DeviceHandle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **PathDevicePath,
+ OUT VOID **Buffer,
+ OUT UINTN *BufferSize
+ );
+
+BOOLEAN
+EblAnyKeyToContinueQtoQuit (
+ IN UINTN *CurrentRow,
+ IN BOOLEAN PrefixNewline
+ );
+
+VOID
+EblUpdateDeviceLists (
+ VOID
+ );
+
+VOID
+EblInitializeCmdTable (
+ VOID
+ );
+
+VOID
+EblShutdownExternalCmdTable (
+ VOID
+ );
+
+VOID
+EblSetTextColor (
+ UINTN Attribute
+ );
+
+
+EFI_STATUS
+EblGetCharKey (
+ IN OUT EFI_INPUT_KEY *Key,
+ IN UINTN TimoutInSec,
+ IN EBL_GET_CHAR_CALL_BACK CallBack OPTIONAL
+ );
+
+// BugBug: Move me to a library
+INTN
+EFIAPI
+AsciiStrniCmp (
+ IN CONST CHAR8 *FirstString,
+ IN CONST CHAR8 *SecondString,
+ IN UINTN Length
+ );
+
+
+VOID
+EblInitializeDeviceCmd (
+ VOID
+ );
+
+VOID
+EblInitializemdHwDebugCmds (
+ VOID
+ );
+
+VOID
+EblInitializeDirCmd (
+ VOID
+ );
+
+VOID
+EblInitializeHobCmd (
+ VOID
+ );
+
+VOID
+EblInitializemdHwIoDebugCmds (
+ VOID
+ );
+
+VOID
+EblInitializeScriptCmd (
+ VOID
+ );
+
+VOID
+EblInitializeNetworkCmd (
+ VOID
+ );
+
+VOID
+EblInitializeVariableCmds (
+ VOID
+ );
+
+CHAR8 *
+ParseArguments (
+ IN CHAR8 *CmdLine,
+ OUT UINTN *Argc,
+ OUT CHAR8 **Argv
+ );
+
+EFI_STATUS
+ProcessCmdLine (
+ IN CHAR8 *CmdLine,
+ IN UINTN MaxCmdLineSize
+ );
+
+EFI_STATUS
+OutputData (
+ IN UINT8 *Address,
+ IN UINTN Length,
+ IN UINTN Width,
+ IN UINTN Offset
+ );
+
+UINTN
+WidthFromCommandName (
+ IN CHAR8 *Argv,
+ IN UINTN Default
+ );
+
+
+extern UINTN gScreenColumns;
+extern UINTN gScreenRows;
+extern BOOLEAN gPageBreak;
+extern CHAR8 *gMemMapType[];
+
+#endif
+
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc
index 8862f3d1ec..e1a4c225e6 100644
--- a/EmbeddedPkg/EmbeddedPkg.dsc
+++ b/EmbeddedPkg/EmbeddedPkg.dsc
@@ -1,262 +1,262 @@
-#/** @file
-# Embedded Package
-#
-#
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-#
-# 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 Section - statements that will be processed to create a Makefile.
-#
-################################################################################
-[Defines]
- PLATFORM_NAME = Embedded
- PLATFORM_GUID = 8DBB580B-CF89-4D57-95C6-DFE96C44686E
- PLATFORM_VERSION = 0.1
- DSC_SPECIFICATION = 0x00010005
- OUTPUT_DIRECTORY = Build/Embedded
- SUPPORTED_ARCHITECTURES = IA32|X64|IPF|ARM
- BUILD_TARGETS = DEBUG|RELEASE
- SKUID_IDENTIFIER = DEFAULT
- FLASH_DEFINITION = EmbeddedPkg/EmbeddedPkg.fdf
-
-
-################################################################################
-#
-# SKU Identification section - list of all SKU IDs supported by this
-# Platform.
-#
-################################################################################
-[SkuIds]
- 0|DEFAULT # The entry: 0|DEFAULT is reserved and always required.
-
-################################################################################
-#
-# Library Class section - list of all Library Classes needed by this Platform.
-#
-################################################################################
-[LibraryClasses.common]
-# DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
- DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
-
-
- BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
- BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
- PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
- PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
- PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
- UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
- EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
-
- TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
-
- ReportStatusCodeLib|IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
-
- PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
- PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
- PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
- CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
- PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
-
- SerialPortLib|EmbeddedPkg/Library/TemplateSerialPortLib/TemplateSerialPortLib.inf
- RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
- EfiResetSystemLib|EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
- GdbSerialLib|EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.inf
-
-
- #
- # Need to change this for IPF
- #
- IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
-
- MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
- UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
- HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
- UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
- DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
- UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
- ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
-
- DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
- UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
- UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
-
-
- PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
- EblCmdLib|EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf
-
- EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
-
-
-[LibraryClasses.common.DXE_DRIVER]
- PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
-
-
-[LibraryClasses.common.UEFI_APPLICATION]
- PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
-
-[LibraryClasses.common.UEFI_DRIVER]
- PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
- ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
-
-[LibraryClasses.common.SEC]
- ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
-
-[LibraryClasses.ARM]
- SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
-
-[LibraryClasses.ARM]
- NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
-
-
-################################################################################
-#
-# Pcd Section - list of all PCD Entries defined by this Platform
-#
-################################################################################
-
-[PcdsFeatureFlag.common]
- gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE
- gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|FALSE
- gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|FALSE
- gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|FALSE
-
- #
- # Control what commands are supported from the UI
- # Turn these on and off to add features or save size
- #
- gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|TRUE
- gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd|TRUE
- gEmbeddedTokenSpaceGuid.PcdEmbeddedHobCmd|TRUE
- gEmbeddedTokenSpaceGuid.PcdEmbeddedHwDebugCmd|TRUE
- gEmbeddedTokenSpaceGuid.PcdEmbeddedIoEnable|FALSE
- gEmbeddedTokenSpaceGuid.PcdEmbeddedScriptCmd|FALSE
- gEmbeddedTokenSpaceGuid.PcdEmbeddedPciDebugCmd|TRUE
-
- gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|FALSE
-
-
-[PcdsFixedAtBuild.common]
- gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
- gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
- gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
- gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
- gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0f
- gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000
- gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x06
- gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
- gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0
- gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
- gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
- gEfiMdePkgTokenSpaceGuid.PcdFSBClock|200000000
- gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
- gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000
- gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
- gEfiMdePkgTokenSpaceGuid.PcdFSBClock|200000000
- gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|L""|VOID*|2
- gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor|0x07
- gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize|0x10000
-
- gEmbeddedTokenSpaceGuid.PcdPrePiHobBase|0
- gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0
- gEmbeddedTokenSpaceGuid.PcdPrePiStackSize|0
-
-#
-# Optinal feature to help prevent EFI memory map fragments
-# Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
-# Values are in EFI Pages (4K). DXE Core will make sure that
-# at least this much of each type of memory can be allocated
-# from a single memory range. This way you only end up with
-# maximum of two fragements for each type in the memory map
-# (the memory used, and the free memory that was prereserved
-# but not used).
-#
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|0
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|0
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|0
- gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
-
-#
-# Timer config for this platform
-#
- gEmbeddedTokenSpaceGuid.PcdTimerBaseAddress|0x3c700000
- gEmbeddedTokenSpaceGuid.PcdTimerVector|7
- gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000
-
-
-[PcdsFixedAtBuild.ARM]
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
-
-[PcdsFixedAtBuild.IA32]
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|36
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
-
-[PcdsFixedAtBuild.X64]
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|52
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
-
-
-
-[PcdsFixedAtBuild.IPF]
- gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf|0x0ffffc000000
-
-#
-# This makes it so you can source level debug with NT32. VC++ debugger limitiation!
-#
-#[BuildOptions]
-# DEBUG_*_IA32_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /ALIGN:4096 /SUBSYSTEM:CONSOLE
-# RELEASE_*_IA32_DLINK_FLAGS = /ALIGN:4096
-# *_*_IA32_CC_FLAGS = /D EFI_SPECIFICATION_VERSION=0x0002000A /D TIANO_RELEASE_VERSION=0x00080006
-
-
-################################################################################
-#
-# Components Section - list of all Modules needed by this Platform
-#
-################################################################################
-[Components.common]
- EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
- EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf
- EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
- EmbeddedPkg/Library/GdbSerialDebugPortLib/GdbSerialDebugPortLib.inf
- EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.inf
- EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
- EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
- EmbeddedPkg/Library/TemplateSerialPortLib/TemplateSerialPortLib.inf
- EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
- EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
- EmbeddedPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.inf
- EmbeddedPkg/Library/NullDmaLib/NullDmaLib.inf
-
- EmbeddedPkg/Ebl/Ebl.inf
-#### EmbeddedPkg/EblExternCmd/EblExternCmd.inf
- EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
- EmbeddedPkg/GdbStub/GdbStub.inf
- EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
- EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
- EmbeddedPkg/SerialDxe/SerialDxe.inf
- EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
- EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
-
- EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
-
-
-
+#/** @file
+# Embedded Package
+#
+#
+# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+#
+# 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 Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = Embedded
+ PLATFORM_GUID = 8DBB580B-CF89-4D57-95C6-DFE96C44686E
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/Embedded
+ SUPPORTED_ARCHITECTURES = IA32|X64|IPF|ARM
+ BUILD_TARGETS = DEBUG|RELEASE
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = EmbeddedPkg/EmbeddedPkg.fdf
+
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this
+# Platform.
+#
+################################################################################
+[SkuIds]
+ 0|DEFAULT # The entry: 0|DEFAULT is reserved and always required.
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses.common]
+# DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+
+
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+ EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
+
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+ PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+
+ SerialPortLib|EmbeddedPkg/Library/TemplateSerialPortLib/TemplateSerialPortLib.inf
+ RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
+ EfiResetSystemLib|EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
+ GdbSerialLib|EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.inf
+
+
+ #
+ # Need to change this for IPF
+ #
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+
+
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ EblCmdLib|EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf
+
+ EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
+
+
+[LibraryClasses.common.DXE_DRIVER]
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+
+[LibraryClasses.common.UEFI_APPLICATION]
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.SEC]
+ ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+
+[LibraryClasses.ARM]
+ SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
+
+[LibraryClasses.ARM]
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+
+################################################################################
+#
+# Pcd Section - list of all PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+ gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|FALSE
+
+ #
+ # Control what commands are supported from the UI
+ # Turn these on and off to add features or save size
+ #
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedHobCmd|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedHwDebugCmd|TRUE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedIoEnable|FALSE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedScriptCmd|FALSE
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedPciDebugCmd|TRUE
+
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|FALSE
+
+
+[PcdsFixedAtBuild.common]
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0f
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x06
+ gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0
+ gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock|200000000
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000
+ gEfiMdePkgTokenSpaceGuid.PcdFSBClock|200000000
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|L""|VOID*|2
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor|0x07
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize|0x10000
+
+ gEmbeddedTokenSpaceGuid.PcdPrePiHobBase|0
+ gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0
+ gEmbeddedTokenSpaceGuid.PcdPrePiStackSize|0
+
+#
+# Optinal feature to help prevent EFI memory map fragments
+# Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+# Values are in EFI Pages (4K). DXE Core will make sure that
+# at least this much of each type of memory can be allocated
+# from a single memory range. This way you only end up with
+# maximum of two fragements for each type in the memory map
+# (the memory used, and the free memory that was prereserved
+# but not used).
+#
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+#
+# Timer config for this platform
+#
+ gEmbeddedTokenSpaceGuid.PcdTimerBaseAddress|0x3c700000
+ gEmbeddedTokenSpaceGuid.PcdTimerVector|7
+ gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000
+
+
+[PcdsFixedAtBuild.ARM]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
+
+[PcdsFixedAtBuild.IA32]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|36
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
+
+[PcdsFixedAtBuild.X64]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|52
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
+
+
+
+[PcdsFixedAtBuild.IPF]
+ gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf|0x0ffffc000000
+
+#
+# This makes it so you can source level debug with NT32. VC++ debugger limitiation!
+#
+#[BuildOptions]
+# DEBUG_*_IA32_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /ALIGN:4096 /SUBSYSTEM:CONSOLE
+# RELEASE_*_IA32_DLINK_FLAGS = /ALIGN:4096
+# *_*_IA32_CC_FLAGS = /D EFI_SPECIFICATION_VERSION=0x0002000A /D TIANO_RELEASE_VERSION=0x00080006
+
+
+################################################################################
+#
+# Components Section - list of all Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+ EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
+ EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf
+ EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
+ EmbeddedPkg/Library/GdbSerialDebugPortLib/GdbSerialDebugPortLib.inf
+ EmbeddedPkg/Library/GdbSerialLib/GdbSerialLib.inf
+ EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+ EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+ EmbeddedPkg/Library/TemplateSerialPortLib/TemplateSerialPortLib.inf
+ EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
+ EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
+ EmbeddedPkg/Library/LzmaHobCustomDecompressLib/LzmaHobCustomDecompressLib.inf
+ EmbeddedPkg/Library/NullDmaLib/NullDmaLib.inf
+
+ EmbeddedPkg/Ebl/Ebl.inf
+#### EmbeddedPkg/EblExternCmd/EblExternCmd.inf
+ EmbeddedPkg/EmbeddedMonotonicCounter/EmbeddedMonotonicCounter.inf
+ EmbeddedPkg/GdbStub/GdbStub.inf
+ EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ EmbeddedPkg/SerialDxe/SerialDxe.inf
+ EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+ EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+
+
+
diff --git a/EmbeddedPkg/GdbStub/GdbStub.c b/EmbeddedPkg/GdbStub/GdbStub.c
index 742de505ca..8a13cc8a19 100644
--- a/EmbeddedPkg/GdbStub/GdbStub.c
+++ b/EmbeddedPkg/GdbStub/GdbStub.c
@@ -1,1263 +1,1263 @@
-/** @file
- UEFI driver that implements a GDB stub
-
- Note: Any code in the path of the Serial IO output can not call DEBUG as will
- will blow out the stack. Serial IO calls DEBUG, debug calls Serail IO, ...
-
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 <GdbStubInternal.h>
-#include <Protocol/DebugPort.h>
-
-
-UINTN gMaxProcessorIndex = 0;
-
-//
-// Buffers for basic gdb communication
-//
-CHAR8 gInBuffer[MAX_BUF_SIZE];
-CHAR8 gOutBuffer[MAX_BUF_SIZE];
-
-// Assume gdb does a "qXfer:libraries:read::offset,length" when it connects so we can default
-// this value to FALSE. Since gdb can reconnect its self a global default is not good enough
-BOOLEAN gSymbolTableUpdate = FALSE;
-EFI_EVENT gEvent;
-VOID *gGdbSymbolEventHandlerRegistration = NULL;
-
-//
-// Globals for returning XML from qXfer:libraries:read packet
-//
-UINTN gPacketqXferLibraryOffset = 0;
-UINTN gEfiDebugImageTableEntry = 0;
-EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;
-EFI_DEBUG_IMAGE_INFO *gDebugTable = NULL;
-CHAR8 gXferLibraryBuffer[2000];
-
-GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexToStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
-
-
-VOID
-EFIAPI
-GdbSymbolEventHandler (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
-}
-
-
-/**
- The user Entry Point for Application. The user code starts with this function
- as the real entry point for the image goes into a library that calls 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
-GdbStubEntry (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-
-{
- EFI_STATUS Status;
- EFI_DEBUG_SUPPORT_PROTOCOL *DebugSupport;
- UINTN HandleCount;
- EFI_HANDLE *Handles;
- UINTN Index;
- UINTN Processor;
- BOOLEAN IsaSupported;
-
-
- Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);
- if (EFI_ERROR (Status)) {
- gDebugImageTableHeader = NULL;
- }
-
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiDebugSupportProtocolGuid,
- NULL,
- &HandleCount,
- &Handles
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Debug Support Protocol not found\n"));
-
- return Status;
- }
-
- DebugSupport = NULL;
- IsaSupported = FALSE;
- do {
- HandleCount--;
- Status = gBS->HandleProtocol (
- Handles[HandleCount],
- &gEfiDebugSupportProtocolGuid,
- (VOID **) &DebugSupport
- );
- if (!EFI_ERROR (Status)) {
- if (CheckIsa (DebugSupport->Isa)) {
- // We found what we are looking for so break out of the loop
- IsaSupported = TRUE;
- break;
- }
- }
- } while (HandleCount > 0);
- FreePool (Handles);
-
- if (!IsaSupported) {
- DEBUG ((EFI_D_ERROR, "Debug Support Protocol does not support our ISA\n"));
-
- return EFI_NOT_FOUND;
- }
-
- Status = DebugSupport->GetMaximumProcessorIndex (DebugSupport, &gMaxProcessorIndex);
- ASSERT_EFI_ERROR (Status);
-
- DEBUG ((EFI_D_INFO, "Debug Support Protocol ISA %x\n", DebugSupport->Isa));
- DEBUG ((EFI_D_INFO, "Debug Support Protocol Processor Index %d\n", gMaxProcessorIndex));
-
- // Call processor-specific init routine
- InitializeProcessor();
-
- for (Processor = 0; Processor <= gMaxProcessorIndex; Processor++) {
-
- for (Index = 0; Index < MaxEfiException (); Index++) {
- Status = DebugSupport->RegisterExceptionCallback (DebugSupport, Processor, GdbExceptionHandler, gExceptionType[Index].Exception);
- ASSERT_EFI_ERROR (Status);
- }
- //
- // Current edk2 DebugPort is not interrupt context safe so we can not use it
- //
- Status = DebugSupport->RegisterPeriodicCallback (DebugSupport, Processor, GdbPeriodicCallBack);
- ASSERT_EFI_ERROR (Status);
- }
-
- //
- // This even fires every time an image is added. This allows the stub to know when gdb needs
- // to update the symbol table.
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- GdbSymbolEventHandler,
- NULL,
- &gEvent
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Register for protocol notifactions on this event
- //
- Status = gBS->RegisterProtocolNotify (
- &gEfiLoadedImageProtocolGuid,
- gEvent,
- &gGdbSymbolEventHandlerRegistration
- );
- ASSERT_EFI_ERROR (Status);
-
-
- if (PcdGetBool (PcdGdbSerial)) {
- GdbInitializeSerialConsole ();
- }
-
- return EFI_SUCCESS;
-}
-
-
-
-/**
- Transfer length bytes of input buffer, starting at Address, to memory.
-
- @param length the number of the bytes to be transferred/written
- @param *address the start address of the transferring/writing the memory
- @param *new_data the new data to be written to memory
- **/
-
-VOID
-TransferFromInBufToMem (
- IN UINTN Length,
- IN unsigned char *Address,
- IN CHAR8 *NewData
- )
-{
- CHAR8 c1;
- CHAR8 c2;
-
- while (Length-- > 0) {
- c1 = (CHAR8)HexCharToInt (*NewData++);
- c2 = (CHAR8)HexCharToInt (*NewData++);
-
- if ((c1 < 0) || (c2 < 0)) {
- Print ((CHAR16 *)L"Bad message from write to memory..\n");
- SendError (GDB_EBADMEMDATA);
- return;
- }
- *Address++ = (UINT8)((c1 << 4) + c2);
- }
-
- SendSuccess();
-}
-
-
-/**
- Transfer Length bytes of memory starting at Address to an output buffer, OutBuffer. This function will finally send the buffer
- as a packet.
-
- @param Length the number of the bytes to be transferred/read
- @param *address pointer to the start address of the transferring/reading the memory
- **/
-
-VOID
-TransferFromMemToOutBufAndSend (
- IN UINTN Length,
- IN unsigned char *Address
- )
-{
- // there are Length bytes and every byte is represented as 2 hex chars
- CHAR8 OutBuffer[MAX_BUF_SIZE];
- CHAR8 *OutBufPtr; // pointer to the output buffer
- CHAR8 Char;
-
- if (ValidateAddress(Address) == FALSE) {
- SendError(14);
- return;
- }
-
- OutBufPtr = OutBuffer;
- while (Length > 0) {
-
- Char = mHexToStr[*Address >> 4];
- if ((Char >= 'A') && (Char <= 'F')) {
- Char = Char - 'A' + 'a';
- }
- *OutBufPtr++ = Char;
-
- Char = mHexToStr[*Address & 0x0f];
- if ((Char >= 'A') && (Char <= 'F')) {
- Char = Char - 'A' + 'a';
- }
- *OutBufPtr++ = Char;
-
- Address++;
- Length--;
- }
-
- *OutBufPtr = '\0' ; // the end of the buffer
- SendPacket (OutBuffer);
-}
-
-
-
-/**
- Send a GDB Remote Serial Protocol Packet
-
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
- the packet teminating character '#' and the two digit checksum.
-
- If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
- in an infinit loop. This is so if you unplug the debugger code just keeps running
-
- @param PacketData Payload data for the packet
-
-
- @retval Number of bytes of packet data sent.
-
-**/
-UINTN
-SendPacket (
- IN CHAR8 *PacketData
- )
-{
- UINT8 CheckSum;
- UINTN Timeout;
- CHAR8 *Ptr;
- CHAR8 TestChar;
- UINTN Count;
-
- Timeout = PcdGet32 (PcdGdbMaxPacketRetryCount);
-
- Count = 0;
- do {
-
- Ptr = PacketData;
-
- if (Timeout-- == 0) {
- // Only try a finite number of times so we don't get stuck in the loop
- return Count;
- }
-
- // Packet prefix
- GdbPutChar ('$');
-
- for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) {
- GdbPutChar (*Ptr);
- CheckSum = CheckSum + *Ptr;
- }
-
- // Packet terminating character and checksum
- GdbPutChar ('#');
- GdbPutChar (mHexToStr[CheckSum >> 4]);
- GdbPutChar (mHexToStr[CheckSum & 0x0F]);
-
- TestChar = GdbGetChar ();
- } while (TestChar != '+');
-
- return Count;
-}
-
-/**
- Receive a GDB Remote Serial Protocol Packet
-
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
- the packet teminating character '#' and the two digit checksum.
-
- If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
- (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
-
- If an ack '+' is not sent resend the packet
-
- @param PacketData Payload data for the packet
-
- @retval Number of bytes of packet data received.
-
-**/
-UINTN
-ReceivePacket (
- OUT CHAR8 *PacketData,
- IN UINTN PacketDataSize
- )
-{
- UINT8 CheckSum;
- UINTN Index;
- CHAR8 Char;
- CHAR8 SumString[3];
- CHAR8 TestChar;
-
- ZeroMem (PacketData, PacketDataSize);
-
- for (;;) {
- // wait for the start of a packet
- TestChar = GdbGetChar ();
- while (TestChar != '$') {
- TestChar = GdbGetChar ();
- };
-
- retry:
- for (Index = 0, CheckSum = 0; Index < (PacketDataSize - 1); Index++) {
- Char = GdbGetChar ();
- if (Char == '$') {
- goto retry;
- }
- if (Char == '#') {
- break;
- }
-
- PacketData[Index] = Char;
- CheckSum = CheckSum + Char;
- }
- PacketData[Index] = '\0';
-
- if (Index == PacketDataSize) {
- continue;
- }
-
- SumString[0] = GdbGetChar ();
- SumString[1] = GdbGetChar ();
- SumString[2] = '\0';
-
- if (AsciiStrHexToUintn (SumString) == CheckSum) {
- // Ack: Success
- GdbPutChar ('+');
-
- // Null terminate the callers string
- PacketData[Index] = '\0';
- return Index;
- } else {
- // Ack: Failure
- GdbPutChar ('-');
- }
- }
-
- //return 0;
-}
-
-
-/**
- Empties the given buffer
- @param Buf pointer to the first element in buffer to be emptied
- **/
-VOID
-EmptyBuffer (
- IN CHAR8 *Buf
- )
-{
- *Buf = '\0';
-}
-
-
-/**
- Converts an 8-bit Hex Char into a INTN.
-
- @param Char the hex character to be converted into UINTN
- @retval a INTN, from 0 to 15, that corressponds to Char
- -1 if Char is not a hex character
- **/
-INTN
-HexCharToInt (
- IN CHAR8 Char
- )
-{
- if ((Char >= 'A') && (Char <= 'F')) {
- return Char - 'A' + 10;
- } else if ((Char >= 'a') && (Char <= 'f')) {
- return Char - 'a' + 10;
- } else if ((Char >= '0') && (Char <= '9')) {
- return Char - '0';
- } else { // if not a hex value, return a negative value
- return -1;
- }
-}
-
- // 'E' + the biggest error number is 255, so its 2 hex digits + buffer end
-CHAR8 *gError = "E__";
-
-/** 'E NN'
- Send an error with the given error number after converting to hex.
- The error number is put into the buffer in hex. '255' is the biggest errno we can send.
- ex: 162 will be sent as A2.
-
- @param errno the error number that will be sent
- **/
-VOID
-EFIAPI
-SendError (
- IN UINT8 ErrorNum
- )
-{
- //
- // Replace _, or old data, with current errno
- //
- gError[1] = mHexToStr [ErrorNum >> 4];
- gError[2] = mHexToStr [ErrorNum & 0x0f];
-
- SendPacket (gError); // send buffer
-}
-
-
-
-/**
- Send 'OK' when the function is done executing successfully.
- **/
-VOID
-EFIAPI
-SendSuccess (
- VOID
- )
-{
- SendPacket ("OK"); // send buffer
-}
-
-
-/**
- Send empty packet to specify that particular command/functionality is not supported.
- **/
-VOID
-EFIAPI
-SendNotSupported (
- VOID
- )
-{
- SendPacket ("");
-}
-
-
-
-/**
- Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
-
- @param SystemContext Register content at time of the exception
- @param GdbExceptionType GDB exception type
- **/
-VOID
-GdbSendTSignal (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINT8 GdbExceptionType
- )
-{
- CHAR8 TSignalBuffer[128];
- CHAR8 *TSignalPtr;
- UINTN BreakpointDetected;
- BREAK_TYPE BreakType;
- UINTN DataAddress;
- CHAR8 *WatchStrPtr = NULL;
- UINTN RegSize;
-
- TSignalPtr = &TSignalBuffer[0];
-
- //Construct TSignal packet
- *TSignalPtr++ = 'T';
-
- //
- // replace _, or previous value, with Exception type
- //
- *TSignalPtr++ = mHexToStr [GdbExceptionType >> 4];
- *TSignalPtr++ = mHexToStr [GdbExceptionType & 0x0f];
-
- if (GdbExceptionType == GDB_SIGTRAP) {
- if (gSymbolTableUpdate) {
- //
- // We can only send back on reason code. So if the flag is set it means the breakpoint is from our event handler
- //
- WatchStrPtr = "library:;";
- while (*WatchStrPtr != '\0') {
- *TSignalPtr++ = *WatchStrPtr++;
- }
- gSymbolTableUpdate = FALSE;
- } else {
-
-
- //
- // possible n:r pairs
- //
-
- //Retrieve the breakpoint number
- BreakpointDetected = GetBreakpointDetected (SystemContext);
-
- //Figure out if the exception is happend due to watch, rwatch or awatch.
- BreakType = GetBreakpointType (SystemContext, BreakpointDetected);
-
- //INFO: rwatch is not supported due to the way IA32 debug registers work
- if ((BreakType == DataWrite) || (BreakType == DataRead) || (BreakType == DataReadWrite)) {
-
- //Construct n:r pair
- DataAddress = GetBreakpointDataAddress (SystemContext, BreakpointDetected);
-
- //Assign appropriate buffer to print particular watchpoint type
- if (BreakType == DataWrite) {
- WatchStrPtr = "watch";
- } else if (BreakType == DataRead) {
- WatchStrPtr = "rwatch";
- } else if (BreakType == DataReadWrite) {
- WatchStrPtr = "awatch";
- }
-
- while (*WatchStrPtr != '\0') {
- *TSignalPtr++ = *WatchStrPtr++;
- }
-
- *TSignalPtr++ = ':';
-
- //Set up series of bytes in big-endian byte order. "awatch" won't work with little-endian byte order.
- RegSize = REG_SIZE;
- while (RegSize > 0) {
- RegSize = RegSize-4;
- *TSignalPtr++ = mHexToStr[(UINT8)(DataAddress >> RegSize) & 0xf];
- }
-
- //Always end n:r pair with ';'
- *TSignalPtr++ = ';';
- }
- }
- }
-
- *TSignalPtr = '\0';
-
- SendPacket (TSignalBuffer);
-}
-
-
-/**
- Translates the EFI mapping to GDB mapping
-
- @param EFIExceptionType EFI Exception that is being processed
- @retval UINTN that corresponds to EFIExceptionType's GDB exception type number
- **/
-UINT8
-ConvertEFItoGDBtype (
- IN EFI_EXCEPTION_TYPE EFIExceptionType
- )
-{
- UINTN i;
-
- for (i=0; i < MaxEfiException() ; i++) {
- if (gExceptionType[i].Exception == EFIExceptionType) {
- return gExceptionType[i].SignalNo;
- }
- }
- return GDB_SIGTRAP; // this is a GDB trap
-}
-
-
-/** "m addr,length"
- Find the Length of the area to read and the start addres. Finally, pass them to
- another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
- send it as a packet.
- **/
-
-VOID
-EFIAPI
-ReadFromMemory (
- CHAR8 *PacketData
- )
-{
- UINTN Address;
- UINTN Length;
- CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the address in hex chars
- CHAR8 *AddrBufPtr; // pointer to the address buffer
- CHAR8 *InBufPtr; /// pointer to the input buffer
-
- AddrBufPtr = AddressBuffer;
- InBufPtr = &PacketData[1];
- while (*InBufPtr != ',') {
- *AddrBufPtr++ = *InBufPtr++;
- }
- *AddrBufPtr = '\0';
-
- InBufPtr++; // this skips ',' in the buffer
-
- /* Error checking */
- if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
- Print((CHAR16 *)L"Address is too long\n");
- SendError (GDB_EBADMEMADDRBUFSIZE);
- return;
- }
-
- // 2 = 'm' + ','
- if (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - 2 >= MAX_LENGTH_SIZE) {
- Print((CHAR16 *)L"Length is too long\n");
- SendError (GDB_EBADMEMLENGTH);
- return;
- }
-
- Address = AsciiStrHexToUintn (AddressBuffer);
- Length = AsciiStrHexToUintn (InBufPtr);
-
- TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address);
-}
-
-
-/** "M addr,length :XX..."
- Find the Length of the area in bytes to write and the start addres. Finally, pass them to
- another function, TransferFromInBufToMem, that will write to that memory space the info in
- the input buffer.
- **/
-VOID
-EFIAPI
-WriteToMemory (
- IN CHAR8 *PacketData
- )
-{
- UINTN Address;
- UINTN Length;
- UINTN MessageLength;
- CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the Address in hex chars
- CHAR8 LengthBuffer[MAX_LENGTH_SIZE]; // the buffer that will hold the Length in hex chars
- CHAR8 *AddrBufPtr; // pointer to the Address buffer
- CHAR8 *LengthBufPtr; // pointer to the Length buffer
- CHAR8 *InBufPtr; /// pointer to the input buffer
-
- AddrBufPtr = AddressBuffer;
- LengthBufPtr = LengthBuffer;
- InBufPtr = &PacketData[1];
-
- while (*InBufPtr != ',') {
- *AddrBufPtr++ = *InBufPtr++;
- }
- *AddrBufPtr = '\0';
-
- InBufPtr++; // this skips ',' in the buffer
-
- while (*InBufPtr != ':') {
- *LengthBufPtr++ = *InBufPtr++;
- }
- *LengthBufPtr = '\0';
-
- InBufPtr++; // this skips ':' in the buffer
-
- Address = AsciiStrHexToUintn (AddressBuffer);
- Length = AsciiStrHexToUintn (LengthBuffer);
-
- /* Error checking */
-
- //Check if Address is not too long.
- if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
- Print ((CHAR16 *)L"Address too long..\n");
- SendError (GDB_EBADMEMADDRBUFSIZE);
- return;
- }
-
- //Check if message length is not too long
- if (AsciiStrLen(LengthBuffer) >= MAX_LENGTH_SIZE) {
- Print ((CHAR16 *)L"Length too long..\n");
- SendError (GDB_EBADMEMLENGBUFSIZE);
- return;
- }
-
- // Check if Message is not too long/short.
- // 3 = 'M' + ',' + ':'
- MessageLength = (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - AsciiStrLen(LengthBuffer) - 3);
- if (MessageLength != (2*Length)) {
- //Message too long/short. New data is not the right size.
- SendError (GDB_EBADMEMDATASIZE);
- return;
- }
- TransferFromInBufToMem (Length, (unsigned char *)Address, InBufPtr);
-}
-
-/**
- Parses breakpoint packet data and captures Breakpoint type, Address and length.
- In case of an error, function returns particular error code. Returning 0 meaning
- no error.
-
- @param PacketData Pointer to the payload data for the packet.
- @param Type Breakpoint type
- @param Address Breakpoint address
- @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
-
- @retval 1 Success
- @retval {other} Particular error code
-
-**/
-UINTN
-ParseBreakpointPacket (
- IN CHAR8 *PacketData,
- OUT UINTN *Type,
- OUT UINTN *Address,
- OUT UINTN *Length
- )
-{
- CHAR8 AddressBuffer[MAX_ADDR_SIZE];
- CHAR8 *AddressBufferPtr;
- CHAR8 *PacketDataPtr;
-
- PacketDataPtr = &PacketData[1];
- AddressBufferPtr = AddressBuffer;
-
- *Type = AsciiStrHexToUintn (PacketDataPtr);
-
- //Breakpoint/watchpoint type should be between 0 to 4
- if (*Type > 4) {
- Print ((CHAR16 *)L"Type is invalid\n");
- return 22; //EINVAL: Invalid argument.
- }
-
- //Skip ',' in the buffer.
- while (*PacketDataPtr++ != ',');
-
- //Parse Address information
- while (*PacketDataPtr != ',') {
- *AddressBufferPtr++ = *PacketDataPtr++;
- }
- *AddressBufferPtr = '\0';
-
- //Check if Address is not too long.
- if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
- Print ((CHAR16 *)L"Address too long..\n");
- return 40; //EMSGSIZE: Message size too long.
- }
-
- *Address = AsciiStrHexToUintn (AddressBuffer);
-
- PacketDataPtr++; //This skips , in the buffer
-
- //Parse Length information
- *Length = AsciiStrHexToUintn (PacketDataPtr);
-
- //Length should be 1, 2 or 4 bytes
- if (*Length > 4) {
- Print ((CHAR16 *)L"Length is invalid\n");
- return 22; //EINVAL: Invalid argument
- }
-
- return 0; //0 = No error
-}
-
-UINTN
-gXferObjectReadResponse (
- IN CHAR8 Type,
- IN CHAR8 *Str
- )
-{
- CHAR8 *OutBufPtr; // pointer to the output buffer
- CHAR8 Char;
- UINTN Count;
-
- // responce starts with 'm' or 'l' if it is the end
- OutBufPtr = gOutBuffer;
- *OutBufPtr++ = Type;
- Count = 1;
-
- // Binary data encoding
- OutBufPtr = gOutBuffer;
- while (*Str != '\0') {
- Char = *Str++;
- if ((Char == 0x7d) || (Char == 0x23) || (Char == 0x24) || (Char == 0x2a)) {
- // escape character
- *OutBufPtr++ = 0x7d;
-
- Char ^= 0x20;
- }
- *OutBufPtr++ = Char;
- Count++;
- }
-
- *OutBufPtr = '\0' ; // the end of the buffer
- SendPacket (gOutBuffer);
-
- return Count;
-}
-
-
-/**
- Note: This should be a library function. In the Apple case you have to add
- the size of the PE/COFF header into the starting address to make things work
- right as there is no way to pad the Mach-O for the size of the PE/COFF header.
-
-
- Returns a pointer to the PDB file name for a PE/COFF image that has been
- loaded into system memory with the PE/COFF Loader Library functions.
-
- Returns the PDB file name for the PE/COFF image specified by Pe32Data. If
- the PE/COFF image specified by Pe32Data is not a valid, then NULL is
- returned. If the PE/COFF image specified by Pe32Data does not contain a
- debug directory entry, then NULL is returned. If the debug directory entry
- in the PE/COFF image specified by Pe32Data does not contain a PDB file name,
- then NULL is returned.
- If Pe32Data is NULL, then ASSERT().
-
- @param Pe32Data Pointer to the PE/COFF image that is loaded in system
- memory.
- @param DebugBase Address that the debugger would use as the base of the image
-
- @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL
- if it cannot be retrieved. DebugBase is only valid if PDB file name is
- valid.
-
-**/
-VOID *
-EFIAPI
-PeCoffLoaderGetDebuggerInfo (
- IN VOID *Pe32Data,
- OUT VOID **DebugBase
- )
-{
- EFI_IMAGE_DOS_HEADER *DosHdr;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
- EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
- EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
- UINTN DirCount;
- VOID *CodeViewEntryPointer;
- INTN TEImageAdjust;
- UINT32 NumberOfRvaAndSizes;
- UINT16 Magic;
- UINTN SizeOfHeaders;
-
- ASSERT (Pe32Data != NULL);
-
- TEImageAdjust = 0;
- DirectoryEntry = NULL;
- DebugEntry = NULL;
- NumberOfRvaAndSizes = 0;
- SizeOfHeaders = 0;
-
- DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
- //
- // DOS image header is present, so read the PE header after the DOS image header.
- //
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
- } else {
- //
- // DOS image header is not present, so PE header is at the image base.
- //
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
- }
-
- if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
- if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
- DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
- TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +
- Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
- TEImageAdjust);
- }
- SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;
-
- // __APPLE__ check this math...
- *DebugBase = ((CHAR8 *)Pe32Data) - TEImageAdjust;
- } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
-
- *DebugBase = Pe32Data;
-
-
- //
- // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.
- // It is due to backward-compatibility, for some system might
- // generate PE32+ image with PE32 Magic.
- //
- switch (Hdr.Pe32->FileHeader.Machine) {
- case EFI_IMAGE_MACHINE_IA32:
- //
- // Assume PE32 image with IA32 Machine field.
- //
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
- break;
- case EFI_IMAGE_MACHINE_X64:
- case EFI_IMAGE_MACHINE_IA64:
- //
- // Assume PE32+ image with X64 or IPF Machine field
- //
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
- break;
- default:
- //
- // For unknow Machine field, use Magic in optional Header
- //
- Magic = Hdr.Pe32->OptionalHeader.Magic;
- }
-
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
- //
- // Use PE32 offset get Debug Directory Entry
- //
- SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
- NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
- } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
- //
- // Use PE32+ offset get Debug Directory Entry
- //
- SizeOfHeaders = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
- NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
- }
-
- if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
- DirectoryEntry = NULL;
- DebugEntry = NULL;
- }
- } else {
- return NULL;
- }
-
- if (DebugEntry == NULL || DirectoryEntry == NULL) {
- return NULL;
- }
-
- for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {
- if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
- if (DebugEntry->SizeOfData > 0) {
- CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);
- switch (* (UINT32 *) CodeViewEntryPointer) {
- case CODEVIEW_SIGNATURE_NB10:
- return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));
- case CODEVIEW_SIGNATURE_RSDS:
- return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));
- case CODEVIEW_SIGNATURE_MTOC:
- *DebugBase = (VOID *)(UINTN)((UINTN)DebugBase - SizeOfHeaders);
- return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));
- default:
- break;
- }
- }
- }
- }
-
- (void)SizeOfHeaders;
- return NULL;
-}
-
-
-
-/**
- Process "qXfer:object:read:annex:offset,length" request.
-
- Returns an XML document that contains loaded libraries. In our case it is
- infomration in the EFI Debug Inmage Table converted into an XML document.
-
- GDB will call with an arbitrary length (it can't know the real length and
- will reply with chunks of XML that are easy for us to deal with. Gdb will
- keep calling until we say we are done. XML doc looks like:
-
- <library-list>
- <library name="/a/a/c/d.dSYM"><segment address="0x10000000"/></library>
- <library name="/a/m/e/e.pdb"><segment address="0x20000000"/></library>
- <library name="/a/l/f/f.dll"><segment address="0x30000000"/></library>
- </library-list>
-
- Since we can not allocate memory in interupt context this module has
- assumptions about how it will get called:
- 1) Length will generally be max remote packet size (big enough)
- 2) First Offset of an XML document read needs to be 0
- 3) This code will return back small chunks of the XML document on every read.
- Each subseqent call will ask for the next availble part of the document.
-
- Note: The only variable size element in the XML is:
- " <library name=\"%s\"><segment address=\"%p\"/></library>\n" and it is
- based on the file path and name of the symbol file. If the symbol file name
- is bigger than the max gdb remote packet size we could update this code
- to respond back in chunks.
-
- @param Offset offset into special data area
- @param Length number of bytes to read starting at Offset
-
- **/
-VOID
-QxferLibrary (
- IN UINTN Offset,
- IN UINTN Length
- )
-{
- VOID *LoadAddress;
- CHAR8 *Pdb;
- UINTN Size;
-
- if (Offset != gPacketqXferLibraryOffset) {
- SendError (GDB_EINVALIDARG);
- Print (L"\nqXferLibrary (%d, %d) != %d\n", Offset, Length, gPacketqXferLibraryOffset);
-
- // Force a retry from the beginning
- gPacketqXferLibraryOffset = 0;
- return;
- }
-
- if (Offset == 0) {
- gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', "<library-list>\n");
-
- // The owner of the table may have had to ralloc it so grab a fresh copy every time
- // we assume qXferLibrary will get called over and over again until the entire XML table is
- // returned in a tight loop. Since we are in the debugger the table should not get updated
- gDebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;
- gEfiDebugImageTableEntry = 0;
- return;
- }
-
- if (gDebugTable != NULL) {
- for (; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {
- if (gDebugTable->NormalImage != NULL) {
- if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
- (gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
- Pdb = PeCoffLoaderGetDebuggerInfo (
- gDebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase,
- &LoadAddress
- );
- if (Pdb != NULL) {
- Size = AsciiSPrint (
- gXferLibraryBuffer,
- sizeof (gXferLibraryBuffer),
- " <library name=\"%a\"><segment address=\"0x%p\"/></library>\n",
- Pdb,
- LoadAddress
- );
- if ((Size != 0) && (Size != (sizeof (gXferLibraryBuffer) - 1))) {
- gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', gXferLibraryBuffer);
-
- // Update loop variables so we are in the right place when we get back
- gEfiDebugImageTableEntry++;
- gDebugTable++;
- return;
- } else {
- // We could handle <library> entires larger than sizeof (gXferLibraryBuffer) here if
- // needed by breaking up into N packets
- // "<library name=\"%s
- // the rest of the string (as many packets as required
- // \"><segment address=\"%d\"/></library> (fixed size)
- //
- // But right now we just skip any entry that is too big
- }
- }
- }
- }
- }
- }
-
-
- gXferObjectReadResponse ('l', "</library-list>\n");
- gPacketqXferLibraryOffset = 0;
- return;
-}
-
-
-/**
- Exception Hanldler for GDB. It will be called for all exceptions
- registered via the gExceptionType[] array.
-
- @param ExceptionType Exception that is being processed
- @param SystemContext Register content at time of the exception
- **/
-VOID
-EFIAPI
-GdbExceptionHandler (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- UINT8 GdbExceptionType;
- CHAR8 *Ptr;
-
-
- if (ValidateException(ExceptionType, SystemContext) == FALSE) {
- return;
- }
-
- RemoveSingleStep (SystemContext);
-
- GdbExceptionType = ConvertEFItoGDBtype (ExceptionType);
- GdbSendTSignal (SystemContext, GdbExceptionType);
-
- for( ; ; ) {
- ReceivePacket (gInBuffer, MAX_BUF_SIZE);
-
- switch (gInBuffer[0]) {
- case '?':
- GdbSendTSignal (SystemContext, GdbExceptionType);
- break;
-
- case 'c':
- ContinueAtAddress (SystemContext, gInBuffer);
- return;
-
- case 'g':
- ReadGeneralRegisters (SystemContext);
- break;
-
- case 'G':
- WriteGeneralRegisters (SystemContext, gInBuffer);
- break;
-
- case 'H':
- //Return "OK" packet since we don't have more than one thread.
- SendSuccess ();
- break;
-
- case 'm':
- ReadFromMemory (gInBuffer);
- break;
-
- case 'M':
- WriteToMemory (gInBuffer);
- break;
-
- case 'P':
- WriteNthRegister (SystemContext, gInBuffer);
- break;
-
- //
- // Still debugging this code. Not used in Darwin
- //
- case 'q':
- // General Query Packets
- if (AsciiStrnCmp (gInBuffer, "qSupported", 10) == 0) {
- // return what we currently support, we don't parse what gdb suports
- AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "qXfer:libraries:read+;PacketSize=%d", MAX_BUF_SIZE);
- SendPacket (gOutBuffer);
- } else if (AsciiStrnCmp (gInBuffer, "qXfer:libraries:read::", 22) == 0) {
- // ‘qXfer:libraries:read::offset,length
- // gInBuffer[22] is offset string, ++Ptr is length string’
- for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++);
-
- // Not sure if multi-radix support is required. Currently only support decimal
- QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr));
- } if (AsciiStrnCmp (gInBuffer, "qOffsets", 10) == 0) {
- AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "Text=1000;Data=f000;Bss=f000");
- SendPacket (gOutBuffer);
- } else {
- //Send empty packet
- SendNotSupported ();
- }
- break;
-
- case 's':
- SingleStep (SystemContext, gInBuffer);
- return;
-
- case 'z':
- RemoveBreakPoint (SystemContext, gInBuffer);
- break;
-
- case 'Z':
- InsertBreakPoint (SystemContext, gInBuffer);
- break;
-
- default:
- //Send empty packet
- SendNotSupported ();
- break;
- }
- }
-}
-
-
-/**
- Periodic callback for GDB. This function is used to catch a ctrl-c or other
- break in type command from GDB.
-
- @param SystemContext Register content at time of the call
- **/
-VOID
-EFIAPI
-GdbPeriodicCallBack (
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- //
- // gCtrlCBreakFlag may have been set from a previous F response package
- // and we set the global as we need to process it at a point where we
- // can update the system context. If we are in the middle of processing
- // a F Packet it is not safe to read the GDB serial stream so we need
- // to skip it on this check
- //
- if (!gCtrlCBreakFlag && !gProcessingFPacket) {
- //
- // Ctrl-C was not pending so grab any pending characters and see if they
- // are a Ctrl-c (0x03). If so set the Ctrl-C global.
- //
- while (TRUE) {
- if (!GdbIsCharAvailable ()) {
- //
- // No characters are pending so exit the loop
- //
- break;
- }
-
- if (GdbGetChar () == 0x03) {
- gCtrlCBreakFlag = TRUE;
- //
- // We have a ctrl-c so exit the loop
- //
- break;
- }
- }
- }
-
- if (gCtrlCBreakFlag) {
- //
- // Update the context to force a single step trap when we exit the GDB
- // stub. This will trasfer control to GdbExceptionHandler () and let
- // us break into the program. We don't want to break into the GDB stub.
- //
- AddSingleStep (SystemContext);
- gCtrlCBreakFlag = FALSE;
- }
-}
+/** @file
+ UEFI driver that implements a GDB stub
+
+ Note: Any code in the path of the Serial IO output can not call DEBUG as will
+ will blow out the stack. Serial IO calls DEBUG, debug calls Serail IO, ...
+
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 <GdbStubInternal.h>
+#include <Protocol/DebugPort.h>
+
+
+UINTN gMaxProcessorIndex = 0;
+
+//
+// Buffers for basic gdb communication
+//
+CHAR8 gInBuffer[MAX_BUF_SIZE];
+CHAR8 gOutBuffer[MAX_BUF_SIZE];
+
+// Assume gdb does a "qXfer:libraries:read::offset,length" when it connects so we can default
+// this value to FALSE. Since gdb can reconnect its self a global default is not good enough
+BOOLEAN gSymbolTableUpdate = FALSE;
+EFI_EVENT gEvent;
+VOID *gGdbSymbolEventHandlerRegistration = NULL;
+
+//
+// Globals for returning XML from qXfer:libraries:read packet
+//
+UINTN gPacketqXferLibraryOffset = 0;
+UINTN gEfiDebugImageTableEntry = 0;
+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;
+EFI_DEBUG_IMAGE_INFO *gDebugTable = NULL;
+CHAR8 gXferLibraryBuffer[2000];
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexToStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+
+
+VOID
+EFIAPI
+GdbSymbolEventHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+}
+
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the image goes into a library that calls 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
+GdbStubEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ EFI_STATUS Status;
+ EFI_DEBUG_SUPPORT_PROTOCOL *DebugSupport;
+ UINTN HandleCount;
+ EFI_HANDLE *Handles;
+ UINTN Index;
+ UINTN Processor;
+ BOOLEAN IsaSupported;
+
+
+ Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&gDebugImageTableHeader);
+ if (EFI_ERROR (Status)) {
+ gDebugImageTableHeader = NULL;
+ }
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiDebugSupportProtocolGuid,
+ NULL,
+ &HandleCount,
+ &Handles
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Debug Support Protocol not found\n"));
+
+ return Status;
+ }
+
+ DebugSupport = NULL;
+ IsaSupported = FALSE;
+ do {
+ HandleCount--;
+ Status = gBS->HandleProtocol (
+ Handles[HandleCount],
+ &gEfiDebugSupportProtocolGuid,
+ (VOID **) &DebugSupport
+ );
+ if (!EFI_ERROR (Status)) {
+ if (CheckIsa (DebugSupport->Isa)) {
+ // We found what we are looking for so break out of the loop
+ IsaSupported = TRUE;
+ break;
+ }
+ }
+ } while (HandleCount > 0);
+ FreePool (Handles);
+
+ if (!IsaSupported) {
+ DEBUG ((EFI_D_ERROR, "Debug Support Protocol does not support our ISA\n"));
+
+ return EFI_NOT_FOUND;
+ }
+
+ Status = DebugSupport->GetMaximumProcessorIndex (DebugSupport, &gMaxProcessorIndex);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "Debug Support Protocol ISA %x\n", DebugSupport->Isa));
+ DEBUG ((EFI_D_INFO, "Debug Support Protocol Processor Index %d\n", gMaxProcessorIndex));
+
+ // Call processor-specific init routine
+ InitializeProcessor();
+
+ for (Processor = 0; Processor <= gMaxProcessorIndex; Processor++) {
+
+ for (Index = 0; Index < MaxEfiException (); Index++) {
+ Status = DebugSupport->RegisterExceptionCallback (DebugSupport, Processor, GdbExceptionHandler, gExceptionType[Index].Exception);
+ ASSERT_EFI_ERROR (Status);
+ }
+ //
+ // Current edk2 DebugPort is not interrupt context safe so we can not use it
+ //
+ Status = DebugSupport->RegisterPeriodicCallback (DebugSupport, Processor, GdbPeriodicCallBack);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // This even fires every time an image is added. This allows the stub to know when gdb needs
+ // to update the symbol table.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ GdbSymbolEventHandler,
+ NULL,
+ &gEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register for protocol notifactions on this event
+ //
+ Status = gBS->RegisterProtocolNotify (
+ &gEfiLoadedImageProtocolGuid,
+ gEvent,
+ &gGdbSymbolEventHandlerRegistration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ if (PcdGetBool (PcdGdbSerial)) {
+ GdbInitializeSerialConsole ();
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Transfer length bytes of input buffer, starting at Address, to memory.
+
+ @param length the number of the bytes to be transferred/written
+ @param *address the start address of the transferring/writing the memory
+ @param *new_data the new data to be written to memory
+ **/
+
+VOID
+TransferFromInBufToMem (
+ IN UINTN Length,
+ IN unsigned char *Address,
+ IN CHAR8 *NewData
+ )
+{
+ CHAR8 c1;
+ CHAR8 c2;
+
+ while (Length-- > 0) {
+ c1 = (CHAR8)HexCharToInt (*NewData++);
+ c2 = (CHAR8)HexCharToInt (*NewData++);
+
+ if ((c1 < 0) || (c2 < 0)) {
+ Print ((CHAR16 *)L"Bad message from write to memory..\n");
+ SendError (GDB_EBADMEMDATA);
+ return;
+ }
+ *Address++ = (UINT8)((c1 << 4) + c2);
+ }
+
+ SendSuccess();
+}
+
+
+/**
+ Transfer Length bytes of memory starting at Address to an output buffer, OutBuffer. This function will finally send the buffer
+ as a packet.
+
+ @param Length the number of the bytes to be transferred/read
+ @param *address pointer to the start address of the transferring/reading the memory
+ **/
+
+VOID
+TransferFromMemToOutBufAndSend (
+ IN UINTN Length,
+ IN unsigned char *Address
+ )
+{
+ // there are Length bytes and every byte is represented as 2 hex chars
+ CHAR8 OutBuffer[MAX_BUF_SIZE];
+ CHAR8 *OutBufPtr; // pointer to the output buffer
+ CHAR8 Char;
+
+ if (ValidateAddress(Address) == FALSE) {
+ SendError(14);
+ return;
+ }
+
+ OutBufPtr = OutBuffer;
+ while (Length > 0) {
+
+ Char = mHexToStr[*Address >> 4];
+ if ((Char >= 'A') && (Char <= 'F')) {
+ Char = Char - 'A' + 'a';
+ }
+ *OutBufPtr++ = Char;
+
+ Char = mHexToStr[*Address & 0x0f];
+ if ((Char >= 'A') && (Char <= 'F')) {
+ Char = Char - 'A' + 'a';
+ }
+ *OutBufPtr++ = Char;
+
+ Address++;
+ Length--;
+ }
+
+ *OutBufPtr = '\0' ; // the end of the buffer
+ SendPacket (OutBuffer);
+}
+
+
+
+/**
+ Send a GDB Remote Serial Protocol Packet
+
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
+ the packet teminating character '#' and the two digit checksum.
+
+ If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
+ in an infinit loop. This is so if you unplug the debugger code just keeps running
+
+ @param PacketData Payload data for the packet
+
+
+ @retval Number of bytes of packet data sent.
+
+**/
+UINTN
+SendPacket (
+ IN CHAR8 *PacketData
+ )
+{
+ UINT8 CheckSum;
+ UINTN Timeout;
+ CHAR8 *Ptr;
+ CHAR8 TestChar;
+ UINTN Count;
+
+ Timeout = PcdGet32 (PcdGdbMaxPacketRetryCount);
+
+ Count = 0;
+ do {
+
+ Ptr = PacketData;
+
+ if (Timeout-- == 0) {
+ // Only try a finite number of times so we don't get stuck in the loop
+ return Count;
+ }
+
+ // Packet prefix
+ GdbPutChar ('$');
+
+ for (CheckSum = 0, Count =0 ; *Ptr != '\0'; Ptr++, Count++) {
+ GdbPutChar (*Ptr);
+ CheckSum = CheckSum + *Ptr;
+ }
+
+ // Packet terminating character and checksum
+ GdbPutChar ('#');
+ GdbPutChar (mHexToStr[CheckSum >> 4]);
+ GdbPutChar (mHexToStr[CheckSum & 0x0F]);
+
+ TestChar = GdbGetChar ();
+ } while (TestChar != '+');
+
+ return Count;
+}
+
+/**
+ Receive a GDB Remote Serial Protocol Packet
+
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
+ the packet teminating character '#' and the two digit checksum.
+
+ If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
+ (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
+
+ If an ack '+' is not sent resend the packet
+
+ @param PacketData Payload data for the packet
+
+ @retval Number of bytes of packet data received.
+
+**/
+UINTN
+ReceivePacket (
+ OUT CHAR8 *PacketData,
+ IN UINTN PacketDataSize
+ )
+{
+ UINT8 CheckSum;
+ UINTN Index;
+ CHAR8 Char;
+ CHAR8 SumString[3];
+ CHAR8 TestChar;
+
+ ZeroMem (PacketData, PacketDataSize);
+
+ for (;;) {
+ // wait for the start of a packet
+ TestChar = GdbGetChar ();
+ while (TestChar != '$') {
+ TestChar = GdbGetChar ();
+ };
+
+ retry:
+ for (Index = 0, CheckSum = 0; Index < (PacketDataSize - 1); Index++) {
+ Char = GdbGetChar ();
+ if (Char == '$') {
+ goto retry;
+ }
+ if (Char == '#') {
+ break;
+ }
+
+ PacketData[Index] = Char;
+ CheckSum = CheckSum + Char;
+ }
+ PacketData[Index] = '\0';
+
+ if (Index == PacketDataSize) {
+ continue;
+ }
+
+ SumString[0] = GdbGetChar ();
+ SumString[1] = GdbGetChar ();
+ SumString[2] = '\0';
+
+ if (AsciiStrHexToUintn (SumString) == CheckSum) {
+ // Ack: Success
+ GdbPutChar ('+');
+
+ // Null terminate the callers string
+ PacketData[Index] = '\0';
+ return Index;
+ } else {
+ // Ack: Failure
+ GdbPutChar ('-');
+ }
+ }
+
+ //return 0;
+}
+
+
+/**
+ Empties the given buffer
+ @param Buf pointer to the first element in buffer to be emptied
+ **/
+VOID
+EmptyBuffer (
+ IN CHAR8 *Buf
+ )
+{
+ *Buf = '\0';
+}
+
+
+/**
+ Converts an 8-bit Hex Char into a INTN.
+
+ @param Char the hex character to be converted into UINTN
+ @retval a INTN, from 0 to 15, that corressponds to Char
+ -1 if Char is not a hex character
+ **/
+INTN
+HexCharToInt (
+ IN CHAR8 Char
+ )
+{
+ if ((Char >= 'A') && (Char <= 'F')) {
+ return Char - 'A' + 10;
+ } else if ((Char >= 'a') && (Char <= 'f')) {
+ return Char - 'a' + 10;
+ } else if ((Char >= '0') && (Char <= '9')) {
+ return Char - '0';
+ } else { // if not a hex value, return a negative value
+ return -1;
+ }
+}
+
+ // 'E' + the biggest error number is 255, so its 2 hex digits + buffer end
+CHAR8 *gError = "E__";
+
+/** 'E NN'
+ Send an error with the given error number after converting to hex.
+ The error number is put into the buffer in hex. '255' is the biggest errno we can send.
+ ex: 162 will be sent as A2.
+
+ @param errno the error number that will be sent
+ **/
+VOID
+EFIAPI
+SendError (
+ IN UINT8 ErrorNum
+ )
+{
+ //
+ // Replace _, or old data, with current errno
+ //
+ gError[1] = mHexToStr [ErrorNum >> 4];
+ gError[2] = mHexToStr [ErrorNum & 0x0f];
+
+ SendPacket (gError); // send buffer
+}
+
+
+
+/**
+ Send 'OK' when the function is done executing successfully.
+ **/
+VOID
+EFIAPI
+SendSuccess (
+ VOID
+ )
+{
+ SendPacket ("OK"); // send buffer
+}
+
+
+/**
+ Send empty packet to specify that particular command/functionality is not supported.
+ **/
+VOID
+EFIAPI
+SendNotSupported (
+ VOID
+ )
+{
+ SendPacket ("");
+}
+
+
+
+/**
+ Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
+
+ @param SystemContext Register content at time of the exception
+ @param GdbExceptionType GDB exception type
+ **/
+VOID
+GdbSendTSignal (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINT8 GdbExceptionType
+ )
+{
+ CHAR8 TSignalBuffer[128];
+ CHAR8 *TSignalPtr;
+ UINTN BreakpointDetected;
+ BREAK_TYPE BreakType;
+ UINTN DataAddress;
+ CHAR8 *WatchStrPtr = NULL;
+ UINTN RegSize;
+
+ TSignalPtr = &TSignalBuffer[0];
+
+ //Construct TSignal packet
+ *TSignalPtr++ = 'T';
+
+ //
+ // replace _, or previous value, with Exception type
+ //
+ *TSignalPtr++ = mHexToStr [GdbExceptionType >> 4];
+ *TSignalPtr++ = mHexToStr [GdbExceptionType & 0x0f];
+
+ if (GdbExceptionType == GDB_SIGTRAP) {
+ if (gSymbolTableUpdate) {
+ //
+ // We can only send back on reason code. So if the flag is set it means the breakpoint is from our event handler
+ //
+ WatchStrPtr = "library:;";
+ while (*WatchStrPtr != '\0') {
+ *TSignalPtr++ = *WatchStrPtr++;
+ }
+ gSymbolTableUpdate = FALSE;
+ } else {
+
+
+ //
+ // possible n:r pairs
+ //
+
+ //Retrieve the breakpoint number
+ BreakpointDetected = GetBreakpointDetected (SystemContext);
+
+ //Figure out if the exception is happend due to watch, rwatch or awatch.
+ BreakType = GetBreakpointType (SystemContext, BreakpointDetected);
+
+ //INFO: rwatch is not supported due to the way IA32 debug registers work
+ if ((BreakType == DataWrite) || (BreakType == DataRead) || (BreakType == DataReadWrite)) {
+
+ //Construct n:r pair
+ DataAddress = GetBreakpointDataAddress (SystemContext, BreakpointDetected);
+
+ //Assign appropriate buffer to print particular watchpoint type
+ if (BreakType == DataWrite) {
+ WatchStrPtr = "watch";
+ } else if (BreakType == DataRead) {
+ WatchStrPtr = "rwatch";
+ } else if (BreakType == DataReadWrite) {
+ WatchStrPtr = "awatch";
+ }
+
+ while (*WatchStrPtr != '\0') {
+ *TSignalPtr++ = *WatchStrPtr++;
+ }
+
+ *TSignalPtr++ = ':';
+
+ //Set up series of bytes in big-endian byte order. "awatch" won't work with little-endian byte order.
+ RegSize = REG_SIZE;
+ while (RegSize > 0) {
+ RegSize = RegSize-4;
+ *TSignalPtr++ = mHexToStr[(UINT8)(DataAddress >> RegSize) & 0xf];
+ }
+
+ //Always end n:r pair with ';'
+ *TSignalPtr++ = ';';
+ }
+ }
+ }
+
+ *TSignalPtr = '\0';
+
+ SendPacket (TSignalBuffer);
+}
+
+
+/**
+ Translates the EFI mapping to GDB mapping
+
+ @param EFIExceptionType EFI Exception that is being processed
+ @retval UINTN that corresponds to EFIExceptionType's GDB exception type number
+ **/
+UINT8
+ConvertEFItoGDBtype (
+ IN EFI_EXCEPTION_TYPE EFIExceptionType
+ )
+{
+ UINTN i;
+
+ for (i=0; i < MaxEfiException() ; i++) {
+ if (gExceptionType[i].Exception == EFIExceptionType) {
+ return gExceptionType[i].SignalNo;
+ }
+ }
+ return GDB_SIGTRAP; // this is a GDB trap
+}
+
+
+/** "m addr,length"
+ Find the Length of the area to read and the start addres. Finally, pass them to
+ another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
+ send it as a packet.
+ **/
+
+VOID
+EFIAPI
+ReadFromMemory (
+ CHAR8 *PacketData
+ )
+{
+ UINTN Address;
+ UINTN Length;
+ CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the address in hex chars
+ CHAR8 *AddrBufPtr; // pointer to the address buffer
+ CHAR8 *InBufPtr; /// pointer to the input buffer
+
+ AddrBufPtr = AddressBuffer;
+ InBufPtr = &PacketData[1];
+ while (*InBufPtr != ',') {
+ *AddrBufPtr++ = *InBufPtr++;
+ }
+ *AddrBufPtr = '\0';
+
+ InBufPtr++; // this skips ',' in the buffer
+
+ /* Error checking */
+ if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
+ Print((CHAR16 *)L"Address is too long\n");
+ SendError (GDB_EBADMEMADDRBUFSIZE);
+ return;
+ }
+
+ // 2 = 'm' + ','
+ if (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - 2 >= MAX_LENGTH_SIZE) {
+ Print((CHAR16 *)L"Length is too long\n");
+ SendError (GDB_EBADMEMLENGTH);
+ return;
+ }
+
+ Address = AsciiStrHexToUintn (AddressBuffer);
+ Length = AsciiStrHexToUintn (InBufPtr);
+
+ TransferFromMemToOutBufAndSend (Length, (unsigned char *)Address);
+}
+
+
+/** "M addr,length :XX..."
+ Find the Length of the area in bytes to write and the start addres. Finally, pass them to
+ another function, TransferFromInBufToMem, that will write to that memory space the info in
+ the input buffer.
+ **/
+VOID
+EFIAPI
+WriteToMemory (
+ IN CHAR8 *PacketData
+ )
+{
+ UINTN Address;
+ UINTN Length;
+ UINTN MessageLength;
+ CHAR8 AddressBuffer[MAX_ADDR_SIZE]; // the buffer that will hold the Address in hex chars
+ CHAR8 LengthBuffer[MAX_LENGTH_SIZE]; // the buffer that will hold the Length in hex chars
+ CHAR8 *AddrBufPtr; // pointer to the Address buffer
+ CHAR8 *LengthBufPtr; // pointer to the Length buffer
+ CHAR8 *InBufPtr; /// pointer to the input buffer
+
+ AddrBufPtr = AddressBuffer;
+ LengthBufPtr = LengthBuffer;
+ InBufPtr = &PacketData[1];
+
+ while (*InBufPtr != ',') {
+ *AddrBufPtr++ = *InBufPtr++;
+ }
+ *AddrBufPtr = '\0';
+
+ InBufPtr++; // this skips ',' in the buffer
+
+ while (*InBufPtr != ':') {
+ *LengthBufPtr++ = *InBufPtr++;
+ }
+ *LengthBufPtr = '\0';
+
+ InBufPtr++; // this skips ':' in the buffer
+
+ Address = AsciiStrHexToUintn (AddressBuffer);
+ Length = AsciiStrHexToUintn (LengthBuffer);
+
+ /* Error checking */
+
+ //Check if Address is not too long.
+ if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
+ Print ((CHAR16 *)L"Address too long..\n");
+ SendError (GDB_EBADMEMADDRBUFSIZE);
+ return;
+ }
+
+ //Check if message length is not too long
+ if (AsciiStrLen(LengthBuffer) >= MAX_LENGTH_SIZE) {
+ Print ((CHAR16 *)L"Length too long..\n");
+ SendError (GDB_EBADMEMLENGBUFSIZE);
+ return;
+ }
+
+ // Check if Message is not too long/short.
+ // 3 = 'M' + ',' + ':'
+ MessageLength = (AsciiStrLen(PacketData) - AsciiStrLen(AddressBuffer) - AsciiStrLen(LengthBuffer) - 3);
+ if (MessageLength != (2*Length)) {
+ //Message too long/short. New data is not the right size.
+ SendError (GDB_EBADMEMDATASIZE);
+ return;
+ }
+ TransferFromInBufToMem (Length, (unsigned char *)Address, InBufPtr);
+}
+
+/**
+ Parses breakpoint packet data and captures Breakpoint type, Address and length.
+ In case of an error, function returns particular error code. Returning 0 meaning
+ no error.
+
+ @param PacketData Pointer to the payload data for the packet.
+ @param Type Breakpoint type
+ @param Address Breakpoint address
+ @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
+
+ @retval 1 Success
+ @retval {other} Particular error code
+
+**/
+UINTN
+ParseBreakpointPacket (
+ IN CHAR8 *PacketData,
+ OUT UINTN *Type,
+ OUT UINTN *Address,
+ OUT UINTN *Length
+ )
+{
+ CHAR8 AddressBuffer[MAX_ADDR_SIZE];
+ CHAR8 *AddressBufferPtr;
+ CHAR8 *PacketDataPtr;
+
+ PacketDataPtr = &PacketData[1];
+ AddressBufferPtr = AddressBuffer;
+
+ *Type = AsciiStrHexToUintn (PacketDataPtr);
+
+ //Breakpoint/watchpoint type should be between 0 to 4
+ if (*Type > 4) {
+ Print ((CHAR16 *)L"Type is invalid\n");
+ return 22; //EINVAL: Invalid argument.
+ }
+
+ //Skip ',' in the buffer.
+ while (*PacketDataPtr++ != ',');
+
+ //Parse Address information
+ while (*PacketDataPtr != ',') {
+ *AddressBufferPtr++ = *PacketDataPtr++;
+ }
+ *AddressBufferPtr = '\0';
+
+ //Check if Address is not too long.
+ if (AsciiStrLen(AddressBuffer) >= MAX_ADDR_SIZE) {
+ Print ((CHAR16 *)L"Address too long..\n");
+ return 40; //EMSGSIZE: Message size too long.
+ }
+
+ *Address = AsciiStrHexToUintn (AddressBuffer);
+
+ PacketDataPtr++; //This skips , in the buffer
+
+ //Parse Length information
+ *Length = AsciiStrHexToUintn (PacketDataPtr);
+
+ //Length should be 1, 2 or 4 bytes
+ if (*Length > 4) {
+ Print ((CHAR16 *)L"Length is invalid\n");
+ return 22; //EINVAL: Invalid argument
+ }
+
+ return 0; //0 = No error
+}
+
+UINTN
+gXferObjectReadResponse (
+ IN CHAR8 Type,
+ IN CHAR8 *Str
+ )
+{
+ CHAR8 *OutBufPtr; // pointer to the output buffer
+ CHAR8 Char;
+ UINTN Count;
+
+ // responce starts with 'm' or 'l' if it is the end
+ OutBufPtr = gOutBuffer;
+ *OutBufPtr++ = Type;
+ Count = 1;
+
+ // Binary data encoding
+ OutBufPtr = gOutBuffer;
+ while (*Str != '\0') {
+ Char = *Str++;
+ if ((Char == 0x7d) || (Char == 0x23) || (Char == 0x24) || (Char == 0x2a)) {
+ // escape character
+ *OutBufPtr++ = 0x7d;
+
+ Char ^= 0x20;
+ }
+ *OutBufPtr++ = Char;
+ Count++;
+ }
+
+ *OutBufPtr = '\0' ; // the end of the buffer
+ SendPacket (gOutBuffer);
+
+ return Count;
+}
+
+
+/**
+ Note: This should be a library function. In the Apple case you have to add
+ the size of the PE/COFF header into the starting address to make things work
+ right as there is no way to pad the Mach-O for the size of the PE/COFF header.
+
+
+ Returns a pointer to the PDB file name for a PE/COFF image that has been
+ loaded into system memory with the PE/COFF Loader Library functions.
+
+ Returns the PDB file name for the PE/COFF image specified by Pe32Data. If
+ the PE/COFF image specified by Pe32Data is not a valid, then NULL is
+ returned. If the PE/COFF image specified by Pe32Data does not contain a
+ debug directory entry, then NULL is returned. If the debug directory entry
+ in the PE/COFF image specified by Pe32Data does not contain a PDB file name,
+ then NULL is returned.
+ If Pe32Data is NULL, then ASSERT().
+
+ @param Pe32Data Pointer to the PE/COFF image that is loaded in system
+ memory.
+ @param DebugBase Address that the debugger would use as the base of the image
+
+ @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL
+ if it cannot be retrieved. DebugBase is only valid if PDB file name is
+ valid.
+
+**/
+VOID *
+EFIAPI
+PeCoffLoaderGetDebuggerInfo (
+ IN VOID *Pe32Data,
+ OUT VOID **DebugBase
+ )
+{
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ UINTN DirCount;
+ VOID *CodeViewEntryPointer;
+ INTN TEImageAdjust;
+ UINT32 NumberOfRvaAndSizes;
+ UINT16 Magic;
+ UINTN SizeOfHeaders;
+
+ ASSERT (Pe32Data != NULL);
+
+ TEImageAdjust = 0;
+ DirectoryEntry = NULL;
+ DebugEntry = NULL;
+ NumberOfRvaAndSizes = 0;
+ SizeOfHeaders = 0;
+
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header.
+ //
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base.
+ //
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
+ }
+
+ if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
+ DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +
+ Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
+ TEImageAdjust);
+ }
+ SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;
+
+ // __APPLE__ check this math...
+ *DebugBase = ((CHAR8 *)Pe32Data) - TEImageAdjust;
+ } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
+
+ *DebugBase = Pe32Data;
+
+
+ //
+ // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.
+ // It is due to backward-compatibility, for some system might
+ // generate PE32+ image with PE32 Magic.
+ //
+ switch (Hdr.Pe32->FileHeader.Machine) {
+ case EFI_IMAGE_MACHINE_IA32:
+ //
+ // Assume PE32 image with IA32 Machine field.
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ break;
+ case EFI_IMAGE_MACHINE_X64:
+ case EFI_IMAGE_MACHINE_IA64:
+ //
+ // Assume PE32+ image with X64 or IPF Machine field
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+ default:
+ //
+ // For unknow Machine field, use Magic in optional Header
+ //
+ Magic = Hdr.Pe32->OptionalHeader.Magic;
+ }
+
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset get Debug Directory Entry
+ //
+ SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
+ } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ //
+ // Use PE32+ offset get Debug Directory Entry
+ //
+ SizeOfHeaders = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);
+ }
+
+ if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ DirectoryEntry = NULL;
+ DebugEntry = NULL;
+ }
+ } else {
+ return NULL;
+ }
+
+ if (DebugEntry == NULL || DirectoryEntry == NULL) {
+ return NULL;
+ }
+
+ for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ if (DebugEntry->SizeOfData > 0) {
+ CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);
+ switch (* (UINT32 *) CodeViewEntryPointer) {
+ case CODEVIEW_SIGNATURE_NB10:
+ return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));
+ case CODEVIEW_SIGNATURE_RSDS:
+ return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));
+ case CODEVIEW_SIGNATURE_MTOC:
+ *DebugBase = (VOID *)(UINTN)((UINTN)DebugBase - SizeOfHeaders);
+ return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ (void)SizeOfHeaders;
+ return NULL;
+}
+
+
+
+/**
+ Process "qXfer:object:read:annex:offset,length" request.
+
+ Returns an XML document that contains loaded libraries. In our case it is
+ infomration in the EFI Debug Inmage Table converted into an XML document.
+
+ GDB will call with an arbitrary length (it can't know the real length and
+ will reply with chunks of XML that are easy for us to deal with. Gdb will
+ keep calling until we say we are done. XML doc looks like:
+
+ <library-list>
+ <library name="/a/a/c/d.dSYM"><segment address="0x10000000"/></library>
+ <library name="/a/m/e/e.pdb"><segment address="0x20000000"/></library>
+ <library name="/a/l/f/f.dll"><segment address="0x30000000"/></library>
+ </library-list>
+
+ Since we can not allocate memory in interupt context this module has
+ assumptions about how it will get called:
+ 1) Length will generally be max remote packet size (big enough)
+ 2) First Offset of an XML document read needs to be 0
+ 3) This code will return back small chunks of the XML document on every read.
+ Each subseqent call will ask for the next availble part of the document.
+
+ Note: The only variable size element in the XML is:
+ " <library name=\"%s\"><segment address=\"%p\"/></library>\n" and it is
+ based on the file path and name of the symbol file. If the symbol file name
+ is bigger than the max gdb remote packet size we could update this code
+ to respond back in chunks.
+
+ @param Offset offset into special data area
+ @param Length number of bytes to read starting at Offset
+
+ **/
+VOID
+QxferLibrary (
+ IN UINTN Offset,
+ IN UINTN Length
+ )
+{
+ VOID *LoadAddress;
+ CHAR8 *Pdb;
+ UINTN Size;
+
+ if (Offset != gPacketqXferLibraryOffset) {
+ SendError (GDB_EINVALIDARG);
+ Print (L"\nqXferLibrary (%d, %d) != %d\n", Offset, Length, gPacketqXferLibraryOffset);
+
+ // Force a retry from the beginning
+ gPacketqXferLibraryOffset = 0;
+ return;
+ }
+
+ if (Offset == 0) {
+ gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', "<library-list>\n");
+
+ // The owner of the table may have had to ralloc it so grab a fresh copy every time
+ // we assume qXferLibrary will get called over and over again until the entire XML table is
+ // returned in a tight loop. Since we are in the debugger the table should not get updated
+ gDebugTable = gDebugImageTableHeader->EfiDebugImageInfoTable;
+ gEfiDebugImageTableEntry = 0;
+ return;
+ }
+
+ if (gDebugTable != NULL) {
+ for (; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {
+ if (gDebugTable->NormalImage != NULL) {
+ if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
+ (gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
+ Pdb = PeCoffLoaderGetDebuggerInfo (
+ gDebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase,
+ &LoadAddress
+ );
+ if (Pdb != NULL) {
+ Size = AsciiSPrint (
+ gXferLibraryBuffer,
+ sizeof (gXferLibraryBuffer),
+ " <library name=\"%a\"><segment address=\"0x%p\"/></library>\n",
+ Pdb,
+ LoadAddress
+ );
+ if ((Size != 0) && (Size != (sizeof (gXferLibraryBuffer) - 1))) {
+ gPacketqXferLibraryOffset += gXferObjectReadResponse ('m', gXferLibraryBuffer);
+
+ // Update loop variables so we are in the right place when we get back
+ gEfiDebugImageTableEntry++;
+ gDebugTable++;
+ return;
+ } else {
+ // We could handle <library> entires larger than sizeof (gXferLibraryBuffer) here if
+ // needed by breaking up into N packets
+ // "<library name=\"%s
+ // the rest of the string (as many packets as required
+ // \"><segment address=\"%d\"/></library> (fixed size)
+ //
+ // But right now we just skip any entry that is too big
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ gXferObjectReadResponse ('l', "</library-list>\n");
+ gPacketqXferLibraryOffset = 0;
+ return;
+}
+
+
+/**
+ Exception Hanldler for GDB. It will be called for all exceptions
+ registered via the gExceptionType[] array.
+
+ @param ExceptionType Exception that is being processed
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+EFIAPI
+GdbExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ UINT8 GdbExceptionType;
+ CHAR8 *Ptr;
+
+
+ if (ValidateException(ExceptionType, SystemContext) == FALSE) {
+ return;
+ }
+
+ RemoveSingleStep (SystemContext);
+
+ GdbExceptionType = ConvertEFItoGDBtype (ExceptionType);
+ GdbSendTSignal (SystemContext, GdbExceptionType);
+
+ for( ; ; ) {
+ ReceivePacket (gInBuffer, MAX_BUF_SIZE);
+
+ switch (gInBuffer[0]) {
+ case '?':
+ GdbSendTSignal (SystemContext, GdbExceptionType);
+ break;
+
+ case 'c':
+ ContinueAtAddress (SystemContext, gInBuffer);
+ return;
+
+ case 'g':
+ ReadGeneralRegisters (SystemContext);
+ break;
+
+ case 'G':
+ WriteGeneralRegisters (SystemContext, gInBuffer);
+ break;
+
+ case 'H':
+ //Return "OK" packet since we don't have more than one thread.
+ SendSuccess ();
+ break;
+
+ case 'm':
+ ReadFromMemory (gInBuffer);
+ break;
+
+ case 'M':
+ WriteToMemory (gInBuffer);
+ break;
+
+ case 'P':
+ WriteNthRegister (SystemContext, gInBuffer);
+ break;
+
+ //
+ // Still debugging this code. Not used in Darwin
+ //
+ case 'q':
+ // General Query Packets
+ if (AsciiStrnCmp (gInBuffer, "qSupported", 10) == 0) {
+ // return what we currently support, we don't parse what gdb suports
+ AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "qXfer:libraries:read+;PacketSize=%d", MAX_BUF_SIZE);
+ SendPacket (gOutBuffer);
+ } else if (AsciiStrnCmp (gInBuffer, "qXfer:libraries:read::", 22) == 0) {
+ // ‘qXfer:libraries:read::offset,length
+ // gInBuffer[22] is offset string, ++Ptr is length string’
+ for (Ptr = &gInBuffer[22]; *Ptr != ','; Ptr++);
+
+ // Not sure if multi-radix support is required. Currently only support decimal
+ QxferLibrary (AsciiStrHexToUintn (&gInBuffer[22]), AsciiStrHexToUintn (++Ptr));
+ } if (AsciiStrnCmp (gInBuffer, "qOffsets", 10) == 0) {
+ AsciiSPrint (gOutBuffer, MAX_BUF_SIZE, "Text=1000;Data=f000;Bss=f000");
+ SendPacket (gOutBuffer);
+ } else {
+ //Send empty packet
+ SendNotSupported ();
+ }
+ break;
+
+ case 's':
+ SingleStep (SystemContext, gInBuffer);
+ return;
+
+ case 'z':
+ RemoveBreakPoint (SystemContext, gInBuffer);
+ break;
+
+ case 'Z':
+ InsertBreakPoint (SystemContext, gInBuffer);
+ break;
+
+ default:
+ //Send empty packet
+ SendNotSupported ();
+ break;
+ }
+ }
+}
+
+
+/**
+ Periodic callback for GDB. This function is used to catch a ctrl-c or other
+ break in type command from GDB.
+
+ @param SystemContext Register content at time of the call
+ **/
+VOID
+EFIAPI
+GdbPeriodicCallBack (
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ //
+ // gCtrlCBreakFlag may have been set from a previous F response package
+ // and we set the global as we need to process it at a point where we
+ // can update the system context. If we are in the middle of processing
+ // a F Packet it is not safe to read the GDB serial stream so we need
+ // to skip it on this check
+ //
+ if (!gCtrlCBreakFlag && !gProcessingFPacket) {
+ //
+ // Ctrl-C was not pending so grab any pending characters and see if they
+ // are a Ctrl-c (0x03). If so set the Ctrl-C global.
+ //
+ while (TRUE) {
+ if (!GdbIsCharAvailable ()) {
+ //
+ // No characters are pending so exit the loop
+ //
+ break;
+ }
+
+ if (GdbGetChar () == 0x03) {
+ gCtrlCBreakFlag = TRUE;
+ //
+ // We have a ctrl-c so exit the loop
+ //
+ break;
+ }
+ }
+ }
+
+ if (gCtrlCBreakFlag) {
+ //
+ // Update the context to force a single step trap when we exit the GDB
+ // stub. This will trasfer control to GdbExceptionHandler () and let
+ // us break into the program. We don't want to break into the GDB stub.
+ //
+ AddSingleStep (SystemContext);
+ gCtrlCBreakFlag = FALSE;
+ }
+}
diff --git a/EmbeddedPkg/GdbStub/GdbStubInternal.h b/EmbeddedPkg/GdbStub/GdbStubInternal.h
index ac04d7b9a5..5f15420f02 100644
--- a/EmbeddedPkg/GdbStub/GdbStubInternal.h
+++ b/EmbeddedPkg/GdbStub/GdbStubInternal.h
@@ -1,746 +1,746 @@
-/** @file
- Private include file for GDB stub
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __GDB_STUB_INTERNAL__
-#define __GDB_STUB_INTERNAL__
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/PcdLib.h>
-#include <Library/GdbSerialLib.h>
-#include <Library/PrintLib.h>
-
-#include <Protocol/DebugSupport.h>
-#include <Protocol/SerialIo.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/LoadedImage.h>
-#include <Guid/DebugImageInfoTable.h>
-#include <IndustryStandard/PeImage.h>
-
-extern CONST CHAR8 mHexToStr[];
-
-// maximum size of input and output buffers
-// This value came from the show remote command of the gdb we tested against
-#define MAX_BUF_SIZE 2000
-
-// maximum size of address buffer
-#define MAX_ADDR_SIZE 32
-
-// maximum size of register number buffer
-#define MAX_REG_NUM_BUF_SIZE 32
-
-// maximum size of length buffer
-#define MAX_LENGTH_SIZE 32
-
-// maximum size of T signal members
-#define MAX_T_SIGNAL_SIZE 64
-
-// the mask used to clear all the cache
-#define TF_BIT 0x00000100
-
-
-//
-// GDB Signal definitions - generic names for interrupts
-//
-#define GDB_SIGILL 4 // Illegal instruction
-#define GDB_SIGTRAP 5 // Trace Trap (Breakpoint and SingleStep)
-#define GDB_SIGEMT 7 // Emulator Trap
-#define GDB_SIGFPE 8 // Floating point exception
-#define GDB_SIGSEGV 11 // Setgment violation, page fault
-
-
-//
-// GDB File I/O Error values, zero means no error
-// Includes all general GDB Unix like error values
-//
-#define GDB_EBADMEMADDRBUFSIZE 11 // the buffer that stores memory Address to be read from/written to is not the right size
-#define GDB_EBADMEMLENGBUFSIZE 12 // the buffer that stores Length is not the right size
-#define GDB_EBADMEMLENGTH 13 // Length, the given number of bytes to read or write, is not the right size
-#define GDB_EBADMEMDATA 14 // one of the bytes or nibbles of the memory is leess than 0
-#define GDB_EBADMEMDATASIZE 15 // the memory data, 'XX..', is too short or too long
-#define GDB_EBADBUFSIZE 21 // the buffer created is not the correct size
-#define GDB_EINVALIDARG 31 // argument is invalid
-#define GDB_ENOSPACE 41 //
-#define GDB_EINVALIDBRKPOINTTYPE 51 // the breakpoint type is not recognized
-#define GDB_EINVALIDREGNUM 61 // given register number is not valid: either <0 or >=Number of Registers
-#define GDB_EUNKNOWN 255 // unknown
-
-
-//
-// These devices are open by GDB so we can just read and write to them
-//
-#define GDB_STDIN 0x00
-#define GDB_STDOUT 0x01
-#define GDB_STDERR 0x02
-
-//
-//Define Register size for different architectures
-//
-#if defined (MDE_CPU_IA32)
-#define REG_SIZE 32
-#elif defined (MDE_CPU_X64)
-#define REG_SIZE 64
-#elif defined (MDE_CPU_ARM)
-#define REG_SIZE 32
-#endif
-
-#define GDB_SERIAL_DEV_SIGNATURE SIGNATURE_32 ('g', 'd', 'b', 's')
-
-typedef struct {
- VENDOR_DEVICE_PATH VendorDevice;
- UINT32 Index; // Suport more than one
- EFI_DEVICE_PATH_PROTOCOL End;
-} GDB_SERIAL_DEVICE_PATH;
-
-//
-// Name: SERIAL_DEV
-// Purpose: To provide device specific information
-// Fields:
-// Signature UINTN: The identity of the serial device
-// SerialIo SERIAL_IO_PROTOCOL: Serial I/O protocol interface
-// SerialMode SERIAL_IO_MODE:
-// DevicePath EFI_DEVICE_PATH_PROTOCOL *: Device path of the serial device
-//
-typedef struct {
- UINTN Signature;
- EFI_HANDLE Handle;
- EFI_SERIAL_IO_PROTOCOL SerialIo;
- EFI_SERIAL_IO_MODE SerialMode;
- GDB_SERIAL_DEVICE_PATH DevicePath;
- INTN InFileDescriptor;
- INTN OutFileDescriptor;
-} GDB_SERIAL_DEV;
-
-
-#define GDB_SERIAL_DEV_FROM_THIS(a) CR (a, GDB_SERIAL_DEV, SerialIo, GDB_SERIAL_DEV_SIGNATURE)
-
-
-typedef struct {
- EFI_EXCEPTION_TYPE Exception;
- UINT8 SignalNo;
-} EFI_EXCEPTION_TYPE_ENTRY;
-
-
-#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
-
-//
-// Byte packed structure for DR6
-// 32-bits on IA-32
-// 64-bits on X64. The upper 32-bits on X64 are reserved
-//
-typedef union {
- struct {
- UINT32 B0:1; // Breakpoint condition detected
- UINT32 B1:1; // Breakpoint condition detected
- UINT32 B2:1; // Breakpoint condition detected
- UINT32 B3:1; // Breakpoint condition detected
- UINT32 Reserved_1:9; // Reserved
- UINT32 BD:1; // Debug register access detected
- UINT32 BS:1; // Single step
- UINT32 BT:1; // Task switch
- UINT32 Reserved_2:16; // Reserved
- } Bits;
- UINTN UintN;
-} IA32_DR6;
-
-//
-// Byte packed structure for DR7
-// 32-bits on IA-32
-// 64-bits on X64. The upper 32-bits on X64 are reserved
-//
-typedef union {
- struct {
- UINT32 L0:1; // Local breakpoint enable
- UINT32 G0:1; // Global breakpoint enable
- UINT32 L1:1; // Local breakpoint enable
- UINT32 G1:1; // Global breakpoint enable
- UINT32 L2:1; // Local breakpoint enable
- UINT32 G2:1; // Global breakpoint enable
- UINT32 L3:1; // Local breakpoint enable
- UINT32 G3:1; // Global breakpoint enable
- UINT32 LE:1; // Local exact breakpoint enable
- UINT32 GE:1; // Global exact breakpoint enable
- UINT32 Reserved_1:3; // Reserved
- UINT32 GD:1; // Global detect enable
- UINT32 Reserved_2:2; // Reserved
- UINT32 RW0:2; // Read/Write field
- UINT32 LEN0:2; // Length field
- UINT32 RW1:2; // Read/Write field
- UINT32 LEN1:2; // Length field
- UINT32 RW2:2; // Read/Write field
- UINT32 LEN2:2; // Length field
- UINT32 RW3:2; // Read/Write field
- UINT32 LEN3:2; // Length field
- } Bits;
- UINTN UintN;
-} IA32_DR7;
-
-#endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */
-
-typedef enum {
- InstructionExecution, //Hardware breakpoint
- DataWrite, //watch
- DataRead, //rwatch
- DataReadWrite, //awatch
- SoftwareBreakpoint, //Software breakpoint
- NotSupported
-} BREAK_TYPE;
-
-//
-// Array of exception types that need to be hooked by the debugger
-//
-extern EFI_EXCEPTION_TYPE_ENTRY gExceptionType[];
-
-//
-// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
-// here we need to wait for the periodic callback to do this.
-//
-extern BOOLEAN gCtrlCBreakFlag;
-
-//
-// If the periodic callback is called while we are processing an F packet we need
-// to let the callback know to not read from the serail stream as it could steal
-// characters from the F reponse packet
-//
-extern BOOLEAN gProcessingFPacket;
-
-
-// The offsets of registers SystemContext.
-// The fields in the array are in the gdb ordering.
-//
-extern UINTN gRegisterOffsets[];
-
-/**
- Return the number of entries in the gExceptionType[]
-
- @retval UINTN, the number of entries in the gExceptionType[] array.
- **/
-UINTN
-MaxEfiException (
- VOID
- );
-
-
-/**
- Return the number of entries in the gRegisters[]
-
- @retval UINTN, the number of entries (registers) in the gRegisters[] array.
- **/
-UINTN
-MaxRegisterCount (
- VOID
- );
-
-
-/**
- Check to see if the ISA is supported.
- ISA = Instruction Set Architecture
-
- @retval TRUE if Isa is supported,
- FALSE otherwise.
- **/
-BOOLEAN
-CheckIsa (
- IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
- );
-
-
-/**
- Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
-
- @param SystemContext Register content at time of the exception
- @param GdbExceptionType GDB exception type
- **/
-
-VOID
-GdbSendTSignal (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINT8 GdbExceptionType
- );
-
-
-/**
- Translates the EFI mapping to GDB mapping
-
- @param EFIExceptionType EFI Exception that is being processed
- @retval UINTN that corresponds to EFIExceptionType's GDB exception type number
- **/
-UINT8
-ConvertEFItoGDBtype (
- IN EFI_EXCEPTION_TYPE EFIExceptionType
- );
-
-
-/**
- Empties the given buffer
- @param *Buf pointer to the first element in buffer to be emptied
- **/
-VOID
-EmptyBuffer (
- IN CHAR8 *Buf
- );
-
-
-/**
- Converts an 8-bit Hex Char into a INTN.
-
- @param Char - the hex character to be converted into UINTN
- @retval a INTN, from 0 to 15, that corressponds to Char
- -1 if Char is not a hex character
- **/
-INTN
-HexCharToInt (
- IN CHAR8 Char
- );
-
-
-/** 'E NN'
- Send an error with the given error number after converting to hex.
- The error number is put into the buffer in hex. '255' is the biggest errno we can send.
- ex: 162 will be sent as A2.
-
- @param errno the error number that will be sent
- **/
-VOID
-EFIAPI
-SendError (
- IN UINT8 ErrorNum
- );
-
-
-/**
- Send 'OK' when the function is done executing successfully.
- **/
-VOID
-SendSuccess (
- VOID
- );
-
-
-/**
- Send empty packet to specify that particular command/functionality is not supported.
- **/
-VOID
-SendNotSupported (
- VOID
- );
-
-/** ‘p n’
- Reads the n-th register's value into an output buffer and sends it as a packet
- @param SystemContext Register content at time of the exception
- @param InBuffer This is the input buffer received from gdb server
- **/
-VOID
-ReadNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘g’
- Reads the general registers into an output buffer and sends it as a packet
- @param SystemContext Register content at time of the exception
- **/
-VOID
-ReadGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/** ‘P n...=r...’
- Writes the new value of n-th register received into the input buffer to the n-th register
- @param SystemContext Register content at time of the exception
- @param InBuffer This is the input buffer received from gdb server
- **/
-VOID
-WriteNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘G XX...’
- Writes the new values received into the input buffer to the general registers
- @param SystemContext Register content at time of the exception
- @param InBuffer Pointer to the input buffer received from gdb server
- **/
-
-VOID
-WriteGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘m addr,length ’
- Find the Length of the area to read and the start addres. Finally, pass them to
- another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
- send it as a packet.
-
- @param *PacketData Pointer to Payload data for the packet
- **/
-VOID
-ReadFromMemory (
- IN CHAR8 *PacketData
- );
-
-
-/** ‘M addr,length :XX...’
- Find the Length of the area in bytes to write and the start addres. Finally, pass them to
- another function, TransferFromInBufToMem, that will write to that memory space the info in
- the input buffer.
-
- @param PacketData Pointer to Payload data for the packet
- **/
-VOID
-WriteToMemory (
- IN CHAR8 *PacketData
- );
-
-
-/** ‘c [addr ]’
- Continue. addr is Address to resume. If addr is omitted, resume at current
- Address.
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to PacketData
- **/
-
-VOID
-ContinueAtAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/** ‘s [addr ]’
- Single step. addr is the Address at which to resume. If addr is omitted, resume
- at same Address.
-
- @param SystemContext Register content at time of the exception
- @param PacketData Pointer to Payload data for the packet
- **/
-VOID
-SingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-/**
- Insert Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-AddSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-/**
- Remove Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-RemoveSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- ‘Z1, [addr], [length]’
- ‘Z2, [addr], [length]’
- ‘Z3, [addr], [length]’
- ‘Z4, [addr], [length]’
-
- Insert hardware breakpoint/watchpoint at address addr of size length
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-InsertBreakPoint(
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/**
- ‘z1, [addr], [length]’
- ‘z2, [addr], [length]’
- ‘z3, [addr], [length]’
- ‘z4, [addr], [length]’
-
- Remove hardware breakpoint/watchpoint at address addr of size length
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-RemoveBreakPoint(
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/**
- Exception Hanldler for GDB. It will be called for all exceptions
- registered via the gExceptionType[] array.
-
- @param ExceptionType Exception that is being processed
- @param SystemContext Register content at time of the exception
-
- **/
-VOID
-EFIAPI
-GdbExceptionHandler (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- Periodic callback for GDB. This function is used to catch a ctrl-c or other
- break in type command from GDB.
-
- @param SystemContext Register content at time of the call
-
- **/
-VOID
-EFIAPI
-GdbPeriodicCallBack (
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- Make two serail consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
-
- These console show up on the remote system running GDB
-
-**/
-
-VOID
-GdbInitializeSerialConsole (
- VOID
- );
-
-
-/**
- Send a GDB Remote Serial Protocol Packet
-
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
- the packet teminating character '#' and the two digit checksum.
-
- If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
- in an infinit loop. This is so if you unplug the debugger code just keeps running
-
- @param PacketData Payload data for the packet
-
- @retval Number of bytes of packet data sent.
-
-**/
-UINTN
-SendPacket (
- IN CHAR8 *PacketData
- );
-
-
-/**
- Receive a GDB Remote Serial Protocol Packet
-
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
- the packet teminating character '#' and the two digit checksum.
-
- If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
- (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
-
- If an ack '+' is not sent resend the packet
-
- @param PacketData Payload data for the packet
-
- @retval Number of bytes of packet data received.
-
- **/
-UINTN
-ReceivePacket (
- OUT CHAR8 *PacketData,
- IN UINTN PacketDataSize
- );
-
-
-/**
- Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
- the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
-
- @param FileDescriptor Device to talk to.
- @param Buffer Buffer to hold Count bytes that were read
- @param Count Number of bytes to transfer.
-
- @retval -1 Error
- @retval {other} Number of bytes read.
-
-**/
-INTN
-GdbRead (
- IN INTN FileDescriptor,
- OUT VOID *Buffer,
- IN UINTN Count
- );
-
-
-/**
- Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
- nothing was written. On error -1 is returned.
-
- @param FileDescriptor Device to talk to.
- @param Buffer Buffer to hold Count bytes that are to be written
- @param Count Number of bytes to transfer.
-
- @retval -1 Error
- @retval {other} Number of bytes written.
-
-**/
-INTN
-GdbWrite (
- IN INTN FileDescriptor,
- OUT CONST VOID *Buffer,
- IN UINTN Count
- );
-
-UINTN *
-FindPointerToRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber
- );
-
-CHAR8 *
-BasicReadRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *OutBufPtr
- );
-
-VOID
-TransferFromInBufToMem (
- IN UINTN Length,
- IN UINT8 *Address,
- IN CHAR8 *NewData
- );
-
-VOID
-TransferFromMemToOutBufAndSend (
- IN UINTN Length,
- IN UINT8 *Address
- );
-
-CHAR8 *
-BasicWriteRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *InBufPtr
- );
-
-VOID
-PrintReg (
- EFI_SYSTEM_CONTEXT SystemContext
- );
-
-UINTN
-ParseBreakpointPacket (
- IN CHAR8 *PacketData,
- OUT UINTN *Type,
- OUT UINTN *Address,
- OUT UINTN *Length
- );
-
-UINTN
-GetBreakpointDataAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- );
-
-UINTN
-GetBreakpointDetected (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-BREAK_TYPE
-GetBreakpointType (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- );
-
-UINTN
-ConvertLengthData (
- IN UINTN Length
- );
-
-EFI_STATUS
-FindNextFreeDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- OUT UINTN *Register
- );
-
-EFI_STATUS
-EnableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type
- );
-
-EFI_STATUS
-FindMatchingDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type,
- OUT UINTN *Register
- );
-
-EFI_STATUS
-DisableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register
- );
-
-VOID
-InitializeProcessor (
- VOID
- );
-
-BOOLEAN
-ValidateAddress (
- IN VOID *Address
- );
-
-BOOLEAN
-ValidateException (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-#endif
+/** @file
+ Private include file for GDB stub
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __GDB_STUB_INTERNAL__
+#define __GDB_STUB_INTERNAL__
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PcdLib.h>
+#include <Library/GdbSerialLib.h>
+#include <Library/PrintLib.h>
+
+#include <Protocol/DebugSupport.h>
+#include <Protocol/SerialIo.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/LoadedImage.h>
+#include <Guid/DebugImageInfoTable.h>
+#include <IndustryStandard/PeImage.h>
+
+extern CONST CHAR8 mHexToStr[];
+
+// maximum size of input and output buffers
+// This value came from the show remote command of the gdb we tested against
+#define MAX_BUF_SIZE 2000
+
+// maximum size of address buffer
+#define MAX_ADDR_SIZE 32
+
+// maximum size of register number buffer
+#define MAX_REG_NUM_BUF_SIZE 32
+
+// maximum size of length buffer
+#define MAX_LENGTH_SIZE 32
+
+// maximum size of T signal members
+#define MAX_T_SIGNAL_SIZE 64
+
+// the mask used to clear all the cache
+#define TF_BIT 0x00000100
+
+
+//
+// GDB Signal definitions - generic names for interrupts
+//
+#define GDB_SIGILL 4 // Illegal instruction
+#define GDB_SIGTRAP 5 // Trace Trap (Breakpoint and SingleStep)
+#define GDB_SIGEMT 7 // Emulator Trap
+#define GDB_SIGFPE 8 // Floating point exception
+#define GDB_SIGSEGV 11 // Setgment violation, page fault
+
+
+//
+// GDB File I/O Error values, zero means no error
+// Includes all general GDB Unix like error values
+//
+#define GDB_EBADMEMADDRBUFSIZE 11 // the buffer that stores memory Address to be read from/written to is not the right size
+#define GDB_EBADMEMLENGBUFSIZE 12 // the buffer that stores Length is not the right size
+#define GDB_EBADMEMLENGTH 13 // Length, the given number of bytes to read or write, is not the right size
+#define GDB_EBADMEMDATA 14 // one of the bytes or nibbles of the memory is leess than 0
+#define GDB_EBADMEMDATASIZE 15 // the memory data, 'XX..', is too short or too long
+#define GDB_EBADBUFSIZE 21 // the buffer created is not the correct size
+#define GDB_EINVALIDARG 31 // argument is invalid
+#define GDB_ENOSPACE 41 //
+#define GDB_EINVALIDBRKPOINTTYPE 51 // the breakpoint type is not recognized
+#define GDB_EINVALIDREGNUM 61 // given register number is not valid: either <0 or >=Number of Registers
+#define GDB_EUNKNOWN 255 // unknown
+
+
+//
+// These devices are open by GDB so we can just read and write to them
+//
+#define GDB_STDIN 0x00
+#define GDB_STDOUT 0x01
+#define GDB_STDERR 0x02
+
+//
+//Define Register size for different architectures
+//
+#if defined (MDE_CPU_IA32)
+#define REG_SIZE 32
+#elif defined (MDE_CPU_X64)
+#define REG_SIZE 64
+#elif defined (MDE_CPU_ARM)
+#define REG_SIZE 32
+#endif
+
+#define GDB_SERIAL_DEV_SIGNATURE SIGNATURE_32 ('g', 'd', 'b', 's')
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevice;
+ UINT32 Index; // Suport more than one
+ EFI_DEVICE_PATH_PROTOCOL End;
+} GDB_SERIAL_DEVICE_PATH;
+
+//
+// Name: SERIAL_DEV
+// Purpose: To provide device specific information
+// Fields:
+// Signature UINTN: The identity of the serial device
+// SerialIo SERIAL_IO_PROTOCOL: Serial I/O protocol interface
+// SerialMode SERIAL_IO_MODE:
+// DevicePath EFI_DEVICE_PATH_PROTOCOL *: Device path of the serial device
+//
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_SERIAL_IO_PROTOCOL SerialIo;
+ EFI_SERIAL_IO_MODE SerialMode;
+ GDB_SERIAL_DEVICE_PATH DevicePath;
+ INTN InFileDescriptor;
+ INTN OutFileDescriptor;
+} GDB_SERIAL_DEV;
+
+
+#define GDB_SERIAL_DEV_FROM_THIS(a) CR (a, GDB_SERIAL_DEV, SerialIo, GDB_SERIAL_DEV_SIGNATURE)
+
+
+typedef struct {
+ EFI_EXCEPTION_TYPE Exception;
+ UINT8 SignalNo;
+} EFI_EXCEPTION_TYPE_ENTRY;
+
+
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+
+//
+// Byte packed structure for DR6
+// 32-bits on IA-32
+// 64-bits on X64. The upper 32-bits on X64 are reserved
+//
+typedef union {
+ struct {
+ UINT32 B0:1; // Breakpoint condition detected
+ UINT32 B1:1; // Breakpoint condition detected
+ UINT32 B2:1; // Breakpoint condition detected
+ UINT32 B3:1; // Breakpoint condition detected
+ UINT32 Reserved_1:9; // Reserved
+ UINT32 BD:1; // Debug register access detected
+ UINT32 BS:1; // Single step
+ UINT32 BT:1; // Task switch
+ UINT32 Reserved_2:16; // Reserved
+ } Bits;
+ UINTN UintN;
+} IA32_DR6;
+
+//
+// Byte packed structure for DR7
+// 32-bits on IA-32
+// 64-bits on X64. The upper 32-bits on X64 are reserved
+//
+typedef union {
+ struct {
+ UINT32 L0:1; // Local breakpoint enable
+ UINT32 G0:1; // Global breakpoint enable
+ UINT32 L1:1; // Local breakpoint enable
+ UINT32 G1:1; // Global breakpoint enable
+ UINT32 L2:1; // Local breakpoint enable
+ UINT32 G2:1; // Global breakpoint enable
+ UINT32 L3:1; // Local breakpoint enable
+ UINT32 G3:1; // Global breakpoint enable
+ UINT32 LE:1; // Local exact breakpoint enable
+ UINT32 GE:1; // Global exact breakpoint enable
+ UINT32 Reserved_1:3; // Reserved
+ UINT32 GD:1; // Global detect enable
+ UINT32 Reserved_2:2; // Reserved
+ UINT32 RW0:2; // Read/Write field
+ UINT32 LEN0:2; // Length field
+ UINT32 RW1:2; // Read/Write field
+ UINT32 LEN1:2; // Length field
+ UINT32 RW2:2; // Read/Write field
+ UINT32 LEN2:2; // Length field
+ UINT32 RW3:2; // Read/Write field
+ UINT32 LEN3:2; // Length field
+ } Bits;
+ UINTN UintN;
+} IA32_DR7;
+
+#endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */
+
+typedef enum {
+ InstructionExecution, //Hardware breakpoint
+ DataWrite, //watch
+ DataRead, //rwatch
+ DataReadWrite, //awatch
+ SoftwareBreakpoint, //Software breakpoint
+ NotSupported
+} BREAK_TYPE;
+
+//
+// Array of exception types that need to be hooked by the debugger
+//
+extern EFI_EXCEPTION_TYPE_ENTRY gExceptionType[];
+
+//
+// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
+// here we need to wait for the periodic callback to do this.
+//
+extern BOOLEAN gCtrlCBreakFlag;
+
+//
+// If the periodic callback is called while we are processing an F packet we need
+// to let the callback know to not read from the serail stream as it could steal
+// characters from the F reponse packet
+//
+extern BOOLEAN gProcessingFPacket;
+
+
+// The offsets of registers SystemContext.
+// The fields in the array are in the gdb ordering.
+//
+extern UINTN gRegisterOffsets[];
+
+/**
+ Return the number of entries in the gExceptionType[]
+
+ @retval UINTN, the number of entries in the gExceptionType[] array.
+ **/
+UINTN
+MaxEfiException (
+ VOID
+ );
+
+
+/**
+ Return the number of entries in the gRegisters[]
+
+ @retval UINTN, the number of entries (registers) in the gRegisters[] array.
+ **/
+UINTN
+MaxRegisterCount (
+ VOID
+ );
+
+
+/**
+ Check to see if the ISA is supported.
+ ISA = Instruction Set Architecture
+
+ @retval TRUE if Isa is supported,
+ FALSE otherwise.
+ **/
+BOOLEAN
+CheckIsa (
+ IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
+ );
+
+
+/**
+ Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
+
+ @param SystemContext Register content at time of the exception
+ @param GdbExceptionType GDB exception type
+ **/
+
+VOID
+GdbSendTSignal (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINT8 GdbExceptionType
+ );
+
+
+/**
+ Translates the EFI mapping to GDB mapping
+
+ @param EFIExceptionType EFI Exception that is being processed
+ @retval UINTN that corresponds to EFIExceptionType's GDB exception type number
+ **/
+UINT8
+ConvertEFItoGDBtype (
+ IN EFI_EXCEPTION_TYPE EFIExceptionType
+ );
+
+
+/**
+ Empties the given buffer
+ @param *Buf pointer to the first element in buffer to be emptied
+ **/
+VOID
+EmptyBuffer (
+ IN CHAR8 *Buf
+ );
+
+
+/**
+ Converts an 8-bit Hex Char into a INTN.
+
+ @param Char - the hex character to be converted into UINTN
+ @retval a INTN, from 0 to 15, that corressponds to Char
+ -1 if Char is not a hex character
+ **/
+INTN
+HexCharToInt (
+ IN CHAR8 Char
+ );
+
+
+/** 'E NN'
+ Send an error with the given error number after converting to hex.
+ The error number is put into the buffer in hex. '255' is the biggest errno we can send.
+ ex: 162 will be sent as A2.
+
+ @param errno the error number that will be sent
+ **/
+VOID
+EFIAPI
+SendError (
+ IN UINT8 ErrorNum
+ );
+
+
+/**
+ Send 'OK' when the function is done executing successfully.
+ **/
+VOID
+SendSuccess (
+ VOID
+ );
+
+
+/**
+ Send empty packet to specify that particular command/functionality is not supported.
+ **/
+VOID
+SendNotSupported (
+ VOID
+ );
+
+/** ‘p n’
+ Reads the n-th register's value into an output buffer and sends it as a packet
+ @param SystemContext Register content at time of the exception
+ @param InBuffer This is the input buffer received from gdb server
+ **/
+VOID
+ReadNthRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ );
+
+
+/** ‘g’
+ Reads the general registers into an output buffer and sends it as a packet
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+ReadGeneralRegisters (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+
+/** ‘P n...=r...’
+ Writes the new value of n-th register received into the input buffer to the n-th register
+ @param SystemContext Register content at time of the exception
+ @param InBuffer This is the input buffer received from gdb server
+ **/
+VOID
+WriteNthRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ );
+
+
+/** ‘G XX...’
+ Writes the new values received into the input buffer to the general registers
+ @param SystemContext Register content at time of the exception
+ @param InBuffer Pointer to the input buffer received from gdb server
+ **/
+
+VOID
+WriteGeneralRegisters (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ );
+
+
+/** ‘m addr,length ’
+ Find the Length of the area to read and the start addres. Finally, pass them to
+ another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
+ send it as a packet.
+
+ @param *PacketData Pointer to Payload data for the packet
+ **/
+VOID
+ReadFromMemory (
+ IN CHAR8 *PacketData
+ );
+
+
+/** ‘M addr,length :XX...’
+ Find the Length of the area in bytes to write and the start addres. Finally, pass them to
+ another function, TransferFromInBufToMem, that will write to that memory space the info in
+ the input buffer.
+
+ @param PacketData Pointer to Payload data for the packet
+ **/
+VOID
+WriteToMemory (
+ IN CHAR8 *PacketData
+ );
+
+
+/** ‘c [addr ]’
+ Continue. addr is Address to resume. If addr is omitted, resume at current
+ Address.
+
+ @param SystemContext Register content at time of the exception
+ @param *PacketData Pointer to PacketData
+ **/
+
+VOID
+ContinueAtAddress (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ );
+
+
+/** ‘s [addr ]’
+ Single step. addr is the Address at which to resume. If addr is omitted, resume
+ at same Address.
+
+ @param SystemContext Register content at time of the exception
+ @param PacketData Pointer to Payload data for the packet
+ **/
+VOID
+SingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ );
+
+/**
+ Insert Single Step in the SystemContext
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+AddSingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+/**
+ Remove Single Step in the SystemContext
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+RemoveSingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+
+/**
+ ‘Z1, [addr], [length]’
+ ‘Z2, [addr], [length]’
+ ‘Z3, [addr], [length]’
+ ‘Z4, [addr], [length]’
+
+ Insert hardware breakpoint/watchpoint at address addr of size length
+
+ @param SystemContext Register content at time of the exception
+ @param *PacketData Pointer to the Payload data for the packet
+
+**/
+VOID
+EFIAPI
+InsertBreakPoint(
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ );
+
+
+/**
+ ‘z1, [addr], [length]’
+ ‘z2, [addr], [length]’
+ ‘z3, [addr], [length]’
+ ‘z4, [addr], [length]’
+
+ Remove hardware breakpoint/watchpoint at address addr of size length
+
+ @param SystemContext Register content at time of the exception
+ @param *PacketData Pointer to the Payload data for the packet
+
+**/
+VOID
+EFIAPI
+RemoveBreakPoint(
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ );
+
+
+/**
+ Exception Hanldler for GDB. It will be called for all exceptions
+ registered via the gExceptionType[] array.
+
+ @param ExceptionType Exception that is being processed
+ @param SystemContext Register content at time of the exception
+
+ **/
+VOID
+EFIAPI
+GdbExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+
+/**
+ Periodic callback for GDB. This function is used to catch a ctrl-c or other
+ break in type command from GDB.
+
+ @param SystemContext Register content at time of the call
+
+ **/
+VOID
+EFIAPI
+GdbPeriodicCallBack (
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+
+/**
+ Make two serail consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
+
+ These console show up on the remote system running GDB
+
+**/
+
+VOID
+GdbInitializeSerialConsole (
+ VOID
+ );
+
+
+/**
+ Send a GDB Remote Serial Protocol Packet
+
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
+ the packet teminating character '#' and the two digit checksum.
+
+ If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
+ in an infinit loop. This is so if you unplug the debugger code just keeps running
+
+ @param PacketData Payload data for the packet
+
+ @retval Number of bytes of packet data sent.
+
+**/
+UINTN
+SendPacket (
+ IN CHAR8 *PacketData
+ );
+
+
+/**
+ Receive a GDB Remote Serial Protocol Packet
+
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
+ the packet teminating character '#' and the two digit checksum.
+
+ If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
+ (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
+
+ If an ack '+' is not sent resend the packet
+
+ @param PacketData Payload data for the packet
+
+ @retval Number of bytes of packet data received.
+
+ **/
+UINTN
+ReceivePacket (
+ OUT CHAR8 *PacketData,
+ IN UINTN PacketDataSize
+ );
+
+
+/**
+ Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
+ the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
+
+ @param FileDescriptor Device to talk to.
+ @param Buffer Buffer to hold Count bytes that were read
+ @param Count Number of bytes to transfer.
+
+ @retval -1 Error
+ @retval {other} Number of bytes read.
+
+**/
+INTN
+GdbRead (
+ IN INTN FileDescriptor,
+ OUT VOID *Buffer,
+ IN UINTN Count
+ );
+
+
+/**
+ Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
+ nothing was written. On error -1 is returned.
+
+ @param FileDescriptor Device to talk to.
+ @param Buffer Buffer to hold Count bytes that are to be written
+ @param Count Number of bytes to transfer.
+
+ @retval -1 Error
+ @retval {other} Number of bytes written.
+
+**/
+INTN
+GdbWrite (
+ IN INTN FileDescriptor,
+ OUT CONST VOID *Buffer,
+ IN UINTN Count
+ );
+
+UINTN *
+FindPointerToRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber
+ );
+
+CHAR8 *
+BasicReadRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber,
+ IN CHAR8 *OutBufPtr
+ );
+
+VOID
+TransferFromInBufToMem (
+ IN UINTN Length,
+ IN UINT8 *Address,
+ IN CHAR8 *NewData
+ );
+
+VOID
+TransferFromMemToOutBufAndSend (
+ IN UINTN Length,
+ IN UINT8 *Address
+ );
+
+CHAR8 *
+BasicWriteRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber,
+ IN CHAR8 *InBufPtr
+ );
+
+VOID
+PrintReg (
+ EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+UINTN
+ParseBreakpointPacket (
+ IN CHAR8 *PacketData,
+ OUT UINTN *Type,
+ OUT UINTN *Address,
+ OUT UINTN *Length
+ );
+
+UINTN
+GetBreakpointDataAddress (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN BreakpointNumber
+ );
+
+UINTN
+GetBreakpointDetected (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+BREAK_TYPE
+GetBreakpointType (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN BreakpointNumber
+ );
+
+UINTN
+ConvertLengthData (
+ IN UINTN Length
+ );
+
+EFI_STATUS
+FindNextFreeDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ OUT UINTN *Register
+ );
+
+EFI_STATUS
+EnableDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Register,
+ IN UINTN Address,
+ IN UINTN Length,
+ IN UINTN Type
+ );
+
+EFI_STATUS
+FindMatchingDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Address,
+ IN UINTN Length,
+ IN UINTN Type,
+ OUT UINTN *Register
+ );
+
+EFI_STATUS
+DisableDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Register
+ );
+
+VOID
+InitializeProcessor (
+ VOID
+ );
+
+BOOLEAN
+ValidateAddress (
+ IN VOID *Address
+ );
+
+BOOLEAN
+ValidateException (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+#endif
diff --git a/EmbeddedPkg/GdbStub/Ia32/Processor.c b/EmbeddedPkg/GdbStub/Ia32/Processor.c
index 442faea023..a6aceaef99 100644
--- a/EmbeddedPkg/GdbStub/Ia32/Processor.c
+++ b/EmbeddedPkg/GdbStub/Ia32/Processor.c
@@ -1,993 +1,993 @@
-/** @file
- Processor specific parts of the GDB stub
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 <GdbStubInternal.h>
-
-//
-// Array of exception types that need to be hooked by the debugger
-// {EFI mapping, GDB mapping}
-//
-EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = {
- { EXCEPT_IA32_DIVIDE_ERROR, GDB_SIGFPE },
- { EXCEPT_IA32_DEBUG, GDB_SIGTRAP },
- { EXCEPT_IA32_NMI, GDB_SIGEMT },
- { EXCEPT_IA32_BREAKPOINT, GDB_SIGTRAP },
- { EXCEPT_IA32_OVERFLOW, GDB_SIGSEGV },
- { EXCEPT_IA32_BOUND, GDB_SIGSEGV },
- { EXCEPT_IA32_INVALID_OPCODE, GDB_SIGILL },
- { EXCEPT_IA32_DOUBLE_FAULT, GDB_SIGEMT },
- { EXCEPT_IA32_STACK_FAULT, GDB_SIGSEGV },
- { EXCEPT_IA32_GP_FAULT, GDB_SIGSEGV },
- { EXCEPT_IA32_PAGE_FAULT, GDB_SIGSEGV },
- { EXCEPT_IA32_FP_ERROR, GDB_SIGEMT },
- { EXCEPT_IA32_ALIGNMENT_CHECK, GDB_SIGEMT },
- { EXCEPT_IA32_MACHINE_CHECK, GDB_SIGEMT }
-};
-
-
-// The offsets of registers SystemContext.
-// The fields in the array are in the gdb ordering.
-//
-//16 regs
-UINTN gRegisterOffsets[] = {
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eax),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ecx),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edx),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebx),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esp),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebp),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esi),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edi),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eip),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eflags),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Cs),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ss),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ds),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Es),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Fs),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Gs)
-};
-
-
-//Debug only..
-VOID
-PrintReg (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- Print ((CHAR16 *)L"EAX: %x ", SystemContext.SystemContextIa32->Eax);
- Print ((CHAR16 *)L"ECX: %x ", SystemContext.SystemContextIa32->Ecx);
- Print ((CHAR16 *)L"EDX: %x ", SystemContext.SystemContextIa32->Edx);
- Print ((CHAR16 *)L"EBX: %x ", SystemContext.SystemContextIa32->Ebx);
- Print ((CHAR16 *)L"ESP: %x ", SystemContext.SystemContextIa32->Esp);
- Print ((CHAR16 *)L"EBP: %x ", SystemContext.SystemContextIa32->Ebp);
- Print ((CHAR16 *)L"ESI: %x ", SystemContext.SystemContextIa32->Esi);
- Print ((CHAR16 *)L"EDI: %x ", SystemContext.SystemContextIa32->Edi);
- Print ((CHAR16 *)L"EIP: %x\n", SystemContext.SystemContextIa32->Eip);
- Print ((CHAR16 *)L"EFlags: %x\n", SystemContext.SystemContextIa32->Eflags);
-}
-
-//Debug only..
-VOID
-PrintDRreg (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- Print ((CHAR16 *)L"DR0: %x ", SystemContext.SystemContextIa32->Dr0);
- Print ((CHAR16 *)L"DR1: %x ", SystemContext.SystemContextIa32->Dr1);
- Print ((CHAR16 *)L"DR2: %x ", SystemContext.SystemContextIa32->Dr2);
- Print ((CHAR16 *)L"DR3: %x ", SystemContext.SystemContextIa32->Dr3);
- Print ((CHAR16 *)L"DR6: %x ", SystemContext.SystemContextIa32->Dr6);
- Print ((CHAR16 *)L"DR7: %x\n", SystemContext.SystemContextIa32->Dr7);
-}
-
-
-/**
- Return the number of entries in the gExceptionType[]
-
- @retval UINTN, the number of entries in the gExceptionType[] array.
- **/
-UINTN
-MaxEfiException (
- VOID
- )
-{
- return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY);
-}
-
-
-/**
- Return the number of entries in the gRegisters[]
-
- @retval UINTN, the number of entries (registers) in the gRegisters[] array.
- **/
-UINTN
-MaxRegisterCount (
- VOID
- )
-{
- return sizeof (gRegisterOffsets)/sizeof (UINTN);
-}
-
-
-/**
- Check to see if the ISA is supported.
- ISA = Instruction Set Architecture
-
- @retval TRUE if Isa is supported,
- FALSE otherwise.
-**/
-BOOLEAN
-CheckIsa (
- IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
- )
-{
- return (BOOLEAN)(Isa == IsaIa32);
-}
-
-
-/**
- This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering
- It is, by default, set to find the register pointer of the IA32 member
-
- @param SystemContext Register content at time of the exception
- @param RegNumber The register to which we want to find a pointer
- @retval the pointer to the RegNumber-th pointer
- **/
-UINTN *
-FindPointerToRegister(
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber
- )
-{
- UINT8 *TempPtr;
- TempPtr = ((UINT8 *)SystemContext.SystemContextIa32) + gRegisterOffsets[RegNumber];
- return (UINTN *)TempPtr;
-}
-
-
-/**
- Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
-
- @param SystemContext Register content at time of the exception
- @param RegNumber the number of the register that we want to read
- @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on.
- @retval the pointer to the next character of the output buffer that is available to be written on.
- **/
-CHAR8 *
-BasicReadRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *OutBufPtr
- )
-{
- UINTN RegSize;
-
- RegSize = 0;
- while (RegSize < REG_SIZE) {
- *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)];
- *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)];
- RegSize = RegSize + 8;
- }
- return OutBufPtr;
-}
-
-
-/** ‘p n’
- Reads the n-th register's value into an output buffer and sends it as a packet
-
- @param SystemContext Register content at time of the exception
- @param InBuffer Pointer to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-ReadNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- )
-{
- UINTN RegNumber;
- CHAR8 OutBuffer[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)
- CHAR8 *OutBufPtr; // pointer to the output buffer
-
- RegNumber = AsciiStrHexToUintn (&InBuffer[1]);
-
- if ((RegNumber < 0) || (RegNumber >= MaxRegisterCount())) {
- SendError (GDB_EINVALIDREGNUM);
- return;
- }
-
- OutBufPtr = OutBuffer;
- OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr);
-
- *OutBufPtr = '\0'; // the end of the buffer
- SendPacket(OutBuffer);
-}
-
-
-/** ‘g’
- Reads the general registers into an output buffer and sends it as a packet
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-EFIAPI
-ReadGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- UINTN i;
- CHAR8 OutBuffer[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
- CHAR8 *OutBufPtr; // pointer to the output buffer
-
- OutBufPtr = OutBuffer;
- for(i = 0 ; i < MaxRegisterCount() ; i++) { // there are only 16 registers to read
- OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr);
- }
-
- *OutBufPtr = '\0'; // the end of the buffer
- SendPacket(OutBuffer);
-}
-
-
-/**
- Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
-
- @param SystemContext Register content at time of the exception
- @param RegNumber the number of the register that we want to write
- @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on.
- @retval the pointer to the next character of the input buffer that can be used
- **/
-CHAR8 *
-BasicWriteRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *InBufPtr
- )
-{
- UINTN RegSize;
- UINTN TempValue; // the value transferred from a hex char
- UINT32 NewValue; // the new value of the RegNumber-th Register
-
- NewValue = 0;
- RegSize = 0;
- while (RegSize < REG_SIZE) {
- TempValue = HexCharToInt(*InBufPtr++);
-
- if (TempValue < 0) {
- SendError (GDB_EBADMEMDATA);
- return NULL;
- }
-
- NewValue += (TempValue << (RegSize+4));
- TempValue = HexCharToInt(*InBufPtr++);
-
- if (TempValue < 0) {
- SendError (GDB_EBADMEMDATA);
- return NULL;
- }
-
- NewValue += (TempValue << RegSize);
- RegSize = RegSize + 8;
- }
- *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue;
- return InBufPtr;
-}
-
-
-/** ‘P n...=r...’
- Writes the new value of n-th register received into the input buffer to the n-th register
-
- @param SystemContext Register content at time of the exception
- @param InBuffer Ponter to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-WriteNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- )
-{
- UINTN RegNumber;
- CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE]; // put the 'n..' part of the message into this array
- CHAR8 *RegNumBufPtr;
- CHAR8 *InBufPtr; // pointer to the input buffer
-
- // find the register number to write
- InBufPtr = &InBuffer[1];
- RegNumBufPtr = RegNumBuffer;
- while (*InBufPtr != '=') {
- *RegNumBufPtr++ = *InBufPtr++;
- }
- *RegNumBufPtr = '\0';
- RegNumber = AsciiStrHexToUintn (RegNumBuffer);
-
- // check if this is a valid Register Number
- if ((RegNumber < 0) || (RegNumber >= MaxRegisterCount())) {
- SendError (GDB_EINVALIDREGNUM);
- return;
- }
- InBufPtr++; // skips the '=' character
- BasicWriteRegister (SystemContext, RegNumber, InBufPtr);
- SendSuccess();
-}
-
-
-/** ‘G XX...’
- Writes the new values received into the input buffer to the general registers
-
- @param SystemContext Register content at time of the exception
- @param InBuffer Pointer to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-WriteGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- )
-{
- UINTN i;
- CHAR8 *InBufPtr; /// pointer to the input buffer
-
- // check to see if the buffer is the right size which is
- // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129
- if (AsciiStrLen(InBuffer) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
- //Bad message. Message is not the right length
- SendError (GDB_EBADBUFSIZE);
- return;
- }
-
- InBufPtr = &InBuffer[1];
-
- // Read the new values for the registers from the input buffer to an array, NewValueArray.
- // The values in the array are in the gdb ordering
- for(i=0; i < MaxRegisterCount(); i++) { // there are only 16 registers to write
- InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr);
- }
-
- SendSuccess();
-}
-
-
-/**
- Insert Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-AddSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- SystemContext.SystemContextIa32->Eflags |= TF_BIT; //Setting the TF bit.
-}
-
-
-/**
- Remove Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-RemoveSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- SystemContext.SystemContextIa32->Eflags &= ~TF_BIT; // clearing the TF bit.
-}
-
-
-
-/** ‘c [addr ]’
- Continue. addr is Address to resume. If addr is omitted, resume at current
- Address.
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-EFIAPI
-ContinueAtAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- if (PacketData[1] != '\0') {
- SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);
- }
-}
-
-
-/** ‘s [addr ]’
- Single step. addr is the Address at which to resume. If addr is omitted, resume
- at same Address.
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-EFIAPI
-SingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- if (PacketData[1] != '\0') {
- SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);
- }
-
- AddSingleStep (SystemContext);
-}
-
-
-/**
- Returns breakpoint data address from DR0-DR3 based on the input breakpoint number
-
- @param SystemContext Register content at time of the exception
- @param BreakpointNumber Breakpoint number
-
- @retval Address Data address from DR0-DR3 based on the breakpoint number.
-
-**/
-UINTN
-GetBreakpointDataAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- )
-{
- UINTN Address;
-
- if (BreakpointNumber == 1) {
- Address = SystemContext.SystemContextIa32->Dr0;
- } else if (BreakpointNumber == 2) {
- Address = SystemContext.SystemContextIa32->Dr1;
- } else if (BreakpointNumber == 3) {
- Address = SystemContext.SystemContextIa32->Dr2;
- } else if (BreakpointNumber == 4) {
- Address = SystemContext.SystemContextIa32->Dr3;
- } else {
- Address = 0;
- }
-
- return Address;
-}
-
-
-/**
- Returns currently detected breakpoint value based on the register DR6 B0-B3 field.
- If no breakpoint is detected then it returns 0.
-
- @param SystemContext Register content at time of the exception
-
- @retval {1-4} Currently detected breakpoint value
- @retval 0 No breakpoint detected.
-
-**/
-UINTN
-GetBreakpointDetected (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- IA32_DR6 Dr6;
- UINTN BreakpointNumber;
-
- Dr6.UintN = SystemContext.SystemContextIa32->Dr6;
-
- if (Dr6.Bits.B0 == 1) {
- BreakpointNumber = 1;
- } else if (Dr6.Bits.B1 == 1) {
- BreakpointNumber = 2;
- } else if (Dr6.Bits.B2 == 1) {
- BreakpointNumber = 3;
- } else if (Dr6.Bits.B3 == 1) {
- BreakpointNumber = 4;
- } else {
- BreakpointNumber = 0; //No breakpoint detected
- }
-
- return BreakpointNumber;
-}
-
-
-/**
- Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)
- based on the Breakpoint number
-
- @param SystemContext Register content at time of the exception
- @param BreakpointNumber Breakpoint number
-
- @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn field
- For unknown value, it returns NotSupported.
-
-**/
-BREAK_TYPE
-GetBreakpointType (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- )
-{
- IA32_DR7 Dr7;
- BREAK_TYPE Type = NotSupported; //Default is NotSupported type
-
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if (BreakpointNumber == 1) {
- Type = (BREAK_TYPE) Dr7.Bits.RW0;
- } else if (BreakpointNumber == 2) {
- Type = (BREAK_TYPE) Dr7.Bits.RW1;
- } else if (BreakpointNumber == 3) {
- Type = (BREAK_TYPE) Dr7.Bits.RW2;
- } else if (BreakpointNumber == 4) {
- Type = (BREAK_TYPE) Dr7.Bits.RW3;
- }
-
- return Type;
-}
-
-
-/**
- Parses Length and returns the length which DR7 LENn field accepts.
- For example: If we receive 1-Byte length then we should return 0.
- Zero gets written to DR7 LENn field.
-
- @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
-
- @retval Length Appropriate converted values which DR7 LENn field accepts.
-
-**/
-UINTN
-ConvertLengthData (
- IN UINTN Length
- )
-{
- if (Length == 1) { //1-Byte length
- return 0;
- } else if (Length == 2) { //2-Byte length
- return 1;
- } else if (Length == 4) { //4-Byte length
- return 3;
- } else { //Undefined or 8-byte length
- return 2;
- }
-}
-
-
-/**
- Finds the next free debug register. If all the registers are occupied then
- EFI_OUT_OF_RESOURCES is returned.
-
- @param SystemContext Register content at time of the exception
- @param Register Register value (0 - 3 for the first free debug register)
-
- @retval EFI_STATUS Appropriate status value.
-
-**/
-EFI_STATUS
-FindNextFreeDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- OUT UINTN *Register
- )
-{
- IA32_DR7 Dr7;
-
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if (Dr7.Bits.G0 == 0) {
- *Register = 0;
- } else if (Dr7.Bits.G1 == 0) {
- *Register = 1;
- } else if (Dr7.Bits.G2 == 0) {
- *Register = 2;
- } else if (Dr7.Bits.G3 == 0) {
- *Register = 3;
- } else {
- return EFI_OUT_OF_RESOURCES;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Enables the debug register. Writes Address value to appropriate DR0-3 register.
- Sets LENn, Gn, RWn bits in DR7 register.
-
- @param SystemContext Register content at time of the exception
- @param Register Register value (0 - 3)
- @param Address Breakpoint address value
- @param Type Breakpoint type (Instruction, Data write, Data read
- or write etc.)
-
- @retval EFI_STATUS Appropriate status value.
-
-**/
-EFI_STATUS
-EnableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type
- )
-{
- IA32_DR7 Dr7;
-
- //Convert length data
- Length = ConvertLengthData (Length);
-
- //For Instruction execution, length should be 0
- //(Ref. Intel reference manual 18.2.4)
- if ((Type == 0) && (Length != 0)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
- //software breakpoint. We should send empty packet in both these cases.
- if ((Type == (BREAK_TYPE)DataRead) ||
- (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
- return EFI_UNSUPPORTED;
- }
-
- //Read DR7 so appropriate Gn, RWn and LENn bits can be modified.
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if (Register == 0) {
- SystemContext.SystemContextIa32->Dr0 = Address;
- Dr7.Bits.G0 = 1;
- Dr7.Bits.RW0 = Type;
- Dr7.Bits.LEN0 = Length;
- } else if (Register == 1) {
- SystemContext.SystemContextIa32->Dr1 = Address;
- Dr7.Bits.G1 = 1;
- Dr7.Bits.RW1 = Type;
- Dr7.Bits.LEN1 = Length;
- } else if (Register == 2) {
- SystemContext.SystemContextIa32->Dr2 = Address;
- Dr7.Bits.G2 = 1;
- Dr7.Bits.RW2 = Type;
- Dr7.Bits.LEN2 = Length;
- } else if (Register == 3) {
- SystemContext.SystemContextIa32->Dr3 = Address;
- Dr7.Bits.G3 = 1;
- Dr7.Bits.RW3 = Type;
- Dr7.Bits.LEN3 = Length;
- } else {
- return EFI_INVALID_PARAMETER;
- }
-
- //Update Dr7 with appropriate Gn, RWn and LENn bits
- SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Returns register number 0 - 3 for the maching debug register.
- This function compares incoming Address, Type, Length and
- if there is a match then it returns the appropriate register number.
- In case of mismatch, function returns EFI_NOT_FOUND message.
-
- @param SystemContext Register content at time of the exception
- @param Address Breakpoint address value
- @param Length Breakpoint length value
- @param Type Breakpoint type (Instruction, Data write,
- Data read or write etc.)
- @param Register Register value to be returned
-
- @retval EFI_STATUS Appropriate status value.
-
-**/
-EFI_STATUS
-FindMatchingDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type,
- OUT UINTN *Register
- )
-{
- IA32_DR7 Dr7;
-
- //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
- //software breakpoint. We should send empty packet in both these cases.
- if ((Type == (BREAK_TYPE)DataRead) ||
- (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
- return EFI_UNSUPPORTED;
- }
-
- //Convert length data
- Length = ConvertLengthData(Length);
-
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if ((Dr7.Bits.G0 == 1) &&
- (Dr7.Bits.LEN0 == Length) &&
- (Dr7.Bits.RW0 == Type) &&
- (Address == SystemContext.SystemContextIa32->Dr0)) {
- *Register = 0;
- } else if ((Dr7.Bits.G1 == 1) &&
- (Dr7.Bits.LEN1 == Length) &&
- (Dr7.Bits.RW1 == Type) &&
- (Address == SystemContext.SystemContextIa32->Dr1)) {
- *Register = 1;
- } else if ((Dr7.Bits.G2 == 1) &&
- (Dr7.Bits.LEN2 == Length) &&
- (Dr7.Bits.RW2 == Type) &&
- (Address == SystemContext.SystemContextIa32->Dr2)) {
- *Register = 2;
- } else if ((Dr7.Bits.G3 == 1) &&
- (Dr7.Bits.LEN3 == Length) &&
- (Dr7.Bits.RW3 == Type) &&
- (Address == SystemContext.SystemContextIa32->Dr3)) {
- *Register = 3;
- } else {
- Print ((CHAR16 *)L"No match found..\n");
- return EFI_NOT_FOUND;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Disables the particular debug register.
-
- @param SystemContext Register content at time of the exception
- @param Register Register to be disabled
-
- @retval EFI_STATUS Appropriate status value.
-
-**/
-EFI_STATUS
-DisableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register
- )
-{
- IA32_DR7 Dr7;
- UINTN Address = 0;
-
- //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if (Register == 0) {
- SystemContext.SystemContextIa32->Dr0 = Address;
- Dr7.Bits.G0 = 0;
- Dr7.Bits.RW0 = 0;
- Dr7.Bits.LEN0 = 0;
- } else if (Register == 1) {
- SystemContext.SystemContextIa32->Dr1 = Address;
- Dr7.Bits.G1 = 0;
- Dr7.Bits.RW1 = 0;
- Dr7.Bits.LEN1 = 0;
- } else if (Register == 2) {
- SystemContext.SystemContextIa32->Dr2 = Address;
- Dr7.Bits.G2 = 0;
- Dr7.Bits.RW2 = 0;
- Dr7.Bits.LEN2 = 0;
- } else if (Register == 3) {
- SystemContext.SystemContextIa32->Dr3 = Address;
- Dr7.Bits.G3 = 0;
- Dr7.Bits.RW3 = 0;
- Dr7.Bits.LEN3 = 0;
- } else {
- return EFI_INVALID_PARAMETER;
- }
-
- //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
- SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
-
- return EFI_SUCCESS;
-}
-
-
-/**
- ‘Z1, [addr], [length]’
- ‘Z2, [addr], [length]’
- ‘Z3, [addr], [length]’
- ‘Z4, [addr], [length]’
-
- Insert hardware breakpoint/watchpoint at address addr of size length
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-InsertBreakPoint (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- UINTN Type;
- UINTN Address;
- UINTN Length;
- UINTN Register;
- EFI_STATUS Status;
- BREAK_TYPE BreakType = NotSupported;
- UINTN ErrorCode;
-
- ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
- if (ErrorCode > 0) {
- SendError ((UINT8)ErrorCode);
- return;
- }
-
- switch (Type) {
-
- case 0: //Software breakpoint
- BreakType = SoftwareBreakpoint;
- break;
-
- case 1: //Hardware breakpoint
- BreakType = InstructionExecution;
- break;
-
- case 2: //Write watchpoint
- BreakType = DataWrite;
- break;
-
- case 3: //Read watchpoint
- BreakType = DataRead;
- break;
-
- case 4: //Access watchpoint
- BreakType = DataReadWrite;
- break;
-
- default :
- Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type);
- SendError (GDB_EINVALIDBRKPOINTTYPE);
- return;
- }
-
- // Find next free debug register
- Status = FindNextFreeDebugRegister (SystemContext, &Register);
- if (EFI_ERROR(Status)) {
- Print ((CHAR16 *)L"No space left on device\n");
- SendError (GDB_ENOSPACE);
- return;
- }
-
- // Write Address, length data at particular DR register
- Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType);
- if (EFI_ERROR(Status)) {
-
- if (Status == EFI_UNSUPPORTED) {
- Print ((CHAR16 *)L"Not supported\n");
- SendNotSupported();
- return;
- }
-
- Print ((CHAR16 *)L"Invalid argument\n");
- SendError (GDB_EINVALIDARG);
- return;
- }
-
- SendSuccess ();
-}
-
-
-/**
- ‘z1, [addr], [length]’
- ‘z2, [addr], [length]’
- ‘z3, [addr], [length]’
- ‘z4, [addr], [length]’
-
- Remove hardware breakpoint/watchpoint at address addr of size length
-
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-RemoveBreakPoint (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- UINTN Type;
- UINTN Address;
- UINTN Length;
- UINTN Register;
- BREAK_TYPE BreakType = NotSupported;
- EFI_STATUS Status;
- UINTN ErrorCode;
-
- //Parse breakpoint packet data
- ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
- if (ErrorCode > 0) {
- SendError ((UINT8)ErrorCode);
- return;
- }
-
- switch (Type) {
-
- case 0: //Software breakpoint
- BreakType = SoftwareBreakpoint;
- break;
-
- case 1: //Hardware breakpoint
- BreakType = InstructionExecution;
- break;
-
- case 2: //Write watchpoint
- BreakType = DataWrite;
- break;
-
- case 3: //Read watchpoint
- BreakType = DataRead;
- break;
-
- case 4: //Access watchpoint
- BreakType = DataReadWrite;
- break;
-
- default :
- SendError (GDB_EINVALIDBRKPOINTTYPE);
- return;
- }
-
- //Find matching debug register
- Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register);
- if (EFI_ERROR(Status)) {
-
- if (Status == EFI_UNSUPPORTED) {
- Print ((CHAR16 *)L"Not supported.\n");
- SendNotSupported();
- return;
- }
-
- Print ((CHAR16 *)L"No matching register found.\n");
- SendError (GDB_ENOSPACE);
- return;
- }
-
- //Remove breakpoint
- Status = DisableDebugRegister(SystemContext, Register);
- if (EFI_ERROR(Status)) {
- Print ((CHAR16 *)L"Invalid argument.\n");
- SendError (GDB_EINVALIDARG);
- return;
- }
-
- SendSuccess ();
-}
-
-
-VOID
-InitializeProcessor (
- VOID
- )
-{
-}
-
-BOOLEAN
-ValidateAddress (
- IN VOID *Address
- )
-{
- return TRUE;
-}
-
-BOOLEAN
-ValidateException (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- return TRUE;
-}
-
+/** @file
+ Processor specific parts of the GDB stub
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 <GdbStubInternal.h>
+
+//
+// Array of exception types that need to be hooked by the debugger
+// {EFI mapping, GDB mapping}
+//
+EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = {
+ { EXCEPT_IA32_DIVIDE_ERROR, GDB_SIGFPE },
+ { EXCEPT_IA32_DEBUG, GDB_SIGTRAP },
+ { EXCEPT_IA32_NMI, GDB_SIGEMT },
+ { EXCEPT_IA32_BREAKPOINT, GDB_SIGTRAP },
+ { EXCEPT_IA32_OVERFLOW, GDB_SIGSEGV },
+ { EXCEPT_IA32_BOUND, GDB_SIGSEGV },
+ { EXCEPT_IA32_INVALID_OPCODE, GDB_SIGILL },
+ { EXCEPT_IA32_DOUBLE_FAULT, GDB_SIGEMT },
+ { EXCEPT_IA32_STACK_FAULT, GDB_SIGSEGV },
+ { EXCEPT_IA32_GP_FAULT, GDB_SIGSEGV },
+ { EXCEPT_IA32_PAGE_FAULT, GDB_SIGSEGV },
+ { EXCEPT_IA32_FP_ERROR, GDB_SIGEMT },
+ { EXCEPT_IA32_ALIGNMENT_CHECK, GDB_SIGEMT },
+ { EXCEPT_IA32_MACHINE_CHECK, GDB_SIGEMT }
+};
+
+
+// The offsets of registers SystemContext.
+// The fields in the array are in the gdb ordering.
+//
+//16 regs
+UINTN gRegisterOffsets[] = {
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eax),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ecx),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edx),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebx),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esp),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebp),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esi),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edi),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eip),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eflags),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Cs),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ss),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ds),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Es),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Fs),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Gs)
+};
+
+
+//Debug only..
+VOID
+PrintReg (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ Print ((CHAR16 *)L"EAX: %x ", SystemContext.SystemContextIa32->Eax);
+ Print ((CHAR16 *)L"ECX: %x ", SystemContext.SystemContextIa32->Ecx);
+ Print ((CHAR16 *)L"EDX: %x ", SystemContext.SystemContextIa32->Edx);
+ Print ((CHAR16 *)L"EBX: %x ", SystemContext.SystemContextIa32->Ebx);
+ Print ((CHAR16 *)L"ESP: %x ", SystemContext.SystemContextIa32->Esp);
+ Print ((CHAR16 *)L"EBP: %x ", SystemContext.SystemContextIa32->Ebp);
+ Print ((CHAR16 *)L"ESI: %x ", SystemContext.SystemContextIa32->Esi);
+ Print ((CHAR16 *)L"EDI: %x ", SystemContext.SystemContextIa32->Edi);
+ Print ((CHAR16 *)L"EIP: %x\n", SystemContext.SystemContextIa32->Eip);
+ Print ((CHAR16 *)L"EFlags: %x\n", SystemContext.SystemContextIa32->Eflags);
+}
+
+//Debug only..
+VOID
+PrintDRreg (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ Print ((CHAR16 *)L"DR0: %x ", SystemContext.SystemContextIa32->Dr0);
+ Print ((CHAR16 *)L"DR1: %x ", SystemContext.SystemContextIa32->Dr1);
+ Print ((CHAR16 *)L"DR2: %x ", SystemContext.SystemContextIa32->Dr2);
+ Print ((CHAR16 *)L"DR3: %x ", SystemContext.SystemContextIa32->Dr3);
+ Print ((CHAR16 *)L"DR6: %x ", SystemContext.SystemContextIa32->Dr6);
+ Print ((CHAR16 *)L"DR7: %x\n", SystemContext.SystemContextIa32->Dr7);
+}
+
+
+/**
+ Return the number of entries in the gExceptionType[]
+
+ @retval UINTN, the number of entries in the gExceptionType[] array.
+ **/
+UINTN
+MaxEfiException (
+ VOID
+ )
+{
+ return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY);
+}
+
+
+/**
+ Return the number of entries in the gRegisters[]
+
+ @retval UINTN, the number of entries (registers) in the gRegisters[] array.
+ **/
+UINTN
+MaxRegisterCount (
+ VOID
+ )
+{
+ return sizeof (gRegisterOffsets)/sizeof (UINTN);
+}
+
+
+/**
+ Check to see if the ISA is supported.
+ ISA = Instruction Set Architecture
+
+ @retval TRUE if Isa is supported,
+ FALSE otherwise.
+**/
+BOOLEAN
+CheckIsa (
+ IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
+ )
+{
+ return (BOOLEAN)(Isa == IsaIa32);
+}
+
+
+/**
+ This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering
+ It is, by default, set to find the register pointer of the IA32 member
+
+ @param SystemContext Register content at time of the exception
+ @param RegNumber The register to which we want to find a pointer
+ @retval the pointer to the RegNumber-th pointer
+ **/
+UINTN *
+FindPointerToRegister(
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber
+ )
+{
+ UINT8 *TempPtr;
+ TempPtr = ((UINT8 *)SystemContext.SystemContextIa32) + gRegisterOffsets[RegNumber];
+ return (UINTN *)TempPtr;
+}
+
+
+/**
+ Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
+
+ @param SystemContext Register content at time of the exception
+ @param RegNumber the number of the register that we want to read
+ @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on.
+ @retval the pointer to the next character of the output buffer that is available to be written on.
+ **/
+CHAR8 *
+BasicReadRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber,
+ IN CHAR8 *OutBufPtr
+ )
+{
+ UINTN RegSize;
+
+ RegSize = 0;
+ while (RegSize < REG_SIZE) {
+ *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)];
+ *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)];
+ RegSize = RegSize + 8;
+ }
+ return OutBufPtr;
+}
+
+
+/** ‘p n’
+ Reads the n-th register's value into an output buffer and sends it as a packet
+
+ @param SystemContext Register content at time of the exception
+ @param InBuffer Pointer to the input buffer received from gdb server
+ **/
+VOID
+EFIAPI
+ReadNthRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ )
+{
+ UINTN RegNumber;
+ CHAR8 OutBuffer[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)
+ CHAR8 *OutBufPtr; // pointer to the output buffer
+
+ RegNumber = AsciiStrHexToUintn (&InBuffer[1]);
+
+ if ((RegNumber < 0) || (RegNumber >= MaxRegisterCount())) {
+ SendError (GDB_EINVALIDREGNUM);
+ return;
+ }
+
+ OutBufPtr = OutBuffer;
+ OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr);
+
+ *OutBufPtr = '\0'; // the end of the buffer
+ SendPacket(OutBuffer);
+}
+
+
+/** ‘g’
+ Reads the general registers into an output buffer and sends it as a packet
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+EFIAPI
+ReadGeneralRegisters (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ UINTN i;
+ CHAR8 OutBuffer[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
+ CHAR8 *OutBufPtr; // pointer to the output buffer
+
+ OutBufPtr = OutBuffer;
+ for(i = 0 ; i < MaxRegisterCount() ; i++) { // there are only 16 registers to read
+ OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr);
+ }
+
+ *OutBufPtr = '\0'; // the end of the buffer
+ SendPacket(OutBuffer);
+}
+
+
+/**
+ Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
+
+ @param SystemContext Register content at time of the exception
+ @param RegNumber the number of the register that we want to write
+ @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on.
+ @retval the pointer to the next character of the input buffer that can be used
+ **/
+CHAR8 *
+BasicWriteRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber,
+ IN CHAR8 *InBufPtr
+ )
+{
+ UINTN RegSize;
+ UINTN TempValue; // the value transferred from a hex char
+ UINT32 NewValue; // the new value of the RegNumber-th Register
+
+ NewValue = 0;
+ RegSize = 0;
+ while (RegSize < REG_SIZE) {
+ TempValue = HexCharToInt(*InBufPtr++);
+
+ if (TempValue < 0) {
+ SendError (GDB_EBADMEMDATA);
+ return NULL;
+ }
+
+ NewValue += (TempValue << (RegSize+4));
+ TempValue = HexCharToInt(*InBufPtr++);
+
+ if (TempValue < 0) {
+ SendError (GDB_EBADMEMDATA);
+ return NULL;
+ }
+
+ NewValue += (TempValue << RegSize);
+ RegSize = RegSize + 8;
+ }
+ *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue;
+ return InBufPtr;
+}
+
+
+/** ‘P n...=r...’
+ Writes the new value of n-th register received into the input buffer to the n-th register
+
+ @param SystemContext Register content at time of the exception
+ @param InBuffer Ponter to the input buffer received from gdb server
+ **/
+VOID
+EFIAPI
+WriteNthRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ )
+{
+ UINTN RegNumber;
+ CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE]; // put the 'n..' part of the message into this array
+ CHAR8 *RegNumBufPtr;
+ CHAR8 *InBufPtr; // pointer to the input buffer
+
+ // find the register number to write
+ InBufPtr = &InBuffer[1];
+ RegNumBufPtr = RegNumBuffer;
+ while (*InBufPtr != '=') {
+ *RegNumBufPtr++ = *InBufPtr++;
+ }
+ *RegNumBufPtr = '\0';
+ RegNumber = AsciiStrHexToUintn (RegNumBuffer);
+
+ // check if this is a valid Register Number
+ if ((RegNumber < 0) || (RegNumber >= MaxRegisterCount())) {
+ SendError (GDB_EINVALIDREGNUM);
+ return;
+ }
+ InBufPtr++; // skips the '=' character
+ BasicWriteRegister (SystemContext, RegNumber, InBufPtr);
+ SendSuccess();
+}
+
+
+/** ‘G XX...’
+ Writes the new values received into the input buffer to the general registers
+
+ @param SystemContext Register content at time of the exception
+ @param InBuffer Pointer to the input buffer received from gdb server
+ **/
+VOID
+EFIAPI
+WriteGeneralRegisters (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ )
+{
+ UINTN i;
+ CHAR8 *InBufPtr; /// pointer to the input buffer
+
+ // check to see if the buffer is the right size which is
+ // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129
+ if (AsciiStrLen(InBuffer) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
+ //Bad message. Message is not the right length
+ SendError (GDB_EBADBUFSIZE);
+ return;
+ }
+
+ InBufPtr = &InBuffer[1];
+
+ // Read the new values for the registers from the input buffer to an array, NewValueArray.
+ // The values in the array are in the gdb ordering
+ for(i=0; i < MaxRegisterCount(); i++) { // there are only 16 registers to write
+ InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr);
+ }
+
+ SendSuccess();
+}
+
+
+/**
+ Insert Single Step in the SystemContext
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+AddSingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ SystemContext.SystemContextIa32->Eflags |= TF_BIT; //Setting the TF bit.
+}
+
+
+/**
+ Remove Single Step in the SystemContext
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+RemoveSingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ SystemContext.SystemContextIa32->Eflags &= ~TF_BIT; // clearing the TF bit.
+}
+
+
+
+/** ‘c [addr ]’
+ Continue. addr is Address to resume. If addr is omitted, resume at current
+ Address.
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+EFIAPI
+ContinueAtAddress (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ )
+{
+ if (PacketData[1] != '\0') {
+ SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);
+ }
+}
+
+
+/** ‘s [addr ]’
+ Single step. addr is the Address at which to resume. If addr is omitted, resume
+ at same Address.
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+EFIAPI
+SingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ )
+{
+ if (PacketData[1] != '\0') {
+ SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);
+ }
+
+ AddSingleStep (SystemContext);
+}
+
+
+/**
+ Returns breakpoint data address from DR0-DR3 based on the input breakpoint number
+
+ @param SystemContext Register content at time of the exception
+ @param BreakpointNumber Breakpoint number
+
+ @retval Address Data address from DR0-DR3 based on the breakpoint number.
+
+**/
+UINTN
+GetBreakpointDataAddress (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN BreakpointNumber
+ )
+{
+ UINTN Address;
+
+ if (BreakpointNumber == 1) {
+ Address = SystemContext.SystemContextIa32->Dr0;
+ } else if (BreakpointNumber == 2) {
+ Address = SystemContext.SystemContextIa32->Dr1;
+ } else if (BreakpointNumber == 3) {
+ Address = SystemContext.SystemContextIa32->Dr2;
+ } else if (BreakpointNumber == 4) {
+ Address = SystemContext.SystemContextIa32->Dr3;
+ } else {
+ Address = 0;
+ }
+
+ return Address;
+}
+
+
+/**
+ Returns currently detected breakpoint value based on the register DR6 B0-B3 field.
+ If no breakpoint is detected then it returns 0.
+
+ @param SystemContext Register content at time of the exception
+
+ @retval {1-4} Currently detected breakpoint value
+ @retval 0 No breakpoint detected.
+
+**/
+UINTN
+GetBreakpointDetected (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ IA32_DR6 Dr6;
+ UINTN BreakpointNumber;
+
+ Dr6.UintN = SystemContext.SystemContextIa32->Dr6;
+
+ if (Dr6.Bits.B0 == 1) {
+ BreakpointNumber = 1;
+ } else if (Dr6.Bits.B1 == 1) {
+ BreakpointNumber = 2;
+ } else if (Dr6.Bits.B2 == 1) {
+ BreakpointNumber = 3;
+ } else if (Dr6.Bits.B3 == 1) {
+ BreakpointNumber = 4;
+ } else {
+ BreakpointNumber = 0; //No breakpoint detected
+ }
+
+ return BreakpointNumber;
+}
+
+
+/**
+ Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)
+ based on the Breakpoint number
+
+ @param SystemContext Register content at time of the exception
+ @param BreakpointNumber Breakpoint number
+
+ @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn field
+ For unknown value, it returns NotSupported.
+
+**/
+BREAK_TYPE
+GetBreakpointType (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN BreakpointNumber
+ )
+{
+ IA32_DR7 Dr7;
+ BREAK_TYPE Type = NotSupported; //Default is NotSupported type
+
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if (BreakpointNumber == 1) {
+ Type = (BREAK_TYPE) Dr7.Bits.RW0;
+ } else if (BreakpointNumber == 2) {
+ Type = (BREAK_TYPE) Dr7.Bits.RW1;
+ } else if (BreakpointNumber == 3) {
+ Type = (BREAK_TYPE) Dr7.Bits.RW2;
+ } else if (BreakpointNumber == 4) {
+ Type = (BREAK_TYPE) Dr7.Bits.RW3;
+ }
+
+ return Type;
+}
+
+
+/**
+ Parses Length and returns the length which DR7 LENn field accepts.
+ For example: If we receive 1-Byte length then we should return 0.
+ Zero gets written to DR7 LENn field.
+
+ @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
+
+ @retval Length Appropriate converted values which DR7 LENn field accepts.
+
+**/
+UINTN
+ConvertLengthData (
+ IN UINTN Length
+ )
+{
+ if (Length == 1) { //1-Byte length
+ return 0;
+ } else if (Length == 2) { //2-Byte length
+ return 1;
+ } else if (Length == 4) { //4-Byte length
+ return 3;
+ } else { //Undefined or 8-byte length
+ return 2;
+ }
+}
+
+
+/**
+ Finds the next free debug register. If all the registers are occupied then
+ EFI_OUT_OF_RESOURCES is returned.
+
+ @param SystemContext Register content at time of the exception
+ @param Register Register value (0 - 3 for the first free debug register)
+
+ @retval EFI_STATUS Appropriate status value.
+
+**/
+EFI_STATUS
+FindNextFreeDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ OUT UINTN *Register
+ )
+{
+ IA32_DR7 Dr7;
+
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if (Dr7.Bits.G0 == 0) {
+ *Register = 0;
+ } else if (Dr7.Bits.G1 == 0) {
+ *Register = 1;
+ } else if (Dr7.Bits.G2 == 0) {
+ *Register = 2;
+ } else if (Dr7.Bits.G3 == 0) {
+ *Register = 3;
+ } else {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Enables the debug register. Writes Address value to appropriate DR0-3 register.
+ Sets LENn, Gn, RWn bits in DR7 register.
+
+ @param SystemContext Register content at time of the exception
+ @param Register Register value (0 - 3)
+ @param Address Breakpoint address value
+ @param Type Breakpoint type (Instruction, Data write, Data read
+ or write etc.)
+
+ @retval EFI_STATUS Appropriate status value.
+
+**/
+EFI_STATUS
+EnableDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Register,
+ IN UINTN Address,
+ IN UINTN Length,
+ IN UINTN Type
+ )
+{
+ IA32_DR7 Dr7;
+
+ //Convert length data
+ Length = ConvertLengthData (Length);
+
+ //For Instruction execution, length should be 0
+ //(Ref. Intel reference manual 18.2.4)
+ if ((Type == 0) && (Length != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
+ //software breakpoint. We should send empty packet in both these cases.
+ if ((Type == (BREAK_TYPE)DataRead) ||
+ (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //Read DR7 so appropriate Gn, RWn and LENn bits can be modified.
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if (Register == 0) {
+ SystemContext.SystemContextIa32->Dr0 = Address;
+ Dr7.Bits.G0 = 1;
+ Dr7.Bits.RW0 = Type;
+ Dr7.Bits.LEN0 = Length;
+ } else if (Register == 1) {
+ SystemContext.SystemContextIa32->Dr1 = Address;
+ Dr7.Bits.G1 = 1;
+ Dr7.Bits.RW1 = Type;
+ Dr7.Bits.LEN1 = Length;
+ } else if (Register == 2) {
+ SystemContext.SystemContextIa32->Dr2 = Address;
+ Dr7.Bits.G2 = 1;
+ Dr7.Bits.RW2 = Type;
+ Dr7.Bits.LEN2 = Length;
+ } else if (Register == 3) {
+ SystemContext.SystemContextIa32->Dr3 = Address;
+ Dr7.Bits.G3 = 1;
+ Dr7.Bits.RW3 = Type;
+ Dr7.Bits.LEN3 = Length;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Update Dr7 with appropriate Gn, RWn and LENn bits
+ SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Returns register number 0 - 3 for the maching debug register.
+ This function compares incoming Address, Type, Length and
+ if there is a match then it returns the appropriate register number.
+ In case of mismatch, function returns EFI_NOT_FOUND message.
+
+ @param SystemContext Register content at time of the exception
+ @param Address Breakpoint address value
+ @param Length Breakpoint length value
+ @param Type Breakpoint type (Instruction, Data write,
+ Data read or write etc.)
+ @param Register Register value to be returned
+
+ @retval EFI_STATUS Appropriate status value.
+
+**/
+EFI_STATUS
+FindMatchingDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Address,
+ IN UINTN Length,
+ IN UINTN Type,
+ OUT UINTN *Register
+ )
+{
+ IA32_DR7 Dr7;
+
+ //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
+ //software breakpoint. We should send empty packet in both these cases.
+ if ((Type == (BREAK_TYPE)DataRead) ||
+ (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //Convert length data
+ Length = ConvertLengthData(Length);
+
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if ((Dr7.Bits.G0 == 1) &&
+ (Dr7.Bits.LEN0 == Length) &&
+ (Dr7.Bits.RW0 == Type) &&
+ (Address == SystemContext.SystemContextIa32->Dr0)) {
+ *Register = 0;
+ } else if ((Dr7.Bits.G1 == 1) &&
+ (Dr7.Bits.LEN1 == Length) &&
+ (Dr7.Bits.RW1 == Type) &&
+ (Address == SystemContext.SystemContextIa32->Dr1)) {
+ *Register = 1;
+ } else if ((Dr7.Bits.G2 == 1) &&
+ (Dr7.Bits.LEN2 == Length) &&
+ (Dr7.Bits.RW2 == Type) &&
+ (Address == SystemContext.SystemContextIa32->Dr2)) {
+ *Register = 2;
+ } else if ((Dr7.Bits.G3 == 1) &&
+ (Dr7.Bits.LEN3 == Length) &&
+ (Dr7.Bits.RW3 == Type) &&
+ (Address == SystemContext.SystemContextIa32->Dr3)) {
+ *Register = 3;
+ } else {
+ Print ((CHAR16 *)L"No match found..\n");
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Disables the particular debug register.
+
+ @param SystemContext Register content at time of the exception
+ @param Register Register to be disabled
+
+ @retval EFI_STATUS Appropriate status value.
+
+**/
+EFI_STATUS
+DisableDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Register
+ )
+{
+ IA32_DR7 Dr7;
+ UINTN Address = 0;
+
+ //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if (Register == 0) {
+ SystemContext.SystemContextIa32->Dr0 = Address;
+ Dr7.Bits.G0 = 0;
+ Dr7.Bits.RW0 = 0;
+ Dr7.Bits.LEN0 = 0;
+ } else if (Register == 1) {
+ SystemContext.SystemContextIa32->Dr1 = Address;
+ Dr7.Bits.G1 = 0;
+ Dr7.Bits.RW1 = 0;
+ Dr7.Bits.LEN1 = 0;
+ } else if (Register == 2) {
+ SystemContext.SystemContextIa32->Dr2 = Address;
+ Dr7.Bits.G2 = 0;
+ Dr7.Bits.RW2 = 0;
+ Dr7.Bits.LEN2 = 0;
+ } else if (Register == 3) {
+ SystemContext.SystemContextIa32->Dr3 = Address;
+ Dr7.Bits.G3 = 0;
+ Dr7.Bits.RW3 = 0;
+ Dr7.Bits.LEN3 = 0;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
+ SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ ‘Z1, [addr], [length]’
+ ‘Z2, [addr], [length]’
+ ‘Z3, [addr], [length]’
+ ‘Z4, [addr], [length]’
+
+ Insert hardware breakpoint/watchpoint at address addr of size length
+
+ @param SystemContext Register content at time of the exception
+ @param *PacketData Pointer to the Payload data for the packet
+
+**/
+VOID
+EFIAPI
+InsertBreakPoint (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ )
+{
+ UINTN Type;
+ UINTN Address;
+ UINTN Length;
+ UINTN Register;
+ EFI_STATUS Status;
+ BREAK_TYPE BreakType = NotSupported;
+ UINTN ErrorCode;
+
+ ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
+ if (ErrorCode > 0) {
+ SendError ((UINT8)ErrorCode);
+ return;
+ }
+
+ switch (Type) {
+
+ case 0: //Software breakpoint
+ BreakType = SoftwareBreakpoint;
+ break;
+
+ case 1: //Hardware breakpoint
+ BreakType = InstructionExecution;
+ break;
+
+ case 2: //Write watchpoint
+ BreakType = DataWrite;
+ break;
+
+ case 3: //Read watchpoint
+ BreakType = DataRead;
+ break;
+
+ case 4: //Access watchpoint
+ BreakType = DataReadWrite;
+ break;
+
+ default :
+ Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type);
+ SendError (GDB_EINVALIDBRKPOINTTYPE);
+ return;
+ }
+
+ // Find next free debug register
+ Status = FindNextFreeDebugRegister (SystemContext, &Register);
+ if (EFI_ERROR(Status)) {
+ Print ((CHAR16 *)L"No space left on device\n");
+ SendError (GDB_ENOSPACE);
+ return;
+ }
+
+ // Write Address, length data at particular DR register
+ Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType);
+ if (EFI_ERROR(Status)) {
+
+ if (Status == EFI_UNSUPPORTED) {
+ Print ((CHAR16 *)L"Not supported\n");
+ SendNotSupported();
+ return;
+ }
+
+ Print ((CHAR16 *)L"Invalid argument\n");
+ SendError (GDB_EINVALIDARG);
+ return;
+ }
+
+ SendSuccess ();
+}
+
+
+/**
+ ‘z1, [addr], [length]’
+ ‘z2, [addr], [length]’
+ ‘z3, [addr], [length]’
+ ‘z4, [addr], [length]’
+
+ Remove hardware breakpoint/watchpoint at address addr of size length
+
+ @param *PacketData Pointer to the Payload data for the packet
+
+**/
+VOID
+EFIAPI
+RemoveBreakPoint (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ )
+{
+ UINTN Type;
+ UINTN Address;
+ UINTN Length;
+ UINTN Register;
+ BREAK_TYPE BreakType = NotSupported;
+ EFI_STATUS Status;
+ UINTN ErrorCode;
+
+ //Parse breakpoint packet data
+ ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
+ if (ErrorCode > 0) {
+ SendError ((UINT8)ErrorCode);
+ return;
+ }
+
+ switch (Type) {
+
+ case 0: //Software breakpoint
+ BreakType = SoftwareBreakpoint;
+ break;
+
+ case 1: //Hardware breakpoint
+ BreakType = InstructionExecution;
+ break;
+
+ case 2: //Write watchpoint
+ BreakType = DataWrite;
+ break;
+
+ case 3: //Read watchpoint
+ BreakType = DataRead;
+ break;
+
+ case 4: //Access watchpoint
+ BreakType = DataReadWrite;
+ break;
+
+ default :
+ SendError (GDB_EINVALIDBRKPOINTTYPE);
+ return;
+ }
+
+ //Find matching debug register
+ Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register);
+ if (EFI_ERROR(Status)) {
+
+ if (Status == EFI_UNSUPPORTED) {
+ Print ((CHAR16 *)L"Not supported.\n");
+ SendNotSupported();
+ return;
+ }
+
+ Print ((CHAR16 *)L"No matching register found.\n");
+ SendError (GDB_ENOSPACE);
+ return;
+ }
+
+ //Remove breakpoint
+ Status = DisableDebugRegister(SystemContext, Register);
+ if (EFI_ERROR(Status)) {
+ Print ((CHAR16 *)L"Invalid argument.\n");
+ SendError (GDB_EINVALIDARG);
+ return;
+ }
+
+ SendSuccess ();
+}
+
+
+VOID
+InitializeProcessor (
+ VOID
+ )
+{
+}
+
+BOOLEAN
+ValidateAddress (
+ IN VOID *Address
+ )
+{
+ return TRUE;
+}
+
+BOOLEAN
+ValidateException (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ return TRUE;
+}
+
diff --git a/EmbeddedPkg/GdbStub/SerialIo.c b/EmbeddedPkg/GdbStub/SerialIo.c
index 8fb8610877..2df967a52a 100644
--- a/EmbeddedPkg/GdbStub/SerialIo.c
+++ b/EmbeddedPkg/GdbStub/SerialIo.c
@@ -1,551 +1,551 @@
-/** @file
- Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system
- running GDB. One consle for error information and another console for user input/output.
-
- Basic packet format is $packet-data#checksum. So every comand has 4 bytes of overhead: $,
- #, 0, 0. The 0 and 0 are the ascii characters for the checksum.
-
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 <GdbStubInternal.h>
-
-//
-// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
-// here we need to wait for the periodic callback to do this.
-//
-BOOLEAN gCtrlCBreakFlag = FALSE;
-
-//
-// If the periodic callback is called while we are processing an F packet we need
-// to let the callback know to not read from the serail stream as it could steal
-// characters from the F reponse packet
-//
-BOOLEAN gProcessingFPacket = FALSE;
-
-/**
- Process a control-C break message.
-
- Currently a place holder, remove the ASSERT when it gets implemented.
-
- @param ErrNo Error infomration from the F reply packet or other source
-
-**/
-
-VOID
-GdbCtrlCBreakMessage (
- IN UINTN ErrNo
- )
-{
- // See D.10.5 of gdb.pdf
- // This should look like a break message. Should look like SIGINT
-
- /* TODO: Make sure if we should do anything with ErrNo */
- //Turn on the global Ctrl-C flag.
- gCtrlCBreakFlag = TRUE;
-}
-
-
-/**
- Parse the F reply packet and extract the return value and an ErrNo if it exists.
-
- @param Packet Packet to parse like an F reply packet
- @param ErrNo Buffer to hold Count bytes that were read
-
- @retval -1 Error, not a valid F reply packet
- @retval other Return the return code from the F reply packet
-
-**/
-INTN
-GdbParseFReplyPacket (
- IN CHAR8 *Packet,
- OUT UINTN *ErrNo
- )
-{
- INTN RetCode;
-
- if (Packet[0] != 'F') {
- // A valid responce would be an F packet
- return -1;
- }
-
- RetCode = AsciiStrHexToUintn (&Packet[1]);
-
- // Find 1st comma
- for (;*Packet != '\0' && *Packet != ','; Packet++);
- if (*Packet == '\0') {
- *ErrNo = 0;
- return RetCode;
- }
-
- *ErrNo = AsciiStrHexToUintn (++Packet);
-
- // Find 2nd comma
- for (;*Packet != '\0' && *Packet != ','; Packet++);
- if (*Packet == '\0') {
- return RetCode;
- }
-
- if (*(++Packet) == 'C') {
- GdbCtrlCBreakMessage (*ErrNo);
- }
-
- return RetCode;
-}
-
-
-/**
- Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
- the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
-
- @param FileDescriptor Device to talk to.
- @param Buffer Buffer to hold Count bytes that were read
- @param Count Number of bytes to transfer.
-
- @retval -1 Error
- @retval {other} Number of bytes read.
-
-**/
-INTN
-GdbRead (
- IN INTN FileDescriptor,
- OUT VOID *Buffer,
- IN UINTN Count
- )
-{
- CHAR8 Packet[128];
- UINTN Size;
- INTN RetCode;
- UINTN ErrNo;
- BOOLEAN ReceiveDone = FALSE;
-
- // Send:
- // "Fread,XX,YYYYYYYY,XX
- //
- // XX - FileDescriptor in ASCII
- // YYYYYYYY - Buffer address in ASCII
- // XX - Count in ASCII
- // SS - check sum
- //
- Size = AsciiSPrint (Packet, sizeof (Packet), "Fread,%x,%x,%x", FileDescriptor, Buffer, Count);
- // Packet array is too small if you got this ASSERT
- ASSERT (Size < sizeof (Packet));
-
- gProcessingFPacket = TRUE;
- SendPacket (Packet);
- Print ((CHAR16 *)L"Packet sent..\n");
-
- do {
- // Reply:
- ReceivePacket (Packet, sizeof (Packet));
- Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);
-
- // Process GDB commands
- switch (Packet[0]) {
- //Write memory command.
- //M addr,length:XX...
- case 'M':
- WriteToMemory (Packet);
- break;
-
- //Fretcode, errno, Ctrl-C flag
- //retcode - Count read
- case 'F':
- //Once target receives F reply packet that means the previous
- //transactions are finished.
- ReceiveDone = TRUE;
- break;
-
- //Send empty buffer
- default :
- SendNotSupported();
- break;
- }
- } while (ReceiveDone == FALSE);
-
- RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
- Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);
-
- if (ErrNo > 0) {
- //Send error to the host if there is any.
- SendError ((UINT8)ErrNo);
- }
-
- gProcessingFPacket = FALSE;
-
- return RetCode;
-}
-
-
-/**
- Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
- nothing was written. On error -1 is returned.
-
- @param FileDescriptor Device to talk to.
- @param Buffer Buffer to hold Count bytes that are to be written
- @param Count Number of bytes to transfer.
-
- @retval -1 Error
- @retval {other} Number of bytes written.
-
-**/
-INTN
-GdbWrite (
- IN INTN FileDescriptor,
- OUT CONST VOID *Buffer,
- IN UINTN Count
- )
-{
- CHAR8 Packet[128];
- UINTN Size;
- INTN RetCode;
- UINTN ErrNo;
- BOOLEAN ReceiveDone = FALSE;
-
- // Send:
- // #Fwrite,XX,YYYYYYYY,XX$SS
- //
- // XX - FileDescriptor in ASCII
- // YYYYYYYY - Buffer address in ASCII
- // XX - Count in ASCII
- // SS - check sum
- //
- Size = AsciiSPrint (Packet, sizeof (Packet), "Fwrite,%x,%x,%x", FileDescriptor, Buffer, Count);
- // Packet array is too small if you got this ASSERT
- ASSERT (Size < sizeof (Packet));
-
- SendPacket (Packet);
- Print ((CHAR16 *)L"Packet sent..\n");
-
- do {
- // Reply:
- ReceivePacket (Packet, sizeof (Packet));
- Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);
-
- // Process GDB commands
- switch (Packet[0]) {
- //Read memory command.
- //m addr,length.
- case 'm':
- ReadFromMemory (Packet);
- break;
-
- //Fretcode, errno, Ctrl-C flag
- //retcode - Count read
- case 'F':
- //Once target receives F reply packet that means the previous
- //transactions are finished.
- ReceiveDone = TRUE;
- break;
-
- //Send empty buffer
- default :
- SendNotSupported();
- break;
- }
- } while (ReceiveDone == FALSE);
-
- RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
- Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);
-
- //Send error to the host if there is any.
- if (ErrNo > 0) {
- SendError((UINT8)ErrNo);
- }
-
- return RetCode;
-}
-
-
-/**
- Reset the serial device.
-
- @param This Protocol instance pointer.
-
- @retval EFI_SUCCESS The device was reset.
- @retval EFI_DEVICE_ERROR The serial device could not be reset.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialReset (
- IN EFI_SERIAL_IO_PROTOCOL *This
- )
-{
- return EFI_SUCCESS;
-}
-
-
-/**
- Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
- data buts, and stop bits on a serial device.
-
- @param This Protocol instance pointer.
- @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
- device's default interface speed.
- @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the
- serial interface. A ReceiveFifoDepth value of 0 will use
- the device's dfault FIFO depth.
- @param Timeout The requested time out for a single character in microseconds.
- This timeout applies to both the transmit and receive side of the
- interface. A Timeout value of 0 will use the device's default time
- out value.
- @param Parity The type of parity to use on this serial device. A Parity value of
- DefaultParity will use the device's default parity value.
- @param DataBits The number of data bits to use on the serial device. A DataBits
- vaule of 0 will use the device's default data bit setting.
- @param StopBits The number of stop bits to use on this serial device. A StopBits
- value of DefaultStopBits will use the device's default number of
- stop bits.
-
- @retval EFI_SUCCESS The device was reset.
- @retval EFI_DEVICE_ERROR The serial device could not be reset.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialSetAttributes (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- IN UINT64 BaudRate,
- IN UINT32 ReceiveFifoDepth,
- IN UINT32 Timeout,
- IN EFI_PARITY_TYPE Parity,
- IN UINT8 DataBits,
- IN EFI_STOP_BITS_TYPE StopBits
- )
-{
- return EFI_UNSUPPORTED;
-}
-
-
-/**
- Set the control bits on a serial device
-
- @param This Protocol instance pointer.
- @param Control Set the bits of Control that are settable.
-
- @retval EFI_SUCCESS The new control bits were set on the serial device.
- @retval EFI_UNSUPPORTED The serial device does not support this operation.
- @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialSetControl (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- IN UINT32 Control
- )
-{
- return EFI_UNSUPPORTED;
-}
-
-
-/**
- Retrieves the status of thecontrol bits on a serial device
-
- @param This Protocol instance pointer.
- @param Control A pointer to return the current Control signals from the serial device.
-
- @retval EFI_SUCCESS The control bits were read from the serial device.
- @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialGetControl (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- OUT UINT32 *Control
- )
-{
- return EFI_UNSUPPORTED;
-}
-
-
-/**
- Writes data to a serial device.
-
- @param This Protocol instance pointer.
- @param BufferSize On input, the size of the Buffer. On output, the amount of
- data actually written.
- @param Buffer The buffer of data to write
-
- @retval EFI_SUCCESS The data was written.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_TIMEOUT The data write was stopped due to a timeout.
-
-**/
-EFI_STATUS
-EFIAPI
-GdbSerialWrite (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- IN VOID *Buffer
- )
-{
- GDB_SERIAL_DEV *SerialDev;
- UINTN Return;
-
- SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);
-
- Return = GdbWrite (SerialDev->OutFileDescriptor, Buffer, *BufferSize);
- if (Return == (UINTN)-1) {
- return EFI_DEVICE_ERROR;
- }
-
- if (Return != *BufferSize) {
- *BufferSize = Return;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Writes data to a serial device.
-
- @param This Protocol instance pointer.
- @param BufferSize On input, the size of the Buffer. On output, the amount of
- data returned in Buffer.
- @param Buffer The buffer to return the data into.
-
- @retval EFI_SUCCESS The data was read.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_TIMEOUT The data write was stopped due to a timeout.
-
-**/
-
-EFI_STATUS
-EFIAPI
-GdbSerialRead (
- IN EFI_SERIAL_IO_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- )
-{
- GDB_SERIAL_DEV *SerialDev;
- UINTN Return;
-
- SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);
-
- Return = GdbRead (SerialDev->InFileDescriptor, Buffer, *BufferSize);
- if (Return == (UINTN)-1) {
- return EFI_DEVICE_ERROR;
- }
-
- if (Return != *BufferSize) {
- *BufferSize = Return;
- }
-
- return EFI_SUCCESS;
-}
-
-
-//
-// Template used to initailize the GDB Serial IO protocols
-//
-GDB_SERIAL_DEV gdbSerialDevTemplate = {
- GDB_SERIAL_DEV_SIGNATURE,
- NULL,
-
- { // SerialIo
- SERIAL_IO_INTERFACE_REVISION,
- GdbSerialReset,
- GdbSerialSetAttributes,
- GdbSerialSetControl,
- GdbSerialGetControl,
- GdbSerialWrite,
- GdbSerialRead,
- NULL
- },
- { // SerialMode
- 0, // ControlMask
- 0, // Timeout
- 0, // BaudRate
- 1, // RceiveFifoDepth
- 0, // DataBits
- 0, // Parity
- 0 // StopBits
- },
- {
- {
- HARDWARE_DEVICE_PATH,
- HW_VENDOR_DP,
- {
- (UINT8) (sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)),
- (UINT8) ((sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)) >> 8)
- },
- EFI_SERIAL_IO_PROTOCOL_GUID,
- },
- 0,
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
- (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL)),
- (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL) >> 8)
- }
- },
- },
- GDB_STDIN,
- GDB_STDOUT
-};
-
-
-/**
- Make two serial consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
-
- These console show up on the remote system running GDB
-
-**/
-VOID
-GdbInitializeSerialConsole (
- VOID
- )
-{
- EFI_STATUS Status;
- GDB_SERIAL_DEV *StdOutSerialDev;
- GDB_SERIAL_DEV *StdErrSerialDev;
-
- // Use the template to make a copy of the Serial Console private data structure.
- StdOutSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
- ASSERT (StdOutSerialDev != NULL);
-
- // Fixup pointer after the copy
- StdOutSerialDev->SerialIo.Mode = &StdOutSerialDev->SerialMode;
-
- StdErrSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
- ASSERT (StdErrSerialDev != NULL);
-
- // Fixup pointer and modify stuff that is different for StdError
- StdErrSerialDev->SerialIo.Mode = &StdErrSerialDev->SerialMode;
- StdErrSerialDev->DevicePath.Index = 1;
- StdErrSerialDev->OutFileDescriptor = GDB_STDERR;
-
- // Make a new handle with Serial IO protocol and its device path on it.
- Status = gBS->InstallMultipleProtocolInterfaces (
- &StdOutSerialDev->Handle,
- &gEfiSerialIoProtocolGuid, &StdOutSerialDev->SerialIo,
- &gEfiDevicePathProtocolGuid, &StdOutSerialDev->DevicePath,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- // Make a new handle with Serial IO protocol and its device path on it.
- Status = gBS->InstallMultipleProtocolInterfaces (
- &StdErrSerialDev->Handle,
- &gEfiSerialIoProtocolGuid, &StdErrSerialDev->SerialIo,
- &gEfiDevicePathProtocolGuid, &StdErrSerialDev->DevicePath,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-}
-
+/** @file
+ Serial IO Abstraction for GDB stub. This allows an EFI consoles that shows up on the system
+ running GDB. One consle for error information and another console for user input/output.
+
+ Basic packet format is $packet-data#checksum. So every comand has 4 bytes of overhead: $,
+ #, 0, 0. The 0 and 0 are the ascii characters for the checksum.
+
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 <GdbStubInternal.h>
+
+//
+// Set TRUE if F Reply package signals a ctrl-c. We can not process the Ctrl-c
+// here we need to wait for the periodic callback to do this.
+//
+BOOLEAN gCtrlCBreakFlag = FALSE;
+
+//
+// If the periodic callback is called while we are processing an F packet we need
+// to let the callback know to not read from the serail stream as it could steal
+// characters from the F reponse packet
+//
+BOOLEAN gProcessingFPacket = FALSE;
+
+/**
+ Process a control-C break message.
+
+ Currently a place holder, remove the ASSERT when it gets implemented.
+
+ @param ErrNo Error infomration from the F reply packet or other source
+
+**/
+
+VOID
+GdbCtrlCBreakMessage (
+ IN UINTN ErrNo
+ )
+{
+ // See D.10.5 of gdb.pdf
+ // This should look like a break message. Should look like SIGINT
+
+ /* TODO: Make sure if we should do anything with ErrNo */
+ //Turn on the global Ctrl-C flag.
+ gCtrlCBreakFlag = TRUE;
+}
+
+
+/**
+ Parse the F reply packet and extract the return value and an ErrNo if it exists.
+
+ @param Packet Packet to parse like an F reply packet
+ @param ErrNo Buffer to hold Count bytes that were read
+
+ @retval -1 Error, not a valid F reply packet
+ @retval other Return the return code from the F reply packet
+
+**/
+INTN
+GdbParseFReplyPacket (
+ IN CHAR8 *Packet,
+ OUT UINTN *ErrNo
+ )
+{
+ INTN RetCode;
+
+ if (Packet[0] != 'F') {
+ // A valid responce would be an F packet
+ return -1;
+ }
+
+ RetCode = AsciiStrHexToUintn (&Packet[1]);
+
+ // Find 1st comma
+ for (;*Packet != '\0' && *Packet != ','; Packet++);
+ if (*Packet == '\0') {
+ *ErrNo = 0;
+ return RetCode;
+ }
+
+ *ErrNo = AsciiStrHexToUintn (++Packet);
+
+ // Find 2nd comma
+ for (;*Packet != '\0' && *Packet != ','; Packet++);
+ if (*Packet == '\0') {
+ return RetCode;
+ }
+
+ if (*(++Packet) == 'C') {
+ GdbCtrlCBreakMessage (*ErrNo);
+ }
+
+ return RetCode;
+}
+
+
+/**
+ Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
+ the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
+
+ @param FileDescriptor Device to talk to.
+ @param Buffer Buffer to hold Count bytes that were read
+ @param Count Number of bytes to transfer.
+
+ @retval -1 Error
+ @retval {other} Number of bytes read.
+
+**/
+INTN
+GdbRead (
+ IN INTN FileDescriptor,
+ OUT VOID *Buffer,
+ IN UINTN Count
+ )
+{
+ CHAR8 Packet[128];
+ UINTN Size;
+ INTN RetCode;
+ UINTN ErrNo;
+ BOOLEAN ReceiveDone = FALSE;
+
+ // Send:
+ // "Fread,XX,YYYYYYYY,XX
+ //
+ // XX - FileDescriptor in ASCII
+ // YYYYYYYY - Buffer address in ASCII
+ // XX - Count in ASCII
+ // SS - check sum
+ //
+ Size = AsciiSPrint (Packet, sizeof (Packet), "Fread,%x,%x,%x", FileDescriptor, Buffer, Count);
+ // Packet array is too small if you got this ASSERT
+ ASSERT (Size < sizeof (Packet));
+
+ gProcessingFPacket = TRUE;
+ SendPacket (Packet);
+ Print ((CHAR16 *)L"Packet sent..\n");
+
+ do {
+ // Reply:
+ ReceivePacket (Packet, sizeof (Packet));
+ Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);
+
+ // Process GDB commands
+ switch (Packet[0]) {
+ //Write memory command.
+ //M addr,length:XX...
+ case 'M':
+ WriteToMemory (Packet);
+ break;
+
+ //Fretcode, errno, Ctrl-C flag
+ //retcode - Count read
+ case 'F':
+ //Once target receives F reply packet that means the previous
+ //transactions are finished.
+ ReceiveDone = TRUE;
+ break;
+
+ //Send empty buffer
+ default :
+ SendNotSupported();
+ break;
+ }
+ } while (ReceiveDone == FALSE);
+
+ RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
+ Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);
+
+ if (ErrNo > 0) {
+ //Send error to the host if there is any.
+ SendError ((UINT8)ErrNo);
+ }
+
+ gProcessingFPacket = FALSE;
+
+ return RetCode;
+}
+
+
+/**
+ Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
+ nothing was written. On error -1 is returned.
+
+ @param FileDescriptor Device to talk to.
+ @param Buffer Buffer to hold Count bytes that are to be written
+ @param Count Number of bytes to transfer.
+
+ @retval -1 Error
+ @retval {other} Number of bytes written.
+
+**/
+INTN
+GdbWrite (
+ IN INTN FileDescriptor,
+ OUT CONST VOID *Buffer,
+ IN UINTN Count
+ )
+{
+ CHAR8 Packet[128];
+ UINTN Size;
+ INTN RetCode;
+ UINTN ErrNo;
+ BOOLEAN ReceiveDone = FALSE;
+
+ // Send:
+ // #Fwrite,XX,YYYYYYYY,XX$SS
+ //
+ // XX - FileDescriptor in ASCII
+ // YYYYYYYY - Buffer address in ASCII
+ // XX - Count in ASCII
+ // SS - check sum
+ //
+ Size = AsciiSPrint (Packet, sizeof (Packet), "Fwrite,%x,%x,%x", FileDescriptor, Buffer, Count);
+ // Packet array is too small if you got this ASSERT
+ ASSERT (Size < sizeof (Packet));
+
+ SendPacket (Packet);
+ Print ((CHAR16 *)L"Packet sent..\n");
+
+ do {
+ // Reply:
+ ReceivePacket (Packet, sizeof (Packet));
+ Print ((CHAR16 *)L"Command received..%c\n", Packet[0]);
+
+ // Process GDB commands
+ switch (Packet[0]) {
+ //Read memory command.
+ //m addr,length.
+ case 'm':
+ ReadFromMemory (Packet);
+ break;
+
+ //Fretcode, errno, Ctrl-C flag
+ //retcode - Count read
+ case 'F':
+ //Once target receives F reply packet that means the previous
+ //transactions are finished.
+ ReceiveDone = TRUE;
+ break;
+
+ //Send empty buffer
+ default :
+ SendNotSupported();
+ break;
+ }
+ } while (ReceiveDone == FALSE);
+
+ RetCode = GdbParseFReplyPacket (Packet, &ErrNo);
+ Print ((CHAR16 *)L"RetCode: %x..ErrNo: %x..\n", RetCode, ErrNo);
+
+ //Send error to the host if there is any.
+ if (ErrNo > 0) {
+ SendError((UINT8)ErrNo);
+ }
+
+ return RetCode;
+}
+
+
+/**
+ Reset the serial device.
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The serial device could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+GdbSerialReset (
+ IN EFI_SERIAL_IO_PROTOCOL *This
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
+ data buts, and stop bits on a serial device.
+
+ @param This Protocol instance pointer.
+ @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
+ device's default interface speed.
+ @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the
+ serial interface. A ReceiveFifoDepth value of 0 will use
+ the device's dfault FIFO depth.
+ @param Timeout The requested time out for a single character in microseconds.
+ This timeout applies to both the transmit and receive side of the
+ interface. A Timeout value of 0 will use the device's default time
+ out value.
+ @param Parity The type of parity to use on this serial device. A Parity value of
+ DefaultParity will use the device's default parity value.
+ @param DataBits The number of data bits to use on the serial device. A DataBits
+ vaule of 0 will use the device's default data bit setting.
+ @param StopBits The number of stop bits to use on this serial device. A StopBits
+ value of DefaultStopBits will use the device's default number of
+ stop bits.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The serial device could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+GdbSerialSetAttributes (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT64 BaudRate,
+ IN UINT32 ReceiveFifoDepth,
+ IN UINT32 Timeout,
+ IN EFI_PARITY_TYPE Parity,
+ IN UINT8 DataBits,
+ IN EFI_STOP_BITS_TYPE StopBits
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Set the control bits on a serial device
+
+ @param This Protocol instance pointer.
+ @param Control Set the bits of Control that are settable.
+
+ @retval EFI_SUCCESS The new control bits were set on the serial device.
+ @retval EFI_UNSUPPORTED The serial device does not support this operation.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+GdbSerialSetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT32 Control
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Retrieves the status of thecontrol bits on a serial device
+
+ @param This Protocol instance pointer.
+ @param Control A pointer to return the current Control signals from the serial device.
+
+ @retval EFI_SUCCESS The control bits were read from the serial device.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+GdbSerialGetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ OUT UINT32 *Control
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Writes data to a serial device.
+
+ @param This Protocol instance pointer.
+ @param BufferSize On input, the size of the Buffer. On output, the amount of
+ data actually written.
+ @param Buffer The buffer of data to write
+
+ @retval EFI_SUCCESS The data was written.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+GdbSerialWrite (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ GDB_SERIAL_DEV *SerialDev;
+ UINTN Return;
+
+ SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);
+
+ Return = GdbWrite (SerialDev->OutFileDescriptor, Buffer, *BufferSize);
+ if (Return == (UINTN)-1) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (Return != *BufferSize) {
+ *BufferSize = Return;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Writes data to a serial device.
+
+ @param This Protocol instance pointer.
+ @param BufferSize On input, the size of the Buffer. On output, the amount of
+ data returned in Buffer.
+ @param Buffer The buffer to return the data into.
+
+ @retval EFI_SUCCESS The data was read.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.
+
+**/
+
+EFI_STATUS
+EFIAPI
+GdbSerialRead (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ GDB_SERIAL_DEV *SerialDev;
+ UINTN Return;
+
+ SerialDev = GDB_SERIAL_DEV_FROM_THIS (This);
+
+ Return = GdbRead (SerialDev->InFileDescriptor, Buffer, *BufferSize);
+ if (Return == (UINTN)-1) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (Return != *BufferSize) {
+ *BufferSize = Return;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//
+// Template used to initailize the GDB Serial IO protocols
+//
+GDB_SERIAL_DEV gdbSerialDevTemplate = {
+ GDB_SERIAL_DEV_SIGNATURE,
+ NULL,
+
+ { // SerialIo
+ SERIAL_IO_INTERFACE_REVISION,
+ GdbSerialReset,
+ GdbSerialSetAttributes,
+ GdbSerialSetControl,
+ GdbSerialGetControl,
+ GdbSerialWrite,
+ GdbSerialRead,
+ NULL
+ },
+ { // SerialMode
+ 0, // ControlMask
+ 0, // Timeout
+ 0, // BaudRate
+ 1, // RceiveFifoDepth
+ 0, // DataBits
+ 0, // Parity
+ 0 // StopBits
+ },
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH) + sizeof (UINT32)) >> 8)
+ },
+ EFI_SERIAL_IO_PROTOCOL_GUID,
+ },
+ 0,
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL)),
+ (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL) >> 8)
+ }
+ },
+ },
+ GDB_STDIN,
+ GDB_STDOUT
+};
+
+
+/**
+ Make two serial consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
+
+ These console show up on the remote system running GDB
+
+**/
+VOID
+GdbInitializeSerialConsole (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ GDB_SERIAL_DEV *StdOutSerialDev;
+ GDB_SERIAL_DEV *StdErrSerialDev;
+
+ // Use the template to make a copy of the Serial Console private data structure.
+ StdOutSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
+ ASSERT (StdOutSerialDev != NULL);
+
+ // Fixup pointer after the copy
+ StdOutSerialDev->SerialIo.Mode = &StdOutSerialDev->SerialMode;
+
+ StdErrSerialDev = AllocateCopyPool (sizeof (GDB_SERIAL_DEV), &gdbSerialDevTemplate);
+ ASSERT (StdErrSerialDev != NULL);
+
+ // Fixup pointer and modify stuff that is different for StdError
+ StdErrSerialDev->SerialIo.Mode = &StdErrSerialDev->SerialMode;
+ StdErrSerialDev->DevicePath.Index = 1;
+ StdErrSerialDev->OutFileDescriptor = GDB_STDERR;
+
+ // Make a new handle with Serial IO protocol and its device path on it.
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &StdOutSerialDev->Handle,
+ &gEfiSerialIoProtocolGuid, &StdOutSerialDev->SerialIo,
+ &gEfiDevicePathProtocolGuid, &StdOutSerialDev->DevicePath,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Make a new handle with Serial IO protocol and its device path on it.
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &StdErrSerialDev->Handle,
+ &gEfiSerialIoProtocolGuid, &StdErrSerialDev->SerialIo,
+ &gEfiDevicePathProtocolGuid, &StdErrSerialDev->DevicePath,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/EmbeddedPkg/Include/Library/DebugAgentTimerLib.h b/EmbeddedPkg/Include/Library/DebugAgentTimerLib.h
index 6a363e0002..1b9769509b 100755
--- a/EmbeddedPkg/Include/Library/DebugAgentTimerLib.h
+++ b/EmbeddedPkg/Include/Library/DebugAgentTimerLib.h
@@ -60,4 +60,4 @@ DebugAgentTimerEndOfInterrupt (
#endif
- \ No newline at end of file
+ \ No newline at end of file
diff --git a/EmbeddedPkg/Include/Library/DmaLib.h b/EmbeddedPkg/Include/Library/DmaLib.h
index badaf21361..6e876dd26a 100755
--- a/EmbeddedPkg/Include/Library/DmaLib.h
+++ b/EmbeddedPkg/Include/Library/DmaLib.h
@@ -1,45 +1,45 @@
-/** @file
- DMA abstraction library APIs. Based on UEFI PCI IO protocol DMA abstractions.
- At some point these functions will probably end up in a non PCI protocol
- for embedded systems.
-
+/** @file
+ DMA abstraction library APIs. Based on UEFI PCI IO protocol DMA abstractions.
+ At some point these functions will probably end up in a non PCI protocol
+ for embedded systems.
+
DMA Bus Master Read Operation:
- Call DmaMap() for MapOperationBusMasterRead.
- Program the DMA Bus Master with the DeviceAddress returned by DmaMap().
- Start the DMA Bus Master.
- Wait for DMA Bus Master to complete the read operation.
- Call DmaUnmap().
-
- DMA Bus Master Write Operation:
+ Call DmaMap() for MapOperationBusMasterRead.
+ Program the DMA Bus Master with the DeviceAddress returned by DmaMap().
+ Start the DMA Bus Master.
+ Wait for DMA Bus Master to complete the read operation.
+ Call DmaUnmap().
+
+ DMA Bus Master Write Operation:
Call DmaMap() for MapOperationBusMasterWrite.
Program the DMA Bus Master with the DeviceAddress returned by DmaMap().
Start the DMA Bus Master.
Wait for DMA Bus Master to complete the write operation.
- Call DmaUnmap().
-
- DMA Bus Master Common Buffer Operation:
- Call DmaAllocateBuffer() to allocate a common buffer.
- Call DmaMap() for MapOperationBusMasterCommonBuffer.
- Program the DMA Bus Master with the DeviceAddress returned by DmaMap().
- The common buffer can now be accessed equally by the processor and the DMA bus master.
- Call DmaUnmap().
- Call DmaFreeBuffer().
-
- Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
-
- 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 __DMA_LIB_H__
-#define __DMA_LIB_H__
-
+ Call DmaUnmap().
+
+ DMA Bus Master Common Buffer Operation:
+ Call DmaAllocateBuffer() to allocate a common buffer.
+ Call DmaMap() for MapOperationBusMasterCommonBuffer.
+ Program the DMA Bus Master with the DeviceAddress returned by DmaMap().
+ The common buffer can now be accessed equally by the processor and the DMA bus master.
+ Call DmaUnmap().
+ Call DmaFreeBuffer().
+
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+ 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 __DMA_LIB_H__
+#define __DMA_LIB_H__
+
typedef enum {
///
/// A read operation from system memory by a bus master.
@@ -56,10 +56,10 @@ typedef enum {
MapOperationBusMasterCommonBuffer,
MapOperationMaximum
} DMA_MAP_OPERATION;
-
-
-
-
+
+
+
+
/**
Provides the DMA controller-specific addresses needed to access system memory.
@@ -79,20 +79,20 @@ typedef enum {
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
@retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
-**/
-EFI_STATUS
-EFIAPI
-DmaMap (
- IN DMA_MAP_OPERATION Operation,
+**/
+EFI_STATUS
+EFIAPI
+DmaMap (
+ IN DMA_MAP_OPERATION Operation,
IN VOID *HostAddress,
IN OUT UINTN *NumberOfBytes,
OUT PHYSICAL_ADDRESS *DeviceAddress,
OUT VOID **Mapping
- );
-
-
-
-
+ );
+
+
+
+
/**
Completes the DmaMapBusMasterRead, DmaMapBusMasterWrite, or DmaMapBusMasterCommonBuffer
operation and releases any corresponding resources.
@@ -102,14 +102,14 @@ DmaMap (
@retval EFI_SUCCESS The range was unmapped.
@retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
-**/
-EFI_STATUS
-EFIAPI
-DmaUnmap (
+**/
+EFI_STATUS
+EFIAPI
+DmaUnmap (
IN VOID *Mapping
- );
-
-
+ );
+
+
/**
Allocates pages that are suitable for an DmaMap() of type MapOperationBusMasterCommonBuffer.
mapping.
@@ -126,16 +126,16 @@ DmaUnmap (
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
-**/
-EFI_STATUS
-EFIAPI
-DmaAllocateBuffer (
- IN EFI_MEMORY_TYPE MemoryType,
+**/
+EFI_STATUS
+EFIAPI
+DmaAllocateBuffer (
+ IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
OUT VOID **HostAddress
);
-
-
+
+
/**
Frees memory that was allocated with DmaAllocateBuffer().
@@ -147,13 +147,13 @@ DmaAllocateBuffer (
was not allocated with DmaAllocateBuffer().
**/
-EFI_STATUS
-EFIAPI
-DmaFreeBuffer (
+EFI_STATUS
+EFIAPI
+DmaFreeBuffer (
IN UINTN Pages,
IN VOID *HostAddress
);
-
-
-#endif
-
+
+
+#endif
+
diff --git a/EmbeddedPkg/Include/Library/EblAddExternalCommandLib.h b/EmbeddedPkg/Include/Library/EblAddExternalCommandLib.h
index c00d04f4d4..f760f8e2af 100644
--- a/EmbeddedPkg/Include/Library/EblAddExternalCommandLib.h
+++ b/EmbeddedPkg/Include/Library/EblAddExternalCommandLib.h
@@ -1,122 +1,122 @@
-/** @file
- Include file for basic command line parser for EBL (Embedded Boot Loader)
-
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __EBL_ADD_EXTERNAL_COMMAND_LIB_H__
-#define __EBL_ADD_EXTERNAL_COMMAND_LIB_H__
-
-#include <PiDxe.h>
-#include <Protocol/EblAddCommand.h>
-
-
-EFI_STATUS
-EFIAPI
-EblAddExternalCommands (
- IN const EBL_COMMAND_TABLE *EntryArray,
- IN UINTN ArrayCount
- );
-
-/**
-
- Return a keypress or optionally timeout if a timeout value was passed in.
-
- An optional callback function is called every second when waiting for a
-
- timeout.
-
-
-
- @param Key EFI Key information returned
-
- @param TimeoutInSec Number of seconds to wait to timeout
-
- @param CallBack Callback called every second during the timeout wait
-
-
-
- @return EFI_SUCCESS Key was returned
-
- @return EFI_TIMEOUT If the TimoutInSec expired
-
-
-
-**/
-
-EFI_STATUS
-
-EFIAPI
-
-EblGetCharKey (
-
- IN OUT EFI_INPUT_KEY *Key,
-
- IN UINTN TimeoutInSec,
-
- IN EBL_GET_CHAR_CALL_BACK CallBack OPTIONAL
-
- );
-
-
-
-
-
-/**
-
- This routine is used prevent command output data from scrolling off the end
-
- of the screen. The global gPageBreak is used to turn on or off this feature.
-
- If the CurrentRow is near the end of the screen pause and print out a prompt
-
- If the use hits Q to quit return TRUE else for any other key return FALSE.
-
- PrefixNewline is used to figure out if a newline is needed before the prompt
-
- string. This depends on the last print done before calling this function.
-
- CurrentRow is updated by one on a call or set back to zero if a prompt is
-
- needed.
-
-
-
- @param CurrentRow Used to figure out if its the end of the page and updated
-
- @param PrefixNewline Did previous print issue a newline
-
-
-
- @return TRUE if Q was hit to quit, FALSE in all other cases.
-
-
-
-**/
-
-BOOLEAN
-
-EFIAPI
-
-EblAnyKeyToContinueQtoQuit (
-
- IN UINTN *CurrentRow,
-
- IN BOOLEAN PrefixNewline
-
- );
-
-
-
-#endif
-
+/** @file
+ Include file for basic command line parser for EBL (Embedded Boot Loader)
+
+ Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __EBL_ADD_EXTERNAL_COMMAND_LIB_H__
+#define __EBL_ADD_EXTERNAL_COMMAND_LIB_H__
+
+#include <PiDxe.h>
+#include <Protocol/EblAddCommand.h>
+
+
+EFI_STATUS
+EFIAPI
+EblAddExternalCommands (
+ IN const EBL_COMMAND_TABLE *EntryArray,
+ IN UINTN ArrayCount
+ );
+
+/**
+
+ Return a keypress or optionally timeout if a timeout value was passed in.
+
+ An optional callback function is called every second when waiting for a
+
+ timeout.
+
+
+
+ @param Key EFI Key information returned
+
+ @param TimeoutInSec Number of seconds to wait to timeout
+
+ @param CallBack Callback called every second during the timeout wait
+
+
+
+ @return EFI_SUCCESS Key was returned
+
+ @return EFI_TIMEOUT If the TimoutInSec expired
+
+
+
+**/
+
+EFI_STATUS
+
+EFIAPI
+
+EblGetCharKey (
+
+ IN OUT EFI_INPUT_KEY *Key,
+
+ IN UINTN TimeoutInSec,
+
+ IN EBL_GET_CHAR_CALL_BACK CallBack OPTIONAL
+
+ );
+
+
+
+
+
+/**
+
+ This routine is used prevent command output data from scrolling off the end
+
+ of the screen. The global gPageBreak is used to turn on or off this feature.
+
+ If the CurrentRow is near the end of the screen pause and print out a prompt
+
+ If the use hits Q to quit return TRUE else for any other key return FALSE.
+
+ PrefixNewline is used to figure out if a newline is needed before the prompt
+
+ string. This depends on the last print done before calling this function.
+
+ CurrentRow is updated by one on a call or set back to zero if a prompt is
+
+ needed.
+
+
+
+ @param CurrentRow Used to figure out if its the end of the page and updated
+
+ @param PrefixNewline Did previous print issue a newline
+
+
+
+ @return TRUE if Q was hit to quit, FALSE in all other cases.
+
+
+
+**/
+
+BOOLEAN
+
+EFIAPI
+
+EblAnyKeyToContinueQtoQuit (
+
+ IN UINTN *CurrentRow,
+
+ IN BOOLEAN PrefixNewline
+
+ );
+
+
+
+#endif
+
diff --git a/EmbeddedPkg/Include/Library/EblCmdLib.h b/EmbeddedPkg/Include/Library/EblCmdLib.h
index 8974463c8c..5c21d05f00 100644
--- a/EmbeddedPkg/Include/Library/EblCmdLib.h
+++ b/EmbeddedPkg/Include/Library/EblCmdLib.h
@@ -1,48 +1,48 @@
-/** @file
- Include file for basic command line parser for EBL (Embedded Boot Loader)
-
- Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
- Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __EBL_LIB_H__
-#define __EBL_LIB_H__
-
-#include <PiDxe.h>
-#include <Protocol/EblAddCommand.h>
-
-
-VOID
-EblAddCommand (
- IN const EBL_COMMAND_TABLE *Entry
- );
-
-VOID
-EblAddCommands (
- IN const EBL_COMMAND_TABLE *EntryArray,
- IN UINTN ArrayCount
- );
-
-
-//
-// LIbrary constructor called directly from Ebl Code.
-// This module calls EblAddCommand () or EblAddCommands () to register new commands
-//
-VOID
-EblInitializeExternalCmd (
- VOID
- );
-
-
-
-#endif
-
+/** @file
+ Include file for basic command line parser for EBL (Embedded Boot Loader)
+
+ Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __EBL_LIB_H__
+#define __EBL_LIB_H__
+
+#include <PiDxe.h>
+#include <Protocol/EblAddCommand.h>
+
+
+VOID
+EblAddCommand (
+ IN const EBL_COMMAND_TABLE *Entry
+ );
+
+VOID
+EblAddCommands (
+ IN const EBL_COMMAND_TABLE *EntryArray,
+ IN UINTN ArrayCount
+ );
+
+
+//
+// LIbrary constructor called directly from Ebl Code.
+// This module calls EblAddCommand () or EblAddCommands () to register new commands
+//
+VOID
+EblInitializeExternalCmd (
+ VOID
+ );
+
+
+
+#endif
+
diff --git a/EmbeddedPkg/Include/Library/EblNetworkLib.h b/EmbeddedPkg/Include/Library/EblNetworkLib.h
index c72973b753..9292cf9b0f 100644
--- a/EmbeddedPkg/Include/Library/EblNetworkLib.h
+++ b/EmbeddedPkg/Include/Library/EblNetworkLib.h
@@ -1,68 +1,68 @@
-/** @file
- Abstractions for Ebl network accesses.
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __EBL_NETWORK_LIB_H__
-#define __EBL_NETWORK_LIB_H__
-
-#include <Protocol/PxeBaseCode.h>
-
-
-EFI_STATUS
-EFIAPI
-EblGetCurrentIpAddress (
- IN OUT EFI_IP_ADDRESS *Ip
- );
-
-EFI_STATUS
-EFIAPI
-EblGetCurrentMacAddress (
- IN OUT EFI_MAC_ADDRESS *Mac
- );
-
-CHAR8 *
-EFIAPI
-EblLoadFileBootTypeString (
- IN EFI_HANDLE Handle
- );
-
-EFI_STATUS
-EFIAPI
-EblPerformDHCP (
- IN BOOLEAN SortOffers
- );
-
-EFI_STATUS
-EFIAPI
-EblSetStationIp (
- IN EFI_IP_ADDRESS *NewStationIp, OPTIONAL
- IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL
- );
-
-EFI_STATUS
-EFIAPI
-EblMtftp (
- IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,
- IN OUT VOID *BufferPtr OPTIONAL,
- IN BOOLEAN Overwrite,
- IN OUT UINT64 *BufferSize,
- IN UINTN *BlockSize OPTIONAL,
- IN EFI_IP_ADDRESS *ServerIp,
- IN UINT8 *Filename OPTIONAL,
- IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL,
- IN BOOLEAN DontUseBuffer
- );
-
-#endif
-
+/** @file
+ Abstractions for Ebl network accesses.
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __EBL_NETWORK_LIB_H__
+#define __EBL_NETWORK_LIB_H__
+
+#include <Protocol/PxeBaseCode.h>
+
+
+EFI_STATUS
+EFIAPI
+EblGetCurrentIpAddress (
+ IN OUT EFI_IP_ADDRESS *Ip
+ );
+
+EFI_STATUS
+EFIAPI
+EblGetCurrentMacAddress (
+ IN OUT EFI_MAC_ADDRESS *Mac
+ );
+
+CHAR8 *
+EFIAPI
+EblLoadFileBootTypeString (
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS
+EFIAPI
+EblPerformDHCP (
+ IN BOOLEAN SortOffers
+ );
+
+EFI_STATUS
+EFIAPI
+EblSetStationIp (
+ IN EFI_IP_ADDRESS *NewStationIp, OPTIONAL
+ IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+EblMtftp (
+ IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,
+ IN OUT VOID *BufferPtr OPTIONAL,
+ IN BOOLEAN Overwrite,
+ IN OUT UINT64 *BufferSize,
+ IN UINTN *BlockSize OPTIONAL,
+ IN EFI_IP_ADDRESS *ServerIp,
+ IN UINT8 *Filename OPTIONAL,
+ IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL,
+ IN BOOLEAN DontUseBuffer
+ );
+
+#endif
+
diff --git a/EmbeddedPkg/Include/Library/GdbSerialLib.h b/EmbeddedPkg/Include/Library/GdbSerialLib.h
index 55800b9fc5..6e8eeb4e6f 100644
--- a/EmbeddedPkg/Include/Library/GdbSerialLib.h
+++ b/EmbeddedPkg/Include/Library/GdbSerialLib.h
@@ -1,107 +1,107 @@
-/** @file
- Basic serial IO abstaction for GDB
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __GDB_SERIAL_LIB_H__
-#define __GDB_SERIAL_LIB_H__
-
-
-
-/**
- Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
- data buts, and stop bits on a serial device. This call is optional as the serial
- port will be set up with defaults base on PCD values.
-
- @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
- device's default interface speed.
- @param Parity The type of parity to use on this serial device. A Parity value of
- DefaultParity will use the device's default parity value.
- @param DataBits The number of data bits to use on the serial device. A DataBits
- vaule of 0 will use the device's default data bit setting.
- @param StopBits The number of stop bits to use on this serial device. A StopBits
- value of DefaultStopBits will use the device's default number of
- stop bits.
-
- @retval EFI_SUCCESS The device was configured.
- @retval EFI_DEVICE_ERROR The serial device could not be coonfigured.
-
-**/
-RETURN_STATUS
-EFIAPI
-GdbSerialInit (
- IN UINT64 BaudRate,
- IN UINT8 Parity,
- IN UINT8 DataBits,
- IN UINT8 StopBits
- );
-
-
-/**
- Check to see if a character is available from GDB. Do not read the character as that is
- done via GdbGetChar().
-
- @return TRUE - Character availible
- @return FALSE - Character not availible
-
-**/
-BOOLEAN
-EFIAPI
-GdbIsCharAvailable (
- VOID
- );
-
-/**
- Get a character from GDB. This function must be able to run in interrupt context.
-
- @return A character from GDB
-
-**/
-CHAR8
-EFIAPI
-GdbGetChar (
- VOID
- );
-
-
-/**
- Send a character to GDB. This function must be able to run in interrupt context.
-
-
- @param Char Send a character to GDB
-
-**/
-
-VOID
-EFIAPI
-GdbPutChar (
- IN CHAR8 Char
- );
-
-
-/**
- Send an ASCII string to GDB. This function must be able to run in interrupt context.
-
-
- @param String Send a string to GDB
-
-**/
-
-VOID
-GdbPutString (
- IN CHAR8 *String
- );
-
-
-#endif
-
+/** @file
+ Basic serial IO abstaction for GDB
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __GDB_SERIAL_LIB_H__
+#define __GDB_SERIAL_LIB_H__
+
+
+
+/**
+ Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
+ data buts, and stop bits on a serial device. This call is optional as the serial
+ port will be set up with defaults base on PCD values.
+
+ @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the
+ device's default interface speed.
+ @param Parity The type of parity to use on this serial device. A Parity value of
+ DefaultParity will use the device's default parity value.
+ @param DataBits The number of data bits to use on the serial device. A DataBits
+ vaule of 0 will use the device's default data bit setting.
+ @param StopBits The number of stop bits to use on this serial device. A StopBits
+ value of DefaultStopBits will use the device's default number of
+ stop bits.
+
+ @retval EFI_SUCCESS The device was configured.
+ @retval EFI_DEVICE_ERROR The serial device could not be coonfigured.
+
+**/
+RETURN_STATUS
+EFIAPI
+GdbSerialInit (
+ IN UINT64 BaudRate,
+ IN UINT8 Parity,
+ IN UINT8 DataBits,
+ IN UINT8 StopBits
+ );
+
+
+/**
+ Check to see if a character is available from GDB. Do not read the character as that is
+ done via GdbGetChar().
+
+ @return TRUE - Character availible
+ @return FALSE - Character not availible
+
+**/
+BOOLEAN
+EFIAPI
+GdbIsCharAvailable (
+ VOID
+ );
+
+/**
+ Get a character from GDB. This function must be able to run in interrupt context.
+
+ @return A character from GDB
+
+**/
+CHAR8
+EFIAPI
+GdbGetChar (
+ VOID
+ );
+
+
+/**
+ Send a character to GDB. This function must be able to run in interrupt context.
+
+
+ @param Char Send a character to GDB
+
+**/
+
+VOID
+EFIAPI
+GdbPutChar (
+ IN CHAR8 Char
+ );
+
+
+/**
+ Send an ASCII string to GDB. This function must be able to run in interrupt context.
+
+
+ @param String Send a string to GDB
+
+**/
+
+VOID
+GdbPutString (
+ IN CHAR8 *String
+ );
+
+
+#endif
+
diff --git a/EmbeddedPkg/Include/Library/PrePiLib.h b/EmbeddedPkg/Include/Library/PrePiLib.h
index 444d7e2885..6144513a86 100644
--- a/EmbeddedPkg/Include/Library/PrePiLib.h
+++ b/EmbeddedPkg/Include/Library/PrePiLib.h
@@ -1,790 +1,790 @@
-/** @file
- Library that helps implement monolithic PEI. (SEC goes to DXE)
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __PRE_PI_LIB_H__
-#define __PRE_PI_LIB_H__
-
-#include <Guid/ExtractSection.h>
-
-/**
- This service enables discovery of additional firmware volumes.
-
- @param Instance This instance of the firmware volume to find. The value 0 is the
- Boot Firmware Volume (BFV).
- @param FwVolHeader Pointer to the firmware volume header of the volume to return.
-
- @retval EFI_SUCCESS The volume was found.
- @retval EFI_NOT_FOUND The volume was not found.
- @retval EFI_INVALID_PARAMETER FwVolHeader is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsFindNextVolume (
- IN UINTN Instance,
- IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
- );
-
-
-/**
- This service enables discovery of additional firmware files.
-
- @param SearchType A filter to find files only of this type.
- @param FwVolHeader Pointer to the firmware volume header of the volume to search.
- This parameter must point to a valid FFS volume.
- @param FileHeader Pointer to the current file from which to begin searching.
-
- @retval EFI_SUCCESS The file was found.
- @retval EFI_NOT_FOUND The file was not found.
- @retval EFI_NOT_FOUND The header checksum was not zero.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsFindNextFile (
- IN EFI_FV_FILETYPE SearchType,
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- IN OUT EFI_PEI_FILE_HANDLE *FileHandle
- );
-
-
-/**
- This service enables discovery sections of a given type within a valid FFS file.
-
- @param SearchType The value of the section type to find.
- @param FfsFileHeader A pointer to the file header that contains the set of sections to
- be searched.
- @param SectionData A pointer to the discovered section, if successful.
-
- @retval EFI_SUCCESS The section was found.
- @retval EFI_NOT_FOUND The section was not found.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsFindSectionData (
- IN EFI_SECTION_TYPE SectionType,
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT VOID **SectionData
- );
-
-
-/**
- Find a file in the volume by name
-
- @param FileName A pointer to the name of the file to
- find within the firmware volume.
-
- @param VolumeHandle The firmware volume to search FileHandle
- Upon exit, points to the found file's
- handle or NULL if it could not be found.
-
- @retval EFI_SUCCESS File was found.
-
- @retval EFI_NOT_FOUND File was not found.
-
- @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
- FileName was NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsFindByName (
- IN CONST EFI_GUID *FileName,
- IN CONST EFI_PEI_FV_HANDLE VolumeHandle,
- OUT EFI_PEI_FILE_HANDLE *FileHandle
- );
-
-
-/**
- Get information about the file by name.
-
- @param FileHandle Handle of the file.
-
- @param FileInfo Upon exit, points to the file's
- information.
-
- @retval EFI_SUCCESS File information returned.
-
- @retval EFI_INVALID_PARAMETER If FileHandle does not
- represent a valid file.
-
- @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsGetFileInfo (
- IN CONST EFI_PEI_FILE_HANDLE FileHandle,
- OUT EFI_FV_FILE_INFO *FileInfo
- );
-
-
-/**
- Get Information about the volume by name
-
- @param VolumeHandle Handle of the volume.
-
- @param VolumeInfo Upon exit, points to the volume's
- information.
-
- @retval EFI_SUCCESS File information returned.
-
- @retval EFI_INVALID_PARAMETER If FileHandle does not
- represent a valid file.
-
- @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsGetVolumeInfo (
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- OUT EFI_FV_INFO *VolumeInfo
- );
-
-
-
-/**
- Get Fv image from the FV type file, then add FV & FV2 Hob.
-
- @param FileHandle File handle of a Fv type file.
-
-
- @retval EFI_NOT_FOUND FV image can't be found.
- @retval EFI_SUCCESS Successfully to process it.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsProcessFvFile (
- IN EFI_PEI_FILE_HANDLE FvFileHandle
- );
-
-
-/**
- Search through every FV until you find a file of type FileType
-
- @param FileType File handle of a Fv type file.
- @param Volumehandle On succes Volume Handle of the match
- @param FileHandle On success File Handle of the match
-
- @retval EFI_NOT_FOUND FV image can't be found.
- @retval EFI_SUCCESS Successfully found FileType
-
-**/
-EFI_STATUS
-EFIAPI
-FfsAnyFvFindFirstFile (
- IN EFI_FV_FILETYPE FileType,
- OUT EFI_PEI_FV_HANDLE *VolumeHandle,
- OUT EFI_PEI_FILE_HANDLE *FileHandle
- );
-
-
-/**
- Get Fv image from the FV type file, then add FV & FV2 Hob.
-
- @param FileHandle File handle of a Fv type file.
-
-
- @retval EFI_NOT_FOUND FV image can't be found.
- @retval EFI_SUCCESS Successfully to process it.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsProcessFvFile (
- IN EFI_PEI_FILE_HANDLE FvFileHandle
- );
-
-
-/**
- This service enables PEIMs to ascertain the present value of the boot mode.
-
-
- @retval BootMode
-
-**/
-EFI_BOOT_MODE
-EFIAPI
-GetBootMode (
- VOID
- );
-
-
-/**
- This service enables PEIMs to update the boot mode variable.
-
- @param BootMode The value of the boot mode to set.
-
- @retval EFI_SUCCESS The value was successfully updated
-
-**/
-EFI_STATUS
-EFIAPI
-SetBootMode (
- IN EFI_BOOT_MODE BootMode
- );
-
-/**
- This service enables a PEIM to ascertain the address of the list of HOBs in memory.
-
- @param HobList A pointer to the list of HOBs that the PEI Foundation will initialize.
-
- @retval EFI_SUCCESS The list was successfully returned.
- @retval EFI_NOT_AVAILABLE_YET The HOB list is not yet published.
-
-**/
-VOID *
-EFIAPI
-GetHobList (
- VOID
- );
-
-
-/**
- Updates the pointer to the HOB list.
-
- @param HobList Hob list pointer to store
-
-**/
-EFI_STATUS
-EFIAPI
-SetHobList (
- IN VOID *HobList
- );
-
-EFI_HOB_HANDOFF_INFO_TABLE*
-HobConstructor (
- IN VOID *EfiMemoryBegin,
- IN UINTN EfiMemoryLength,
- IN VOID *EfiFreeMemoryBottom,
- IN VOID *EfiFreeMemoryTop
- );
-
-/**
- Retrieves the magic value from the PE/COFF header.
-
- @param Hdr The buffer in which to return the PE32, PE32+, or TE header.
-
- @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32
- @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+
-
-**/
-VOID
-CreateHobList (
- IN VOID *MemoryBegin,
- IN UINTN MemoryLength,
- IN VOID *HobBase,
- IN VOID *StackBase
- );
-
-
-/**
- This service enables PEIMs to create various types of HOBs.
-
- @param Type The type of HOB to be installed.
- @param Length The length of the HOB to be added.
-
- @retval !NULL The HOB was successfully created.
- @retval NULL There is no additional space for HOB creation.
-
-**/
-VOID *
-CreateHob (
- IN UINT16 HobType,
- IN UINT16 HobLenght
- );
-
-
-/**
- Returns the next instance of a HOB type from the starting HOB.
-
- This function searches the first instance of a HOB type from the starting HOB pointer.
- If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
- In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
- unconditionally: it returns HobStart back if HobStart itself meets the requirement;
- caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
- If HobStart is NULL, then ASSERT().
-
- @param Type The HOB type to return.
- @param HobStart The starting HOB pointer to search from.
-
- @return The next instance of a HOB type from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetNextHob (
- IN UINT16 Type,
- IN CONST VOID *HobStart
- );
-
-/**
- Returns the first instance of a HOB type among the whole HOB list.
-
- This function searches the first instance of a HOB type among the whole HOB list.
- If there does not exist such HOB type in the HOB list, it will return NULL.
-
- @param Type The HOB type to return.
-
- @return The next instance of a HOB type from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetFirstHob (
- IN UINT16 Type
- );
-
-/**
- This function searches the first instance of a HOB from the starting HOB pointer.
- Such HOB should satisfy two conditions:
- its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
- If there does not exist such HOB from the starting HOB pointer, it will return NULL.
- Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
- to extract the data section and its size info respectively.
- In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
- unconditionally: it returns HobStart back if HobStart itself meets the requirement;
- caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
- If Guid is NULL, then ASSERT().
- If HobStart is NULL, then ASSERT().
-
- @param Guid The GUID to match with in the HOB list.
- @param HobStart A pointer to a Guid.
-
- @return The next instance of the matched GUID HOB from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetNextGuidHob (
- IN CONST EFI_GUID *Guid,
- IN CONST VOID *HobStart
- );
-
-/**
- This function searches the first instance of a HOB among the whole HOB list.
- Such HOB should satisfy two conditions:
- its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
- If there does not exist such HOB from the starting HOB pointer, it will return NULL.
- Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
- to extract the data section and its size info respectively.
- If Guid is NULL, then ASSERT().
-
- @param Guid The GUID to match with in the HOB list.
-
- @return The first instance of the matched GUID HOB among the whole HOB list.
-
-**/
-VOID *
-EFIAPI
-GetFirstGuidHob (
- IN CONST EFI_GUID *Guid
- );
-
-
-/**
- Builds a HOB for a loaded PE32 module.
-
- This function builds a HOB for a loaded PE32 module.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If ModuleName is NULL, then ASSERT().
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ModuleName The GUID File Name of the module.
- @param MemoryAllocationModule The 64 bit physical address of the module.
- @param ModuleLength The length of the module in bytes.
- @param EntryPoint The 64 bit physical address of the module entry point.
-
-**/
-VOID
-EFIAPI
-BuildModuleHob (
- IN CONST EFI_GUID *ModuleName,
- IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
- IN UINT64 ModuleLength,
- IN EFI_PHYSICAL_ADDRESS EntryPoint
- );
-
-/**
- Builds a HOB that describes a chunk of system memory.
-
- This function builds a HOB that describes a chunk of system memory.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ResourceType The type of resource described by this HOB.
- @param ResourceAttribute The resource attributes of the memory described by this HOB.
- @param PhysicalStart The 64 bit physical address of memory described by this HOB.
- @param NumberOfBytes The length of the memory described by this HOB in bytes.
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorHob (
- IN EFI_RESOURCE_TYPE ResourceType,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes
- );
-
-/**
- Builds a GUID HOB with a certain data length.
-
- This function builds a customized HOB tagged with a GUID for identification
- and returns the start address of GUID HOB data so that caller can fill the customized data.
- The HOB Header and Name field is already stripped.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If Guid is NULL, then ASSERT().
- If there is no additional space for HOB creation, then ASSERT().
- If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
-
- @param Guid The GUID to tag the customized HOB.
- @param DataLength The size of the data payload for the GUID HOB.
-
- @return The start address of GUID HOB data.
-
-**/
-VOID *
-EFIAPI
-BuildGuidHob (
- IN CONST EFI_GUID *Guid,
- IN UINTN DataLength
- );
-
-/**
- Copies a data buffer to a newly-built HOB.
-
- This function builds a customized HOB tagged with a GUID for identification,
- copies the input data to the HOB data field and returns the start address of the GUID HOB data.
- The HOB Header and Name field is already stripped.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If Guid is NULL, then ASSERT().
- If Data is NULL and DataLength > 0, then ASSERT().
- If there is no additional space for HOB creation, then ASSERT().
- If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
-
- @param Guid The GUID to tag the customized HOB.
- @param Data The data to be copied into the data field of the GUID HOB.
- @param DataLength The size of the data payload for the GUID HOB.
-
- @return The start address of GUID HOB data.
-
-**/
-VOID *
-EFIAPI
-BuildGuidDataHob (
- IN CONST EFI_GUID *Guid,
- IN VOID *Data,
- IN UINTN DataLength
- );
-
-/**
- Builds a Firmware Volume HOB.
-
- This function builds a Firmware Volume HOB.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The base address of the Firmware Volume.
- @param Length The size of the Firmware Volume in bytes.
-
-**/
-VOID
-EFIAPI
-BuildFvHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- );
-
-/**
- Builds a Firmware Volume HOB and a resrouce descriptor hob
-
- This function builds a Firmware Volume HOB.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The base address of the Firmware Volume.
- @param Length The size of the Firmware Volume in bytes.
-
-**/
-VOID
-EFIAPI
-BuildFvHobs (
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute OPTIONAL
- );
-
-
-/**
- Builds a EFI_HOB_TYPE_FV2 HOB.
-
- This function builds a EFI_HOB_TYPE_FV2 HOB.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The base address of the Firmware Volume.
- @param Length The size of the Firmware Volume in bytes.
- @param FvName The name of the Firmware Volume.
- @param FileName The name of the file.
-
-**/
-VOID
-EFIAPI
-BuildFv2Hob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length,
- IN CONST EFI_GUID *FvName,
- IN CONST EFI_GUID *FileName
- );
-
-/**
- Builds a Capsule Volume HOB.
-
- This function builds a Capsule Volume HOB.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The base address of the Capsule Volume.
- @param Length The size of the Capsule Volume in bytes.
-
-**/
-VOID
-EFIAPI
-BuildCvHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- );
-
-/**
- Builds a HOB for the CPU.
-
- This function builds a HOB for the CPU.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
- @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
-
-**/
-VOID
-EFIAPI
-BuildCpuHob (
- IN UINT8 SizeOfMemorySpace,
- IN UINT8 SizeOfIoSpace
- );
-
-/**
- Builds a HOB for the Stack.
-
- This function builds a HOB for the stack.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The 64 bit physical address of the Stack.
- @param Length The length of the stack in bytes.
-
-**/
-VOID
-EFIAPI
-BuildStackHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- );
-
-/**
- Update the Stack Hob if the stack has been moved
-
- @param BaseAddress The 64 bit physical address of the Stack.
- @param Length The length of the stack in bytes.
-
-**/
-VOID
-UpdateStackHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- );
-
-
-/**
- Builds a HOB for the BSP store.
-
- This function builds a HOB for BSP store.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The 64 bit physical address of the BSP.
- @param Length The length of the BSP store in bytes.
- @param MemoryType Type of memory allocated by this HOB.
-
-**/
-VOID
-EFIAPI
-BuildBspStoreHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length,
- IN EFI_MEMORY_TYPE MemoryType
- );
-
-/**
- Builds a HOB for the memory allocation.
-
- This function builds a HOB for the memory allocation.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The 64 bit physical address of the memory.
- @param Length The length of the memory allocation in bytes.
- @param MemoryType Type of memory allocated by this HOB.
-
-**/
-VOID
-EFIAPI
-BuildMemoryAllocationHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length,
- IN EFI_MEMORY_TYPE MemoryType
- );
-
-
-VOID
-EFIAPI
-BuildExtractSectionHob (
- IN EFI_GUID *Guid,
- IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER SectionGetInfo,
- IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER SectionExtraction
- );
-
-VOID
-EFIAPI
-BuildPeCoffLoaderHob (
- VOID
- );
-
-
-/**
- Allocates one or more 4KB pages of type EfiBootServicesData.
-
- Allocates the number of 4KB pages of MemoryType and returns a pointer to the
- allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
- is returned. If there is not enough memory remaining to satisfy the request, then NULL is
- returned.
-
- @param Pages The number of 4 KB pages to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocatePages (
- IN UINTN Pages
- );
-
-/**
- Allocates a buffer of type EfiBootServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
- pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
- returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocatePool (
- IN UINTN AllocationSize
- );
-
-
-/**
- Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
-
- Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
- alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
- returned. If there is not enough memory at the specified alignment remaining to satisfy the
- request, then NULL is returned.
- If Alignment is not a power of two and Alignment is not zero, then ASSERT().
-
- @param Pages The number of 4 KB pages to allocate.
- @param Alignment The requested alignment of the allocation. Must be a power of two.
- If Alignment is zero, then byte alignment is used.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateAlignedPages (
- IN UINTN Pages,
- IN UINTN Alignment
- );
-
-
-EFI_STATUS
-EFIAPI
-LoadPeCoffImage (
- IN VOID *PeCoffImage,
- OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
- OUT UINT64 *ImageSize,
- OUT EFI_PHYSICAL_ADDRESS *EntryPoint
- );
-
-EFI_STATUS
-EFIAPI
-LoadDxeCoreFromFfsFile (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN UINTN StackSize
- );
-
-EFI_STATUS
-EFIAPI
-LoadDxeCoreFromFv (
- IN UINTN *FvInstance, OPTIONAL
- IN UINTN StackSize
- );
-
-EFI_STATUS
-EFIAPI
-DecompressFirstFv (
- VOID
- );
-
-VOID
-EFIAPI
-AddDxeCoreReportStatusCodeCallback (
- VOID
- );
-
-
-#endif
+/** @file
+ Library that helps implement monolithic PEI. (SEC goes to DXE)
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __PRE_PI_LIB_H__
+#define __PRE_PI_LIB_H__
+
+#include <Guid/ExtractSection.h>
+
+/**
+ This service enables discovery of additional firmware volumes.
+
+ @param Instance This instance of the firmware volume to find. The value 0 is the
+ Boot Firmware Volume (BFV).
+ @param FwVolHeader Pointer to the firmware volume header of the volume to return.
+
+ @retval EFI_SUCCESS The volume was found.
+ @retval EFI_NOT_FOUND The volume was not found.
+ @retval EFI_INVALID_PARAMETER FwVolHeader is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindNextVolume (
+ IN UINTN Instance,
+ IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ );
+
+
+/**
+ This service enables discovery of additional firmware files.
+
+ @param SearchType A filter to find files only of this type.
+ @param FwVolHeader Pointer to the firmware volume header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ @param FileHeader Pointer to the current file from which to begin searching.
+
+ @retval EFI_SUCCESS The file was found.
+ @retval EFI_NOT_FOUND The file was not found.
+ @retval EFI_NOT_FOUND The header checksum was not zero.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindNextFile (
+ IN EFI_FV_FILETYPE SearchType,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ );
+
+
+/**
+ This service enables discovery sections of a given type within a valid FFS file.
+
+ @param SearchType The value of the section type to find.
+ @param FfsFileHeader A pointer to the file header that contains the set of sections to
+ be searched.
+ @param SectionData A pointer to the discovered section, if successful.
+
+ @retval EFI_SUCCESS The section was found.
+ @retval EFI_NOT_FOUND The section was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindSectionData (
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **SectionData
+ );
+
+
+/**
+ Find a file in the volume by name
+
+ @param FileName A pointer to the name of the file to
+ find within the firmware volume.
+
+ @param VolumeHandle The firmware volume to search FileHandle
+ Upon exit, points to the found file's
+ handle or NULL if it could not be found.
+
+ @retval EFI_SUCCESS File was found.
+
+ @retval EFI_NOT_FOUND File was not found.
+
+ @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
+ FileName was NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindByName (
+ IN CONST EFI_GUID *FileName,
+ IN CONST EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ );
+
+
+/**
+ Get information about the file by name.
+
+ @param FileHandle Handle of the file.
+
+ @param FileInfo Upon exit, points to the file's
+ information.
+
+ @retval EFI_SUCCESS File information returned.
+
+ @retval EFI_INVALID_PARAMETER If FileHandle does not
+ represent a valid file.
+
+ @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsGetFileInfo (
+ IN CONST EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_FV_FILE_INFO *FileInfo
+ );
+
+
+/**
+ Get Information about the volume by name
+
+ @param VolumeHandle Handle of the volume.
+
+ @param VolumeInfo Upon exit, points to the volume's
+ information.
+
+ @retval EFI_SUCCESS File information returned.
+
+ @retval EFI_INVALID_PARAMETER If FileHandle does not
+ represent a valid file.
+
+ @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsGetVolumeInfo (
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_FV_INFO *VolumeInfo
+ );
+
+
+
+/**
+ Get Fv image from the FV type file, then add FV & FV2 Hob.
+
+ @param FileHandle File handle of a Fv type file.
+
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully to process it.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsProcessFvFile (
+ IN EFI_PEI_FILE_HANDLE FvFileHandle
+ );
+
+
+/**
+ Search through every FV until you find a file of type FileType
+
+ @param FileType File handle of a Fv type file.
+ @param Volumehandle On succes Volume Handle of the match
+ @param FileHandle On success File Handle of the match
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully found FileType
+
+**/
+EFI_STATUS
+EFIAPI
+FfsAnyFvFindFirstFile (
+ IN EFI_FV_FILETYPE FileType,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ );
+
+
+/**
+ Get Fv image from the FV type file, then add FV & FV2 Hob.
+
+ @param FileHandle File handle of a Fv type file.
+
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully to process it.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsProcessFvFile (
+ IN EFI_PEI_FILE_HANDLE FvFileHandle
+ );
+
+
+/**
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+
+ @retval BootMode
+
+**/
+EFI_BOOT_MODE
+EFIAPI
+GetBootMode (
+ VOID
+ );
+
+
+/**
+ This service enables PEIMs to update the boot mode variable.
+
+ @param BootMode The value of the boot mode to set.
+
+ @retval EFI_SUCCESS The value was successfully updated
+
+**/
+EFI_STATUS
+EFIAPI
+SetBootMode (
+ IN EFI_BOOT_MODE BootMode
+ );
+
+/**
+ This service enables a PEIM to ascertain the address of the list of HOBs in memory.
+
+ @param HobList A pointer to the list of HOBs that the PEI Foundation will initialize.
+
+ @retval EFI_SUCCESS The list was successfully returned.
+ @retval EFI_NOT_AVAILABLE_YET The HOB list is not yet published.
+
+**/
+VOID *
+EFIAPI
+GetHobList (
+ VOID
+ );
+
+
+/**
+ Updates the pointer to the HOB list.
+
+ @param HobList Hob list pointer to store
+
+**/
+EFI_STATUS
+EFIAPI
+SetHobList (
+ IN VOID *HobList
+ );
+
+EFI_HOB_HANDOFF_INFO_TABLE*
+HobConstructor (
+ IN VOID *EfiMemoryBegin,
+ IN UINTN EfiMemoryLength,
+ IN VOID *EfiFreeMemoryBottom,
+ IN VOID *EfiFreeMemoryTop
+ );
+
+/**
+ Retrieves the magic value from the PE/COFF header.
+
+ @param Hdr The buffer in which to return the PE32, PE32+, or TE header.
+
+ @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32
+ @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+
+
+**/
+VOID
+CreateHobList (
+ IN VOID *MemoryBegin,
+ IN UINTN MemoryLength,
+ IN VOID *HobBase,
+ IN VOID *StackBase
+ );
+
+
+/**
+ This service enables PEIMs to create various types of HOBs.
+
+ @param Type The type of HOB to be installed.
+ @param Length The length of the HOB to be added.
+
+ @retval !NULL The HOB was successfully created.
+ @retval NULL There is no additional space for HOB creation.
+
+**/
+VOID *
+CreateHob (
+ IN UINT16 HobType,
+ IN UINT16 HobLenght
+ );
+
+
+/**
+ Returns the next instance of a HOB type from the starting HOB.
+
+ This function searches the first instance of a HOB type from the starting HOB pointer.
+ If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
+ In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+ unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+ caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+ If HobStart is NULL, then ASSERT().
+
+ @param Type The HOB type to return.
+ @param HobStart The starting HOB pointer to search from.
+
+ @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextHob (
+ IN UINT16 Type,
+ IN CONST VOID *HobStart
+ );
+
+/**
+ Returns the first instance of a HOB type among the whole HOB list.
+
+ This function searches the first instance of a HOB type among the whole HOB list.
+ If there does not exist such HOB type in the HOB list, it will return NULL.
+
+ @param Type The HOB type to return.
+
+ @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetFirstHob (
+ IN UINT16 Type
+ );
+
+/**
+ This function searches the first instance of a HOB from the starting HOB pointer.
+ Such HOB should satisfy two conditions:
+ its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
+ If there does not exist such HOB from the starting HOB pointer, it will return NULL.
+ Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+ to extract the data section and its size info respectively.
+ In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+ unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+ caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+ If Guid is NULL, then ASSERT().
+ If HobStart is NULL, then ASSERT().
+
+ @param Guid The GUID to match with in the HOB list.
+ @param HobStart A pointer to a Guid.
+
+ @return The next instance of the matched GUID HOB from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextGuidHob (
+ IN CONST EFI_GUID *Guid,
+ IN CONST VOID *HobStart
+ );
+
+/**
+ This function searches the first instance of a HOB among the whole HOB list.
+ Such HOB should satisfy two conditions:
+ its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
+ If there does not exist such HOB from the starting HOB pointer, it will return NULL.
+ Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+ to extract the data section and its size info respectively.
+ If Guid is NULL, then ASSERT().
+
+ @param Guid The GUID to match with in the HOB list.
+
+ @return The first instance of the matched GUID HOB among the whole HOB list.
+
+**/
+VOID *
+EFIAPI
+GetFirstGuidHob (
+ IN CONST EFI_GUID *Guid
+ );
+
+
+/**
+ Builds a HOB for a loaded PE32 module.
+
+ This function builds a HOB for a loaded PE32 module.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If ModuleName is NULL, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ModuleName The GUID File Name of the module.
+ @param MemoryAllocationModule The 64 bit physical address of the module.
+ @param ModuleLength The length of the module in bytes.
+ @param EntryPoint The 64 bit physical address of the module entry point.
+
+**/
+VOID
+EFIAPI
+BuildModuleHob (
+ IN CONST EFI_GUID *ModuleName,
+ IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
+ IN UINT64 ModuleLength,
+ IN EFI_PHYSICAL_ADDRESS EntryPoint
+ );
+
+/**
+ Builds a HOB that describes a chunk of system memory.
+
+ This function builds a HOB that describes a chunk of system memory.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes
+ );
+
+/**
+ Builds a GUID HOB with a certain data length.
+
+ This function builds a customized HOB tagged with a GUID for identification
+ and returns the start address of GUID HOB data so that caller can fill the customized data.
+ The HOB Header and Name field is already stripped.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If Guid is NULL, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+ If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+ @param Guid The GUID to tag the customized HOB.
+ @param DataLength The size of the data payload for the GUID HOB.
+
+ @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidHob (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN DataLength
+ );
+
+/**
+ Copies a data buffer to a newly-built HOB.
+
+ This function builds a customized HOB tagged with a GUID for identification,
+ copies the input data to the HOB data field and returns the start address of the GUID HOB data.
+ The HOB Header and Name field is already stripped.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If Guid is NULL, then ASSERT().
+ If Data is NULL and DataLength > 0, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+ If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+ @param Guid The GUID to tag the customized HOB.
+ @param Data The data to be copied into the data field of the GUID HOB.
+ @param DataLength The size of the data payload for the GUID HOB.
+
+ @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidDataHob (
+ IN CONST EFI_GUID *Guid,
+ IN VOID *Data,
+ IN UINTN DataLength
+ );
+
+/**
+ Builds a Firmware Volume HOB.
+
+ This function builds a Firmware Volume HOB.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Firmware Volume.
+ @param Length The size of the Firmware Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildFvHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ );
+
+/**
+ Builds a Firmware Volume HOB and a resrouce descriptor hob
+
+ This function builds a Firmware Volume HOB.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Firmware Volume.
+ @param Length The size of the Firmware Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildFvHobs (
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute OPTIONAL
+ );
+
+
+/**
+ Builds a EFI_HOB_TYPE_FV2 HOB.
+
+ This function builds a EFI_HOB_TYPE_FV2 HOB.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Firmware Volume.
+ @param Length The size of the Firmware Volume in bytes.
+ @param FvName The name of the Firmware Volume.
+ @param FileName The name of the file.
+
+**/
+VOID
+EFIAPI
+BuildFv2Hob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN CONST EFI_GUID *FvName,
+ IN CONST EFI_GUID *FileName
+ );
+
+/**
+ Builds a Capsule Volume HOB.
+
+ This function builds a Capsule Volume HOB.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Capsule Volume.
+ @param Length The size of the Capsule Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildCvHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ );
+
+/**
+ Builds a HOB for the CPU.
+
+ This function builds a HOB for the CPU.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
+ @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
+
+**/
+VOID
+EFIAPI
+BuildCpuHob (
+ IN UINT8 SizeOfMemorySpace,
+ IN UINT8 SizeOfIoSpace
+ );
+
+/**
+ Builds a HOB for the Stack.
+
+ This function builds a HOB for the stack.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The 64 bit physical address of the Stack.
+ @param Length The length of the stack in bytes.
+
+**/
+VOID
+EFIAPI
+BuildStackHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ );
+
+/**
+ Update the Stack Hob if the stack has been moved
+
+ @param BaseAddress The 64 bit physical address of the Stack.
+ @param Length The length of the stack in bytes.
+
+**/
+VOID
+UpdateStackHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ );
+
+
+/**
+ Builds a HOB for the BSP store.
+
+ This function builds a HOB for BSP store.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The 64 bit physical address of the BSP.
+ @param Length The length of the BSP store in bytes.
+ @param MemoryType Type of memory allocated by this HOB.
+
+**/
+VOID
+EFIAPI
+BuildBspStoreHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_MEMORY_TYPE MemoryType
+ );
+
+/**
+ Builds a HOB for the memory allocation.
+
+ This function builds a HOB for the memory allocation.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The 64 bit physical address of the memory.
+ @param Length The length of the memory allocation in bytes.
+ @param MemoryType Type of memory allocated by this HOB.
+
+**/
+VOID
+EFIAPI
+BuildMemoryAllocationHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_MEMORY_TYPE MemoryType
+ );
+
+
+VOID
+EFIAPI
+BuildExtractSectionHob (
+ IN EFI_GUID *Guid,
+ IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER SectionGetInfo,
+ IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER SectionExtraction
+ );
+
+VOID
+EFIAPI
+BuildPeCoffLoaderHob (
+ VOID
+ );
+
+
+/**
+ Allocates one or more 4KB pages of type EfiBootServicesData.
+
+ Allocates the number of 4KB pages of MemoryType and returns a pointer to the
+ allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
+ is returned. If there is not enough memory remaining to satisfy the request, then NULL is
+ returned.
+
+ @param Pages The number of 4 KB pages to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePages (
+ IN UINTN Pages
+ );
+
+/**
+ Allocates a buffer of type EfiBootServicesData.
+
+ Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
+ pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocatePool (
+ IN UINTN AllocationSize
+ );
+
+
+/**
+ Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
+
+ Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
+ alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
+ returned. If there is not enough memory at the specified alignment remaining to satisfy the
+ request, then NULL is returned.
+ If Alignment is not a power of two and Alignment is not zero, then ASSERT().
+
+ @param Pages The number of 4 KB pages to allocate.
+ @param Alignment The requested alignment of the allocation. Must be a power of two.
+ If Alignment is zero, then byte alignment is used.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAlignedPages (
+ IN UINTN Pages,
+ IN UINTN Alignment
+ );
+
+
+EFI_STATUS
+EFIAPI
+LoadPeCoffImage (
+ IN VOID *PeCoffImage,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
+ OUT UINT64 *ImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint
+ );
+
+EFI_STATUS
+EFIAPI
+LoadDxeCoreFromFfsFile (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN UINTN StackSize
+ );
+
+EFI_STATUS
+EFIAPI
+LoadDxeCoreFromFv (
+ IN UINTN *FvInstance, OPTIONAL
+ IN UINTN StackSize
+ );
+
+EFI_STATUS
+EFIAPI
+DecompressFirstFv (
+ VOID
+ );
+
+VOID
+EFIAPI
+AddDxeCoreReportStatusCodeCallback (
+ VOID
+ );
+
+
+#endif
diff --git a/EmbeddedPkg/Include/Library/SerialPortExtLib.h b/EmbeddedPkg/Include/Library/SerialPortExtLib.h
index 74f5e4c58c..a12847ca94 100644
--- a/EmbeddedPkg/Include/Library/SerialPortExtLib.h
+++ b/EmbeddedPkg/Include/Library/SerialPortExtLib.h
@@ -1,66 +1,66 @@
-/** @file
-
- Copyright (c) 2012, ARM Ltd. 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 __SERIAL_PORT_EXT_LIB_H__
-#define __SERIAL_PORT_EXT_LIB_H__
-
-#include <Uefi/UefiBaseType.h>
-#include <Protocol/SerialIo.h>
-
-/**
- Set the serial device control bits.
-
- @return Always return EFI_UNSUPPORTED.
-
-**/
-RETURN_STATUS
-EFIAPI
-SerialPortSetControl (
- IN UINT32 Control
- );
-
-/**
- Get the serial device control bits.
-
- @param Control Control signals read from the serial device.
-
- @retval EFI_SUCCESS The control bits were read from the serial device.
- @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
-
-**/
-RETURN_STATUS
-EFIAPI
-SerialPortGetControl (
- OUT UINT32 *Control
- );
-
-/**
- Set the serial device attributes.
-
- @return Always return EFI_UNSUPPORTED.
-
-**/
-RETURN_STATUS
-EFIAPI
-SerialPortSetAttributes (
- IN UINT64 BaudRate,
- IN UINT32 ReceiveFifoDepth,
- IN UINT32 Timeout,
- IN EFI_PARITY_TYPE Parity,
- IN UINT8 DataBits,
- IN EFI_STOP_BITS_TYPE StopBits
- );
-
-#endif
-
+/** @file
+
+ Copyright (c) 2012, ARM Ltd. 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 __SERIAL_PORT_EXT_LIB_H__
+#define __SERIAL_PORT_EXT_LIB_H__
+
+#include <Uefi/UefiBaseType.h>
+#include <Protocol/SerialIo.h>
+
+/**
+ Set the serial device control bits.
+
+ @return Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+ IN UINT32 Control
+ );
+
+/**
+ Get the serial device control bits.
+
+ @param Control Control signals read from the serial device.
+
+ @retval EFI_SUCCESS The control bits were read from the serial device.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+ OUT UINT32 *Control
+ );
+
+/**
+ Set the serial device attributes.
+
+ @return Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+ IN UINT64 BaudRate,
+ IN UINT32 ReceiveFifoDepth,
+ IN UINT32 Timeout,
+ IN EFI_PARITY_TYPE Parity,
+ IN UINT8 DataBits,
+ IN EFI_STOP_BITS_TYPE StopBits
+ );
+
+#endif
+
diff --git a/EmbeddedPkg/Include/Protocol/EblAddCommand.h b/EmbeddedPkg/Include/Protocol/EblAddCommand.h
index 1ce5a8f3bf..a7809b27b3 100644
--- a/EmbeddedPkg/Include/Protocol/EblAddCommand.h
+++ b/EmbeddedPkg/Include/Protocol/EblAddCommand.h
@@ -73,11 +73,11 @@ VOID
);
-typedef
-VOID
-(EFIAPI *EBL_GET_CHAR_CALL_BACK) (
- IN UINTN ElapsedTime
- );
+typedef
+VOID
+(EFIAPI *EBL_GET_CHAR_CALL_BACK) (
+ IN UINTN ElapsedTime
+ );
/**
Return a keypress or optionally timeout if a timeout value was passed in.
diff --git a/EmbeddedPkg/Include/Protocol/EmbeddedExternalDevice.h b/EmbeddedPkg/Include/Protocol/EmbeddedExternalDevice.h
index 17188f04aa..603dc5ed86 100644
--- a/EmbeddedPkg/Include/Protocol/EmbeddedExternalDevice.h
+++ b/EmbeddedPkg/Include/Protocol/EmbeddedExternalDevice.h
@@ -1,94 +1,94 @@
-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __EMBEDDED_EXTERNAL_DEVICE_H__
-#define __EMBEDDED_EXTERNAL_DEVICE_H__
-
-//
-// Protocol GUID
-//
-#define EMBEDDED_EXTERNAL_DEVICE_PROTOCOL_GUID { 0x735F8C64, 0xD696, 0x44D0, { 0xBD, 0xF2, 0x44, 0x7F, 0xD0, 0x5A, 0x54, 0x06 }}
-
-//
-// Protocol interface structure
-//
-typedef struct _EMBEDDED_EXTERNAL_DEVICE EMBEDDED_EXTERNAL_DEVICE;
-
-//
-// Function Prototypes
-//
-typedef
-EFI_STATUS
-(EFIAPI *EMBEDDED_EXTERNAL_DEVICE_READ) (
- IN EMBEDDED_EXTERNAL_DEVICE *This,
- IN UINTN Register,
- IN UINTN Length,
- OUT VOID *Buffer
- )
-/*++
-
-Routine Description:
-
- Read a set of contiguous external device registers.
-
-Arguments:
-
- This - pointer to protocol
- Offset - starting register number
- Length - number of bytes to read
- Buffer - destination buffer
-
-Returns:
-
- EFI_SUCCESS - registers read successfully
-
---*/
-;
-
-typedef
-EFI_STATUS
-(EFIAPI *EMBEDDED_EXTERNAL_DEVICE_WRITE) (
- IN EMBEDDED_EXTERNAL_DEVICE *This,
- IN UINTN Register,
- IN UINTN Length,
- IN VOID *Buffer
- )
-/*++
-
-Routine Description:
-
- Write to a set of contiguous external device registers.
-
-Arguments:
-
- This - pointer to protocol
- Offset - starting register number
- Length - number of bytes to write
- Buffer - source buffer
-
-Returns:
-
- EFI_SUCCESS - registers written successfully
-
---*/
-;
-
-struct _EMBEDDED_EXTERNAL_DEVICE {
- EMBEDDED_EXTERNAL_DEVICE_READ Read;
- EMBEDDED_EXTERNAL_DEVICE_WRITE Write;
-};
-
-extern EFI_GUID gEmbeddedExternalDeviceProtocolGuid;
-
-#endif // __EMBEDDED_EXTERNAL_DEVICE_H__
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __EMBEDDED_EXTERNAL_DEVICE_H__
+#define __EMBEDDED_EXTERNAL_DEVICE_H__
+
+//
+// Protocol GUID
+//
+#define EMBEDDED_EXTERNAL_DEVICE_PROTOCOL_GUID { 0x735F8C64, 0xD696, 0x44D0, { 0xBD, 0xF2, 0x44, 0x7F, 0xD0, 0x5A, 0x54, 0x06 }}
+
+//
+// Protocol interface structure
+//
+typedef struct _EMBEDDED_EXTERNAL_DEVICE EMBEDDED_EXTERNAL_DEVICE;
+
+//
+// Function Prototypes
+//
+typedef
+EFI_STATUS
+(EFIAPI *EMBEDDED_EXTERNAL_DEVICE_READ) (
+ IN EMBEDDED_EXTERNAL_DEVICE *This,
+ IN UINTN Register,
+ IN UINTN Length,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Read a set of contiguous external device registers.
+
+Arguments:
+
+ This - pointer to protocol
+ Offset - starting register number
+ Length - number of bytes to read
+ Buffer - destination buffer
+
+Returns:
+
+ EFI_SUCCESS - registers read successfully
+
+--*/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *EMBEDDED_EXTERNAL_DEVICE_WRITE) (
+ IN EMBEDDED_EXTERNAL_DEVICE *This,
+ IN UINTN Register,
+ IN UINTN Length,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Write to a set of contiguous external device registers.
+
+Arguments:
+
+ This - pointer to protocol
+ Offset - starting register number
+ Length - number of bytes to write
+ Buffer - source buffer
+
+Returns:
+
+ EFI_SUCCESS - registers written successfully
+
+--*/
+;
+
+struct _EMBEDDED_EXTERNAL_DEVICE {
+ EMBEDDED_EXTERNAL_DEVICE_READ Read;
+ EMBEDDED_EXTERNAL_DEVICE_WRITE Write;
+};
+
+extern EFI_GUID gEmbeddedExternalDeviceProtocolGuid;
+
+#endif // __EMBEDDED_EXTERNAL_DEVICE_H__
diff --git a/EmbeddedPkg/Include/Protocol/EmbeddedGpio.h b/EmbeddedPkg/Include/Protocol/EmbeddedGpio.h
index 97a9a8bd9d..77ea7ad034 100644
--- a/EmbeddedPkg/Include/Protocol/EmbeddedGpio.h
+++ b/EmbeddedPkg/Include/Protocol/EmbeddedGpio.h
@@ -1,167 +1,167 @@
-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __EMBEDDED_GPIO_H__
-#define __EMBEDDED_GPIO_H__
-
-//
-// Protocol interface structure
-//
-typedef struct _EMBEDDED_GPIO EMBEDDED_GPIO;
-
-//
-// Data Types
-//
-typedef UINTN EMBEDDED_GPIO_PIN;
-
-#define GPIO(Port, Pin) ((EMBEDDED_GPIO_PIN)(((Port) << (16)) | (Pin)))
-#define GPIO_PIN(x) ((EMBEDDED_GPIO_PIN)(x) & (0xFFFF))
-#define GPIO_PORT(x) ((EMBEDDED_GPIO_PIN)(x) >> (16))
-
-typedef enum {
- GPIO_MODE_INPUT = 0x00,
- GPIO_MODE_OUTPUT_0 = 0x0E,
- GPIO_MODE_OUTPUT_1 = 0x0F,
- GPIO_MODE_SPECIAL_FUNCTION_2 = 0x02,
- GPIO_MODE_SPECIAL_FUNCTION_3 = 0x03,
- GPIO_MODE_SPECIAL_FUNCTION_4 = 0x04,
- GPIO_MODE_SPECIAL_FUNCTION_5 = 0x05,
- GPIO_MODE_SPECIAL_FUNCTION_6 = 0x06,
- GPIO_MODE_SPECIAL_FUNCTION_7 = 0x07
-} EMBEDDED_GPIO_MODE;
-
-typedef enum {
- GPIO_PULL_NONE,
- GPIO_PULL_UP,
- GPIO_PULL_DOWN
-} EMBEDDED_GPIO_PULL;
-
-//
-// Function Prototypes
-//
-typedef
-EFI_STATUS
-(EFIAPI *EMBEDDED_GPIO_GET) (
- IN EMBEDDED_GPIO *This,
- IN EMBEDDED_GPIO_PIN Gpio,
- OUT UINTN *Value
- );
-/*++
-
-Routine Description:
-
- Gets the state of a GPIO pin
-
-Arguments:
-
- This - pointer to protocol
- Gpio - which pin to read
- Value - state of the pin
-
-Returns:
-
- EFI_SUCCESS - GPIO state returned in Value
-
---*/
-
-
-typedef
-EFI_STATUS
-(EFIAPI *EMBEDDED_GPIO_SET) (
- IN EMBEDDED_GPIO *This,
- IN EMBEDDED_GPIO_PIN Gpio,
- IN EMBEDDED_GPIO_MODE Mode
- );
-/*++
-
-Routine Description:
-
- Sets the state of a GPIO pin
-
-Arguments:
-
- This - pointer to protocol
- Gpio - which pin to modify
- Mode - mode to set
-
-Returns:
-
- EFI_SUCCESS - GPIO set as requested
-
---*/
-
-
-typedef
-EFI_STATUS
-(EFIAPI *EMBEDDED_GPIO_GET_MODE) (
- IN EMBEDDED_GPIO *This,
- IN EMBEDDED_GPIO_PIN Gpio,
- OUT EMBEDDED_GPIO_MODE *Mode
- );
-/*++
-
-Routine Description:
-
- Gets the mode (function) of a GPIO pin
-
-Arguments:
-
- This - pointer to protocol
- Gpio - which pin
- Mode - pointer to output mode value
-
-Returns:
-
- EFI_SUCCESS - mode value retrieved
-
---*/
-
-
-typedef
-EFI_STATUS
-(EFIAPI *EMBEDDED_GPIO_SET_PULL) (
- IN EMBEDDED_GPIO *This,
- IN EMBEDDED_GPIO_PIN Gpio,
- IN EMBEDDED_GPIO_PULL Direction
- );
-/*++
-
-Routine Description:
-
- Sets the pull-up / pull-down resistor of a GPIO pin
-
-Arguments:
-
- This - pointer to protocol
- Gpio - which pin
- Direction - pull-up, pull-down, or none
-
-Returns:
-
- EFI_SUCCESS - pin was set
-
---*/
-
-
-
-struct _EMBEDDED_GPIO {
- EMBEDDED_GPIO_GET Get;
- EMBEDDED_GPIO_SET Set;
- EMBEDDED_GPIO_GET_MODE GetMode;
- EMBEDDED_GPIO_SET_PULL SetPull;
-};
-
-extern EFI_GUID gEmbeddedGpioProtocolGuid;
-
-#endif
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __EMBEDDED_GPIO_H__
+#define __EMBEDDED_GPIO_H__
+
+//
+// Protocol interface structure
+//
+typedef struct _EMBEDDED_GPIO EMBEDDED_GPIO;
+
+//
+// Data Types
+//
+typedef UINTN EMBEDDED_GPIO_PIN;
+
+#define GPIO(Port, Pin) ((EMBEDDED_GPIO_PIN)(((Port) << (16)) | (Pin)))
+#define GPIO_PIN(x) ((EMBEDDED_GPIO_PIN)(x) & (0xFFFF))
+#define GPIO_PORT(x) ((EMBEDDED_GPIO_PIN)(x) >> (16))
+
+typedef enum {
+ GPIO_MODE_INPUT = 0x00,
+ GPIO_MODE_OUTPUT_0 = 0x0E,
+ GPIO_MODE_OUTPUT_1 = 0x0F,
+ GPIO_MODE_SPECIAL_FUNCTION_2 = 0x02,
+ GPIO_MODE_SPECIAL_FUNCTION_3 = 0x03,
+ GPIO_MODE_SPECIAL_FUNCTION_4 = 0x04,
+ GPIO_MODE_SPECIAL_FUNCTION_5 = 0x05,
+ GPIO_MODE_SPECIAL_FUNCTION_6 = 0x06,
+ GPIO_MODE_SPECIAL_FUNCTION_7 = 0x07
+} EMBEDDED_GPIO_MODE;
+
+typedef enum {
+ GPIO_PULL_NONE,
+ GPIO_PULL_UP,
+ GPIO_PULL_DOWN
+} EMBEDDED_GPIO_PULL;
+
+//
+// Function Prototypes
+//
+typedef
+EFI_STATUS
+(EFIAPI *EMBEDDED_GPIO_GET) (
+ IN EMBEDDED_GPIO *This,
+ IN EMBEDDED_GPIO_PIN Gpio,
+ OUT UINTN *Value
+ );
+/*++
+
+Routine Description:
+
+ Gets the state of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin to read
+ Value - state of the pin
+
+Returns:
+
+ EFI_SUCCESS - GPIO state returned in Value
+
+--*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EMBEDDED_GPIO_SET) (
+ IN EMBEDDED_GPIO *This,
+ IN EMBEDDED_GPIO_PIN Gpio,
+ IN EMBEDDED_GPIO_MODE Mode
+ );
+/*++
+
+Routine Description:
+
+ Sets the state of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin to modify
+ Mode - mode to set
+
+Returns:
+
+ EFI_SUCCESS - GPIO set as requested
+
+--*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EMBEDDED_GPIO_GET_MODE) (
+ IN EMBEDDED_GPIO *This,
+ IN EMBEDDED_GPIO_PIN Gpio,
+ OUT EMBEDDED_GPIO_MODE *Mode
+ );
+/*++
+
+Routine Description:
+
+ Gets the mode (function) of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin
+ Mode - pointer to output mode value
+
+Returns:
+
+ EFI_SUCCESS - mode value retrieved
+
+--*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EMBEDDED_GPIO_SET_PULL) (
+ IN EMBEDDED_GPIO *This,
+ IN EMBEDDED_GPIO_PIN Gpio,
+ IN EMBEDDED_GPIO_PULL Direction
+ );
+/*++
+
+Routine Description:
+
+ Sets the pull-up / pull-down resistor of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin
+ Direction - pull-up, pull-down, or none
+
+Returns:
+
+ EFI_SUCCESS - pin was set
+
+--*/
+
+
+
+struct _EMBEDDED_GPIO {
+ EMBEDDED_GPIO_GET Get;
+ EMBEDDED_GPIO_SET Set;
+ EMBEDDED_GPIO_GET_MODE GetMode;
+ EMBEDDED_GPIO_SET_PULL SetPull;
+};
+
+extern EFI_GUID gEmbeddedGpioProtocolGuid;
+
+#endif
diff --git a/EmbeddedPkg/Include/fdt.h b/EmbeddedPkg/Include/fdt.h
index 6e7a8b3973..3b7c37102d 100644
--- a/EmbeddedPkg/Include/fdt.h
+++ b/EmbeddedPkg/Include/fdt.h
@@ -1,74 +1,74 @@
-/** @file
-*
-* Copyright (c) 2011-2012, ARM Limited. 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 _FDT_H
-#define _FDT_H
-
-#ifndef __ASSEMBLY__
-
-struct fdt_header {
- uint32_t magic; /* magic word FDT_MAGIC */
- uint32_t totalsize; /* total size of DT block */
- uint32_t off_dt_struct; /* offset to structure */
- uint32_t off_dt_strings; /* offset to strings */
- uint32_t off_mem_rsvmap; /* offset to memory reserve map */
- uint32_t version; /* format version */
- uint32_t last_comp_version; /* last compatible version */
-
- /* version 2 fields below */
- uint32_t boot_cpuid_phys; /* Which physical CPU id we're
- booting on */
- /* version 3 fields below */
- uint32_t size_dt_strings; /* size of the strings block */
-
- /* version 17 fields below */
- uint32_t size_dt_struct; /* size of the structure block */
-};
-
-struct fdt_reserve_entry {
- uint64_t address;
- uint64_t size;
-};
-
-struct fdt_node_header {
- uint32_t tag;
- char name[0];
-};
-
-struct fdt_property {
- uint32_t tag;
- uint32_t len;
- uint32_t nameoff;
- char data[0];
-};
-
-#endif /* !__ASSEMBLY */
-
-#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
-#define FDT_TAGSIZE sizeof(uint32_t)
-
-#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
-#define FDT_END_NODE 0x2 /* End node */
-#define FDT_PROP 0x3 /* Property: name off,
- size, content */
-#define FDT_NOP 0x4 /* nop */
-#define FDT_END 0x9
-
-#define FDT_V1_SIZE (7*sizeof(uint32_t))
-#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t))
-#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t))
-#define FDT_V16_SIZE FDT_V3_SIZE
-#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t))
-
-#endif /* _FDT_H */
+/** @file
+*
+* Copyright (c) 2011-2012, ARM Limited. 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 _FDT_H
+#define _FDT_H
+
+#ifndef __ASSEMBLY__
+
+struct fdt_header {
+ uint32_t magic; /* magic word FDT_MAGIC */
+ uint32_t totalsize; /* total size of DT block */
+ uint32_t off_dt_struct; /* offset to structure */
+ uint32_t off_dt_strings; /* offset to strings */
+ uint32_t off_mem_rsvmap; /* offset to memory reserve map */
+ uint32_t version; /* format version */
+ uint32_t last_comp_version; /* last compatible version */
+
+ /* version 2 fields below */
+ uint32_t boot_cpuid_phys; /* Which physical CPU id we're
+ booting on */
+ /* version 3 fields below */
+ uint32_t size_dt_strings; /* size of the strings block */
+
+ /* version 17 fields below */
+ uint32_t size_dt_struct; /* size of the structure block */
+};
+
+struct fdt_reserve_entry {
+ uint64_t address;
+ uint64_t size;
+};
+
+struct fdt_node_header {
+ uint32_t tag;
+ char name[0];
+};
+
+struct fdt_property {
+ uint32_t tag;
+ uint32_t len;
+ uint32_t nameoff;
+ char data[0];
+};
+
+#endif /* !__ASSEMBLY */
+
+#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
+#define FDT_TAGSIZE sizeof(uint32_t)
+
+#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
+#define FDT_END_NODE 0x2 /* End node */
+#define FDT_PROP 0x3 /* Property: name off,
+ size, content */
+#define FDT_NOP 0x4 /* nop */
+#define FDT_END 0x9
+
+#define FDT_V1_SIZE (7*sizeof(uint32_t))
+#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t))
+#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t))
+#define FDT_V16_SIZE FDT_V3_SIZE
+#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t))
+
+#endif /* _FDT_H */
diff --git a/EmbeddedPkg/Include/libfdt.h b/EmbeddedPkg/Include/libfdt.h
index 73f49759a5..85fe324c4d 100644
--- a/EmbeddedPkg/Include/libfdt.h
+++ b/EmbeddedPkg/Include/libfdt.h
@@ -1,1478 +1,1478 @@
-#ifndef _LIBFDT_H
-#define _LIBFDT_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <libfdt_env.h>
-#include <fdt.h>
-
-#define FDT_FIRST_SUPPORTED_VERSION 0x10
-#define FDT_LAST_SUPPORTED_VERSION 0x11
-
-/* Error codes: informative error codes */
-#define FDT_ERR_NOTFOUND 1
- /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
-#define FDT_ERR_EXISTS 2
- /* FDT_ERR_EXISTS: Attemped to create a node or property which
- * already exists */
-#define FDT_ERR_NOSPACE 3
- /* FDT_ERR_NOSPACE: Operation needed to expand the device
- * tree, but its buffer did not have sufficient space to
- * contain the expanded tree. Use fdt_open_into() to move the
- * device tree to a buffer with more space. */
-
-/* Error codes: codes for bad parameters */
-#define FDT_ERR_BADOFFSET 4
- /* FDT_ERR_BADOFFSET: Function was passed a structure block
- * offset which is out-of-bounds, or which points to an
- * unsuitable part of the structure for the operation. */
-#define FDT_ERR_BADPATH 5
- /* FDT_ERR_BADPATH: Function was passed a badly formatted path
- * (e.g. missing a leading / for a function which requires an
- * absolute path) */
-#define FDT_ERR_BADPHANDLE 6
- /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
- * value. phandle values of 0 and -1 are not permitted. */
-#define FDT_ERR_BADSTATE 7
- /* FDT_ERR_BADSTATE: Function was passed an incomplete device
- * tree created by the sequential-write functions, which is
- * not sufficiently complete for the requested operation. */
-
-/* Error codes: codes for bad device tree blobs */
-#define FDT_ERR_TRUNCATED 8
- /* FDT_ERR_TRUNCATED: Structure block of the given device tree
- * ends without an FDT_END tag. */
-#define FDT_ERR_BADMAGIC 9
- /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
- * device tree at all - it is missing the flattened device
- * tree magic number. */
-#define FDT_ERR_BADVERSION 10
- /* FDT_ERR_BADVERSION: Given device tree has a version which
- * can't be handled by the requested operation. For
- * read-write functions, this may mean that fdt_open_into() is
- * required to convert the tree to the expected version. */
-#define FDT_ERR_BADSTRUCTURE 11
- /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
- * structure block or other serious error (e.g. misnested
- * nodes, or subnodes preceding properties). */
-#define FDT_ERR_BADLAYOUT 12
- /* FDT_ERR_BADLAYOUT: For read-write functions, the given
- * device tree has it's sub-blocks in an order that the
- * function can't handle (memory reserve map, then structure,
- * then strings). Use fdt_open_into() to reorganize the tree
- * into a form suitable for the read-write operations. */
-
-/* "Can't happen" error indicating a bug in libfdt */
-#define FDT_ERR_INTERNAL 13
- /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
- * Should never be returned, if it is, it indicates a bug in
- * libfdt itself. */
-
-#define FDT_ERR_MAX 13
-
-/**********************************************************************/
-/* Low-level functions (you probably don't need these) */
-/**********************************************************************/
-
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
-static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
-{
- return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
-}
-
-uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
-
-/**********************************************************************/
-/* Traversal functions */
-/**********************************************************************/
-
-int fdt_next_node(const void *fdt, int offset, int *depth);
-
-/**********************************************************************/
-/* General functions */
-/**********************************************************************/
-
-#define fdt_get_header(fdt, field) \
- (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
-#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
-#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
-#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
-#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
-#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
-#define fdt_version(fdt) (fdt_get_header(fdt, version))
-#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
-#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
-#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
-#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
-
-#define __fdt_set_hdr(name) \
- static inline void fdt_set_##name(void *fdt, uint32_t val) \
- { \
- struct fdt_header *fdth = (struct fdt_header*)fdt; \
- fdth->name = cpu_to_fdt32(val); \
- }
-__fdt_set_hdr(magic);
-__fdt_set_hdr(totalsize);
-__fdt_set_hdr(off_dt_struct);
-__fdt_set_hdr(off_dt_strings);
-__fdt_set_hdr(off_mem_rsvmap);
-__fdt_set_hdr(version);
-__fdt_set_hdr(last_comp_version);
-__fdt_set_hdr(boot_cpuid_phys);
-__fdt_set_hdr(size_dt_strings);
-__fdt_set_hdr(size_dt_struct);
-#undef __fdt_set_hdr
-
-/**
- * fdt_check_header - sanity check a device tree or possible device tree
- * @fdt: pointer to data which might be a flattened device tree
- *
- * fdt_check_header() checks that the given buffer contains what
- * appears to be a flattened device tree with sane information in its
- * header.
- *
- * returns:
- * 0, if the buffer appears to contain a valid device tree
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings, as above
- */
-int fdt_check_header(const void *fdt);
-
-/**
- * fdt_move - move a device tree around in memory
- * @fdt: pointer to the device tree to move
- * @buf: pointer to memory where the device is to be moved
- * @bufsize: size of the memory space at buf
- *
- * fdt_move() relocates, if possible, the device tree blob located at
- * fdt to the buffer at buf of size bufsize. The buffer may overlap
- * with the existing device tree blob at fdt. Therefore,
- * fdt_move(fdt, fdt, fdt_totalsize(fdt))
- * should always succeed.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_move(const void *fdt, void *buf, int bufsize);
-
-/**********************************************************************/
-/* Read-only functions */
-/**********************************************************************/
-
-/**
- * fdt_string - retrieve a string from the strings block of a device tree
- * @fdt: pointer to the device tree blob
- * @stroffset: offset of the string within the strings block (native endian)
- *
- * fdt_string() retrieves a pointer to a single string from the
- * strings block of the device tree blob at fdt.
- *
- * returns:
- * a pointer to the string, on success
- * NULL, if stroffset is out of bounds
- */
-const char *fdt_string(const void *fdt, int stroffset);
-
-/**
- * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
- * @fdt: pointer to the device tree blob
- *
- * Returns the number of entries in the device tree blob's memory
- * reservation map. This does not include the terminating 0,0 entry
- * or any other (0,0) entries reserved for expansion.
- *
- * returns:
- * the number of entries
- */
-int fdt_num_mem_rsv(const void *fdt);
-
-/**
- * fdt_get_mem_rsv - retrieve one memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @address, @size: pointers to 64-bit variables
- *
- * On success, *address and *size will contain the address and size of
- * the n-th reserve map entry from the device tree blob, in
- * native-endian format.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
-
-/**
- * fdt_subnode_offset_namelen - find a subnode based on substring
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- * @namelen: number of characters of name to consider
- *
- * Identical to fdt_subnode_offset(), but only examine the first
- * namelen characters of name for matching the subnode name. This is
- * useful for finding subnodes based on a portion of a larger string,
- * such as a full path.
- */
-int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
- const char *name, int namelen);
-/**
- * fdt_subnode_offset - find a subnode of a given node
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- *
- * fdt_subnode_offset() finds a subnode of the node at structure block
- * offset parentoffset with the given name. name may include a unit
- * address, in which case fdt_subnode_offset() will find the subnode
- * with that unit address, or the unit address may be omitted, in
- * which case fdt_subnode_offset() will find an arbitrary subnode
- * whose name excluding unit address matches the given name.
- *
- * returns:
- * structure block offset of the requested subnode (>=0), on success
- * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
-
-/**
- * fdt_path_offset - find a tree node by its full path
- * @fdt: pointer to the device tree blob
- * @path: full path of the node to locate
- *
- * fdt_path_offset() finds a node of a given path in the device tree.
- * Each path component may omit the unit address portion, but the
- * results of this are undefined if any such path component is
- * ambiguous (that is if there are multiple nodes at the relevant
- * level matching the given component, differentiated only by unit
- * address).
- *
- * returns:
- * structure block offset of the node with the requested path (>=0), on success
- * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
- * -FDT_ERR_NOTFOUND, if the requested node does not exist
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_path_offset(const void *fdt, const char *path);
-
-/**
- * fdt_get_name - retrieve the name of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of the starting node
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_get_name() retrieves the name (including unit address) of the
- * device tree node at structure block offset nodeoffset. If lenp is
- * non-NULL, the length of this name is also returned, in the integer
- * pointed to by lenp.
- *
- * returns:
- * pointer to the node's name, on success
- * If lenp is non-NULL, *lenp contains the length of that name (>=0)
- * NULL, on error
- * if lenp is non-NULL *lenp contains an error code (<0):
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings
- */
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
-
-/**
- * fdt_first_property_offset - find the offset of a node's first property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of a node
- *
- * fdt_first_property_offset() finds the first property of the node at
- * the given structure block offset.
- *
- * returns:
- * structure block offset of the property (>=0), on success
- * -FDT_ERR_NOTFOUND, if the requested node has no properties
- * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_first_property_offset(const void *fdt, int nodeoffset);
-
-/**
- * fdt_next_property_offset - step through a node's properties
- * @fdt: pointer to the device tree blob
- * @offset: structure block offset of a property
- *
- * fdt_next_property_offset() finds the property immediately after the
- * one at the given structure block offset. This will be a property
- * of the same node as the given property.
- *
- * returns:
- * structure block offset of the next property (>=0), on success
- * -FDT_ERR_NOTFOUND, if the given property is the last in its node
- * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_next_property_offset(const void *fdt, int offset);
-
-/**
- * fdt_get_property_by_offset - retrieve the property at a given offset
- * @fdt: pointer to the device tree blob
- * @offset: offset of the property to retrieve
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_get_property_by_offset() retrieves a pointer to the
- * fdt_property structure within the device tree blob at the given
- * offset. If lenp is non-NULL, the length of the property value is
- * also returned, in the integer pointed to by lenp.
- *
- * returns:
- * pointer to the structure representing the property
- * if lenp is non-NULL, *lenp contains the length of the property
- * value (>=0)
- * NULL, on error
- * if lenp is non-NULL, *lenp contains an error code (<0):
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
- int offset,
- int *lenp);
-
-/**
- * fdt_get_property_namelen - find a property based on substring
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @namelen: number of characters of name to consider
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * Identical to fdt_get_property_namelen(), but only examine the first
- * namelen characters of name for matching the property name.
- */
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
- int nodeoffset,
- const char *name,
- int namelen, int *lenp);
-
-/**
- * fdt_get_property - find a given property in a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_get_property() retrieves a pointer to the fdt_property
- * structure within the device tree blob corresponding to the property
- * named 'name' of the node at offset nodeoffset. If lenp is
- * non-NULL, the length of the property value is also returned, in the
- * integer pointed to by lenp.
- *
- * returns:
- * pointer to the structure representing the property
- * if lenp is non-NULL, *lenp contains the length of the property
- * value (>=0)
- * NULL, on error
- * if lenp is non-NULL, *lenp contains an error code (<0):
- * -FDT_ERR_NOTFOUND, node does not have named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
- const char *name, int *lenp);
-static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
- const char *name,
- int *lenp)
-{
- return (struct fdt_property *)(uintptr_t)
- fdt_get_property(fdt, nodeoffset, name, lenp);
-}
-
-/**
- * fdt_getprop_by_offset - retrieve the value of a property at a given offset
- * @fdt: pointer to the device tree blob
- * @ffset: offset of the property to read
- * @namep: pointer to a string variable (will be overwritten) or NULL
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_getprop_by_offset() retrieves a pointer to the value of the
- * property at structure block offset 'offset' (this will be a pointer
- * to within the device blob itself, not a copy of the value). If
- * lenp is non-NULL, the length of the property value is also
- * returned, in the integer pointed to by lenp. If namep is non-NULL,
- * the property's namne will also be returned in the char * pointed to
- * by namep (this will be a pointer to within the device tree's string
- * block, not a new copy of the name).
- *
- * returns:
- * pointer to the property's value
- * if lenp is non-NULL, *lenp contains the length of the property
- * value (>=0)
- * if namep is non-NULL *namep contiains a pointer to the property
- * name.
- * NULL, on error
- * if lenp is non-NULL, *lenp contains an error code (<0):
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-const void *fdt_getprop_by_offset(const void *fdt, int offset,
- const char **namep, int *lenp);
-
-/**
- * fdt_getprop_namelen - get property value based on substring
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @namelen: number of characters of name to consider
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * Identical to fdt_getprop(), but only examine the first namelen
- * characters of name for matching the property name.
- */
-const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
- const char *name, int namelen, int *lenp);
-
-/**
- * fdt_getprop - retrieve the value of a given property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to find
- * @name: name of the property to find
- * @lenp: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_getprop() retrieves a pointer to the value of the property
- * named 'name' of the node at offset nodeoffset (this will be a
- * pointer to within the device blob itself, not a copy of the value).
- * If lenp is non-NULL, the length of the property value is also
- * returned, in the integer pointed to by lenp.
- *
- * returns:
- * pointer to the property's value
- * if lenp is non-NULL, *lenp contains the length of the property
- * value (>=0)
- * NULL, on error
- * if lenp is non-NULL, *lenp contains an error code (<0):
- * -FDT_ERR_NOTFOUND, node does not have named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-const void *fdt_getprop(const void *fdt, int nodeoffset,
- const char *name, int *lenp);
-static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
- const char *name, int *lenp)
-{
- return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
-}
-
-/**
- * fdt_get_phandle - retrieve the phandle of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of the node
- *
- * fdt_get_phandle() retrieves the phandle of the device tree node at
- * structure block offset nodeoffset.
- *
- * returns:
- * the phandle of the node at nodeoffset, on success (!= 0, != -1)
- * 0, if the node has no phandle, or another error occurs
- */
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
-
-/**
- * fdt_get_alias_namelen - get alias based on substring
- * @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
- * @namelen: number of characters of name to consider
- *
- * Identical to fdt_get_alias(), but only examine the first namelen
- * characters of name for matching the alias name.
- */
-const char *fdt_get_alias_namelen(const void *fdt,
- const char *name, int namelen);
-
-/**
- * fdt_get_alias - retreive the path referenced by a given alias
- * @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
- *
- * fdt_get_alias() retrieves the value of a given alias. That is, the
- * value of the property named 'name' in the node /aliases.
- *
- * returns:
- * a pointer to the expansion of the alias named 'name', of it exists
- * NULL, if the given alias or the /aliases node does not exist
- */
-const char *fdt_get_alias(const void *fdt, const char *name);
-
-/**
- * fdt_get_path - determine the full path of a node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose path to find
- * @buf: character buffer to contain the returned path (will be overwritten)
- * @buflen: size of the character buffer at buf
- *
- * fdt_get_path() computes the full path of the node at offset
- * nodeoffset, and records that path in the buffer at buf.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
- * 0, on success
- * buf contains the absolute path of the node at
- * nodeoffset, as a NUL-terminated string.
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
- * characters and will not fit in the given buffer.
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
-
-/**
- * fdt_supernode_atdepth_offset - find a specific ancestor of a node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- * @supernodedepth: depth of the ancestor to find
- * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
- *
- * fdt_supernode_atdepth_offset() finds an ancestor of the given node
- * at a specific depth from the root (where the root itself has depth
- * 0, its immediate subnodes depth 1 and so forth). So
- * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
- * will always return 0, the offset of the root node. If the node at
- * nodeoffset has depth D, then:
- * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
- * will return nodeoffset itself.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
-
- * structure block offset of the node at node offset's ancestor
- * of depth supernodedepth (>=0), on success
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
-* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
- int supernodedepth, int *nodedepth);
-
-/**
- * fdt_node_depth - find the depth of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- *
- * fdt_node_depth() finds the depth of a given node. The root node
- * has depth 0, its immediate subnodes depth 1 and so forth.
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset.
- *
- * returns:
- * depth of the node at nodeoffset (>=0), on success
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_depth(const void *fdt, int nodeoffset);
-
-/**
- * fdt_parent_offset - find the parent of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose parent to find
- *
- * fdt_parent_offset() locates the parent node of a given node (that
- * is, it finds the offset of the node which contains the node at
- * nodeoffset as a subnode).
- *
- * NOTE: This function is expensive, as it must scan the device tree
- * structure from the start to nodeoffset, *twice*.
- *
- * returns:
- * structure block offset of the parent of the node at nodeoffset
- * (>=0), on success
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_parent_offset(const void *fdt, int nodeoffset);
-
-/**
- * fdt_node_offset_by_prop_value - find nodes with a given property value
- * @fdt: pointer to the device tree blob
- * @startoffset: only find nodes after this offset
- * @propname: property name to check
- * @propval: property value to search for
- * @proplen: length of the value in propval
- *
- * fdt_node_offset_by_prop_value() returns the offset of the first
- * node after startoffset, which has a property named propname whose
- * value is of length proplen and has value equal to propval; or if
- * startoffset is -1, the very first such node in the tree.
- *
- * To iterate through all nodes matching the criterion, the following
- * idiom can be used:
- * offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
- * propval, proplen);
- * while (offset != -FDT_ERR_NOTFOUND) {
- * // other code here
- * offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
- * propval, proplen);
- * }
- *
- * Note the -1 in the first call to the function, if 0 is used here
- * instead, the function will never locate the root node, even if it
- * matches the criterion.
- *
- * returns:
- * structure block offset of the located node (>= 0, >startoffset),
- * on success
- * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
- * tree after startoffset
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
- const char *propname,
- const void *propval, int proplen);
-
-/**
- * fdt_node_offset_by_phandle - find the node with a given phandle
- * @fdt: pointer to the device tree blob
- * @phandle: phandle value
- *
- * fdt_node_offset_by_phandle() returns the offset of the node
- * which has the given phandle value. If there is more than one node
- * in the tree with the given phandle (an invalid tree), results are
- * undefined.
- *
- * returns:
- * structure block offset of the located node (>= 0), on success
- * -FDT_ERR_NOTFOUND, no node with that phandle exists
- * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
-
-/**
- * fdt_node_check_compatible: check a node's compatible property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of a tree node
- * @compatible: string to match against
- *
- *
- * fdt_node_check_compatible() returns 0 if the given node contains a
- * 'compatible' property with the given string as one of its elements,
- * it returns non-zero otherwise, or on error.
- *
- * returns:
- * 0, if the node has a 'compatible' property listing the given string
- * 1, if the node has a 'compatible' property, but it does not list
- * the given string
- * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
- * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
- const char *compatible);
-
-/**
- * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
- * @fdt: pointer to the device tree blob
- * @startoffset: only find nodes after this offset
- * @compatible: 'compatible' string to match against
- *
- * fdt_node_offset_by_compatible() returns the offset of the first
- * node after startoffset, which has a 'compatible' property which
- * lists the given compatible string; or if startoffset is -1, the
- * very first such node in the tree.
- *
- * To iterate through all nodes matching the criterion, the following
- * idiom can be used:
- * offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
- * while (offset != -FDT_ERR_NOTFOUND) {
- * // other code here
- * offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
- * }
- *
- * Note the -1 in the first call to the function, if 0 is used here
- * instead, the function will never locate the root node, even if it
- * matches the criterion.
- *
- * returns:
- * structure block offset of the located node (>= 0, >startoffset),
- * on success
- * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
- * tree after startoffset
- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE, standard meanings
- */
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
- const char *compatible);
-
-/**********************************************************************/
-/* Write-in-place functions */
-/**********************************************************************/
-
-/**
- * fdt_setprop_inplace - change a property's value, but not its size
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: pointer to data to replace the property value with
- * @len: length of the property value
- *
- * fdt_setprop_inplace() replaces the value of a given property with
- * the data in val, of length len. This function cannot change the
- * size of a property, and so will only work if len is equal to the
- * current length of the property.
- *
- * This function will alter only the bytes in the blob which contain
- * the given property value, and will not alter or move any other part
- * of the tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, if len is not equal to the property's current length
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
-
-/**
- * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 32-bit integer value to replace the property with
- *
- * fdt_setprop_inplace_u32() replaces the value of a given property
- * with the 32-bit integer value in val, converting val to big-endian
- * if necessary. This function cannot change the size of a property,
- * and so will only work if the property already exists and has length
- * 4.
- *
- * This function will alter only the bytes in the blob which contain
- * the given property value, and will not alter or move any other part
- * of the tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, if the property's length is not equal to 4
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
-{
- val = cpu_to_fdt32(val);
- return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
-}
-
-/**
- * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 64-bit integer value to replace the property with
- *
- * fdt_setprop_inplace_u64() replaces the value of a given property
- * with the 64-bit integer value in val, converting val to big-endian
- * if necessary. This function cannot change the size of a property,
- * and so will only work if the property already exists and has length
- * 8.
- *
- * This function will alter only the bytes in the blob which contain
- * the given property value, and will not alter or move any other part
- * of the tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, if the property's length is not equal to 8
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
- const char *name, uint64_t val)
-{
- val = cpu_to_fdt64(val);
- return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
-}
-
-/**
- * fdt_setprop_inplace_cell - change the value of a single-cell property
- *
- * This is an alternative name for fdt_setprop_inplace_u32()
- */
-static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
-{
- return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
-}
-
-/**
- * fdt_nop_property - replace a property with nop tags
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to nop
- * @name: name of the property to nop
- *
- * fdt_nop_property() will replace a given property's representation
- * in the blob with FDT_NOP tags, effectively removing it from the
- * tree.
- *
- * This function will alter only the bytes in the blob which contain
- * the property, and will not alter or move any other part of the
- * tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_nop_node - replace a node (subtree) with nop tags
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node to nop
- *
- * fdt_nop_node() will replace a given node's representation in the
- * blob, including all its subnodes, if any, with FDT_NOP tags,
- * effectively removing it from the tree.
- *
- * This function will alter only the bytes in the blob which contain
- * the node and its properties and subnodes, and will not alter or
- * move any other part of the tree.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_nop_node(void *fdt, int nodeoffset);
-
-/**********************************************************************/
-/* Sequential write functions */
-/**********************************************************************/
-
-int fdt_create(void *buf, int bufsize);
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
-int fdt_finish_reservemap(void *fdt);
-int fdt_begin_node(void *fdt, const char *name);
-int fdt_property(void *fdt, const char *name, const void *val, int len);
-static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
-{
- val = cpu_to_fdt32(val);
- return fdt_property(fdt, name, &val, sizeof(val));
-}
-static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
-{
- val = cpu_to_fdt64(val);
- return fdt_property(fdt, name, &val, sizeof(val));
-}
-static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
-{
- return fdt_property_u32(fdt, name, val);
-}
-#define fdt_property_string(fdt, name, str) \
- fdt_property(fdt, name, str, strlen(str)+1)
-int fdt_end_node(void *fdt);
-int fdt_finish(void *fdt);
-
-/**********************************************************************/
-/* Read-write functions */
-/**********************************************************************/
-
-int fdt_create_empty_tree(void *buf, int bufsize);
-int fdt_open_into(const void *fdt, void *buf, int bufsize);
-int fdt_pack(void *fdt);
-
-/**
- * fdt_add_mem_rsv - add one memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @address, @size: 64-bit values (native endian)
- *
- * Adds a reserve map entry to the given blob reserving a region at
- * address address of length size.
- *
- * This function will insert data into the reserve map and will
- * therefore change the indexes of some entries in the table.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new reservation entry
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
-
-/**
- * fdt_del_mem_rsv - remove a memory reserve map entry
- * @fdt: pointer to the device tree blob
- * @n: entry to remove
- *
- * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
- * the blob.
- *
- * This function will delete data from the reservation table and will
- * therefore change the indexes of some entries in the table.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
- * are less than n+1 reserve map entries)
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_del_mem_rsv(void *fdt, int n);
-
-/**
- * fdt_set_name - change the name of a given node
- * @fdt: pointer to the device tree blob
- * @nodeoffset: structure block offset of a node
- * @name: name to give the node
- *
- * fdt_set_name() replaces the name (including unit address, if any)
- * of the given node with the given string. NOTE: this function can't
- * efficiently check if the new name is unique amongst the given
- * node's siblings; results are undefined if this function is invoked
- * with a name equal to one of the given node's siblings.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob
- * to contain the new name
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE, standard meanings
- */
-int fdt_set_name(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_setprop - create or change a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: pointer to data to set the property value to
- * @len: length of the property value
- *
- * fdt_setprop() sets the value of the named property in the given
- * node to the given value and length, creating the property if it
- * does not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
-
-/**
- * fdt_setprop_u32 - set a property to a 32-bit integer
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 32-bit integer value for the property (native endian)
- *
- * fdt_setprop_u32() sets the value of the named property in the given
- * node to the given 32-bit integer value (converting to big-endian if
- * necessary), or creates a new property with that value if it does
- * not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
- uint32_t val)
-{
- val = cpu_to_fdt32(val);
- return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
-}
-
-/**
- * fdt_setprop_u64 - set a property to a 64-bit integer
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 64-bit integer value for the property (native endian)
- *
- * fdt_setprop_u64() sets the value of the named property in the given
- * node to the given 64-bit integer value (converting to big-endian if
- * necessary), or creates a new property with that value if it does
- * not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
- uint64_t val)
-{
- val = cpu_to_fdt64(val);
- return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
-}
-
-/**
- * fdt_setprop_cell - set a property to a single cell value
- *
- * This is an alternative name for fdt_setprop_u32()
- */
-static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
- uint32_t val)
-{
- return fdt_setprop_u32(fdt, nodeoffset, name, val);
-}
-
-/**
- * fdt_setprop_string - set a property to a string value
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @str: string value for the property
- *
- * fdt_setprop_string() sets the value of the named property in the
- * given node to the given string value (using the length of the
- * string to determine the new length of the property), or creates a
- * new property with that value if it does not already exist.
- *
- * This function may insert or delete data from the blob, and will
- * therefore change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-#define fdt_setprop_string(fdt, nodeoffset, name, str) \
- fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
-
-/**
- * fdt_appendprop - append to or create a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to append to
- * @val: pointer to data to append to the property value
- * @len: length of the data to append to the property value
- *
- * fdt_appendprop() appends the value to the named property in the
- * given node, creating the property if it does not already exist.
- *
- * This function may insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
-
-/**
- * fdt_appendprop_u32 - append a 32-bit integer value to a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 32-bit integer value to append to the property (native endian)
- *
- * fdt_appendprop_u32() appends the given 32-bit integer value
- * (converting to big-endian if necessary) to the value of the named
- * property in the given node, or creates a new property with that
- * value if it does not already exist.
- *
- * This function may insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
-{
- val = cpu_to_fdt32(val);
- return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
-}
-
-/**
- * fdt_appendprop_u64 - append a 64-bit integer value to a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @val: 64-bit integer value to append to the property (native endian)
- *
- * fdt_appendprop_u64() appends the given 64-bit integer value
- * (converting to big-endian if necessary) to the value of the named
- * property in the given node, or creates a new property with that
- * value if it does not already exist.
- *
- * This function may insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
- const char *name, uint64_t val)
-{
- val = cpu_to_fdt64(val);
- return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
-}
-
-/**
- * fdt_appendprop_cell - append a single cell value to a property
- *
- * This is an alternative name for fdt_appendprop_u32()
- */
-static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
- const char *name, uint32_t val)
-{
- return fdt_appendprop_u32(fdt, nodeoffset, name, val);
-}
-
-/**
- * fdt_appendprop_string - append a string to a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to change
- * @name: name of the property to change
- * @str: string value to append to the property
- *
- * fdt_appendprop_string() appends the given string to the value of
- * the named property in the given node, or creates a new property
- * with that value if it does not already exist.
- *
- * This function may insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
- * contain the new property value
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
- fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
-
-/**
- * fdt_delprop - delete a property
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node whose property to nop
- * @name: name of the property to nop
- *
- * fdt_del_property() will delete the given property.
- *
- * This function will delete data from the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_NOTFOUND, node does not have the named property
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_delprop(void *fdt, int nodeoffset, const char *name);
-
-/**
- * fdt_add_subnode_namelen - creates a new node based on substring
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- * @namelen: number of characters of name to consider
- *
- * Identical to fdt_add_subnode(), but use only the first namelen
- * characters of name as the name of the new node. This is useful for
- * creating subnodes based on a portion of a larger string, such as a
- * full path.
- */
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
- const char *name, int namelen);
-
-/**
- * fdt_add_subnode - creates a new node
- * @fdt: pointer to the device tree blob
- * @parentoffset: structure block offset of a node
- * @name: name of the subnode to locate
- *
- * fdt_add_subnode() creates a new node as a subnode of the node at
- * structure block offset parentoffset, with the given name (which
- * should include the unit address, if any).
- *
- * This function will insert data into the blob, and will therefore
- * change the offsets of some existing nodes.
-
- * returns:
- * structure block offset of the created nodeequested subnode (>=0), on success
- * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
- * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
- * the given name
- * -FDT_ERR_NOSPACE, if there is insufficient free space in the
- * blob to contain the new node
- * -FDT_ERR_NOSPACE
- * -FDT_ERR_BADLAYOUT
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings.
- */
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
-
-/**
- * fdt_del_node - delete a node (subtree)
- * @fdt: pointer to the device tree blob
- * @nodeoffset: offset of the node to nop
- *
- * fdt_del_node() will remove the given node, including all its
- * subnodes if any, from the blob.
- *
- * This function will delete data from the blob, and will therefore
- * change the offsets of some existing nodes.
- *
- * returns:
- * 0, on success
- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
- * -FDT_ERR_BADLAYOUT,
- * -FDT_ERR_BADMAGIC,
- * -FDT_ERR_BADVERSION,
- * -FDT_ERR_BADSTATE,
- * -FDT_ERR_BADSTRUCTURE,
- * -FDT_ERR_TRUNCATED, standard meanings
- */
-int fdt_del_node(void *fdt, int nodeoffset);
-
-/**********************************************************************/
-/* Debugging / informational functions */
-/**********************************************************************/
-
-const char *fdt_strerror(int errval);
-
-#endif /* _LIBFDT_H */
+#ifndef _LIBFDT_H
+#define _LIBFDT_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <libfdt_env.h>
+#include <fdt.h>
+
+#define FDT_FIRST_SUPPORTED_VERSION 0x10
+#define FDT_LAST_SUPPORTED_VERSION 0x11
+
+/* Error codes: informative error codes */
+#define FDT_ERR_NOTFOUND 1
+ /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
+#define FDT_ERR_EXISTS 2
+ /* FDT_ERR_EXISTS: Attemped to create a node or property which
+ * already exists */
+#define FDT_ERR_NOSPACE 3
+ /* FDT_ERR_NOSPACE: Operation needed to expand the device
+ * tree, but its buffer did not have sufficient space to
+ * contain the expanded tree. Use fdt_open_into() to move the
+ * device tree to a buffer with more space. */
+
+/* Error codes: codes for bad parameters */
+#define FDT_ERR_BADOFFSET 4
+ /* FDT_ERR_BADOFFSET: Function was passed a structure block
+ * offset which is out-of-bounds, or which points to an
+ * unsuitable part of the structure for the operation. */
+#define FDT_ERR_BADPATH 5
+ /* FDT_ERR_BADPATH: Function was passed a badly formatted path
+ * (e.g. missing a leading / for a function which requires an
+ * absolute path) */
+#define FDT_ERR_BADPHANDLE 6
+ /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
+ * value. phandle values of 0 and -1 are not permitted. */
+#define FDT_ERR_BADSTATE 7
+ /* FDT_ERR_BADSTATE: Function was passed an incomplete device
+ * tree created by the sequential-write functions, which is
+ * not sufficiently complete for the requested operation. */
+
+/* Error codes: codes for bad device tree blobs */
+#define FDT_ERR_TRUNCATED 8
+ /* FDT_ERR_TRUNCATED: Structure block of the given device tree
+ * ends without an FDT_END tag. */
+#define FDT_ERR_BADMAGIC 9
+ /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
+ * device tree at all - it is missing the flattened device
+ * tree magic number. */
+#define FDT_ERR_BADVERSION 10
+ /* FDT_ERR_BADVERSION: Given device tree has a version which
+ * can't be handled by the requested operation. For
+ * read-write functions, this may mean that fdt_open_into() is
+ * required to convert the tree to the expected version. */
+#define FDT_ERR_BADSTRUCTURE 11
+ /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
+ * structure block or other serious error (e.g. misnested
+ * nodes, or subnodes preceding properties). */
+#define FDT_ERR_BADLAYOUT 12
+ /* FDT_ERR_BADLAYOUT: For read-write functions, the given
+ * device tree has it's sub-blocks in an order that the
+ * function can't handle (memory reserve map, then structure,
+ * then strings). Use fdt_open_into() to reorganize the tree
+ * into a form suitable for the read-write operations. */
+
+/* "Can't happen" error indicating a bug in libfdt */
+#define FDT_ERR_INTERNAL 13
+ /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
+ * Should never be returned, if it is, it indicates a bug in
+ * libfdt itself. */
+
+#define FDT_ERR_MAX 13
+
+/**********************************************************************/
+/* Low-level functions (you probably don't need these) */
+/**********************************************************************/
+
+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
+static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
+{
+ return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
+}
+
+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
+
+/**********************************************************************/
+/* Traversal functions */
+/**********************************************************************/
+
+int fdt_next_node(const void *fdt, int offset, int *depth);
+
+/**********************************************************************/
+/* General functions */
+/**********************************************************************/
+
+#define fdt_get_header(fdt, field) \
+ (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
+#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
+#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
+#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
+#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
+#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
+#define fdt_version(fdt) (fdt_get_header(fdt, version))
+#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
+#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
+#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
+#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
+
+#define __fdt_set_hdr(name) \
+ static inline void fdt_set_##name(void *fdt, uint32_t val) \
+ { \
+ struct fdt_header *fdth = (struct fdt_header*)fdt; \
+ fdth->name = cpu_to_fdt32(val); \
+ }
+__fdt_set_hdr(magic);
+__fdt_set_hdr(totalsize);
+__fdt_set_hdr(off_dt_struct);
+__fdt_set_hdr(off_dt_strings);
+__fdt_set_hdr(off_mem_rsvmap);
+__fdt_set_hdr(version);
+__fdt_set_hdr(last_comp_version);
+__fdt_set_hdr(boot_cpuid_phys);
+__fdt_set_hdr(size_dt_strings);
+__fdt_set_hdr(size_dt_struct);
+#undef __fdt_set_hdr
+
+/**
+ * fdt_check_header - sanity check a device tree or possible device tree
+ * @fdt: pointer to data which might be a flattened device tree
+ *
+ * fdt_check_header() checks that the given buffer contains what
+ * appears to be a flattened device tree with sane information in its
+ * header.
+ *
+ * returns:
+ * 0, if the buffer appears to contain a valid device tree
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings, as above
+ */
+int fdt_check_header(const void *fdt);
+
+/**
+ * fdt_move - move a device tree around in memory
+ * @fdt: pointer to the device tree to move
+ * @buf: pointer to memory where the device is to be moved
+ * @bufsize: size of the memory space at buf
+ *
+ * fdt_move() relocates, if possible, the device tree blob located at
+ * fdt to the buffer at buf of size bufsize. The buffer may overlap
+ * with the existing device tree blob at fdt. Therefore,
+ * fdt_move(fdt, fdt, fdt_totalsize(fdt))
+ * should always succeed.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_move(const void *fdt, void *buf, int bufsize);
+
+/**********************************************************************/
+/* Read-only functions */
+/**********************************************************************/
+
+/**
+ * fdt_string - retrieve a string from the strings block of a device tree
+ * @fdt: pointer to the device tree blob
+ * @stroffset: offset of the string within the strings block (native endian)
+ *
+ * fdt_string() retrieves a pointer to a single string from the
+ * strings block of the device tree blob at fdt.
+ *
+ * returns:
+ * a pointer to the string, on success
+ * NULL, if stroffset is out of bounds
+ */
+const char *fdt_string(const void *fdt, int stroffset);
+
+/**
+ * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
+ * @fdt: pointer to the device tree blob
+ *
+ * Returns the number of entries in the device tree blob's memory
+ * reservation map. This does not include the terminating 0,0 entry
+ * or any other (0,0) entries reserved for expansion.
+ *
+ * returns:
+ * the number of entries
+ */
+int fdt_num_mem_rsv(const void *fdt);
+
+/**
+ * fdt_get_mem_rsv - retrieve one memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @address, @size: pointers to 64-bit variables
+ *
+ * On success, *address and *size will contain the address and size of
+ * the n-th reserve map entry from the device tree blob, in
+ * native-endian format.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
+
+/**
+ * fdt_subnode_offset_namelen - find a subnode based on substring
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_subnode_offset(), but only examine the first
+ * namelen characters of name for matching the subnode name. This is
+ * useful for finding subnodes based on a portion of a larger string,
+ * such as a full path.
+ */
+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
+ const char *name, int namelen);
+/**
+ * fdt_subnode_offset - find a subnode of a given node
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ *
+ * fdt_subnode_offset() finds a subnode of the node at structure block
+ * offset parentoffset with the given name. name may include a unit
+ * address, in which case fdt_subnode_offset() will find the subnode
+ * with that unit address, or the unit address may be omitted, in
+ * which case fdt_subnode_offset() will find an arbitrary subnode
+ * whose name excluding unit address matches the given name.
+ *
+ * returns:
+ * structure block offset of the requested subnode (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
+
+/**
+ * fdt_path_offset - find a tree node by its full path
+ * @fdt: pointer to the device tree blob
+ * @path: full path of the node to locate
+ *
+ * fdt_path_offset() finds a node of a given path in the device tree.
+ * Each path component may omit the unit address portion, but the
+ * results of this are undefined if any such path component is
+ * ambiguous (that is if there are multiple nodes at the relevant
+ * level matching the given component, differentiated only by unit
+ * address).
+ *
+ * returns:
+ * structure block offset of the node with the requested path (>=0), on success
+ * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
+ * -FDT_ERR_NOTFOUND, if the requested node does not exist
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_path_offset(const void *fdt, const char *path);
+
+/**
+ * fdt_get_name - retrieve the name of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of the starting node
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_name() retrieves the name (including unit address) of the
+ * device tree node at structure block offset nodeoffset. If lenp is
+ * non-NULL, the length of this name is also returned, in the integer
+ * pointed to by lenp.
+ *
+ * returns:
+ * pointer to the node's name, on success
+ * If lenp is non-NULL, *lenp contains the length of that name (>=0)
+ * NULL, on error
+ * if lenp is non-NULL *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
+
+/**
+ * fdt_first_property_offset - find the offset of a node's first property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of a node
+ *
+ * fdt_first_property_offset() finds the first property of the node at
+ * the given structure block offset.
+ *
+ * returns:
+ * structure block offset of the property (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the requested node has no properties
+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_first_property_offset(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_next_property_offset - step through a node's properties
+ * @fdt: pointer to the device tree blob
+ * @offset: structure block offset of a property
+ *
+ * fdt_next_property_offset() finds the property immediately after the
+ * one at the given structure block offset. This will be a property
+ * of the same node as the given property.
+ *
+ * returns:
+ * structure block offset of the next property (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the given property is the last in its node
+ * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_next_property_offset(const void *fdt, int offset);
+
+/**
+ * fdt_get_property_by_offset - retrieve the property at a given offset
+ * @fdt: pointer to the device tree blob
+ * @offset: offset of the property to retrieve
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_property_by_offset() retrieves a pointer to the
+ * fdt_property structure within the device tree blob at the given
+ * offset. If lenp is non-NULL, the length of the property value is
+ * also returned, in the integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the structure representing the property
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *lenp);
+
+/**
+ * fdt_get_property_namelen - find a property based on substring
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @namelen: number of characters of name to consider
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * Identical to fdt_get_property_namelen(), but only examine the first
+ * namelen characters of name for matching the property name.
+ */
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+ int nodeoffset,
+ const char *name,
+ int namelen, int *lenp);
+
+/**
+ * fdt_get_property - find a given property in a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_get_property() retrieves a pointer to the fdt_property
+ * structure within the device tree blob corresponding to the property
+ * named 'name' of the node at offset nodeoffset. If lenp is
+ * non-NULL, the length of the property value is also returned, in the
+ * integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the structure representing the property
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_NOTFOUND, node does not have named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
+ const char *name,
+ int *lenp)
+{
+ return (struct fdt_property *)(uintptr_t)
+ fdt_get_property(fdt, nodeoffset, name, lenp);
+}
+
+/**
+ * fdt_getprop_by_offset - retrieve the value of a property at a given offset
+ * @fdt: pointer to the device tree blob
+ * @ffset: offset of the property to read
+ * @namep: pointer to a string variable (will be overwritten) or NULL
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_getprop_by_offset() retrieves a pointer to the value of the
+ * property at structure block offset 'offset' (this will be a pointer
+ * to within the device blob itself, not a copy of the value). If
+ * lenp is non-NULL, the length of the property value is also
+ * returned, in the integer pointed to by lenp. If namep is non-NULL,
+ * the property's namne will also be returned in the char * pointed to
+ * by namep (this will be a pointer to within the device tree's string
+ * block, not a new copy of the name).
+ *
+ * returns:
+ * pointer to the property's value
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * if namep is non-NULL *namep contiains a pointer to the property
+ * name.
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ const char **namep, int *lenp);
+
+/**
+ * fdt_getprop_namelen - get property value based on substring
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @namelen: number of characters of name to consider
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * Identical to fdt_getprop(), but only examine the first namelen
+ * characters of name for matching the property name.
+ */
+const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+ const char *name, int namelen, int *lenp);
+
+/**
+ * fdt_getprop - retrieve the value of a given property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to find
+ * @name: name of the property to find
+ * @lenp: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_getprop() retrieves a pointer to the value of the property
+ * named 'name' of the node at offset nodeoffset (this will be a
+ * pointer to within the device blob itself, not a copy of the value).
+ * If lenp is non-NULL, the length of the property value is also
+ * returned, in the integer pointed to by lenp.
+ *
+ * returns:
+ * pointer to the property's value
+ * if lenp is non-NULL, *lenp contains the length of the property
+ * value (>=0)
+ * NULL, on error
+ * if lenp is non-NULL, *lenp contains an error code (<0):
+ * -FDT_ERR_NOTFOUND, node does not have named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
+ const char *name, int *lenp)
+{
+ return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
+}
+
+/**
+ * fdt_get_phandle - retrieve the phandle of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of the node
+ *
+ * fdt_get_phandle() retrieves the phandle of the device tree node at
+ * structure block offset nodeoffset.
+ *
+ * returns:
+ * the phandle of the node at nodeoffset, on success (!= 0, != -1)
+ * 0, if the node has no phandle, or another error occurs
+ */
+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_get_alias_namelen - get alias based on substring
+ * @fdt: pointer to the device tree blob
+ * @name: name of the alias th look up
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_get_alias(), but only examine the first namelen
+ * characters of name for matching the alias name.
+ */
+const char *fdt_get_alias_namelen(const void *fdt,
+ const char *name, int namelen);
+
+/**
+ * fdt_get_alias - retreive the path referenced by a given alias
+ * @fdt: pointer to the device tree blob
+ * @name: name of the alias th look up
+ *
+ * fdt_get_alias() retrieves the value of a given alias. That is, the
+ * value of the property named 'name' in the node /aliases.
+ *
+ * returns:
+ * a pointer to the expansion of the alias named 'name', of it exists
+ * NULL, if the given alias or the /aliases node does not exist
+ */
+const char *fdt_get_alias(const void *fdt, const char *name);
+
+/**
+ * fdt_get_path - determine the full path of a node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose path to find
+ * @buf: character buffer to contain the returned path (will be overwritten)
+ * @buflen: size of the character buffer at buf
+ *
+ * fdt_get_path() computes the full path of the node at offset
+ * nodeoffset, and records that path in the buffer at buf.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ * 0, on success
+ * buf contains the absolute path of the node at
+ * nodeoffset, as a NUL-terminated string.
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
+ * characters and will not fit in the given buffer.
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
+
+/**
+ * fdt_supernode_atdepth_offset - find a specific ancestor of a node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ * @supernodedepth: depth of the ancestor to find
+ * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
+ *
+ * fdt_supernode_atdepth_offset() finds an ancestor of the given node
+ * at a specific depth from the root (where the root itself has depth
+ * 0, its immediate subnodes depth 1 and so forth). So
+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
+ * will always return 0, the offset of the root node. If the node at
+ * nodeoffset has depth D, then:
+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
+ * will return nodeoffset itself.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+
+ * structure block offset of the node at node offset's ancestor
+ * of depth supernodedepth (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
+ int supernodedepth, int *nodedepth);
+
+/**
+ * fdt_node_depth - find the depth of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ *
+ * fdt_node_depth() finds the depth of a given node. The root node
+ * has depth 0, its immediate subnodes depth 1 and so forth.
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset.
+ *
+ * returns:
+ * depth of the node at nodeoffset (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_depth(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_parent_offset - find the parent of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose parent to find
+ *
+ * fdt_parent_offset() locates the parent node of a given node (that
+ * is, it finds the offset of the node which contains the node at
+ * nodeoffset as a subnode).
+ *
+ * NOTE: This function is expensive, as it must scan the device tree
+ * structure from the start to nodeoffset, *twice*.
+ *
+ * returns:
+ * structure block offset of the parent of the node at nodeoffset
+ * (>=0), on success
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_parent_offset(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_node_offset_by_prop_value - find nodes with a given property value
+ * @fdt: pointer to the device tree blob
+ * @startoffset: only find nodes after this offset
+ * @propname: property name to check
+ * @propval: property value to search for
+ * @proplen: length of the value in propval
+ *
+ * fdt_node_offset_by_prop_value() returns the offset of the first
+ * node after startoffset, which has a property named propname whose
+ * value is of length proplen and has value equal to propval; or if
+ * startoffset is -1, the very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following
+ * idiom can be used:
+ * offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
+ * propval, proplen);
+ * while (offset != -FDT_ERR_NOTFOUND) {
+ * // other code here
+ * offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
+ * propval, proplen);
+ * }
+ *
+ * Note the -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0, >startoffset),
+ * on success
+ * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
+ * tree after startoffset
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
+ const char *propname,
+ const void *propval, int proplen);
+
+/**
+ * fdt_node_offset_by_phandle - find the node with a given phandle
+ * @fdt: pointer to the device tree blob
+ * @phandle: phandle value
+ *
+ * fdt_node_offset_by_phandle() returns the offset of the node
+ * which has the given phandle value. If there is more than one node
+ * in the tree with the given phandle (an invalid tree), results are
+ * undefined.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0), on success
+ * -FDT_ERR_NOTFOUND, no node with that phandle exists
+ * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
+
+/**
+ * fdt_node_check_compatible: check a node's compatible property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of a tree node
+ * @compatible: string to match against
+ *
+ *
+ * fdt_node_check_compatible() returns 0 if the given node contains a
+ * 'compatible' property with the given string as one of its elements,
+ * it returns non-zero otherwise, or on error.
+ *
+ * returns:
+ * 0, if the node has a 'compatible' property listing the given string
+ * 1, if the node has a 'compatible' property, but it does not list
+ * the given string
+ * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
+ * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_check_compatible(const void *fdt, int nodeoffset,
+ const char *compatible);
+
+/**
+ * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
+ * @fdt: pointer to the device tree blob
+ * @startoffset: only find nodes after this offset
+ * @compatible: 'compatible' string to match against
+ *
+ * fdt_node_offset_by_compatible() returns the offset of the first
+ * node after startoffset, which has a 'compatible' property which
+ * lists the given compatible string; or if startoffset is -1, the
+ * very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following
+ * idiom can be used:
+ * offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
+ * while (offset != -FDT_ERR_NOTFOUND) {
+ * // other code here
+ * offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
+ * }
+ *
+ * Note the -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * returns:
+ * structure block offset of the located node (>= 0, >startoffset),
+ * on success
+ * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
+ * tree after startoffset
+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE, standard meanings
+ */
+int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
+ const char *compatible);
+
+/**********************************************************************/
+/* Write-in-place functions */
+/**********************************************************************/
+
+/**
+ * fdt_setprop_inplace - change a property's value, but not its size
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: pointer to data to replace the property value with
+ * @len: length of the property value
+ *
+ * fdt_setprop_inplace() replaces the value of a given property with
+ * the data in val, of length len. This function cannot change the
+ * size of a property, and so will only work if len is equal to the
+ * current length of the property.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if len is not equal to the property's current length
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+
+/**
+ * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value to replace the property with
+ *
+ * fdt_setprop_inplace_u32() replaces the value of a given property
+ * with the 32-bit integer value in val, converting val to big-endian
+ * if necessary. This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 4.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if the property's length is not equal to 4
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to replace the property with
+ *
+ * fdt_setprop_inplace_u64() replaces the value of a given property
+ * with the 64-bit integer value in val, converting val to big-endian
+ * if necessary. This function cannot change the size of a property,
+ * and so will only work if the property already exists and has length
+ * 8.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the given property value, and will not alter or move any other part
+ * of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, if the property's length is not equal to 8
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
+ const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_inplace_cell - change the value of a single-cell property
+ *
+ * This is an alternative name for fdt_setprop_inplace_u32()
+ */
+static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_nop_property - replace a property with nop tags
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to nop
+ * @name: name of the property to nop
+ *
+ * fdt_nop_property() will replace a given property's representation
+ * in the blob with FDT_NOP tags, effectively removing it from the
+ * tree.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the property, and will not alter or move any other part of the
+ * tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_nop_node - replace a node (subtree) with nop tags
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to nop
+ *
+ * fdt_nop_node() will replace a given node's representation in the
+ * blob, including all its subnodes, if any, with FDT_NOP tags,
+ * effectively removing it from the tree.
+ *
+ * This function will alter only the bytes in the blob which contain
+ * the node and its properties and subnodes, and will not alter or
+ * move any other part of the tree.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_nop_node(void *fdt, int nodeoffset);
+
+/**********************************************************************/
+/* Sequential write functions */
+/**********************************************************************/
+
+int fdt_create(void *buf, int bufsize);
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
+int fdt_finish_reservemap(void *fdt);
+int fdt_begin_node(void *fdt, const char *name);
+int fdt_property(void *fdt, const char *name, const void *val, int len);
+static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_property(fdt, name, &val, sizeof(val));
+}
+static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_property(fdt, name, &val, sizeof(val));
+}
+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+{
+ return fdt_property_u32(fdt, name, val);
+}
+#define fdt_property_string(fdt, name, str) \
+ fdt_property(fdt, name, str, strlen(str)+1)
+int fdt_end_node(void *fdt);
+int fdt_finish(void *fdt);
+
+/**********************************************************************/
+/* Read-write functions */
+/**********************************************************************/
+
+int fdt_create_empty_tree(void *buf, int bufsize);
+int fdt_open_into(const void *fdt, void *buf, int bufsize);
+int fdt_pack(void *fdt);
+
+/**
+ * fdt_add_mem_rsv - add one memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @address, @size: 64-bit values (native endian)
+ *
+ * Adds a reserve map entry to the given blob reserving a region at
+ * address address of length size.
+ *
+ * This function will insert data into the reserve map and will
+ * therefore change the indexes of some entries in the table.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new reservation entry
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
+
+/**
+ * fdt_del_mem_rsv - remove a memory reserve map entry
+ * @fdt: pointer to the device tree blob
+ * @n: entry to remove
+ *
+ * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
+ * the blob.
+ *
+ * This function will delete data from the reservation table and will
+ * therefore change the indexes of some entries in the table.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
+ * are less than n+1 reserve map entries)
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_del_mem_rsv(void *fdt, int n);
+
+/**
+ * fdt_set_name - change the name of a given node
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: structure block offset of a node
+ * @name: name to give the node
+ *
+ * fdt_set_name() replaces the name (including unit address, if any)
+ * of the given node with the given string. NOTE: this function can't
+ * efficiently check if the new name is unique amongst the given
+ * node's siblings; results are undefined if this function is invoked
+ * with a name equal to one of the given node's siblings.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob
+ * to contain the new name
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE, standard meanings
+ */
+int fdt_set_name(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_setprop - create or change a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: pointer to data to set the property value to
+ * @len: length of the property value
+ *
+ * fdt_setprop() sets the value of the named property in the given
+ * node to the given value and length, creating the property if it
+ * does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+
+/**
+ * fdt_setprop_u32 - set a property to a 32-bit integer
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value for the property (native endian)
+ *
+ * fdt_setprop_u32() sets the value of the named property in the given
+ * node to the given 32-bit integer value (converting to big-endian if
+ * necessary), or creates a new property with that value if it does
+ * not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
+ uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_u64 - set a property to a 64-bit integer
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value for the property (native endian)
+ *
+ * fdt_setprop_u64() sets the value of the named property in the given
+ * node to the given 64-bit integer value (converting to big-endian if
+ * necessary), or creates a new property with that value if it does
+ * not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
+ uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_setprop_cell - set a property to a single cell value
+ *
+ * This is an alternative name for fdt_setprop_u32()
+ */
+static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
+ uint32_t val)
+{
+ return fdt_setprop_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_setprop_string - set a property to a string value
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @str: string value for the property
+ *
+ * fdt_setprop_string() sets the value of the named property in the
+ * given node to the given string value (using the length of the
+ * string to determine the new length of the property), or creates a
+ * new property with that value if it does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_setprop_string(fdt, nodeoffset, name, str) \
+ fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+
+/**
+ * fdt_appendprop - append to or create a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to append to
+ * @val: pointer to data to append to the property value
+ * @len: length of the data to append to the property value
+ *
+ * fdt_appendprop() appends the value to the named property in the
+ * given node, creating the property if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+
+/**
+ * fdt_appendprop_u32 - append a 32-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 32-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u32() appends the given 32-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ val = cpu_to_fdt32(val);
+ return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_appendprop_u64 - append a 64-bit integer value to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @val: 64-bit integer value to append to the property (native endian)
+ *
+ * fdt_appendprop_u64() appends the given 64-bit integer value
+ * (converting to big-endian if necessary) to the value of the named
+ * property in the given node, or creates a new property with that
+ * value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
+ const char *name, uint64_t val)
+{
+ val = cpu_to_fdt64(val);
+ return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
+}
+
+/**
+ * fdt_appendprop_cell - append a single cell value to a property
+ *
+ * This is an alternative name for fdt_appendprop_u32()
+ */
+static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,
+ const char *name, uint32_t val)
+{
+ return fdt_appendprop_u32(fdt, nodeoffset, name, val);
+}
+
+/**
+ * fdt_appendprop_string - append a string to a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @str: string value to append to the property
+ *
+ * fdt_appendprop_string() appends the given string to the value of
+ * the named property in the given node, or creates a new property
+ * with that value if it does not already exist.
+ *
+ * This function may insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_appendprop_string(fdt, nodeoffset, name, str) \
+ fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+
+/**
+ * fdt_delprop - delete a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to nop
+ * @name: name of the property to nop
+ *
+ * fdt_del_property() will delete the given property.
+ *
+ * This function will delete data from the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOTFOUND, node does not have the named property
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_delprop(void *fdt, int nodeoffset, const char *name);
+
+/**
+ * fdt_add_subnode_namelen - creates a new node based on substring
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ * @namelen: number of characters of name to consider
+ *
+ * Identical to fdt_add_subnode(), but use only the first namelen
+ * characters of name as the name of the new node. This is useful for
+ * creating subnodes based on a portion of a larger string, such as a
+ * full path.
+ */
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ const char *name, int namelen);
+
+/**
+ * fdt_add_subnode - creates a new node
+ * @fdt: pointer to the device tree blob
+ * @parentoffset: structure block offset of a node
+ * @name: name of the subnode to locate
+ *
+ * fdt_add_subnode() creates a new node as a subnode of the node at
+ * structure block offset parentoffset, with the given name (which
+ * should include the unit address, if any).
+ *
+ * This function will insert data into the blob, and will therefore
+ * change the offsets of some existing nodes.
+
+ * returns:
+ * structure block offset of the created nodeequested subnode (>=0), on success
+ * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
+ * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
+ * the given name
+ * -FDT_ERR_NOSPACE, if there is insufficient free space in the
+ * blob to contain the new node
+ * -FDT_ERR_NOSPACE
+ * -FDT_ERR_BADLAYOUT
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings.
+ */
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
+
+/**
+ * fdt_del_node - delete a node (subtree)
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to nop
+ *
+ * fdt_del_node() will remove the given node, including all its
+ * subnodes if any, from the blob.
+ *
+ * This function will delete data from the blob, and will therefore
+ * change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_del_node(void *fdt, int nodeoffset);
+
+/**********************************************************************/
+/* Debugging / informational functions */
+/**********************************************************************/
+
+const char *fdt_strerror(int errval);
+
+#endif /* _LIBFDT_H */
diff --git a/EmbeddedPkg/Include/libfdt_env.h b/EmbeddedPkg/Include/libfdt_env.h
index d35b8692c6..6cc311fe73 100644
--- a/EmbeddedPkg/Include/libfdt_env.h
+++ b/EmbeddedPkg/Include/libfdt_env.h
@@ -1,77 +1,77 @@
-/** @file
-*
-* Copyright (c) 2011-2012, ARM Limited. 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 _LIBFDT_ENV_H
-#define _LIBFDT_ENV_H
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-
-typedef UINT8 uint8_t;
-typedef UINT16 uint16_t;
-typedef UINT32 uint32_t;
-typedef UINT64 uint64_t;
-typedef UINTN uintptr_t;
-typedef UINTN size_t;
-
-static inline uint16_t fdt16_to_cpu(uint16_t x)
-{
- return SwapBytes16 (x);
-}
-#define cpu_to_fdt16(x) fdt16_to_cpu(x)
-
-static inline uint32_t fdt32_to_cpu(uint32_t x)
-{
- return SwapBytes32 (x);
-}
-#define cpu_to_fdt32(x) fdt32_to_cpu(x)
-
-static inline uint64_t fdt64_to_cpu(uint64_t x)
-{
- return SwapBytes64 (x);
-}
-#define cpu_to_fdt64(x) fdt64_to_cpu(x)
-
-static inline void* memcpy(void* dest, const void* src, size_t len) {
- return CopyMem (dest, src, len);
-}
-
-static inline void *memmove(void *dest, const void *src, size_t n) {
- return CopyMem (dest, src, n);
-}
-
-static inline void *memset(void *s, int c, size_t n) {
- return SetMem (s, n, c);
-}
-
-static inline int memcmp(const void* dest, const void* src, int len) {
- return CompareMem (dest, src, len);
-}
-
-static inline void *memchr(const void *s, int c, size_t n) {
- return ScanMem8 (s, n, c);
-}
-
-static inline size_t strlen (const char* str) {
- return AsciiStrLen (str);
-}
-
-static inline char *strchr(const char *s, int c) {
- char pattern[2];
- pattern[0] = c;
- pattern[1] = 0;
- return AsciiStrStr (s, pattern);
-}
-
-#endif /* _LIBFDT_ENV_H */
+/** @file
+*
+* Copyright (c) 2011-2012, ARM Limited. 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 _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+typedef UINT8 uint8_t;
+typedef UINT16 uint16_t;
+typedef UINT32 uint32_t;
+typedef UINT64 uint64_t;
+typedef UINTN uintptr_t;
+typedef UINTN size_t;
+
+static inline uint16_t fdt16_to_cpu(uint16_t x)
+{
+ return SwapBytes16 (x);
+}
+#define cpu_to_fdt16(x) fdt16_to_cpu(x)
+
+static inline uint32_t fdt32_to_cpu(uint32_t x)
+{
+ return SwapBytes32 (x);
+}
+#define cpu_to_fdt32(x) fdt32_to_cpu(x)
+
+static inline uint64_t fdt64_to_cpu(uint64_t x)
+{
+ return SwapBytes64 (x);
+}
+#define cpu_to_fdt64(x) fdt64_to_cpu(x)
+
+static inline void* memcpy(void* dest, const void* src, size_t len) {
+ return CopyMem (dest, src, len);
+}
+
+static inline void *memmove(void *dest, const void *src, size_t n) {
+ return CopyMem (dest, src, n);
+}
+
+static inline void *memset(void *s, int c, size_t n) {
+ return SetMem (s, n, c);
+}
+
+static inline int memcmp(const void* dest, const void* src, int len) {
+ return CompareMem (dest, src, len);
+}
+
+static inline void *memchr(const void *s, int c, size_t n) {
+ return ScanMem8 (s, n, c);
+}
+
+static inline size_t strlen (const char* str) {
+ return AsciiStrLen (str);
+}
+
+static inline char *strchr(const char *s, int c) {
+ char pattern[2];
+ pattern[0] = c;
+ pattern[1] = 0;
+ return AsciiStrStr (s, pattern);
+}
+
+#endif /* _LIBFDT_ENV_H */
diff --git a/EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLib.c b/EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLib.c
index 7ee5609c5b..7fab09bad6 100755
--- a/EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLib.c
+++ b/EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLib.c
@@ -61,4 +61,4 @@ DebugAgentTimerEndOfInterrupt (
{
}
- \ No newline at end of file
+ \ No newline at end of file
diff --git a/EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf b/EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
index 1429c37f29..03258751c0 100644
--- a/EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
+++ b/EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
@@ -45,4 +45,4 @@
gEfiEblAddCommandProtocolGuid
[Guids]
- \ No newline at end of file
+ \ No newline at end of file
diff --git a/EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf b/EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf
index 3fd8e92dcd..52e343997d 100644
--- a/EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf
+++ b/EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf
@@ -41,4 +41,4 @@
[Protocols]
[Guids]
- \ No newline at end of file
+ \ No newline at end of file
diff --git a/EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.c b/EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.c
index 0edd5d018d..3b0f6a1c71 100644
--- a/EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.c
+++ b/EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.c
@@ -1,173 +1,173 @@
-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 <Uefi.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-
-#include <Protocol/SimpleNetwork.h>
-#include <Protocol/PxeBaseCode.h>
-
-
-BOOLEAN gUseIpv6 = FALSE;
-
-EFI_STATUS
-EFIAPI
-EblGetCurrentIpAddress (
- IN OUT EFI_IP_ADDRESS *Ip
- )
-{
- EFI_STATUS Status;
- EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
-
- Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- Status = Pxe->Start (Pxe, gUseIpv6);
- if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
- return Status;
- }
-
- CopyMem (Ip, &Pxe->Mode->StationIp, sizeof (EFI_IP_ADDRESS));
-
- return EFI_SUCCESS;
-}
-
-
-EFI_STATUS
-EFIAPI
-EblGetCurrentMacAddress (
- IN OUT EFI_MAC_ADDRESS *Mac
- )
-{
- EFI_STATUS Status;
- EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNet;
-
- Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- CopyMem (Mac, SimpleNet->Mode->CurrentAddress.Addr, sizeof (EFI_MAC_ADDRESS));
- return Status;
-}
-
-
-CHAR8 *
-EFIAPI
-EblLoadFileBootTypeString (
- IN EFI_HANDLE Handle
- )
-{
- EFI_STATUS Status;
- VOID *NullPtr;
-
- Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, &NullPtr);
- if (!EFI_ERROR (Status)) {
- return "EFI PXE Network Boot";
- }
-
- return "";
-}
-
-EFI_STATUS
-EFIAPI
-EblPerformDHCP (
- IN BOOLEAN SortOffers
- )
-{
- EFI_STATUS Status;
- EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
-
- Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- Status = Pxe->Start (Pxe, gUseIpv6);
- if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
- return Status;
- }
-
- Status = Pxe->Dhcp(Pxe, TRUE);
- return Status;
-}
-
-
-EFI_STATUS
-EFIAPI
-EblSetStationIp (
- IN EFI_IP_ADDRESS *NewStationIp, OPTIONAL
- IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL
- )
-{
- EFI_STATUS Status;
- EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
-
- Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- Status = Pxe->Start (Pxe, gUseIpv6);
- if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
- return Status;
- }
-
- Status = Pxe->SetStationIp (Pxe, NewStationIp, NewSubnetMask);
- return Status;
-}
-
-
-EFI_STATUS
-EFIAPI
-EblMtftp (
- IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,
- IN OUT VOID *BufferPtr OPTIONAL,
- IN BOOLEAN Overwrite,
- IN OUT UINT64 *BufferSize,
- IN UINTN *BlockSize OPTIONAL,
- IN EFI_IP_ADDRESS *ServerIp,
- IN UINT8 *Filename OPTIONAL,
- IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL,
- IN BOOLEAN DontUseBuffer
- )
-{
- EFI_STATUS Status;
- EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
-
- Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- Status = Pxe->Mtftp (
- Pxe,
- Operation,
- BufferPtr,
- Overwrite,
- BufferSize,
- BlockSize,
- ServerIp,
- Filename,
- Info,
- DontUseBuffer
- );
- return Status;
-}
-
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/PxeBaseCode.h>
+
+
+BOOLEAN gUseIpv6 = FALSE;
+
+EFI_STATUS
+EFIAPI
+EblGetCurrentIpAddress (
+ IN OUT EFI_IP_ADDRESS *Ip
+ )
+{
+ EFI_STATUS Status;
+ EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
+
+ Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = Pxe->Start (Pxe, gUseIpv6);
+ if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ CopyMem (Ip, &Pxe->Mode->StationIp, sizeof (EFI_IP_ADDRESS));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+EblGetCurrentMacAddress (
+ IN OUT EFI_MAC_ADDRESS *Mac
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNet;
+
+ Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ CopyMem (Mac, SimpleNet->Mode->CurrentAddress.Addr, sizeof (EFI_MAC_ADDRESS));
+ return Status;
+}
+
+
+CHAR8 *
+EFIAPI
+EblLoadFileBootTypeString (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ VOID *NullPtr;
+
+ Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, &NullPtr);
+ if (!EFI_ERROR (Status)) {
+ return "EFI PXE Network Boot";
+ }
+
+ return "";
+}
+
+EFI_STATUS
+EFIAPI
+EblPerformDHCP (
+ IN BOOLEAN SortOffers
+ )
+{
+ EFI_STATUS Status;
+ EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
+
+ Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = Pxe->Start (Pxe, gUseIpv6);
+ if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ Status = Pxe->Dhcp(Pxe, TRUE);
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+EblSetStationIp (
+ IN EFI_IP_ADDRESS *NewStationIp, OPTIONAL
+ IN EFI_IP_ADDRESS *NewSubnetMask OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
+
+ Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = Pxe->Start (Pxe, gUseIpv6);
+ if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ Status = Pxe->SetStationIp (Pxe, NewStationIp, NewSubnetMask);
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+EblMtftp (
+ IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,
+ IN OUT VOID *BufferPtr OPTIONAL,
+ IN BOOLEAN Overwrite,
+ IN OUT UINT64 *BufferSize,
+ IN UINTN *BlockSize OPTIONAL,
+ IN EFI_IP_ADDRESS *ServerIp,
+ IN UINT8 *Filename OPTIONAL,
+ IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL,
+ IN BOOLEAN DontUseBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_PXE_BASE_CODE_PROTOCOL *Pxe;
+
+ Status = gBS->LocateProtocol (&gEfiPxeBaseCodeProtocolGuid, NULL, (VOID **)&Pxe);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = Pxe->Mtftp (
+ Pxe,
+ Operation,
+ BufferPtr,
+ Overwrite,
+ BufferSize,
+ BlockSize,
+ ServerIp,
+ Filename,
+ Info,
+ DontUseBuffer
+ );
+ return Status;
+}
+
diff --git a/EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf b/EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
index b0d6e80aea..4d66bacb81 100644
--- a/EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
+++ b/EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
@@ -31,4 +31,4 @@
gEfiPxeBaseCodeProtocolGuid
[Depex]
- TRUE \ No newline at end of file
+ TRUE \ No newline at end of file
diff --git a/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c b/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c
index 5e0f9ca117..83a3b7841f 100644
--- a/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c
+++ b/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c
@@ -1,1778 +1,1778 @@
-/** @file
-File IO routines inspired by Streams with an EFI flavor
-
-Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
-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.
-
-Basic support for opening files on different device types. The device string
-is in the form of DevType:Path. Current DevType is required as there is no
-current mounted device concept of current working directory concept implement
-by this library.
-
-Device names are case insensitive and only check the leading characters for
-unique matches. Thus the following are all the same:
-LoadFile0:
-l0:
-L0:
-Lo0:
-
-Supported Device Names:
-A0x1234:0x12 - A memory buffer starting at address 0x1234 for 0x12 bytes
-l1: - EFI LoadFile device one.
-B0: - EFI BlockIo zero.
-fs3: - EFI Simple File System device 3
-Fv2: - EFI Firmware VOlume device 2
-10.0.1.102: - TFTP service IP followed by the file name
-**/
-
-#include <PiDxe.h>
-#include <Protocol/BlockIo.h>
-#include <Protocol/DiskIo.h>
-#include <Protocol/SimpleFileSystem.h>
-#include <Protocol/FirmwareVolume2.h>
-#include <Protocol/LoadFile.h>
-#include <Protocol/FirmwareVolumeBlock.h>
-#include <Guid/FileInfo.h>
-#include <Library/BaseLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/PrintLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/DebugLib.h>
-#include <Library/EfiFileLib.h>
-#include <Library/PcdLib.h>
-#include <Library/EblNetworkLib.h>
-
-
-CHAR8 *gCwd = NULL;
-
-CONST EFI_GUID gZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
-
-#define EFI_OPEN_FILE_GUARD_HEADER 0x4B4D4641
-#define EFI_OPEN_FILE_GUARD_FOOTER 0x444D5A56
-
-// Need to defend against this overflowing
-#define MAX_CMD_LINE 0x200
-
-typedef struct {
- UINT32 Header;
- EFI_OPEN_FILE File;
- UINT32 Footer;
-} EFI_OPEN_FILE_GUARD;
-
-
-// globals to store current open device info
-EFI_HANDLE *mBlkIo = NULL;
-UINTN mBlkIoCount = 0;
-
-EFI_HANDLE *mFs = NULL;
-UINTN mFsCount = 0;
-// mFsInfo[] array entries must match mFs[] handles
-EFI_FILE_SYSTEM_INFO **mFsInfo = NULL;
-
-EFI_HANDLE *mFv = NULL;
-UINTN mFvCount = 0;
-EFI_HANDLE *mLoadFile = NULL;
-UINTN mLoadFileCount = 0;
-
-
-
-/**
-Internal worker function to validate a File handle.
-
-@param File Open File Handle
-
-@return TRUE File is valid
-@return FALSE File is not valid
-
-
-**/
-BOOLEAN
-FileHandleValid (
- IN EFI_OPEN_FILE *File
- )
-{
- EFI_OPEN_FILE_GUARD *GuardFile;
-
- // Look right before and after file structure for the correct signatures
- GuardFile = BASE_CR (File, EFI_OPEN_FILE_GUARD, File);
- if ((GuardFile->Header != EFI_OPEN_FILE_GUARD_HEADER) ||
- (GuardFile->Footer != EFI_OPEN_FILE_GUARD_FOOTER) ) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
-Internal worker function. If Buffer is not NULL free it.
-
-@param Buffer Buffer to FreePool()
-
-**/
-VOID
-EblFreePool (
- IN VOID *Buffer
- )
-{
- if (Buffer != NULL) {
- FreePool (Buffer);
- }
-}
-
-/**
-Update Device List Global Variables
-
-**/
-VOID
-EblUpdateDeviceLists (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN Size;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
- EFI_FILE_HANDLE Root;
- UINTN Index;
-
- if (mBlkIo != NULL) {
- FreePool (mBlkIo);
- }
- gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &mBlkIoCount, &mBlkIo);
-
-
-
- if (mFv != NULL) {
- FreePool (mFv);
- }
- gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &mFvCount, &mFv);
-
- if (mLoadFile != NULL) {
- FreePool (mLoadFile);
- }
- gBS->LocateHandleBuffer (ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &mLoadFileCount, &mLoadFile);
-
- if (mFs != NULL) {
- FreePool (mFs);
- }
-
- if (&mFsInfo[0] != NULL) {
- // Need to Free the mFsInfo prior to recalculating mFsCount so don't move this code
- for (Index = 0; Index < mFsCount; Index++) {
- if (mFsInfo[Index] != NULL) {
- FreePool (mFsInfo[Index]);
- }
- }
- FreePool (mFsInfo);
- }
-
- gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &mFsCount, &mFs);
-
-
- mFsInfo = AllocateZeroPool (mFsCount * sizeof (EFI_FILE_SYSTEM_INFO *));
- if (mFsInfo == NULL) {
- // If we can't do this then we can't support file system entries
- mFsCount = 0;
- } else {
- // Loop through all the file system structures and cache the file system info data
- for (Index =0; Index < mFsCount; Index++) {
- Status = gBS->HandleProtocol (mFs[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
- if (!EFI_ERROR (Status)) {
- Status = Fs->OpenVolume (Fs, &Root);
- if (!EFI_ERROR (Status)) {
- // Get information about the volume
- Size = 0;
- Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- mFsInfo[Index] = AllocatePool (Size);
- Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]);
- }
-
- Root->Close (Root);
- }
- }
- }
- }
-}
-
-
-/**
-PathName is in the form <device name>:<path> for example fs1:\ or ROOT:\.
-Return TRUE if the <devce name> prefix of PathName matches a file system
-Volume Name. MatchIndex is the array index in mFsInfo[] of the match,
-and it can be used with mFs[] to find the handle that needs to be opened
-
-@param PathName PathName to check
-@param FileStart Index of the first character of the <path>
-@param MatchIndex Index in mFsInfo[] that matches
-
-@return TRUE PathName matches a Volume Label and MatchIndex is valid
-@return FALSE PathName does not match a Volume Label MatchIndex undefined
-
-**/
-BOOLEAN
-EblMatchVolumeName (
- IN CHAR8 *PathName,
- IN UINTN FileStart,
- OUT UINTN *MatchIndex
- )
-{
- UINTN Index;
- UINTN Compare;
- UINTN VolStrLen;
- BOOLEAN Match;
-
- for (Index =0; Index < mFsCount; Index++) {
- if (mFsInfo[Index] == NULL) {
- // FsInfo is not valid so skip it
- continue;
- }
- VolStrLen = StrLen (mFsInfo[Index]->VolumeLabel);
- for (Compare = 0, Match = TRUE; Compare < (FileStart - 1); Compare++) {
- if (Compare > VolStrLen) {
- Match = FALSE;
- break;
- }
- if (PathName[Compare] != (CHAR8)mFsInfo[Index]->VolumeLabel[Compare]) {
- // If the VolumeLabel has a space allow a _ to match with it in addition to ' '
- if (!((PathName[Compare] == '_') && (mFsInfo[Index]->VolumeLabel[Compare] == L' '))) {
- Match = FALSE;
- break;
- }
- }
- }
- if (Match) {
- *MatchIndex = Index;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-
-/**
-Return the number of devices of the current type active in the system
-
-@param Type Device type to check
-
-@return 0 Invalid type
-
-**/
-UINTN
-EfiGetDeviceCounts (
- IN EFI_OPEN_FILE_TYPE DeviceType
- )
-{
- switch (DeviceType) {
- case EfiOpenLoadFile:
- return mLoadFileCount;
- case EfiOpenFirmwareVolume:
- return mFvCount;
- case EfiOpenFileSystem:
- return mFsCount;
- case EfiOpenBlockIo:
- return mBlkIoCount;
- default:
- return 0;
- }
-}
-
-EFI_STATUS
-ConvertIpStringToEfiIp (
- IN CHAR8 *PathName,
- OUT EFI_IP_ADDRESS *ServerIp
- )
-{
- CHAR8 *Str;
-
- Str = PathName;
- ServerIp->v4.Addr[0] = (UINT8)AsciiStrDecimalToUintn (Str);
-
- Str = AsciiStrStr (Str, ".");
- if (Str == NULL) {
- return EFI_DEVICE_ERROR;
- }
-
- ServerIp->v4.Addr[1] = (UINT8)AsciiStrDecimalToUintn (++Str);
-
- Str = AsciiStrStr (Str, ".");
- if (Str == NULL) {
- return EFI_DEVICE_ERROR;
- }
-
- ServerIp->v4.Addr[2] = (UINT8)AsciiStrDecimalToUintn (++Str);
-
- Str = AsciiStrStr (Str, ".");
- if (Str == NULL) {
- return EFI_DEVICE_ERROR;
- }
-
- ServerIp->v4.Addr[3] = (UINT8)AsciiStrDecimalToUintn (++Str);
-
- return EFI_SUCCESS;
-}
-
-
-/**
-Internal work function to extract a device number from a string skipping
-text. Easy way to extract numbers from strings like blk7:.
-
-@param Str String to extract device number form
-
-@return -1 Device string is not valid
-@return Device #
-
-**/
-UINTN
-EblConvertDevStringToNumber (
- IN CHAR8 *Str
- )
-{
- UINTN Max;
- UINTN Index;
-
-
- // Find the first digit
- Max = AsciiStrLen (Str);
- for (Index = 0; !((*Str >= '0') && (*Str <= '9')) && (Index < Max); Index++) {
- Str++;
- }
- if (Index == Max) {
- return (UINTN)-1;
- }
-
- return AsciiStrDecimalToUintn (Str);
-}
-
-
-/**
-Internal work function to fill in EFI_OPEN_FILE information for the Fs and BlkIo
-
-@param File Open file handle
-@param FileName Name of file after device stripped off
-
-
-**/
-EFI_STATUS
-EblFileDevicePath (
- IN OUT EFI_OPEN_FILE *File,
- IN CHAR8 *FileName,
- IN CONST UINT64 OpenMode
- )
-{
- EFI_STATUS Status;
- UINTN Size;
- FILEPATH_DEVICE_PATH *FilePath;
- EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;
- CHAR16 UnicodeFileName[MAX_PATHNAME];
- EFI_BLOCK_IO_PROTOCOL *BlkIo;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
- EFI_FILE_HANDLE Root;
-
-
- if ( *FileName != 0 ) {
- AsciiStrToUnicodeStr (FileName, UnicodeFileName);
- } else {
- AsciiStrToUnicodeStr ("\\", UnicodeFileName);
- }
-
- Size = StrSize (UnicodeFileName);
- FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL));
- if (FileDevicePath != NULL) {
- FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
- FilePath->Header.Type = MEDIA_DEVICE_PATH;
- FilePath->Header.SubType = MEDIA_FILEPATH_DP;
- CopyMem (&FilePath->PathName, UnicodeFileName, Size);
- SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
- SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
-
- if (File->EfiHandle != NULL) {
- File->DevicePath = DevicePathFromHandle (File->EfiHandle);
- }
-
- File->DevicePath = AppendDevicePath (File->DevicePath, FileDevicePath);
- FreePool (FileDevicePath);
- }
-
- Status = gBS->HandleProtocol (File->EfiHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo);
- if (!EFI_ERROR (Status)) {
- File->FsBlockIoMedia = BlkIo->Media;
- File->FsBlockIo = BlkIo;
-
- // If we are not opening the device this will get over written with file info
- File->MaxPosition = MultU64x32 (BlkIo->Media->LastBlock + 1, BlkIo->Media->BlockSize);
- }
-
- if (File->Type == EfiOpenFileSystem) {
- Status = gBS->HandleProtocol (File->EfiHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
- if (!EFI_ERROR (Status)) {
- Status = Fs->OpenVolume (Fs, &Root);
- if (!EFI_ERROR (Status)) {
- // Get information about the volume
- Size = 0;
- Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- File->FsInfo = AllocatePool (Size);
- Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
- }
-
- // Get information about the file
- Status = Root->Open (Root, &File->FsFileHandle, UnicodeFileName, OpenMode, 0);
- if (!EFI_ERROR (Status)) {
- Size = 0;
- Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, NULL);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- File->FsFileInfo = AllocatePool (Size);
- Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, File->FsFileInfo);
- if (!EFI_ERROR (Status)) {
- File->Size = (UINTN)File->FsFileInfo->FileSize;
- File->MaxPosition = (UINT64)File->Size;
- }
- }
- }
-
- Root->Close (Root);
- }
- }
- } else if (File->Type == EfiOpenBlockIo) {
- File->Size = (UINTN)File->MaxPosition;
- }
-
- return Status;
-}
-
-#define ToUpper(a) ((((a) >= 'a') && ((a) <= 'z')) ? ((a) - 'a' + 'A') : (a))
-
-EFI_STATUS
-CompareGuidToString (
- IN EFI_GUID *Guid,
- IN CHAR8 *String
- )
-{
- CHAR8 AsciiGuid[64];
- CHAR8 *StringPtr;
- CHAR8 *GuidPtr;
-
- AsciiSPrint (AsciiGuid, sizeof(AsciiGuid), "%g", Guid);
-
- StringPtr = String;
- GuidPtr = AsciiGuid;
-
- while ((*StringPtr != '\0') && (*GuidPtr != '\0')) {
- // Skip dashes
- if (*StringPtr == '-') {
- StringPtr++;
- continue;
- }
-
- if (*GuidPtr == '-') {
- GuidPtr++;
- continue;
- }
-
- if (ToUpper(*StringPtr) != ToUpper(*GuidPtr)) {
- return EFI_NOT_FOUND;
- }
-
- StringPtr++;
- GuidPtr++;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
-Internal work function to fill in EFI_OPEN_FILE information for the FV
-
-@param File Open file handle
-@param FileName Name of file after device stripped off
-
-
-**/
-EFI_STATUS
-EblFvFileDevicePath (
- IN OUT EFI_OPEN_FILE *File,
- IN CHAR8 *FileName,
- IN CONST UINT64 OpenMode
- )
-{
- EFI_STATUS Status;
- EFI_STATUS GetNextFileStatus;
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH DevicePathNode;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- UINTN Key;
- UINT32 AuthenticationStatus;
- CHAR8 AsciiSection[MAX_PATHNAME];
- VOID *Section;
- UINTN SectionSize;
- EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
- EFI_LBA Lba;
- UINTN BlockSize;
- UINTN NumberOfBlocks;
- EFI_FIRMWARE_VOLUME_HEADER *FvHeader = NULL;
- UINTN Index;
-
-
- Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&File->Fv);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- // Get FVB Info about the handle
- Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
- if (!EFI_ERROR (Status)) {
- Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
- if (!EFI_ERROR (Status)) {
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)File->FvStart;
- File->FvHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
- for (Index = 0; FvHeader->BlockMap[Index].Length !=0; Index++) {
- File->FvHeaderSize += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
- }
-
- for (Lba = 0, File->FvSize = 0, NumberOfBlocks = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
- Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
- if (EFI_ERROR (Status)) {
- break;
- }
- }
- }
- }
-
-
- DevicePath = DevicePathFromHandle (File->EfiHandle);
-
- if (*FileName == '\0') {
- File->DevicePath = DuplicateDevicePath (DevicePath);
- File->Size = File->FvSize;
- File->MaxPosition = File->Size;
- } else {
- Key = 0;
- do {
- File->FvType = EFI_FV_FILETYPE_ALL;
- GetNextFileStatus = File->Fv->GetNextFile (
- File->Fv,
- &Key,
- &File->FvType,
- &File->FvNameGuid,
- &File->FvAttributes,
- &File->Size
- );
- if (!EFI_ERROR (GetNextFileStatus)) {
- // Compare GUID first
- Status = CompareGuidToString (&File->FvNameGuid, FileName);
- if (!EFI_ERROR(Status)) {
- break;
- }
-
- Section = NULL;
- Status = File->Fv->ReadSection (
- File->Fv,
- &File->FvNameGuid,
- EFI_SECTION_USER_INTERFACE,
- 0,
- &Section,
- &SectionSize,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- UnicodeStrToAsciiStr (Section, AsciiSection);
- if (AsciiStriCmp (FileName, AsciiSection) == 0) {
- FreePool (Section);
- break;
- }
- FreePool (Section);
- }
- }
- } while (!EFI_ERROR (GetNextFileStatus));
-
- if (EFI_ERROR (GetNextFileStatus)) {
- return GetNextFileStatus;
- }
-
- if (OpenMode != EFI_SECTION_ALL) {
- // Calculate the size of the section we are targeting
- Section = NULL;
- File->Size = 0;
- Status = File->Fv->ReadSection (
- File->Fv,
- &File->FvNameGuid,
- (EFI_SECTION_TYPE)OpenMode,
- 0,
- &Section,
- &File->Size,
- &AuthenticationStatus
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- File->MaxPosition = File->Size;
- EfiInitializeFwVolDevicepathNode (&DevicePathNode, &File->FvNameGuid);
- File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode);
- }
-
-
- // FVB not required if FV was soft loaded...
- return EFI_SUCCESS;
-}
-
-
-
-
-/**
-Open a device named by PathName. The PathName includes a device name and
-path separated by a :. See file header for more details on the PathName
-syntax. There is no checking to prevent a file from being opened more than
-one type.
-
-SectionType is only used to open an FV. Each file in an FV contains multiple
-sections and only the SectionType section is opened.
-
-For any file that is opened with EfiOpen() must be closed with EfiClose().
-
-@param PathName Path to parse to open
-@param OpenMode Same as EFI_FILE.Open()
-@param SectionType Section in FV to open.
-
-@return NULL Open failed
-@return Valid EFI_OPEN_FILE handle
-
-**/
-EFI_OPEN_FILE *
-EfiOpen (
- IN CHAR8 *PathName,
- IN CONST UINT64 OpenMode,
- IN CONST EFI_SECTION_TYPE SectionType
- )
-{
- EFI_STATUS Status;
- EFI_OPEN_FILE *File;
- EFI_OPEN_FILE FileData;
- UINTN StrLen;
- UINTN FileStart;
- UINTN DevNumber = 0;
- EFI_OPEN_FILE_GUARD *GuardFile;
- BOOLEAN VolumeNameMatch;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- UINTN Size;
- EFI_IP_ADDRESS Ip;
- CHAR8 *CwdPlusPathName;
- UINTN Index;
- EFI_SECTION_TYPE ModifiedSectionType;
-
- EblUpdateDeviceLists ();
-
- File = &FileData;
- ZeroMem (File, sizeof (EFI_OPEN_FILE));
-
- StrLen = AsciiStrSize (PathName);
- if (StrLen <= 1) {
- // Smallest valid path is 1 char and a null
- return NULL;
- }
-
- for (FileStart = 0; FileStart < StrLen; FileStart++) {
- if (PathName[FileStart] == ':') {
- FileStart++;
- break;
- }
- }
-
- //
- // Matching volume name has precedence over handle based names
- //
- VolumeNameMatch = EblMatchVolumeName (PathName, FileStart, &DevNumber);
- if (!VolumeNameMatch) {
- if (FileStart == StrLen) {
- // No Volume name or device name, so try Current Working Directory
- if (gCwd == NULL) {
- // No CWD
- return NULL;
- }
-
- // We could add a current working directory concept
- CwdPlusPathName = AllocatePool (AsciiStrSize (gCwd) + AsciiStrSize (PathName));
- if (CwdPlusPathName == NULL) {
- return NULL;
- }
-
- if ((PathName[0] == '/') || (PathName[0] == '\\')) {
- // PathName starts in / so this means we go to the root of the device in the CWD.
- CwdPlusPathName[0] = '\0';
- for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
- CwdPlusPathName[FileStart] = gCwd[FileStart];
- if (gCwd[FileStart] == ':') {
- FileStart++;
- CwdPlusPathName[FileStart] = '\0';
- break;
- }
- }
- } else {
- AsciiStrCpy (CwdPlusPathName, gCwd);
- StrLen = AsciiStrLen (gCwd);
- if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
- AsciiStrCat (CwdPlusPathName, "\\");
- }
- }
-
- AsciiStrCat (CwdPlusPathName, PathName);
- if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
- // Extra error check to make sure we don't recurse and blow stack
- return NULL;
- }
-
- File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
- FreePool (CwdPlusPathName);
- return File;
- }
-
- DevNumber = EblConvertDevStringToNumber ((CHAR8 *)PathName);
- }
-
- File->DeviceName = AllocatePool (StrLen);
- AsciiStrCpy (File->DeviceName, PathName);
- File->DeviceName[FileStart - 1] = '\0';
- File->FileName = &File->DeviceName[FileStart];
- if (File->FileName[0] == '\0') {
- // if it is just a file name use / as root
- File->FileName = "\\";
- }
-
- //
- // Use best match algorithm on the dev names so we only need to look at the
- // first few charters to match the full device name. Short name forms are
- // legal from the caller.
- //
- Status = EFI_SUCCESS;
- if (*PathName == 'f' || *PathName == 'F' || VolumeNameMatch) {
- if (PathName[1] == 's' || PathName[1] == 'S' || VolumeNameMatch) {
- if (DevNumber >= mFsCount) {
- goto ErrorExit;
- }
- File->Type = EfiOpenFileSystem;
- File->EfiHandle = mFs[DevNumber];
- Status = EblFileDevicePath (File, &PathName[FileStart], OpenMode);
-
- } else if (PathName[1] == 'v' || PathName[1] == 'V') {
- if (DevNumber >= mFvCount) {
- goto ErrorExit;
- }
- File->Type = EfiOpenFirmwareVolume;
- File->EfiHandle = mFv[DevNumber];
-
- if ((PathName[FileStart] == '/') || (PathName[FileStart] == '\\')) {
- // Skip leading / as its not really needed for the FV since no directories are supported
- FileStart++;
- }
-
- // Check for 2nd :
- ModifiedSectionType = SectionType;
- for (Index = FileStart; PathName[Index] != '\0'; Index++) {
- if (PathName[Index] == ':') {
- // Support fv0:\DxeCore:0x10
- // This means open the PE32 Section of the file
- ModifiedSectionType = (EFI_SECTION_TYPE)AsciiStrHexToUintn (&PathName[Index + 1]);
- PathName[Index] = '\0';
- }
- }
- File->FvSectionType = ModifiedSectionType;
- Status = EblFvFileDevicePath (File, &PathName[FileStart], ModifiedSectionType);
- }
- } else if ((*PathName == 'A') || (*PathName == 'a')) {
- // Handle a:0x10000000:0x1234 address form a:ADDRESS:SIZE
- File->Type = EfiOpenMemoryBuffer;
- // 1st colon is at PathName[FileStart - 1]
- File->Buffer = (VOID *)AsciiStrHexToUintn (&PathName[FileStart]);
-
- // Find 2nd colon
- while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
- FileStart++;
- }
-
- // If we ran out of string, there's no extra data
- if (PathName[FileStart] == '\0') {
- File->Size = 0;
- } else {
- File->Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
- }
-
- // if there's no number after the second colon, default
- // the end of memory
- if (File->Size == 0) {
- File->Size = (UINTN)(0 - (UINTN)File->Buffer);
- }
-
- File->MaxPosition = File->Size;
- File->BaseOffset = (UINTN)File->Buffer;
-
- } else if (*PathName== 'l' || *PathName == 'L') {
- if (DevNumber >= mLoadFileCount) {
- goto ErrorExit;
- }
- File->Type = EfiOpenLoadFile;
- File->EfiHandle = mLoadFile[DevNumber];
-
- Status = gBS->HandleProtocol (File->EfiHandle, &gEfiLoadFileProtocolGuid, (VOID **)&File->LoadFile);
- if (EFI_ERROR (Status)) {
- goto ErrorExit;
- }
-
- Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
- if (EFI_ERROR (Status)) {
- goto ErrorExit;
- }
- File->DevicePath = DuplicateDevicePath (DevicePath);
-
- } else if (*PathName == 'b' || *PathName == 'B') {
- // Handle b#:0x10000000:0x1234 address form b#:ADDRESS:SIZE
- if (DevNumber >= mBlkIoCount) {
- goto ErrorExit;
- }
- File->Type = EfiOpenBlockIo;
- File->EfiHandle = mBlkIo[DevNumber];
- EblFileDevicePath (File, "", OpenMode);
-
- // 1st colon is at PathName[FileStart - 1]
- File->DiskOffset = AsciiStrHexToUintn (&PathName[FileStart]);
-
- // Find 2nd colon
- while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
- FileStart++;
- }
-
- // If we ran out of string, there's no extra data
- if (PathName[FileStart] == '\0') {
- Size = 0;
- } else {
- Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
- }
-
- // if a zero size is passed in (or the size is left out entirely),
- // go to the end of the device.
- if (Size == 0) {
- File->Size = File->Size - File->DiskOffset;
- } else {
- File->Size = Size;
- }
-
- File->MaxPosition = File->Size;
- File->BaseOffset = File->DiskOffset;
- } else if ((*PathName) >= '0' && (*PathName <= '9')) {
-
- // Get current IP address
- Status = EblGetCurrentIpAddress (&Ip);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Device IP Address is not configured.\n");
- goto ErrorExit;
- }
-
-
- // Parse X.X.X.X:Filename, only support IPv4 TFTP for now...
- File->Type = EfiOpenTftp;
- File->IsDirty = FALSE;
- File->IsBufferValid = FALSE;
-
- Status = ConvertIpStringToEfiIp (PathName, &File->ServerIp);
- }
-
- if (EFI_ERROR (Status)) {
- goto ErrorExit;
- }
-
- GuardFile = (EFI_OPEN_FILE_GUARD *)AllocateZeroPool (sizeof (EFI_OPEN_FILE_GUARD));
- if (GuardFile == NULL) {
- goto ErrorExit;
- }
-
- GuardFile->Header = EFI_OPEN_FILE_GUARD_HEADER;
- CopyMem (&(GuardFile->File), &FileData, sizeof (EFI_OPEN_FILE));
- GuardFile->Footer = EFI_OPEN_FILE_GUARD_FOOTER;
-
- return &(GuardFile->File);
-
-ErrorExit:
- FreePool (File->DeviceName);
- return NULL;
-}
-
-#define FILE_COPY_CHUNK 0x01000000
-
-EFI_STATUS
-EfiCopyFile (
- IN CHAR8 *DestinationFile,
- IN CHAR8 *SourceFile
- )
-{
- EFI_OPEN_FILE *Source = NULL;
- EFI_OPEN_FILE *Destination = NULL;
- EFI_STATUS Status = EFI_SUCCESS;
- VOID *Buffer = NULL;
- UINTN Size;
- UINTN Offset;
- UINTN Chunk = FILE_COPY_CHUNK;
-
- Source = EfiOpen (SourceFile, EFI_FILE_MODE_READ, 0);
- if (Source == NULL) {
- AsciiPrint("Source file open error.\n");
- Status = EFI_NOT_FOUND;
- goto Exit;
- }
-
- Destination = EfiOpen (DestinationFile, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
- if (Destination == NULL) {
- AsciiPrint("Destination file open error.\n");
- Status = EFI_NOT_FOUND;
- goto Exit;
- }
-
- Buffer = AllocatePool(FILE_COPY_CHUNK);
- if (Buffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- Size = EfiTell(Source, NULL);
-
- for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size; Offset += Chunk) {
- Chunk = FILE_COPY_CHUNK;
-
- Status = EfiRead(Source, Buffer, &Chunk);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Read file error %r\n", Status);
- goto Exit;
- }
-
- Status = EfiWrite(Destination, Buffer, &Chunk);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Write file error %r\n", Status);
- goto Exit;
- }
- }
-
- // Any left over?
- if (Offset < Size) {
- Chunk = Size - Offset;
-
- Status = EfiRead(Source, Buffer, &Chunk);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Read file error\n");
- goto Exit;
- }
-
- Status = EfiWrite(Destination, Buffer, &Chunk);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Write file error\n");
- goto Exit;
- }
- }
-
-Exit:
- if (Source != NULL) {
- Status = EfiClose(Source);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Source close error");
- }
- }
-
- if (Destination != NULL) {
- Status = EfiClose(Destination);
- if (EFI_ERROR(Status)) {
- AsciiPrint("Destination close error");
- }
- }
-
- if (Buffer != NULL) {
- FreePool(Buffer);
- }
-
- return Status;
-}
-
-/**
-Use DeviceType and Index to form a valid PathName and try and open it.
-
-@param DeviceType Device type to open
-@param Index Device Index to use. Zero relative.
-
-@return NULL Open failed
-@return Valid EFI_OPEN_FILE handle
-
-**/
-EFI_OPEN_FILE *
-EfiDeviceOpenByType (
- IN EFI_OPEN_FILE_TYPE DeviceType,
- IN UINTN Index
- )
-{
- CHAR8 *DevStr;
- CHAR8 Path[MAX_CMD_LINE];
-
- switch (DeviceType) {
- case EfiOpenLoadFile:
- DevStr = "loadfile%d:";
- break;
- case EfiOpenFirmwareVolume:
- DevStr = "fv%d:";
- break;
- case EfiOpenFileSystem:
- DevStr = "fs%d:";
- break;
- case EfiOpenBlockIo:
- DevStr = "blk%d:";
- break;
- case EfiOpenMemoryBuffer:
- DevStr = "a%d:";
- break;
- default:
- return NULL;
- }
-
- AsciiSPrint (Path, MAX_PATHNAME, DevStr, Index);
-
- return EfiOpen (Path, EFI_FILE_MODE_READ, 0);
-}
-
-
-/**
-Close a file handle opened by EfiOpen() and free all resources allocated by
-EfiOpen().
-
-@param Stream Open File Handle
-
-@return EFI_INVALID_PARAMETER Stream is not an Open File
-@return EFI_SUCCESS Steam closed
-
-**/
-EFI_STATUS
-EfiClose (
- IN EFI_OPEN_FILE *File
- )
-{
- EFI_STATUS Status;
- UINT64 TftpBufferSize;
-
- if (!FileHandleValid (File)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //Write the buffer contents to TFTP file.
- if ((File->Type == EfiOpenTftp) && (File->IsDirty)) {
-
- TftpBufferSize = File->Size;
- Status = EblMtftp (
- EFI_PXE_BASE_CODE_TFTP_WRITE_FILE,
- File->Buffer,
- TRUE,
- &TftpBufferSize,
- NULL,
- &File->ServerIp,
- (UINT8 *)File->FileName,
- NULL,
- FALSE
- );
- if (EFI_ERROR(Status)) {
- AsciiPrint("TFTP error during APPLE_NSP_TFTP_WRITE_FILE: %r\n", Status);
- return Status;
- }
- }
-
- if ((File->Type == EfiOpenLoadFile) ||
- ((File->Type == EfiOpenTftp) && (File->IsBufferValid == TRUE)) ||
- ((File->Type == EfiOpenFirmwareVolume) && (File->IsBufferValid == TRUE))) {
- EblFreePool(File->Buffer);
- }
-
- EblFreePool (File->DevicePath);
- EblFreePool (File->DeviceName);
- EblFreePool (File->FsFileInfo);
- EblFreePool (File->FsInfo);
-
- if (File->FsFileHandle != NULL) {
- File->FsFileHandle->Close (File->FsFileHandle);
- }
-
- // Need to free File and it's Guard structures
- EblFreePool (BASE_CR (File, EFI_OPEN_FILE_GUARD, File));
- return EFI_SUCCESS;
-}
-
-
-/**
-Return the size of the file represented by Stream. Also return the current
-Seek position. Opening a file will enable a valid file size to be returned.
-LoadFile is an exception as a load file size is set to zero.
-
-@param Stream Open File Handle
-
-@return 0 Stream is not an Open File or a valid LoadFile handle
-
-**/
-UINTN
-EfiTell (
- IN EFI_OPEN_FILE *File,
- OUT EFI_LBA *CurrentPosition OPTIONAL
- )
-{
- EFI_STATUS Status;
- UINT64 BufferSize = 0;
-
- if (!FileHandleValid (File)) {
- return 0;
- }
-
- if (CurrentPosition != NULL) {
- *CurrentPosition = File->CurrentPosition;
- }
-
- if (File->Type == EfiOpenLoadFile) {
- // Figure out the File->Size
- File->Buffer = NULL;
- File->Size = 0;
- Status = File->LoadFile->LoadFile (File->LoadFile, File->DevicePath, FALSE, &File->Size, File->Buffer);
- if (Status != EFI_BUFFER_TOO_SMALL) {
- return 0;
- }
-
- File->MaxPosition = (UINT64)File->Size;
- } else if (File->Type == EfiOpenTftp) {
-
- Status = EblMtftp (
- EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
- NULL,
- FALSE,
- &BufferSize,
- NULL,
- &File->ServerIp,
- (UINT8 *)File->FileName,
- NULL,
- TRUE
- );
- if (EFI_ERROR(Status)) {
- AsciiPrint("TFTP error during APPLE_NSP_TFTP_GET_FILE_SIZE: %r\n", Status);
- return 0;
- }
-
- File->Size = (UINTN)BufferSize;
- File->MaxPosition = File->Size;
- }
-
- return File->Size;
-}
-
-
-/**
-Seek to the Offset location in the file. LoadFile and FV device types do
-not support EfiSeek(). It is not possible to grow the file size using
-EfiSeek().
-
-SeekType defines how use Offset to calculate the new file position:
-EfiSeekStart : Position = Offset
-EfiSeekCurrent: Position is Offset bytes from the current position
-EfiSeekEnd : Only supported if Offset is zero to seek to end of file.
-
-@param Stream Open File Handle
-@param Offset Offset to seek too.
-@param SeekType Type of seek to perform
-
-
-@return EFI_INVALID_PARAMETER Stream is not an Open File
-@return EFI_UNSUPPORTED LoadFile and FV do not support Seek
-@return EFI_NOT_FOUND Seek past the end of the file.
-@return EFI_SUCCESS Steam closed
-
-**/
-EFI_STATUS
-EfiSeek (
- IN EFI_OPEN_FILE *File,
- IN EFI_LBA Offset,
- IN EFI_SEEK_TYPE SeekType
- )
-{
- EFI_STATUS Status;
- UINT64 CurrentPosition;
-
- if (!FileHandleValid (File)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (File->Type == EfiOpenLoadFile) {
- // LoadFile does not support Seek
- return EFI_UNSUPPORTED;
- }
-
- CurrentPosition = File->CurrentPosition;
- switch (SeekType) {
- case EfiSeekStart:
- if (Offset > File->MaxPosition) {
- return EFI_NOT_FOUND;
- }
- CurrentPosition = Offset;
- break;
-
- case EfiSeekCurrent:
- if ((File->CurrentPosition + Offset) > File->MaxPosition) {
- return EFI_NOT_FOUND;
- }
- CurrentPosition += Offset;
- break;
-
- case EfiSeekEnd:
- if (Offset != 0) {
- // We don't support growing file size via seeking past end of file
- return EFI_UNSUPPORTED;
- }
- CurrentPosition = File->MaxPosition;
- break;
-
- default:
- return EFI_NOT_FOUND;
- }
-
- Status = EFI_SUCCESS;
- if (File->FsFileHandle != NULL) {
- Status = File->FsFileHandle->SetPosition (File->FsFileHandle, CurrentPosition);
- }
-
- if (!EFI_ERROR (Status)) {
- File->CurrentPosition = CurrentPosition;
- }
-
- return Status;
-}
-
-EFI_STATUS
-CacheTftpFile (
- IN OUT EFI_OPEN_FILE *File
- )
-{
- EFI_STATUS Status;
- UINT64 TftpBufferSize;
-
- if (File->IsBufferValid) {
- return EFI_SUCCESS;
- }
-
- // Make sure the file size is set.
- EfiTell (File, NULL);
-
- //Allocate a buffer to hold the whole file.
- File->Buffer = AllocatePool(File->Size);
- if (File->Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TftpBufferSize = File->Size;
-
- Status = EblMtftp (
- EFI_PXE_BASE_CODE_TFTP_READ_FILE,
- File->Buffer,
- FALSE,
- &TftpBufferSize,
- NULL,
- &File->ServerIp,
- (UINT8 *)File->FileName,
- NULL,
- FALSE);
- if (EFI_ERROR(Status)) {
- AsciiPrint("TFTP error during APPLE_NSP_TFTP_READ_FILE: %r\n", Status);
- FreePool(File->Buffer);
- return Status;
- }
-
- // Set the buffer valid flag.
- File->IsBufferValid = TRUE;
-
- return Status;
-}
-
-/**
-Read BufferSize bytes from the current location in the file. For load file,
-FV, and TFTP case you must read the entire file.
-
-@param Stream Open File Handle
-@param Buffer Caller allocated buffer.
-@param BufferSize Size of buffer in bytes.
-
-
-@return EFI_SUCCESS Stream is not an Open File
-@return EFI_END_OF_FILE Tried to read past the end of the file
-@return EFI_INVALID_PARAMETER Stream is not an open file handle
-@return EFI_BUFFER_TOO_SMALL Buffer is not big enough to do the read
-@return "other" Error returned from device read
-
-**/
-EFI_STATUS
-EfiRead (
- IN EFI_OPEN_FILE *File,
- OUT VOID *Buffer,
- OUT UINTN *BufferSize
- )
-{
- EFI_STATUS Status;
- UINT32 AuthenticationStatus;
- EFI_DISK_IO_PROTOCOL *DiskIo;
-
- if (!FileHandleValid (File)) {
- return EFI_INVALID_PARAMETER;
- }
-
- // Don't read past the end of the file.
- if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
- return EFI_END_OF_FILE;
- }
-
- switch (File->Type) {
- case EfiOpenLoadFile:
- // Figure out the File->Size
- EfiTell (File, NULL);
-
- Status = File->LoadFile->LoadFile (File->LoadFile, File->DevicePath, FALSE, BufferSize, Buffer);
- break;
-
- case EfiOpenFirmwareVolume:
- if (CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
- // This is the entire FV device, so treat like a memory buffer
- CopyMem (Buffer, (VOID *)(UINTN)(File->FvStart + File->CurrentPosition), *BufferSize);
- File->CurrentPosition += *BufferSize;
- Status = EFI_SUCCESS;
- } else {
- if (File->Buffer == NULL) {
- if (File->FvSectionType == EFI_SECTION_ALL) {
- Status = File->Fv->ReadFile (
- File->Fv,
- &File->FvNameGuid,
- (VOID **)&File->Buffer,
- &File->Size,
- &File->FvType,
- &File->FvAttributes,
- &AuthenticationStatus
- );
- } else {
- Status = File->Fv->ReadSection (
- File->Fv,
- &File->FvNameGuid,
- File->FvSectionType,
- 0,
- (VOID **)&File->Buffer,
- &File->Size,
- &AuthenticationStatus
- );
- }
- if (EFI_ERROR (Status)) {
- return Status;
- }
- File->IsBufferValid = TRUE;
- }
- // Operate on the cached buffer so Seek will work
- CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
- File->CurrentPosition += *BufferSize;
- Status = EFI_SUCCESS;
- }
- break;
-
- case EfiOpenMemoryBuffer:
- CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
- File->CurrentPosition += *BufferSize;
- Status = EFI_SUCCESS;
- break;
-
- case EfiOpenFileSystem:
- Status = File->FsFileHandle->Read (File->FsFileHandle, BufferSize, Buffer);
- File->CurrentPosition += *BufferSize;
- break;
-
- case EfiOpenBlockIo:
- Status = gBS->HandleProtocol(File->EfiHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
- if (!EFI_ERROR(Status)) {
- Status = DiskIo->ReadDisk(DiskIo, File->FsBlockIoMedia->MediaId, File->DiskOffset + File->CurrentPosition, *BufferSize, Buffer);
- }
- File->CurrentPosition += *BufferSize;
- break;
-
- case EfiOpenTftp:
- // Cache the file if it hasn't been cached yet.
- if (File->IsBufferValid == FALSE) {
- Status = CacheTftpFile (File);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- // Copy out the requested data
- CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
- File->CurrentPosition += *BufferSize;
-
- Status = EFI_SUCCESS;
- break;
-
- default:
- return EFI_INVALID_PARAMETER;
- };
-
- return Status;
-}
-
-
-/**
-Read the entire file into a buffer. This routine allocates the buffer and
-returns it to the user full of the read data.
-
-This is very useful for load file where it's hard to know how big the buffer
-must be.
-
-@param Stream Open File Handle
-@param Buffer Pointer to buffer to return.
-@param BufferSize Pointer to Size of buffer return..
-
-
-@return EFI_SUCCESS Stream is not an Open File
-@return EFI_END_OF_FILE Tried to read past the end of the file
-@return EFI_INVALID_PARAMETER Stream is not an open file handle
-@return EFI_BUFFER_TOO_SMALL Buffer is not big enough to do the read
-@return "other" Error returned from device read
-
-**/
-EFI_STATUS
-EfiReadAllocatePool (
- IN EFI_OPEN_FILE *File,
- OUT VOID **Buffer,
- OUT UINTN *BufferSize
- )
-{
- if (!FileHandleValid (File)) {
- return EFI_INVALID_PARAMETER;
- }
-
- // Loadfile defers file size determination on Open so use tell to find it
- EfiTell (File, NULL);
-
- *BufferSize = File->Size;
- *Buffer = AllocatePool (*BufferSize);
- if (*Buffer == NULL) {
- return EFI_NOT_FOUND;
- }
-
- return EfiRead (File, *Buffer, BufferSize);
-}
-
-
-/**
-Write data back to the file. For TFTP case you must write the entire file.
-
-@param Stream Open File Handle
-@param Buffer Pointer to buffer to return.
-@param BufferSize Pointer to Size of buffer return..
-
-
-@return EFI_SUCCESS Stream is not an Open File
-@return EFI_END_OF_FILE Tried to read past the end of the file
-@return EFI_INVALID_PARAMETER Stream is not an open file handle
-@return EFI_BUFFER_TOO_SMALL Buffer is not big enough to do the read
-@return "other" Error returned from device write
-
-**/
-EFI_STATUS
-EfiWrite (
- IN EFI_OPEN_FILE *File,
- OUT VOID *Buffer,
- OUT UINTN *BufferSize
- )
-{
- EFI_STATUS Status;
- EFI_FV_WRITE_FILE_DATA FileData;
- EFI_DISK_IO_PROTOCOL *DiskIo;
-
- if (!FileHandleValid (File)) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (File->Type) {
- case EfiOpenMemoryBuffer:
- if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
- return EFI_END_OF_FILE;
- }
-
- CopyMem (File->Buffer + File->CurrentPosition, Buffer, *BufferSize);
- File->CurrentPosition += *BufferSize;
- Status = EFI_SUCCESS;
-
- case EfiOpenLoadFile:
- // LoadFile device is read only be definition
- Status = EFI_UNSUPPORTED;
-
- case EfiOpenFirmwareVolume:
- if (File->FvSectionType != EFI_SECTION_ALL) {
- // Writes not support to a specific section. You have to update entire file
- return EFI_UNSUPPORTED;
- }
-
- FileData.NameGuid = &(File->FvNameGuid);
- FileData.Type = File->FvType;
- FileData.FileAttributes = File->FvAttributes;
- FileData.Buffer = Buffer;
- FileData.BufferSize = (UINT32)*BufferSize;
- Status = File->Fv->WriteFile (File->Fv, 1, EFI_FV_UNRELIABLE_WRITE, &FileData);
- break;
-
- case EfiOpenFileSystem:
- Status = File->FsFileHandle->Write (File->FsFileHandle, BufferSize, Buffer);
- File->CurrentPosition += *BufferSize;
- break;
-
- case EfiOpenBlockIo:
- if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
- return EFI_END_OF_FILE;
- }
-
- Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
- if (!EFI_ERROR(Status)) {
- Status = DiskIo->WriteDisk (DiskIo, File->FsBlockIoMedia->MediaId, File->DiskOffset + File->CurrentPosition, *BufferSize, Buffer);
- }
- File->CurrentPosition += *BufferSize;
- break;
-
- case EfiOpenTftp:
- // Cache the file if it hasn't been cached yet.
- if (File->IsBufferValid == FALSE) {
- Status = CacheTftpFile(File);
- if (EFI_ERROR(Status)) {
- return Status;
- }
- }
-
- // Don't overwrite the buffer
- if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
- UINT8 *TempBuffer;
-
- TempBuffer = File->Buffer;
-
- File->Buffer = AllocatePool ((UINTN)(File->CurrentPosition + *BufferSize));
- if (File->Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- CopyMem (File->Buffer, TempBuffer, File->Size);
-
- FreePool (TempBuffer);
-
- File->Size = (UINTN)(File->CurrentPosition + *BufferSize);
- File->MaxPosition = (UINT64)File->Size;
- }
-
- // Copy in the requested data
- CopyMem (File->Buffer + File->CurrentPosition, Buffer, *BufferSize);
- File->CurrentPosition += *BufferSize;
-
- // Mark the file dirty
- File->IsDirty = TRUE;
-
- Status = EFI_SUCCESS;
- break;
-
- default:
- Status = EFI_INVALID_PARAMETER;
- };
-
- return Status;
-}
-
-
-/**
-Given Cwd expand Path to remove .. and replace them with real
-directory names.
-
-@param Cwd Current Working Directory
-@param Path Path to expand
-
-@return NULL Cwd or Path are not valid
-@return 'other' Path with .. expanded
-
-**/
-CHAR8 *
-ExpandPath (
- IN CHAR8 *Cwd,
- IN CHAR8 *Path
- )
-{
- CHAR8 *NewPath;
- CHAR8 *Work, *Start, *End;
- UINTN StrLen;
- INTN i;
-
- if (Cwd == NULL || Path == NULL) {
- return NULL;
- }
-
- StrLen = AsciiStrSize (Cwd);
- if (StrLen <= 2) {
- // Smallest valid path is 1 char and a null
- return NULL;
- }
-
- StrLen = AsciiStrSize (Path);
- NewPath = AllocatePool (AsciiStrSize (Cwd) + StrLen + 1);
- if (NewPath == NULL) {
- return NULL;
- }
- AsciiStrCpy (NewPath, Cwd);
-
- End = Path + StrLen;
- for (Start = Path ;;) {
- Work = AsciiStrStr (Start, "..") ;
- if (Work == NULL) {
- // Remaining part of Path contains no more ..
- break;
- }
-
- // append path prior to ..
- AsciiStrnCat (NewPath, Start, Work - Start);
- StrLen = AsciiStrLen (NewPath);
- for (i = StrLen; i >= 0; i--) {
- if (NewPath[i] == ':') {
- // too many ..
- return NULL;
- }
- if (NewPath[i] == '/' || NewPath[i] == '\\') {
- if ((i > 0) && (NewPath[i-1] == ':')) {
- // leave the / before a :
- NewPath[i+1] = '\0';
- } else {
- // replace / will Null to remove trailing file/dir reference
- NewPath[i] = '\0';
- }
- break;
- }
- }
-
- Start = Work + 3;
- }
-
- // Handle the path that remains after the ..
- AsciiStrnCat (NewPath, Start, End - Start);
-
- return NewPath;
-}
-
-
-/**
-Set the Current Working Directory (CWD). If a call is made to EfiOpen () and
-the path does not contain a device name, The CWD is prepended to the path.
-
-@param Cwd Current Working Directory to set
-
-
-@return EFI_SUCCESS CWD is set
-@return EFI_INVALID_PARAMETER Cwd is not a valid device:path
-
-**/
-EFI_STATUS
-EfiSetCwd (
- IN CHAR8 *Cwd
- )
-{
- EFI_OPEN_FILE *File;
- UINTN Len;
- CHAR8 *Path;
-
- if (Cwd == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (AsciiStrCmp (Cwd, ".") == 0) {
- // cd . is a no-op
- return EFI_SUCCESS;
- }
-
- Path = Cwd;
- if (AsciiStrStr (Cwd, "..") != NULL) {
- if (gCwd == NULL) {
- // no parent
- return EFI_SUCCESS;
- }
-
- Len = AsciiStrLen (gCwd);
- if ((gCwd[Len-2] == ':') && ((gCwd[Len-1] == '/') || (gCwd[Len-1] == '\\'))) {
- // parent is device so nothing to do
- return EFI_SUCCESS;
- }
-
- // Expand .. in Cwd, given we know current working directory
- Path = ExpandPath (gCwd, Cwd);
- if (Path == NULL) {
- return EFI_NOT_FOUND;
- }
- }
-
- File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
- if (File == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (gCwd != NULL) {
- FreePool (gCwd);
- }
-
- // Use the info returned from EfiOpen as it can add in CWD if needed. So Cwd could be
- // relative to the current gCwd or not.
- gCwd = AllocatePool (AsciiStrSize (File->DeviceName) + AsciiStrSize (File->FileName) + 10);
- if (gCwd == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- AsciiStrCpy (gCwd, File->DeviceName);
- if (File->FileName == NULL) {
- AsciiStrCat (gCwd, ":\\");
- } else {
- AsciiStrCat (gCwd, ":");
- AsciiStrCat (gCwd, File->FileName);
- }
-
-
- EfiClose (File);
- if (Path != Cwd) {
- FreePool (Path);
- }
- return EFI_SUCCESS;
-}
-
-
-/**
-Set the Current Working Directory (CWD). If a call is made to EfiOpen () and
-the path does not contain a device name, The CWD is prepended to the path.
-The CWD buffer is only valid until a new call is made to EfiSetCwd(). After
-a call to EfiSetCwd() it is not legal to use the pointer returned by
-this function.
-
-@param Cwd Current Working Directory
-
-
-@return "" No CWD set
-@return 'other' Returns buffer that contains CWD.
-
-**/
-CHAR8 *
-EfiGetCwd (
- VOID
- )
-{
- if (gCwd == NULL) {
- return "";
- }
- return gCwd;
-}
-
-
+/** @file
+File IO routines inspired by Streams with an EFI flavor
+
+Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+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.
+
+Basic support for opening files on different device types. The device string
+is in the form of DevType:Path. Current DevType is required as there is no
+current mounted device concept of current working directory concept implement
+by this library.
+
+Device names are case insensitive and only check the leading characters for
+unique matches. Thus the following are all the same:
+LoadFile0:
+l0:
+L0:
+Lo0:
+
+Supported Device Names:
+A0x1234:0x12 - A memory buffer starting at address 0x1234 for 0x12 bytes
+l1: - EFI LoadFile device one.
+B0: - EFI BlockIo zero.
+fs3: - EFI Simple File System device 3
+Fv2: - EFI Firmware VOlume device 2
+10.0.1.102: - TFTP service IP followed by the file name
+**/
+
+#include <PiDxe.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Guid/FileInfo.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EfiFileLib.h>
+#include <Library/PcdLib.h>
+#include <Library/EblNetworkLib.h>
+
+
+CHAR8 *gCwd = NULL;
+
+CONST EFI_GUID gZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
+
+#define EFI_OPEN_FILE_GUARD_HEADER 0x4B4D4641
+#define EFI_OPEN_FILE_GUARD_FOOTER 0x444D5A56
+
+// Need to defend against this overflowing
+#define MAX_CMD_LINE 0x200
+
+typedef struct {
+ UINT32 Header;
+ EFI_OPEN_FILE File;
+ UINT32 Footer;
+} EFI_OPEN_FILE_GUARD;
+
+
+// globals to store current open device info
+EFI_HANDLE *mBlkIo = NULL;
+UINTN mBlkIoCount = 0;
+
+EFI_HANDLE *mFs = NULL;
+UINTN mFsCount = 0;
+// mFsInfo[] array entries must match mFs[] handles
+EFI_FILE_SYSTEM_INFO **mFsInfo = NULL;
+
+EFI_HANDLE *mFv = NULL;
+UINTN mFvCount = 0;
+EFI_HANDLE *mLoadFile = NULL;
+UINTN mLoadFileCount = 0;
+
+
+
+/**
+Internal worker function to validate a File handle.
+
+@param File Open File Handle
+
+@return TRUE File is valid
+@return FALSE File is not valid
+
+
+**/
+BOOLEAN
+FileHandleValid (
+ IN EFI_OPEN_FILE *File
+ )
+{
+ EFI_OPEN_FILE_GUARD *GuardFile;
+
+ // Look right before and after file structure for the correct signatures
+ GuardFile = BASE_CR (File, EFI_OPEN_FILE_GUARD, File);
+ if ((GuardFile->Header != EFI_OPEN_FILE_GUARD_HEADER) ||
+ (GuardFile->Footer != EFI_OPEN_FILE_GUARD_FOOTER) ) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+Internal worker function. If Buffer is not NULL free it.
+
+@param Buffer Buffer to FreePool()
+
+**/
+VOID
+EblFreePool (
+ IN VOID *Buffer
+ )
+{
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+}
+
+/**
+Update Device List Global Variables
+
+**/
+VOID
+EblUpdateDeviceLists (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
+ EFI_FILE_HANDLE Root;
+ UINTN Index;
+
+ if (mBlkIo != NULL) {
+ FreePool (mBlkIo);
+ }
+ gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &mBlkIoCount, &mBlkIo);
+
+
+
+ if (mFv != NULL) {
+ FreePool (mFv);
+ }
+ gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &mFvCount, &mFv);
+
+ if (mLoadFile != NULL) {
+ FreePool (mLoadFile);
+ }
+ gBS->LocateHandleBuffer (ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &mLoadFileCount, &mLoadFile);
+
+ if (mFs != NULL) {
+ FreePool (mFs);
+ }
+
+ if (&mFsInfo[0] != NULL) {
+ // Need to Free the mFsInfo prior to recalculating mFsCount so don't move this code
+ for (Index = 0; Index < mFsCount; Index++) {
+ if (mFsInfo[Index] != NULL) {
+ FreePool (mFsInfo[Index]);
+ }
+ }
+ FreePool (mFsInfo);
+ }
+
+ gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &mFsCount, &mFs);
+
+
+ mFsInfo = AllocateZeroPool (mFsCount * sizeof (EFI_FILE_SYSTEM_INFO *));
+ if (mFsInfo == NULL) {
+ // If we can't do this then we can't support file system entries
+ mFsCount = 0;
+ } else {
+ // Loop through all the file system structures and cache the file system info data
+ for (Index =0; Index < mFsCount; Index++) {
+ Status = gBS->HandleProtocol (mFs[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
+ if (!EFI_ERROR (Status)) {
+ Status = Fs->OpenVolume (Fs, &Root);
+ if (!EFI_ERROR (Status)) {
+ // Get information about the volume
+ Size = 0;
+ Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ mFsInfo[Index] = AllocatePool (Size);
+ Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, mFsInfo[Index]);
+ }
+
+ Root->Close (Root);
+ }
+ }
+ }
+ }
+}
+
+
+/**
+PathName is in the form <device name>:<path> for example fs1:\ or ROOT:\.
+Return TRUE if the <devce name> prefix of PathName matches a file system
+Volume Name. MatchIndex is the array index in mFsInfo[] of the match,
+and it can be used with mFs[] to find the handle that needs to be opened
+
+@param PathName PathName to check
+@param FileStart Index of the first character of the <path>
+@param MatchIndex Index in mFsInfo[] that matches
+
+@return TRUE PathName matches a Volume Label and MatchIndex is valid
+@return FALSE PathName does not match a Volume Label MatchIndex undefined
+
+**/
+BOOLEAN
+EblMatchVolumeName (
+ IN CHAR8 *PathName,
+ IN UINTN FileStart,
+ OUT UINTN *MatchIndex
+ )
+{
+ UINTN Index;
+ UINTN Compare;
+ UINTN VolStrLen;
+ BOOLEAN Match;
+
+ for (Index =0; Index < mFsCount; Index++) {
+ if (mFsInfo[Index] == NULL) {
+ // FsInfo is not valid so skip it
+ continue;
+ }
+ VolStrLen = StrLen (mFsInfo[Index]->VolumeLabel);
+ for (Compare = 0, Match = TRUE; Compare < (FileStart - 1); Compare++) {
+ if (Compare > VolStrLen) {
+ Match = FALSE;
+ break;
+ }
+ if (PathName[Compare] != (CHAR8)mFsInfo[Index]->VolumeLabel[Compare]) {
+ // If the VolumeLabel has a space allow a _ to match with it in addition to ' '
+ if (!((PathName[Compare] == '_') && (mFsInfo[Index]->VolumeLabel[Compare] == L' '))) {
+ Match = FALSE;
+ break;
+ }
+ }
+ }
+ if (Match) {
+ *MatchIndex = Index;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+/**
+Return the number of devices of the current type active in the system
+
+@param Type Device type to check
+
+@return 0 Invalid type
+
+**/
+UINTN
+EfiGetDeviceCounts (
+ IN EFI_OPEN_FILE_TYPE DeviceType
+ )
+{
+ switch (DeviceType) {
+ case EfiOpenLoadFile:
+ return mLoadFileCount;
+ case EfiOpenFirmwareVolume:
+ return mFvCount;
+ case EfiOpenFileSystem:
+ return mFsCount;
+ case EfiOpenBlockIo:
+ return mBlkIoCount;
+ default:
+ return 0;
+ }
+}
+
+EFI_STATUS
+ConvertIpStringToEfiIp (
+ IN CHAR8 *PathName,
+ OUT EFI_IP_ADDRESS *ServerIp
+ )
+{
+ CHAR8 *Str;
+
+ Str = PathName;
+ ServerIp->v4.Addr[0] = (UINT8)AsciiStrDecimalToUintn (Str);
+
+ Str = AsciiStrStr (Str, ".");
+ if (Str == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ServerIp->v4.Addr[1] = (UINT8)AsciiStrDecimalToUintn (++Str);
+
+ Str = AsciiStrStr (Str, ".");
+ if (Str == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ServerIp->v4.Addr[2] = (UINT8)AsciiStrDecimalToUintn (++Str);
+
+ Str = AsciiStrStr (Str, ".");
+ if (Str == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ServerIp->v4.Addr[3] = (UINT8)AsciiStrDecimalToUintn (++Str);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+Internal work function to extract a device number from a string skipping
+text. Easy way to extract numbers from strings like blk7:.
+
+@param Str String to extract device number form
+
+@return -1 Device string is not valid
+@return Device #
+
+**/
+UINTN
+EblConvertDevStringToNumber (
+ IN CHAR8 *Str
+ )
+{
+ UINTN Max;
+ UINTN Index;
+
+
+ // Find the first digit
+ Max = AsciiStrLen (Str);
+ for (Index = 0; !((*Str >= '0') && (*Str <= '9')) && (Index < Max); Index++) {
+ Str++;
+ }
+ if (Index == Max) {
+ return (UINTN)-1;
+ }
+
+ return AsciiStrDecimalToUintn (Str);
+}
+
+
+/**
+Internal work function to fill in EFI_OPEN_FILE information for the Fs and BlkIo
+
+@param File Open file handle
+@param FileName Name of file after device stripped off
+
+
+**/
+EFI_STATUS
+EblFileDevicePath (
+ IN OUT EFI_OPEN_FILE *File,
+ IN CHAR8 *FileName,
+ IN CONST UINT64 OpenMode
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ FILEPATH_DEVICE_PATH *FilePath;
+ EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;
+ CHAR16 UnicodeFileName[MAX_PATHNAME];
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
+ EFI_FILE_HANDLE Root;
+
+
+ if ( *FileName != 0 ) {
+ AsciiStrToUnicodeStr (FileName, UnicodeFileName);
+ } else {
+ AsciiStrToUnicodeStr ("\\", UnicodeFileName);
+ }
+
+ Size = StrSize (UnicodeFileName);
+ FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL));
+ if (FileDevicePath != NULL) {
+ FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
+ FilePath->Header.Type = MEDIA_DEVICE_PATH;
+ FilePath->Header.SubType = MEDIA_FILEPATH_DP;
+ CopyMem (&FilePath->PathName, UnicodeFileName, Size);
+ SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
+ SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
+
+ if (File->EfiHandle != NULL) {
+ File->DevicePath = DevicePathFromHandle (File->EfiHandle);
+ }
+
+ File->DevicePath = AppendDevicePath (File->DevicePath, FileDevicePath);
+ FreePool (FileDevicePath);
+ }
+
+ Status = gBS->HandleProtocol (File->EfiHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo);
+ if (!EFI_ERROR (Status)) {
+ File->FsBlockIoMedia = BlkIo->Media;
+ File->FsBlockIo = BlkIo;
+
+ // If we are not opening the device this will get over written with file info
+ File->MaxPosition = MultU64x32 (BlkIo->Media->LastBlock + 1, BlkIo->Media->BlockSize);
+ }
+
+ if (File->Type == EfiOpenFileSystem) {
+ Status = gBS->HandleProtocol (File->EfiHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
+ if (!EFI_ERROR (Status)) {
+ Status = Fs->OpenVolume (Fs, &Root);
+ if (!EFI_ERROR (Status)) {
+ // Get information about the volume
+ Size = 0;
+ Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ File->FsInfo = AllocatePool (Size);
+ Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
+ }
+
+ // Get information about the file
+ Status = Root->Open (Root, &File->FsFileHandle, UnicodeFileName, OpenMode, 0);
+ if (!EFI_ERROR (Status)) {
+ Size = 0;
+ Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, NULL);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ File->FsFileInfo = AllocatePool (Size);
+ Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, File->FsFileInfo);
+ if (!EFI_ERROR (Status)) {
+ File->Size = (UINTN)File->FsFileInfo->FileSize;
+ File->MaxPosition = (UINT64)File->Size;
+ }
+ }
+ }
+
+ Root->Close (Root);
+ }
+ }
+ } else if (File->Type == EfiOpenBlockIo) {
+ File->Size = (UINTN)File->MaxPosition;
+ }
+
+ return Status;
+}
+
+#define ToUpper(a) ((((a) >= 'a') && ((a) <= 'z')) ? ((a) - 'a' + 'A') : (a))
+
+EFI_STATUS
+CompareGuidToString (
+ IN EFI_GUID *Guid,
+ IN CHAR8 *String
+ )
+{
+ CHAR8 AsciiGuid[64];
+ CHAR8 *StringPtr;
+ CHAR8 *GuidPtr;
+
+ AsciiSPrint (AsciiGuid, sizeof(AsciiGuid), "%g", Guid);
+
+ StringPtr = String;
+ GuidPtr = AsciiGuid;
+
+ while ((*StringPtr != '\0') && (*GuidPtr != '\0')) {
+ // Skip dashes
+ if (*StringPtr == '-') {
+ StringPtr++;
+ continue;
+ }
+
+ if (*GuidPtr == '-') {
+ GuidPtr++;
+ continue;
+ }
+
+ if (ToUpper(*StringPtr) != ToUpper(*GuidPtr)) {
+ return EFI_NOT_FOUND;
+ }
+
+ StringPtr++;
+ GuidPtr++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+Internal work function to fill in EFI_OPEN_FILE information for the FV
+
+@param File Open file handle
+@param FileName Name of file after device stripped off
+
+
+**/
+EFI_STATUS
+EblFvFileDevicePath (
+ IN OUT EFI_OPEN_FILE *File,
+ IN CHAR8 *FileName,
+ IN CONST UINT64 OpenMode
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS GetNextFileStatus;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN Key;
+ UINT32 AuthenticationStatus;
+ CHAR8 AsciiSection[MAX_PATHNAME];
+ VOID *Section;
+ UINTN SectionSize;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
+ EFI_LBA Lba;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader = NULL;
+ UINTN Index;
+
+
+ Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&File->Fv);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Get FVB Info about the handle
+ Status = gBS->HandleProtocol (File->EfiHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb);
+ if (!EFI_ERROR (Status)) {
+ Status = Fvb->GetPhysicalAddress (Fvb, &File->FvStart);
+ if (!EFI_ERROR (Status)) {
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)File->FvStart;
+ File->FvHeaderSize = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
+ for (Index = 0; FvHeader->BlockMap[Index].Length !=0; Index++) {
+ File->FvHeaderSize += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
+ }
+
+ for (Lba = 0, File->FvSize = 0, NumberOfBlocks = 0; ; File->FvSize += (BlockSize * NumberOfBlocks), Lba += NumberOfBlocks) {
+ Status = Fvb->GetBlockSize (Fvb, Lba, &BlockSize, &NumberOfBlocks);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+ }
+ }
+
+
+ DevicePath = DevicePathFromHandle (File->EfiHandle);
+
+ if (*FileName == '\0') {
+ File->DevicePath = DuplicateDevicePath (DevicePath);
+ File->Size = File->FvSize;
+ File->MaxPosition = File->Size;
+ } else {
+ Key = 0;
+ do {
+ File->FvType = EFI_FV_FILETYPE_ALL;
+ GetNextFileStatus = File->Fv->GetNextFile (
+ File->Fv,
+ &Key,
+ &File->FvType,
+ &File->FvNameGuid,
+ &File->FvAttributes,
+ &File->Size
+ );
+ if (!EFI_ERROR (GetNextFileStatus)) {
+ // Compare GUID first
+ Status = CompareGuidToString (&File->FvNameGuid, FileName);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+
+ Section = NULL;
+ Status = File->Fv->ReadSection (
+ File->Fv,
+ &File->FvNameGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ &Section,
+ &SectionSize,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ UnicodeStrToAsciiStr (Section, AsciiSection);
+ if (AsciiStriCmp (FileName, AsciiSection) == 0) {
+ FreePool (Section);
+ break;
+ }
+ FreePool (Section);
+ }
+ }
+ } while (!EFI_ERROR (GetNextFileStatus));
+
+ if (EFI_ERROR (GetNextFileStatus)) {
+ return GetNextFileStatus;
+ }
+
+ if (OpenMode != EFI_SECTION_ALL) {
+ // Calculate the size of the section we are targeting
+ Section = NULL;
+ File->Size = 0;
+ Status = File->Fv->ReadSection (
+ File->Fv,
+ &File->FvNameGuid,
+ (EFI_SECTION_TYPE)OpenMode,
+ 0,
+ &Section,
+ &File->Size,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ File->MaxPosition = File->Size;
+ EfiInitializeFwVolDevicepathNode (&DevicePathNode, &File->FvNameGuid);
+ File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode);
+ }
+
+
+ // FVB not required if FV was soft loaded...
+ return EFI_SUCCESS;
+}
+
+
+
+
+/**
+Open a device named by PathName. The PathName includes a device name and
+path separated by a :. See file header for more details on the PathName
+syntax. There is no checking to prevent a file from being opened more than
+one type.
+
+SectionType is only used to open an FV. Each file in an FV contains multiple
+sections and only the SectionType section is opened.
+
+For any file that is opened with EfiOpen() must be closed with EfiClose().
+
+@param PathName Path to parse to open
+@param OpenMode Same as EFI_FILE.Open()
+@param SectionType Section in FV to open.
+
+@return NULL Open failed
+@return Valid EFI_OPEN_FILE handle
+
+**/
+EFI_OPEN_FILE *
+EfiOpen (
+ IN CHAR8 *PathName,
+ IN CONST UINT64 OpenMode,
+ IN CONST EFI_SECTION_TYPE SectionType
+ )
+{
+ EFI_STATUS Status;
+ EFI_OPEN_FILE *File;
+ EFI_OPEN_FILE FileData;
+ UINTN StrLen;
+ UINTN FileStart;
+ UINTN DevNumber = 0;
+ EFI_OPEN_FILE_GUARD *GuardFile;
+ BOOLEAN VolumeNameMatch;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN Size;
+ EFI_IP_ADDRESS Ip;
+ CHAR8 *CwdPlusPathName;
+ UINTN Index;
+ EFI_SECTION_TYPE ModifiedSectionType;
+
+ EblUpdateDeviceLists ();
+
+ File = &FileData;
+ ZeroMem (File, sizeof (EFI_OPEN_FILE));
+
+ StrLen = AsciiStrSize (PathName);
+ if (StrLen <= 1) {
+ // Smallest valid path is 1 char and a null
+ return NULL;
+ }
+
+ for (FileStart = 0; FileStart < StrLen; FileStart++) {
+ if (PathName[FileStart] == ':') {
+ FileStart++;
+ break;
+ }
+ }
+
+ //
+ // Matching volume name has precedence over handle based names
+ //
+ VolumeNameMatch = EblMatchVolumeName (PathName, FileStart, &DevNumber);
+ if (!VolumeNameMatch) {
+ if (FileStart == StrLen) {
+ // No Volume name or device name, so try Current Working Directory
+ if (gCwd == NULL) {
+ // No CWD
+ return NULL;
+ }
+
+ // We could add a current working directory concept
+ CwdPlusPathName = AllocatePool (AsciiStrSize (gCwd) + AsciiStrSize (PathName));
+ if (CwdPlusPathName == NULL) {
+ return NULL;
+ }
+
+ if ((PathName[0] == '/') || (PathName[0] == '\\')) {
+ // PathName starts in / so this means we go to the root of the device in the CWD.
+ CwdPlusPathName[0] = '\0';
+ for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
+ CwdPlusPathName[FileStart] = gCwd[FileStart];
+ if (gCwd[FileStart] == ':') {
+ FileStart++;
+ CwdPlusPathName[FileStart] = '\0';
+ break;
+ }
+ }
+ } else {
+ AsciiStrCpy (CwdPlusPathName, gCwd);
+ StrLen = AsciiStrLen (gCwd);
+ if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
+ AsciiStrCat (CwdPlusPathName, "\\");
+ }
+ }
+
+ AsciiStrCat (CwdPlusPathName, PathName);
+ if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
+ // Extra error check to make sure we don't recurse and blow stack
+ return NULL;
+ }
+
+ File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
+ FreePool (CwdPlusPathName);
+ return File;
+ }
+
+ DevNumber = EblConvertDevStringToNumber ((CHAR8 *)PathName);
+ }
+
+ File->DeviceName = AllocatePool (StrLen);
+ AsciiStrCpy (File->DeviceName, PathName);
+ File->DeviceName[FileStart - 1] = '\0';
+ File->FileName = &File->DeviceName[FileStart];
+ if (File->FileName[0] == '\0') {
+ // if it is just a file name use / as root
+ File->FileName = "\\";
+ }
+
+ //
+ // Use best match algorithm on the dev names so we only need to look at the
+ // first few charters to match the full device name. Short name forms are
+ // legal from the caller.
+ //
+ Status = EFI_SUCCESS;
+ if (*PathName == 'f' || *PathName == 'F' || VolumeNameMatch) {
+ if (PathName[1] == 's' || PathName[1] == 'S' || VolumeNameMatch) {
+ if (DevNumber >= mFsCount) {
+ goto ErrorExit;
+ }
+ File->Type = EfiOpenFileSystem;
+ File->EfiHandle = mFs[DevNumber];
+ Status = EblFileDevicePath (File, &PathName[FileStart], OpenMode);
+
+ } else if (PathName[1] == 'v' || PathName[1] == 'V') {
+ if (DevNumber >= mFvCount) {
+ goto ErrorExit;
+ }
+ File->Type = EfiOpenFirmwareVolume;
+ File->EfiHandle = mFv[DevNumber];
+
+ if ((PathName[FileStart] == '/') || (PathName[FileStart] == '\\')) {
+ // Skip leading / as its not really needed for the FV since no directories are supported
+ FileStart++;
+ }
+
+ // Check for 2nd :
+ ModifiedSectionType = SectionType;
+ for (Index = FileStart; PathName[Index] != '\0'; Index++) {
+ if (PathName[Index] == ':') {
+ // Support fv0:\DxeCore:0x10
+ // This means open the PE32 Section of the file
+ ModifiedSectionType = (EFI_SECTION_TYPE)AsciiStrHexToUintn (&PathName[Index + 1]);
+ PathName[Index] = '\0';
+ }
+ }
+ File->FvSectionType = ModifiedSectionType;
+ Status = EblFvFileDevicePath (File, &PathName[FileStart], ModifiedSectionType);
+ }
+ } else if ((*PathName == 'A') || (*PathName == 'a')) {
+ // Handle a:0x10000000:0x1234 address form a:ADDRESS:SIZE
+ File->Type = EfiOpenMemoryBuffer;
+ // 1st colon is at PathName[FileStart - 1]
+ File->Buffer = (VOID *)AsciiStrHexToUintn (&PathName[FileStart]);
+
+ // Find 2nd colon
+ while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
+ FileStart++;
+ }
+
+ // If we ran out of string, there's no extra data
+ if (PathName[FileStart] == '\0') {
+ File->Size = 0;
+ } else {
+ File->Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
+ }
+
+ // if there's no number after the second colon, default
+ // the end of memory
+ if (File->Size == 0) {
+ File->Size = (UINTN)(0 - (UINTN)File->Buffer);
+ }
+
+ File->MaxPosition = File->Size;
+ File->BaseOffset = (UINTN)File->Buffer;
+
+ } else if (*PathName== 'l' || *PathName == 'L') {
+ if (DevNumber >= mLoadFileCount) {
+ goto ErrorExit;
+ }
+ File->Type = EfiOpenLoadFile;
+ File->EfiHandle = mLoadFile[DevNumber];
+
+ Status = gBS->HandleProtocol (File->EfiHandle, &gEfiLoadFileProtocolGuid, (VOID **)&File->LoadFile);
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+ File->DevicePath = DuplicateDevicePath (DevicePath);
+
+ } else if (*PathName == 'b' || *PathName == 'B') {
+ // Handle b#:0x10000000:0x1234 address form b#:ADDRESS:SIZE
+ if (DevNumber >= mBlkIoCount) {
+ goto ErrorExit;
+ }
+ File->Type = EfiOpenBlockIo;
+ File->EfiHandle = mBlkIo[DevNumber];
+ EblFileDevicePath (File, "", OpenMode);
+
+ // 1st colon is at PathName[FileStart - 1]
+ File->DiskOffset = AsciiStrHexToUintn (&PathName[FileStart]);
+
+ // Find 2nd colon
+ while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
+ FileStart++;
+ }
+
+ // If we ran out of string, there's no extra data
+ if (PathName[FileStart] == '\0') {
+ Size = 0;
+ } else {
+ Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
+ }
+
+ // if a zero size is passed in (or the size is left out entirely),
+ // go to the end of the device.
+ if (Size == 0) {
+ File->Size = File->Size - File->DiskOffset;
+ } else {
+ File->Size = Size;
+ }
+
+ File->MaxPosition = File->Size;
+ File->BaseOffset = File->DiskOffset;
+ } else if ((*PathName) >= '0' && (*PathName <= '9')) {
+
+ // Get current IP address
+ Status = EblGetCurrentIpAddress (&Ip);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("Device IP Address is not configured.\n");
+ goto ErrorExit;
+ }
+
+
+ // Parse X.X.X.X:Filename, only support IPv4 TFTP for now...
+ File->Type = EfiOpenTftp;
+ File->IsDirty = FALSE;
+ File->IsBufferValid = FALSE;
+
+ Status = ConvertIpStringToEfiIp (PathName, &File->ServerIp);
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ GuardFile = (EFI_OPEN_FILE_GUARD *)AllocateZeroPool (sizeof (EFI_OPEN_FILE_GUARD));
+ if (GuardFile == NULL) {
+ goto ErrorExit;
+ }
+
+ GuardFile->Header = EFI_OPEN_FILE_GUARD_HEADER;
+ CopyMem (&(GuardFile->File), &FileData, sizeof (EFI_OPEN_FILE));
+ GuardFile->Footer = EFI_OPEN_FILE_GUARD_FOOTER;
+
+ return &(GuardFile->File);
+
+ErrorExit:
+ FreePool (File->DeviceName);
+ return NULL;
+}
+
+#define FILE_COPY_CHUNK 0x01000000
+
+EFI_STATUS
+EfiCopyFile (
+ IN CHAR8 *DestinationFile,
+ IN CHAR8 *SourceFile
+ )
+{
+ EFI_OPEN_FILE *Source = NULL;
+ EFI_OPEN_FILE *Destination = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ VOID *Buffer = NULL;
+ UINTN Size;
+ UINTN Offset;
+ UINTN Chunk = FILE_COPY_CHUNK;
+
+ Source = EfiOpen (SourceFile, EFI_FILE_MODE_READ, 0);
+ if (Source == NULL) {
+ AsciiPrint("Source file open error.\n");
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+
+ Destination = EfiOpen (DestinationFile, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
+ if (Destination == NULL) {
+ AsciiPrint("Destination file open error.\n");
+ Status = EFI_NOT_FOUND;
+ goto Exit;
+ }
+
+ Buffer = AllocatePool(FILE_COPY_CHUNK);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ Size = EfiTell(Source, NULL);
+
+ for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size; Offset += Chunk) {
+ Chunk = FILE_COPY_CHUNK;
+
+ Status = EfiRead(Source, Buffer, &Chunk);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("Read file error %r\n", Status);
+ goto Exit;
+ }
+
+ Status = EfiWrite(Destination, Buffer, &Chunk);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("Write file error %r\n", Status);
+ goto Exit;
+ }
+ }
+
+ // Any left over?
+ if (Offset < Size) {
+ Chunk = Size - Offset;
+
+ Status = EfiRead(Source, Buffer, &Chunk);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("Read file error\n");
+ goto Exit;
+ }
+
+ Status = EfiWrite(Destination, Buffer, &Chunk);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("Write file error\n");
+ goto Exit;
+ }
+ }
+
+Exit:
+ if (Source != NULL) {
+ Status = EfiClose(Source);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("Source close error");
+ }
+ }
+
+ if (Destination != NULL) {
+ Status = EfiClose(Destination);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("Destination close error");
+ }
+ }
+
+ if (Buffer != NULL) {
+ FreePool(Buffer);
+ }
+
+ return Status;
+}
+
+/**
+Use DeviceType and Index to form a valid PathName and try and open it.
+
+@param DeviceType Device type to open
+@param Index Device Index to use. Zero relative.
+
+@return NULL Open failed
+@return Valid EFI_OPEN_FILE handle
+
+**/
+EFI_OPEN_FILE *
+EfiDeviceOpenByType (
+ IN EFI_OPEN_FILE_TYPE DeviceType,
+ IN UINTN Index
+ )
+{
+ CHAR8 *DevStr;
+ CHAR8 Path[MAX_CMD_LINE];
+
+ switch (DeviceType) {
+ case EfiOpenLoadFile:
+ DevStr = "loadfile%d:";
+ break;
+ case EfiOpenFirmwareVolume:
+ DevStr = "fv%d:";
+ break;
+ case EfiOpenFileSystem:
+ DevStr = "fs%d:";
+ break;
+ case EfiOpenBlockIo:
+ DevStr = "blk%d:";
+ break;
+ case EfiOpenMemoryBuffer:
+ DevStr = "a%d:";
+ break;
+ default:
+ return NULL;
+ }
+
+ AsciiSPrint (Path, MAX_PATHNAME, DevStr, Index);
+
+ return EfiOpen (Path, EFI_FILE_MODE_READ, 0);
+}
+
+
+/**
+Close a file handle opened by EfiOpen() and free all resources allocated by
+EfiOpen().
+
+@param Stream Open File Handle
+
+@return EFI_INVALID_PARAMETER Stream is not an Open File
+@return EFI_SUCCESS Steam closed
+
+**/
+EFI_STATUS
+EfiClose (
+ IN EFI_OPEN_FILE *File
+ )
+{
+ EFI_STATUS Status;
+ UINT64 TftpBufferSize;
+
+ if (!FileHandleValid (File)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Write the buffer contents to TFTP file.
+ if ((File->Type == EfiOpenTftp) && (File->IsDirty)) {
+
+ TftpBufferSize = File->Size;
+ Status = EblMtftp (
+ EFI_PXE_BASE_CODE_TFTP_WRITE_FILE,
+ File->Buffer,
+ TRUE,
+ &TftpBufferSize,
+ NULL,
+ &File->ServerIp,
+ (UINT8 *)File->FileName,
+ NULL,
+ FALSE
+ );
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("TFTP error during APPLE_NSP_TFTP_WRITE_FILE: %r\n", Status);
+ return Status;
+ }
+ }
+
+ if ((File->Type == EfiOpenLoadFile) ||
+ ((File->Type == EfiOpenTftp) && (File->IsBufferValid == TRUE)) ||
+ ((File->Type == EfiOpenFirmwareVolume) && (File->IsBufferValid == TRUE))) {
+ EblFreePool(File->Buffer);
+ }
+
+ EblFreePool (File->DevicePath);
+ EblFreePool (File->DeviceName);
+ EblFreePool (File->FsFileInfo);
+ EblFreePool (File->FsInfo);
+
+ if (File->FsFileHandle != NULL) {
+ File->FsFileHandle->Close (File->FsFileHandle);
+ }
+
+ // Need to free File and it's Guard structures
+ EblFreePool (BASE_CR (File, EFI_OPEN_FILE_GUARD, File));
+ return EFI_SUCCESS;
+}
+
+
+/**
+Return the size of the file represented by Stream. Also return the current
+Seek position. Opening a file will enable a valid file size to be returned.
+LoadFile is an exception as a load file size is set to zero.
+
+@param Stream Open File Handle
+
+@return 0 Stream is not an Open File or a valid LoadFile handle
+
+**/
+UINTN
+EfiTell (
+ IN EFI_OPEN_FILE *File,
+ OUT EFI_LBA *CurrentPosition OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT64 BufferSize = 0;
+
+ if (!FileHandleValid (File)) {
+ return 0;
+ }
+
+ if (CurrentPosition != NULL) {
+ *CurrentPosition = File->CurrentPosition;
+ }
+
+ if (File->Type == EfiOpenLoadFile) {
+ // Figure out the File->Size
+ File->Buffer = NULL;
+ File->Size = 0;
+ Status = File->LoadFile->LoadFile (File->LoadFile, File->DevicePath, FALSE, &File->Size, File->Buffer);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return 0;
+ }
+
+ File->MaxPosition = (UINT64)File->Size;
+ } else if (File->Type == EfiOpenTftp) {
+
+ Status = EblMtftp (
+ EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,
+ NULL,
+ FALSE,
+ &BufferSize,
+ NULL,
+ &File->ServerIp,
+ (UINT8 *)File->FileName,
+ NULL,
+ TRUE
+ );
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("TFTP error during APPLE_NSP_TFTP_GET_FILE_SIZE: %r\n", Status);
+ return 0;
+ }
+
+ File->Size = (UINTN)BufferSize;
+ File->MaxPosition = File->Size;
+ }
+
+ return File->Size;
+}
+
+
+/**
+Seek to the Offset location in the file. LoadFile and FV device types do
+not support EfiSeek(). It is not possible to grow the file size using
+EfiSeek().
+
+SeekType defines how use Offset to calculate the new file position:
+EfiSeekStart : Position = Offset
+EfiSeekCurrent: Position is Offset bytes from the current position
+EfiSeekEnd : Only supported if Offset is zero to seek to end of file.
+
+@param Stream Open File Handle
+@param Offset Offset to seek too.
+@param SeekType Type of seek to perform
+
+
+@return EFI_INVALID_PARAMETER Stream is not an Open File
+@return EFI_UNSUPPORTED LoadFile and FV do not support Seek
+@return EFI_NOT_FOUND Seek past the end of the file.
+@return EFI_SUCCESS Steam closed
+
+**/
+EFI_STATUS
+EfiSeek (
+ IN EFI_OPEN_FILE *File,
+ IN EFI_LBA Offset,
+ IN EFI_SEEK_TYPE SeekType
+ )
+{
+ EFI_STATUS Status;
+ UINT64 CurrentPosition;
+
+ if (!FileHandleValid (File)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (File->Type == EfiOpenLoadFile) {
+ // LoadFile does not support Seek
+ return EFI_UNSUPPORTED;
+ }
+
+ CurrentPosition = File->CurrentPosition;
+ switch (SeekType) {
+ case EfiSeekStart:
+ if (Offset > File->MaxPosition) {
+ return EFI_NOT_FOUND;
+ }
+ CurrentPosition = Offset;
+ break;
+
+ case EfiSeekCurrent:
+ if ((File->CurrentPosition + Offset) > File->MaxPosition) {
+ return EFI_NOT_FOUND;
+ }
+ CurrentPosition += Offset;
+ break;
+
+ case EfiSeekEnd:
+ if (Offset != 0) {
+ // We don't support growing file size via seeking past end of file
+ return EFI_UNSUPPORTED;
+ }
+ CurrentPosition = File->MaxPosition;
+ break;
+
+ default:
+ return EFI_NOT_FOUND;
+ }
+
+ Status = EFI_SUCCESS;
+ if (File->FsFileHandle != NULL) {
+ Status = File->FsFileHandle->SetPosition (File->FsFileHandle, CurrentPosition);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ File->CurrentPosition = CurrentPosition;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+CacheTftpFile (
+ IN OUT EFI_OPEN_FILE *File
+ )
+{
+ EFI_STATUS Status;
+ UINT64 TftpBufferSize;
+
+ if (File->IsBufferValid) {
+ return EFI_SUCCESS;
+ }
+
+ // Make sure the file size is set.
+ EfiTell (File, NULL);
+
+ //Allocate a buffer to hold the whole file.
+ File->Buffer = AllocatePool(File->Size);
+ if (File->Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TftpBufferSize = File->Size;
+
+ Status = EblMtftp (
+ EFI_PXE_BASE_CODE_TFTP_READ_FILE,
+ File->Buffer,
+ FALSE,
+ &TftpBufferSize,
+ NULL,
+ &File->ServerIp,
+ (UINT8 *)File->FileName,
+ NULL,
+ FALSE);
+ if (EFI_ERROR(Status)) {
+ AsciiPrint("TFTP error during APPLE_NSP_TFTP_READ_FILE: %r\n", Status);
+ FreePool(File->Buffer);
+ return Status;
+ }
+
+ // Set the buffer valid flag.
+ File->IsBufferValid = TRUE;
+
+ return Status;
+}
+
+/**
+Read BufferSize bytes from the current location in the file. For load file,
+FV, and TFTP case you must read the entire file.
+
+@param Stream Open File Handle
+@param Buffer Caller allocated buffer.
+@param BufferSize Size of buffer in bytes.
+
+
+@return EFI_SUCCESS Stream is not an Open File
+@return EFI_END_OF_FILE Tried to read past the end of the file
+@return EFI_INVALID_PARAMETER Stream is not an open file handle
+@return EFI_BUFFER_TOO_SMALL Buffer is not big enough to do the read
+@return "other" Error returned from device read
+
+**/
+EFI_STATUS
+EfiRead (
+ IN EFI_OPEN_FILE *File,
+ OUT VOID *Buffer,
+ OUT UINTN *BufferSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 AuthenticationStatus;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+
+ if (!FileHandleValid (File)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Don't read past the end of the file.
+ if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
+ return EFI_END_OF_FILE;
+ }
+
+ switch (File->Type) {
+ case EfiOpenLoadFile:
+ // Figure out the File->Size
+ EfiTell (File, NULL);
+
+ Status = File->LoadFile->LoadFile (File->LoadFile, File->DevicePath, FALSE, BufferSize, Buffer);
+ break;
+
+ case EfiOpenFirmwareVolume:
+ if (CompareGuid (&File->FvNameGuid, &gZeroGuid)) {
+ // This is the entire FV device, so treat like a memory buffer
+ CopyMem (Buffer, (VOID *)(UINTN)(File->FvStart + File->CurrentPosition), *BufferSize);
+ File->CurrentPosition += *BufferSize;
+ Status = EFI_SUCCESS;
+ } else {
+ if (File->Buffer == NULL) {
+ if (File->FvSectionType == EFI_SECTION_ALL) {
+ Status = File->Fv->ReadFile (
+ File->Fv,
+ &File->FvNameGuid,
+ (VOID **)&File->Buffer,
+ &File->Size,
+ &File->FvType,
+ &File->FvAttributes,
+ &AuthenticationStatus
+ );
+ } else {
+ Status = File->Fv->ReadSection (
+ File->Fv,
+ &File->FvNameGuid,
+ File->FvSectionType,
+ 0,
+ (VOID **)&File->Buffer,
+ &File->Size,
+ &AuthenticationStatus
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ File->IsBufferValid = TRUE;
+ }
+ // Operate on the cached buffer so Seek will work
+ CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
+ File->CurrentPosition += *BufferSize;
+ Status = EFI_SUCCESS;
+ }
+ break;
+
+ case EfiOpenMemoryBuffer:
+ CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
+ File->CurrentPosition += *BufferSize;
+ Status = EFI_SUCCESS;
+ break;
+
+ case EfiOpenFileSystem:
+ Status = File->FsFileHandle->Read (File->FsFileHandle, BufferSize, Buffer);
+ File->CurrentPosition += *BufferSize;
+ break;
+
+ case EfiOpenBlockIo:
+ Status = gBS->HandleProtocol(File->EfiHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
+ if (!EFI_ERROR(Status)) {
+ Status = DiskIo->ReadDisk(DiskIo, File->FsBlockIoMedia->MediaId, File->DiskOffset + File->CurrentPosition, *BufferSize, Buffer);
+ }
+ File->CurrentPosition += *BufferSize;
+ break;
+
+ case EfiOpenTftp:
+ // Cache the file if it hasn't been cached yet.
+ if (File->IsBufferValid == FALSE) {
+ Status = CacheTftpFile (File);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ // Copy out the requested data
+ CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize);
+ File->CurrentPosition += *BufferSize;
+
+ Status = EFI_SUCCESS;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ };
+
+ return Status;
+}
+
+
+/**
+Read the entire file into a buffer. This routine allocates the buffer and
+returns it to the user full of the read data.
+
+This is very useful for load file where it's hard to know how big the buffer
+must be.
+
+@param Stream Open File Handle
+@param Buffer Pointer to buffer to return.
+@param BufferSize Pointer to Size of buffer return..
+
+
+@return EFI_SUCCESS Stream is not an Open File
+@return EFI_END_OF_FILE Tried to read past the end of the file
+@return EFI_INVALID_PARAMETER Stream is not an open file handle
+@return EFI_BUFFER_TOO_SMALL Buffer is not big enough to do the read
+@return "other" Error returned from device read
+
+**/
+EFI_STATUS
+EfiReadAllocatePool (
+ IN EFI_OPEN_FILE *File,
+ OUT VOID **Buffer,
+ OUT UINTN *BufferSize
+ )
+{
+ if (!FileHandleValid (File)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Loadfile defers file size determination on Open so use tell to find it
+ EfiTell (File, NULL);
+
+ *BufferSize = File->Size;
+ *Buffer = AllocatePool (*BufferSize);
+ if (*Buffer == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EfiRead (File, *Buffer, BufferSize);
+}
+
+
+/**
+Write data back to the file. For TFTP case you must write the entire file.
+
+@param Stream Open File Handle
+@param Buffer Pointer to buffer to return.
+@param BufferSize Pointer to Size of buffer return..
+
+
+@return EFI_SUCCESS Stream is not an Open File
+@return EFI_END_OF_FILE Tried to read past the end of the file
+@return EFI_INVALID_PARAMETER Stream is not an open file handle
+@return EFI_BUFFER_TOO_SMALL Buffer is not big enough to do the read
+@return "other" Error returned from device write
+
+**/
+EFI_STATUS
+EfiWrite (
+ IN EFI_OPEN_FILE *File,
+ OUT VOID *Buffer,
+ OUT UINTN *BufferSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_FV_WRITE_FILE_DATA FileData;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+
+ if (!FileHandleValid (File)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (File->Type) {
+ case EfiOpenMemoryBuffer:
+ if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
+ return EFI_END_OF_FILE;
+ }
+
+ CopyMem (File->Buffer + File->CurrentPosition, Buffer, *BufferSize);
+ File->CurrentPosition += *BufferSize;
+ Status = EFI_SUCCESS;
+
+ case EfiOpenLoadFile:
+ // LoadFile device is read only be definition
+ Status = EFI_UNSUPPORTED;
+
+ case EfiOpenFirmwareVolume:
+ if (File->FvSectionType != EFI_SECTION_ALL) {
+ // Writes not support to a specific section. You have to update entire file
+ return EFI_UNSUPPORTED;
+ }
+
+ FileData.NameGuid = &(File->FvNameGuid);
+ FileData.Type = File->FvType;
+ FileData.FileAttributes = File->FvAttributes;
+ FileData.Buffer = Buffer;
+ FileData.BufferSize = (UINT32)*BufferSize;
+ Status = File->Fv->WriteFile (File->Fv, 1, EFI_FV_UNRELIABLE_WRITE, &FileData);
+ break;
+
+ case EfiOpenFileSystem:
+ Status = File->FsFileHandle->Write (File->FsFileHandle, BufferSize, Buffer);
+ File->CurrentPosition += *BufferSize;
+ break;
+
+ case EfiOpenBlockIo:
+ if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
+ return EFI_END_OF_FILE;
+ }
+
+ Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
+ if (!EFI_ERROR(Status)) {
+ Status = DiskIo->WriteDisk (DiskIo, File->FsBlockIoMedia->MediaId, File->DiskOffset + File->CurrentPosition, *BufferSize, Buffer);
+ }
+ File->CurrentPosition += *BufferSize;
+ break;
+
+ case EfiOpenTftp:
+ // Cache the file if it hasn't been cached yet.
+ if (File->IsBufferValid == FALSE) {
+ Status = CacheTftpFile(File);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ // Don't overwrite the buffer
+ if ((File->CurrentPosition + *BufferSize) > File->MaxPosition) {
+ UINT8 *TempBuffer;
+
+ TempBuffer = File->Buffer;
+
+ File->Buffer = AllocatePool ((UINTN)(File->CurrentPosition + *BufferSize));
+ if (File->Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (File->Buffer, TempBuffer, File->Size);
+
+ FreePool (TempBuffer);
+
+ File->Size = (UINTN)(File->CurrentPosition + *BufferSize);
+ File->MaxPosition = (UINT64)File->Size;
+ }
+
+ // Copy in the requested data
+ CopyMem (File->Buffer + File->CurrentPosition, Buffer, *BufferSize);
+ File->CurrentPosition += *BufferSize;
+
+ // Mark the file dirty
+ File->IsDirty = TRUE;
+
+ Status = EFI_SUCCESS;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ };
+
+ return Status;
+}
+
+
+/**
+Given Cwd expand Path to remove .. and replace them with real
+directory names.
+
+@param Cwd Current Working Directory
+@param Path Path to expand
+
+@return NULL Cwd or Path are not valid
+@return 'other' Path with .. expanded
+
+**/
+CHAR8 *
+ExpandPath (
+ IN CHAR8 *Cwd,
+ IN CHAR8 *Path
+ )
+{
+ CHAR8 *NewPath;
+ CHAR8 *Work, *Start, *End;
+ UINTN StrLen;
+ INTN i;
+
+ if (Cwd == NULL || Path == NULL) {
+ return NULL;
+ }
+
+ StrLen = AsciiStrSize (Cwd);
+ if (StrLen <= 2) {
+ // Smallest valid path is 1 char and a null
+ return NULL;
+ }
+
+ StrLen = AsciiStrSize (Path);
+ NewPath = AllocatePool (AsciiStrSize (Cwd) + StrLen + 1);
+ if (NewPath == NULL) {
+ return NULL;
+ }
+ AsciiStrCpy (NewPath, Cwd);
+
+ End = Path + StrLen;
+ for (Start = Path ;;) {
+ Work = AsciiStrStr (Start, "..") ;
+ if (Work == NULL) {
+ // Remaining part of Path contains no more ..
+ break;
+ }
+
+ // append path prior to ..
+ AsciiStrnCat (NewPath, Start, Work - Start);
+ StrLen = AsciiStrLen (NewPath);
+ for (i = StrLen; i >= 0; i--) {
+ if (NewPath[i] == ':') {
+ // too many ..
+ return NULL;
+ }
+ if (NewPath[i] == '/' || NewPath[i] == '\\') {
+ if ((i > 0) && (NewPath[i-1] == ':')) {
+ // leave the / before a :
+ NewPath[i+1] = '\0';
+ } else {
+ // replace / will Null to remove trailing file/dir reference
+ NewPath[i] = '\0';
+ }
+ break;
+ }
+ }
+
+ Start = Work + 3;
+ }
+
+ // Handle the path that remains after the ..
+ AsciiStrnCat (NewPath, Start, End - Start);
+
+ return NewPath;
+}
+
+
+/**
+Set the Current Working Directory (CWD). If a call is made to EfiOpen () and
+the path does not contain a device name, The CWD is prepended to the path.
+
+@param Cwd Current Working Directory to set
+
+
+@return EFI_SUCCESS CWD is set
+@return EFI_INVALID_PARAMETER Cwd is not a valid device:path
+
+**/
+EFI_STATUS
+EfiSetCwd (
+ IN CHAR8 *Cwd
+ )
+{
+ EFI_OPEN_FILE *File;
+ UINTN Len;
+ CHAR8 *Path;
+
+ if (Cwd == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (AsciiStrCmp (Cwd, ".") == 0) {
+ // cd . is a no-op
+ return EFI_SUCCESS;
+ }
+
+ Path = Cwd;
+ if (AsciiStrStr (Cwd, "..") != NULL) {
+ if (gCwd == NULL) {
+ // no parent
+ return EFI_SUCCESS;
+ }
+
+ Len = AsciiStrLen (gCwd);
+ if ((gCwd[Len-2] == ':') && ((gCwd[Len-1] == '/') || (gCwd[Len-1] == '\\'))) {
+ // parent is device so nothing to do
+ return EFI_SUCCESS;
+ }
+
+ // Expand .. in Cwd, given we know current working directory
+ Path = ExpandPath (gCwd, Cwd);
+ if (Path == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
+ if (File == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (gCwd != NULL) {
+ FreePool (gCwd);
+ }
+
+ // Use the info returned from EfiOpen as it can add in CWD if needed. So Cwd could be
+ // relative to the current gCwd or not.
+ gCwd = AllocatePool (AsciiStrSize (File->DeviceName) + AsciiStrSize (File->FileName) + 10);
+ if (gCwd == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AsciiStrCpy (gCwd, File->DeviceName);
+ if (File->FileName == NULL) {
+ AsciiStrCat (gCwd, ":\\");
+ } else {
+ AsciiStrCat (gCwd, ":");
+ AsciiStrCat (gCwd, File->FileName);
+ }
+
+
+ EfiClose (File);
+ if (Path != Cwd) {
+ FreePool (Path);
+ }
+ return EFI_SUCCESS;
+}
+
+
+/**
+Set the Current Working Directory (CWD). If a call is made to EfiOpen () and
+the path does not contain a device name, The CWD is prepended to the path.
+The CWD buffer is only valid until a new call is made to EfiSetCwd(). After
+a call to EfiSetCwd() it is not legal to use the pointer returned by
+this function.
+
+@param Cwd Current Working Directory
+
+
+@return "" No CWD set
+@return 'other' Returns buffer that contains CWD.
+
+**/
+CHAR8 *
+EfiGetCwd (
+ VOID
+ )
+{
+ if (gCwd == NULL) {
+ return "";
+ }
+ return gCwd;
+}
+
+
diff --git a/EmbeddedPkg/Library/FdtLib/fdt.c b/EmbeddedPkg/Library/FdtLib/fdt.c
index e56833ae9b..151fcb2ab0 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt.c
@@ -1,222 +1,222 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_check_header(const void *fdt)
-{
- if (fdt_magic(fdt) == FDT_MAGIC) {
- /* Complete tree */
- if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
- return -FDT_ERR_BADVERSION;
- } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
- /* Unfinished sequential-write blob */
- if (fdt_size_dt_struct(fdt) == 0)
- return -FDT_ERR_BADSTATE;
- } else {
- return -FDT_ERR_BADMAGIC;
- }
-
- return 0;
-}
-
-const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
-{
- const char *p;
-
- if (fdt_version(fdt) >= 0x11)
- if (((offset + len) < offset)
- || ((offset + len) > fdt_size_dt_struct(fdt)))
- return NULL;
-
- p = _fdt_offset_ptr(fdt, offset);
-
- if (p + len < p)
- return NULL;
- return p;
-}
-
-uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
-{
- const uint32_t *tagp, *lenp;
- uint32_t tag;
- int offset = startoffset;
- const char *p;
-
- *nextoffset = -FDT_ERR_TRUNCATED;
- tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
- if (!tagp)
- return FDT_END; /* premature end */
- tag = fdt32_to_cpu(*tagp);
- offset += FDT_TAGSIZE;
-
- *nextoffset = -FDT_ERR_BADSTRUCTURE;
- switch (tag) {
- case FDT_BEGIN_NODE:
- /* skip name */
- do {
- p = fdt_offset_ptr(fdt, offset++, 1);
- } while (p && (*p != '\0'));
- if (!p)
- return FDT_END; /* premature end */
- break;
-
- case FDT_PROP:
- lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
- if (!lenp)
- return FDT_END; /* premature end */
- /* skip-name offset, length and value */
- offset += sizeof(struct fdt_property) - FDT_TAGSIZE
- + fdt32_to_cpu(*lenp);
- break;
-
- case FDT_END:
- case FDT_END_NODE:
- case FDT_NOP:
- break;
-
- default:
- return FDT_END;
- }
-
- if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
- return FDT_END; /* premature end */
-
- *nextoffset = FDT_TAGALIGN(offset);
- return tag;
-}
-
-int _fdt_check_node_offset(const void *fdt, int offset)
-{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
- return -FDT_ERR_BADOFFSET;
-
- return offset;
-}
-
-int _fdt_check_prop_offset(const void *fdt, int offset)
-{
- if ((offset < 0) || (offset % FDT_TAGSIZE)
- || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
- return -FDT_ERR_BADOFFSET;
-
- return offset;
-}
-
-int fdt_next_node(const void *fdt, int offset, int *depth)
-{
- int nextoffset = 0;
- uint32_t tag;
-
- if (offset >= 0)
- if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
- return nextoffset;
-
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_PROP:
- case FDT_NOP:
- break;
-
- case FDT_BEGIN_NODE:
- if (depth)
- (*depth)++;
- break;
-
- case FDT_END_NODE:
- if (depth && ((--(*depth)) < 0))
- return nextoffset;
- break;
-
- case FDT_END:
- if ((nextoffset >= 0)
- || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
- return -FDT_ERR_NOTFOUND;
- else
- return nextoffset;
- }
- } while (tag != FDT_BEGIN_NODE);
-
- return offset;
-}
-
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
-{
- int len = strlen(s) + 1;
- const char *last = strtab + tabsize - len;
- const char *p;
-
- for (p = strtab; p <= last; p++)
- if (memcmp(p, s, len) == 0)
- return p;
- return NULL;
-}
-
-int fdt_move(const void *fdt, void *buf, int bufsize)
-{
- FDT_CHECK_HEADER(fdt);
-
- if (fdt_totalsize(fdt) > bufsize)
- return -FDT_ERR_NOSPACE;
-
- memmove(buf, fdt, fdt_totalsize(fdt));
- return 0;
-}
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_check_header(const void *fdt)
+{
+ if (fdt_magic(fdt) == FDT_MAGIC) {
+ /* Complete tree */
+ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
+ /* Unfinished sequential-write blob */
+ if (fdt_size_dt_struct(fdt) == 0)
+ return -FDT_ERR_BADSTATE;
+ } else {
+ return -FDT_ERR_BADMAGIC;
+ }
+
+ return 0;
+}
+
+const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
+{
+ const char *p;
+
+ if (fdt_version(fdt) >= 0x11)
+ if (((offset + len) < offset)
+ || ((offset + len) > fdt_size_dt_struct(fdt)))
+ return NULL;
+
+ p = _fdt_offset_ptr(fdt, offset);
+
+ if (p + len < p)
+ return NULL;
+ return p;
+}
+
+uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
+{
+ const uint32_t *tagp, *lenp;
+ uint32_t tag;
+ int offset = startoffset;
+ const char *p;
+
+ *nextoffset = -FDT_ERR_TRUNCATED;
+ tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
+ if (!tagp)
+ return FDT_END; /* premature end */
+ tag = fdt32_to_cpu(*tagp);
+ offset += FDT_TAGSIZE;
+
+ *nextoffset = -FDT_ERR_BADSTRUCTURE;
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ /* skip name */
+ do {
+ p = fdt_offset_ptr(fdt, offset++, 1);
+ } while (p && (*p != '\0'));
+ if (!p)
+ return FDT_END; /* premature end */
+ break;
+
+ case FDT_PROP:
+ lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
+ if (!lenp)
+ return FDT_END; /* premature end */
+ /* skip-name offset, length and value */
+ offset += sizeof(struct fdt_property) - FDT_TAGSIZE
+ + fdt32_to_cpu(*lenp);
+ break;
+
+ case FDT_END:
+ case FDT_END_NODE:
+ case FDT_NOP:
+ break;
+
+ default:
+ return FDT_END;
+ }
+
+ if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
+ return FDT_END; /* premature end */
+
+ *nextoffset = FDT_TAGALIGN(offset);
+ return tag;
+}
+
+int _fdt_check_node_offset(const void *fdt, int offset)
+{
+ if ((offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
+ return -FDT_ERR_BADOFFSET;
+
+ return offset;
+}
+
+int _fdt_check_prop_offset(const void *fdt, int offset)
+{
+ if ((offset < 0) || (offset % FDT_TAGSIZE)
+ || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
+ return -FDT_ERR_BADOFFSET;
+
+ return offset;
+}
+
+int fdt_next_node(const void *fdt, int offset, int *depth)
+{
+ int nextoffset = 0;
+ uint32_t tag;
+
+ if (offset >= 0)
+ if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
+ return nextoffset;
+
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ case FDT_BEGIN_NODE:
+ if (depth)
+ (*depth)++;
+ break;
+
+ case FDT_END_NODE:
+ if (depth && ((--(*depth)) < 0))
+ return nextoffset;
+ break;
+
+ case FDT_END:
+ if ((nextoffset >= 0)
+ || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
+ return -FDT_ERR_NOTFOUND;
+ else
+ return nextoffset;
+ }
+ } while (tag != FDT_BEGIN_NODE);
+
+ return offset;
+}
+
+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
+{
+ int len = strlen(s) + 1;
+ const char *last = strtab + tabsize - len;
+ const char *p;
+
+ for (p = strtab; p <= last; p++)
+ if (memcmp(p, s, len) == 0)
+ return p;
+ return NULL;
+}
+
+int fdt_move(const void *fdt, void *buf, int bufsize)
+{
+ FDT_CHECK_HEADER(fdt);
+
+ if (fdt_totalsize(fdt) > bufsize)
+ return -FDT_ERR_NOSPACE;
+
+ memmove(buf, fdt, fdt_totalsize(fdt));
+ return 0;
+}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c b/EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c
index f72d13b1d1..f00a8991d4 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_empty_tree.c
@@ -1,84 +1,84 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2012 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_create_empty_tree(void *buf, int bufsize)
-{
- int err;
-
- err = fdt_create(buf, bufsize);
- if (err)
- return err;
-
- err = fdt_finish_reservemap(buf);
- if (err)
- return err;
-
- err = fdt_begin_node(buf, "");
- if (err)
- return err;
-
- err = fdt_end_node(buf);
- if (err)
- return err;
-
- err = fdt_finish(buf);
- if (err)
- return err;
-
- return fdt_open_into(buf, buf, bufsize);
-}
-
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2012 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_create_empty_tree(void *buf, int bufsize)
+{
+ int err;
+
+ err = fdt_create(buf, bufsize);
+ if (err)
+ return err;
+
+ err = fdt_finish_reservemap(buf);
+ if (err)
+ return err;
+
+ err = fdt_begin_node(buf, "");
+ if (err)
+ return err;
+
+ err = fdt_end_node(buf);
+ if (err)
+ return err;
+
+ err = fdt_finish(buf);
+ if (err)
+ return err;
+
+ return fdt_open_into(buf, buf, bufsize);
+}
+
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_ro.c b/EmbeddedPkg/Library/FdtLib/fdt_ro.c
index 95fdbeadd4..9ae6b5ecc5 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_ro.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_ro.c
@@ -1,575 +1,575 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_nodename_eq(const void *fdt, int offset,
- const char *s, int len)
-{
- const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
-
- if (! p)
- /* short match */
- return 0;
-
- if (memcmp(p, s, len) != 0)
- return 0;
-
- if (p[len] == '\0')
- return 1;
- else if (!memchr(s, '@', len) && (p[len] == '@'))
- return 1;
- else
- return 0;
-}
-
-const char *fdt_string(const void *fdt, int stroffset)
-{
- return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
-}
-
-static int _fdt_string_eq(const void *fdt, int stroffset,
- const char *s, int len)
-{
- const char *p = fdt_string(fdt, stroffset);
-
- return (strlen(p) == len) && (memcmp(p, s, len) == 0);
-}
-
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
-{
- FDT_CHECK_HEADER(fdt);
- *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
- *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
- return 0;
-}
-
-int fdt_num_mem_rsv(const void *fdt)
-{
- int i = 0;
-
- while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
- i++;
- return i;
-}
-
-static int _nextprop(const void *fdt, int offset)
-{
- uint32_t tag;
- int nextoffset;
-
- do {
- tag = fdt_next_tag(fdt, offset, &nextoffset);
-
- switch (tag) {
- case FDT_END:
- if (nextoffset >= 0)
- return -FDT_ERR_BADSTRUCTURE;
- else
- return nextoffset;
-
- case FDT_PROP:
- return offset;
- }
- offset = nextoffset;
- } while (tag == FDT_NOP);
-
- return -FDT_ERR_NOTFOUND;
-}
-
-int fdt_subnode_offset_namelen(const void *fdt, int offset,
- const char *name, int namelen)
-{
- int depth;
-
- FDT_CHECK_HEADER(fdt);
-
- for (depth = 0;
- (offset >= 0) && (depth >= 0);
- offset = fdt_next_node(fdt, offset, &depth))
- if ((depth == 1)
- && _fdt_nodename_eq(fdt, offset, name, namelen))
- return offset;
-
- if (depth < 0)
- return -FDT_ERR_NOTFOUND;
- return offset; /* error */
-}
-
-int fdt_subnode_offset(const void *fdt, int parentoffset,
- const char *name)
-{
- return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
-}
-
-int fdt_path_offset(const void *fdt, const char *path)
-{
- const char *end = path + strlen(path);
- const char *p = path;
- int offset = 0;
-
- FDT_CHECK_HEADER(fdt);
-
- /* see if we have an alias */
- if (*path != '/') {
- const char *q = strchr(path, '/');
-
- if (!q)
- q = end;
-
- p = fdt_get_alias_namelen(fdt, p, q - p);
- if (!p)
- return -FDT_ERR_BADPATH;
- offset = fdt_path_offset(fdt, p);
-
- p = q;
- }
-
- while (*p) {
- const char *q;
-
- while (*p == '/')
- p++;
- if (! *p)
- return offset;
- q = strchr(p, '/');
- if (! q)
- q = end;
-
- offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
- if (offset < 0)
- return offset;
-
- p = q;
- }
-
- return offset;
-}
-
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
-{
- const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
- int err;
-
- if (((err = fdt_check_header(fdt)) != 0)
- || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
- goto fail;
-
- if (len)
- *len = strlen(nh->name);
-
- return nh->name;
-
- fail:
- if (len)
- *len = err;
- return NULL;
-}
-
-int fdt_first_property_offset(const void *fdt, int nodeoffset)
-{
- int offset;
-
- if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
- return offset;
-
- return _nextprop(fdt, offset);
-}
-
-int fdt_next_property_offset(const void *fdt, int offset)
-{
- if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
- return offset;
-
- return _nextprop(fdt, offset);
-}
-
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
- int offset,
- int *lenp)
-{
- int err;
- const struct fdt_property *prop;
-
- if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
- if (lenp)
- *lenp = err;
- return NULL;
- }
-
- prop = _fdt_offset_ptr(fdt, offset);
-
- if (lenp)
- *lenp = fdt32_to_cpu(prop->len);
-
- return prop;
-}
-
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,
- int offset,
- const char *name,
- int namelen, int *lenp)
-{
- for (offset = fdt_first_property_offset(fdt, offset);
- (offset >= 0);
- (offset = fdt_next_property_offset(fdt, offset))) {
- const struct fdt_property *prop;
-
- prop = fdt_get_property_by_offset(fdt, offset, lenp);
- if (!prop) {
- offset = -FDT_ERR_INTERNAL;
- break;
- }
- if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
- name, namelen))
- return prop;
- }
-
- if (lenp)
- *lenp = offset;
- return NULL;
-}
-
-const struct fdt_property *fdt_get_property(const void *fdt,
- int nodeoffset,
- const char *name, int *lenp)
-{
- return fdt_get_property_namelen(fdt, nodeoffset, name,
- strlen(name), lenp);
-}
-
-const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
- const char *name, int namelen, int *lenp)
-{
- const struct fdt_property *prop;
-
- prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
- if (! prop)
- return NULL;
-
- return prop->data;
-}
-
-const void *fdt_getprop_by_offset(const void *fdt, int offset,
- const char **namep, int *lenp)
-{
- const struct fdt_property *prop;
-
- prop = fdt_get_property_by_offset(fdt, offset, lenp);
- if (!prop)
- return NULL;
- if (namep)
- *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
- return prop->data;
-}
-
-const void *fdt_getprop(const void *fdt, int nodeoffset,
- const char *name, int *lenp)
-{
- return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
-}
-
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
-{
- const uint32_t *php;
- int len;
-
- /* FIXME: This is a bit sub-optimal, since we potentially scan
- * over all the properties twice. */
- php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
- if (!php || (len != sizeof(*php))) {
- php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
- if (!php || (len != sizeof(*php)))
- return 0;
- }
-
- return fdt32_to_cpu(*php);
-}
-
-const char *fdt_get_alias_namelen(const void *fdt,
- const char *name, int namelen)
-{
- int aliasoffset;
-
- aliasoffset = fdt_path_offset(fdt, "/aliases");
- if (aliasoffset < 0)
- return NULL;
-
- return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
-}
-
-const char *fdt_get_alias(const void *fdt, const char *name)
-{
- return fdt_get_alias_namelen(fdt, name, strlen(name));
-}
-
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
-{
- int pdepth = 0, p = 0;
- int offset, depth, namelen;
- const char *name;
-
- FDT_CHECK_HEADER(fdt);
-
- if (buflen < 2)
- return -FDT_ERR_NOSPACE;
-
- for (offset = 0, depth = 0;
- (offset >= 0) && (offset <= nodeoffset);
- offset = fdt_next_node(fdt, offset, &depth)) {
- while (pdepth > depth) {
- do {
- p--;
- } while (buf[p-1] != '/');
- pdepth--;
- }
-
- if (pdepth >= depth) {
- name = fdt_get_name(fdt, offset, &namelen);
- if (!name)
- return namelen;
- if ((p + namelen + 1) <= buflen) {
- memcpy(buf + p, name, namelen);
- p += namelen;
- buf[p++] = '/';
- pdepth++;
- }
- }
-
- if (offset == nodeoffset) {
- if (pdepth < (depth + 1))
- return -FDT_ERR_NOSPACE;
-
- if (p > 1) /* special case so that root path is "/", not "" */
- p--;
- buf[p] = '\0';
- return 0;
- }
- }
-
- if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
- return -FDT_ERR_BADOFFSET;
- else if (offset == -FDT_ERR_BADOFFSET)
- return -FDT_ERR_BADSTRUCTURE;
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
- int supernodedepth, int *nodedepth)
-{
- int offset, depth;
- int supernodeoffset = -FDT_ERR_INTERNAL;
-
- FDT_CHECK_HEADER(fdt);
-
- if (supernodedepth < 0)
- return -FDT_ERR_NOTFOUND;
-
- for (offset = 0, depth = 0;
- (offset >= 0) && (offset <= nodeoffset);
- offset = fdt_next_node(fdt, offset, &depth)) {
- if (depth == supernodedepth)
- supernodeoffset = offset;
-
- if (offset == nodeoffset) {
- if (nodedepth)
- *nodedepth = depth;
-
- if (supernodedepth > depth)
- return -FDT_ERR_NOTFOUND;
- else
- return supernodeoffset;
- }
- }
-
- if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
- return -FDT_ERR_BADOFFSET;
- else if (offset == -FDT_ERR_BADOFFSET)
- return -FDT_ERR_BADSTRUCTURE;
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_node_depth(const void *fdt, int nodeoffset)
-{
- int nodedepth;
- int err;
-
- err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
- if (err)
- return (err < 0) ? err : -FDT_ERR_INTERNAL;
- return nodedepth;
-}
-
-int fdt_parent_offset(const void *fdt, int nodeoffset)
-{
- int nodedepth = fdt_node_depth(fdt, nodeoffset);
-
- if (nodedepth < 0)
- return nodedepth;
- return fdt_supernode_atdepth_offset(fdt, nodeoffset,
- nodedepth - 1, NULL);
-}
-
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
- const char *propname,
- const void *propval, int proplen)
-{
- int offset;
- const void *val;
- int len;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we scan each
- * property of a node in fdt_getprop(), then if that didn't
- * find what we want, we scan over them again making our way
- * to the next node. Still it's the easiest to implement
- * approach; performance can come later. */
- for (offset = fdt_next_node(fdt, startoffset, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- val = fdt_getprop(fdt, offset, propname, &len);
- if (val && (len == proplen)
- && (memcmp(val, propval, len) == 0))
- return offset;
- }
-
- return offset; /* error from fdt_next_node() */
-}
-
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
-{
- int offset;
-
- if ((phandle == 0) || (phandle == (uint32_t)-1))
- return -FDT_ERR_BADPHANDLE;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we
- * potentially scan each property of a node in
- * fdt_get_phandle(), then if that didn't find what
- * we want, we scan over them again making our way to the next
- * node. Still it's the easiest to implement approach;
- * performance can come later. */
- for (offset = fdt_next_node(fdt, -1, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- if (fdt_get_phandle(fdt, offset) == phandle)
- return offset;
- }
-
- return offset; /* error from fdt_next_node() */
-}
-
-static int _fdt_stringlist_contains(const char *strlist, int listlen,
- const char *str)
-{
- int len = strlen(str);
- const char *p;
-
- while (listlen >= len) {
- if (memcmp(str, strlist, len+1) == 0)
- return 1;
- p = memchr(strlist, '\0', listlen);
- if (!p)
- return 0; /* malformed strlist.. */
- listlen -= (p-strlist) + 1;
- strlist = p + 1;
- }
- return 0;
-}
-
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,
- const char *compatible)
-{
- const void *prop;
- int len;
-
- prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
- if (!prop)
- return len;
- if (_fdt_stringlist_contains(prop, len, compatible))
- return 0;
- else
- return 1;
-}
-
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
- const char *compatible)
-{
- int offset, err;
-
- FDT_CHECK_HEADER(fdt);
-
- /* FIXME: The algorithm here is pretty horrible: we scan each
- * property of a node in fdt_node_check_compatible(), then if
- * that didn't find what we want, we scan over them again
- * making our way to the next node. Still it's the easiest to
- * implement approach; performance can come later. */
- for (offset = fdt_next_node(fdt, startoffset, NULL);
- offset >= 0;
- offset = fdt_next_node(fdt, offset, NULL)) {
- err = fdt_node_check_compatible(fdt, offset, compatible);
- if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
- return err;
- else if (err == 0)
- return offset;
- }
-
- return offset; /* error from fdt_next_node() */
-}
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int _fdt_nodename_eq(const void *fdt, int offset,
+ const char *s, int len)
+{
+ const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
+
+ if (! p)
+ /* short match */
+ return 0;
+
+ if (memcmp(p, s, len) != 0)
+ return 0;
+
+ if (p[len] == '\0')
+ return 1;
+ else if (!memchr(s, '@', len) && (p[len] == '@'))
+ return 1;
+ else
+ return 0;
+}
+
+const char *fdt_string(const void *fdt, int stroffset)
+{
+ return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
+}
+
+static int _fdt_string_eq(const void *fdt, int stroffset,
+ const char *s, int len)
+{
+ const char *p = fdt_string(fdt, stroffset);
+
+ return (strlen(p) == len) && (memcmp(p, s, len) == 0);
+}
+
+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
+{
+ FDT_CHECK_HEADER(fdt);
+ *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
+ *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
+ return 0;
+}
+
+int fdt_num_mem_rsv(const void *fdt)
+{
+ int i = 0;
+
+ while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
+ i++;
+ return i;
+}
+
+static int _nextprop(const void *fdt, int offset)
+{
+ uint32_t tag;
+ int nextoffset;
+
+ do {
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ switch (tag) {
+ case FDT_END:
+ if (nextoffset >= 0)
+ return -FDT_ERR_BADSTRUCTURE;
+ else
+ return nextoffset;
+
+ case FDT_PROP:
+ return offset;
+ }
+ offset = nextoffset;
+ } while (tag == FDT_NOP);
+
+ return -FDT_ERR_NOTFOUND;
+}
+
+int fdt_subnode_offset_namelen(const void *fdt, int offset,
+ const char *name, int namelen)
+{
+ int depth;
+
+ FDT_CHECK_HEADER(fdt);
+
+ for (depth = 0;
+ (offset >= 0) && (depth >= 0);
+ offset = fdt_next_node(fdt, offset, &depth))
+ if ((depth == 1)
+ && _fdt_nodename_eq(fdt, offset, name, namelen))
+ return offset;
+
+ if (depth < 0)
+ return -FDT_ERR_NOTFOUND;
+ return offset; /* error */
+}
+
+int fdt_subnode_offset(const void *fdt, int parentoffset,
+ const char *name)
+{
+ return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
+}
+
+int fdt_path_offset(const void *fdt, const char *path)
+{
+ const char *end = path + strlen(path);
+ const char *p = path;
+ int offset = 0;
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* see if we have an alias */
+ if (*path != '/') {
+ const char *q = strchr(path, '/');
+
+ if (!q)
+ q = end;
+
+ p = fdt_get_alias_namelen(fdt, p, q - p);
+ if (!p)
+ return -FDT_ERR_BADPATH;
+ offset = fdt_path_offset(fdt, p);
+
+ p = q;
+ }
+
+ while (*p) {
+ const char *q;
+
+ while (*p == '/')
+ p++;
+ if (! *p)
+ return offset;
+ q = strchr(p, '/');
+ if (! q)
+ q = end;
+
+ offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
+ if (offset < 0)
+ return offset;
+
+ p = q;
+ }
+
+ return offset;
+}
+
+const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
+{
+ const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
+ int err;
+
+ if (((err = fdt_check_header(fdt)) != 0)
+ || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
+ goto fail;
+
+ if (len)
+ *len = strlen(nh->name);
+
+ return nh->name;
+
+ fail:
+ if (len)
+ *len = err;
+ return NULL;
+}
+
+int fdt_first_property_offset(const void *fdt, int nodeoffset)
+{
+ int offset;
+
+ if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+ return offset;
+
+ return _nextprop(fdt, offset);
+}
+
+int fdt_next_property_offset(const void *fdt, int offset)
+{
+ if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)
+ return offset;
+
+ return _nextprop(fdt, offset);
+}
+
+const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+ int offset,
+ int *lenp)
+{
+ int err;
+ const struct fdt_property *prop;
+
+ if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {
+ if (lenp)
+ *lenp = err;
+ return NULL;
+ }
+
+ prop = _fdt_offset_ptr(fdt, offset);
+
+ if (lenp)
+ *lenp = fdt32_to_cpu(prop->len);
+
+ return prop;
+}
+
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+ int offset,
+ const char *name,
+ int namelen, int *lenp)
+{
+ for (offset = fdt_first_property_offset(fdt, offset);
+ (offset >= 0);
+ (offset = fdt_next_property_offset(fdt, offset))) {
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_by_offset(fdt, offset, lenp);
+ if (!prop) {
+ offset = -FDT_ERR_INTERNAL;
+ break;
+ }
+ if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),
+ name, namelen))
+ return prop;
+ }
+
+ if (lenp)
+ *lenp = offset;
+ return NULL;
+}
+
+const struct fdt_property *fdt_get_property(const void *fdt,
+ int nodeoffset,
+ const char *name, int *lenp)
+{
+ return fdt_get_property_namelen(fdt, nodeoffset, name,
+ strlen(name), lenp);
+}
+
+const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+ const char *name, int namelen, int *lenp)
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
+ if (! prop)
+ return NULL;
+
+ return prop->data;
+}
+
+const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ const char **namep, int *lenp)
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property_by_offset(fdt, offset, lenp);
+ if (!prop)
+ return NULL;
+ if (namep)
+ *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ return prop->data;
+}
+
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp)
+{
+ return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
+}
+
+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
+{
+ const uint32_t *php;
+ int len;
+
+ /* FIXME: This is a bit sub-optimal, since we potentially scan
+ * over all the properties twice. */
+ php = fdt_getprop(fdt, nodeoffset, "phandle", &len);
+ if (!php || (len != sizeof(*php))) {
+ php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
+ if (!php || (len != sizeof(*php)))
+ return 0;
+ }
+
+ return fdt32_to_cpu(*php);
+}
+
+const char *fdt_get_alias_namelen(const void *fdt,
+ const char *name, int namelen)
+{
+ int aliasoffset;
+
+ aliasoffset = fdt_path_offset(fdt, "/aliases");
+ if (aliasoffset < 0)
+ return NULL;
+
+ return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
+}
+
+const char *fdt_get_alias(const void *fdt, const char *name)
+{
+ return fdt_get_alias_namelen(fdt, name, strlen(name));
+}
+
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
+{
+ int pdepth = 0, p = 0;
+ int offset, depth, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER(fdt);
+
+ if (buflen < 2)
+ return -FDT_ERR_NOSPACE;
+
+ for (offset = 0, depth = 0;
+ (offset >= 0) && (offset <= nodeoffset);
+ offset = fdt_next_node(fdt, offset, &depth)) {
+ while (pdepth > depth) {
+ do {
+ p--;
+ } while (buf[p-1] != '/');
+ pdepth--;
+ }
+
+ if (pdepth >= depth) {
+ name = fdt_get_name(fdt, offset, &namelen);
+ if (!name)
+ return namelen;
+ if ((p + namelen + 1) <= buflen) {
+ memcpy(buf + p, name, namelen);
+ p += namelen;
+ buf[p++] = '/';
+ pdepth++;
+ }
+ }
+
+ if (offset == nodeoffset) {
+ if (pdepth < (depth + 1))
+ return -FDT_ERR_NOSPACE;
+
+ if (p > 1) /* special case so that root path is "/", not "" */
+ p--;
+ buf[p] = '\0';
+ return 0;
+ }
+ }
+
+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
+ return -FDT_ERR_BADOFFSET;
+ else if (offset == -FDT_ERR_BADOFFSET)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
+ int supernodedepth, int *nodedepth)
+{
+ int offset, depth;
+ int supernodeoffset = -FDT_ERR_INTERNAL;
+
+ FDT_CHECK_HEADER(fdt);
+
+ if (supernodedepth < 0)
+ return -FDT_ERR_NOTFOUND;
+
+ for (offset = 0, depth = 0;
+ (offset >= 0) && (offset <= nodeoffset);
+ offset = fdt_next_node(fdt, offset, &depth)) {
+ if (depth == supernodedepth)
+ supernodeoffset = offset;
+
+ if (offset == nodeoffset) {
+ if (nodedepth)
+ *nodedepth = depth;
+
+ if (supernodedepth > depth)
+ return -FDT_ERR_NOTFOUND;
+ else
+ return supernodeoffset;
+ }
+ }
+
+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
+ return -FDT_ERR_BADOFFSET;
+ else if (offset == -FDT_ERR_BADOFFSET)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int fdt_node_depth(const void *fdt, int nodeoffset)
+{
+ int nodedepth;
+ int err;
+
+ err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
+ if (err)
+ return (err < 0) ? err : -FDT_ERR_INTERNAL;
+ return nodedepth;
+}
+
+int fdt_parent_offset(const void *fdt, int nodeoffset)
+{
+ int nodedepth = fdt_node_depth(fdt, nodeoffset);
+
+ if (nodedepth < 0)
+ return nodedepth;
+ return fdt_supernode_atdepth_offset(fdt, nodeoffset,
+ nodedepth - 1, NULL);
+}
+
+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
+ const char *propname,
+ const void *propval, int proplen)
+{
+ int offset;
+ const void *val;
+ int len;
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_getprop(), then if that didn't
+ * find what we want, we scan over them again making our way
+ * to the next node. Still it's the easiest to implement
+ * approach; performance can come later. */
+ for (offset = fdt_next_node(fdt, startoffset, NULL);
+ offset >= 0;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ val = fdt_getprop(fdt, offset, propname, &len);
+ if (val && (len == proplen)
+ && (memcmp(val, propval, len) == 0))
+ return offset;
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
+
+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
+{
+ int offset;
+
+ if ((phandle == 0) || (phandle == (uint32_t)-1))
+ return -FDT_ERR_BADPHANDLE;
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we
+ * potentially scan each property of a node in
+ * fdt_get_phandle(), then if that didn't find what
+ * we want, we scan over them again making our way to the next
+ * node. Still it's the easiest to implement approach;
+ * performance can come later. */
+ for (offset = fdt_next_node(fdt, -1, NULL);
+ offset >= 0;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ if (fdt_get_phandle(fdt, offset) == phandle)
+ return offset;
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
+
+static int _fdt_stringlist_contains(const char *strlist, int listlen,
+ const char *str)
+{
+ int len = strlen(str);
+ const char *p;
+
+ while (listlen >= len) {
+ if (memcmp(str, strlist, len+1) == 0)
+ return 1;
+ p = memchr(strlist, '\0', listlen);
+ if (!p)
+ return 0; /* malformed strlist.. */
+ listlen -= (p-strlist) + 1;
+ strlist = p + 1;
+ }
+ return 0;
+}
+
+int fdt_node_check_compatible(const void *fdt, int nodeoffset,
+ const char *compatible)
+{
+ const void *prop;
+ int len;
+
+ prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
+ if (!prop)
+ return len;
+ if (_fdt_stringlist_contains(prop, len, compatible))
+ return 0;
+ else
+ return 1;
+}
+
+int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
+ const char *compatible)
+{
+ int offset, err;
+
+ FDT_CHECK_HEADER(fdt);
+
+ /* FIXME: The algorithm here is pretty horrible: we scan each
+ * property of a node in fdt_node_check_compatible(), then if
+ * that didn't find what we want, we scan over them again
+ * making our way to the next node. Still it's the easiest to
+ * implement approach; performance can come later. */
+ for (offset = fdt_next_node(fdt, startoffset, NULL);
+ offset >= 0;
+ offset = fdt_next_node(fdt, offset, NULL)) {
+ err = fdt_node_check_compatible(fdt, offset, compatible);
+ if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
+ return err;
+ else if (err == 0)
+ return offset;
+ }
+
+ return offset; /* error from fdt_next_node() */
+}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_rw.c b/EmbeddedPkg/Library/FdtLib/fdt_rw.c
index 878a775a7b..1d95a73ec1 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_rw.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_rw.c
@@ -1,495 +1,495 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_blocks_misordered(const void *fdt,
- int mem_rsv_size, int struct_size)
-{
- return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
- || (fdt_off_dt_struct(fdt) <
- (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
- || (fdt_off_dt_strings(fdt) <
- (fdt_off_dt_struct(fdt) + struct_size))
- || (fdt_totalsize(fdt) <
- (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
-}
-
-static int _fdt_rw_check_header(void *fdt)
-{
- FDT_CHECK_HEADER(fdt);
-
- if (fdt_version(fdt) < 17)
- return -FDT_ERR_BADVERSION;
- if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
- fdt_size_dt_struct(fdt)))
- return -FDT_ERR_BADLAYOUT;
- if (fdt_version(fdt) > 17)
- fdt_set_version(fdt, 17);
-
- return 0;
-}
-
-#define FDT_RW_CHECK_HEADER(fdt) \
- { \
- int err; \
- if ((err = _fdt_rw_check_header(fdt)) != 0) \
- return err; \
- }
-
-static inline int _fdt_data_size(void *fdt)
-{
- return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
-}
-
-static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
-{
- char *p = splicepoint;
- char *end = (char *)fdt + _fdt_data_size(fdt);
-
- if (((p + oldlen) < p) || ((p + oldlen) > end))
- return -FDT_ERR_BADOFFSET;
- if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
- return -FDT_ERR_NOSPACE;
- memmove(p + newlen, p + oldlen, end - p - oldlen);
- return 0;
-}
-
-static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
- int oldn, int newn)
-{
- int delta = (newn - oldn) * sizeof(*p);
- int err;
- err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
- if (err)
- return err;
- fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
- fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
- return 0;
-}
-
-static int _fdt_splice_struct(void *fdt, void *p,
- int oldlen, int newlen)
-{
- int delta = newlen - oldlen;
- int err;
-
- err = _fdt_splice(fdt, p, oldlen, newlen);
- if (err)
- return err;
-
- fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
- fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
- return 0;
-}
-
-static int _fdt_splice_string(void *fdt, int newlen)
-{
- void *p = (char *)fdt
- + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
- int err;
-
- err = _fdt_splice(fdt, p, 0, newlen);
- if (err)
- return err;
-
- fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
- return 0;
-}
-
-static int _fdt_find_add_string(void *fdt, const char *s)
-{
- char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
- const char *p;
- char *new;
- int len = strlen(s) + 1;
- int err;
-
- p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
- if (p)
- /* found it */
- return (p - strtab);
-
- new = strtab + fdt_size_dt_strings(fdt);
- err = _fdt_splice_string(fdt, len);
- if (err)
- return err;
-
- memcpy(new, s, len);
- return (new - strtab);
-}
-
-int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
-{
- struct fdt_reserve_entry *re;
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
- err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
- if (err)
- return err;
-
- re->address = cpu_to_fdt64(address);
- re->size = cpu_to_fdt64(size);
- return 0;
-}
-
-int fdt_del_mem_rsv(void *fdt, int n)
-{
- struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- if (n >= fdt_num_mem_rsv(fdt))
- return -FDT_ERR_NOTFOUND;
-
- err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
- if (err)
- return err;
- return 0;
-}
-
-static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
-{
- int oldlen;
- int err;
-
- *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (! (*prop))
- return oldlen;
-
- err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
- FDT_TAGALIGN(len));
- if (err)
- return err;
-
- (*prop)->len = cpu_to_fdt32(len);
- return 0;
-}
-
-static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
-{
- int proplen;
- int nextoffset;
- int namestroff;
- int err;
-
- if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
- return nextoffset;
-
- namestroff = _fdt_find_add_string(fdt, name);
- if (namestroff < 0)
- return namestroff;
-
- *prop = _fdt_offset_ptr_w(fdt, nextoffset);
- proplen = sizeof(**prop) + FDT_TAGALIGN(len);
-
- err = _fdt_splice_struct(fdt, *prop, 0, proplen);
- if (err)
- return err;
-
- (*prop)->tag = cpu_to_fdt32(FDT_PROP);
- (*prop)->nameoff = cpu_to_fdt32(namestroff);
- (*prop)->len = cpu_to_fdt32(len);
- return 0;
-}
-
-int fdt_set_name(void *fdt, int nodeoffset, const char *name)
-{
- char *namep;
- int oldlen, newlen;
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
- if (!namep)
- return oldlen;
-
- newlen = strlen(name);
-
- err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
- FDT_TAGALIGN(newlen+1));
- if (err)
- return err;
-
- memcpy(namep, name, newlen+1);
- return 0;
-}
-
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
-{
- struct fdt_property *prop;
- int err;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
- if (err == -FDT_ERR_NOTFOUND)
- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
- if (err)
- return err;
-
- memcpy(prop->data, val, len);
- return 0;
-}
-
-int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
-{
- struct fdt_property *prop;
- int err, oldlen, newlen;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (prop) {
- newlen = len + oldlen;
- err = _fdt_splice_struct(fdt, prop->data,
- FDT_TAGALIGN(oldlen),
- FDT_TAGALIGN(newlen));
- if (err)
- return err;
- prop->len = cpu_to_fdt32(newlen);
- memcpy(prop->data + oldlen, val, len);
- } else {
- err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
- if (err)
- return err;
- memcpy(prop->data, val, len);
- }
- return 0;
-}
-
-int fdt_delprop(void *fdt, int nodeoffset, const char *name)
-{
- struct fdt_property *prop;
- int len, proplen;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
- return len;
-
- proplen = sizeof(*prop) + FDT_TAGALIGN(len);
- return _fdt_splice_struct(fdt, prop, proplen, 0);
-}
-
-int fdt_add_subnode_namelen(void *fdt, int parentoffset,
- const char *name, int namelen)
-{
- struct fdt_node_header *nh;
- int offset, nextoffset;
- int nodelen;
- int err;
- uint32_t tag;
- uint32_t *endtag;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
- if (offset >= 0)
- return -FDT_ERR_EXISTS;
- else if (offset != -FDT_ERR_NOTFOUND)
- return offset;
-
- /* Try to place the new node after the parent's properties */
- fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
- do {
- offset = nextoffset;
- tag = fdt_next_tag(fdt, offset, &nextoffset);
- } while ((tag == FDT_PROP) || (tag == FDT_NOP));
-
- nh = _fdt_offset_ptr_w(fdt, offset);
- nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
-
- err = _fdt_splice_struct(fdt, nh, 0, nodelen);
- if (err)
- return err;
-
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
- memcpy(nh->name, name, namelen);
- endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
- *endtag = cpu_to_fdt32(FDT_END_NODE);
-
- return offset;
-}
-
-int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
-{
- return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
-}
-
-int fdt_del_node(void *fdt, int nodeoffset)
-{
- int endoffset;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
-
- return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
- endoffset - nodeoffset, 0);
-}
-
-static void _fdt_packblocks(const char *old, char *new,
- int mem_rsv_size, int struct_size)
-{
- int mem_rsv_off, struct_off, strings_off;
-
- mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
- struct_off = mem_rsv_off + mem_rsv_size;
- strings_off = struct_off + struct_size;
-
- memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
- fdt_set_off_mem_rsvmap(new, mem_rsv_off);
-
- memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
- fdt_set_off_dt_struct(new, struct_off);
- fdt_set_size_dt_struct(new, struct_size);
-
- memmove(new + strings_off, old + fdt_off_dt_strings(old),
- fdt_size_dt_strings(old));
- fdt_set_off_dt_strings(new, strings_off);
- fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
-}
-
-int fdt_open_into(const void *fdt, void *buf, int bufsize)
-{
- int err;
- int mem_rsv_size, struct_size;
- int newsize;
- const char *fdtstart = fdt;
- const char *fdtend = fdtstart + fdt_totalsize(fdt);
- char *tmp;
-
- FDT_CHECK_HEADER(fdt);
-
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
-
- if (fdt_version(fdt) >= 17) {
- struct_size = fdt_size_dt_struct(fdt);
- } else {
- struct_size = 0;
- while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
- ;
- if (struct_size < 0)
- return struct_size;
- }
-
- if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
- /* no further work necessary */
- err = fdt_move(fdt, buf, bufsize);
- if (err)
- return err;
- fdt_set_version(buf, 17);
- fdt_set_size_dt_struct(buf, struct_size);
- fdt_set_totalsize(buf, bufsize);
- return 0;
- }
-
- /* Need to reorder */
- newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
- + struct_size + fdt_size_dt_strings(fdt);
-
- if (bufsize < newsize)
- return -FDT_ERR_NOSPACE;
-
- /* First attempt to build converted tree at beginning of buffer */
- tmp = buf;
- /* But if that overlaps with the old tree... */
- if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
- /* Try right after the old tree instead */
- tmp = (char *)(uintptr_t)fdtend;
- if ((tmp + newsize) > ((char *)buf + bufsize))
- return -FDT_ERR_NOSPACE;
- }
-
- _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
- memmove(buf, tmp, newsize);
-
- fdt_set_magic(buf, FDT_MAGIC);
- fdt_set_totalsize(buf, bufsize);
- fdt_set_version(buf, 17);
- fdt_set_last_comp_version(buf, 16);
- fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
-
- return 0;
-}
-
-int fdt_pack(void *fdt)
-{
- int mem_rsv_size;
-
- FDT_RW_CHECK_HEADER(fdt);
-
- mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
- * sizeof(struct fdt_reserve_entry);
- _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
- fdt_set_totalsize(fdt, _fdt_data_size(fdt));
-
- return 0;
-}
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int _fdt_blocks_misordered(const void *fdt,
+ int mem_rsv_size, int struct_size)
+{
+ return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
+ || (fdt_off_dt_struct(fdt) <
+ (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
+ || (fdt_off_dt_strings(fdt) <
+ (fdt_off_dt_struct(fdt) + struct_size))
+ || (fdt_totalsize(fdt) <
+ (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
+}
+
+static int _fdt_rw_check_header(void *fdt)
+{
+ FDT_CHECK_HEADER(fdt);
+
+ if (fdt_version(fdt) < 17)
+ return -FDT_ERR_BADVERSION;
+ if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
+ fdt_size_dt_struct(fdt)))
+ return -FDT_ERR_BADLAYOUT;
+ if (fdt_version(fdt) > 17)
+ fdt_set_version(fdt, 17);
+
+ return 0;
+}
+
+#define FDT_RW_CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = _fdt_rw_check_header(fdt)) != 0) \
+ return err; \
+ }
+
+static inline int _fdt_data_size(void *fdt)
+{
+ return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+}
+
+static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
+{
+ char *p = splicepoint;
+ char *end = (char *)fdt + _fdt_data_size(fdt);
+
+ if (((p + oldlen) < p) || ((p + oldlen) > end))
+ return -FDT_ERR_BADOFFSET;
+ if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
+ return -FDT_ERR_NOSPACE;
+ memmove(p + newlen, p + oldlen, end - p - oldlen);
+ return 0;
+}
+
+static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
+ int oldn, int newn)
+{
+ int delta = (newn - oldn) * sizeof(*p);
+ int err;
+ err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
+ if (err)
+ return err;
+ fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
+ return 0;
+}
+
+static int _fdt_splice_struct(void *fdt, void *p,
+ int oldlen, int newlen)
+{
+ int delta = newlen - oldlen;
+ int err;
+
+ err = _fdt_splice(fdt, p, oldlen, newlen);
+ if (err)
+ return err;
+
+ fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
+ return 0;
+}
+
+static int _fdt_splice_string(void *fdt, int newlen)
+{
+ void *p = (char *)fdt
+ + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+ int err;
+
+ err = _fdt_splice(fdt, p, 0, newlen);
+ if (err)
+ return err;
+
+ fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
+ return 0;
+}
+
+static int _fdt_find_add_string(void *fdt, const char *s)
+{
+ char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
+ const char *p;
+ char *new;
+ int len = strlen(s) + 1;
+ int err;
+
+ p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
+ if (p)
+ /* found it */
+ return (p - strtab);
+
+ new = strtab + fdt_size_dt_strings(fdt);
+ err = _fdt_splice_string(fdt, len);
+ if (err)
+ return err;
+
+ memcpy(new, s, len);
+ return (new - strtab);
+}
+
+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
+{
+ struct fdt_reserve_entry *re;
+ int err;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
+ err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
+ if (err)
+ return err;
+
+ re->address = cpu_to_fdt64(address);
+ re->size = cpu_to_fdt64(size);
+ return 0;
+}
+
+int fdt_del_mem_rsv(void *fdt, int n)
+{
+ struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
+ int err;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ if (n >= fdt_num_mem_rsv(fdt))
+ return -FDT_ERR_NOTFOUND;
+
+ err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
+ if (err)
+ return err;
+ return 0;
+}
+
+static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
+ int len, struct fdt_property **prop)
+{
+ int oldlen;
+ int err;
+
+ *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ if (! (*prop))
+ return oldlen;
+
+ err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
+ FDT_TAGALIGN(len));
+ if (err)
+ return err;
+
+ (*prop)->len = cpu_to_fdt32(len);
+ return 0;
+}
+
+static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
+ int len, struct fdt_property **prop)
+{
+ int proplen;
+ int nextoffset;
+ int namestroff;
+ int err;
+
+ if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
+ return nextoffset;
+
+ namestroff = _fdt_find_add_string(fdt, name);
+ if (namestroff < 0)
+ return namestroff;
+
+ *prop = _fdt_offset_ptr_w(fdt, nextoffset);
+ proplen = sizeof(**prop) + FDT_TAGALIGN(len);
+
+ err = _fdt_splice_struct(fdt, *prop, 0, proplen);
+ if (err)
+ return err;
+
+ (*prop)->tag = cpu_to_fdt32(FDT_PROP);
+ (*prop)->nameoff = cpu_to_fdt32(namestroff);
+ (*prop)->len = cpu_to_fdt32(len);
+ return 0;
+}
+
+int fdt_set_name(void *fdt, int nodeoffset, const char *name)
+{
+ char *namep;
+ int oldlen, newlen;
+ int err;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
+ if (!namep)
+ return oldlen;
+
+ newlen = strlen(name);
+
+ err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
+ FDT_TAGALIGN(newlen+1));
+ if (err)
+ return err;
+
+ memcpy(namep, name, newlen+1);
+ return 0;
+}
+
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
+ if (err == -FDT_ERR_NOTFOUND)
+ err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
+
+ memcpy(prop->data, val, len);
+ return 0;
+}
+
+int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err, oldlen, newlen;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ if (prop) {
+ newlen = len + oldlen;
+ err = _fdt_splice_struct(fdt, prop->data,
+ FDT_TAGALIGN(oldlen),
+ FDT_TAGALIGN(newlen));
+ if (err)
+ return err;
+ prop->len = cpu_to_fdt32(newlen);
+ memcpy(prop->data + oldlen, val, len);
+ } else {
+ err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
+ memcpy(prop->data, val, len);
+ }
+ return 0;
+}
+
+int fdt_delprop(void *fdt, int nodeoffset, const char *name)
+{
+ struct fdt_property *prop;
+ int len, proplen;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
+ if (! prop)
+ return len;
+
+ proplen = sizeof(*prop) + FDT_TAGALIGN(len);
+ return _fdt_splice_struct(fdt, prop, proplen, 0);
+}
+
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ const char *name, int namelen)
+{
+ struct fdt_node_header *nh;
+ int offset, nextoffset;
+ int nodelen;
+ int err;
+ uint32_t tag;
+ uint32_t *endtag;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
+ if (offset >= 0)
+ return -FDT_ERR_EXISTS;
+ else if (offset != -FDT_ERR_NOTFOUND)
+ return offset;
+
+ /* Try to place the new node after the parent's properties */
+ fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ } while ((tag == FDT_PROP) || (tag == FDT_NOP));
+
+ nh = _fdt_offset_ptr_w(fdt, offset);
+ nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
+
+ err = _fdt_splice_struct(fdt, nh, 0, nodelen);
+ if (err)
+ return err;
+
+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+ memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
+ memcpy(nh->name, name, namelen);
+ endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
+ *endtag = cpu_to_fdt32(FDT_END_NODE);
+
+ return offset;
+}
+
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
+{
+ return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
+}
+
+int fdt_del_node(void *fdt, int nodeoffset)
+{
+ int endoffset;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
+
+ return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
+ endoffset - nodeoffset, 0);
+}
+
+static void _fdt_packblocks(const char *old, char *new,
+ int mem_rsv_size, int struct_size)
+{
+ int mem_rsv_off, struct_off, strings_off;
+
+ mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
+ struct_off = mem_rsv_off + mem_rsv_size;
+ strings_off = struct_off + struct_size;
+
+ memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
+ fdt_set_off_mem_rsvmap(new, mem_rsv_off);
+
+ memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
+ fdt_set_off_dt_struct(new, struct_off);
+ fdt_set_size_dt_struct(new, struct_size);
+
+ memmove(new + strings_off, old + fdt_off_dt_strings(old),
+ fdt_size_dt_strings(old));
+ fdt_set_off_dt_strings(new, strings_off);
+ fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
+}
+
+int fdt_open_into(const void *fdt, void *buf, int bufsize)
+{
+ int err;
+ int mem_rsv_size, struct_size;
+ int newsize;
+ const char *fdtstart = fdt;
+ const char *fdtend = fdtstart + fdt_totalsize(fdt);
+ char *tmp;
+
+ FDT_CHECK_HEADER(fdt);
+
+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+ * sizeof(struct fdt_reserve_entry);
+
+ if (fdt_version(fdt) >= 17) {
+ struct_size = fdt_size_dt_struct(fdt);
+ } else {
+ struct_size = 0;
+ while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
+ ;
+ if (struct_size < 0)
+ return struct_size;
+ }
+
+ if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
+ /* no further work necessary */
+ err = fdt_move(fdt, buf, bufsize);
+ if (err)
+ return err;
+ fdt_set_version(buf, 17);
+ fdt_set_size_dt_struct(buf, struct_size);
+ fdt_set_totalsize(buf, bufsize);
+ return 0;
+ }
+
+ /* Need to reorder */
+ newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
+ + struct_size + fdt_size_dt_strings(fdt);
+
+ if (bufsize < newsize)
+ return -FDT_ERR_NOSPACE;
+
+ /* First attempt to build converted tree at beginning of buffer */
+ tmp = buf;
+ /* But if that overlaps with the old tree... */
+ if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
+ /* Try right after the old tree instead */
+ tmp = (char *)(uintptr_t)fdtend;
+ if ((tmp + newsize) > ((char *)buf + bufsize))
+ return -FDT_ERR_NOSPACE;
+ }
+
+ _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
+ memmove(buf, tmp, newsize);
+
+ fdt_set_magic(buf, FDT_MAGIC);
+ fdt_set_totalsize(buf, bufsize);
+ fdt_set_version(buf, 17);
+ fdt_set_last_comp_version(buf, 16);
+ fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
+
+ return 0;
+}
+
+int fdt_pack(void *fdt)
+{
+ int mem_rsv_size;
+
+ FDT_RW_CHECK_HEADER(fdt);
+
+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
+ * sizeof(struct fdt_reserve_entry);
+ _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
+ fdt_set_totalsize(fdt, _fdt_data_size(fdt));
+
+ return 0;
+}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_strerror.c b/EmbeddedPkg/Library/FdtLib/fdt_strerror.c
index e6c3ceee8c..a49793d936 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_strerror.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_strerror.c
@@ -1,96 +1,96 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-struct fdt_errtabent {
- const char *str;
-};
-
-#define FDT_ERRTABENT(val) \
- [(val)] = { .str = #val, }
-
-static struct fdt_errtabent fdt_errtable[] = {
- FDT_ERRTABENT(FDT_ERR_NOTFOUND),
- FDT_ERRTABENT(FDT_ERR_EXISTS),
- FDT_ERRTABENT(FDT_ERR_NOSPACE),
-
- FDT_ERRTABENT(FDT_ERR_BADOFFSET),
- FDT_ERRTABENT(FDT_ERR_BADPATH),
- FDT_ERRTABENT(FDT_ERR_BADSTATE),
-
- FDT_ERRTABENT(FDT_ERR_TRUNCATED),
- FDT_ERRTABENT(FDT_ERR_BADMAGIC),
- FDT_ERRTABENT(FDT_ERR_BADVERSION),
- FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
- FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
-};
-#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
-
-const char *fdt_strerror(int errval)
-{
- if (errval > 0)
- return "<valid offset/length>";
- else if (errval == 0)
- return "<no error>";
- else if (errval > -FDT_ERRTABSIZE) {
- const char *s = fdt_errtable[-errval].str;
-
- if (s)
- return s;
- }
-
- return "<unknown error>";
-}
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+struct fdt_errtabent {
+ const char *str;
+};
+
+#define FDT_ERRTABENT(val) \
+ [(val)] = { .str = #val, }
+
+static struct fdt_errtabent fdt_errtable[] = {
+ FDT_ERRTABENT(FDT_ERR_NOTFOUND),
+ FDT_ERRTABENT(FDT_ERR_EXISTS),
+ FDT_ERRTABENT(FDT_ERR_NOSPACE),
+
+ FDT_ERRTABENT(FDT_ERR_BADOFFSET),
+ FDT_ERRTABENT(FDT_ERR_BADPATH),
+ FDT_ERRTABENT(FDT_ERR_BADSTATE),
+
+ FDT_ERRTABENT(FDT_ERR_TRUNCATED),
+ FDT_ERRTABENT(FDT_ERR_BADMAGIC),
+ FDT_ERRTABENT(FDT_ERR_BADVERSION),
+ FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
+ FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
+};
+#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
+
+const char *fdt_strerror(int errval)
+{
+ if (errval > 0)
+ return "<valid offset/length>";
+ else if (errval == 0)
+ return "<no error>";
+ else if (errval > -FDT_ERRTABSIZE) {
+ const char *s = fdt_errtable[-errval].str;
+
+ if (s)
+ return s;
+ }
+
+ return "<unknown error>";
+}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_sw.c b/EmbeddedPkg/Library/FdtLib/fdt_sw.c
index 55ebebf1eb..240fabc554 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_sw.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_sw.c
@@ -1,256 +1,256 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-static int _fdt_sw_check_header(void *fdt)
-{
- if (fdt_magic(fdt) != FDT_SW_MAGIC)
- return -FDT_ERR_BADMAGIC;
- /* FIXME: should check more details about the header state */
- return 0;
-}
-
-#define FDT_SW_CHECK_HEADER(fdt) \
- { \
- int err; \
- if ((err = _fdt_sw_check_header(fdt)) != 0) \
- return err; \
- }
-
-static void *_fdt_grab_space(void *fdt, size_t len)
-{
- int offset = fdt_size_dt_struct(fdt);
- int spaceleft;
-
- spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
- - fdt_size_dt_strings(fdt);
-
- if ((offset + len < offset) || (offset + len > spaceleft))
- return NULL;
-
- fdt_set_size_dt_struct(fdt, offset + len);
- return _fdt_offset_ptr_w(fdt, offset);
-}
-
-int fdt_create(void *buf, int bufsize)
-{
- void *fdt = buf;
-
- if (bufsize < sizeof(struct fdt_header))
- return -FDT_ERR_NOSPACE;
-
- memset(buf, 0, bufsize);
-
- fdt_set_magic(fdt, FDT_SW_MAGIC);
- fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
- fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
- fdt_set_totalsize(fdt, bufsize);
-
- fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
- sizeof(struct fdt_reserve_entry)));
- fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
- fdt_set_off_dt_strings(fdt, bufsize);
-
- return 0;
-}
-
-int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
-{
- struct fdt_reserve_entry *re;
- int offset;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- if (fdt_size_dt_struct(fdt))
- return -FDT_ERR_BADSTATE;
-
- offset = fdt_off_dt_struct(fdt);
- if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
- return -FDT_ERR_NOSPACE;
-
- re = (struct fdt_reserve_entry *)((char *)fdt + offset);
- re->address = cpu_to_fdt64(addr);
- re->size = cpu_to_fdt64(size);
-
- fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
-
- return 0;
-}
-
-int fdt_finish_reservemap(void *fdt)
-{
- return fdt_add_reservemap_entry(fdt, 0, 0);
-}
-
-int fdt_begin_node(void *fdt, const char *name)
-{
- struct fdt_node_header *nh;
- int namelen = strlen(name) + 1;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
- if (! nh)
- return -FDT_ERR_NOSPACE;
-
- nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
- memcpy(nh->name, name, namelen);
- return 0;
-}
-
-int fdt_end_node(void *fdt)
-{
- uint32_t *en;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- en = _fdt_grab_space(fdt, FDT_TAGSIZE);
- if (! en)
- return -FDT_ERR_NOSPACE;
-
- *en = cpu_to_fdt32(FDT_END_NODE);
- return 0;
-}
-
-static int _fdt_find_add_string(void *fdt, const char *s)
-{
- char *strtab = (char *)fdt + fdt_totalsize(fdt);
- const char *p;
- int strtabsize = fdt_size_dt_strings(fdt);
- int len = strlen(s) + 1;
- int struct_top, offset;
-
- p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
- if (p)
- return p - strtab;
-
- /* Add it */
- offset = -strtabsize - len;
- struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- if (fdt_totalsize(fdt) + offset < struct_top)
- return 0; /* no more room :( */
-
- memcpy(strtab + offset, s, len);
- fdt_set_size_dt_strings(fdt, strtabsize + len);
- return offset;
-}
-
-int fdt_property(void *fdt, const char *name, const void *val, int len)
-{
- struct fdt_property *prop;
- int nameoff;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- nameoff = _fdt_find_add_string(fdt, name);
- if (nameoff == 0)
- return -FDT_ERR_NOSPACE;
-
- prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
- if (! prop)
- return -FDT_ERR_NOSPACE;
-
- prop->tag = cpu_to_fdt32(FDT_PROP);
- prop->nameoff = cpu_to_fdt32(nameoff);
- prop->len = cpu_to_fdt32(len);
- memcpy(prop->data, val, len);
- return 0;
-}
-
-int fdt_finish(void *fdt)
-{
- char *p = (char *)fdt;
- uint32_t *end;
- int oldstroffset, newstroffset;
- uint32_t tag;
- int offset, nextoffset;
-
- FDT_SW_CHECK_HEADER(fdt);
-
- /* Add terminator */
- end = _fdt_grab_space(fdt, sizeof(*end));
- if (! end)
- return -FDT_ERR_NOSPACE;
- *end = cpu_to_fdt32(FDT_END);
-
- /* Relocate the string table */
- oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
- newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
- memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
- fdt_set_off_dt_strings(fdt, newstroffset);
-
- /* Walk the structure, correcting string offsets */
- offset = 0;
- while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
- if (tag == FDT_PROP) {
- struct fdt_property *prop =
- _fdt_offset_ptr_w(fdt, offset);
- int nameoff;
-
- nameoff = fdt32_to_cpu(prop->nameoff);
- nameoff += fdt_size_dt_strings(fdt);
- prop->nameoff = cpu_to_fdt32(nameoff);
- }
- offset = nextoffset;
- }
- if (nextoffset < 0)
- return nextoffset;
-
- /* Finally, adjust the header */
- fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
- fdt_set_magic(fdt, FDT_MAGIC);
- return 0;
-}
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int _fdt_sw_check_header(void *fdt)
+{
+ if (fdt_magic(fdt) != FDT_SW_MAGIC)
+ return -FDT_ERR_BADMAGIC;
+ /* FIXME: should check more details about the header state */
+ return 0;
+}
+
+#define FDT_SW_CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = _fdt_sw_check_header(fdt)) != 0) \
+ return err; \
+ }
+
+static void *_fdt_grab_space(void *fdt, size_t len)
+{
+ int offset = fdt_size_dt_struct(fdt);
+ int spaceleft;
+
+ spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
+ - fdt_size_dt_strings(fdt);
+
+ if ((offset + len < offset) || (offset + len > spaceleft))
+ return NULL;
+
+ fdt_set_size_dt_struct(fdt, offset + len);
+ return _fdt_offset_ptr_w(fdt, offset);
+}
+
+int fdt_create(void *buf, int bufsize)
+{
+ void *fdt = buf;
+
+ if (bufsize < sizeof(struct fdt_header))
+ return -FDT_ERR_NOSPACE;
+
+ memset(buf, 0, bufsize);
+
+ fdt_set_magic(fdt, FDT_SW_MAGIC);
+ fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
+ fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
+ fdt_set_totalsize(fdt, bufsize);
+
+ fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
+ sizeof(struct fdt_reserve_entry)));
+ fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
+ fdt_set_off_dt_strings(fdt, bufsize);
+
+ return 0;
+}
+
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
+{
+ struct fdt_reserve_entry *re;
+ int offset;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ if (fdt_size_dt_struct(fdt))
+ return -FDT_ERR_BADSTATE;
+
+ offset = fdt_off_dt_struct(fdt);
+ if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
+ return -FDT_ERR_NOSPACE;
+
+ re = (struct fdt_reserve_entry *)((char *)fdt + offset);
+ re->address = cpu_to_fdt64(addr);
+ re->size = cpu_to_fdt64(size);
+
+ fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
+
+ return 0;
+}
+
+int fdt_finish_reservemap(void *fdt)
+{
+ return fdt_add_reservemap_entry(fdt, 0, 0);
+}
+
+int fdt_begin_node(void *fdt, const char *name)
+{
+ struct fdt_node_header *nh;
+ int namelen = strlen(name) + 1;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
+ if (! nh)
+ return -FDT_ERR_NOSPACE;
+
+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+ memcpy(nh->name, name, namelen);
+ return 0;
+}
+
+int fdt_end_node(void *fdt)
+{
+ uint32_t *en;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ en = _fdt_grab_space(fdt, FDT_TAGSIZE);
+ if (! en)
+ return -FDT_ERR_NOSPACE;
+
+ *en = cpu_to_fdt32(FDT_END_NODE);
+ return 0;
+}
+
+static int _fdt_find_add_string(void *fdt, const char *s)
+{
+ char *strtab = (char *)fdt + fdt_totalsize(fdt);
+ const char *p;
+ int strtabsize = fdt_size_dt_strings(fdt);
+ int len = strlen(s) + 1;
+ int struct_top, offset;
+
+ p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
+ if (p)
+ return p - strtab;
+
+ /* Add it */
+ offset = -strtabsize - len;
+ struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ if (fdt_totalsize(fdt) + offset < struct_top)
+ return 0; /* no more room :( */
+
+ memcpy(strtab + offset, s, len);
+ fdt_set_size_dt_strings(fdt, strtabsize + len);
+ return offset;
+}
+
+int fdt_property(void *fdt, const char *name, const void *val, int len)
+{
+ struct fdt_property *prop;
+ int nameoff;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ nameoff = _fdt_find_add_string(fdt, name);
+ if (nameoff == 0)
+ return -FDT_ERR_NOSPACE;
+
+ prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
+ if (! prop)
+ return -FDT_ERR_NOSPACE;
+
+ prop->tag = cpu_to_fdt32(FDT_PROP);
+ prop->nameoff = cpu_to_fdt32(nameoff);
+ prop->len = cpu_to_fdt32(len);
+ memcpy(prop->data, val, len);
+ return 0;
+}
+
+int fdt_finish(void *fdt)
+{
+ char *p = (char *)fdt;
+ uint32_t *end;
+ int oldstroffset, newstroffset;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ FDT_SW_CHECK_HEADER(fdt);
+
+ /* Add terminator */
+ end = _fdt_grab_space(fdt, sizeof(*end));
+ if (! end)
+ return -FDT_ERR_NOSPACE;
+ *end = cpu_to_fdt32(FDT_END);
+
+ /* Relocate the string table */
+ oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
+ newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
+ fdt_set_off_dt_strings(fdt, newstroffset);
+
+ /* Walk the structure, correcting string offsets */
+ offset = 0;
+ while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
+ if (tag == FDT_PROP) {
+ struct fdt_property *prop =
+ _fdt_offset_ptr_w(fdt, offset);
+ int nameoff;
+
+ nameoff = fdt32_to_cpu(prop->nameoff);
+ nameoff += fdt_size_dt_strings(fdt);
+ prop->nameoff = cpu_to_fdt32(nameoff);
+ }
+ offset = nextoffset;
+ }
+ if (nextoffset < 0)
+ return nextoffset;
+
+ /* Finally, adjust the header */
+ fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
+ fdt_set_magic(fdt, FDT_MAGIC);
+ return 0;
+}
diff --git a/EmbeddedPkg/Library/FdtLib/fdt_wip.c b/EmbeddedPkg/Library/FdtLib/fdt_wip.c
index 6025fa1fe8..e009a88f51 100644
--- a/EmbeddedPkg/Library/FdtLib/fdt_wip.c
+++ b/EmbeddedPkg/Library/FdtLib/fdt_wip.c
@@ -1,118 +1,118 @@
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "libfdt_env.h"
-
-#include <fdt.h>
-#include <libfdt.h>
-
-#include "libfdt_internal.h"
-
-int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
-{
- void *propval;
- int proplen;
-
- propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
- if (! propval)
- return proplen;
-
- if (proplen != len)
- return -FDT_ERR_NOSPACE;
-
- memcpy(propval, val, len);
- return 0;
-}
-
-static void _fdt_nop_region(void *start, int len)
-{
- uint32_t *p;
-
- for (p = start; (char *)p < ((char *)start + len); p++)
- *p = cpu_to_fdt32(FDT_NOP);
-}
-
-int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
-{
- struct fdt_property *prop;
- int len;
-
- prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
- return len;
-
- _fdt_nop_region(prop, len + sizeof(*prop));
-
- return 0;
-}
-
-int _fdt_node_end_offset(void *fdt, int offset)
-{
- int depth = 0;
-
- while ((offset >= 0) && (depth >= 0))
- offset = fdt_next_node(fdt, offset, &depth);
-
- return offset;
-}
-
-int fdt_nop_node(void *fdt, int nodeoffset)
-{
- int endoffset;
-
- endoffset = _fdt_node_end_offset(fdt, nodeoffset);
- if (endoffset < 0)
- return endoffset;
-
- _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
- endoffset - nodeoffset);
- return 0;
-}
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ void *propval;
+ int proplen;
+
+ propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
+ if (! propval)
+ return proplen;
+
+ if (proplen != len)
+ return -FDT_ERR_NOSPACE;
+
+ memcpy(propval, val, len);
+ return 0;
+}
+
+static void _fdt_nop_region(void *start, int len)
+{
+ uint32_t *p;
+
+ for (p = start; (char *)p < ((char *)start + len); p++)
+ *p = cpu_to_fdt32(FDT_NOP);
+}
+
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
+{
+ struct fdt_property *prop;
+ int len;
+
+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
+ if (! prop)
+ return len;
+
+ _fdt_nop_region(prop, len + sizeof(*prop));
+
+ return 0;
+}
+
+int _fdt_node_end_offset(void *fdt, int offset)
+{
+ int depth = 0;
+
+ while ((offset >= 0) && (depth >= 0))
+ offset = fdt_next_node(fdt, offset, &depth);
+
+ return offset;
+}
+
+int fdt_nop_node(void *fdt, int nodeoffset)
+{
+ int endoffset;
+
+ endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
+
+ _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
+ endoffset - nodeoffset);
+ return 0;
+}
diff --git a/EmbeddedPkg/Library/FdtLib/libfdt_internal.h b/EmbeddedPkg/Library/FdtLib/libfdt_internal.h
index 381133ba81..15456110a3 100644
--- a/EmbeddedPkg/Library/FdtLib/libfdt_internal.h
+++ b/EmbeddedPkg/Library/FdtLib/libfdt_internal.h
@@ -1,95 +1,95 @@
-#ifndef _LIBFDT_INTERNAL_H
-#define _LIBFDT_INTERNAL_H
-/*
- * libfdt - Flat Device Tree manipulation
- * Copyright (C) 2006 David Gibson, IBM Corporation.
- *
- * libfdt is dual licensed: you can use it either under the terms of
- * the GPL, or the BSD license, at your option.
- *
- * a) This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- *
- * Alternatively,
- *
- * b) Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <fdt.h>
-
-#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
-#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
-
-#define FDT_CHECK_HEADER(fdt) \
- { \
- int err; \
- if ((err = fdt_check_header(fdt)) != 0) \
- return err; \
- }
-
-int _fdt_check_node_offset(const void *fdt, int offset);
-int _fdt_check_prop_offset(const void *fdt, int offset);
-const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
-int _fdt_node_end_offset(void *fdt, int nodeoffset);
-
-static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
-{
- return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
-}
-
-static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
-{
- return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
-}
-
-static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
-{
- const struct fdt_reserve_entry *rsv_table =
- (const struct fdt_reserve_entry *)
- ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
-
- return rsv_table + n;
-}
-static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
-{
- return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
-}
-
-#define FDT_SW_MAGIC (~FDT_MAGIC)
-
-#endif /* _LIBFDT_INTERNAL_H */
+#ifndef _LIBFDT_INTERNAL_H
+#define _LIBFDT_INTERNAL_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <fdt.h>
+
+#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
+
+#define FDT_CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = fdt_check_header(fdt)) != 0) \
+ return err; \
+ }
+
+int _fdt_check_node_offset(const void *fdt, int offset);
+int _fdt_check_prop_offset(const void *fdt, int offset);
+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
+int _fdt_node_end_offset(void *fdt, int nodeoffset);
+
+static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
+{
+ return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
+}
+
+static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
+{
+ return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
+}
+
+static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
+{
+ const struct fdt_reserve_entry *rsv_table =
+ (const struct fdt_reserve_entry *)
+ ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
+
+ return rsv_table + n;
+}
+static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
+{
+ return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
+}
+
+#define FDT_SW_MAGIC (~FDT_MAGIC)
+
+#endif /* _LIBFDT_INTERNAL_H */
diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S b/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S
index f8c4e296ca..9c3cc3ce3c 100755
--- a/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S
+++ b/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.S
@@ -1,258 +1,258 @@
-#------------------------------------------------------------------------------
-#
-# Use ARMv6 instruction to operate on a single stack
-#
-# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
-#
-# 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.
-#
-#------------------------------------------------------------------------------
-
-/*
-
-This is the stack constructed by the exception handler (low address to high address)
- # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
- Reg Offset
- === ======
- R0 0x00 # stmfd SP!,{R0-R12}
- R1 0x04
- R2 0x08
- R3 0x0c
- R4 0x10
- R5 0x14
- R6 0x18
- R7 0x1c
- R8 0x20
- R9 0x24
- R10 0x28
- R11 0x2c
- R12 0x30
- SP 0x34 # reserved via adding 0x20 (32) to the SP
- LR 0x38
- PC 0x3c
- CPSR 0x40
- DFSR 0x44
- DFAR 0x48
- IFSR 0x4c
- IFAR 0x50
-
- LR 0x54 # SVC Link register (we need to restore it)
-
- LR 0x58 # pushed by srsfd
- CPSR 0x5c
-
- */
-
-
-GCC_ASM_EXPORT(ExceptionHandlersStart)
-GCC_ASM_EXPORT(ExceptionHandlersEnd)
-GCC_ASM_EXPORT(CommonExceptionEntry)
-GCC_ASM_EXPORT(AsmCommonExceptionEntry)
-GCC_ASM_EXPORT(GdbExceptionHandler)
-
-.text
-.align 3
-
-
-//
-// This code gets copied to the ARM vector table
-// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
-//
-ASM_PFX(ExceptionHandlersStart):
-
-ASM_PFX(Reset):
- b ASM_PFX(Reset)
-
-ASM_PFX(UndefinedInstruction):
- b ASM_PFX(UndefinedInstructionEntry)
-
-ASM_PFX(SoftwareInterrupt):
- b ASM_PFX(SoftwareInterruptEntry)
-
-ASM_PFX(PrefetchAbort):
- b ASM_PFX(PrefetchAbortEntry)
-
-ASM_PFX(DataAbort):
- b ASM_PFX(DataAbortEntry)
-
-ASM_PFX(ReservedException):
- b ASM_PFX(ReservedExceptionEntry)
-
-ASM_PFX(Irq):
- b ASM_PFX(Irq)
-
-ASM_PFX(Fiq):
- b ASM_PFX(FiqEntry)
-
-
-ASM_PFX(UndefinedInstructionEntry):
- sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
- srsdb #0x13! @ Store return state on SVC stack
- cpsid f,#0x13 @ Switch to SVC for common stack
- stmfd SP!,{LR} @ Store the link register for the current mode
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} @ Store the register state
-
- mov R0,#1 @ ExceptionType
- ldr R1,ASM_PFX(CommonExceptionEntry)
- bx R1
-
-ASM_PFX(SoftwareInterruptEntry):
- sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
- srsdb #0x13! @ Store return state on SVC stack
- cpsid f @ We are already in SVC mode
- stmfd SP!,{LR} @ Store the link register for the current mode
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} @ Store the register state
-
- mov R0,#2 @ ExceptionType
- ldr R1,ASM_PFX(CommonExceptionEntry)
- bx R1
-
-ASM_PFX(PrefetchAbortEntry):
- sub LR,LR,#4
- srsdb #0x13! @ Store return state on SVC stack
- cpsid f,#0x13 @ Switch to SVC for common stack
- stmfd SP!,{LR} @ Store the link register for the current mode
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} @ Store the register state
-
- mov R0,#3 @ ExceptionType
- ldr R1,ASM_PFX(CommonExceptionEntry)
- bx R1
-
-ASM_PFX(DataAbortEntry):
- sub LR,LR,#8
- srsdb #0x13! @ Store return state on SVC stack
- cpsid f,#0x13 @ Switch to SVC for common stack
- stmfd SP!,{LR} @ Store the link register for the current mode
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} @ Store the register state
-
- mov R0,#4
- ldr R1,ASM_PFX(CommonExceptionEntry)
- bx R1
-
-ASM_PFX(ReservedExceptionEntry):
- srsdb #0x13! @ Store return state on SVC stack
- cpsid f,#0x13 @ Switch to SVC for common stack
- stmfd SP!,{LR} @ Store the link register for the current mode
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} @ Store the register state
-
- mov R0,#5
- ldr R1,ASM_PFX(CommonExceptionEntry)
- bx R1
-
-ASM_PFX(FiqEntry):
- sub LR,LR,#4
- srsdb #0x13! @ Store return state on SVC stack
- cps #0x13 @ Switch to SVC for common stack
- stmfd SP!,{LR} @ Store the link register for the current mode
- sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} @ Store the register state
- @ Since we have already switch to SVC R8_fiq - R12_fiq
- @ never get used or saved
- mov R0,#7 @ ExceptionType
- ldr R1,ASM_PFX(CommonExceptionEntry)
- bx R1
-
-//
-// This gets patched by the C code that patches in the vector table
-//
-ASM_PFX(CommonExceptionEntry):
- .byte 0x12
- .byte 0x34
- .byte 0x56
- .byte 0x78
-
-ASM_PFX(ExceptionHandlersEnd):
-
-//
-// This code runs from CpuDxe driver loaded address. It is patched into
-// CommonExceptionEntry.
-//
-ASM_PFX(AsmCommonExceptionEntry):
- mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
- str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
-
- mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
- str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
-
- mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
- str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
-
- mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
- str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
-
- ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
- str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
-
- add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
- and R3, R1, #0x1f @ Check CPSR to see if User or System Mode
- cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1df))
- cmpne R3, #0x10 @
- stmeqed R2, {lr}^ @ save unbanked lr
- @ else
- stmneed R2, {lr} @ save SVC lr
-
-
- ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
- @ Check to see if we have to adjust for Thumb entry
- sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType ==2)) {
- cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb
- bhi NoAdjustNeeded
-
- tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
- addne R5, R5, #2 @ PC += 2@
- str R5,[SP,#0x58] @ Update LR value pused by srsfd
-
-NoAdjustNeeded:
-
- str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
-
- sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
- str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
-
- @ R0 is ExceptionType
- mov R1,SP @ R1 is SystemContext
-
-/*
-VOID
-EFIAPI
-GdbExceptionHandler (
- IN EFI_EXCEPTION_TYPE ExceptionType, R0
- IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
- )
-
-*/
- blx ASM_PFX(GdbExceptionHandler) @ Call exception handler
-
- ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
- str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored
-
- ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
- str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored
-
- add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry
- add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
- and R1, R1, #0x1f @ Check to see if User or System Mode
- cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
- cmpne R1, #0x10 @
- ldmeqed R2, {lr}^ @ restore unbanked lr
- @ else
- ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}
-
- ldmfd SP!,{R0-R12} @ Restore general purpose registers
- @ Exception handler can not change SP
-
- add SP,SP,#0x20 @ Clear out the remaining stack space
- ldmfd SP!,{LR} @ restore the link register for this context
- rfefd SP! @ return from exception via srsfd stack slot
-
+#------------------------------------------------------------------------------
+#
+# Use ARMv6 instruction to operate on a single stack
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#
+# 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.
+#
+#------------------------------------------------------------------------------
+
+/*
+
+This is the stack constructed by the exception handler (low address to high address)
+ # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
+ Reg Offset
+ === ======
+ R0 0x00 # stmfd SP!,{R0-R12}
+ R1 0x04
+ R2 0x08
+ R3 0x0c
+ R4 0x10
+ R5 0x14
+ R6 0x18
+ R7 0x1c
+ R8 0x20
+ R9 0x24
+ R10 0x28
+ R11 0x2c
+ R12 0x30
+ SP 0x34 # reserved via adding 0x20 (32) to the SP
+ LR 0x38
+ PC 0x3c
+ CPSR 0x40
+ DFSR 0x44
+ DFAR 0x48
+ IFSR 0x4c
+ IFAR 0x50
+
+ LR 0x54 # SVC Link register (we need to restore it)
+
+ LR 0x58 # pushed by srsfd
+ CPSR 0x5c
+
+ */
+
+
+GCC_ASM_EXPORT(ExceptionHandlersStart)
+GCC_ASM_EXPORT(ExceptionHandlersEnd)
+GCC_ASM_EXPORT(CommonExceptionEntry)
+GCC_ASM_EXPORT(AsmCommonExceptionEntry)
+GCC_ASM_EXPORT(GdbExceptionHandler)
+
+.text
+.align 3
+
+
+//
+// This code gets copied to the ARM vector table
+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
+//
+ASM_PFX(ExceptionHandlersStart):
+
+ASM_PFX(Reset):
+ b ASM_PFX(Reset)
+
+ASM_PFX(UndefinedInstruction):
+ b ASM_PFX(UndefinedInstructionEntry)
+
+ASM_PFX(SoftwareInterrupt):
+ b ASM_PFX(SoftwareInterruptEntry)
+
+ASM_PFX(PrefetchAbort):
+ b ASM_PFX(PrefetchAbortEntry)
+
+ASM_PFX(DataAbort):
+ b ASM_PFX(DataAbortEntry)
+
+ASM_PFX(ReservedException):
+ b ASM_PFX(ReservedExceptionEntry)
+
+ASM_PFX(Irq):
+ b ASM_PFX(Irq)
+
+ASM_PFX(Fiq):
+ b ASM_PFX(FiqEntry)
+
+
+ASM_PFX(UndefinedInstructionEntry):
+ sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsdb #0x13! @ Store return state on SVC stack
+ cpsid f,#0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#1 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(SoftwareInterruptEntry):
+ sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsdb #0x13! @ Store return state on SVC stack
+ cpsid f @ We are already in SVC mode
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#2 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(PrefetchAbortEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cpsid f,#0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#3 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(DataAbortEntry):
+ sub LR,LR,#8
+ srsdb #0x13! @ Store return state on SVC stack
+ cpsid f,#0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#4
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(ReservedExceptionEntry):
+ srsdb #0x13! @ Store return state on SVC stack
+ cpsid f,#0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+
+ mov R0,#5
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+ASM_PFX(FiqEntry):
+ sub LR,LR,#4
+ srsdb #0x13! @ Store return state on SVC stack
+ cps #0x13 @ Switch to SVC for common stack
+ stmfd SP!,{LR} @ Store the link register for the current mode
+ sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} @ Store the register state
+ @ Since we have already switch to SVC R8_fiq - R12_fiq
+ @ never get used or saved
+ mov R0,#7 @ ExceptionType
+ ldr R1,ASM_PFX(CommonExceptionEntry)
+ bx R1
+
+//
+// This gets patched by the C code that patches in the vector table
+//
+ASM_PFX(CommonExceptionEntry):
+ .byte 0x12
+ .byte 0x34
+ .byte 0x56
+ .byte 0x78
+
+ASM_PFX(ExceptionHandlersEnd):
+
+//
+// This code runs from CpuDxe driver loaded address. It is patched into
+// CommonExceptionEntry.
+//
+ASM_PFX(AsmCommonExceptionEntry):
+ mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
+ str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
+
+ mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
+ str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
+
+ mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
+ str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
+
+ mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
+ str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
+
+ ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
+ str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
+
+ add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R3, R1, #0x1f @ Check CPSR to see if User or System Mode
+ cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1df))
+ cmpne R3, #0x10 @
+ stmeqed R2, {lr}^ @ save unbanked lr
+ @ else
+ stmneed R2, {lr} @ save SVC lr
+
+
+ ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
+ @ Check to see if we have to adjust for Thumb entry
+ sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType ==2)) {
+ cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb
+ bhi NoAdjustNeeded
+
+ tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
+ addne R5, R5, #2 @ PC += 2@
+ str R5,[SP,#0x58] @ Update LR value pused by srsfd
+
+NoAdjustNeeded:
+
+ str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+
+ sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
+ str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
+
+ @ R0 is ExceptionType
+ mov R1,SP @ R1 is SystemContext
+
+/*
+VOID
+EFIAPI
+GdbExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType, R0
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
+ )
+
+*/
+ blx ASM_PFX(GdbExceptionHandler) @ Call exception handler
+
+ ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
+ str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored
+
+ ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
+ str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored
+
+ add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry
+ add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R1, R1, #0x1f @ Check to see if User or System Mode
+ cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
+ cmpne R1, #0x10 @
+ ldmeqed R2, {lr}^ @ restore unbanked lr
+ @ else
+ ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}
+
+ ldmfd SP!,{R0-R12} @ Restore general purpose registers
+ @ Exception handler can not change SP
+
+ add SP,SP,#0x20 @ Clear out the remaining stack space
+ ldmfd SP!,{LR} @ restore the link register for this context
+ rfefd SP! @ return from exception via srsfd stack slot
+
diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm b/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm
index c133073f4b..c70fb92482 100755
--- a/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm
+++ b/EmbeddedPkg/Library/GdbDebugAgent/Arm/ExceptionSupport.ARMv6.asm
@@ -1,259 +1,259 @@
-//------------------------------------------------------------------------------
-//
-// Use ARMv6 instruction to operate on a single stack
-//
-// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
-//
-// 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.
-//
-//------------------------------------------------------------------------------
-
-
-
-/*
-
-This is the stack constructed by the exception handler (low address to high address)
- # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
- Reg Offset
- === ======
- R0 0x00 # stmfd SP!,{R0-R12}
- R1 0x04
- R2 0x08
- R3 0x0c
- R4 0x10
- R5 0x14
- R6 0x18
- R7 0x1c
- R8 0x20
- R9 0x24
- R10 0x28
- R11 0x2c
- R12 0x30
- SP 0x34 # reserved via adding 0x20 (32) to the SP
- LR 0x38
- PC 0x3c
- CPSR 0x40
- DFSR 0x44
- DFAR 0x48
- IFSR 0x4c
- IFAR 0x50
-
- LR 0x54 # SVC Link register (we need to restore it)
-
- LR 0x58 # pushed by srsfd
- CPSR 0x5c
-
- */
-
-
- EXPORT ExceptionHandlersStart
- EXPORT ExceptionHandlersEnd
- EXPORT CommonExceptionEntry
- EXPORT AsmCommonExceptionEntry
- IMPORT GdbExceptionHandler
-
- PRESERVE8
- AREA DxeExceptionHandlers, CODE, READONLY
-
-//
-// This code gets copied to the ARM vector table
-// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
-//
-ExceptionHandlersStart
-
-Reset
- b Reset
-
-UndefinedInstruction
- b UndefinedInstructionEntry
-
-SoftwareInterrupt
- b SoftwareInterruptEntry
-
-PrefetchAbort
- b PrefetchAbortEntry
-
-DataAbort
- b DataAbortEntry
-
-ReservedException
- b ReservedExceptionEntry
-
-Irq
- b Irq
-
-Fiq
- b FiqEntry
-
-
-UndefinedInstructionEntry
- sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
- srsfd #0x13! ; Store return state on SVC stack
- cpsid f, #0x13 ; Switch to SVC for common stack
- stmfd SP!,{LR} ; Store the link register for the current mode
- sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} ; Store the register state
-
- mov R0,#1 ; ExceptionType
- ldr R1,CommonExceptionEntry;
- bx R1
-
-SoftwareInterruptEntry
- sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
- srsfd #0x13! ; Store return state on SVC stack
- cpsid f ; We are already in SVC mode
- stmfd SP!,{LR} ; Store the link register for the current mode
- sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} ; Store the register state
-
- mov R0,#2 ; ExceptionType
- ldr R1,CommonExceptionEntry
- bx R1
-
-PrefetchAbortEntry
- sub LR,LR,#4
- srsfd #0x13! ; Store return state on SVC stack
- cpsid f, #0x13 ; Switch to SVC for common stack
- stmfd SP!,{LR} ; Store the link register for the current mode
- sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} ; Store the register state
-
- mov R0,#3 ; ExceptionType
- ldr R1,CommonExceptionEntry
- bx R1
-
-DataAbortEntry
- sub LR,LR,#8
- srsfd #0x13! ; Store return state on SVC stack
- cpsid f, #0x13 ; Switch to SVC for common stack
- stmfd SP!,{LR} ; Store the link register for the current mode
- sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} ; Store the register state
-
- mov R0,#4 ; ExceptionType
- ldr R1,CommonExceptionEntry
- bx R1
-
-ReservedExceptionEntry
- srsfd #0x13! ; Store return state on SVC stack
- cpsid f, #0x13 ; Switch to SVC for common stack
- stmfd SP!,{LR} ; Store the link register for the current mode
- sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} ; Store the register state
-
- mov R0,#5 ; ExceptionType
- ldr R1,CommonExceptionEntry
- bx R1
-
-FiqEntry
- sub LR,LR,#4
- srsfd #0x13! ; Store return state on SVC stack
- cps #0x13 ; Switch to SVC for common stack
- stmfd SP!,{LR} ; Store the link register for the current mode
- sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
- stmfd SP!,{R0-R12} ; Store the register state
- ; Since we have already switch to SVC R8_fiq - R12_fiq
- ; never get used or saved
- mov R0,#7 ; ExceptionType
- ldr R1,CommonExceptionEntry
- bx R1
-
-//
-// This gets patched by the C code that patches in the vector table
-//
-CommonExceptionEntry
- dcd 0x12345678
-
-ExceptionHandlersEnd
-
-//
-// This code runs from CpuDxe driver loaded address. It is patched into
-// CommonExceptionEntry.
-//
-AsmCommonExceptionEntry
- mrc p15, 0, R1, c6, c0, 2 ; Read IFAR
- str R1, [SP, #0x50] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
-
- mrc p15, 0, R1, c5, c0, 1 ; Read IFSR
- str R1, [SP, #0x4c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
-
- mrc p15, 0, R1, c6, c0, 0 ; Read DFAR
- str R1, [SP, #0x48] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
-
- mrc p15, 0, R1, c5, c0, 0 ; Read DFSR
- str R1, [SP, #0x44] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
-
- ldr R1, [SP, #0x5c] ; srsfd saved pre-exception CPSR on the stack
- str R1, [SP, #0x40] ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
-
- add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
- and R3, R1, #0x1f ; Check CPSR to see if User or System Mode
- cmp R3, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1df))
- cmpne R3, #0x10 ;
- stmeqed R2, {lr}^ ; save unbanked lr
- ; else
- stmneed R2, {lr} ; save SVC lr
-
-
- ldr R5, [SP, #0x58] ; PC is the LR pushed by srsfd
- ; Check to see if we have to adjust for Thumb entry
- sub r4, r0, #1 ; if (ExceptionType == 1 || ExceptionType ==2)) {
- cmp r4, #1 ; // UND & SVC have differnt LR adjust for Thumb
- bhi NoAdjustNeeded
-
- tst r1, #0x20 ; if ((CPSR & T)) == T) { // Thumb Mode on entry
- addne R5, R5, #2 ; PC += 2;
- str R5,[SP,#0x58] ; Update LR value pused by srsfd
-
-NoAdjustNeeded
-
- str R5, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
-
- sub R1, SP, #0x60 ; We pused 0x60 bytes on the stack
- str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
-
- ; R0 is ExceptionType
- mov R1,SP ; R1 is SystemContext
-
-/*
-VOID
-EFIAPI
-GdbExceptionHandler (
- IN EFI_EXCEPTION_TYPE ExceptionType, R0
- IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
- )
-
-*/
- blx GdbExceptionHandler ; Call exception handler
-
- ldr R1,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC
- str R1,[SP,#0x58] ; Store it back to srsfd stack slot so it can be restored
-
- ldr R1,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR
- str R1,[SP,#0x5c] ; Store it back to srsfd stack slot so it can be restored
-
- add R3, SP, #0x54 ; Make R3 point to SVC LR saved on entry
- add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
- and R1, R1, #0x1f ; Check to see if User or System Mode
- cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f))
- cmpne R1, #0x10 ;
- ldmeqed R2, {lr}^ ; restore unbanked lr
- ; else
- ldmneed R3, {lr} ; restore SVC lr, via ldmfd SP!, {LR}
-
- ldmfd SP!,{R0-R12} ; Restore general purpose registers
- ; Exception handler can not change SP
-
- add SP,SP,#0x20 ; Clear out the remaining stack space
- ldmfd SP!,{LR} ; restore the link register for this context
- rfefd SP! ; return from exception via srsfd stack slot
-
- END
-
-
+//------------------------------------------------------------------------------
+//
+// Use ARMv6 instruction to operate on a single stack
+//
+// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+//
+// 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.
+//
+//------------------------------------------------------------------------------
+
+
+
+/*
+
+This is the stack constructed by the exception handler (low address to high address)
+ # R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
+ Reg Offset
+ === ======
+ R0 0x00 # stmfd SP!,{R0-R12}
+ R1 0x04
+ R2 0x08
+ R3 0x0c
+ R4 0x10
+ R5 0x14
+ R6 0x18
+ R7 0x1c
+ R8 0x20
+ R9 0x24
+ R10 0x28
+ R11 0x2c
+ R12 0x30
+ SP 0x34 # reserved via adding 0x20 (32) to the SP
+ LR 0x38
+ PC 0x3c
+ CPSR 0x40
+ DFSR 0x44
+ DFAR 0x48
+ IFSR 0x4c
+ IFAR 0x50
+
+ LR 0x54 # SVC Link register (we need to restore it)
+
+ LR 0x58 # pushed by srsfd
+ CPSR 0x5c
+
+ */
+
+
+ EXPORT ExceptionHandlersStart
+ EXPORT ExceptionHandlersEnd
+ EXPORT CommonExceptionEntry
+ EXPORT AsmCommonExceptionEntry
+ IMPORT GdbExceptionHandler
+
+ PRESERVE8
+ AREA DxeExceptionHandlers, CODE, READONLY
+
+//
+// This code gets copied to the ARM vector table
+// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
+//
+ExceptionHandlersStart
+
+Reset
+ b Reset
+
+UndefinedInstruction
+ b UndefinedInstructionEntry
+
+SoftwareInterrupt
+ b SoftwareInterruptEntry
+
+PrefetchAbort
+ b PrefetchAbortEntry
+
+DataAbort
+ b DataAbortEntry
+
+ReservedException
+ b ReservedExceptionEntry
+
+Irq
+ b Irq
+
+Fiq
+ b FiqEntry
+
+
+UndefinedInstructionEntry
+ sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ cpsid f, #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#1 ; ExceptionType
+ ldr R1,CommonExceptionEntry;
+ bx R1
+
+SoftwareInterruptEntry
+ sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ cpsid f ; We are already in SVC mode
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#2 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+PrefetchAbortEntry
+ sub LR,LR,#4
+ srsfd #0x13! ; Store return state on SVC stack
+ cpsid f, #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#3 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+DataAbortEntry
+ sub LR,LR,#8
+ srsfd #0x13! ; Store return state on SVC stack
+ cpsid f, #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#4 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+ReservedExceptionEntry
+ srsfd #0x13! ; Store return state on SVC stack
+ cpsid f, #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+
+ mov R0,#5 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+FiqEntry
+ sub LR,LR,#4
+ srsfd #0x13! ; Store return state on SVC stack
+ cps #0x13 ; Switch to SVC for common stack
+ stmfd SP!,{LR} ; Store the link register for the current mode
+ sub SP,SP,#0x20 ; Save space for SP, LR, PC, IFAR - CPSR
+ stmfd SP!,{R0-R12} ; Store the register state
+ ; Since we have already switch to SVC R8_fiq - R12_fiq
+ ; never get used or saved
+ mov R0,#7 ; ExceptionType
+ ldr R1,CommonExceptionEntry
+ bx R1
+
+//
+// This gets patched by the C code that patches in the vector table
+//
+CommonExceptionEntry
+ dcd 0x12345678
+
+ExceptionHandlersEnd
+
+//
+// This code runs from CpuDxe driver loaded address. It is patched into
+// CommonExceptionEntry.
+//
+AsmCommonExceptionEntry
+ mrc p15, 0, R1, c6, c0, 2 ; Read IFAR
+ str R1, [SP, #0x50] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
+
+ mrc p15, 0, R1, c5, c0, 1 ; Read IFSR
+ str R1, [SP, #0x4c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
+
+ mrc p15, 0, R1, c6, c0, 0 ; Read DFAR
+ str R1, [SP, #0x48] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
+
+ mrc p15, 0, R1, c5, c0, 0 ; Read DFSR
+ str R1, [SP, #0x44] ; Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
+
+ ldr R1, [SP, #0x5c] ; srsfd saved pre-exception CPSR on the stack
+ str R1, [SP, #0x40] ; Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
+
+ add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R3, R1, #0x1f ; Check CPSR to see if User or System Mode
+ cmp R3, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1df))
+ cmpne R3, #0x10 ;
+ stmeqed R2, {lr}^ ; save unbanked lr
+ ; else
+ stmneed R2, {lr} ; save SVC lr
+
+
+ ldr R5, [SP, #0x58] ; PC is the LR pushed by srsfd
+ ; Check to see if we have to adjust for Thumb entry
+ sub r4, r0, #1 ; if (ExceptionType == 1 || ExceptionType ==2)) {
+ cmp r4, #1 ; // UND & SVC have differnt LR adjust for Thumb
+ bhi NoAdjustNeeded
+
+ tst r1, #0x20 ; if ((CPSR & T)) == T) { // Thumb Mode on entry
+ addne R5, R5, #2 ; PC += 2;
+ str R5,[SP,#0x58] ; Update LR value pused by srsfd
+
+NoAdjustNeeded
+
+ str R5, [SP, #0x3c] ; Store it in EFI_SYSTEM_CONTEXT_ARM.PC
+
+ sub R1, SP, #0x60 ; We pused 0x60 bytes on the stack
+ str R1, [SP, #0x34] ; Store it in EFI_SYSTEM_CONTEXT_ARM.SP
+
+ ; R0 is ExceptionType
+ mov R1,SP ; R1 is SystemContext
+
+/*
+VOID
+EFIAPI
+GdbExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType, R0
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
+ )
+
+*/
+ blx GdbExceptionHandler ; Call exception handler
+
+ ldr R1,[SP,#0x3c] ; EFI_SYSTEM_CONTEXT_ARM.PC
+ str R1,[SP,#0x58] ; Store it back to srsfd stack slot so it can be restored
+
+ ldr R1,[SP,#0x40] ; EFI_SYSTEM_CONTEXT_ARM.CPSR
+ str R1,[SP,#0x5c] ; Store it back to srsfd stack slot so it can be restored
+
+ add R3, SP, #0x54 ; Make R3 point to SVC LR saved on entry
+ add R2, SP, #0x38 ; Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
+ and R1, R1, #0x1f ; Check to see if User or System Mode
+ cmp R1, #0x1f ; if ((CPSR == 0x10) || (CPSR == 0x1f))
+ cmpne R1, #0x10 ;
+ ldmeqed R2, {lr}^ ; restore unbanked lr
+ ; else
+ ldmneed R3, {lr} ; restore SVC lr, via ldmfd SP!, {LR}
+
+ ldmfd SP!,{R0-R12} ; Restore general purpose registers
+ ; Exception handler can not change SP
+
+ add SP,SP,#0x20 ; Clear out the remaining stack space
+ ldmfd SP!,{LR} ; restore the link register for this context
+ rfefd SP! ; return from exception via srsfd stack slot
+
+ END
+
+
diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c b/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c
index e6aabf940a..f22a19dded 100755
--- a/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c
+++ b/EmbeddedPkg/Library/GdbDebugAgent/Arm/Processor.c
@@ -447,23 +447,23 @@ RemoveBreakPoint (
}
-/**
- Send the T signal with the given exception type (in gdb order) and possibly
- with n:r pairs related to the watchpoints
-
- @param SystemContext Register content at time of the exception
- @param GdbExceptionType GDB exception type
- **/
-VOID
-ProcessorSendTSignal (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINT8 GdbExceptionType,
- IN OUT CHAR8 *TSignalPtr,
- IN UINTN SizeOfBuffer
- )
-{
- *TSignalPtr = '\0';
-}
+/**
+ Send the T signal with the given exception type (in gdb order) and possibly
+ with n:r pairs related to the watchpoints
+
+ @param SystemContext Register content at time of the exception
+ @param GdbExceptionType GDB exception type
+ **/
+VOID
+ProcessorSendTSignal (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINT8 GdbExceptionType,
+ IN OUT CHAR8 *TSignalPtr,
+ IN UINTN SizeOfBuffer
+ )
+{
+ *TSignalPtr = '\0';
+}
/**
FIQ state is only changed by FIQ exception. We don't want to take FIQ
@@ -475,21 +475,21 @@ ProcessorSendTSignal (
@return TRUE We are in the GDB stub exception preamble
@return FALSE We are not in GDB stub code
- **/
-BOOLEAN
-InFiqCrack (
- IN UINT32 PC
- )
-{
- UINT32 VectorBase = PcdGet32 (PcdCpuVectorBaseAddress);
- UINT32 Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;
-
- if ((PC >= VectorBase) && (PC <= (VectorBase + Length))) {
- return TRUE;
- }
-
- return FALSE;
-}
+ **/
+BOOLEAN
+InFiqCrack (
+ IN UINT32 PC
+ )
+{
+ UINT32 VectorBase = PcdGet32 (PcdCpuVectorBaseAddress);
+ UINT32 Length = (UINTN)ExceptionHandlersEnd - (UINTN)ExceptionHandlersStart;
+
+ if ((PC >= VectorBase) && (PC <= (VectorBase + Length))) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
/**
@@ -526,24 +526,24 @@ ProcessorControlC (
return FALSE;
}
- while (TRUE) {
- if (!GdbIsCharAvailable ()) {
- //
- // No characters are pending so exit the loop
- //
- Return = TRUE;
- break;
- }
-
- Char = GdbGetChar ();
- if (Char == 0x03) {
- //
- // We have a ctrl-c so exit and process exception for ctrl-c
- //
- Return = FALSE;
- break;
- }
- }
+ while (TRUE) {
+ if (!GdbIsCharAvailable ()) {
+ //
+ // No characters are pending so exit the loop
+ //
+ Return = TRUE;
+ break;
+ }
+
+ Char = GdbGetChar ();
+ if (Char == 0x03) {
+ //
+ // We have a ctrl-c so exit and process exception for ctrl-c
+ //
+ Return = FALSE;
+ break;
+ }
+ }
DebugAgentTimerEndOfInterrupt ();
@@ -622,13 +622,13 @@ InitializeDebugAgent (
IN VOID *Context, OPTIONAL
IN DEBUG_AGENT_CONTINUE Function OPTIONAL
)
-{
+{
UINTN Offset;
UINTN Length;
BOOLEAN IrqEnabled;
UINT32 *VectorBase;
-
+
//
// Disable interrupts
//
diff --git a/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h b/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h
index 2d0570e3dc..44c82f3472 100755
--- a/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h
+++ b/EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.h
@@ -1,697 +1,697 @@
-/** @file
- Private include file for GDB stub
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 __GCC_DEBUG_AGENT_INTERNAL__
-#define __GCC_DEBUG_AGENT_INTERNAL__
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/PcdLib.h>
-#include <Library/GdbSerialLib.h>
-#include <Library/PrintLib.h>
-#include <Library/CacheMaintenanceLib.h>
-#include <Library/DebugAgentTimerLib.h>
+/** @file
+ Private include file for GDB stub
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 __GCC_DEBUG_AGENT_INTERNAL__
+#define __GCC_DEBUG_AGENT_INTERNAL__
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/GdbSerialLib.h>
+#include <Library/PrintLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugAgentTimerLib.h>
#include <Library/DebugAgentLib.h>
-
-#include <IndustryStandard/PeImage.h>
-#include <Protocol/DebugSupport.h>
-
-extern CONST CHAR8 mHexToStr[];
-
-// maximum size of input and output buffers
-// This value came from the show remote command of the gdb we tested against
-#define MAX_BUF_SIZE 2000
-
-// maximum size of address buffer
-#define MAX_ADDR_SIZE 32
-
-// maximum size of register number buffer
-#define MAX_REG_NUM_BUF_SIZE 32
-
-// maximum size of length buffer
-#define MAX_LENGTH_SIZE 32
-
-// maximum size of T signal members
-#define MAX_T_SIGNAL_SIZE 64
-
-// the mask used to clear all the cache
-#define TF_BIT 0x00000100
-
-
-//
-// GDB Signal definitions - generic names for interrupts
-//
-#define GDB_SIGINT 2 // Interrupt process via ctrl-c
-#define GDB_SIGILL 4 // Illegal instruction
-#define GDB_SIGTRAP 5 // Trace Trap (Breakpoint and SingleStep)
-#define GDB_SIGEMT 7 // Emulator Trap
-#define GDB_SIGFPE 8 // Floating point exception
-#define GDB_SIGSEGV 11 // Setgment violation, page fault
-
-
-//
-// GDB File I/O Error values, zero means no error
-// Includes all general GDB Unix like error values
-//
-#define GDB_EBADMEMADDRBUFSIZE 11 // the buffer that stores memory Address to be read from/written to is not the right size
-#define GDB_EBADMEMLENGBUFSIZE 12 // the buffer that stores Length is not the right size
-#define GDB_EBADMEMLENGTH 13 // Length, the given number of bytes to read or write, is not the right size
-#define GDB_EBADMEMDATA 14 // one of the bytes or nibbles of the memory is leess than 0
-#define GDB_EBADMEMDATASIZE 15 // the memory data, 'XX..', is too short or too long
-#define GDB_EBADBUFSIZE 21 // the buffer created is not the correct size
-#define GDB_EINVALIDARG 31 // argument is invalid
-#define GDB_ENOSPACE 41 //
-#define GDB_EINVALIDBRKPOINTTYPE 51 // the breakpoint type is not recognized
-#define GDB_EINVALIDREGNUM 61 // given register number is not valid: either <0 or >=Number of Registers
-#define GDB_EUNKNOWN 255 // unknown
-
-
-//
-// These devices are open by GDB so we can just read and write to them
-//
-#define GDB_STDIN 0x00
-#define GDB_STDOUT 0x01
-#define GDB_STDERR 0x02
-
-//
-//Define Register size for different architectures
-//
-#if defined (MDE_CPU_IA32)
-#define REG_SIZE 32
-#elif defined (MDE_CPU_X64)
-#define REG_SIZE 64
-#elif defined (MDE_CPU_ARM)
-#define REG_SIZE 32
-#endif
-
-
-typedef struct {
- EFI_EXCEPTION_TYPE Exception;
- UINT8 SignalNo;
-} EFI_EXCEPTION_TYPE_ENTRY;
-
-
-#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
-
-//
-// Byte packed structure for DR6
-// 32-bits on IA-32
-// 64-bits on X64. The upper 32-bits on X64 are reserved
-//
-typedef union {
- struct {
- UINT32 B0:1; // Breakpoint condition detected
- UINT32 B1:1; // Breakpoint condition detected
- UINT32 B2:1; // Breakpoint condition detected
- UINT32 B3:1; // Breakpoint condition detected
- UINT32 Reserved_1:9; // Reserved
- UINT32 BD:1; // Debug register access detected
- UINT32 BS:1; // Single step
- UINT32 BT:1; // Task switch
- UINT32 Reserved_2:16; // Reserved
- } Bits;
- UINTN UintN;
-} IA32_DR6;
-
-//
-// Byte packed structure for DR7
-// 32-bits on IA-32
-// 64-bits on X64. The upper 32-bits on X64 are reserved
-//
-typedef union {
- struct {
- UINT32 L0:1; // Local breakpoint enable
- UINT32 G0:1; // Global breakpoint enable
- UINT32 L1:1; // Local breakpoint enable
- UINT32 G1:1; // Global breakpoint enable
- UINT32 L2:1; // Local breakpoint enable
- UINT32 G2:1; // Global breakpoint enable
- UINT32 L3:1; // Local breakpoint enable
- UINT32 G3:1; // Global breakpoint enable
- UINT32 LE:1; // Local exact breakpoint enable
- UINT32 GE:1; // Global exact breakpoint enable
- UINT32 Reserved_1:3; // Reserved
- UINT32 GD:1; // Global detect enable
- UINT32 Reserved_2:2; // Reserved
- UINT32 RW0:2; // Read/Write field
- UINT32 LEN0:2; // Length field
- UINT32 RW1:2; // Read/Write field
- UINT32 LEN1:2; // Length field
- UINT32 RW2:2; // Read/Write field
- UINT32 LEN2:2; // Length field
- UINT32 RW3:2; // Read/Write field
- UINT32 LEN3:2; // Length field
- } Bits;
- UINTN UintN;
-} IA32_DR7;
-
-#endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */
-
-typedef enum {
- InstructionExecution, //Hardware breakpoint
- DataWrite, //watch
- DataRead, //rwatch
- DataReadWrite, //awatch
- SoftwareBreakpoint, //Software breakpoint
- NotSupported
-} BREAK_TYPE;
-
-//
-// Array of exception types that need to be hooked by the debugger
-//
-extern EFI_EXCEPTION_TYPE_ENTRY gExceptionType[];
-
-//
-// If the periodic callback is called while we are processing an F packet we need
-// to let the callback know to not read from the serail stream as it could steal
-// characters from the F reponse packet
-//
-extern BOOLEAN gProcessingFPacket;
-
-
-/**
- Return the number of entries in the gExceptionType[]
-
- @retval UINTN, the number of entries in the gExceptionType[] array.
- **/
-UINTN
-MaxEfiException (
- VOID
- );
-
-
-/**
- Check to see if the ISA is supported.
- ISA = Instruction Set Architecture
-
- @retval TRUE if Isa is supported,
- FALSE otherwise.
- **/
-BOOLEAN
-CheckIsa (
- IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
- );
-
-
-/**
- Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
-
- @param SystemContext Register content at time of the exception
- @param GdbExceptionType GDB exception type
- **/
-
-VOID
-GdbSendTSignal (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINT8 GdbExceptionType
- );
-
-
-/**
- Translates the EFI mapping to GDB mapping
-
- @param EFIExceptionType EFI Exception that is being processed
- @retval UINTN that corresponds to EFIExceptionType's GDB exception type number
- **/
-UINT8
-ConvertEFItoGDBtype (
- IN EFI_EXCEPTION_TYPE EFIExceptionType
- );
-
-
-/**
- Empties the given buffer
- @param *Buf pointer to the first element in buffer to be emptied
- **/
-VOID
-EmptyBuffer (
- IN CHAR8 *Buf
- );
-
-
-/**
- Converts an 8-bit Hex Char into a INTN.
-
- @param Char - the hex character to be converted into UINTN
- @retval a INTN, from 0 to 15, that corressponds to Char
- -1 if Char is not a hex character
- **/
-INTN
-HexCharToInt (
- IN CHAR8 Char
- );
-
-
-/** 'E NN'
- Send an error with the given error number after converting to hex.
- The error number is put into the buffer in hex. '255' is the biggest errno we can send.
- ex: 162 will be sent as A2.
-
- @param errno the error number that will be sent
- **/
-VOID
-EFIAPI
-SendError (
- IN UINT8 ErrorNum
- );
-
-
-/**
- Send 'OK' when the function is done executing successfully.
- **/
-VOID
-SendSuccess (
- VOID
- );
-
-
-/**
- Send empty packet to specify that particular command/functionality is not supported.
- **/
-VOID
-SendNotSupported (
- VOID
- );
-
-/** ‘p n’
- Reads the n-th register's value into an output buffer and sends it as a packet
- @param SystemContext Register content at time of the exception
- @param InBuffer This is the input buffer received from gdb server
- **/
-VOID
-ReadNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘g’
- Reads the general registers into an output buffer and sends it as a packet
- @param SystemContext Register content at time of the exception
- **/
-VOID
-ReadGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/** ‘P n...=r...’
- Writes the new value of n-th register received into the input buffer to the n-th register
- @param SystemContext Register content at time of the exception
- @param InBuffer This is the input buffer received from gdb server
- **/
-VOID
-WriteNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘G XX...’
- Writes the new values received into the input buffer to the general registers
- @param SystemContext Register content at time of the exception
- @param InBuffer Pointer to the input buffer received from gdb server
- **/
-
-VOID
-WriteGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- );
-
-
-/** ‘m addr,length ’
- Find the Length of the area to read and the start addres. Finally, pass them to
- another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
- send it as a packet.
-
- @param *PacketData Pointer to Payload data for the packet
- **/
-VOID
-ReadFromMemory (
- IN CHAR8 *PacketData
- );
-
-
-/** ‘M addr,length :XX...’
- Find the Length of the area in bytes to write and the start addres. Finally, pass them to
- another function, TransferFromInBufToMem, that will write to that memory space the info in
- the input buffer.
-
- @param PacketData Pointer to Payload data for the packet
- **/
-VOID
-WriteToMemory (
- IN CHAR8 *PacketData
- );
-
-
-/** ‘c [addr ]’
- Continue. addr is Address to resume. If addr is omitted, resume at current
- Address.
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to PacketData
- **/
-
-VOID
-ContinueAtAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/** ‘s [addr ]’
- Single step. addr is the Address at which to resume. If addr is omitted, resume
- at same Address.
-
- @param SystemContext Register content at time of the exception
- @param PacketData Pointer to Payload data for the packet
- **/
-VOID
-SingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-/**
- Insert Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-AddSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-/**
- Remove Single Step in the SystemContext
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-RemoveSingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- ‘Z1, [addr], [length]’
- ‘Z2, [addr], [length]’
- ‘Z3, [addr], [length]’
- ‘Z4, [addr], [length]’
-
- Insert hardware breakpoint/watchpoint at address addr of size length
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-InsertBreakPoint(
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/**
- ‘z1, [addr], [length]’
- ‘z2, [addr], [length]’
- ‘z3, [addr], [length]’
- ‘z4, [addr], [length]’
-
- Remove hardware breakpoint/watchpoint at address addr of size length
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-RemoveBreakPoint(
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- );
-
-
-/**
- Exception Hanldler for GDB. It will be called for all exceptions
- registered via the gExceptionType[] array.
-
- @param ExceptionType Exception that is being processed
- @param SystemContext Register content at time of the exception
-
- **/
-VOID
-EFIAPI
-GdbExceptionHandler (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- Periodic callback for GDB. This function is used to catch a ctrl-c or other
- break in type command from GDB.
-
- @param SystemContext Register content at time of the call
-
- **/
-VOID
-EFIAPI
-GdbPeriodicCallBack (
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
-/**
- Make two serail consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
-
- These console show up on the remote system running GDB
-
-**/
-
-VOID
-GdbInitializeSerialConsole (
- VOID
- );
-
-
-/**
- Send a GDB Remote Serial Protocol Packet
-
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
- the packet teminating character '#' and the two digit checksum.
-
- If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
- in an infinit loop. This is so if you unplug the debugger code just keeps running
-
- @param PacketData Payload data for the packet
-
- @retval Number of bytes of packet data sent.
-
-**/
-UINTN
-SendPacket (
- IN CHAR8 *PacketData
- );
-
-
-/**
- Receive a GDB Remote Serial Protocol Packet
-
- $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
- the packet teminating character '#' and the two digit checksum.
-
- If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
- (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
-
- If an ack '+' is not sent resend the packet
-
- @param PacketData Payload data for the packet
-
- @retval Number of bytes of packet data received.
-
- **/
-UINTN
-ReceivePacket (
- OUT CHAR8 *PacketData,
- IN UINTN PacketDataSize
- );
-
-
-/**
- Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
- the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
-
- @param FileDescriptor Device to talk to.
- @param Buffer Buffer to hold Count bytes that were read
- @param Count Number of bytes to transfer.
-
- @retval -1 Error
- @retval {other} Number of bytes read.
-
-**/
-INTN
-GdbRead (
- IN INTN FileDescriptor,
- OUT VOID *Buffer,
- IN UINTN Count
- );
-
-
-/**
- Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
- nothing was written. On error -1 is returned.
-
- @param FileDescriptor Device to talk to.
- @param Buffer Buffer to hold Count bytes that are to be written
- @param Count Number of bytes to transfer.
-
- @retval -1 Error
- @retval {other} Number of bytes written.
-
-**/
-INTN
-GdbWrite (
- IN INTN FileDescriptor,
- OUT CONST VOID *Buffer,
- IN UINTN Count
- );
-
-UINTN *
-FindPointerToRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber
- );
-
-CHAR8 *
-BasicReadRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *OutBufPtr
- );
-
-VOID
-TransferFromInBufToMem (
- IN UINTN Length,
- IN UINT8 *Address,
- IN CHAR8 *NewData
- );
-
-VOID
-TransferFromMemToOutBufAndSend (
- IN UINTN Length,
- IN UINT8 *Address
- );
-
-CHAR8 *
-BasicWriteRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *InBufPtr
- );
-
-VOID
-PrintReg (
- EFI_SYSTEM_CONTEXT SystemContext
- );
-
-UINTN
-ParseBreakpointPacket (
- IN CHAR8 *PacketData,
- OUT UINTN *Type,
- OUT UINTN *Address,
- OUT UINTN *Length
- );
-
-UINTN
-GetBreakpointDataAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- );
-
-UINTN
-GetBreakpointDetected (
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-BREAK_TYPE
-GetBreakpointType (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- );
-
-UINTN
-ConvertLengthData (
- IN UINTN Length
- );
-
-EFI_STATUS
-FindNextFreeDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- OUT UINTN *Register
- );
-
-EFI_STATUS
-EnableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type
- );
-
-EFI_STATUS
-FindMatchingDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type,
- OUT UINTN *Register
- );
-
-EFI_STATUS
-DisableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register
- );
-
-VOID
-InitializeProcessor (
- VOID
- );
-
-/**
- Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
-
- @param SystemContext Register content at time of the exception
- @param GdbExceptionType GDB exception type
- **/
-VOID
-ProcessorSendTSignal (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINT8 GdbExceptionType,
- IN OUT CHAR8 *TSignalPtr,
- IN UINTN SizeOfBuffer
- );
-
+
+#include <IndustryStandard/PeImage.h>
+#include <Protocol/DebugSupport.h>
+
+extern CONST CHAR8 mHexToStr[];
+
+// maximum size of input and output buffers
+// This value came from the show remote command of the gdb we tested against
+#define MAX_BUF_SIZE 2000
+
+// maximum size of address buffer
+#define MAX_ADDR_SIZE 32
+
+// maximum size of register number buffer
+#define MAX_REG_NUM_BUF_SIZE 32
+
+// maximum size of length buffer
+#define MAX_LENGTH_SIZE 32
+
+// maximum size of T signal members
+#define MAX_T_SIGNAL_SIZE 64
+
+// the mask used to clear all the cache
+#define TF_BIT 0x00000100
+
+
+//
+// GDB Signal definitions - generic names for interrupts
+//
+#define GDB_SIGINT 2 // Interrupt process via ctrl-c
+#define GDB_SIGILL 4 // Illegal instruction
+#define GDB_SIGTRAP 5 // Trace Trap (Breakpoint and SingleStep)
+#define GDB_SIGEMT 7 // Emulator Trap
+#define GDB_SIGFPE 8 // Floating point exception
+#define GDB_SIGSEGV 11 // Setgment violation, page fault
+
+
+//
+// GDB File I/O Error values, zero means no error
+// Includes all general GDB Unix like error values
+//
+#define GDB_EBADMEMADDRBUFSIZE 11 // the buffer that stores memory Address to be read from/written to is not the right size
+#define GDB_EBADMEMLENGBUFSIZE 12 // the buffer that stores Length is not the right size
+#define GDB_EBADMEMLENGTH 13 // Length, the given number of bytes to read or write, is not the right size
+#define GDB_EBADMEMDATA 14 // one of the bytes or nibbles of the memory is leess than 0
+#define GDB_EBADMEMDATASIZE 15 // the memory data, 'XX..', is too short or too long
+#define GDB_EBADBUFSIZE 21 // the buffer created is not the correct size
+#define GDB_EINVALIDARG 31 // argument is invalid
+#define GDB_ENOSPACE 41 //
+#define GDB_EINVALIDBRKPOINTTYPE 51 // the breakpoint type is not recognized
+#define GDB_EINVALIDREGNUM 61 // given register number is not valid: either <0 or >=Number of Registers
+#define GDB_EUNKNOWN 255 // unknown
+
+
+//
+// These devices are open by GDB so we can just read and write to them
+//
+#define GDB_STDIN 0x00
+#define GDB_STDOUT 0x01
+#define GDB_STDERR 0x02
+
+//
+//Define Register size for different architectures
+//
+#if defined (MDE_CPU_IA32)
+#define REG_SIZE 32
+#elif defined (MDE_CPU_X64)
+#define REG_SIZE 64
+#elif defined (MDE_CPU_ARM)
+#define REG_SIZE 32
+#endif
+
+
+typedef struct {
+ EFI_EXCEPTION_TYPE Exception;
+ UINT8 SignalNo;
+} EFI_EXCEPTION_TYPE_ENTRY;
+
+
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+
+//
+// Byte packed structure for DR6
+// 32-bits on IA-32
+// 64-bits on X64. The upper 32-bits on X64 are reserved
+//
+typedef union {
+ struct {
+ UINT32 B0:1; // Breakpoint condition detected
+ UINT32 B1:1; // Breakpoint condition detected
+ UINT32 B2:1; // Breakpoint condition detected
+ UINT32 B3:1; // Breakpoint condition detected
+ UINT32 Reserved_1:9; // Reserved
+ UINT32 BD:1; // Debug register access detected
+ UINT32 BS:1; // Single step
+ UINT32 BT:1; // Task switch
+ UINT32 Reserved_2:16; // Reserved
+ } Bits;
+ UINTN UintN;
+} IA32_DR6;
+
+//
+// Byte packed structure for DR7
+// 32-bits on IA-32
+// 64-bits on X64. The upper 32-bits on X64 are reserved
+//
+typedef union {
+ struct {
+ UINT32 L0:1; // Local breakpoint enable
+ UINT32 G0:1; // Global breakpoint enable
+ UINT32 L1:1; // Local breakpoint enable
+ UINT32 G1:1; // Global breakpoint enable
+ UINT32 L2:1; // Local breakpoint enable
+ UINT32 G2:1; // Global breakpoint enable
+ UINT32 L3:1; // Local breakpoint enable
+ UINT32 G3:1; // Global breakpoint enable
+ UINT32 LE:1; // Local exact breakpoint enable
+ UINT32 GE:1; // Global exact breakpoint enable
+ UINT32 Reserved_1:3; // Reserved
+ UINT32 GD:1; // Global detect enable
+ UINT32 Reserved_2:2; // Reserved
+ UINT32 RW0:2; // Read/Write field
+ UINT32 LEN0:2; // Length field
+ UINT32 RW1:2; // Read/Write field
+ UINT32 LEN1:2; // Length field
+ UINT32 RW2:2; // Read/Write field
+ UINT32 LEN2:2; // Length field
+ UINT32 RW3:2; // Read/Write field
+ UINT32 LEN3:2; // Length field
+ } Bits;
+ UINTN UintN;
+} IA32_DR7;
+
+#endif /* if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) */
+
+typedef enum {
+ InstructionExecution, //Hardware breakpoint
+ DataWrite, //watch
+ DataRead, //rwatch
+ DataReadWrite, //awatch
+ SoftwareBreakpoint, //Software breakpoint
+ NotSupported
+} BREAK_TYPE;
+
+//
+// Array of exception types that need to be hooked by the debugger
+//
+extern EFI_EXCEPTION_TYPE_ENTRY gExceptionType[];
+
+//
+// If the periodic callback is called while we are processing an F packet we need
+// to let the callback know to not read from the serail stream as it could steal
+// characters from the F reponse packet
+//
+extern BOOLEAN gProcessingFPacket;
+
+
+/**
+ Return the number of entries in the gExceptionType[]
+
+ @retval UINTN, the number of entries in the gExceptionType[] array.
+ **/
+UINTN
+MaxEfiException (
+ VOID
+ );
+
+
+/**
+ Check to see if the ISA is supported.
+ ISA = Instruction Set Architecture
+
+ @retval TRUE if Isa is supported,
+ FALSE otherwise.
+ **/
+BOOLEAN
+CheckIsa (
+ IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
+ );
+
+
+/**
+ Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
+
+ @param SystemContext Register content at time of the exception
+ @param GdbExceptionType GDB exception type
+ **/
+
+VOID
+GdbSendTSignal (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINT8 GdbExceptionType
+ );
+
+
+/**
+ Translates the EFI mapping to GDB mapping
+
+ @param EFIExceptionType EFI Exception that is being processed
+ @retval UINTN that corresponds to EFIExceptionType's GDB exception type number
+ **/
+UINT8
+ConvertEFItoGDBtype (
+ IN EFI_EXCEPTION_TYPE EFIExceptionType
+ );
+
+
+/**
+ Empties the given buffer
+ @param *Buf pointer to the first element in buffer to be emptied
+ **/
+VOID
+EmptyBuffer (
+ IN CHAR8 *Buf
+ );
+
+
+/**
+ Converts an 8-bit Hex Char into a INTN.
+
+ @param Char - the hex character to be converted into UINTN
+ @retval a INTN, from 0 to 15, that corressponds to Char
+ -1 if Char is not a hex character
+ **/
+INTN
+HexCharToInt (
+ IN CHAR8 Char
+ );
+
+
+/** 'E NN'
+ Send an error with the given error number after converting to hex.
+ The error number is put into the buffer in hex. '255' is the biggest errno we can send.
+ ex: 162 will be sent as A2.
+
+ @param errno the error number that will be sent
+ **/
+VOID
+EFIAPI
+SendError (
+ IN UINT8 ErrorNum
+ );
+
+
+/**
+ Send 'OK' when the function is done executing successfully.
+ **/
+VOID
+SendSuccess (
+ VOID
+ );
+
+
+/**
+ Send empty packet to specify that particular command/functionality is not supported.
+ **/
+VOID
+SendNotSupported (
+ VOID
+ );
+
+/** ‘p n’
+ Reads the n-th register's value into an output buffer and sends it as a packet
+ @param SystemContext Register content at time of the exception
+ @param InBuffer This is the input buffer received from gdb server
+ **/
+VOID
+ReadNthRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ );
+
+
+/** ‘g’
+ Reads the general registers into an output buffer and sends it as a packet
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+ReadGeneralRegisters (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+
+/** ‘P n...=r...’
+ Writes the new value of n-th register received into the input buffer to the n-th register
+ @param SystemContext Register content at time of the exception
+ @param InBuffer This is the input buffer received from gdb server
+ **/
+VOID
+WriteNthRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ );
+
+
+/** ‘G XX...’
+ Writes the new values received into the input buffer to the general registers
+ @param SystemContext Register content at time of the exception
+ @param InBuffer Pointer to the input buffer received from gdb server
+ **/
+
+VOID
+WriteGeneralRegisters (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ );
+
+
+/** ‘m addr,length ’
+ Find the Length of the area to read and the start addres. Finally, pass them to
+ another function, TransferFromMemToOutBufAndSend, that will read from that memory space and
+ send it as a packet.
+
+ @param *PacketData Pointer to Payload data for the packet
+ **/
+VOID
+ReadFromMemory (
+ IN CHAR8 *PacketData
+ );
+
+
+/** ‘M addr,length :XX...’
+ Find the Length of the area in bytes to write and the start addres. Finally, pass them to
+ another function, TransferFromInBufToMem, that will write to that memory space the info in
+ the input buffer.
+
+ @param PacketData Pointer to Payload data for the packet
+ **/
+VOID
+WriteToMemory (
+ IN CHAR8 *PacketData
+ );
+
+
+/** ‘c [addr ]’
+ Continue. addr is Address to resume. If addr is omitted, resume at current
+ Address.
+
+ @param SystemContext Register content at time of the exception
+ @param *PacketData Pointer to PacketData
+ **/
+
+VOID
+ContinueAtAddress (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ );
+
+
+/** ‘s [addr ]’
+ Single step. addr is the Address at which to resume. If addr is omitted, resume
+ at same Address.
+
+ @param SystemContext Register content at time of the exception
+ @param PacketData Pointer to Payload data for the packet
+ **/
+VOID
+SingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ );
+
+/**
+ Insert Single Step in the SystemContext
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+AddSingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+/**
+ Remove Single Step in the SystemContext
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+RemoveSingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+
+/**
+ ‘Z1, [addr], [length]’
+ ‘Z2, [addr], [length]’
+ ‘Z3, [addr], [length]’
+ ‘Z4, [addr], [length]’
+
+ Insert hardware breakpoint/watchpoint at address addr of size length
+
+ @param SystemContext Register content at time of the exception
+ @param *PacketData Pointer to the Payload data for the packet
+
+**/
+VOID
+EFIAPI
+InsertBreakPoint(
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ );
+
+
+/**
+ ‘z1, [addr], [length]’
+ ‘z2, [addr], [length]’
+ ‘z3, [addr], [length]’
+ ‘z4, [addr], [length]’
+
+ Remove hardware breakpoint/watchpoint at address addr of size length
+
+ @param SystemContext Register content at time of the exception
+ @param *PacketData Pointer to the Payload data for the packet
+
+**/
+VOID
+EFIAPI
+RemoveBreakPoint(
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ );
+
+
+/**
+ Exception Hanldler for GDB. It will be called for all exceptions
+ registered via the gExceptionType[] array.
+
+ @param ExceptionType Exception that is being processed
+ @param SystemContext Register content at time of the exception
+
+ **/
+VOID
+EFIAPI
+GdbExceptionHandler (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+
+/**
+ Periodic callback for GDB. This function is used to catch a ctrl-c or other
+ break in type command from GDB.
+
+ @param SystemContext Register content at time of the call
+
+ **/
+VOID
+EFIAPI
+GdbPeriodicCallBack (
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+
+/**
+ Make two serail consoles: 1) StdIn and StdOut via GDB. 2) StdErr via GDB.
+
+ These console show up on the remote system running GDB
+
+**/
+
+VOID
+GdbInitializeSerialConsole (
+ VOID
+ );
+
+
+/**
+ Send a GDB Remote Serial Protocol Packet
+
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
+ the packet teminating character '#' and the two digit checksum.
+
+ If an ack '+' is not sent resend the packet, but timeout eventually so we don't end up
+ in an infinit loop. This is so if you unplug the debugger code just keeps running
+
+ @param PacketData Payload data for the packet
+
+ @retval Number of bytes of packet data sent.
+
+**/
+UINTN
+SendPacket (
+ IN CHAR8 *PacketData
+ );
+
+
+/**
+ Receive a GDB Remote Serial Protocol Packet
+
+ $PacketData#checksum PacketData is passed in and this function adds the packet prefix '$',
+ the packet teminating character '#' and the two digit checksum.
+
+ If host re-starts sending a packet without ending the previous packet, only the last valid packet is proccessed.
+ (In other words, if received packet is '$12345$12345$123456#checksum', only '$123456#checksum' will be processed.)
+
+ If an ack '+' is not sent resend the packet
+
+ @param PacketData Payload data for the packet
+
+ @retval Number of bytes of packet data received.
+
+ **/
+UINTN
+ReceivePacket (
+ OUT CHAR8 *PacketData,
+ IN UINTN PacketDataSize
+ );
+
+
+/**
+ Read data from a FileDescriptor. On success number of bytes read is returned. Zero indicates
+ the end of a file. On error -1 is returned. If count is zero, GdbRead returns zero.
+
+ @param FileDescriptor Device to talk to.
+ @param Buffer Buffer to hold Count bytes that were read
+ @param Count Number of bytes to transfer.
+
+ @retval -1 Error
+ @retval {other} Number of bytes read.
+
+**/
+INTN
+GdbRead (
+ IN INTN FileDescriptor,
+ OUT VOID *Buffer,
+ IN UINTN Count
+ );
+
+
+/**
+ Write data to a FileDescriptor. On success number of bytes written is returned. Zero indicates
+ nothing was written. On error -1 is returned.
+
+ @param FileDescriptor Device to talk to.
+ @param Buffer Buffer to hold Count bytes that are to be written
+ @param Count Number of bytes to transfer.
+
+ @retval -1 Error
+ @retval {other} Number of bytes written.
+
+**/
+INTN
+GdbWrite (
+ IN INTN FileDescriptor,
+ OUT CONST VOID *Buffer,
+ IN UINTN Count
+ );
+
+UINTN *
+FindPointerToRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber
+ );
+
+CHAR8 *
+BasicReadRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber,
+ IN CHAR8 *OutBufPtr
+ );
+
+VOID
+TransferFromInBufToMem (
+ IN UINTN Length,
+ IN UINT8 *Address,
+ IN CHAR8 *NewData
+ );
+
+VOID
+TransferFromMemToOutBufAndSend (
+ IN UINTN Length,
+ IN UINT8 *Address
+ );
+
+CHAR8 *
+BasicWriteRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber,
+ IN CHAR8 *InBufPtr
+ );
+
+VOID
+PrintReg (
+ EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+UINTN
+ParseBreakpointPacket (
+ IN CHAR8 *PacketData,
+ OUT UINTN *Type,
+ OUT UINTN *Address,
+ OUT UINTN *Length
+ );
+
+UINTN
+GetBreakpointDataAddress (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN BreakpointNumber
+ );
+
+UINTN
+GetBreakpointDetected (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+BREAK_TYPE
+GetBreakpointType (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN BreakpointNumber
+ );
+
+UINTN
+ConvertLengthData (
+ IN UINTN Length
+ );
+
+EFI_STATUS
+FindNextFreeDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ OUT UINTN *Register
+ );
+
+EFI_STATUS
+EnableDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Register,
+ IN UINTN Address,
+ IN UINTN Length,
+ IN UINTN Type
+ );
+
+EFI_STATUS
+FindMatchingDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Address,
+ IN UINTN Length,
+ IN UINTN Type,
+ OUT UINTN *Register
+ );
+
+EFI_STATUS
+DisableDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Register
+ );
+
+VOID
+InitializeProcessor (
+ VOID
+ );
+
+/**
+ Send the T signal with the given exception type (in gdb order) and possibly with n:r pairs related to the watchpoints
+
+ @param SystemContext Register content at time of the exception
+ @param GdbExceptionType GDB exception type
+ **/
+VOID
+ProcessorSendTSignal (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINT8 GdbExceptionType,
+ IN OUT CHAR8 *TSignalPtr,
+ IN UINTN SizeOfBuffer
+ );
+
/**
Check to see if this exception is related to ctrl-c handling.
@@ -705,9 +705,9 @@ BOOLEAN
ProcessorControlC (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-
+ );
+
+
/**
Initialize debug agent.
@@ -723,6 +723,6 @@ DebugAgentHookExceptions (
IN UINT32 InitFlag,
IN VOID *Context OPTIONAL
);
-
-
-#endif
+
+
+#endif
diff --git a/EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c b/EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c
index 96a1a596f3..4e4350a0f2 100755
--- a/EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c
+++ b/EmbeddedPkg/Library/GdbDebugAgent/Ia32/Processor.c
@@ -1,917 +1,917 @@
-/** @file
- Processor specific parts of the GDB stub
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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.
-
-**/
-
+/** @file
+ Processor specific parts of the GDB stub
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 <GdbDebugAgent.h>
-
-//
-// Array of exception types that need to be hooked by the debugger
-// {EFI mapping, GDB mapping}
-//
-EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = {
- { EXCEPT_IA32_DIVIDE_ERROR, GDB_SIGFPE },
- { EXCEPT_IA32_DEBUG, GDB_SIGTRAP },
- { EXCEPT_IA32_NMI, GDB_SIGEMT },
- { EXCEPT_IA32_BREAKPOINT, GDB_SIGTRAP },
- { EXCEPT_IA32_OVERFLOW, GDB_SIGSEGV },
- { EXCEPT_IA32_BOUND, GDB_SIGSEGV },
- { EXCEPT_IA32_INVALID_OPCODE, GDB_SIGILL },
- { EXCEPT_IA32_DOUBLE_FAULT, GDB_SIGEMT },
- { EXCEPT_IA32_STACK_FAULT, GDB_SIGSEGV },
- { EXCEPT_IA32_GP_FAULT, GDB_SIGSEGV },
- { EXCEPT_IA32_PAGE_FAULT, GDB_SIGSEGV },
- { EXCEPT_IA32_FP_ERROR, GDB_SIGEMT },
- { EXCEPT_IA32_ALIGNMENT_CHECK, GDB_SIGEMT },
- { EXCEPT_IA32_MACHINE_CHECK, GDB_SIGEMT }
-};
-
-
-// The offsets of registers SystemContext.
-// The fields in the array are in the gdb ordering.
-//
-//16 regs
-UINTN gRegisterOffsets[] = {
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eax),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ecx),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edx),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebx),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esp),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebp),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esi),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edi),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eip),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eflags),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Cs),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ss),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ds),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Es),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Fs),
- OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Gs)
-};
-
-
-//Debug only..
-VOID
-PrintReg (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- Print ((CHAR16 *)L"EAX: %x ", SystemContext.SystemContextIa32->Eax);
- Print ((CHAR16 *)L"ECX: %x ", SystemContext.SystemContextIa32->Ecx);
- Print ((CHAR16 *)L"EDX: %x ", SystemContext.SystemContextIa32->Edx);
- Print ((CHAR16 *)L"EBX: %x ", SystemContext.SystemContextIa32->Ebx);
- Print ((CHAR16 *)L"ESP: %x ", SystemContext.SystemContextIa32->Esp);
- Print ((CHAR16 *)L"EBP: %x ", SystemContext.SystemContextIa32->Ebp);
- Print ((CHAR16 *)L"ESI: %x ", SystemContext.SystemContextIa32->Esi);
- Print ((CHAR16 *)L"EDI: %x ", SystemContext.SystemContextIa32->Edi);
- Print ((CHAR16 *)L"EIP: %x\n", SystemContext.SystemContextIa32->Eip);
- Print ((CHAR16 *)L"EFlags: %x\n", SystemContext.SystemContextIa32->Eflags);
-}
-
-//Debug only..
-VOID
-PrintDRreg (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- Print ((CHAR16 *)L"DR0: %x ", SystemContext.SystemContextIa32->Dr0);
- Print ((CHAR16 *)L"DR1: %x ", SystemContext.SystemContextIa32->Dr1);
- Print ((CHAR16 *)L"DR2: %x ", SystemContext.SystemContextIa32->Dr2);
- Print ((CHAR16 *)L"DR3: %x ", SystemContext.SystemContextIa32->Dr3);
- Print ((CHAR16 *)L"DR6: %x ", SystemContext.SystemContextIa32->Dr6);
- Print ((CHAR16 *)L"DR7: %x\n", SystemContext.SystemContextIa32->Dr7);
-}
-
-
-/**
- Return the number of entries in the gExceptionType[]
-
- @retval UINTN, the number of entries in the gExceptionType[] array.
- **/
-UINTN
-MaxEfiException (
- VOID
- )
-{
- return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY);
-}
-
-
-/**
- Check to see if the ISA is supported.
- ISA = Instruction Set Architecture
-
- @retval TRUE if Isa is supported,
- FALSE otherwise.
-**/
-BOOLEAN
-CheckIsa (
- IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
- )
-{
- return (BOOLEAN)(Isa == IsaIa32);
-}
-
-
-/**
- This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering
- It is, by default, set to find the register pointer of the IA32 member
-
- @param SystemContext Register content at time of the exception
- @param RegNumber The register to which we want to find a pointer
- @retval the pointer to the RegNumber-th pointer
- **/
-UINTN *
-FindPointerToRegister(
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber
- )
-{
- UINT8 *TempPtr;
- TempPtr = ((UINT8 *)SystemContext.SystemContextIa32) + gRegisterOffsets[RegNumber];
- return (UINTN *)TempPtr;
-}
-
-
-/**
- Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
-
- @param SystemContext Register content at time of the exception
- @param RegNumber the number of the register that we want to read
- @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on.
- @retval the pointer to the next character of the output buffer that is available to be written on.
- **/
-CHAR8 *
-BasicReadRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *OutBufPtr
- )
-{
- UINTN RegSize;
-
- RegSize = 0;
- while (RegSize < REG_SIZE) {
- *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)];
- *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)];
- RegSize = RegSize + 8;
- }
- return OutBufPtr;
-}
-
-
-/** ‘p n’
- Reads the n-th register's value into an output buffer and sends it as a packet
-
- @param SystemContext Register content at time of the exception
- @param InBuffer Pointer to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-ReadNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- )
-{
- UINTN RegNumber;
- CHAR8 OutBuffer[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)
- CHAR8 *OutBufPtr; // pointer to the output buffer
-
- RegNumber = AsciiStrHexToUintn (&InBuffer[1]);
-
- if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) {
- SendError (GDB_EINVALIDREGNUM);
- return;
- }
-
- OutBufPtr = OutBuffer;
- OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr);
-
- *OutBufPtr = '\0'; // the end of the buffer
- SendPacket(OutBuffer);
-}
-
-
-/** ‘g’
- Reads the general registers into an output buffer and sends it as a packet
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-EFIAPI
-ReadGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- UINTN i;
- CHAR8 OutBuffer[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
- CHAR8 *OutBufPtr; // pointer to the output buffer
-
- OutBufPtr = OutBuffer;
- for(i = 0 ; i < sizeof (gRegisterOffsets)/sizeof (UINTN) ; i++) { // there are only 16 registers to read
- OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr);
- }
-
- *OutBufPtr = '\0'; // the end of the buffer
- SendPacket(OutBuffer);
-}
-
-
-/**
- Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
-
- @param SystemContext Register content at time of the exception
- @param RegNumber the number of the register that we want to write
- @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on.
- @retval the pointer to the next character of the input buffer that can be used
- **/
-CHAR8 *
-BasicWriteRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN RegNumber,
- IN CHAR8 *InBufPtr
- )
-{
- UINTN RegSize;
- UINTN TempValue; // the value transferred from a hex char
- UINT32 NewValue; // the new value of the RegNumber-th Register
-
- NewValue = 0;
- RegSize = 0;
- while (RegSize < REG_SIZE) {
- TempValue = HexCharToInt(*InBufPtr++);
-
- if (TempValue < 0) {
- SendError (GDB_EBADMEMDATA);
- return NULL;
- }
-
- NewValue += (TempValue << (RegSize+4));
- TempValue = HexCharToInt(*InBufPtr++);
-
- if (TempValue < 0) {
- SendError (GDB_EBADMEMDATA);
- return NULL;
- }
-
- NewValue += (TempValue << RegSize);
- RegSize = RegSize + 8;
- }
- *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue;
- return InBufPtr;
-}
-
-
-/** ‘P n...=r...’
- Writes the new value of n-th register received into the input buffer to the n-th register
-
- @param SystemContext Register content at time of the exception
- @param InBuffer Ponter to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-WriteNthRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- )
-{
- UINTN RegNumber;
- CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE]; // put the 'n..' part of the message into this array
- CHAR8 *RegNumBufPtr;
- CHAR8 *InBufPtr; // pointer to the input buffer
-
- // find the register number to write
- InBufPtr = &InBuffer[1];
- RegNumBufPtr = RegNumBuffer;
- while (*InBufPtr != '=') {
- *RegNumBufPtr++ = *InBufPtr++;
- }
- *RegNumBufPtr = '\0';
- RegNumber = AsciiStrHexToUintn (RegNumBuffer);
-
- // check if this is a valid Register Number
- if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) {
- SendError (GDB_EINVALIDREGNUM);
- return;
- }
- InBufPtr++; // skips the '=' character
- BasicWriteRegister (SystemContext, RegNumber, InBufPtr);
- SendSuccess();
-}
-
-
-/** ‘G XX...’
- Writes the new values received into the input buffer to the general registers
-
- @param SystemContext Register content at time of the exception
- @param InBuffer Pointer to the input buffer received from gdb server
- **/
-VOID
-EFIAPI
-WriteGeneralRegisters (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *InBuffer
- )
-{
- UINTN i;
- CHAR8 *InBufPtr; /// pointer to the input buffer
-
- // check to see if the buffer is the right size which is
- // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129
- if (AsciiStrLen(InBuffer) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
- //Bad message. Message is not the right length
- SendError (GDB_EBADBUFSIZE);
- return;
- }
-
- InBufPtr = &InBuffer[1];
-
- // Read the new values for the registers from the input buffer to an array, NewValueArray.
- // The values in the array are in the gdb ordering
- for(i=0; i < sizeof (gRegisterOffsets)/sizeof (UINTN); i++) { // there are only 16 registers to write
- InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr);
- }
-
- SendSuccess();
-}
-
-/** ‘c [addr ]’
- Continue. addr is Address to resume. If addr is omitted, resume at current
- Address.
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-EFIAPI
-ContinueAtAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- if (PacketData[1] != '\0') {
- SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);
- }
-}
-
-
-/** ‘s [addr ]’
- Single step. addr is the Address at which to resume. If addr is omitted, resume
- at same Address.
-
- @param SystemContext Register content at time of the exception
- **/
-VOID
-EFIAPI
-SingleStep (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
+
+//
+// Array of exception types that need to be hooked by the debugger
+// {EFI mapping, GDB mapping}
+//
+EFI_EXCEPTION_TYPE_ENTRY gExceptionType[] = {
+ { EXCEPT_IA32_DIVIDE_ERROR, GDB_SIGFPE },
+ { EXCEPT_IA32_DEBUG, GDB_SIGTRAP },
+ { EXCEPT_IA32_NMI, GDB_SIGEMT },
+ { EXCEPT_IA32_BREAKPOINT, GDB_SIGTRAP },
+ { EXCEPT_IA32_OVERFLOW, GDB_SIGSEGV },
+ { EXCEPT_IA32_BOUND, GDB_SIGSEGV },
+ { EXCEPT_IA32_INVALID_OPCODE, GDB_SIGILL },
+ { EXCEPT_IA32_DOUBLE_FAULT, GDB_SIGEMT },
+ { EXCEPT_IA32_STACK_FAULT, GDB_SIGSEGV },
+ { EXCEPT_IA32_GP_FAULT, GDB_SIGSEGV },
+ { EXCEPT_IA32_PAGE_FAULT, GDB_SIGSEGV },
+ { EXCEPT_IA32_FP_ERROR, GDB_SIGEMT },
+ { EXCEPT_IA32_ALIGNMENT_CHECK, GDB_SIGEMT },
+ { EXCEPT_IA32_MACHINE_CHECK, GDB_SIGEMT }
+};
+
+
+// The offsets of registers SystemContext.
+// The fields in the array are in the gdb ordering.
+//
+//16 regs
+UINTN gRegisterOffsets[] = {
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eax),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ecx),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edx),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebx),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esp),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ebp),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Esi),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Edi),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eip),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Eflags),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Cs),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ss),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Ds),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Es),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Fs),
+ OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32, Gs)
+};
+
+
+//Debug only..
+VOID
+PrintReg (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ Print ((CHAR16 *)L"EAX: %x ", SystemContext.SystemContextIa32->Eax);
+ Print ((CHAR16 *)L"ECX: %x ", SystemContext.SystemContextIa32->Ecx);
+ Print ((CHAR16 *)L"EDX: %x ", SystemContext.SystemContextIa32->Edx);
+ Print ((CHAR16 *)L"EBX: %x ", SystemContext.SystemContextIa32->Ebx);
+ Print ((CHAR16 *)L"ESP: %x ", SystemContext.SystemContextIa32->Esp);
+ Print ((CHAR16 *)L"EBP: %x ", SystemContext.SystemContextIa32->Ebp);
+ Print ((CHAR16 *)L"ESI: %x ", SystemContext.SystemContextIa32->Esi);
+ Print ((CHAR16 *)L"EDI: %x ", SystemContext.SystemContextIa32->Edi);
+ Print ((CHAR16 *)L"EIP: %x\n", SystemContext.SystemContextIa32->Eip);
+ Print ((CHAR16 *)L"EFlags: %x\n", SystemContext.SystemContextIa32->Eflags);
+}
+
+//Debug only..
+VOID
+PrintDRreg (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ Print ((CHAR16 *)L"DR0: %x ", SystemContext.SystemContextIa32->Dr0);
+ Print ((CHAR16 *)L"DR1: %x ", SystemContext.SystemContextIa32->Dr1);
+ Print ((CHAR16 *)L"DR2: %x ", SystemContext.SystemContextIa32->Dr2);
+ Print ((CHAR16 *)L"DR3: %x ", SystemContext.SystemContextIa32->Dr3);
+ Print ((CHAR16 *)L"DR6: %x ", SystemContext.SystemContextIa32->Dr6);
+ Print ((CHAR16 *)L"DR7: %x\n", SystemContext.SystemContextIa32->Dr7);
+}
+
+
+/**
+ Return the number of entries in the gExceptionType[]
+
+ @retval UINTN, the number of entries in the gExceptionType[] array.
+ **/
+UINTN
+MaxEfiException (
+ VOID
+ )
+{
+ return sizeof (gExceptionType)/sizeof (EFI_EXCEPTION_TYPE_ENTRY);
+}
+
+
+/**
+ Check to see if the ISA is supported.
+ ISA = Instruction Set Architecture
+
+ @retval TRUE if Isa is supported,
+ FALSE otherwise.
+**/
+BOOLEAN
+CheckIsa (
+ IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
+ )
+{
+ return (BOOLEAN)(Isa == IsaIa32);
+}
+
+
+/**
+ This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering
+ It is, by default, set to find the register pointer of the IA32 member
+
+ @param SystemContext Register content at time of the exception
+ @param RegNumber The register to which we want to find a pointer
+ @retval the pointer to the RegNumber-th pointer
+ **/
+UINTN *
+FindPointerToRegister(
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber
+ )
+{
+ UINT8 *TempPtr;
+ TempPtr = ((UINT8 *)SystemContext.SystemContextIa32) + gRegisterOffsets[RegNumber];
+ return (UINTN *)TempPtr;
+}
+
+
+/**
+ Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
+
+ @param SystemContext Register content at time of the exception
+ @param RegNumber the number of the register that we want to read
+ @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on.
+ @retval the pointer to the next character of the output buffer that is available to be written on.
+ **/
+CHAR8 *
+BasicReadRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber,
+ IN CHAR8 *OutBufPtr
+ )
+{
+ UINTN RegSize;
+
+ RegSize = 0;
+ while (RegSize < REG_SIZE) {
+ *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> (RegSize+4)) & 0xf)];
+ *OutBufPtr++ = mHexToStr[((*FindPointerToRegister(SystemContext, RegNumber) >> RegSize) & 0xf)];
+ RegSize = RegSize + 8;
+ }
+ return OutBufPtr;
+}
+
+
+/** ‘p n’
+ Reads the n-th register's value into an output buffer and sends it as a packet
+
+ @param SystemContext Register content at time of the exception
+ @param InBuffer Pointer to the input buffer received from gdb server
+ **/
+VOID
+EFIAPI
+ReadNthRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ )
+{
+ UINTN RegNumber;
+ CHAR8 OutBuffer[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)
+ CHAR8 *OutBufPtr; // pointer to the output buffer
+
+ RegNumber = AsciiStrHexToUintn (&InBuffer[1]);
+
+ if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) {
+ SendError (GDB_EINVALIDREGNUM);
+ return;
+ }
+
+ OutBufPtr = OutBuffer;
+ OutBufPtr = BasicReadRegister(SystemContext, RegNumber, OutBufPtr);
+
+ *OutBufPtr = '\0'; // the end of the buffer
+ SendPacket(OutBuffer);
+}
+
+
+/** ‘g’
+ Reads the general registers into an output buffer and sends it as a packet
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+EFIAPI
+ReadGeneralRegisters (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ UINTN i;
+ CHAR8 OutBuffer[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
+ CHAR8 *OutBufPtr; // pointer to the output buffer
+
+ OutBufPtr = OutBuffer;
+ for(i = 0 ; i < sizeof (gRegisterOffsets)/sizeof (UINTN) ; i++) { // there are only 16 registers to read
+ OutBufPtr = BasicReadRegister(SystemContext, i, OutBufPtr);
+ }
+
+ *OutBufPtr = '\0'; // the end of the buffer
+ SendPacket(OutBuffer);
+}
+
+
+/**
+ Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
+
+ @param SystemContext Register content at time of the exception
+ @param RegNumber the number of the register that we want to write
+ @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on.
+ @retval the pointer to the next character of the input buffer that can be used
+ **/
+CHAR8 *
+BasicWriteRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN RegNumber,
+ IN CHAR8 *InBufPtr
+ )
+{
+ UINTN RegSize;
+ UINTN TempValue; // the value transferred from a hex char
+ UINT32 NewValue; // the new value of the RegNumber-th Register
+
+ NewValue = 0;
+ RegSize = 0;
+ while (RegSize < REG_SIZE) {
+ TempValue = HexCharToInt(*InBufPtr++);
+
+ if (TempValue < 0) {
+ SendError (GDB_EBADMEMDATA);
+ return NULL;
+ }
+
+ NewValue += (TempValue << (RegSize+4));
+ TempValue = HexCharToInt(*InBufPtr++);
+
+ if (TempValue < 0) {
+ SendError (GDB_EBADMEMDATA);
+ return NULL;
+ }
+
+ NewValue += (TempValue << RegSize);
+ RegSize = RegSize + 8;
+ }
+ *(FindPointerToRegister(SystemContext, RegNumber)) = NewValue;
+ return InBufPtr;
+}
+
+
+/** ‘P n...=r...’
+ Writes the new value of n-th register received into the input buffer to the n-th register
+
+ @param SystemContext Register content at time of the exception
+ @param InBuffer Ponter to the input buffer received from gdb server
+ **/
+VOID
+EFIAPI
+WriteNthRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ )
+{
+ UINTN RegNumber;
+ CHAR8 RegNumBuffer[MAX_REG_NUM_BUF_SIZE]; // put the 'n..' part of the message into this array
+ CHAR8 *RegNumBufPtr;
+ CHAR8 *InBufPtr; // pointer to the input buffer
+
+ // find the register number to write
+ InBufPtr = &InBuffer[1];
+ RegNumBufPtr = RegNumBuffer;
+ while (*InBufPtr != '=') {
+ *RegNumBufPtr++ = *InBufPtr++;
+ }
+ *RegNumBufPtr = '\0';
+ RegNumber = AsciiStrHexToUintn (RegNumBuffer);
+
+ // check if this is a valid Register Number
+ if ((RegNumber < 0) || (RegNumber >= sizeof (gRegisterOffsets)/sizeof (UINTN))) {
+ SendError (GDB_EINVALIDREGNUM);
+ return;
+ }
+ InBufPtr++; // skips the '=' character
+ BasicWriteRegister (SystemContext, RegNumber, InBufPtr);
+ SendSuccess();
+}
+
+
+/** ‘G XX...’
+ Writes the new values received into the input buffer to the general registers
+
+ @param SystemContext Register content at time of the exception
+ @param InBuffer Pointer to the input buffer received from gdb server
+ **/
+VOID
+EFIAPI
+WriteGeneralRegisters (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *InBuffer
+ )
+{
+ UINTN i;
+ CHAR8 *InBufPtr; /// pointer to the input buffer
+
+ // check to see if the buffer is the right size which is
+ // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129
+ if (AsciiStrLen(InBuffer) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
+ //Bad message. Message is not the right length
+ SendError (GDB_EBADBUFSIZE);
+ return;
+ }
+
+ InBufPtr = &InBuffer[1];
+
+ // Read the new values for the registers from the input buffer to an array, NewValueArray.
+ // The values in the array are in the gdb ordering
+ for(i=0; i < sizeof (gRegisterOffsets)/sizeof (UINTN); i++) { // there are only 16 registers to write
+ InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr);
+ }
+
+ SendSuccess();
+}
+
+/** ‘c [addr ]’
+ Continue. addr is Address to resume. If addr is omitted, resume at current
+ Address.
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+EFIAPI
+ContinueAtAddress (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ )
+{
+ if (PacketData[1] != '\0') {
+ SystemContext.SystemContextIa32->Eip = AsciiStrHexToUintn (&PacketData[1]);
+ }
+}
+
+
+/** ‘s [addr ]’
+ Single step. addr is the Address at which to resume. If addr is omitted, resume
+ at same Address.
+
+ @param SystemContext Register content at time of the exception
+ **/
+VOID
+EFIAPI
+SingleStep (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ )
+{
SendNotSupported();
-}
-
-
-/**
- Returns breakpoint data address from DR0-DR3 based on the input breakpoint number
-
- @param SystemContext Register content at time of the exception
- @param BreakpointNumber Breakpoint number
-
- @retval Address Data address from DR0-DR3 based on the breakpoint number.
-
-**/
-UINTN
-GetBreakpointDataAddress (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- )
-{
- UINTN Address;
-
- if (BreakpointNumber == 1) {
- Address = SystemContext.SystemContextIa32->Dr0;
- } else if (BreakpointNumber == 2) {
- Address = SystemContext.SystemContextIa32->Dr1;
- } else if (BreakpointNumber == 3) {
- Address = SystemContext.SystemContextIa32->Dr2;
- } else if (BreakpointNumber == 4) {
- Address = SystemContext.SystemContextIa32->Dr3;
- } else {
- Address = 0;
- }
-
- return Address;
-}
-
-
-/**
- Returns currently detected breakpoint value based on the register DR6 B0-B3 field.
- If no breakpoint is detected then it returns 0.
-
- @param SystemContext Register content at time of the exception
-
- @retval {1-4} Currently detected breakpoint value
- @retval 0 No breakpoint detected.
-
-**/
-UINTN
-GetBreakpointDetected (
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- IA32_DR6 Dr6;
- UINTN BreakpointNumber;
-
- Dr6.UintN = SystemContext.SystemContextIa32->Dr6;
-
- if (Dr6.Bits.B0 == 1) {
- BreakpointNumber = 1;
- } else if (Dr6.Bits.B1 == 1) {
- BreakpointNumber = 2;
- } else if (Dr6.Bits.B2 == 1) {
- BreakpointNumber = 3;
- } else if (Dr6.Bits.B3 == 1) {
- BreakpointNumber = 4;
- } else {
- BreakpointNumber = 0; //No breakpoint detected
- }
-
- return BreakpointNumber;
-}
-
-
-/**
- Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)
- based on the Breakpoint number
-
- @param SystemContext Register content at time of the exception
- @param BreakpointNumber Breakpoint number
-
- @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn field
- For unknown value, it returns NotSupported.
-
-**/
-BREAK_TYPE
-GetBreakpointType (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN BreakpointNumber
- )
-{
- IA32_DR7 Dr7;
- BREAK_TYPE Type = NotSupported; //Default is NotSupported type
-
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if (BreakpointNumber == 1) {
- Type = (BREAK_TYPE) Dr7.Bits.RW0;
- } else if (BreakpointNumber == 2) {
- Type = (BREAK_TYPE) Dr7.Bits.RW1;
- } else if (BreakpointNumber == 3) {
- Type = (BREAK_TYPE) Dr7.Bits.RW2;
- } else if (BreakpointNumber == 4) {
- Type = (BREAK_TYPE) Dr7.Bits.RW3;
- }
-
- return Type;
-}
-
-
-/**
- Parses Length and returns the length which DR7 LENn field accepts.
- For example: If we receive 1-Byte length then we should return 0.
- Zero gets written to DR7 LENn field.
-
- @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
-
- @retval Length Appropriate converted values which DR7 LENn field accepts.
-
-**/
-UINTN
-ConvertLengthData (
- IN UINTN Length
- )
-{
- if (Length == 1) { //1-Byte length
- return 0;
- } else if (Length == 2) { //2-Byte length
- return 1;
- } else if (Length == 4) { //4-Byte length
- return 3;
- } else { //Undefined or 8-byte length
- return 2;
- }
-}
-
-
-/**
- Finds the next free debug register. If all the registers are occupied then
- EFI_OUT_OF_RESOURCES is returned.
-
- @param SystemContext Register content at time of the exception
- @param Register Register value (0 - 3 for the first free debug register)
-
- @retval EFI_STATUS Appropriate status value.
-
-**/
-EFI_STATUS
-FindNextFreeDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- OUT UINTN *Register
- )
-{
- IA32_DR7 Dr7;
-
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if (Dr7.Bits.G0 == 0) {
- *Register = 0;
- } else if (Dr7.Bits.G1 == 0) {
- *Register = 1;
- } else if (Dr7.Bits.G2 == 0) {
- *Register = 2;
- } else if (Dr7.Bits.G3 == 0) {
- *Register = 3;
- } else {
- return EFI_OUT_OF_RESOURCES;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Enables the debug register. Writes Address value to appropriate DR0-3 register.
- Sets LENn, Gn, RWn bits in DR7 register.
-
- @param SystemContext Register content at time of the exception
- @param Register Register value (0 - 3)
- @param Address Breakpoint address value
- @param Type Breakpoint type (Instruction, Data write, Data read
- or write etc.)
-
- @retval EFI_STATUS Appropriate status value.
-
-**/
-EFI_STATUS
-EnableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type
- )
-{
- IA32_DR7 Dr7;
-
- //Convert length data
- Length = ConvertLengthData (Length);
-
- //For Instruction execution, length should be 0
- //(Ref. Intel reference manual 18.2.4)
- if ((Type == 0) && (Length != 0)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
- //software breakpoint. We should send empty packet in both these cases.
- if ((Type == (BREAK_TYPE)DataRead) ||
- (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
- return EFI_UNSUPPORTED;
- }
-
- //Read DR7 so appropriate Gn, RWn and LENn bits can be modified.
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if (Register == 0) {
- SystemContext.SystemContextIa32->Dr0 = Address;
- Dr7.Bits.G0 = 1;
- Dr7.Bits.RW0 = Type;
- Dr7.Bits.LEN0 = Length;
- } else if (Register == 1) {
- SystemContext.SystemContextIa32->Dr1 = Address;
- Dr7.Bits.G1 = 1;
- Dr7.Bits.RW1 = Type;
- Dr7.Bits.LEN1 = Length;
- } else if (Register == 2) {
- SystemContext.SystemContextIa32->Dr2 = Address;
- Dr7.Bits.G2 = 1;
- Dr7.Bits.RW2 = Type;
- Dr7.Bits.LEN2 = Length;
- } else if (Register == 3) {
- SystemContext.SystemContextIa32->Dr3 = Address;
- Dr7.Bits.G3 = 1;
- Dr7.Bits.RW3 = Type;
- Dr7.Bits.LEN3 = Length;
- } else {
- return EFI_INVALID_PARAMETER;
- }
-
- //Update Dr7 with appropriate Gn, RWn and LENn bits
- SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Returns register number 0 - 3 for the maching debug register.
- This function compares incoming Address, Type, Length and
- if there is a match then it returns the appropriate register number.
- In case of mismatch, function returns EFI_NOT_FOUND message.
-
- @param SystemContext Register content at time of the exception
- @param Address Breakpoint address value
- @param Length Breakpoint length value
- @param Type Breakpoint type (Instruction, Data write,
- Data read or write etc.)
- @param Register Register value to be returned
-
- @retval EFI_STATUS Appropriate status value.
-
-**/
-EFI_STATUS
-FindMatchingDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Address,
- IN UINTN Length,
- IN UINTN Type,
- OUT UINTN *Register
- )
-{
- IA32_DR7 Dr7;
-
- //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
- //software breakpoint. We should send empty packet in both these cases.
- if ((Type == (BREAK_TYPE)DataRead) ||
- (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
- return EFI_UNSUPPORTED;
- }
-
- //Convert length data
- Length = ConvertLengthData(Length);
-
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if ((Dr7.Bits.G0 == 1) &&
- (Dr7.Bits.LEN0 == Length) &&
- (Dr7.Bits.RW0 == Type) &&
- (Address == SystemContext.SystemContextIa32->Dr0)) {
- *Register = 0;
- } else if ((Dr7.Bits.G1 == 1) &&
- (Dr7.Bits.LEN1 == Length) &&
- (Dr7.Bits.RW1 == Type) &&
- (Address == SystemContext.SystemContextIa32->Dr1)) {
- *Register = 1;
- } else if ((Dr7.Bits.G2 == 1) &&
- (Dr7.Bits.LEN2 == Length) &&
- (Dr7.Bits.RW2 == Type) &&
- (Address == SystemContext.SystemContextIa32->Dr2)) {
- *Register = 2;
- } else if ((Dr7.Bits.G3 == 1) &&
- (Dr7.Bits.LEN3 == Length) &&
- (Dr7.Bits.RW3 == Type) &&
- (Address == SystemContext.SystemContextIa32->Dr3)) {
- *Register = 3;
- } else {
- Print ((CHAR16 *)L"No match found..\n");
- return EFI_NOT_FOUND;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Disables the particular debug register.
-
- @param SystemContext Register content at time of the exception
- @param Register Register to be disabled
-
- @retval EFI_STATUS Appropriate status value.
-
-**/
-EFI_STATUS
-DisableDebugRegister (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN UINTN Register
- )
-{
- IA32_DR7 Dr7;
- UINTN Address = 0;
-
- //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
- Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
-
- if (Register == 0) {
- SystemContext.SystemContextIa32->Dr0 = Address;
- Dr7.Bits.G0 = 0;
- Dr7.Bits.RW0 = 0;
- Dr7.Bits.LEN0 = 0;
- } else if (Register == 1) {
- SystemContext.SystemContextIa32->Dr1 = Address;
- Dr7.Bits.G1 = 0;
- Dr7.Bits.RW1 = 0;
- Dr7.Bits.LEN1 = 0;
- } else if (Register == 2) {
- SystemContext.SystemContextIa32->Dr2 = Address;
- Dr7.Bits.G2 = 0;
- Dr7.Bits.RW2 = 0;
- Dr7.Bits.LEN2 = 0;
- } else if (Register == 3) {
- SystemContext.SystemContextIa32->Dr3 = Address;
- Dr7.Bits.G3 = 0;
- Dr7.Bits.RW3 = 0;
- Dr7.Bits.LEN3 = 0;
- } else {
- return EFI_INVALID_PARAMETER;
- }
-
- //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
- SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
-
- return EFI_SUCCESS;
-}
-
-
-/**
- ‘Z1, [addr], [length]’
- ‘Z2, [addr], [length]’
- ‘Z3, [addr], [length]’
- ‘Z4, [addr], [length]’
-
- Insert hardware breakpoint/watchpoint at address addr of size length
-
- @param SystemContext Register content at time of the exception
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-InsertBreakPoint (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- UINTN Type;
- UINTN Address;
- UINTN Length;
- UINTN Register;
- EFI_STATUS Status;
- BREAK_TYPE BreakType = NotSupported;
- UINTN ErrorCode;
-
- ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
- if (ErrorCode > 0) {
- SendError ((UINT8)ErrorCode);
- return;
- }
-
- switch (Type) {
-
- case 0: //Software breakpoint
- BreakType = SoftwareBreakpoint;
- break;
-
- case 1: //Hardware breakpoint
- BreakType = InstructionExecution;
- break;
-
- case 2: //Write watchpoint
- BreakType = DataWrite;
- break;
-
- case 3: //Read watchpoint
- BreakType = DataRead;
- break;
-
- case 4: //Access watchpoint
- BreakType = DataReadWrite;
- break;
-
- default :
- Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type);
- SendError (GDB_EINVALIDBRKPOINTTYPE);
- return;
- }
-
- // Find next free debug register
- Status = FindNextFreeDebugRegister (SystemContext, &Register);
- if (EFI_ERROR(Status)) {
- Print ((CHAR16 *)L"No space left on device\n");
- SendError (GDB_ENOSPACE);
- return;
- }
-
- // Write Address, length data at particular DR register
- Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType);
- if (EFI_ERROR(Status)) {
- if (Status == EFI_UNSUPPORTED) {
- SendNotSupported();
- return;
- }
-
- SendError (GDB_EINVALIDARG);
- return;
- }
-
- SendSuccess ();
-}
-
-
-/**
- ‘z1, [addr], [length]’
- ‘z2, [addr], [length]’
- ‘z3, [addr], [length]’
- ‘z4, [addr], [length]’
-
- Remove hardware breakpoint/watchpoint at address addr of size length
-
- @param *PacketData Pointer to the Payload data for the packet
-
-**/
-VOID
-EFIAPI
-RemoveBreakPoint (
- IN EFI_SYSTEM_CONTEXT SystemContext,
- IN CHAR8 *PacketData
- )
-{
- UINTN Type;
- UINTN Address;
- UINTN Length;
- UINTN Register;
- BREAK_TYPE BreakType = NotSupported;
- EFI_STATUS Status;
- UINTN ErrorCode;
-
- //Parse breakpoint packet data
- ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
- if (ErrorCode > 0) {
- SendError ((UINT8)ErrorCode);
- return;
- }
-
- switch (Type) {
-
- case 0: //Software breakpoint
- BreakType = SoftwareBreakpoint;
- break;
-
- case 1: //Hardware breakpoint
- BreakType = InstructionExecution;
- break;
-
- case 2: //Write watchpoint
- BreakType = DataWrite;
- break;
-
- case 3: //Read watchpoint
- BreakType = DataRead;
- break;
-
- case 4: //Access watchpoint
- BreakType = DataReadWrite;
- break;
-
- default :
- SendError (GDB_EINVALIDBRKPOINTTYPE);
- return;
- }
-
- //Find matching debug register
- Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register);
- if (EFI_ERROR(Status)) {
- if (Status == EFI_UNSUPPORTED) {
- SendNotSupported();
- return;
- }
-
- SendError (GDB_ENOSPACE);
- return;
- }
-
- //Remove breakpoint
- Status = DisableDebugRegister(SystemContext, Register);
- if (EFI_ERROR(Status)) {
- SendError (GDB_EINVALIDARG);
- return;
- }
-
- SendSuccess ();
-}
-
-
+}
+
+
+/**
+ Returns breakpoint data address from DR0-DR3 based on the input breakpoint number
+
+ @param SystemContext Register content at time of the exception
+ @param BreakpointNumber Breakpoint number
+
+ @retval Address Data address from DR0-DR3 based on the breakpoint number.
+
+**/
+UINTN
+GetBreakpointDataAddress (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN BreakpointNumber
+ )
+{
+ UINTN Address;
+
+ if (BreakpointNumber == 1) {
+ Address = SystemContext.SystemContextIa32->Dr0;
+ } else if (BreakpointNumber == 2) {
+ Address = SystemContext.SystemContextIa32->Dr1;
+ } else if (BreakpointNumber == 3) {
+ Address = SystemContext.SystemContextIa32->Dr2;
+ } else if (BreakpointNumber == 4) {
+ Address = SystemContext.SystemContextIa32->Dr3;
+ } else {
+ Address = 0;
+ }
+
+ return Address;
+}
+
+
+/**
+ Returns currently detected breakpoint value based on the register DR6 B0-B3 field.
+ If no breakpoint is detected then it returns 0.
+
+ @param SystemContext Register content at time of the exception
+
+ @retval {1-4} Currently detected breakpoint value
+ @retval 0 No breakpoint detected.
+
+**/
+UINTN
+GetBreakpointDetected (
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ IA32_DR6 Dr6;
+ UINTN BreakpointNumber;
+
+ Dr6.UintN = SystemContext.SystemContextIa32->Dr6;
+
+ if (Dr6.Bits.B0 == 1) {
+ BreakpointNumber = 1;
+ } else if (Dr6.Bits.B1 == 1) {
+ BreakpointNumber = 2;
+ } else if (Dr6.Bits.B2 == 1) {
+ BreakpointNumber = 3;
+ } else if (Dr6.Bits.B3 == 1) {
+ BreakpointNumber = 4;
+ } else {
+ BreakpointNumber = 0; //No breakpoint detected
+ }
+
+ return BreakpointNumber;
+}
+
+
+/**
+ Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)
+ based on the Breakpoint number
+
+ @param SystemContext Register content at time of the exception
+ @param BreakpointNumber Breakpoint number
+
+ @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn field
+ For unknown value, it returns NotSupported.
+
+**/
+BREAK_TYPE
+GetBreakpointType (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN BreakpointNumber
+ )
+{
+ IA32_DR7 Dr7;
+ BREAK_TYPE Type = NotSupported; //Default is NotSupported type
+
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if (BreakpointNumber == 1) {
+ Type = (BREAK_TYPE) Dr7.Bits.RW0;
+ } else if (BreakpointNumber == 2) {
+ Type = (BREAK_TYPE) Dr7.Bits.RW1;
+ } else if (BreakpointNumber == 3) {
+ Type = (BREAK_TYPE) Dr7.Bits.RW2;
+ } else if (BreakpointNumber == 4) {
+ Type = (BREAK_TYPE) Dr7.Bits.RW3;
+ }
+
+ return Type;
+}
+
+
+/**
+ Parses Length and returns the length which DR7 LENn field accepts.
+ For example: If we receive 1-Byte length then we should return 0.
+ Zero gets written to DR7 LENn field.
+
+ @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
+
+ @retval Length Appropriate converted values which DR7 LENn field accepts.
+
+**/
+UINTN
+ConvertLengthData (
+ IN UINTN Length
+ )
+{
+ if (Length == 1) { //1-Byte length
+ return 0;
+ } else if (Length == 2) { //2-Byte length
+ return 1;
+ } else if (Length == 4) { //4-Byte length
+ return 3;
+ } else { //Undefined or 8-byte length
+ return 2;
+ }
+}
+
+
+/**
+ Finds the next free debug register. If all the registers are occupied then
+ EFI_OUT_OF_RESOURCES is returned.
+
+ @param SystemContext Register content at time of the exception
+ @param Register Register value (0 - 3 for the first free debug register)
+
+ @retval EFI_STATUS Appropriate status value.
+
+**/
+EFI_STATUS
+FindNextFreeDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ OUT UINTN *Register
+ )
+{
+ IA32_DR7 Dr7;
+
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if (Dr7.Bits.G0 == 0) {
+ *Register = 0;
+ } else if (Dr7.Bits.G1 == 0) {
+ *Register = 1;
+ } else if (Dr7.Bits.G2 == 0) {
+ *Register = 2;
+ } else if (Dr7.Bits.G3 == 0) {
+ *Register = 3;
+ } else {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Enables the debug register. Writes Address value to appropriate DR0-3 register.
+ Sets LENn, Gn, RWn bits in DR7 register.
+
+ @param SystemContext Register content at time of the exception
+ @param Register Register value (0 - 3)
+ @param Address Breakpoint address value
+ @param Type Breakpoint type (Instruction, Data write, Data read
+ or write etc.)
+
+ @retval EFI_STATUS Appropriate status value.
+
+**/
+EFI_STATUS
+EnableDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Register,
+ IN UINTN Address,
+ IN UINTN Length,
+ IN UINTN Type
+ )
+{
+ IA32_DR7 Dr7;
+
+ //Convert length data
+ Length = ConvertLengthData (Length);
+
+ //For Instruction execution, length should be 0
+ //(Ref. Intel reference manual 18.2.4)
+ if ((Type == 0) && (Length != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
+ //software breakpoint. We should send empty packet in both these cases.
+ if ((Type == (BREAK_TYPE)DataRead) ||
+ (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //Read DR7 so appropriate Gn, RWn and LENn bits can be modified.
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if (Register == 0) {
+ SystemContext.SystemContextIa32->Dr0 = Address;
+ Dr7.Bits.G0 = 1;
+ Dr7.Bits.RW0 = Type;
+ Dr7.Bits.LEN0 = Length;
+ } else if (Register == 1) {
+ SystemContext.SystemContextIa32->Dr1 = Address;
+ Dr7.Bits.G1 = 1;
+ Dr7.Bits.RW1 = Type;
+ Dr7.Bits.LEN1 = Length;
+ } else if (Register == 2) {
+ SystemContext.SystemContextIa32->Dr2 = Address;
+ Dr7.Bits.G2 = 1;
+ Dr7.Bits.RW2 = Type;
+ Dr7.Bits.LEN2 = Length;
+ } else if (Register == 3) {
+ SystemContext.SystemContextIa32->Dr3 = Address;
+ Dr7.Bits.G3 = 1;
+ Dr7.Bits.RW3 = Type;
+ Dr7.Bits.LEN3 = Length;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Update Dr7 with appropriate Gn, RWn and LENn bits
+ SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Returns register number 0 - 3 for the maching debug register.
+ This function compares incoming Address, Type, Length and
+ if there is a match then it returns the appropriate register number.
+ In case of mismatch, function returns EFI_NOT_FOUND message.
+
+ @param SystemContext Register content at time of the exception
+ @param Address Breakpoint address value
+ @param Length Breakpoint length value
+ @param Type Breakpoint type (Instruction, Data write,
+ Data read or write etc.)
+ @param Register Register value to be returned
+
+ @retval EFI_STATUS Appropriate status value.
+
+**/
+EFI_STATUS
+FindMatchingDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Address,
+ IN UINTN Length,
+ IN UINTN Type,
+ OUT UINTN *Register
+ )
+{
+ IA32_DR7 Dr7;
+
+ //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
+ //software breakpoint. We should send empty packet in both these cases.
+ if ((Type == (BREAK_TYPE)DataRead) ||
+ (Type == (BREAK_TYPE)SoftwareBreakpoint)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //Convert length data
+ Length = ConvertLengthData(Length);
+
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if ((Dr7.Bits.G0 == 1) &&
+ (Dr7.Bits.LEN0 == Length) &&
+ (Dr7.Bits.RW0 == Type) &&
+ (Address == SystemContext.SystemContextIa32->Dr0)) {
+ *Register = 0;
+ } else if ((Dr7.Bits.G1 == 1) &&
+ (Dr7.Bits.LEN1 == Length) &&
+ (Dr7.Bits.RW1 == Type) &&
+ (Address == SystemContext.SystemContextIa32->Dr1)) {
+ *Register = 1;
+ } else if ((Dr7.Bits.G2 == 1) &&
+ (Dr7.Bits.LEN2 == Length) &&
+ (Dr7.Bits.RW2 == Type) &&
+ (Address == SystemContext.SystemContextIa32->Dr2)) {
+ *Register = 2;
+ } else if ((Dr7.Bits.G3 == 1) &&
+ (Dr7.Bits.LEN3 == Length) &&
+ (Dr7.Bits.RW3 == Type) &&
+ (Address == SystemContext.SystemContextIa32->Dr3)) {
+ *Register = 3;
+ } else {
+ Print ((CHAR16 *)L"No match found..\n");
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Disables the particular debug register.
+
+ @param SystemContext Register content at time of the exception
+ @param Register Register to be disabled
+
+ @retval EFI_STATUS Appropriate status value.
+
+**/
+EFI_STATUS
+DisableDebugRegister (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN UINTN Register
+ )
+{
+ IA32_DR7 Dr7;
+ UINTN Address = 0;
+
+ //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
+ Dr7.UintN = SystemContext.SystemContextIa32->Dr7;
+
+ if (Register == 0) {
+ SystemContext.SystemContextIa32->Dr0 = Address;
+ Dr7.Bits.G0 = 0;
+ Dr7.Bits.RW0 = 0;
+ Dr7.Bits.LEN0 = 0;
+ } else if (Register == 1) {
+ SystemContext.SystemContextIa32->Dr1 = Address;
+ Dr7.Bits.G1 = 0;
+ Dr7.Bits.RW1 = 0;
+ Dr7.Bits.LEN1 = 0;
+ } else if (Register == 2) {
+ SystemContext.SystemContextIa32->Dr2 = Address;
+ Dr7.Bits.G2 = 0;
+ Dr7.Bits.RW2 = 0;
+ Dr7.Bits.LEN2 = 0;
+ } else if (Register == 3) {
+ SystemContext.SystemContextIa32->Dr3 = Address;
+ Dr7.Bits.G3 = 0;
+ Dr7.Bits.RW3 = 0;
+ Dr7.Bits.LEN3 = 0;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
+ SystemContext.SystemContextIa32->Dr7 = Dr7.UintN;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ ‘Z1, [addr], [length]’
+ ‘Z2, [addr], [length]’
+ ‘Z3, [addr], [length]’
+ ‘Z4, [addr], [length]’
+
+ Insert hardware breakpoint/watchpoint at address addr of size length
+
+ @param SystemContext Register content at time of the exception
+ @param *PacketData Pointer to the Payload data for the packet
+
+**/
+VOID
+EFIAPI
+InsertBreakPoint (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ )
+{
+ UINTN Type;
+ UINTN Address;
+ UINTN Length;
+ UINTN Register;
+ EFI_STATUS Status;
+ BREAK_TYPE BreakType = NotSupported;
+ UINTN ErrorCode;
+
+ ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
+ if (ErrorCode > 0) {
+ SendError ((UINT8)ErrorCode);
+ return;
+ }
+
+ switch (Type) {
+
+ case 0: //Software breakpoint
+ BreakType = SoftwareBreakpoint;
+ break;
+
+ case 1: //Hardware breakpoint
+ BreakType = InstructionExecution;
+ break;
+
+ case 2: //Write watchpoint
+ BreakType = DataWrite;
+ break;
+
+ case 3: //Read watchpoint
+ BreakType = DataRead;
+ break;
+
+ case 4: //Access watchpoint
+ BreakType = DataReadWrite;
+ break;
+
+ default :
+ Print ((CHAR16 *)L"Insert breakpoint default: %x\n", Type);
+ SendError (GDB_EINVALIDBRKPOINTTYPE);
+ return;
+ }
+
+ // Find next free debug register
+ Status = FindNextFreeDebugRegister (SystemContext, &Register);
+ if (EFI_ERROR(Status)) {
+ Print ((CHAR16 *)L"No space left on device\n");
+ SendError (GDB_ENOSPACE);
+ return;
+ }
+
+ // Write Address, length data at particular DR register
+ Status = EnableDebugRegister (SystemContext, Register, Address, Length, (UINTN)BreakType);
+ if (EFI_ERROR(Status)) {
+ if (Status == EFI_UNSUPPORTED) {
+ SendNotSupported();
+ return;
+ }
+
+ SendError (GDB_EINVALIDARG);
+ return;
+ }
+
+ SendSuccess ();
+}
+
+
+/**
+ ‘z1, [addr], [length]’
+ ‘z2, [addr], [length]’
+ ‘z3, [addr], [length]’
+ ‘z4, [addr], [length]’
+
+ Remove hardware breakpoint/watchpoint at address addr of size length
+
+ @param *PacketData Pointer to the Payload data for the packet
+
+**/
+VOID
+EFIAPI
+RemoveBreakPoint (
+ IN EFI_SYSTEM_CONTEXT SystemContext,
+ IN CHAR8 *PacketData
+ )
+{
+ UINTN Type;
+ UINTN Address;
+ UINTN Length;
+ UINTN Register;
+ BREAK_TYPE BreakType = NotSupported;
+ EFI_STATUS Status;
+ UINTN ErrorCode;
+
+ //Parse breakpoint packet data
+ ErrorCode = ParseBreakpointPacket (PacketData, &Type, &Address, &Length);
+ if (ErrorCode > 0) {
+ SendError ((UINT8)ErrorCode);
+ return;
+ }
+
+ switch (Type) {
+
+ case 0: //Software breakpoint
+ BreakType = SoftwareBreakpoint;
+ break;
+
+ case 1: //Hardware breakpoint
+ BreakType = InstructionExecution;
+ break;
+
+ case 2: //Write watchpoint
+ BreakType = DataWrite;
+ break;
+
+ case 3: //Read watchpoint
+ BreakType = DataRead;
+ break;
+
+ case 4: //Access watchpoint
+ BreakType = DataReadWrite;
+ break;
+
+ default :
+ SendError (GDB_EINVALIDBRKPOINTTYPE);
+ return;
+ }
+
+ //Find matching debug register
+ Status = FindMatchingDebugRegister (SystemContext, Address, Length, (UINTN)BreakType, &Register);
+ if (EFI_ERROR(Status)) {
+ if (Status == EFI_UNSUPPORTED) {
+ SendNotSupported();
+ return;
+ }
+
+ SendError (GDB_ENOSPACE);
+ return;
+ }
+
+ //Remove breakpoint
+ Status = DisableDebugRegister(SystemContext, Register);
+ if (EFI_ERROR(Status)) {
+ SendError (GDB_EINVALIDARG);
+ return;
+ }
+
+ SendSuccess ();
+}
+
+
/**
Initialize debug agent.
diff --git a/EmbeddedPkg/Library/NullDmaLib/NullDmaLib.inf b/EmbeddedPkg/Library/NullDmaLib/NullDmaLib.inf
index 4897a8a969..8e8ccaee38 100755
--- a/EmbeddedPkg/Library/NullDmaLib/NullDmaLib.inf
+++ b/EmbeddedPkg/Library/NullDmaLib/NullDmaLib.inf
@@ -38,4 +38,4 @@
[Pcd]
[Depex]
- TRUE \ No newline at end of file
+ TRUE \ No newline at end of file
diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c
index a92a1de52e..320dddfc25 100644
--- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c
+++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c
@@ -1,852 +1,852 @@
-/** @file
-
- Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
-
- 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 <PiPei.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/PeCoffLib.h>
-#include <Library/HobLib.h>
-#include <Library/PcdLib.h>
-#include <Library/PrePiHobListPointerLib.h>
-
-#include <Protocol/PeCoffLoader.h>
-#include <Guid/ExtractSection.h>
-#include <Guid/MemoryTypeInformation.h>
-#include <Guid/MemoryAllocationHob.h>
-
-VOID
-BuildMemoryTypeInformationHob (
- VOID
- );
-
-/**
- Returns the pointer to the HOB list.
-
- This function returns the pointer to first HOB in the list.
-
- @return The pointer to the HOB list.
-
-**/
-VOID *
-EFIAPI
-GetHobList (
- VOID
- )
-{
- return PrePeiGetHobList ();
-}
-
-
-
-/**
- Updates the pointer to the HOB list.
-
- @param HobList Hob list pointer to store
-
-**/
-EFI_STATUS
-EFIAPI
-SetHobList (
- IN VOID *HobList
- )
-{
- return PrePeiSetHobList (HobList);
-}
-
-/**
-
-
-**/
-EFI_HOB_HANDOFF_INFO_TABLE*
-HobConstructor (
- IN VOID *EfiMemoryBegin,
- IN UINTN EfiMemoryLength,
- IN VOID *EfiFreeMemoryBottom,
- IN VOID *EfiFreeMemoryTop
- )
-{
- EFI_HOB_HANDOFF_INFO_TABLE *Hob;
- EFI_HOB_GENERIC_HEADER *HobEnd;
-
- Hob = EfiFreeMemoryBottom;
- HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
-
- Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
- Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
- Hob->Header.Reserved = 0;
-
- HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
- HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
- HobEnd->Reserved = 0;
-
- Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
- Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;
-
- Hob->EfiMemoryTop = (UINTN)EfiMemoryBegin + EfiMemoryLength;
- Hob->EfiMemoryBottom = (UINTN)EfiMemoryBegin;
- Hob->EfiFreeMemoryTop = (UINTN)EfiFreeMemoryTop;
- Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
- Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
-
- return Hob;
-}
-
-VOID *
-CreateHob (
- IN UINT16 HobType,
- IN UINT16 HobLength
- )
-{
- EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
- EFI_HOB_GENERIC_HEADER *HobEnd;
- EFI_PHYSICAL_ADDRESS FreeMemory;
- VOID *Hob;
-
- HandOffHob = GetHobList ();
-
- HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
-
- FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
-
- if (FreeMemory < HobLength) {
- return NULL;
- }
-
- Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
- ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
- ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
- ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
-
- HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
- HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
-
- HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
- HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
- HobEnd->Reserved = 0;
- HobEnd++;
- HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
-
- return Hob;
-}
-
-/**
- Builds a HOB that describes a chunk of system memory.
-
- This function builds a HOB that describes a chunk of system memory.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ResourceType The type of resource described by this HOB.
- @param ResourceAttribute The resource attributes of the memory described by this HOB.
- @param PhysicalStart The 64 bit physical address of memory described by this HOB.
- @param NumberOfBytes The length of the memory described by this HOB in bytes.
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorHob (
- IN EFI_RESOURCE_TYPE ResourceType,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes
- )
-{
- EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
-
- Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
- ASSERT(Hob != NULL);
-
- Hob->ResourceType = ResourceType;
- Hob->ResourceAttribute = ResourceAttribute;
- Hob->PhysicalStart = PhysicalStart;
- Hob->ResourceLength = NumberOfBytes;
-}
-
-/**
-
-
-**/
-VOID
-CreateHobList (
- IN VOID *MemoryBegin,
- IN UINTN MemoryLength,
- IN VOID *HobBase,
- IN VOID *StackBase
- )
-{
- EFI_HOB_HANDOFF_INFO_TABLE *Hob;
- EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
-
- Hob = HobConstructor (MemoryBegin,MemoryLength,HobBase,StackBase);
- SetHobList (Hob);
-
- BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
-
- Attributes =(
- EFI_RESOURCE_ATTRIBUTE_PRESENT |
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
- EFI_RESOURCE_ATTRIBUTE_TESTED |
- EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
- );
-
- BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attributes, (UINTN)MemoryBegin, MemoryLength);
-
- BuildStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)StackBase, ((UINTN)MemoryBegin + MemoryLength) - (UINTN)StackBase);
-
- if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
- // Optional feature that helps prevent EFI memory map fragmentation.
- BuildMemoryTypeInformationHob ();
- }
-}
-
-
-VOID
-EFIAPI
-BuildFvHobs (
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute
- )
-{
-
- EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
-
- BuildFvHob (PhysicalStart, NumberOfBytes);
-
- if (ResourceAttribute == NULL) {
- Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT |
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
- EFI_RESOURCE_ATTRIBUTE_TESTED |
- EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
- } else {
- Resource = *ResourceAttribute;
- }
-
- BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
-}
-
-/**
- Returns the next instance of a HOB type from the starting HOB.
-
- This function searches the first instance of a HOB type from the starting HOB pointer.
- If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
- In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
- unconditionally: it returns HobStart back if HobStart itself meets the requirement;
- caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
- If HobStart is NULL, then ASSERT().
-
- @param Type The HOB type to return.
- @param HobStart The starting HOB pointer to search from.
-
- @return The next instance of a HOB type from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetNextHob (
- IN UINT16 Type,
- IN CONST VOID *HobStart
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- ASSERT (HobStart != NULL);
-
- Hob.Raw = (UINT8 *) HobStart;
- //
- // Parse the HOB list until end of list or matching type is found.
- //
- while (!END_OF_HOB_LIST (Hob)) {
- if (Hob.Header->HobType == Type) {
- return Hob.Raw;
- }
- Hob.Raw = GET_NEXT_HOB (Hob);
- }
- return NULL;
-}
-
-
-
-/**
- Returns the first instance of a HOB type among the whole HOB list.
-
- This function searches the first instance of a HOB type among the whole HOB list.
- If there does not exist such HOB type in the HOB list, it will return NULL.
-
- @param Type The HOB type to return.
-
- @return The next instance of a HOB type from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetFirstHob (
- IN UINT16 Type
- )
-{
- VOID *HobList;
-
- HobList = GetHobList ();
- return GetNextHob (Type, HobList);
-}
-
-
-/**
- This function searches the first instance of a HOB from the starting HOB pointer.
- Such HOB should satisfy two conditions:
- its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
- If there does not exist such HOB from the starting HOB pointer, it will return NULL.
- Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
- to extract the data section and its size info respectively.
- In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
- unconditionally: it returns HobStart back if HobStart itself meets the requirement;
- caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
- If Guid is NULL, then ASSERT().
- If HobStart is NULL, then ASSERT().
-
- @param Guid The GUID to match with in the HOB list.
- @param HobStart A pointer to a Guid.
-
- @return The next instance of the matched GUID HOB from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetNextGuidHob (
- IN CONST EFI_GUID *Guid,
- IN CONST VOID *HobStart
- ){
- EFI_PEI_HOB_POINTERS GuidHob;
-
- GuidHob.Raw = (UINT8 *) HobStart;
- while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
- if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
- break;
- }
- GuidHob.Raw = GET_NEXT_HOB (GuidHob);
- }
- return GuidHob.Raw;
-}
-
-
-/**
- This function searches the first instance of a HOB among the whole HOB list.
- Such HOB should satisfy two conditions:
- its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
- If there does not exist such HOB from the starting HOB pointer, it will return NULL.
- Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
- to extract the data section and its size info respectively.
- If Guid is NULL, then ASSERT().
-
- @param Guid The GUID to match with in the HOB list.
-
- @return The first instance of the matched GUID HOB among the whole HOB list.
-
-**/
-VOID *
-EFIAPI
-GetFirstGuidHob (
- IN CONST EFI_GUID *Guid
- )
-{
- VOID *HobList;
-
- HobList = GetHobList ();
- return GetNextGuidHob (Guid, HobList);
-}
-
-
-/**
- Get the Boot Mode from the HOB list.
-
- This function returns the system boot mode information from the
- PHIT HOB in HOB list.
-
- @param VOID
-
- @return The Boot Mode.
-
-**/
-EFI_BOOT_MODE
-EFIAPI
-GetBootMode (
- VOID
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = GetHobList ();
- return Hob.HandoffInformationTable->BootMode;
-}
-
-
-/**
- Get the Boot Mode from the HOB list.
-
- This function returns the system boot mode information from the
- PHIT HOB in HOB list.
-
- @param VOID
-
- @return The Boot Mode.
-
-**/
-EFI_STATUS
-EFIAPI
-SetBootMode (
- IN EFI_BOOT_MODE BootMode
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = GetHobList ();
- Hob.HandoffInformationTable->BootMode = BootMode;
- return BootMode;
-}
-
-/**
- Builds a HOB for a loaded PE32 module.
-
- This function builds a HOB for a loaded PE32 module.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If ModuleName is NULL, then ASSERT().
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ModuleName The GUID File Name of the module.
- @param MemoryAllocationModule The 64 bit physical address of the module.
- @param ModuleLength The length of the module in bytes.
- @param EntryPoint The 64 bit physical address of the module entry point.
-
-**/
-VOID
-EFIAPI
-BuildModuleHob (
- IN CONST EFI_GUID *ModuleName,
- IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
- IN UINT64 ModuleLength,
- IN EFI_PHYSICAL_ADDRESS EntryPoint
- )
-{
- EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;
-
- ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
- ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
-
- Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
-
- CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
- Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
- Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;
- Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;
-
- //
- // Zero the reserved space to match HOB spec
- //
- ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
-
- CopyGuid (&Hob->ModuleName, ModuleName);
- Hob->EntryPoint = EntryPoint;
-}
-
-/**
- Builds a GUID HOB with a certain data length.
-
- This function builds a customized HOB tagged with a GUID for identification
- and returns the start address of GUID HOB data so that caller can fill the customized data.
- The HOB Header and Name field is already stripped.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If Guid is NULL, then ASSERT().
- If there is no additional space for HOB creation, then ASSERT().
- If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
-
- @param Guid The GUID to tag the customized HOB.
- @param DataLength The size of the data payload for the GUID HOB.
-
- @return The start address of GUID HOB data.
-
-**/
-VOID *
-EFIAPI
-BuildGuidHob (
- IN CONST EFI_GUID *Guid,
- IN UINTN DataLength
- )
-{
- EFI_HOB_GUID_TYPE *Hob;
-
- //
- // Make sure that data length is not too long.
- //
- ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
-
- Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
- CopyGuid (&Hob->Name, Guid);
- return Hob + 1;
-}
-
-
-/**
- Copies a data buffer to a newly-built HOB.
-
- This function builds a customized HOB tagged with a GUID for identification,
- copies the input data to the HOB data field and returns the start address of the GUID HOB data.
- The HOB Header and Name field is already stripped.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If Guid is NULL, then ASSERT().
- If Data is NULL and DataLength > 0, then ASSERT().
- If there is no additional space for HOB creation, then ASSERT().
- If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
-
- @param Guid The GUID to tag the customized HOB.
- @param Data The data to be copied into the data field of the GUID HOB.
- @param DataLength The size of the data payload for the GUID HOB.
-
- @return The start address of GUID HOB data.
-
-**/
-VOID *
-EFIAPI
-BuildGuidDataHob (
- IN CONST EFI_GUID *Guid,
- IN VOID *Data,
- IN UINTN DataLength
- )
-{
- VOID *HobData;
-
- ASSERT (Data != NULL || DataLength == 0);
-
- HobData = BuildGuidHob (Guid, DataLength);
-
- return CopyMem (HobData, Data, DataLength);
-}
-
-
-/**
- Builds a Firmware Volume HOB.
-
- This function builds a Firmware Volume HOB.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The base address of the Firmware Volume.
- @param Length The size of the Firmware Volume in bytes.
-
-**/
-VOID
-EFIAPI
-BuildFvHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- )
-{
- EFI_HOB_FIRMWARE_VOLUME *Hob;
-
- Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
-
- Hob->BaseAddress = BaseAddress;
- Hob->Length = Length;
-}
-
-
-/**
- Builds a EFI_HOB_TYPE_FV2 HOB.
-
- This function builds a EFI_HOB_TYPE_FV2 HOB.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The base address of the Firmware Volume.
- @param Length The size of the Firmware Volume in bytes.
- @param FvName The name of the Firmware Volume.
- @param FileName The name of the file.
-
-**/
-VOID
-EFIAPI
-BuildFv2Hob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length,
- IN CONST EFI_GUID *FvName,
- IN CONST EFI_GUID *FileName
- )
-{
- EFI_HOB_FIRMWARE_VOLUME2 *Hob;
-
- Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
-
- Hob->BaseAddress = BaseAddress;
- Hob->Length = Length;
- CopyGuid (&Hob->FvName, FvName);
- CopyGuid (&Hob->FileName, FileName);
-}
-
-
-
-/**
- Builds a Capsule Volume HOB.
-
- This function builds a Capsule Volume HOB.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The base address of the Capsule Volume.
- @param Length The size of the Capsule Volume in bytes.
-
-**/
-VOID
-EFIAPI
-BuildCvHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- )
-{
- ASSERT (FALSE);
-}
-
-
-/**
- Builds a HOB for the CPU.
-
- This function builds a HOB for the CPU.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
- @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
-
-**/
-VOID
-EFIAPI
-BuildCpuHob (
- IN UINT8 SizeOfMemorySpace,
- IN UINT8 SizeOfIoSpace
- )
-{
- EFI_HOB_CPU *Hob;
-
- Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
-
- Hob->SizeOfMemorySpace = SizeOfMemorySpace;
- Hob->SizeOfIoSpace = SizeOfIoSpace;
-
- //
- // Zero the reserved space to match HOB spec
- //
- ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
-}
-
-
-/**
- Builds a HOB for the Stack.
-
- This function builds a HOB for the stack.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The 64 bit physical address of the Stack.
- @param Length The length of the stack in bytes.
-
-**/
-VOID
-EFIAPI
-BuildStackHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- )
-{
- EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;
-
- ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
- ((Length & (EFI_PAGE_SIZE - 1)) == 0));
-
- Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
-
- CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
- Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
- Hob->AllocDescriptor.MemoryLength = Length;
- Hob->AllocDescriptor.MemoryType = EfiBootServicesData;
-
- //
- // Zero the reserved space to match HOB spec
- //
- ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
-}
-
-
-/**
- Update the Stack Hob if the stack has been moved
-
- @param BaseAddress The 64 bit physical address of the Stack.
- @param Length The length of the stack in bytes.
-
-**/
-VOID
-UpdateStackHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = GetHobList ();
- while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
- if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
- //
- // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
- // to be reclaimed by DXE core.
- //
- BuildMemoryAllocationHob (
- Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
- Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
- EfiConventionalMemory
- );
- //
- // Update the BSP Stack Hob to reflect the new stack info.
- //
- Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
- Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
- break;
- }
- Hob.Raw = GET_NEXT_HOB (Hob);
- }
-}
-
-
-
-/**
- Builds a HOB for the memory allocation.
-
- This function builds a HOB for the memory allocation.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
- If there is no additional space for HOB creation, then ASSERT().
-
- @param BaseAddress The 64 bit physical address of the memory.
- @param Length The length of the memory allocation in bytes.
- @param MemoryType Type of memory allocated by this HOB.
-
-**/
-VOID
-EFIAPI
-BuildMemoryAllocationHob (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length,
- IN EFI_MEMORY_TYPE MemoryType
- )
-{
- EFI_HOB_MEMORY_ALLOCATION *Hob;
-
- ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
- ((Length & (EFI_PAGE_SIZE - 1)) == 0));
-
- Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
-
- ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
- Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
- Hob->AllocDescriptor.MemoryLength = Length;
- Hob->AllocDescriptor.MemoryType = MemoryType;
- //
- // Zero the reserved space to match HOB spec
- //
- ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
-}
-
-
-
-VOID
-EFIAPI
-BuildExtractSectionHob (
- IN EFI_GUID *Guid,
- IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER SectionGetInfo,
- IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER SectionExtraction
- )
-{
- EXTRACT_SECTION_DATA Data;
-
- Data.SectionGetInfo = SectionGetInfo;
- Data.SectionExtraction = SectionExtraction;
- BuildGuidDataHob (Guid, &Data, sizeof (Data));
-}
-
-PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {
- PeCoffLoaderGetImageInfo,
- PeCoffLoaderLoadImage,
- PeCoffLoaderRelocateImage,
- PeCoffLoaderImageReadFromMemory,
- PeCoffLoaderRelocateImageForRuntime,
- PeCoffLoaderUnloadImage
-};
-
-
-
-VOID
-EFIAPI
-BuildPeCoffLoaderHob (
- VOID
- )
-{
- VOID *Ptr;
-
- Ptr = &gPeCoffProtocol;
- BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));
-}
-
-// May want to put this into a library so you only need the PCD setings if you are using the feature?
-VOID
-BuildMemoryTypeInformationHob (
- VOID
- )
-{
- EFI_MEMORY_TYPE_INFORMATION Info[10];
-
- Info[0].Type = EfiACPIReclaimMemory;
- Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
- Info[1].Type = EfiACPIMemoryNVS;
- Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
- Info[2].Type = EfiReservedMemoryType;
- Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
- Info[3].Type = EfiRuntimeServicesData;
- Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
- Info[4].Type = EfiRuntimeServicesCode;
- Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
- Info[5].Type = EfiBootServicesCode;
- Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
- Info[6].Type = EfiBootServicesData;
- Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
- Info[7].Type = EfiLoaderCode;
- Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
- Info[8].Type = EfiLoaderData;
- Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
-
- // Terminator for the list
- Info[9].Type = EfiMaxMemoryType;
- Info[9].NumberOfPages = 0;
-
-
- BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
-}
-
+/** @file
+
+ Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
+
+ 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 <PiPei.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+
+#include <Protocol/PeCoffLoader.h>
+#include <Guid/ExtractSection.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/MemoryAllocationHob.h>
+
+VOID
+BuildMemoryTypeInformationHob (
+ VOID
+ );
+
+/**
+ Returns the pointer to the HOB list.
+
+ This function returns the pointer to first HOB in the list.
+
+ @return The pointer to the HOB list.
+
+**/
+VOID *
+EFIAPI
+GetHobList (
+ VOID
+ )
+{
+ return PrePeiGetHobList ();
+}
+
+
+
+/**
+ Updates the pointer to the HOB list.
+
+ @param HobList Hob list pointer to store
+
+**/
+EFI_STATUS
+EFIAPI
+SetHobList (
+ IN VOID *HobList
+ )
+{
+ return PrePeiSetHobList (HobList);
+}
+
+/**
+
+
+**/
+EFI_HOB_HANDOFF_INFO_TABLE*
+HobConstructor (
+ IN VOID *EfiMemoryBegin,
+ IN UINTN EfiMemoryLength,
+ IN VOID *EfiFreeMemoryBottom,
+ IN VOID *EfiFreeMemoryTop
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+
+ Hob = EfiFreeMemoryBottom;
+ HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
+
+ Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
+ Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
+ Hob->Header.Reserved = 0;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+
+ Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
+ Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+ Hob->EfiMemoryTop = (UINTN)EfiMemoryBegin + EfiMemoryLength;
+ Hob->EfiMemoryBottom = (UINTN)EfiMemoryBegin;
+ Hob->EfiFreeMemoryTop = (UINTN)EfiFreeMemoryTop;
+ Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
+ Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
+
+ return Hob;
+}
+
+VOID *
+CreateHob (
+ IN UINT16 HobType,
+ IN UINT16 HobLength
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+ EFI_PHYSICAL_ADDRESS FreeMemory;
+ VOID *Hob;
+
+ HandOffHob = GetHobList ();
+
+ HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
+
+ FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
+
+ if (FreeMemory < HobLength) {
+ return NULL;
+ }
+
+ Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
+
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
+ HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+ HobEnd++;
+ HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ return Hob;
+}
+
+/**
+ Builds a HOB that describes a chunk of system memory.
+
+ This function builds a HOB that describes a chunk of system memory.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes
+ )
+{
+ EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
+ ASSERT(Hob != NULL);
+
+ Hob->ResourceType = ResourceType;
+ Hob->ResourceAttribute = ResourceAttribute;
+ Hob->PhysicalStart = PhysicalStart;
+ Hob->ResourceLength = NumberOfBytes;
+}
+
+/**
+
+
+**/
+VOID
+CreateHobList (
+ IN VOID *MemoryBegin,
+ IN UINTN MemoryLength,
+ IN VOID *HobBase,
+ IN VOID *StackBase
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
+
+ Hob = HobConstructor (MemoryBegin,MemoryLength,HobBase,StackBase);
+ SetHobList (Hob);
+
+ BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
+
+ Attributes =(
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_TESTED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+ );
+
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attributes, (UINTN)MemoryBegin, MemoryLength);
+
+ BuildStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)StackBase, ((UINTN)MemoryBegin + MemoryLength) - (UINTN)StackBase);
+
+ if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
+ // Optional feature that helps prevent EFI memory map fragmentation.
+ BuildMemoryTypeInformationHob ();
+ }
+}
+
+
+VOID
+EFIAPI
+BuildFvHobs (
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE *ResourceAttribute
+ )
+{
+
+ EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
+
+ BuildFvHob (PhysicalStart, NumberOfBytes);
+
+ if (ResourceAttribute == NULL) {
+ Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_TESTED |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
+ } else {
+ Resource = *ResourceAttribute;
+ }
+
+ BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
+}
+
+/**
+ Returns the next instance of a HOB type from the starting HOB.
+
+ This function searches the first instance of a HOB type from the starting HOB pointer.
+ If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
+ In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+ unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+ caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+ If HobStart is NULL, then ASSERT().
+
+ @param Type The HOB type to return.
+ @param HobStart The starting HOB pointer to search from.
+
+ @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextHob (
+ IN UINT16 Type,
+ IN CONST VOID *HobStart
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ ASSERT (HobStart != NULL);
+
+ Hob.Raw = (UINT8 *) HobStart;
+ //
+ // Parse the HOB list until end of list or matching type is found.
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == Type) {
+ return Hob.Raw;
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ return NULL;
+}
+
+
+
+/**
+ Returns the first instance of a HOB type among the whole HOB list.
+
+ This function searches the first instance of a HOB type among the whole HOB list.
+ If there does not exist such HOB type in the HOB list, it will return NULL.
+
+ @param Type The HOB type to return.
+
+ @return The next instance of a HOB type from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetFirstHob (
+ IN UINT16 Type
+ )
+{
+ VOID *HobList;
+
+ HobList = GetHobList ();
+ return GetNextHob (Type, HobList);
+}
+
+
+/**
+ This function searches the first instance of a HOB from the starting HOB pointer.
+ Such HOB should satisfy two conditions:
+ its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
+ If there does not exist such HOB from the starting HOB pointer, it will return NULL.
+ Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+ to extract the data section and its size info respectively.
+ In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
+ unconditionally: it returns HobStart back if HobStart itself meets the requirement;
+ caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
+ If Guid is NULL, then ASSERT().
+ If HobStart is NULL, then ASSERT().
+
+ @param Guid The GUID to match with in the HOB list.
+ @param HobStart A pointer to a Guid.
+
+ @return The next instance of the matched GUID HOB from the starting HOB.
+
+**/
+VOID *
+EFIAPI
+GetNextGuidHob (
+ IN CONST EFI_GUID *Guid,
+ IN CONST VOID *HobStart
+ ){
+ EFI_PEI_HOB_POINTERS GuidHob;
+
+ GuidHob.Raw = (UINT8 *) HobStart;
+ while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
+ if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
+ break;
+ }
+ GuidHob.Raw = GET_NEXT_HOB (GuidHob);
+ }
+ return GuidHob.Raw;
+}
+
+
+/**
+ This function searches the first instance of a HOB among the whole HOB list.
+ Such HOB should satisfy two conditions:
+ its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
+ If there does not exist such HOB from the starting HOB pointer, it will return NULL.
+ Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
+ to extract the data section and its size info respectively.
+ If Guid is NULL, then ASSERT().
+
+ @param Guid The GUID to match with in the HOB list.
+
+ @return The first instance of the matched GUID HOB among the whole HOB list.
+
+**/
+VOID *
+EFIAPI
+GetFirstGuidHob (
+ IN CONST EFI_GUID *Guid
+ )
+{
+ VOID *HobList;
+
+ HobList = GetHobList ();
+ return GetNextGuidHob (Guid, HobList);
+}
+
+
+/**
+ Get the Boot Mode from the HOB list.
+
+ This function returns the system boot mode information from the
+ PHIT HOB in HOB list.
+
+ @param VOID
+
+ @return The Boot Mode.
+
+**/
+EFI_BOOT_MODE
+EFIAPI
+GetBootMode (
+ VOID
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = GetHobList ();
+ return Hob.HandoffInformationTable->BootMode;
+}
+
+
+/**
+ Get the Boot Mode from the HOB list.
+
+ This function returns the system boot mode information from the
+ PHIT HOB in HOB list.
+
+ @param VOID
+
+ @return The Boot Mode.
+
+**/
+EFI_STATUS
+EFIAPI
+SetBootMode (
+ IN EFI_BOOT_MODE BootMode
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = GetHobList ();
+ Hob.HandoffInformationTable->BootMode = BootMode;
+ return BootMode;
+}
+
+/**
+ Builds a HOB for a loaded PE32 module.
+
+ This function builds a HOB for a loaded PE32 module.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If ModuleName is NULL, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ModuleName The GUID File Name of the module.
+ @param MemoryAllocationModule The 64 bit physical address of the module.
+ @param ModuleLength The length of the module in bytes.
+ @param EntryPoint The 64 bit physical address of the module entry point.
+
+**/
+VOID
+EFIAPI
+BuildModuleHob (
+ IN CONST EFI_GUID *ModuleName,
+ IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,
+ IN UINT64 ModuleLength,
+ IN EFI_PHYSICAL_ADDRESS EntryPoint
+ )
+{
+ EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;
+
+ ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
+ ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
+
+ Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
+
+ CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
+ Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
+ Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;
+ Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;
+
+ //
+ // Zero the reserved space to match HOB spec
+ //
+ ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
+
+ CopyGuid (&Hob->ModuleName, ModuleName);
+ Hob->EntryPoint = EntryPoint;
+}
+
+/**
+ Builds a GUID HOB with a certain data length.
+
+ This function builds a customized HOB tagged with a GUID for identification
+ and returns the start address of GUID HOB data so that caller can fill the customized data.
+ The HOB Header and Name field is already stripped.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If Guid is NULL, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+ If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+ @param Guid The GUID to tag the customized HOB.
+ @param DataLength The size of the data payload for the GUID HOB.
+
+ @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidHob (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN DataLength
+ )
+{
+ EFI_HOB_GUID_TYPE *Hob;
+
+ //
+ // Make sure that data length is not too long.
+ //
+ ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
+
+ Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
+ CopyGuid (&Hob->Name, Guid);
+ return Hob + 1;
+}
+
+
+/**
+ Copies a data buffer to a newly-built HOB.
+
+ This function builds a customized HOB tagged with a GUID for identification,
+ copies the input data to the HOB data field and returns the start address of the GUID HOB data.
+ The HOB Header and Name field is already stripped.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If Guid is NULL, then ASSERT().
+ If Data is NULL and DataLength > 0, then ASSERT().
+ If there is no additional space for HOB creation, then ASSERT().
+ If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
+
+ @param Guid The GUID to tag the customized HOB.
+ @param Data The data to be copied into the data field of the GUID HOB.
+ @param DataLength The size of the data payload for the GUID HOB.
+
+ @return The start address of GUID HOB data.
+
+**/
+VOID *
+EFIAPI
+BuildGuidDataHob (
+ IN CONST EFI_GUID *Guid,
+ IN VOID *Data,
+ IN UINTN DataLength
+ )
+{
+ VOID *HobData;
+
+ ASSERT (Data != NULL || DataLength == 0);
+
+ HobData = BuildGuidHob (Guid, DataLength);
+
+ return CopyMem (HobData, Data, DataLength);
+}
+
+
+/**
+ Builds a Firmware Volume HOB.
+
+ This function builds a Firmware Volume HOB.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Firmware Volume.
+ @param Length The size of the Firmware Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildFvHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ EFI_HOB_FIRMWARE_VOLUME *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
+
+ Hob->BaseAddress = BaseAddress;
+ Hob->Length = Length;
+}
+
+
+/**
+ Builds a EFI_HOB_TYPE_FV2 HOB.
+
+ This function builds a EFI_HOB_TYPE_FV2 HOB.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Firmware Volume.
+ @param Length The size of the Firmware Volume in bytes.
+ @param FvName The name of the Firmware Volume.
+ @param FileName The name of the file.
+
+**/
+VOID
+EFIAPI
+BuildFv2Hob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN CONST EFI_GUID *FvName,
+ IN CONST EFI_GUID *FileName
+ )
+{
+ EFI_HOB_FIRMWARE_VOLUME2 *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
+
+ Hob->BaseAddress = BaseAddress;
+ Hob->Length = Length;
+ CopyGuid (&Hob->FvName, FvName);
+ CopyGuid (&Hob->FileName, FileName);
+}
+
+
+
+/**
+ Builds a Capsule Volume HOB.
+
+ This function builds a Capsule Volume HOB.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The base address of the Capsule Volume.
+ @param Length The size of the Capsule Volume in bytes.
+
+**/
+VOID
+EFIAPI
+BuildCvHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ ASSERT (FALSE);
+}
+
+
+/**
+ Builds a HOB for the CPU.
+
+ This function builds a HOB for the CPU.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param SizeOfMemorySpace The maximum physical memory addressability of the processor.
+ @param SizeOfIoSpace The maximum physical I/O addressability of the processor.
+
+**/
+VOID
+EFIAPI
+BuildCpuHob (
+ IN UINT8 SizeOfMemorySpace,
+ IN UINT8 SizeOfIoSpace
+ )
+{
+ EFI_HOB_CPU *Hob;
+
+ Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
+
+ Hob->SizeOfMemorySpace = SizeOfMemorySpace;
+ Hob->SizeOfIoSpace = SizeOfIoSpace;
+
+ //
+ // Zero the reserved space to match HOB spec
+ //
+ ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
+}
+
+
+/**
+ Builds a HOB for the Stack.
+
+ This function builds a HOB for the stack.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The 64 bit physical address of the Stack.
+ @param Length The length of the stack in bytes.
+
+**/
+VOID
+EFIAPI
+BuildStackHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;
+
+ ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
+ ((Length & (EFI_PAGE_SIZE - 1)) == 0));
+
+ Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
+
+ CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
+ Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+ Hob->AllocDescriptor.MemoryLength = Length;
+ Hob->AllocDescriptor.MemoryType = EfiBootServicesData;
+
+ //
+ // Zero the reserved space to match HOB spec
+ //
+ ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
+}
+
+
+/**
+ Update the Stack Hob if the stack has been moved
+
+ @param BaseAddress The 64 bit physical address of the Stack.
+ @param Length The length of the stack in bytes.
+
+**/
+VOID
+UpdateStackHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = GetHobList ();
+ while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
+ if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
+ //
+ // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
+ // to be reclaimed by DXE core.
+ //
+ BuildMemoryAllocationHob (
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
+ EfiConventionalMemory
+ );
+ //
+ // Update the BSP Stack Hob to reflect the new stack info.
+ //
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+ Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
+ break;
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+}
+
+
+
+/**
+ Builds a HOB for the memory allocation.
+
+ This function builds a HOB for the memory allocation.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param BaseAddress The 64 bit physical address of the memory.
+ @param Length The length of the memory allocation in bytes.
+ @param MemoryType Type of memory allocated by this HOB.
+
+**/
+VOID
+EFIAPI
+BuildMemoryAllocationHob (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+{
+ EFI_HOB_MEMORY_ALLOCATION *Hob;
+
+ ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
+ ((Length & (EFI_PAGE_SIZE - 1)) == 0));
+
+ Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
+
+ ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
+ Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+ Hob->AllocDescriptor.MemoryLength = Length;
+ Hob->AllocDescriptor.MemoryType = MemoryType;
+ //
+ // Zero the reserved space to match HOB spec
+ //
+ ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
+}
+
+
+
+VOID
+EFIAPI
+BuildExtractSectionHob (
+ IN EFI_GUID *Guid,
+ IN EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER SectionGetInfo,
+ IN EXTRACT_GUIDED_SECTION_DECODE_HANDLER SectionExtraction
+ )
+{
+ EXTRACT_SECTION_DATA Data;
+
+ Data.SectionGetInfo = SectionGetInfo;
+ Data.SectionExtraction = SectionExtraction;
+ BuildGuidDataHob (Guid, &Data, sizeof (Data));
+}
+
+PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {
+ PeCoffLoaderGetImageInfo,
+ PeCoffLoaderLoadImage,
+ PeCoffLoaderRelocateImage,
+ PeCoffLoaderImageReadFromMemory,
+ PeCoffLoaderRelocateImageForRuntime,
+ PeCoffLoaderUnloadImage
+};
+
+
+
+VOID
+EFIAPI
+BuildPeCoffLoaderHob (
+ VOID
+ )
+{
+ VOID *Ptr;
+
+ Ptr = &gPeCoffProtocol;
+ BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));
+}
+
+// May want to put this into a library so you only need the PCD setings if you are using the feature?
+VOID
+BuildMemoryTypeInformationHob (
+ VOID
+ )
+{
+ EFI_MEMORY_TYPE_INFORMATION Info[10];
+
+ Info[0].Type = EfiACPIReclaimMemory;
+ Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
+ Info[1].Type = EfiACPIMemoryNVS;
+ Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
+ Info[2].Type = EfiReservedMemoryType;
+ Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
+ Info[3].Type = EfiRuntimeServicesData;
+ Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
+ Info[4].Type = EfiRuntimeServicesCode;
+ Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
+ Info[5].Type = EfiBootServicesCode;
+ Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
+ Info[6].Type = EfiBootServicesData;
+ Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
+ Info[7].Type = EfiLoaderCode;
+ Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
+ Info[8].Type = EfiLoaderData;
+ Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
+
+ // Terminator for the list
+ Info[9].Type = EfiMaxMemoryType;
+ Info[9].NumberOfPages = 0;
+
+
+ BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
+}
+
diff --git a/EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointer.c b/EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointer.c
index 9f9e9c7d44..bf4f80f4e4 100644
--- a/EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointer.c
+++ b/EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointer.c
@@ -17,11 +17,11 @@
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
-//
-// Have to use build system to set the original value in case we are running
-// from FLASH and globals don't work. So if you do a GetHobList() and gHobList
-// and gHobList is NULL the PCD default values are used.
-//
+//
+// Have to use build system to set the original value in case we are running
+// from FLASH and globals don't work. So if you do a GetHobList() and gHobList
+// and gHobList is NULL the PCD default values are used.
+//
VOID *gHobList = NULL;
diff --git a/EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf b/EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
index 1ba976780b..fea8f43687 100644
--- a/EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+++ b/EmbeddedPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
@@ -36,4 +36,4 @@
[FixedPcd.common]
gEmbeddedTokenSpaceGuid.PcdPrePiHobBase
- \ No newline at end of file
+ \ No newline at end of file
diff --git a/EmbeddedPkg/Library/PrePiLib/FwVol.c b/EmbeddedPkg/Library/PrePiLib/FwVol.c
index 75d28a7257..9e4cdd002e 100644
--- a/EmbeddedPkg/Library/PrePiLib/FwVol.c
+++ b/EmbeddedPkg/Library/PrePiLib/FwVol.c
@@ -1,842 +1,842 @@
-/** @file
- Implementation of the 6 PEI Ffs (FV) APIs in library form.
-
- This code only knows about a FV if it has a EFI_HOB_TYPE_FV entry in the HOB list
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 <PrePi.h>
-#include <Library/ExtractGuidedSectionLib.h>
-
-
-#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
- (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
-
-
-/**
- Returns the highest bit set of the State field
-
- @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
- in the Attributes field.
- @param FfsHeader Pointer to FFS File Header
-
-
- @retval the highest bit in the State field
-
-**/
-STATIC
-EFI_FFS_FILE_STATE
-GetFileState(
- IN UINT8 ErasePolarity,
- IN EFI_FFS_FILE_HEADER *FfsHeader
- )
-{
- EFI_FFS_FILE_STATE FileState;
- EFI_FFS_FILE_STATE HighestBit;
-
- FileState = FfsHeader->State;
-
- if (ErasePolarity != 0) {
- FileState = (EFI_FFS_FILE_STATE)~FileState;
- }
-
- HighestBit = 0x80;
- while (HighestBit != 0 && (HighestBit & FileState) == 0) {
- HighestBit >>= 1;
- }
-
- return HighestBit;
-}
-
-
-/**
- Calculates the checksum of the header of a file.
- The header is a zero byte checksum, so zero means header is good
-
- @param FfsHeader Pointer to FFS File Header
-
- @retval Checksum of the header
-
-**/
-STATIC
-UINT8
-CalculateHeaderChecksum (
- IN EFI_FFS_FILE_HEADER *FileHeader
- )
-{
- UINT8 *Ptr;
- UINTN Index;
- UINT8 Sum;
-
- Sum = 0;
- Ptr = (UINT8 *)FileHeader;
-
- for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {
- Sum = (UINT8)(Sum + Ptr[Index]);
- Sum = (UINT8)(Sum + Ptr[Index+1]);
- Sum = (UINT8)(Sum + Ptr[Index+2]);
- Sum = (UINT8)(Sum + Ptr[Index+3]);
- }
-
- for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
- Sum = (UINT8)(Sum + Ptr[Index]);
- }
-
- //
- // State field (since this indicates the different state of file).
- //
- Sum = (UINT8)(Sum - FileHeader->State);
- //
- // Checksum field of the file is not part of the header checksum.
- //
- Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
-
- return Sum;
-}
-
-
-/**
- Given a FileHandle return the VolumeHandle
-
- @param FileHandle File handle to look up
- @param VolumeHandle Match for FileHandle
-
- @retval TRUE VolumeHandle is valid
-
-**/
-STATIC
-BOOLEAN
-EFIAPI
-FileHandleToVolume (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT EFI_PEI_FV_HANDLE *VolumeHandle
- )
-{
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
- EFI_PEI_HOB_POINTERS Hob;
-
- Hob.Raw = GetHobList ();
- if (Hob.Raw == NULL) {
- return FALSE;
- }
-
- do {
- Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw);
- if (Hob.Raw != NULL) {
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(Hob.FirmwareVolume->BaseAddress);
- if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \
- ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) {
- *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;
- return TRUE;
- }
-
- Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob));
- }
- } while (Hob.Raw != NULL);
-
- return FALSE;
-}
-
-
-
-/**
- Given the input file pointer, search for the next matching file in the
- FFS volume as defined by SearchType. The search starts from FileHeader inside
- the Firmware Volume defined by FwVolHeader.
-
- @param FileHandle File handle to look up
- @param VolumeHandle Match for FileHandle
-
-
-**/
-EFI_STATUS
-FindFileEx (
- IN CONST EFI_PEI_FV_HANDLE FvHandle,
- IN CONST EFI_GUID *FileName, OPTIONAL
- IN EFI_FV_FILETYPE SearchType,
- IN OUT EFI_PEI_FILE_HANDLE *FileHandle
- )
-{
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
- EFI_FFS_FILE_HEADER **FileHeader;
- EFI_FFS_FILE_HEADER *FfsFileHeader;
- EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
- UINT32 FileLength;
- UINT32 FileOccupiedSize;
- UINT32 FileOffset;
- UINT64 FvLength;
- UINT8 ErasePolarity;
- UINT8 FileState;
-
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;
- FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;
-
- FvLength = FwVolHeader->FvLength;
- if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
- ErasePolarity = 1;
- } else {
- ErasePolarity = 0;
- }
-
- //
- // If FileHeader is not specified (NULL) or FileName is not NULL,
- // start with the first file in the firmware volume. Otherwise,
- // start from the FileHeader.
- //
- if ((*FileHeader == NULL) || (FileName != NULL)) {
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
- if (FwVolHeader->ExtHeaderOffset != 0) {
- FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);
- }
- } else {
- //
- // Length is 24 bits wide so mask upper 8 bits
- // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
- //
- FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
- FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
- }
-
- FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
- ASSERT (FileOffset <= 0xFFFFFFFF);
-
- while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
- //
- // Get FileState which is the highest bit of the State
- //
- FileState = GetFileState (ErasePolarity, FfsFileHeader);
-
- switch (FileState) {
-
- case EFI_FILE_HEADER_INVALID:
- FileOffset += sizeof(EFI_FFS_FILE_HEADER);
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
- break;
-
- case EFI_FILE_DATA_VALID:
- case EFI_FILE_MARKED_FOR_UPDATE:
- if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
- ASSERT (FALSE);
- *FileHeader = NULL;
- return EFI_NOT_FOUND;
- }
-
- FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
- FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
-
- if (FileName != NULL) {
- if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {
- *FileHeader = FfsFileHeader;
- return EFI_SUCCESS;
- }
- } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) &&
- (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) {
- *FileHeader = FfsFileHeader;
- return EFI_SUCCESS;
- }
-
- FileOffset += FileOccupiedSize;
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
- break;
-
- case EFI_FILE_DELETED:
- FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
- FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
- FileOffset += FileOccupiedSize;
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
- break;
-
- default:
- *FileHeader = NULL;
- return EFI_NOT_FOUND;
- }
- }
-
-
- *FileHeader = NULL;
- return EFI_NOT_FOUND;
-}
-
-
-/**
- Go through the file to search SectionType section,
- when meeting an encapsuled section.
-
- @param SectionType - Filter to find only section of this type.
- @param Section - From where to search.
- @param SectionSize - The file size to search.
- @param OutputBuffer - Pointer to the section to search.
-
- @retval EFI_SUCCESS
-**/
-EFI_STATUS
-FfsProcessSection (
- IN EFI_SECTION_TYPE SectionType,
- IN EFI_COMMON_SECTION_HEADER *Section,
- IN UINTN SectionSize,
- OUT VOID **OutputBuffer
- )
-{
- EFI_STATUS Status;
- UINT32 SectionLength;
- UINT32 ParsedLength;
- EFI_COMPRESSION_SECTION *CompressionSection;
- UINTN DstBufferSize;
- VOID *ScratchBuffer;
- UINT32 ScratchBufferSize;
- VOID *DstBuffer;
- UINT16 SectionAttribute;
- UINT32 AuthenticationStatus;
-
-
- *OutputBuffer = NULL;
- ParsedLength = 0;
- Status = EFI_NOT_FOUND;
- while (ParsedLength < SectionSize) {
- if (Section->Type == SectionType) {
- *OutputBuffer = (VOID *)(Section + 1);
-
- return EFI_SUCCESS;
- } else if ((Section->Type == EFI_SECTION_COMPRESSION) || (Section->Type == EFI_SECTION_GUID_DEFINED)) {
-
- if (Section->Type == EFI_SECTION_COMPRESSION) {
- CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
- SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
-
- if (CompressionSection->CompressionType != EFI_STANDARD_COMPRESSION) {
- return EFI_UNSUPPORTED;
- }
-
- Status = UefiDecompressGetInfo (
- (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
- (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
- (UINT32 *) &DstBufferSize,
- &ScratchBufferSize
- );
- } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
- Status = ExtractGuidedSectionGetInfo (
- Section,
- (UINT32 *) &DstBufferSize,
- &ScratchBufferSize,
- &SectionAttribute
- );
- }
-
- if (EFI_ERROR (Status)) {
- //
- // GetInfo failed
- //
- DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));
- return EFI_NOT_FOUND;
- }
- //
- // Allocate scratch buffer
- //
- ScratchBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
- if (ScratchBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Allocate destination buffer, extra one page for adjustment
- //
- DstBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
- // to make section data at page alignment.
- //
- DstBuffer = (UINT8 *)DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
- //
- // Call decompress function
- //
- if (Section->Type == EFI_SECTION_COMPRESSION) {
- Status = UefiDecompress (
- (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
- DstBuffer,
- ScratchBuffer
- );
- } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
- Status = ExtractGuidedSectionDecode (
- Section,
- &DstBuffer,
- ScratchBuffer,
- &AuthenticationStatus
- );
- }
-
- if (EFI_ERROR (Status)) {
- //
- // Decompress failed
- //
- DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
- return EFI_NOT_FOUND;
- } else {
- return FfsProcessSection (
- SectionType,
- DstBuffer,
- DstBufferSize,
- OutputBuffer
- );
- }
- }
-
- //
- // Size is 24 bits wide so mask upper 8 bits.
- // SectionLength is adjusted it is 4 byte aligned.
- // Go to the next section
- //
- SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
- SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
- ASSERT (SectionLength != 0);
- ParsedLength += SectionLength;
- Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
- }
-
- return EFI_NOT_FOUND;
-}
-
-
-
-/**
- This service enables discovery sections of a given type within a valid FFS file.
-
- @param SearchType The value of the section type to find.
- @param FfsFileHeader A pointer to the file header that contains the set of sections to
- be searched.
- @param SectionData A pointer to the discovered section, if successful.
-
- @retval EFI_SUCCESS The section was found.
- @retval EFI_NOT_FOUND The section was not found.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsFindSectionData (
- IN EFI_SECTION_TYPE SectionType,
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT VOID **SectionData
- )
-{
- EFI_FFS_FILE_HEADER *FfsFileHeader;
- UINT32 FileSize;
- EFI_COMMON_SECTION_HEADER *Section;
-
- FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
-
- //
- // Size is 24 bits wide so mask upper 8 bits.
- // Does not include FfsFileHeader header size
- // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
- //
- Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
- FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
- FileSize -= sizeof (EFI_FFS_FILE_HEADER);
-
- return FfsProcessSection (
- SectionType,
- Section,
- FileSize,
- SectionData
- );
-}
-
-
-
-
-
-
-/**
- This service enables discovery of additional firmware files.
-
- @param SearchType A filter to find files only of this type.
- @param FwVolHeader Pointer to the firmware volume header of the volume to search.
- This parameter must point to a valid FFS volume.
- @param FileHeader Pointer to the current file from which to begin searching.
-
- @retval EFI_SUCCESS The file was found.
- @retval EFI_NOT_FOUND The file was not found.
- @retval EFI_NOT_FOUND The header checksum was not zero.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsFindNextFile (
- IN UINT8 SearchType,
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- IN OUT EFI_PEI_FILE_HANDLE *FileHandle
- )
-{
- return FindFileEx (VolumeHandle, NULL, SearchType, FileHandle);
-}
-
-
-/**
- This service enables discovery of additional firmware volumes.
-
- @param Instance This instance of the firmware volume to find. The value 0 is the
- Boot Firmware Volume (BFV).
- @param FwVolHeader Pointer to the firmware volume header of the volume to return.
-
- @retval EFI_SUCCESS The volume was found.
- @retval EFI_NOT_FOUND The volume was not found.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsFindNextVolume (
- IN UINTN Instance,
- IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
- )
-{
- EFI_PEI_HOB_POINTERS Hob;
-
-
- Hob.Raw = GetHobList ();
- if (Hob.Raw == NULL) {
- return EFI_NOT_FOUND;
- }
-
- do {
- Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw);
- if (Hob.Raw != NULL) {
- if (Instance-- == 0) {
- *VolumeHandle = (EFI_PEI_FV_HANDLE)(UINTN)(Hob.FirmwareVolume->BaseAddress);
- return EFI_SUCCESS;
- }
-
- Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob));
- }
- } while (Hob.Raw != NULL);
-
- return EFI_NOT_FOUND;
-
-}
-
-
-/**
- Find a file in the volume by name
-
- @param FileName A pointer to the name of the file to
- find within the firmware volume.
-
- @param VolumeHandle The firmware volume to search FileHandle
- Upon exit, points to the found file's
- handle or NULL if it could not be found.
-
- @retval EFI_SUCCESS File was found.
-
- @retval EFI_NOT_FOUND File was not found.
-
- @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
- FileName was NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsFindFileByName (
- IN CONST EFI_GUID *FileName,
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- OUT EFI_PEI_FILE_HANDLE *FileHandle
- )
-{
- EFI_STATUS Status;
- if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Status = FindFileEx (VolumeHandle, FileName, 0, FileHandle);
- if (Status == EFI_NOT_FOUND) {
- *FileHandle = NULL;
- }
- return Status;
-}
-
-
-
-
-/**
- Get information about the file by name.
-
- @param FileHandle Handle of the file.
-
- @param FileInfo Upon exit, points to the file's
- information.
-
- @retval EFI_SUCCESS File information returned.
-
- @retval EFI_INVALID_PARAMETER If FileHandle does not
- represent a valid file.
-
- @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsGetFileInfo (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT EFI_FV_FILE_INFO *FileInfo
- )
-{
- UINT8 FileState;
- UINT8 ErasePolarity;
- EFI_FFS_FILE_HEADER *FileHeader;
- EFI_PEI_FV_HANDLE VolumeHandle;
-
- if ((FileHandle == NULL) || (FileInfo == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- VolumeHandle = 0;
- //
- // Retrieve the FirmwareVolume which the file resides in.
- //
- if (!FileHandleToVolume(FileHandle, &VolumeHandle)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB2_ERASE_POLARITY) {
- ErasePolarity = 1;
- } else {
- ErasePolarity = 0;
- }
-
- //
- // Get FileState which is the highest bit of the State
- //
- FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);
-
- switch (FileState) {
- case EFI_FILE_DATA_VALID:
- case EFI_FILE_MARKED_FOR_UPDATE:
- break;
- default:
- return EFI_INVALID_PARAMETER;
- }
-
- FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
- CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));
- FileInfo->FileType = FileHeader->Type;
- FileInfo->FileAttributes = FileHeader->Attributes;
- FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
- FileInfo->Buffer = (FileHeader + 1);
- return EFI_SUCCESS;
-}
-
-
-/**
- Get Information about the volume by name
-
- @param VolumeHandle Handle of the volume.
-
- @param VolumeInfo Upon exit, points to the volume's
- information.
-
- @retval EFI_SUCCESS File information returned.
-
- @retval EFI_INVALID_PARAMETER If FileHandle does not
- represent a valid file.
-
- @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsGetVolumeInfo (
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- OUT EFI_FV_INFO *VolumeInfo
- )
-{
- EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;
- EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
-
- if (VolumeInfo == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // VolumeHandle may not align at 8 byte,
- // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
- // So, Copy FvHeader into the local FvHeader structure.
- //
- CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
- //
- // Check Fv Image Signature
- //
- if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {
- return EFI_INVALID_PARAMETER;
- }
- VolumeInfo->FvAttributes = FwVolHeader.Attributes;
- VolumeInfo->FvStart = (VOID *) VolumeHandle;
- VolumeInfo->FvSize = FwVolHeader.FvLength;
- CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));
-
- if (FwVolHeader.ExtHeaderOffset != 0) {
- FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset);
- CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
- }
- return EFI_SUCCESS;
-}
-
-
-
-/**
- Search through every FV until you find a file of type FileType
-
- @param FileType File handle of a Fv type file.
- @param Volumehandle On succes Volume Handle of the match
- @param FileHandle On success File Handle of the match
-
- @retval EFI_NOT_FOUND FV image can't be found.
- @retval EFI_SUCCESS Successfully found FileType
-
-**/
-EFI_STATUS
-EFIAPI
-FfsAnyFvFindFirstFile (
- IN EFI_FV_FILETYPE FileType,
- OUT EFI_PEI_FV_HANDLE *VolumeHandle,
- OUT EFI_PEI_FILE_HANDLE *FileHandle
- )
-{
- EFI_STATUS Status;
- UINTN Instance;
-
- //
- // Search every FV for the DXE Core
- //
- Instance = 0;
- *FileHandle = NULL;
-
- while (1)
- {
- Status = FfsFindNextVolume (Instance++, VolumeHandle);
- if (EFI_ERROR (Status))
- {
- break;
- }
-
- Status = FfsFindNextFile (FileType, *VolumeHandle, FileHandle);
- if (!EFI_ERROR (Status))
- {
- break;
- }
- }
-
- return Status;
-}
-
-
-
-/**
- Get Fv image from the FV type file, then add FV & FV2 Hob.
-
- @param FileHandle File handle of a Fv type file.
-
-
- @retval EFI_NOT_FOUND FV image can't be found.
- @retval EFI_SUCCESS Successfully to process it.
-
-**/
-EFI_STATUS
-EFIAPI
-FfsProcessFvFile (
- IN EFI_PEI_FILE_HANDLE FvFileHandle
- )
-{
- EFI_STATUS Status;
- EFI_PEI_FV_HANDLE FvImageHandle;
- EFI_FV_INFO FvImageInfo;
- UINT32 FvAlignment;
- VOID *FvBuffer;
- EFI_PEI_HOB_POINTERS HobFv2;
-
- FvBuffer = NULL;
-
-
- //
- // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
- // been extracted.
- //
- HobFv2.Raw = GetHobList ();
- while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
- if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) {
- //
- // this FILE has been dispatched, it will not be dispatched again.
- //
- return EFI_SUCCESS;
- }
- HobFv2.Raw = GET_NEXT_HOB (HobFv2);
- }
-
- //
- // Find FvImage in FvFile
- //
- Status = FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, FvFileHandle, (VOID **)&FvImageHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Collect FvImage Info.
- //
- ZeroMem (&FvImageInfo, sizeof (FvImageInfo));
- Status = FfsGetVolumeInfo (FvImageHandle, &FvImageInfo);
- ASSERT_EFI_ERROR (Status);
-
- //
- // FvAlignment must be more than 8 bytes required by FvHeader structure.
- //
- FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16);
- if (FvAlignment < 8) {
- FvAlignment = 8;
- }
-
- //
- // Check FvImage
- //
- if ((UINTN) FvImageInfo.FvStart % FvAlignment != 0) {
- FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvImageInfo.FvSize), FvAlignment);
- if (FvBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN) FvImageInfo.FvSize);
- //
- // Update FvImageInfo after reload FvImage to new aligned memory
- //
- FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE) FvBuffer, &FvImageInfo);
- }
-
-
- //
- // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
- //
- BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart, FvImageInfo.FvSize);
-
- //
- // Makes the encapsulated volume show up in DXE phase to skip processing of
- // encapsulated file again.
- //
- BuildFv2Hob (
- (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,
- FvImageInfo.FvSize,
- &FvImageInfo.FvName,
- &(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name)
- );
-
- return EFI_SUCCESS;
-}
-
-
+/** @file
+ Implementation of the 6 PEI Ffs (FV) APIs in library form.
+
+ This code only knows about a FV if it has a EFI_HOB_TYPE_FV entry in the HOB list
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 <PrePi.h>
+#include <Library/ExtractGuidedSectionLib.h>
+
+
+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
+ (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
+
+
+/**
+ Returns the highest bit set of the State field
+
+ @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
+ in the Attributes field.
+ @param FfsHeader Pointer to FFS File Header
+
+
+ @retval the highest bit in the State field
+
+**/
+STATIC
+EFI_FFS_FILE_STATE
+GetFileState(
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+{
+ EFI_FFS_FILE_STATE FileState;
+ EFI_FFS_FILE_STATE HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity != 0) {
+ FileState = (EFI_FFS_FILE_STATE)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && (HighestBit & FileState) == 0) {
+ HighestBit >>= 1;
+ }
+
+ return HighestBit;
+}
+
+
+/**
+ Calculates the checksum of the header of a file.
+ The header is a zero byte checksum, so zero means header is good
+
+ @param FfsHeader Pointer to FFS File Header
+
+ @retval Checksum of the header
+
+**/
+STATIC
+UINT8
+CalculateHeaderChecksum (
+ IN EFI_FFS_FILE_HEADER *FileHeader
+ )
+{
+ UINT8 *Ptr;
+ UINTN Index;
+ UINT8 Sum;
+
+ Sum = 0;
+ Ptr = (UINT8 *)FileHeader;
+
+ for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {
+ Sum = (UINT8)(Sum + Ptr[Index]);
+ Sum = (UINT8)(Sum + Ptr[Index+1]);
+ Sum = (UINT8)(Sum + Ptr[Index+2]);
+ Sum = (UINT8)(Sum + Ptr[Index+3]);
+ }
+
+ for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
+ Sum = (UINT8)(Sum + Ptr[Index]);
+ }
+
+ //
+ // State field (since this indicates the different state of file).
+ //
+ Sum = (UINT8)(Sum - FileHeader->State);
+ //
+ // Checksum field of the file is not part of the header checksum.
+ //
+ Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
+
+ return Sum;
+}
+
+
+/**
+ Given a FileHandle return the VolumeHandle
+
+ @param FileHandle File handle to look up
+ @param VolumeHandle Match for FileHandle
+
+ @retval TRUE VolumeHandle is valid
+
+**/
+STATIC
+BOOLEAN
+EFIAPI
+FileHandleToVolume (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = GetHobList ();
+ if (Hob.Raw == NULL) {
+ return FALSE;
+ }
+
+ do {
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw);
+ if (Hob.Raw != NULL) {
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(Hob.FirmwareVolume->BaseAddress);
+ if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \
+ ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) {
+ *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;
+ return TRUE;
+ }
+
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob));
+ }
+ } while (Hob.Raw != NULL);
+
+ return FALSE;
+}
+
+
+
+/**
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+ @param FileHandle File handle to look up
+ @param VolumeHandle Match for FileHandle
+
+
+**/
+EFI_STATUS
+FindFileEx (
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN CONST EFI_GUID *FileName, OPTIONAL
+ IN EFI_FV_FILETYPE SearchType,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FFS_FILE_HEADER **FileHeader;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
+ UINT32 FileLength;
+ UINT32 FileOccupiedSize;
+ UINT32 FileOffset;
+ UINT64 FvLength;
+ UINT8 ErasePolarity;
+ UINT8 FileState;
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;
+ FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;
+
+ FvLength = FwVolHeader->FvLength;
+ if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // If FileHeader is not specified (NULL) or FileName is not NULL,
+ // start with the first file in the firmware volume. Otherwise,
+ // start from the FileHeader.
+ //
+ if ((*FileHeader == NULL) || (FileName != NULL)) {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
+ if (FwVolHeader->ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);
+ }
+ } else {
+ //
+ // Length is 24 bits wide so mask upper 8 bits
+ // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
+ }
+
+ FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
+ ASSERT (FileOffset <= 0xFFFFFFFF);
+
+ while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, FfsFileHeader);
+
+ switch (FileState) {
+
+ case EFI_FILE_HEADER_INVALID:
+ FileOffset += sizeof(EFI_FFS_FILE_HEADER);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
+ break;
+
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
+ ASSERT (FALSE);
+ *FileHeader = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+
+ if (FileName != NULL) {
+ if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+ } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) &&
+ (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ case EFI_FILE_DELETED:
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ default:
+ *FileHeader = NULL;
+ return EFI_NOT_FOUND;
+ }
+ }
+
+
+ *FileHeader = NULL;
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ Go through the file to search SectionType section,
+ when meeting an encapsuled section.
+
+ @param SectionType - Filter to find only section of this type.
+ @param Section - From where to search.
+ @param SectionSize - The file size to search.
+ @param OutputBuffer - Pointer to the section to search.
+
+ @retval EFI_SUCCESS
+**/
+EFI_STATUS
+FfsProcessSection (
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_COMMON_SECTION_HEADER *Section,
+ IN UINTN SectionSize,
+ OUT VOID **OutputBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINT32 SectionLength;
+ UINT32 ParsedLength;
+ EFI_COMPRESSION_SECTION *CompressionSection;
+ UINTN DstBufferSize;
+ VOID *ScratchBuffer;
+ UINT32 ScratchBufferSize;
+ VOID *DstBuffer;
+ UINT16 SectionAttribute;
+ UINT32 AuthenticationStatus;
+
+
+ *OutputBuffer = NULL;
+ ParsedLength = 0;
+ Status = EFI_NOT_FOUND;
+ while (ParsedLength < SectionSize) {
+ if (Section->Type == SectionType) {
+ *OutputBuffer = (VOID *)(Section + 1);
+
+ return EFI_SUCCESS;
+ } else if ((Section->Type == EFI_SECTION_COMPRESSION) || (Section->Type == EFI_SECTION_GUID_DEFINED)) {
+
+ if (Section->Type == EFI_SECTION_COMPRESSION) {
+ CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+
+ if (CompressionSection->CompressionType != EFI_STANDARD_COMPRESSION) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = UefiDecompressGetInfo (
+ (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+ (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
+ (UINT32 *) &DstBufferSize,
+ &ScratchBufferSize
+ );
+ } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ Status = ExtractGuidedSectionGetInfo (
+ Section,
+ (UINT32 *) &DstBufferSize,
+ &ScratchBufferSize,
+ &SectionAttribute
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // GetInfo failed
+ //
+ DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Allocate scratch buffer
+ //
+ ScratchBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
+ if (ScratchBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Allocate destination buffer, extra one page for adjustment
+ //
+ DstBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);
+ if (DstBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header
+ // to make section data at page alignment.
+ //
+ DstBuffer = (UINT8 *)DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);
+ //
+ // Call decompress function
+ //
+ if (Section->Type == EFI_SECTION_COMPRESSION) {
+ Status = UefiDecompress (
+ (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+ DstBuffer,
+ ScratchBuffer
+ );
+ } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ Status = ExtractGuidedSectionDecode (
+ Section,
+ &DstBuffer,
+ ScratchBuffer,
+ &AuthenticationStatus
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Decompress failed
+ //
+ DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
+ } else {
+ return FfsProcessSection (
+ SectionType,
+ DstBuffer,
+ DstBufferSize,
+ OutputBuffer
+ );
+ }
+ }
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // SectionLength is adjusted it is 4 byte aligned.
+ // Go to the next section
+ //
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+ SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ ASSERT (SectionLength != 0);
+ ParsedLength += SectionLength;
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+
+/**
+ This service enables discovery sections of a given type within a valid FFS file.
+
+ @param SearchType The value of the section type to find.
+ @param FfsFileHeader A pointer to the file header that contains the set of sections to
+ be searched.
+ @param SectionData A pointer to the discovered section, if successful.
+
+ @retval EFI_SUCCESS The section was found.
+ @retval EFI_NOT_FOUND The section was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindSectionData (
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **SectionData
+ )
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINT32 FileSize;
+ EFI_COMMON_SECTION_HEADER *Section;
+
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // Does not include FfsFileHeader header size
+ // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
+ FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileSize -= sizeof (EFI_FFS_FILE_HEADER);
+
+ return FfsProcessSection (
+ SectionType,
+ Section,
+ FileSize,
+ SectionData
+ );
+}
+
+
+
+
+
+
+/**
+ This service enables discovery of additional firmware files.
+
+ @param SearchType A filter to find files only of this type.
+ @param FwVolHeader Pointer to the firmware volume header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ @param FileHeader Pointer to the current file from which to begin searching.
+
+ @retval EFI_SUCCESS The file was found.
+ @retval EFI_NOT_FOUND The file was not found.
+ @retval EFI_NOT_FOUND The header checksum was not zero.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindNextFile (
+ IN UINT8 SearchType,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+{
+ return FindFileEx (VolumeHandle, NULL, SearchType, FileHandle);
+}
+
+
+/**
+ This service enables discovery of additional firmware volumes.
+
+ @param Instance This instance of the firmware volume to find. The value 0 is the
+ Boot Firmware Volume (BFV).
+ @param FwVolHeader Pointer to the firmware volume header of the volume to return.
+
+ @retval EFI_SUCCESS The volume was found.
+ @retval EFI_NOT_FOUND The volume was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindNextVolume (
+ IN UINTN Instance,
+ IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+
+ Hob.Raw = GetHobList ();
+ if (Hob.Raw == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ do {
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, Hob.Raw);
+ if (Hob.Raw != NULL) {
+ if (Instance-- == 0) {
+ *VolumeHandle = (EFI_PEI_FV_HANDLE)(UINTN)(Hob.FirmwareVolume->BaseAddress);
+ return EFI_SUCCESS;
+ }
+
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_FV, GET_NEXT_HOB (Hob));
+ }
+ } while (Hob.Raw != NULL);
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+/**
+ Find a file in the volume by name
+
+ @param FileName A pointer to the name of the file to
+ find within the firmware volume.
+
+ @param VolumeHandle The firmware volume to search FileHandle
+ Upon exit, points to the found file's
+ handle or NULL if it could not be found.
+
+ @retval EFI_SUCCESS File was found.
+
+ @retval EFI_NOT_FOUND File was not found.
+
+ @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or
+ FileName was NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsFindFileByName (
+ IN CONST EFI_GUID *FileName,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+{
+ EFI_STATUS Status;
+ if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = FindFileEx (VolumeHandle, FileName, 0, FileHandle);
+ if (Status == EFI_NOT_FOUND) {
+ *FileHandle = NULL;
+ }
+ return Status;
+}
+
+
+
+
+/**
+ Get information about the file by name.
+
+ @param FileHandle Handle of the file.
+
+ @param FileInfo Upon exit, points to the file's
+ information.
+
+ @retval EFI_SUCCESS File information returned.
+
+ @retval EFI_INVALID_PARAMETER If FileHandle does not
+ represent a valid file.
+
+ @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsGetFileInfo (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_FV_FILE_INFO *FileInfo
+ )
+{
+ UINT8 FileState;
+ UINT8 ErasePolarity;
+ EFI_FFS_FILE_HEADER *FileHeader;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+
+ if ((FileHandle == NULL) || (FileInfo == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ VolumeHandle = 0;
+ //
+ // Retrieve the FirmwareVolume which the file resides in.
+ //
+ if (!FileHandleToVolume(FileHandle, &VolumeHandle)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB2_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);
+
+ switch (FileState) {
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
+ CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));
+ FileInfo->FileType = FileHeader->Type;
+ FileInfo->FileAttributes = FileHeader->Attributes;
+ FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
+ FileInfo->Buffer = (FileHeader + 1);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get Information about the volume by name
+
+ @param VolumeHandle Handle of the volume.
+
+ @param VolumeInfo Upon exit, points to the volume's
+ information.
+
+ @retval EFI_SUCCESS File information returned.
+
+ @retval EFI_INVALID_PARAMETER If FileHandle does not
+ represent a valid file.
+
+ @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsGetVolumeInfo (
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_FV_INFO *VolumeInfo
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
+
+ if (VolumeInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // VolumeHandle may not align at 8 byte,
+ // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
+ // So, Copy FvHeader into the local FvHeader structure.
+ //
+ CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
+ //
+ // Check Fv Image Signature
+ //
+ if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ VolumeInfo->FvAttributes = FwVolHeader.Attributes;
+ VolumeInfo->FvStart = (VOID *) VolumeHandle;
+ VolumeInfo->FvSize = FwVolHeader.FvLength;
+ CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));
+
+ if (FwVolHeader.ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset);
+ CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Search through every FV until you find a file of type FileType
+
+ @param FileType File handle of a Fv type file.
+ @param Volumehandle On succes Volume Handle of the match
+ @param FileHandle On success File Handle of the match
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully found FileType
+
+**/
+EFI_STATUS
+EFIAPI
+FfsAnyFvFindFirstFile (
+ IN EFI_FV_FILETYPE FileType,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+{
+ EFI_STATUS Status;
+ UINTN Instance;
+
+ //
+ // Search every FV for the DXE Core
+ //
+ Instance = 0;
+ *FileHandle = NULL;
+
+ while (1)
+ {
+ Status = FfsFindNextVolume (Instance++, VolumeHandle);
+ if (EFI_ERROR (Status))
+ {
+ break;
+ }
+
+ Status = FfsFindNextFile (FileType, *VolumeHandle, FileHandle);
+ if (!EFI_ERROR (Status))
+ {
+ break;
+ }
+ }
+
+ return Status;
+}
+
+
+
+/**
+ Get Fv image from the FV type file, then add FV & FV2 Hob.
+
+ @param FileHandle File handle of a Fv type file.
+
+
+ @retval EFI_NOT_FOUND FV image can't be found.
+ @retval EFI_SUCCESS Successfully to process it.
+
+**/
+EFI_STATUS
+EFIAPI
+FfsProcessFvFile (
+ IN EFI_PEI_FILE_HANDLE FvFileHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE FvImageHandle;
+ EFI_FV_INFO FvImageInfo;
+ UINT32 FvAlignment;
+ VOID *FvBuffer;
+ EFI_PEI_HOB_POINTERS HobFv2;
+
+ FvBuffer = NULL;
+
+
+ //
+ // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
+ // been extracted.
+ //
+ HobFv2.Raw = GetHobList ();
+ while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
+ if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) {
+ //
+ // this FILE has been dispatched, it will not be dispatched again.
+ //
+ return EFI_SUCCESS;
+ }
+ HobFv2.Raw = GET_NEXT_HOB (HobFv2);
+ }
+
+ //
+ // Find FvImage in FvFile
+ //
+ Status = FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, FvFileHandle, (VOID **)&FvImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Collect FvImage Info.
+ //
+ ZeroMem (&FvImageInfo, sizeof (FvImageInfo));
+ Status = FfsGetVolumeInfo (FvImageHandle, &FvImageInfo);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // FvAlignment must be more than 8 bytes required by FvHeader structure.
+ //
+ FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16);
+ if (FvAlignment < 8) {
+ FvAlignment = 8;
+ }
+
+ //
+ // Check FvImage
+ //
+ if ((UINTN) FvImageInfo.FvStart % FvAlignment != 0) {
+ FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvImageInfo.FvSize), FvAlignment);
+ if (FvBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN) FvImageInfo.FvSize);
+ //
+ // Update FvImageInfo after reload FvImage to new aligned memory
+ //
+ FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE) FvBuffer, &FvImageInfo);
+ }
+
+
+ //
+ // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
+ //
+ BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart, FvImageInfo.FvSize);
+
+ //
+ // Makes the encapsulated volume show up in DXE phase to skip processing of
+ // encapsulated file again.
+ //
+ BuildFv2Hob (
+ (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,
+ FvImageInfo.FvSize,
+ &FvImageInfo.FvName,
+ &(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name)
+ );
+
+ return EFI_SUCCESS;
+}
+
+
diff --git a/EmbeddedPkg/Library/PrePiLib/PrePi.h b/EmbeddedPkg/Library/PrePiLib/PrePi.h
index 77fe32898b..d637277d2a 100644
--- a/EmbeddedPkg/Library/PrePiLib/PrePi.h
+++ b/EmbeddedPkg/Library/PrePiLib/PrePi.h
@@ -1,46 +1,46 @@
-/** @file
- Library that helps implement monolithic PEI (i.e. PEI part of SEC)
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 _PI_PEI_H_
-#define _PI_PEI_H_
-
-#include <PiPei.h>
-
-#include <Library/BaseLib.h>
-#include <Library/PrePiLib.h>
-#include <Library/PcdLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiDecompressLib.h>
-#include <Library/PeCoffLib.h>
-#include <Library/CacheMaintenanceLib.h>
-#include <Library/TimerLib.h>
-#include <Library/PerformanceLib.h>
-
-#include <Guid/MemoryAllocationHob.h>
-
-
-#define GET_HOB_TYPE(Hob) ((Hob).Header->HobType)
-#define GET_HOB_LENGTH(Hob) ((Hob).Header->HobLength)
-#define GET_NEXT_HOB(Hob) ((Hob).Raw + GET_HOB_LENGTH (Hob))
-#define END_OF_HOB_LIST(Hob) (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_END_OF_HOB_LIST)
-
-//
-// Get the data and data size field of GUID
-//
-#define GET_GUID_HOB_DATA(GuidHob) ((VOID *) (((UINT8 *) &((GuidHob)->Name)) + sizeof (EFI_GUID)))
-#define GET_GUID_HOB_DATA_SIZE(GuidHob) (((GuidHob)->Header).HobLength - sizeof (EFI_HOB_GUID_TYPE))
-
-#endif
+/** @file
+ Library that helps implement monolithic PEI (i.e. PEI part of SEC)
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 _PI_PEI_H_
+#define _PI_PEI_H_
+
+#include <PiPei.h>
+
+#include <Library/BaseLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDecompressLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <Guid/MemoryAllocationHob.h>
+
+
+#define GET_HOB_TYPE(Hob) ((Hob).Header->HobType)
+#define GET_HOB_LENGTH(Hob) ((Hob).Header->HobLength)
+#define GET_NEXT_HOB(Hob) ((Hob).Raw + GET_HOB_LENGTH (Hob))
+#define END_OF_HOB_LIST(Hob) (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_END_OF_HOB_LIST)
+
+//
+// Get the data and data size field of GUID
+//
+#define GET_GUID_HOB_DATA(GuidHob) ((VOID *) (((UINT8 *) &((GuidHob)->Name)) + sizeof (EFI_GUID)))
+#define GET_GUID_HOB_DATA_SIZE(GuidHob) (((GuidHob)->Header).HobLength - sizeof (EFI_HOB_GUID_TYPE))
+
+#endif
diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c
index e46cafec3b..4cc974f1a9 100644
--- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c
+++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c
@@ -1,226 +1,226 @@
-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 <PrePi.h>
-
-//
-// Hack to work in NT32
-//
-EFI_STATUS
-
-EFIAPI
-
-SecWinNtPeiLoadFile (
- IN VOID *Pe32Data,
- IN EFI_PHYSICAL_ADDRESS *ImageAddress,
- IN UINT64 *ImageSize,
- IN EFI_PHYSICAL_ADDRESS *EntryPoint
- );
-
-
-EFI_STATUS
-EFIAPI
-LoadPeCoffImage (
- IN VOID *PeCoffImage,
- OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
- OUT UINT64 *ImageSize,
- OUT EFI_PHYSICAL_ADDRESS *EntryPoint
- )
-{
- RETURN_STATUS Status;
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
- VOID *Buffer;
-
- ZeroMem (&ImageContext, sizeof (ImageContext));
-
- ImageContext.Handle = PeCoffImage;
- ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
-
- Status = PeCoffLoaderGetImageInfo (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
-
- //
- // Allocate Memory for the image
- //
- Buffer = AllocatePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));
- ASSERT (Buffer != 0);
-
-
- ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
-
- //
- // Load the image to our new buffer
- //
- Status = PeCoffLoaderLoadImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Relocate the image in our new buffer
- //
- Status = PeCoffLoaderRelocateImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
-
- *ImageAddress = ImageContext.ImageAddress;
- *ImageSize = ImageContext.ImageSize;
- *EntryPoint = ImageContext.EntryPoint;
-
- //
- // Flush not needed for all architectures. We could have a processor specific
- // function in this library that does the no-op if needed.
- //
- InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);
-
- return Status;
-}
-
-
-
-typedef
-VOID
-(EFIAPI *DXE_CORE_ENTRY_POINT) (
- IN VOID *HobStart
- );
-
-EFI_STATUS
-EFIAPI
-LoadDxeCoreFromFfsFile (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN UINTN StackSize
- )
-{
- EFI_STATUS Status;
- VOID *PeCoffImage;
- EFI_PHYSICAL_ADDRESS ImageAddress;
- UINT64 ImageSize;
- EFI_PHYSICAL_ADDRESS EntryPoint;
- VOID *BaseOfStack;
- VOID *TopOfStack;
- VOID *Hob;
- EFI_FV_FILE_INFO FvFileInfo;
-
- Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
-
- Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
-// For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Extract the DxeCore GUID file name.
- //
- Status = FfsGetFileInfo (FileHandle, &FvFileInfo);
- ASSERT_EFI_ERROR (Status);
-
- BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, EntryPoint);
-
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));
-
- Hob = GetHobList ();
- if (StackSize == 0) {
- // User the current stack
-
- ((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint) (Hob);
- } else {
-
- //
- // Allocate 128KB for the Stack
- //
- BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize));
- ASSERT (BaseOfStack != NULL);
-
- //
- // Compute the top of the stack we were allocated. Pre-allocate a UINTN
- // for safety.
- //
- TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
- TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
-
- //
- // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
- //
- UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, StackSize);
-
- SwitchStack (
- (SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint,
- Hob,
- NULL,
- TopOfStack
- );
-
- }
-
- // Should never get here as DXE Core does not return
- DEBUG ((EFI_D_ERROR, "DxeCore returned\n"));
- ASSERT (FALSE);
-
- return EFI_DEVICE_ERROR;
-}
-
-
-
-EFI_STATUS
-EFIAPI
-LoadDxeCoreFromFv (
- IN UINTN *FvInstance, OPTIONAL
- IN UINTN StackSize
- )
-{
- EFI_STATUS Status;
- EFI_PEI_FV_HANDLE VolumeHandle;
- EFI_PEI_FILE_HANDLE FileHandle = NULL;
-
- if (FvInstance != NULL) {
- //
- // Caller passed in a specific FV to try, so only try that one
- //
- Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);
- if (!EFI_ERROR (Status)) {
- Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
- }
- } else {
- Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);
- }
-
- if (!EFI_ERROR (Status)) {
- return LoadDxeCoreFromFfsFile (FileHandle, StackSize);
- }
-
- return Status;
-}
-
-
-EFI_STATUS
-EFIAPI
-DecompressFirstFv (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_PEI_FV_HANDLE VolumeHandle;
- EFI_PEI_FILE_HANDLE FileHandle;
-
- Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);
- if (!EFI_ERROR (Status)) {
- Status = FfsProcessFvFile (FileHandle);
- }
-
- return Status;
-}
-
-
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 <PrePi.h>
+
+//
+// Hack to work in NT32
+//
+EFI_STATUS
+
+EFIAPI
+
+SecWinNtPeiLoadFile (
+ IN VOID *Pe32Data,
+ IN EFI_PHYSICAL_ADDRESS *ImageAddress,
+ IN UINT64 *ImageSize,
+ IN EFI_PHYSICAL_ADDRESS *EntryPoint
+ );
+
+
+EFI_STATUS
+EFIAPI
+LoadPeCoffImage (
+ IN VOID *PeCoffImage,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
+ OUT UINT64 *ImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint
+ )
+{
+ RETURN_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ VOID *Buffer;
+
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+
+ ImageContext.Handle = PeCoffImage;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Allocate Memory for the image
+ //
+ Buffer = AllocatePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));
+ ASSERT (Buffer != 0);
+
+
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
+
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+
+ *ImageAddress = ImageContext.ImageAddress;
+ *ImageSize = ImageContext.ImageSize;
+ *EntryPoint = ImageContext.EntryPoint;
+
+ //
+ // Flush not needed for all architectures. We could have a processor specific
+ // function in this library that does the no-op if needed.
+ //
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);
+
+ return Status;
+}
+
+
+
+typedef
+VOID
+(EFIAPI *DXE_CORE_ENTRY_POINT) (
+ IN VOID *HobStart
+ );
+
+EFI_STATUS
+EFIAPI
+LoadDxeCoreFromFfsFile (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN UINTN StackSize
+ )
+{
+ EFI_STATUS Status;
+ VOID *PeCoffImage;
+ EFI_PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+ VOID *BaseOfStack;
+ VOID *TopOfStack;
+ VOID *Hob;
+ EFI_FV_FILE_INFO FvFileInfo;
+
+ Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+ Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
+// For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Extract the DxeCore GUID file name.
+ //
+ Status = FfsGetFileInfo (FileHandle, &FvFileInfo);
+ ASSERT_EFI_ERROR (Status);
+
+ BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, EntryPoint);
+
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));
+
+ Hob = GetHobList ();
+ if (StackSize == 0) {
+ // User the current stack
+
+ ((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint) (Hob);
+ } else {
+
+ //
+ // Allocate 128KB for the Stack
+ //
+ BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize));
+ ASSERT (BaseOfStack != NULL);
+
+ //
+ // Compute the top of the stack we were allocated. Pre-allocate a UINTN
+ // for safety.
+ //
+ TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
+ TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
+
+ //
+ // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
+ //
+ UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, StackSize);
+
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint,
+ Hob,
+ NULL,
+ TopOfStack
+ );
+
+ }
+
+ // Should never get here as DXE Core does not return
+ DEBUG ((EFI_D_ERROR, "DxeCore returned\n"));
+ ASSERT (FALSE);
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+LoadDxeCoreFromFv (
+ IN UINTN *FvInstance, OPTIONAL
+ IN UINTN StackSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE FileHandle = NULL;
+
+ if (FvInstance != NULL) {
+ //
+ // Caller passed in a specific FV to try, so only try that one
+ //
+ Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);
+ if (!EFI_ERROR (Status)) {
+ Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
+ }
+ } else {
+ Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ return LoadDxeCoreFromFfsFile (FileHandle, StackSize);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+DecompressFirstFv (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+
+ Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);
+ if (!EFI_ERROR (Status)) {
+ Status = FfsProcessFvFile (FileHandle);
+ }
+
+ return Status;
+}
+
+
diff --git a/EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c b/EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c
index f898808deb..8d60d5ab5d 100644
--- a/EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c
+++ b/EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c
@@ -1,327 +1,327 @@
-/** @file
- Library that helps implement monolithic PEI
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
- 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 <PrePi.h>
-#include <Library/ReportStatusCodeLib.h>
-#include <Library/SerialPortLib.h>
-#include <Library/PrintLib.h>
-
-#include <Protocol/StatusCode.h>
-#include <Guid/StatusCodeDataTypeId.h>
-#include <Guid/StatusCodeDataTypeDebug.h>
-#include <FrameworkPei.h>
-
-#define EFI_STATUS_CODE_DATA_MAX_SIZE 200
-
-EFI_STATUS
-EFIAPI
-SerialReportStatusCode (
- IN EFI_STATUS_CODE_TYPE CodeType,
- IN EFI_STATUS_CODE_VALUE Value,
- IN UINT32 Instance,
- IN CONST EFI_GUID *CallerId,
- IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
- );
-
-
-EFI_STATUS_CODE_PROTOCOL gStatusCode = {
- (EFI_REPORT_STATUS_CODE)SerialReportStatusCode
-};
-
-/**
- Extracts ASSERT() information from a status code structure.
-
- Converts the status code specified by CodeType, Value, and Data to the ASSERT()
- arguments specified by Filename, Description, and LineNumber. If CodeType is
- an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and
- Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract
- Filename, Description, and LineNumber from the optional data area of the
- status code buffer specified by Data. The optional data area of Data contains
- a Null-terminated ASCII string for the FileName, followed by a Null-terminated
- ASCII string for the Description, followed by a 32-bit LineNumber. If the
- ASSERT() information could be extracted from Data, then return TRUE.
- Otherwise, FALSE is returned.
-
- If Data is NULL, then ASSERT().
- If Filename is NULL, then ASSERT().
- If Description is NULL, then ASSERT().
- If LineNumber is NULL, then ASSERT().
-
- @param CodeType The type of status code being converted.
- @param Value The status code value being converted.
- @param Data Pointer to status code data buffer.
- @param Filename Pointer to the source file name that generated the ASSERT().
- @param Description Pointer to the description of the ASSERT().
- @param LineNumber Pointer to source line number that generated the ASSERT().
-
- @retval TRUE The status code specified by CodeType, Value, and Data was
- converted ASSERT() arguments specified by Filename, Description,
- and LineNumber.
- @retval FALSE The status code specified by CodeType, Value, and Data could
- not be converted to ASSERT() arguments.
-
-**/
-BOOLEAN
-EFIAPI
-ReportStatusCodeExtractAssertInfo (
- IN EFI_STATUS_CODE_TYPE CodeType,
- IN EFI_STATUS_CODE_VALUE Value,
- IN CONST EFI_STATUS_CODE_DATA *Data,
- OUT CHAR8 **Filename,
- OUT CHAR8 **Description,
- OUT UINT32 *LineNumber
- )
-{
- EFI_DEBUG_ASSERT_DATA *AssertData;
-
- ASSERT (Data != NULL);
- ASSERT (Filename != NULL);
- ASSERT (Description != NULL);
- ASSERT (LineNumber != NULL);
-
- if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
- ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&
- ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {
- AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
- *Filename = (CHAR8 *)(AssertData + 1);
- *Description = *Filename + AsciiStrLen (*Filename) + 1;
- *LineNumber = AssertData->LineNumber;
- return TRUE;
- }
- return FALSE;
-}
-
-
-/**
- Extracts DEBUG() information from a status code structure.
-
- Converts the status code specified by Data to the DEBUG() arguments specified
- by ErrorLevel, Marker, and Format. If type GUID in Data is
- EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and
- Format from the optional data area of the status code buffer specified by Data.
- The optional data area of Data contains a 32-bit ErrorLevel followed by Marker
- which is 12 UINTN parameters, followed by a Null-terminated ASCII string for
- the Format. If the DEBUG() information could be extracted from Data, then
- return TRUE. Otherwise, FALSE is returned.
-
- If Data is NULL, then ASSERT().
- If ErrorLevel is NULL, then ASSERT().
- If Marker is NULL, then ASSERT().
- If Format is NULL, then ASSERT().
-
- @param Data Pointer to status code data buffer.
- @param ErrorLevel Pointer to error level mask for a debug message.
- @param Marker Pointer to the variable argument list associated with Format.
- @param Format Pointer to a Null-terminated ASCII format string of a
- debug message.
-
- @retval TRUE The status code specified by Data was converted DEBUG() arguments
- specified by ErrorLevel, Marker, and Format.
- @retval FALSE The status code specified by Data could not be converted to
- DEBUG() arguments.
-
-**/
-BOOLEAN
-EFIAPI
-ReportStatusCodeExtractDebugInfo (
- IN CONST EFI_STATUS_CODE_DATA *Data,
- OUT UINT32 *ErrorLevel,
- OUT BASE_LIST *Marker,
- OUT CHAR8 **Format
- )
-{
- EFI_DEBUG_INFO *DebugInfo;
-
- ASSERT (Data != NULL);
- ASSERT (ErrorLevel != NULL);
- ASSERT (Marker != NULL);
- ASSERT (Format != NULL);
-
- //
- // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE
- //
- if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {
- return FALSE;
- }
-
- //
- // Retrieve the debug information from the status code record
- //
- DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
-
- *ErrorLevel = DebugInfo->ErrorLevel;
-
- //
- // The first 12 * UINTN bytes of the string are really an
- // argument stack to support varargs on the Format string.
- //
- *Marker = (BASE_LIST) (DebugInfo + 1);
- *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
-
- return TRUE;
-}
-
-
-
-
-EFI_STATUS
-EFIAPI
-SerialReportStatusCode (
- IN EFI_STATUS_CODE_TYPE CodeType,
- IN EFI_STATUS_CODE_VALUE Value,
- IN UINT32 Instance,
- IN CONST EFI_GUID *CallerId,
- IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
- )
-{
- CHAR8 *Filename;
- CHAR8 *Description;
- CHAR8 *Format;
- CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
- UINT32 ErrorLevel;
- UINT32 LineNumber;
- UINTN CharCount;
- BASE_LIST Marker;
- EFI_DEBUG_INFO *DebugInfo;
-
- Buffer[0] = '\0';
-
-
- if (Data != NULL &&
- ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
-
- //
- // Print ASSERT() information into output buffer.
- //
- CharCount = AsciiSPrint (
- Buffer,
- EFI_STATUS_CODE_DATA_MAX_SIZE,
- "\n\rASSERT!: %a (%d): %a\n\r",
- Filename,
- LineNumber,
- Description
- );
-
-
- //
- // Callout to standard output.
- //
- SerialPortWrite ((UINT8 *)Buffer, CharCount);
- return EFI_SUCCESS;
-
- } else if (Data != NULL &&
- ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
-
- //
- // Print DEBUG() information into output buffer.
- //
- CharCount = AsciiBSPrint (
- Buffer,
- EFI_STATUS_CODE_DATA_MAX_SIZE,
- Format,
- Marker
- );
-
- } else if (Data != NULL &&
- CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&
- (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
-
- //
- // Print specific data into output buffer.
- //
- DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
- Marker = (BASE_LIST) (DebugInfo + 1);
- Format = (CHAR8 *) (((UINT64 *) (DebugInfo + 1)) + 12);
-
- CharCount = AsciiBSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);
-
- } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
- //
- // Print ERROR information into output buffer.
- //
-
- CharCount = AsciiSPrint (
- Buffer,
- EFI_STATUS_CODE_DATA_MAX_SIZE,
- "ERROR: C%x:V%x I%x",
- CodeType,
- Value,
- Instance
- );
-
- //
- // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
- //
- if (CallerId != NULL) {
- CharCount += AsciiSPrint (
- &Buffer[CharCount - 1],
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
- " %g",
- CallerId
- );
- }
-
- if (Data != NULL) {
- CharCount += AsciiSPrint (
- &Buffer[CharCount - 1],
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
- " %x",
- Data
- );
-
- }
-
-
- CharCount += AsciiSPrint (
- &Buffer[CharCount - 1],
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
- "\n\r"
- );
-
- } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
- CharCount = AsciiSPrint (
- Buffer,
- EFI_STATUS_CODE_DATA_MAX_SIZE,
- "PROGRESS CODE: V%x I%x\n\r",
- Value,
- Instance
- );
- } else {
- CharCount = AsciiSPrint (
- Buffer,
- EFI_STATUS_CODE_DATA_MAX_SIZE,
- "Undefined: C%x:V%x I%x\n\r",
- CodeType,
- Value,
- Instance
- );
-
- }
-
- SerialPortWrite ((UINT8 *)Buffer, CharCount);
- return EFI_SUCCESS;
-
-}
-
-
-VOID
-EFIAPI
-AddDxeCoreReportStatusCodeCallback (
- VOID
- )
-{
- BuildGuidDataHob (&gEfiStatusCodeRuntimeProtocolGuid, &gStatusCode, sizeof(VOID *));
-}
-
+/** @file
+ Library that helps implement monolithic PEI
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ 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 <PrePi.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/PrintLib.h>
+
+#include <Protocol/StatusCode.h>
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+#include <FrameworkPei.h>
+
+#define EFI_STATUS_CODE_DATA_MAX_SIZE 200
+
+EFI_STATUS
+EFIAPI
+SerialReportStatusCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN CONST EFI_GUID *CallerId,
+ IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
+ );
+
+
+EFI_STATUS_CODE_PROTOCOL gStatusCode = {
+ (EFI_REPORT_STATUS_CODE)SerialReportStatusCode
+};
+
+/**
+ Extracts ASSERT() information from a status code structure.
+
+ Converts the status code specified by CodeType, Value, and Data to the ASSERT()
+ arguments specified by Filename, Description, and LineNumber. If CodeType is
+ an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and
+ Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract
+ Filename, Description, and LineNumber from the optional data area of the
+ status code buffer specified by Data. The optional data area of Data contains
+ a Null-terminated ASCII string for the FileName, followed by a Null-terminated
+ ASCII string for the Description, followed by a 32-bit LineNumber. If the
+ ASSERT() information could be extracted from Data, then return TRUE.
+ Otherwise, FALSE is returned.
+
+ If Data is NULL, then ASSERT().
+ If Filename is NULL, then ASSERT().
+ If Description is NULL, then ASSERT().
+ If LineNumber is NULL, then ASSERT().
+
+ @param CodeType The type of status code being converted.
+ @param Value The status code value being converted.
+ @param Data Pointer to status code data buffer.
+ @param Filename Pointer to the source file name that generated the ASSERT().
+ @param Description Pointer to the description of the ASSERT().
+ @param LineNumber Pointer to source line number that generated the ASSERT().
+
+ @retval TRUE The status code specified by CodeType, Value, and Data was
+ converted ASSERT() arguments specified by Filename, Description,
+ and LineNumber.
+ @retval FALSE The status code specified by CodeType, Value, and Data could
+ not be converted to ASSERT() arguments.
+
+**/
+BOOLEAN
+EFIAPI
+ReportStatusCodeExtractAssertInfo (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN CONST EFI_STATUS_CODE_DATA *Data,
+ OUT CHAR8 **Filename,
+ OUT CHAR8 **Description,
+ OUT UINT32 *LineNumber
+ )
+{
+ EFI_DEBUG_ASSERT_DATA *AssertData;
+
+ ASSERT (Data != NULL);
+ ASSERT (Filename != NULL);
+ ASSERT (Description != NULL);
+ ASSERT (LineNumber != NULL);
+
+ if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
+ ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&
+ ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {
+ AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
+ *Filename = (CHAR8 *)(AssertData + 1);
+ *Description = *Filename + AsciiStrLen (*Filename) + 1;
+ *LineNumber = AssertData->LineNumber;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/**
+ Extracts DEBUG() information from a status code structure.
+
+ Converts the status code specified by Data to the DEBUG() arguments specified
+ by ErrorLevel, Marker, and Format. If type GUID in Data is
+ EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and
+ Format from the optional data area of the status code buffer specified by Data.
+ The optional data area of Data contains a 32-bit ErrorLevel followed by Marker
+ which is 12 UINTN parameters, followed by a Null-terminated ASCII string for
+ the Format. If the DEBUG() information could be extracted from Data, then
+ return TRUE. Otherwise, FALSE is returned.
+
+ If Data is NULL, then ASSERT().
+ If ErrorLevel is NULL, then ASSERT().
+ If Marker is NULL, then ASSERT().
+ If Format is NULL, then ASSERT().
+
+ @param Data Pointer to status code data buffer.
+ @param ErrorLevel Pointer to error level mask for a debug message.
+ @param Marker Pointer to the variable argument list associated with Format.
+ @param Format Pointer to a Null-terminated ASCII format string of a
+ debug message.
+
+ @retval TRUE The status code specified by Data was converted DEBUG() arguments
+ specified by ErrorLevel, Marker, and Format.
+ @retval FALSE The status code specified by Data could not be converted to
+ DEBUG() arguments.
+
+**/
+BOOLEAN
+EFIAPI
+ReportStatusCodeExtractDebugInfo (
+ IN CONST EFI_STATUS_CODE_DATA *Data,
+ OUT UINT32 *ErrorLevel,
+ OUT BASE_LIST *Marker,
+ OUT CHAR8 **Format
+ )
+{
+ EFI_DEBUG_INFO *DebugInfo;
+
+ ASSERT (Data != NULL);
+ ASSERT (ErrorLevel != NULL);
+ ASSERT (Marker != NULL);
+ ASSERT (Format != NULL);
+
+ //
+ // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE
+ //
+ if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {
+ return FALSE;
+ }
+
+ //
+ // Retrieve the debug information from the status code record
+ //
+ DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
+
+ *ErrorLevel = DebugInfo->ErrorLevel;
+
+ //
+ // The first 12 * UINTN bytes of the string are really an
+ // argument stack to support varargs on the Format string.
+ //
+ *Marker = (BASE_LIST) (DebugInfo + 1);
+ *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
+
+ return TRUE;
+}
+
+
+
+
+EFI_STATUS
+EFIAPI
+SerialReportStatusCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN CONST EFI_GUID *CallerId,
+ IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+{
+ CHAR8 *Filename;
+ CHAR8 *Description;
+ CHAR8 *Format;
+ CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+ UINT32 ErrorLevel;
+ UINT32 LineNumber;
+ UINTN CharCount;
+ BASE_LIST Marker;
+ EFI_DEBUG_INFO *DebugInfo;
+
+ Buffer[0] = '\0';
+
+
+ if (Data != NULL &&
+ ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+
+ //
+ // Print ASSERT() information into output buffer.
+ //
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "\n\rASSERT!: %a (%d): %a\n\r",
+ Filename,
+ LineNumber,
+ Description
+ );
+
+
+ //
+ // Callout to standard output.
+ //
+ SerialPortWrite ((UINT8 *)Buffer, CharCount);
+ return EFI_SUCCESS;
+
+ } else if (Data != NULL &&
+ ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+
+ //
+ // Print DEBUG() information into output buffer.
+ //
+ CharCount = AsciiBSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ Format,
+ Marker
+ );
+
+ } else if (Data != NULL &&
+ CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&
+ (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
+
+ //
+ // Print specific data into output buffer.
+ //
+ DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
+ Marker = (BASE_LIST) (DebugInfo + 1);
+ Format = (CHAR8 *) (((UINT64 *) (DebugInfo + 1)) + 12);
+
+ CharCount = AsciiBSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);
+
+ } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+ //
+ // Print ERROR information into output buffer.
+ //
+
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "ERROR: C%x:V%x I%x",
+ CodeType,
+ Value,
+ Instance
+ );
+
+ //
+ // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
+ //
+ if (CallerId != NULL) {
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ " %g",
+ CallerId
+ );
+ }
+
+ if (Data != NULL) {
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ " %x",
+ Data
+ );
+
+ }
+
+
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ "\n\r"
+ );
+
+ } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "PROGRESS CODE: V%x I%x\n\r",
+ Value,
+ Instance
+ );
+ } else {
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "Undefined: C%x:V%x I%x\n\r",
+ CodeType,
+ Value,
+ Instance
+ );
+
+ }
+
+ SerialPortWrite ((UINT8 *)Buffer, CharCount);
+ return EFI_SUCCESS;
+
+}
+
+
+VOID
+EFIAPI
+AddDxeCoreReportStatusCodeCallback (
+ VOID
+ )
+{
+ BuildGuidDataHob (&gEfiStatusCodeRuntimeProtocolGuid, &gStatusCode, sizeof(VOID *));
+}
+
diff --git a/EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf b/EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
index b88d9abf5c..ce0d13257c 100644
--- a/EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
+++ b/EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
@@ -34,4 +34,4 @@
[LibraryClasses]
IoLib
DebugLib
- \ No newline at end of file
+ \ No newline at end of file
diff --git a/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf b/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
index 446c56b39d..375cb49421 100644
--- a/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
+++ b/EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf
@@ -32,4 +32,4 @@
[LibraryClasses]
IoLib
- DebugLib \ No newline at end of file
+ DebugLib \ No newline at end of file
diff --git a/EmbeddedPkg/TemplateSec/TemplateSec.inf b/EmbeddedPkg/TemplateSec/TemplateSec.inf
index a7dad5e329..81f4ac761b 100644
--- a/EmbeddedPkg/TemplateSec/TemplateSec.inf
+++ b/EmbeddedPkg/TemplateSec/TemplateSec.inf
@@ -1,65 +1,65 @@
-#/** @file
-#
-# Component description file for DxeIpl module
-#
-# The responsibility of this module is to load the DXE Core from a Firmware Volume. This implementation i used to load a 32-bit DXE Core.
-#
-# Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
-# 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 = TemplateSec
- FILE_GUID = 1D6F730F-5A55-4078-869B-E0A18324BDC8
- MODULE_TYPE = SEC
- VERSION_STRING = 1.0
-
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64 ARM
-#
-
-[Sources.common]
- TemplateSec.c
-
-[Sources.Ia32]
-# Ia32/ResetVector.asm | MSFT
-# Ia32/ResetVector.S | GCC
-
-[Sources.X64]
-# X64/ResetVector.asm | MSFT
-# X64/ResetVector.S | GCC
-
-[Sources.ARM]
-# Arm/ResetVector.asm | RVCT
-# Arm/ResetVector.S | GCC
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
-
-
-[LibraryClasses]
- BaseLib
- DebugLib
- BaseMemoryLib
- UefiDecompressLib
- PeCoffLib
- CacheMaintenanceLib
- PrePiLib
-
-[Pcd]
- gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress
- gEmbeddedTokenSpaceGuid.PcdEmbeddedFdSize
-
+#/** @file
+#
+# Component description file for DxeIpl module
+#
+# The responsibility of this module is to load the DXE Core from a Firmware Volume. This implementation i used to load a 32-bit DXE Core.
+#
+# Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+# 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 = TemplateSec
+ FILE_GUID = 1D6F730F-5A55-4078-869B-E0A18324BDC8
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM
+#
+
+[Sources.common]
+ TemplateSec.c
+
+[Sources.Ia32]
+# Ia32/ResetVector.asm | MSFT
+# Ia32/ResetVector.S | GCC
+
+[Sources.X64]
+# X64/ResetVector.asm | MSFT
+# X64/ResetVector.S | GCC
+
+[Sources.ARM]
+# Arm/ResetVector.asm | RVCT
+# Arm/ResetVector.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ UefiDecompressLib
+ PeCoffLib
+ CacheMaintenanceLib
+ PrePiLib
+
+[Pcd]
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedFdSize
+
diff --git a/EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf b/EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
index 4a21fb4952..9deceea9c1 100644
--- a/EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+++ b/EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
@@ -47,4 +47,4 @@
gEfiDriverDiagnostics2ProtocolGuid
[Depex]
- TRUE \ No newline at end of file
+ TRUE \ No newline at end of file