[edk2-devel] [PATCH v1 23/34] MdePkg/BaseLib: BaseLib for LOONGARCH64 architecture.

Chao Li lichao at loongson.cn
Sun Sep 11 04:17:23 UTC 2022


Hi Mike,
I will check and try it.

Thanks,
Chao


> -----原始邮件-----
> 发件人: "Michael D Kinney" <michael.d.kinney at intel.com>
> 发送时间:2022-09-10 01:20:37 (星期六)
> 收件人: "Chao Li" <lichao at loongson.cn>, "devel at edk2.groups.io" <devel at edk2.groups.io>, "Kinney, Michael D" <michael.d.kinney at intel.com>
> 抄送: "Gao, Liming" <gaoliming at byosoft.com.cn>, "Liu, Zhiguang" <zhiguang.liu at intel.com>, "Baoqi Zhang" <zhangbaoqi at 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 at loongson.cn>
> > Sent: Wednesday, September 7, 2022 9:52 PM
> > To: devel at edk2.groups.io
> > Cc: Kinney, Michael D <michael.d.kinney at intel.com>; Gao, Liming <gaoliming at byosoft.com.cn>; Liu, Zhiguang
> > <zhiguang.liu at intel.com>; Baoqi Zhang <zhangbaoqi at 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 at intel.com>
> > Cc: Liming Gao <gaoliming at byosoft.com.cn>
> > Cc: Zhiguang Liu <zhiguang.liu at intel.com>
> > 
> > Signed-off-by: Chao Li <lichao at loongson.cn>
> > Co-authored-by: Baoqi Zhang <zhangbaoqi at 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. 

-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#93628): https://edk2.groups.io/g/devel/message/93628
Mute This Topic: https://groups.io/mt/93542556/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list