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:
Chao Li 2023-10-16 11:43:40 +08:00 committed by Liming Gao
parent 414ad233a5
commit 0565a8e885
4 changed files with 550 additions and 0 deletions

View File

@ -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)
//

View File

@ -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

View 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

View 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);
}