1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2008 David Gibson, IBM Corporation 4 * Copyright (C) 2012 Regents of the University of California 5 * Copyright (C) 2017 SiFive 6 */ 7 8 #include <linux/console.h> 9 #include <linux/err.h> 10 #include <linux/init.h> 11 #include <linux/moduleparam.h> 12 #include <linux/types.h> 13 14 #include <asm/sbi.h> 15 16 #include "hvc_console.h" 17 18 static ssize_t hvc_sbi_tty_put(uint32_t vtermno, const u8 *buf, size_t count) 19 { 20 size_t i; 21 22 for (i = 0; i < count; i++) 23 sbi_console_putchar(buf[i]); 24 25 return i; 26 } 27 28 static ssize_t hvc_sbi_tty_get(uint32_t vtermno, u8 *buf, size_t count) 29 { 30 size_t i; 31 int c; 32 33 for (i = 0; i < count; i++) { 34 c = sbi_console_getchar(); 35 if (c < 0) 36 break; 37 buf[i] = c; 38 } 39 40 return i; 41 } 42 43 static const struct hv_ops hvc_sbi_v01_ops = { 44 .get_chars = hvc_sbi_tty_get, 45 .put_chars = hvc_sbi_tty_put, 46 }; 47 48 static ssize_t hvc_sbi_dbcn_tty_put(uint32_t vtermno, const u8 *buf, size_t count) 49 { 50 return sbi_debug_console_write(buf, count); 51 } 52 53 static ssize_t hvc_sbi_dbcn_tty_get(uint32_t vtermno, u8 *buf, size_t count) 54 { 55 return sbi_debug_console_read(buf, count); 56 } 57 58 static const struct hv_ops hvc_sbi_dbcn_ops = { 59 .put_chars = hvc_sbi_dbcn_tty_put, 60 .get_chars = hvc_sbi_dbcn_tty_get, 61 }; 62 63 static int __init hvc_sbi_init(void) 64 { 65 int err; 66 67 if (sbi_debug_console_available) { 68 err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_dbcn_ops, 256)); 69 if (err) 70 return err; 71 hvc_instantiate(0, 0, &hvc_sbi_dbcn_ops); 72 } else if (IS_ENABLED(CONFIG_RISCV_SBI_V01)) { 73 err = PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_v01_ops, 256)); 74 if (err) 75 return err; 76 hvc_instantiate(0, 0, &hvc_sbi_v01_ops); 77 } else { 78 return -ENODEV; 79 } 80 81 return 0; 82 } 83 device_initcall(hvc_sbi_init); 84