From: Nathan Froyd <froydnj@codesourcery.com>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 3/6] add implementation of MIPS semihosting
Date: Mon, 20 Jul 2009 08:24:20 -0700 [thread overview]
Message-ID: <20090720152420.GF26319@codesourcery.com> (raw)
In-Reply-To: <f43fc5580907180022x1d8b4944x115857a609eb3c76@mail.gmail.com>
Later patches will call into this file via do_mips_semihosting.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
---
Makefile.target | 1 +
mips-semi.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++
target-mips/cpu.h | 1 +
3 files changed, 218 insertions(+), 0 deletions(-)
create mode 100644 mips-semi.c
v2: point at FSF website for copies of GPL
diff --git a/Makefile.target b/Makefile.target
index f9cd42a..7230c44 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -534,6 +534,7 @@ obj-mips-y += piix_pci.o parallel.o cirrus_vga.o pcspk.o $(sound-obj-y)
obj-mips-y += mipsnet.o
obj-mips-y += pflash_cfi01.o
obj-mips-y += vmware_vga.o
+obj-mips-y += mips-semi.o
ifeq ($(TARGET_BASE_ARCH), mips)
CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
diff --git a/mips-semi.c b/mips-semi.c
new file mode 100644
index 0000000..77ecff3
--- /dev/null
+++ b/mips-semi.c
@@ -0,0 +1,216 @@
+
+/*
+ * MIPS MDI semihosting syscalls
+ *
+ * Copyright (c) 2009 CodeSourcery.
+ * Written by Nathan Froyd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "cpu.h"
+#include "qemu-common.h"
+#include "sysemu.h"
+#include "gdbstub.h"
+#include "softmmu-semi.h"
+
+#define HOSTED_OPEN 0
+#define HOSTED_CLOSE 1
+#define HOSTED_READ 2
+#define HOSTED_WRITE 3
+#define HOSTED_GETCHAR 4
+#define HOSTED_PUTCHAR 5
+#define HOSTED_LSEEK32 6
+#define HOSTED_GETTIME 7
+#define HOSTED_EXIT 8
+#define HOSTED_MOVED 9
+#define HOSTED_GETARGS 10
+#define HOSTED_ISATTY 11
+#define HOSTED_PROFIL 12
+#define HOSTED_SIGHOOK 13
+
+#define ARG(n) env->active_tc.gpr[4 + n]
+
+static void mips_store_result(CPUState *env, target_ulong ret, target_ulong err)
+{
+ env->active_tc.PC = env->active_tc.gpr[31];
+ env->active_tc.gpr[2] = ret;
+ env->active_tc.gpr[3] = err;
+}
+
+static void mips_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
+{
+ mips_store_result(env, ret, err);
+}
+
+#define GDB_O_RDONLY 0x0
+#define GDB_O_WRONLY 0x1
+#define GDB_O_RDWR 0x2
+#define GDB_O_APPEND 0x8
+#define GDB_O_CREAT 0x200
+#define GDB_O_TRUNC 0x400
+#define GDB_O_EXCL 0x800
+
+static int translate_openflags(int flags)
+{
+ int hf;
+
+ if (flags & GDB_O_WRONLY)
+ hf = O_WRONLY;
+ else if (flags & GDB_O_RDWR)
+ hf = O_RDWR;
+ else
+ hf = O_RDONLY;
+
+ if (flags & GDB_O_APPEND) hf |= O_APPEND;
+ if (flags & GDB_O_CREAT) hf |= O_CREAT;
+ if (flags & GDB_O_TRUNC) hf |= O_TRUNC;
+ if (flags & GDB_O_EXCL) hf |= O_EXCL;
+
+ return hf;
+}
+
+void do_mips_semihosting(CPUState *env)
+{
+ target_ulong result;
+ void *p;
+ uint32_t len;
+ target_ulong err = 0;
+ char *s;
+
+ switch (env->active_tc.gpr[2]) {
+ case HOSTED_OPEN:
+ if (use_gdb_syscalls()) {
+ gdb_do_syscall(mips_semi_cb, "open,%s,%x,%x", ARG(0),
+ target_strlen(ARG(0))+1, ARG(1), ARG(2));
+ return;
+ } else {
+ if (!(s = lock_user_string(ARG(0)))) {
+ result = -1;
+ } else {
+ result = open(s, translate_openflags(ARG(1)), ARG(2));
+ }
+ unlock_user(s, ARG(0), 0);
+ }
+ break;
+ case HOSTED_CLOSE:
+ /* Ignore attempts to close stdin/out/err */
+ if (ARG(0) > 2) {
+ if (use_gdb_syscalls()) {
+ gdb_do_syscall(mips_semi_cb, "close,%x", ARG(0));
+ return;
+ } else {
+ result = close(ARG(0));
+ }
+ } else {
+ result = 0;
+ }
+ break;
+ case HOSTED_READ:
+ len = ARG(2);
+ if (use_gdb_syscalls()) {
+ gdb_do_syscall(mips_semi_cb, "read,%x,%x,%x",
+ ARG(0), ARG(1), len);
+ return;
+ } else {
+ if (!(p = lock_user(VERIFY_WRITE, ARG(1), len, 0))) {
+ result = -1;
+ } else {
+ result = read(ARG(0), p, len);
+ unlock_user(p, ARG(1), len);
+ }
+ }
+ break;
+ case HOSTED_WRITE:
+ len = ARG(2);
+ if (use_gdb_syscalls()) {
+ gdb_do_syscall(mips_semi_cb, "write,%x,%x,%x",
+ ARG(0), ARG(1), len);
+ return;
+ } else {
+ if (!(p = lock_user(VERIFY_READ, ARG(1), len, 1))) {
+ result = -1;
+ } else {
+ result = write(ARG(0), p, len);
+ unlock_user(p, ARG(1), len);
+ }
+ }
+ break;
+ case HOSTED_LSEEK32:
+ {
+ off_t off = (target_long) ARG(1);
+ if (use_gdb_syscalls()) {
+ gdb_do_syscall(mips_semi_cb, "lseek,%x,%lx,%x",
+ ARG(0), off, ARG(2));
+ return;
+ } else {
+ off = lseek(ARG(0), off, ARG(2));
+ result = (uint32_t) off;
+ }
+ }
+ break;
+ case HOSTED_GETTIME:
+ {
+ qemu_timeval tv;
+ result = qemu_gettimeofday(&tv);
+ if (!result) {
+ result = tv.tv_sec;
+ err = tv.tv_usec;
+ } else {
+ result = -1;
+ err = errno;
+ }
+ }
+ break;
+ case HOSTED_EXIT:
+ exit(ARG(0));
+ break;
+ case HOSTED_ISATTY:
+ if (use_gdb_syscalls()) {
+ gdb_do_syscall(mips_semi_cb, "isatty,%x", ARG(0));
+ return;
+ } else {
+ result = isatty(ARG(0));
+ }
+ break;
+ case HOSTED_GETARGS:
+ /* argc gets placed in A0, argv gets copied onto the stack and
+ the address of the copy placed in A1. We have nothing to
+ provide in terms of argc/argv, so just stuff NULL in
+ each. */
+ ARG(1) = ARG(0) = 0;
+ result = 0;
+ break;
+ case HOSTED_GETCHAR:
+ case HOSTED_PUTCHAR:
+ case HOSTED_MOVED:
+ case HOSTED_PROFIL:
+ case HOSTED_SIGHOOK:
+ default:
+ result = -1;
+ err = 88; /* ENOSYS */
+ break;
+ }
+
+ mips_store_result(env, result, err);
+}
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index bb9a49b..44420a1 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -587,6 +587,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
void do_interrupt (CPUState *env);
void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
+void do_mips_semihosting(CPUState *env);
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{
env->active_tc.PC = tb->pc;
--
1.6.3.2
next prev parent reply other threads:[~2009-07-20 15:24 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-17 20:33 [Qemu-devel] [PATCH 0/6] target-mips: add MDI semihosting Nathan Froyd
2009-07-17 20:33 ` [Qemu-devel] [PATCH 1/6] sysemu: add section_callback argument to ELF loader Nathan Froyd
2009-07-17 20:33 ` [Qemu-devel] [PATCH 2/6] add softmmu_target_strlen Nathan Froyd
2009-07-17 20:33 ` [Qemu-devel] [PATCH 3/6] add implementation of MIPS semihosting Nathan Froyd
2009-07-18 7:22 ` Blue Swirl
2009-07-20 15:24 ` Nathan Froyd [this message]
2009-07-17 20:33 ` [Qemu-devel] [PATCH 4/6] target-mips: add MDI semihosting support to mipssim machine Nathan Froyd
2009-07-17 20:33 ` [Qemu-devel] [PATCH 5/6] enable --semihosting option for TARGET_MIPS Nathan Froyd
2009-07-17 20:33 ` [Qemu-devel] [PATCH 6/6] gdbstub: add qSymbol handling " Nathan Froyd
-- strict thread matches above, loose matches on Subject: below --
2009-08-03 14:45 [Qemu-devel] [PATCH 0/6] target-mips: add MDI semihosting, v2 Nathan Froyd
2009-08-03 14:45 ` [Qemu-devel] [PATCH 3/6] add implementation of MIPS semihosting Nathan Froyd
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090720152420.GF26319@codesourcery.com \
--to=froydnj@codesourcery.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).