1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2024 Andes Technology Corporation 4 */ 5 6 #include <compiler.h> 7 #include <console.h> 8 #include <drivers/semihosting_console.h> 9 #include <drivers/serial.h> 10 #include <kernel/semihosting.h> 11 #include <util.h> 12 13 /* 14 * struct semihosting_console_data - Structure for semihosting console driver 15 * @chip - General structure for each serial chip 16 * @fd - Handle of the file at @file_path when semihosting_console_init() is 17 * called, or -1 if using the semihosting console 18 */ 19 struct semihosting_console_data { 20 struct serial_chip chip; 21 int fd; 22 }; 23 24 static struct semihosting_console_data sh_console_data __nex_bss; 25 26 static void semihosting_console_putc(struct serial_chip *chip __unused, int ch) 27 { 28 semihosting_sys_writec(ch); 29 } 30 31 static int semihosting_console_getchar(struct serial_chip *chip __unused) 32 { 33 return semihosting_sys_readc(); 34 } 35 36 static const struct serial_ops semihosting_console_ops = { 37 .putc = semihosting_console_putc, 38 .getchar = semihosting_console_getchar, 39 }; 40 DECLARE_KEEP_PAGER(semihosting_console_ops); 41 42 static void semihosting_console_fd_putc(struct serial_chip *chip __unused, 43 int ch) 44 { 45 if (sh_console_data.fd >= 0) 46 semihosting_write(sh_console_data.fd, &ch, 1); 47 } 48 49 static const struct serial_ops semihosting_console_fd_ops = { 50 .putc = semihosting_console_fd_putc, 51 }; 52 DECLARE_KEEP_PAGER(semihosting_console_fd_ops); 53 54 void semihosting_console_init(const char *file_path) 55 { 56 if (file_path) { 57 /* Output log to given file on the semihosting host system. */ 58 sh_console_data.chip.ops = &semihosting_console_fd_ops; 59 sh_console_data.fd = 60 semihosting_open(file_path, O_RDWR | O_CREAT | O_TRUNC); 61 } else { 62 /* Output log to semihosting host debug console. */ 63 sh_console_data.chip.ops = &semihosting_console_ops; 64 sh_console_data.fd = -1; 65 } 66 67 register_serial_console(&sh_console_data.chip); 68 } 69