Date   

Re: [PATCH 00/22] RISC-V EDK2 Port on edk2-staging/RISC-V-V2 branch

Leif Lindholm
 

Hi Abner,

Many thanks for this.
I have now gone through all of the patches, and left some specific as
well as some general comments. Please address those, or comment on why
you would prefer not changing.

For v2, could you do a few things please (some of which I've mentioned
throughout my comments on various patches):
- Run PatchCheck.py on all patches and address the output. If you
disagree with some specific failure, please comment on this below
the --- in the commit message in the generated patch.
- Run SetupGit.py in your edk2 repository (this includes installing
git-python)
- Run BaseTools/Scripts/GetMaintainer.py on each of the commits, and
add a Cc: tag for each person listed in the output to the commit
message of that patch. Then add all of those Cc:d people as Cc: tags
to the [0/xx patch for the next set. This wat they will all get Cc:d
on the patches that are relevant to them.
Few read all messages posted to edk2-devel diligently, so it's
possible they will have missed this set completely. (Feel free to
reply to your patches from v1, adding the relevant reviewers to cc.)
- Add your own entry in Maintainers.txt for the new packages.
My suggestion would be that you add yourself as a designated
reviewer (R:) for now. Find some people willing to actually sling
the patches and add them as M: for now. I would be willing to be one
of them as long as you can also find others :)
- Convert all of the .uni files to UTF-8 (no BOM, I think?).

Additionally, it would be really helpful if you could include a link
to the set on a branch in a public git repository
somewhere. Converting the .uni files to UTF-8 should make it possible
for my usual scripts to start working again, but being able to just
pull from a repo is even easier.

Best Regards,

Leif

On Wed, Sep 04, 2019 at 06:42:55PM +0800, Abner Chang wrote:
This branch "RISC-V-V2" is used to contribute RISC-V architecture on EDK2.
Compare to the old branch "RISC-V", this branch "RISC-V-V2" is created based on
the most recent edk2/master @37eef910. This is easier for reviewers to have
clear ideas of edk2 code changes for RISC-V EDK2 implementation.
Because of the code changes made on old branch "RISC-V" is stale and not
compliant with the latest RISC-V spec, this new branch has the fresh changes
for RISC-V EDK2 implementation.

The main changes of these series of patches are,
- Add RiscVPkg which conform with RISC-V Privilege Spec v1.10.
- Incorporate and leverage RISC-V OpenSBI to provide EDK2 port OpenSBI library.
- Provide RISC-V platform implementation specific drivers to EDK2 RISC-V platform
package.
- Provide generic RISC-V SMBIOS DXE drive to create SMBIOS type 4, 7 and 44 records,
in which the SMBIOS type 44 record is introduced in SMBIOS spec 3.3.0.


Abner Chang (22):
[edk2-staging/RISC-V-V2 PATCH v1]: RiscVPkg: RISC-V processor package.
[edk2-staging/RISC-V-V2 PATCH v1]: RiscVPkg/Include: Add header files
of RISC-V CPU package
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg: RISC-V sections in DEC
file.
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg/Include: RISC-V definitions.
[edk2-staging/RISC-V-V2 PATCH v1]: MdeModulePkg/CapsuleRuntimeDxe: Add
RISC-V arch.
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg/BaseCacheMaintenanceLib:
RISC-V cache maintenance implementation.
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg/BaseIoLibIntrinsic: RISC-V
I/O intrinsic functions.
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg/BasePeCoff: Add RISC-V
PE/Coff related code.
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg/BaseCpuLib: RISC-V Base CPU
library implementation.
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg/BaseSynchronizationLib:
RISC-V cache related code.
[edk2-staging/RISC-V-V2 PATCH v1]: BaseTools: BaseTools changes for
RISC-V platform.
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg/BaseLib: BaseLib for RISC-V
RV64 Processor.
[edk2-staging/RISC-V-V2 PATCH v1]: MdePkg/Include: Update SmBios
header file.
[edk2-staging/RISC-V-V2 PATCH v1]: RiscVPkg/opesbi: Add
opensbi-HOWTO.txt
[edk2-staging/RISC-V-V2 PATCH v1]: RiscVPkg/RealTimeClockRuntimeDxe:
Add RISC-V RTC Runtime Driver
[edk2-staging/RISC-V-V2 PATCH v1]: RiscVPkg/CpuDxe: Add RISC-V CPU DXE
driver.
[edk2-staging/RISC-V-V2 PATCH v1]: RiscVPkg/SmbiosDxe: RISC-V platform
generic SMBIOS DXE driver
[edk2-staging/RISC-V-V2 PATCH v1]: RiscVPkg/Library: Add/Update/Remove
Library instances for RISC-V platform
[edk2-staging/RISC-V-V2 PATCH v1]: MdeModulePkg/DxeIplPeim:RISC-V
platform DXEIPL.
[edk2-staging/RISC-V-V2 PATCH v1]: MdeModulePkg/Logo
[edk2-staging/RISC-V-V2 PATCH v1]: NetworkPkg
[edk2-staging/RISC-V-V2 PATCH v1]: BaseTools/Scripts

BaseTools/Conf/build_rule.template | 23 +-
BaseTools/Conf/tools_def.template | 108 +-
BaseTools/Scripts/GccBaseRiscV.lds | 71 ++
BaseTools/Source/C/Common/BasePeCoff.c | 19 +-
BaseTools/Source/C/Common/PeCoffLoaderEx.c | 96 ++
BaseTools/Source/C/GenFv/GenFvInternalLib.c | 281 ++++-
BaseTools/Source/C/GenFw/Elf32Convert.c | 6 +-
BaseTools/Source/C/GenFw/Elf64Convert.c | 273 ++++-
BaseTools/Source/C/GenFw/elf_common.h | 63 ++
.../Source/C/Include/IndustryStandard/PeImage.h | 10 +
BaseTools/Source/Python/Common/DataType.py | 1075 ++++++++++----------
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 13 +-
MdeModulePkg/Core/DxeIplPeim/RiscV64/DxeLoadFunc.c | 76 ++
MdeModulePkg/Logo/Logo.inf | 2 +-
.../CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf | 9 +-
MdePkg/Include/IndustryStandard/PeImage.h | 14 +-
MdePkg/Include/IndustryStandard/SmBios.h | 74 +-
MdePkg/Include/Library/BaseLib.h | 67 ++
MdePkg/Include/Protocol/DebugSupport.h | 55 +
MdePkg/Include/Protocol/PxeBaseCode.h | 8 +
MdePkg/Include/RiscV64/ProcessorBind.h | 336 ++++++
MdePkg/Include/Uefi/UefiBaseType.h | 25 +
MdePkg/Include/Uefi/UefiSpec.h | 11 +
.../BaseCacheMaintenanceLib.inf | 4 +
.../Library/BaseCacheMaintenanceLib/RiscVCache.c | 242 +++++
MdePkg/Library/BaseCpuLib/BaseCpuLib.inf | 4 +
MdePkg/Library/BaseCpuLib/RiscV/Cpu.s | 25 +
.../BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf | 8 +-
MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c | 697 +++++++++++++
MdePkg/Library/BaseLib/BaseLib.inf | 18 +-
MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c | 33 +
MdePkg/Library/BaseLib/RiscV64/CpuPause.c | 35 +
MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c | 33 +
MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c | 33 +
MdePkg/Library/BaseLib/RiscV64/FlushCache.S | 28 +
MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c | 43 +
.../Library/BaseLib/RiscV64/InternalSwitchStack.c | 61 ++
MdePkg/Library/BaseLib/RiscV64/LongJump.c | 38 +
.../Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S | 20 +
MdePkg/Library/BaseLib/RiscV64/RiscVCpuPause.S | 20 +
MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S | 33 +
.../Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S | 61 ++
MdePkg/Library/BaseLib/RiscV64/Unaligned.c | 270 +++++
MdePkg/Library/BaseLib/RiscV64/riscv_asm.h | 194 ++++
MdePkg/Library/BaseLib/RiscV64/riscv_encoding.h | 574 +++++++++++
MdePkg/Library/BaseLib/RiscV64/sbi_const.h | 53 +
MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 3 +-
MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf | 5 +
MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni | 4 +-
.../Library/BasePeCoffLib/BasePeCoffLibInternals.h | 1 +
.../Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c | 149 +++
.../BaseSynchronizationLib.inf | 6 +
.../RiscV64/Synchronization.c | 189 ++++
.../RiscV64/SynchronizationAsm.s | 84 ++
MdePkg/MdePkg.dec | 9 +
NetworkPkg/Network.dsc.inc | 2 +-
RiscVPkg/Include/Library/RealTimeClockLib.h | 136 +++
RiscVPkg/Include/Library/RiscVCpuLib.h | 74 ++
RiscVPkg/Include/Library/RiscVPlatformDxeIpl.h | 47 +
.../Library/RiscVPlatformTempMemoryInitLib.h | 23 +
RiscVPkg/Include/ProcessorSpecificDataHob.h | 99 ++
RiscVPkg/Include/RiscV.h | 168 +++
RiscVPkg/Include/SmbiosProcessorSpecificData.h | 64 ++
RiscVPkg/Include/sbi/SbiFirmwareContext.h | 44 +
RiscVPkg/Include/sbi/sbi.h | 103 ++
RiscVPkg/Include/sbi/sbi_bits.h | 23 +
RiscVPkg/Include/sbi/sbi_types.h | 24 +
.../PeiServicesTablePointerLibOpenSbi.inf | 45 +
.../PeiServicesTablePointerLibOpenSbi.uni | Bin 0 -> 2462 bytes
.../PeiServicesTablePointerOpenSbi.c | 127 +++
RiscVPkg/Library/RiscVCpuLib/Cpu.s | 121 +++
RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf | 46 +
.../RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.c | 47 +
.../RiscVDxeIplHandoffLib.inf | 39 +
.../RiscVDxeIplHandoffOpenSbiLib.c | 108 ++
.../RiscVDxeIplHandoffOpenSbiLib.inf | 39 +
.../RiscVExceptionLib/CpuExceptionHandler.s | 94 ++
.../CpuExceptionHandlerDxeLib.inf | 47 +
.../RiscVExceptionLib/CpuExceptionHandlerLib.c | 187 ++++
.../RiscVExceptionLib/CpuExceptionHandlerLib.uni | Bin 0 -> 1516 bytes
.../Library/RiscVOpensbiLib/RiscVOpensbiLib.inf | 65 ++
.../RiscVPlatformTempMemoryInitLibNull.inf | 42 +
.../Riscv64/TempMemInit.s | 31 +
.../Library/RiscVTimerLib/BaseRiscVTimerLib.inf | 40 +
RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.c | 201 ++++
RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.h | 26 +
RiscVPkg/RiscVPkg.dec | 57 ++
RiscVPkg/RiscVPkg.uni | Bin 0 -> 1718 bytes
RiscVPkg/RiscVPkgExtra.uni | Bin 0 -> 1374 bytes
RiscVPkg/Universal/CpuDxe/CpuDxe.c | 324 ++++++
RiscVPkg/Universal/CpuDxe/CpuDxe.h | 212 ++++
RiscVPkg/Universal/CpuDxe/CpuDxe.inf | 66 ++
RiscVPkg/Universal/CpuDxe/CpuDxe.uni | Bin 0 -> 1564 bytes
RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni | Bin 0 -> 1392 bytes
RiscVPkg/Universal/CpuDxe/CpuMp.h | 648 ++++++++++++
.../RealTimeClockRuntimeDxe/RealTimeClock.c | 157 +++
.../RealTimeClockRuntimeDxe.inf | 44 +
RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.c | 343 +++++++
RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.h | 38 +
RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf | 63 ++
RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.uni | Bin 0 -> 1542 bytes
.../Universal/SmbiosDxe/RiscVSmbiosDxeExtra.uni | Bin 0 -> 1438 bytes
RiscVPkg/opensbi/opensbi-HOWTO.txt | 17 +
103 files changed, 9195 insertions(+), 578 deletions(-)
create mode 100644 BaseTools/Scripts/GccBaseRiscV.lds
create mode 100644 MdeModulePkg/Core/DxeIplPeim/RiscV64/DxeLoadFunc.c
create mode 100644 MdePkg/Include/RiscV64/ProcessorBind.h
create mode 100644 MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c
create mode 100644 MdePkg/Library/BaseCpuLib/RiscV/Cpu.s
create mode 100644 MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/CpuPause.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/FlushCache.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/LongJump.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVCpuPause.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/Unaligned.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/riscv_asm.h
create mode 100644 MdePkg/Library/BaseLib/RiscV64/riscv_encoding.h
create mode 100644 MdePkg/Library/BaseLib/RiscV64/sbi_const.h
create mode 100644 MdePkg/Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c
create mode 100644 MdePkg/Library/BaseSynchronizationLib/RiscV64/Synchronization.c
create mode 100644 MdePkg/Library/BaseSynchronizationLib/RiscV64/SynchronizationAsm.s
create mode 100644 RiscVPkg/Include/Library/RealTimeClockLib.h
create mode 100644 RiscVPkg/Include/Library/RiscVCpuLib.h
create mode 100644 RiscVPkg/Include/Library/RiscVPlatformDxeIpl.h
create mode 100644 RiscVPkg/Include/Library/RiscVPlatformTempMemoryInitLib.h
create mode 100644 RiscVPkg/Include/ProcessorSpecificDataHob.h
create mode 100644 RiscVPkg/Include/RiscV.h
create mode 100644 RiscVPkg/Include/SmbiosProcessorSpecificData.h
create mode 100644 RiscVPkg/Include/sbi/SbiFirmwareContext.h
create mode 100644 RiscVPkg/Include/sbi/sbi.h
create mode 100644 RiscVPkg/Include/sbi/sbi_bits.h
create mode 100644 RiscVPkg/Include/sbi/sbi_types.h
create mode 100644 RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
create mode 100644 RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.uni
create mode 100644 RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerOpenSbi.c
create mode 100644 RiscVPkg/Library/RiscVCpuLib/Cpu.s
create mode 100644 RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf
create mode 100644 RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.c
create mode 100644 RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.inf
create mode 100644 RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.c
create mode 100644 RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.inf
create mode 100644 RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandler.s
create mode 100644 RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf
create mode 100644 RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.c
create mode 100644 RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.uni
create mode 100644 RiscVPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf
create mode 100644 RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/RiscVPlatformTempMemoryInitLibNull.inf
create mode 100644 RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/Riscv64/TempMemInit.s
create mode 100644 RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
create mode 100644 RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.c
create mode 100644 RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.h
create mode 100644 RiscVPkg/RiscVPkg.dec
create mode 100644 RiscVPkg/RiscVPkg.uni
create mode 100644 RiscVPkg/RiscVPkgExtra.uni
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.c
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.h
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.inf
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.uni
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuMp.h
create mode 100644 RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClock.c
create mode 100644 RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.c
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.h
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.uni
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxeExtra.uni
create mode 100644 RiscVPkg/opensbi/opensbi-HOWTO.txt

--
2.7.4




Re: [PATCH] ArmVirtPkg/ArmVirtPrePiUniCoreRelocatable: revert to PIE linking

Ard Biesheuvel
 

On Thu, 5 Sep 2019 at 08:55, Leif Lindholm <leif.lindholm@...> wrote:

On Thu, Sep 05, 2019 at 07:25:39AM -0700, Ard Biesheuvel wrote:
[BuildOptions]
- GCC:*_*_*_DLINK_FLAGS = -shared -Wl,-Bsymbolic -Wl,-T,$(MODULE_DIR)/Scripts/PrePi-PIE.lds
+ GCC:*_*_*_DLINK_FLAGS = -Wl,-Bsymbolic,-pie,-T,$(MODULE_DIR)/Scripts/PrePi-PIE.lds
We already merged a fix for AARCH64 though - could/should this be
active on ARM only?

A problem I have with this patch is that ArmVirtQemuKernel curently
doesn't boot on my qemu (with/without kvm, built with GCC5 or CLANG38,
with or without this patch):
ProcessPciHost: Config[0x4010000000+0x10000000) Bus[0x0..0xFF]
Io[0x0+0x10000)@0x3EFF0000 Mem32[0x10000000+0x2EFF0000)@0x0
Mem64[0x8000000000+0x8000000000)@0x0
MapGcdMmioSpace: failed to set memory space attributes for region
[0x4010000000+0x10000000)

ASSERT_EFI_ERROR (Status = Unsupported)
ASSERT [PciHostBridgeDxe]
/work/git/edk2/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c(293):
!EFI_ERROR (Status)
qemu-system-arm: terminating on signal 15 from pid 4680 (killall)
Does it work with -M virt,highmem=off ?
Ah, yes - that works fine then, also with the patch.

Well, with that, and your explanation in the other thread:
Acked-by: Leif Lindholm <leif.lindholm@...>
Thanks. I am going to replace the last paragraph of the commit log with

Note that in this particular case, we are interested in PIE linking
only (i.e., producing a .rela section containing dynamic relocations
that the startup code can process directly), and not in position
independent code generation, and by passing the -pie option to the
linker directly using -Wl,-pie (and dropping -shared), we can coerce
the GOLD linker into doing only the former rather than both when it
performs its LTO code generation.

and push (unless you have any objections)


Re: [edk2-staging/RISC-V-V2 PATCH v1 22/22]: BaseTools/Scripts

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:17PM +0800, Abner Chang wrote:
Add RISC-V specific LD scripts. ."rela(INFO)" in the latest GccBase.lds causes PE32 relocation error. This is the temporaty solution untill we find the root casue.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
I have no issue with this patch, but I can't claim to have properly
reviewed it. I'll leave that for the BaseTools maintainers.

/
Leif

---
BaseTools/Scripts/GccBaseRiscV.lds | 71 ++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 BaseTools/Scripts/GccBaseRiscV.lds

diff --git a/BaseTools/Scripts/GccBaseRiscV.lds b/BaseTools/Scripts/GccBaseRiscV.lds
new file mode 100644
index 0000000..b24086d
--- /dev/null
+++ b/BaseTools/Scripts/GccBaseRiscV.lds
@@ -0,0 +1,71 @@
+/** @file
+
+ Unified linker script for GCC based builds
+
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that 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.
+
+**/
+
+SECTIONS {
+
+ /*
+ * The PE/COFF binary consists of DOS and PE/COFF headers, and a sequence of
+ * section headers adding up to PECOFF_HEADER_SIZE bytes (which differs
+ * between 32-bit and 64-bit builds). The actual start of the .text section
+ * will be rounded up based on its actual alignment.
+ */
+ . = PECOFF_HEADER_SIZE;
+
+ .text : ALIGN(CONSTANT(COMMONPAGESIZE)) {
+ *(.text .text.* .stub .gnu.linkonce.t.*)
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.got .got.*)
+
+ /*
+ * The contents of AutoGen.c files are constant from the POV of the program,
+ * but most of its contents end up in .data or .bss by default since few of
+ * the variable definitions that get emitted are declared as CONST.
+ */
+ *:AutoGen.obj(.data.g*Guid)
+ }
+
+ /*
+ * The alignment of the .data section should be less than or equal to the
+ * alignment of the .text section. This ensures that the relative offset
+ * between these sections is the same in the ELF and the PE/COFF versions of
+ * this binary.
+ */
+ .data ALIGN(ALIGNOF(.text)) : ALIGN(CONSTANT(COMMONPAGESIZE)) {
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.bss .bss.*)
+ }
+
+ .eh_frame ALIGN(CONSTANT(COMMONPAGESIZE)) : {
+ KEEP (*(.eh_frame))
+ }
+
+ .rela ALIGN(CONSTANT(COMMONPAGESIZE)) : {
+ *(.rela .rela.*)
+ }
+
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.gnu_debuglink)
+ *(.interp)
+ *(.dynsym)
+ *(.dynstr)
+ *(.dynamic)
+ *(.hash)
+ *(.comment)
+ *(COMMON)
+ }
+}
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 21/22]: NetworkPkg

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:16PM +0800, Abner Chang wrote:
Add RISCV64 Arch.

Contributed-under: TianoCore Contribution Agreement 1.0
If you drop that contribution agreement:
Reviewed-by: Leif Lindholm <leif.lindholm@...>


Signed-off-by: Abner Chang <abner.chang@...>
---
NetworkPkg/Network.dsc.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/NetworkPkg/Network.dsc.inc b/NetworkPkg/Network.dsc.inc
index c7f4328..b484f9b 100644
--- a/NetworkPkg/Network.dsc.inc
+++ b/NetworkPkg/Network.dsc.inc
@@ -34,7 +34,7 @@
!include NetworkPkg/NetworkComponents.dsc.inc

!else
-[Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
+[Components.IA32, Components.X64, Components.ARM, Components.AARCH64, Components.RISCV64]
!include NetworkPkg/NetworkComponents.dsc.inc

!endif
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 20/22]: MdeModulePkg/Logo

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:15PM +0800, Abner Chang wrote:
Add RISCV64 Arch.

Contributed-under: TianoCore Contribution Agreement 1.0
If you drop that contribution agreement:
Reviewed-by: Leif Lindholm <leif.lindholm@...>

Signed-off-by: Abner Chang <abner.chang@...>
---
MdeModulePkg/Logo/Logo.inf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MdeModulePkg/Logo/Logo.inf b/MdeModulePkg/Logo/Logo.inf
index 0182025..243748c 100644
--- a/MdeModulePkg/Logo/Logo.inf
+++ b/MdeModulePkg/Logo/Logo.inf
@@ -19,7 +19,7 @@
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
+# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64
#

[Binaries]
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 19/22]: MdeModulePkg/DxeIplPeim:RISC-V platform DXEIPL.

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:14PM +0800, Abner Chang wrote:
- Implement RISC-V DxeIpl.
- Provide DxeIpl platform implementation-specifc library for RISC-V platform. Two libraries are provided in this commit,
* Defualt library which simply switch stack and transfer
control to DXE core.
* Switch stack, privilege mode and then transfer control to
DXE core through RISC-V opensbi.
No comments beyond SPDX/license and contribution agreement.

/
Leif

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 13 +++-
MdeModulePkg/Core/DxeIplPeim/RiscV64/DxeLoadFunc.c | 76 ++++++++++++++++++++++
2 files changed, 88 insertions(+), 1 deletion(-)
create mode 100644 MdeModulePkg/Core/DxeIplPeim/RiscV64/DxeLoadFunc.c

diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index 98bc17f..5532323 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -7,6 +7,7 @@
#
# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
+# Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -25,7 +26,7 @@
#
# The following information is for reference only and not required by the build tools.
#
-# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) AARCH64
+# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) AARCH64 RISCV64
#

[Sources]
@@ -49,6 +50,9 @@
[Sources.ARM, Sources.AARCH64]
Arm/DxeLoadFunc.c

+[Sources.RISCV64]
+ RiscV64/DxeLoadFunc.c
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
@@ -56,6 +60,9 @@
[Packages.ARM, Packages.AARCH64]
ArmPkg/ArmPkg.dec

+[Packages.RISCV64]
+ RiscVPkg/RiscVPkg.dec
+
[LibraryClasses]
PcdLib
MemoryAllocationLib
@@ -75,6 +82,10 @@
[LibraryClasses.ARM, LibraryClasses.AARCH64]
ArmMmuLib

+[LibraryClasses.RISCV64]
+ RiscVPlatformDxeIplLib
+ RiscVOpensbiLib
+
[Ppis]
gEfiDxeIplPpiGuid ## PRODUCES
gEfiPeiDecompressPpiGuid ## PRODUCES
diff --git a/MdeModulePkg/Core/DxeIplPeim/RiscV64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/RiscV64/DxeLoadFunc.c
new file mode 100644
index 0000000..934dfa5
--- /dev/null
+++ b/MdeModulePkg/Core/DxeIplPeim/RiscV64/DxeLoadFunc.c
@@ -0,0 +1,76 @@
+/** @file
+ RISC-V specific functionality for DxeLoad.
+
+ Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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 "DxeIpl.h"
+#include "Library/RiscVPlatformDxeIpl.h"
+
+typedef
+VOID*
+(EFIAPI *DXEENTRYPOINT) (
+ IN VOID *HobStart
+ );
+
+/**
+ Transfers control to DxeCore.
+
+ This function performs a CPU architecture specific operations to execute
+ the entry point of DxeCore with the parameters of HobList.
+ It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
+
+ @param DxeCoreEntryPoint The entry point of DxeCore.
+ @param HobList The start of HobList passed to DxeCore.
+
+**/
+VOID
+HandOffToDxeCore (
+ IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
+ IN EFI_PEI_HOB_POINTERS HobList
+ )
+{
+ VOID *BaseOfStack;
+ VOID *TopOfStack;
+ EFI_STATUS Status;
+ //
+ //
+ // Allocate 128KB for the Stack
+ //
+ BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
+ 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 (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
+ TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
+
+ //
+ // End of PEI phase signal
+ //
+ Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
+ //
+ UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE);
+
+ DEBUG ((EFI_D_INFO, "DXE Core new stack at %x, stack pointer at %x\n", BaseOfStack, TopOfStack));
+
+ //
+ // Transfer the control to the entry point of DxeCore.
+ //
+ RiscVPlatformHandOffToDxeCore (BaseOfStack, TopOfStack, DxeCoreEntryPoint, HobList);
+}
+
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 18/22]: RiscVPkg/Library: Add/Update/Remove Library instances for RISC-V platform

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:13PM +0800, Abner Chang wrote:
RiscVCpuLib: Add RISC-V CPU Library.
- This library provides CSR assembly functions to read/write RISC-V specific Control and Status registers.

RiscVDxeIplHandoffLib
RiscVDxeIplHandoffOpenSbiLib
- Provide DxeIpl platform implementation-specifc library for RISC-V platform. Two libraries are provided in this commit,
* Defualt library which simply switch stack and transfer
control to DXE core.
* Switch stack, privilege mode and then transfer control to
DXE core through RISC-V opensbi.

RiscvOpensbiLib
- EDK2 RISC-V OpenSBI library which pull in external source files under RiscVPkg/opensbi to the build process.

PeiServicesTablePointerLibOpenSbi
- Library instance of PEI Service Table for RISC-V platform based on OpenSBI.

RiscVPlatformTempMemoryInitLibNull
- NULL lib to return temporary memory information.

RiscVDxeIplHandoffOpenSbiLib
- This is the instance of platform level DXE IPL library based on RISC-V OpenSBI implementation.

RiscVExceptionLib
- Initial RISC-V Supervisor Mode trap handler

RiscVTimerLib
- Add RiscVTimerLib library.
- Due to RISC-V timer CSR is platform implementation specific, RISC-V timer library invokes platform level timer library mputo access to timer CSRs.
This sounds like it should really be multiple separate patches.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
.../PeiServicesTablePointerLibOpenSbi.inf | 45 +++++
.../PeiServicesTablePointerLibOpenSbi.uni | Bin 0 -> 2462 bytes
.../PeiServicesTablePointerOpenSbi.c | 127 +++++++++++++
RiscVPkg/Library/RiscVCpuLib/Cpu.s | 121 +++++++++++++
RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf | 46 +++++
.../RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.c | 47 +++++
.../RiscVDxeIplHandoffLib.inf | 39 ++++
.../RiscVDxeIplHandoffOpenSbiLib.c | 108 +++++++++++
.../RiscVDxeIplHandoffOpenSbiLib.inf | 39 ++++
.../RiscVExceptionLib/CpuExceptionHandler.s | 94 ++++++++++
.../CpuExceptionHandlerDxeLib.inf | 47 +++++
.../RiscVExceptionLib/CpuExceptionHandlerLib.c | 187 +++++++++++++++++++
.../RiscVExceptionLib/CpuExceptionHandlerLib.uni | Bin 0 -> 1516 bytes
.../Library/RiscVOpensbiLib/RiscVOpensbiLib.inf | 65 +++++++
.../RiscVPlatformTempMemoryInitLibNull.inf | 42 +++++
.../Riscv64/TempMemInit.s | 31 ++++
.../Library/RiscVTimerLib/BaseRiscVTimerLib.inf | 40 ++++
RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.c | 201 +++++++++++++++++++++
RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.h | 26 +++
19 files changed, 1305 insertions(+)
create mode 100644 RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
create mode 100644 RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.uni
create mode 100644 RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerOpenSbi.c
create mode 100644 RiscVPkg/Library/RiscVCpuLib/Cpu.s
.S, not .s

create mode 100644 RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf
create mode 100644 RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.c
create mode 100644 RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.inf
create mode 100644 RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.c
create mode 100644 RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.inf
create mode 100644 RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandler.s
.S, not .s

create mode 100644 RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf
create mode 100644 RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.c
create mode 100644 RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.uni
create mode 100644 RiscVPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf
create mode 100644 RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/RiscVPlatformTempMemoryInitLibNull.inf
create mode 100644 RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/Riscv64/TempMemInit.s
.S, not .s

create mode 100644 RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
create mode 100644 RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.c
create mode 100644 RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.h

diff --git a/RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf b/RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
new file mode 100644
index 0000000..c49377b
--- /dev/null
+++ b/RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf
@@ -0,0 +1,45 @@
+## @file
+# Instance of PEI Services Table Pointer Library using RISC-V OpenSBI FirmwareContext.
+#
+# PEI Services Table Pointer Library implementation that retrieves a pointer to the
+# PEI Services Table from a RISC-V OpenSBI sbi_platform firmware context structure.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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 = PeiServicesTablePointerLibOpenSbi
+ MODULE_UNI_FILE = PeiServicesTablePointerLibOpenSbi.uni
+ FILE_GUID = B4054E46-FE75-4290-B442-4836B1265D8F
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PeiServicesTablePointerLib|PEIM PEI_CORE
+
+ CONSTRUCTOR = PeiServicesTablePointerLibOpenSbiConstructor
+
+#
+# VALID_ARCHITECTURES = RISCV64
+#
+
+[Sources]
+ PeiServicesTablePointerOpenSbi.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+[Pcd]
+
+[LibraryClasses]
+ DebugLib
+ RiscVCpuLib
+ RiscVOpensbiLib
diff --git a/RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.uni b/RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.uni
new file mode 100644
index 0000000000000000000000000000000000000000..e7a0c4702e4b6db9a4dd433d212f34195baf6290
GIT binary patch
literal 2462
zcmchZ+iwy<6vof9iT}fdzNl$IebX2tSZaw{2&Gn^8tx@>%d)igpI3k18J2}wZDXn-
zyR$QMF5i6TGW_^nvXTX!C;WoFv4M?jY<+uZ4_Ga&$6z&^+QL$6Gj@>(HbXjC!>a5B
zJ7z7h3-q<SV5Nm@$E`_f#?BOdNd^1BtixBE=Zg6f4eby4Zes7)-rAmhVpg{~I#X6E
z?&kox#3pv>x_#tkE4$yYUR)#2PH<lcNBErkX(o<GOr&6u_rTY=&jZ-{%o29`uo0PP
zBQd|mK*~Jo<!s*->j3*R@C1C`#@7O#M|S4eg?NCb_zNEEO(p}8+vGBMyc1&6MQ`aR
zyNO>#U``Zu<{><!*nWi0W5(z9)SlT3+vWQZHZGmP)MXl=@7h=1iS^j8uHu+rO|}-u
z2isrqICd`?_sXCK(GFI|;+Qe_uG~`;q_2$ZW4&mv$e*UYz9BzaV3s$<NW2btw^!^=
z9hsslEW#^}lnJVXEA(Q{PMF8s9`QBCTAqJ8pR~tFt2R_e!X$gqzO;KQ4;Or^2J_lk
zx>T&23`z7ganzZW7`-0aSzhW)u}U+&3U##4s_HMtl4HGeF1oybJ*_fY7G*2)C12_Z
z;=V(MWPTNw){3(M>oG#YtQx(JX`7b-yKV0Y9cM)O8W|9xbc0uAT1q5ddZ$tjMs6ja
z`00x1Cd9LJjr#>F9gz3vG27mYSUKm(^IRu6BsW!?O}f!L-evp9TwO}}sj=l<t70d7
zRh{7zJ7TP|o?FP-uhF-vNF2N6I$z3Uy$g)8E2{;@iqAFM-8lOx`@&UskHJonYC5tb
z)@xXmjk<epG81;K$!7~$$;fMzIzU$5zc9XMN61yN>g@6KIz`n!ukGa4YjDvZpX76Y
zgSR}VbhpHtL~D9>)>#v)C-QfOr8+iFuvVpGl{tIdDZ^F^1i$<3c)iHhk{lU&-Y6IL
zuqC7g(EYF5YY3JZ*`+QJ=sv1`^@QvujQuz3{2KGU?K`62T-}{7Wt;9z-Jgwhgm2>P
zcD}Oey`S6tU*4U6cW3@NO6p%nL{Yt}?J?Z$$nox;Akp*gmiI+<sNj9BPX|&*ROip{
cYuyCu^?T?}$q@bb(VZq+`X^K*SF<Yl3Gf+@ZvX%Q

literal 0
HcmV?d00001

diff --git a/RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerOpenSbi.c b/RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerOpenSbi.c
new file mode 100644
index 0000000..8e68fba
--- /dev/null
+++ b/RiscVPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerOpenSbi.c
@@ -0,0 +1,127 @@
+/** @file
+ PEI Services Table Pointer Library.
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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/PeiServicesTablePointerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RiscVCpuLib.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/SbiFirmwareContext.h>
+
+/**
+ Caches a pointer PEI Services Table.
+
+ Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer
+ in a CPU specific manner as specified in the CPU binding section of the Platform Initialization
+ Pre-EFI Initialization Core Interface Specification.
+
+ If PeiServicesTablePointer is NULL, then ASSERT().
+
+ @param PeiServicesTablePointer The address of PeiServices pointer.
+**/
+VOID
+EFIAPI
+SetPeiServicesTablePointer (
+ IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer
+ )
+{
+ struct sbi_platform *ThisSbiPlatform;
+ EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext;
+
+ ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
+ FirmwareContext = (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context;
+ FirmwareContext->PeiServiceTable = (VOID *)(UINTN)PeiServicesTablePointer;
+
+ DEBUG ((EFI_D_ERROR, "[OpenSBI]: Set PEI Service 0x%x at Firmware Context at 0x%x\n",
+ PeiServicesTablePointer,
+ ThisSbiPlatform->firmware_context
+ ));
+}
+
+/**
+ Retrieves the cached value of the PEI Services Table pointer.
+
+ Returns the cached value of the PEI Services Table pointer in a CPU specific manner
+ as specified in the CPU binding section of the Platform Initialization Pre-EFI
+ Initialization Core Interface Specification.
+
+ If the cached PEI Services Table pointer is NULL, then ASSERT().
+
+ @return The pointer to PeiServices.
+
+**/
+CONST EFI_PEI_SERVICES **
+EFIAPI
+GetPeiServicesTablePointer (
+ VOID
+ )
+{
+ struct sbi_platform *ThisSbiPlatform;
+ EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext;
+
+ ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
+ FirmwareContext = (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context;
+ return (CONST EFI_PEI_SERVICES **)FirmwareContext->PeiServiceTable;
+}
+
+/**
+ The constructor function caches the pointer to PEI services.
+
+ The constructor function caches the pointer to PEI services.
+ It will always return EFI_SUCCESS.
+
+ @param FileHandle The handle of FFS header the loaded driver.
+ @param PeiServices The pointer to the PEI services.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiServicesTablePointerLibOpenSbiConstructor (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ SetPeiServicesTablePointer (PeiServices);
+ return EFI_SUCCESS;
+}
+
+/**
+ Perform CPU specific actions required to migrate the PEI Services Table
+ pointer from temporary RAM to permanent RAM.
+
+ For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes
And for RISCV CPUs?

+ immediately preceding the Interrupt Descriptor Table (IDT) in memory.
+ For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes
+ immediately preceding the Interrupt Descriptor Table (IDT) in memory.
+ For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in
+ a dedicated CPU register. This means that there is no memory storage
+ associated with storing the PEI Services Table pointer, so no additional
+ migration actions are required for Itanium or ARM CPUs.
+
+**/
+VOID
+EFIAPI
+MigratePeiServicesTablePointer (
+ VOID
+ )
+{
+ //
+ // PEI Services Table pointer is cached in the global variable. No additional
+ // migration actions are required.
+ //
+ return;
+}
diff --git a/RiscVPkg/Library/RiscVCpuLib/Cpu.s b/RiscVPkg/Library/RiscVCpuLib/Cpu.s
new file mode 100644
index 0000000..ccd7e87
--- /dev/null
+++ b/RiscVPkg/Library/RiscVCpuLib/Cpu.s
@@ -0,0 +1,121 @@
+//------------------------------------------------------------------------------
+//
+// RISC-V CPU functions.
+//
+// Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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 <Base.h>
+#include <RiscV.h>
+
+.data
+
+.text
+.align 3
+
+.global ASM_PFX(RiscVSetScratch)
+.global ASM_PFX(RiscVGetScratch)
+.global ASM_PFX(RiscVGetMachineTrapCause)
+.global ASM_PFX(RiscVReadMachineIE)
+.global ASM_PFX(RiscVReadMachineIP)
+.global ASM_PFX(RiscVReadMachineStatus)
+.global ASM_PFX(RiscVWriteMachineStatus)
+.global ASM_PFX(RiscVReadMachineTvec)
+.global ASM_PFX(RiscVReadMisa)
+.global ASM_PFX(RiscVReadMVendorId)
+.global ASM_PFX(RiscVReadMArchId)
+.global ASM_PFX(RiscVReadMImplId)
+//
+// Set machine mode scratch.
+// @param a0 : Pointer to RISCV_MACHINE_MODE_CONTEXT.
+//
+ASM_PFX (RiscVSetScratch):
+ csrrw a1, RISCV_CSR_MACHINE_MSCRATCH, a0
+ ret
+
+//
+// Get machine mode scratch.
+// @retval a0 : Pointer to RISCV_MACHINE_MODE_CONTEXT.
+//
+ASM_PFX (RiscVGetScratch):
+ csrrs a0, RISCV_CSR_MACHINE_MSCRATCH, 0
+ ret
+
+//
+// Get machine trap cause CSR.
+//
+ASM_PFX (RiscVGetMachineTrapCause):
+ csrrs a0, RISCV_CSR_MACHINE_MCAUSE, 0
+ ret
+
+//
+// Get machine interrupt enable
+//
+ASM_PFX (RiscVReadMachineIE):
+ csrr a0, RISCV_CSR_MACHINE_MIE
+ ret
+
+//
+// Get machine interrupt pending
+//
+ASM_PFX (RiscVReadMachineIP):
+ csrr a0, RISCV_CSR_MACHINE_MIP
+ ret
+
+//
+// Get machine status
+//
+ASM_PFX(RiscVReadMachineStatus):
+ csrr a0, RISCV_CSR_MACHINE_MSTATUS
+ ret
+
+//
+// Set machine status
+//
+ASM_PFX(RiscVWriteMachineStatus):
+ csrw RISCV_CSR_MACHINE_MSTATUS, a0
+ ret
+
+//
+// Get machine trap vector
+//
+ASM_PFX(RiscVReadMachineTvec):
+ csrr a0, RISCV_CSR_MACHINE_MTVEC
+ ret
+
+//
+// Read machine ISA
+//
+ASM_PFX(RiscVReadMisa):
+ csrr a0, RISCV_CSR_MACHINE_MISA
+ ret
+
+//
+// Read machine vendor ID
+//
+ASM_PFX(RiscVReadMVendorId):
+ csrr a0, RISCV_CSR_MACHINE_MVENDORID
+ ret
+
+//
+// Read machine architecture ID
+//
+ASM_PFX(RiscVReadMArchId):
+ csrr a0, RISCV_CSR_MACHINE_MARCHID
+ ret
+
+//
+// Read machine implementation ID
+//
+ASM_PFX(RiscVReadMImplId):
+ csrr a0, RISCV_CSR_MACHINE_MIMPID
+ ret
+
diff --git a/RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf b/RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf
new file mode 100644
index 0000000..2d8a32d
--- /dev/null
+++ b/RiscVPkg/Library/RiscVCpuLib/RiscVCpuLib.inf
@@ -0,0 +1,46 @@
+## @file
+# Memory Status Code Library for UEFI drivers
+#
+# Lib to provide memory journal status code reporting Routines
+# Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+# Copyright (c) 2007 - 2010, 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 = RiscVCpuLib
+ FILE_GUID = 8C6CFB0D-A0EE-40D5-90DA-2E51EAE0583F
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RiscVCpuLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = RISCV32 RISCV64
Please leave RISCV32 out for now.

+#
+
+[Sources]
+
+[Sources.RISCV32]
+ Cpu.s
Please leave RISCV32 out for now.

+
+[Sources.RISCV64]
+ Cpu.s
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+
diff --git a/RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.c b/RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.c
new file mode 100644
index 0000000..309cb19
--- /dev/null
+++ b/RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.c
@@ -0,0 +1,47 @@
+/** @file
+ RISC-V platform level DXE core hand off library
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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.
+**/
+
+/**
+ RISC-V platform DXE IPL to DXE core handoff process.
+
+ This function performs a CPU architecture specific operations to execute
+ the entry point of DxeCore with the parameters of HobList.
+ It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
+
+ @param BaseOfStack Base address of stack
+ @param TopOfStack Top address of stack
+ @param DxeCoreEntryPoint The entry point of DxeCore.
+ @param HobList The start of HobList passed to DxeCore.
+
+**/
+
+VOID
+RiscVPlatformHandOffToDxeCore (
+ IN VOID *BaseOfStack,
+ IN VOID *TopOfStack,
+ IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
+ IN EFI_PEI_HOB_POINTERS HobList
+ )
+{
+
+ //
+ // Transfer the control to the entry point of DxeCore.
+ //
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
+ HobList.Raw,
+ NULL,
+ TopOfStack
+ );
+}
diff --git a/RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.inf b/RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.inf
new file mode 100644
index 0000000..62599ac
--- /dev/null
+++ b/RiscVPkg/Library/RiscVDxeIplHandoffLib/RiscVDxeIplHandoffLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Instance of RISC-V DXE IPL to DXE core handoff platform library
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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 = RiscVPlatformDxeIplLib
+ FILE_GUID = 2A77EE71-9F55-43F9-8773-7854A5B56086
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RiscVPlatformDxeIplLib|PEIM PEI_CORE
+
+#
+# VALID_ARCHITECTURES = RISCV64
+#
+
+[Sources]
+ RiscVDxeIplHandoffLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ RiscVCpuLib
+ RiscVOpensbiLib
+
+[Pcd]
diff --git a/RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.c b/RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.c
new file mode 100644
index 0000000..37b4d32
--- /dev/null
+++ b/RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.c
@@ -0,0 +1,108 @@
+/** @file
+ RISC-V DXE IPL to DXE core handoff platform library using OpenSBI
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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/DebugLib.h>
+#include <Library/BaseLib.h>
+
+#include <sbi/sbi.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_init.h>
+#include <sbi/riscv_encoding.h>
+#include <Library/RiscVCpuLib.h>
+#include <Library/RiscVPlatformDxeIpl.h>
+
+/**
+ RISC-V platform DXE IPL to DXE OpenSBI mdoe switch handler.
+ This function is executed in RISC-V Supervisor mode.
+
+ This function performs a CPU architecture specific operations to execute
+ the entry point of DxeCore with the parameters of HobList.
+ It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
+
+ @param BaseOfStack Base address of stack
+ @param TopOfStack Top address of stack
+ @param DxeCoreEntryPoint The entry point of DxeCore.
+ @param HobList The start of HobList passed to DxeCore.
+
+**/
+VOID
+RiscVDxeIplHandoffOpenSbiHandler (
+ IN UINTN HardId,
+ IN OPENSBI_SWITCH_MODE_CONTEXT *ThisSwitchContext
+ )
+{
+ DEBUG ((EFI_D_INFO, "[OpenSBI]: OpenSBI mode switch DXE IPL Handoff handler entry\n"));
+
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)ThisSwitchContext->DxeCoreEntryPoint,
+ ThisSwitchContext->HobList.Raw,
+ NULL,
+ ThisSwitchContext->TopOfStack
+ );
+
+ //
+ // Shold never came back.
+ //
+ __builtin_unreachable();
+}
+
+
+/**
+ RISC-V platform DXE IPL to DXE core handoff process.
+
+ This function performs a CPU architecture specific operations to execute
+ the entry point of DxeCore with the parameters of HobList.
+ It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
+
+ @param BaseOfStack Base address of stack
+ @param TopOfStack Top address of stack
+ @param DxeCoreEntryPoint The entry point of DxeCore.
+ @param HobList The start of HobList passed to DxeCore.
+
+**/
+VOID
+RiscVPlatformHandOffToDxeCore (
+ IN VOID *BaseOfStack,
+ IN VOID *TopOfStack,
+ IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint,
+ IN EFI_PEI_HOB_POINTERS HobList
+ )
+{
+ struct sbi_scratch *ThisScratch;
+ OPENSBI_SWITCH_MODE_CONTEXT OpenSbiSwitchModeContext;
+
+ DEBUG ((EFI_D_INFO, "[OpenSBI]: DXE IPL to DXE Core using OpenSBI\n"));
+ //
+ // Setup next address in OpenSBI scratch
+ //
+ OpenSbiSwitchModeContext.BaseOfStack = BaseOfStack;
+ OpenSbiSwitchModeContext.TopOfStack = TopOfStack;
+ OpenSbiSwitchModeContext.HobList = HobList;
+ OpenSbiSwitchModeContext.DxeCoreEntryPoint = DxeCoreEntryPoint;
+ ThisScratch = sbi_scratch_thishart_ptr ();
+ ThisScratch->next_arg1 = (unsigned long)(UINTN)&OpenSbiSwitchModeContext;
+ ThisScratch->next_addr = (unsigned long)(UINTN)RiscVDxeIplHandoffOpenSbiHandler;
+ ThisScratch->next_mode = PRV_S;
+
+ DEBUG ((EFI_D_INFO, " Base address of satck: 0x%x\n", BaseOfStack));
+ DEBUG ((EFI_D_INFO, " Top address of satck: 0x%x\n", TopOfStack));
+ DEBUG ((EFI_D_INFO, " HOB list address: 0x%x\n", &HobList));
+ DEBUG ((EFI_D_INFO, " DXE core entry pointer: 0x%x\n", DxeCoreEntryPoint));
+ DEBUG ((EFI_D_INFO, " OpenSBI Switch mode arg1: 0x%x\n", (UINTN)&OpenSbiSwitchModeContext));
+ DEBUG ((EFI_D_INFO, " OpenSBI Switch mode handler address: 0x%x\n", (UINTN)RiscVDxeIplHandoffOpenSbiHandler));
+ DEBUG ((EFI_D_INFO, " OpenSBI Switch mode to privilege 0x%x\n", PRV_S));
+ sbi_init (ThisScratch);
+}
diff --git a/RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.inf b/RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.inf
new file mode 100644
index 0000000..3ddfe41
--- /dev/null
+++ b/RiscVPkg/Library/RiscVDxeIplHandoffOpenSbiLib/RiscVDxeIplHandoffOpenSbiLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Instance of RISC-V DXE IPL to DXE core handoff platform library using OpenSBI
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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 = RiscVPlatformDxeIplLib
+ FILE_GUID = 906A4BB9-8DE2-4CE0-A609-23818A8FF514
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RiscVPlatformDxeIplLib|PEIM PEI_CORE
+
+#
+# VALID_ARCHITECTURES = RISCV64
+#
+
+[Sources]
+ RiscVDxeIplHandoffOpenSbiLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ RiscVCpuLib
+ RiscVOpensbiLib
+
+[Pcd]
diff --git a/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandler.s b/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandler.s
new file mode 100644
index 0000000..a987c9b
--- /dev/null
+++ b/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandler.s
@@ -0,0 +1,94 @@
+/** @file
+ RISC-V Processor supervisor mode trap handler
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that 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 <Base.h>
+#include <RiscV.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_trap.h>
+
+ .align 3
+ .section .entry, "ax", %progbits
+ .globl _strap_handler
+_strap_handler:
+ addi sp, sp, -34*8
+ /* Save all general regisers except SP and T0 */
+ sd ra, 1*8(sp)
+ sd gp, 2*8(sp)
+ sd tp, 3*8(sp)
+ sd t1, 4*8(sp)
+ sd t2, 5*8(sp)
+ sd s0, 6*8(sp)
+ sd s1, 7*8(sp)
+ sd a0, 8*8(sp)
+ sd a1, 9*8(sp)
+ sd a2, 10*8(sp)
+ sd a3, 11*8(sp)
+ sd a4, 12*8(sp)
+ sd a5, 13*8(sp)
+ sd a6, 14*8(sp)
+ sd a7, 15*8(sp)
+ sd s2, 16*8(sp)
+ sd s3, 17*8(sp)
+ sd s4, 18*8(sp)
+ sd s5, 19*8(sp)
+ sd s6, 20*8(sp)
+ sd s7, 21*8(sp)
+ sd s8, 22*8(sp)
+ sd s9, 23*8(sp)
+ sd s10, 24*8(sp)
+ sd s11, 25*8(sp)
+ sd t3, 26*8(sp)
+ sd t4, 27*8(sp)
+ sd t5, 28*8(sp)
+ sd t6, 29*8(sp)
+
+ /* Call C routine */
+ call RiscVSupervisorModeTrapHandler
+
+ /* Restore all general regisers except SP and T0 */
+ ld ra, 1*8(sp)
+ ld gp, 2*8(sp)
+ ld tp, 3*8(sp)
+ ld t1, 4*8(sp)
+ ld t2, 5*8(sp)
+ ld s0, 6*8(sp)
+ ld s1, 7*8(sp)
+ ld a0, 8*8(sp)
+ ld a1, 9*8(sp)
+ ld a2, 10*8(sp)
+ ld a3, 11*8(sp)
+ ld a4, 12*8(sp)
+ ld a5, 13*8(sp)
+ ld a6, 14*8(sp)
+ ld a7, 15*8(sp)
+ ld s2, 16*8(sp)
+ ld s3, 17*8(sp)
+ ld s4, 18*8(sp)
+ ld s5, 19*8(sp)
+ ld s6, 20*8(sp)
+ ld s7, 21*8(sp)
+ ld s8, 22*8(sp)
+ ld s9, 23*8(sp)
+ ld s10, 24*8(sp)
+ ld s11, 25*8(sp)
+ ld t3, 26*8(sp)
+ ld t4, 27*8(sp)
+ ld t5, 28*8(sp)
+ ld t6, 29*8(sp)
+ addi sp, sp, 34*8
+ sret
\ No newline at end of file
diff --git a/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf b/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf
new file mode 100644
index 0000000..04bdd6a
--- /dev/null
+++ b/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf
@@ -0,0 +1,47 @@
+## @file
+# RISC-V CPU Exception Handler Library
+#
+# Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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 = CpuExceptionHandlerLib
+ MODULE_UNI_FILE = CpuExceptionHandlerLib.uni
+ FILE_GUID = 16309FCF-E900-459C-B071-052118394D11
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CpuExceptionHandlerLib
+ CONSTRUCTOR = CpuExceptionHandlerLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = RISCV64
+#
+
+[Sources.RISCV64]
+ CpuExceptionHandler.s
+
+[Sources.common]
+ CpuExceptionHandlerLib.c
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ BaseLib
+ DebugLib
+ RiscVCpuLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
diff --git a/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.c b/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.c
new file mode 100644
index 0000000..7be18af
--- /dev/null
+++ b/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.c
@@ -0,0 +1,187 @@
+/** @file
+ RISC-V Exception Handler library implementition.
+
+ Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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/CpuExceptionHandlerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RiscVCpuLib.h>
+#include <sbi/sbi_types.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+
+
+extern void _strap_handler(void);
+EFI_CPU_INTERRUPT_HANDLER gInterruptHandlers[2];
+/**
+ Initializes all CPU exceptions entries and provides the default exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
+ with default interrupt/exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuInterruptHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+**/
+EFI_STATUS
+EFIAPI
+RegisterCpuInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+
+ DEBUG ((DEBUG_INFO, "RegisterCpuInterruptHandler: Type:%x Handler: %x\n", InterruptType, InterruptHandler));
+ gInterruptHandlers[InterruptType] = InterruptHandler;
+ return EFI_SUCCESS;
+}
+/**
+ Machine mode trap handler.
+
+**/
+VOID
+RiscVSupervisorModeTrapHandler (
+ VOID
+ )
+{
+ EFI_SYSTEM_CONTEXT RiscVSystemContext;
+
+ //
+ // Check scasue register.
+ //
+ if(gInterruptHandlers[EXCEPT_RISCV_TIMER_INT] != NULL) {
+ gInterruptHandlers[EXCEPT_RISCV_TIMER_INT](EXCEPT_RISCV_TIMER_INT, (CONST EFI_SYSTEM_CONTEXT)RiscVSystemContext);
+ }
+}
+
+/**
+ Initializes all CPU exceptions entries with optional extra initializations.
+
+ By default, this method should include all functionalities implemented by
+ InitializeCpuExceptionHandlers(), plus extra initialization works, if any.
+ This could be done by calling InitializeCpuExceptionHandlers() directly
+ in this method besides the extra works.
+
+ InitData is optional and its use and content are processor arch dependent.
+ The typical usage of it is to convey resources which have to be reserved
+ elsewhere and are necessary for the extra initializations of exception.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+ @param[in] InitData Pointer to data optional for extra initializations
+ of exception.
+
+ @retval EFI_SUCCESS The exceptions have been successfully
+ initialized.
+ @retval EFI_INVALID_PARAMETER VectorInfo or InitData contains invalid
+ content.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlersEx (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL,
+ IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL
+ )
+{
+ return InitializeCpuExceptionHandlers (VectorInfo);
+}
+
+/**
+ The constructor function to initial interrupt handlers in
+ RISCV_MACHINE_MODE_CONTEXT.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The destructor completed successfully.
+ @retval Other value The destructor did not complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuExceptionHandlerLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ //
+ // Set Superviosr mode trap handler.
+ //
+ csr_write(CSR_STVEC, _strap_handler);
+
+ return EFI_SUCCESS;
+}
diff --git a/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.uni b/RiscVPkg/Library/RiscVExceptionLib/CpuExceptionHandlerLib.uni
new file mode 100644
index 0000000000000000000000000000000000000000..ef38a57603a7a20e05391e4b47cbd0e3764107a9
GIT binary patch
literal 1516
zcmc(fUvCmY6vfZ8iQi#EU(~dqKKNja5$LMK+9edMJ~jMnyAcWj+RB$#e`khe5%s|*
zLw4@Wojd2Ad*%*5zSmS!!uNz<qBpu!u8GEas0Vm!Tbrn<ndVw+LBy4=wIcqJhI)*B
zuBUpY7dmAAp40aMV-;fB>J#;qaiJ0Wsc!I(S<M61l6j(I#yh@A$TDT-s6;1ftBS3&
zGr^YGmti%Q&o9E+5s|OdP)Dz~yo)*#b>W;7orJtIYFNN&%DPW3Gg}d1F6KLg$COC#
ztvPo?e1fOH;hr;_fL7wWKA)ZtJq-NK%(w-<PmeYk?wDKYz6OjwcN<u^mXb--X&P7;
zC}w89IZW~}cTF>Ht~}S!8H!rHT`ncp`=G^;@%L(T*cj1jM7^AA$=ccv;92DLy;xPV
zzr-JJ$eh0sv(M>QU80t2q6VAuvyB2~wA#_townj8UWR^j54ty&RD25~D_v#2;C^a*
z+Ar}8h#cu?Z>I{%HD9Snm%dG5)24eey<@EFBkLAQx;t&Vcw6*Wk69Y@?dcSo;<pkJ
zq13*`n@Nc{3&<HW_p!$c*0@HkU>jlW)!`1ObM}pzg^Y>LiRuJqr}$f-8Y2tYJFLvz
zKIiNb>lkN^QE!QL_Al5E?3lUVYr4r2t4Q^Ei&LVv(4tK@Ip;BY7rGTT3I8AQ-@-nB
z2iu;BZzt+^0a6A=542PlFtT1&wvJj|`26j6z#aMxTygJxMt7Y%;Rq}<t$<+#n|MC4
zZo;^SP3cB=$($~V@5TR7@iqD7`Mvp_44C;1ui;$<?ceHf7dW>$w71Itsh0m$$4~Ue
B=s5rY

literal 0
HcmV?d00001

diff --git a/RiscVPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf b/RiscVPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf
new file mode 100644
index 0000000..05180da
--- /dev/null
+++ b/RiscVPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf
@@ -0,0 +1,65 @@
+## @file
+# RISC-V Opensbi Library Instance.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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 = RiscVOpensbiLib
+ FILE_GUID = 6EF0C812-66F6-11E9-93CE-3F5D5F0DF0A7
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RiscVOpensbiLib
+
+[Sources]
+ ../../opensbi/lib/sbi/riscv_asm.c
No, we need to figure out a proper way of doing this.
.. in .inf files is a big no-no.

+ ../../opensbi/lib/sbi/riscv_atomic.c
+ ../../opensbi/lib/sbi/riscv_hardfp.S
+ ../../opensbi/lib/sbi/riscv_locks.c
+ ../../opensbi/lib/sbi/riscv_unpriv.c
+ ../../opensbi/lib/sbi/sbi_console.c
+ ../../opensbi/lib/sbi/sbi_ecall.c
+ ../../opensbi/lib/sbi/sbi_emulate_csr.c
+ ../../opensbi/lib/sbi/sbi_fifo.c
+ ../../opensbi/lib/sbi/sbi_hart.c
+ ../../opensbi/lib/sbi/sbi_illegal_insn.c
+ ../../opensbi/lib/sbi/sbi_init.c
+ ../../opensbi/lib/sbi/sbi_ipi.c
+ ../../opensbi/lib/sbi/sbi_misaligned_ldst.c
+ ../../opensbi/lib/sbi/sbi_scratch.c
+ ../../opensbi/lib/sbi/sbi_string.c
+ ../../opensbi/lib/sbi/sbi_system.c
+ ../../opensbi/lib/sbi/sbi_timer.c
+ ../../opensbi/lib/sbi/sbi_tlb.c
+ ../../opensbi/lib/sbi/sbi_trap.c
+ ../../opensbi/lib/utils/sys/clint.c
+ ../../opensbi/lib/utils/irqchip/plic.c
+ ../../opensbi/lib/utils/serial/sifive-uart.c
+ ../../opensbi/lib/utils/serial/uart8250.c
+ ../../opensbi/lib/utils/libfdt/fdt.c
+ ../../opensbi/lib/utils/libfdt/fdt_ro.c
+ ../../opensbi/lib/utils/libfdt/fdt_wip.c
+ ../../opensbi/lib/utils/libfdt/fdt_rw.c
+ ../../opensbi/lib/utils/libfdt/fdt_sw.c
+ ../../opensbi/lib/utils/libfdt/fdt_strerror.c
+ ../../opensbi/lib/utils/libfdt/fdt_empty_tree.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ PcdLib
+ RiscVCpuLib
+
diff --git a/RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/RiscVPlatformTempMemoryInitLibNull.inf b/RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/RiscVPlatformTempMemoryInitLibNull.inf
new file mode 100644
index 0000000..193452f
--- /dev/null
+++ b/RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/RiscVPlatformTempMemoryInitLibNull.inf
@@ -0,0 +1,42 @@
+## @file
+# RISC-V platform temporary memory library.
+#
+# Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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
OK, so I've not mentioned this before, but unless you are specifically
targeting an ancient version of BaseTools, it would be better to
specify the current version as published at
https://github.com/tianocore/tianocore.github.io/wiki/EDK-II-Specifications.

If you *are* targeting an ancient version of BaseTools, I'm pretty
sure it's still not quite as ancient as that :):)

Current versions are 1.27 for .dec and .inf, 1.28 for .dsc and .fdf.

+ BASE_NAME = RiscVPlatformTempMemoryInitLibNull
+ FILE_GUID = 67294857-C0F8-4ACB-8237-D91FE506B710
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RiscVPlatformTempMemoryInitLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = RISCV32 RISCV64
Please drop RISCV32 for now.

+#
+
+[Sources]
+
+[Sources.RISCV32]
+
And here.

/
Leif

+[Sources.RISCV64]
+ Riscv64/TempMemInit.s
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+
diff --git a/RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/Riscv64/TempMemInit.s b/RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/Riscv64/TempMemInit.s
new file mode 100644
index 0000000..22ff329
--- /dev/null
+++ b/RiscVPkg/Library/RiscVPlatformTempMemoryInitLibNull/Riscv64/TempMemInit.s
@@ -0,0 +1,31 @@
+//------------------------------------------------------------------------------
+//
+// RISC-V RiscVPlatformTemporaryMemInit.
+//
+// Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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 <Base.h>
+
+.data
+
+.text
+.align 3
+
+.global ASM_PFX(RiscVPlatformTemporaryMemInit)
+
+//
+// @retval a0 Temporary memory base.
+// a1 Temporary memory size.
+//
+ASM_PFX(RiscVPlatformTemporaryMemInit):
+ li a0, FixedPcdGet32 (PcdRiscVSecPeiTempRamBase)
+ li a1, FixedPcdGet32 (PcdRiscVSecPeiTempRamSize)
+ ret
diff --git a/RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf b/RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
new file mode 100644
index 0000000..66e821b
--- /dev/null
+++ b/RiscVPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf
@@ -0,0 +1,40 @@
+## @file
+# RISC-V Timer Library Instance.
+#
+# Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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 = BaseRiscVTimerLib
+ FILE_GUID = FB648CF5-91BE-4737-9023-FD807AC6D96D
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TimerLib
+
+[Sources]
+ RiscVTimerLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+[Pcd]
+ gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerTickInNanoSecond
+ gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz
+
+[LibraryClasses]
+ BaseLib
+ PcdLib
+ RiscVCpuLib
+ RiscVPlatformTimerLib
+
diff --git a/RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.c b/RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.c
new file mode 100644
index 0000000..5dd4a4e
--- /dev/null
+++ b/RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.c
@@ -0,0 +1,201 @@
+/** @file
+ RISC-V instance of Timer Library.
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 <RiscVTimerLib.h>
+
+/**
+ Stalls the CPU for at least the given number of ticks.
+
+ Stalls the CPU for at least the given number of ticks. It's invoked by
+ MicroSecondDelay() and NanoSecondDelay().
+
+ @param Delay A period of time to delay in ticks.
+
+**/
+VOID
+InternalRiscVTimerDelay (
+ IN UINT32 Delay
+ )
+{
+ UINT32 Ticks;
+ UINT32 Times;
+
+ Times = Delay >> (RISCV_TIMER_COMPARE_BITS - 2);
+ Delay &= (( 1 << (RISCV_TIMER_COMPARE_BITS - 2)) - 1);
+ do {
+ //
+ // The target timer count is calculated here
+ //
+ Ticks = RiscVReadMachineTimer () + Delay;
+ Delay = 1 << (RISCV_TIMER_COMPARE_BITS - 2);
+ while (((Ticks - RiscVReadMachineTimer ()) & ( 1 << (RISCV_TIMER_COMPARE_BITS - 1))) == 0) {
+ CpuPause ();
+ }
+ } while (Times-- > 0);
+}
+
+/**
+ Stalls the CPU for at least the given number of microseconds.
+
+ Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+ @param MicroSeconds The minimum number of microseconds to delay.
+
+ @return MicroSeconds
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+ IN UINTN MicroSeconds
+ )
+{
+ InternalRiscVTimerDelay (
+ (UINT32)DivU64x32 (
+ MultU64x32 (
+ MicroSeconds,
+ PcdGet64 (PcdRiscVMachineTimerFrequencyInHerz)
+ ),
+ 1000000u
+ )
+ );
+ return MicroSeconds;
+}
+
+/**
+ Stalls the CPU for at least the given number of nanoseconds.
+
+ Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+ @param NanoSeconds The minimum number of nanoseconds to delay.
+
+ @return NanoSeconds
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+ IN UINTN NanoSeconds
+ )
+{
+ InternalRiscVTimerDelay (
+ (UINT32)DivU64x32 (
+ MultU64x32 (
+ NanoSeconds,
+ PcdGet64 (PcdRiscVMachineTimerFrequencyInHerz)
+ ),
+ 1000000000u
+ )
+ );
+ return NanoSeconds;
+}
+
+/**
+ Retrieves the current value of a 64-bit free running performance counter.
+
+ Retrieves the current value of a 64-bit free running performance counter. The
+ counter can either count up by 1 or count down by 1. If the physical
+ performance counter counts by a larger increment, then the counter values
+ must be translated. The properties of the counter can be retrieved from
+ GetPerformanceCounterProperties().
+
+ @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+ VOID
+ )
+{
+ return (UINT64)RiscVReadMachineTimer ();
+}
+
+/**return
+ Retrieves the 64-bit frequency in Hz and the range of performance counter
+ values.
+
+ If StartValue is not NULL, then the value that the performance counter starts
+ with immediately after is it rolls over is returned in StartValue. If
+ EndValue is not NULL, then the value that the performance counter end with
+ immediately before it rolls over is returned in EndValue. The 64-bit
+ frequency of the performance counter in Hz is always returned. If StartValue
+ is less than EndValue, then the performance counter counts up. If StartValue
+ is greater than EndValue, then the performance counter counts down. For
+ example, a 64-bit free running counter that counts up would have a StartValue
+ of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+ that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+ @param StartValue The value the performance counter starts with when it
+ rolls over.
+ @param EndValue The value that the performance counter ends with before
+ it rolls over.
+
+ @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+ OUT UINT64 *StartValue, OPTIONAL
+ OUT UINT64 *EndValue OPTIONAL
+ )
+{
+ if (StartValue != NULL) {
+ *StartValue = 0;
+ }
+
+ if (EndValue != NULL) {
+ *EndValue = 32 - 1;
+ }
+
+ return PcdGet64 (PcdRiscVMachineTimerFrequencyInHerz);
+}
+
+/**
+ Converts elapsed ticks of performance counter to time in nanoseconds.
+
+ This function converts the elapsed ticks of running performance counter to
+ time value in unit of nanoseconds.
+
+ @param Ticks The number of elapsed ticks of running performance counter.
+
+ @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+ IN UINT64 Ticks
+ )
+{
+ UINT64 NanoSeconds;
+ UINT32 Remainder;
+
+ //
+ // Ticks
+ // Time = --------- x 1,000,000,000
+ // Frequency
+ //
+ NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, PcdGet64 (PcdRiscVMachineTimerFrequencyInHerz), &Remainder), 1000000000u);
+
+ //
+ // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
+ // will not overflow 64-bit.
+ //
+ NanoSeconds += DivU64x32 (MultU64x32 ((UINT64) Remainder, 1000000000u), PcdGet64 (PcdRiscVMachineTimerFrequencyInHerz));
+
+ return NanoSeconds;
+}
diff --git a/RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.h b/RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.h
new file mode 100644
index 0000000..1704bbb
--- /dev/null
+++ b/RiscVPkg/Library/RiscVTimerLib/RiscVTimerLib.h
@@ -0,0 +1,26 @@
+/** @file
+ RISC-V timer library definitions.
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 _RISCV_TIMER_LIB_INTERNAL_H_
+#define _RISCV_TIMER_LIB_INTERNAL_H_
+
+#include <Uefi.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+#include <Library/RiscVCpuLib.h>
+
+#endif // _RISCV_TIMER_LIB_INTERNAL_H_
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 17/22]: RiscVPkg/SmbiosDxe: RISC-V platform generic SMBIOS DXE driver

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:12PM +0800, Abner Chang wrote:
RISC-V generic SMBIOS DXE driver for building up SMBIOS type 4, type 7 and type 44 records.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.c | 343 +++++++++++++++++++++
RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.h | 38 +++
RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf | 63 ++++
RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.uni | Bin 0 -> 1542 bytes
.../Universal/SmbiosDxe/RiscVSmbiosDxeExtra.uni | Bin 0 -> 1438 bytes
5 files changed, 444 insertions(+)
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.c
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.h
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.uni
create mode 100644 RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxeExtra.uni

diff --git a/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.c b/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.c
new file mode 100644
index 0000000..b59af1a
--- /dev/null
+++ b/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.c
@@ -0,0 +1,343 @@
+/** @file
+ RISC-V generic SMBIOS DXE driver to build up SMBIOS type 4, type 7 and type 44 records.
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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 "RiscVSmbiosDxe.h"
+
+#define RISCV_SMBIOS_DEBUG_INFO 1
+
+EFI_SMBIOS_PROTOCOL *Smbios;
+
+/**
+ This function builds SMBIOS type 7 record according to
+ the given RISC_V_PROCESSOR_TYPE7_DATA_HOB.
+
+ @param Type4DataHob Pointer to RISC_V_PROCESSOR_TYPE4_DATA_HOB
+ @param Type7DataHob Pointer to RISC_V_PROCESSOR_TYPE7_DATA_HOB
+ @param SmbiosHandle Pointer to SMBIOS_HANDLE
+
+ @retval EFI_STATUS
+
+**/
+static
+EFI_STATUS
+BuildSmbiosType7 (
+ IN RISC_V_PROCESSOR_TYPE4_DATA_HOB *Type4DataHob,
+ IN RISC_V_PROCESSOR_TYPE7_DATA_HOB *Type7DataHob,
+ OUT SMBIOS_HANDLE *SmbiosHandle
+)
+{
+ EFI_STATUS Status;
+ SMBIOS_HANDLE Handle;
+
+ if (!CompareGuid (&Type4DataHob->PrcessorGuid, &Type7DataHob->PrcessorGuid) ||
+ Type4DataHob->ProcessorUid != Type7DataHob->ProcessorUid) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Handle = SMBIOS_HANDLE_PI_RESERVED;
+ Type7DataHob->SmbiosType7Cache.Hdr.Type = SMBIOS_TYPE_CACHE_INFORMATION;
+ Type7DataHob->SmbiosType7Cache.Hdr.Length = sizeof(SMBIOS_TABLE_TYPE7);
+ Type7DataHob->SmbiosType7Cache.Hdr.Handle = 0;
+ Status = Smbios->Add (Smbios, NULL, &Handle, &Type7DataHob->SmbiosType7Cache.Hdr);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: Fail to add SMBIOS Type 7\n"));
+ return Status;
+ }
+ DEBUG ((EFI_D_INFO, "[RISC-V SMBIOS Builder]: SMBIOS Type 7 was added. SMBIOS Handle: 0x%x\n", Handle));
+#if RISCV_SMBIOS_DEBUG_INFO
+ DEBUG ((EFI_D_INFO, " Cache belone to processor GUID: %g\n", &Type7DataHob->PrcessorGuid));
+ DEBUG ((EFI_D_INFO, " Cache belone processor UID: %d\n", Type7DataHob->ProcessorUid));
+ DEBUG ((EFI_D_INFO, " ==============================\n"));
+ DEBUG ((EFI_D_INFO, " Socket Designation: %d\n", Type7DataHob->SmbiosType7Cache.SocketDesignation));
+ DEBUG ((EFI_D_INFO, " Cache Configuration: 0x%x\n", Type7DataHob->SmbiosType7Cache.CacheConfiguration));
+ DEBUG ((EFI_D_INFO, " Maximum Cache Size: 0x%x\n", Type7DataHob->SmbiosType7Cache.MaximumCacheSize));
+ DEBUG ((EFI_D_INFO, " Installed Size: 0x%x\n", Type7DataHob->SmbiosType7Cache.InstalledSize));
+ DEBUG ((EFI_D_INFO, " Supported SRAM Type: 0x%x\n", Type7DataHob->SmbiosType7Cache.SupportedSRAMType));
+ DEBUG ((EFI_D_INFO, " Current SRAMT ype: 0x%x\n", Type7DataHob->SmbiosType7Cache.CurrentSRAMType));
+ DEBUG ((EFI_D_INFO, " Cache Speed: 0x%x\n", Type7DataHob->SmbiosType7Cache.CacheSpeed));
+ DEBUG ((EFI_D_INFO, " Error Correction Type: 0x%x\n", Type7DataHob->SmbiosType7Cache.ErrorCorrectionType));
+ DEBUG ((EFI_D_INFO, " System Cache Type: 0x%x\n", Type7DataHob->SmbiosType7Cache.SystemCacheType));
+ DEBUG ((EFI_D_INFO, " Associativity: 0x%x\n", Type7DataHob->SmbiosType7Cache.Associativity));
+#endif
+
+ *SmbiosHandle = Handle;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function builds SMBIOS type 4 record according to
+ the given RISC_V_PROCESSOR_TYPE4_DATA_HOB.
+
+ @param Type4DataHob Pointer to RISC_V_PROCESSOR_TYPE4_DATA_HOB
+ @param SmbiosHandle Pointer to SMBIOS_HANDLE
+
+ @retval EFI_STATUS
+
+**/
+static
+EFI_STATUS
+BuildSmbiosType4 (
+ IN RISC_V_PROCESSOR_TYPE4_DATA_HOB *Type4DataHob,
+ OUT SMBIOS_HANDLE *SmbiosHandle
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ RISC_V_PROCESSOR_TYPE7_DATA_HOB *Type7HobData;
+ SMBIOS_HANDLE Cache;
+ SMBIOS_HANDLE Processor;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "[RISC-V SMBIOS Builder]: Building Type 4.\n"));
+ DEBUG ((EFI_D_INFO, " Processor GUID: %g\n", &Type4DataHob->PrcessorGuid));
+ DEBUG ((EFI_D_INFO, " Processor UUID: %d\n", Type4DataHob->ProcessorUid));
+
+ Type4DataHob->SmbiosType4Processor.L1CacheHandle = RISC_V_CACHE_INFO_NOT_PROVIDED;
+ Type4DataHob->SmbiosType4Processor.L2CacheHandle = RISC_V_CACHE_INFO_NOT_PROVIDED;
+ Type4DataHob->SmbiosType4Processor.L3CacheHandle = RISC_V_CACHE_INFO_NOT_PROVIDED;
+ GuidHob = (EFI_HOB_GUID_TYPE *)GetFirstGuidHob ((EFI_GUID *)PcdGetPtr(PcdProcessorSmbiosType7GuidHobGuid));
+ if (GuidHob == NULL) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: No RISC-V SMBIOS Type7 data HOB found.\n"));
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Go through each RISC_V_PROCESSOR_TYPE4_DATA_HOB for multiple processors.
+ //
+ do {
+ Type7HobData = (RISC_V_PROCESSOR_TYPE7_DATA_HOB *)GET_GUID_HOB_DATA (GuidHob);
+ Status = BuildSmbiosType7 (Type4DataHob, Type7HobData, &Cache);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if ((Type7HobData->SmbiosType7Cache.SystemCacheType & RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_MASK) ==
+ RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1) {
+ Type4DataHob->SmbiosType4Processor.L1CacheHandle = Cache;
+ } else if ((Type7HobData->SmbiosType7Cache.SystemCacheType & RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_MASK) ==
+ RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2) {
+ Type4DataHob->SmbiosType4Processor.L2CacheHandle = Cache;
+ } else if ((Type7HobData->SmbiosType7Cache.SystemCacheType & RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_MASK) ==
+ RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_3) {
+ Type4DataHob->SmbiosType4Processor.L3CacheHandle = Cache;
+ } else {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: Improper cache level of SMBIOS handle %d\n", Cache));
+ }
+ GuidHob = GetNextGuidHob((EFI_GUID *)PcdGetPtr(PcdProcessorSmbiosType7GuidHobGuid), GET_NEXT_HOB(GuidHob));
+ } while (GuidHob != NULL);
+
+ //
+ // Build SMBIOS Type 4 record
+ //
+ Processor = SMBIOS_HANDLE_PI_RESERVED;
+ Type4DataHob->SmbiosType4Processor.Hdr.Type = SMBIOS_TYPE_PROCESSOR_INFORMATION;
+ Type4DataHob->SmbiosType4Processor.Hdr.Length = sizeof(SMBIOS_TABLE_TYPE4);
+ Type4DataHob->SmbiosType4Processor.Hdr.Handle = 0;
+ Status = Smbios->Add (Smbios, NULL, &Processor, &Type4DataHob->SmbiosType4Processor.Hdr);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: Fail to add SMBIOS Type 4\n"));
+ return Status;
+ }
+ DEBUG ((EFI_D_INFO, "[RISC-V SMBIOS Builder]: SMBIOS Type 4 was added. SMBIOS Handle: 0x%x\n", Processor));
+#if RISCV_SMBIOS_DEBUG_INFO
+ DEBUG ((EFI_D_INFO, " Socket StringID: %d\n", Type4DataHob->SmbiosType4Processor.Socket));
+ DEBUG ((EFI_D_INFO, " Processor Type: 0x%x\n", Type4DataHob->SmbiosType4Processor.ProcessorType));
+ DEBUG ((EFI_D_INFO, " Processor Family: 0x%x\n", Type4DataHob->SmbiosType4Processor.ProcessorFamily));
+ DEBUG ((EFI_D_INFO, " Processor Manufacture StringID: %d\n", Type4DataHob->SmbiosType4Processor.ProcessorManufacture));
+ DEBUG ((EFI_D_INFO, " Processor Id: 0x%x:0x%x\n", \
+ Type4DataHob->SmbiosType4Processor.ProcessorId.Signature, Type4DataHob->SmbiosType4Processor.ProcessorId.FeatureFlags));
+ DEBUG ((EFI_D_INFO, " Processor Version StringID: %d\n", Type4DataHob->SmbiosType4Processor.ProcessorVersion));
+ DEBUG ((EFI_D_INFO, " Voltage: 0x%x\n", Type4DataHob->SmbiosType4Processor.Voltage));
+ DEBUG ((EFI_D_INFO, " External Clock: 0x%x\n", Type4DataHob->SmbiosType4Processor.ExternalClock));
+ DEBUG ((EFI_D_INFO, " Max Speed: 0x%x\n", Type4DataHob->SmbiosType4Processor.MaxSpeed));
+ DEBUG ((EFI_D_INFO, " Current Speed: 0x%x\n", Type4DataHob->SmbiosType4Processor.CurrentSpeed));
+ DEBUG ((EFI_D_INFO, " Status: 0x%x\n", Type4DataHob->SmbiosType4Processor.Status));
+ DEBUG ((EFI_D_INFO, " ProcessorUpgrade: 0x%x\n", Type4DataHob->SmbiosType4Processor.ProcessorUpgrade));
+ DEBUG ((EFI_D_INFO, " L1 Cache Handle: 0x%x\n", Type4DataHob->SmbiosType4Processor.L1CacheHandle));
+ DEBUG ((EFI_D_INFO, " L2 Cache Handle: 0x%x\n",Type4DataHob->SmbiosType4Processor.L2CacheHandle));
+ DEBUG ((EFI_D_INFO, " L3 Cache Handle: 0x%x\n", Type4DataHob->SmbiosType4Processor.L3CacheHandle));
+ DEBUG ((EFI_D_INFO, " Serial Number StringID: %d\n", Type4DataHob->SmbiosType4Processor.SerialNumber));
+ DEBUG ((EFI_D_INFO, " Asset Tag StringID: %d\n", Type4DataHob->SmbiosType4Processor.AssetTag));
+ DEBUG ((EFI_D_INFO, " Part Number StringID: %d\n", Type4DataHob->SmbiosType4Processor.PartNumber));
+ DEBUG ((EFI_D_INFO, " Core Count: %d\n", Type4DataHob->SmbiosType4Processor.CoreCount));
+ DEBUG ((EFI_D_INFO, " Enabled CoreCount: %d\n", Type4DataHob->SmbiosType4Processor.EnabledCoreCount));
+ DEBUG ((EFI_D_INFO, " Thread Count: %d\n", Type4DataHob->SmbiosType4Processor.ThreadCount));
+ DEBUG ((EFI_D_INFO, " Processor Characteristics: 0x%x\n", Type4DataHob->SmbiosType4Processor.ProcessorCharacteristics));
+ DEBUG ((EFI_D_INFO, " Processor Family2: 0x%x\n", Type4DataHob->SmbiosType4Processor.ProcessorFamily2));
+ DEBUG ((EFI_D_INFO, " Core Count 2: %d\n", Type4DataHob->SmbiosType4Processor.CoreCount2));
+ DEBUG ((EFI_D_INFO, " Enabled CoreCount : %d\n", Type4DataHob->SmbiosType4Processor.EnabledCoreCount2));
+ DEBUG ((EFI_D_INFO, " Thread Count 2: %d\n", Type4DataHob->SmbiosType4Processor.ThreadCount2));
+#endif
+
+ *SmbiosHandle = Processor;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function builds SMBIOS type 44 record according..
+
+ @param Type4DataHob Pointer to RISC_V_PROCESSOR_TYPE4_DATA_HOB
+ @param Type4Handle SMBIOS handle of type 4
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+BuildSmbiosType44 (
+ IN RISC_V_PROCESSOR_TYPE4_DATA_HOB *Type4DataHob,
+ IN SMBIOS_HANDLE Type4Handle
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *ProcessorSpecificData;
+ SMBIOS_HANDLE RiscVType44;
+ SMBIOS_TABLE_TYPE44 *Type44Ptr;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "[RISC-V SMBIOS Builder]: Building Type 44 for...\n"));
+#if RISCV_SMBIOS_DEBUG_INFO
+ DEBUG ((EFI_D_INFO, " Processor GUID: %g\n", &Type4DataHob->PrcessorGuid));
+ DEBUG ((EFI_D_INFO, " Processor UUID: %d\n", Type4DataHob->ProcessorUid));
+#endif
+
+ GuidHob = (EFI_HOB_GUID_TYPE *)GetFirstGuidHob ((EFI_GUID *)PcdGetPtr(PcdProcessorSpecificDataGuidHobGuid));
+ if (GuidHob == NULL) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: No RISC_V_PROCESSOR_SPECIFIC_DATA_HOB found.\n"));
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Go through each RISC_V_PROCESSOR_SPECIFIC_DATA_HOB for multiple cores.
+ //
+ do {
+ ProcessorSpecificData = (RISC_V_PROCESSOR_SPECIFIC_DATA_HOB *)GET_GUID_HOB_DATA (GuidHob);
+ if (!CompareGuid (&ProcessorSpecificData->ParentPrcessorGuid, &Type4DataHob->PrcessorGuid) ||
+ ProcessorSpecificData->ParentProcessorUid != Type4DataHob->ProcessorUid) {
+ GuidHob = GetNextGuidHob((EFI_GUID *)PcdGetPtr(PcdProcessorSpecificDataGuidHobGuid), GET_NEXT_HOB(GuidHob));
+ if (GuidHob == NULL) {
+ break;
+ }
+ continue;
+ }
+
+#if RISCV_SMBIOS_DEBUG_INFO
+ DEBUG ((EFI_D_INFO, "[ ================================\n"));
+ DEBUG ((EFI_D_INFO, "[ Core GUID: %g\n", &ProcessorSpecificData->CoreGuid));
+#endif
+
+ Type44Ptr = AllocateZeroPool(sizeof(SMBIOS_TABLE_TYPE44) + sizeof(SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA));
+ if (Type44Ptr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ Type44Ptr->Hdr.Type = SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION;
+ Type44Ptr->Hdr.Handle = 0;
+ Type44Ptr->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE44) + sizeof(SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA);
+ Type44Ptr->RefHandle = Type4Handle;
+ Type44Ptr->ProcessorSpecificBlock.Length = sizeof(RISC_V_PROCESSOR_SPECIFIC_DATA_HOB);
+ Type44Ptr->ProcessorSpecificBlock.ProcessorArchType = Type4DataHob->SmbiosType4Processor.ProcessorFamily2 -
+ ProcessorFamilyRiscvRV32 + \
+ ProcessorSpecificBlockArchTypeRiscVRV32;
+ CopyMem ((VOID *)(Type44Ptr + 1), (VOID *)&ProcessorSpecificData->ProcessorSpecificData, sizeof (SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA));
+
+#if RISCV_SMBIOS_DEBUG_INFO
+ DEBUG ((EFI_D_INFO, "[ Core type: %d\n", Type44Ptr->ProcessorSpecificBlock.ProcessorArchType));
+ DEBUG ((EFI_D_INFO, " HartId = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->HartId.Value64_L));
+ DEBUG ((EFI_D_INFO, " Is Boot Hart? = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->BootHartId));
+ DEBUG ((EFI_D_INFO, " PrivilegeModeSupported = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->PrivilegeModeSupported));
+ DEBUG ((EFI_D_INFO, " MModeExcepDelegation = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->MModeExcepDelegation.Value64_L));
+ DEBUG ((EFI_D_INFO, " MModeInterruptDelegation = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->MModeInterruptDelegation.Value64_L));
+ DEBUG ((EFI_D_INFO, " HartXlen = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->HartXlen));
+ DEBUG ((EFI_D_INFO, " MachineModeXlen = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->MachineModeXlen));
+ DEBUG ((EFI_D_INFO, " SupervisorModeXlen = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->SupervisorModeXlen));
+ DEBUG ((EFI_D_INFO, " UserModeXlen = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->UserModeXlen));
+ DEBUG ((EFI_D_INFO, " InstSetSupported = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->InstSetSupported));
+ DEBUG ((EFI_D_INFO, " MachineVendorId = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->MachineVendorId.Value64_L));
+ DEBUG ((EFI_D_INFO, " MachineArchId = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->MachineArchId.Value64_L));
+ DEBUG ((EFI_D_INFO, " MachineImplId = 0x%x\n", ((SMBIOS_RISC_V_PROCESSOR_SPECIFIC_DATA *)(Type44Ptr + 1))->MachineImplId.Value64_L));
+#endif
+
+ //
+ // Add to SMBIOS table.
+ //
+ RiscVType44 = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add (Smbios, NULL, &RiscVType44, &Type44Ptr->Hdr);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: Fail to add SMBIOS Type 44\n"));
+ return Status;
+ }
+ DEBUG ((EFI_D_INFO, "[RISC-V SMBIOS Builder]: SMBIOS Type 44 was added. SMBIOS Handle: 0x%x\n", RiscVType44));
+
+ GuidHob = GetNextGuidHob((EFI_GUID *)PcdGetPtr(PcdProcessorSpecificDataGuidHobGuid), GET_NEXT_HOB(GuidHob));
+ } while (GuidHob != NULL);
+ return EFI_SUCCESS;
+}
+
+/**
+ Entry point of RISC-V SMBIOS builder.
+
+ @param ImageHandle Image handle this driver.
+ @param SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS Thread can be successfully created
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Cannot create the thread
+
+**/
+EFI_STATUS
+EFIAPI
+RiscVSmbiosBuilderEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ RISC_V_PROCESSOR_TYPE4_DATA_HOB *Type4HobData;
+ SMBIOS_HANDLE Processor;
+
+ DEBUG ((EFI_D_INFO, "[RISC-V SMBIOS Builder]: %a entry\n", __FUNCTION__));
+
+ Status = gBS->LocateProtocol (
+ &gEfiSmbiosProtocolGuid,
+ NULL,
+ (VOID **)&Smbios
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: Locate SMBIOS Protocol fail\n"));
+ return Status;
+ }
+ GuidHob = (EFI_HOB_GUID_TYPE *)GetFirstGuidHob ((EFI_GUID *)PcdGetPtr(PcdProcessorSmbiosType4GuidHobGuid));
+ if (GuidHob == NULL) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: No RISC-V SMBIOS information found.\n"));
+ return EFI_NOT_FOUND;
+ }
+ Type4HobData = (RISC_V_PROCESSOR_TYPE4_DATA_HOB *)GET_GUID_HOB_DATA (GuidHob);
+ Status = EFI_NOT_FOUND;
+ //
+ // Go through each RISC_V_PROCESSOR_TYPE4_DATA_HOB for multiple processors.
+ //
+ do {
+ Status = BuildSmbiosType4 (Type4HobData, &Processor);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: No RISC-V SMBIOS type 4 created.\n"));
+ ASSERT (FALSE);
+ }
+ Status = BuildSmbiosType44 (Type4HobData, Processor);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[RISC-V SMBIOS Builder]: No RISC-V SMBIOS type 44 found.\n"));
+ ASSERT (FALSE);
+ }
+
+ GuidHob = GetNextGuidHob((EFI_GUID *)PcdGetPtr(PcdProcessorSmbiosType4GuidHobGuid), GET_NEXT_HOB(GuidHob));
+ } while (GuidHob != NULL);
+ DEBUG ((EFI_D_INFO, "[RISC-V SMBIOS Builder]: %a exit\n", __FUNCTION__));
+ return Status;
+}
+
diff --git a/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.h b/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.h
new file mode 100644
index 0000000..9f7577f
--- /dev/null
+++ b/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.h
@@ -0,0 +1,38 @@
+/** @file
+ RISC-V SMBIOS Builder DXE module header file.
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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 _RISC_V_SMBIOS_DXE_H_
+#define _RISC_V_SMBIOS_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/Smbios.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+
+#include <SmbiosProcessorSpecificData.h>
+#include <ProcessorSpecificDataHob.h>
+
+#endif
+
diff --git a/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf b/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
new file mode 100644
index 0000000..5624226
--- /dev/null
+++ b/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf
@@ -0,0 +1,63 @@
+## @file
+# RISC-V SMBIOS DXE module.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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 = RiscVSmbiosDxe
+ MODULE_UNI_FILE = RiscVSmbiosDxe.uni
+ FILE_GUID = 5FC01647-AADD-42E1-AD99-DF4CB89F5A92
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RiscVSmbiosBuilderEntry
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CpuLib
+ DebugLib
+ DxeServicesTableLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+ HobLib
All the others are in alphabetical order, so can you move HobLib into
its natural position too?

/
Leif

+
+[Sources]
+ RiscVSmbiosDxe.c
+ RiscVSmbiosDxe.h
+
+[Protocols]
+ gEfiSmbiosProtocolGuid # Consumed
+
+[Guids]
+
+
+[Pcd]
+
+[FixedPcd]
+ gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid
+ gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid
+ gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid
+ gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSpecificDataGuidHobGuid
+
+[Depex]
+ gEfiSmbiosProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ RiscVSmbiosDxeExtra.uni
diff --git a/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.uni b/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.uni
new file mode 100644
index 0000000000000000000000000000000000000000..e35ce629d3c92f24ef55f9ac136059716f2a81bb
GIT binary patch
literal 1542
zcmb7^TW`}q6ok(+68~Y9z5r?yK$Q>(A(GZW1k_gIP<X0xZ7q_fvO`P%Jn+qN9ESix
zmF2z8&Y7J(yFY)ltYv}!5nr&^HnYs;Hnsb9kI~kq4t8WqyRuu$L7dx#t-wF9u|1@I
zYLD%SJ-2<@?^u1~94p5pHU#yRGPeoykzF!ArFZ3A1?^zRl-K-okFua8RIm@0Sd+TV
z%$&N8UU+Y6TA%yc3CNe$v7Wu!=&tq=EJbq$I(XbAd&tqWpg$y*l&wHWi}a4su>h&L
zTh?8I4~z`g+A~^n*lK?5Ppjvk$F5(>#9Q%e^<*94nzo!C+K5u?zPSqRrB+h<v~blG
zi<C)khLX(N+S8JgtJig`kE3#LTT89=#=RI*{<+%>HDZ(-rC*9w(3kfkbXIY7E~T&1
zKVzmmBdPulYFE|o&XjK6f*Se$XY8T$K$=!t&MMbdoW%>zNM)h2qi}rgUN>pyoKS1W
z{eqDZ$cY{7%rs%S;IBQYTPZmlp(`PiVtY&3wvY6?xT;K5oif@b*9NpA_j+I_)Dh$I
zq-3biq09Y=K=hqCrlp)#*`OA$SR2$G@2j`JrS6n@vBn-T*eR%<D?4Gl3#&L{kKUsv
z?HW_e6s$0cTB6>7RrD{^@0pQu-Q8#%rQAhipEo=;dlxSfGD|U!xp9?mRUP~-DPIna
z>EGMrPkE0@|IT2F;TXUc*%^xDmz-_mR*If~eS4gy?!!45Go)1hDJKr#lF|koa`1?e
zPxKSAW9gYvc;4ua^@-jA75j<~OuCP{pE>LArd;Q)Xo{L_y#AZ||0}PRggfsd<*m}~
a2zKb_`OM2hdU`ph{;KH}E;zS(kG}wCE9rRv

literal 0
HcmV?d00001

diff --git a/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxeExtra.uni b/RiscVPkg/Universal/SmbiosDxe/RiscVSmbiosDxeExtra.uni
new file mode 100644
index 0000000000000000000000000000000000000000..ccfdb2aa9e6bb05715d27beb7c5d1edec7aca7cf
GIT binary patch
literal 1438
zcmZ{kTW=FV42AuS#D5s2FM!$vcmp9s(kwKhO`=@5JXN`nbVY93q%Gmc1K;uPWR(J1
z?Tp9cIX?E-^ZQrLY8LpP@dbNlGfQn@-|VqHLaV)=wXARFc4nVg_3g?UXgWv%>DKM1
zoXA*T+S(>I0wJ}Z=%#*R$6jhHo7<N42ub>LY*)6!N@MgF=X`%-dp|q38*G9-0sSfS
zOM7lF?3JA&Ux0A$oOf>1#lytDGiL55DZFI1ajY%&!J3SB{0mrYY>6ZmilA#%<~lnI
zW--sbi+hHh&S!phisc(}(6hJy;6H$K>JiKD8k7u9OHg74c36mu_)f4`!bE%fB3l8?
z2v+i!A}v5G^P~85TDhJet(=)M8}W5oHzUm*zixJ9V@Bz2IT7zIGRb`{opnSJGg+oE
zNnKVZ)>KMBlSj~?8k(#xkGPav?>!e2#=oOYVIxFg<@u7YEo((RhG+DvdkHoue9qX(
z??|kFVD*sIac1&t?y(ws{4-+6b0AJ-1qSd{NgI3Z9iaNivn%_|b6w?Z#*Nk<WPgih
z4EHJBa_qed$_;<aNt_kWg(a}+Qb!&8z*wipf_I(jRNXi5E^OEkDe+7Xt<9XEFA>UH
zXwh8>7JWzVAgQ7?R+#$*dWE^+Yxy`ma0~Vsuj18lk6PF9BxY^&El`Egaqm4=;x3(h
z4zQAqyyjN#vDL}1%pchib9HV~c*&zk?8^bCL~oIcE_EfJP5Le7EzZGTuA1wmJ2_O2
z-W$DF%H4I5-7YA-Lj>1gcR(G2pJ3C5<rPwJv=eSnJuv6iM~vzj)xjC|;wNtv(Ek5A
c_OMs?<nPeKx3WpR^40V@*ISf<C)D`=0ZK&O-T(jq

literal 0
HcmV?d00001

--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 16/22]: RiscVPkg/CpuDxe: Add RISC-V CPU DXE driver.

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:11PM +0800, Abner Chang wrote:
The driver produces RISC-V EFI_CPU_ARCH_PROTOCOL and use RISC-V platform level timer library

Due to RISC-V timer CSR is platform implementation specific, RISC-V CPU DXE driver invokes platform level timer library
to access to timer CSRs.
No comments beyond PatchCheck.py, license/SPDX and contribution agreement.

/
Leif

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
RiscVPkg/Universal/CpuDxe/CpuDxe.c | 324 +++++++++++++++
RiscVPkg/Universal/CpuDxe/CpuDxe.h | 212 ++++++++++
RiscVPkg/Universal/CpuDxe/CpuDxe.inf | 66 +++
RiscVPkg/Universal/CpuDxe/CpuDxe.uni | Bin 0 -> 1564 bytes
RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni | Bin 0 -> 1392 bytes
RiscVPkg/Universal/CpuDxe/CpuMp.h | 648 ++++++++++++++++++++++++++++++
6 files changed, 1250 insertions(+)
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.c
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.h
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.inf
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxe.uni
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni
create mode 100644 RiscVPkg/Universal/CpuDxe/CpuMp.h

diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxe.c b/RiscVPkg/Universal/CpuDxe/CpuDxe.c
new file mode 100644
index 0000000..37d9bcf
--- /dev/null
+++ b/RiscVPkg/Universal/CpuDxe/CpuDxe.c
@@ -0,0 +1,324 @@
+/** @file
+ RISC-V CPU DXE driver.
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 "CpuDxe.h"
+
+//
+// Global Variables
+//
+BOOLEAN InterruptState = FALSE;
+EFI_HANDLE mCpuHandle = NULL;
+BOOLEAN mIsFlushingGCD;
+
+EFI_CPU_ARCH_PROTOCOL gCpu = {
+ CpuFlushCpuDataCache,
+ CpuEnableInterrupt,
+ CpuDisableInterrupt,
+ CpuGetInterruptState,
+ CpuInit,
+ CpuRegisterInterruptHandler,
+ CpuGetTimerValue,
+ CpuSetMemoryAttributes,
+ 1, // NumberOfTimers
+ 4 // DmaBufferAlignment
+};
+
+//
+// CPU Arch Protocol Functions
+//
+
+/**
+ Flush CPU data cache. If the instruction cache is fully coherent
+ with all DMA operations then function can just return EFI_SUCCESS.
+
+ @param This Protocol instance structure
+ @param Start Physical address to start flushing from.
+ @param Length Number of bytes to flush. Round up to chipset
+ granularity.
+ @param FlushType Specifies the type of flush operation to perform.
+
+ @retval EFI_SUCCESS If cache was flushed
+ @retval EFI_UNSUPPORTED If flush type is not supported.
+ @retval EFI_DEVICE_ERROR If requested range could not be flushed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Enables CPU interrupts.
+
+ @param This Protocol instance structure
+
+ @retval EFI_SUCCESS If interrupts were enabled in the CPU
+ @retval EFI_DEVICE_ERROR If interrupts could not be enabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ )
+{
+ EnableInterrupts ();
+ InterruptState = TRUE;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Disables CPU interrupts.
+
+ @param This Protocol instance structure
+
+ @retval EFI_SUCCESS If interrupts were disabled in the CPU.
+ @retval EFI_DEVICE_ERROR If interrupts could not be disabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ )
+{
+ DisableInterrupts ();
+ InterruptState = FALSE;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Return the state of interrupts.
+
+ @param This Protocol instance structure
+ @param State Pointer to the CPU's current interrupt state
+
+ @retval EFI_SUCCESS If interrupts were disabled in the CPU.
+ @retval EFI_INVALID_PARAMETER State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ OUT BOOLEAN *State
+ )
+{
+ if (State == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *State = InterruptState;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Generates an INIT to the CPU.
+
+ @param This Protocol instance structure
+ @param InitType Type of CPU INIT to perform
+
+ @retval EFI_SUCCESS If CPU INIT occurred. This value should never be
+ seen.
+ @retval EFI_DEVICE_ERROR If CPU INIT failed.
+ @retval EFI_UNSUPPORTED Requested type of CPU INIT not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_CPU_INIT_TYPE InitType
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Registers a function to be called from the CPU interrupt handler.
+
+ @param This Protocol instance structure
+ @param InterruptType Defines which interrupt to hook. IA-32
+ valid range is 0x00 through 0xFF
+ @param InterruptHandler A pointer to a function of type
+ EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. A null
+ pointer is an error condition.
+
+ @retval EFI_SUCCESS If handler installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler
+ for InterruptType was previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for
+ InterruptType was not previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType
+ is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuRegisterInterruptHandler (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ return RegisterCpuInterruptHandler (InterruptType, InterruptHandler);
+}
+
+
+/**
+ Returns a timer value from one of the CPU's internal timers. There is no
+ inherent time interval between ticks but is a function of the CPU frequency.
+
+ @param This - Protocol instance structure.
+ @param TimerIndex - Specifies which CPU timer is requested.
+ @param TimerValue - Pointer to the returned timer value.
+ @param TimerPeriod - A pointer to the amount of time that passes
+ in femtoseconds (10-15) for each increment
+ of TimerValue. If TimerValue does not
+ increment at a predictable rate, then 0 is
+ returned. The amount of time that has
+ passed between two calls to GetTimerValue()
+ can be calculated with the formula
+ (TimerValue2 - TimerValue1) * TimerPeriod.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS - If the CPU timer count was returned.
+ @retval EFI_UNSUPPORTED - If the CPU does not have any readable timers.
+ @retval EFI_DEVICE_ERROR - If an error occurred while reading the timer.
+ @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN UINT32 TimerIndex,
+ OUT UINT64 *TimerValue,
+ OUT UINT64 *TimerPeriod OPTIONAL
+ )
+{
+ if (TimerValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TimerIndex != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TimerValue = (UINT64)RiscVReadMachineTimer ();
+ if (TimerPeriod != NULL) {
+ *TimerPeriod = DivU64x32 (
+ 1000000000000000u,
+ PcdGet64 (PcdRiscVMachineTimerFrequencyInHerz)
+ );
+ }
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Implementation of SetMemoryAttributes() service of CPU Architecture Protocol.
+
+ This function modifies the attributes for the memory region specified by BaseAddress and
+ Length from their current attributes to the attributes specified by Attributes.
+
+ @param This The EFI_CPU_ARCH_PROTOCOL instance.
+ @param BaseAddress The physical address that is the start address of a memory region.
+ @param Length The size in bytes of the memory region.
+ @param Attributes The bit mask of attributes to set for the memory region.
+
+ @retval EFI_SUCCESS The attributes were set for the memory region.
+ @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
+ BaseAddress and Length cannot be modified.
+ @retval EFI_INVALID_PARAMETER Length is zero.
+ Attributes specified an illegal combination of attributes that
+ cannot be set together.
+ @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
+ the memory resource range.
+ @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
+ resource range specified by BaseAddress and Length.
+ The bit mask of attributes is not support for the memory resource
+ range specified by BaseAddress and Length.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+{
+ DEBUG ((DEBUG_INFO, "%a:Set memory attributes not supported yet\n", __FUNCTION__));
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Initialize the state information for the CPU Architectural Protocol.
+
+ @param ImageHandle Image handle this driver.
+ @param SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS Thread can be successfully created
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Cannot create the thread
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpu (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Machine mode handler is initiated in CpuExceptionHandlerLibConstructor in
+ // CpuExecptionHandlerLib.
+ //
+
+ //
+ // Make sure interrupts are disabled
+ //
+ DisableInterrupts ();
+
+ //
+ // Install CPU Architectural Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mCpuHandle,
+ &gEfiCpuArchProtocolGuid, &gCpu,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxe.h b/RiscVPkg/Universal/CpuDxe/CpuDxe.h
new file mode 100644
index 0000000..00f40ff
--- /dev/null
+++ b/RiscVPkg/Universal/CpuDxe/CpuDxe.h
@@ -0,0 +1,212 @@
+/** @file
+ RISC-V CPU DXE module header file.
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 _CPU_DXE_H_
+#define _CPU_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
+#include <Library/TimerLib.h>
+#include <Library/RiscVCpuLib.h>
+
+/**
+ Flush CPU data cache. If the instruction cache is fully coherent
+ with all DMA operations then function can just return EFI_SUCCESS.
+
+ @param This Protocol instance structure
+ @param Start Physical address to start flushing from.
+ @param Length Number of bytes to flush. Round up to chipset
+ granularity.
+ @param FlushType Specifies the type of flush operation to perform.
+
+ @retval EFI_SUCCESS If cache was flushed
+ @retval EFI_UNSUPPORTED If flush type is not supported.
+ @retval EFI_DEVICE_ERROR If requested range could not be flushed.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuFlushCpuDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType
+ );
+
+/**
+ Enables CPU interrupts.
+
+ @param This Protocol instance structure
+
+ @retval EFI_SUCCESS If interrupts were enabled in the CPU
+ @retval EFI_DEVICE_ERROR If interrupts could not be enabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuEnableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ );
+
+/**
+ Disables CPU interrupts.
+
+ @param This Protocol instance structure
+
+ @retval EFI_SUCCESS If interrupts were disabled in the CPU.
+ @retval EFI_DEVICE_ERROR If interrupts could not be disabled on the CPU.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuDisableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ );
+
+/**
+ Return the state of interrupts.
+
+ @param This Protocol instance structure
+ @param State Pointer to the CPU's current interrupt state
+
+ @retval EFI_SUCCESS If interrupts were disabled in the CPU.
+ @retval EFI_INVALID_PARAMETER State is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetInterruptState (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ OUT BOOLEAN *State
+ );
+
+/**
+ Generates an INIT to the CPU.
+
+ @param This Protocol instance structure
+ @param InitType Type of CPU INIT to perform
+
+ @retval EFI_SUCCESS If CPU INIT occurred. This value should never be
+ seen.
+ @retval EFI_DEVICE_ERROR If CPU INIT failed.
+ @retval EFI_UNSUPPORTED Requested type of CPU INIT not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuInit (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_CPU_INIT_TYPE InitType
+ );
+
+/**
+ Registers a function to be called from the CPU interrupt handler.
+
+ @param This Protocol instance structure
+ @param InterruptType Defines which interrupt to hook. IA-32
+ valid range is 0x00 through 0xFF
+ @param InterruptHandler A pointer to a function of type
+ EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. A null
+ pointer is an error condition.
+
+ @retval EFI_SUCCESS If handler installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler
+ for InterruptType was previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for
+ InterruptType was not previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType
+ is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuRegisterInterruptHandler (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+/**
+ Returns a timer value from one of the CPU's internal timers. There is no
+ inherent time interval between ticks but is a function of the CPU frequency.
+
+ @param This - Protocol instance structure.
+ @param TimerIndex - Specifies which CPU timer is requested.
+ @param TimerValue - Pointer to the returned timer value.
+ @param TimerPeriod - A pointer to the amount of time that passes
+ in femtoseconds (10-15) for each increment
+ of TimerValue. If TimerValue does not
+ increment at a predictable rate, then 0 is
+ returned. The amount of time that has
+ passed between two calls to GetTimerValue()
+ can be calculated with the formula
+ (TimerValue2 - TimerValue1) * TimerPeriod.
+ This parameter is optional and may be NULL.
+
+ @retval EFI_SUCCESS - If the CPU timer count was returned.
+ @retval EFI_UNSUPPORTED - If the CPU does not have any readable timers.
+ @retval EFI_DEVICE_ERROR - If an error occurred while reading the timer.
+ @retval EFI_INVALID_PARAMETER - TimerIndex is not valid or TimerValue is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuGetTimerValue (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN UINT32 TimerIndex,
+ OUT UINT64 *TimerValue,
+ OUT UINT64 *TimerPeriod OPTIONAL
+ );
+
+/**
+ Set memory cacheability attributes for given range of memeory.
+
+ @param This Protocol instance structure
+ @param BaseAddress Specifies the start address of the
+ memory range
+ @param Length Specifies the length of the memory range
+ @param Attributes The memory cacheability for the memory range
+
+ @retval EFI_SUCCESS If the cacheability of that memory range is
+ set successfully
+ @retval EFI_UNSUPPORTED If the desired operation cannot be done
+ @retval EFI_INVALID_PARAMETER The input parameter is not correct,
+ such as Length = 0
+
+**/
+EFI_STATUS
+EFIAPI
+CpuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+#endif
+
diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxe.inf b/RiscVPkg/Universal/CpuDxe/CpuDxe.inf
new file mode 100644
index 0000000..93638e7
--- /dev/null
+++ b/RiscVPkg/Universal/CpuDxe/CpuDxe.inf
@@ -0,0 +1,66 @@
+## @file
+# RISC-V CPU DXE module.
+#
+# Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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 = CpuDxe
+ MODULE_UNI_FILE = CpuDxe.uni
+ FILE_GUID = 1A1E4886-9517-440e-9FDE-3BE44CEE2136
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeCpu
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ CpuLib
+ DebugLib
+ DxeServicesTableLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+ CpuExceptionHandlerLib
+ TimerLib
+ SynchronizationLib
+ HobLib
+ ReportStatusCodeLib
+ RiscVCpuLib
+ RiscVPlatformTimerLib
+
+[Sources]
+ CpuDxe.c
+ CpuDxe.h
+
+[Protocols]
+ gEfiCpuArchProtocolGuid ## PRODUCES
+
+[Guids]
+
+[Ppis]
+
+[Pcd]
+ gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ CpuDxeExtra.uni
diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxe.uni b/RiscVPkg/Universal/CpuDxe/CpuDxe.uni
new file mode 100644
index 0000000000000000000000000000000000000000..51e3c0c06df37e5abb4be67ca2bc73d5da4cbdd2
GIT binary patch
literal 1564
zcmb7^TW`}q5QXO%iT_}wFMyf^c;EpcMA90FfX2#&!c&!NYmwBI<F@3_1K*jA<1`cj
zvb?jG*)wO(&hF12O>0`j|Aa5HH#WD_7B;ho_JG;u)<$+@nO)i1ay-uM!V3H!*~A`W
zpW9P=W-siJ{(E-cI!56>iH-33Mw{D|_1G?%pE0^}tQGypj%jcB7anCvPhOFIw8R?N
z7Ap&E6@BHSnQ4FSd#8B5vbOc?^_F*;M`Qyyr+7ymHzS7}PD{okVu@LShq#FE1RhH~
zwYFy8CH@gJqYd|z-U74=U-@bG0`H0Q7c=3O_}V?)M7W_ZrAIcV)xK+Ip<F5^L8qm&
zE>Xlxd{daD-d9c;Cs*xjTOUQG-Y%Dl>#b`sq5VDE6gEPX8bL3`S}~UPV|bQvbuK|y
z@t?C2&Pc4k<F(J~t};Q*HC|)Se@+fT192*LlvS-2oW)D8NL8V#W99z2Yu%uqb3)BM
z^;gV{@tj(HZ>0gs1%IVU)f-U5F}xBgscY|OTlR@@2US(6vIAy2)Y_0<>{<`)1RFCi
zO#(u74jt}Kj7Q&*yYy7kYHL{G3blr9`&gsH9d@Uz3$^PJBRj>b=gdx+?|>?du1D`N
z5_ioh<^W&$C~EL}i?5=8#eQH#%yoC;O_Y#DY+trG6?z9P5-LkEkGXNBZl#U<EeS7&
z=JX$I>nGf!px+rtT`-2A#dZcG=_O@bs5OAkpS}Z5Q}^MViW$+W{!|lnu*9?mJ5@-*
zs%mn@oX)EcZrwgJIwFT5wng3O9_TjB=oKJ_dz@f1#u>927&Xu2-?LFID4yabTmA3L
c=<nIw&wUER)L%Zm8G57cX8iv-Hg>Z71xlCjC;$Ke

literal 0
HcmV?d00001

diff --git a/RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni b/RiscVPkg/Universal/CpuDxe/CpuDxeExtra.uni
new file mode 100644
index 0000000000000000000000000000000000000000..e6201a906ae37cfb24a6b501d9789d28f15b96f7
GIT binary patch
literal 1392
zcmZXU+iwz45XR@(#Q))hzNl$I`{08yMqpP<Y=KbF`qXe~=|(7Ip%?t))!#RJYcZQW
zmpL=veCM0l{rjh34GX+)c!GVlYfEflSN76gVAWaM)^=x+Jz@=ZYAc)C7@x#`W0_$)
zx2>h@Z*6WH_G4DExADE@?8?Uiv6!>-we381ZZ~)adj<My=3{$n@9e!DvOWRf!C7tH
zr%#5d{bEc#Pn>5-VJaRQXBsiy^Dbbqwk0cZ(GB`mXKr$`U{*wyUEEXr6rXzR49}0&
zvVnan6{+|S;jC=I^R7Ti;k0C5D6qvts)_Fu9!orRw#(HDSjMi9SV+}PnMYA#6R;*k
zi@%sj*#ckDvpmB+Yt?RS6Gp||5uwwRb-_f{NXh!NPGTm{1h2%`I$hBVRa}cIN9<3Z
zajCR;a4n{c|KBztrx3*<(@VKF>~-r2Jd3=lOEBpw{@0vjH4^Jby!Kf=S0+<)hu0*J
zU*#Hz)Aot7>a{Jk_~1RR{>apof9hJ-xqnJU8++<+uuR}Sv!lI}Iw&{1g(k(U`<z$|
zt3G|yv#*RzJ7eEL(}1d)hgdsw+K5%`N{_6|9AmE#sw#B&x?()e9l6I!9j&p(EL@@1
zm|MQr?y%$*><8!K)$@$nH_0SsUF;oDh0*iu19svrn{p2El8>@xUSIH4<WJ^roQS!;
z+&IsY-6FP&5~o7%phcg)QqG9)t<bHQga4ZvZkO$#>>T}X^!Jf=m$|xqPzL1<F2U}B
zIs!k&rwhw7R>9E@sGz>2IaMDss^`=PNBE1MveiJ7c5STRu{FIv)W_<{DWf_@U#=>7
Q;n)$D#Qz^D@j@xye-~NTv;Y7A

literal 0
HcmV?d00001

diff --git a/RiscVPkg/Universal/CpuDxe/CpuMp.h b/RiscVPkg/Universal/CpuDxe/CpuMp.h
new file mode 100644
index 0000000..adb3ef3
--- /dev/null
+++ b/RiscVPkg/Universal/CpuDxe/CpuMp.h
@@ -0,0 +1,648 @@
+/** @file
+ RISC-V CPU DXE MP definitions.
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 _CPU_MP_H_
+#define _CPU_MP_H_
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPlatformInformation2.h>
+#include <Protocol/MpService.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/HobLib.h>
+#include <Library/ReportStatusCodeLib.h>
+
+/**
+ Initialize Multi-processor support.
+
+**/
+VOID
+InitializeMpSupport (
+ VOID
+ );
+
+typedef
+VOID
+(EFIAPI *STACKLESS_AP_ENTRY_POINT)(
+ VOID
+ );
+
+/**
+ Starts the Application Processors and directs them to jump to the
+ specified routine.
+
+ The processor jumps to this code in flat mode, but the processor's
+ stack is not initialized.
+
+ @retval EFI_SUCCESS The APs were started
+
+**/
+EFI_STATUS
+StartApsStackless (
+ VOID
+ );
+
+/**
+ The AP entry point that the Startup-IPI target code will jump to.
+
+ The processor jumps to this code in flat mode, but the processor's
+ stack is not initialized.
+
+**/
+VOID
+EFIAPI
+AsmApEntryPoint (
+ VOID
+ );
+
+/**
+ Releases the lock preventing other APs from using the shared AP
+ stack.
+
+ Once the AP has transitioned to using a new stack, it can call this
+ function to allow another AP to proceed with using the shared stack.
+
+**/
+VOID
+EFIAPI
+AsmApDoneWithCommonStack (
+ VOID
+ );
+
+typedef enum {
+ CpuStateIdle,
+ CpuStateBlocked,
+ CpuStateReady,
+ CpuStateBusy,
+ CpuStateFinished,
+ CpuStateSleeping
+} CPU_STATE;
+
+/**
+ Define Individual Processor Data block.
+
+**/
+typedef struct {
+ EFI_PROCESSOR_INFORMATION Info;
+ SPIN_LOCK CpuDataLock;
+ INTN LockSelf;
+ volatile CPU_STATE State;
+
+ volatile EFI_AP_PROCEDURE Procedure;
+ volatile VOID* Parameter;
+ BOOLEAN *Finished;
+ INTN Timeout;
+ EFI_EVENT WaitEvent;
+ BOOLEAN TimeoutActive;
+ EFI_EVENT CheckThisAPEvent;
+ VOID *TopOfStack;
+} CPU_DATA_BLOCK;
+
+/**
+ Define MP data block which consumes individual processor block.
+
+**/
+typedef struct {
+ CPU_DATA_BLOCK *CpuDatas;
+ UINTN NumberOfProcessors;
+ UINTN NumberOfEnabledProcessors;
+
+ EFI_AP_PROCEDURE Procedure;
+ VOID *ProcedureArgument;
+ UINTN StartCount;
+ UINTN FinishCount;
+ BOOLEAN SingleThread;
+ UINTN **FailedList;
+ UINTN FailedListIndex;
+ INTN Timeout;
+ EFI_EVENT WaitEvent;
+ BOOLEAN TimeoutActive;
+ EFI_EVENT CheckAllAPsEvent;
+} MP_SYSTEM_DATA;
+
+/**
+ This function is called by all processors (both BSP and AP) once and collects MP related data.
+
+ @param Bsp TRUE if the CPU is BSP
+ @param ProcessorNumber The specific processor number
+
+ @retval EFI_SUCCESS Data for the processor collected and filled in
+
+**/
+EFI_STATUS
+FillInProcessorInformation (
+ IN BOOLEAN Bsp,
+ IN UINTN ProcessorNumber
+ );
+
+/**
+ This service retrieves the number of logical processor in the platform
+ and the number of those logical processors that are enabled on this boot.
+ This service may only be called from the BSP.
+
+ This function is used to retrieve the following information:
+ - The number of logical processors that are present in the system.
+ - The number of enabled logical processors in the system at the instant
+ this call is made.
+
+ Because MP Service Protocol provides services to enable and disable processors
+ dynamically, the number of enabled logical processors may vary during the
+ course of a boot session.
+
+ If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
+ If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
+ is returned in NumberOfProcessors, the number of currently enabled processor
+ is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[out] NumberOfProcessors Pointer to the total number of logical
+ processors in the system, including the BSP
+ and disabled APs.
+ @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
+ processors that exist in system, including
+ the BSP.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
+ @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetNumberOfProcessors (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors
+ );
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ This service retrieves detailed MP-related information about any processor
+ on the platform. Note the following:
+ - The processor information may change during the course of a boot session.
+ - The information presented here is entirely MP related.
+
+ Information regarding the number of caches and their sizes, frequency of operation,
+ slot numbers is all considered platform-related information and is not provided
+ by this service.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] ProcessorNumber The handle number of processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
+ the requested processor is deposited.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+
+**/
+EFI_STATUS
+EFIAPI
+GetProcessorInfo (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ );
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking and non-blocking requests. The non-blocking requests use EFI
+ events so the BSP can detect when the APs have finished. This service may only
+ be called from the BSP.
+
+ This function is used to dispatch all the enabled APs to the function specified
+ by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
+ immediately and Procedure is not started on any AP.
+
+ If SingleThread is TRUE, all the enabled APs execute the function specified by
+ Procedure one by one, in ascending order of processor handle number. Otherwise,
+ all the enabled APs execute the function specified by Procedure simultaneously.
+
+ If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
+ APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking
+ mode, and the BSP returns from this service without waiting for APs. If a
+ non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled, then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before all APs return
+ from Procedure, then Procedure on the failed APs is terminated. All enabled APs
+ are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
+ content points to the list of processor handle numbers in which Procedure was
+ terminated.
+
+ Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ to make sure that the nature of the code that is executed on the BSP and the
+ dispatched APs is well controlled. The MP Services Protocol does not guarantee
+ that the Procedure function is MP-safe. Hence, the tasks that can be run in
+ parallel are limited to certain independent tasks and well-controlled exclusive
+ code. EFI services and protocols may not be called by APs unless otherwise
+ specified.
+
+ In blocking execution mode, BSP waits until all APs finish or
+ TimeoutInMicroseconds expires.
+
+ In non-blocking execution mode, BSP is freed to return to the caller and then
+ proceed to the next task without having to wait for APs. The following
+ sequence needs to occur in a non-blocking execution mode:
+
+ -# The caller that intends to use this MP Services Protocol in non-blocking
+ mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
+ invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
+ is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
+ the function specified by Procedure to be started on all the enabled APs,
+ and releases the BSP to continue with other tasks.
+ -# The caller can use the CheckEvent() and WaitForEvent() services to check
+ the state of the WaitEvent created in step 1.
+ -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
+ Service signals WaitEvent by calling the EFI SignalEvent() function. If
+ FailedCpuList is not NULL, its content is available when WaitEvent is
+ signaled. If all APs returned from Procedure prior to the timeout, then
+ FailedCpuList is set to NULL. If not all APs return from Procedure before
+ the timeout, then FailedCpuList is filled in with the list of the failed
+ APs. The buffer is allocated by MP Service Protocol using AllocatePool().
+ It is the caller's responsibility to free the buffer with FreePool() service.
+ -# This invocation of SignalEvent() function informs the caller that invoked
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
+ the specified task or a timeout occurred. The contents of FailedCpuList
+ can be examined to determine which APs did not complete the specified task
+ prior to the timeout.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
+ execute the function specified by Procedure
+ simultaneously.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure, or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
+ if all APs finish successfully, then its
+ content is set to NULL. If not all APs
+ finish before timeout expires, then its
+ content is set to address of the buffer
+ holding handle numbers of the failed APs.
+ The buffer is allocated by MP Service Protocol,
+ and it's the caller's responsibility to
+ free the buffer with FreePool() service.
+ In blocking mode, it is ready for consumption
+ when the call returns. In non-blocking mode,
+ it is ready when WaitEvent is signaled. The
+ list of failed CPU is terminated by
+ END_OF_CPU_LIST.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
+ to all enabled APs.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ all enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+StartupAllAPs (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ );
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to either wait for the completion
+ of the AP or just proceed with the next task by using the EFI event mechanism.
+ See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
+ execution support. This service may only be called from the BSP.
+
+ This function is used to dispatch one enabled AP to the function specified by
+ Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
+ is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
+ TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
+ BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
+ is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
+ then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
+ EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] Finished If NULL, this parameter is ignored. In
+ blocking mode, this parameter is ignored.
+ In non-blocking mode, if AP returns from
+ Procedure before the timeout expires, its
+ content is set to TRUE. Otherwise, the
+ value is set to FALSE. The caller can
+ determine if the AP returned from Procedure
+ by evaluating this value.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval EFI_SUCCESS In non-blocking mode, the function has been
+ dispatched to specified AP.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ the specified AP has finished.
+ @retval EFI_NOT_READY The specified AP is busy.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+StartupThisAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ );
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be performed
+ by the current BSP.
+
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. The new BSP can take over the
+ execution of the old BSP and continue seamlessly from where the old one left
+ off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled.
+
+ If the BSP cannot be switched prior to the return from this service, then
+ EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ this service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+
+**/
+EFI_STATUS
+EFIAPI
+SwitchBSP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ );
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ This service allows the caller enable or disable an AP from this point onward.
+ The caller can optionally specify the health status of the AP by Health. If
+ an AP is being disabled, then the state of the disabled AP is implementation
+ dependent. If an AP is enabled, then the implementation must guarantee that a
+ complete initialization sequence is performed on the AP, so the AP is in a state
+ that is compatible with an MP operating system. This service may not be supported
+ after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
+
+ If the enable or disable AP operation cannot be completed prior to the return
+ from this service, then EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP. This flag
+ corresponds to StatusFlag defined in
+ EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
+ the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter
+ is ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
+ prior to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableDisableAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ );
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ This service returns the processor handle number for the calling processor.
+ The returned value is in the range from 0 to the total number of logical
+ processors minus 1. The total number of logical processors can be retrieved
+ with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
+ called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
+ is returned. Otherwise, the current processors handle number is returned in
+ ProcessorNumber, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[out] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned
+ in ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+WhoAmI (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *ProcessorNumber
+ );
+
+/**
+ Terminate AP's task and set it to idle state.
+
+ This function terminates AP's task due to timeout by sending INIT-SIPI,
+ and sends it to idle state.
+
+ @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
+
+**/
+VOID
+ResetProcessorToIdleState (
+ IN CPU_DATA_BLOCK *CpuData
+ );
+
+/**
+ Prepares Startup Code for APs.
+ This function prepares Startup Code for APs.
+
+ @retval EFI_SUCCESS The APs were started
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate memory to start APs
+
+**/
+EFI_STATUS
+PrepareAPStartupCode (
+ VOID
+ );
+
+/**
+ Free the code buffer of startup AP.
+
+**/
+VOID
+FreeApStartupCode (
+ VOID
+ );
+
+/**
+ Resets the Application Processor and directs it to jump to the
+ specified routine.
+
+ The processor jumps to this code in flat mode, but the processor's
+ stack is not initialized.
+
+ @param ProcessorId the AP of ProcessorId was reset
+**/
+VOID
+ResetApStackless (
+ IN UINT32 ProcessorId
+ );
+
+#endif // _CPU_MP_H_
+
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 15/22]: RiscVPkg/RealTimeClockRuntimeDxe: Add RISC-V RTC Runtime Driver

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:10PM +0800, Abner Chang wrote:
This is the abstract driver which incorporate with platform level RTC library (RealTimeClockLib) to provide Real Time Clock Architecture Protocol.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
.../RealTimeClockRuntimeDxe/RealTimeClock.c | 157 +++++++++++++++++++++
.../RealTimeClockRuntimeDxe.inf | 44 ++++++
2 files changed, 201 insertions(+)
create mode 100644 RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClock.c
create mode 100644 RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
Why do we have this separate implementation?
It looks pretty much equivalent to
EmbeddedPkg/RealTimeClockRuntimeDxe/, but with the timezone handling
ripped out.

/
Leif


diff --git a/RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClock.c b/RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClock.c
new file mode 100644
index 0000000..c3d04e7
--- /dev/null
+++ b/RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClock.c
@@ -0,0 +1,157 @@
+/** @file
+ Implementation of EFI RealTimeClock runtime services via platform RTC Lib.
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+ 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 <PiDxe.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/RealTimeClockLib.h>
+#include <Protocol/RealTimeClock.h>
+
+EFI_HANDLE mHandle = NULL;
+
+/**
+ Returns the current time and date information, and the time-keeping capabilities
+ of the hardware platform.
+
+ @param Time A pointer to storage to receive a snapshot of the current time.
+ @param Capabilities An optional pointer to a buffer to receive the real time clock
+ device's capabilities.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Time is NULL.
+ @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+GetTime (
+ OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities
+ )
+{
+ return LibGetTime (Time, Capabilities);
+}
+
+
+
+/**
+ Sets the current local time and date information.
+
+ @param Time A pointer to the current time.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER A time field is out of range.
+ @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+SetTime (
+ IN EFI_TIME *Time
+ )
+{
+ return LibSetTime (Time);
+}
+
+
+/**
+ Returns the current wakeup alarm clock setting.
+
+ @param Enabled Indicates if the alarm is currently enabled or disabled.
+ @param Pending Indicates if the alarm signal is pending and requires acknowledgement.
+ @param Time The current alarm setting.
+
+ @retval EFI_SUCCESS The alarm settings were returned.
+ @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+ @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+GetWakeupTime (
+ OUT BOOLEAN *Enabled,
+ OUT BOOLEAN *Pending,
+ OUT EFI_TIME *Time
+ )
+{
+ return LibGetWakeupTime (Enabled, Pending, Time);
+}
+
+
+/**
+ Sets the system wakeup alarm clock time.
+
+ @param Enabled Enable or disable the wakeup alarm.
+ @param Time If Enable is TRUE, the time to set the wakeup alarm for.
+
+ @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If
+ Enable is FALSE, then the wakeup alarm was disabled.
+ @retval EFI_INVALID_PARAMETER A time field is out of range.
+ @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error.
+ @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+SetWakeupTime (
+ IN BOOLEAN Enabled,
+ OUT EFI_TIME *Time
+ )
+{
+ return LibSetWakeupTime (Enabled, Time);
+}
+
+
+
+/**
+ This is the declaration of an EFI image entry point. This can be the entry point to an application
+ written to this specification, an EFI boot service driver, or an EFI runtime driver.
+
+ @param ImageHandle Handle that identifies the loaded image.
+ @param SystemTable System Table for this image.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeRealTimeClock (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = LibRtcInitialize (ImageHandle, SystemTable);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ SystemTable->RuntimeServices->GetTime = GetTime;
+ SystemTable->RuntimeServices->SetTime = SetTime;
+ SystemTable->RuntimeServices->GetWakeupTime = GetWakeupTime;
+ SystemTable->RuntimeServices->SetWakeupTime = SetWakeupTime;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEfiRealTimeClockArchProtocolGuid,
+ NULL,
+ NULL
+ );
+
+ return Status;
+}
+
diff --git a/RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf b/RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
new file mode 100644
index 0000000..afc1bca
--- /dev/null
+++ b/RiscVPkg/Universal/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
@@ -0,0 +1,44 @@
+#/** @file
+# This driver installs RTC Architecture Protocol
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+# Copyright (c) 2006 - 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]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RealTimeClock
+ FILE_GUID = C641D483-B367-40EF-96B3-860B75A4604E
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeRealTimeClock
+
+[Sources.common]
+ RealTimeClock.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ RiscVPkg/RiscVPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ DebugLib
+ RealTimeClockLib
+
+[Protocols]
+ gEfiRealTimeClockArchProtocolGuid
+
+[Depex]
+ TRUE
+
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 14/22]: RiscVPkg/opesbi: Add opensbi-HOWTO.txt

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:09PM +0800, Abner Chang wrote:
Add opensbi-HOWTO.txt for users to build RISC-V platform with RISC-V OpenSBI library.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
RiscVPkg/opensbi/opensbi-HOWTO.txt | 17 +++++++++++++++++
Could you replace this patch with one that adds the stated repository
as a git submodule at the specified tag?

/
Leif

1 file changed, 17 insertions(+)
create mode 100644 RiscVPkg/opensbi/opensbi-HOWTO.txt

diff --git a/RiscVPkg/opensbi/opensbi-HOWTO.txt b/RiscVPkg/opensbi/opensbi-HOWTO.txt
new file mode 100644
index 0000000..aff7a69
--- /dev/null
+++ b/RiscVPkg/opensbi/opensbi-HOWTO.txt
@@ -0,0 +1,17 @@
+================================================================================
+ Instroduction
+================================================================================
+RISC-V Open Source Supervisor Binary Interface (OpenSBI) is an open source
+implementation (Refer to https://github.com/riscv/opensbi) of RISC-V SBI spec
+(Refer to https://github.com/riscv/riscv-sbi-doc), whcih is designed for the
+platform-specific firmwares executing in RISC-V Machine mode (M-mode).
+EDK2 RISC-V port leverage OpenSBI source files and build it into EDK2 RISC-V
+OpenSBI library (RiscVPkg/Library/RiscVOpensbiLib) using edk2 toolchain.
+
+User has to get OpenSBI source code and put it under RiscVPkg/opensbi using below
+command before building RISC-V platform in EDK2 build environment.
+
+Current supported RISC-V OpenSBI version on EDK2 is v0.4
+
+ $ git clone https://github.com/riscv/opensbi
+ $ git checkout tags/v0.4
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 13/22]: MdePkg/Include: Update SmBios header file.

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:08PM +0800, Abner Chang wrote:
Update SmBios header file to conform with SMBIOS v3.3.0.
The major update is to add definitions of SMBIOS Type 44h record.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
This would be really useful to get straight into edk2 - could you
submit it straight for inclusion in edk2 master? We can then
cherry-pick that back to the edk2-staging branch.

/
Leif

---
MdePkg/Include/IndustryStandard/SmBios.h | 74 +++++++++++++++++++++++++++++++-
1 file changed, 72 insertions(+), 2 deletions(-)

diff --git a/MdePkg/Include/IndustryStandard/SmBios.h b/MdePkg/Include/IndustryStandard/SmBios.h
index f3b6f18..a744d06 100644
--- a/MdePkg/Include/IndustryStandard/SmBios.h
+++ b/MdePkg/Include/IndustryStandard/SmBios.h
@@ -3,6 +3,7 @@

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP<BR>
+(C) Copyright 2015 - 2019 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -46,7 +47,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define SMBIOS_3_0_TABLE_MAX_LENGTH 0xFFFFFFFF

//
-// SMBIOS type macros which is according to SMBIOS 2.7 specification.
+// SMBIOS type macros which is according to SMBIOS 3.3.0 specification.
//
#define SMBIOS_TYPE_BIOS_INFORMATION 0
#define SMBIOS_TYPE_SYSTEM_INFORMATION 1
@@ -92,6 +93,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION 41
#define SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE 42
#define SMBIOS_TYPE_TPM_DEVICE 43
+#define SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION 44

///
/// Inactive type is added from SMBIOS 2.2. Reference SMBIOS 2.6, chapter 3.3.43.
@@ -727,7 +729,10 @@ typedef enum {
ProcessorFamilyMII = 0x012E,
ProcessorFamilyWinChip = 0x0140,
ProcessorFamilyDSP = 0x015E,
- ProcessorFamilyVideoProcessor = 0x01F4
+ ProcessorFamilyVideoProcessor = 0x01F4,
+ ProcessorFamilyRiscvRV32 = 0x0200, ///< SMBIOS spec 3.3.0 added
+ ProcessorFamilyRiscVRV64 = 0x0201, ///< SMBIOS spec 3.3.0 added
+ ProcessorFamilyRiscVRV128 = 0x0202 ///< SMBIOS spec 3.3.0 added
} PROCESSOR_FAMILY2_DATA;

///
@@ -857,6 +862,19 @@ typedef struct {
} PROCESSOR_FEATURE_FLAGS;

typedef struct {
+ UINT32 ProcessorReserved1 :1;
+ UINT32 ProcessorUnknown :1;
+ UINT32 Processor64BitCapble :1;
+ UINT32 ProcessorMultiCore :1;
+ UINT32 ProcessorHardwareThread :1;
+ UINT32 ProcessorExecuteProtection :1;
+ UINT32 ProcessorEnhancedVirtulization :1;
+ UINT32 ProcessorPowerPerformanceCtrl :1;
+ UINT32 Processor128bitCapble :1;
+ UINT32 ProcessorReserved2 :7;
+} PROCESSOR_CHARACTERISTIC_FLAGS;
+
+typedef struct {
PROCESSOR_SIGNATURE Signature;
PROCESSOR_FEATURE_FLAGS FeatureFlags;
} PROCESSOR_ID_DATA;
@@ -2508,6 +2526,57 @@ typedef struct {
UINT8 InterfaceTypeSpecificData[4]; ///< This field has a minimum of four bytes
} SMBIOS_TABLE_TYPE42;

+
+///
+/// Processor Specific Block - Processor Architecture Type
+///
+typedef enum{
+ ProcessorSpecificBlockArchTypeReserved = 0x00,
+ ProcessorSpecificBlockArchTypeIa32 = 0x01,
+ ProcessorSpecificBlockArchTypeX64 = 0x02,
+ ProcessorSpecificBlockArchTypeItanium = 0x03,
+ ProcessorSpecificBlockArchTypeAarch32 = 0x04,
+ ProcessorSpecificBlockArchTypeAarch64 = 0x05,
+ ProcessorSpecificBlockArchTypeRiscVRV32 = 0x06,
+ ProcessorSpecificBlockArchTypeRiscVRV64 = 0x07,
+ ProcessorSpecificBlockArchTypeRiscVRV128 = 0x08
+} PROCESSOR_SPECIFIC_BLOCK_ARCH_TYPE;
+
+///
+/// Processor Specific Block is the standard container of processor-specific data.
+///
+typedef struct {
+ UINT8 Length;
+ UINT8 ProcessorArchType;
+ ///
+ /// Below followed by Processor-specific data
+ ///
+ ///
+} PROCESSOR_SPECIFIC_BLOCK;
+
+///
+/// Processor Additional Information(Type 44).
+///
+/// The information in this structure defines the processor additional information in case
+/// SMBIOS type 4 is not sufficient to describe processor characteristics.
+/// The SMBIOS type 44 structure has a reference handle field to link back to the related
+/// SMBIOS type 4 structure. There may be multiple SMBIOS type 44 structures linked to the
+/// same SMBIOS type 4 structure. For example, when cores are not identical in a processor,
+/// SMBIOS type 44 structures describe different core-specific information.
+///
+/// SMBIOS type 44 defines the standard header for the processor-specific block, while the
+/// contents of processor-specific data are maintained by processor
+/// architecture workgroups or vendors in separate documents.
+///
+typedef struct {
+ SMBIOS_STRUCTURE Hdr;
+ SMBIOS_HANDLE RefHandle; ///< This field refer to associated SMBIOS type 4
+ ///
+ /// Below followed by Processor-specific block
+ ///
+ PROCESSOR_SPECIFIC_BLOCK ProcessorSpecificBlock;
+} SMBIOS_TABLE_TYPE44;
+
///
/// TPM Device (Type 43).
///
@@ -2586,6 +2655,7 @@ typedef union {
SMBIOS_TABLE_TYPE41 *Type41;
SMBIOS_TABLE_TYPE42 *Type42;
SMBIOS_TABLE_TYPE43 *Type43;
+ SMBIOS_TABLE_TYPE44 *Type44;
SMBIOS_TABLE_TYPE126 *Type126;
SMBIOS_TABLE_TYPE127 *Type127;
UINT8 *Raw;
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 12/22]: MdePkg/BaseLib: BaseLib for RISC-V RV64 Processor.

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:07PM +0800, Abner Chang wrote:
Add RISC-V processor binding and RISC-V processor specific definitions and macros.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
MdePkg/Library/BaseLib/BaseLib.inf | 18 +-
MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c | 33 ++
MdePkg/Library/BaseLib/RiscV64/CpuPause.c | 35 ++
MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c | 33 ++
MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c | 33 ++
MdePkg/Library/BaseLib/RiscV64/FlushCache.S | 28 +
MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c | 43 ++
.../Library/BaseLib/RiscV64/InternalSwitchStack.c | 61 +++
MdePkg/Library/BaseLib/RiscV64/LongJump.c | 38 ++
.../Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S | 20 +
MdePkg/Library/BaseLib/RiscV64/RiscVCpuPause.S | 20 +
MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S | 33 ++
.../Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S | 61 +++
MdePkg/Library/BaseLib/RiscV64/Unaligned.c | 270 ++++++++++
MdePkg/Library/BaseLib/RiscV64/riscv_asm.h | 194 +++++++
MdePkg/Library/BaseLib/RiscV64/riscv_encoding.h | 574 +++++++++++++++++++++
MdePkg/Library/BaseLib/RiscV64/sbi_const.h | 53 ++
17 files changed, 1546 insertions(+), 1 deletion(-)
create mode 100644 MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/CpuPause.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/FlushCache.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/LongJump.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVCpuPause.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S
create mode 100644 MdePkg/Library/BaseLib/RiscV64/Unaligned.c
create mode 100644 MdePkg/Library/BaseLib/RiscV64/riscv_asm.h
create mode 100644 MdePkg/Library/BaseLib/RiscV64/riscv_encoding.h
create mode 100644 MdePkg/Library/BaseLib/RiscV64/sbi_const.h

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 3586beb..28d5795 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -4,6 +4,7 @@
# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -20,7 +21,7 @@
LIBRARY_CLASS = BaseLib

#
-# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
+# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64
#

[Sources]
@@ -381,6 +382,21 @@
Ah, right. I just noticed these patches don't follow the patch
generation guidelines from
https://github.com/tianocore/tianocore.github.io/wiki/Laszlo%27s-unkempt-git-guide-for-edk2-contributors-and-maintainers

If you run BaseTools/Scripts/SetupGit.py, it will set up most of the
important defaults for your clone (needs to be done once per
repository). This greatly improves the reviewability of patches.

/
Leif

AArch64/CpuBreakpoint.asm | MSFT
AArch64/SpeculationBarrier.asm | MSFT

+[Sources.RISCV64]
+ Math64.c
+ RiscV64/Unaligned.c
+ RiscV64/InternalSwitchStack.c
+ RiscV64/CpuBreakpoint.c
+ RiscV64/GetInterruptState.c
+ RiscV64/DisableInterrupts.c
+ RiscV64/EnableInterrupts.c
+ RiscV64/CpuPause.c
+ RiscV64/RiscVSetJumpLongJump.S | GCC
+ RiscV64/RiscVCpuBreakpoint.S | GCC
+ RiscV64/RiscVCpuPause.S | GCC
+ RiscV64/RiscVInterrupt.S | GCC
+ RiscV64/FlushCache.S | GCC
+
[Packages]
MdePkg/MdePkg.dec

diff --git a/MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c b/MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c
new file mode 100644
index 0000000..763b813
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c
@@ -0,0 +1,33 @@
+/** @file
+ CPU breakpoint for RISC-V
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 "BaseLibInternals.h"
+
+extern VOID RiscVCpuBreakpoint (VOID);
+
+/**
+ Generates a breakpoint on the CPU.
+
+ Generates a breakpoint on the CPU. The breakpoint must be implemented such
+ that code can resume normal execution after the breakpoint.
+
+**/
+VOID
+EFIAPI
+CpuBreakpoint (
+ VOID
+ )
+{
+ RiscVCpuBreakpoint ();
+}
diff --git a/MdePkg/Library/BaseLib/RiscV64/CpuPause.c b/MdePkg/Library/BaseLib/RiscV64/CpuPause.c
new file mode 100644
index 0000000..3094aac
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/CpuPause.c
@@ -0,0 +1,35 @@
+/** @file
+ CPU pause for RISC-V
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 "BaseLibInternals.h"
+
+extern VOID RiscVCpuPause (VOID);
+
+
+/**
+ Requests CPU to pause for a short period of time.
+
+ Requests CPU to pause for a short period of time. Typically used in MP
+ systems to prevent memory starvation while waiting for a spin lock.
+
+**/
+VOID
+EFIAPI
+CpuPause (
+ VOID
+ )
+{
+ RiscVCpuPause ();
+}
+
diff --git a/MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c b/MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c
new file mode 100644
index 0000000..6f7e88c
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c
@@ -0,0 +1,33 @@
+/** @file
+ CPU disable interrupt function for RISC-V
+
+ Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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 "BaseLibInternals.h"
+#include "riscv_asm.h"
+#include "riscv_encoding.h"
+
+
+extern VOID RiscVDisableInterrupts (VOID);
+
+/**
+ Disables CPU interrupts.
+
+**/
+VOID
+EFIAPI
+DisableInterrupts (
+ VOID
+ )
+{
+ csr_clear(CSR_SSTATUS, MSTATUS_SIE); //SIE
+}
+
diff --git a/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c b/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c
new file mode 100644
index 0000000..a0ce150
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c
@@ -0,0 +1,33 @@
+/** @file
+ CPU enable interrupt function for RISC-V
+
+ Copyright (c) 2016-2019, Hewlett Packard Enterprise Development LP. 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 "BaseLibInternals.h"
+#include "riscv_asm.h"
+#include "riscv_encoding.h"
+
+extern VOID RiscVEnableInterrupt (VOID);
+
+/**
+ Enables CPU interrupts.
+
+**/
+VOID
+EFIAPI
+EnableInterrupts (
+ VOID
+ )
+{
+ csr_set(CSR_SSTATUS, MSTATUS_SIE); //SIE
+}
+
diff --git a/MdePkg/Library/BaseLib/RiscV64/FlushCache.S b/MdePkg/Library/BaseLib/RiscV64/FlushCache.S
new file mode 100644
index 0000000..75ddc46
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/FlushCache.S
@@ -0,0 +1,28 @@
+//------------------------------------------------------------------------------
+//
+// RISC-V cache operation.
+//
+// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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.
+//
+//------------------------------------------------------------------------------
+
+.align 3
+ASM_GLOBAL ASM_PFX(RiscVInvdInstCacheAsm)
+ASM_GLOBAL ASM_PFX(RiscVInvdDataCacheAsm)
+
+
+ASM_PFX(RiscVInvdInstCacheAsm):
+ //fence.i
+ ret
+
+ASM_PFX(RiscVInvdDataCacheAsm):
+ //fence
+ ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c b/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c
new file mode 100644
index 0000000..b12450f
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c
@@ -0,0 +1,43 @@
+/** @file
+ CPU get interrupt state function for RISC-V
+
+ Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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 "BaseLibInternals.h"
+#include "riscv_asm.h"
+#include "riscv_encoding.h"
+
+extern UINT32 RiscVGetInterrupts (VOID);
+
+/**
+ Retrieves the current CPU interrupt state.
+
+ Returns TRUE is interrupts are currently enabled. Otherwise
+ returns FALSE.
+
+ @retval TRUE CPU interrupts are enabled.
+ @retval FALSE CPU interrupts are disabled.
+
+**/
+BOOLEAN
+EFIAPI
+GetInterruptState (
+ VOID
+ )
+{
+ unsigned long RetValue;
+
+ RetValue = csr_read(CSR_SSTATUS);
+ return (RetValue & MSTATUS_SIE)? TRUE: FALSE;
+}
+
+
diff --git a/MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c b/MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c
new file mode 100644
index 0000000..7d748a1
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c
@@ -0,0 +1,61 @@
+/** @file
+ Switch stack function for RISC-V
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 "BaseLibInternals.h"
+
+/**
+ Transfers control to a function starting with a new stack.
+
+ Transfers control to the function specified by EntryPoint using the
+ new stack specified by NewStack and passing in the parameters specified
+ by Context1 and Context2. Context1 and Context2 are optional and may
+ be NULL. The function EntryPoint must never return.
+ Marker will be ignored on IA-32, x64, and EBC.
+ IPF CPUs expect one additional parameter of type VOID * that specifies
+ the new backing store pointer.
+
+ If EntryPoint is NULL, then ASSERT().
+ If NewStack is NULL, then ASSERT().
+
+ @param EntryPoint A pointer to function to call with the new stack.
+ @param Context1 A pointer to the context to pass into the EntryPoint
+ function.
+ @param Context2 A pointer to the context to pass into the EntryPoint
+ function.
+ @param NewStack A pointer to the new stack to use for the EntryPoint
+ function.
+ @param Marker VA_LIST marker for the variable argument list.
+
+**/
+VOID
+EFIAPI
+InternalSwitchStack (
+ IN SWITCH_STACK_ENTRY_POINT EntryPoint,
+ IN VOID *Context1, OPTIONAL
+ IN VOID *Context2, OPTIONAL
+ IN VOID *NewStack,
+ IN VA_LIST Marker
+ )
+{
+ BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
+
+ DEBUG ((EFI_D_INFO, "RISC-V InternalSwitchStack Entry:%x Context1:%x Context2:%x NewStack%x\n", \
+ EntryPoint, Context1, Context2, NewStack));
+ JumpBuffer.RA = (UINTN)EntryPoint;
+ JumpBuffer.SP = (UINTN)NewStack - sizeof (VOID *);
+ JumpBuffer.S0 = (UINT64)(UINTN)Context1;
+ JumpBuffer.S1 = (UINT64)(UINTN)Context2;
+ LongJump (&JumpBuffer, (UINTN)-1);
+ ASSERT(FALSE);
+}
diff --git a/MdePkg/Library/BaseLib/RiscV64/LongJump.c b/MdePkg/Library/BaseLib/RiscV64/LongJump.c
new file mode 100644
index 0000000..bd081f2
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/LongJump.c
@@ -0,0 +1,38 @@
+/** @file
+ Long jump implementation of RISC-V
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 "BaseLibInternals.h"
+
+
+/**
+ Restores the CPU context that was saved with SetJump().
+
+ Restores the CPU context from the buffer specified by JumpBuffer.
+ This function never returns to the caller.
+ Instead is resumes execution based on the state of JumpBuffer.
+
+ @param JumpBuffer A pointer to CPU context buffer.
+ @param Value The value to return when the SetJump() context is restored.
+
+**/
+VOID
+EFIAPI
+InternalLongJump (
+ IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer,
+ IN UINTN Value
+ )
+{
+ ASSERT (FALSE);
+}
+
diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S b/MdePkg/Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S
new file mode 100644
index 0000000..3c38e4d
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S
@@ -0,0 +1,20 @@
+//------------------------------------------------------------------------------
+//
+// CpuBreakpoint for RISC-V
+//
+// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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.
+//
+//------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(RiscVCpuBreakpoint)
+ASM_PFX(RiscVCpuBreakpoint):
+ ebreak
+ ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVCpuPause.S b/MdePkg/Library/BaseLib/RiscV64/RiscVCpuPause.S
new file mode 100644
index 0000000..64b9fb5
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/RiscVCpuPause.S
@@ -0,0 +1,20 @@
+//------------------------------------------------------------------------------
+//
+// CpuPause for RISC-V
+//
+// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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.
+//
+//------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(RiscVCpuPause)
+ASM_PFX(RiscVCpuPause):
+ nop
+ ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
new file mode 100644
index 0000000..5782ced
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+//
+// Cpu interrupt enable/disable for RISC-V
+//
+// Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. 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.
+//
+//------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(RiscVDisableInterrupts)
+ASM_GLOBAL ASM_PFX(RiscVEnableInterrupt)
+ASM_GLOBAL ASM_PFX(RiscVGetInterrupts)
+
+ASM_PFX(RiscVDisableInterrupts):
+ li a1, 0xaaa
+ csrc 0x304, a1
+ ret
+
+ASM_PFX(RiscVEnableInterrupt):
+ li a1, 0x80
+ csrs 0x304, a1
+ ret
+
+ASM_PFX(RiscVGetInterrupts):
+ csrr a0, 0x304
+ ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S b/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S
new file mode 100644
index 0000000..bd75408
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------
+//
+// Set/Long jump for RISC-V
+//
+// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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.
+//
+//------------------------------------------------------------------------------
+# define REG_S sd
+# define REG_L ld
+# define SZREG 8
+.align 3
+ .globl SetJump
+
+SetJump:
+ REG_S ra, 0*SZREG(a0)
+ REG_S s0, 1*SZREG(a0)
+ REG_S s1, 2*SZREG(a0)
+ REG_S s2, 3*SZREG(a0)
+ REG_S s3, 4*SZREG(a0)
+ REG_S s4, 5*SZREG(a0)
+ REG_S s5, 6*SZREG(a0)
+ REG_S s6, 7*SZREG(a0)
+ REG_S s7, 8*SZREG(a0)
+ REG_S s8, 9*SZREG(a0)
+ REG_S s9, 10*SZREG(a0)
+ REG_S s10,11*SZREG(a0)
+ REG_S s11,12*SZREG(a0)
+ REG_S sp, 13*SZREG(a0)
+ li a0, 0
+ ret
+
+ .globl InternalLongJump
+InternalLongJump:
+ REG_L ra, 0*SZREG(a0)
+ REG_L s0, 1*SZREG(a0)
+ REG_L s1, 2*SZREG(a0)
+ REG_L s2, 3*SZREG(a0)
+ REG_L s3, 4*SZREG(a0)
+ REG_L s4, 5*SZREG(a0)
+ REG_L s5, 6*SZREG(a0)
+ REG_L s6, 7*SZREG(a0)
+ REG_L s7, 8*SZREG(a0)
+ REG_L s8, 9*SZREG(a0)
+ REG_L s9, 10*SZREG(a0)
+ REG_L s10,11*SZREG(a0)
+ REG_L s11,12*SZREG(a0)
+ REG_L sp, 13*SZREG(a0)
+
+ add a0, s0, 0
+ add a1, s1, 0
+ add a2, s2, 0
+ add a3, s3, 0
+ ret
diff --git a/MdePkg/Library/BaseLib/RiscV64/Unaligned.c b/MdePkg/Library/BaseLib/RiscV64/Unaligned.c
new file mode 100644
index 0000000..7068a63
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/Unaligned.c
@@ -0,0 +1,270 @@
+/** @file
+ RISC-V specific functionality for (un)aligned memory read/write.
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 "BaseLibInternals.h"
+
+/**
+ Reads a 16-bit value from memory that may be unaligned.
+
+ This function returns the 16-bit value pointed to by Buffer. The function
+ guarantees that the read operation does not produce an alignment fault.
+
+ If the Buffer is NULL, then ASSERT().
+
+ @param Buffer A pointer to a 16-bit value that may be unaligned.
+
+ @return The 16-bit value read from Buffer.
+
+**/
+UINT16
+EFIAPI
+ReadUnaligned16 (
+ IN CONST UINT16 *Buffer
+ )
+{
+ UINT16 Value;
+ INT8 Count;
+
+ ASSERT (Buffer != NULL);
+
+ for (Count = sizeof (UINT16) - 1, Value = 0; Count >= 0 ; Count --) {
+ Value = Value << 8;
+ Value |= *((UINT8*)Buffer + Count);
+ }
+ return Value;
+}
+
+/**
+ Writes a 16-bit value to memory that may be unaligned.
+
+ This function writes the 16-bit value specified by Value to Buffer. Value is
+ returned. The function guarantees that the write operation does not produce
+ an alignment fault.
+
+ If the Buffer is NULL, then ASSERT().
+
+ @param Buffer A pointer to a 16-bit value that may be unaligned.
+ @param Value 16-bit value to write to Buffer.
+
+ @return The 16-bit value to write to Buffer.
+
+**/
+UINT16
+EFIAPI
+WriteUnaligned16 (
+ OUT UINT16 *Buffer,
+ IN UINT16 Value
+ )
+{
+ INT8 Count;
+ UINT16 ValueTemp;
+
+ ASSERT (Buffer != NULL);
+
+ for (Count = 0, ValueTemp = Value; Count < sizeof (UINT16) ; Count ++) {
+ *((UINT8*)Buffer + Count) = (UINT8)(ValueTemp & 0xff);
+ ValueTemp = ValueTemp >> 8;
+ }
+ return Value;
+}
+
+/**
+ Reads a 24-bit value from memory that may be unaligned.
+
+ This function returns the 24-bit value pointed to by Buffer. The function
+ guarantees that the read operation does not produce an alignment fault.
+
+ If the Buffer is NULL, then ASSERT().
+
+ @param Buffer A pointer to a 24-bit value that may be unaligned.
+
+ @return The 24-bit value read from Buffer.
+
+**/
+UINT32
+EFIAPI
+ReadUnaligned24 (
+ IN CONST UINT32 *Buffer
+ )
+{
+ UINT32 Value;
+ INT8 Count;
+
+ ASSERT (Buffer != NULL);
+ for (Count = 2, Value = 0; Count >= 0 ; Count --) {
+ Value = Value << 8;
+ Value |= *((UINT8*)Buffer + Count);
+ }
+ return Value;
+}
+
+/**
+ Writes a 24-bit value to memory that may be unaligned.
+
+ This function writes the 24-bit value specified by Value to Buffer. Value is
+ returned. The function guarantees that the write operation does not produce
+ an alignment fault.
+
+ If the Buffer is NULL, then ASSERT().
+
+ @param Buffer A pointer to a 24-bit value that may be unaligned.
+ @param Value 24-bit value to write to Buffer.
+
+ @return The 24-bit value to write to Buffer.
+
+**/
+UINT32
+EFIAPI
+WriteUnaligned24 (
+ OUT UINT32 *Buffer,
+ IN UINT32 Value
+ )
+{
+ INT8 Count;
+ UINT32 ValueTemp;
+
+ ASSERT (Buffer != NULL);
+ for (Count = 0, ValueTemp = Value; Count < 3 ; Count ++) {
+ *((UINT8*)Buffer + Count) = (UINT8)(ValueTemp & 0xff);
+ ValueTemp = ValueTemp >> 8;
+ }
+ return Value;
+}
+
+/**
+ Reads a 32-bit value from memory that may be unaligned.
+
+ This function returns the 32-bit value pointed to by Buffer. The function
+ guarantees that the read operation does not produce an alignment fault.
+
+ If the Buffer is NULL, then ASSERT().
+
+ @param Buffer A pointer to a 32-bit value that may be unaligned.
+
+ @return The 32-bit value read from Buffer.
+
+**/
+UINT32
+EFIAPI
+ReadUnaligned32 (
+ IN CONST UINT32 *Buffer
+ )
+{
+ UINT32 Value;
+ INT8 Count;
+
+ ASSERT (Buffer != NULL);
+
+ for (Count = sizeof (UINT32) - 1, Value = 0; Count >= 0 ; Count --) {
+ Value = Value << 8;
+ Value |= *((UINT8*)Buffer + Count);
+ }
+ return Value;
+}
+
+/**
+ Writes a 32-bit value to memory that may be unaligned.
+
+ This function writes the 32-bit value specified by Value to Buffer. Value is
+ returned. The function guarantees that the write operation does not produce
+ an alignment fault.
+
+ If the Buffer is NULL, then ASSERT().
+
+ @param Buffer A pointer to a 32-bit value that may be unaligned.
+ @param Value The 32-bit value to write to Buffer.
+
+ @return The 32-bit value to write to Buffer.
+
+**/
+UINT32
+EFIAPI
+WriteUnaligned32 (
+ OUT UINT32 *Buffer,
+ IN UINT32 Value
+ )
+{
+ INT8 Count;
+ UINT32 ValueTemp;
+
+ ASSERT (Buffer != NULL);
+ for (Count = 0, ValueTemp = Value; Count < sizeof (UINT32) ; Count ++) {
+ *((UINT8*)Buffer + Count) = (UINT8)(ValueTemp & 0xff);
+ ValueTemp = ValueTemp >> 8;
+ }
+ return Value;
+}
+
+/**
+ Reads a 64-bit value from memory that may be unaligned.
+
+ This function returns the 64-bit value pointed to by Buffer. The function
+ guarantees that the read operation does not produce an alignment fault.
+
+ If the Buffer is NULL, then ASSERT().
+
+ @param Buffer A pointer to a 64-bit value that may be unaligned.
+
+ @return The 64-bit value read from Buffer.
+
+**/
+UINT64
+EFIAPI
+ReadUnaligned64 (
+ IN CONST UINT64 *Buffer
+ )
+{
+ UINT64 Value;
+ INT8 Count;
+
+ ASSERT (Buffer != NULL);
+ for (Count = sizeof (UINT64) - 1, Value = 0; Count >= 0 ; Count --) {
+ Value = Value << 8;
+ Value |= *((UINT8*)Buffer + Count);
+ }
+ return Value;
+}
+
+/**
+ Writes a 64-bit value to memory that may be unaligned.
+
+ This function writes the 64-bit value specified by Value to Buffer. Value is
+ returned. The function guarantees that the write operation does not produce
+ an alignment fault.
+
+ If the Buffer is NULL, then ASSERT().
+
+ @param Buffer A pointer to a 64-bit value that may be unaligned.
+ @param Value The 64-bit value to write to Buffer.
+
+ @return The 64-bit value to write to Buffer.
+
+**/
+UINT64
+EFIAPI
+WriteUnaligned64 (
+ OUT UINT64 *Buffer,
+ IN UINT64 Value
+ )
+{
+ INT8 Count;
+ UINT64 ValueTemp;
+
+ ASSERT (Buffer != NULL);
+ for (Count = 0, ValueTemp = Value; Count < sizeof (UINT64) ; Count ++) {
+ *((UINT8*)Buffer + Count) = (UINT8)(ValueTemp & 0xff);
+ ValueTemp = ValueTemp >> 8;
+ }
+ return Value;
+}
diff --git a/MdePkg/Library/BaseLib/RiscV64/riscv_asm.h b/MdePkg/Library/BaseLib/RiscV64/riscv_asm.h
new file mode 100644
index 0000000..b050742
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/riscv_asm.h
@@ -0,0 +1,194 @@
+/** @file
+ Macro definitions of RISC-V CSR assembly.
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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.
+
+ SPDX-License-Identifier: BSD-2-Clause
+
+ Copyright (c) 2019 Western Digital Corporation or its affiliates.
+
+**/
+
+#ifndef __RISCV_ASM_H__
+#define __RISCV_ASM_H__
+
+#include "riscv_encoding.h"
+
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x) x
+#else
+#define __ASM_STR(x) #x
+#endif
+
+#if __riscv_xlen == 64
+#define __REG_SEL(a, b) __ASM_STR(a)
+#elif __riscv_xlen == 32
+#define __REG_SEL(a, b) __ASM_STR(b)
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
+#define PAGE_SHIFT (12)
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+#define SBI_TLB_FLUSH_ALL ((unsigned long)-1)
+
+#define REG_L __REG_SEL(ld, lw)
+#define REG_S __REG_SEL(sd, sw)
+#define SZREG __REG_SEL(8, 4)
+#define LGREG __REG_SEL(3, 2)
+
+#if __SIZEOF_POINTER__ == 8
+#define BITS_PER_LONG 64
+#ifdef __ASSEMBLY__
+#define RISCV_PTR .dword
+#define RISCV_SZPTR 8
+#define RISCV_LGPTR 3
+#else
+#define RISCV_PTR ".dword"
+#define RISCV_SZPTR "8"
+#define RISCV_LGPTR "3"
+#endif
+#elif __SIZEOF_POINTER__ == 4
+#define BITS_PER_LONG 32
+#ifdef __ASSEMBLY__
+#define RISCV_PTR .word
+#define RISCV_SZPTR 4
+#define RISCV_LGPTR 2
+#else
+#define RISCV_PTR ".word"
+#define RISCV_SZPTR "4"
+#define RISCV_LGPTR "2"
+#endif
+#else
+#error "Unexpected __SIZEOF_POINTER__"
+#endif
+
+#if (__SIZEOF_INT__ == 4)
+#define RISCV_INT __ASM_STR(.word)
+#define RISCV_SZINT __ASM_STR(4)
+#define RISCV_LGINT __ASM_STR(2)
+#else
+#error "Unexpected __SIZEOF_INT__"
+#endif
+
+#if (__SIZEOF_SHORT__ == 2)
+#define RISCV_SHORT __ASM_STR(.half)
+#define RISCV_SZSHORT __ASM_STR(2)
+#define RISCV_LGSHORT __ASM_STR(1)
+#else
+#error "Unexpected __SIZEOF_SHORT__"
+#endif
+
+#ifndef __ASSEMBLY__
+
+#define csr_swap(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_read(csr) \
+({ \
+ register unsigned long __v; \
+ __asm__ __volatile__ ("csrr %0, " __ASM_STR(csr) \
+ : "=r" (__v) : \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_write(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_read_set(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_set(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+#define csr_read_clear(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\
+ : "=r" (__v) : "rK" (__v) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_clear(csr, val) \
+({ \
+ unsigned long __v = (unsigned long)(val); \
+ __asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0" \
+ : : "rK" (__v) \
+ : "memory"); \
+})
+
+unsigned long csr_read_num(int csr_num);
+
+void csr_write_num(int csr_num, unsigned long val);
+
+#define wfi() \
+do { \
+ __asm__ __volatile__ ("wfi" ::: "memory"); \
+} while (0)
+
+static inline int misa_extension(char ext)
+{
+ return csr_read(CSR_MISA) & (1 << (ext - 'A'));
+}
+
+static inline int misa_xlen(void)
+{
+ return ((long)csr_read(CSR_MISA) < 0) ? 64 : 32;
+}
+
+static inline void misa_string(char *out, unsigned int out_sz)
+{
+ unsigned long i, val = csr_read(CSR_MISA);
+
+ for (i = 0; i < 26; i++) {
+ if (val & (1 << i)) {
+ *out = 'A' + i;
+ out++;
+ }
+ }
+ *out = '\0';
+ out++;
+}
+
+int pmp_set(unsigned int n, unsigned long prot,
+ unsigned long addr, unsigned long log2len);
+
+int pmp_get(unsigned int n, unsigned long *prot_out,
+ unsigned long *addr_out, unsigned long *log2len_out);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif
diff --git a/MdePkg/Library/BaseLib/RiscV64/riscv_encoding.h b/MdePkg/Library/BaseLib/RiscV64/riscv_encoding.h
new file mode 100644
index 0000000..6f5fefd
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/riscv_encoding.h
@@ -0,0 +1,574 @@
+/** @file
+ Definitions of RISC-V CSR.
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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.
+
+ SPDX-License-Identifier: BSD-2-Clause
+
+ Copyright (c) 2019 Western Digital Corporation or its affiliates.
+
+**/
+
+#ifndef __RISCV_ENCODING_H__
+#define __RISCV_ENCODING_H__
+
+#include "sbi_const.h"
+
+/* TODO: Make constants usable in assembly with _AC() macro */
+
+#define MSTATUS_UIE 0x00000001
+#define MSTATUS_SIE 0x00000002
+#define MSTATUS_HIE 0x00000004
+#define MSTATUS_MIE 0x00000008
+#define MSTATUS_UPIE 0x00000010
+#define MSTATUS_SPIE_SHIFT 5
+#define MSTATUS_SPIE (1UL << MSTATUS_SPIE_SHIFT)
+#define MSTATUS_HPIE 0x00000040
+#define MSTATUS_MPIE 0x00000080
+#define MSTATUS_SPP_SHIFT 8
+#define MSTATUS_SPP (1UL << MSTATUS_SPP_SHIFT)
+#define MSTATUS_HPP 0x00000600
+#define MSTATUS_MPP_SHIFT 11
+#define MSTATUS_MPP (3UL << MSTATUS_MPP_SHIFT)
+#define MSTATUS_FS 0x00006000
+#define MSTATUS_XS 0x00018000
+#define MSTATUS_MPRV 0x00020000
+#define MSTATUS_SUM 0x00040000
+#define MSTATUS_MXR 0x00080000
+#define MSTATUS_TVM 0x00100000
+#define MSTATUS_TW 0x00200000
+#define MSTATUS_TSR 0x00400000
+#define MSTATUS32_SD 0x80000000
+#define MSTATUS_UXL 0x0000000300000000
+#define MSTATUS_SXL 0x0000000C00000000
+#define MSTATUS64_SD 0x8000000000000000
+
+#define SSTATUS_UIE 0x00000001
+#define SSTATUS_SIE 0x00000002
+#define SSTATUS_UPIE 0x00000010
+#define SSTATUS_SPIE 0x00000020
+#define SSTATUS_SPP 0x00000100
+#define SSTATUS_FS 0x00006000
+#define SSTATUS_XS 0x00018000
+#define SSTATUS_SUM 0x00040000
+#define SSTATUS_MXR 0x00080000
+#define SSTATUS32_SD 0x80000000
+#define SSTATUS_UXL 0x0000000300000000
+#define SSTATUS64_SD 0x8000000000000000
+
+#define DCSR_XDEBUGVER (3U<<30)
+#define DCSR_NDRESET (1<<29)
+#define DCSR_FULLRESET (1<<28)
+#define DCSR_EBREAKM (1<<15)
+#define DCSR_EBREAKH (1<<14)
+#define DCSR_EBREAKS (1<<13)
+#define DCSR_EBREAKU (1<<12)
+#define DCSR_STOPCYCLE (1<<10)
+#define DCSR_STOPTIME (1<<9)
+#define DCSR_CAUSE (7<<6)
+#define DCSR_DEBUGINT (1<<5)
+#define DCSR_HALT (1<<3)
+#define DCSR_STEP (1<<2)
+#define DCSR_PRV (3<<0)
+
+#define DCSR_CAUSE_NONE 0
+#define DCSR_CAUSE_SWBP 1
+#define DCSR_CAUSE_HWBP 2
+#define DCSR_CAUSE_DEBUGINT 3
+#define DCSR_CAUSE_STEP 4
+#define DCSR_CAUSE_HALT 5
+
+#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
+#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
+#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
+
+#define MCONTROL_SELECT (1<<19)
+#define MCONTROL_TIMING (1<<18)
+#define MCONTROL_ACTION (0x3f<<12)
+#define MCONTROL_CHAIN (1<<11)
+#define MCONTROL_MATCH (0xf<<7)
+#define MCONTROL_M (1<<6)
+#define MCONTROL_H (1<<5)
+#define MCONTROL_S (1<<4)
+#define MCONTROL_U (1<<3)
+#define MCONTROL_EXECUTE (1<<2)
+#define MCONTROL_STORE (1<<1)
+#define MCONTROL_LOAD (1<<0)
+
+#define MCONTROL_TYPE_NONE 0
+#define MCONTROL_TYPE_MATCH 2
+
+#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
+#define MCONTROL_ACTION_DEBUG_MODE 1
+#define MCONTROL_ACTION_TRACE_START 2
+#define MCONTROL_ACTION_TRACE_STOP 3
+#define MCONTROL_ACTION_TRACE_EMIT 4
+
+#define MCONTROL_MATCH_EQUAL 0
+#define MCONTROL_MATCH_NAPOT 1
+#define MCONTROL_MATCH_GE 2
+#define MCONTROL_MATCH_LT 3
+#define MCONTROL_MATCH_MASK_LOW 4
+#define MCONTROL_MATCH_MASK_HIGH 5
+
+#define IRQ_S_SOFT 1
+#define IRQ_H_SOFT 2
+#define IRQ_M_SOFT 3
+#define IRQ_S_TIMER 5
+#define IRQ_H_TIMER 6
+#define IRQ_M_TIMER 7
+#define IRQ_S_EXT 9
+#define IRQ_H_EXT 10
+#define IRQ_M_EXT 11
+#define IRQ_COP 12
+#define IRQ_HOST 13
+
+#define MIP_SSIP (1 << IRQ_S_SOFT)
+#define MIP_HSIP (1 << IRQ_H_SOFT)
+#define MIP_MSIP (1 << IRQ_M_SOFT)
+#define MIP_STIP (1 << IRQ_S_TIMER)
+#define MIP_HTIP (1 << IRQ_H_TIMER)
+#define MIP_MTIP (1 << IRQ_M_TIMER)
+#define MIP_SEIP (1 << IRQ_S_EXT)
+#define MIP_HEIP (1 << IRQ_H_EXT)
+#define MIP_MEIP (1 << IRQ_M_EXT)
+
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+
+#define PRV_U 0
+#define PRV_S 1
+#define PRV_H 2
+#define PRV_M 3
+
+#define SATP32_MODE 0x80000000
+#define SATP32_ASID 0x7FC00000
+#define SATP32_PPN 0x003FFFFF
+#define SATP64_MODE 0xF000000000000000
+#define SATP64_ASID 0x0FFFF00000000000
+#define SATP64_PPN 0x00000FFFFFFFFFFF
+
+#define SATP_MODE_OFF 0
+#define SATP_MODE_SV32 1
+#define SATP_MODE_SV39 8
+#define SATP_MODE_SV48 9
+#define SATP_MODE_SV57 10
+#define SATP_MODE_SV64 11
+
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_A 0x18
+#define PMP_A_TOR 0x08
+#define PMP_A_NA4 0x10
+#define PMP_A_NAPOT 0x18
+#define PMP_L 0x80
+
+#define PMP_SHIFT 2
+#define PMP_COUNT 16
+
+/* page table entry (PTE) fields */
+#define PTE_V 0x001 /* Valid */
+#define PTE_R 0x002 /* Read */
+#define PTE_W 0x004 /* Write */
+#define PTE_X 0x008 /* Execute */
+#define PTE_U 0x010 /* User */
+#define PTE_G 0x020 /* Global */
+#define PTE_A 0x040 /* Accessed */
+#define PTE_D 0x080 /* Dirty */
+#define PTE_SOFT 0x300 /* Reserved for Software */
+
+#define PTE_PPN_SHIFT 10
+
+#define PTE_TABLE(PTE) \
+ (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
+
+#if __riscv_xlen == 64
+#define MSTATUS_SD MSTATUS64_SD
+#define SSTATUS_SD SSTATUS64_SD
+#define RISCV_PGLEVEL_BITS 9
+#define SATP_MODE SATP64_MODE
+#else
+#define MSTATUS_SD MSTATUS32_SD
+#define SSTATUS_SD SSTATUS32_SD
+#define RISCV_PGLEVEL_BITS 10
+#define SATP_MODE SATP32_MODE
+#endif
+#define RISCV_PGSHIFT 12
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
+#define CSR_USTATUS 0x0
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_CYCLE 0xc00
+#define CSR_UIE 0x4
+#define CSR_UTVEC 0x5
+#define CSR_USCRATCH 0x40
+#define CSR_UEPC 0x41
+#define CSR_UCAUSE 0x42
+#define CSR_UTVAL 0x43
+#define CSR_UIP 0x44
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_SSTATUS 0x100
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_STVAL 0x143
+#define CSR_SIP 0x144
+#define CSR_SATP 0x180
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MTVAL 0x343
+#define CSR_MIP 0x344
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH 0x7b2
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FETCH_ACCESS 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_BREAKPOINT 0x3
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_USER_ECALL 0x8
+#define CAUSE_HYPERVISOR_ECALL 0x9
+#define CAUSE_SUPERVISOR_ECALL 0xa
+#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+
+#define INSN_MATCH_LB 0x3
+#define INSN_MASK_LB 0x707f
+#define INSN_MATCH_LH 0x1003
+#define INSN_MASK_LH 0x707f
+#define INSN_MATCH_LW 0x2003
+#define INSN_MASK_LW 0x707f
+#define INSN_MATCH_LD 0x3003
+#define INSN_MASK_LD 0x707f
+#define INSN_MATCH_LBU 0x4003
+#define INSN_MASK_LBU 0x707f
+#define INSN_MATCH_LHU 0x5003
+#define INSN_MASK_LHU 0x707f
+#define INSN_MATCH_LWU 0x6003
+#define INSN_MASK_LWU 0x707f
+#define INSN_MATCH_SB 0x23
+#define INSN_MASK_SB 0x707f
+#define INSN_MATCH_SH 0x1023
+#define INSN_MASK_SH 0x707f
+#define INSN_MATCH_SW 0x2023
+#define INSN_MASK_SW 0x707f
+#define INSN_MATCH_SD 0x3023
+#define INSN_MASK_SD 0x707f
+
+#define INSN_MATCH_FLW 0x2007
+#define INSN_MASK_FLW 0x707f
+#define INSN_MATCH_FLD 0x3007
+#define INSN_MASK_FLD 0x707f
+#define INSN_MATCH_FLQ 0x4007
+#define INSN_MASK_FLQ 0x707f
+#define INSN_MATCH_FSW 0x2027
+#define INSN_MASK_FSW 0x707f
+#define INSN_MATCH_FSD 0x3027
+#define INSN_MASK_FSD 0x707f
+#define INSN_MATCH_FSQ 0x4027
+#define INSN_MASK_FSQ 0x707f
+
+#define INSN_MATCH_C_LD 0x6000
+#define INSN_MASK_C_LD 0xe003
+#define INSN_MATCH_C_SD 0xe000
+#define INSN_MASK_C_SD 0xe003
+#define INSN_MATCH_C_LW 0x4000
+#define INSN_MASK_C_LW 0xe003
+#define INSN_MATCH_C_SW 0xc000
+#define INSN_MASK_C_SW 0xe003
+#define INSN_MATCH_C_LDSP 0x6002
+#define INSN_MASK_C_LDSP 0xe003
+#define INSN_MATCH_C_SDSP 0xe002
+#define INSN_MASK_C_SDSP 0xe003
+#define INSN_MATCH_C_LWSP 0x4002
+#define INSN_MASK_C_LWSP 0xe003
+#define INSN_MATCH_C_SWSP 0xc002
+#define INSN_MASK_C_SWSP 0xe003
+
+#define INSN_MATCH_C_FLD 0x2000
+#define INSN_MASK_C_FLD 0xe003
+#define INSN_MATCH_C_FLW 0x6000
+#define INSN_MASK_C_FLW 0xe003
+#define INSN_MATCH_C_FSD 0xa000
+#define INSN_MASK_C_FSD 0xe003
+#define INSN_MATCH_C_FSW 0xe000
+#define INSN_MASK_C_FSW 0xe003
+#define INSN_MATCH_C_FLDSP 0x2002
+#define INSN_MASK_C_FLDSP 0xe003
+#define INSN_MATCH_C_FSDSP 0xa002
+#define INSN_MASK_C_FSDSP 0xe003
+#define INSN_MATCH_C_FLWSP 0x6002
+#define INSN_MASK_C_FLWSP 0xe003
+#define INSN_MATCH_C_FSWSP 0xe002
+#define INSN_MASK_C_FSWSP 0xe003
+
+#define INSN_LEN(insn) ((((insn) & 0x3) < 0x3) ? 2 : 4)
+
+#if __riscv_xlen == 64
+#define LOG_REGBYTES 3
+#else
+#define LOG_REGBYTES 2
+#endif
+#define REGBYTES (1 << LOG_REGBYTES)
+
+#define SH_RD 7
+#define SH_RS1 15
+#define SH_RS2 20
+#define SH_RS2C 2
+
+#define RV_X(x, s, n) (((x) >> (s)) & ((1 << (n)) - 1))
+#define RVC_LW_IMM(x) ((RV_X(x, 6, 1) << 2) | \
+ (RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 5, 1) << 6))
+#define RVC_LD_IMM(x) ((RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 5, 2) << 6))
+#define RVC_LWSP_IMM(x) ((RV_X(x, 4, 3) << 2) | \
+ (RV_X(x, 12, 1) << 5) | \
+ (RV_X(x, 2, 2) << 6))
+#define RVC_LDSP_IMM(x) ((RV_X(x, 5, 2) << 3) | \
+ (RV_X(x, 12, 1) << 5) | \
+ (RV_X(x, 2, 3) << 6))
+#define RVC_SWSP_IMM(x) ((RV_X(x, 9, 4) << 2) | \
+ (RV_X(x, 7, 2) << 6))
+#define RVC_SDSP_IMM(x) ((RV_X(x, 10, 3) << 3) | \
+ (RV_X(x, 7, 3) << 6))
+#define RVC_RS1S(insn) (8 + RV_X(insn, SH_RD, 3))
+#define RVC_RS2S(insn) (8 + RV_X(insn, SH_RS2C, 3))
+#define RVC_RS2(insn) RV_X(insn, SH_RS2C, 5)
+
+#define SHIFT_RIGHT(x, y) \
+ ((y) < 0 ? ((x) << -(y)) : ((x) >> (y)))
+
+#define REG_MASK \
+ ((1 << (5 + LOG_REGBYTES)) - (1 << LOG_REGBYTES))
+
+#define REG_OFFSET(insn, pos) \
+ (SHIFT_RIGHT((insn), (pos) - LOG_REGBYTES) & REG_MASK)
+
+#define REG_PTR(insn, pos, regs) \
+ (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
+
+#define GET_RM(insn) (((insn) >> 12) & 7)
+
+#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs))
+#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs))
+#define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs))
+#define GET_RS2S(insn, regs) (*REG_PTR(RVC_RS2S(insn), 0, regs))
+#define GET_RS2C(insn, regs) (*REG_PTR(insn, SH_RS2C, regs))
+#define GET_SP(regs) (*REG_PTR(2, 0, regs))
+#define SET_RD(insn, regs, val) (*REG_PTR(insn, SH_RD, regs) = (val))
+#define IMM_I(insn) ((s32)(insn) >> 20)
+#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \
+ (s32)(((insn) >> 7) & 0x1f))
+#define MASK_FUNCT3 0x7000
+
+#endif
diff --git a/MdePkg/Library/BaseLib/RiscV64/sbi_const.h b/MdePkg/Library/BaseLib/RiscV64/sbi_const.h
new file mode 100644
index 0000000..e6868c4
--- /dev/null
+++ b/MdePkg/Library/BaseLib/RiscV64/sbi_const.h
@@ -0,0 +1,53 @@
+/** @file
+ Definitions of RISC-V SBI constants.
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. 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.
+
+ SPDX-License-Identifier: BSD-2-Clause
+
+ Copyright (c) 2019 Western Digital Corporation or its affiliates.
+
+**/
+
+#ifndef __SBI_CONST_H__
+#define __SBI_CONST_H__
+
+/* Some constant macros are used in both assembler and
+ * C code. Therefore we cannot annotate them always with
+ * 'UL' and other type specifiers unilaterally. We
+ * use the following macros to deal with this.
+ *
+ * Similarly, _AT() will cast an expression with a type in C, but
+ * leave it unchanged in asm.
+ */
+
+#ifdef __ASSEMBLY__
+#define _AC(X,Y) X
+#define _AT(T,X) X
+#else
+#define __AC(X,Y) (X##Y)
+#define _AC(X,Y) __AC(X,Y)
+#define _AT(T,X) ((T)(X))
+#endif
+
+#define _UL(x) (_AC(x, UL))
+#define _ULL(x) (_AC(x, ULL))
+
+#define _BITUL(x) (_UL(1) << (x))
+#define _BITULL(x) (_ULL(1) << (x))
+
+#define UL(x) (_UL(x))
+#define ULL(x) (_ULL(x))
+
+#define __STR(s) #s
+#define STRINGIFY(s) __STR(s)
+
+#endif
--
2.7.4




Re: [PATCH] ArmVirtPkg/ArmVirtPrePiUniCoreRelocatable: revert to PIE linking

Leif Lindholm
 

On Thu, Sep 05, 2019 at 07:25:39AM -0700, Ard Biesheuvel wrote:
[BuildOptions]
- GCC:*_*_*_DLINK_FLAGS = -shared -Wl,-Bsymbolic -Wl,-T,$(MODULE_DIR)/Scripts/PrePi-PIE.lds
+ GCC:*_*_*_DLINK_FLAGS = -Wl,-Bsymbolic,-pie,-T,$(MODULE_DIR)/Scripts/PrePi-PIE.lds
We already merged a fix for AARCH64 though - could/should this be
active on ARM only?

A problem I have with this patch is that ArmVirtQemuKernel curently
doesn't boot on my qemu (with/without kvm, built with GCC5 or CLANG38,
with or without this patch):
ProcessPciHost: Config[0x4010000000+0x10000000) Bus[0x0..0xFF]
Io[0x0+0x10000)@0x3EFF0000 Mem32[0x10000000+0x2EFF0000)@0x0
Mem64[0x8000000000+0x8000000000)@0x0
MapGcdMmioSpace: failed to set memory space attributes for region
[0x4010000000+0x10000000)

ASSERT_EFI_ERROR (Status = Unsupported)
ASSERT [PciHostBridgeDxe]
/work/git/edk2/ArmVirtPkg/Library/FdtPciHostBridgeLib/FdtPciHostBridgeLib.c(293):
!EFI_ERROR (Status)
qemu-system-arm: terminating on signal 15 from pid 4680 (killall)
Does it work with -M virt,highmem=off ?
Ah, yes - that works fine then, also with the patch.

Well, with that, and your explanation in the other thread:
Acked-by: Leif Lindholm <leif.lindholm@...>


[PATCH] q35: lpc: allow to lock down 128K RAM at default SMBASE address

Igor Mammedov
 

lpc already has SMI negotiation feature, extend it by adding
optin ICH9_LPC_SMI_F_LOCKED_SMBASE_BIT to supported features.

Writing this bit into "etc/smi/requested-features" fw_cfg file,
tells QEMU to alias 0x30000,128K RAM range into SMRAM address
space and mask this region from normal RAM address space
(reads return 0xff and writes are ignored, i.e. guest code
should be able to deal with not usable 0x30000,128K RAM range
once ICH9_LPC_SMI_F_LOCKED_SMBASE_BIT is activated).

To make negotiated change effective, guest should read
"etc/smi/features-ok" fw_cfg file, which activates negotiated
features and locks down negotiating capabilities until hard reset.

Flow for initializing SMI handler on guest side:
1. set SMI handler entry point at default SMBASE location
2. check that host supports ICH9_LPC_SMI_F_LOCKED_SMBASE_BIT
in "etc/smi/supported-features" and set if supported set
it in "etc/smi/requested-features"
3. read "etc/smi/features-ok", if returned value is 1
negotiated at step 2 features are activated successfully.

Signed-off-by: Igor Mammedov <imammedo@...>
---
include/hw/i386/ich9.h | 11 ++++++--
hw/i386/pc.c | 4 ++-
hw/i386/pc_q35.c | 3 ++-
hw/isa/lpc_ich9.c | 58 +++++++++++++++++++++++++++++++++++++++++-
4 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index 72e803f6e2..c28685b753 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -12,11 +12,14 @@
#include "hw/acpi/acpi.h"
#include "hw/acpi/ich9.h"
#include "hw/pci/pci_bus.h"
+#include "qemu/units.h"

void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx);
PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin);
-void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled);
+void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled,
+ MemoryRegion *system_memory, MemoryRegion *ram,
+ MemoryRegion *smram);
I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);

void ich9_generate_smi(void);
@@ -71,6 +74,8 @@ typedef struct ICH9LPCState {
uint8_t smi_features_ok; /* guest-visible, read-only; selecting it
* triggers feature lockdown */
uint64_t smi_negotiated_features; /* guest-invisible, host endian */
+ MemoryRegion smbase_blackhole;
+ MemoryRegion smbase_window;

/* isa bus */
ISABus *isa_bus;
@@ -248,5 +253,7 @@ typedef struct ICH9LPCState {

/* bit positions used in fw_cfg SMI feature negotiation */
#define ICH9_LPC_SMI_F_BROADCAST_BIT 0
-
+#define ICH9_LPC_SMI_F_LOCKED_SMBASE_BIT 1
+#define ICH9_LPC_SMBASE_ADDR 0x30000
+#define ICH9_LPC_SMBASE_RAM_SIZE (128 * KiB)
#endif /* HW_ICH9_H */
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c14ed86439..99a98303eb 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -119,7 +119,9 @@ struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
/* Physical Address of PVH entry point read from kernel ELF NOTE */
static size_t pvh_start_addr;

-GlobalProperty pc_compat_4_1[] = {};
+GlobalProperty pc_compat_4_1[] = {
+ { "ICH9-LPC", "x-smi-locked-smbase", "off" },
+};
const size_t pc_compat_4_1_len = G_N_ELEMENTS(pc_compat_4_1);

GlobalProperty pc_compat_4_0[] = {};
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index d4e8a1cb9f..50462686a0 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -292,7 +292,8 @@ static void pc_q35_init(MachineState *machine)
0xff0104);

/* connect pm stuff to lpc */
- ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms));
+ ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms), get_system_memory(),
+ ram_memory, MEMORY_REGION(object_resolve_path("/machine/smram", NULL)));

if (pcms->sata_enabled) {
/* ahci and SATA device, for q35 1 ahci controller is built-in */
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 17c292e306..17a8cd1b51 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -359,6 +359,38 @@ static void ich9_set_sci(void *opaque, int irq_num, int level)
}
}

+static uint64_t smbase_blackhole_read(void *ptr, hwaddr reg, unsigned size)
+{
+ return 0xffffffff;
+}
+
+static void smbase_blackhole_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned width)
+{
+ /* nothing */
+}
+
+static const MemoryRegionOps smbase_blackhole_ops = {
+ .read = smbase_blackhole_read,
+ .write = smbase_blackhole_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
+ .impl.min_access_size = 4,
+ .impl.max_access_size = 4,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void ich9_lpc_smbase_locked_update(ICH9LPCState *lpc)
+{
+ bool en = lpc->smi_negotiated_features & ICH9_LPC_SMI_F_LOCKED_SMBASE_BIT;
+
+ memory_region_transaction_begin();
+ memory_region_set_enabled(&lpc->smbase_blackhole, en);
+ memory_region_set_enabled(&lpc->smbase_window, en);
+ memory_region_transaction_commit();
+}
+
static void smi_features_ok_callback(void *opaque)
{
ICH9LPCState *lpc = opaque;
@@ -379,9 +411,13 @@ static void smi_features_ok_callback(void *opaque)
/* valid feature subset requested, lock it down, report success */
lpc->smi_negotiated_features = guest_features;
lpc->smi_features_ok = 1;
+
+ ich9_lpc_smbase_locked_update(lpc);
}

-void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled)
+void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled,
+ MemoryRegion *system_memory, MemoryRegion *ram,
+ MemoryRegion *smram)
{
ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci);
qemu_irq sci_irq;
@@ -413,6 +449,20 @@ void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled)
&lpc->smi_features_ok,
sizeof lpc->smi_features_ok,
true);
+
+ memory_region_init_io(&lpc->smbase_blackhole, OBJECT(lpc),
+ &smbase_blackhole_ops, NULL,
+ "smbase-blackhole", ICH9_LPC_SMBASE_RAM_SIZE);
+ memory_region_set_enabled(&lpc->smbase_blackhole, false);
+ memory_region_add_subregion_overlap(system_memory, ICH9_LPC_SMBASE_ADDR,
+ &lpc->smbase_blackhole, 1);
+
+
+ memory_region_init_alias(&lpc->smbase_window, OBJECT(lpc),
+ "smbase-window", ram,
+ ICH9_LPC_SMBASE_ADDR, ICH9_LPC_SMBASE_RAM_SIZE);
+ memory_region_set_enabled(&lpc->smbase_window, false);
+ memory_region_add_subregion(smram, 0x30000, &lpc->smbase_window);
}

ich9_lpc_reset(DEVICE(lpc));
@@ -508,6 +558,7 @@ static int ich9_lpc_post_load(void *opaque, int version_id)
ich9_lpc_pmbase_sci_update(lpc);
ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RCBA_EN */);
ich9_lpc_pmcon_update(lpc);
+ ich9_lpc_smbase_locked_update(lpc);
return 0;
}

@@ -567,6 +618,8 @@ static void ich9_lpc_reset(DeviceState *qdev)
memset(lpc->smi_guest_features_le, 0, sizeof lpc->smi_guest_features_le);
lpc->smi_features_ok = 0;
lpc->smi_negotiated_features = 0;
+
+ ich9_lpc_smbase_locked_update(lpc);
}

/* root complex register block is mapped into memory space */
@@ -697,6 +750,7 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS);

isa_bus_irqs(isa_bus, lpc->gsi);
+
}

static bool ich9_rst_cnt_needed(void *opaque)
@@ -764,6 +818,8 @@ static Property ich9_lpc_properties[] = {
DEFINE_PROP_BOOL("noreboot", ICH9LPCState, pin_strap.spkr_hi, true),
DEFINE_PROP_BIT64("x-smi-broadcast", ICH9LPCState, smi_host_features,
ICH9_LPC_SMI_F_BROADCAST_BIT, true),
+ DEFINE_PROP_BIT64("x-smi-locked-smbase", ICH9LPCState, smi_host_features,
+ ICH9_LPC_SMI_F_LOCKED_SMBASE_BIT, true),
DEFINE_PROP_END_OF_LIST(),
};

--
2.18.1


Re: [Qemu-devel] [edk2-rfc] [edk2-devel] CPU hotplug using SMM with QEMU+OVMF

Igor Mammedov
 

On Thu, 5 Sep 2019 15:08:31 +0200
Laszlo Ersek <lersek@...> wrote:

On 09/04/19 11:52, Igor Mammedov wrote:

it could be stolen RAM + black hole like TSEG, assuming fw can live without RAM(0x30000+128K) range
(in this case fwcfg interface would only work for locking down the range)

or

we can actually have a dedicated SMRAM (like in my earlier RFC),
in this case FW can use RAM(0x30000+128K) when SMRAM isn't mapped into RAM address space
(in this case fwcfg would be used to temporarily map SMRAM into normal RAM and unmap/lock
after SMI relocation handler was initialized).

If possible I'd prefer a simpler TSEG like variant.
I think TSEG-like behavior is between these two. That is, I believe we
should have explicit open/close/lock operations. And, when the range is
closed (meaning, closed+unlocked, or closed+locked), then the black hole
should take effect for code that's not running in SMM.

Put differently, its like the second choice, except the range never
appears as normal RAM. "When SMRAM isn't mapped into RAM address space",
then the address range shows "nothing" (black hole).
I guess we at point where patch is better then words, I'll send one as reply here shortly.
I've just implemented subset of above (opened, closed+locked).


Regarding "fw can live without RAM(0x30000+128K) range" -- do you mean
whether the firmware could use another RAM area for fw_cfg DMA?

If that's the question, then I wouldn't worry about it. I'd remove the
0x30000+128K range from the memory map, so the fw_cfg stuff (or anything
else) would never allocate memory from the range. It's much more
concerning to me however how the SMM infrastructure would deal with a
hole in the memory map right there.
I didn't mean fwcfg in this context, what I meant if firmware were able
to avoid using RAM(0x30000+128K) range (since it becomes unusable after locking).
Looks like you just answered it here


Re: [edk2-staging/RISC-V-V2 PATCH v1 11/22]: BaseTools: BaseTools changes for RISC-V platform.

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:06PM +0800, Abner Chang wrote:
BaseTools changes for building EDK2 RISC-V platform.
The changes made to build_rule.template is to avoid build errors cause by GCC711RISCV tool chain.
What errors?

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
BaseTools/Conf/build_rule.template | 23 +-
BaseTools/Conf/tools_def.template | 108 +-
BaseTools/Source/C/Common/BasePeCoff.c | 19 +-
BaseTools/Source/C/Common/PeCoffLoaderEx.c | 96 ++
BaseTools/Source/C/GenFv/GenFvInternalLib.c | 281 ++++-
BaseTools/Source/C/GenFw/Elf32Convert.c | 6 +-
BaseTools/Source/C/GenFw/Elf64Convert.c | 273 ++++-
BaseTools/Source/C/GenFw/elf_common.h | 63 ++
.../Source/C/Include/IndustryStandard/PeImage.h | 10 +
BaseTools/Source/Python/Common/DataType.py | 1075 ++++++++++----------
10 files changed, 1393 insertions(+), 561 deletions(-)

diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template
index db06d3a..8e7f6e0 100755
--- a/BaseTools/Conf/build_rule.template
+++ b/BaseTools/Conf/build_rule.template
@@ -145,14 +145,6 @@
<Command.GCC, Command.RVCT>
"$(CC)" $(CC_FLAGS) $(CC_XIPFLAGS) -c -o ${dst} $(INC) ${src}

-[C-Header-File]
- <InputFile>
- *.h, *.H
-
- <OutputFile>
-
- <Command>
-
[Assembly-Code-File.COMMON.COMMON]
<InputFile.MSFT, InputFile.INTEL, InputFile.RVCT>
?.asm, ?.Asm, ?.ASM
@@ -321,6 +313,21 @@
"$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}


+[Static-Library-File.COMMON.RISCV64, Static-Library-File.COMMON.RISCV32]
+ <InputFile>
+ *.lib
+
+ <ExtraDependency>
+ $(MAKE_FILE)
+
+ <OutputFile>
+ $(DEBUG_DIR)(+)$(MODULE_NAME).dll
+
+ <Command.GCC>
+ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) --end-group $(DLINK2_FLAGS)
+ "$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}
+
+
[Static-Library-File.USER_DEFINED, Static-Library-File.HOST_APPLICATION]
<InputFile>
*.lib
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index 8f0e6cb..36a301a 100755
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -3,7 +3,7 @@
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
# Portions copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
# Copyright (c) 2015, Hewlett-Packard Development Company, L.P.<BR>
-# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+# (C) Copyright 2016-2019 Hewlett Packard Enterprise Development LP<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -114,6 +114,12 @@ DEFINE GCC49_X64_PREFIX = ENV(GCC49_BIN)
DEFINE GCC5_IA32_PREFIX = ENV(GCC5_BIN)
DEFINE GCC5_X64_PREFIX = ENV(GCC5_BIN)
DEFINE GCC_HOST_PREFIX = ENV(GCC_HOST_BIN)
+#
+# RISC-V GCC toolchain
+# This is the default directory used when install official riscv-tools.
+#
+DEFINE GCCRISCV_RISCV32_PREFIX = ENV(GCC_RISCV32_BIN)
I won't complain about adding 32-bit RISC-V things to industry
standard headers, but apart from that I don't want to see bits of
32-bit support trickle through until there is actually a full port
going in. So please delete all lines including "RISCV32" in this file.

+DEFINE GCCRISCV_RISCV64_PREFIX = ENV(GCC_RISCV64_BIN)

DEFINE UNIX_IASL_BIN = ENV(IASL_PREFIX)iasl
DEFINE WIN_IASL_BIN = ENV(IASL_PREFIX)iasl.exe
@@ -236,6 +242,15 @@ DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc
# Required to build platforms or ACPI tables:
# Intel(r) ACPI Compiler from
# https://acpica.org/downloads
+# GCCRISCV - Linux - Requires:
+# RISC-V official release of RISC-V GNU toolchain,
+# https://github.com/riscv/riscv-gnu-toolchain @64879b24
+# The commit ID 64879b24 is the one can build RISC-V platform and boo to EFI shell.
+# Follow the instructions mentioned in README.md to build RISC-V tool change.
+# Set below environment variables to the RISC-V tool chain binaries before building RISC-V EDK2 port.
+# - GCC_RISCV32_BIN
+# - GCC_RISCV64_BIN
+#
# CLANG35 -Linux,Windows- Requires:
# Clang v3.5 or later, and GNU binutils targeting aarch64-linux-gnu or arm-linux-gnueabi
# Optional:
@@ -1806,6 +1821,26 @@ DEFINE GCC5_ARM_ASLDLINK_FLAGS = DEF(GCC49_ARM_ASLDLINK_FLAGS)
DEFINE GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS)
DEFINE GCC5_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -fno-lto

+DEFINE GCC_RISCV_ALL_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -c -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings
+DEFINE GCC_RISCV_ALL_DLINK_COMMON = -nostdlib -n -q --gc-sections -z common-page-size=0x40
+DEFINE GCC_RISCV_ALL_DLINK_FLAGS = DEF(GCC_RISCV_ALL_DLINK_COMMON) --entry $(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC_RISCV_ALL_DLINK2_FLAGS = --defsym=PECOFF_HEADER_SIZE=0x220 --script=$(EDK_TOOLS_PATH)/Scripts/GccBaseRiscV.lds
+DEFINE GCC_RISCV_ALL_ASM_FLAGS = -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h
+DEFINE GCC_RISCV_RISCV32_DLINK2_FLAGS = --defsym=PECOFF_HEADER_SIZE=0x220 DEF(GCC_DLINK2_FLAGS_COMMON)
+
+DEFINE GCCRISCV_RISCV32_ARCH = rv32imafdc
+DEFINE GCCRISCV_RISCV64_ARCH = rv64imafdc
+DEFINE GCCRISCV_CC_FLAGS_WARNING_DISABLE = -Wno-tautological-compare -Wno-pointer-compare
+DEFINE GCCRISCV_RISCV32_CC_FLAGS = DEF(GCC_RISCV_ALL_CC_FLAGS) DEF(GCCRISCV_CC_FLAGS_WARNING_DISABLE) -march=DEF(GCCRISCV_RISCV32_ARCH) -malign-double -fno-stack-protector -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -Wno-unused-but-set-variable -fpack-struct=8
+DEFINE GCCRISCV_RISCV64_CC_FLAGS = DEF(GCC_RISCV_ALL_CC_FLAGS) DEF(GCCRISCV_CC_FLAGS_WARNING_DISABLE) -march=DEF(GCCRISCV_RISCV64_ARCH) -fno-builtin -fno-builtin-memcpy -fno-stack-protector -Wno-address -fno-asynchronous-unwind-tables -Wno-unused-but-set-variable -fpack-struct=8 -mcmodel=medany -mabi=lp64
+DEFINE GCCRISCV_RISCV32_RISCV64_DLINK_COMMON = -nostdlib -n -q --gc-sections -z common-page-size=0x40
+DEFINE GCCRISCV_RISCV32_RISCV64_ASLDLINK_FLAGS = DEF(GCC_RISCV_ALL_DLINK_COMMON) --entry ReferenceAcpiTable -u ReferenceAcpiTable
+DEFINE GCCRISCV_RISCV32_RISCV64_DLINK_FLAGS = DEF(GCC_RISCV_ALL_DLINK_COMMON) --entry $(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCCRISCV_RISCV32_DLINK2_FLAGS = DEF(GCC_RISCV_RISCV32_DLINK2_FLAGS)
+DEFINE GCCRISCV_RISCV64_DLINK_FLAGS = DEF(GCC_RISCV_ALL_DLINK_FLAGS) -melf64lriscv --oformat=elf64-littleriscv --no-relax
+DEFINE GCCRISCV_RISCV64_DLINK2_FLAGS = DEF(GCC_RISCV_ALL_DLINK2_FLAGS)
+DEFINE GCCRISCV_ASM_FLAGS = DEF(GCC_RISCV_ALL_ASM_FLAGS) -march=DEF(GCCRISCV_RISCV64_ARCH) -mcmodel=medany -mabi=lp64
+
####################################################################################
#
# GCC 4.8 - This configuration is used to compile under Linux to produce
@@ -2247,6 +2282,77 @@ RELEASE_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20
NOOPT_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0
NOOPT_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 -O0

+###################################################################################
+####################################################################################
+#
+# GCC RISC-V This configuration is used to compile under Linux to produce
+# PE/COFF binaries using GCC RISC-V tool chain
+# https://github.com/riscv/riscv-gnu-toolchain @64879b24
+# The commit ID 64879b24 is the one can build RISC-V platform and boo to EFI shell.
+#
+####################################################################################
+
+*_GCCRISCV_*_*_FAMILY = GCC
+
+*_GCCRISCV_*_MAKE_PATH = DEF(GCC49_IA32_PREFIX)make
+*_GCCRISCV_*_PP_FLAGS = DEF(GCC_PP_FLAGS)
+*_GCCRISCV_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS)
+*_GCCRISCV_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS)
+*_GCCRISCV_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS)
+*_GCCRISCV_*_APP_FLAGS =
+*_GCCRISCV_*_ASL_FLAGS = DEF(IASL_FLAGS)
+*_GCCRISCV_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS)
+
+##################
+# GCCRISCV RISCV32 definitions
+##################
+
+*_GCCRISCV_RISCV32_OBJCOPY_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-objcopy
+*_GCCRISCV_RISCV32_SLINK_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-gcc-ar
+*_GCCRISCV_RISCV32_DLINK_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-ld
+*_GCCRISCV_RISCV32_ASLDLINK_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-ld
+*_GCCRISCV_RISCV32_ASM_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV32_PP_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV32_VFRPP_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV32_ASLCC_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV32_ASLPP_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV32_RC_PATH = DEF(GCCRISCV_RISCV32_PREFIX)riscv64-unknown-elf-objcopy
+
+*_GCCRISCV_RISCV32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32
+*_GCCRISCV_RISCV32_ASLDLINK_FLAGS = DEF(GCCRISCV_RISCV32_RISCV64_ASLDLINK_FLAGS) -m elf_i386
+*_GCCRISCV_RISCV32_ASM_FLAGS = DEF(GCCRISCV_ASM_FLAGS) -m32 -march=i386
+*_GCCRISCV_RISCV32_CC_FLAGS = DEF(GCCRISCV_RISCV32_CC_FLAGS) -Os
+*_GCCRISCV_RISCV32_DLINK_FLAGS = DEF(GCCRISCV_RISCV32_RISCV64_DLINK_FLAGS) -m elf_i386 --oformat=elf32-i386
+*_GCCRISCV_RISCV32_DLINK2_FLAGS = DEF(GCCRISCV_RISCV32_DLINK2_FLAGS)
+*_GCCRISCV_RISCV32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+*_GCCRISCV_RISCV32_OBJCOPY_FLAGS =
+*_GCCRISCV_RISCV32_NASM_FLAGS = -f elf32
+
+##################
+# GCCRISCV RISCV64 definitions
+##################
+*_GCCRISCV_RISCV64_OBJCOPY_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-objcopy
+*_GCCRISCV_RISCV64_CC_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV64_SLINK_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-gcc-ar
+*_GCCRISCV_RISCV64_DLINK_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-ld
+*_GCCRISCV_RISCV64_ASLDLINK_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-ld
+*_GCCRISCV_RISCV64_ASM_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV64_PP_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV64_VFRPP_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV64_ASLCC_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV64_ASLPP_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-gcc
+*_GCCRISCV_RISCV64_RC_PATH = DEF(GCCRISCV_RISCV64_PREFIX)riscv64-unknown-elf-objcopy
+
+*_GCCRISCV_RISCV64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64
+*_GCCRISCV_RISCV64_ASLDLINK_FLAGS = DEF(GCCRISCV_RISCV32_RISCV64_ASLDLINK_FLAGS) -m elf_x86_64
+*_GCCRISCV_RISCV64_ASM_FLAGS = DEF(GCCRISCV_ASM_FLAGS)
+*_GCCRISCV_RISCV64_CC_FLAGS = DEF(GCCRISCV_RISCV64_CC_FLAGS) -save-temps
+*_GCCRISCV_RISCV64_DLINK_FLAGS = DEF(GCCRISCV_RISCV64_DLINK_FLAGS)
+*_GCCRISCV_RISCV64_DLINK2_FLAGS = DEF(GCCRISCV_RISCV64_DLINK2_FLAGS)
+*_GCCRISCV_RISCV64_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS)
+*_GCCRISCV_RISCV64_OBJCOPY_FLAGS =
+*_GCCRISCV_RISCV64_NASM_FLAGS = -f elf64
+
####################################################################################
#
# CLANG35 - This configuration is used to compile under Linux to produce
diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Common/BasePeCoff.c
index e7566b3..e346e02 100644
--- a/BaseTools/Source/C/Common/BasePeCoff.c
+++ b/BaseTools/Source/C/Common/BasePeCoff.c
@@ -4,6 +4,7 @@

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+Portions Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -59,6 +60,14 @@ PeCoffLoaderRelocateArmImage (
IN UINT64 Adjust
);

+RETURN_STATUS
+PeCoffLoaderRelocateRiscVImage (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ );
+
STATIC
RETURN_STATUS
PeCoffLoaderGetPeHeader (
@@ -174,7 +183,10 @@ Returns:
ImageContext->Machine != EFI_IMAGE_MACHINE_X64 && \
ImageContext->Machine != EFI_IMAGE_MACHINE_ARMT && \
ImageContext->Machine != EFI_IMAGE_MACHINE_EBC && \
- ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64) {
+ ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64 && \
+ ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV32 && \
+ ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64 && \
+ ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV128) {
if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) {
//
// There are two types of ARM images. Pure ARM and ARM/Thumb.
@@ -802,6 +814,11 @@ Returns:
case EFI_IMAGE_MACHINE_ARMT:
Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust);
break;
+ case EFI_IMAGE_MACHINE_RISCV32:
+ case EFI_IMAGE_MACHINE_RISCV64:
+ case EFI_IMAGE_MACHINE_RISCV128:
And please delete all code related to RISCV32/RISCV128 from this file.
Submit them with future full ports.

+ Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust);
+ break;
default:
Status = RETURN_UNSUPPORTED;
break;
diff --git a/BaseTools/Source/C/Common/PeCoffLoaderEx.c b/BaseTools/Source/C/Common/PeCoffLoaderEx.c
index e367836..867c47b 100644
--- a/BaseTools/Source/C/Common/PeCoffLoaderEx.c
+++ b/BaseTools/Source/C/Common/PeCoffLoaderEx.c
@@ -3,6 +3,7 @@ IA32 and X64 Specific relocation fixups

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

--*/
@@ -61,6 +62,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define IMM64_SIGN_INST_WORD_POS_X 27
#define IMM64_SIGN_VAL_POS_X 63

+//
+// RISC-V definition.
+//
+#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
+#define RISCV_IMM_BITS 12
+#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
+#define RISCV_CONST_HIGH_PART(VALUE) \
+ (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
+
+UINT32 *RiscVHi20Fixup = NULL;
+
RETURN_STATUS
PeCoffLoaderRelocateIa32Image (
IN UINT16 *Reloc,
@@ -94,6 +106,90 @@ Returns:
}


+RETURN_STATUS
+PeCoffLoaderRelocateRiscVImage (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an RISC-V specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ Status code
+
+--*/
The description comment goes before the whole thing, not between ) and {.
I know this is following (bad) examples in this file, but let's start
improving it. This applies to other functions in this file too.

+{
+ UINT32 Value;
+ UINT32 Value2;
+ UINT32 OrgValue;
+
+ OrgValue = *(UINT32 *) Fixup;
+ OrgValue = OrgValue;
+ switch ((*Reloc) >> 12) {
+ case EFI_IMAGE_REL_BASED_RISCV_HI20:
+ RiscVHi20Fixup = (UINT32 *) Fixup;
+ break;
+
+ case EFI_IMAGE_REL_BASED_RISCV_LOW12I:
+ if (RiscVHi20Fixup != NULL) {
+ Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value += (UINT32)Adjust;
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
+ *(UINT32 *)Fixup = (RV_X (Value, 0, 12) << 20) | \
+ (RV_X (*(UINT32 *)Fixup, 0, 20));
+ }
+ RiscVHi20Fixup = NULL;
+ break;
+
+ case EFI_IMAGE_REL_BASED_RISCV_LOW12S:
+ if (RiscVHi20Fixup != NULL) {
+ Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 *)Fixup, 25, 7) << 5));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value += (UINT32)Adjust;
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
+ Value2 = *(UINT32 *)Fixup & 0x01fff07f;
+ Value &= RISCV_IMM_REACH - 1;
+ *(UINT32 *)Fixup = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));
+ }
+ RiscVHi20Fixup = NULL;
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+
+ }
+ return RETURN_SUCCESS;
+}
+
/**
Pass in a pointer to an ARM MOVT or MOVW immediate instruction and
return the immediate data encoded in the instruction
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 908740d..b1dc7ec 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -4,6 +4,7 @@ This file contains the internal functions required to generate a Firmware Volume
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>
+Portions Copyright (c) 2016 - 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
@@ -37,6 +38,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000

BOOLEAN mArm = FALSE;
+BOOLEAN mRiscV = FALSE;
STATIC UINT32 MaxFfsAlignment = 0;
BOOLEAN VtfFileFlag = FALSE;

@@ -1802,6 +1804,154 @@ if (MachineType == EFI_IMAGE_MACHINE_IA32 || MachineType == EFI_IMAGE_MACHINE_X6
}

EFI_STATUS
+RiscvPatchVtfTrapHandler (EFI_FFS_FILE_HEADER *VtfFileImage, UINTN UserTrapAddressInFile)
+/*++
+
+Routine Description:
+ This patches RISC-V trap handler in VTF.
+ 0xF...FE00 Trap from user-mode
+ 0xF...FE40 Trap from supervisor-mode
+ 0xF...FE80 Trap from hypervisor-mode
+ 0xF...FEC0 Trap from machine-mode
+ 0xF...FEFC Non-maskable interrupt(s)
+
+Arguments:
+ VtfFileImage VTF file.
+ UserTrapAddressInFile User Trap address in file image.
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_NOT_FOUND PEI Core file not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FILE_SECTION_POINTER Pe32Section;
+ UINT32 EntryPoint;
+ UINT32 BaseOfCode;
+ UINT16 MachineType;
+ UINT8 *HighTrapVectorAddress;
+ UINTN TrapPrivilegeNum;
+
+ if (UserTrapAddressInFile == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetSectionByType (VtfFileImage, EFI_SECTION_PE32, 1, &Pe32Section); // Get PE32 section.
+ if (!EFI_ERROR (Status)) {
+ Status = GetPe32Info ( // Get entry point.
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
+ &EntryPoint,
+ &BaseOfCode,
+ &MachineType
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Pacth trap handler.
+ //
+ HighTrapVectorAddress = (UINT8 *)((UINTN)EntryPoint + ((UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)));
+ HighTrapVectorAddress -= (0x10 + 0x100);
+
+ //
+ // Patch all privilege trap bases.
+ //
+ for (TrapPrivilegeNum = 0; TrapPrivilegeNum < 4; TrapPrivilegeNum ++) {
+ *((UINT32 *)HighTrapVectorAddress) = (*((UINT32 *)HighTrapVectorAddress) & 0xfff) | (*((UINT32 *)(UINTN)UserTrapAddressInFile) & 0xfffff000);
+ *((UINT32 *)(HighTrapVectorAddress + 4)) = (*((UINT32 *)(HighTrapVectorAddress + 4)) & 0x000fffff) | ((*((UINT32 *)(UINTN)UserTrapAddressInFile) & 0xfff) << 20);
+ HighTrapVectorAddress += 0x40;
+ UserTrapAddressInFile += 8;
+ }
+
+ return EFI_SUCCESS;
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Patch RISC-V trap: Incorrect PE32 format of RISC-V VTF");
+ }
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "atch RISC-V trap: Can't find PE32 section of RISC-V VTF.");
+ }
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+RiscvPatchVtf (EFI_FFS_FILE_HEADER *VtfFileImage, UINT32 ResetVector)
+/*++
+
+Routine Description:
+ This patches the entry point of either SecCore or
+
+ For RISC-V ISA, the reset vector is at 0xfff~ff00h or 200h
+
+Arguments:
+ VtfFileImage VTF file.
+ ResetVector Entry point for reset vector.
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_NOT_FOUND PEI Core file not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FILE_SECTION_POINTER Pe32Section;
+ UINT32 EntryPoint;
+ UINT8 *EntryPointAddress;
+ UINT32 *LoadHigh20BitInstrcutionAddr;
+ UINT32 *JmpLow12BitInstrcutionAddr;
+ UINT32 LoadHigh20BitAddressOffset;
+ UINT32 JmpLow12BitAddressOffset;
+ UINT32 BaseOfCode;
+ UINT16 MachineType;
+ UINT32 LoadHigh20BitOpc;
+ UINT32 JmpLow12BitOpc;
+
+ if (ResetVector == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetSectionByType (VtfFileImage, EFI_SECTION_PE32, 1, &Pe32Section); // Get PE32 section.
+ if (!EFI_ERROR (Status)) {
+ Status = GetPe32Info ( // Get entry point.
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
+ &EntryPoint,
+ &BaseOfCode,
+ &MachineType
+ );
+ if (!EFI_ERROR (Status)) {
+ EntryPointAddress = (UINT8 *)((UINTN)EntryPoint + ((UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)));
+ LoadHigh20BitAddressOffset = *((UINT32 *)(EntryPointAddress - 16)); // (Entrypoint - 16) map to the second qword from Entrypoint
+ JmpLow12BitAddressOffset = *((UINT32 *)(EntryPointAddress - 8)); // (Entrypoint - 8) map to the second qword from Entrypoint
+ LoadHigh20BitInstrcutionAddr = (UINT32 *)(EntryPointAddress + LoadHigh20BitAddressOffset);
+ JmpLow12BitInstrcutionAddr = (UINT32 *)(EntryPointAddress + JmpLow12BitAddressOffset);
+ //
+ // Patch RISC-V instruction : li a0, 0x12345000
+ //
+ LoadHigh20BitOpc = *LoadHigh20BitInstrcutionAddr;
+ LoadHigh20BitOpc = (LoadHigh20BitOpc & 0xfff) | (ResetVector & 0xfffff000);
+ *((UINT32 *)(EntryPointAddress - 16)) = LoadHigh20BitOpc;
+ //
+ // Patch RISC-V instruction : jalr x0, a0, 0x678
+ //
+ JmpLow12BitOpc = *JmpLow12BitInstrcutionAddr;
+ JmpLow12BitOpc = (JmpLow12BitOpc & 0x000fffff) | ((ResetVector & 0xfff) << 20);
+ *((UINT32 *)(EntryPointAddress - 12)) = JmpLow12BitOpc;
+ return EFI_SUCCESS;
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Incorrect PE32 format of RISC-V VTF");
+ }
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "Can't find PE32 section of RISC-V VTF.");
+ }
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
FindCorePeSection(
IN VOID *FvImageBuffer,
IN UINT64 FvSize,
@@ -2274,6 +2424,106 @@ Returns:
}

EFI_STATUS
+UpdateRiscvResetVectorIfNeeded (
+ MEMORY_FILE *FvImage,
+ FV_INFO *FvInfo
+ )
+/*++
+
+Routine Description:
+ This parses the FV looking for SEC and patches that address into the
+ beginning of the FV header.
+
+ For RISC-V ISA, the reset vector is at 0xfff~ff00h or 200h
+
+Arguments:
+ FvImage Memory file for the FV memory image/
+ FvInfo Information read from INF file.
+
+Returns:
+
+ EFI_SUCCESS Function Completed successfully.
+ EFI_ABORTED Error encountered.
+ EFI_INVALID_PARAMETER A required parameter was NULL.
+ EFI_NOT_FOUND PEI Core file not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT16 MachineType;
+ EFI_FILE_SECTION_POINTER SecPe32;
+ EFI_PHYSICAL_ADDRESS SecCoreEntryAddress;
+
+ UINT32 bSecCore;
+ UINT32 tmp;
+
+
+ //
+ // Verify input parameters
+ //
+ if (FvImage == NULL || FvInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Initialize FV library
+ //
+ InitializeFvLib (FvImage->FileImage, FvInfo->Size);
+
+ //
+ // Find the Sec Core
+ //
+ Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
+ if(EFI_ERROR(Status)) {
+ printf("skip because Secutiry Core not found\n");
+ return EFI_SUCCESS;
+ }
+
+ DebugMsg (NULL, 0, 9, "Update SEC core in FV Header", NULL);
+
+ Status = GetCoreMachineType(SecPe32, &MachineType);
+ if(EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC core.");
+ return EFI_ABORTED;
+ }
+
+ if ((MachineType != EFI_IMAGE_MACHINE_RISCV32) && (MachineType != EFI_IMAGE_MACHINE_RISCV64)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not update SEC core because Machine type is not RiscV.");
+ return EFI_ABORTED;
+ }
+
+ Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
+ if(EFI_ERROR(Status)) {
+ Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
+ return EFI_ABORTED;
+ }
+
+ VerboseMsg("SecCore entry point Address = 0x%llX", (unsigned long long) SecCoreEntryAddress);
+ VerboseMsg("BaseAddress = 0x%llX", (unsigned long long) FvInfo->BaseAddress);
+ bSecCore = (SecCoreEntryAddress - FvInfo->BaseAddress);
+ VerboseMsg("offset = 0x%llX", bSecCore);
+
+ if(bSecCore > 0x0fffff) {
+ Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 1MB of start of the FV");
+ return EFI_ABORTED;
+ }
+
+ tmp = bSecCore;
+ bSecCore = 0;
+ //J-type
+ bSecCore = (tmp&0x100000)<<11; //imm[20] at bit[31]
+ bSecCore |= (tmp&0x0007FE)<<20; //imm[10:1] at bit[30:21]
+ bSecCore |= (tmp&0x000800)<<9; //imm[11] at bit[20]
+ bSecCore |= (tmp&0x0FF000); //imm[19:12] at bit[19:12]
+ bSecCore |= 0x6F; //JAL opcode
+
+ memcpy(FvImage->FileImage, &bSecCore, sizeof(bSecCore));
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
GetPe32Info (
IN UINT8 *Pe32,
OUT UINT32 *EntryPoint,
@@ -2365,7 +2615,8 @@ Returns:
// Verify machine type is supported
//
if ((*MachineType != EFI_IMAGE_MACHINE_IA32) && (*MachineType != EFI_IMAGE_MACHINE_X64) && (*MachineType != EFI_IMAGE_MACHINE_EBC) &&
- (*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64)) {
+ (*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64) &&
+ (*MachineType != EFI_IMAGE_MACHINE_RISCV32) && (*MachineType != EFI_IMAGE_MACHINE_RISCV64) && (*MachineType != EFI_IMAGE_MACHINE_RISCV128)) {
Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");
return EFI_UNSUPPORTED;
}
@@ -2777,7 +3028,6 @@ Returns:
FvHeader->Checksum = 0;
FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
}
-
Please don't spuriously add or delete blank lines.

//
// Add files to FV
//
@@ -2808,7 +3058,8 @@ Returns:
Error (NULL, 0, 4002, "Resource", "FV space is full, cannot add pad file between the last file and the VTF file.");
goto Finish;
}
- if (!mArm) {
+
Please don't spuriously add or delete blank lines.
#
+ if (!mArm && !mRiscV) {
//
// Update reset vector (SALE_ENTRY for IPF)
// Now for IA32 and IA64 platform, the fv which has bsf file must have the
@@ -2843,6 +3094,22 @@ Returns:
FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
}

+ if (mRiscV) {
+ //
+ // Update RISCV reset vector.
+ //
+ Status = UpdateRiscvResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector for RISC-V.");
+ goto Finish;
+ }
+ //
+ // Update Checksum for FvHeader
+ //
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+ }
+
//
// Update FV Alignment attribute to the largest alignment of all the FFS files in the FV
//
@@ -3430,6 +3697,12 @@ Returns:
mArm = TRUE;
}

+ if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_RISCV32) ||
+ (ImageContext.Machine == EFI_IMAGE_MACHINE_RISCV64) ||
+ (ImageContext.Machine == EFI_IMAGE_MACHINE_RISCV128)) {
+ mRiscV = TRUE;
+ }
+
//
// Keep Image Context for PE image in FV
//
@@ -3583,7 +3856,7 @@ Returns:
ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
- Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status);
free ((VOID *) MemoryImagePointer);
return Status;
}
diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.c b/BaseTools/Source/C/GenFw/Elf32Convert.c
index 46089ff..3e47475 100644
--- a/BaseTools/Source/C/GenFw/Elf32Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf32Convert.c
@@ -3,6 +3,7 @@ Elf32 Convert solution

Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
+Portions Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

@@ -141,8 +142,9 @@ InitializeElf32 (
Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");
return FALSE;
}
- if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM))) {
- Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM");
+
+ if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM) || (mEhdr->e_machine == EM_RISCV))) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386, EM_ARM or EM_RISCV");
Nothing wrong with this change really, but I think instead of
enumerating all supported 32-bit architectures (as someone started
with the ARM port), let's change the message to "ELF e_machine is not
an Elf32 machine".

And *cough* of course, as a RISCV32 change, we don't really want it as
part of this set. I'd take it as a separate patch unrelated to this
set though.

return FALSE;
}
if (mEhdr->e_version != EV_CURRENT) {
diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c
index 3d6319c..e65f640 100644
--- a/BaseTools/Source/C/GenFw/Elf64Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
@@ -3,6 +3,7 @@ Elf64 convert solution

Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
+Portions Copyright (c) 2016 - 2017 Hewlett Packard Enterprise Development LP. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

@@ -31,6 +32,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "ElfConvert.h"
#include "Elf64Convert.h"

+#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
+#define RISCV_IMM_BITS 12
+#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
+#define RISCV_CONST_HIGH_PART(VALUE) \
+ (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
+
STATIC
VOID
ScanSections64 (
@@ -153,8 +160,9 @@ InitializeElf64 (
Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");
return FALSE;
}
- if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64))) {
- Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_X86_64 or EM_AARCH64");
+
+ if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64))) {
+ Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_X86_64, EM_AARCH64 or EM_RISCV64");
And the opposite here of course - "ELF e_machine is not an Elf64 machine".

return FALSE;
}
if (mEhdr->e_version != EV_CURRENT) {
@@ -481,6 +489,7 @@ ScanSections64 (
switch (mEhdr->e_machine) {
case EM_X86_64:
case EM_AARCH64:
+ case EM_RISCV64:
mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
break;
default:
@@ -690,6 +699,12 @@ ScanSections64 (
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_AARCH64;
NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
break;
+
+ case EM_RISCV64:
+ NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_RISCV64;
+ NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ break;
+
default:
VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;
@@ -769,6 +784,11 @@ WriteSections64 (
Elf_Shdr *SecShdr;
UINT32 SecOffset;
BOOLEAN (*Filter)(Elf_Shdr *);
+ UINT32 Value;
+ UINT32 Value2;
+ UINT8 *RiscvHi20Targ = NULL;
+ Elf_Shdr *RiscvHi20Sym = NULL;
+ Elf64_Half RiscvSymSecIndex = 0;
I am a little bit concerned over 5 new variables being added for a
specific architecture in an non-architecture-specific function.
Do some of the relocations need to be broken out into helper
functions? If not, can we find some more generic names?

Elf64_Addr GOTEntryRva;

//
@@ -893,13 +913,14 @@ WriteSections64 (
if (SymName == NULL) {
SymName = (const UINT8 *)"<unknown>";
}
-
- Error (NULL, 0, 3000, "Invalid",
- "%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type. "
- "For example, absolute and undefined symbols are not supported.",
- mInImageName, SymName, Sym->st_value);
-
- exit(EXIT_FAILURE);
+ if (mEhdr->e_machine != EM_RISCV64) {
+ Error (NULL, 0, 3000, "Invalid",
+ "%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type. "
+ "For example, absolute and undefined symbols are not supported.",
+ mInImageName, SymName, Sym->st_value);
+
+ exit(EXIT_FAILURE);
+ }
}
SymShdr = GetShdrByIndex(Sym->st_shndx);

@@ -1114,6 +1135,135 @@ WriteSections64 (
default:
Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
}
+ } else if (mEhdr->e_machine == EM_RISCV64) {
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_RISCV_NONE:
+ break;
+ case R_RISCV_32:
+ *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);
+ break;
+ case R_RISCV_64:
+ *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ break;
+ case R_RISCV_HI20:
+ RiscvHi20Targ = Targ;
+ RiscvHi20Sym = SymShdr;
+ RiscvSymSecIndex = Sym->st_shndx;
+ break;
+ case R_RISCV_LO12_I:
+ if (RiscvHi20Sym == SymShdr && RiscvHi20Targ != NULL && RiscvSymSecIndex == Sym->st_shndx && RiscvSymSecIndex != 0) {
+ Value = (UINT32)(RV_X(*(UINT32 *)RiscvHi20Targ, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value = Value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)RiscvHi20Targ = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)RiscvHi20Targ, 0, 12));
+ *(UINT32 *)Targ = (RV_X (Value, 0, 12) << 20) | \
+ (RV_X (*(UINT32 *)Targ, 0, 20));
+ }
+ RiscvHi20Sym = NULL;
+ RiscvHi20Targ = NULL;
+ RiscvSymSecIndex = 0;
+ break;
+
+ case R_RISCV_LO12_S:
+ if (RiscvHi20Sym == SymShdr && RiscvHi20Targ != NULL && RiscvSymSecIndex == Sym->st_shndx && RiscvSymSecIndex != 0) {
+ Value = (UINT32)(RV_X(*(UINT32 *)RiscvHi20Targ, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 7, 5) | (RV_X(*(UINT32 *)Targ, 25, 7) << 5));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value = Value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)RiscvHi20Targ = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)RiscvHi20Targ, 0, 12));
+
+ Value2 = *(UINT32 *)Targ & 0x01fff07f;
+ Value &= RISCV_IMM_REACH - 1;
+ *(UINT32 *)Targ = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));
+ }
+ RiscvHi20Sym = NULL;
+ RiscvHi20Targ = NULL;
+ RiscvSymSecIndex = 0;
+ break;
+
+ case R_RISCV_PCREL_HI20:
+ RiscvHi20Targ = Targ;
+ RiscvHi20Sym = SymShdr;
+ RiscvSymSecIndex = Sym->st_shndx;
+
+ Value = (UINT32)(RV_X(*(UINT32 *)RiscvHi20Targ, 12, 20));
+ //printf("PCREL_HI20 Sym:[%s] value:0x%x SymShdr->sh_addr:0x%lx mCoffSectionOffset:%x \n", GetSymName(Sym), Value, SymShdr->sh_addr, mCoffSectionsOffset[Sym->st_shndx]);
+ break;
+ case R_RISCV_PCREL_LO12_I:
+ if (RiscvHi20Targ != NULL && RiscvHi20Sym != NULL && RiscvSymSecIndex != 0) {
+ int i;
+ Value2 = (UINT32)(RV_X(*(UINT32 *)RiscvHi20Targ, 12, 20));
+ Value = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12));
+ if(Value & (RISCV_IMM_REACH/2)) {
+ Value |= ~(RISCV_IMM_REACH-1);
+ }
+ //printf("PCREL_LO12_I Sym:[%s] value:0x%x SymShdr->sh_addr:0x%lx mCoffSectionOffset:%x \n", GetSymName(Sym), Value, SymShdr->sh_addr, mCoffSectionsOffset[Sym->st_shndx]);
+ Value = Value - RiscvHi20Sym->sh_addr + mCoffSectionsOffset[RiscvSymSecIndex];
+ if(-2048 > (INT32)Value) {
+ i = (-Value / 4096);
+ //Error (NULL, 0, 3000, "Invalid", "WriteSections64(): PCREL_LO12_I relocation out of range. %d i=%d", Value, i);
+ printf("WriteSections64(): PCREL_LO12_I relocation out of range. Value:%d Value2:%d i=%d\n", Value, Value2, i);
+ Value2 -= i;
+ Value += 4096 * i;
+ if(-2048 > (INT32)Value) {
+ Value2 -= 1;
+ Value += 4096;
+ }
+ }
+ else if( 2047 < (INT32)Value) {
+ i = (Value / 4096);
+ //Error (NULL, 0, 3000, "Invalid", "WriteSections64(): PCREL_LO12_I relocation out of range. %d i=%d", Value, i);
+ printf("WriteSections64(): PCREL_LO12_I relocation out of range. Value:%d Value2:%d i=%d\n", Value, Value2, i);
+ Value2 += i;
+ Value -= 4096 * i;
+ if(2047 < (INT32)Value) {
+ Value2 += 1;
+ Value -= 4096;
+ }
+ }
+
+ *(UINT32 *)Targ = (RV_X(Value, 0, 12) << 20) | (RV_X(*(UINT32*)Targ, 0, 20));
+ *(UINT32 *)RiscvHi20Targ = (RV_X(Value2, 0, 20)<<12) | (RV_X(*(UINT32 *)RiscvHi20Targ, 0, 12));
+ //printf("PCREL_LO12_I Sym:[%s] relocated value:0x%x(%d) value2:0x%x(%d) SymShdr->sh_addr:0x%lx mCoffSectionOffset:%x \n", GetSymName(Sym), Value, Value, Value2, Value2, SymShdr->sh_addr, mCoffSectionsOffset[Sym->st_shndx]);
+ }
+ RiscvHi20Sym = NULL;
+ RiscvHi20Targ = NULL;
+ RiscvSymSecIndex = 0;
+ break;
+
+ case R_RISCV_ADD64:
+ case R_RISCV_SUB64:
+ case R_RISCV_ADD32:
+ case R_RISCV_SUB32:
+ case R_RISCV_BRANCH:
+ case R_RISCV_JAL:
+ case R_RISCV_GPREL_I:
+ case R_RISCV_GPREL_S:
+ case R_RISCV_CALL:
+ case R_RISCV_RVC_BRANCH:
+ case R_RISCV_RVC_JUMP:
+ case R_RISCV_RELAX:
+ case R_RISCV_SUB6:
+ case R_RISCV_SET6:
+ case R_RISCV_SET8:
+ case R_RISCV_SET16:
+ case R_RISCV_SET32:
+ break;
+
+ default:
+ Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
} else {
Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");
}
@@ -1133,6 +1283,7 @@ WriteRelocations64 (
UINT32 Index;
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
EFI_IMAGE_DATA_DIRECTORY *Dir;
+ UINT32 RiscVRelType;

for (Index = 0; Index < mEhdr->e_shnum; Index++) {
Elf_Shdr *RelShdr = GetShdrByIndex(Index);
@@ -1237,8 +1388,110 @@ WriteRelocations64 (
default:
Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
}
+ } else if (mEhdr->e_machine == EM_RISCV64) {
+ RiscVRelType = ELF_R_TYPE(Rel->r_info);
+ switch (RiscVRelType) {
+ case R_RISCV_NONE:
+ break;
+
+ case R_RISCV_32:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_HIGHLOW);
+ break;
+
+ case R_RISCV_64:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_DIR64);
+ break;
+
+ case R_RISCV_HI20:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_RISCV_HI20);
+ break;
+
+ case R_RISCV_LO12_I:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_RISCV_LOW12I);
+ break;
+
+ case R_RISCV_LO12_S:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_RISCV_LOW12S);
+ break;
+
+ case R_RISCV_ADD64:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_SUB64:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_ADD32:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_SUB32:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_BRANCH:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_JAL:
+ CoffAddFixup(
+ (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr)),
+ EFI_IMAGE_REL_BASED_ABSOLUTE);
+ break;
+
+ case R_RISCV_GPREL_I:
+ case R_RISCV_GPREL_S:
+ case R_RISCV_CALL:
+ case R_RISCV_RVC_BRANCH:
+ case R_RISCV_RVC_JUMP:
+ case R_RISCV_RELAX:
+ case R_RISCV_SUB6:
+ case R_RISCV_SET6:
+ case R_RISCV_SET8:
+ case R_RISCV_SET16:
+ case R_RISCV_SET32:
+ case R_RISCV_PCREL_HI20:
+ case R_RISCV_PCREL_LO12_I:
+ break;
+
+ default:
+ printf ("Unsupported RISCV64 ELF relocation type 0x%x, offset: %lx\n", RiscVRelType, Rel->r_offset);
+ Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
+ }
} else {
- Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);
+ Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);
}
}
if (mEhdr->e_machine == EM_X86_64 && RelShdr->sh_info == mGOTShindex) {
diff --git a/BaseTools/Source/C/GenFw/elf_common.h b/BaseTools/Source/C/GenFw/elf_common.h
index 15c9e33..5f286cc 100644
--- a/BaseTools/Source/C/GenFw/elf_common.h
+++ b/BaseTools/Source/C/GenFw/elf_common.h
@@ -3,6 +3,7 @@ Ported ELF include files from FreeBSD

Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+Portion Copyright (c) 2016 - 2017, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent


@@ -178,6 +179,9 @@ typedef struct {
#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
#define EM_AARCH64 183 /* ARM 64bit Architecture */
+#define EM_RISCV64 243 /* 64bit RISC-V Architecture */
+#define EM_RISCV 244 /* 32bit RISC-V Architecture */
+#define EM_RISCV128 245 /* 128bit RISC-V Architecture */

/* Non-standard or deprecated. */
#define EM_486 6 /* Intel i486. */
@@ -979,5 +983,64 @@ typedef struct {
#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable. */
#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable. */

+/*
+ * RISC-V relocation types
+ */
+
+/* Relocation types used by the dynamic linker */
+#define R_RISCV_NONE 0
+#define R_RISCV_32 1
+#define R_RISCV_64 2
+#define R_RISCV_RELATIVE 3
+#define R_RISCV_COPY 4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD32 6
+#define R_RISCV_TLS_DTPMOD64 7
+#define R_RISCV_TLS_DTPREL32 8
+#define R_RISCV_TLS_DTPREL64 9
+#define R_RISCV_TLS_TPREL32 10
+#define R_RISCV_TLS_TPREL64 11

+/* Relocation types not used by the dynamic linker */
+#define R_RISCV_BRANCH 16
+#define R_RISCV_JAL 17
+#define R_RISCV_CALL 18
+#define R_RISCV_CALL_PLT 19
+#define R_RISCV_GOT_HI20 20
+#define R_RISCV_TLS_GOT_HI20 21
+#define R_RISCV_TLS_GD_HI20 22
+#define R_RISCV_PCREL_HI20 23
+#define R_RISCV_PCREL_LO12_I 24
+#define R_RISCV_PCREL_LO12_S 25
+#define R_RISCV_HI20 26
+#define R_RISCV_LO12_I 27
+#define R_RISCV_LO12_S 28
+#define R_RISCV_TPREL_HI20 29
+#define R_RISCV_TPREL_LO12_I 30
+#define R_RISCV_TPREL_LO12_S 31
+#define R_RISCV_TPREL_ADD 32
+#define R_RISCV_ADD8 33
+#define R_RISCV_ADD16 34
+#define R_RISCV_ADD32 35
+#define R_RISCV_ADD64 36
+#define R_RISCV_SUB8 37
+#define R_RISCV_SUB16 38
+#define R_RISCV_SUB32 39
+#define R_RISCV_SUB64 40
+#define R_RISCV_GNU_VTINHERIT 41
+#define R_RISCV_GNU_VTENTRY 42
+#define R_RISCV_ALIGN 43
+#define R_RISCV_RVC_BRANCH 44
+#define R_RISCV_RVC_JUMP 45
+#define R_RISCV_RVC_LUI 46
+#define R_RISCV_GPREL_I 47
+#define R_RISCV_GPREL_S 48
+#define R_RISCV_TPREL_I 49
+#define R_RISCV_TPREL_S 50
+#define R_RISCV_RELAX 51
+#define R_RISCV_SUB6 52
+#define R_RISCV_SET6 53
+#define R_RISCV_SET8 54
+#define R_RISCV_SET16 55
+#define R_RISCV_SET32 56
#endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
index 44037d1..4edf2d4 100644
--- a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
+++ b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h
@@ -6,6 +6,7 @@

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

@@ -41,6 +42,9 @@
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only
#define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/Thumb 2 Little Endian
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Little Endian
+#define IMAGE_FILE_MACHINE_RISCV32 0x5032 // 32bit RISC-V ISA
+#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // 64bit RISC-V ISA
+#define IMAGE_FILE_MACHINE_RISCV128 0x5128 // 128bit RISC-V ISA

//
// Support old names for backward compatible
@@ -50,6 +54,9 @@
#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64
#define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT
#define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64
+#define EFI_IMAGE_MACHINE_RISCV32 IMAGE_FILE_MACHINE_RISCV32
+#define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64
+#define EFI_IMAGE_MACHINE_RISCV128 IMAGE_FILE_MACHINE_RISCV128

#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ
#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE
@@ -504,7 +511,10 @@ typedef struct {
#define EFI_IMAGE_REL_BASED_HIGHADJ 4
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
+#define EFI_IMAGE_REL_BASED_RISCV_HI20 5
#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
+#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7
+#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8
#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
#define EFI_IMAGE_REL_BASED_DIR64 10

diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py
index 8ae1bd2..2ee6b37 100644
--- a/BaseTools/Source/Python/Common/DataType.py
+++ b/BaseTools/Source/Python/Common/DataType.py
@@ -1,535 +1,540 @@
Something has clearly gone wrong here, presumably something to do with
CRLF line endings vs LF line endings. Please address for v2.

/
Leif

-## @file
-# This file is used to define common static strings used by INF/DEC/DSC files
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-
-##
-# Common Definitions
-#
-TAB_SPLIT = '.'
-TAB_COMMENT_EDK_START = '/*'
-TAB_COMMENT_EDK_END = '*/'
-TAB_COMMENT_EDK_SPLIT = '//'
-TAB_COMMENT_SPLIT = '#'
-TAB_SPECIAL_COMMENT = '##'
-TAB_EQUAL_SPLIT = '='
-TAB_VALUE_SPLIT = '|'
-TAB_COMMA_SPLIT = ','
-TAB_SPACE_SPLIT = ' '
-TAB_SEMI_COLON_SPLIT = ';'
-TAB_SECTION_START = '['
-TAB_SECTION_END = ']'
-TAB_OPTION_START = '<'
-TAB_OPTION_END = '>'
-TAB_SLASH = '\\'
-TAB_BACK_SLASH = '/'
-TAB_STAR = '*'
-TAB_LINE_BREAK = '\n'
-TAB_PRINTCHAR_VT = '\x0b'
-TAB_PRINTCHAR_BS = '\b'
-TAB_PRINTCHAR_NUL = '\0'
-TAB_UINT8 = 'UINT8'
-TAB_UINT16 = 'UINT16'
-TAB_UINT32 = 'UINT32'
-TAB_UINT64 = 'UINT64'
-TAB_VOID = 'VOID*'
-TAB_GUID = 'GUID'
-
-TAB_PCD_CLEAN_NUMERIC_TYPES = {TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64}
-TAB_PCD_NUMERIC_TYPES = {TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN'}
-TAB_PCD_NUMERIC_TYPES_VOID = {TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN', TAB_VOID}
-
-TAB_WORKSPACE = '$(WORKSPACE)'
-TAB_FV_DIRECTORY = 'FV'
-
-TAB_ARCH_NULL = ''
-TAB_ARCH_COMMON = 'COMMON'
-TAB_ARCH_IA32 = 'IA32'
-TAB_ARCH_X64 = 'X64'
-TAB_ARCH_ARM = 'ARM'
-TAB_ARCH_EBC = 'EBC'
-TAB_ARCH_AARCH64 = 'AARCH64'
-
-ARCH_SET_FULL = {TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_ARM, TAB_ARCH_EBC, TAB_ARCH_AARCH64, TAB_ARCH_COMMON}
-
-SUP_MODULE_BASE = 'BASE'
-SUP_MODULE_SEC = 'SEC'
-SUP_MODULE_PEI_CORE = 'PEI_CORE'
-SUP_MODULE_PEIM = 'PEIM'
-SUP_MODULE_DXE_CORE = 'DXE_CORE'
-SUP_MODULE_DXE_DRIVER = 'DXE_DRIVER'
-SUP_MODULE_DXE_RUNTIME_DRIVER = 'DXE_RUNTIME_DRIVER'
-SUP_MODULE_DXE_SAL_DRIVER = 'DXE_SAL_DRIVER'
-SUP_MODULE_DXE_SMM_DRIVER = 'DXE_SMM_DRIVER'
-SUP_MODULE_UEFI_DRIVER = 'UEFI_DRIVER'
-SUP_MODULE_UEFI_APPLICATION = 'UEFI_APPLICATION'
-SUP_MODULE_USER_DEFINED = 'USER_DEFINED'
-SUP_MODULE_HOST_APPLICATION = 'HOST_APPLICATION'
-SUP_MODULE_SMM_CORE = 'SMM_CORE'
-SUP_MODULE_MM_STANDALONE = 'MM_STANDALONE'
-SUP_MODULE_MM_CORE_STANDALONE = 'MM_CORE_STANDALONE'
-
-SUP_MODULE_LIST = [SUP_MODULE_BASE, SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, \
- SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_UEFI_DRIVER, \
- SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, SUP_MODULE_HOST_APPLICATION, SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE, SUP_MODULE_MM_CORE_STANDALONE]
-SUP_MODULE_LIST_STRING = TAB_VALUE_SPLIT.join(SUP_MODULE_LIST)
-SUP_MODULE_SET_PEI = {SUP_MODULE_PEIM, SUP_MODULE_PEI_CORE}
-
-EDK_COMPONENT_TYPE_LIBRARY = 'LIBRARY'
-EDK_COMPONENT_TYPE_SECURITY_CORE = 'SECURITY_CORE'
-EDK_COMPONENT_TYPE_PEI_CORE = SUP_MODULE_PEI_CORE
-EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER = 'COMBINED_PEIM_DRIVER'
-EDK_COMPONENT_TYPE_PIC_PEIM = 'PIC_PEIM'
-EDK_COMPONENT_TYPE_RELOCATABLE_PEIM = 'RELOCATABLE_PEIM'
-EDK_COMPONENT_TYPE_BS_DRIVER = 'BS_DRIVER'
-EDK_COMPONENT_TYPE_RT_DRIVER = 'RT_DRIVER'
-EDK_COMPONENT_TYPE_SAL_RT_DRIVER = 'SAL_RT_DRIVER'
-EDK_COMPONENT_TYPE_APPLICATION = 'APPLICATION'
-EDK_NAME = 'EDK'
-EDKII_NAME = 'EDKII'
-MSG_EDKII_MAIL_ADDR = 'devel@edk2.groups.io'
-
-COMPONENT_TO_MODULE_MAP_DICT = {
- EDK_COMPONENT_TYPE_LIBRARY : SUP_MODULE_BASE,
- EDK_COMPONENT_TYPE_SECURITY_CORE : SUP_MODULE_SEC,
- EDK_COMPONENT_TYPE_PEI_CORE : SUP_MODULE_PEI_CORE,
- EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER : SUP_MODULE_PEIM,
- EDK_COMPONENT_TYPE_PIC_PEIM : SUP_MODULE_PEIM,
- EDK_COMPONENT_TYPE_RELOCATABLE_PEIM : SUP_MODULE_PEIM,
- "PE32_PEIM" : SUP_MODULE_PEIM,
- EDK_COMPONENT_TYPE_BS_DRIVER : SUP_MODULE_DXE_DRIVER,
- EDK_COMPONENT_TYPE_RT_DRIVER : SUP_MODULE_DXE_RUNTIME_DRIVER,
- EDK_COMPONENT_TYPE_SAL_RT_DRIVER : SUP_MODULE_DXE_SAL_DRIVER,
- EDK_COMPONENT_TYPE_APPLICATION : SUP_MODULE_UEFI_APPLICATION,
- "LOGO" : SUP_MODULE_BASE,
-}
-
-BINARY_FILE_TYPE_FW = 'FW'
-BINARY_FILE_TYPE_GUID = 'GUID'
-BINARY_FILE_TYPE_PREEFORM = 'PREEFORM'
-BINARY_FILE_TYPE_UEFI_APP = 'UEFI_APP'
-BINARY_FILE_TYPE_UNI_UI = 'UNI_UI'
-BINARY_FILE_TYPE_UNI_VER = 'UNI_VER'
-BINARY_FILE_TYPE_LIB = 'LIB'
-BINARY_FILE_TYPE_PE32 = 'PE32'
-BINARY_FILE_TYPE_PIC = 'PIC'
-BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX'
-BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX'
-BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX'
-BINARY_FILE_TYPE_TE = 'TE'
-BINARY_FILE_TYPE_VER = 'VER'
-BINARY_FILE_TYPE_UI = 'UI'
-BINARY_FILE_TYPE_BIN = 'BIN'
-BINARY_FILE_TYPE_FV = 'FV'
-BINARY_FILE_TYPE_RAW = 'RAW_BINARY'
-
-PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS = 'LIBRARY_CLASS'
-PLATFORM_COMPONENT_TYPE_MODULE = 'MODULE'
-
-TAB_SOURCES = 'Sources'
-TAB_SOURCES_COMMON = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_SOURCES_IA32 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_IA32
-TAB_SOURCES_X64 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_X64
-TAB_SOURCES_ARM = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_ARM
-TAB_SOURCES_EBC = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_EBC
-TAB_SOURCES_AARCH64 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_BINARIES = 'Binaries'
-TAB_BINARIES_COMMON = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_BINARIES_IA32 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_IA32
-TAB_BINARIES_X64 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_X64
-TAB_BINARIES_ARM = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_ARM
-TAB_BINARIES_EBC = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_EBC
-TAB_BINARIES_AARCH64 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_INCLUDES = 'Includes'
-TAB_INCLUDES_COMMON = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_INCLUDES_IA32 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_IA32
-TAB_INCLUDES_X64 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_X64
-TAB_INCLUDES_ARM = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_ARM
-TAB_INCLUDES_EBC = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_EBC
-TAB_INCLUDES_AARCH64 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_GUIDS = 'Guids'
-TAB_GUIDS_COMMON = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_GUIDS_IA32 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_IA32
-TAB_GUIDS_X64 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_X64
-TAB_GUIDS_ARM = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_ARM
-TAB_GUIDS_EBC = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_EBC
-TAB_GUIDS_AARCH64 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PROTOCOLS = 'Protocols'
-TAB_PROTOCOLS_COMMON = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_PROTOCOLS_IA32 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_IA32
-TAB_PROTOCOLS_X64 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_X64
-TAB_PROTOCOLS_ARM = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_ARM
-TAB_PROTOCOLS_EBC = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_EBC
-TAB_PROTOCOLS_AARCH64 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PPIS = 'Ppis'
-TAB_PPIS_COMMON = TAB_PPIS + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_PPIS_IA32 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_IA32
-TAB_PPIS_X64 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_X64
-TAB_PPIS_ARM = TAB_PPIS + TAB_SPLIT + TAB_ARCH_ARM
-TAB_PPIS_EBC = TAB_PPIS + TAB_SPLIT + TAB_ARCH_EBC
-TAB_PPIS_AARCH64 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_LIBRARY_CLASSES = 'LibraryClasses'
-TAB_LIBRARY_CLASSES_COMMON = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_LIBRARY_CLASSES_IA32 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_IA32
-TAB_LIBRARY_CLASSES_X64 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_X64
-TAB_LIBRARY_CLASSES_ARM = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_ARM
-TAB_LIBRARY_CLASSES_EBC = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_EBC
-TAB_LIBRARY_CLASSES_AARCH64 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PACKAGES = 'Packages'
-TAB_PACKAGES_COMMON = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_PACKAGES_IA32 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_IA32
-TAB_PACKAGES_X64 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_X64
-TAB_PACKAGES_ARM = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_ARM
-TAB_PACKAGES_EBC = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_EBC
-TAB_PACKAGES_AARCH64 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PCDS = 'Pcds'
-TAB_PCDS_FIXED_AT_BUILD = 'FixedAtBuild'
-TAB_PCDS_PATCHABLE_IN_MODULE = 'PatchableInModule'
-TAB_PCDS_FEATURE_FLAG = 'FeatureFlag'
-TAB_PCDS_DYNAMIC_EX = 'DynamicEx'
-TAB_PCDS_DYNAMIC_EX_DEFAULT = 'DynamicExDefault'
-TAB_PCDS_DYNAMIC_EX_VPD = 'DynamicExVpd'
-TAB_PCDS_DYNAMIC_EX_HII = 'DynamicExHii'
-TAB_PCDS_DYNAMIC = 'Dynamic'
-TAB_PCDS_DYNAMIC_DEFAULT = 'DynamicDefault'
-TAB_PCDS_DYNAMIC_VPD = 'DynamicVpd'
-TAB_PCDS_DYNAMIC_HII = 'DynamicHii'
-
-PCD_DYNAMIC_TYPE_SET = {TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII}
-PCD_DYNAMIC_EX_TYPE_SET = {TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII}
-
-# leave as a list for order
-PCD_TYPE_LIST = [TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX]
-
-TAB_PCDS_FIXED_AT_BUILD_NULL = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD
-TAB_PCDS_FIXED_AT_BUILD_COMMON = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_PCDS_FIXED_AT_BUILD_IA32 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_IA32
-TAB_PCDS_FIXED_AT_BUILD_X64 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_X64
-TAB_PCDS_FIXED_AT_BUILD_ARM = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_ARM
-TAB_PCDS_FIXED_AT_BUILD_EBC = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_EBC
-TAB_PCDS_FIXED_AT_BUILD_AARCH64 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PCDS_PATCHABLE_IN_MODULE_NULL = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE
-TAB_PCDS_PATCHABLE_IN_MODULE_COMMON = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_PCDS_PATCHABLE_IN_MODULE_IA32 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_IA32
-TAB_PCDS_PATCHABLE_IN_MODULE_X64 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_X64
-TAB_PCDS_PATCHABLE_IN_MODULE_ARM = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_ARM
-TAB_PCDS_PATCHABLE_IN_MODULE_EBC = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_EBC
-TAB_PCDS_PATCHABLE_IN_MODULE_AARCH64 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PCDS_FEATURE_FLAG_NULL = TAB_PCDS + TAB_PCDS_FEATURE_FLAG
-TAB_PCDS_FEATURE_FLAG_COMMON = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_PCDS_FEATURE_FLAG_IA32 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_IA32
-TAB_PCDS_FEATURE_FLAG_X64 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_X64
-TAB_PCDS_FEATURE_FLAG_ARM = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_ARM
-TAB_PCDS_FEATURE_FLAG_EBC = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_EBC
-TAB_PCDS_FEATURE_FLAG_AARCH64 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PCDS_DYNAMIC_EX_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX
-TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_DEFAULT
-TAB_PCDS_DYNAMIC_EX_HII_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_HII
-TAB_PCDS_DYNAMIC_EX_VPD_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_VPD
-TAB_PCDS_DYNAMIC_EX_COMMON = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_PCDS_DYNAMIC_EX_IA32 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_IA32
-TAB_PCDS_DYNAMIC_EX_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_X64
-TAB_PCDS_DYNAMIC_EX_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_ARM
-TAB_PCDS_DYNAMIC_EX_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_EBC
-TAB_PCDS_DYNAMIC_EX_AARCH64 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PCDS_DYNAMIC_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC
-TAB_PCDS_DYNAMIC_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_DEFAULT
-TAB_PCDS_DYNAMIC_HII_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_HII
-TAB_PCDS_DYNAMIC_VPD_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_VPD
-TAB_PCDS_DYNAMIC_COMMON = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_PCDS_DYNAMIC_IA32 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_IA32
-TAB_PCDS_DYNAMIC_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_X64
-TAB_PCDS_DYNAMIC_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_ARM
-TAB_PCDS_DYNAMIC_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_EBC
-TAB_PCDS_DYNAMIC_AARCH64 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE = 'PcdLoadFixAddressPeiCodePageNumber'
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE_DATA_TYPE = 'UINT32'
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE = 'PcdLoadFixAddressBootTimeCodePageNumber'
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE_DATA_TYPE = 'UINT32'
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE = 'PcdLoadFixAddressRuntimeCodePageNumber'
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE_DATA_TYPE = 'UINT32'
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE = 'PcdLoadFixAddressSmmCodePageNumber'
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE_DATA_TYPE = 'UINT32'
-TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SET = {TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE, \
- TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE, \
- TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE, \
- TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE}
-
-## The mapping dictionary from datum type to its maximum number.
-MAX_VAL_TYPE = {"BOOLEAN":0x01, TAB_UINT8:0xFF, TAB_UINT16:0xFFFF, TAB_UINT32:0xFFFFFFFF, TAB_UINT64:0xFFFFFFFFFFFFFFFF}
-## The mapping dictionary from datum type to size string.
-MAX_SIZE_TYPE = {"BOOLEAN":1, TAB_UINT8:1, TAB_UINT16:2, TAB_UINT32:4, TAB_UINT64:8}
-
-TAB_DEPEX = 'Depex'
-TAB_DEPEX_COMMON = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_DEPEX_IA32 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_IA32
-TAB_DEPEX_X64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_X64
-TAB_DEPEX_ARM = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_ARM
-TAB_DEPEX_EBC = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_EBC
-TAB_DEPEX_AARCH64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_SKUIDS = 'SkuIds'
-TAB_DEFAULT_STORES = 'DefaultStores'
-TAB_DEFAULT_STORES_DEFAULT = 'STANDARD'
-
-TAB_LIBRARIES = 'Libraries'
-TAB_LIBRARIES_COMMON = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_LIBRARIES_IA32 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_IA32
-TAB_LIBRARIES_X64 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_X64
-TAB_LIBRARIES_ARM = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_ARM
-TAB_LIBRARIES_EBC = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_EBC
-TAB_LIBRARIES_AARCH64 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_COMPONENTS = 'Components'
-TAB_COMPONENTS_COMMON = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_COMMON
-TAB_COMPONENTS_IA32 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_IA32
-TAB_COMPONENTS_X64 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_X64
-TAB_COMPONENTS_ARM = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_ARM
-TAB_COMPONENTS_EBC = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_EBC
-TAB_COMPONENTS_AARCH64 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_AARCH64
-
-TAB_BUILD_OPTIONS = 'BuildOptions'
-
-TAB_DEFINE = 'DEFINE'
-TAB_NMAKE = 'Nmake'
-TAB_USER_EXTENSIONS = 'UserExtensions'
-TAB_INCLUDE = '!include'
-TAB_DEFAULT = 'DEFAULT'
-TAB_COMMON = 'COMMON'
-
-#
-# Common Define
-#
-TAB_COMMON_DEFINES = 'Defines'
-
-#
-# Inf Definitions
-#
-TAB_INF_DEFINES = TAB_COMMON_DEFINES
-TAB_INF_DEFINES_INF_VERSION = 'INF_VERSION'
-TAB_INF_DEFINES_BASE_NAME = 'BASE_NAME'
-TAB_INF_DEFINES_FILE_GUID = 'FILE_GUID'
-TAB_INF_DEFINES_MODULE_TYPE = 'MODULE_TYPE'
-TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION = 'EFI_SPECIFICATION_VERSION'
-TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION = 'UEFI_SPECIFICATION_VERSION'
-TAB_INF_DEFINES_PI_SPECIFICATION_VERSION = 'PI_SPECIFICATION_VERSION'
-TAB_INF_DEFINES_EDK_RELEASE_VERSION = 'EDK_RELEASE_VERSION'
-TAB_INF_DEFINES_BINARY_MODULE = 'BINARY_MODULE'
-TAB_INF_DEFINES_LIBRARY_CLASS = 'LIBRARY_CLASS'
-TAB_INF_DEFINES_COMPONENT_TYPE = 'COMPONENT_TYPE'
-TAB_INF_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
-TAB_INF_DEFINES_DPX_SOURCE = 'DPX_SOURCE'
-TAB_INF_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
-TAB_INF_DEFINES_BUILD_TYPE = 'BUILD_TYPE'
-TAB_INF_DEFINES_FFS_EXT = 'FFS_EXT'
-TAB_INF_DEFINES_FV_EXT = 'FV_EXT'
-TAB_INF_DEFINES_SOURCE_FV = 'SOURCE_FV'
-TAB_INF_DEFINES_VERSION_NUMBER = 'VERSION_NUMBER'
-TAB_INF_DEFINES_VERSION = 'VERSION' # for Edk inf, the same as VERSION_NUMBER
-TAB_INF_DEFINES_VERSION_STRING = 'VERSION_STRING'
-TAB_INF_DEFINES_PCD_IS_DRIVER = 'PCD_IS_DRIVER'
-TAB_INF_DEFINES_TIANO_EDK_FLASHMAP_H = 'TIANO_EDK_FLASHMAP_H'
-TAB_INF_DEFINES_ENTRY_POINT = 'ENTRY_POINT'
-TAB_INF_DEFINES_UNLOAD_IMAGE = 'UNLOAD_IMAGE'
-TAB_INF_DEFINES_CONSTRUCTOR = 'CONSTRUCTOR'
-TAB_INF_DEFINES_DESTRUCTOR = 'DESTRUCTOR'
-TAB_INF_DEFINES_DEFINE = 'DEFINE'
-TAB_INF_DEFINES_SPEC = 'SPEC'
-TAB_INF_DEFINES_CUSTOM_MAKEFILE = 'CUSTOM_MAKEFILE'
-TAB_INF_DEFINES_MACRO = '__MACROS__'
-TAB_INF_DEFINES_SHADOW = 'SHADOW'
-TAB_INF_FIXED_PCD = 'FixedPcd'
-TAB_INF_FEATURE_PCD = 'FeaturePcd'
-TAB_INF_PATCH_PCD = 'PatchPcd'
-TAB_INF_PCD = 'Pcd'
-TAB_INF_PCD_EX = 'PcdEx'
-TAB_INF_USAGE_PRO = 'PRODUCES'
-TAB_INF_USAGE_SOME_PRO = 'SOMETIMES_PRODUCES'
-TAB_INF_USAGE_CON = 'CONSUMES'
-TAB_INF_USAGE_SOME_CON = 'SOMETIMES_CONSUMES'
-TAB_INF_USAGE_NOTIFY = 'NOTIFY'
-TAB_INF_USAGE_TO_START = 'TO_START'
-TAB_INF_USAGE_BY_START = 'BY_START'
-TAB_INF_GUIDTYPE_EVENT = 'Event'
-TAB_INF_GUIDTYPE_FILE = 'File'
-TAB_INF_GUIDTYPE_FV = 'FV'
-TAB_INF_GUIDTYPE_GUID = 'GUID'
-TAB_INF_GUIDTYPE_HII = 'HII'
-TAB_INF_GUIDTYPE_HOB = 'HOB'
-TAB_INF_GUIDTYPE_ST = 'SystemTable'
-TAB_INF_GUIDTYPE_TSG = 'TokenSpaceGuid'
-TAB_INF_GUIDTYPE_VAR = 'Variable'
-TAB_INF_GUIDTYPE_PROTOCOL = 'PROTOCOL'
-TAB_INF_GUIDTYPE_PPI = 'PPI'
-TAB_INF_USAGE_UNDEFINED = 'UNDEFINED'
-
-#
-# Dec Definitions
-#
-TAB_DEC_DEFINES = TAB_COMMON_DEFINES
-TAB_DEC_DEFINES_DEC_SPECIFICATION = 'DEC_SPECIFICATION'
-TAB_DEC_DEFINES_PACKAGE_NAME = 'PACKAGE_NAME'
-TAB_DEC_DEFINES_PACKAGE_GUID = 'PACKAGE_GUID'
-TAB_DEC_DEFINES_PACKAGE_VERSION = 'PACKAGE_VERSION'
-TAB_DEC_DEFINES_PKG_UNI_FILE = 'PKG_UNI_FILE'
-
-#
-# Dsc Definitions
-#
-TAB_DSC_DEFINES = TAB_COMMON_DEFINES
-TAB_DSC_DEFINES_PLATFORM_NAME = 'PLATFORM_NAME'
-TAB_DSC_DEFINES_PLATFORM_GUID = 'PLATFORM_GUID'
-TAB_DSC_DEFINES_PLATFORM_VERSION = 'PLATFORM_VERSION'
-TAB_DSC_DEFINES_DSC_SPECIFICATION = 'DSC_SPECIFICATION'
-TAB_DSC_DEFINES_OUTPUT_DIRECTORY = 'OUTPUT_DIRECTORY'
-TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES = 'SUPPORTED_ARCHITECTURES'
-TAB_DSC_DEFINES_BUILD_TARGETS = 'BUILD_TARGETS'
-TAB_DSC_DEFINES_SKUID_IDENTIFIER = 'SKUID_IDENTIFIER'
-TAB_DSC_DEFINES_PCD_INFO_GENERATION = 'PCD_INFO_GENERATION'
-TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION = 'PCD_VAR_CHECK_GENERATION'
-TAB_DSC_DEFINES_FLASH_DEFINITION = 'FLASH_DEFINITION'
-TAB_DSC_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
-TAB_DSC_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
-TAB_DSC_DEFINES_BS_BASE_ADDRESS = 'BsBaseAddress'
-TAB_DSC_DEFINES_RT_BASE_ADDRESS = 'RtBaseAddress'
-TAB_DSC_DEFINES_RFC_LANGUAGES = 'RFC_LANGUAGES'
-TAB_DSC_DEFINES_ISO_LANGUAGES = 'ISO_LANGUAGES'
-TAB_DSC_DEFINES_DEFINE = 'DEFINE'
-TAB_DSC_DEFINES_VPD_TOOL_GUID = 'VPD_TOOL_GUID'
-TAB_FIX_LOAD_TOP_MEMORY_ADDRESS = 'FIX_LOAD_TOP_MEMORY_ADDRESS'
-TAB_DSC_DEFINES_EDKGLOBAL = 'EDK_GLOBAL'
-TAB_DSC_PREBUILD = 'PREBUILD'
-TAB_DSC_POSTBUILD = 'POSTBUILD'
-#
-# TargetTxt Definitions
-#
-TAB_TAT_DEFINES_ACTIVE_PLATFORM = 'ACTIVE_PLATFORM'
-TAB_TAT_DEFINES_ACTIVE_MODULE = 'ACTIVE_MODULE'
-TAB_TAT_DEFINES_TOOL_CHAIN_CONF = 'TOOL_CHAIN_CONF'
-TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER = 'MAX_CONCURRENT_THREAD_NUMBER'
-TAB_TAT_DEFINES_TARGET = 'TARGET'
-TAB_TAT_DEFINES_TOOL_CHAIN_TAG = 'TOOL_CHAIN_TAG'
-TAB_TAT_DEFINES_TARGET_ARCH = 'TARGET_ARCH'
-TAB_TAT_DEFINES_BUILD_RULE_CONF = "BUILD_RULE_CONF"
-
-#
-# ToolDef Definitions
-#
-TAB_TOD_DEFINES_TARGET = 'TARGET'
-TAB_TOD_DEFINES_TOOL_CHAIN_TAG = 'TOOL_CHAIN_TAG'
-TAB_TOD_DEFINES_TARGET_ARCH = 'TARGET_ARCH'
-TAB_TOD_DEFINES_COMMAND_TYPE = 'COMMAND_TYPE'
-TAB_TOD_DEFINES_FAMILY = 'FAMILY'
-TAB_TOD_DEFINES_BUILDRULEFAMILY = 'BUILDRULEFAMILY'
-TAB_TOD_DEFINES_BUILDRULEORDER = 'BUILDRULEORDER'
-
-#
-# Conditional Statements
-#
-TAB_IF = '!if'
-TAB_END_IF = '!endif'
-TAB_ELSE_IF = '!elseif'
-TAB_ELSE = '!else'
-TAB_IF_DEF = '!ifdef'
-TAB_IF_N_DEF = '!ifndef'
-TAB_IF_EXIST = '!if exist'
-TAB_ERROR = '!error'
-
-#
-# Unknown section
-#
-TAB_UNKNOWN = 'UNKNOWN'
-
-#
-# Build database path
-#
-DATABASE_PATH = ":memory:" #"BuildDatabase.db"
-
-# used by ECC
-MODIFIER_SET = {'IN', 'OUT', 'OPTIONAL', 'UNALIGNED', 'EFI_RUNTIMESERVICE', 'EFI_BOOTSERVICE', 'EFIAPI'}
-
-# Dependency Opcodes
-DEPEX_OPCODE_BEFORE = "BEFORE"
-DEPEX_OPCODE_AFTER = "AFTER"
-DEPEX_OPCODE_PUSH = "PUSH"
-DEPEX_OPCODE_AND = "AND"
-DEPEX_OPCODE_OR = "OR"
-DEPEX_OPCODE_NOT = "NOT"
-DEPEX_OPCODE_END = "END"
-DEPEX_OPCODE_SOR = "SOR"
-DEPEX_OPCODE_TRUE = "TRUE"
-DEPEX_OPCODE_FALSE = "FALSE"
-
-# Dependency Expression
-DEPEX_SUPPORTED_OPCODE_SET = {"BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "END", "SOR", "TRUE", "FALSE", '(', ')'}
-
-TAB_STATIC_LIBRARY = "STATIC-LIBRARY-FILE"
-TAB_DYNAMIC_LIBRARY = "DYNAMIC-LIBRARY-FILE"
-TAB_FRAMEWORK_IMAGE = "EFI-IMAGE-FILE"
-TAB_C_CODE_FILE = "C-CODE-FILE"
-TAB_C_HEADER_FILE = "C-HEADER-FILE"
-TAB_UNICODE_FILE = "UNICODE-TEXT-FILE"
-TAB_IMAGE_FILE = "IMAGE-DEFINITION-FILE"
-TAB_DEPENDENCY_EXPRESSION_FILE = "DEPENDENCY-EXPRESSION-FILE"
-TAB_UNKNOWN_FILE = "UNKNOWN-TYPE-FILE"
-TAB_DEFAULT_BINARY_FILE = "_BINARY_FILE_"
-TAB_OBJECT_FILE = "OBJECT-FILE"
-TAB_VFR_FILE = 'VISUAL-FORM-REPRESENTATION-FILE'
-
-# used by BRG
-TAB_BRG_PCD = 'PCD'
-TAB_BRG_LIBRARY = 'Library'
-
-#
-# Build Rule File Version Definition
-#
-TAB_BUILD_RULE_VERSION = "build_rule_version"
-
-# section name for PCDs
-PCDS_DYNAMIC_DEFAULT = "PcdsDynamicDefault"
-PCDS_DYNAMIC_VPD = "PcdsDynamicVpd"
-PCDS_DYNAMIC_HII = "PcdsDynamicHii"
-PCDS_DYNAMICEX_DEFAULT = "PcdsDynamicExDefault"
-PCDS_DYNAMICEX_VPD = "PcdsDynamicExVpd"
-PCDS_DYNAMICEX_HII = "PcdsDynamicExHii"
-
-SECTIONS_HAVE_ITEM_PCD_SET = {PCDS_DYNAMIC_DEFAULT.upper(), PCDS_DYNAMIC_VPD.upper(), PCDS_DYNAMIC_HII.upper(), \
- PCDS_DYNAMICEX_DEFAULT.upper(), PCDS_DYNAMICEX_VPD.upper(), PCDS_DYNAMICEX_HII.upper()}
-# Section allowed to have items after arch
-SECTIONS_HAVE_ITEM_AFTER_ARCH_SET = {TAB_LIBRARY_CLASSES.upper(), TAB_DEPEX.upper(), TAB_USER_EXTENSIONS.upper(),
- PCDS_DYNAMIC_DEFAULT.upper(),
- PCDS_DYNAMIC_VPD.upper(),
- PCDS_DYNAMIC_HII.upper(),
- PCDS_DYNAMICEX_DEFAULT.upper(),
- PCDS_DYNAMICEX_VPD.upper(),
- PCDS_DYNAMICEX_HII.upper(),
- TAB_BUILD_OPTIONS.upper(),
- TAB_INCLUDES.upper()}
-
-#
-# pack codes as used in PcdDb and elsewhere
-#
-PACK_PATTERN_GUID = '=LHHBBBBBBBB'
-PACK_CODE_BY_SIZE = {8:'=Q',
- 4:'=L',
- 2:'=H',
- 1:'=B',
- 0:'=B',
- 16:""}
-
-TAB_COMPILER_MSFT = 'MSFT'
\ No newline at end of file
+## @file
+# This file is used to define common static strings used by INF/DEC/DSC files
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+# Portions Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+##
+# Common Definitions
+#
+TAB_SPLIT = '.'
+TAB_COMMENT_EDK_START = '/*'
+TAB_COMMENT_EDK_END = '*/'
+TAB_COMMENT_EDK_SPLIT = '//'
+TAB_COMMENT_SPLIT = '#'
+TAB_SPECIAL_COMMENT = '##'
+TAB_EQUAL_SPLIT = '='
+TAB_VALUE_SPLIT = '|'
+TAB_COMMA_SPLIT = ','
+TAB_SPACE_SPLIT = ' '
+TAB_SEMI_COLON_SPLIT = ';'
+TAB_SECTION_START = '['
+TAB_SECTION_END = ']'
+TAB_OPTION_START = '<'
+TAB_OPTION_END = '>'
+TAB_SLASH = '\\'
+TAB_BACK_SLASH = '/'
+TAB_STAR = '*'
+TAB_LINE_BREAK = '\n'
+TAB_PRINTCHAR_VT = '\x0b'
+TAB_PRINTCHAR_BS = '\b'
+TAB_PRINTCHAR_NUL = '\0'
+TAB_UINT8 = 'UINT8'
+TAB_UINT16 = 'UINT16'
+TAB_UINT32 = 'UINT32'
+TAB_UINT64 = 'UINT64'
+TAB_VOID = 'VOID*'
+TAB_GUID = 'GUID'
+
+TAB_PCD_CLEAN_NUMERIC_TYPES = {TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64}
+TAB_PCD_NUMERIC_TYPES = {TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN'}
+TAB_PCD_NUMERIC_TYPES_VOID = {TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN', TAB_VOID}
+
+TAB_WORKSPACE = '$(WORKSPACE)'
+TAB_FV_DIRECTORY = 'FV'
+
+TAB_ARCH_NULL = ''
+TAB_ARCH_COMMON = 'COMMON'
+TAB_ARCH_IA32 = 'IA32'
+TAB_ARCH_X64 = 'X64'
+TAB_ARCH_ARM = 'ARM'
+TAB_ARCH_EBC = 'EBC'
+TAB_ARCH_AARCH64 = 'AARCH64'
+
+TAB_ARCH_RISCV32 = 'RISCV32'
+TAB_ARCH_RISCV64 = 'RISCV64'
+TAB_ARCH_RISCV128 = 'RISCV128'
+
+ARCH_SET_FULL = {TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_ARM, TAB_ARCH_EBC, TAB_ARCH_AARCH64, TAB_ARCH_RISCV32, TAB_ARCH_RISCV64, TAB_ARCH_RISCV128, TAB_ARCH_COMMON}
+
+SUP_MODULE_BASE = 'BASE'
+SUP_MODULE_SEC = 'SEC'
+SUP_MODULE_PEI_CORE = 'PEI_CORE'
+SUP_MODULE_PEIM = 'PEIM'
+SUP_MODULE_DXE_CORE = 'DXE_CORE'
+SUP_MODULE_DXE_DRIVER = 'DXE_DRIVER'
+SUP_MODULE_DXE_RUNTIME_DRIVER = 'DXE_RUNTIME_DRIVER'
+SUP_MODULE_DXE_SAL_DRIVER = 'DXE_SAL_DRIVER'
+SUP_MODULE_DXE_SMM_DRIVER = 'DXE_SMM_DRIVER'
+SUP_MODULE_UEFI_DRIVER = 'UEFI_DRIVER'
+SUP_MODULE_UEFI_APPLICATION = 'UEFI_APPLICATION'
+SUP_MODULE_USER_DEFINED = 'USER_DEFINED'
+SUP_MODULE_HOST_APPLICATION = 'HOST_APPLICATION'
+SUP_MODULE_SMM_CORE = 'SMM_CORE'
+SUP_MODULE_MM_STANDALONE = 'MM_STANDALONE'
+SUP_MODULE_MM_CORE_STANDALONE = 'MM_CORE_STANDALONE'
+
+SUP_MODULE_LIST = [SUP_MODULE_BASE, SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, \
+ SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_UEFI_DRIVER, \
+ SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, SUP_MODULE_HOST_APPLICATION, SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE, SUP_MODULE_MM_CORE_STANDALONE]
+SUP_MODULE_LIST_STRING = TAB_VALUE_SPLIT.join(SUP_MODULE_LIST)
+SUP_MODULE_SET_PEI = {SUP_MODULE_PEIM, SUP_MODULE_PEI_CORE}
+
+EDK_COMPONENT_TYPE_LIBRARY = 'LIBRARY'
+EDK_COMPONENT_TYPE_SECURITY_CORE = 'SECURITY_CORE'
+EDK_COMPONENT_TYPE_PEI_CORE = SUP_MODULE_PEI_CORE
+EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER = 'COMBINED_PEIM_DRIVER'
+EDK_COMPONENT_TYPE_PIC_PEIM = 'PIC_PEIM'
+EDK_COMPONENT_TYPE_RELOCATABLE_PEIM = 'RELOCATABLE_PEIM'
+EDK_COMPONENT_TYPE_BS_DRIVER = 'BS_DRIVER'
+EDK_COMPONENT_TYPE_RT_DRIVER = 'RT_DRIVER'
+EDK_COMPONENT_TYPE_SAL_RT_DRIVER = 'SAL_RT_DRIVER'
+EDK_COMPONENT_TYPE_APPLICATION = 'APPLICATION'
+EDK_NAME = 'EDK'
+EDKII_NAME = 'EDKII'
+MSG_EDKII_MAIL_ADDR = 'devel@edk2.groups.io'
+
+COMPONENT_TO_MODULE_MAP_DICT = {
+ EDK_COMPONENT_TYPE_LIBRARY : SUP_MODULE_BASE,
+ EDK_COMPONENT_TYPE_SECURITY_CORE : SUP_MODULE_SEC,
+ EDK_COMPONENT_TYPE_PEI_CORE : SUP_MODULE_PEI_CORE,
+ EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER : SUP_MODULE_PEIM,
+ EDK_COMPONENT_TYPE_PIC_PEIM : SUP_MODULE_PEIM,
+ EDK_COMPONENT_TYPE_RELOCATABLE_PEIM : SUP_MODULE_PEIM,
+ "PE32_PEIM" : SUP_MODULE_PEIM,
+ EDK_COMPONENT_TYPE_BS_DRIVER : SUP_MODULE_DXE_DRIVER,
+ EDK_COMPONENT_TYPE_RT_DRIVER : SUP_MODULE_DXE_RUNTIME_DRIVER,
+ EDK_COMPONENT_TYPE_SAL_RT_DRIVER : SUP_MODULE_DXE_SAL_DRIVER,
+ EDK_COMPONENT_TYPE_APPLICATION : SUP_MODULE_UEFI_APPLICATION,
+ "LOGO" : SUP_MODULE_BASE,
+}
+
+BINARY_FILE_TYPE_FW = 'FW'
+BINARY_FILE_TYPE_GUID = 'GUID'
+BINARY_FILE_TYPE_PREEFORM = 'PREEFORM'
+BINARY_FILE_TYPE_UEFI_APP = 'UEFI_APP'
+BINARY_FILE_TYPE_UNI_UI = 'UNI_UI'
+BINARY_FILE_TYPE_UNI_VER = 'UNI_VER'
+BINARY_FILE_TYPE_LIB = 'LIB'
+BINARY_FILE_TYPE_PE32 = 'PE32'
+BINARY_FILE_TYPE_PIC = 'PIC'
+BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX'
+BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX'
+BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX'
+BINARY_FILE_TYPE_TE = 'TE'
+BINARY_FILE_TYPE_VER = 'VER'
+BINARY_FILE_TYPE_UI = 'UI'
+BINARY_FILE_TYPE_BIN = 'BIN'
+BINARY_FILE_TYPE_FV = 'FV'
+BINARY_FILE_TYPE_RAW = 'RAW_BINARY'
+
+PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS = 'LIBRARY_CLASS'
+PLATFORM_COMPONENT_TYPE_MODULE = 'MODULE'
+
+TAB_SOURCES = 'Sources'
+TAB_SOURCES_COMMON = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_SOURCES_IA32 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_SOURCES_X64 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_X64
+TAB_SOURCES_ARM = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_SOURCES_EBC = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_EBC
+TAB_SOURCES_AARCH64 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_BINARIES = 'Binaries'
+TAB_BINARIES_COMMON = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_BINARIES_IA32 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_BINARIES_X64 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_X64
+TAB_BINARIES_ARM = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_BINARIES_EBC = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_EBC
+TAB_BINARIES_AARCH64 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_INCLUDES = 'Includes'
+TAB_INCLUDES_COMMON = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_INCLUDES_IA32 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_INCLUDES_X64 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_X64
+TAB_INCLUDES_ARM = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_INCLUDES_EBC = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_EBC
+TAB_INCLUDES_AARCH64 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_GUIDS = 'Guids'
+TAB_GUIDS_COMMON = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_GUIDS_IA32 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_IA32
+TAB_GUIDS_X64 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_X64
+TAB_GUIDS_ARM = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_ARM
+TAB_GUIDS_EBC = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_EBC
+TAB_GUIDS_AARCH64 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PROTOCOLS = 'Protocols'
+TAB_PROTOCOLS_COMMON = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PROTOCOLS_IA32 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PROTOCOLS_X64 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_X64
+TAB_PROTOCOLS_ARM = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PROTOCOLS_EBC = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_EBC
+TAB_PROTOCOLS_AARCH64 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PPIS = 'Ppis'
+TAB_PPIS_COMMON = TAB_PPIS + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PPIS_IA32 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PPIS_X64 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_X64
+TAB_PPIS_ARM = TAB_PPIS + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PPIS_EBC = TAB_PPIS + TAB_SPLIT + TAB_ARCH_EBC
+TAB_PPIS_AARCH64 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_LIBRARY_CLASSES = 'LibraryClasses'
+TAB_LIBRARY_CLASSES_COMMON = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_LIBRARY_CLASSES_IA32 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_LIBRARY_CLASSES_X64 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_X64
+TAB_LIBRARY_CLASSES_ARM = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_LIBRARY_CLASSES_EBC = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_EBC
+TAB_LIBRARY_CLASSES_AARCH64 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PACKAGES = 'Packages'
+TAB_PACKAGES_COMMON = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PACKAGES_IA32 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PACKAGES_X64 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_X64
+TAB_PACKAGES_ARM = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PACKAGES_EBC = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_EBC
+TAB_PACKAGES_AARCH64 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PCDS = 'Pcds'
+TAB_PCDS_FIXED_AT_BUILD = 'FixedAtBuild'
+TAB_PCDS_PATCHABLE_IN_MODULE = 'PatchableInModule'
+TAB_PCDS_FEATURE_FLAG = 'FeatureFlag'
+TAB_PCDS_DYNAMIC_EX = 'DynamicEx'
+TAB_PCDS_DYNAMIC_EX_DEFAULT = 'DynamicExDefault'
+TAB_PCDS_DYNAMIC_EX_VPD = 'DynamicExVpd'
+TAB_PCDS_DYNAMIC_EX_HII = 'DynamicExHii'
+TAB_PCDS_DYNAMIC = 'Dynamic'
+TAB_PCDS_DYNAMIC_DEFAULT = 'DynamicDefault'
+TAB_PCDS_DYNAMIC_VPD = 'DynamicVpd'
+TAB_PCDS_DYNAMIC_HII = 'DynamicHii'
+
+PCD_DYNAMIC_TYPE_SET = {TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII}
+PCD_DYNAMIC_EX_TYPE_SET = {TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII}
+
+# leave as a list for order
+PCD_TYPE_LIST = [TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_PATCHABLE_IN_MODULE, TAB_PCDS_FEATURE_FLAG, TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_EX]
+
+TAB_PCDS_FIXED_AT_BUILD_NULL = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD
+TAB_PCDS_FIXED_AT_BUILD_COMMON = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PCDS_FIXED_AT_BUILD_IA32 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PCDS_FIXED_AT_BUILD_X64 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_X64
+TAB_PCDS_FIXED_AT_BUILD_ARM = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PCDS_FIXED_AT_BUILD_EBC = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_EBC
+TAB_PCDS_FIXED_AT_BUILD_AARCH64 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PCDS_PATCHABLE_IN_MODULE_NULL = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE
+TAB_PCDS_PATCHABLE_IN_MODULE_COMMON = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PCDS_PATCHABLE_IN_MODULE_IA32 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PCDS_PATCHABLE_IN_MODULE_X64 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_X64
+TAB_PCDS_PATCHABLE_IN_MODULE_ARM = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PCDS_PATCHABLE_IN_MODULE_EBC = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_EBC
+TAB_PCDS_PATCHABLE_IN_MODULE_AARCH64 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PCDS_FEATURE_FLAG_NULL = TAB_PCDS + TAB_PCDS_FEATURE_FLAG
+TAB_PCDS_FEATURE_FLAG_COMMON = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PCDS_FEATURE_FLAG_IA32 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PCDS_FEATURE_FLAG_X64 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_X64
+TAB_PCDS_FEATURE_FLAG_ARM = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PCDS_FEATURE_FLAG_EBC = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_EBC
+TAB_PCDS_FEATURE_FLAG_AARCH64 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PCDS_DYNAMIC_EX_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX
+TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_DEFAULT
+TAB_PCDS_DYNAMIC_EX_HII_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_HII
+TAB_PCDS_DYNAMIC_EX_VPD_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_VPD
+TAB_PCDS_DYNAMIC_EX_COMMON = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PCDS_DYNAMIC_EX_IA32 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PCDS_DYNAMIC_EX_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_X64
+TAB_PCDS_DYNAMIC_EX_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PCDS_DYNAMIC_EX_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_EBC
+TAB_PCDS_DYNAMIC_EX_AARCH64 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PCDS_DYNAMIC_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC
+TAB_PCDS_DYNAMIC_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_DEFAULT
+TAB_PCDS_DYNAMIC_HII_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_HII
+TAB_PCDS_DYNAMIC_VPD_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_VPD
+TAB_PCDS_DYNAMIC_COMMON = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PCDS_DYNAMIC_IA32 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PCDS_DYNAMIC_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_X64
+TAB_PCDS_DYNAMIC_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PCDS_DYNAMIC_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_EBC
+TAB_PCDS_DYNAMIC_AARCH64 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE = 'PcdLoadFixAddressPeiCodePageNumber'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE_DATA_TYPE = 'UINT32'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE = 'PcdLoadFixAddressBootTimeCodePageNumber'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE_DATA_TYPE = 'UINT32'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE = 'PcdLoadFixAddressRuntimeCodePageNumber'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE_DATA_TYPE = 'UINT32'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE = 'PcdLoadFixAddressSmmCodePageNumber'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE_DATA_TYPE = 'UINT32'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SET = {TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE, \
+ TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE, \
+ TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE, \
+ TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE}
+
+## The mapping dictionary from datum type to its maximum number.
+MAX_VAL_TYPE = {"BOOLEAN":0x01, TAB_UINT8:0xFF, TAB_UINT16:0xFFFF, TAB_UINT32:0xFFFFFFFF, TAB_UINT64:0xFFFFFFFFFFFFFFFF}
+## The mapping dictionary from datum type to size string.
+MAX_SIZE_TYPE = {"BOOLEAN":1, TAB_UINT8:1, TAB_UINT16:2, TAB_UINT32:4, TAB_UINT64:8}
+
+TAB_DEPEX = 'Depex'
+TAB_DEPEX_COMMON = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_DEPEX_IA32 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_IA32
+TAB_DEPEX_X64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_X64
+TAB_DEPEX_ARM = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_ARM
+TAB_DEPEX_EBC = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_EBC
+TAB_DEPEX_AARCH64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_SKUIDS = 'SkuIds'
+TAB_DEFAULT_STORES = 'DefaultStores'
+TAB_DEFAULT_STORES_DEFAULT = 'STANDARD'
+
+TAB_LIBRARIES = 'Libraries'
+TAB_LIBRARIES_COMMON = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_LIBRARIES_IA32 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_LIBRARIES_X64 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_X64
+TAB_LIBRARIES_ARM = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_LIBRARIES_EBC = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_EBC
+TAB_LIBRARIES_AARCH64 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_COMPONENTS = 'Components'
+TAB_COMPONENTS_COMMON = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_COMPONENTS_IA32 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_IA32
+TAB_COMPONENTS_X64 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_X64
+TAB_COMPONENTS_ARM = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_ARM
+TAB_COMPONENTS_EBC = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_EBC
+TAB_COMPONENTS_AARCH64 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_AARCH64
+
+TAB_BUILD_OPTIONS = 'BuildOptions'
+
+TAB_DEFINE = 'DEFINE'
+TAB_NMAKE = 'Nmake'
+TAB_USER_EXTENSIONS = 'UserExtensions'
+TAB_INCLUDE = '!include'
+TAB_DEFAULT = 'DEFAULT'
+TAB_COMMON = 'COMMON'
+
+#
+# Common Define
+#
+TAB_COMMON_DEFINES = 'Defines'
+
+#
+# Inf Definitions
+#
+TAB_INF_DEFINES = TAB_COMMON_DEFINES
+TAB_INF_DEFINES_INF_VERSION = 'INF_VERSION'
+TAB_INF_DEFINES_BASE_NAME = 'BASE_NAME'
+TAB_INF_DEFINES_FILE_GUID = 'FILE_GUID'
+TAB_INF_DEFINES_MODULE_TYPE = 'MODULE_TYPE'
+TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION = 'EFI_SPECIFICATION_VERSION'
+TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION = 'UEFI_SPECIFICATION_VERSION'
+TAB_INF_DEFINES_PI_SPECIFICATION_VERSION = 'PI_SPECIFICATION_VERSION'
+TAB_INF_DEFINES_EDK_RELEASE_VERSION = 'EDK_RELEASE_VERSION'
+TAB_INF_DEFINES_BINARY_MODULE = 'BINARY_MODULE'
+TAB_INF_DEFINES_LIBRARY_CLASS = 'LIBRARY_CLASS'
+TAB_INF_DEFINES_COMPONENT_TYPE = 'COMPONENT_TYPE'
+TAB_INF_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
+TAB_INF_DEFINES_DPX_SOURCE = 'DPX_SOURCE'
+TAB_INF_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
+TAB_INF_DEFINES_BUILD_TYPE = 'BUILD_TYPE'
+TAB_INF_DEFINES_FFS_EXT = 'FFS_EXT'
+TAB_INF_DEFINES_FV_EXT = 'FV_EXT'
+TAB_INF_DEFINES_SOURCE_FV = 'SOURCE_FV'
+TAB_INF_DEFINES_VERSION_NUMBER = 'VERSION_NUMBER'
+TAB_INF_DEFINES_VERSION = 'VERSION' # for Edk inf, the same as VERSION_NUMBER
+TAB_INF_DEFINES_VERSION_STRING = 'VERSION_STRING'
+TAB_INF_DEFINES_PCD_IS_DRIVER = 'PCD_IS_DRIVER'
+TAB_INF_DEFINES_TIANO_EDK_FLASHMAP_H = 'TIANO_EDK_FLASHMAP_H'
+TAB_INF_DEFINES_ENTRY_POINT = 'ENTRY_POINT'
+TAB_INF_DEFINES_UNLOAD_IMAGE = 'UNLOAD_IMAGE'
+TAB_INF_DEFINES_CONSTRUCTOR = 'CONSTRUCTOR'
+TAB_INF_DEFINES_DESTRUCTOR = 'DESTRUCTOR'
+TAB_INF_DEFINES_DEFINE = 'DEFINE'
+TAB_INF_DEFINES_SPEC = 'SPEC'
+TAB_INF_DEFINES_CUSTOM_MAKEFILE = 'CUSTOM_MAKEFILE'
+TAB_INF_DEFINES_MACRO = '__MACROS__'
+TAB_INF_DEFINES_SHADOW = 'SHADOW'
+TAB_INF_FIXED_PCD = 'FixedPcd'
+TAB_INF_FEATURE_PCD = 'FeaturePcd'
+TAB_INF_PATCH_PCD = 'PatchPcd'
+TAB_INF_PCD = 'Pcd'
+TAB_INF_PCD_EX = 'PcdEx'
+TAB_INF_USAGE_PRO = 'PRODUCES'
+TAB_INF_USAGE_SOME_PRO = 'SOMETIMES_PRODUCES'
+TAB_INF_USAGE_CON = 'CONSUMES'
+TAB_INF_USAGE_SOME_CON = 'SOMETIMES_CONSUMES'
+TAB_INF_USAGE_NOTIFY = 'NOTIFY'
+TAB_INF_USAGE_TO_START = 'TO_START'
+TAB_INF_USAGE_BY_START = 'BY_START'
+TAB_INF_GUIDTYPE_EVENT = 'Event'
+TAB_INF_GUIDTYPE_FILE = 'File'
+TAB_INF_GUIDTYPE_FV = 'FV'
+TAB_INF_GUIDTYPE_GUID = 'GUID'
+TAB_INF_GUIDTYPE_HII = 'HII'
+TAB_INF_GUIDTYPE_HOB = 'HOB'
+TAB_INF_GUIDTYPE_ST = 'SystemTable'
+TAB_INF_GUIDTYPE_TSG = 'TokenSpaceGuid'
+TAB_INF_GUIDTYPE_VAR = 'Variable'
+TAB_INF_GUIDTYPE_PROTOCOL = 'PROTOCOL'
+TAB_INF_GUIDTYPE_PPI = 'PPI'
+TAB_INF_USAGE_UNDEFINED = 'UNDEFINED'
+
+#
+# Dec Definitions
+#
+TAB_DEC_DEFINES = TAB_COMMON_DEFINES
+TAB_DEC_DEFINES_DEC_SPECIFICATION = 'DEC_SPECIFICATION'
+TAB_DEC_DEFINES_PACKAGE_NAME = 'PACKAGE_NAME'
+TAB_DEC_DEFINES_PACKAGE_GUID = 'PACKAGE_GUID'
+TAB_DEC_DEFINES_PACKAGE_VERSION = 'PACKAGE_VERSION'
+TAB_DEC_DEFINES_PKG_UNI_FILE = 'PKG_UNI_FILE'
+
+#
+# Dsc Definitions
+#
+TAB_DSC_DEFINES = TAB_COMMON_DEFINES
+TAB_DSC_DEFINES_PLATFORM_NAME = 'PLATFORM_NAME'
+TAB_DSC_DEFINES_PLATFORM_GUID = 'PLATFORM_GUID'
+TAB_DSC_DEFINES_PLATFORM_VERSION = 'PLATFORM_VERSION'
+TAB_DSC_DEFINES_DSC_SPECIFICATION = 'DSC_SPECIFICATION'
+TAB_DSC_DEFINES_OUTPUT_DIRECTORY = 'OUTPUT_DIRECTORY'
+TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES = 'SUPPORTED_ARCHITECTURES'
+TAB_DSC_DEFINES_BUILD_TARGETS = 'BUILD_TARGETS'
+TAB_DSC_DEFINES_SKUID_IDENTIFIER = 'SKUID_IDENTIFIER'
+TAB_DSC_DEFINES_PCD_INFO_GENERATION = 'PCD_INFO_GENERATION'
+TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION = 'PCD_VAR_CHECK_GENERATION'
+TAB_DSC_DEFINES_FLASH_DEFINITION = 'FLASH_DEFINITION'
+TAB_DSC_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
+TAB_DSC_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
+TAB_DSC_DEFINES_BS_BASE_ADDRESS = 'BsBaseAddress'
+TAB_DSC_DEFINES_RT_BASE_ADDRESS = 'RtBaseAddress'
+TAB_DSC_DEFINES_RFC_LANGUAGES = 'RFC_LANGUAGES'
+TAB_DSC_DEFINES_ISO_LANGUAGES = 'ISO_LANGUAGES'
+TAB_DSC_DEFINES_DEFINE = 'DEFINE'
+TAB_DSC_DEFINES_VPD_TOOL_GUID = 'VPD_TOOL_GUID'
+TAB_FIX_LOAD_TOP_MEMORY_ADDRESS = 'FIX_LOAD_TOP_MEMORY_ADDRESS'
+TAB_DSC_DEFINES_EDKGLOBAL = 'EDK_GLOBAL'
+TAB_DSC_PREBUILD = 'PREBUILD'
+TAB_DSC_POSTBUILD = 'POSTBUILD'
+#
+# TargetTxt Definitions
+#
+TAB_TAT_DEFINES_ACTIVE_PLATFORM = 'ACTIVE_PLATFORM'
+TAB_TAT_DEFINES_ACTIVE_MODULE = 'ACTIVE_MODULE'
+TAB_TAT_DEFINES_TOOL_CHAIN_CONF = 'TOOL_CHAIN_CONF'
+TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER = 'MAX_CONCURRENT_THREAD_NUMBER'
+TAB_TAT_DEFINES_TARGET = 'TARGET'
+TAB_TAT_DEFINES_TOOL_CHAIN_TAG = 'TOOL_CHAIN_TAG'
+TAB_TAT_DEFINES_TARGET_ARCH = 'TARGET_ARCH'
+TAB_TAT_DEFINES_BUILD_RULE_CONF = "BUILD_RULE_CONF"
+
+#
+# ToolDef Definitions
+#
+TAB_TOD_DEFINES_TARGET = 'TARGET'
+TAB_TOD_DEFINES_TOOL_CHAIN_TAG = 'TOOL_CHAIN_TAG'
+TAB_TOD_DEFINES_TARGET_ARCH = 'TARGET_ARCH'
+TAB_TOD_DEFINES_COMMAND_TYPE = 'COMMAND_TYPE'
+TAB_TOD_DEFINES_FAMILY = 'FAMILY'
+TAB_TOD_DEFINES_BUILDRULEFAMILY = 'BUILDRULEFAMILY'
+TAB_TOD_DEFINES_BUILDRULEORDER = 'BUILDRULEORDER'
+
+#
+# Conditional Statements
+#
+TAB_IF = '!if'
+TAB_END_IF = '!endif'
+TAB_ELSE_IF = '!elseif'
+TAB_ELSE = '!else'
+TAB_IF_DEF = '!ifdef'
+TAB_IF_N_DEF = '!ifndef'
+TAB_IF_EXIST = '!if exist'
+TAB_ERROR = '!error'
+
+#
+# Unknown section
+#
+TAB_UNKNOWN = 'UNKNOWN'
+
+#
+# Build database path
+#
+DATABASE_PATH = ":memory:" #"BuildDatabase.db"
+
+# used by ECC
+MODIFIER_SET = {'IN', 'OUT', 'OPTIONAL', 'UNALIGNED', 'EFI_RUNTIMESERVICE', 'EFI_BOOTSERVICE', 'EFIAPI'}
+
+# Dependency Opcodes
+DEPEX_OPCODE_BEFORE = "BEFORE"
+DEPEX_OPCODE_AFTER = "AFTER"
+DEPEX_OPCODE_PUSH = "PUSH"
+DEPEX_OPCODE_AND = "AND"
+DEPEX_OPCODE_OR = "OR"
+DEPEX_OPCODE_NOT = "NOT"
+DEPEX_OPCODE_END = "END"
+DEPEX_OPCODE_SOR = "SOR"
+DEPEX_OPCODE_TRUE = "TRUE"
+DEPEX_OPCODE_FALSE = "FALSE"
+
+# Dependency Expression
+DEPEX_SUPPORTED_OPCODE_SET = {"BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "END", "SOR", "TRUE", "FALSE", '(', ')'}
+
+TAB_STATIC_LIBRARY = "STATIC-LIBRARY-FILE"
+TAB_DYNAMIC_LIBRARY = "DYNAMIC-LIBRARY-FILE"
+TAB_FRAMEWORK_IMAGE = "EFI-IMAGE-FILE"
+TAB_C_CODE_FILE = "C-CODE-FILE"
+TAB_C_HEADER_FILE = "C-HEADER-FILE"
+TAB_UNICODE_FILE = "UNICODE-TEXT-FILE"
+TAB_IMAGE_FILE = "IMAGE-DEFINITION-FILE"
+TAB_DEPENDENCY_EXPRESSION_FILE = "DEPENDENCY-EXPRESSION-FILE"
+TAB_UNKNOWN_FILE = "UNKNOWN-TYPE-FILE"
+TAB_DEFAULT_BINARY_FILE = "_BINARY_FILE_"
+TAB_OBJECT_FILE = "OBJECT-FILE"
+TAB_VFR_FILE = 'VISUAL-FORM-REPRESENTATION-FILE'
+
+# used by BRG
+TAB_BRG_PCD = 'PCD'
+TAB_BRG_LIBRARY = 'Library'
+
+#
+# Build Rule File Version Definition
+#
+TAB_BUILD_RULE_VERSION = "build_rule_version"
+
+# section name for PCDs
+PCDS_DYNAMIC_DEFAULT = "PcdsDynamicDefault"
+PCDS_DYNAMIC_VPD = "PcdsDynamicVpd"
+PCDS_DYNAMIC_HII = "PcdsDynamicHii"
+PCDS_DYNAMICEX_DEFAULT = "PcdsDynamicExDefault"
+PCDS_DYNAMICEX_VPD = "PcdsDynamicExVpd"
+PCDS_DYNAMICEX_HII = "PcdsDynamicExHii"
+
+SECTIONS_HAVE_ITEM_PCD_SET = {PCDS_DYNAMIC_DEFAULT.upper(), PCDS_DYNAMIC_VPD.upper(), PCDS_DYNAMIC_HII.upper(), \
+ PCDS_DYNAMICEX_DEFAULT.upper(), PCDS_DYNAMICEX_VPD.upper(), PCDS_DYNAMICEX_HII.upper()}
+# Section allowed to have items after arch
+SECTIONS_HAVE_ITEM_AFTER_ARCH_SET = {TAB_LIBRARY_CLASSES.upper(), TAB_DEPEX.upper(), TAB_USER_EXTENSIONS.upper(),
+ PCDS_DYNAMIC_DEFAULT.upper(),
+ PCDS_DYNAMIC_VPD.upper(),
+ PCDS_DYNAMIC_HII.upper(),
+ PCDS_DYNAMICEX_DEFAULT.upper(),
+ PCDS_DYNAMICEX_VPD.upper(),
+ PCDS_DYNAMICEX_HII.upper(),
+ TAB_BUILD_OPTIONS.upper(),
+ TAB_INCLUDES.upper()}
+
+#
+# pack codes as used in PcdDb and elsewhere
+#
+PACK_PATTERN_GUID = '=LHHBBBBBBBB'
+PACK_CODE_BY_SIZE = {8:'=Q',
+ 4:'=L',
+ 2:'=H',
+ 1:'=B',
+ 0:'=B',
+ 16:""}
+
+TAB_COMPILER_MSFT = 'MSFT'
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 10/22]: MdePkg/BaseSynchronizationLib: RISC-V cache related code.

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:05PM +0800, Abner Chang wrote:
Support RISC-V cache related functions.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
.../BaseSynchronizationLib.inf | 6 +
.../RiscV64/Synchronization.c | 189 +++++++++++++++++++++
.../RiscV64/SynchronizationAsm.s | 84 +++++++++
Shouldn't this be SynchronizationAsm.S?
Or well, "Asm" shouldn't be in the name, the filename ending takes
care of dscribing what type of file it is.

But .s (lowercase) denotes an assembler file that is *not* run through
the C preprocessor, which ... I really don't see the point of.
The filename should always be *.S (so we don't need to go back and
rename the files if we decide to add include statements or local
#defines).

/
Leif

3 files changed, 279 insertions(+)
create mode 100644 MdePkg/Library/BaseSynchronizationLib/RiscV64/Synchronization.c
create mode 100644 MdePkg/Library/BaseSynchronizationLib/RiscV64/SynchronizationAsm.s


Re: [edk2-staging/RISC-V-V2 PATCH v1 09/22]: MdePkg/BaseCpuLib: RISC-V Base CPU library implementation.

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:04PM +0800, Abner Chang wrote:
Implement RISC-V CPU related functions in BaseCpuLib.

Contributed-under: TianoCore Contribution Agreement 1.0
Apart from the CLA and the License of the new file, this one looks
fine to me.

/
Leif

Signed-off-by: Abner Chang <abner.chang@...>
---
MdePkg/Library/BaseCpuLib/BaseCpuLib.inf | 4 ++++
MdePkg/Library/BaseCpuLib/RiscV/Cpu.s | 25 +++++++++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 MdePkg/Library/BaseCpuLib/RiscV/Cpu.s

diff --git a/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf b/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
index a7cb381..20ee774 100644
--- a/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+++ b/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
@@ -7,6 +7,7 @@
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -59,6 +60,9 @@
AArch64/CpuFlushTlb.asm | MSFT
AArch64/CpuSleep.asm | MSFT

+[Sources.RISCV64]
+ RiscV/Cpu.s
+
[Packages]
MdePkg/MdePkg.dec

diff --git a/MdePkg/Library/BaseCpuLib/RiscV/Cpu.s b/MdePkg/Library/BaseCpuLib/RiscV/Cpu.s
new file mode 100644
index 0000000..9a1bf0f
--- /dev/null
+++ b/MdePkg/Library/BaseCpuLib/RiscV/Cpu.s
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+//
+// CpuSleep for RISC-V
+//
+// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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.
+//
+//------------------------------------------------------------------------------
+.data
+.align 3
+.section .text
+
+.global ASM_PFX(_CpuSleep)
+
+ASM_PFX(_CpuSleep):
+ wfi
+ ret
+
+
--
2.7.4




Re: [edk2-staging/RISC-V-V2 PATCH v1 08/22]: MdePkg/BasePeCoff: Add RISC-V PE/Coff related code.

Leif Lindholm
 

On Wed, Sep 04, 2019 at 06:43:03PM +0800, Abner Chang wrote:
Support RISC-V image relocation.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Abner Chang <abner.chang@...>
---
MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 3 +-
MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf | 5 +
MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni | 4 +-
.../Library/BasePeCoffLib/BasePeCoffLibInternals.h | 1 +
.../Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c | 149 +++++++++++++++++++++
5 files changed, 160 insertions(+), 2 deletions(-)
create mode 100644 MdePkg/Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c

diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
index 07bb62f..97e0ff4 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
@@ -1,6 +1,6 @@
/** @file
Base PE/COFF loader supports loading any PE32/PE32+ or TE image, but
- only supports relocating IA32, x64, IPF, and EBC images.
+ only supports relocating IA32, x64, IPF, ARM, RISC-V and EBC images.

Caution: This file requires additional review when modified.
This library will have external input - PE/COFF image.
@@ -17,6 +17,7 @@

Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Portions Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf b/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
index 395c140..e5c8e66 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
@@ -3,6 +3,7 @@
# The IPF version library supports loading IPF and EBC PE/COFF image.
# The IA32 version library support loading IA32, X64 and EBC PE/COFF images.
# The X64 version library support loading IA32, X64 and EBC PE/COFF images.
+# The RISC-V version library support loading RISC-V images.
#
# Caution: This module requires additional review when modified.
# This library will have external input - PE/COFF image.
@@ -11,6 +12,7 @@
#
# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -41,6 +43,9 @@
[Sources.ARM]
Arm/PeCoffLoaderEx.c

+[Sources.RISCV64]
+ RiscV/PeCoffLoaderEx.c
+
[Packages]
MdePkg/MdePkg.dec

diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni b/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni
index b0ea702..edc48cd 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni
@@ -4,7 +4,8 @@
// The IPF version library supports loading IPF and EBC PE/COFF image.
// The IA32 version library support loading IA32, X64 and EBC PE/COFF images.
// The X64 version library support loading IA32, X64 and EBC PE/COFF images.
-//
+// The RISC-V version library support loading RISC-V32 and RISC-V64 PE/COFF images.
+//
The above diff looks like you're adding a blank line and deleting
another one. This happens because you have added a trailing space on
the gap line. PatchCheck.py finds these.

/
Leif

// Caution: This module requires additional review when modified.
// This library will have external input - PE/COFF image.
// This external input must be validated carefully to avoid security issue like
@@ -12,6 +13,7 @@
//
// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
// Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
index b74277f..9c33703 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
@@ -2,6 +2,7 @@
Declaration of internal functions in PE/COFF Lib.

Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
diff --git a/MdePkg/Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c b/MdePkg/Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c
new file mode 100644
index 0000000..a99550f
--- /dev/null
+++ b/MdePkg/Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c
@@ -0,0 +1,149 @@
+/** @file
+ PE/Coff loader for RISC-V PE image
+
+ Copyright (c) 2016, Hewlett Packard Enterprise Development LP. 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 "BasePeCoffLibInternals.h"
+#include <Library/BaseLib.h>
+
+//
+// RISC-V definition.
+//
+#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
+#define RISCV_IMM_BITS 12
+#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
+#define RISCV_CONST_HIGH_PART(VALUE) \
+ (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
+
+/**
+ Performs an RISC-V specific relocation fixup and is a no-op on
+ other instruction sets.
+ RISC-V splits 32-bit fixup into 20bit and 12-bit with two relocation
+ types. We have to know the lower 12-bit fixup first then we can deal
+ carry over on high 20-bit fixup. So we log the high 20-bit in
+ FixupData.
+
+ @param Reloc The pointer to the relocation record.
+ @param Fixup The pointer to the address to fix up.
+ @param FixupData The pointer to a buffer to log the fixups.
+ @param Adjust The offset to adjust the fixup.
+
+ @return Status code.
+
+**/
+RETURN_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+{
+ UINT32 Value;
+ UINT32 Value2;
+ UINT32 *RiscVHi20Fixup;
+
+ switch ((*Reloc) >> 12) {
+ case EFI_IMAGE_REL_BASED_RISCV_HI20:
+ *(UINT64 *)(*FixupData) = (UINT64)(UINTN)Fixup;
+ break;
+
+ case EFI_IMAGE_REL_BASED_RISCV_LOW12I:
+ RiscVHi20Fixup = (UINT32 *)(*(UINT64 *)(*FixupData));
+ if (RiscVHi20Fixup != NULL) {
+
+ Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value += (UINT32)Adjust;
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) |\
+ (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
+ *(UINT32 *)Fixup = (RV_X (Value, 0, 12) << 20) |\
+ (RV_X (*(UINT32 *)Fixup, 0, 20));
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_RISCV_LOW12S:
+ RiscVHi20Fixup = (UINT32 *)(*(UINT64 *)(*FixupData));
+ if (RiscVHi20Fixup != NULL) {
+ Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
+ Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 *)Fixup, 25, 7) << 5));
+ if (Value2 & (RISCV_IMM_REACH/2)) {
+ Value2 |= ~(RISCV_IMM_REACH-1);
+ }
+ Value += Value2;
+ Value += (UINT32)Adjust;
+ Value2 = RISCV_CONST_HIGH_PART (Value);
+ *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
+ (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
+ Value2 = *(UINT32 *)Fixup & 0x01fff07f;
+ Value &= RISCV_IMM_REACH - 1;
+ *(UINT32 *)Fixup = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));
+ }
+ break;
+
+ default:
+ return RETURN_UNSUPPORTED;
+
+ }
+ return RETURN_SUCCESS;
+}
+
+/**
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ @param Machine Machine type from the PE Header.
+
+ @return TRUE if this PE/COFF loader can load the image
+
+**/
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+{
+ if ((Machine == IMAGE_FILE_MACHINE_RISCV32) || (Machine == IMAGE_FILE_MACHINE_RISCV64)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Performs an Itanium-based specific re-relocation fixup and is a no-op on other
+ instruction sets. This is used to re-relocated the image into the EFI virtual
+ space for runtime calls.
+
+ @param Reloc The pointer to the relocation record.
+ @param Fixup The pointer to the address to fix up.
+ @param FixupData The pointer to a buffer to log the fixups.
+ @param Adjust The offset to adjust the fixup.
+
+ @return Status code.
+
+**/
+RETURN_STATUS
+PeHotRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+{
+ return RETURN_UNSUPPORTED;
+}
--
2.7.4