2022-05-31 18:04:11 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
|
|
|
*
|
|
|
|
* Derived from MIPS:
|
|
|
|
* Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
|
|
|
|
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
|
|
|
|
* Copyright (C) 2002, 2007 Maciej W. Rozycki
|
|
|
|
* Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved.
|
|
|
|
*/
|
|
|
|
#include <asm/asm.h>
|
|
|
|
#include <asm/asmmacro.h>
|
|
|
|
#include <asm/loongarch.h>
|
|
|
|
#include <asm/regdef.h>
|
|
|
|
#include <asm/fpregdef.h>
|
|
|
|
#include <asm/stackframe.h>
|
|
|
|
#include <asm/thread_info.h>
|
|
|
|
|
2025-05-14 22:17:52 +08:00
|
|
|
.section .cpuidle.text, "ax"
|
2022-05-31 18:04:11 +08:00
|
|
|
.align 5
|
|
|
|
SYM_FUNC_START(__arch_cpu_idle)
|
2025-02-13 12:02:35 +08:00
|
|
|
/* start of idle interrupt region */
|
|
|
|
ori t0, zero, CSR_CRMD_IE
|
|
|
|
/* idle instruction needs irq enabled */
|
|
|
|
csrxchg t0, t0, LOONGARCH_CSR_CRMD
|
|
|
|
/*
|
|
|
|
* If an interrupt lands here; between enabling interrupts above and
|
|
|
|
* going idle on the next instruction, we must *NOT* go idle since the
|
|
|
|
* interrupt could have set TIF_NEED_RESCHED or caused an timer to need
|
|
|
|
* reprogramming. Fall through -- see handle_vint() below -- and have
|
|
|
|
* the idle loop take care of things.
|
|
|
|
*/
|
2022-05-31 18:04:11 +08:00
|
|
|
idle 0
|
2025-02-13 12:02:35 +08:00
|
|
|
/* end of idle interrupt region */
|
2025-05-14 22:17:52 +08:00
|
|
|
idle_exit:
|
|
|
|
jr ra
|
2022-05-31 18:04:11 +08:00
|
|
|
SYM_FUNC_END(__arch_cpu_idle)
|
2025-05-14 22:17:52 +08:00
|
|
|
.previous
|
2022-05-31 18:04:11 +08:00
|
|
|
|
2023-10-18 08:42:52 +08:00
|
|
|
SYM_CODE_START(handle_vint)
|
2024-03-11 22:23:47 +08:00
|
|
|
UNWIND_HINT_UNDEFINED
|
2022-05-31 18:04:11 +08:00
|
|
|
BACKUP_T0T1
|
|
|
|
SAVE_ALL
|
2025-05-14 22:17:52 +08:00
|
|
|
la_abs t1, idle_exit
|
2022-07-26 23:57:22 +08:00
|
|
|
LONG_L t0, sp, PT_ERA
|
2025-02-13 12:02:35 +08:00
|
|
|
/* 3 instructions idle interrupt region */
|
|
|
|
ori t0, t0, 0b1100
|
2022-05-31 18:04:11 +08:00
|
|
|
bne t0, t1, 1f
|
2022-07-26 23:57:22 +08:00
|
|
|
LONG_S t0, sp, PT_ERA
|
2022-05-31 18:04:11 +08:00
|
|
|
1: move a0, sp
|
|
|
|
move a1, sp
|
2023-02-25 15:52:56 +08:00
|
|
|
la_abs t0, do_vint
|
2022-07-26 23:57:22 +08:00
|
|
|
jirl ra, t0, 0
|
2022-05-31 18:04:11 +08:00
|
|
|
RESTORE_ALL_AND_RET
|
2023-10-18 08:42:52 +08:00
|
|
|
SYM_CODE_END(handle_vint)
|
2022-05-31 18:04:11 +08:00
|
|
|
|
2023-10-18 08:42:52 +08:00
|
|
|
SYM_CODE_START(except_vec_cex)
|
2024-03-11 22:23:47 +08:00
|
|
|
UNWIND_HINT_UNDEFINED
|
2022-05-31 18:04:11 +08:00
|
|
|
b cache_parity_error
|
2023-10-18 08:42:52 +08:00
|
|
|
SYM_CODE_END(except_vec_cex)
|
2022-05-31 18:04:11 +08:00
|
|
|
|
|
|
|
.macro build_prep_badv
|
|
|
|
csrrd t0, LOONGARCH_CSR_BADV
|
|
|
|
PTR_S t0, sp, PT_BVADDR
|
|
|
|
.endm
|
|
|
|
|
|
|
|
.macro build_prep_fcsr
|
|
|
|
movfcsr2gr a1, fcsr0
|
|
|
|
.endm
|
|
|
|
|
|
|
|
.macro build_prep_none
|
|
|
|
.endm
|
|
|
|
|
|
|
|
.macro BUILD_HANDLER exception handler prep
|
|
|
|
.align 5
|
2023-10-18 08:42:52 +08:00
|
|
|
SYM_CODE_START(handle_\exception)
|
2024-03-11 22:23:47 +08:00
|
|
|
UNWIND_HINT_UNDEFINED
|
2023-01-17 11:42:16 +08:00
|
|
|
666:
|
2022-05-31 18:04:11 +08:00
|
|
|
BACKUP_T0T1
|
|
|
|
SAVE_ALL
|
|
|
|
build_prep_\prep
|
|
|
|
move a0, sp
|
2023-02-25 15:52:56 +08:00
|
|
|
la_abs t0, do_\handler
|
2022-07-26 23:57:22 +08:00
|
|
|
jirl ra, t0, 0
|
2023-01-17 11:42:16 +08:00
|
|
|
668:
|
2022-05-31 18:04:11 +08:00
|
|
|
RESTORE_ALL_AND_RET
|
2023-10-18 08:42:52 +08:00
|
|
|
SYM_CODE_END(handle_\exception)
|
2024-03-11 22:23:47 +08:00
|
|
|
.pushsection ".data", "aw", %progbits
|
2023-01-17 11:42:16 +08:00
|
|
|
SYM_DATA(unwind_hint_\exception, .word 668b - 666b)
|
2024-03-11 22:23:47 +08:00
|
|
|
.popsection
|
2022-05-31 18:04:11 +08:00
|
|
|
.endm
|
|
|
|
|
|
|
|
BUILD_HANDLER ade ade badv
|
|
|
|
BUILD_HANDLER ale ale badv
|
LoongArch: Relay BCE exceptions to userland as SIGSEGV with si_code=SEGV_BNDERR
SEGV_BNDERR was introduced initially for supporting the Intel MPX, but
fell into disuse after the MPX support was removed. The LoongArch
bounds-checking instructions behave very differently than MPX, but
overall the interface is still kind of suitable for conveying the
information to userland when bounds-checking assertions trigger, so we
wouldn't have to invent more UAPI. Specifically, when the BCE triggers,
a SEGV_BNDERR is sent to userland, with si_addr set to the out-of-bounds
address or value (in asrt{gt,le}'s case), and one of si_lower or
si_upper set to the configured bound depending on the faulting
instruction. The other bound is set to either 0 or ULONG_MAX to resemble
a range with both lower and upper bounds.
Note that it is possible to have si_addr == si_lower in case of a
failing asrtgt or {ld,st}gt, because those instructions test for strict
greater-than relationship. This should not pose a problem for userland,
though, because the faulting PC is available for the application to
associate back to the exact instruction for figuring out the
expectation.
Example exception context generated by a faulting `asrtgt.d t0, t1`
(assert t0 > t1 or BCE) with t0=100 and t1=200:
> pc 00005555558206a4 ra 00007ffff2d854fc tp 00007ffff2f2f180 sp 00007ffffbf9fb80
> a0 0000000000000002 a1 00007ffffbf9fce8 a2 00007ffffbf9fd00 a3 00007ffff2ed4558
> a4 0000000000000000 a5 00007ffff2f044c8 a6 00007ffffbf9fce0 a7 fffffffffffff000
> t0 0000000000000064 t1 00000000000000c8 t2 00007ffffbfa2d5e t3 00007ffff2f12aa0
> t4 00007ffff2ed6158 t5 00007ffff2ed6158 t6 000000000000002e t7 0000000003d8f538
> t8 0000000000000005 u0 0000000000000000 s9 0000000000000000 s0 00007ffffbf9fce8
> s1 0000000000000002 s2 0000000000000000 s3 00007ffff2f2c038 s4 0000555555820610
> s5 00007ffff2ed5000 s6 0000555555827e38 s7 00007ffffbf9fd00 s8 0000555555827e38
> ra: 00007ffff2d854fc
> ERA: 00005555558206a4
> CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
> PRMD: 00000007 (PPLV3 +PIE -PWE)
> EUEN: 00000000 (-FPE -SXE -ASXE -BTE)
> ECFG: 0007181c (LIE=2-4,11-12 VS=7)
> ESTAT: 000a0000 [BCE] (IS= ECode=10 EsubCode=0)
> PRID: 0014c010 (Loongson-64bit, Loongson-3A5000)
Signed-off-by: WANG Xuerui <git@xen0n.name>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2023-05-01 17:19:27 +08:00
|
|
|
BUILD_HANDLER bce bce none
|
2022-05-31 18:04:11 +08:00
|
|
|
BUILD_HANDLER bp bp none
|
|
|
|
BUILD_HANDLER fpe fpe fcsr
|
|
|
|
BUILD_HANDLER fpu fpu none
|
|
|
|
BUILD_HANDLER lsx lsx none
|
|
|
|
BUILD_HANDLER lasx lasx none
|
|
|
|
BUILD_HANDLER lbt lbt none
|
|
|
|
BUILD_HANDLER ri ri none
|
|
|
|
BUILD_HANDLER watch watch none
|
|
|
|
BUILD_HANDLER reserved reserved none /* others */
|
|
|
|
|
2023-10-18 08:42:52 +08:00
|
|
|
SYM_CODE_START(handle_sys)
|
2024-03-11 22:23:47 +08:00
|
|
|
UNWIND_HINT_UNDEFINED
|
2023-02-25 15:52:56 +08:00
|
|
|
la_abs t0, handle_syscall
|
2022-07-26 23:57:17 +08:00
|
|
|
jr t0
|
2023-10-18 08:42:52 +08:00
|
|
|
SYM_CODE_END(handle_sys)
|