1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <arch/exception.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
++) {
16 OTHER_HLS(i
)->ipi_pending
|= type
;
17 /* send soft interrupt to target hart */
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
;
33 #if CONFIG(CONSOLE_SERIAL)
34 static uintptr_t sbi_console_putchar(uint8_t ch
)
36 uart_tx_byte(CONFIG_UART_FOR_CONSOLE
, ch
);
40 static uintptr_t sbi_console_getchar(void)
42 return uart_rx_byte(CONFIG_UART_FOR_CONSOLE
);
46 static uintptr_t sbi_clear_ipi(void)
48 clear_csr(mip
, MIP_SSIP
);
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
)
61 uintptr_t arg0
= tf
->gpr
[10];
62 __maybe_unused
uintptr_t arg1
= tf
->gpr
[11];
63 uintptr_t which
= tf
->gpr
[17];
67 #if __riscv_xlen == 32
68 ret
= sbi_set_timer(arg0
+ ((uint64_t)arg1
<< 32));
70 ret
= sbi_set_timer(arg0
);
73 #if CONFIG(CONSOLE_SERIAL)
74 case SBI_CONSOLE_PUTCHAR
:
75 ret
= sbi_console_putchar(arg0
);
77 case SBI_CONSOLE_GETCHAR
:
78 ret
= sbi_console_getchar();
82 ret
= sbi_clear_ipi();
85 ret
= send_ipi((uintptr_t *)arg0
, IPI_SOFT
);
87 case SBI_REMOTE_FENCE_I
:
88 ret
= send_ipi((uintptr_t *)arg0
, IPI_FENCE_I
);
90 case SBI_REMOTE_SFENCE_VMA
:
91 ret
= send_ipi((uintptr_t *)arg0
, IPI_SFENCE_VMA
);
93 case SBI_REMOTE_SFENCE_VMA_ASID
:
94 ret
= send_ipi((uintptr_t *)arg0
, IPI_SFENCE_VMA_ASID
);
97 ret
= send_ipi((uintptr_t *)arg0
, IPI_SHUTDOWN
);
104 write_csr(mepc
, read_csr(mepc
) + 4);