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.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: Bibo Mao <maob...@loongson.cn> Acked-by: Michael D Kinney <michael.d.kin...@intel.com> --- MdePkg/Include/Library/BaseLib.h | 45 +++ MdePkg/Library/BaseLib/BaseLib.inf | 2 + MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S | 422 ++++++++++++++++++++ MdePkg/Library/BaseLib/LoongArch64/Csr.c | 81 ++++ 4 files changed, 550 insertions(+) create mode 100644 MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S create mode 100644 MdePkg/Library/BaseLib/LoongArch64/Csr.c diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 55d53c75a0..234f3065c2 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -293,6 +293,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 aaf221822b..74a323c798 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -409,7 +409,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..c7453934c6 --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/AsmCsr.S @@ -0,0 +1,422 @@ +#------------------------------------------------------------------------------ +# +# LoongArch ASM CSR operation functions +# +# Copyright (c) 2023, 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 diff --git a/MdePkg/Library/BaseLib/LoongArch64/Csr.c b/MdePkg/Library/BaseLib/LoongArch64/Csr.c new file mode 100644 index 0000000000..d51f30aacc --- /dev/null +++ b/MdePkg/Library/BaseLib/LoongArch64/Csr.c @@ -0,0 +1,81 @@ +/** @file + LoongArch CSR operation functions. + + Copyright (c) 2023, 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); +} -- 2.27.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#112398): https://edk2.groups.io/g/devel/message/112398 Mute This Topic: https://groups.io/mt/103129080/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-