mirror of https://github.com/acidanthera/audk.git
MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4053 Add LoongArch LOONGARCH64 BaseLib functions. Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Zhiguang Liu <zhiguang.liu@intel.com> Signed-off-by: Chao Li <lichao@loongson.cn> Co-authored-by: Baoqi Zhang <zhangbaoqi@loongson.cn> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
parent
f0a704f9b5
commit
cd24eb578b
|
@ -6,6 +6,7 @@ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>
|
||||||
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||||
Copyright (c) Microsoft Corporation.<BR>
|
Copyright (c) Microsoft Corporation.<BR>
|
||||||
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
|
||||||
|
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
@ -152,6 +153,29 @@ typedef struct {
|
||||||
|
|
||||||
#endif // defined (MDE_CPU_RISCV64)
|
#endif // defined (MDE_CPU_RISCV64)
|
||||||
|
|
||||||
|
#if defined (MDE_CPU_LOONGARCH64)
|
||||||
|
///
|
||||||
|
/// The LoongArch architecture context buffer used by SetJump() and LongJump()
|
||||||
|
///
|
||||||
|
typedef struct {
|
||||||
|
UINT64 S0;
|
||||||
|
UINT64 S1;
|
||||||
|
UINT64 S2;
|
||||||
|
UINT64 S3;
|
||||||
|
UINT64 S4;
|
||||||
|
UINT64 S5;
|
||||||
|
UINT64 S6;
|
||||||
|
UINT64 S7;
|
||||||
|
UINT64 S8;
|
||||||
|
UINT64 SP;
|
||||||
|
UINT64 FP;
|
||||||
|
UINT64 RA;
|
||||||
|
} BASE_LIBRARY_JUMP_BUFFER;
|
||||||
|
|
||||||
|
#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
|
||||||
|
|
||||||
|
#endif // defined (MDE_CPU_LOONGARCH64)
|
||||||
|
|
||||||
//
|
//
|
||||||
// String Services
|
// String Services
|
||||||
//
|
//
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
LIBRARY_CLASS = BaseLib
|
LIBRARY_CLASS = BaseLib
|
||||||
|
|
||||||
#
|
#
|
||||||
# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64
|
# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64
|
||||||
#
|
#
|
||||||
|
|
||||||
[Sources]
|
[Sources]
|
||||||
|
@ -402,6 +402,20 @@
|
||||||
RiscV64/RiscVInterrupt.S | GCC
|
RiscV64/RiscVInterrupt.S | GCC
|
||||||
RiscV64/FlushCache.S | GCC
|
RiscV64/FlushCache.S | GCC
|
||||||
|
|
||||||
|
[Sources.LOONGARCH64]
|
||||||
|
Math64.c
|
||||||
|
Unaligned.c
|
||||||
|
LoongArch64/InternalSwitchStack.c
|
||||||
|
LoongArch64/GetInterruptState.S | GCC
|
||||||
|
LoongArch64/EnableInterrupts.S | GCC
|
||||||
|
LoongArch64/DisableInterrupts.S | GCC
|
||||||
|
LoongArch64/Barrier.S | GCC
|
||||||
|
LoongArch64/MemoryFence.S | GCC
|
||||||
|
LoongArch64/CpuBreakpoint.S | GCC
|
||||||
|
LoongArch64/CpuPause.S | GCC
|
||||||
|
LoongArch64/SetJumpLongJump.S | GCC
|
||||||
|
LoongArch64/SwitchStack.S | GCC
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# LoongArch Barrier Operations
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmDataBarrierLoongArch)
|
||||||
|
ASM_GLOBAL ASM_PFX(AsmInstructionBarrierLoongArch)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Data barrier operation for LoongArch.
|
||||||
|
#
|
||||||
|
ASM_PFX(AsmDataBarrierLoongArch):
|
||||||
|
dbar 0
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
|
||||||
|
#
|
||||||
|
# Instruction barrier operation for LoongArch.
|
||||||
|
#
|
||||||
|
ASM_PFX(AsmInstructionBarrierLoongArch):
|
||||||
|
ibar 0
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
|
||||||
|
.end
|
|
@ -0,0 +1,24 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# CpuBreakpoint for LoongArch
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(CpuBreakpoint)
|
||||||
|
|
||||||
|
#/**
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#**/
|
||||||
|
|
||||||
|
ASM_PFX(CpuBreakpoint):
|
||||||
|
break 3
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
.end
|
|
@ -0,0 +1,31 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# CpuPause for LoongArch
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(CpuPause)
|
||||||
|
|
||||||
|
#/**
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#**/
|
||||||
|
|
||||||
|
ASM_PFX(CpuPause):
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
.end
|
|
@ -0,0 +1,21 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# LoongArch interrupt disable
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(DisableInterrupts)
|
||||||
|
|
||||||
|
#/**
|
||||||
|
# Disables CPU interrupts.
|
||||||
|
#**/
|
||||||
|
|
||||||
|
ASM_PFX(DisableInterrupts):
|
||||||
|
li.w $t0, 0x4
|
||||||
|
csrxchg $zero, $t0, 0x0
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
.end
|
|
@ -0,0 +1,21 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# LoongArch interrupt enable
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(EnableInterrupts)
|
||||||
|
|
||||||
|
#/**
|
||||||
|
# Enables CPU interrupts.
|
||||||
|
#**/
|
||||||
|
|
||||||
|
ASM_PFX(EnableInterrupts):
|
||||||
|
li.w $t0, 0x4
|
||||||
|
csrxchg $t0, $t0, 0x0
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
.end
|
|
@ -0,0 +1,35 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Get LoongArch interrupt status
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(GetInterruptState)
|
||||||
|
|
||||||
|
#/**
|
||||||
|
# Retrieves the current CPU interrupt state.
|
||||||
|
#
|
||||||
|
# Returns TRUE means interrupts are currently enabled. Otherwise,
|
||||||
|
# returns FALSE.
|
||||||
|
#
|
||||||
|
# @retval TRUE CPU interrupts are enabled.
|
||||||
|
# @retval FALSE CPU interrupts are disabled.
|
||||||
|
#
|
||||||
|
#**/
|
||||||
|
|
||||||
|
ASM_PFX(GetInterruptState):
|
||||||
|
li.w $t1, 0x4
|
||||||
|
csrrd $t0, 0x0
|
||||||
|
and $t0, $t0, $t1
|
||||||
|
beqz $t0, 1f
|
||||||
|
li.w $a0, 0x1
|
||||||
|
b 2f
|
||||||
|
1:
|
||||||
|
li.w $a0, 0x0
|
||||||
|
2:
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
.end
|
|
@ -0,0 +1,58 @@
|
||||||
|
/** @file
|
||||||
|
SwitchStack() function for LoongArch.
|
||||||
|
|
||||||
|
Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "BaseLibInternals.h"
|
||||||
|
|
||||||
|
UINTN
|
||||||
|
EFIAPI
|
||||||
|
InternalSwitchStackAsm (
|
||||||
|
IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
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.
|
||||||
|
|
||||||
|
If EntryPoint is NULL, then ASSERT().
|
||||||
|
If NewStack is NULL, then ASSERT().
|
||||||
|
|
||||||
|
@param[in] EntryPoint A pointer to function to call with the new stack.
|
||||||
|
@param[in] Context1 A pointer to the context to pass into the EntryPoint
|
||||||
|
function.
|
||||||
|
@param[in] Context2 A pointer to the context to pass into the EntryPoint
|
||||||
|
function.
|
||||||
|
@param[in] NewStack A pointer to the new stack to use for the EntryPoint
|
||||||
|
function.
|
||||||
|
@param[in] 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;
|
||||||
|
|
||||||
|
JumpBuffer.RA = (UINTN)EntryPoint;
|
||||||
|
JumpBuffer.SP = (UINTN)NewStack - sizeof (VOID *);
|
||||||
|
JumpBuffer.SP -= sizeof (Context1) + sizeof (Context2);
|
||||||
|
((VOID **)(UINTN)JumpBuffer.SP)[0] = Context1;
|
||||||
|
((VOID **)(UINTN)JumpBuffer.SP)[1] = Context2;
|
||||||
|
|
||||||
|
InternalSwitchStackAsm (&JumpBuffer);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# MemoryFence() for LoongArch
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(MemoryFence)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Memory fence for LoongArch
|
||||||
|
#
|
||||||
|
ASM_PFX(MemoryFence):
|
||||||
|
b AsmDataBarrierLoongArch
|
||||||
|
.end
|
|
@ -0,0 +1,49 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Set/Long jump for LoongArch
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define STORE st.d /* 64 bit mode regsave instruction */
|
||||||
|
#define LOAD ld.d /* 64 bit mode regload instruction */
|
||||||
|
#define RSIZE 8 /* 64 bit mode register size */
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(SetJump)
|
||||||
|
ASM_GLOBAL ASM_PFX(InternalLongJump)
|
||||||
|
|
||||||
|
ASM_PFX(SetJump):
|
||||||
|
STORE $s0, $a0, RSIZE * 0
|
||||||
|
STORE $s1, $a0, RSIZE * 1
|
||||||
|
STORE $s2, $a0, RSIZE * 2
|
||||||
|
STORE $s3, $a0, RSIZE * 3
|
||||||
|
STORE $s4, $a0, RSIZE * 4
|
||||||
|
STORE $s5, $a0, RSIZE * 5
|
||||||
|
STORE $s6, $a0, RSIZE * 6
|
||||||
|
STORE $s7, $a0, RSIZE * 7
|
||||||
|
STORE $s8, $a0, RSIZE * 8
|
||||||
|
STORE $sp, $a0, RSIZE * 9
|
||||||
|
STORE $fp, $a0, RSIZE * 10
|
||||||
|
STORE $ra, $a0, RSIZE * 11
|
||||||
|
li.w $a0, 0 # Setjmp return
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
|
||||||
|
ASM_PFX(InternalLongJump):
|
||||||
|
LOAD $ra, $a0, RSIZE * 11
|
||||||
|
LOAD $s0, $a0, RSIZE * 0
|
||||||
|
LOAD $s1, $a0, RSIZE * 1
|
||||||
|
LOAD $s2, $a0, RSIZE * 2
|
||||||
|
LOAD $s3, $a0, RSIZE * 3
|
||||||
|
LOAD $s4, $a0, RSIZE * 4
|
||||||
|
LOAD $s5, $a0, RSIZE * 5
|
||||||
|
LOAD $s6, $a0, RSIZE * 6
|
||||||
|
LOAD $s7, $a0, RSIZE * 7
|
||||||
|
LOAD $s8, $a0, RSIZE * 8
|
||||||
|
LOAD $sp, $a0, RSIZE * 9
|
||||||
|
LOAD $fp, $a0, RSIZE * 10
|
||||||
|
move $a0, $a1
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
.end
|
|
@ -0,0 +1,39 @@
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# InternalSwitchStackAsm for LoongArch
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define STORE st.d /* 64 bit mode regsave instruction */
|
||||||
|
#define LOAD ld.d /* 64 bit mode regload instruction */
|
||||||
|
#define RSIZE 8 /* 64 bit mode register size */
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(InternalSwitchStackAsm)
|
||||||
|
|
||||||
|
/**
|
||||||
|
This allows the caller to switch the stack and goes to the new entry point
|
||||||
|
|
||||||
|
@param JumpBuffer A pointer to CPU context buffer.
|
||||||
|
**/
|
||||||
|
|
||||||
|
ASM_PFX(InternalSwitchStackAsm):
|
||||||
|
LOAD $ra, $a0, RSIZE * 11
|
||||||
|
LOAD $s0, $a0, RSIZE * 0
|
||||||
|
LOAD $s1, $a0, RSIZE * 1
|
||||||
|
LOAD $s2, $a0, RSIZE * 2
|
||||||
|
LOAD $s3, $a0, RSIZE * 3
|
||||||
|
LOAD $s4, $a0, RSIZE * 4
|
||||||
|
LOAD $s5, $a0, RSIZE * 5
|
||||||
|
LOAD $s6, $a0, RSIZE * 6
|
||||||
|
LOAD $s7, $a0, RSIZE * 7
|
||||||
|
LOAD $s8, $a0, RSIZE * 8
|
||||||
|
LOAD $sp, $a0, RSIZE * 9
|
||||||
|
LOAD $fp, $a0, RSIZE * 10
|
||||||
|
LOAD $a0, $sp, 0
|
||||||
|
LOAD $a1, $sp, 8
|
||||||
|
jirl $zero, $ra, 0
|
||||||
|
.end
|
Loading…
Reference in New Issue