mb/starlabs/{lite_adl,byte_adl}: Don't select MAINBOARD_HAS_TPM2
[coreboot2.git] / src / arch / riscv / sbi.c
blob2ef7625f57442be9caab7187d10340fba3a394df
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <mcall.h>
5 #include <stdint.h>
6 #include <arch/exception.h>
7 #include <sbi.h>
8 #include <vm.h>
9 #include <console/uart.h>
10 #include <commonlib/helpers.h>
12 static uintptr_t send_ipi(uintptr_t *pmask, intptr_t type)
14 uintptr_t mask = mprv_read_uintptr_t(pmask);
15 for (int i = 0; mask; i++) {
16 if (mask & 1) {
17 OTHER_HLS(i)->ipi_pending |= type;
18 /* send soft interrupt to target hart */
19 set_msip(i, 1);
21 mask = mask >> 1;
23 return 0;
26 static uintptr_t sbi_set_timer(uint64_t when)
28 clear_csr(mip, MIP_STIP);
29 set_csr(mie, MIP_MTIP);
30 *(HLS()->timecmp) = when;
31 return 0;
34 #if CONFIG(CONSOLE_SERIAL)
35 static uintptr_t sbi_console_putchar(uint8_t ch)
37 uart_tx_byte(CONFIG_UART_FOR_CONSOLE, ch);
38 return 0;
41 static uintptr_t sbi_console_getchar(void)
43 return uart_rx_byte(CONFIG_UART_FOR_CONSOLE);
45 #endif
47 static uintptr_t sbi_clear_ipi(void)
49 clear_csr(mip, MIP_SSIP);
50 return 0;
53 static void print_sbi_trap(uintptr_t trap)
55 switch (trap) {
56 case SBI_SHUTDOWN:
57 printk(BIOS_EMERG, "SBI_SHUTDOWN\n");
58 break;
59 case SBI_REMOTE_SFENCE_VMA_ASID:
60 printk(BIOS_EMERG, "SBI_REMOTE_SFENCE_VMA_ASID\n");
61 break;
62 case SBI_REMOTE_SFENCE_VMA:
63 printk(BIOS_EMERG, "SBI_REMOTE_SFENCE_VMA\n");
64 break;
65 case SBI_REMOTE_FENCE_I:
66 printk(BIOS_EMERG, "SBI_REMOTE_FENCE_I\n");
67 break;
68 case SBI_SEND_IPI:
69 printk(BIOS_EMERG, "SBI_SEND_IPI\n");
70 break;
71 case SBI_CLEAR_IPI:
72 printk(BIOS_EMERG, "SBI_CLEAR_IPI\n");
73 break;
74 case SBI_CONSOLE_GETCHAR:
75 printk(BIOS_EMERG, "SBI_CONSOLE_GETCHAR\n");
76 break;
77 case SBI_CONSOLE_PUTCHAR:
78 printk(BIOS_EMERG, "SBI_CONSOLE_PUTCHAR\n");
79 break;
80 case SBI_SET_TIMER:
81 printk(BIOS_EMERG, "SBI_SET_TIMER\n");
82 break;
83 case SBI_BASE_EXTENSION:
84 printk(BIOS_EMERG, "SBI_BASE_EXTENSION\n");
85 break;
86 default:
87 printk(BIOS_EMERG, "%lx is an unknown SBI trap\n", trap);
88 break;
93 * These are the default SBI extension values.
94 * They can be overridden, by specialized code,
95 * but since this is a GPL SBI, it may be better
96 * that they evolve as we extend this SBI.
97 * over time, the will be updated.
99 int sbi_features[] = {1, 0, 0, 0, 0, 0, 0};
102 * sbi is triggered by the s-mode ecall
103 * parameter : register a0 a1 a2
104 * function : register a7
105 * return : register a0
107 void handle_sbi(struct trapframe *tf)
109 uintptr_t ret = 0;
110 uintptr_t sbiret = 0;
111 uintptr_t arg0 = tf->gpr[10];
112 __maybe_unused uintptr_t arg1 = tf->gpr[11];
113 uintptr_t fid = tf->gpr[16];
114 uintptr_t eid = tf->gpr[17];
115 uintptr_t retpc = read_csr(mepc) + 4;
117 switch (eid) {
118 case SBI_SET_TIMER:
119 #if __riscv_xlen == 32
120 ret = sbi_set_timer(arg0 + ((uint64_t)arg1 << 32));
121 #else
122 ret = sbi_set_timer(arg0);
123 #endif
124 break;
125 #if CONFIG(CONSOLE_SERIAL)
126 case SBI_CONSOLE_PUTCHAR:
127 ret = sbi_console_putchar(arg0);
128 break;
129 case SBI_CONSOLE_GETCHAR:
130 ret = sbi_console_getchar();
131 break;
132 #endif
133 case SBI_CLEAR_IPI:
134 ret = sbi_clear_ipi();
135 break;
136 case SBI_SEND_IPI:
137 ret = send_ipi((uintptr_t *)arg0, IPI_SOFT);
138 break;
139 case SBI_REMOTE_FENCE_I:
140 ret = send_ipi((uintptr_t *)arg0, IPI_FENCE_I);
141 break;
142 case SBI_REMOTE_SFENCE_VMA:
143 ret = send_ipi((uintptr_t *)arg0, IPI_SFENCE_VMA);
144 break;
145 case SBI_REMOTE_SFENCE_VMA_ASID:
146 ret = send_ipi((uintptr_t *)arg0, IPI_SFENCE_VMA_ASID);
147 break;
148 case SBI_SHUTDOWN:
149 ret = send_ipi((uintptr_t *)arg0, IPI_SHUTDOWN);
150 break;
151 case SBI_BASE_EXTENSION:
152 /* zero is an allowed return value for most features,
153 * and the only required one is feature 0.
154 * So this test will return legal values
155 * for all possible values of fid.
157 if (fid < ARRAY_SIZE(sbi_features))
158 ret = sbi_features[fid];
159 break;
160 default:
161 print_sbi_trap(eid);
162 printk(BIOS_EMERG, "SBI: %lx: ENOSYS\n", fid);
163 sbiret = -SBI_ENOSYS;
164 break;
166 tf->gpr[10] = sbiret;
167 tf->gpr[11] = ret;
169 write_csr(mepc, retpc);