Sounds good. Thanks!

> Hi Jiewen,
> Below is my answer
> 
> >>>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?
> I will have comment on this.
> 
> >>>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.
> Actually, RISC-V only support MMIO, no I/O instruction. However, I use
> PC/AT architecture as RISC-V platform spec. Therefore, I/O access is required
> for those PC/AT component(drivers). I will have comment in I/O lib.
> 
> >>>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.
> I don't think compiler will generate AMO instruction. I missed this one, I 
> will
> revise it. 
> 
> Thanks for your comment.
> Abner
> 
> -----Original Message-----
> From: Yao, Jiewen [mailto:[email protected]]
> Sent: Monday, May 09, 2016 10:04 AM
> To: Chang, Abner (HPS SW/FW Technologist) <[email protected]>;
> [email protected]
> Cc: AbnerChang <[email protected]>; Gao, Liming
> <[email protected]>
> Subject: RE: [edk2] [PATCH 2/2] MdePkg: MDE implementations for RISC-V
> arch.
> 
> 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

Reply via email to