diff options
Diffstat (limited to 'meta/packages')
-rw-r--r-- | meta/packages/qemu/files/arm_nptl.patch | 857 | ||||
-rw-r--r-- | meta/packages/qemu/qemu_cvs.bb | 3 |
2 files changed, 859 insertions, 1 deletions
diff --git a/meta/packages/qemu/files/arm_nptl.patch b/meta/packages/qemu/files/arm_nptl.patch new file mode 100644 index 0000000000..958c27e5e1 --- /dev/null +++ b/meta/packages/qemu/files/arm_nptl.patch | |||
@@ -0,0 +1,857 @@ | |||
1 | Index: qemu/configure | ||
2 | =================================================================== | ||
3 | --- qemu.orig/configure 2006-08-14 22:09:39.000000000 +0100 | ||
4 | +++ qemu/configure 2006-08-14 22:38:54.000000000 +0100 | ||
5 | @@ -96,6 +96,7 @@ | ||
6 | user="no" | ||
7 | build_docs="no" | ||
8 | uname_release="" | ||
9 | +nptl="yes" | ||
10 | |||
11 | # OS specific | ||
12 | targetos=`uname -s` | ||
13 | @@ -240,6 +241,8 @@ | ||
14 | ;; | ||
15 | --enable-uname-release=*) uname_release="$optarg" | ||
16 | ;; | ||
17 | + --disable-nptl) nptl="no" | ||
18 | + ;; | ||
19 | esac | ||
20 | done | ||
21 | |||
22 | @@ -438,6 +441,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 | @@ -556,6 +576,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 | @@ -864,6 +885,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-05-26 18:10:52.000000000 +0100 | ||
72 | +++ qemu/exec-all.h 2006-08-14 22:37:29.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 2005-04-27 21:11:21.000000000 +0100 | ||
241 | +++ qemu/linux-user/arm/syscall.h 2006-08-14 22:37:29.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-05-26 18:11:01.000000000 +0100 | ||
256 | +++ qemu/linux-user/main.c 2006-08-14 22:37:29.000000000 +0100 | ||
257 | @@ -331,6 +331,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 | @@ -387,10 +431,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 | @@ -401,14 +443,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 | @@ -447,6 +509,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 | @@ -1649,6 +1715,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-05-26 18:11:01.000000000 +0100 | ||
389 | +++ qemu/linux-user/qemu.h 2006-08-14 22:37:29.000000000 +0100 | ||
390 | @@ -76,6 +76,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 | uint8_t stack[0]; | ||
398 | } __attribute__((aligned(16))) TaskState; | ||
399 | |||
400 | Index: qemu/linux-user/syscall.c | ||
401 | =================================================================== | ||
402 | --- qemu.orig/linux-user/syscall.c 2006-05-26 18:11:01.000000000 +0100 | ||
403 | +++ qemu/linux-user/syscall.c 2006-08-14 22:44:47.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 | @@ -1569,20 +1578,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 | @@ -1627,16 +1654,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 | @@ -1880,7 +1951,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 | @@ -2836,7 +2907,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 | @@ -3186,7 +3258,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 | @@ -3681,4 +3754,3 @@ | ||
558 | #endif | ||
559 | return ret; | ||
560 | } | ||
561 | - | ||
562 | Index: qemu/target-arm/cpu.h | ||
563 | =================================================================== | ||
564 | --- qemu.orig/target-arm/cpu.h 2006-02-20 00:33:36.000000000 +0000 | ||
565 | +++ qemu/target-arm/cpu.h 2006-08-14 22:39:35.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 2005-11-26 10:38:39.000000000 +0000 | ||
616 | +++ qemu/target-arm/exec.h 2006-08-14 22:37:29.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-02-20 00:33:36.000000000 +0000 | ||
629 | +++ qemu/target-arm/op.c 2006-08-14 22:37:29.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-05-26 18:11:04.000000000 +0100 | ||
646 | +++ qemu/target-arm/translate.c 2006-08-14 22:37:29.000000000 +0100 | ||
647 | @@ -2377,6 +2377,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 | @@ -2411,6 +2412,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-14 22:37:29.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 */ | ||
diff --git a/meta/packages/qemu/qemu_cvs.bb b/meta/packages/qemu/qemu_cvs.bb index 5697e69578..3675be4a72 100644 --- a/meta/packages/qemu/qemu_cvs.bb +++ b/meta/packages/qemu/qemu_cvs.bb | |||
@@ -1,10 +1,11 @@ | |||
1 | LICENSE = "GPL" | 1 | LICENSE = "GPL" |
2 | PV = "0.8.0+cvs${SRCDATE}" | 2 | PV = "0.8.0+cvs${SRCDATE}" |
3 | PR = "r1" | 3 | PR = "r2" |
4 | 4 | ||
5 | SRC_URI = "cvs://anonymous@cvs.savannah.nongnu.org/sources/qemu;method=pserver;rsh=ssh;module=qemu \ | 5 | SRC_URI = "cvs://anonymous@cvs.savannah.nongnu.org/sources/qemu;method=pserver;rsh=ssh;module=qemu \ |
6 | file://configure.patch;patch=1 \ | 6 | file://configure.patch;patch=1 \ |
7 | file://mouse_fix-r0.patch;patch=1 \ | 7 | file://mouse_fix-r0.patch;patch=1 \ |
8 | file://arm_nptl.patch;patch=1 \ | ||
8 | file://pl110_rgb-r0.patch;patch=1" | 9 | file://pl110_rgb-r0.patch;patch=1" |
9 | 10 | ||
10 | S = "${WORKDIR}/qemu" | 11 | S = "${WORKDIR}/qemu" |