.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | 3 | * 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. |
---|
| 4 | + * Copyright (c) 2020 Western Digital Corporation or its affiliates. |
---|
12 | 5 | */ |
---|
13 | 6 | |
---|
14 | 7 | #ifndef _ASM_RISCV_SBI_H |
---|
.. | .. |
---|
16 | 9 | |
---|
17 | 10 | #include <linux/types.h> |
---|
18 | 11 | |
---|
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) ({ \ |
---|
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 a7 asm ("a7") = (uintptr_t)(which); \ |
---|
34 | | - asm volatile ("ecall" \ |
---|
35 | | - : "+r" (a0) \ |
---|
36 | | - : "r" (a1), "r" (a2), "r" (a7) \ |
---|
37 | | - : "memory"); \ |
---|
38 | | - a0; \ |
---|
39 | | -}) |
---|
40 | | - |
---|
41 | | -/* Lazy implementations until SBI is finalized */ |
---|
42 | | -#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0) |
---|
43 | | -#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0) |
---|
44 | | -#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0) |
---|
45 | | - |
---|
46 | | -static inline void sbi_console_putchar(int ch) |
---|
47 | | -{ |
---|
48 | | - SBI_CALL_1(SBI_CONSOLE_PUTCHAR, ch); |
---|
49 | | -} |
---|
50 | | - |
---|
51 | | -static inline int sbi_console_getchar(void) |
---|
52 | | -{ |
---|
53 | | - return SBI_CALL_0(SBI_CONSOLE_GETCHAR); |
---|
54 | | -} |
---|
55 | | - |
---|
56 | | -static inline void sbi_set_timer(uint64_t stime_value) |
---|
57 | | -{ |
---|
58 | | -#if __riscv_xlen == 32 |
---|
59 | | - SBI_CALL_2(SBI_SET_TIMER, stime_value, stime_value >> 32); |
---|
60 | | -#else |
---|
61 | | - SBI_CALL_1(SBI_SET_TIMER, stime_value); |
---|
| 12 | +#ifdef CONFIG_RISCV_SBI |
---|
| 13 | +enum sbi_ext_id { |
---|
| 14 | +#ifdef CONFIG_RISCV_SBI_V01 |
---|
| 15 | + SBI_EXT_0_1_SET_TIMER = 0x0, |
---|
| 16 | + SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, |
---|
| 17 | + SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, |
---|
| 18 | + SBI_EXT_0_1_CLEAR_IPI = 0x3, |
---|
| 19 | + SBI_EXT_0_1_SEND_IPI = 0x4, |
---|
| 20 | + SBI_EXT_0_1_REMOTE_FENCE_I = 0x5, |
---|
| 21 | + SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, |
---|
| 22 | + SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, |
---|
| 23 | + SBI_EXT_0_1_SHUTDOWN = 0x8, |
---|
62 | 24 | #endif |
---|
63 | | -} |
---|
| 25 | + SBI_EXT_BASE = 0x10, |
---|
| 26 | + SBI_EXT_TIME = 0x54494D45, |
---|
| 27 | + SBI_EXT_IPI = 0x735049, |
---|
| 28 | + SBI_EXT_RFENCE = 0x52464E43, |
---|
| 29 | + SBI_EXT_HSM = 0x48534D, |
---|
| 30 | +}; |
---|
64 | 31 | |
---|
65 | | -static inline void sbi_shutdown(void) |
---|
| 32 | +enum sbi_ext_base_fid { |
---|
| 33 | + SBI_EXT_BASE_GET_SPEC_VERSION = 0, |
---|
| 34 | + SBI_EXT_BASE_GET_IMP_ID, |
---|
| 35 | + SBI_EXT_BASE_GET_IMP_VERSION, |
---|
| 36 | + SBI_EXT_BASE_PROBE_EXT, |
---|
| 37 | + SBI_EXT_BASE_GET_MVENDORID, |
---|
| 38 | + SBI_EXT_BASE_GET_MARCHID, |
---|
| 39 | + SBI_EXT_BASE_GET_MIMPID, |
---|
| 40 | +}; |
---|
| 41 | + |
---|
| 42 | +enum sbi_ext_time_fid { |
---|
| 43 | + SBI_EXT_TIME_SET_TIMER = 0, |
---|
| 44 | +}; |
---|
| 45 | + |
---|
| 46 | +enum sbi_ext_ipi_fid { |
---|
| 47 | + SBI_EXT_IPI_SEND_IPI = 0, |
---|
| 48 | +}; |
---|
| 49 | + |
---|
| 50 | +enum sbi_ext_rfence_fid { |
---|
| 51 | + SBI_EXT_RFENCE_REMOTE_FENCE_I = 0, |
---|
| 52 | + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, |
---|
| 53 | + SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, |
---|
| 54 | + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, |
---|
| 55 | + SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, |
---|
| 56 | + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, |
---|
| 57 | + SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, |
---|
| 58 | +}; |
---|
| 59 | + |
---|
| 60 | +enum sbi_ext_hsm_fid { |
---|
| 61 | + SBI_EXT_HSM_HART_START = 0, |
---|
| 62 | + SBI_EXT_HSM_HART_STOP, |
---|
| 63 | + SBI_EXT_HSM_HART_STATUS, |
---|
| 64 | +}; |
---|
| 65 | + |
---|
| 66 | +enum sbi_hsm_hart_status { |
---|
| 67 | + SBI_HSM_HART_STATUS_STARTED = 0, |
---|
| 68 | + SBI_HSM_HART_STATUS_STOPPED, |
---|
| 69 | + SBI_HSM_HART_STATUS_START_PENDING, |
---|
| 70 | + SBI_HSM_HART_STATUS_STOP_PENDING, |
---|
| 71 | +}; |
---|
| 72 | + |
---|
| 73 | +#define SBI_SPEC_VERSION_DEFAULT 0x1 |
---|
| 74 | +#define SBI_SPEC_VERSION_MAJOR_SHIFT 24 |
---|
| 75 | +#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f |
---|
| 76 | +#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff |
---|
| 77 | + |
---|
| 78 | +/* SBI return error codes */ |
---|
| 79 | +#define SBI_SUCCESS 0 |
---|
| 80 | +#define SBI_ERR_FAILURE -1 |
---|
| 81 | +#define SBI_ERR_NOT_SUPPORTED -2 |
---|
| 82 | +#define SBI_ERR_INVALID_PARAM -3 |
---|
| 83 | +#define SBI_ERR_DENIED -4 |
---|
| 84 | +#define SBI_ERR_INVALID_ADDRESS -5 |
---|
| 85 | + |
---|
| 86 | +extern unsigned long sbi_spec_version; |
---|
| 87 | +struct sbiret { |
---|
| 88 | + long error; |
---|
| 89 | + long value; |
---|
| 90 | +}; |
---|
| 91 | + |
---|
| 92 | +int sbi_init(void); |
---|
| 93 | +struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, |
---|
| 94 | + unsigned long arg1, unsigned long arg2, |
---|
| 95 | + unsigned long arg3, unsigned long arg4, |
---|
| 96 | + unsigned long arg5); |
---|
| 97 | + |
---|
| 98 | +void sbi_console_putchar(int ch); |
---|
| 99 | +int sbi_console_getchar(void); |
---|
| 100 | +void sbi_set_timer(uint64_t stime_value); |
---|
| 101 | +void sbi_shutdown(void); |
---|
| 102 | +void sbi_clear_ipi(void); |
---|
| 103 | +void sbi_send_ipi(const unsigned long *hart_mask); |
---|
| 104 | +void sbi_remote_fence_i(const unsigned long *hart_mask); |
---|
| 105 | +void sbi_remote_sfence_vma(const unsigned long *hart_mask, |
---|
| 106 | + unsigned long start, |
---|
| 107 | + unsigned long size); |
---|
| 108 | + |
---|
| 109 | +void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, |
---|
| 110 | + unsigned long start, |
---|
| 111 | + unsigned long size, |
---|
| 112 | + unsigned long asid); |
---|
| 113 | +int sbi_remote_hfence_gvma(const unsigned long *hart_mask, |
---|
| 114 | + unsigned long start, |
---|
| 115 | + unsigned long size); |
---|
| 116 | +int sbi_remote_hfence_gvma_vmid(const unsigned long *hart_mask, |
---|
| 117 | + unsigned long start, |
---|
| 118 | + unsigned long size, |
---|
| 119 | + unsigned long vmid); |
---|
| 120 | +int sbi_remote_hfence_vvma(const unsigned long *hart_mask, |
---|
| 121 | + unsigned long start, |
---|
| 122 | + unsigned long size); |
---|
| 123 | +int sbi_remote_hfence_vvma_asid(const unsigned long *hart_mask, |
---|
| 124 | + unsigned long start, |
---|
| 125 | + unsigned long size, |
---|
| 126 | + unsigned long asid); |
---|
| 127 | +int sbi_probe_extension(int ext); |
---|
| 128 | + |
---|
| 129 | +/* Check if current SBI specification version is 0.1 or not */ |
---|
| 130 | +static inline int sbi_spec_is_0_1(void) |
---|
66 | 131 | { |
---|
67 | | - SBI_CALL_0(SBI_SHUTDOWN); |
---|
| 132 | + return (sbi_spec_version == SBI_SPEC_VERSION_DEFAULT) ? 1 : 0; |
---|
68 | 133 | } |
---|
69 | 134 | |
---|
70 | | -static inline void sbi_clear_ipi(void) |
---|
| 135 | +/* Get the major version of SBI */ |
---|
| 136 | +static inline unsigned long sbi_major_version(void) |
---|
71 | 137 | { |
---|
72 | | - SBI_CALL_0(SBI_CLEAR_IPI); |
---|
| 138 | + return (sbi_spec_version >> SBI_SPEC_VERSION_MAJOR_SHIFT) & |
---|
| 139 | + SBI_SPEC_VERSION_MAJOR_MASK; |
---|
73 | 140 | } |
---|
74 | 141 | |
---|
75 | | -static inline void sbi_send_ipi(const unsigned long *hart_mask) |
---|
| 142 | +/* Get the minor version of SBI */ |
---|
| 143 | +static inline unsigned long sbi_minor_version(void) |
---|
76 | 144 | { |
---|
77 | | - SBI_CALL_1(SBI_SEND_IPI, hart_mask); |
---|
| 145 | + return sbi_spec_version & SBI_SPEC_VERSION_MINOR_MASK; |
---|
78 | 146 | } |
---|
79 | 147 | |
---|
80 | | -static inline void sbi_remote_fence_i(const unsigned long *hart_mask) |
---|
81 | | -{ |
---|
82 | | - SBI_CALL_1(SBI_REMOTE_FENCE_I, hart_mask); |
---|
83 | | -} |
---|
84 | | - |
---|
85 | | -static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask, |
---|
86 | | - unsigned long start, |
---|
87 | | - unsigned long size) |
---|
88 | | -{ |
---|
89 | | - SBI_CALL_1(SBI_REMOTE_SFENCE_VMA, hart_mask); |
---|
90 | | -} |
---|
91 | | - |
---|
92 | | -static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, |
---|
93 | | - unsigned long start, |
---|
94 | | - unsigned long size, |
---|
95 | | - unsigned long asid) |
---|
96 | | -{ |
---|
97 | | - SBI_CALL_1(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask); |
---|
98 | | -} |
---|
99 | | - |
---|
100 | | -#endif |
---|
| 148 | +int sbi_err_map_linux_errno(int err); |
---|
| 149 | +#else /* CONFIG_RISCV_SBI */ |
---|
| 150 | +/* stubs for code that is only reachable under IS_ENABLED(CONFIG_RISCV_SBI): */ |
---|
| 151 | +void sbi_set_timer(uint64_t stime_value); |
---|
| 152 | +void sbi_clear_ipi(void); |
---|
| 153 | +void sbi_send_ipi(const unsigned long *hart_mask); |
---|
| 154 | +void sbi_remote_fence_i(const unsigned long *hart_mask); |
---|
| 155 | +void sbi_init(void); |
---|
| 156 | +#endif /* CONFIG_RISCV_SBI */ |
---|
| 157 | +#endif /* _ASM_RISCV_SBI_H */ |
---|