mb/**/hda_verb.c: Drop empty files
[coreboot.git] / src / arch / riscv / sbi.c
blob415ea9499dc2769c79d46df0e1af0e4bdd9f9408
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <mcall.h>
4 #include <stdint.h>
5 #include <arch/exception.h>
6 #include <sbi.h>
7 #include <vm.h>
8 #include <console/uart.h>
9 #include <commonlib/helpers.h>
11 static uintptr_t send_ipi(uintptr_t *pmask, intptr_t type)
13 uintptr_t mask = mprv_read_uintptr_t(pmask);
14 for (int i = 0; mask; i++) {
15 if (mask & 1) {
16 OTHER_HLS(i)->ipi_pending |= type;
17 /* send soft interrupt to target hart */
18 set_msip(i, 1);
20 mask = mask >> 1;
22 return 0;
25 static uintptr_t sbi_set_timer(uint64_t when)
27 clear_csr(mip, MIP_STIP);
28 set_csr(mie, MIP_MTIP);
29 *(HLS()->timecmp) = when;
30 return 0;
33 #if CONFIG(CONSOLE_SERIAL)
34 static uintptr_t sbi_console_putchar(uint8_t ch)
36 uart_tx_byte(CONFIG_UART_FOR_CONSOLE, ch);
37 return 0;
40 static uintptr_t sbi_console_getchar(void)
42 return uart_rx_byte(CONFIG_UART_FOR_CONSOLE);
44 #endif
46 static uintptr_t sbi_clear_ipi(void)
48 clear_csr(mip, MIP_SSIP);
49 return 0;
53 * sbi is triggered by the s-mode ecall
54 * parameter : register a0 a1 a2
55 * function : register a7
56 * return : register a0
58 void handle_sbi(trapframe *tf)
60 uintptr_t ret = 0;
61 uintptr_t arg0 = tf->gpr[10];
62 __maybe_unused uintptr_t arg1 = tf->gpr[11];
63 uintptr_t which = tf->gpr[17];
65 switch (which) {
66 case SBI_SET_TIMER:
67 #if __riscv_xlen == 32
68 ret = sbi_set_timer(arg0 + ((uint64_t)arg1 << 32));
69 #else
70 ret = sbi_set_timer(arg0);
71 #endif
72 break;
73 #if CONFIG(CONSOLE_SERIAL)
74 case SBI_CONSOLE_PUTCHAR:
75 ret = sbi_console_putchar(arg0);
76 break;
77 case SBI_CONSOLE_GETCHAR:
78 ret = sbi_console_getchar();
79 break;
80 #endif
81 case SBI_CLEAR_IPI:
82 ret = sbi_clear_ipi();
83 break;
84 case SBI_SEND_IPI:
85 ret = send_ipi((uintptr_t *)arg0, IPI_SOFT);
86 break;
87 case SBI_REMOTE_FENCE_I:
88 ret = send_ipi((uintptr_t *)arg0, IPI_FENCE_I);
89 break;
90 case SBI_REMOTE_SFENCE_VMA:
91 ret = send_ipi((uintptr_t *)arg0, IPI_SFENCE_VMA);
92 break;
93 case SBI_REMOTE_SFENCE_VMA_ASID:
94 ret = send_ipi((uintptr_t *)arg0, IPI_SFENCE_VMA_ASID);
95 break;
96 case SBI_SHUTDOWN:
97 ret = send_ipi((uintptr_t *)arg0, IPI_SHUTDOWN);
98 break;
99 default:
100 ret = -SBI_ENOSYS;
101 break;
103 tf->gpr[10] = ret;
104 write_csr(mepc, read_csr(mepc) + 4);