19ccb00e4SAndrew Jones // SPDX-License-Identifier: GPL-2.0-only 29ccb00e4SAndrew Jones #include <libcflat.h> 39ccb00e4SAndrew Jones #include <asm/sbi.h> 49ccb00e4SAndrew Jones 59ccb00e4SAndrew Jones struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, 69ccb00e4SAndrew Jones unsigned long arg1, unsigned long arg2, 79ccb00e4SAndrew Jones unsigned long arg3, unsigned long arg4, 89ccb00e4SAndrew Jones unsigned long arg5) 99ccb00e4SAndrew Jones { 109ccb00e4SAndrew Jones register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); 119ccb00e4SAndrew Jones register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); 129ccb00e4SAndrew Jones register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); 139ccb00e4SAndrew Jones register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); 149ccb00e4SAndrew Jones register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); 159ccb00e4SAndrew Jones register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); 169ccb00e4SAndrew Jones register uintptr_t a6 asm ("a6") = (uintptr_t)(fid); 179ccb00e4SAndrew Jones register uintptr_t a7 asm ("a7") = (uintptr_t)(ext); 189ccb00e4SAndrew Jones struct sbiret ret; 199ccb00e4SAndrew Jones 209ccb00e4SAndrew Jones asm volatile ( 219ccb00e4SAndrew Jones "ecall" 229ccb00e4SAndrew Jones : "+r" (a0), "+r" (a1) 239ccb00e4SAndrew Jones : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) 249ccb00e4SAndrew Jones : "memory"); 259ccb00e4SAndrew Jones ret.error = a0; 269ccb00e4SAndrew Jones ret.value = a1; 279ccb00e4SAndrew Jones 289ccb00e4SAndrew Jones return ret; 299ccb00e4SAndrew Jones } 309ccb00e4SAndrew Jones 319ccb00e4SAndrew Jones void sbi_shutdown(void) 329ccb00e4SAndrew Jones { 339ccb00e4SAndrew Jones sbi_ecall(SBI_EXT_SRST, 0, 0, 0, 0, 0, 0, 0); 349ccb00e4SAndrew Jones puts("SBI shutdown failed!\n"); 359ccb00e4SAndrew Jones } 369c92b28eSAndrew Jones 379c92b28eSAndrew Jones struct sbiret sbi_hart_start(unsigned long hartid, unsigned long entry, unsigned long sp) 389c92b28eSAndrew Jones { 399c92b28eSAndrew Jones return sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_START, hartid, entry, sp, 0, 0, 0); 409c92b28eSAndrew Jones } 41*7040d2a9SJames Raphael Tiovalen 42*7040d2a9SJames Raphael Tiovalen long sbi_probe(int ext) 43*7040d2a9SJames Raphael Tiovalen { 44*7040d2a9SJames Raphael Tiovalen struct sbiret ret; 45*7040d2a9SJames Raphael Tiovalen 46*7040d2a9SJames Raphael Tiovalen ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_GET_SPEC_VERSION, 0, 0, 0, 0, 0, 0); 47*7040d2a9SJames Raphael Tiovalen assert(!ret.error && ret.value >= 2); 48*7040d2a9SJames Raphael Tiovalen 49*7040d2a9SJames Raphael Tiovalen ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, ext, 0, 0, 0, 0, 0); 50*7040d2a9SJames Raphael Tiovalen assert(!ret.error); 51*7040d2a9SJames Raphael Tiovalen 52*7040d2a9SJames Raphael Tiovalen return ret.value; 53*7040d2a9SJames Raphael Tiovalen } 54