Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from jcmvbkbc/xtensa-qemu-sim-fixes
xtensa: qemu: support -serial output with sim machine
- Loading branch information
Showing
4 changed files
with
280 additions
and
0 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
recipes-devtools/qemu/files/0003-target-xtensa-fix-mapping-direction-in-read-write-si.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
From 93ebcc3e2414dcca5fc8a221a3e8eb63d6448e3e Mon Sep 17 00:00:00 2001 | ||
From: Max Filippov <jcmvbkbc@gmail.com> | ||
Date: Fri, 12 May 2017 11:17:01 -0700 | ||
Subject: [PATCH 3/5] target/xtensa: fix mapping direction in read/write | ||
simcalls | ||
|
||
Read and write simcalls map physical memory to access I/O buffers, but | ||
'read' simcall need to map it for writing and 'write' simcall need to | ||
map it for reading, i.e. the opposite of what they do now. Fix that. | ||
|
||
Cc: qemu-stable@nongnu.org | ||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> | ||
--- | ||
target-xtensa/xtensa-semi.c | 4 ++-- | ||
1 file changed, 2 insertions(+), 2 deletions(-) | ||
|
||
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c | ||
index 370e365..8da61ae 100644 | ||
--- a/target-xtensa/xtensa-semi.c | ||
+++ b/target-xtensa/xtensa-semi.c | ||
@@ -172,7 +172,7 @@ void HELPER(simcall)(CPUXtensaState *env) | ||
TARGET_PAGE_SIZE - (vaddr & (TARGET_PAGE_SIZE - 1)); | ||
uint32_t io_sz = page_left < len ? page_left : len; | ||
hwaddr sz = io_sz; | ||
- void *buf = cpu_physical_memory_map(paddr, &sz, is_write); | ||
+ void *buf = cpu_physical_memory_map(paddr, &sz, !is_write); | ||
|
||
if (buf) { | ||
vaddr += io_sz; | ||
@@ -181,7 +181,7 @@ void HELPER(simcall)(CPUXtensaState *env) | ||
write(fd, buf, io_sz) : | ||
read(fd, buf, io_sz); | ||
regs[3] = errno_h2g(errno); | ||
- cpu_physical_memory_unmap(buf, sz, is_write, sz); | ||
+ cpu_physical_memory_unmap(buf, sz, !is_write, sz); | ||
if (regs[2] == -1) { | ||
break; | ||
} | ||
-- | ||
2.1.4 | ||
|
75 changes: 75 additions & 0 deletions
75
recipes-devtools/qemu/files/0004-target-xtensa-fix-return-value-of-read-write-simcall.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
From 0c8d3f87b38bcbba692e2711a78cccd37f483b75 Mon Sep 17 00:00:00 2001 | ||
From: Max Filippov <jcmvbkbc@gmail.com> | ||
Date: Fri, 12 May 2017 12:05:23 -0700 | ||
Subject: [PATCH 4/5] target/xtensa: fix return value of read/write simcalls | ||
|
||
Return value of read/write simcalls is not calculated correctly in case | ||
of operations crossing page boundary and in case of short reads/writes. | ||
Read and write simcalls should return the size of data actually | ||
read/written or -1 in case of error. | ||
|
||
Cc: qemu-stable@nongnu.org | ||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> | ||
--- | ||
target-xtensa/xtensa-semi.c | 25 ++++++++++++++++++++----- | ||
1 file changed, 20 insertions(+), 5 deletions(-) | ||
|
||
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c | ||
index 8da61ae..807e1b8 100644 | ||
--- a/target-xtensa/xtensa-semi.c | ||
+++ b/target-xtensa/xtensa-semi.c | ||
@@ -165,6 +165,7 @@ void HELPER(simcall)(CPUXtensaState *env) | ||
uint32_t fd = regs[3]; | ||
uint32_t vaddr = regs[4]; | ||
uint32_t len = regs[5]; | ||
+ uint32_t len_done = 0; | ||
|
||
while (len > 0) { | ||
hwaddr paddr = cpu_get_phys_page_debug(cs, vaddr); | ||
@@ -173,24 +174,38 @@ void HELPER(simcall)(CPUXtensaState *env) | ||
uint32_t io_sz = page_left < len ? page_left : len; | ||
hwaddr sz = io_sz; | ||
void *buf = cpu_physical_memory_map(paddr, &sz, !is_write); | ||
+ uint32_t io_done; | ||
+ bool error = false; | ||
|
||
if (buf) { | ||
vaddr += io_sz; | ||
len -= io_sz; | ||
- regs[2] = is_write ? | ||
+ io_done = is_write ? | ||
write(fd, buf, io_sz) : | ||
read(fd, buf, io_sz); | ||
regs[3] = errno_h2g(errno); | ||
- cpu_physical_memory_unmap(buf, sz, !is_write, sz); | ||
- if (regs[2] == -1) { | ||
- break; | ||
+ if (io_done == -1) { | ||
+ error = true; | ||
+ io_done = 0; | ||
} | ||
+ cpu_physical_memory_unmap(buf, sz, !is_write, io_done); | ||
} else { | ||
- regs[2] = -1; | ||
+ error = true; | ||
regs[3] = TARGET_EINVAL; | ||
break; | ||
} | ||
+ if (error) { | ||
+ if (!len_done) { | ||
+ len_done = -1; | ||
+ } | ||
+ break; | ||
+ } | ||
+ len_done += io_done; | ||
+ if (io_done < io_sz) { | ||
+ break; | ||
+ } | ||
} | ||
+ regs[2] = len_done; | ||
} | ||
break; | ||
|
||
-- | ||
2.1.4 | ||
|
161 changes: 161 additions & 0 deletions
161
recipes-devtools/qemu/files/0005-target-xtensa-support-output-to-chardev-console.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
From 01cb3050ef87bf71330d79e2139310c72e1d25ab Mon Sep 17 00:00:00 2001 | ||
From: Max Filippov <jcmvbkbc@gmail.com> | ||
Date: Fri, 12 May 2017 11:09:14 -0700 | ||
Subject: [PATCH 5/5] target/xtensa: support output to chardev console | ||
|
||
In semihosting mode QEMU allows guest to read and write host file | ||
descriptors directly, including descriptors 0..2, a.k.a. stdin, stdout | ||
and stderr. Sometimes it's desirable to have semihosting console | ||
controlled by -serial option, e.g. to connect it to network. | ||
|
||
Add semihosting console to xtensa-semi.c, open it in the 'sim' machine | ||
in the presence of -serial option and direct stdout and stderr to it | ||
when it's present. | ||
|
||
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> | ||
--- | ||
hw/xtensa/sim.c | 4 +++ | ||
target-xtensa/cpu.h | 1 + | ||
target-xtensa/xtensa-semi.c | 63 +++++++++++++++++++++++++++++++++++---------- | ||
3 files changed, 54 insertions(+), 14 deletions(-) | ||
|
||
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c | ||
index d2d1d3a..685f592 100644 | ||
--- a/hw/xtensa/sim.c | ||
+++ b/hw/xtensa/sim.c | ||
@@ -114,6 +114,9 @@ static void xtensa_sim_init(MachineState *machine) | ||
xtensa_create_memory_regions(&sysram, "xtensa.sysram"); | ||
} | ||
|
||
+ if (serial_hds[0]) { | ||
+ xtensa_sim_open_console(serial_hds[0]); | ||
+ } | ||
if (kernel_filename) { | ||
uint64_t elf_entry; | ||
uint64_t elf_lowaddr; | ||
@@ -136,6 +139,7 @@ static void xtensa_sim_machine_init(MachineClass *mc) | ||
mc->is_default = true; | ||
mc->init = xtensa_sim_init; | ||
mc->max_cpus = 4; | ||
+ mc->no_serial = 1; | ||
} | ||
|
||
DEFINE_MACHINE("sim", xtensa_sim_machine_init) | ||
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h | ||
index d330dfa..c62e03f 100644 | ||
--- a/target-xtensa/cpu.h | ||
+++ b/target-xtensa/cpu.h | ||
@@ -416,6 +416,7 @@ void xtensa_breakpoint_handler(CPUState *cs); | ||
int cpu_xtensa_exec(CPUState *cpu); | ||
void xtensa_finalize_config(XtensaConfig *config); | ||
void xtensa_register_core(XtensaConfigList *node); | ||
+void xtensa_sim_open_console(CharDriverState *chr); | ||
void check_interrupts(CPUXtensaState *s); | ||
void xtensa_irq_init(CPUXtensaState *env); | ||
void *xtensa_get_extint(CPUXtensaState *env, unsigned extint); | ||
diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c | ||
index 807e1b8..7e0c400 100644 | ||
--- a/target-xtensa/xtensa-semi.c | ||
+++ b/target-xtensa/xtensa-semi.c | ||
@@ -28,7 +28,13 @@ | ||
#include "qemu/osdep.h" | ||
#include "cpu.h" | ||
#include "exec/helper-proto.h" | ||
+#include "exec/semihost.h" | ||
+#include "qapi/error.h" | ||
#include "qemu/log.h" | ||
+#include "sysemu/char.h" | ||
+#include "sysemu/sysemu.h" | ||
+ | ||
+static CharDriverState *xtensa_sim_console; | ||
|
||
enum { | ||
TARGET_SYS_exit = 1, | ||
@@ -147,6 +153,11 @@ static uint32_t errno_h2g(int host_errno) | ||
} | ||
} | ||
|
||
+void xtensa_sim_open_console(CharDriverState *chr) | ||
+{ | ||
+ xtensa_sim_console = chr; | ||
+} | ||
+ | ||
void HELPER(simcall)(CPUXtensaState *env) | ||
{ | ||
CPUState *cs = CPU(xtensa_env_get_cpu(env)); | ||
@@ -180,10 +191,25 @@ void HELPER(simcall)(CPUXtensaState *env) | ||
if (buf) { | ||
vaddr += io_sz; | ||
len -= io_sz; | ||
- io_done = is_write ? | ||
- write(fd, buf, io_sz) : | ||
- read(fd, buf, io_sz); | ||
- regs[3] = errno_h2g(errno); | ||
+ if (fd < 3 && xtensa_sim_console) { | ||
+ if (is_write && (fd == 1 || fd == 2)) { | ||
+ io_done = qemu_chr_fe_write_all(xtensa_sim_console, | ||
+ buf, io_sz); | ||
+ regs[3] = errno_h2g(errno); | ||
+ } else { | ||
+ qemu_log_mask(LOG_GUEST_ERROR, | ||
+ "%s fd %d is not supported with chardev console\n", | ||
+ is_write ? | ||
+ "writing to" : "reading from", fd); | ||
+ io_done = -1; | ||
+ regs[3] = TARGET_EBADF; | ||
+ } | ||
+ } else { | ||
+ io_done = is_write ? | ||
+ write(fd, buf, io_sz) : | ||
+ read(fd, buf, io_sz); | ||
+ regs[3] = errno_h2g(errno); | ||
+ } | ||
if (io_done == -1) { | ||
error = true; | ||
io_done = 0; | ||
@@ -255,10 +281,6 @@ void HELPER(simcall)(CPUXtensaState *env) | ||
uint32_t target_tvv[2]; | ||
|
||
struct timeval tv = {0}; | ||
- fd_set fdset; | ||
- | ||
- FD_ZERO(&fdset); | ||
- FD_SET(fd, &fdset); | ||
|
||
if (target_tv) { | ||
cpu_memory_rw_debug(cs, target_tv, | ||
@@ -266,12 +288,25 @@ void HELPER(simcall)(CPUXtensaState *env) | ||
tv.tv_sec = (int32_t)tswap32(target_tvv[0]); | ||
tv.tv_usec = (int32_t)tswap32(target_tvv[1]); | ||
} | ||
- regs[2] = select(fd + 1, | ||
- rq == SELECT_ONE_READ ? &fdset : NULL, | ||
- rq == SELECT_ONE_WRITE ? &fdset : NULL, | ||
- rq == SELECT_ONE_EXCEPT ? &fdset : NULL, | ||
- target_tv ? &tv : NULL); | ||
- regs[3] = errno_h2g(errno); | ||
+ if (fd < 3 && xtensa_sim_console) { | ||
+ if ((fd == 1 || fd == 2) && rq == SELECT_ONE_WRITE) { | ||
+ regs[2] = 1; | ||
+ } else { | ||
+ regs[2] = 0; | ||
+ } | ||
+ regs[3] = 0; | ||
+ } else { | ||
+ fd_set fdset; | ||
+ | ||
+ FD_ZERO(&fdset); | ||
+ FD_SET(fd, &fdset); | ||
+ regs[2] = select(fd + 1, | ||
+ rq == SELECT_ONE_READ ? &fdset : NULL, | ||
+ rq == SELECT_ONE_WRITE ? &fdset : NULL, | ||
+ rq == SELECT_ONE_EXCEPT ? &fdset : NULL, | ||
+ target_tv ? &tv : NULL); | ||
+ regs[3] = errno_h2g(errno); | ||
+ } | ||
} | ||
break; | ||
|
||
-- | ||
2.1.4 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters