Skip to content

Commit f43fabf

Browse files
avpatelpalmer-dabbelt
authored andcommitted
RISC-V: Add SBI debug console helper routines
Let us provide SBI debug console helper routines which can be shared by serial/earlycon-riscv-sbi.c and hvc/hvc_riscv_sbi.c. Signed-off-by: Anup Patel <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent f503b16 commit f43fabf

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

arch/riscv/include/asm/sbi.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,11 @@ static inline unsigned long sbi_mk_version(unsigned long major,
334334
}
335335

336336
int sbi_err_map_linux_errno(int err);
337+
338+
extern bool sbi_debug_console_available;
339+
int sbi_debug_console_write(const char *bytes, unsigned int num_bytes);
340+
int sbi_debug_console_read(char *bytes, unsigned int num_bytes);
341+
337342
#else /* CONFIG_RISCV_SBI */
338343
static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1; }
339344
static inline void sbi_init(void) {}

arch/riscv/kernel/sbi.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <linux/bits.h>
99
#include <linux/init.h>
10+
#include <linux/mm.h>
1011
#include <linux/pm.h>
1112
#include <linux/reboot.h>
1213
#include <asm/sbi.h>
@@ -571,6 +572,66 @@ long sbi_get_mimpid(void)
571572
}
572573
EXPORT_SYMBOL_GPL(sbi_get_mimpid);
573574

575+
bool sbi_debug_console_available;
576+
577+
int sbi_debug_console_write(const char *bytes, unsigned int num_bytes)
578+
{
579+
phys_addr_t base_addr;
580+
struct sbiret ret;
581+
582+
if (!sbi_debug_console_available)
583+
return -EOPNOTSUPP;
584+
585+
if (is_vmalloc_addr(bytes))
586+
base_addr = page_to_phys(vmalloc_to_page(bytes)) +
587+
offset_in_page(bytes);
588+
else
589+
base_addr = __pa(bytes);
590+
if (PAGE_SIZE < (offset_in_page(bytes) + num_bytes))
591+
num_bytes = PAGE_SIZE - offset_in_page(bytes);
592+
593+
if (IS_ENABLED(CONFIG_32BIT))
594+
ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE,
595+
num_bytes, lower_32_bits(base_addr),
596+
upper_32_bits(base_addr), 0, 0, 0);
597+
else
598+
ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE,
599+
num_bytes, base_addr, 0, 0, 0, 0);
600+
601+
if (ret.error == SBI_ERR_FAILURE)
602+
return -EIO;
603+
return ret.error ? sbi_err_map_linux_errno(ret.error) : ret.value;
604+
}
605+
606+
int sbi_debug_console_read(char *bytes, unsigned int num_bytes)
607+
{
608+
phys_addr_t base_addr;
609+
struct sbiret ret;
610+
611+
if (!sbi_debug_console_available)
612+
return -EOPNOTSUPP;
613+
614+
if (is_vmalloc_addr(bytes))
615+
base_addr = page_to_phys(vmalloc_to_page(bytes)) +
616+
offset_in_page(bytes);
617+
else
618+
base_addr = __pa(bytes);
619+
if (PAGE_SIZE < (offset_in_page(bytes) + num_bytes))
620+
num_bytes = PAGE_SIZE - offset_in_page(bytes);
621+
622+
if (IS_ENABLED(CONFIG_32BIT))
623+
ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ,
624+
num_bytes, lower_32_bits(base_addr),
625+
upper_32_bits(base_addr), 0, 0, 0);
626+
else
627+
ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_READ,
628+
num_bytes, base_addr, 0, 0, 0, 0);
629+
630+
if (ret.error == SBI_ERR_FAILURE)
631+
return -EIO;
632+
return ret.error ? sbi_err_map_linux_errno(ret.error) : ret.value;
633+
}
634+
574635
void __init sbi_init(void)
575636
{
576637
int ret;
@@ -612,6 +673,11 @@ void __init sbi_init(void)
612673
sbi_srst_reboot_nb.priority = 192;
613674
register_restart_handler(&sbi_srst_reboot_nb);
614675
}
676+
if ((sbi_spec_version >= sbi_mk_version(2, 0)) &&
677+
(sbi_probe_extension(SBI_EXT_DBCN) > 0)) {
678+
pr_info("SBI DBCN extension detected\n");
679+
sbi_debug_console_available = true;
680+
}
615681
} else {
616682
__sbi_set_timer = __sbi_set_timer_v01;
617683
__sbi_send_ipi = __sbi_send_ipi_v01;

0 commit comments

Comments
 (0)