diff options
-rw-r--r-- | firmware/payloads/test_main.c | 2 | ||||
-rw-r--r-- | include/sbi/sbi_ecall_interface.h | 20 | ||||
-rw-r--r-- | lib/sbi/sbi_ecall.c | 54 |
3 files changed, 48 insertions, 28 deletions
diff --git a/firmware/payloads/test_main.c b/firmware/payloads/test_main.c index eba5e4d..0d65930 100644 --- a/firmware/payloads/test_main.c +++ b/firmware/payloads/test_main.c @@ -26,7 +26,7 @@ #define SBI_ECALL_1(__num, __a0) SBI_ECALL(__num, __a0, 0, 0) #define SBI_ECALL_2(__num, __a0, __a1) SBI_ECALL(__num, __a0, __a1, 0) -#define sbi_ecall_console_putc(c) SBI_ECALL_1(SBI_ECALL_CONSOLE_PUTCHAR, (c)) +#define sbi_ecall_console_putc(c) SBI_ECALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, (c)) static inline void sbi_ecall_console_puts(const char *str) { diff --git a/include/sbi/sbi_ecall_interface.h b/include/sbi/sbi_ecall_interface.h index 0d8e5ea..a7564d6 100644 --- a/include/sbi/sbi_ecall_interface.h +++ b/include/sbi/sbi_ecall_interface.h @@ -12,15 +12,17 @@ /* clang-format off */ -#define SBI_ECALL_SET_TIMER 0 -#define SBI_ECALL_CONSOLE_PUTCHAR 1 -#define SBI_ECALL_CONSOLE_GETCHAR 2 -#define SBI_ECALL_CLEAR_IPI 3 -#define SBI_ECALL_SEND_IPI 4 -#define SBI_ECALL_REMOTE_FENCE_I 5 -#define SBI_ECALL_REMOTE_SFENCE_VMA 6 -#define SBI_ECALL_REMOTE_SFENCE_VMA_ASID 7 -#define SBI_ECALL_SHUTDOWN 8 +enum sbi_ext_id { + SBI_EXT_0_1_SET_TIMER = 0x0, + SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1, + SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2, + SBI_EXT_0_1_CLEAR_IPI = 0x3, + SBI_EXT_0_1_SEND_IPI = 0x4, + SBI_EXT_0_1_REMOTE_FENCE_I = 0x5, + SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6, + SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7, + SBI_EXT_0_1_SHUTDOWN = 0x8, +}; /* clang-format on */ diff --git a/lib/sbi/sbi_ecall.c b/lib/sbi/sbi_ecall.c index c6ec76e..311c4cf 100644 --- a/lib/sbi/sbi_ecall.c +++ b/lib/sbi/sbi_ecall.c @@ -31,16 +31,16 @@ u16 sbi_ecall_version_minor(void) return SBI_ECALL_VERSION_MINOR; } -int sbi_ecall_handler(u32 hartid, ulong mcause, struct sbi_trap_regs *regs, - struct sbi_scratch *scratch) +int sbi_ecall_0_1_handler(u32 hartid, struct sbi_trap_regs *regs, + struct sbi_scratch *scratch, + struct unpriv_trap *uptrap) { int ret = SBI_ENOTSUPP; - struct unpriv_trap uptrap; struct sbi_tlb_info tlb_info; u32 source_hart = sbi_current_hartid(); switch (regs->a7) { - case SBI_ECALL_SET_TIMER: + case SBI_EXT_0_1_SET_TIMER: #if __riscv_xlen == 32 sbi_timer_event_start(scratch, (((u64)regs->a1 << 32) | (u64)regs->a0)); @@ -49,60 +49,78 @@ int sbi_ecall_handler(u32 hartid, ulong mcause, struct sbi_trap_regs *regs, #endif ret = 0; break; - case SBI_ECALL_CONSOLE_PUTCHAR: + case SBI_EXT_0_1_CONSOLE_PUTCHAR: sbi_putc(regs->a0); ret = 0; break; - case SBI_ECALL_CONSOLE_GETCHAR: + case SBI_EXT_0_1_CONSOLE_GETCHAR: regs->a0 = sbi_getc(); ret = 0; break; - case SBI_ECALL_CLEAR_IPI: + case SBI_EXT_0_1_CLEAR_IPI: sbi_ipi_clear_smode(scratch); ret = 0; break; - case SBI_ECALL_SEND_IPI: - ret = sbi_ipi_send_many(scratch, &uptrap, (ulong *)regs->a0, + case SBI_EXT_0_1_SEND_IPI: + ret = sbi_ipi_send_many(scratch, uptrap, (ulong *)regs->a0, SBI_IPI_EVENT_SOFT, NULL); break; - case SBI_ECALL_REMOTE_FENCE_I: + case SBI_EXT_0_1_REMOTE_FENCE_I: tlb_info.start = 0; tlb_info.size = 0; tlb_info.type = SBI_ITLB_FLUSH; tlb_info.shart_mask = 1UL << source_hart; - ret = sbi_ipi_send_many(scratch, &uptrap, (ulong *)regs->a0, + ret = sbi_ipi_send_many(scratch, uptrap, (ulong *)regs->a0, SBI_IPI_EVENT_FENCE_I, &tlb_info); break; - case SBI_ECALL_REMOTE_SFENCE_VMA: + case SBI_EXT_0_1_REMOTE_SFENCE_VMA: tlb_info.start = (unsigned long)regs->a1; tlb_info.size = (unsigned long)regs->a2; tlb_info.type = SBI_TLB_FLUSH_VMA; tlb_info.shart_mask = 1UL << source_hart; - ret = sbi_ipi_send_many(scratch, &uptrap, (ulong *)regs->a0, + ret = sbi_ipi_send_many(scratch, uptrap, (ulong *)regs->a0, SBI_IPI_EVENT_SFENCE_VMA, &tlb_info); break; - case SBI_ECALL_REMOTE_SFENCE_VMA_ASID: + case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID: tlb_info.start = (unsigned long)regs->a1; tlb_info.size = (unsigned long)regs->a2; tlb_info.asid = (unsigned long)regs->a3; tlb_info.type = SBI_TLB_FLUSH_VMA_ASID; tlb_info.shart_mask = 1UL << source_hart; - ret = sbi_ipi_send_many(scratch, &uptrap, (ulong *)regs->a0, + ret = sbi_ipi_send_many(scratch, uptrap, (ulong *)regs->a0, SBI_IPI_EVENT_SFENCE_VMA_ASID, &tlb_info); break; - case SBI_ECALL_SHUTDOWN: + case SBI_EXT_0_1_SHUTDOWN: sbi_system_shutdown(scratch, 0); ret = 0; break; default: regs->a0 = SBI_ENOTSUPP; - ret = 0; - break; + ret = 0; }; + return ret; + +} + +int sbi_ecall_handler(u32 hartid, ulong mcause, struct sbi_trap_regs *regs, + struct sbi_scratch *scratch) +{ + int ret = SBI_ENOTSUPP; + struct unpriv_trap uptrap; + u32 extension_id = regs->a7; + + if (extension_id >= SBI_EXT_0_1_SET_TIMER && + extension_id <= SBI_EXT_0_1_SHUTDOWN) { + ret = sbi_ecall_0_1_handler(hartid, regs, scratch, &uptrap); + } else { + regs->a0 = SBI_ENOTSUPP; + ret = 0; + } + if (!ret) { regs->mepc += 4; } else if (ret == SBI_ETRAP) { |