MdePkg: Add CSR operation for LoongArch
Add CsrRead, CsrWrite and CsrXChg functions for LoongArch, and use them to operate the CSR register of LoongArch architecture. BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4584 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: Bibo Mao <maobibo@loongson.cn> Acked-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
This commit is contained in:
		@@ -351,6 +351,51 @@ AsmReadStableCounter (
 | 
			
		||||
  VOID
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  CSR read operation.
 | 
			
		||||
 | 
			
		||||
  @param[in]  Select   CSR read instruction select values.
 | 
			
		||||
 | 
			
		||||
  @return     The return value of csrrd instruction, return -1 means no CSR instruction
 | 
			
		||||
              is found.
 | 
			
		||||
**/
 | 
			
		||||
UINTN
 | 
			
		||||
CsrRead (
 | 
			
		||||
  IN UINT16  Select
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  CSR write operation.
 | 
			
		||||
 | 
			
		||||
  @param[in]  Select   CSR write instruction select values.
 | 
			
		||||
  @param[in]  Value    The csrwr will write the value.
 | 
			
		||||
 | 
			
		||||
  @return     The return value of csrwr instruction, that is, store the old value of
 | 
			
		||||
              the register, return -1 means no CSR instruction is found.
 | 
			
		||||
**/
 | 
			
		||||
UINTN
 | 
			
		||||
CsrWrite (
 | 
			
		||||
  IN UINT16  Select,
 | 
			
		||||
  IN UINTN   Value
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  CSR exchange operation.
 | 
			
		||||
 | 
			
		||||
  @param[in]  Select   CSR exchange instruction select values.
 | 
			
		||||
  @param[in]  Value    The csrxchg will write the value.
 | 
			
		||||
  @param[in]  Mask     The csrxchg mask value.
 | 
			
		||||
 | 
			
		||||
  @return     The return value of csrxchg instruction, that is, store the old value of
 | 
			
		||||
              the register, return -1 means no CSR instruction is found.
 | 
			
		||||
**/
 | 
			
		||||
UINTN
 | 
			
		||||
CsrXChg (
 | 
			
		||||
  IN UINT16  Select,
 | 
			
		||||
  IN UINTN   Value,
 | 
			
		||||
  IN UINTN   Mask
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
#endif // defined (MDE_CPU_LOONGARCH64)
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 
 | 
			
		||||
@@ -410,7 +410,9 @@
 | 
			
		||||
[Sources.LOONGARCH64]
 | 
			
		||||
  Math64.c
 | 
			
		||||
  Unaligned.c
 | 
			
		||||
  LoongArch64/Csr.c
 | 
			
		||||
  LoongArch64/InternalSwitchStack.c
 | 
			
		||||
  LoongArch64/AsmCsr.S              | GCC
 | 
			
		||||
  LoongArch64/GetInterruptState.S   | GCC
 | 
			
		||||
  LoongArch64/EnableInterrupts.S    | GCC
 | 
			
		||||
  LoongArch64/DisableInterrupts.S   | GCC
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										422
									
								
								MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										422
									
								
								MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,422 @@
 | 
			
		||||
#------------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
# LoongArch ASM CSR operation functions
 | 
			
		||||
#
 | 
			
		||||
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
			
		||||
#
 | 
			
		||||
#------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#include <Register/LoongArch64/Csr.h>
 | 
			
		||||
 | 
			
		||||
ASM_GLOBAL ASM_PFX (AsmCsrRead)
 | 
			
		||||
ASM_GLOBAL ASM_PFX (AsmCsrWrite)
 | 
			
		||||
ASM_GLOBAL ASM_PFX (AsmCsrXChg)
 | 
			
		||||
 | 
			
		||||
.macro AsmCsrRd Sel
 | 
			
		||||
  csrrd   $a0, \Sel
 | 
			
		||||
  jirl    $zero, $ra, 0
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
.macro AsmCsrWr Sel
 | 
			
		||||
  csrwr   $a0, \Sel
 | 
			
		||||
  jirl    $zero, $ra, 0
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
.macro AsmCsrXChange Sel
 | 
			
		||||
  csrxchg $a0, $a1, \Sel
 | 
			
		||||
  jirl    $zero, $ra, 0
 | 
			
		||||
.endm
 | 
			
		||||
 | 
			
		||||
ASM_PFX(AsmCsrRead):
 | 
			
		||||
  blt      $a0, $zero, ReadSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_EBASE
 | 
			
		||||
  bltu     $t0, $a0, TlbCsrRd
 | 
			
		||||
 | 
			
		||||
BasicCsrRd:
 | 
			
		||||
  la.pcrel $t0, BasicCsrRead
 | 
			
		||||
  alsl.d   $t0, $a0, $t0, 3
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
TlbCsrRd:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  bltu     $a0, $t0, ReadSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_RVACFG
 | 
			
		||||
  bltu     $t0, $a0, CfgCsrRd
 | 
			
		||||
  la.pcrel $t0, TlbCsrRead
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
CfgCsrRd:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  bltu     $a0, $t0, ReadSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_PRCFG3
 | 
			
		||||
  bltu     $t0, $a0, KcsCsrRd
 | 
			
		||||
  la.pcrel $t0, CfgCsrRead
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
KcsCsrRd:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_KS0
 | 
			
		||||
  bltu     $a0, $t0, ReadSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_KS8
 | 
			
		||||
  bltu     $t0, $a0, StableTimerCsrRd
 | 
			
		||||
  la.pcrel $t0, KcsCsrRead
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_KS0
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
StableTimerCsrRd:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TMID
 | 
			
		||||
  bltu     $a0, $t0, ReadSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TINTCLR
 | 
			
		||||
  bltu     $t0, $a0, TlbRefillCsrRd
 | 
			
		||||
  la.pcrel $t0, StableTimerCsrRead
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TMID
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
TlbRefillCsrRd:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  bltu     $a0, $t0, ReadSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBREHI
 | 
			
		||||
  bltu     $t0, $a0, DirMapCsrRd
 | 
			
		||||
  la.pcrel $t0, TlbRefillCsrRead
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
DirMapCsrRd:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  bltu     $a0, $t0, ReadSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_DMWIN3
 | 
			
		||||
  bltu     $t0, $a0, ReadSelNumErr
 | 
			
		||||
  la.pcrel $t0, DirMapCsrRead
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
ReadSelNumErr:
 | 
			
		||||
  addi.d   $a0, $zero, -1
 | 
			
		||||
  jirl     $zero, $ra, 0
 | 
			
		||||
 | 
			
		||||
BasicCsrRead:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_CRMD
 | 
			
		||||
  .rept LOONGARCH_CSR_EBASE - LOONGARCH_CSR_CRMD + 1
 | 
			
		||||
    AsmCsrRd CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
TlbCsrRead:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  .rept LOONGARCH_CSR_RVACFG - LOONGARCH_CSR_TLBIDX + 1
 | 
			
		||||
    AsmCsrRd CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
CfgCsrRead:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1
 | 
			
		||||
    AsmCsrRd CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
KcsCsrRead:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_KS0
 | 
			
		||||
  .rept LOONGARCH_CSR_KS8 - LOONGARCH_CSR_KS0 + 1
 | 
			
		||||
    AsmCsrRd CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
StableTimerCsrRead:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TMID
 | 
			
		||||
  .rept LOONGARCH_CSR_TINTCLR - LOONGARCH_CSR_TMID + 1
 | 
			
		||||
    AsmCsrRd CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
TlbRefillCsrRead:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  .rept LOONGARCH_CSR_TLBREHI - LOONGARCH_CSR_TLBREBASE + 1
 | 
			
		||||
    AsmCsrRd CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
DirMapCsrRead:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  .rept LOONGARCH_CSR_DMWIN3 - LOONGARCH_CSR_DMWIN0 + 1
 | 
			
		||||
    AsmCsrRd CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
ASM_PFX(AsmCsrWrite):
 | 
			
		||||
  blt      $a0, $zero, WriteSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_EBASE
 | 
			
		||||
  bltu     $t0, $a0, TlbCsrWr
 | 
			
		||||
 | 
			
		||||
BasicCsrWr:
 | 
			
		||||
  la.pcrel $t0, BasicCsrWrite
 | 
			
		||||
  alsl.d   $t0, $a0, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
TlbCsrWr:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  bltu     $a0, $t0, WriteSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_RVACFG
 | 
			
		||||
  bltu     $t0, $a0, CfgCsrWr
 | 
			
		||||
  la.pcrel $t0, TlbCsrWrite
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
CfgCsrWr:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  bltu     $a0, $t0, WriteSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_PRCFG3
 | 
			
		||||
  bltu     $t0, $a0, KcsCsrWr
 | 
			
		||||
  la.pcrel $t0, CfgCsrWrite
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
KcsCsrWr:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_KS0
 | 
			
		||||
  bltu     $a0, $t0, WriteSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_KS8
 | 
			
		||||
  bltu     $t0, $a0, StableTimerCsrWr
 | 
			
		||||
  la.pcrel $t0, KcsCsrWrite
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_KS0
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
StableTimerCsrWr:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TMID
 | 
			
		||||
  bltu     $a0, $t0, WriteSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TINTCLR
 | 
			
		||||
  bltu     $t0, $a0, TlbRefillCsrWr
 | 
			
		||||
  la.pcrel $t0, StableTimerCsrWrite
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TMID
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
TlbRefillCsrWr:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  bltu     $a0, $t0, WriteSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBREHI
 | 
			
		||||
  bltu     $t0, $a0, DirMapCsrWr
 | 
			
		||||
  la.pcrel $t0, TlbRefillCsrWrite
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
DirMapCsrWr:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  bltu     $a0, $t0, WriteSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_DMWIN3
 | 
			
		||||
  bltu     $t0, $a0, WriteSelNumErr
 | 
			
		||||
  la.pcrel $t0, DirMapCsrWrite
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
WriteSelNumErr:
 | 
			
		||||
  addi.d   $a0, $zero, -1
 | 
			
		||||
  jirl     $zero, $ra, 0
 | 
			
		||||
 | 
			
		||||
BasicCsrWrite:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_CRMD
 | 
			
		||||
  .rept LOONGARCH_CSR_EBASE - LOONGARCH_CSR_CRMD + 1
 | 
			
		||||
    AsmCsrWr CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
TlbCsrWrite:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  .rept LOONGARCH_CSR_RVACFG - LOONGARCH_CSR_TLBIDX + 1
 | 
			
		||||
    AsmCsrWr CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
CfgCsrWrite:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1
 | 
			
		||||
    AsmCsrWr CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
KcsCsrWrite:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_KS0
 | 
			
		||||
  .rept LOONGARCH_CSR_KS8 - LOONGARCH_CSR_KS0 + 1
 | 
			
		||||
    AsmCsrWr CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
StableTimerCsrWrite:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TMID
 | 
			
		||||
  .rept LOONGARCH_CSR_TINTCLR - LOONGARCH_CSR_TMID + 1
 | 
			
		||||
    AsmCsrWr CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
TlbRefillCsrWrite:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  .rept LOONGARCH_CSR_TLBREHI - LOONGARCH_CSR_TLBREBASE + 1
 | 
			
		||||
    AsmCsrWr CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
DirMapCsrWrite:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  .rept LOONGARCH_CSR_DMWIN3 - LOONGARCH_CSR_DMWIN0 + 1
 | 
			
		||||
    AsmCsrWr CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ASM_PFX(AsmCsrXChg):
 | 
			
		||||
  blt      $a0, $zero, XchgSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_EBASE
 | 
			
		||||
  bltu     $t0, $a0, TlbCsrXchg
 | 
			
		||||
 | 
			
		||||
BasicCsrXchg:
 | 
			
		||||
  la.pcrel $t0, BasicCsrXchange
 | 
			
		||||
  alsl.d   $t0, $a0, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  move     $a1, $a2
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
TlbCsrXchg:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  bltu     $a0, $t0, XchgSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_RVACFG
 | 
			
		||||
  bltu     $t0, $a0, CfgCsrXchg
 | 
			
		||||
  la.pcrel $t0, TlbCsrXchange
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  move     $a1, $a2
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
CfgCsrXchg:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  bltu     $a0, $t0, XchgSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_PRCFG3
 | 
			
		||||
  bltu     $t0, $a0, KcsCsrXchg
 | 
			
		||||
  la.pcrel $t0, CfgCsrXchange
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  move     $a1, $a2
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
KcsCsrXchg:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_KS0
 | 
			
		||||
  bltu     $a0, $t0, XchgSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_KS8
 | 
			
		||||
  bltu     $t0, $a0, StableTimerCsrXchg
 | 
			
		||||
  la.pcrel $t0, KcsCsrXchange
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_KS0
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  move     $a1, $a2
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
StableTimerCsrXchg:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TMID
 | 
			
		||||
  bltu     $a0, $t0, XchgSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TINTCLR
 | 
			
		||||
  bltu     $t0, $a0, TlbRefillCsrXchg
 | 
			
		||||
  la.pcrel $t0, StableTimerCsrXchange
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TMID
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  move     $a1, $a2
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
TlbRefillCsrXchg:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  bltu     $a0, $t0, XchgSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_TLBREHI
 | 
			
		||||
  bltu     $t0, $a0, DirMapCsrXchg
 | 
			
		||||
  la.pcrel $t0, TlbRefillCsrXchange
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  move     $a1, $a2
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
DirMapCsrXchg:
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  bltu     $a0, $t0, XchgSelNumErr
 | 
			
		||||
  li.w     $t0, LOONGARCH_CSR_DMWIN3
 | 
			
		||||
  bltu     $t0, $a0, XchgSelNumErr
 | 
			
		||||
  la.pcrel $t0, DirMapCsrXchange
 | 
			
		||||
  addi.w   $t1, $a0, -LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  alsl.d   $t0, $t1, $t0, 3
 | 
			
		||||
  move     $a0, $a1
 | 
			
		||||
  move     $a1, $a2
 | 
			
		||||
  jirl     $zero, $t0, 0
 | 
			
		||||
 | 
			
		||||
XchgSelNumErr:
 | 
			
		||||
  addi.d   $a0, $zero, -1
 | 
			
		||||
  jirl     $zero, $ra, 0
 | 
			
		||||
 | 
			
		||||
BasicCsrXchange:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_CRMD
 | 
			
		||||
  .rept LOONGARCH_CSR_EBASE - LOONGARCH_CSR_CRMD + 1
 | 
			
		||||
    AsmCsrXChange CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
TlbCsrXchange:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TLBIDX
 | 
			
		||||
  .rept LOONGARCH_CSR_RVACFG - LOONGARCH_CSR_TLBIDX + 1
 | 
			
		||||
    AsmCsrXChange CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
CfgCsrXchange:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_CPUNUM
 | 
			
		||||
  .rept LOONGARCH_CSR_PRCFG3 - LOONGARCH_CSR_CPUNUM + 1
 | 
			
		||||
    AsmCsrXChange CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
KcsCsrXchange:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_KS0
 | 
			
		||||
  .rept LOONGARCH_CSR_KS8 - LOONGARCH_CSR_KS0 + 1
 | 
			
		||||
    AsmCsrXChange CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
StableTimerCsrXchange:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TMID
 | 
			
		||||
  .rept LOONGARCH_CSR_TINTCLR - LOONGARCH_CSR_TMID + 1
 | 
			
		||||
    AsmCsrXChange CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
TlbRefillCsrXchange:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_TLBREBASE
 | 
			
		||||
  .rept LOONGARCH_CSR_TLBREHI - LOONGARCH_CSR_TLBREBASE + 1
 | 
			
		||||
    AsmCsrXChange CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
 | 
			
		||||
DirMapCsrXchange:
 | 
			
		||||
  CsrSel = LOONGARCH_CSR_DMWIN0
 | 
			
		||||
  .rept LOONGARCH_CSR_DMWIN3 - LOONGARCH_CSR_DMWIN0 + 1
 | 
			
		||||
    AsmCsrXChange CsrSel
 | 
			
		||||
    CsrSel = CsrSel + 1
 | 
			
		||||
  .endr
 | 
			
		||||
.end
 | 
			
		||||
							
								
								
									
										81
									
								
								MdePkg/Library/BaseLib/LoongArch64/Csr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								MdePkg/Library/BaseLib/LoongArch64/Csr.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
/** @file
 | 
			
		||||
  LoongArch CSR operation functions.
 | 
			
		||||
 | 
			
		||||
  Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
 | 
			
		||||
 | 
			
		||||
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
			
		||||
**/
 | 
			
		||||
 | 
			
		||||
UINTN
 | 
			
		||||
AsmCsrRead (
 | 
			
		||||
  IN UINT16  Select
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
UINTN
 | 
			
		||||
AsmCsrWrite (
 | 
			
		||||
  IN UINT16  Select,
 | 
			
		||||
  IN UINTN   Value
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
UINTN
 | 
			
		||||
AsmCsrXChg (
 | 
			
		||||
  IN UINT16  Select,
 | 
			
		||||
  IN UINTN   Value,
 | 
			
		||||
  IN UINTN   Mask
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  CSR read operation.
 | 
			
		||||
 | 
			
		||||
  @param[in]  Select   CSR read instruction select values.
 | 
			
		||||
 | 
			
		||||
  @return     The return value of csrrd instruction, return -1 means Select is out of support.
 | 
			
		||||
**/
 | 
			
		||||
UINTN
 | 
			
		||||
EFIAPI
 | 
			
		||||
CsrRead (
 | 
			
		||||
  IN UINT16  Select
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  return AsmCsrRead (Select);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  CSR write operation.
 | 
			
		||||
 | 
			
		||||
  @param[in]       Select  CSR write instruction select values.
 | 
			
		||||
  @param[in, out]  Value   The csrwr will write the value.
 | 
			
		||||
 | 
			
		||||
  @return     The return value of csrwr instruction, that is, store the old value of
 | 
			
		||||
              the register, return -1 means Select is out of support.
 | 
			
		||||
**/
 | 
			
		||||
UINTN
 | 
			
		||||
EFIAPI
 | 
			
		||||
CsrWrite (
 | 
			
		||||
  IN     UINT16  Select,
 | 
			
		||||
  IN OUT UINTN   Value
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  return AsmCsrWrite (Select, Value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  CSR exchange operation.
 | 
			
		||||
 | 
			
		||||
  @param[in]       Select   CSR exchange instruction select values.
 | 
			
		||||
  @param[in, out]  Value    The csrxchg will write the value.
 | 
			
		||||
  @param[in]       Mask     The csrxchg mask value.
 | 
			
		||||
 | 
			
		||||
  @return     The return value of csrxchg instruction, that is, store the old value of
 | 
			
		||||
              the register, return -1 means Select is out of support.
 | 
			
		||||
**/
 | 
			
		||||
UINTN
 | 
			
		||||
EFIAPI
 | 
			
		||||
CsrXChg (
 | 
			
		||||
  IN     UINT16  Select,
 | 
			
		||||
  IN OUT UINTN   Value,
 | 
			
		||||
  IN     UINTN   Mask
 | 
			
		||||
  )
 | 
			
		||||
{
 | 
			
		||||
  return AsmCsrXChg (Select, Value, Mask);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user