Reviewed-by: Michael D Kinney <michael.d.kin...@intel.com>

> -----Original Message-----
> From: Chao Li <lic...@loongson.cn>
> Sent: Tuesday, September 27, 2022 4:14 AM
> To: devel@edk2.groups.io
> Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Gao, Liming 
> <gaolim...@byosoft.com.cn>; Liu, Zhiguang
> <zhiguang....@intel.com>; Baoqi Zhang <zhangba...@loongson.cn>
> Subject: [PATCH v3 29/34] MdePkg/BaseSynchronizationLib: LoongArch cache 
> related code.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4053
> 
> Support LoongArch cache related functions.
> 
> Cc: Michael D Kinney <michael.d.kin...@intel.com>
> Cc: Liming Gao <gaolim...@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang....@intel.com>
> 
> Signed-off-by: Chao Li <lic...@loongson.cn>
> Co-authored-by: Baoqi Zhang <zhangba...@loongson.cn>
> ---
>  .../BaseSynchronizationLib.inf                |   6 +
>  .../LoongArch64/AsmSynchronization.S          | 122 +++++++++
>  .../LoongArch64/Synchronization.c             | 233 ++++++++++++++++++
>  3 files changed, 361 insertions(+)
>  create mode 100644 
> MdePkg/Library/BaseSynchronizationLib/LoongArch64/AsmSynchronization.S
>  create mode 100644 
> MdePkg/Library/BaseSynchronizationLib/LoongArch64/Synchronization.c
> 
> diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> index 02ba12961a..dd66ec1d03 100755
> --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> @@ -4,6 +4,7 @@
>  #  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> 
>  #  Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
> 
>  #  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights 
> reserved.<BR>
> 
> +#  Copyright (c) 2022, Loongson Technology Corporation Limited. All rights 
> reserved.<BR>
> 
>  #
> 
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  #
> 
> @@ -82,6 +83,11 @@
>    Synchronization.c
> 
>    RiscV64/Synchronization.S
> 
> 
> 
> +[Sources.LOONGARCH64]
> 
> +  Synchronization.c
> 
> +  LoongArch64/Synchronization.c    | GCC
> 
> +  LoongArch64/AsmSynchronization.S | GCC
> 
> +
> 
>  [Packages]
> 
>    MdePkg/MdePkg.dec
> 
> 
> 
> diff --git 
> a/MdePkg/Library/BaseSynchronizationLib/LoongArch64/AsmSynchronization.S
> b/MdePkg/Library/BaseSynchronizationLib/LoongArch64/AsmSynchronization.S
> new file mode 100644
> index 0000000000..3f1b06172d
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/LoongArch64/AsmSynchronization.S
> @@ -0,0 +1,122 @@
> +#------------------------------------------------------------------------------
> +#
> +# LoongArch synchronization ASM functions.
> +#
> +# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights 
> reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#------------------------------------------------------------------------------
> +
> +ASM_GLOBAL ASM_PFX(AsmInternalSyncCompareExchange16)
> +ASM_GLOBAL ASM_PFX(AsmInternalSyncCompareExchange32)
> +ASM_GLOBAL ASM_PFX(AsmInternalSyncCompareExchange64)
> +ASM_GLOBAL ASM_PFX(AsmInternalSyncIncrement)
> +ASM_GLOBAL ASM_PFX(AsmInternalSyncDecrement)
> +
> +/**
> +UINT32
> +EFIAPI
> +AsmInternalSyncCompareExchange16 (
> +  IN volatile UINT32 *Ptr32,
> +  IN UINT64          Mask,
> +  IN UINT64          LocalCompareValue,
> +  IN UINT64          LocalExchangeValue
> +  )
> +**/
> +ASM_PFX(AsmInternalSyncCompareExchange16):
> +1:
> +  ll.w  $t0, $a0, 0x0
> +  and   $t1, $t0, $a1
> +  bne   $t1, $a2, 2f
> +  andn  $t1, $t0, $a1
> +  or    $t1, $t1, $a3
> +  sc.w  $t1, $a0, 0x0
> +  beqz  $t1, 1b
> +  b     3f
> +2:
> +  dbar  0
> +3:
> +  move   $a0, $t0
> +  jirl   $zero, $ra, 0
> +
> +/**
> +UINT32
> +EFIAPI
> +AsmInternalSyncCompareExchange32 (
> +  IN volatile UINT32 *Value,
> +  IN UINT64          CompareValue,
> +  IN UINT64          ExchangeValue
> +  )
> +**/
> +ASM_PFX(AsmInternalSyncCompareExchange32):
> +1:
> +  ll.w  $t0, $a0, 0x0
> +  bne   $t0, $a1, 2f
> +  move  $t0, $a2
> +  sc.w  $t0, $a0, 0x0
> +  beqz  $t0, 1b
> +  b     3f
> +2:
> +  dbar  0
> +3:
> +  move   $a0, $t0
> +  jirl   $zero, $ra, 0
> +
> +/**
> +UINT64
> +EFIAPI
> +AsmInternalSyncCompareExchange64 (
> +  IN volatile UINT64 *Value,
> +  IN UINT64          CompareValue,
> +  IN UINT64          ExchangeValue
> +  )
> +**/
> +ASM_PFX(AsmInternalSyncCompareExchange64):
> +1:
> +  ll.d  $t0, $a0, 0x0
> +  bne   $t0, $a1, 2f
> +  move  $t0, $a2
> +  sc.d  $t0, $a0, 0x0
> +  beqz  $t0, 1b
> +  b     3f
> +2:
> +  dbar  0
> +3:
> +  move   $a0, $t0
> +  jirl   $zero, $ra, 0
> +
> +/**
> +UINT32
> +EFIAPI
> +AsmInternalSyncIncrement (
> +  IN      volatile UINT32  *Value
> +  )
> +**/
> +ASM_PFX(AsmInternalSyncIncrement):
> +  move     $t0, $a0
> +  dbar     0
> +  ld.w     $t1, $t0, 0x0
> +  li.w     $t2, 1
> +  amadd.w  $t1, $t2, $t0
> +
> +  ld.w     $a0, $t0, 0x0
> +  jirl     $zero, $ra, 0
> +
> +/**
> +UINT32
> +EFIAPI
> +AsmInternalSyncDecrement (
> +  IN      volatile UINT32  *Value
> +  )
> +**/
> +ASM_PFX(AsmInternalSyncDecrement):
> +  move     $t0, $a0
> +  dbar     0
> +  ld.w     $t1, $t0, 0x0
> +  li.w     $t2, -1
> +  amadd.w  $t1, $t2, $t0
> +
> +  ld.w     $a0, $t0, 0x0
> +  jirl     $zero, $ra, 0
> +.end
> diff --git 
> a/MdePkg/Library/BaseSynchronizationLib/LoongArch64/Synchronization.c
> b/MdePkg/Library/BaseSynchronizationLib/LoongArch64/Synchronization.c
> new file mode 100644
> index 0000000000..d696c8ce10
> --- /dev/null
> +++ b/MdePkg/Library/BaseSynchronizationLib/LoongArch64/Synchronization.c
> @@ -0,0 +1,233 @@
> +/** @file
> 
> +  LoongArch synchronization functions.
> 
> +
> 
> +  Copyright (c) 2022, Loongson Technology Corporation Limited. All rights 
> reserved.<BR>
> 
> +
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <Library/DebugLib.h>
> 
> +
> 
> +UINT32
> 
> +EFIAPI
> 
> +AsmInternalSyncCompareExchange16 (
> 
> +  IN volatile UINT32 *,
> 
> +  IN UINT64,
> 
> +  IN UINT64,
> 
> +  IN UINT64
> 
> +  );
> 
> +
> 
> +UINT32
> 
> +EFIAPI
> 
> +AsmInternalSyncCompareExchange32 (
> 
> +  IN volatile UINT32 *,
> 
> +  IN UINT64,
> 
> +  IN UINT64
> 
> +  );
> 
> +
> 
> +UINT64
> 
> +EFIAPI
> 
> +AsmInternalSyncCompareExchange64 (
> 
> +  IN volatile UINT64 *,
> 
> +  IN UINT64,
> 
> +  IN UINT64
> 
> +  );
> 
> +
> 
> +UINT32
> 
> +EFIAPI
> 
> +AsmInternalSyncIncrement (
> 
> +  IN      volatile UINT32 *
> 
> +  );
> 
> +
> 
> +UINT32
> 
> +EFIAPI
> 
> +AsmInternalSyncDecrement (
> 
> +  IN      volatile UINT32 *
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Performs an atomic compare exchange operation on a 16-bit
> 
> +  unsigned integer.
> 
> +
> 
> +  Performs an atomic compare exchange operation on the 16-bit
> 
> +  unsigned integer specified by Value.  If Value is equal to
> 
> +  CompareValue, then Value is set to ExchangeValue and
> 
> +  CompareValue is returned.  If Value is not equal to
> 
> +  CompareValue, then Value is returned. The compare exchange
> 
> +  operation must be performed using MP safe mechanisms.
> 
> +
> 
> +  @param[in]  Value         A pointer to the 16-bit value for the
> 
> +                        compare exchange operation.
> 
> +  @param[in]  CompareValue  16-bit value used in compare operation.
> 
> +  @param[in]  ExchangeValue 16-bit value used in exchange operation.
> 
> +
> 
> +  @return The original *Value before exchange.
> 
> +
> 
> +**/
> 
> +UINT16
> 
> +EFIAPI
> 
> +InternalSyncCompareExchange16 (
> 
> +  IN      volatile UINT16  *Value,
> 
> +  IN      UINT16           CompareValue,
> 
> +  IN      UINT16           ExchangeValue
> 
> +  )
> 
> +{
> 
> +  UINT32           RetValue;
> 
> +  UINT32           Shift;
> 
> +  UINT64           Mask;
> 
> +  UINT64           LocalCompareValue;
> 
> +  UINT64           LocalExchangeValue;
> 
> +  volatile UINT32  *Ptr32;
> 
> +
> 
> +  /* Check that ptr is naturally aligned */
> 
> +  ASSERT (!((UINT64)Value & (sizeof (Value) - 1)));
> 
> +
> 
> +  /* Mask inputs to the correct size. */
> 
> +  Mask               = (((~0UL) - (1UL << (0)) + 1) & (~0UL >> (64 - 1 - 
> ((sizeof (UINT16) * 8) - 1))));
> 
> +  LocalCompareValue  = ((UINT64)CompareValue) & Mask;
> 
> +  LocalExchangeValue = ((UINT64)ExchangeValue) & Mask;
> 
> +
> 
> +  /*
> 
> +   * Calculate a shift & mask that correspond to the value we wish to
> 
> +   * compare & exchange within the naturally aligned 4 byte integer
> 
> +   * that includes it.
> 
> +   */
> 
> +  Shift                = (UINT64)Value & 0x3;
> 
> +  Shift               *= 8; /* BITS_PER_BYTE */
> 
> +  LocalCompareValue  <<= Shift;
> 
> +  LocalExchangeValue <<= Shift;
> 
> +  Mask               <<= Shift;
> 
> +
> 
> +  /*
> 
> +   * Calculate a pointer to the naturally aligned 4 byte integer that
> 
> +   * includes our byte of interest, and load its value.
> 
> +   */
> 
> +  Ptr32 = (UINT32 *)((UINT64)Value & ~0x3);
> 
> +
> 
> +  RetValue = AsmInternalSyncCompareExchange16 (
> 
> +               Ptr32,
> 
> +               Mask,
> 
> +               LocalCompareValue,
> 
> +               LocalExchangeValue
> 
> +               );
> 
> +
> 
> +  return (RetValue & Mask) >> Shift;
> 
> +}
> 
> +
> 
> +/**
> 
> +  Performs an atomic compare exchange operation on a 32-bit
> 
> +  unsigned integer.
> 
> +
> 
> +  Performs an atomic compare exchange operation on the 32-bit
> 
> +  unsigned integer specified by Value.  If Value is equal to
> 
> +  CompareValue, then Value is set to ExchangeValue and
> 
> +  CompareValue is returned.  If Value is not equal to
> 
> +  CompareValue, then Value is returned. The compare exchange
> 
> +  operation must be performed using MP safe mechanisms.
> 
> +
> 
> +  @param[in]  Value         A pointer to the 32-bit value for the
> 
> +                        compare exchange operation.
> 
> +  @param[in]  CompareValue  32-bit value used in compare operation.
> 
> +  @param[in]  ExchangeValue 32-bit value used in exchange operation.
> 
> +
> 
> +  @return The original *Value before exchange.
> 
> +
> 
> +**/
> 
> +UINT32
> 
> +EFIAPI
> 
> +InternalSyncCompareExchange32 (
> 
> +  IN      volatile UINT32  *Value,
> 
> +  IN      UINT32           CompareValue,
> 
> +  IN      UINT32           ExchangeValue
> 
> +  )
> 
> +{
> 
> +  UINT32  RetValue;
> 
> +
> 
> +  RetValue = AsmInternalSyncCompareExchange32 (
> 
> +               Value,
> 
> +               CompareValue,
> 
> +               ExchangeValue
> 
> +               );
> 
> +
> 
> +  return RetValue;
> 
> +}
> 
> +
> 
> +/**
> 
> +  Performs an atomic compare exchange operation on a 64-bit unsigned integer.
> 
> +
> 
> +  Performs an atomic compare exchange operation on the 64-bit unsigned 
> integer specified
> 
> +  by Value.  If Value is equal to CompareValue, then Value is set to 
> ExchangeValue and
> 
> +  CompareValue is returned.  If Value is not equal to CompareValue, then 
> Value is returned.
> 
> +  The compare exchange operation must be performed using MP safe mechanisms.
> 
> +
> 
> +  @param[in]  Value         A pointer to the 64-bit value for the compare 
> exchange
> 
> +                        operation.
> 
> +  @param[in]  CompareValue  64-bit value used in compare operation.
> 
> +  @param[in]  ExchangeValue 64-bit value used in exchange operation.
> 
> +
> 
> +  @return The original *Value before exchange.
> 
> +
> 
> +**/
> 
> +UINT64
> 
> +EFIAPI
> 
> +InternalSyncCompareExchange64 (
> 
> +  IN      volatile UINT64  *Value,
> 
> +  IN      UINT64           CompareValue,
> 
> +  IN      UINT64           ExchangeValue
> 
> +  )
> 
> +{
> 
> +  UINT64  RetValue;
> 
> +
> 
> +  RetValue = AsmInternalSyncCompareExchange64 (
> 
> +               Value,
> 
> +               CompareValue,
> 
> +               ExchangeValue
> 
> +               );
> 
> +
> 
> +  return RetValue;
> 
> +}
> 
> +
> 
> +/**
> 
> +  Performs an atomic increment of an 32-bit unsigned integer.
> 
> +
> 
> +  Performs an atomic increment of the 32-bit unsigned integer specified by
> 
> +  Value and returns the incremented value. The increment operation must be
> 
> +  performed using MP safe mechanisms. The state of the return value is not
> 
> +  guaranteed to be MP safe.
> 
> +
> 
> +  @param[in]  Value A pointer to the 32-bit value to increment.
> 
> +
> 
> +  @return The incremented value.
> 
> +
> 
> +**/
> 
> +UINT32
> 
> +EFIAPI
> 
> +InternalSyncIncrement (
> 
> +  IN      volatile UINT32  *Value
> 
> +  )
> 
> +{
> 
> +  return AsmInternalSyncIncrement (Value);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Performs an atomic decrement of an 32-bit unsigned integer.
> 
> +
> 
> +  Performs an atomic decrement of the 32-bit unsigned integer specified by
> 
> +  Value and returns the decrement value. The decrement operation must be
> 
> +  performed using MP safe mechanisms. The state of the return value is not
> 
> +  guaranteed to be MP safe.
> 
> +
> 
> +  @param[in]  Value A pointer to the 32-bit value to decrement.
> 
> +
> 
> +  @return The decrement value.
> 
> +
> 
> +**/
> 
> +UINT32
> 
> +EFIAPI
> 
> +InternalSyncDecrement (
> 
> +  IN      volatile UINT32  *Value
> 
> +  )
> 
> +{
> 
> +  return AsmInternalSyncDecrement (Value);
> 
> +}
> 
> --
> 2.27.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#94573): https://edk2.groups.io/g/devel/message/94573
Mute This Topic: https://groups.io/mt/93947386/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to