1 /* 2 * Copyright (C) 2015 Regents of the University of California 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14 #ifndef _ASM_RISCV_SBI_H 15 #define _ASM_RISCV_SBI_H 16 17 #include <linux/types.h> 18 19 #define SBI_SET_TIMER 0 20 #define SBI_CONSOLE_PUTCHAR 1 21 #define SBI_CONSOLE_GETCHAR 2 22 #define SBI_CLEAR_IPI 3 23 #define SBI_SEND_IPI 4 24 #define SBI_REMOTE_FENCE_I 5 25 #define SBI_REMOTE_SFENCE_VMA 6 26 #define SBI_REMOTE_SFENCE_VMA_ASID 7 27 #define SBI_SHUTDOWN 8 28 29 #define SBI_CALL(which, arg0, arg1, arg2, arg3) ({ \ 30 register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ 31 register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ 32 register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ 33 register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); \ 34 register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ 35 asm volatile ("ecall" \ 36 : "+r" (a0) \ 37 : "r" (a1), "r" (a2), "r" (a3), "r" (a7) \ 38 : "memory"); \ 39 a0; \ 40 }) 41 42 /* Lazy implementations until SBI is finalized */ 43 #define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0, 0) 44 #define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0, 0) 45 #define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0, 0) 46 #define SBI_CALL_3(which, arg0, arg1, arg2) \ 47 SBI_CALL(which, arg0, arg1, arg2, 0) 48 #define SBI_CALL_4(which, arg0, arg1, arg2, arg3) \ 49 SBI_CALL(which, arg0, arg1, arg2, arg3) 50 51 static inline void sbi_console_putchar(int ch) 52 { 53 SBI_CALL_1(SBI_CONSOLE_PUTCHAR, ch); 54 } 55 56 static inline int sbi_console_getchar(void) 57 { 58 return SBI_CALL_0(SBI_CONSOLE_GETCHAR); 59 } 60 61 static inline void sbi_set_timer(uint64_t stime_value) 62 { 63 #if __riscv_xlen == 32 64 SBI_CALL_2(SBI_SET_TIMER, stime_value, stime_value >> 32); 65 #else 66 SBI_CALL_1(SBI_SET_TIMER, stime_value); 67 #endif 68 } 69 70 static inline void sbi_shutdown(void) 71 { 72 SBI_CALL_0(SBI_SHUTDOWN); 73 } 74 75 static inline void sbi_clear_ipi(void) 76 { 77 SBI_CALL_0(SBI_CLEAR_IPI); 78 } 79 80 static inline void sbi_send_ipi(const unsigned long *hart_mask) 81 { 82 SBI_CALL_1(SBI_SEND_IPI, hart_mask); 83 } 84 85 static inline void sbi_remote_fence_i(const unsigned long *hart_mask) 86 { 87 SBI_CALL_1(SBI_REMOTE_FENCE_I, hart_mask); 88 } 89 90 static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask, 91 unsigned long start, 92 unsigned long size) 93 { 94 SBI_CALL_3(SBI_REMOTE_SFENCE_VMA, hart_mask, start, size); 95 } 96 97 static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, 98 unsigned long start, 99 unsigned long size, 100 unsigned long asid) 101 { 102 SBI_CALL_4(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid); 103 } 104 105 #endif 106