]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/qemu/files/arm_nptl.patch
qemu: add cvs version from 20060723. bb files contain fix for building qemu with...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / qemu / files / arm_nptl.patch
1 Index: qemu/configure
2 ===================================================================
3 --- qemu.orig/configure 2006-08-26 16:31:53.000000000 +0100
4 +++ qemu/configure      2006-08-26 16:31:53.000000000 +0100
5 @@ -97,6 +97,7 @@
6  build_docs="no"
7  build_acpi_tables="no"
8  uname_release=""
9 +nptl="yes"
10  
11  # OS specific
12  targetos=`uname -s`
13 @@ -243,6 +244,8 @@
14    ;;
15    --enable-iasl) build_acpi_tables="yes"
16    ;;
17 +  --disable-nptl) nptl="no"
18 +  ;;
19    esac
20  done
21  
22 @@ -441,6 +444,23 @@
23      fi
24  fi
25  
26 +# check NPTL support
27 +cat > $TMPC <<EOF
28 +#include <sched.h>
29 +void foo()
30 +{
31 +#ifndef CLONE_SETTLS
32 +#error bork
33 +#endif
34 +}
35 +EOF
36 +
37 +if $cc -c -o $TMPO $TMPC 2> /dev/null ; then
38 +  :
39 +else
40 +   nptl="no"
41 +fi
42 +
43  ##########################################
44  # SDL probe
45  
46 @@ -559,6 +579,7 @@
47  fi
48  echo "FMOD support      $fmod $fmod_support"
49  echo "kqemu support     $kqemu"
50 +echo "NPTL support      $nptl"
51  echo "Documentation     $build_docs"
52  [ ! -z "$uname_release" ] && \
53  echo "uname -r          $uname_release"
54 @@ -880,6 +901,14 @@
55              echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
56          fi
57      fi
58 +else
59 +    if test "$nptl" = "yes" ; then
60 +        case "$target_cpu" in
61 +          arm | armeb)
62 +            echo "#define USE_NPTL 1" >> $config_h
63 +          ;;
64 +        esac
65 +    fi
66  fi
67  
68  if test "$cocoa" = "yes" ; then
69 Index: qemu/exec-all.h
70 ===================================================================
71 --- qemu.orig/exec-all.h        2006-08-26 16:28:32.000000000 +0100
72 +++ qemu/exec-all.h     2006-08-26 16:31:53.000000000 +0100
73 @@ -347,163 +347,7 @@
74  extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
75  extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
76  
77 -#ifdef __powerpc__
78 -static inline int testandset (int *p)
79 -{
80 -    int ret;
81 -    __asm__ __volatile__ (
82 -                          "0:    lwarx %0,0,%1\n"
83 -                          "      xor. %0,%3,%0\n"
84 -                          "      bne 1f\n"
85 -                          "      stwcx. %2,0,%1\n"
86 -                          "      bne- 0b\n"
87 -                          "1:    "
88 -                          : "=&r" (ret)
89 -                          : "r" (p), "r" (1), "r" (0)
90 -                          : "cr0", "memory");
91 -    return ret;
92 -}
93 -#endif
94 -
95 -#ifdef __i386__
96 -static inline int testandset (int *p)
97 -{
98 -    long int readval = 0;
99 -    
100 -    __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
101 -                          : "+m" (*p), "+a" (readval)
102 -                          : "r" (1)
103 -                          : "cc");
104 -    return readval;
105 -}
106 -#endif
107 -
108 -#ifdef __x86_64__
109 -static inline int testandset (int *p)
110 -{
111 -    long int readval = 0;
112 -    
113 -    __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
114 -                          : "+m" (*p), "+a" (readval)
115 -                          : "r" (1)
116 -                          : "cc");
117 -    return readval;
118 -}
119 -#endif
120 -
121 -#ifdef __s390__
122 -static inline int testandset (int *p)
123 -{
124 -    int ret;
125 -
126 -    __asm__ __volatile__ ("0: cs    %0,%1,0(%2)\n"
127 -                         "   jl    0b"
128 -                         : "=&d" (ret)
129 -                         : "r" (1), "a" (p), "0" (*p) 
130 -                         : "cc", "memory" );
131 -    return ret;
132 -}
133 -#endif
134 -
135 -#ifdef __alpha__
136 -static inline int testandset (int *p)
137 -{
138 -    int ret;
139 -    unsigned long one;
140 -
141 -    __asm__ __volatile__ ("0:  mov 1,%2\n"
142 -                         "     ldl_l %0,%1\n"
143 -                         "     stl_c %2,%1\n"
144 -                         "     beq %2,1f\n"
145 -                         ".subsection 2\n"
146 -                         "1:   br 0b\n"
147 -                         ".previous"
148 -                         : "=r" (ret), "=m" (*p), "=r" (one)
149 -                         : "m" (*p));
150 -    return ret;
151 -}
152 -#endif
153 -
154 -#ifdef __sparc__
155 -static inline int testandset (int *p)
156 -{
157 -       int ret;
158 -
159 -       __asm__ __volatile__("ldstub    [%1], %0"
160 -                            : "=r" (ret)
161 -                            : "r" (p)
162 -                            : "memory");
163 -
164 -       return (ret ? 1 : 0);
165 -}
166 -#endif
167 -
168 -#ifdef __arm__
169 -static inline int testandset (int *spinlock)
170 -{
171 -    register unsigned int ret;
172 -    __asm__ __volatile__("swp %0, %1, [%2]"
173 -                         : "=r"(ret)
174 -                         : "0"(1), "r"(spinlock));
175 -    
176 -    return ret;
177 -}
178 -#endif
179 -
180 -#ifdef __mc68000
181 -static inline int testandset (int *p)
182 -{
183 -    char ret;
184 -    __asm__ __volatile__("tas %1; sne %0"
185 -                         : "=r" (ret)
186 -                         : "m" (p)
187 -                         : "cc","memory");
188 -    return ret;
189 -}
190 -#endif
191 -
192 -#ifdef __ia64
193 -#include <ia64intrin.h>
194 -
195 -static inline int testandset (int *p)
196 -{
197 -    return __sync_lock_test_and_set (p, 1);
198 -}
199 -#endif
200 -
201 -typedef int spinlock_t;
202 -
203 -#define SPIN_LOCK_UNLOCKED 0
204 -
205 -#if defined(CONFIG_USER_ONLY)
206 -static inline void spin_lock(spinlock_t *lock)
207 -{
208 -    while (testandset(lock));
209 -}
210 -
211 -static inline void spin_unlock(spinlock_t *lock)
212 -{
213 -    *lock = 0;
214 -}
215 -
216 -static inline int spin_trylock(spinlock_t *lock)
217 -{
218 -    return !testandset(lock);
219 -}
220 -#else
221 -static inline void spin_lock(spinlock_t *lock)
222 -{
223 -}
224 -
225 -static inline void spin_unlock(spinlock_t *lock)
226 -{
227 -}
228 -
229 -static inline int spin_trylock(spinlock_t *lock)
230 -{
231 -    return 1;
232 -}
233 -#endif
234 +#include "qemu_spinlock.h"
235  
236  extern spinlock_t tb_lock;
237  
238 Index: qemu/linux-user/arm/syscall.h
239 ===================================================================
240 --- qemu.orig/linux-user/arm/syscall.h  2006-03-09 19:18:11.000000000 +0000
241 +++ qemu/linux-user/arm/syscall.h       2006-08-26 16:31:53.000000000 +0100
242 @@ -28,7 +28,9 @@
243  #define ARM_SYSCALL_BASE       0x900000
244  #define ARM_THUMB_SYSCALL      0
245  
246 -#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2)
247 +#define ARM_NR_BASE      0xf0000
248 +#define ARM_NR_cacheflush (ARM_NR_BASE + 2)
249 +#define ARM_NR_set_tls   (ARM_NR_BASE + 5)
250  
251  #define ARM_NR_semihosting       0x123456
252  #define ARM_NR_thumb_semihosting  0xAB
253 Index: qemu/linux-user/main.c
254 ===================================================================
255 --- qemu.orig/linux-user/main.c 2006-08-26 16:28:40.000000000 +0100
256 +++ qemu/linux-user/main.c      2006-08-26 16:31:53.000000000 +0100
257 @@ -309,6 +309,50 @@
258      }
259  }
260  
261 +/* Handle a jump to the kernel code page.  */
262 +static int
263 +do_kernel_trap(CPUARMState *env)
264 +{
265 +    uint32_t addr;
266 +    uint32_t *ptr;
267 +    uint32_t cpsr;
268 +
269 +    switch (env->regs[15]) {
270 +    case 0xffff0fc0: /* __kernel_cmpxchg */
271 +        /* XXX: This only works between threads, not between processes.
272 +           Use native atomic operations.  */
273 +        /* ??? This probably breaks horribly if the access segfaults.  */
274 +        cpu_lock();
275 +        ptr = (uint32_t *)env->regs[2];
276 +        cpsr = cpsr_read(env);
277 +        if (*ptr == env->regs[0]) {
278 +            *ptr = env->regs[1];
279 +            env->regs[0] = 0;
280 +            cpsr |= CPSR_C;
281 +        } else {
282 +            env->regs[0] = -1;
283 +            cpsr &= ~CPSR_C;
284 +        }
285 +        cpsr_write(env, cpsr, CPSR_C);
286 +        cpu_unlock();
287 +        break;
288 +    case 0xffff0fe0: /* __kernel_get_tls */
289 +        env->regs[0] = env->cp15.c13_tls;
290 +        break;
291 +    default:
292 +        return 1;
293 +    }
294 +    /* Jump back to the caller.  */
295 +    addr = env->regs[14];
296 +    if (addr & 1) {
297 +        env->thumb = 1;
298 +        addr &= ~1;
299 +    }
300 +    env->regs[15] = addr;
301 +
302 +    return 0;
303 +}
304 +
305  void cpu_loop(CPUARMState *env)
306  {
307      int trapnr;
308 @@ -365,10 +409,8 @@
309                      }
310                  }
311  
312 -                if (n == ARM_NR_cacheflush) {
313 -                    arm_cache_flush(env->regs[0], env->regs[1]);
314 -                } else if (n == ARM_NR_semihosting
315 -                           || n == ARM_NR_thumb_semihosting) {
316 +                if (n == ARM_NR_semihosting
317 +                    || n == ARM_NR_thumb_semihosting) {
318                      env->regs[0] = do_arm_semihosting (env);
319                  } else if (n == 0 || n >= ARM_SYSCALL_BASE
320                             || (env->thumb && n == ARM_THUMB_SYSCALL)) {
321 @@ -379,14 +421,34 @@
322                          n -= ARM_SYSCALL_BASE;
323                          env->eabi = 0;
324                      }
325 -                    env->regs[0] = do_syscall(env, 
326 -                                              n, 
327 -                                              env->regs[0],
328 -                                              env->regs[1],
329 -                                              env->regs[2],
330 -                                              env->regs[3],
331 -                                              env->regs[4],
332 -                                              env->regs[5]);
333 +                    if ( n > ARM_NR_BASE) {
334 +                        switch (n)
335 +                          {
336 +                          case ARM_NR_cacheflush:
337 +                              arm_cache_flush(env->regs[0], env->regs[1]);
338 +                              break;
339 +#ifdef USE_NPTL
340 +                          case ARM_NR_set_tls:
341 +                              cpu_set_tls(env, env->regs[0]);
342 +                              env->regs[0] = 0;
343 +                              break;
344 +#endif
345 +                          default:
346 +                              printf ("Error: Bad syscall: %x\n", n);
347 +                              goto error;
348 +                          }
349 +                      }
350 +                    else
351 +                      {
352 +                        env->regs[0] = do_syscall(env, 
353 +                                                  n, 
354 +                                                  env->regs[0],
355 +                                                  env->regs[1],
356 +                                                  env->regs[2],
357 +                                                  env->regs[3],
358 +                                                  env->regs[4],
359 +                                                  env->regs[5]);
360 +                      }
361                  } else {
362                      goto error;
363                  }
364 @@ -425,6 +487,10 @@
365                    }
366              }
367              break;
368 +        case EXCP_KERNEL_TRAP:
369 +            if (do_kernel_trap(env))
370 +              goto error;
371 +            break;
372          default:
373          error:
374              fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", 
375 @@ -1639,6 +1705,10 @@
376          ts->heap_base = info->brk;
377          /* This will be filled in on the first SYS_HEAPINFO call.  */
378          ts->heap_limit = 0;
379 +        /* Register the magic kernel code page.  The cpu will generate a
380 +           special exception when it tries to execute code here.  We can't
381 +           put real code here because it may be in use by the host kernel.  */
382 +        page_set_flags(0xffff0000, 0xffff0fff, 0);
383      }
384  #elif defined(TARGET_SPARC)
385      {
386 Index: qemu/linux-user/qemu.h
387 ===================================================================
388 --- qemu.orig/linux-user/qemu.h 2006-08-26 16:28:40.000000000 +0100
389 +++ qemu/linux-user/qemu.h      2006-08-26 16:33:50.000000000 +0100
390 @@ -75,6 +75,9 @@
391      uint32_t v86mask;
392  #endif
393      int used; /* non zero if used */
394 +#ifdef USE_NPTL
395 +    uint32_t *child_tidptr;
396 +#endif
397      struct image_info *info;
398      uint8_t stack[0];
399  } __attribute__((aligned(16))) TaskState;
400 Index: qemu/linux-user/syscall.c
401 ===================================================================
402 --- qemu.orig/linux-user/syscall.c      2006-08-26 16:28:40.000000000 +0100
403 +++ qemu/linux-user/syscall.c   2006-08-26 16:31:53.000000000 +0100
404 @@ -66,9 +66,18 @@
405  #include <linux/kd.h>
406  
407  #include "qemu.h"
408 +#include "qemu_spinlock.h"
409  
410  //#define DEBUG
411  
412 +#ifdef USE_NPTL
413 +#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
414 +    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
415 +#else
416 +/* XXX: Hardcode the above values.  */
417 +#define CLONE_NPTL_FLAGS2 0
418 +#endif
419 +
420  #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
421  /* 16 bit uid wrappers emulation */
422  #define USE_UID16
423 @@ -1602,20 +1611,38 @@
424     thread/process */
425  #define NEW_STACK_SIZE 8192
426  
427 +#ifdef USE_NPTL
428 +static spinlock_t nptl_lock = SPIN_LOCK_UNLOCKED;
429 +#endif
430 +
431  static int clone_func(void *arg)
432  {
433      CPUState *env = arg;
434 +#ifdef HAVE_NPTL
435 +    /* Wait until the parent has finshed initializing the tls state.  */
436 +    while (!spin_trylock(&nptl_lock))
437 +        usleep(1);
438 +    spin_unlock(&nptl_lock);
439 +#endif
440      cpu_loop(env);
441      /* never exits */
442      return 0;
443  }
444  
445 -int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
446 +int do_fork(CPUState *env, unsigned int flags, unsigned long newsp,
447 +            uint32_t *parent_tidptr, void *newtls,
448 +            uint32_t *child_tidptr)
449  {
450      int ret;
451      TaskState *ts;
452      uint8_t *new_stack;
453      CPUState *new_env;
454 +#ifdef USE_NPTL
455 +    unsigned int nptl_flags;
456 +
457 +    if (flags & CLONE_PARENT_SETTID)
458 +        *parent_tidptr = gettid();
459 +#endif
460      
461      if (flags & CLONE_VM) {
462          ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
463 @@ -1665,16 +1692,60 @@
464  #error unsupported target CPU
465  #endif
466          new_env->opaque = ts;
467 +#ifdef USE_NPTL
468 +     nptl_flags = flags;
469 +     flags &= ~CLONE_NPTL_FLAGS2;
470 +     if (nptl_flags & CLONE_CHILD_CLEARTID) {
471 +          ts->child_tidptr = child_tidptr;
472 +     }
473 +     if (nptl_flags & CLONE_SETTLS)
474 +         cpu_set_tls (new_env, newtls);
475 +     /* Grab the global cpu lock so that the thread setup appears
476 +        atomic.  */
477 +     if (nptl_flags & CLONE_CHILD_SETTID)
478 +         spin_lock(&nptl_lock);
479 +#else
480 +     if (flags & CLONE_NPTL_FLAGS2)
481 +         return -EINVAL;
482 +#endif
483 +
484  #ifdef __ia64__
485          ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
486  #else
487         ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
488  #endif
489 +#ifdef USE_NPTL
490 +     if (ret != -1) {
491 +         if (nptl_flags & CLONE_CHILD_SETTID)
492 +             *child_tidptr = ret;
493 +     }
494 +     /* Allow the child to continue.  */
495 +     if (nptl_flags & CLONE_CHILD_SETTID)
496 +         spin_unlock(&nptl_lock);
497 +#endif
498      } else {
499 -        /* if no CLONE_VM, we consider it is a fork */
500 -        if ((flags & ~CSIGNAL) != 0)
501 -            return -EINVAL;
502 -        ret = fork();
503 +    /* if no CLONE_VM, we consider it is a fork */
504 +    if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
505 +          return -EINVAL;
506 +      ret = fork();
507 +#ifdef USE_NPTL
508 +     /* There is a race condition here.  The parent process could
509 +        theoretically read the TID in the child process before the child
510 +        tid is set.  This would require using either ptrace
511 +        (not implemented) or having *_tidptr to point at a shared memory
512 +        mapping.  We can't repeat the spinlock hack used above because
513 +        the child process gets its own copy of the lock.  */
514 +     if (ret == 0) {
515 +         /* Child Process.  */
516 +         if (flags & CLONE_CHILD_SETTID)
517 +             *child_tidptr = gettid();
518 +         ts = (TaskState *)env->opaque;
519 +         if (flags & CLONE_CHILD_CLEARTID)
520 +             ts->child_tidptr = child_tidptr;
521 +         if (flags & CLONE_SETTLS)
522 +             cpu_set_tls (env, newtls);
523 +     }
524 +#endif
525      }
526      return ret;
527  }
528 @@ -1918,7 +1989,7 @@
529          ret = do_brk(arg1);
530          break;
531      case TARGET_NR_fork:
532 -        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
533 +        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, NULL, NULL, NULL));
534          break;
535      case TARGET_NR_waitpid:
536          {
537 @@ -2989,7 +3060,8 @@
538          ret = get_errno(fsync(arg1));
539          break;
540      case TARGET_NR_clone:
541 -        ret = get_errno(do_fork(cpu_env, arg1, arg2));
542 +        ret = get_errno(do_fork(cpu_env, arg1, arg2, (uint32_t *)arg3,
543 +                        (void *)arg4, (uint32_t *)arg5));
544          break;
545  #ifdef __NR_exit_group
546          /* new thread calls */
547 @@ -3339,7 +3411,8 @@
548  #endif
549  #ifdef TARGET_NR_vfork
550      case TARGET_NR_vfork:
551 -        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
552 +        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
553 +                                NULL, NULL, NULL));
554          break;
555  #endif
556  #ifdef TARGET_NR_ugetrlimit
557 @@ -3838,4 +3911,3 @@
558  #endif
559      return ret;
560  }
561 -
562 Index: qemu/target-arm/cpu.h
563 ===================================================================
564 --- qemu.orig/target-arm/cpu.h  2006-03-09 19:18:27.000000000 +0000
565 +++ qemu/target-arm/cpu.h       2006-08-26 16:31:53.000000000 +0100
566 @@ -35,6 +35,9 @@
567  #define EXCP_IRQ             5
568  #define EXCP_FIQ             6
569  #define EXCP_BKPT            7
570 +#define EXCP_KERNEL_TRAP     8   /* Jumped to kernel code page.  */
571 +
572 +
573  
574  /* We currently assume float and double are IEEE single and double
575     precision respectively.
576 @@ -85,6 +88,7 @@
577          uint32_t c9_data;
578          uint32_t c13_fcse; /* FCSE PID.  */
579          uint32_t c13_context; /* Context ID.  */
580 +        uint32_t c13_tls; /* Paul Brook told me to just add this ;)  */
581      } cp15;
582  
583      /* Internal CPU feature flags.  */
584 @@ -135,6 +139,15 @@
585  int cpu_arm_signal_handler(int host_signum, struct siginfo *info, 
586                             void *puc);
587  
588 +void cpu_lock(void);
589 +void cpu_unlock(void);
590 +#if defined(USE_NPTL)
591 +static inline void cpu_set_tls(CPUARMState *env, void *newtls)
592 +{
593 +  env->cp15.c13_tls = (uint32_t)newtls;
594 +}
595 +#endif
596 +
597  #define CPSR_M (0x1f)
598  #define CPSR_T (1 << 5)
599  #define CPSR_F (1 << 6)
600 @@ -146,7 +159,11 @@
601  #define CPSR_J (1 << 24)
602  #define CPSR_IT_0_1 (3 << 25)
603  #define CPSR_Q (1 << 27)
604 -#define CPSR_NZCV (0xf << 28)
605 +#define CPSR_V (1 << 28)
606 +#define CPSR_C (1 << 29)
607 +#define CPSR_Z (1 << 30)
608 +#define CPSR_N (1 << 31)
609 +#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V)
610  
611  #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV)
612  /* Return the current CPSR value.  */
613 Index: qemu/target-arm/exec.h
614 ===================================================================
615 --- qemu.orig/target-arm/exec.h 2006-03-09 19:18:27.000000000 +0000
616 +++ qemu/target-arm/exec.h      2006-08-26 16:31:53.000000000 +0100
617 @@ -51,8 +51,6 @@
618  
619  /* In op_helper.c */
620  
621 -void cpu_lock(void);
622 -void cpu_unlock(void);
623  void helper_set_cp15(CPUState *, uint32_t, uint32_t);
624  uint32_t helper_get_cp15(CPUState *, uint32_t);
625  
626 Index: qemu/target-arm/op.c
627 ===================================================================
628 --- qemu.orig/target-arm/op.c   2006-08-26 16:28:48.000000000 +0100
629 +++ qemu/target-arm/op.c        2006-08-26 16:31:53.000000000 +0100
630 @@ -891,6 +891,12 @@
631      cpu_loop_exit();
632  }
633  
634 +void OPPROTO op_kernel_trap(void)
635 +{
636 +    env->exception_index = EXCP_KERNEL_TRAP;
637 +    cpu_loop_exit();
638 +}
639 +
640  /* VFP support.  We follow the convention used for VFP instrunctions:
641     Single precition routines have a "s" suffix, double precision a
642     "d" suffix.  */
643 Index: qemu/target-arm/translate.c
644 ===================================================================
645 --- qemu.orig/target-arm/translate.c    2006-08-26 16:28:48.000000000 +0100
646 +++ qemu/target-arm/translate.c 2006-08-26 16:31:53.000000000 +0100
647 @@ -2382,6 +2382,7 @@
648      s->is_jmp = DISAS_JUMP;
649  }
650  
651 +
652  /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
653     basic block 'tb'. If search_pc is TRUE, also generate PC
654     information for each intermediate instruction. */
655 @@ -2416,6 +2417,15 @@
656      nb_gen_labels = 0;
657      lj = -1;
658      do {
659 +#ifdef CONFIG_USER_ONLY
660 +        /* Intercept jump to the magic kernel page.  */
661 +        if (dc->pc > 0xffff0000) {
662 +            gen_op_kernel_trap();
663 +            dc->is_jmp = DISAS_UPDATE;
664 +            break;
665 +        }
666 +#endif
667 +
668          if (env->nb_breakpoints > 0) {
669              for(j = 0; j < env->nb_breakpoints; j++) {
670                  if (env->breakpoints[j] == dc->pc) {
671 Index: qemu/qemu_spinlock.h
672 ===================================================================
673 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
674 +++ qemu/qemu_spinlock.h        2006-08-26 16:31:53.000000000 +0100
675 @@ -0,0 +1,182 @@
676 +/*
677 + * internal execution defines for qemu
678 + *
679 + *  Copyright (c) 2003 Fabrice Bellard
680 + *
681 + * This library is free software; you can redistribute it and/or
682 + * modify it under the terms of the GNU Lesser General Public
683 + * License as published by the Free Software Foundation; either
684 + * version 2 of the License, or (at your option) any later version.
685 + *
686 + * This library is distributed in the hope that it will be useful,
687 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
688 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
689 + * Lesser General Public License for more details.
690 + *
691 + * You should have received a copy of the GNU Lesser General Public
692 + * License along with this library; if not, write to the Free Software
693 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
694 + */
695 +
696 +#ifndef _QEMU_SPINLOCK_H
697 +#define _QEMU_SPINLOCK_H
698 +
699 +#ifdef __powerpc__
700 +static inline int testandset (int *p)
701 +{
702 +    int ret;
703 +    __asm__ __volatile__ (
704 +                          "0:    lwarx %0,0,%1\n"
705 +                          "      xor. %0,%3,%0\n"
706 +                          "      bne 1f\n"
707 +                          "      stwcx. %2,0,%1\n"
708 +                          "      bne- 0b\n"
709 +                          "1:    "
710 +                          : "=&r" (ret)
711 +                          : "r" (p), "r" (1), "r" (0)
712 +                          : "cr0", "memory");
713 +    return ret;
714 +}
715 +#endif
716 +
717 +#ifdef __i386__
718 +static inline int testandset (int *p)
719 +{
720 +    long int readval = 0;
721 +
722 +    __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
723 +                          : "+m" (*p), "+a" (readval)
724 +                          : "r" (1)
725 +                          : "cc");
726 +    return readval;
727 +}
728 +#endif
729 +
730 +#ifdef __x86_64__
731 +static inline int testandset (int *p)
732 +{
733 +    long int readval = 0;
734 +
735 +    __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
736 +                          : "+m" (*p), "+a" (readval)
737 +                          : "r" (1)
738 +                          : "cc");
739 +    return readval;
740 +}
741 +#endif
742 +
743 +#ifdef __s390__
744 +static inline int testandset (int *p)
745 +{
746 +    int ret;
747 +
748 +    __asm__ __volatile__ ("0: cs    %0,%1,0(%2)\n"
749 +                         "   jl    0b"
750 +                         : "=&d" (ret)
751 +                         : "r" (1), "a" (p), "0" (*p)
752 +                         : "cc", "memory" );
753 +    return ret;
754 +}
755 +#endif
756 +
757 +#ifdef __alpha__
758 +static inline int testandset (int *p)
759 +{
760 +    int ret;
761 +    unsigned long one;
762 +
763 +    __asm__ __volatile__ ("0:  mov 1,%2\n"
764 +                         "     ldl_l %0,%1\n"
765 +                         "     stl_c %2,%1\n"
766 +                         "     beq %2,1f\n"
767 +                         ".subsection 2\n"
768 +                         "1:   br 0b\n"
769 +                         ".previous"
770 +                         : "=r" (ret), "=m" (*p), "=r" (one)
771 +                         : "m" (*p));
772 +    return ret;
773 +}
774 +#endif
775 +
776 +#ifdef __sparc__
777 +static inline int testandset (int *p)
778 +{
779 +       int ret;
780 +
781 +       __asm__ __volatile__("ldstub    [%1], %0"
782 +                            : "=r" (ret)
783 +                            : "r" (p)
784 +                            : "memory");
785 +
786 +       return (ret ? 1 : 0);
787 +}
788 +#endif
789 +
790 +#ifdef __arm__
791 +static inline int testandset (int *spinlock)
792 +{
793 +    register unsigned int ret;
794 +    __asm__ __volatile__("swp %0, %1, [%2]"
795 +                         : "=r"(ret)
796 +                         : "0"(1), "r"(spinlock));
797 +
798 +    return ret;
799 +}
800 +#endif
801 +
802 +#ifdef __mc68000
803 +static inline int testandset (int *p)
804 +{
805 +    char ret;
806 +    __asm__ __volatile__("tas %1; sne %0"
807 +                         : "=r" (ret)
808 +                         : "m" (p)
809 +                         : "cc","memory");
810 +    return ret;
811 +}
812 +#endif
813 +
814 +#ifdef __ia64
815 +#include <ia64intrin.h>
816 +
817 +static inline int testandset (int *p)
818 +{
819 +    return __sync_lock_test_and_set (p, 1);
820 +}
821 +#endif
822 +
823 +typedef int spinlock_t;
824 +
825 +#define SPIN_LOCK_UNLOCKED 0
826 +
827 +#if defined(CONFIG_USER_ONLY)
828 +static inline void spin_lock(spinlock_t *lock)
829 +{
830 +    while (testandset(lock));
831 +}
832 +
833 +static inline void spin_unlock(spinlock_t *lock)
834 +{
835 +    *lock = 0;
836 +}
837 +
838 +static inline int spin_trylock(spinlock_t *lock)
839 +{
840 +    return !testandset(lock);
841 +}
842 +#else
843 +static inline void spin_lock(spinlock_t *lock)
844 +{
845 +}
846 +
847 +static inline void spin_unlock(spinlock_t *lock)
848 +{
849 +}
850 +
851 +static inline int spin_trylock(spinlock_t *lock)
852 +{
853 +    return 1;
854 +}
855 +#endif
856 +
857 +#endif /* ! _QEMU_SPINLOCK_H */