diff --git a/sys/riscv/include/sbi.h b/sys/riscv/include/sbi.h --- a/sys/riscv/include/sbi.h +++ b/sys/riscv/include/sbi.h @@ -108,6 +108,12 @@ #define SBI_SRST_REASON_NONE 0 #define SBI_SRST_REASON_SYSTEM_FAILURE 1 +/* Debug Console (DBCN) Extension */ +#define SBI_EXT_ID_DBGCON 0x4442434E +#define SBI_DBGCON_WRITE 0 +#define SBI_DBGCON_READ 1 +#define SBI_DBGCON_WRITECHAR 2 + /* Legacy Extensions */ #define SBI_SET_TIMER 0 #define SBI_CONSOLE_PUTCHAR 1 @@ -220,24 +226,10 @@ */ void sbi_system_reset(u_long reset_type, u_long reset_reason); -/* Legacy extension functions. */ -static __inline void -sbi_console_putchar(int ch) -{ - - (void)SBI_CALL1(SBI_CONSOLE_PUTCHAR, 0, ch); -} - -static __inline int -sbi_console_getchar(void) -{ - - /* - * XXX: The "error" is returned here because legacy SBI functions - * continue to return their value in a0. - */ - return (SBI_CALL0(SBI_CONSOLE_GETCHAR, 0).error); -} +/* Debug Console extension functions. */ +int sbi_console_puts(char *str); +void sbi_console_putchar(char ch); +char sbi_console_getchar(void); void sbi_print_version(void); void sbi_init(void); diff --git a/sys/riscv/riscv/sbi.c b/sys/riscv/riscv/sbi.c --- a/sys/riscv/riscv/sbi.c +++ b/sys/riscv/riscv/sbi.c @@ -50,6 +50,7 @@ static bool has_ipi_extension = false; static bool has_rfnc_extension = false; static bool has_srst_extension = false; +static bool has_dbgcon_extension = false; static struct sbi_ret sbi_get_spec_version(void) @@ -256,6 +257,49 @@ return (ret.error != 0 ? (int)ret.error : (int)ret.value); } +/* Console functions. */ +int +sbi_console_puts(char *str) +{ + if (!has_dbgcon_extension) + return (EOPNOTSUPP); + + return (SBI_CALL2(SBI_EXT_ID_DBGCON, SBI_DBGCON_WRITE, strlen(str), + (uint64_t)str).error); +} + +void +sbi_console_putchar(char ch) +{ + if (has_dbgcon_extension) + (void)SBI_CALL1(SBI_EXT_ID_DBGCON, SBI_DBGCON_WRITECHAR, + (uint8_t)ch); + else + (void)SBI_CALL1(SBI_CONSOLE_PUTCHAR, 0, ch); +} + +char +sbi_console_getchar(void) +{ + struct sbi_ret ret; + char ch; + + if (has_dbgcon_extension) { + ret = SBI_CALL3(SBI_EXT_ID_DBGCON, SBI_DBGCON_READ, 1, (u_long)&ch, + (u_long)&ch); + ch = (char)ret.value; + } else { + /* + * XXX: The "error" is returned here because legacy SBI + * functions continue to return their value in a0. + */ + ret = SBI_CALL0(SBI_CONSOLE_GETCHAR, 0); + ch = (char)ret.error; + } + + return (ch); +} + void sbi_init(void) { @@ -291,6 +335,8 @@ has_rfnc_extension = true; if (sbi_has_extension(SBI_EXT_ID_SRST)) has_srst_extension = true; + if (sbi_has_extension(SBI_EXT_ID_DBGCON)) + has_dbgcon_extension = true; /* * Probe for legacy extensions. We still rely on many of them to be @@ -298,10 +344,8 @@ */ KASSERT(has_time_extension || sbi_has_extension(SBI_SET_TIMER), ("SBI doesn't implement sbi_set_timer()")); - KASSERT(sbi_has_extension(SBI_CONSOLE_PUTCHAR), + KASSERT(has_dbgcon_extension || sbi_has_extension(SBI_CONSOLE_PUTCHAR), ("SBI doesn't implement sbi_console_putchar()")); - KASSERT(sbi_has_extension(SBI_CONSOLE_GETCHAR), - ("SBI doesn't implement sbi_console_getchar()")); KASSERT(has_ipi_extension || sbi_has_extension(SBI_SEND_IPI), ("SBI doesn't implement sbi_send_ipi()")); KASSERT(has_rfnc_extension ||