qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] ARM CPSR and conditional instructions - revisited
@ 2008-11-14  9:52 Simon Willcocks
  2008-11-14 12:48 ` Paul Brook
  0 siblings, 1 reply; 5+ messages in thread
From: Simon Willcocks @ 2008-11-14  9:52 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1138 bytes --]

Hello,

I was having a problem emulating some ARM code that I don't have any right
to modify, and which has its origins back in the early nineties.  I tracked
it down to incorrect flag handling and found Justin Fletcher's post of Thu,
23 Nov 2006 via Google.  Since his fix doesn't completely correct the
problem, I've developed the attached patch and a simple test program.

I haven't tested whether the flags are set correctly other than by the MSR
instruction, but the code I'm emulating gets a lot further than it used to,
which is a reasonable smoke test, and the modifications to the flag setting
routines are reasonably minor.

I doubt the modifications will result in a significant change in speed
since, while the _cc routines are a little more complicated, the op_test_
routines have only got simpler and ARM code only sets the flags when they
will be checked, and they are checked at least as often as they are set.

This is a very useful project, thanks to everyone who has worked on it.

Regards,
Simon Willcocks

-- 
ROLF - The RISC OS Look and Feel on Linux.
http://stoppers.drobe.co.uk
http://ro-lookandfeel.blogspot.com/

[-- Attachment #2: flags_test1.c --]
[-- Type: text/plain, Size: 5577 bytes --]

/* QEMU ARM Flags test
 *
 * Copyright (c) 2008 Simon Willcocks
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/* This is a test of the op_test_* routines in target-arm/op.c.
 *
 * The unpatched qemu-0.9.1 doesn't allow the N and Z flags to be
 * set simultaneously, although ARM processors allow it.
 *
 * The code to be emulated is:
 *
 *   mov        r0, #16 ; 0x10
 *   subs       r0, r0, #1      ; 0x1
 *   svcvs      0x00000000
 *   lsl        r1, r0, #28
 *   msr        CPSR_f, r1
 *   mov        r2, #0  ; 0x0
 *   orreq      r2, r2, #1      ; 0x1
 *   orrne      r2, r2, #2      ; 0x2
 *   orrcs      r2, r2, #16     ; 0x10
 *   orrcc      r2, r2, #32     ; 0x20
 *   orrmi      r2, r2, #256    ; 0x100
 *   orrpl      r2, r2, #512    ; 0x200
 *   orrvs      r2, r2, #4096   ; 0x1000
 *   orrvc      r2, r2, #8192   ; 0x2000
 *   orrhi      r2, r2, #65536  ; 0x10000
 *   orrls      r2, r2, #131072 ; 0x20000
 *   orrge      r2, r2, #1048576        ; 0x100000
 *   orrlt      r2, r2, #2097152        ; 0x200000
 *   orrgt      r2, r2, #16777216       ; 0x1000000
 *   orrle      r2, r2, #33554432       ; 0x2000000
 *   svc        0x00000000
 *   b  0xbfe115c8
 *
 * The cpu_arm_exec routine exits for the caller to implement the svc (SWI)
 * instructions (when executed), and continues after them when the routine is
 * called again.
 *
 * The value of r2 on exit should be a leading zero and a string of 1 and 2s.
 */

/* Build library with:
 *
 * ./configure --disable-kqemu --disable-system --target-list=arm-linux-user \
 *             --disable-sdl --disable-gfx-check --disable-vnc-tls && make
 *
 * Compile this file with:
 *
 * gcc flags_test1.c -o flags_test1 qemu-0.9.1/arm-linux-user/libqemu.a \
 *     -I qemu-0.9.1 -DNEED_CPU_H -Iqemu-0.9.1/fpu -I qemu-0.9.1/arm-linux-user/ \
 *     -Wall qemu-0.9.1/osdep.c -I qemu-0.9.1/target-arm/ -D_XOPEN_SOURCE=600
 *
 * The unpatched library outputs the following:
 *
 * bf86f878: 0000000f 01111112 NzCV
 * bf86f878: 0000000e 02212112 NzCv
 * bf86f878: 0000000d 01121122 NzcV
 * bf86f878: 0000000c 02222122 Nzcv
 * bf86f878: 0000000b 01111112 NzCV
 * bf86f878: 0000000a 02212112 NzCv
 * bf86f878: 00000009 01121122 NzcV
 * bf86f878: 00000008 02222122 Nzcv
 * bf86f878: 00000007 02221211 nZCV
 * bf86f878: 00000006 02122211 nZCv
 * bf86f878: 00000005 02221221 nZcV
 * bf86f878: 00000004 02122221 nZcv
 * bf86f878: 00000003 02211212 nzCV
 * bf86f878: 00000002 01112212 nzCv
 * bf86f878: 00000001 02221222 nzcV
 * bf86f878: 00000000 01122222 nzcv
 *
 * Note that the first four lines are incorrect (although the conditional
 * instructions are correct according to the stored flags).
 *
 * The patched library:
 *
 * bfe11618: 0000000f 02121111 NZCV
 * bfe11618: 0000000e 02222111 NZCv
 * bfe11618: 0000000d 02121121 NZcV
 * bfe11618: 0000000c 02222121 NZcv
 * bfe11618: 0000000b 01111112 NzCV
 * bfe11618: 0000000a 02212112 NzCv
 * bfe11618: 00000009 01121122 NzcV
 * bfe11618: 00000008 02222122 Nzcv
 * bfe11618: 00000007 02221211 nZCV
 * bfe11618: 00000006 02122211 nZCv
 * bfe11618: 00000005 02221221 nZcV
 * bfe11618: 00000004 02122221 nZcv
 * bfe11618: 00000003 02211212 nzCV
 * bfe11618: 00000002 01112212 nzCv
 * bfe11618: 00000001 02221222 nzcV
 * bfe11618: 00000000 01122222 nzcv
 *
 */

#include <stdio.h>
#include <stdint.h>
#include "cpu.h"

static const char *flag_string[16] = {
    "nzcv", "nzcV", "nzCv", "nzCV", "nZcv", "nZcV", "nZCv", "nZCV",
    "Nzcv", "NzcV", "NzCv", "NzCV", "NZcv", "NZcV", "NZCv", "NZCV" };

int main()
{
    uint32_t code[] =  { 0xE3A00010, 0xE2500001, 0x6F000000, 0xE1A01E00, 
                         0xE128F001, 0xE3A02000, 0x3822001, 0x13822002,
                         0x23822010, 0x33822020, 0x43822C01, 0x53822C02,
                         0x63822A01, 0x73822A02, 0x83822801, 0x93822802,
                         0xA3822601, 0xB3822602, 0xC3822401, 0xD3822402,
                         0xef000000, 0xEAFFFFEA };

    struct CPUARMState *state = cpu_arm_init( "any" );
    state->user_mode_only = 1;

    cpu_set_log_filename("cpu_log.txt");
    cpu_set_log(0xfff);
    //state->singlestep_enabled = 1;

    state->regs[15] = (uint32_t) code;

    while ((cpu_arm_exec( state ) == EXCP_SWI && (state->regs[0] & 0x8000000) == 0)) {
        printf( "%08x: %08x %08x %s\n", state->regs[15], state->regs[0], state->regs[2], flag_string[(cpsr_read( state ) >> 28 )] );
    }

    return 0;
}

[-- Attachment #3: qemu-0.9.1.patch --]
[-- Type: text/plain, Size: 8779 bytes --]

diff -Naur qemu-0.9.1/target-arm/cpu.h qemu-0.9.1.patched/target-arm/cpu.h
--- qemu-0.9.1/target-arm/cpu.h	2008-01-06 20:38:44.000000000 +0100
+++ qemu-0.9.1.patched/target-arm/cpu.h	2008-11-12 10:35:29.000000000 +0100
@@ -84,9 +84,17 @@
     uint32_t fiq_regs[5];
 
     /* cpsr flag cache for faster execution */
+    /* All the NZCV flags may be set independently (MSR cpsr_f, #0xe0000000 works) */
+    /* All the flags are zero or one; the flags are calculated less often than they are
+     * read, since ARM code only sets flags when it knows they will be read and often
+     * they are read more than once. */
+    /* I note an assumption that in boolean true is the value 1. i.e. (0 == 0) == 1. */
+    /* TODO: Establish whether storing the flags as 8 bit values is more efficient */
+    uint32_t NF; /* 0 or 1 */
+    uint32_t ZF; /* 0 or 1 */
     uint32_t CF; /* 0 or 1 */
-    uint32_t VF; /* V is the bit 31. All other bits are undefined */
-    uint32_t NZF; /* N is bit 31. Z is computed from NZF */
+    uint32_t VF; /* 0 or 1 */
+
     uint32_t QF; /* 0 or 1 */
     uint32_t GE; /* cpsr[19:16] */
     int thumb; /* cprs[5]. 0 = arm mode, 1 = thumb mode. */
@@ -255,10 +263,8 @@
 /* Return the current xPSR value.  */
 static inline uint32_t xpsr_read(CPUARMState *env)
 {
-    int ZF;
-    ZF = (env->NZF == 0);
-    return (env->NZF & 0x80000000) | (ZF << 30)
-        | (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
+    return (env->NF << 31) | (env->ZF << 30)
+        | (env->CF << 29) | (env->VF << 28) | (env->QF << 27)
         | (env->thumb << 24) | ((env->condexec_bits & 3) << 25)
         | ((env->condexec_bits & 0xfc) << 8)
         | env->v7m.exception;
@@ -267,11 +273,11 @@
 /* Set the xPSR.  Note that some bits of mask must be all-set or all-clear.  */
 static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 {
-    /* NOTE: N = 1 and Z = 1 cannot be stored currently */
     if (mask & CPSR_NZCV) {
-        env->NZF = (val & 0xc0000000) ^ 0x40000000;
+        env->NF = (val >> 31);
+        env->ZF = (val >> 30) & 1;
         env->CF = (val >> 29) & 1;
-        env->VF = (val << 3) & 0x80000000;
+        env->VF = (val >> 28) & 1;
     }
     if (mask & CPSR_Q)
         env->QF = ((val & CPSR_Q) != 0);
diff -Naur qemu-0.9.1/target-arm/helper.c qemu-0.9.1.patched/target-arm/helper.c
--- qemu-0.9.1/target-arm/helper.c	2008-01-06 20:38:44.000000000 +0100
+++ qemu-0.9.1.patched/target-arm/helper.c	2008-11-12 10:37:26.000000000 +0100
@@ -275,10 +275,8 @@
 
 uint32_t cpsr_read(CPUARMState *env)
 {
-    int ZF;
-    ZF = (env->NZF == 0);
-    return env->uncached_cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
-        (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
+    return env->uncached_cpsr | (env->NF << 31) | (env->ZF << 30)
+        | (env->CF << 29) | (env->VF << 28) | (env->QF << 27)
         | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
         | ((env->condexec_bits & 0xfc) << 8)
         | (env->GE << 16);
@@ -286,11 +284,11 @@
 
 void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 {
-    /* NOTE: N = 1 and Z = 1 cannot be stored currently */
     if (mask & CPSR_NZCV) {
-        env->NZF = (val & 0xc0000000) ^ 0x40000000;
+        env->NF = (val >> 31) & 1;
+        env->ZF = (val >> 30) & 1;
         env->CF = (val >> 29) & 1;
-        env->VF = (val << 3) & 0x80000000;
+        env->VF = (val >> 28) & 1;
     }
     if (mask & CPSR_Q)
         env->QF = ((val & CPSR_Q) != 0);
diff -Naur qemu-0.9.1/target-arm/op.c qemu-0.9.1.patched/target-arm/op.c
--- qemu-0.9.1/target-arm/op.c	2008-01-06 20:38:44.000000000 +0100
+++ qemu-0.9.1.patched/target-arm/op.c	2008-11-12 10:14:42.000000000 +0100
@@ -141,9 +141,10 @@
     unsigned int src1;
     src1 = T0;
     T0 += T1;
-    env->NZF = T0;
+    env->NF = (T0 >> 31) & 1;
+    env->ZF = T0 == 0;
     env->CF = T0 < src1;
-    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
+    env->VF = (((src1 ^ T1 ^ -1) & (src1 ^ T0)) >> 31) & 1;
 }
 
 void OPPROTO op_adcl_T0_T1(void)
@@ -162,8 +163,9 @@
         T0 += T1 + 1;
         env->CF = T0 <= src1;
     }
-    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
-    env->NZF = T0;
+    env->VF = (((src1 ^ T1 ^ -1) & (src1 ^ T0)) >> 31) & 1;
+    env->NF = (T0 >> 31) & 1;
+    env->ZF = T0 == 0;
     FORCE_RET();
 }
 
@@ -179,9 +181,10 @@
     unsigned int src1;                          \
     src1 = T0;                                  \
     T0 -= T1;                                   \
-    env->NZF = T0;                              \
+    env->NF = (T0 >> 31) & 1;                   \
+    env->ZF = T0 == 0;                          \
     env->CF = src1 >= T1;                       \
-    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
+    env->VF = (((src1 ^ T1) & (src1 ^ T0)) >> 31) & 1;\
     res = T0;                                   \
 }                                               \
                                                 \
@@ -201,8 +204,9 @@
         T0 = T0 - T1;                           \
         env->CF = src1 >= T1;                   \
     }                                           \
-    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
-    env->NZF = T0;                              \
+    env->VF = (((src1 ^ T1) & (src1 ^ T0)) >> 31) & 1;\
+    env->NF = (T0 >> 31) & 1;                   \
+    env->ZF = T0 == 0;                          \
     res = T0;                                   \
     FORCE_RET();                                \
 }
@@ -243,26 +247,28 @@
 
 void OPPROTO op_logic_T0_cc(void)
 {
-    env->NZF = T0;
+    env->NF = (T0 >> 31) & 1;
+    env->ZF = T0 == 0;
 }
 
 void OPPROTO op_logic_T1_cc(void)
 {
-    env->NZF = T1;
+    env->NF = (T1 >> 31) & 1;
+    env->ZF = T1 == 0;
 }
 
 #define EIP (env->regs[15])
 
 void OPPROTO op_test_eq(void)
 {
-    if (env->NZF == 0)
+    if (env->ZF)
         GOTO_LABEL_PARAM(1);;
     FORCE_RET();
 }
 
 void OPPROTO op_test_ne(void)
 {
-    if (env->NZF != 0)
+    if (!env->ZF)
         GOTO_LABEL_PARAM(1);;
     FORCE_RET();
 }
@@ -283,70 +289,70 @@
 
 void OPPROTO op_test_mi(void)
 {
-    if ((env->NZF & 0x80000000) != 0)
+    if (env->NF)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_pl(void)
 {
-    if ((env->NZF & 0x80000000) == 0)
+    if (!env->NF)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_vs(void)
 {
-    if ((env->VF & 0x80000000) != 0)
+    if (env->VF)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_vc(void)
 {
-    if ((env->VF & 0x80000000) == 0)
+    if (!env->VF)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_hi(void)
 {
-    if (env->CF != 0 && env->NZF != 0)
+    if (env->CF && !env->ZF)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_ls(void)
 {
-    if (env->CF == 0 || env->NZF == 0)
+    if (!env->CF || env->ZF)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_ge(void)
 {
-    if (((env->VF ^ env->NZF) & 0x80000000) == 0)
+    if (env->VF == env->NF)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_lt(void)
 {
-    if (((env->VF ^ env->NZF) & 0x80000000) != 0)
+    if (env->VF != env->NF)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_gt(void)
 {
-    if (env->NZF != 0 && ((env->VF ^ env->NZF) & 0x80000000) == 0)
+    if (!env->ZF && (env->NF == env->VF))
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
 
 void OPPROTO op_test_le(void)
 {
-    if (env->NZF == 0 || ((env->VF ^ env->NZF) & 0x80000000) != 0)
+    if (env->ZF || (env->NF != env->VF))
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
 }
@@ -476,7 +482,8 @@
 
 void OPPROTO op_logicq_cc(void)
 {
-    env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
+    env->ZF = ((T0 | T1) != 0);
+    env->NF = (T1 >> 31);
 }
 
 /* memory access */
@@ -902,7 +909,8 @@
 	env->CF = (T0 >> (32 - shift)) & 1;
 	T0 = T0 << shift;
     }
-    env->NZF = T0;
+    env->NF = (T0 >> 31) & 1;
+    env->ZF = T0 == 0;
     FORCE_RET();
 }
 
@@ -924,7 +932,8 @@
 	env->CF = (T0 >> (shift - 1)) & 1;
 	T0 = T0 >> shift;
     }
-    env->NZF = T0;
+    env->NF = (T0 >> 31) & 1;
+    env->ZF = T0 == 0;
     FORCE_RET();
 }
 
@@ -953,7 +962,8 @@
 	env->CF = (T0 >> (shift - 1)) & 1;
 	T0 = ((int32_t)T0) >> shift;
     }
-    env->NZF = T0;
+    env->NF = (T0 >> 31) & 1;
+    env->ZF = T0 == 0;
     FORCE_RET();
 }
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] ARM CPSR and conditional instructions - revisited
  2008-11-14  9:52 [Qemu-devel] [PATCH] ARM CPSR and conditional instructions - revisited Simon Willcocks
@ 2008-11-14 12:48 ` Paul Brook
  2008-11-16  1:25   ` Simon Willcocks
  0 siblings, 1 reply; 5+ messages in thread
From: Paul Brook @ 2008-11-14 12:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Simon Willcocks

On Friday 14 November 2008, Simon Willcocks wrote:
> Hello,
>
> I was having a problem emulating some ARM code

You need to use a newer qemu. This has been fixed for ages.

Paul

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] ARM CPSR and conditional instructions - revisited
  2008-11-14 12:48 ` Paul Brook
@ 2008-11-16  1:25   ` Simon Willcocks
  2008-11-16 16:49     ` Paul Brook
  0 siblings, 1 reply; 5+ messages in thread
From: Simon Willcocks @ 2008-11-16  1:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: paul

In message <200811141248.31086.paul@codesourcery.com>
          Paul Brook <paul@codesourcery.com> wrote:

> On Friday 14 November 2008, Simon Willcocks wrote:
> > Hello,
> >
> > I was having a problem emulating some ARM code
> 
> You need to use a newer qemu. This has been fixed for ages.

You're right; on the 1st April, I guess that makes me an April Fool :-)

On the other hand, it has raised a couple of questions.

1. At what point will there be a new release of the software?

Is there a target being worked towards? 

2. How do I compile my simple test program?

This used to be good enough:

gcc flags_test1.c -o flags_test1 qemu-0.9.1/arm-linux-user/libqemu.a \
   -I qemu-0.9.1 -DNEED_CPU_H -Iqemu-0.9.1/fpu -I qemu-0.9.1/arm-linux-user/ \
   -Wall qemu-0.9.1/osdep.c -I qemu-0.9.1/target-arm/ -D_XOPEN_SOURCE=600

But now libqemu.a seems to need a lot of features from other places that I
can't easily identify.  (Just osdep.c covered everything, before.)

I can understand the emulator needing wrapped malloc-like routines, but why
does the base emulator (which is what I thought the libqemu.a file
contained) need to know about mmap_lock?

I'm a little frustrated, and inclined to go back to using the 0.9.1. library
with my patch to continue, although there are presumably other improvements
to the development build.

Thanks,
Simon

-- 
ROLF - The RISC OS Look and Feel on Linux.
http://stoppers.drobe.co.uk
http://ro-lookandfeel.blogspot.com/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] ARM CPSR and conditional instructions - revisited
  2008-11-16  1:25   ` Simon Willcocks
@ 2008-11-16 16:49     ` Paul Brook
  2008-11-16 21:34       ` Simon Willcocks
  0 siblings, 1 reply; 5+ messages in thread
From: Paul Brook @ 2008-11-16 16:49 UTC (permalink / raw)
  To: qemu-devel; +Cc: Simon Willcocks

> 2. How do I compile my simple test program?
>
> This used to be good enough:
>
> gcc flags_test1.c -o flags_test1 qemu-0.9.1/arm-linux-user/libqemu.a \
>    -I qemu-0.9.1 -DNEED_CPU_H -Iqemu-0.9.1/fpu -I
> qemu-0.9.1/arm-linux-user/ \ -Wall qemu-0.9.1/osdep.c -I
> qemu-0.9.1/target-arm/ -D_XOPEN_SOURCE=600
>
> But now libqemu.a seems to need a lot of features from other places that I
> can't easily identify.

Don't do that. libqemu has never really been usable as a standaline library.

Paul

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] ARM CPSR and conditional instructions - revisited
  2008-11-16 16:49     ` Paul Brook
@ 2008-11-16 21:34       ` Simon Willcocks
  0 siblings, 0 replies; 5+ messages in thread
From: Simon Willcocks @ 2008-11-16 21:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Brook

In message <200811161649.17521.paul@codesourcery.com> you wrote:

> > 2. How do I compile my simple test program?
> >
> > This used to be good enough:
> >
> > gcc flags_test1.c -o flags_test1 qemu-0.9.1/arm-linux-user/libqemu.a \
> >    -I qemu-0.9.1 -DNEED_CPU_H -Iqemu-0.9.1/fpu -I
> > qemu-0.9.1/arm-linux-user/ \ -Wall qemu-0.9.1/osdep.c -I
> > qemu-0.9.1/target-arm/ -D_XOPEN_SOURCE=600
> >
> > But now libqemu.a seems to need a lot of features from other places that I
> > can't easily identify.
> 
> Don't do that. libqemu has never really been usable as a standaline library.

Unfortunately, that's exactly how I want to use it!

What I have is a system, based on a Linux kernel, that behaves similarly to
RISC OS; the OS developed by Acorn to run on their Acorn RISC Machine
processors, later spun off to be Advanced RISC Machines Ltd..

I have tried to make it sufficiently similar that it should be relatively
easy to map RISC OS system calls (especially the WIMP and font ones) to the
ROLF interface, so that RISC OS programs can be ported to run on faster
hardware.  There's a new interface to the Wimp, which adds a couple of
features so that people can make use of pre-emptive scheduling and
asynchronous I/O from Linux but, at heart, is the cooperative mechanism from
1987 that still works very well indeed but is limited by the speed of ARM
processors.

One feature that I would like to implement is the ability to run some RISC
OS programs under ROLF (on i386), for which I need an emulator.  The example
I chose to start with was a vector graphics renderer for a program called
ArtWorks, which requires some "Relocatable Modules" which have been
supported over the last sixeen years on RISC OS.   (A Relocatable Module can
be any combination of a shared library, a device driver, a kernel extension
module, or an application.)

I don't need to emulate the hardware of a RISC OS computer (nor would I want
to; Acorn wrote operating systems with a good abstraction from the hardware
from before MS were around, and programs generally used it).  What I do need
to do is convince old software that it is running on an ARM processor
(that's where QEMU comes in) and interfacing with RISC OS when it makes a
SWI call.  To do the latter, I'm implementing a shared library that can
provide a one-routine interface to run any* RISC OS system call, and trying
to make those calls available to ARM code in an emulator as a way to get
native RISC OS applications to run.  The same library is callable from BASIC
(built in to RISC OS and therefore commonly used for application
development) via the Brandy basic interpreter.

As at qemu-0.9.1, that seemed to be relatively easy, now it seems to be
harder, and I'm not sure why.

I could be wrong, but I think there is a movement from emulation of a
particular processor to emulation of a particular processor running a
particular OS, on a particular piece of hardware, which is probably very
useful for many people, but isn't so much for me.  I'd like the abstraction
to allow me to extract the processor without any preconceptions; to be able
to use QEMU as a tool, rather than being forced to integrate ROLF into QEMU.

* potentially; many won't ever be needed.

-- 
ROLF - The RISC OS Look and Feel on Linux.
http://stoppers.drobe.co.uk
http://ro-lookandfeel.blogspot.com/

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-11-16 21:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-14  9:52 [Qemu-devel] [PATCH] ARM CPSR and conditional instructions - revisited Simon Willcocks
2008-11-14 12:48 ` Paul Brook
2008-11-16  1:25   ` Simon Willcocks
2008-11-16 16:49     ` Paul Brook
2008-11-16 21:34       ` Simon Willcocks

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).