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#include <asm/asm.h> 8#include <asm/csr.h> 9#include <asm/asm-offsets.h> 10#include <generated/sbi-asm-offsets.h> 11 12#include "sbi-tests.h" 13 14.section .text 15 16/* 17 * sbi_hsm_check 18 * a0 and a1 are set by SBI HSM start/suspend 19 * s1 is the address of the results array 20 * Doesn't return. 21 * 22 * This function is only called from HSM start and on resumption 23 * from HSM suspend which means we can do whatever we like with 24 * all registers. So, to avoid complicated register agreements with 25 * other assembly functions called, we just always use the saved 26 * registers for anything that should be maintained across calls. 27 */ 28#define HSM_RESULTS_ARRAY s1 29#define HSM_RESULTS_MAP s2 30#define HSM_CPU_INDEX s3 31.balign 4 32sbi_hsm_check: 33 li HSM_RESULTS_MAP, 0 34 REG_L t0, ASMARR(a1, SBI_HSM_MAGIC_IDX) 35 li t1, SBI_HSM_MAGIC 36 bne t0, t1, 1f 37 ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_MAGIC_A1 381: REG_L t0, ASMARR(a1, SBI_HSM_HARTID_IDX) 39 bne a0, t0, 2f 40 ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_HARTID_A0 412: csrr t0, CSR_SATP 42 bnez t0, 3f 43 ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_SATP 443: csrr t0, CSR_SSTATUS 45 andi t0, t0, SR_SIE 46 bnez t0, 4f 47 ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_SIE 484: call hartid_to_cpu 49 mv HSM_CPU_INDEX, a0 50 li t0, -1 51 bne HSM_CPU_INDEX, t0, 6f 525: pause 53 j 5b 546: ori HSM_RESULTS_MAP, HSM_RESULTS_MAP, SBI_HSM_TEST_DONE 55 add t0, HSM_RESULTS_ARRAY, HSM_CPU_INDEX 56 sb HSM_RESULTS_MAP, 0(t0) 57 la t1, sbi_hsm_stop_hart 58 add t1, t1, HSM_CPU_INDEX 597: lb t0, 0(t1) 60 pause 61 beqz t0, 7b 62 li a7, ASM_SBI_EXT_HSM 63 li a6, ASM_SBI_EXT_HSM_HART_STOP 64 ecall 658: pause 66 j 8b 67 68.balign 4 69.global sbi_hsm_check_hart_start 70sbi_hsm_check_hart_start: 71 la HSM_RESULTS_ARRAY, sbi_hsm_hart_start_checks 72 j sbi_hsm_check 73 74.balign 4 75.global sbi_hsm_check_non_retentive_suspend 76sbi_hsm_check_non_retentive_suspend: 77 la HSM_RESULTS_ARRAY, sbi_hsm_non_retentive_hart_suspend_checks 78 j sbi_hsm_check 79 80.balign 4 81restore_csrs: 82 REG_L a1, ASMARR(a0, SBI_CSR_SSTATUS_IDX) 83 csrw CSR_SSTATUS, a1 84 REG_L a1, ASMARR(a0, SBI_CSR_SIE_IDX) 85 csrw CSR_SIE, a1 86 REG_L a1, ASMARR(a0, SBI_CSR_STVEC_IDX) 87 csrw CSR_STVEC, a1 88 REG_L a1, ASMARR(a0, SBI_CSR_SSCRATCH_IDX) 89 csrw CSR_SSCRATCH, a1 90 REG_L a1, ASMARR(a0, SBI_CSR_SATP_IDX) 91 sfence.vma 92 csrw CSR_SATP, a1 93 ret 94 95/* 96 * sbi_susp_resume 97 * 98 * State is as specified by "SUSP System Resume Register State" of the SBI spec 99 * a0 is the hartid 100 * a1 is the opaque parameter (here, it's the context array defined in check_susp()) 101 * Doesn't return. 102 */ 103#define SUSP_CTX s1 104#define SUSP_RESULTS_MAP s2 105.balign 4 106.global sbi_susp_resume 107sbi_susp_resume: 108 li SUSP_RESULTS_MAP, 0 109 mv SUSP_CTX, a1 110 REG_L t0, ASMARR(SUSP_CTX, SBI_SUSP_MAGIC_IDX) 111 li t1, SBI_SUSP_MAGIC 112 beq t0, t1, 2f 1131: pause 114 j 1b 1152: csrr t0, CSR_SATP 116 bnez t0, 3f 117 ori SUSP_RESULTS_MAP, SUSP_RESULTS_MAP, SBI_SUSP_TEST_SATP 1183: csrr t0, CSR_SSTATUS 119 andi t0, t0, SR_SIE 120 bnez t0, 4f 121 ori SUSP_RESULTS_MAP, SUSP_RESULTS_MAP, SBI_SUSP_TEST_SIE 1224: REG_L t0, ASMARR(SUSP_CTX, SBI_SUSP_HARTID_IDX) 123 bne t0, a0, 5f 124 ori SUSP_RESULTS_MAP, SUSP_RESULTS_MAP, SBI_SUSP_TEST_HARTID 1255: REG_S SUSP_RESULTS_MAP, ASMARR(SUSP_CTX, SBI_SUSP_RESULTS_IDX) 126 REG_L a0, ASMARR(SUSP_CTX, SBI_SUSP_CSRS_IDX) 127 call restore_csrs 128 la a0, sbi_susp_jmp 129 REG_L a1, ASMARR(SUSP_CTX, SBI_SUSP_TESTNUM_IDX) 130 call longjmp 1316: pause /* unreachable */ 132 j 6b 133