MdePkg/BaseLib: BaseLib for RISCV64 architecture

Add RISC-V RV64 BaseLib functions.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2672

Signed-off-by: Abner Chang <abner.chang@hpe.com>
Co-authored-by: Gilbert Chen <gilbert.chen@hpe.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Zhiguang Liu <zhiguang.liu@intel.com>

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Gilbert Chen <gilbert.chen@hpe.com>
This commit is contained in:
Abner Chang 2020-04-07 15:53:22 +08:00 committed by mergify[bot]
parent d3abb40d77
commit 7601b251fd
13 changed files with 374 additions and 1 deletions

View File

@ -5,6 +5,8 @@
Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.<BR>
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -125,6 +127,30 @@ typedef struct {
#endif // defined (MDE_CPU_AARCH64)
#if defined (MDE_CPU_RISCV64)
///
/// The RISC-V architecture context buffer used by SetJump() and LongJump().
///
typedef struct {
UINT64 RA;
UINT64 S0;
UINT64 S1;
UINT64 S2;
UINT64 S3;
UINT64 S4;
UINT64 S5;
UINT64 S6;
UINT64 S7;
UINT64 S8;
UINT64 S9;
UINT64 S10;
UINT64 S11;
UINT64 SP;
} BASE_LIBRARY_JUMP_BUFFER;
#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
#endif // defined (MDE_CPU_RISCV64)
//
// String Services

View File

@ -4,6 +4,7 @@
# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@ -20,7 +21,7 @@
LIBRARY_CLASS = BaseLib
#
# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64
# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64
#
[Sources]
@ -381,6 +382,21 @@
AArch64/CpuBreakpoint.asm | MSFT
AArch64/SpeculationBarrier.asm | MSFT
[Sources.RISCV64]
Math64.c
Unaligned.c
RiscV64/InternalSwitchStack.c
RiscV64/CpuBreakpoint.c
RiscV64/GetInterruptState.c
RiscV64/DisableInterrupts.c
RiscV64/EnableInterrupts.c
RiscV64/CpuPause.c
RiscV64/RiscVSetJumpLongJump.S | GCC
RiscV64/RiscVCpuBreakpoint.S | GCC
RiscV64/RiscVCpuPause.S | GCC
RiscV64/RiscVInterrupt.S | GCC
RiscV64/FlushCache.S | GCC
[Packages]
MdePkg/MdePkg.dec

View File

@ -0,0 +1,27 @@
/** @file
CPU breakpoint for RISC-V
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#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 ();
}

View File

@ -0,0 +1,29 @@
/** @file
CPU pause for RISC-V
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#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 ();
}

View File

@ -0,0 +1,24 @@
/** @file
CPU disable interrupt function for RISC-V
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "BaseLibInternals.h"
extern VOID RiscVDisableSupervisorModeInterrupts (VOID);
/**
Disables CPU interrupts.
**/
VOID
EFIAPI
DisableInterrupts (
VOID
)
{
RiscVDisableSupervisorModeInterrupts ();
}

View File

@ -0,0 +1,25 @@
/** @file
CPU enable interrupt function for RISC-V
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "BaseLibInternals.h"
extern VOID RiscVEnableSupervisorModeInterrupt (VOID);
/**
Enables CPU interrupts.
**/
VOID
EFIAPI
EnableInterrupts (
VOID
)
{
RiscVEnableSupervisorModeInterrupt ();
}

View File

@ -0,0 +1,21 @@
//------------------------------------------------------------------------------
//
// RISC-V cache operation.
//
// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//------------------------------------------------------------------------------
.align 3
ASM_GLOBAL ASM_PFX(RiscVInvalidateInstCacheAsm)
ASM_GLOBAL ASM_PFX(RiscVInvalidateDataCacheAsm)
ASM_PFX(RiscVInvalidateInstCacheAsm):
fence.i
ret
ASM_PFX(RiscVInvalidateDataCacheAsm):
fence
ret

View File

@ -0,0 +1,35 @@
/** @file
CPU get interrupt state function for RISC-V
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "BaseLibInternals.h"
extern UINT32 RiscVGetSupervisorModeInterrupts (VOID);
/**
Retrieves the current CPU interrupt state.
Returns TRUE is interrupts are currently enabled. Otherwise
returns FALSE.
@retval TRUE CPU interrupts are enabled.
@retval FALSE CPU interrupts are disabled.
**/
BOOLEAN
EFIAPI
GetInterruptState (
VOID
)
{
unsigned long RetValue;
RetValue = RiscVGetSupervisorModeInterrupts ();
return RetValue? TRUE: FALSE;
}

View File

@ -0,0 +1,55 @@
/** @file
Switch stack function for RISC-V
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#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 ((DEBUG_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);
}

View File

@ -0,0 +1,14 @@
//------------------------------------------------------------------------------
//
// CpuBreakpoint for RISC-V
//
// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(RiscVCpuBreakpoint)
ASM_PFX(RiscVCpuBreakpoint):
ebreak
ret

View File

@ -0,0 +1,14 @@
//------------------------------------------------------------------------------
//
// CpuPause for RISC-V
//
// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(RiscVCpuPause)
ASM_PFX(RiscVCpuPause):
nop
ret

View File

@ -0,0 +1,32 @@
//------------------------------------------------------------------------------
//
// RISC-V Supervisor Mode interrupt enable/disable
//
// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(RiscVDisableSupervisorModeInterrupts)
ASM_GLOBAL ASM_PFX(RiscVEnableSupervisorModeInterrupt)
ASM_GLOBAL ASM_PFX(RiscVGetSupervisorModeInterrupts)
# define MSTATUS_SIE 0x00000002
# define CSR_SSTATUS 0x100
ASM_PFX(RiscVDisableSupervisorModeInterrupts):
li a1, MSTATUS_SIE
csrc CSR_SSTATUS, a1
ret
ASM_PFX(RiscVEnableSupervisorModeInterrupt):
li a1, MSTATUS_SIE
csrs CSR_SSTATUS, a1
ret
ASM_PFX(RiscVGetSupervisorModeInterrupts):
csrr a0, CSR_SSTATUS
andi a0, a0, MSTATUS_SIE
ret

View File

@ -0,0 +1,55 @@
//------------------------------------------------------------------------------
//
// Set/Long jump for RISC-V
//
// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//------------------------------------------------------------------------------
# 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