diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 29009adbc9..4e97368ae2 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -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) // diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index 1dad587b0c..7c46306883 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S new file mode 100644 index 0000000000..3a879411f5 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S @@ -0,0 +1,422 @@ +#------------------------------------------------------------------------------ +# +# LoongArch ASM CSR operation functions +# +# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +#include + +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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/Csr.c b/MdePkg/Library/BaseLib/LoongArch64/Csr.c new file mode 100644 index 0000000000..f2ec80b38d --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/Csr.c @@ -0,0 +1,81 @@ +/** @file + LoongArch CSR operation functions. + + Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.
+ + 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); +}