diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index d066f1be24..b0bbe8cef8 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5,6 +5,8 @@ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
Copyright (c) Microsoft Corporation.
+Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ 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 diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index 3586beb0ab..a57ae2da31 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -4,6 +4,7 @@ # Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
# # 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 diff --git a/MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c b/MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c new file mode 100644 index 0000000000..88d0877a2f --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/CpuBreakpoint.c @@ -0,0 +1,27 @@ +/** @file + CPU breakpoint for RISC-V + + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + 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 (); +} diff --git a/MdePkg/Library/BaseLib/RiscV64/CpuPause.c b/MdePkg/Library/BaseLib/RiscV64/CpuPause.c new file mode 100644 index 0000000000..9931bad294 --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/CpuPause.c @@ -0,0 +1,29 @@ +/** @file + CPU pause for RISC-V + + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + 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 (); +} + diff --git a/MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c b/MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c new file mode 100644 index 0000000000..867086c09c --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/DisableInterrupts.c @@ -0,0 +1,24 @@ +/** @file + CPU disable interrupt function for RISC-V + + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include "BaseLibInternals.h" + +extern VOID RiscVDisableSupervisorModeInterrupts (VOID); + +/** + Disables CPU interrupts. + +**/ +VOID +EFIAPI +DisableInterrupts ( + VOID + ) +{ + RiscVDisableSupervisorModeInterrupts (); +} + diff --git a/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c b/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c new file mode 100644 index 0000000000..22ef73067e --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/EnableInterrupts.c @@ -0,0 +1,25 @@ +/** @file + CPU enable interrupt function for RISC-V + + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "BaseLibInternals.h" + +extern VOID RiscVEnableSupervisorModeInterrupt (VOID); + +/** + Enables CPU interrupts. + +**/ +VOID +EFIAPI +EnableInterrupts ( + VOID + ) +{ + RiscVEnableSupervisorModeInterrupt (); +} + diff --git a/MdePkg/Library/BaseLib/RiscV64/FlushCache.S b/MdePkg/Library/BaseLib/RiscV64/FlushCache.S new file mode 100644 index 0000000000..7c10fdd268 --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/FlushCache.S @@ -0,0 +1,21 @@ +//------------------------------------------------------------------------------ +// +// RISC-V cache operation. +// +// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+// +// 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 diff --git a/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c b/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c new file mode 100644 index 0000000000..292f1ec441 --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/GetInterruptState.c @@ -0,0 +1,35 @@ +/** @file + CPU get interrupt state function for RISC-V + + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + 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; +} + + diff --git a/MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c b/MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c new file mode 100644 index 0000000000..0bb292141d --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/InternalSwitchStack.c @@ -0,0 +1,55 @@ +/** @file + Switch stack function for RISC-V + + Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + 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); +} diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S b/MdePkg/Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S new file mode 100644 index 0000000000..ccf91df816 --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVCpuBreakpoint.S @@ -0,0 +1,14 @@ +//------------------------------------------------------------------------------ +// +// CpuBreakpoint for RISC-V +// +// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//------------------------------------------------------------------------------ + +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 0000000000..6660c2fcb3 --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVCpuPause.S @@ -0,0 +1,14 @@ +//------------------------------------------------------------------------------ +// +// CpuPause for RISC-V +// +// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//------------------------------------------------------------------------------ + +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 0000000000..766fcfb9cb --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVInterrupt.S @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +// +// RISC-V Supervisor Mode interrupt enable/disable +// +// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+// +// 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 + diff --git a/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S b/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S new file mode 100644 index 0000000000..34486eabba --- /dev/null +++ b/MdePkg/Library/BaseLib/RiscV64/RiscVSetJumpLongJump.S @@ -0,0 +1,55 @@ +//------------------------------------------------------------------------------ +// +// Set/Long jump for RISC-V +// +// Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+// +// 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