Hi Abner
I have a quick review on that and I have question for below library/APIs:
1) BaseCacheMaintenanceLib - It seems you just leave empty function there,
without any implementation.
If there is no need to implement this, would you please add some comments
around the code?
2) IoLib - It seems MMIO and IO is treated to be same. Is that true?
If there is no special IO instruction in RISC-V, using ASSERT might be better.
You can take ARM as example.
3) BaseSynchronizationLib - It seems you use C-code to perform atomic memory
read-modify-write. Will the compiler generic atomic memory operation? If yes,
would you please add some comments around the c-code?
If no, I suggest using AMO instruction in assembly code.
UINT32
EFIAPI
InternalSyncIncrement (
IN volatile UINT32 *Value
)
{
return ++*Value;
}
Thank you
Yao Jiewen
> -----Original Message-----
> From: edk2-devel [mailto:[email protected]] On Behalf Of
> Abner Chang
> Sent: Sunday, May 8, 2016 12:17 PM
> To: [email protected]
> Cc: AbnerChang <[email protected]>; Gao, Liming
> <[email protected]>
> Subject: [edk2] [PATCH 2/2] MdePkg: MDE implementations for RISC-V arch.
>
> From: AbnerChang <[email protected]>
>
> The library instances of RISC-V MDE implementations.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: Abner Chang<[email protected]>
>
> ---
> .../BaseCacheMaintenanceLib.inf | 4 +
> .../Library/BaseCacheMaintenanceLib/RiscVCache.c | 228 +++++++++++
> MdePkg/Library/BaseCpuLib/BaseCpuLib.inf | 4 +
> MdePkg/Library/BaseCpuLib/RiscV/Cpu.s | 25 ++
> .../BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf | 8 +-
> MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c | 418
> +++++++++++++++++++++
> MdePkg/Library/BaseLib/BaseLib.inf | 14 +
> MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c | 33 ++
> MdePkg/Library/BaseLib/RiscV64/CpuPause.c | 35 ++
> MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c | 30 ++
> MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c | 31 ++
> MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c | 42 +++
> .../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 | 63 ++++
> MdePkg/Library/BaseLib/RiscV64/Unaligned.c | 270
> +++++++++++++
> MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 3 +-
> MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf | 5 +
> MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni | 2 +
> .../Library/BasePeCoffLib/BasePeCoffLibInternals.h | 1 +
> .../Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c | 161 ++++++++
> .../BaseSynchronizationLib.inf | 5 +
> .../RiscV64/Synchronization.c | 147 ++++++++
> 26 files changed, 1698 insertions(+), 3 deletions(-)
> 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/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/BasePeCoffLib/RiscV/PeCoffLoaderEx.c
> create mode 100644
> MdePkg/Library/BaseSynchronizationLib/RiscV64/Synchronization.c
>
> diff --git
> a/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.in
> f
> b/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.in
> f
> index d659161..dcb6043 100644
> ---
> a/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.in
> f
> +++
> b/MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.in
> f
> @@ -6,6 +6,7 @@
> #
> # Copyright (c) 2007 - 2015, 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>
> #
> # This program and the accompanying materials
> # are licensed and made available under the terms and conditions of the
> BSD License
> @@ -49,6 +50,9 @@
> [Sources.AARCH64]
> ArmCache.c
>
> +[Sources.RISCV64]
> + RiscVCache.c
> +
> [Packages]
> MdePkg/MdePkg.dec
>
> diff --git a/MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c
> b/MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c
> new file mode 100644
> index 0000000..27b4c35
> --- /dev/null
> +++ b/MdePkg/Library/BaseCacheMaintenanceLib/RiscVCache.c
> @@ -0,0 +1,228 @@
> +/** @file
> + RISC-V specific functionality for cache.
> +
> + 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 <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +
> +/**
> + Invalidates the entire instruction cache in cache coherency domain of the
> + calling CPU.
> +
> +**/
> +VOID
> +EFIAPI
> +InvalidateInstructionCache (
> + VOID
> + )
> +{
> +}
> +
> +/**
> + Invalidates a range of instruction cache lines in the cache coherency
> domain
> + of the calling CPU.
> +
> + Invalidates the instruction cache lines specified by Address and Length. If
> + Address is not aligned on a cache line boundary, then entire instruction
> + cache line containing Address is invalidated. If Address + Length is not
> + aligned on a cache line boundary, then the entire instruction cache line
> + containing Address + Length -1 is invalidated. This function may choose
> to
> + invalidate the entire instruction cache if that is more efficient than
> + invalidating the specified range. If Length is 0, then no instruction cache
> + lines are invalidated. Address is returned.
> +
> + If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
> +
> + @param Address The base address of the instruction cache lines to
> + invalidate. If the CPU is in a physical addressing mode,
> then
> + Address is a physical address. If the CPU is in a virtual
> + addressing mode, then Address is a virtual address.
> +
> + @param Length The number of bytes to invalidate from the
> instruction cache.
> +
> + @return Address.
> +
> +**/
> +VOID *
> +EFIAPI
> +InvalidateInstructionCacheRange (
> + IN VOID *Address,
> + IN UINTN Length
> + )
> +{
> + return Address;
> +}
> +
> +/**
> + Writes back and invalidates the entire data cache in cache coherency
> domain
> + of the calling CPU.
> +
> + Writes back and invalidates the entire data cache in cache coherency
> domain
> + of the calling CPU. This function guarantees that all dirty cache lines are
> + written back to system memory, and also invalidates all the data cache
> lines
> + in the cache coherency domain of the calling CPU.
> +
> +**/
> +VOID
> +EFIAPI
> +WriteBackInvalidateDataCache (
> + VOID
> + )
> +{
> +}
> +
> +/**
> + Writes back and invalidates a range of data cache lines in the cache
> + coherency domain of the calling CPU.
> +
> + Writes back and invalidates the data cache lines specified by Address and
> + Length. If Address is not aligned on a cache line boundary, then entire
> data
> + cache line containing Address is written back and invalidated. If Address +
> + Length is not aligned on a cache line boundary, then the entire data
> cache
> + line containing Address + Length -1 is written back and invalidated. This
> + function may choose to write back and invalidate the entire data cache if
> + that is more efficient than writing back and invalidating the specified
> + range. If Length is 0, then no data cache lines are written back and
> + invalidated. Address is returned.
> +
> + If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
> +
> + @param Address The base address of the data cache lines to write
> back and
> + invalidate. If the CPU is in a physical addressing mode,
> then
> + Address is a physical address. If the CPU is in a virtual
> + addressing mode, then Address is a virtual address.
> + @param Length The number of bytes to write back and invalidate
> from the
> + data cache.
> +
> + @return Address of cache invalidation.
> +
> +**/
> +VOID *
> +EFIAPI
> +WriteBackInvalidateDataCacheRange (
> + IN VOID *Address,
> + IN UINTN Length
> + )
> +{
> + return Address;
> +}
> +
> +/**
> + Writes back the entire data cache in cache coherency domain of the
> calling
> + CPU.
> +
> + Writes back the entire data cache in cache coherency domain of the
> calling
> + CPU. This function guarantees that all dirty cache lines are written back
> to
> + system memory. This function may also invalidate all the data cache lines
> in
> + the cache coherency domain of the calling CPU.
> +
> +**/
> +VOID
> +EFIAPI
> +WriteBackDataCache (
> + VOID
> + )
> +{
> +}
> +
> +/**
> + Writes back a range of data cache lines in the cache coherency domain
> of the
> + calling CPU.
> +
> + Writes back the data cache lines specified by Address and Length. If
> Address
> + is not aligned on a cache line boundary, then entire data cache line
> + containing Address is written back. If Address + Length is not aligned on a
> + cache line boundary, then the entire data cache line containing Address +
> + Length -1 is written back. This function may choose to write back the
> entire
> + data cache if that is more efficient than writing back the specified range.
> + If Length is 0, then no data cache lines are written back. This function
> may
> + also invalidate all the data cache lines in the specified range of the
> cache
> + coherency domain of the calling CPU. Address is returned.
> +
> + If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
> +
> + @param Address The base address of the data cache lines to write
> back. If
> + the CPU is in a physical addressing mode, then
> Address is a
> + physical address. If the CPU is in a virtual addressing
> + mode, then Address is a virtual address.
> + @param Length The number of bytes to write back from the data
> cache.
> +
> + @return Address of cache written in main memory.
> +
> +**/
> +VOID *
> +EFIAPI
> +WriteBackDataCacheRange (
> + IN VOID *Address,
> + IN UINTN Length
> + )
> +{
> + return Address;
> +}
> +
> +/**
> + Invalidates the entire data cache in cache coherency domain of the
> calling
> + CPU.
> +
> + Invalidates the entire data cache in cache coherency domain of the
> calling
> + CPU. This function must be used with care because dirty cache lines are
> not
> + written back to system memory. It is typically used for cache diagnostics.
> If
> + the CPU does not support invalidation of the entire data cache, then a
> write
> + back and invalidate operation should be performed on the entire data
> cache.
> +
> +**/
> +VOID
> +EFIAPI
> +InvalidateDataCache (
> + VOID
> + )
> +{
> +}
> +
> +/**
> + Invalidates a range of data cache lines in the cache coherency domain of
> the
> + calling CPU.
> +
> + Invalidates the data cache lines specified by Address and Length. If
> Address
> + is not aligned on a cache line boundary, then entire data cache line
> + containing Address is invalidated. If Address + Length is not aligned on a
> + cache line boundary, then the entire data cache line containing Address +
> + Length -1 is invalidated. This function must never invalidate any cache
> lines
> + outside the specified range. If Length is 0, then no data cache lines are
> + invalidated. Address is returned. This function must be used with care
> + because dirty cache lines are not written back to system memory. It is
> + typically used for cache diagnostics. If the CPU does not support
> + invalidation of a data cache range, then a write back and invalidate
> + operation should be performed on the data cache range.
> +
> + If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
> +
> + @param Address The base address of the data cache lines to invalidate.
> If
> + the CPU is in a physical addressing mode, then
> Address is a
> + physical address. If the CPU is in a virtual addressing
> mode,
> + then Address is a virtual address.
> + @param Length The number of bytes to invalidate from the data
> cache.
> +
> + @return Address.
> +
> +**/
> +VOID *
> +EFIAPI
> +InvalidateDataCacheRange (
> + IN VOID *Address,
> + IN UINTN Length
> + )
> +{
> + return Address;
> +}
> diff --git a/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> b/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> index 4e0f0a1..f2f7419 100644
> --- a/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> +++ b/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> @@ -7,6 +7,7 @@
> # Copyright (c) 2007 - 2014, 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>
> #
> # This program and the accompanying materials
> # are licensed and made available under the terms and conditions of the
> BSD License
> @@ -66,6 +67,9 @@
> AArch64/CpuFlushTlb.S | GCC
> AArch64/CpuSleep.S | GCC
>
> +[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..91c1d74
> --- /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
> +
> +
> diff --git a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> index 29b9e8b..700ce38 100644
> --- a/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> +++ b/MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> @@ -2,12 +2,13 @@
> # Instance of I/O Library using compiler intrinsics.
> #
> # I/O Library that uses compiler intrinsics to perform IN and OUT
> instructions
> -# for IA-32 and x64. On IPF, I/O port requests are translated into MMIO
> requests.
> +# for IA-32, x64 and RISC-V. On IPF, I/O port requests are translated into
> MMIO requests.
> # MMIO requests are forwarded directly to memory. For EBC, I/O port
> requests
> # ASSERT().
> #
> # Copyright (c) 2007 - 2015, 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>
> #
> # This program and the accompanying materials
> # are licensed and made available under the terms and conditions of the
> BSD License
> @@ -30,7 +31,7 @@
>
>
> #
> -# VALID_ARCHITECTURES = IA32 X64 EBC IPF ARM AARCH64
> +# VALID_ARCHITECTURES = IA32 X64 EBC IPF ARM AARCH64
> RISCV64
> #
>
> [Sources]
> @@ -63,6 +64,9 @@
> [Sources.AARCH64]
> IoLibArm.c
>
> +[Sources.RISCV64]
> + IoLibRiscV.c
> +
> [Packages]
> MdePkg/MdePkg.dec
>
> diff --git a/MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c
> b/MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c
> new file mode 100644
> index 0000000..cb110fe
> --- /dev/null
> +++ b/MdePkg/Library/BaseIoLibIntrinsic/IoLibRiscV.c
> @@ -0,0 +1,418 @@
> +/** @file
> + Common I/O Library routines 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 "BaseIoLibIntrinsicInternal.h"
> +
> +/**
> + Reads an 8-bit MMIO register.
> +
> + Reads the 8-bit MMIO register specified by Address. The 8-bit read value
> is
> + returned. This function must guarantee that all MMIO read and write
> + operations are serialized.
> +
> + If 8-bit MMIO register operations are not supported, then ASSERT().
> +
> + @param Address The MMIO register to read.
> +
> + @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +MmioRead8 (
> + IN UINTN Address
> + )
> +{
> + return *(volatile UINT8*)Address;
> +}
> +
> +/**
> + Writes an 8-bit MMIO register.
> +
> + Writes the 8-bit MMIO register specified by Address with the value
> specified
> + by Value and returns Value. This function must guarantee that all MMIO
> read
> + and write operations are serialized.
> +
> + If 8-bit MMIO register operations are not supported, then ASSERT().
> +
> + @param Address The MMIO register to write.
> + @param Value The value to write to the MMIO register.
> +
> + @return Value.
> +
> +**/
> +UINT8
> +EFIAPI
> +MmioWrite8 (
> + IN UINTN Address,
> + IN UINT8 Value
> + )
> +{
> + *(volatile UINT8 *)Address = Value;
> + return Value;
> +}
> +
> +/**
> + Reads a 16-bit MMIO register.
> +
> + Reads the 16-bit MMIO register specified by Address. The 16-bit read
> value is
> + returned. This function must guarantee that all MMIO read and write
> + operations are serialized.
> +
> + If 16-bit MMIO register operations are not supported, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The MMIO register to read.
> +
> + @return The value read.
> +
> +**/
> +UINT16
> +EFIAPI
> +MmioRead16 (
> + IN UINTN Address
> + )
> +{
> + return *(volatile UINT16 *)Address;
> +}
> +
> +/**
> + Writes a 16-bit MMIO register.
> +
> + Writes the 16-bit MMIO register specified by Address with the value
> specified
> + by Value and returns Value. This function must guarantee that all MMIO
> read
> + and write operations are serialized.
> +
> + If 16-bit MMIO register operations are not supported, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The MMIO register to write.
> + @param Value The value to write to the MMIO register.
> +
> + @return Value.
> +
> +**/
> +UINT16
> +EFIAPI
> +MmioWrite16 (
> + IN UINTN Address,
> + IN UINT16 Value
> + )
> +{
> + *(volatile UINT16 *)Address = Value;
> + return Value;
> +}
> +
> +/**
> + Reads a 32-bit MMIO register.
> +
> + Reads the 32-bit MMIO register specified by Address. The 32-bit read
> value is
> + returned. This function must guarantee that all MMIO read and write
> + operations are serialized.
> +
> + If 32-bit MMIO register operations are not supported, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The MMIO register to read.
> +
> + @return The value read.
> +
> +**/
> +UINT32
> +EFIAPI
> +MmioRead32 (
> + IN UINTN Address
> + )
> +{
> + return *(volatile UINT32 *)Address;
> +}
> +
> +/**
> + Writes a 32-bit MMIO register.
> +
> + Writes the 32-bit MMIO register specified by Address with the value
> specified
> + by Value and returns Value. This function must guarantee that all MMIO
> read
> + and write operations are serialized.
> +
> + If 32-bit MMIO register operations are not supported, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The MMIO register to write.
> + @param Value The valu return *(volatile UINT8*)Address;e
> + to write to the MMIO register.
> +
> + @return Value.
> +
> +**/
> +UINT32
> +EFIAPI
> +MmioWrite32 (
> + IN UINTN Address,
> + IN UINT32 Value
> + )
> +{
> + *(volatile UINT32 *)Address = Value;
> + return Value;
> +}
> +
> +/**
> + Reads a 64-bit MMIO register.
> +
> + Reads the 64-bit MMIO register specified by Address. The 64-bit read
> value is
> + returned. This function must guarantee that all MMIO read and write
> + operations are serialized.
> +
> + If 64-bit MMIO register operations are not supported, then ASSERT().
> + If Address is not aligned on a 64-bit boundary, then ASSERT().
> +
> + @param Address The MMIO register to read.
> +
> + @return The value read.
> +
> +**/
> +UINT64
> +EFIAPI
> +MmioRead64 (
> + IN UINTN Address
> + )
> +{
> + return *(volatile UINT64 *)Address;
> +}
> +
> +/**
> + Writes a 64-bit MMIO register.
> +
> + Writes the 64-bit MMIO register specified by Address with the value
> specified
> + by Value and returns Value. This function must guarantee that all MMIO
> read
> + and write operations are serialized.
> +
> + If 64-bit MMIO register operations are not supported, then ASSERT().
> + If Address is not aligned on a 64-bit boundary, then ASSERT().
> +
> + @param Address The MMIO register to write.
> + @param Value The value to write to the MMIO register.
> +
> +**/
> +UINT64
> +EFIAPI
> +MmioWrite64 (
> + IN UINTN Address,
> + IN UINT64 Value
> + )
> +{
> + *(volatile UINT64 *)Address = Value;
> + return Value;
> +}
> +
> +/**
> + Reads an 8-bit I/O port.
> +
> + Reads the 8-bit I/O port specified by Port. The 8-bit read value is
> returned.
> + This function must guarantee that all I/O read and write operations are
> + serialized.
> +
> + If 8-bit I/O port operations are not supported, then ASSERT().
> +
> + @param Port The I/O port to read.
> +
> + @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +IoRead8 (
> + IN UINTN Port
> + )
> +{
> + return *(volatile UINT8*)Port;
> +}
> +
> +/**
> + Writes an 8-bit I/O port.
> +
> + Writes the 8-bit I/O port specified by Port with the value specified by
> Value
> + and returns Value. This function must guarantee that all I/O read and
> write
> + operations are serialized.
> +
> + If 8-bit I/O port operations are not supported, then ASSERT().
> +
> + @param Port The I/O port to write.
> + @param Value The value to write to the I/O port.
> +
> + @return The value written the I/O port.
> +
> +**/
> +
> +UINT8
> +EFIAPI
> +IoWrite8 (
> + IN UINTN Port,
> + IN UINT8 Value
> + )
> +{
> +
> + *(volatile UINT8 *)Port = Value;
> + return Value;
> +}
> +
> +/**
> + Reads a 16-bit I/O port.
> +
> + Reads the 16-bit I/O port specified by Port. The 16-bit read value is
> returned.
> + This function must guarantee that all I/O read and write operations are
> + serialized.
> +
> + If 16-bit I/O port operations are not supported, then ASSERT().
> +
> + @param Port The I/O port to read.
> +
> + @return The value read.
> +
> +**/
> +UINT16
> +EFIAPI
> +IoRead16 (
> + IN UINTN Port
> + )
> +{
> + return *(volatile UINT16*)Port;
> +}
> +
> +/**
> + Writes a 16-bit I/O port.
> +
> + Writes the 16-bit I/O port specified by Port with the value specified by
> Value
> + and returns Value. This function must guarantee that all I/O read and
> write
> + operations are serialized.
> +
> + If 16-bit I/O port operations are not supported, then ASSERT().
> +
> + @param Port The I/O port to write.
> + @param Value The value to write to the I/O port.
> +
> + @return The value written the I/O port.
> +
> +**/
> +UINT16
> +EFIAPI
> +IoWrite16 (
> + IN UINTN Port,
> + IN UINT16 Value
> + )
> +{
> + *(volatile UINT16*)Port = Value;
> + return Value;
> +}
> +
> +/**
> + Reads a 32-bit I/O port.
> +
> + Reads the 32-bit I/O port specified by Port. The 32-bit read value is
> returned.
> + This function must guarantee that all I/O read and write operations are
> + serialized.
> +
> + If 32-bit I/O port operations are not supported, then ASSERT().
> +
> + @param Port The I/O port to read.
> +
> + @return The value read.
> +
> +**/
> +UINT32
> +EFIAPI
> +IoRead32 (
> + IN UINTN Port
> + )
> +{
> + return *(volatile UINT32*)Port;
> +}
> +
> +/**
> + Writes a 32-bit I/O port.
> +
> + Writes the 32-bit I/O port specified by Port with the value specified by
> Value
> + and returns Value. This function must guarantee that all I/O read and
> write
> + operations are serialized.
> +
> + If 32-bit I/O port operations are not supported, then ASSERT().
> +
> + @param Port The I/O port to write.
> + @param Value The value to write to the I/O port.
> +
> + @return The value written the I/O port.
> +
> +**/
> +UINT32
> +EFIAPI
> +IoWrite32 (
> + IN UINTN Port,
> + IN UINT32 Value
> + )
> +{
> + *(volatile UINT32*)Port = Value;
> + return Value;
> +}
> +
> +/**
> + Reads a 64-bit I/O port.
> +
> + Reads the 64-bit I/O port specified by Port. The 64-bit read value is
> returned.
> + This function must guarantee that all I/O read and write operations are
> + serialized.
> +
> + If 64-bit I/O port operations are not supported, then ASSERT().
> + If Port is not aligned on a 64-bit boundary, then ASSERT().
> +
> + @param Port The I/O port to read.
> +
> + @return The value read.
> +
> +**/
> +UINT64
> +EFIAPI
> +IoRead64 (
> + IN UINTN Port
> + )
> +{
> + return *(volatile UINT64*)Port;
> +}
> +
> +/**
> + Writes a 64-bit I/O port.
> +
> + Writes the 64-bit I/O port specified by Port with the value specified by
> Value
> + and returns Value. This function must guarantee that all I/O read and
> write
> + operations are serialized.
> +
> + If 64-bit I/O port operations are not supported, then ASSERT().
> + If Port is not aligned on a 64-bit boundary, then ASSERT().
> +
> + @param Port The I/O port to write.
> + @param Value The value to write to the I/O port.
> +
> + @return The value written to the I/O port.
> +
> +**/
> +UINT64
> +EFIAPI
> +IoWrite64 (
> + IN UINTN Port,
> + IN UINT64 Value
> + )
> +{
> + *(volatile UINT64*)Port = Value;
> + return 0;
> +}
> +
> +
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> b/MdePkg/Library/BaseLib/BaseLib.inf
> index e83a569..a605c61 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -503,6 +503,20 @@
> AArch64/SetJumpLongJump.S | GCC
> AArch64/CpuBreakpoint.S | GCC
>
> +[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
> +
> [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..68cf521
> --- /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..6fc1833
> --- /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..8bd0cb7
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c
> @@ -0,0 +1,30 @@
> +/** @file
> + CPU disable interrupt 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"
> +
> +extern VOID RiscVDisableInterrupts (VOID);
> +
> +/**
> + Disables CPU interrupts.
> +
> +**/
> +VOID
> +EFIAPI
> +DisableInterrupts (
> + VOID
> + )
> +{
> + RiscVDisableInterrupts ();
> +}
> +
> diff --git a/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c
> b/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c
> new file mode 100644
> index 0000000..345f544
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c
> @@ -0,0 +1,31 @@
> +/** @file
> + CPU enable interrupt 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"
> +
> +extern VOID RiscVEnableInterrupt (VOID);
> +
> +/**
> + Enables CPU interrupts.
> +
> +**/
> +VOID
> +EFIAPI
> +EnableInterrupts (
> + VOID
> + )
> +{
> + RiscVEnableInterrupt ();
> +}
> +
> diff --git a/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c
> b/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c
> new file mode 100644
> index 0000000..9183cfc
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c
> @@ -0,0 +1,42 @@
> +/** @file
> + CPU get interrupt state 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"
> +
> +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
> + )
> +{
> + UINT32 RetValue;
> +
> + RetValue = RiscVGetInterrupts ();
> + return (RetValue == 0)? FALSE: TRUE;
> +}
> +
> +
> diff --git a/MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c
> b/MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c
> new file mode 100644
> index 0000000..ac7a765
> --- /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..efab00d
> --- /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..6d8de1f
> --- /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..b924b7a
> --- /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..8f39667
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S
> @@ -0,0 +1,33 @@
> +//------------------------------------------------------------------------------
> +//
> +// Cpu interrupt enable/disable 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(RiscVDisableInterrupts)
> +ASM_GLOBAL ASM_PFX(RiscVEnableInterrupt)
> +ASM_GLOBAL ASM_PFX(RiscVGetInterrupts)
> +
> +ASM_PFX(RiscVDisableInterrupts):
> + li a1, 0xee
> + csrrc a0, 0x304, a1
> + ret
> +
> +ASM_PFX(RiscVEnableInterrupt):
> + li a1, 0xee
> + csrrw a0, 0x304, a1
> + ret
> +
> +ASM_PFX(RiscVGetInterrupts):
> + csrrw a0, 0x304, 0
> + ret
> diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S
> b/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S
> new file mode 100644
> index 0000000..8625280
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S
> @@ -0,0 +1,63 @@
> +//------------------------------------------------------------------------------
> +//
> +// 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..3d17cc8
> --- /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/BasePeCoffLib/BasePeCoff.c
> b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
> index 33cad23..d66d209 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 - 2014, 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>
> 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
> diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> b/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> index ff0580f..8f839e4 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 - 2014, 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>
> #
> # This program and the accompanying materials
> # are licensed and made available under the terms and conditions of the
> BSD License
> @@ -49,6 +51,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 56b6f1b..fe8ab15 100644
> --- a/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni
> +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.uni
> @@ -4,6 +4,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-V32 and RISC-V64
> PE/COFF images.
> //
> // Caution: This module requires additional review when modified.
> // This library will have external input - PE/COFF image.
> @@ -12,6 +13,7 @@
> //
> // Copyright (c) 2006 - 2014, 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>
> //
> // This program and the accompanying materials
> // are licensed and made available under the terms and conditions of the
> BSD License
> diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
> b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
> index 0851acc..88129da 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>
> 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
> diff --git a/MdePkg/Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c
> b/MdePkg/Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c
> new file mode 100644
> index 0000000..3bdfbea
> --- /dev/null
> +++ b/MdePkg/Library/BasePeCoffLib/RiscV/PeCoffLoaderEx.c
> @@ -0,0 +1,161 @@
> +/** @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:
> + //*(UINT32 *)ScratchBuffer = (UINT32)(UINTN)Fixup;
> + *(UINT64 *)(*FixupData) = (UINT64)(UINTN)Fixup;
> + //*FixupData = *FixupData + sizeof(UINT64);
> + break;
> +
> + case EFI_IMAGE_REL_BASED_RISCV_LOW12I:
> + //RiscVHi20Fixup = (UINT32 *)*ScratchBuffer;
> + RiscVHi20Fixup = (UINT32 *)(*(UINT64 *)(*FixupData));
> + if (RiscVHi20Fixup != NULL) {
> + //*(UINT64 *)(*FixupData) = (UINT64)(UINTN)Fixup;
> + //*FixupData = *FixupData + sizeof(UINT64);
> +
> + 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));
> + }
> + //*ScratchBuffer = (UINT64)NULL;
> + break;
> +
> + case EFI_IMAGE_REL_BASED_RISCV_LOW12S:
> + //RiscVHi20Fixup = (UINT32 *)*ScratchBuffer;
> + RiscVHi20Fixup = (UINT32 *)(*(UINT64 *)(*FixupData));
> + if (RiscVHi20Fixup != NULL) {
> + //*(UINT64 *)(*FixupData) = (UINT64)(UINTN)Fixup;
> + //*FixupData = *FixupData + sizeof(UINT64);
> +
> + 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)));
> + }
> + //*ScratchBuffer = (UINT64)NULL;
> + 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;
> +}
> +
> diff --git
> a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> index bcd7935..e7cd8bc 100755
> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> @@ -3,6 +3,7 @@
> #
> # Copyright (c) 2007 - 2016, 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>
> #
> # This program and the accompanying materials
> # are licensed and made available under the terms and conditions of the
> BSD License
> @@ -97,6 +98,10 @@
> Synchronization.c
> AArch64/Synchronization.S
>
> +[Sources.RISCV64]
> + Synchronization.c
> + RiscV64/Synchronization.c | GCC
> +
> [Packages]
> MdePkg/MdePkg.dec
>
> diff --git
> a/MdePkg/Library/BaseSynchronizationLib/RiscV64/Synchronization.c
> b/MdePkg/Library/BaseSynchronizationLib/RiscV64/Synchronization.c
> new file mode 100644
> index 0000000..a93827d
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/RiscV64/Synchronization.c
> @@ -0,0 +1,147 @@
> +/** @file
> + Implementation of synchronization functions on 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.
> +**/
> +
> +/**
> + Performs an atomic compare exchange operation on a 16-bit
> + unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 16-bit
> + unsigned integer specified by Value. If Value is equal to
> + CompareValue, then Value is set to ExchangeValue and
> + CompareValue is returned. If Value is not equal to
> + CompareValue, then Value is returned. The compare exchange
> + operation must be performed using MP safe mechanisms.
> +
> + @param Value A pointer to the 16-bit value for the
> + compare exchange operation.
> + @param CompareValue 16-bit value used in compare operation.
> + @param ExchangeValue 16-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT16
> +EFIAPI
> +InternalSyncCompareExchange16 (
> + IN volatile UINT16 *Value,
> + IN UINT16 CompareValue,
> + IN UINT16 ExchangeValue
> + )
> +{
> + return *Value != CompareValue ? *Value :
> + ((*Value = ExchangeValue), CompareValue);
> +}
> +
> +/**
> + Performs an atomic compare exchange operation on a 32-bit
> + unsigned integer.
> +
> + Performs an atomic compare exchange operation on the 32-bit
> + unsigned integer specified by Value. If Value is equal to
> + CompareValue, then Value is set to ExchangeValue and
> + CompareValue is returned. If Value is not equal to
> + CompareValue, then Value is returned. The compare exchange
> + operation must be performed using MP safe mechanisms.
> +
> + @param Value A pointer to the 32-bit value for the
> + compare exchange operation.
> + @param CompareValue 32-bit value used in compare operation.
> + @param ExchangeValue 32-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT32
> +EFIAPI
> +InternalSyncCompareExchange32 (
> + IN volatile UINT32 *Value,
> + IN UINT32 CompareValue,
> + IN UINT32 ExchangeValue
> + )
> +{
> + return *Value != CompareValue ? *Value :
> + ((*Value = ExchangeValue), CompareValue);
> +}
> +
> +/**
> + Performs an atomic compare exchange operation on a 64-bit unsigned
> integer.
> +
> + Performs an atomic compare exchange operation on the 64-bit unsigned
> integer specified
> + by Value. If Value is equal to CompareValue, then Value is set to
> ExchangeValue and
> + CompareValue is returned. If Value is not equal to CompareValue, then
> Value is returned.
> + The compare exchange operation must be performed using MP safe
> mechanisms.
> +
> + @param Value A pointer to the 64-bit value for the compare
> exchange
> + operation.
> + @param CompareValue 64-bit value used in compare operation.
> + @param ExchangeValue 64-bit value used in exchange operation.
> +
> + @return The original *Value before exchange.
> +
> +**/
> +UINT64
> +EFIAPI
> +InternalSyncCompareExchange64 (
> + IN volatile UINT64 *Value,
> + IN UINT64 CompareValue,
> + IN UINT64 ExchangeValue
> + )
> +{
> + return *Value != CompareValue ? *Value :
> + ((*Value = ExchangeValue), CompareValue);
> +}
> +
> +/**
> + Performs an atomic increment of an 32-bit unsigned integer.
> +
> + Performs an atomic increment of the 32-bit unsigned integer specified by
> + Value and returns the incremented value. The increment operation must
> be
> + performed using MP safe mechanisms. The state of the return value is
> not
> + guaranteed to be MP safe.
> +
> + @param Value A pointer to the 32-bit value to increment.
> +
> + @return The incremented value.
> +
> +**/
> +UINT32
> +EFIAPI
> +InternalSyncIncrement (
> + IN volatile UINT32 *Value
> + )
> +{
> + return ++*Value;
> +}
> +
> +/**
> + Performs an atomic decrement of an 32-bit unsigned integer.
> +
> + Performs an atomic decrement of the 32-bit unsigned integer specified
> by
> + Value and returns the decrement value. The decrement operation must
> be
> + performed using MP safe mechanisms. The state of the return value is
> not
> + guaranteed to be MP safe.
> +
> + @param Value A pointer to the 32-bit value to decrement.
> +
> + @return The decrement value.
> +
> +**/
> +UINT32
> +EFIAPI
> +InternalSyncDecrement (
> + IN volatile UINT32 *Value
> + )
> +{
> + return --*Value;
> +}
> --
> 1.9.5.msysgit.0
>
> _______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel