diff options
| author | Richard Purdie <richard@openedhand.com> | 2008-04-24 22:10:12 +0000 |
|---|---|---|
| committer | Richard Purdie <richard@openedhand.com> | 2008-04-24 22:10:12 +0000 |
| commit | 927ad4986670f4938049c97e1bbabd5714e410e7 (patch) | |
| tree | 0ab419dc6e50129f342b6291e66719b8a25cf57e /meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch | |
| parent | 0e1fe2007df82725e6ce46d4f92d8bf4434ee887 (diff) | |
| download | poky-927ad4986670f4938049c97e1bbabd5714e410e7.tar.gz | |
qemu-svn: Upgrade from r4027 -> 4242. Removes the need for gcc 3.x, adds USB networking for the n800
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@4332 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch')
| -rw-r--r-- | meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch | 450 |
1 files changed, 348 insertions, 102 deletions
diff --git a/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch b/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch index 4a87d8d637..ac68ebf460 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch | |||
| @@ -1,19 +1,3 @@ | |||
| 1 | These are Paul Brook's patches to QEMU-0.8.2 to enable the running of single | ||
| 2 | ARM binaries under QEMU's user-emulation mode. Without them, QEMU-0.8.1 | ||
| 3 | immediately dies saying: | ||
| 4 | Error: f0005 | ||
| 5 | qemu: uncaught target signal 6 (Aborted) - exiting | ||
| 6 | while qemu-0.8.2 dies saying: | ||
| 7 | qemu: Unsupported syscall: 983045 | ||
| 8 | cannot set up thread-local storage: unknown error | ||
| 9 | |||
| 10 | This file is a rediffing of the patches visible at | ||
| 11 | https://nowt.dyndns.org/patch.qemu_nptl on 27 Sept 2006 | ||
| 12 | which "patch" fails to apply automatically. | ||
| 13 | See also http://lists.gnu.org/archive/html/qemu-devel/2006-09/msg00194.html | ||
| 14 | |||
| 15 | Martin Guy, 27 Sept 2006 | ||
| 16 | |||
| 17 | --- | 1 | --- |
| 18 | configure | 25 ++++++ | 2 | configure | 25 ++++++ |
| 19 | exec-all.h | 165 ------------------------------------------ | 3 | exec-all.h | 165 ------------------------------------------ |
| @@ -27,11 +11,11 @@ See also http://lists.gnu.org/archive/html/qemu-devel/2006-09/msg00194.html | |||
| 27 | target-arm/translate.c | 9 ++ | 11 | target-arm/translate.c | 9 ++ |
| 28 | 10 files changed, 405 insertions(+), 183 deletions(-) | 12 | 10 files changed, 405 insertions(+), 183 deletions(-) |
| 29 | 13 | ||
| 30 | Index: qemu/configure | 14 | Index: trunk/configure |
| 31 | =================================================================== | 15 | =================================================================== |
| 32 | --- qemu.orig/configure 2008-04-09 23:02:37.000000000 +0100 | 16 | --- trunk.orig/configure 2008-04-24 20:16:52.000000000 +0100 |
| 33 | +++ qemu/configure 2008-04-09 23:06:36.000000000 +0100 | 17 | +++ trunk/configure 2008-04-24 20:16:53.000000000 +0100 |
| 34 | @@ -109,6 +109,7 @@ | 18 | @@ -112,6 +112,7 @@ |
| 35 | build_docs="no" | 19 | build_docs="no" |
| 36 | uname_release="" | 20 | uname_release="" |
| 37 | curses="yes" | 21 | curses="yes" |
| @@ -39,7 +23,7 @@ Index: qemu/configure | |||
| 39 | 23 | ||
| 40 | # OS specific | 24 | # OS specific |
| 41 | targetos=`uname -s` | 25 | targetos=`uname -s` |
| 42 | @@ -334,6 +335,8 @@ | 26 | @@ -339,6 +340,8 @@ |
| 43 | ;; | 27 | ;; |
| 44 | *) echo "ERROR: unknown option $opt"; show_help="yes" | 28 | *) echo "ERROR: unknown option $opt"; show_help="yes" |
| 45 | ;; | 29 | ;; |
| @@ -48,7 +32,7 @@ Index: qemu/configure | |||
| 48 | esac | 32 | esac |
| 49 | done | 33 | done |
| 50 | 34 | ||
| 51 | @@ -429,6 +432,7 @@ | 35 | @@ -436,6 +439,7 @@ |
| 52 | echo " --disable-linux-user disable all linux usermode emulation targets" | 36 | echo " --disable-linux-user disable all linux usermode emulation targets" |
| 53 | echo " --enable-darwin-user enable all darwin usermode emulation targets" | 37 | echo " --enable-darwin-user enable all darwin usermode emulation targets" |
| 54 | echo " --disable-darwin-user disable all darwin usermode emulation targets" | 38 | echo " --disable-darwin-user disable all darwin usermode emulation targets" |
| @@ -56,7 +40,7 @@ Index: qemu/configure | |||
| 56 | echo " --fmod-lib path to FMOD library" | 40 | echo " --fmod-lib path to FMOD library" |
| 57 | echo " --fmod-inc path to FMOD includes" | 41 | echo " --fmod-inc path to FMOD includes" |
| 58 | echo " --enable-uname-release=R Return R for uname -r in usermode emulation" | 42 | echo " --enable-uname-release=R Return R for uname -r in usermode emulation" |
| 59 | @@ -595,6 +599,23 @@ | 43 | @@ -647,6 +651,23 @@ |
| 60 | } | 44 | } |
| 61 | EOF | 45 | EOF |
| 62 | 46 | ||
| @@ -80,7 +64,7 @@ Index: qemu/configure | |||
| 80 | ########################################## | 64 | ########################################## |
| 81 | # SDL probe | 65 | # SDL probe |
| 82 | 66 | ||
| 83 | @@ -778,6 +799,7 @@ | 67 | @@ -845,6 +866,7 @@ |
| 84 | echo "Documentation $build_docs" | 68 | echo "Documentation $build_docs" |
| 85 | [ ! -z "$uname_release" ] && \ | 69 | [ ! -z "$uname_release" ] && \ |
| 86 | echo "uname -r $uname_release" | 70 | echo "uname -r $uname_release" |
| @@ -88,24 +72,48 @@ Index: qemu/configure | |||
| 88 | 72 | ||
| 89 | if test $sdl_too_old = "yes"; then | 73 | if test $sdl_too_old = "yes"; then |
| 90 | echo "-> Your SDL version is too old - please upgrade to have SDL support" | 74 | echo "-> Your SDL version is too old - please upgrade to have SDL support" |
| 91 | @@ -1115,6 +1137,9 @@ | 75 | @@ -1228,6 +1250,9 @@ |
| 92 | echo "TARGET_ARCH=arm" >> $config_mak | 76 | echo "#define TARGET_ARM 1" >> $config_h |
| 93 | echo "#define TARGET_ARCH \"arm\"" >> $config_h | 77 | echo "#define CONFIG_NO_DYNGEN_OP 1" >> $config_h |
| 94 | echo "#define TARGET_ARM 1" >> $config_h | 78 | bflt="yes" |
| 95 | + if test "$nptl" = "yes" ; then | 79 | + if test "$nptl" = "yes" ; then |
| 96 | + echo "#define USE_NPTL 1" >> $config_h | 80 | + echo "#define USE_NPTL 1" >> $config_h |
| 97 | + fi | 81 | + fi |
| 98 | bflt="yes" | 82 | ;; |
| 99 | elif test "$target_cpu" = "sparc" ; then | 83 | cris) |
| 100 | echo "TARGET_ARCH=sparc" >> $config_mak | 84 | echo "TARGET_ARCH=cris" >> $config_mak |
| 101 | Index: qemu/exec-all.h | 85 | Index: trunk/exec-all.h |
| 102 | =================================================================== | 86 | =================================================================== |
| 103 | --- qemu.orig/exec-all.h 2008-04-09 22:39:38.000000000 +0100 | 87 | --- trunk.orig/exec-all.h 2008-04-24 20:16:41.000000000 +0100 |
| 104 | +++ qemu/exec-all.h 2008-04-09 23:05:55.000000000 +0100 | 88 | +++ trunk/exec-all.h 2008-04-24 20:16:53.000000000 +0100 |
| 105 | @@ -297,170 +297,7 @@ | 89 | @@ -303,217 +303,7 @@ |
| 106 | extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; | 90 | extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; |
| 107 | extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; | 91 | extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; |
| 108 | 92 | ||
| 93 | -#if defined(__hppa__) | ||
| 94 | - | ||
| 95 | -typedef int spinlock_t[4]; | ||
| 96 | - | ||
| 97 | -#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } | ||
| 98 | - | ||
| 99 | -static inline void resetlock (spinlock_t *p) | ||
| 100 | -{ | ||
| 101 | - (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; | ||
| 102 | -} | ||
| 103 | - | ||
| 104 | -#else | ||
| 105 | - | ||
| 106 | -typedef int spinlock_t; | ||
| 107 | - | ||
| 108 | -#define SPIN_LOCK_UNLOCKED 0 | ||
| 109 | - | ||
| 110 | -static inline void resetlock (spinlock_t *p) | ||
| 111 | -{ | ||
| 112 | - *p = SPIN_LOCK_UNLOCKED; | ||
| 113 | -} | ||
| 114 | - | ||
| 115 | -#endif | ||
| 116 | - | ||
| 109 | -#if defined(__powerpc__) | 117 | -#if defined(__powerpc__) |
| 110 | -static inline int testandset (int *p) | 118 | -static inline int testandset (int *p) |
| 111 | -{ | 119 | -{ |
| @@ -205,6 +213,33 @@ Index: qemu/exec-all.h | |||
| 205 | - : "cc","memory"); | 213 | - : "cc","memory"); |
| 206 | - return ret; | 214 | - return ret; |
| 207 | -} | 215 | -} |
| 216 | -#elif defined(__hppa__) | ||
| 217 | - | ||
| 218 | -/* Because malloc only guarantees 8-byte alignment for malloc'd data, | ||
| 219 | - and GCC only guarantees 8-byte alignment for stack locals, we can't | ||
| 220 | - be assured of 16-byte alignment for atomic lock data even if we | ||
| 221 | - specify "__attribute ((aligned(16)))" in the type declaration. So, | ||
| 222 | - we use a struct containing an array of four ints for the atomic lock | ||
| 223 | - type and dynamically select the 16-byte aligned int from the array | ||
| 224 | - for the semaphore. */ | ||
| 225 | -#define __PA_LDCW_ALIGNMENT 16 | ||
| 226 | -static inline void *ldcw_align (void *p) { | ||
| 227 | - unsigned long a = (unsigned long)p; | ||
| 228 | - a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); | ||
| 229 | - return (void *)a; | ||
| 230 | -} | ||
| 231 | - | ||
| 232 | -static inline int testandset (spinlock_t *p) | ||
| 233 | -{ | ||
| 234 | - unsigned int ret; | ||
| 235 | - p = ldcw_align(p); | ||
| 236 | - __asm__ __volatile__("ldcw 0(%1),%0" | ||
| 237 | - : "=r" (ret) | ||
| 238 | - : "r" (p) | ||
| 239 | - : "memory" ); | ||
| 240 | - return !ret; | ||
| 241 | -} | ||
| 242 | - | ||
| 208 | -#elif defined(__ia64) | 243 | -#elif defined(__ia64) |
| 209 | - | 244 | - |
| 210 | -#include <ia64intrin.h> | 245 | -#include <ia64intrin.h> |
| @@ -237,10 +272,6 @@ Index: qemu/exec-all.h | |||
| 237 | -#error unimplemented CPU support | 272 | -#error unimplemented CPU support |
| 238 | -#endif | 273 | -#endif |
| 239 | - | 274 | - |
| 240 | -typedef int spinlock_t; | ||
| 241 | - | ||
| 242 | -#define SPIN_LOCK_UNLOCKED 0 | ||
| 243 | - | ||
| 244 | -#if defined(CONFIG_USER_ONLY) | 275 | -#if defined(CONFIG_USER_ONLY) |
| 245 | -static inline void spin_lock(spinlock_t *lock) | 276 | -static inline void spin_lock(spinlock_t *lock) |
| 246 | -{ | 277 | -{ |
| @@ -249,7 +280,7 @@ Index: qemu/exec-all.h | |||
| 249 | - | 280 | - |
| 250 | -static inline void spin_unlock(spinlock_t *lock) | 281 | -static inline void spin_unlock(spinlock_t *lock) |
| 251 | -{ | 282 | -{ |
| 252 | - *lock = 0; | 283 | - resetlock(lock); |
| 253 | -} | 284 | -} |
| 254 | - | 285 | - |
| 255 | -static inline int spin_trylock(spinlock_t *lock) | 286 | -static inline int spin_trylock(spinlock_t *lock) |
| @@ -274,10 +305,10 @@ Index: qemu/exec-all.h | |||
| 274 | 305 | ||
| 275 | extern spinlock_t tb_lock; | 306 | extern spinlock_t tb_lock; |
| 276 | 307 | ||
| 277 | Index: qemu/linux-user/arm/syscall.h | 308 | Index: trunk/linux-user/arm/syscall.h |
| 278 | =================================================================== | 309 | =================================================================== |
| 279 | --- qemu.orig/linux-user/arm/syscall.h 2007-11-27 12:09:33.000000000 +0000 | 310 | --- trunk.orig/linux-user/arm/syscall.h 2008-04-24 20:16:41.000000000 +0100 |
| 280 | +++ qemu/linux-user/arm/syscall.h 2008-04-09 23:05:55.000000000 +0100 | 311 | +++ trunk/linux-user/arm/syscall.h 2008-04-24 20:16:53.000000000 +0100 |
| 281 | @@ -28,7 +28,9 @@ | 312 | @@ -28,7 +28,9 @@ |
| 282 | #define ARM_SYSCALL_BASE 0x900000 | 313 | #define ARM_SYSCALL_BASE 0x900000 |
| 283 | #define ARM_THUMB_SYSCALL 0 | 314 | #define ARM_THUMB_SYSCALL 0 |
| @@ -289,11 +320,11 @@ Index: qemu/linux-user/arm/syscall.h | |||
| 289 | 320 | ||
| 290 | #define ARM_NR_semihosting 0x123456 | 321 | #define ARM_NR_semihosting 0x123456 |
| 291 | #define ARM_NR_thumb_semihosting 0xAB | 322 | #define ARM_NR_thumb_semihosting 0xAB |
| 292 | Index: qemu/linux-user/main.c | 323 | Index: trunk/linux-user/main.c |
| 293 | =================================================================== | 324 | =================================================================== |
| 294 | --- qemu.orig/linux-user/main.c 2008-04-09 23:02:37.000000000 +0100 | 325 | --- trunk.orig/linux-user/main.c 2008-04-24 20:16:47.000000000 +0100 |
| 295 | +++ qemu/linux-user/main.c 2008-04-09 23:05:55.000000000 +0100 | 326 | +++ trunk/linux-user/main.c 2008-04-24 20:17:38.000000000 +0100 |
| 296 | @@ -364,6 +364,50 @@ | 327 | @@ -365,6 +365,50 @@ |
| 297 | } | 328 | } |
| 298 | } | 329 | } |
| 299 | 330 | ||
| @@ -325,7 +356,7 @@ Index: qemu/linux-user/main.c | |||
| 325 | + cpu_unlock(); | 356 | + cpu_unlock(); |
| 326 | + break; | 357 | + break; |
| 327 | + case 0xffff0fe0: /* __kernel_get_tls */ | 358 | + case 0xffff0fe0: /* __kernel_get_tls */ |
| 328 | + env->regs[0] = env->cp15.c13_tls; | 359 | + env->regs[0] = env->cp15.c13_tls2; |
| 329 | + break; | 360 | + break; |
| 330 | + default: | 361 | + default: |
| 331 | + return 1; | 362 | + return 1; |
| @@ -344,7 +375,7 @@ Index: qemu/linux-user/main.c | |||
| 344 | void cpu_loop(CPUARMState *env) | 375 | void cpu_loop(CPUARMState *env) |
| 345 | { | 376 | { |
| 346 | int trapnr; | 377 | int trapnr; |
| 347 | @@ -474,10 +518,8 @@ | 378 | @@ -475,10 +519,8 @@ |
| 348 | } | 379 | } |
| 349 | } | 380 | } |
| 350 | 381 | ||
| @@ -357,7 +388,7 @@ Index: qemu/linux-user/main.c | |||
| 357 | env->regs[0] = do_arm_semihosting (env); | 388 | env->regs[0] = do_arm_semihosting (env); |
| 358 | } else if (n == 0 || n >= ARM_SYSCALL_BASE | 389 | } else if (n == 0 || n >= ARM_SYSCALL_BASE |
| 359 | || (env->thumb && n == ARM_THUMB_SYSCALL)) { | 390 | || (env->thumb && n == ARM_THUMB_SYSCALL)) { |
| 360 | @@ -488,14 +530,34 @@ | 391 | @@ -489,14 +531,34 @@ |
| 361 | n -= ARM_SYSCALL_BASE; | 392 | n -= ARM_SYSCALL_BASE; |
| 362 | env->eabi = 0; | 393 | env->eabi = 0; |
| 363 | } | 394 | } |
| @@ -400,7 +431,7 @@ Index: qemu/linux-user/main.c | |||
| 400 | } else { | 431 | } else { |
| 401 | goto error; | 432 | goto error; |
| 402 | } | 433 | } |
| 403 | @@ -534,6 +596,10 @@ | 434 | @@ -535,6 +597,10 @@ |
| 404 | } | 435 | } |
| 405 | } | 436 | } |
| 406 | break; | 437 | break; |
| @@ -411,7 +442,19 @@ Index: qemu/linux-user/main.c | |||
| 411 | default: | 442 | default: |
| 412 | error: | 443 | error: |
| 413 | fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", | 444 | fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
| 414 | @@ -2402,6 +2468,10 @@ | 445 | @@ -1994,6 +2060,11 @@ |
| 446 | int drop_ld_preload = 0, environ_count = 0; | ||
| 447 | char **target_environ, **wrk, **dst; | ||
| 448 | |||
| 449 | + char *assume_kernel = getenv("QEMU_ASSUME_KERNEL"); | ||
| 450 | + | ||
| 451 | + if (assume_kernel) | ||
| 452 | + setenv("LD_ASSUME_KERNEL", assume_kernel, 1); | ||
| 453 | + | ||
| 454 | if (argc <= 1) | ||
| 455 | usage(); | ||
| 456 | |||
| 457 | @@ -2403,6 +2474,10 @@ | ||
| 415 | ts->heap_base = info->brk; | 458 | ts->heap_base = info->brk; |
| 416 | /* This will be filled in on the first SYS_HEAPINFO call. */ | 459 | /* This will be filled in on the first SYS_HEAPINFO call. */ |
| 417 | ts->heap_limit = 0; | 460 | ts->heap_limit = 0; |
| @@ -422,10 +465,10 @@ Index: qemu/linux-user/main.c | |||
| 422 | #endif | 465 | #endif |
| 423 | 466 | ||
| 424 | if (gdbstub_port) { | 467 | if (gdbstub_port) { |
| 425 | Index: qemu/linux-user/qemu.h | 468 | Index: trunk/linux-user/qemu.h |
| 426 | =================================================================== | 469 | =================================================================== |
| 427 | --- qemu.orig/linux-user/qemu.h 2008-01-02 15:48:21.000000000 +0000 | 470 | --- trunk.orig/linux-user/qemu.h 2008-04-24 20:16:41.000000000 +0100 |
| 428 | +++ qemu/linux-user/qemu.h 2008-04-09 23:05:55.000000000 +0100 | 471 | +++ trunk/linux-user/qemu.h 2008-04-24 20:16:53.000000000 +0100 |
| 429 | @@ -107,6 +107,9 @@ | 472 | @@ -107,6 +107,9 @@ |
| 430 | uint32_t heap_base; | 473 | uint32_t heap_base; |
| 431 | uint32_t heap_limit; | 474 | uint32_t heap_limit; |
| @@ -436,11 +479,19 @@ Index: qemu/linux-user/qemu.h | |||
| 436 | int used; /* non zero if used */ | 479 | int used; /* non zero if used */ |
| 437 | struct image_info *info; | 480 | struct image_info *info; |
| 438 | uint8_t stack[0]; | 481 | uint8_t stack[0]; |
| 439 | Index: qemu/linux-user/syscall.c | 482 | Index: trunk/linux-user/syscall.c |
| 440 | =================================================================== | 483 | =================================================================== |
| 441 | --- qemu.orig/linux-user/syscall.c 2008-04-09 23:02:38.000000000 +0100 | 484 | --- trunk.orig/linux-user/syscall.c 2008-04-24 20:16:50.000000000 +0100 |
| 442 | +++ qemu/linux-user/syscall.c 2008-04-09 23:05:55.000000000 +0100 | 485 | +++ trunk/linux-user/syscall.c 2008-04-24 20:19:52.000000000 +0100 |
| 443 | @@ -71,9 +71,18 @@ | 486 | @@ -61,6 +61,7 @@ |
| 487 | #define tchars host_tchars /* same as target */ | ||
| 488 | #define ltchars host_ltchars /* same as target */ | ||
| 489 | |||
| 490 | +#include <linux/futex.h> | ||
| 491 | #include <linux/termios.h> | ||
| 492 | #include <linux/unistd.h> | ||
| 493 | #include <linux/utsname.h> | ||
| 494 | @@ -71,9 +72,18 @@ | ||
| 444 | #include <linux/kd.h> | 495 | #include <linux/kd.h> |
| 445 | 496 | ||
| 446 | #include "qemu.h" | 497 | #include "qemu.h" |
| @@ -459,7 +510,14 @@ Index: qemu/linux-user/syscall.c | |||
| 459 | #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ | 510 | #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ |
| 460 | || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) | 511 | || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) |
| 461 | /* 16 bit uid wrappers emulation */ | 512 | /* 16 bit uid wrappers emulation */ |
| 462 | @@ -2702,9 +2711,19 @@ | 513 | @@ -2695,16 +2705,25 @@ |
| 514 | return 0; | ||
| 515 | } | ||
| 516 | #endif | ||
| 517 | - | ||
| 518 | #endif /* defined(TARGET_I386) */ | ||
| 519 | |||
| 520 | /* this stack is the equivalent of the kernel stack associated with a | ||
| 463 | thread/process */ | 521 | thread/process */ |
| 464 | #define NEW_STACK_SIZE 8192 | 522 | #define NEW_STACK_SIZE 8192 |
| 465 | 523 | ||
| @@ -479,7 +537,7 @@ Index: qemu/linux-user/syscall.c | |||
| 479 | cpu_loop(env); | 537 | cpu_loop(env); |
| 480 | /* never exits */ | 538 | /* never exits */ |
| 481 | return 0; | 539 | return 0; |
| 482 | @@ -2712,13 +2731,22 @@ | 540 | @@ -2712,15 +2731,27 @@ |
| 483 | 541 | ||
| 484 | /* do_fork() Must return host values and target errnos (unlike most | 542 | /* do_fork() Must return host values and target errnos (unlike most |
| 485 | do_*() functions). */ | 543 | do_*() functions). */ |
| @@ -492,18 +550,53 @@ Index: qemu/linux-user/syscall.c | |||
| 492 | TaskState *ts; | 550 | TaskState *ts; |
| 493 | uint8_t *new_stack; | 551 | uint8_t *new_stack; |
| 494 | CPUState *new_env; | 552 | CPUState *new_env; |
| 495 | 553 | +#if defined(TARGET_I386) | |
| 554 | + uint64_t *new_gdt_table; | ||
| 555 | +#endif | ||
| 496 | +#ifdef USE_NPTL | 556 | +#ifdef USE_NPTL |
| 497 | + unsigned int nptl_flags; | 557 | + unsigned int nptl_flags; |
| 498 | + | 558 | |
| 499 | + if (flags & CLONE_PARENT_SETTID) | 559 | + if (flags & CLONE_PARENT_SETTID) |
| 500 | + *parent_tidptr = gettid(); | 560 | + *parent_tidptr = gettid(); |
| 501 | +#endif | 561 | +#endif |
| 502 | + | ||
| 503 | if (flags & CLONE_VM) { | 562 | if (flags & CLONE_VM) { |
| 504 | ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); | 563 | ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); |
| 564 | + if (!ts) | ||
| 565 | + return -ENOMEM; | ||
| 505 | memset(ts, 0, sizeof(TaskState)); | 566 | memset(ts, 0, sizeof(TaskState)); |
| 506 | @@ -2784,16 +2812,67 @@ | 567 | new_stack = ts->stack; |
| 568 | ts->used = 1; | ||
| 569 | @@ -2732,6 +2763,29 @@ | ||
| 570 | #if defined(TARGET_I386) | ||
| 571 | if (!newsp) | ||
| 572 | newsp = env->regs[R_ESP]; | ||
| 573 | + new_gdt_table = malloc(9 * 8); | ||
| 574 | + if (!new_gdt_table) { | ||
| 575 | + free(new_env); | ||
| 576 | + return -ENOMEM; | ||
| 577 | + } | ||
| 578 | + /* Copy main GDT table from parent, but clear TLS entries */ | ||
| 579 | + memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); | ||
| 580 | + memset(&new_gdt_table[6], 0, 3 * 8); | ||
| 581 | + new_env->gdt.base = h2g(new_gdt_table); | ||
| 582 | + if (flags & 0x00080000 /* CLONE_SETTLS */) { | ||
| 583 | + ret = do_set_thread_area(new_env, new_env->regs[R_ESI]); | ||
| 584 | + if (ret) { | ||
| 585 | + free(new_gdt_table); | ||
| 586 | + free(new_env); | ||
| 587 | + return ret; | ||
| 588 | + } | ||
| 589 | + } | ||
| 590 | + cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]); | ||
| 591 | + cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]); | ||
| 592 | + cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]); | ||
| 593 | + cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]); | ||
| 594 | + cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]); | ||
| 595 | + cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]); | ||
| 596 | new_env->regs[R_ESP] = newsp; | ||
| 597 | new_env->regs[R_EAX] = 0; | ||
| 598 | #elif defined(TARGET_ARM) | ||
| 599 | @@ -2784,16 +2838,67 @@ | ||
| 507 | #error unsupported target CPU | 600 | #error unsupported target CPU |
| 508 | #endif | 601 | #endif |
| 509 | new_env->opaque = ts; | 602 | new_env->opaque = ts; |
| @@ -572,7 +665,85 @@ Index: qemu/linux-user/syscall.c | |||
| 572 | } | 665 | } |
| 573 | return ret; | 666 | return ret; |
| 574 | } | 667 | } |
| 575 | @@ -3118,7 +3197,7 @@ | 668 | @@ -3052,6 +3157,68 @@ |
| 669 | unlock_user_struct(target_ts, target_addr, 1); | ||
| 670 | } | ||
| 671 | |||
| 672 | +static long do_futex(target_ulong uaddr, int op, uint32_t val, | ||
| 673 | + target_ulong utime, target_ulong uaddr2, | ||
| 674 | + uint32_t val3) | ||
| 675 | +{ | ||
| 676 | + struct timespec host_utime; | ||
| 677 | + unsigned long val2 = utime; | ||
| 678 | + | ||
| 679 | + if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { | ||
| 680 | + target_to_host_timespec(&host_utime, utime); | ||
| 681 | + val2 = (unsigned long)&host_utime; | ||
| 682 | + } | ||
| 683 | + | ||
| 684 | +#ifdef BSWAP_NEEDED | ||
| 685 | + switch(op) { | ||
| 686 | + case FUTEX_CMP_REQUEUE: | ||
| 687 | + val3 = tswap32(val3); | ||
| 688 | + case FUTEX_REQUEUE: | ||
| 689 | + val2 = tswap32(val2); | ||
| 690 | + case FUTEX_WAIT: | ||
| 691 | + case FUTEX_WAKE: | ||
| 692 | + val = tswap32(val); | ||
| 693 | + case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ | ||
| 694 | + case FUTEX_UNLOCK_PI: | ||
| 695 | + break; | ||
| 696 | + default: | ||
| 697 | + gemu_log("qemu: Unsupported futex op %d\n", op); | ||
| 698 | + return -ENOSYS; | ||
| 699 | + } | ||
| 700 | +#if 0 /* No, it's worse than this */ | ||
| 701 | + if (op == FUTEX_WAKE_OP) { | ||
| 702 | + /* Need to munge the secondary operation (val3) */ | ||
| 703 | + val3 = tswap32(val3); | ||
| 704 | + int op2 = (val3 >> 28) & 7; | ||
| 705 | + int cmp = (val3 >> 24) & 15; | ||
| 706 | + int oparg = (val3 << 8) >> 20; | ||
| 707 | + int cmparg = (val3 << 20) >> 20; | ||
| 708 | + int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); | ||
| 709 | + | ||
| 710 | + if (shift) | ||
| 711 | + oparg = (oparg & 7) + 24 - (oparg & 24); | ||
| 712 | + else oparg = | ||
| 713 | + if (op2 == FUTEX_OP_ADD) { | ||
| 714 | + gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n"); | ||
| 715 | + return -ENOSYS; | ||
| 716 | + } | ||
| 717 | + if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE || | ||
| 718 | + cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) { | ||
| 719 | + gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg); | ||
| 720 | + return -ENOSYS; | ||
| 721 | + } | ||
| 722 | + val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg; | ||
| 723 | + } | ||
| 724 | +#endif | ||
| 725 | +#endif | ||
| 726 | + return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); | ||
| 727 | +} | ||
| 728 | + | ||
| 729 | +int do_set_tid_address(target_ulong tidptr) | ||
| 730 | +{ | ||
| 731 | + return syscall(__NR_set_tid_address, g2h(tidptr)); | ||
| 732 | +} | ||
| 733 | + | ||
| 734 | /* do_syscall() should always have a single exit point at the end so | ||
| 735 | that actions, such as logging of syscall results, can be performed. | ||
| 736 | All errnos that do_syscall() returns must be -TARGET_<errcode>. */ | ||
| 737 | @@ -3076,7 +3243,7 @@ | ||
| 738 | _mcleanup(); | ||
| 739 | #endif | ||
| 740 | gdb_exit(cpu_env, arg1); | ||
| 741 | - /* XXX: should free thread stack and CPU env */ | ||
| 742 | + /* XXX: should free thread stack, GDT and CPU env */ | ||
| 743 | _exit(arg1); | ||
| 744 | ret = 0; /* avoid warning */ | ||
| 745 | break; | ||
| 746 | @@ -3118,7 +3285,7 @@ | ||
| 576 | ret = do_brk(arg1); | 747 | ret = do_brk(arg1); |
| 577 | break; | 748 | break; |
| 578 | case TARGET_NR_fork: | 749 | case TARGET_NR_fork: |
| @@ -581,7 +752,7 @@ Index: qemu/linux-user/syscall.c | |||
| 581 | break; | 752 | break; |
| 582 | #ifdef TARGET_NR_waitpid | 753 | #ifdef TARGET_NR_waitpid |
| 583 | case TARGET_NR_waitpid: | 754 | case TARGET_NR_waitpid: |
| 584 | @@ -4481,7 +4560,8 @@ | 755 | @@ -4482,7 +4649,8 @@ |
| 585 | ret = get_errno(fsync(arg1)); | 756 | ret = get_errno(fsync(arg1)); |
| 586 | break; | 757 | break; |
| 587 | case TARGET_NR_clone: | 758 | case TARGET_NR_clone: |
| @@ -591,7 +762,7 @@ Index: qemu/linux-user/syscall.c | |||
| 591 | break; | 762 | break; |
| 592 | #ifdef __NR_exit_group | 763 | #ifdef __NR_exit_group |
| 593 | /* new thread calls */ | 764 | /* new thread calls */ |
| 594 | @@ -4928,7 +5008,8 @@ | 765 | @@ -4943,7 +5111,8 @@ |
| 595 | #endif | 766 | #endif |
| 596 | #ifdef TARGET_NR_vfork | 767 | #ifdef TARGET_NR_vfork |
| 597 | case TARGET_NR_vfork: | 768 | case TARGET_NR_vfork: |
| @@ -601,11 +772,34 @@ Index: qemu/linux-user/syscall.c | |||
| 601 | break; | 772 | break; |
| 602 | #endif | 773 | #endif |
| 603 | #ifdef TARGET_NR_ugetrlimit | 774 | #ifdef TARGET_NR_ugetrlimit |
| 604 | Index: qemu/qemu_spinlock.h | 775 | @@ -5521,6 +5690,9 @@ |
| 776 | #elif defined(TARGET_I386) && defined(TARGET_ABI32) | ||
| 777 | ret = do_set_thread_area(cpu_env, arg1); | ||
| 778 | break; | ||
| 779 | +#elif TARGET_i386 | ||
| 780 | + ret = get_errno(do_set_thread_area(cpu_env, arg1)); | ||
| 781 | + break; | ||
| 782 | #else | ||
| 783 | goto unimplemented_nowarn; | ||
| 784 | #endif | ||
| 785 | @@ -5538,6 +5710,12 @@ | ||
| 786 | goto unimplemented_nowarn; | ||
| 787 | #endif | ||
| 788 | |||
| 789 | +#ifdef TARGET_NR_futex | ||
| 790 | + case TARGET_NR_futex: | ||
| 791 | + ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6)); | ||
| 792 | + break; | ||
| 793 | +#endif | ||
| 794 | + | ||
| 795 | #ifdef TARGET_NR_clock_gettime | ||
| 796 | case TARGET_NR_clock_gettime: | ||
| 797 | { | ||
| 798 | Index: trunk/qemu_spinlock.h | ||
| 605 | =================================================================== | 799 | =================================================================== |
| 606 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | 800 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
| 607 | +++ qemu/qemu_spinlock.h 2008-04-09 23:05:55.000000000 +0100 | 801 | +++ trunk/qemu_spinlock.h 2008-04-24 20:16:53.000000000 +0100 |
| 608 | @@ -0,0 +1,181 @@ | 802 | @@ -0,0 +1,250 @@ |
| 609 | +/* | 803 | +/* |
| 610 | + * Atomic operation helper include | 804 | + * Atomic operation helper include |
| 611 | + * | 805 | + * |
| @@ -743,6 +937,33 @@ Index: qemu/qemu_spinlock.h | |||
| 743 | +} | 937 | +} |
| 744 | +#endif | 938 | +#endif |
| 745 | + | 939 | + |
| 940 | +#ifdef __hppa__ | ||
| 941 | +/* Because malloc only guarantees 8-byte alignment for malloc'd data, | ||
| 942 | + and GCC only guarantees 8-byte alignment for stack locals, we can't | ||
| 943 | + be assured of 16-byte alignment for atomic lock data even if we | ||
| 944 | + specify "__attribute ((aligned(16)))" in the type declaration. So, | ||
| 945 | + we use a struct containing an array of four ints for the atomic lock | ||
| 946 | + type and dynamically select the 16-byte aligned int from the array | ||
| 947 | + for the semaphore. */ | ||
| 948 | +#define __PA_LDCW_ALIGNMENT 16 | ||
| 949 | +static inline void *ldcw_align (void *p) { | ||
| 950 | + unsigned long a = (unsigned long)p; | ||
| 951 | + a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); | ||
| 952 | + return (void *)a; | ||
| 953 | +} | ||
| 954 | + | ||
| 955 | +static inline int testandset (spinlock_t *p) | ||
| 956 | +{ | ||
| 957 | + unsigned int ret; | ||
| 958 | + p = ldcw_align(p); | ||
| 959 | + __asm__ __volatile__("ldcw 0(%1),%0" | ||
| 960 | + : "=r" (ret) | ||
| 961 | + : "r" (p) | ||
| 962 | + : "memory" ); | ||
| 963 | + return !ret; | ||
| 964 | +} | ||
| 965 | +#endif | ||
| 966 | + | ||
| 746 | +#ifdef __ia64 | 967 | +#ifdef __ia64 |
| 747 | +#include <ia64intrin.h> | 968 | +#include <ia64intrin.h> |
| 748 | + | 969 | + |
| @@ -752,10 +973,52 @@ Index: qemu/qemu_spinlock.h | |||
| 752 | +} | 973 | +} |
| 753 | +#endif | 974 | +#endif |
| 754 | + | 975 | + |
| 976 | +#ifdef __mips__ | ||
| 977 | +static inline int testandset (int *p) | ||
| 978 | +{ | ||
| 979 | + int ret; | ||
| 980 | + | ||
| 981 | + __asm__ __volatile__ ( | ||
| 982 | + " .set push \n" | ||
| 983 | + " .set noat \n" | ||
| 984 | + " .set mips2 \n" | ||
| 985 | + "1: li $1, 1 \n" | ||
| 986 | + " ll %0, %1 \n" | ||
| 987 | + " sc $1, %1 \n" | ||
| 988 | + " beqz $1, 1b \n" | ||
| 989 | + " .set pop " | ||
| 990 | + : "=r" (ret), "+R" (*p) | ||
| 991 | + : | ||
| 992 | + : "memory"); | ||
| 993 | + | ||
| 994 | + return ret; | ||
| 995 | +} | ||
| 996 | +#endif | ||
| 997 | + | ||
| 998 | +#if defined(__hppa__) | ||
| 999 | + | ||
| 1000 | +typedef int spinlock_t[4]; | ||
| 1001 | + | ||
| 1002 | +#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } | ||
| 1003 | + | ||
| 1004 | +static inline void resetlock (spinlock_t *p) | ||
| 1005 | +{ | ||
| 1006 | + (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; | ||
| 1007 | +} | ||
| 1008 | + | ||
| 1009 | +#else | ||
| 1010 | + | ||
| 755 | +typedef int spinlock_t; | 1011 | +typedef int spinlock_t; |
| 756 | + | 1012 | + |
| 757 | +#define SPIN_LOCK_UNLOCKED 0 | 1013 | +#define SPIN_LOCK_UNLOCKED 0 |
| 758 | + | 1014 | + |
| 1015 | +static inline void resetlock (spinlock_t *p) | ||
| 1016 | +{ | ||
| 1017 | + *p = SPIN_LOCK_UNLOCKED; | ||
| 1018 | +} | ||
| 1019 | + | ||
| 1020 | +#endif | ||
| 1021 | + | ||
| 759 | +#if defined(CONFIG_USER_ONLY) | 1022 | +#if defined(CONFIG_USER_ONLY) |
| 760 | +static inline void spin_lock(spinlock_t *lock) | 1023 | +static inline void spin_lock(spinlock_t *lock) |
| 761 | +{ | 1024 | +{ |
| @@ -764,7 +1027,7 @@ Index: qemu/qemu_spinlock.h | |||
| 764 | + | 1027 | + |
| 765 | +static inline void spin_unlock(spinlock_t *lock) | 1028 | +static inline void spin_unlock(spinlock_t *lock) |
| 766 | +{ | 1029 | +{ |
| 767 | + *lock = 0; | 1030 | + resetlock(lock); |
| 768 | +} | 1031 | +} |
| 769 | + | 1032 | + |
| 770 | +static inline int spin_trylock(spinlock_t *lock) | 1033 | +static inline int spin_trylock(spinlock_t *lock) |
| @@ -787,10 +1050,10 @@ Index: qemu/qemu_spinlock.h | |||
| 787 | +#endif | 1050 | +#endif |
| 788 | + | 1051 | + |
| 789 | +#endif | 1052 | +#endif |
| 790 | Index: qemu/target-arm/cpu.h | 1053 | Index: trunk/target-arm/cpu.h |
| 791 | =================================================================== | 1054 | =================================================================== |
| 792 | --- qemu.orig/target-arm/cpu.h 2007-11-27 12:09:57.000000000 +0000 | 1055 | --- trunk.orig/target-arm/cpu.h 2008-04-24 20:16:41.000000000 +0100 |
| 793 | +++ qemu/target-arm/cpu.h 2008-04-09 23:05:55.000000000 +0100 | 1056 | +++ trunk/target-arm/cpu.h 2008-04-24 20:16:53.000000000 +0100 |
| 794 | @@ -38,6 +38,7 @@ | 1057 | @@ -38,6 +38,7 @@ |
| 795 | #define EXCP_FIQ 6 | 1058 | #define EXCP_FIQ 6 |
| 796 | #define EXCP_BKPT 7 | 1059 | #define EXCP_BKPT 7 |
| @@ -799,7 +1062,7 @@ Index: qemu/target-arm/cpu.h | |||
| 799 | 1062 | ||
| 800 | #define ARMV7M_EXCP_RESET 1 | 1063 | #define ARMV7M_EXCP_RESET 1 |
| 801 | #define ARMV7M_EXCP_NMI 2 | 1064 | #define ARMV7M_EXCP_NMI 2 |
| 802 | @@ -222,6 +223,15 @@ | 1065 | @@ -218,6 +219,15 @@ |
| 803 | void cpu_lock(void); | 1066 | void cpu_lock(void); |
| 804 | void cpu_unlock(void); | 1067 | void cpu_unlock(void); |
| 805 | 1068 | ||
| @@ -815,36 +1078,19 @@ Index: qemu/target-arm/cpu.h | |||
| 815 | #define CPSR_M (0x1f) | 1078 | #define CPSR_M (0x1f) |
| 816 | #define CPSR_T (1 << 5) | 1079 | #define CPSR_T (1 << 5) |
| 817 | #define CPSR_F (1 << 6) | 1080 | #define CPSR_F (1 << 6) |
| 818 | Index: qemu/target-arm/op.c | 1081 | Index: trunk/target-arm/translate.c |
| 819 | =================================================================== | ||
| 820 | --- qemu.orig/target-arm/op.c 2008-04-09 22:40:01.000000000 +0100 | ||
| 821 | +++ qemu/target-arm/op.c 2008-04-09 23:05:55.000000000 +0100 | ||
| 822 | @@ -994,6 +994,12 @@ | ||
| 823 | cpu_loop_exit(); | ||
| 824 | } | ||
| 825 | |||
| 826 | +void OPPROTO op_kernel_trap(void) | ||
| 827 | +{ | ||
| 828 | + env->exception_index = EXCP_KERNEL_TRAP; | ||
| 829 | + cpu_loop_exit(); | ||
| 830 | +} | ||
| 831 | + | ||
| 832 | /* VFP support. We follow the convention used for VFP instrunctions: | ||
| 833 | Single precition routines have a "s" suffix, double precision a | ||
| 834 | "d" suffix. */ | ||
| 835 | Index: qemu/target-arm/translate.c | ||
| 836 | =================================================================== | 1082 | =================================================================== |
| 837 | --- qemu.orig/target-arm/translate.c 2008-04-09 22:40:01.000000000 +0100 | 1083 | --- trunk.orig/target-arm/translate.c 2008-04-24 20:16:41.000000000 +0100 |
| 838 | +++ qemu/target-arm/translate.c 2008-04-09 23:05:55.000000000 +0100 | 1084 | +++ trunk/target-arm/translate.c 2008-04-24 20:16:53.000000000 +0100 |
| 839 | @@ -7496,7 +7496,14 @@ | 1085 | @@ -8606,7 +8606,14 @@ |
| 840 | gen_op_exception_exit(); | 1086 | gen_exception(EXCP_EXCEPTION_EXIT); |
| 841 | } | 1087 | } |
| 842 | #endif | 1088 | #endif |
| 843 | - | 1089 | - |
| 844 | +#ifdef CONFIG_USER_ONLY | 1090 | +#ifdef CONFIG_USER_ONLY |
| 845 | + /* Intercept jump to the magic kernel page. */ | 1091 | + /* Intercept jump to the magic kernel page. */ |
| 846 | + if (dc->pc > 0xffff0000) { | 1092 | + if (dc->pc > 0xffff0000) { |
| 847 | + gen_op_kernel_trap(); | 1093 | + gen_exception(EXCP_KERNEL_TRAP); |
| 848 | + dc->is_jmp = DISAS_UPDATE; | 1094 | + dc->is_jmp = DISAS_UPDATE; |
| 849 | + break; | 1095 | + break; |
| 850 | + } | 1096 | + } |
