1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2022 NXP 4 */ 5 6 #include <riscv.h> 7 #include <sbi.h> 8 9 struct sbiret { 10 long error; 11 long value; 12 }; 13 14 #define _sbi_ecall(ext, fid, arg0, arg1, arg2, arg3, arg4, arg5, ...) ({ \ 15 register unsigned long a0 asm("a0") = (unsigned long)arg0; \ 16 register unsigned long a1 asm("a1") = (unsigned long)arg1; \ 17 register unsigned long a2 asm("a2") = (unsigned long)arg2; \ 18 register unsigned long a3 asm("a3") = (unsigned long)arg3; \ 19 register unsigned long a4 asm("a4") = (unsigned long)arg4; \ 20 register unsigned long a5 asm("a5") = (unsigned long)arg5; \ 21 register unsigned long a6 asm("a6") = (unsigned long)fid; \ 22 register unsigned long a7 asm("a7") = (unsigned long)ext; \ 23 asm volatile ("ecall" \ 24 : "+r" (a0), "+r" (a1) \ 25 : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r"(a6), "r"(a7) \ 26 : "memory"); \ 27 (struct sbiret){ .error = a0, .value = a1 }; \ 28 }) 29 30 #define sbi_ecall(...) _sbi_ecall(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0) 31 32 /** 33 * sbi_probe_extension() - Check if an SBI extension ID is supported or not. 34 * @extid: The extension ID to be probed. 35 * 36 * Return: 1 or an extension specific nonzero value if yes, 0 otherwise. 37 */ 38 int sbi_probe_extension(int extid) 39 { 40 struct sbiret ret = { }; 41 42 ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid); 43 if (!ret.error) 44 return ret.value; 45 46 return 0; 47 } 48 49 /** 50 * sbi_console_putchar() - Writes given character to the console device. 51 * @ch: The data to be written to the console. 52 */ 53 void sbi_console_putchar(int ch) 54 { 55 sbi_ecall(SBI_EXT_0_1_CONSOLE_PUTCHAR, 0, ch); 56 } 57 58 /** 59 * sbi_dbcn_write_byte() - Write byte to debug console 60 * @ch: Byte to be written 61 * 62 * Return: SBI error code (SBI_SUCCESS = 0 on success) 63 */ 64 int sbi_dbcn_write_byte(unsigned char ch) 65 { 66 struct sbiret ret = { }; 67 68 ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE_BYTE, ch); 69 return ret.error; 70 } 71 72 int sbi_hsm_hart_start(uint32_t hartid, paddr_t start_addr, unsigned long arg) 73 { 74 struct sbiret ret = { }; 75 76 ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_START, hartid, start_addr, 77 arg); 78 79 return ret.error; 80 } 81