summaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-04-25 18:00:45 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-04-25 18:00:45 +0000
commit6f1f31c069b20611f8df768bd4cc484a49624d62 (patch)
tree3e36c97714f8169168ec8b19ffded953dbca0f7f /linux-user
parent5467a722943adaa3d11e97656cf789586e31ee93 (diff)
ARM cache flush support (untested) - '-d' option fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@748 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/arm/syscall.h2
-rw-r--r--linux-user/main.c35
2 files changed, 33 insertions, 4 deletions
diff --git a/linux-user/arm/syscall.h b/linux-user/arm/syscall.h
index 34153c998d..0ced33ee5b 100644
--- a/linux-user/arm/syscall.h
+++ b/linux-user/arm/syscall.h
@@ -26,3 +26,5 @@ struct target_pt_regs {
#define ARM_ORIG_r0 uregs[17]
#define ARM_SYSCALL_BASE 0x900000
+
+#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2)
diff --git a/linux-user/main.c b/linux-user/main.c
index 6018292304..2af888fddc 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -246,6 +246,27 @@ void cpu_loop(CPUX86State *env)
#ifdef TARGET_ARM
+/* XXX: find a better solution */
+extern void tb_invalidate_page_range(target_ulong start, target_ulong end);
+
+static void arm_cache_flush(target_ulong start, target_ulong last)
+{
+ target_ulong addr, last1;
+
+ if (last < start)
+ return;
+ addr = start;
+ for(;;) {
+ last1 = ((addr + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK) - 1;
+ if (last1 > last)
+ last1 = last;
+ tb_invalidate_page_range(addr, last1 + 1);
+ if (last1 == last)
+ break;
+ addr = last1 + 1;
+ }
+}
+
void cpu_loop(CPUARMState *env)
{
int trapnr;
@@ -281,7 +302,9 @@ void cpu_loop(CPUARMState *env)
/* system call */
insn = ldl((void *)(env->regs[15] - 4));
n = insn & 0xffffff;
- if (n >= ARM_SYSCALL_BASE) {
+ if (n == ARM_NR_cacheflush) {
+ arm_cache_flush(env->regs[0], env->regs[1]);
+ } else if (n >= ARM_SYSCALL_BASE) {
/* linux syscall */
n -= ARM_SYSCALL_BASE;
env->regs[0] = do_syscall(env,
@@ -792,7 +815,7 @@ void cpu_loop(CPUPPCState *env)
void usage(void)
{
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
- "usage: qemu-" TARGET_ARCH " [-h] [-d] [-L path] [-s size] program [arguments...]\n"
+ "usage: qemu-" TARGET_ARCH " [-h] [-d opts] [-L path] [-s size] program [arguments...]\n"
"Linux CPU emulator (compiled for %s emulation)\n"
"\n"
"-h print this help\n"
@@ -803,7 +826,7 @@ void usage(void)
#ifdef USE_CODE_COPY
"-no-code-copy disable code copy acceleration\n"
#endif
- "-d activate log (logfile=%s)\n"
+ "-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n",
TARGET_ARCH,
interp_prefix,
@@ -850,8 +873,12 @@ int main(int argc, char **argv)
} else if (!strcmp(r, "d")) {
int mask;
CPULogItem *item;
+
+ if (optind >= argc)
+ break;
- mask = cpu_str_to_log_mask(optarg);
+ r = argv[optind++];
+ mask = cpu_str_to_log_mask(r);
if (!mask) {
printf("Log items (comma separated):\n");
for(item = cpu_log_items; item->mask != 0; item++) {