* [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture. @ 2022-09-08 4:51 Chao Li 2022-09-09 17:20 ` Michael D Kinney 0 siblings, 1 reply; 3+ messages in thread From: Chao Li @ 2022-09-08 4:51 UTC (permalink / raw) To: devel; +Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Baoqi Zhang 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> --- MdePkg/Include/Library/BaseLib.h | 24 ++ MdePkg/Library/BaseLib/BaseLib.inf | 13 + .../BaseLib/LoongArch64/CpuBreakpoint.S | 24 ++ MdePkg/Library/BaseLib/LoongArch64/CpuPause.S | 31 +++ .../BaseLib/LoongArch64/DisableInterrupts.S | 21 ++ .../BaseLib/LoongArch64/EnableInterrupts.S | 21 ++ .../BaseLib/LoongArch64/GetInterruptState.S | 35 +++ .../BaseLib/LoongArch64/InternalSwitchStack.c | 58 +++++ .../Library/BaseLib/LoongArch64/MemoryFence.S | 19 ++ .../BaseLib/LoongArch64/SetJumpLongJump.S | 49 ++++ .../Library/BaseLib/LoongArch64/SwitchStack.S | 39 +++ .../Library/BaseLib/LoongArch64/Unaligned.c | 242 ++++++++++++++++++ 12 files changed, 576 insertions(+) create mode 100644 MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/CpuPause.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c create mode 100644 MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/Unaligned.c diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index a6f9a194ef..f3f59f21c2 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -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> Copyright (c) Microsoft Corporation.<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 @@ -152,6 +153,29 @@ typedef struct { #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 // diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index 6be5be9428..86de3ae7cd 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -402,6 +402,19 @@ RiscV64/RiscVInterrupt.S | GCC RiscV64/FlushCache.S | GCC +[Sources.LOONGARCH64] + Math64.c + LoongArch64/Unaligned.c + LoongArch64/InternalSwitchStack.c + LoongArch64/GetInterruptState.S | GCC + LoongArch64/EnableInterrupts.S | GCC + LoongArch64/DisableInterrupts.S | GCC + LoongArch64/MemoryFence.S | GCC + LoongArch64/CpuBreakpoint.S | GCC + LoongArch64/CpuPause.S | GCC + LoongArch64/SetJumpLongJump.S | GCC + LoongArch64/SwitchStack.S | GCC + [Packages] MdePkg/MdePkg.dec diff --git a/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S b/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S new file mode 100644 index 0000000000..4e022e9bb5 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S @@ -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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S b/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S new file mode 100644 index 0000000000..e9140e8742 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S @@ -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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S b/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S new file mode 100644 index 0000000000..0f228339af --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S @@ -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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S b/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S new file mode 100644 index 0000000000..3c34fb2cdd --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S @@ -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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S b/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S new file mode 100644 index 0000000000..bfd1f2d5f7 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S @@ -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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c b/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c new file mode 100644 index 0000000000..859bc96329 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c @@ -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); +} diff --git a/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S b/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S new file mode 100644 index 0000000000..0d8dc10914 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S @@ -0,0 +1,19 @@ +#------------------------------------------------------------------------------ +# +# MemoryFence() for LoongArch64 +# +# 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 LoongArch64 +# +ASM_PFX(MemoryFence): + dbar 0 + jirl $zero, $ra, 0 + .end diff --git a/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S b/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S new file mode 100644 index 0000000000..1c6ee54b6f --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S @@ -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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S b/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S new file mode 100644 index 0000000000..ad9aa8b343 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S @@ -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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c b/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c new file mode 100644 index 0000000000..335379ecb1 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c @@ -0,0 +1,242 @@ +/** @file + Unaligned access functions of BaseLib for LoongArch. + + Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#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[in] Buffer The 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 + ) +{ + volatile UINT8 LowerByte; + volatile UINT8 HigherByte; + + ASSERT (Buffer != NULL); + + LowerByte = ((UINT8 *)Buffer)[0]; + HigherByte = ((UINT8 *)Buffer)[1]; + + return (UINT16)(LowerByte | (HigherByte << 8)); +} + +/** + 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[out] Buffer The pointer to a 16-bit value that may be unaligned. + @param[in] 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 + ) +{ + ASSERT (Buffer != NULL); + + ((volatile UINT8 *)Buffer)[0] = (UINT8)Value; + ((volatile UINT8 *)Buffer)[1] = (UINT8)(Value >> 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[in] Buffer The 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 + ) +{ + ASSERT (Buffer != NULL); + + return (UINT32)(ReadUnaligned16 ((UINT16 *)Buffer) | + (((UINT8 *)Buffer)[2] << 16)); +} + +/** + 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[out] Buffer The pointer to a 24-bit value that may be unaligned. + @param[in] 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 + ) +{ + ASSERT (Buffer != NULL); + + WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)Value); + *(UINT8 *)((UINT16 *)Buffer + 1) = (UINT8)(Value >> 16); + 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[in] Buffer The 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 + ) +{ + UINT16 LowerBytes; + UINT16 HigherBytes; + + ASSERT (Buffer != NULL); + + LowerBytes = ReadUnaligned16 ((UINT16 *)Buffer); + HigherBytes = ReadUnaligned16 ((UINT16 *)Buffer + 1); + + return (UINT32)(LowerBytes | (HigherBytes << 16)); +} + +/** + 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[out] Buffer The pointer to a 32-bit value that may be unaligned. + @param[in] Value 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 + ) +{ + ASSERT (Buffer != NULL); + + WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)Value); + WriteUnaligned16 ((UINT16 *)Buffer + 1, (UINT16)(Value >> 16)); + 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[in] Buffer The 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 + ) +{ + UINT32 LowerBytes; + UINT32 HigherBytes; + + ASSERT (Buffer != NULL); + + LowerBytes = ReadUnaligned32 ((UINT32 *)Buffer); + HigherBytes = ReadUnaligned32 ((UINT32 *)Buffer + 1); + + return (UINT64)(LowerBytes | LShiftU64 (HigherBytes, 32)); +} + +/** + 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[out] Buffer The pointer to a 64-bit value that may be unaligned. + @param[in] Value 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 + ) +{ + ASSERT (Buffer != NULL); + + WriteUnaligned32 ((UINT32 *)Buffer, (UINT32)Value); + WriteUnaligned32 ((UINT32 *)Buffer + 1, (UINT32)RShiftU64 (Value, 32)); + return Value; +} -- 2.27.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture. 2022-09-08 4:51 [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture Chao Li @ 2022-09-09 17:20 ` Michael D Kinney 2022-09-11 4:17 ` [edk2-devel] " Chao Li 0 siblings, 1 reply; 3+ messages in thread From: Michael D Kinney @ 2022-09-09 17:20 UTC (permalink / raw) To: Chao Li, devel@edk2.groups.io, Kinney, Michael D Cc: Gao, Liming, Liu, Zhiguang, Baoqi Zhang For unaligned read/write functions, can you use one of the other BaseLib source files that already provides a generic implementation? Mike > -----Original Message----- > From: Chao Li <lichao@loongson.cn> > Sent: Wednesday, September 7, 2022 9:52 PM > To: devel@edk2.groups.io > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang > <zhiguang.liu@intel.com>; Baoqi Zhang <zhangbaoqi@loongson.cn> > Subject: [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture. > > 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> > --- > MdePkg/Include/Library/BaseLib.h | 24 ++ > MdePkg/Library/BaseLib/BaseLib.inf | 13 + > .../BaseLib/LoongArch64/CpuBreakpoint.S | 24 ++ > MdePkg/Library/BaseLib/LoongArch64/CpuPause.S | 31 +++ > .../BaseLib/LoongArch64/DisableInterrupts.S | 21 ++ > .../BaseLib/LoongArch64/EnableInterrupts.S | 21 ++ > .../BaseLib/LoongArch64/GetInterruptState.S | 35 +++ > .../BaseLib/LoongArch64/InternalSwitchStack.c | 58 +++++ > .../Library/BaseLib/LoongArch64/MemoryFence.S | 19 ++ > .../BaseLib/LoongArch64/SetJumpLongJump.S | 49 ++++ > .../Library/BaseLib/LoongArch64/SwitchStack.S | 39 +++ > .../Library/BaseLib/LoongArch64/Unaligned.c | 242 ++++++++++++++++++ > 12 files changed, 576 insertions(+) > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/CpuPause.S > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/Unaligned.c > > diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h > index a6f9a194ef..f3f59f21c2 100644 > --- a/MdePkg/Include/Library/BaseLib.h > +++ b/MdePkg/Include/Library/BaseLib.h > @@ -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> > > Copyright (c) Microsoft Corporation.<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 > > > > @@ -152,6 +153,29 @@ typedef struct { > > > #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 > > // > > diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf > index 6be5be9428..86de3ae7cd 100644 > --- a/MdePkg/Library/BaseLib/BaseLib.inf > +++ b/MdePkg/Library/BaseLib/BaseLib.inf > @@ -402,6 +402,19 @@ > RiscV64/RiscVInterrupt.S | GCC > > RiscV64/FlushCache.S | GCC > > > > +[Sources.LOONGARCH64] > > + Math64.c > > + LoongArch64/Unaligned.c > > + LoongArch64/InternalSwitchStack.c > > + LoongArch64/GetInterruptState.S | GCC > > + LoongArch64/EnableInterrupts.S | GCC > > + LoongArch64/DisableInterrupts.S | GCC > > + LoongArch64/MemoryFence.S | GCC > > + LoongArch64/CpuBreakpoint.S | GCC > > + LoongArch64/CpuPause.S | GCC > > + LoongArch64/SetJumpLongJump.S | GCC > > + LoongArch64/SwitchStack.S | GCC > > + > > [Packages] > > MdePkg/MdePkg.dec > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S b/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S > new file mode 100644 > index 0000000000..4e022e9bb5 > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S > @@ -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 > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S b/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S > new file mode 100644 > index 0000000000..e9140e8742 > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S > @@ -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 > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S b/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S > new file mode 100644 > index 0000000000..0f228339af > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S > @@ -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 > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S b/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S > new file mode 100644 > index 0000000000..3c34fb2cdd > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S > @@ -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 > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S b/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S > new file mode 100644 > index 0000000000..bfd1f2d5f7 > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S > @@ -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 > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c > b/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c > new file mode 100644 > index 0000000000..859bc96329 > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c > @@ -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); > > +} > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S b/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S > new file mode 100644 > index 0000000000..0d8dc10914 > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S > @@ -0,0 +1,19 @@ > +#------------------------------------------------------------------------------ > > +# > > +# MemoryFence() for LoongArch64 > > +# > > +# 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 LoongArch64 > > +# > > +ASM_PFX(MemoryFence): > > + dbar 0 > > + jirl $zero, $ra, 0 > > + .end > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S b/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S > new file mode 100644 > index 0000000000..1c6ee54b6f > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S > @@ -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 > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S b/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S > new file mode 100644 > index 0000000000..ad9aa8b343 > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S > @@ -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 > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c b/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c > new file mode 100644 > index 0000000000..335379ecb1 > --- /dev/null > +++ b/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c > @@ -0,0 +1,242 @@ > +/** @file > > + Unaligned access functions of BaseLib for LoongArch. > > + > > + Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR> > > + > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#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[in] Buffer The 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 > > + ) > > +{ > > + volatile UINT8 LowerByte; > > + volatile UINT8 HigherByte; > > + > > + ASSERT (Buffer != NULL); > > + > > + LowerByte = ((UINT8 *)Buffer)[0]; > > + HigherByte = ((UINT8 *)Buffer)[1]; > > + > > + return (UINT16)(LowerByte | (HigherByte << 8)); > > +} > > + > > +/** > > + 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[out] Buffer The pointer to a 16-bit value that may be unaligned. > > + @param[in] 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 > > + ) > > +{ > > + ASSERT (Buffer != NULL); > > + > > + ((volatile UINT8 *)Buffer)[0] = (UINT8)Value; > > + ((volatile UINT8 *)Buffer)[1] = (UINT8)(Value >> 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[in] Buffer The 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 > > + ) > > +{ > > + ASSERT (Buffer != NULL); > > + > > + return (UINT32)(ReadUnaligned16 ((UINT16 *)Buffer) | > > + (((UINT8 *)Buffer)[2] << 16)); > > +} > > + > > +/** > > + 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[out] Buffer The pointer to a 24-bit value that may be unaligned. > > + @param[in] 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 > > + ) > > +{ > > + ASSERT (Buffer != NULL); > > + > > + WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)Value); > > + *(UINT8 *)((UINT16 *)Buffer + 1) = (UINT8)(Value >> 16); > > + 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[in] Buffer The 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 > > + ) > > +{ > > + UINT16 LowerBytes; > > + UINT16 HigherBytes; > > + > > + ASSERT (Buffer != NULL); > > + > > + LowerBytes = ReadUnaligned16 ((UINT16 *)Buffer); > > + HigherBytes = ReadUnaligned16 ((UINT16 *)Buffer + 1); > > + > > + return (UINT32)(LowerBytes | (HigherBytes << 16)); > > +} > > + > > +/** > > + 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[out] Buffer The pointer to a 32-bit value that may be unaligned. > > + @param[in] Value 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 > > + ) > > +{ > > + ASSERT (Buffer != NULL); > > + > > + WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)Value); > > + WriteUnaligned16 ((UINT16 *)Buffer + 1, (UINT16)(Value >> 16)); > > + 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[in] Buffer The 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 > > + ) > > +{ > > + UINT32 LowerBytes; > > + UINT32 HigherBytes; > > + > > + ASSERT (Buffer != NULL); > > + > > + LowerBytes = ReadUnaligned32 ((UINT32 *)Buffer); > > + HigherBytes = ReadUnaligned32 ((UINT32 *)Buffer + 1); > > + > > + return (UINT64)(LowerBytes | LShiftU64 (HigherBytes, 32)); > > +} > > + > > +/** > > + 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[out] Buffer The pointer to a 64-bit value that may be unaligned. > > + @param[in] Value 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 > > + ) > > +{ > > + ASSERT (Buffer != NULL); > > + > > + WriteUnaligned32 ((UINT32 *)Buffer, (UINT32)Value); > > + WriteUnaligned32 ((UINT32 *)Buffer + 1, (UINT32)RShiftU64 (Value, 32)); > > + return Value; > > +} > > -- > 2.27.0 ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [edk2-devel] [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture. 2022-09-09 17:20 ` Michael D Kinney @ 2022-09-11 4:17 ` Chao Li 0 siblings, 0 replies; 3+ messages in thread From: Chao Li @ 2022-09-11 4:17 UTC (permalink / raw) To: devel, michael.d.kinney; +Cc: Gao, Liming, Liu, Zhiguang, Baoqi Zhang Hi Mike, I will check and try it. Thanks, Chao > -----原始邮件----- > 发件人: "Michael D Kinney" <michael.d.kinney@intel.com> > 发送时间:2022-09-10 01:20:37 (星期六) > 收件人: "Chao Li" <lichao@loongson.cn>, "devel@edk2.groups.io" <devel@edk2.groups.io>, "Kinney, Michael D" <michael.d.kinney@intel.com> > 抄送: "Gao, Liming" <gaoliming@byosoft.com.cn>, "Liu, Zhiguang" <zhiguang.liu@intel.com>, "Baoqi Zhang" <zhangbaoqi@loongson.cn> > 主题: Re: [edk2-devel] [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture. > > For unaligned read/write functions, can you use one of the other BaseLib source files > that already provides a generic implementation? > > Mike > > > -----Original Message----- > > From: Chao Li <lichao@loongson.cn> > > Sent: Wednesday, September 7, 2022 9:52 PM > > To: devel@edk2.groups.io > > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang > > <zhiguang.liu@intel.com>; Baoqi Zhang <zhangbaoqi@loongson.cn> > > Subject: [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture. > > > > 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> > > --- > > MdePkg/Include/Library/BaseLib.h | 24 ++ > > MdePkg/Library/BaseLib/BaseLib.inf | 13 + > > .../BaseLib/LoongArch64/CpuBreakpoint.S | 24 ++ > > MdePkg/Library/BaseLib/LoongArch64/CpuPause.S | 31 +++ > > .../BaseLib/LoongArch64/DisableInterrupts.S | 21 ++ > > .../BaseLib/LoongArch64/EnableInterrupts.S | 21 ++ > > .../BaseLib/LoongArch64/GetInterruptState.S | 35 +++ > > .../BaseLib/LoongArch64/InternalSwitchStack.c | 58 +++++ > > .../Library/BaseLib/LoongArch64/MemoryFence.S | 19 ++ > > .../BaseLib/LoongArch64/SetJumpLongJump.S | 49 ++++ > > .../Library/BaseLib/LoongArch64/SwitchStack.S | 39 +++ > > .../Library/BaseLib/LoongArch64/Unaligned.c | 242 ++++++++++++++++++ > > 12 files changed, 576 insertions(+) > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/CpuPause.S > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S > > create mode 100644 MdePkg/Library/BaseLib/LoongArch64/Unaligned.c > > > > diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h > > index a6f9a194ef..f3f59f21c2 100644 > > --- a/MdePkg/Include/Library/BaseLib.h > > +++ b/MdePkg/Include/Library/BaseLib.h > > @@ -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> > > > > Copyright (c) Microsoft Corporation.<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 > > > > > > > > @@ -152,6 +153,29 @@ typedef struct { > > > > > > #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 > > > > // > > > > diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf > > index 6be5be9428..86de3ae7cd 100644 > > --- a/MdePkg/Library/BaseLib/BaseLib.inf > > +++ b/MdePkg/Library/BaseLib/BaseLib.inf > > @@ -402,6 +402,19 @@ > > RiscV64/RiscVInterrupt.S | GCC > > > > RiscV64/FlushCache.S | GCC > > > > > > > > +[Sources.LOONGARCH64] > > > > + Math64.c > > > > + LoongArch64/Unaligned.c > > > > + LoongArch64/InternalSwitchStack.c > > > > + LoongArch64/GetInterruptState.S | GCC > > > > + LoongArch64/EnableInterrupts.S | GCC > > > > + LoongArch64/DisableInterrupts.S | GCC > > > > + LoongArch64/MemoryFence.S | GCC > > > > + LoongArch64/CpuBreakpoint.S | GCC > > > > + LoongArch64/CpuPause.S | GCC > > > > + LoongArch64/SetJumpLongJump.S | GCC > > > > + LoongArch64/SwitchStack.S | GCC > > > > + > > > > [Packages] > > > > MdePkg/MdePkg.dec > > > > > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S b/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S > > new file mode 100644 > > index 0000000000..4e022e9bb5 > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/CpuBreakpoint.S > > @@ -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 > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S b/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S > > new file mode 100644 > > index 0000000000..e9140e8742 > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/CpuPause.S > > @@ -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 > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S b/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S > > new file mode 100644 > > index 0000000000..0f228339af > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/DisableInterrupts.S > > @@ -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 > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S b/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S > > new file mode 100644 > > index 0000000000..3c34fb2cdd > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/EnableInterrupts.S > > @@ -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 > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S b/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S > > new file mode 100644 > > index 0000000000..bfd1f2d5f7 > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/GetInterruptState.S > > @@ -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 > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c > > b/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c > > new file mode 100644 > > index 0000000000..859bc96329 > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/InternalSwitchStack.c > > @@ -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); > > > > +} > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S b/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S > > new file mode 100644 > > index 0000000000..0d8dc10914 > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/MemoryFence.S > > @@ -0,0 +1,19 @@ > > +#------------------------------------------------------------------------------ > > > > +# > > > > +# MemoryFence() for LoongArch64 > > > > +# > > > > +# 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 LoongArch64 > > > > +# > > > > +ASM_PFX(MemoryFence): > > > > + dbar 0 > > > > + jirl $zero, $ra, 0 > > > > + .end > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S b/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S > > new file mode 100644 > > index 0000000000..1c6ee54b6f > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/SetJumpLongJump.S > > @@ -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 > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S b/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S > > new file mode 100644 > > index 0000000000..ad9aa8b343 > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/SwitchStack.S > > @@ -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 > > > > diff --git a/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c b/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c > > new file mode 100644 > > index 0000000000..335379ecb1 > > --- /dev/null > > +++ b/MdePkg/Library/BaseLib/LoongArch64/Unaligned.c > > @@ -0,0 +1,242 @@ > > +/** @file > > > > + Unaligned access functions of BaseLib for LoongArch. > > > > + > > > > + Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR> > > > > + > > > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > > > + > > > > +**/ > > > > + > > > > +#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[in] Buffer The 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 > > > > + ) > > > > +{ > > > > + volatile UINT8 LowerByte; > > > > + volatile UINT8 HigherByte; > > > > + > > > > + ASSERT (Buffer != NULL); > > > > + > > > > + LowerByte = ((UINT8 *)Buffer)[0]; > > > > + HigherByte = ((UINT8 *)Buffer)[1]; > > > > + > > > > + return (UINT16)(LowerByte | (HigherByte << 8)); > > > > +} > > > > + > > > > +/** > > > > + 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[out] Buffer The pointer to a 16-bit value that may be unaligned. > > > > + @param[in] 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 > > > > + ) > > > > +{ > > > > + ASSERT (Buffer != NULL); > > > > + > > > > + ((volatile UINT8 *)Buffer)[0] = (UINT8)Value; > > > > + ((volatile UINT8 *)Buffer)[1] = (UINT8)(Value >> 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[in] Buffer The 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 > > > > + ) > > > > +{ > > > > + ASSERT (Buffer != NULL); > > > > + > > > > + return (UINT32)(ReadUnaligned16 ((UINT16 *)Buffer) | > > > > + (((UINT8 *)Buffer)[2] << 16)); > > > > +} > > > > + > > > > +/** > > > > + 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[out] Buffer The pointer to a 24-bit value that may be unaligned. > > > > + @param[in] 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 > > > > + ) > > > > +{ > > > > + ASSERT (Buffer != NULL); > > > > + > > > > + WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)Value); > > > > + *(UINT8 *)((UINT16 *)Buffer + 1) = (UINT8)(Value >> 16); > > > > + 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[in] Buffer The 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 > > > > + ) > > > > +{ > > > > + UINT16 LowerBytes; > > > > + UINT16 HigherBytes; > > > > + > > > > + ASSERT (Buffer != NULL); > > > > + > > > > + LowerBytes = ReadUnaligned16 ((UINT16 *)Buffer); > > > > + HigherBytes = ReadUnaligned16 ((UINT16 *)Buffer + 1); > > > > + > > > > + return (UINT32)(LowerBytes | (HigherBytes << 16)); > > > > +} > > > > + > > > > +/** > > > > + 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[out] Buffer The pointer to a 32-bit value that may be unaligned. > > > > + @param[in] Value 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 > > > > + ) > > > > +{ > > > > + ASSERT (Buffer != NULL); > > > > + > > > > + WriteUnaligned16 ((UINT16 *)Buffer, (UINT16)Value); > > > > + WriteUnaligned16 ((UINT16 *)Buffer + 1, (UINT16)(Value >> 16)); > > > > + 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[in] Buffer The 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 > > > > + ) > > > > +{ > > > > + UINT32 LowerBytes; > > > > + UINT32 HigherBytes; > > > > + > > > > + ASSERT (Buffer != NULL); > > > > + > > > > + LowerBytes = ReadUnaligned32 ((UINT32 *)Buffer); > > > > + HigherBytes = ReadUnaligned32 ((UINT32 *)Buffer + 1); > > > > + > > > > + return (UINT64)(LowerBytes | LShiftU64 (HigherBytes, 32)); > > > > +} > > > > + > > > > +/** > > > > + 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[out] Buffer The pointer to a 64-bit value that may be unaligned. > > > > + @param[in] Value 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 > > > > + ) > > > > +{ > > > > + ASSERT (Buffer != NULL); > > > > + > > > > + WriteUnaligned32 ((UINT32 *)Buffer, (UINT32)Value); > > > > + WriteUnaligned32 ((UINT32 *)Buffer + 1, (UINT32)RShiftU64 (Value, 32)); > > > > + return Value; > > > > +} > > > > -- > > 2.27.0 > > > > > > 本邮件及其附件含有龙芯中科的商业秘密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制或散发)本邮件及其附件中的信息。如果您错收本邮件,请您立即电话或邮件通知发件人并删除本邮件。 This email and its attachments contain confidential information from Loongson Technology , which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this email in error, please notify the sender by phone or email immediately and delete it. ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-09-11 4:17 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-09-08 4:51 [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture Chao Li 2022-09-09 17:20 ` Michael D Kinney 2022-09-11 4:17 ` [edk2-devel] " Chao Li
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox