mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-31 05:51:53 -06:00
semihosting: Create qemu_semihosting_guestfd_init
For arm-compat, initialize console_{in,out}_gf; otherwise, initialize stdio file descriptors. This will go some way to cleaning up arm-compat, and will allow other semihosting to use normal stdio. Reviewed-by: Luc Michel <lmichel@kalray.eu> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
008e147572
commit
e4a4aaa51b
5 changed files with 61 additions and 10 deletions
|
@ -35,6 +35,13 @@ typedef struct GuestFD {
|
||||||
};
|
};
|
||||||
} GuestFD;
|
} GuestFD;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For ARM semihosting, we have a separate structure for routing
|
||||||
|
* data for the console which is outside the guest fd address space.
|
||||||
|
*/
|
||||||
|
extern GuestFD console_in_gf;
|
||||||
|
extern GuestFD console_out_gf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* alloc_guestfd:
|
* alloc_guestfd:
|
||||||
*
|
*
|
||||||
|
|
|
@ -64,5 +64,6 @@ int qemu_semihosting_config_options(const char *opt);
|
||||||
void qemu_semihosting_chardev_init(void);
|
void qemu_semihosting_chardev_init(void);
|
||||||
void qemu_semihosting_console_init(Chardev *);
|
void qemu_semihosting_console_init(Chardev *);
|
||||||
#endif /* CONFIG_USER_ONLY */
|
#endif /* CONFIG_USER_ONLY */
|
||||||
|
void qemu_semihosting_guestfd_init(void);
|
||||||
|
|
||||||
#endif /* SEMIHOST_H */
|
#endif /* SEMIHOST_H */
|
||||||
|
|
|
@ -54,6 +54,10 @@
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "user-mmap.h"
|
#include "user-mmap.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_SEMIHOSTING
|
||||||
|
#include "semihosting/semihost.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef AT_FLAGS_PRESERVE_ARGV0
|
#ifndef AT_FLAGS_PRESERVE_ARGV0
|
||||||
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
|
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
|
||||||
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
|
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
|
||||||
|
@ -906,6 +910,11 @@ int main(int argc, char **argv, char **envp)
|
||||||
}
|
}
|
||||||
gdb_handlesig(cpu, 0);
|
gdb_handlesig(cpu, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SEMIHOSTING
|
||||||
|
qemu_semihosting_guestfd_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
cpu_loop(env);
|
cpu_loop(env);
|
||||||
/* never exits */
|
/* never exits */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -190,4 +190,6 @@ void qemu_semihosting_console_init(Chardev *chr)
|
||||||
NULL, NULL, &console,
|
NULL, NULL, &console,
|
||||||
NULL, true);
|
NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemu_semihosting_guestfd_init();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,56 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "exec/gdbstub.h"
|
#include "exec/gdbstub.h"
|
||||||
|
#include "semihosting/semihost.h"
|
||||||
#include "semihosting/guestfd.h"
|
#include "semihosting/guestfd.h"
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
#include "qemu.h"
|
#include "qemu.h"
|
||||||
#else
|
#else
|
||||||
#include "semihosting/softmmu-uaccess.h"
|
#include "semihosting/softmmu-uaccess.h"
|
||||||
|
#include CONFIG_DEVICES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static GArray *guestfd_array;
|
static GArray *guestfd_array;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARM_COMPATIBLE_SEMIHOSTING
|
||||||
|
GuestFD console_in_gf;
|
||||||
|
GuestFD console_out_gf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void qemu_semihosting_guestfd_init(void)
|
||||||
|
{
|
||||||
|
/* New entries zero-initialized, i.e. type GuestFDUnused */
|
||||||
|
guestfd_array = g_array_new(FALSE, TRUE, sizeof(GuestFD));
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARM_COMPATIBLE_SEMIHOSTING
|
||||||
|
/* For ARM-compat, the console is in a separate namespace. */
|
||||||
|
if (use_gdb_syscalls()) {
|
||||||
|
console_in_gf.type = GuestFDGDB;
|
||||||
|
console_in_gf.hostfd = 0;
|
||||||
|
console_out_gf.type = GuestFDGDB;
|
||||||
|
console_out_gf.hostfd = 2;
|
||||||
|
} else {
|
||||||
|
console_in_gf.type = GuestFDConsole;
|
||||||
|
console_out_gf.type = GuestFDConsole;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Otherwise, the stdio file descriptors apply. */
|
||||||
|
guestfd_array = g_array_set_size(guestfd_array, 3);
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
if (!use_gdb_syscalls()) {
|
||||||
|
GuestFD *gf = &g_array_index(guestfd_array, GuestFD, 0);
|
||||||
|
gf[0].type = GuestFDConsole;
|
||||||
|
gf[1].type = GuestFDConsole;
|
||||||
|
gf[2].type = GuestFDConsole;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
associate_guestfd(0, 0);
|
||||||
|
associate_guestfd(1, 1);
|
||||||
|
associate_guestfd(2, 2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a new guest file descriptor and return it; if we
|
* Allocate a new guest file descriptor and return it; if we
|
||||||
* couldn't allocate a new fd then return -1.
|
* couldn't allocate a new fd then return -1.
|
||||||
|
@ -30,11 +71,6 @@ int alloc_guestfd(void)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
if (!guestfd_array) {
|
|
||||||
/* New entries zero-initialized, i.e. type GuestFDUnused */
|
|
||||||
guestfd_array = g_array_new(FALSE, TRUE, sizeof(GuestFD));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SYS_OPEN should return nonzero handle on success. Start guestfd from 1 */
|
/* SYS_OPEN should return nonzero handle on success. Start guestfd from 1 */
|
||||||
for (i = 1; i < guestfd_array->len; i++) {
|
for (i = 1; i < guestfd_array->len; i++) {
|
||||||
GuestFD *gf = &g_array_index(guestfd_array, GuestFD, i);
|
GuestFD *gf = &g_array_index(guestfd_array, GuestFD, i);
|
||||||
|
@ -61,11 +97,7 @@ static void do_dealloc_guestfd(GuestFD *gf)
|
||||||
*/
|
*/
|
||||||
static GuestFD *do_get_guestfd(int guestfd)
|
static GuestFD *do_get_guestfd(int guestfd)
|
||||||
{
|
{
|
||||||
if (!guestfd_array) {
|
if (guestfd < 0 || guestfd >= guestfd_array->len) {
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guestfd <= 0 || guestfd >= guestfd_array->len) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue