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:
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
|
Reference in New Issue
Block a user