Package: qemu
Version: 0.8.0-2
Severity: important
Tags: patch
This patch was provided by Ulrich Hecht to fix a QEMU FP emulation
bug, which affects running programs like "cp" with qemu-arm. See
http://lists.gnu.org/archive/html/qemu-devel/2006-03/msg00036.html for
details.
Changelog:
* Fix bug in the glue code between NWFPE and QEMU.
- debian/patches/41_nwfpe_cpsr.patch: New file.
Thanks to Ulrich Hecht.
--
Anderson Lizardo
Embedded Linux Lab - 10LE
Nokia Institute of Technology - INdT
Manaus - Brazil
--- qemu-0.8.0.orig/debian/patches/41_nwfpe_cpsr.patch
+++ qemu-0.8.0/debian/patches/41_nwfpe_cpsr.patch
@@ -0,0 +1,103 @@
+#DPATCHLEVEL=1
+diff -ru qemu-0.8.0/linux-user/main.c qemu-0.8.0.fixed/linux-user/main.c
+--- qemu-0.8.0/linux-user/main.c 2005-12-19 23:51:53.000000000 +0100
++++ qemu-0.8.0.fixed/linux-user/main.c 2006-03-06 14:21:49.000000000 +0100
+@@ -345,7 +345,7 @@
+ /* we get the opcode */
+ opcode = ldl_raw((uint8_t *)env->regs[15]);
+
+- if ((rc=EmulateAll(opcode, &ts->fpa, env->regs)) == 0) { /* illegal instruction */
++ if ((rc=EmulateAll(opcode, &ts->fpa, env)) == 0) { /* illegal instruction */
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = TARGET_ILL_ILLOPN;
+diff -ru qemu-0.8.0/target-arm/nwfpe/fpa11.c qemu-0.8.0.fixed/target-arm/nwfpe/fpa11.c
+--- qemu-0.8.0/target-arm/nwfpe/fpa11.c 2005-12-19 23:51:53.000000000 +0100
++++ qemu-0.8.0.fixed/target-arm/nwfpe/fpa11.c 2006-03-06 14:19:43.000000000 +0100
+@@ -36,7 +36,7 @@
+ unsigned int EmulateCPRT(const unsigned int);
+
+ FPA11* qemufpa=0;
+-unsigned int* user_registers=0;
++CPUARMState* user_registers=0;
+
+ /* Reset the FPA11 chip. Called to initialize and reset the emulator. */
+ void resetFPA11(void)
+@@ -137,7 +137,7 @@
+ }
+
+ /* Emulate the instruction in the opcode. */
+-unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, unsigned int* qregs)
++unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
+ {
+ unsigned int nRc = 0;
+ // unsigned long flags;
+diff -ru qemu-0.8.0/target-arm/nwfpe/fpa11.h qemu-0.8.0.fixed/target-arm/nwfpe/fpa11.h
+--- qemu-0.8.0/target-arm/nwfpe/fpa11.h 2005-12-19 23:51:53.000000000 +0100
++++ qemu-0.8.0.fixed/target-arm/nwfpe/fpa11.h 2006-03-06 14:58:21.000000000 +0100
+@@ -26,6 +26,8 @@
+ #include <stdio.h>
+ #include <errno.h>
+
++#include <cpu.h>
++
+ #define GET_FPA11() (qemufpa)
+
+ /*
+@@ -33,7 +35,7 @@
+ * stack+task struct. Use the same method as 'current' uses to
+ * reach them.
+ */
+-extern unsigned int *user_registers;
++extern CPUARMState *user_registers;
+
+ #define GET_USERREG() (user_registers)
+
+@@ -94,7 +96,7 @@
+
+ static inline unsigned int readRegister(unsigned int reg)
+ {
+- return (user_registers[(reg)]);
++ return (user_registers->regs[(reg)]);
+ }
+
+ static inline void writeRegister(unsigned int x, unsigned int y)
+@@ -102,34 +104,17 @@
+ #if 0
+ printf("writing %d to r%d\n",y,x);
+ #endif
+- user_registers[(x)]=(y);
++ user_registers->regs[(x)]=(y);
+ }
+
+ static inline void writeConditionCodes(unsigned int x)
+ {
+-#if 0
+-unsigned int y;
+-unsigned int ZF;
+- printf("setting flags to %x from %x\n",x,user_registers[16]);
+-#endif
+- user_registers[16]=(x); // cpsr
+- user_registers[17]=(x>>29)&1; // cf
+- user_registers[18]=(x<<3)&(1<<31); // vf
+- user_registers[19]=x&(1<<31); // nzf
+- if(!(x&(1<<30))) user_registers[19]++; // nzf must be non-zero for zf to be cleared
+-
+-#if 0
+- ZF = (user_registers[19] == 0);
+- y=user_registers[16] | (user_registers[19] & 0x80000000) | (ZF << 30) |
+- (user_registers[17] << 29) | ((user_registers[18] & 0x80000000) >> 3);
+- if(y != x)
+- printf("GODDAM SHIIIIIIIIIIIIIIIIT! %x %x nzf %x zf %x\n",x,y,user_registers[19],ZF);
+-#endif
++ cpsr_write(user_registers,x,~CPSR_M);
+ }
+
+ #define REG_PC 15
+
+-unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, unsigned int* qregs);
++unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs);
+
+ /* included only for get_user/put_user macros */
+ #include "qemu.h"
+