1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Helper assembly code routines for RISC-V SBI extension tests. 4 * 5 * Copyright (C) 2024, James Raphael Tiovalen <jamestiotio@gmail.com> 6 */ 7#define __ASSEMBLY__ 8#include <asm/asm.h> 9#include <asm/csr.h> 10 11#include "sbi-tests.h" 12 13.section .text 14 15/* 16 * sbi_hsm_check 17 * a0 and a1 are set by SBI HSM start/suspend 18 * s1 is the address of the results array 19 * Doesn't return. 20 * 21 * This function is only called from HSM start and on resumption 22 * from HSM suspend which means we can do whatever we like with 23 * all registers. So, to avoid complicated register agreements with 24 * other assembly functions called, we just always use the saved 25 * registers for anything that should be maintained across calls. 26 */ 27#define HSM_RESULTS_ARRAY s1 28#define HSM_RESULTS_MAP s2 29#define HSM_CPU_INDEX s3 30.balign 4 31sbi_hsm_check: 32 li HSM_RESULTS_MAP, 0 33 REG_L t0, ASMARR(a1, SBI_HSM_MAGIC_IDX) 34 li t1, SBI_HSM_MAGIC 35 bne t0, t1, 1f 36 ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_MAGIC_A1 371: REG_L t0, ASMARR(a1, SBI_HSM_HARTID_IDX) 38 bne a0, t0, 2f 39 ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_HARTID_A0 402: csrr t0, CSR_SATP 41 bnez t0, 3f 42 ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_SATP 433: csrr t0, CSR_SSTATUS 44 andi t0, t0, SR_SIE 45 bnez t0, 4f 46 ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_SIE 474: call hartid_to_cpu 48 mv HSM_CPU_INDEX, a0 49 li t0, -1 50 bne HSM_CPU_INDEX, t0, 6f 515: pause 52 j 5b 536: ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_DONE 54 add t0, HSM_RESULTS_ARRAY, HSM_CPU_INDEX 55 sb HSM_RESULTS_MAP, 0(t0) 56 la t1, sbi_hsm_stop_hart 57 add t1, t1, HSM_CPU_INDEX 587: lb t0, 0(t1) 59 pause 60 beqz t0, 7b 61 li a7, 0x48534d /* SBI_EXT_HSM */ 62 li a6, 1 /* SBI_EXT_HSM_HART_STOP */ 63 ecall 648: pause 65 j 8b 66 67.balign 4 68.global sbi_hsm_check_hart_start 69sbi_hsm_check_hart_start: 70 la HSM_RESULTS_ARRAY, sbi_hsm_hart_start_checks 71 j sbi_hsm_check 72 73.balign 4 74.global sbi_hsm_check_non_retentive_suspend 75sbi_hsm_check_non_retentive_suspend: 76 la HSM_RESULTS_ARRAY, sbi_hsm_non_retentive_hart_suspend_checks 77 j sbi_hsm_check 78 79.balign 4 80restore_csrs: 81 REG_L a1, ASMARR(a0, SBI_CSR_SSTATUS_IDX) 82 csrw CSR_SSTATUS, a1 83 REG_L a1, ASMARR(a0, SBI_CSR_SIE_IDX) 84 csrw CSR_SIE, a1 85 REG_L a1, ASMARR(a0, SBI_CSR_STVEC_IDX) 86 csrw CSR_STVEC, a1 87 REG_L a1, ASMARR(a0, SBI_CSR_SSCRATCH_IDX) 88 csrw CSR_SSCRATCH, a1 89 REG_L a1, ASMARR(a0, SBI_CSR_SATP_IDX) 90 sfence.vma 91 csrw CSR_SATP, a1 92 ret 93 94/* 95 * sbi_susp_resume 96 * 97 * State is as specified by "SUSP System Resume Register State" of the SBI spec 98 * a0 is the hartid 99 * a1 is the opaque parameter (here, it's the context array defined in check_susp()) 100 * Doesn't return. 101 */ 102#define SUSP_CTX s1 103#define SUSP_RESULTS_MAP s2 104.balign 4 105.global sbi_susp_resume 106sbi_susp_resume: 107 li SUSP_RESULTS_MAP, 0 108 mv SUSP_CTX, a1 109 REG_L t0, ASMARR(SUSP_CTX, SBI_SUSP_MAGIC_IDX) 110 li t1, SBI_SUSP_MAGIC 111 beq t0, t1, 2f 1121: pause 113 j 1b 1142: csrr t0, CSR_SATP 115 bnez t0, 3f 116 ori SUSP_RESULTS_MAP, SUSP_RESULTS_MAP, SBI_SUSP_TEST_SATP 1173: csrr t0, CSR_SSTATUS 118 andi t0, t0, SR_SIE 119 bnez t0, 4f 120 ori SUSP_RESULTS_MAP, SUSP_RESULTS_MAP, SBI_SUSP_TEST_SIE 1214: REG_L t0, ASMARR(SUSP_CTX, SBI_SUSP_HARTID_IDX) 122 bne t0, a0, 5f 123 ori SUSP_RESULTS_MAP, SUSP_RESULTS_MAP, SBI_SUSP_TEST_HARTID 1245: REG_S SUSP_RESULTS_MAP, ASMARR(SUSP_CTX, SBI_SUSP_RESULTS_IDX) 125 REG_L a0, ASMARR(SUSP_CTX, SBI_SUSP_CSRS_IDX) 126 call restore_csrs 127 la a0, sbi_susp_jmp 128 REG_L a1, ASMARR(SUSP_CTX, SBI_SUSP_TESTNUM_IDX) 129 call longjmp 1306: pause /* unreachable */ 131 j 6b 132