diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2021-03-11 16:20:57 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2021-03-11 16:20:58 +0000 |
| commit | f4abdf32714d1845b7c01ec136dd2b04c2f7db47 (patch) | |
| tree | 38a0a3c8aa2a7295bf54411b1e7f6090a6c489a6 /hw/semihosting/console.c | |
| parent | 9abda42bf2f5aa6ef403d3140fd3d7d88e8064e9 (diff) | |
| parent | 8df9f0c3d7f53c5a123ebb873d1c22daec003c22 (diff) | |
| download | focaccia-qemu-f4abdf32714d1845b7c01ec136dd2b04c2f7db47.tar.gz focaccia-qemu-f4abdf32714d1845b7c01ec136dd2b04c2f7db47.zip | |
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-docs-xen-updates-100321-2' into staging
Testing, guest-loader and other misc tweaks - add warning text to quickstart example - add CFI tests to CI - use --arch-only for docker pre-requisites - fix .editorconfig for emacs - add guest-loader for Xen-like hypervisor testing - move generic-loader docs into manual proper - move semihosting out of hw/ # gpg: Signature made Wed 10 Mar 2021 15:35:31 GMT # gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full] # Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44 * remotes/stsquad/tags/pull-testing-docs-xen-updates-100321-2: semihosting: Move hw/semihosting/ -> semihosting/ semihosting: Move include/hw/semihosting/ -> include/semihosting/ tests/avocado: add boot_xen tests docs: add some documentation for the guest-loader docs: move generic-loader documentation into the main manual hw/core: implement a guest-loader to support static hypervisor guests device_tree: add qemu_fdt_setprop_string_array helper hw/riscv: migrate fdt field to generic MachineState hw/board: promote fdt from ARM VirtMachineState to MachineState .editorconfig: update the automatic mode setting for Emacs tests/docker: Use --arch-only when building Debian cross image gitlab-ci.yml: Add jobs to test CFI flags gitlab-ci.yml: Allow custom # of parallel linkers tests/docker: add a test-tcg for building then running check-tcg docs/system: add a gentle prompt for the complexity to come Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/semihosting/console.c')
| -rw-r--r-- | hw/semihosting/console.c | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/hw/semihosting/console.c b/hw/semihosting/console.c deleted file mode 100644 index 9b4fee9260..0000000000 --- a/hw/semihosting/console.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Semihosting Console Support - * - * Copyright (c) 2015 Imagination Technologies - * Copyright (c) 2019 Linaro Ltd - * - * This provides support for outputting to a semihosting console. - * - * While most semihosting implementations support reading and writing - * to arbitrary file descriptors we treat the console as something - * specifically for debugging interaction. This means messages can be - * re-directed to gdb (if currently being used to debug) or even - * re-directed elsewhere. - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "qemu/osdep.h" -#include "cpu.h" -#include "hw/semihosting/semihost.h" -#include "hw/semihosting/console.h" -#include "exec/gdbstub.h" -#include "exec/exec-all.h" -#include "qemu/log.h" -#include "chardev/char.h" -#include "chardev/char-fe.h" -#include "sysemu/sysemu.h" -#include "qemu/main-loop.h" -#include "qapi/error.h" -#include "qemu/fifo8.h" - -int qemu_semihosting_log_out(const char *s, int len) -{ - Chardev *chardev = semihosting_get_chardev(); - if (chardev) { - return qemu_chr_write_all(chardev, (uint8_t *) s, len); - } else { - return write(STDERR_FILENO, s, len); - } -} - -/* - * A re-implementation of lock_user_string that we can use locally - * instead of relying on softmmu-semi. Hopefully we can deprecate that - * in time. Copy string until we find a 0 or address error. - */ -static GString *copy_user_string(CPUArchState *env, target_ulong addr) -{ - CPUState *cpu = env_cpu(env); - GString *s = g_string_sized_new(128); - uint8_t c; - - do { - if (cpu_memory_rw_debug(cpu, addr++, &c, 1, 0) == 0) { - if (c) { - s = g_string_append_c(s, c); - } - } else { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: passed inaccessible address " TARGET_FMT_lx, - __func__, addr); - break; - } - } while (c!=0); - - return s; -} - -static void semihosting_cb(CPUState *cs, target_ulong ret, target_ulong err) -{ - if (ret == (target_ulong) -1) { - qemu_log("%s: gdb console output failed ("TARGET_FMT_ld")", - __func__, err); - } -} - -int qemu_semihosting_console_outs(CPUArchState *env, target_ulong addr) -{ - GString *s = copy_user_string(env, addr); - int out = s->len; - - if (use_gdb_syscalls()) { - gdb_do_syscall(semihosting_cb, "write,2,%x,%x", addr, s->len); - } else { - out = qemu_semihosting_log_out(s->str, s->len); - } - - g_string_free(s, true); - return out; -} - -void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr) -{ - CPUState *cpu = env_cpu(env); - uint8_t c; - - if (cpu_memory_rw_debug(cpu, addr, &c, 1, 0) == 0) { - if (use_gdb_syscalls()) { - gdb_do_syscall(semihosting_cb, "write,2,%x,%x", addr, 1); - } else { - qemu_semihosting_log_out((const char *) &c, 1); - } - } else { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: passed inaccessible address " TARGET_FMT_lx, - __func__, addr); - } -} - -#define FIFO_SIZE 1024 - -/* Access to this structure is protected by the BQL */ -typedef struct SemihostingConsole { - CharBackend backend; - GSList *sleeping_cpus; - bool got; - Fifo8 fifo; -} SemihostingConsole; - -static SemihostingConsole console; - -static int console_can_read(void *opaque) -{ - SemihostingConsole *c = opaque; - int ret; - g_assert(qemu_mutex_iothread_locked()); - ret = (int) fifo8_num_free(&c->fifo); - return ret; -} - -static void console_wake_up(gpointer data, gpointer user_data) -{ - CPUState *cs = (CPUState *) data; - /* cpu_handle_halt won't know we have work so just unbung here */ - cs->halted = 0; - qemu_cpu_kick(cs); -} - -static void console_read(void *opaque, const uint8_t *buf, int size) -{ - SemihostingConsole *c = opaque; - g_assert(qemu_mutex_iothread_locked()); - while (size-- && !fifo8_is_full(&c->fifo)) { - fifo8_push(&c->fifo, *buf++); - } - g_slist_foreach(c->sleeping_cpus, console_wake_up, NULL); - c->sleeping_cpus = NULL; -} - -target_ulong qemu_semihosting_console_inc(CPUArchState *env) -{ - uint8_t ch; - SemihostingConsole *c = &console; - g_assert(qemu_mutex_iothread_locked()); - g_assert(current_cpu); - if (fifo8_is_empty(&c->fifo)) { - c->sleeping_cpus = g_slist_prepend(c->sleeping_cpus, current_cpu); - current_cpu->halted = 1; - current_cpu->exception_index = EXCP_HALTED; - cpu_loop_exit(current_cpu); - /* never returns */ - } - ch = fifo8_pop(&c->fifo); - return (target_ulong) ch; -} - -void qemu_semihosting_console_init(void) -{ - Chardev *chr = semihosting_get_chardev(); - - if (chr) { - fifo8_create(&console.fifo, FIFO_SIZE); - qemu_chr_fe_init(&console.backend, chr, &error_abort); - qemu_chr_fe_set_handlers(&console.backend, - console_can_read, - console_read, - NULL, NULL, &console, - NULL, true); - } -} |