diff options
| author | Richard Purdie <richard@openedhand.com> | 2007-06-29 11:10:33 +0000 |
|---|---|---|
| committer | Richard Purdie <richard@openedhand.com> | 2007-06-29 11:10:33 +0000 |
| commit | f1edd3b119e65256c90230f7d2adb03d52c16dc3 (patch) | |
| tree | d8563728d668efe0321dee42824664ac518a7815 | |
| parent | 13e87f0a9638168eb7cf5a705a472a1a99113aa2 (diff) | |
| download | poky-f1edd3b119e65256c90230f7d2adb03d52c16dc3.tar.gz | |
qemu: Resolve various segfault issues
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@2060 311d38ba-8fff-0310-9ca6-ca027cbcb966
| -rw-r--r-- | meta/packages/qemu/files/31_syscalls.patch | 13 | ||||
| -rw-r--r-- | meta/packages/qemu/files/fix_segfault.patch | 46 | ||||
| -rw-r--r-- | meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch | 294 | ||||
| -rw-r--r-- | meta/packages/qemu/files/qemu-0.9.0-nptl.patch (renamed from meta/packages/qemu/files/94-oh-arm-nptl.patch) | 504 | ||||
| -rw-r--r-- | meta/packages/qemu/qemu_cvs.bb | 7 |
5 files changed, 593 insertions, 271 deletions
diff --git a/meta/packages/qemu/files/31_syscalls.patch b/meta/packages/qemu/files/31_syscalls.patch index e7a1b338f3..3878079f19 100644 --- a/meta/packages/qemu/files/31_syscalls.patch +++ b/meta/packages/qemu/files/31_syscalls.patch | |||
| @@ -47,16 +47,3 @@ Index: linux-user/syscall.c | |||
| 47 | #endif | 47 | #endif |
| 48 | #ifdef TARGET_NR_setxattr | 48 | #ifdef TARGET_NR_setxattr |
| 49 | case TARGET_NR_setxattr: | 49 | case TARGET_NR_setxattr: |
| 50 | Index: Makefile.target | ||
| 51 | =================================================================== | ||
| 52 | --- Makefile.target.orig 2007-06-13 11:51:52.000000000 +0100 | ||
| 53 | +++ Makefile.target 2007-06-13 11:51:54.000000000 +0100 | ||
| 54 | @@ -215,7 +215,7 @@ OP_LDFLAGS+=$(OS_LDFLAGS) $(ARCH_LDFLAGS | ||
| 55 | ######################################################### | ||
| 56 | |||
| 57 | CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE | ||
| 58 | -LIBS+=-lm | ||
| 59 | +LIBS+=-lm -lrt | ||
| 60 | ifndef CONFIG_USER_ONLY | ||
| 61 | LIBS+=-lz | ||
| 62 | endif | ||
diff --git a/meta/packages/qemu/files/fix_segfault.patch b/meta/packages/qemu/files/fix_segfault.patch new file mode 100644 index 0000000000..976c75cd60 --- /dev/null +++ b/meta/packages/qemu/files/fix_segfault.patch | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | Index: qemu/Makefile.target | ||
| 2 | =================================================================== | ||
| 3 | --- qemu.orig/Makefile.target 2007-06-29 10:57:58.000000000 +0000 | ||
| 4 | +++ qemu/Makefile.target 2007-06-29 10:58:01.000000000 +0000 | ||
| 5 | @@ -241,7 +241,6 @@ | ||
| 6 | ifdef CONFIG_LINUX_USER | ||
| 7 | OBJS= main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o \ | ||
| 8 | elfload.o linuxload.o | ||
| 9 | -LIBS+= $(AIOLIBS) | ||
| 10 | ifdef TARGET_HAS_BFLT | ||
| 11 | OBJS+= flatload.o | ||
| 12 | endif | ||
| 13 | Index: qemu/linux-user/syscall.c | ||
| 14 | =================================================================== | ||
| 15 | --- qemu.orig/linux-user/syscall.c 2007-06-29 10:58:01.000000000 +0000 | ||
| 16 | +++ qemu/linux-user/syscall.c 2007-06-29 10:58:30.000000000 +0000 | ||
| 17 | @@ -4872,29 +4872,6 @@ | ||
| 18 | goto unimplemented_nowarn; | ||
| 19 | #endif | ||
| 20 | |||
| 21 | -#ifdef TARGET_NR_clock_gettime | ||
| 22 | - case TARGET_NR_clock_gettime: | ||
| 23 | - { | ||
| 24 | - struct timespec ts; | ||
| 25 | - ret = get_errno(clock_gettime(arg1, &ts)); | ||
| 26 | - if (!is_error(ret)) { | ||
| 27 | - host_to_target_timespec(arg2, &ts); | ||
| 28 | - } | ||
| 29 | - break; | ||
| 30 | - } | ||
| 31 | -#endif | ||
| 32 | -#ifdef TARGET_NR_clock_getres | ||
| 33 | - case TARGET_NR_clock_getres: | ||
| 34 | - { | ||
| 35 | - struct timespec ts; | ||
| 36 | - ret = get_errno(clock_getres(arg1, &ts)); | ||
| 37 | - if (!is_error(ret)) { | ||
| 38 | - host_to_target_timespec(arg2, &ts); | ||
| 39 | - } | ||
| 40 | - break; | ||
| 41 | - } | ||
| 42 | -#endif | ||
| 43 | - | ||
| 44 | default: | ||
| 45 | unimplemented: | ||
| 46 | gemu_log("qemu: Unsupported syscall: %d\n", num); | ||
diff --git a/meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch b/meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch new file mode 100644 index 0000000000..869acba2cf --- /dev/null +++ b/meta/packages/qemu/files/qemu-0.9.0-nptl-update.patch | |||
| @@ -0,0 +1,294 @@ | |||
| 1 | Index: qemu/linux-user/main.c | ||
| 2 | =================================================================== | ||
| 3 | --- qemu.orig/linux-user/main.c 2007-06-29 10:47:58.000000000 +0000 | ||
| 4 | +++ qemu/linux-user/main.c 2007-06-29 10:47:58.000000000 +0000 | ||
| 5 | @@ -156,7 +156,7 @@ | ||
| 6 | p[1] = tswapl(e2); | ||
| 7 | } | ||
| 8 | |||
| 9 | -uint64_t gdt_table[6]; | ||
| 10 | +uint64_t gdt_table[9]; | ||
| 11 | uint64_t idt_table[256]; | ||
| 12 | |||
| 13 | /* only dpl matters as we do only user space emulation */ | ||
| 14 | @@ -1768,7 +1768,11 @@ | ||
| 15 | int optind; | ||
| 16 | const char *r; | ||
| 17 | int gdbstub_port = 0; | ||
| 18 | - | ||
| 19 | + char *assume_kernel = getenv("QEMU_ASSUME_KERNEL"); | ||
| 20 | + | ||
| 21 | + if (assume_kernel) | ||
| 22 | + setenv("LD_ASSUME_KERNEL", assume_kernel, 1); | ||
| 23 | + | ||
| 24 | if (argc <= 1) | ||
| 25 | usage(); | ||
| 26 | |||
| 27 | Index: qemu/linux-user/syscall.c | ||
| 28 | =================================================================== | ||
| 29 | --- qemu.orig/linux-user/syscall.c 2007-06-29 10:47:58.000000000 +0000 | ||
| 30 | +++ qemu/linux-user/syscall.c 2007-06-29 10:53:44.000000000 +0000 | ||
| 31 | @@ -60,6 +60,7 @@ | ||
| 32 | #define tchars host_tchars /* same as target */ | ||
| 33 | #define ltchars host_ltchars /* same as target */ | ||
| 34 | |||
| 35 | +#include <linux/futex.h> | ||
| 36 | #include <linux/termios.h> | ||
| 37 | #include <linux/unistd.h> | ||
| 38 | #include <linux/utsname.h> | ||
| 39 | @@ -2122,6 +2123,80 @@ | ||
| 40 | return ret; | ||
| 41 | } | ||
| 42 | |||
| 43 | +int do_set_thread_area(CPUX86State *env, target_ulong ptr) | ||
| 44 | +{ | ||
| 45 | + uint64_t *gdt_table = g2h(env->gdt.base); | ||
| 46 | + struct target_modify_ldt_ldt_s ldt_info; | ||
| 47 | + struct target_modify_ldt_ldt_s *target_ldt_info; | ||
| 48 | + int seg_32bit, contents, read_exec_only, limit_in_pages; | ||
| 49 | + int seg_not_present, useable; | ||
| 50 | + uint32_t *lp, entry_1, entry_2; | ||
| 51 | + int i; | ||
| 52 | + | ||
| 53 | + lock_user_struct(target_ldt_info, ptr, 1); | ||
| 54 | + ldt_info.entry_number = tswap32(target_ldt_info->entry_number); | ||
| 55 | + ldt_info.base_addr = tswapl(target_ldt_info->base_addr); | ||
| 56 | + ldt_info.limit = tswap32(target_ldt_info->limit); | ||
| 57 | + ldt_info.flags = tswap32(target_ldt_info->flags); | ||
| 58 | + if (ldt_info.entry_number == -1) { | ||
| 59 | + for (i=6; i<8; i++) | ||
| 60 | + if (gdt_table[i] == 0) { | ||
| 61 | + ldt_info.entry_number = i; | ||
| 62 | + target_ldt_info->entry_number = tswap32(i); | ||
| 63 | + break; | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + unlock_user_struct(target_ldt_info, ptr, 0); | ||
| 67 | + | ||
| 68 | + if (ldt_info.entry_number < 6 || ldt_info.entry_number > 8) | ||
| 69 | + return -EINVAL; | ||
| 70 | + seg_32bit = ldt_info.flags & 1; | ||
| 71 | + contents = (ldt_info.flags >> 1) & 3; | ||
| 72 | + read_exec_only = (ldt_info.flags >> 3) & 1; | ||
| 73 | + limit_in_pages = (ldt_info.flags >> 4) & 1; | ||
| 74 | + seg_not_present = (ldt_info.flags >> 5) & 1; | ||
| 75 | + useable = (ldt_info.flags >> 6) & 1; | ||
| 76 | + | ||
| 77 | + if (contents == 3) { | ||
| 78 | + if (seg_not_present == 0) | ||
| 79 | + return -EINVAL; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + /* NOTE: same code as Linux kernel */ | ||
| 83 | + /* Allow LDTs to be cleared by the user. */ | ||
| 84 | + if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { | ||
| 85 | + if ((contents == 0 && | ||
| 86 | + read_exec_only == 1 && | ||
| 87 | + seg_32bit == 0 && | ||
| 88 | + limit_in_pages == 0 && | ||
| 89 | + seg_not_present == 1 && | ||
| 90 | + useable == 0 )) { | ||
| 91 | + entry_1 = 0; | ||
| 92 | + entry_2 = 0; | ||
| 93 | + goto install; | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | | ||
| 98 | + (ldt_info.limit & 0x0ffff); | ||
| 99 | + entry_2 = (ldt_info.base_addr & 0xff000000) | | ||
| 100 | + ((ldt_info.base_addr & 0x00ff0000) >> 16) | | ||
| 101 | + (ldt_info.limit & 0xf0000) | | ||
| 102 | + ((read_exec_only ^ 1) << 9) | | ||
| 103 | + (contents << 10) | | ||
| 104 | + ((seg_not_present ^ 1) << 15) | | ||
| 105 | + (seg_32bit << 22) | | ||
| 106 | + (limit_in_pages << 23) | | ||
| 107 | + (useable << 20) | | ||
| 108 | + 0x7000; | ||
| 109 | + | ||
| 110 | + /* Install the new entry ... */ | ||
| 111 | +install: | ||
| 112 | + lp = (uint32_t *)(gdt_table + ldt_info.entry_number); | ||
| 113 | + lp[0] = tswap32(entry_1); | ||
| 114 | + lp[1] = tswap32(entry_2); | ||
| 115 | + return 0; | ||
| 116 | +} | ||
| 117 | #endif /* defined(TARGET_I386) */ | ||
| 118 | |||
| 119 | /* this stack is the equivalent of the kernel stack associated with a | ||
| 120 | @@ -2154,15 +2229,20 @@ | ||
| 121 | TaskState *ts; | ||
| 122 | uint8_t *new_stack; | ||
| 123 | CPUState *new_env; | ||
| 124 | +#if defined(TARGET_I386) | ||
| 125 | + uint64_t *new_gdt_table; | ||
| 126 | +#endif | ||
| 127 | #ifdef USE_NPTL | ||
| 128 | unsigned int nptl_flags; | ||
| 129 | |||
| 130 | if (flags & CLONE_PARENT_SETTID) | ||
| 131 | *parent_tidptr = gettid(); | ||
| 132 | #endif | ||
| 133 | - | ||
| 134 | + | ||
| 135 | if (flags & CLONE_VM) { | ||
| 136 | ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); | ||
| 137 | + if (!ts) | ||
| 138 | + return -ENOMEM; | ||
| 139 | memset(ts, 0, sizeof(TaskState)); | ||
| 140 | new_stack = ts->stack; | ||
| 141 | ts->used = 1; | ||
| 142 | @@ -2174,6 +2254,29 @@ | ||
| 143 | #if defined(TARGET_I386) | ||
| 144 | if (!newsp) | ||
| 145 | newsp = env->regs[R_ESP]; | ||
| 146 | + new_gdt_table = malloc(9 * 8); | ||
| 147 | + if (!new_gdt_table) { | ||
| 148 | + free(new_env); | ||
| 149 | + return -ENOMEM; | ||
| 150 | + } | ||
| 151 | + /* Copy main GDT table from parent, but clear TLS entries */ | ||
| 152 | + memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); | ||
| 153 | + memset(&new_gdt_table[6], 0, 3 * 8); | ||
| 154 | + new_env->gdt.base = h2g(new_gdt_table); | ||
| 155 | + if (flags & 0x00080000 /* CLONE_SETTLS */) { | ||
| 156 | + ret = do_set_thread_area(new_env, new_env->regs[R_ESI]); | ||
| 157 | + if (ret) { | ||
| 158 | + free(new_gdt_table); | ||
| 159 | + free(new_env); | ||
| 160 | + return ret; | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | + cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]); | ||
| 164 | + cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]); | ||
| 165 | + cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]); | ||
| 166 | + cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]); | ||
| 167 | + cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]); | ||
| 168 | + cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]); | ||
| 169 | new_env->regs[R_ESP] = newsp; | ||
| 170 | new_env->regs[R_EAX] = 0; | ||
| 171 | #elif defined(TARGET_ARM) | ||
| 172 | @@ -2517,6 +2620,68 @@ | ||
| 173 | unlock_user_struct(target_ts, target_addr, 1); | ||
| 174 | } | ||
| 175 | |||
| 176 | +static long do_futex(target_ulong uaddr, int op, uint32_t val, | ||
| 177 | + target_ulong utime, target_ulong uaddr2, | ||
| 178 | + uint32_t val3) | ||
| 179 | +{ | ||
| 180 | + struct timespec host_utime; | ||
| 181 | + unsigned long val2 = utime; | ||
| 182 | + | ||
| 183 | + if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { | ||
| 184 | + target_to_host_timespec(&host_utime, utime); | ||
| 185 | + val2 = (unsigned long)&host_utime; | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | +#ifdef BSWAP_NEEDED | ||
| 189 | + switch(op) { | ||
| 190 | + case FUTEX_CMP_REQUEUE: | ||
| 191 | + val3 = tswap32(val3); | ||
| 192 | + case FUTEX_REQUEUE: | ||
| 193 | + val2 = tswap32(val2); | ||
| 194 | + case FUTEX_WAIT: | ||
| 195 | + case FUTEX_WAKE: | ||
| 196 | + val = tswap32(val); | ||
| 197 | + case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ | ||
| 198 | + case FUTEX_UNLOCK_PI: | ||
| 199 | + break; | ||
| 200 | + default: | ||
| 201 | + gemu_log("qemu: Unsupported futex op %d\n", op); | ||
| 202 | + return -ENOSYS; | ||
| 203 | + } | ||
| 204 | +#if 0 /* No, it's worse than this */ | ||
| 205 | + if (op == FUTEX_WAKE_OP) { | ||
| 206 | + /* Need to munge the secondary operation (val3) */ | ||
| 207 | + val3 = tswap32(val3); | ||
| 208 | + int op2 = (val3 >> 28) & 7; | ||
| 209 | + int cmp = (val3 >> 24) & 15; | ||
| 210 | + int oparg = (val3 << 8) >> 20; | ||
| 211 | + int cmparg = (val3 << 20) >> 20; | ||
| 212 | + int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); | ||
| 213 | + | ||
| 214 | + if (shift) | ||
| 215 | + oparg = (oparg & 7) + 24 - (oparg & 24); | ||
| 216 | + else oparg = | ||
| 217 | + if (op2 == FUTEX_OP_ADD) { | ||
| 218 | + gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n"); | ||
| 219 | + return -ENOSYS; | ||
| 220 | + } | ||
| 221 | + if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE || | ||
| 222 | + cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) { | ||
| 223 | + gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg); | ||
| 224 | + return -ENOSYS; | ||
| 225 | + } | ||
| 226 | + val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg; | ||
| 227 | + } | ||
| 228 | +#endif | ||
| 229 | +#endif | ||
| 230 | + return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); | ||
| 231 | +} | ||
| 232 | + | ||
| 233 | +int do_set_tid_address(target_ulong tidptr) | ||
| 234 | +{ | ||
| 235 | + return syscall(__NR_set_tid_address, g2h(tidptr)); | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | ||
| 239 | long arg4, long arg5, long arg6) | ||
| 240 | { | ||
| 241 | @@ -2534,7 +2699,7 @@ | ||
| 242 | _mcleanup(); | ||
| 243 | #endif | ||
| 244 | gdb_exit(cpu_env, arg1); | ||
| 245 | - /* XXX: should free thread stack and CPU env */ | ||
| 246 | + /* XXX: should free thread stack, GDT and CPU env */ | ||
| 247 | _exit(arg1); | ||
| 248 | ret = 0; /* avoid warning */ | ||
| 249 | break; | ||
| 250 | @@ -4642,6 +4807,9 @@ | ||
| 251 | ((CPUMIPSState *) cpu_env)->tls_value = arg1; | ||
| 252 | ret = 0; | ||
| 253 | break; | ||
| 254 | +#elif TARGET_i386 | ||
| 255 | + ret = get_errno(do_set_thread_area(cpu_env, arg1)); | ||
| 256 | + break; | ||
| 257 | #else | ||
| 258 | goto unimplemented_nowarn; | ||
| 259 | #endif | ||
| 260 | @@ -4655,6 +4823,21 @@ | ||
| 261 | goto unimplemented_nowarn; | ||
| 262 | #endif | ||
| 263 | |||
| 264 | +#ifdef TARGET_NR_futex | ||
| 265 | + case TARGET_NR_futex: | ||
| 266 | + ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6)); | ||
| 267 | + break; | ||
| 268 | +#endif | ||
| 269 | +#ifdef TARGET_NR_set_tid_address | ||
| 270 | + case TARGET_NR_set_tid_address: | ||
| 271 | + ret = get_errno(do_set_tid_address(arg1)); | ||
| 272 | + break; | ||
| 273 | +#endif | ||
| 274 | +#ifdef TARGET_NR_set_robust_list | ||
| 275 | + case TARGET_NR_set_robust_list: | ||
| 276 | + goto unimplemented_nowarn; | ||
| 277 | +#endif | ||
| 278 | + | ||
| 279 | #ifdef TARGET_NR_clock_gettime | ||
| 280 | case TARGET_NR_clock_gettime: | ||
| 281 | { | ||
| 282 | @@ -4678,12 +4861,6 @@ | ||
| 283 | } | ||
| 284 | #endif | ||
| 285 | |||
| 286 | -#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) | ||
| 287 | - case TARGET_NR_set_tid_address: | ||
| 288 | - ret = get_errno(set_tid_address((int *) arg1)); | ||
| 289 | - break; | ||
| 290 | -#endif | ||
| 291 | - | ||
| 292 | default: | ||
| 293 | unimplemented: | ||
| 294 | gemu_log("qemu: Unsupported syscall: %d\n", num); | ||
diff --git a/meta/packages/qemu/files/94-oh-arm-nptl.patch b/meta/packages/qemu/files/qemu-0.9.0-nptl.patch index 37d7171983..fc7b0cfa4b 100644 --- a/meta/packages/qemu/files/94-oh-arm-nptl.patch +++ b/meta/packages/qemu/files/qemu-0.9.0-nptl.patch | |||
| @@ -1,22 +1,24 @@ | |||
| 1 | --- | 1 | These are Paul Brook's patches to QEMU-0.8.2 to enable the running of single |
| 2 | configure | 29 ++++++ | 2 | ARM binaries under QEMU's user-emulation mode. Without them, QEMU-0.8.1 |
| 3 | exec-all.h | 165 -------------------------------------- | 3 | immediately dies saying: |
| 4 | linux-user/arm/syscall.h | 4 | 4 | Error: f0005 |
| 5 | linux-user/main.c | 94 ++++++++++++++++++--- | 5 | qemu: uncaught target signal 6 (Aborted) - exiting |
| 6 | linux-user/qemu.h | 3 | 6 | while qemu-0.8.2 dies saying: |
| 7 | linux-user/syscall.c | 90 ++++++++++++++++++-- | 7 | qemu: Unsupported syscall: 983045 |
| 8 | qemu_spinlock.h | 204 +++++++++++++++++++++++++++++++++++++++++++++++ | 8 | cannot set up thread-local storage: unknown error |
| 9 | target-arm/cpu.h | 19 ++++ | 9 | |
| 10 | target-arm/exec.h | 2 | 10 | This file is a rediffing of the patches visible at |
| 11 | target-arm/op.c | 6 + | 11 | https://nowt.dyndns.org/patch.qemu_nptl on 27 Sept 2006 |
| 12 | target-arm/translate.c | 10 ++ | 12 | which "patch" fails to apply automatically. |
| 13 | 11 files changed, 437 insertions(+), 189 deletions(-) | 13 | See also http://lists.gnu.org/archive/html/qemu-devel/2006-09/msg00194.html |
| 14 | |||
| 15 | Martin Guy, 27 Sept 2006 | ||
| 14 | 16 | ||
| 15 | Index: qemu/configure | 17 | Index: qemu/configure |
| 16 | =================================================================== | 18 | =================================================================== |
| 17 | --- qemu.orig/configure 2007-06-13 11:51:56.000000000 +0100 | 19 | --- qemu.orig/configure 2007-06-29 10:47:39.000000000 +0000 |
| 18 | +++ qemu/configure 2007-06-13 11:51:57.000000000 +0100 | 20 | +++ qemu/configure 2007-06-29 10:47:58.000000000 +0000 |
| 19 | @@ -101,6 +101,7 @@ linux_user="no" | 21 | @@ -101,6 +101,7 @@ |
| 20 | darwin_user="no" | 22 | darwin_user="no" |
| 21 | build_docs="no" | 23 | build_docs="no" |
| 22 | uname_release="" | 24 | uname_release="" |
| @@ -24,7 +26,7 @@ Index: qemu/configure | |||
| 24 | 26 | ||
| 25 | # OS specific | 27 | # OS specific |
| 26 | targetos=`uname -s` | 28 | targetos=`uname -s` |
| 27 | @@ -287,6 +288,8 @@ for opt do | 29 | @@ -281,6 +282,8 @@ |
| 28 | *) echo "undefined SPARC architecture. Exiting";exit 1;; | 30 | *) echo "undefined SPARC architecture. Exiting";exit 1;; |
| 29 | esac | 31 | esac |
| 30 | ;; | 32 | ;; |
| @@ -33,7 +35,15 @@ Index: qemu/configure | |||
| 33 | esac | 35 | esac |
| 34 | done | 36 | done |
| 35 | 37 | ||
| 36 | @@ -530,6 +533,23 @@ int main(void) { | 38 | @@ -355,6 +358,7 @@ |
| 39 | echo " --disable-linux-user disable all linux usermode emulation targets" | ||
| 40 | echo " --enable-darwin-user enable all darwin usermode emulation targets" | ||
| 41 | echo " --disable-darwin-user disable all darwin usermode emulation targets" | ||
| 42 | +echo " --disable-nptl disable usermode NPTL guest support" | ||
| 43 | echo " --fmod-lib path to FMOD library" | ||
| 44 | echo " --fmod-inc path to FMOD includes" | ||
| 45 | echo " --enable-uname-release=R Return R for uname -r in usermode emulation" | ||
| 46 | @@ -524,6 +528,23 @@ | ||
| 37 | } | 47 | } |
| 38 | EOF | 48 | EOF |
| 39 | 49 | ||
| @@ -57,15 +67,15 @@ Index: qemu/configure | |||
| 57 | ########################################## | 67 | ########################################## |
| 58 | # SDL probe | 68 | # SDL probe |
| 59 | 69 | ||
| 60 | @@ -681,6 +701,7 @@ if test -n "$sparc_cpu"; then | 70 | @@ -678,6 +699,7 @@ |
| 61 | echo "Target Sparc Arch $sparc_cpu" | ||
| 62 | fi | ||
| 63 | echo "kqemu support $kqemu" | ||
| 64 | +echo "NPTL support $nptl" | ||
| 65 | echo "Documentation $build_docs" | 71 | echo "Documentation $build_docs" |
| 66 | [ ! -z "$uname_release" ] && \ | 72 | [ ! -z "$uname_release" ] && \ |
| 67 | echo "uname -r $uname_release" | 73 | echo "uname -r $uname_release" |
| 68 | @@ -1063,6 +1084,14 @@ if test "$target_user_only" = "no"; then | 74 | +echo "NPTL support $nptl" |
| 75 | |||
| 76 | if test $sdl_too_old = "yes"; then | ||
| 77 | echo "-> Your SDL version is too old - please upgrade to have SDL support" | ||
| 78 | @@ -1057,6 +1079,14 @@ | ||
| 69 | echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak | 79 | echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak |
| 70 | fi | 80 | fi |
| 71 | fi | 81 | fi |
| @@ -82,9 +92,9 @@ Index: qemu/configure | |||
| 82 | if test "$cocoa" = "yes" ; then | 92 | if test "$cocoa" = "yes" ; then |
| 83 | Index: qemu/exec-all.h | 93 | Index: qemu/exec-all.h |
| 84 | =================================================================== | 94 | =================================================================== |
| 85 | --- qemu.orig/exec-all.h 2007-06-13 11:48:22.000000000 +0100 | 95 | --- qemu.orig/exec-all.h 2007-06-29 10:47:39.000000000 +0000 |
| 86 | +++ qemu/exec-all.h 2007-06-13 11:51:57.000000000 +0100 | 96 | +++ qemu/exec-all.h 2007-06-29 10:47:58.000000000 +0000 |
| 87 | @@ -360,170 +360,7 @@ extern CPUWriteMemoryFunc *io_mem_write[ | 97 | @@ -360,170 +360,7 @@ |
| 88 | extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; | 98 | extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; |
| 89 | extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; | 99 | extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; |
| 90 | 100 | ||
| @@ -258,9 +268,9 @@ Index: qemu/exec-all.h | |||
| 258 | 268 | ||
| 259 | Index: qemu/linux-user/arm/syscall.h | 269 | Index: qemu/linux-user/arm/syscall.h |
| 260 | =================================================================== | 270 | =================================================================== |
| 261 | --- qemu.orig/linux-user/arm/syscall.h 2007-06-13 11:48:22.000000000 +0100 | 271 | --- qemu.orig/linux-user/arm/syscall.h 2007-06-29 10:47:39.000000000 +0000 |
| 262 | +++ qemu/linux-user/arm/syscall.h 2007-06-13 11:51:57.000000000 +0100 | 272 | +++ qemu/linux-user/arm/syscall.h 2007-06-29 10:47:58.000000000 +0000 |
| 263 | @@ -28,7 +28,9 @@ struct target_pt_regs { | 273 | @@ -28,7 +28,9 @@ |
| 264 | #define ARM_SYSCALL_BASE 0x900000 | 274 | #define ARM_SYSCALL_BASE 0x900000 |
| 265 | #define ARM_THUMB_SYSCALL 0 | 275 | #define ARM_THUMB_SYSCALL 0 |
| 266 | 276 | ||
| @@ -273,9 +283,9 @@ Index: qemu/linux-user/arm/syscall.h | |||
| 273 | #define ARM_NR_thumb_semihosting 0xAB | 283 | #define ARM_NR_thumb_semihosting 0xAB |
| 274 | Index: qemu/linux-user/main.c | 284 | Index: qemu/linux-user/main.c |
| 275 | =================================================================== | 285 | =================================================================== |
| 276 | --- qemu.orig/linux-user/main.c 2007-06-13 11:51:55.000000000 +0100 | 286 | --- qemu.orig/linux-user/main.c 2007-06-29 10:47:39.000000000 +0000 |
| 277 | +++ qemu/linux-user/main.c 2007-06-13 11:51:57.000000000 +0100 | 287 | +++ qemu/linux-user/main.c 2007-06-29 10:53:47.000000000 +0000 |
| 278 | @@ -325,6 +325,50 @@ static void arm_cache_flush(target_ulong | 288 | @@ -325,6 +325,50 @@ |
| 279 | } | 289 | } |
| 280 | } | 290 | } |
| 281 | 291 | ||
| @@ -326,7 +336,7 @@ Index: qemu/linux-user/main.c | |||
| 326 | void cpu_loop(CPUARMState *env) | 336 | void cpu_loop(CPUARMState *env) |
| 327 | { | 337 | { |
| 328 | int trapnr; | 338 | int trapnr; |
| 329 | @@ -430,10 +474,8 @@ void cpu_loop(CPUARMState *env) | 339 | @@ -381,10 +425,8 @@ |
| 330 | } | 340 | } |
| 331 | } | 341 | } |
| 332 | 342 | ||
| @@ -339,7 +349,7 @@ Index: qemu/linux-user/main.c | |||
| 339 | env->regs[0] = do_arm_semihosting (env); | 349 | env->regs[0] = do_arm_semihosting (env); |
| 340 | } else if (n == 0 || n >= ARM_SYSCALL_BASE | 350 | } else if (n == 0 || n >= ARM_SYSCALL_BASE |
| 341 | || (env->thumb && n == ARM_THUMB_SYSCALL)) { | 351 | || (env->thumb && n == ARM_THUMB_SYSCALL)) { |
| 342 | @@ -444,14 +486,34 @@ void cpu_loop(CPUARMState *env) | 352 | @@ -395,14 +437,34 @@ |
| 343 | n -= ARM_SYSCALL_BASE; | 353 | n -= ARM_SYSCALL_BASE; |
| 344 | env->eabi = 0; | 354 | env->eabi = 0; |
| 345 | } | 355 | } |
| @@ -382,7 +392,7 @@ Index: qemu/linux-user/main.c | |||
| 382 | } else { | 392 | } else { |
| 383 | goto error; | 393 | goto error; |
| 384 | } | 394 | } |
| 385 | @@ -490,6 +552,10 @@ void cpu_loop(CPUARMState *env) | 395 | @@ -441,6 +503,10 @@ |
| 386 | } | 396 | } |
| 387 | } | 397 | } |
| 388 | break; | 398 | break; |
| @@ -393,7 +403,7 @@ Index: qemu/linux-user/main.c | |||
| 393 | default: | 403 | default: |
| 394 | error: | 404 | error: |
| 395 | fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", | 405 | fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
| 396 | @@ -2096,6 +2162,10 @@ int main(int argc, char **argv) | 406 | @@ -2047,6 +2113,10 @@ |
| 397 | ts->heap_base = info->brk; | 407 | ts->heap_base = info->brk; |
| 398 | /* This will be filled in on the first SYS_HEAPINFO call. */ | 408 | /* This will be filled in on the first SYS_HEAPINFO call. */ |
| 399 | ts->heap_limit = 0; | 409 | ts->heap_limit = 0; |
| @@ -406,23 +416,23 @@ Index: qemu/linux-user/main.c | |||
| 406 | if (gdbstub_port) { | 416 | if (gdbstub_port) { |
| 407 | Index: qemu/linux-user/qemu.h | 417 | Index: qemu/linux-user/qemu.h |
| 408 | =================================================================== | 418 | =================================================================== |
| 409 | --- qemu.orig/linux-user/qemu.h 2007-06-13 11:48:22.000000000 +0100 | 419 | --- qemu.orig/linux-user/qemu.h 2007-06-29 10:47:39.000000000 +0000 |
| 410 | +++ qemu/linux-user/qemu.h 2007-06-13 11:51:57.000000000 +0100 | 420 | +++ qemu/linux-user/qemu.h 2007-06-29 10:47:58.000000000 +0000 |
| 411 | @@ -81,6 +81,9 @@ typedef struct TaskState { | 421 | @@ -80,6 +80,9 @@ |
| 422 | uint32_t heap_base; | ||
| 412 | uint32_t heap_limit; | 423 | uint32_t heap_limit; |
| 413 | #endif | 424 | #endif |
| 414 | int used; /* non zero if used */ | ||
| 415 | +#ifdef USE_NPTL | 425 | +#ifdef USE_NPTL |
| 416 | + uint32_t *child_tidptr; | 426 | + uint32_t *child_tidptr; |
| 417 | +#endif | 427 | +#endif |
| 428 | int used; /* non zero if used */ | ||
| 418 | struct image_info *info; | 429 | struct image_info *info; |
| 419 | uint8_t stack[0]; | 430 | uint8_t stack[0]; |
| 420 | } __attribute__((aligned(16))) TaskState; | ||
| 421 | Index: qemu/linux-user/syscall.c | 431 | Index: qemu/linux-user/syscall.c |
| 422 | =================================================================== | 432 | =================================================================== |
| 423 | --- qemu.orig/linux-user/syscall.c 2007-06-13 11:51:55.000000000 +0100 | 433 | --- qemu.orig/linux-user/syscall.c 2007-06-29 10:47:39.000000000 +0000 |
| 424 | +++ qemu/linux-user/syscall.c 2007-06-13 11:51:57.000000000 +0100 | 434 | +++ qemu/linux-user/syscall.c 2007-06-29 10:53:47.000000000 +0000 |
| 425 | @@ -71,9 +71,18 @@ | 435 | @@ -70,9 +70,18 @@ |
| 426 | #include <linux/kd.h> | 436 | #include <linux/kd.h> |
| 427 | 437 | ||
| 428 | #include "qemu.h" | 438 | #include "qemu.h" |
| @@ -441,7 +451,7 @@ Index: qemu/linux-user/syscall.c | |||
| 441 | #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ | 451 | #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ |
| 442 | || defined(TARGET_M68K) || defined(TARGET_SH4) | 452 | || defined(TARGET_M68K) || defined(TARGET_SH4) |
| 443 | /* 16 bit uid wrappers emulation */ | 453 | /* 16 bit uid wrappers emulation */ |
| 444 | @@ -2121,20 +2130,38 @@ int do_modify_ldt(CPUX86State *env, int | 454 | @@ -2119,20 +2128,38 @@ |
| 445 | thread/process */ | 455 | thread/process */ |
| 446 | #define NEW_STACK_SIZE 8192 | 456 | #define NEW_STACK_SIZE 8192 |
| 447 | 457 | ||
| @@ -481,72 +491,76 @@ Index: qemu/linux-user/syscall.c | |||
| 481 | 491 | ||
| 482 | if (flags & CLONE_VM) { | 492 | if (flags & CLONE_VM) { |
| 483 | ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); | 493 | ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); |
| 484 | @@ -2197,16 +2224,60 @@ int do_fork(CPUState *env, unsigned int | 494 | @@ -2199,16 +2226,67 @@ |
| 485 | #error unsupported target CPU | 495 | #error unsupported target CPU |
| 486 | #endif | 496 | #endif |
| 487 | new_env->opaque = ts; | 497 | new_env->opaque = ts; |
| 488 | +#ifdef USE_NPTL | 498 | +#ifdef USE_NPTL |
| 489 | + nptl_flags = flags; | 499 | + nptl_flags = flags; |
| 490 | + flags &= ~CLONE_NPTL_FLAGS2; | 500 | + flags &= ~CLONE_NPTL_FLAGS2; |
| 491 | + if (nptl_flags & CLONE_CHILD_CLEARTID) { | 501 | + |
| 492 | + ts->child_tidptr = child_tidptr; | 502 | + if (nptl_flags & CLONE_CHILD_CLEARTID) { |
| 493 | + } | 503 | + ts->child_tidptr = child_tidptr; |
| 494 | + if (nptl_flags & CLONE_SETTLS) | 504 | + } |
| 495 | + cpu_set_tls (new_env, newtls); | 505 | + |
| 496 | + /* Grab the global cpu lock so that the thread setup appears | 506 | + if (nptl_flags & CLONE_SETTLS) |
| 497 | + atomic. */ | 507 | + cpu_set_tls (new_env, newtls); |
| 498 | + if (nptl_flags & CLONE_CHILD_SETTID) | 508 | + |
| 499 | + spin_lock(&nptl_lock); | 509 | + /* Grab the global cpu lock so that the thread setup appears |
| 510 | + atomic. */ | ||
| 511 | + if (nptl_flags & CLONE_CHILD_SETTID) | ||
| 512 | + spin_lock(&nptl_lock); | ||
| 513 | + | ||
| 500 | +#else | 514 | +#else |
| 501 | + if (flags & CLONE_NPTL_FLAGS2) | 515 | + if (flags & CLONE_NPTL_FLAGS2) |
| 502 | + return -EINVAL; | 516 | + return -EINVAL; |
| 503 | +#endif | 517 | +#endif |
| 504 | + | 518 | + |
| 519 | + if (CLONE_VFORK & flags) | ||
| 520 | + flags ^= CLONE_VM; | ||
| 505 | #ifdef __ia64__ | 521 | #ifdef __ia64__ |
| 506 | ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); | 522 | ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); |
| 507 | #else | 523 | #else |
| 508 | ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); | 524 | ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); |
| 509 | #endif | 525 | #endif |
| 510 | +#ifdef USE_NPTL | 526 | +#ifdef USE_NPTL |
| 511 | + if (ret != -1) { | 527 | + if (ret != -1) { |
| 512 | + if (nptl_flags & CLONE_CHILD_SETTID) | 528 | + if (nptl_flags & CLONE_CHILD_SETTID) |
| 513 | + *child_tidptr = ret; | 529 | + *child_tidptr = ret; |
| 514 | + } | 530 | + } |
| 515 | + /* Allow the child to continue. */ | 531 | + |
| 516 | + if (nptl_flags & CLONE_CHILD_SETTID) | 532 | + /* Allow the child to continue. */ |
| 517 | + spin_unlock(&nptl_lock); | 533 | + if (nptl_flags & CLONE_CHILD_SETTID) |
| 534 | + spin_unlock(&nptl_lock); | ||
| 518 | +#endif | 535 | +#endif |
| 519 | } else { | 536 | } else { |
| 520 | - /* if no CLONE_VM, we consider it is a fork */ | 537 | /* if no CLONE_VM, we consider it is a fork */ |
| 521 | - if ((flags & ~CSIGNAL) != 0) | 538 | - if ((flags & ~CSIGNAL) != 0) |
| 522 | - return -EINVAL; | 539 | + if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) |
| 523 | - ret = fork(); | 540 | return -EINVAL; |
| 524 | + /* if no CLONE_VM, we consider it is a fork */ | 541 | ret = fork(); |
| 525 | + if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) | ||
| 526 | + return -EINVAL; | ||
| 527 | + ret = fork(); | ||
| 528 | +#ifdef USE_NPTL | 542 | +#ifdef USE_NPTL |
| 529 | + /* There is a race condition here. The parent process could | 543 | + /* There is a race condition here. The parent process could |
| 530 | + theoretically read the TID in the child process before the child | 544 | + theoretically read the TID in the child process before the child |
| 531 | + tid is set. This would require using either ptrace | 545 | + tid is set. This would require using either ptrace |
| 532 | + (not implemented) or having *_tidptr to point at a shared memory | 546 | + (not implemented) or having *_tidptr to point at a shared memory |
| 533 | + mapping. We can't repeat the spinlock hack used above because | 547 | + mapping. We can't repeat the spinlock hack used above because |
| 534 | + the child process gets its own copy of the lock. */ | 548 | + the child process gets its own copy of the lock. */ |
| 535 | + if (ret == 0) { | 549 | + if (ret == 0) { |
| 536 | + /* Child Process. */ | 550 | + /* Child Process. */ |
| 537 | + if (flags & CLONE_CHILD_SETTID) | 551 | + if (flags & CLONE_CHILD_SETTID) |
| 538 | + *child_tidptr = gettid(); | 552 | + *child_tidptr = gettid(); |
| 539 | + ts = (TaskState *)env->opaque; | 553 | + ts = (TaskState *)env->opaque; |
| 540 | + if (flags & CLONE_CHILD_CLEARTID) | 554 | + if (flags & CLONE_CHILD_CLEARTID) |
| 541 | + ts->child_tidptr = child_tidptr; | 555 | + ts->child_tidptr = child_tidptr; |
| 542 | + if (flags & CLONE_SETTLS) | 556 | + if (flags & CLONE_SETTLS) |
| 543 | + cpu_set_tls (env, newtls); | 557 | + cpu_set_tls (env, newtls); |
| 544 | + } | 558 | + } |
| 545 | +#endif | 559 | +#endif |
| 546 | } | 560 | } |
| 547 | return ret; | 561 | return ret; |
| 548 | } | 562 | } |
| 549 | @@ -2483,7 +2554,7 @@ long do_syscall(void *cpu_env, int num, | 563 | @@ -2485,7 +2563,7 @@ |
| 550 | ret = do_brk(arg1); | 564 | ret = do_brk(arg1); |
| 551 | break; | 565 | break; |
| 552 | case TARGET_NR_fork: | 566 | case TARGET_NR_fork: |
| @@ -555,7 +569,7 @@ Index: qemu/linux-user/syscall.c | |||
| 555 | break; | 569 | break; |
| 556 | #ifdef TARGET_NR_waitpid | 570 | #ifdef TARGET_NR_waitpid |
| 557 | case TARGET_NR_waitpid: | 571 | case TARGET_NR_waitpid: |
| 558 | @@ -3648,7 +3719,8 @@ long do_syscall(void *cpu_env, int num, | 572 | @@ -3649,7 +3727,8 @@ |
| 559 | ret = get_errno(fsync(arg1)); | 573 | ret = get_errno(fsync(arg1)); |
| 560 | break; | 574 | break; |
| 561 | case TARGET_NR_clone: | 575 | case TARGET_NR_clone: |
| @@ -565,7 +579,7 @@ Index: qemu/linux-user/syscall.c | |||
| 565 | break; | 579 | break; |
| 566 | #ifdef __NR_exit_group | 580 | #ifdef __NR_exit_group |
| 567 | /* new thread calls */ | 581 | /* new thread calls */ |
| 568 | @@ -4062,7 +4134,8 @@ long do_syscall(void *cpu_env, int num, | 582 | @@ -4037,7 +4116,8 @@ |
| 569 | #endif | 583 | #endif |
| 570 | #ifdef TARGET_NR_vfork | 584 | #ifdef TARGET_NR_vfork |
| 571 | case TARGET_NR_vfork: | 585 | case TARGET_NR_vfork: |
| @@ -575,129 +589,20 @@ Index: qemu/linux-user/syscall.c | |||
| 575 | break; | 589 | break; |
| 576 | #endif | 590 | #endif |
| 577 | #ifdef TARGET_NR_ugetrlimit | 591 | #ifdef TARGET_NR_ugetrlimit |
| 578 | @@ -4660,4 +4733,3 @@ long do_syscall(void *cpu_env, int num, | 592 | @@ -4619,4 +4699,3 @@ |
| 579 | #endif | 593 | #endif |
| 580 | return ret; | 594 | return ret; |
| 581 | } | 595 | } |
| 582 | - | 596 | - |
| 583 | Index: qemu/target-arm/cpu.h | ||
| 584 | =================================================================== | ||
| 585 | --- qemu.orig/target-arm/cpu.h 2007-06-13 11:48:22.000000000 +0100 | ||
| 586 | +++ qemu/target-arm/cpu.h 2007-06-13 11:51:57.000000000 +0100 | ||
| 587 | @@ -37,6 +37,9 @@ | ||
| 588 | #define EXCP_IRQ 5 | ||
| 589 | #define EXCP_FIQ 6 | ||
| 590 | #define EXCP_BKPT 7 | ||
| 591 | +#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */ | ||
| 592 | + | ||
| 593 | + | ||
| 594 | |||
| 595 | typedef void ARMWriteCPFunc(void *opaque, int cp_info, | ||
| 596 | int srcreg, int operand, uint32_t value); | ||
| 597 | @@ -97,6 +100,7 @@ typedef struct CPUARMState { | ||
| 598 | uint32_t c9_data; | ||
| 599 | uint32_t c13_fcse; /* FCSE PID. */ | ||
| 600 | uint32_t c13_context; /* Context ID. */ | ||
| 601 | + uint32_t c13_tls; /* Paul Brook told me to just add this ;) */ | ||
| 602 | uint32_t c15_cpar; /* XScale Coprocessor Access Register */ | ||
| 603 | } cp15; | ||
| 604 | |||
| 605 | @@ -169,6 +173,15 @@ void switch_mode(CPUARMState *, int); | ||
| 606 | int cpu_arm_signal_handler(int host_signum, void *pinfo, | ||
| 607 | void *puc); | ||
| 608 | |||
| 609 | +void cpu_lock(void); | ||
| 610 | +void cpu_unlock(void); | ||
| 611 | +#if defined(USE_NPTL) | ||
| 612 | +static inline void cpu_set_tls(CPUARMState *env, void *newtls) | ||
| 613 | +{ | ||
| 614 | + env->cp15.c13_tls = (uint32_t)newtls; | ||
| 615 | +} | ||
| 616 | +#endif | ||
| 617 | + | ||
| 618 | #define CPSR_M (0x1f) | ||
| 619 | #define CPSR_T (1 << 5) | ||
| 620 | #define CPSR_F (1 << 6) | ||
| 621 | @@ -180,7 +193,11 @@ int cpu_arm_signal_handler(int host_sign | ||
| 622 | #define CPSR_J (1 << 24) | ||
| 623 | #define CPSR_IT_0_1 (3 << 25) | ||
| 624 | #define CPSR_Q (1 << 27) | ||
| 625 | -#define CPSR_NZCV (0xf << 28) | ||
| 626 | +#define CPSR_V (1 << 28) | ||
| 627 | +#define CPSR_C (1 << 29) | ||
| 628 | +#define CPSR_Z (1 << 30) | ||
| 629 | +#define CPSR_N (1 << 31) | ||
| 630 | +#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) | ||
| 631 | |||
| 632 | #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV) | ||
| 633 | /* Return the current CPSR value. */ | ||
| 634 | Index: qemu/target-arm/exec.h | ||
| 635 | =================================================================== | ||
| 636 | --- qemu.orig/target-arm/exec.h 2007-06-13 11:48:22.000000000 +0100 | ||
| 637 | +++ qemu/target-arm/exec.h 2007-06-13 11:51:57.000000000 +0100 | ||
| 638 | @@ -68,8 +68,6 @@ static inline int cpu_halted(CPUState *e | ||
| 639 | |||
| 640 | /* In op_helper.c */ | ||
| 641 | |||
| 642 | -void cpu_lock(void); | ||
| 643 | -void cpu_unlock(void); | ||
| 644 | void helper_set_cp(CPUState *, uint32_t, uint32_t); | ||
| 645 | uint32_t helper_get_cp(CPUState *, uint32_t); | ||
| 646 | void helper_set_cp15(CPUState *, uint32_t, uint32_t); | ||
| 647 | Index: qemu/target-arm/op.c | ||
| 648 | =================================================================== | ||
| 649 | --- qemu.orig/target-arm/op.c 2007-06-13 11:48:22.000000000 +0100 | ||
| 650 | +++ qemu/target-arm/op.c 2007-06-13 11:51:57.000000000 +0100 | ||
| 651 | @@ -891,6 +891,12 @@ void OPPROTO op_bkpt(void) | ||
| 652 | cpu_loop_exit(); | ||
| 653 | } | ||
| 654 | |||
| 655 | +void OPPROTO op_kernel_trap(void) | ||
| 656 | +{ | ||
| 657 | + env->exception_index = EXCP_KERNEL_TRAP; | ||
| 658 | + cpu_loop_exit(); | ||
| 659 | +} | ||
| 660 | + | ||
| 661 | /* VFP support. We follow the convention used for VFP instrunctions: | ||
| 662 | Single precition routines have a "s" suffix, double precision a | ||
| 663 | "d" suffix. */ | ||
| 664 | Index: qemu/target-arm/translate.c | ||
| 665 | =================================================================== | ||
| 666 | --- qemu.orig/target-arm/translate.c 2007-06-13 11:48:22.000000000 +0100 | ||
| 667 | +++ qemu/target-arm/translate.c 2007-06-13 11:51:57.000000000 +0100 | ||
| 668 | @@ -3513,6 +3513,7 @@ undef: | ||
| 669 | s->is_jmp = DISAS_JUMP; | ||
| 670 | } | ||
| 671 | |||
| 672 | + | ||
| 673 | /* generate intermediate code in gen_opc_buf and gen_opparam_buf for | ||
| 674 | basic block 'tb'. If search_pc is TRUE, also generate PC | ||
| 675 | information for each intermediate instruction. */ | ||
| 676 | @@ -3548,6 +3549,15 @@ static inline int gen_intermediate_code_ | ||
| 677 | nb_gen_labels = 0; | ||
| 678 | lj = -1; | ||
| 679 | do { | ||
| 680 | +#ifdef CONFIG_USER_ONLY | ||
| 681 | + /* Intercept jump to the magic kernel page. */ | ||
| 682 | + if (dc->pc > 0xffff0000) { | ||
| 683 | + gen_op_kernel_trap(); | ||
| 684 | + dc->is_jmp = DISAS_UPDATE; | ||
| 685 | + break; | ||
| 686 | + } | ||
| 687 | +#endif | ||
| 688 | + | ||
| 689 | if (env->nb_breakpoints > 0) { | ||
| 690 | for(j = 0; j < env->nb_breakpoints; j++) { | ||
| 691 | if (env->breakpoints[j] == dc->pc) { | ||
| 692 | Index: qemu/qemu_spinlock.h | 597 | Index: qemu/qemu_spinlock.h |
| 693 | =================================================================== | 598 | =================================================================== |
| 694 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | 599 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 |
| 695 | +++ qemu/qemu_spinlock.h 2007-06-13 11:51:57.000000000 +0100 | 600 | +++ qemu/qemu_spinlock.h 2007-06-29 10:47:58.000000000 +0000 |
| 696 | @@ -0,0 +1,204 @@ | 601 | @@ -0,0 +1,181 @@ |
| 697 | +/* | 602 | +/* |
| 698 | + * internal execution defines for qemu | 603 | + * Atomic operation helper include |
| 699 | + * | 604 | + * |
| 700 | + * Copyright (c) 2003 Fabrice Bellard | 605 | + * Copyright (c) 2005 Fabrice Bellard |
| 701 | + * | 606 | + * |
| 702 | + * This library is free software; you can redistribute it and/or | 607 | + * This library is free software; you can redistribute it and/or |
| 703 | + * modify it under the terms of the GNU Lesser General Public | 608 | + * modify it under the terms of the GNU Lesser General Public |
| @@ -713,9 +618,8 @@ Index: qemu/qemu_spinlock.h | |||
| 713 | + * License along with this library; if not, write to the Free Software | 618 | + * License along with this library; if not, write to the Free Software |
| 714 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 619 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 715 | + */ | 620 | + */ |
| 716 | + | 621 | +#ifndef QEMU_SPINLOCK_H |
| 717 | +#ifndef _QEMU_SPINLOCK_H | 622 | +#define QEMU_SPINLOCK_H |
| 718 | +#define _QEMU_SPINLOCK_H | ||
| 719 | + | 623 | + |
| 720 | +#ifdef __powerpc__ | 624 | +#ifdef __powerpc__ |
| 721 | +static inline int testandset (int *p) | 625 | +static inline int testandset (int *p) |
| @@ -739,7 +643,7 @@ Index: qemu/qemu_spinlock.h | |||
| 739 | +static inline int testandset (int *p) | 643 | +static inline int testandset (int *p) |
| 740 | +{ | 644 | +{ |
| 741 | + long int readval = 0; | 645 | + long int readval = 0; |
| 742 | + | 646 | + |
| 743 | + __asm__ __volatile__ ("lock; cmpxchgl %2, %0" | 647 | + __asm__ __volatile__ ("lock; cmpxchgl %2, %0" |
| 744 | + : "+m" (*p), "+a" (readval) | 648 | + : "+m" (*p), "+a" (readval) |
| 745 | + : "r" (1) | 649 | + : "r" (1) |
| @@ -752,7 +656,7 @@ Index: qemu/qemu_spinlock.h | |||
| 752 | +static inline int testandset (int *p) | 656 | +static inline int testandset (int *p) |
| 753 | +{ | 657 | +{ |
| 754 | + long int readval = 0; | 658 | + long int readval = 0; |
| 755 | + | 659 | + |
| 756 | + __asm__ __volatile__ ("lock; cmpxchgl %2, %0" | 660 | + __asm__ __volatile__ ("lock; cmpxchgl %2, %0" |
| 757 | + : "+m" (*p), "+a" (readval) | 661 | + : "+m" (*p), "+a" (readval) |
| 758 | + : "r" (1) | 662 | + : "r" (1) |
| @@ -767,10 +671,10 @@ Index: qemu/qemu_spinlock.h | |||
| 767 | + int ret; | 671 | + int ret; |
| 768 | + | 672 | + |
| 769 | + __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" | 673 | + __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" |
| 770 | + " jl 0b" | 674 | + " jl 0b" |
| 771 | + : "=&d" (ret) | 675 | + : "=&d" (ret) |
| 772 | + : "r" (1), "a" (p), "0" (*p) | 676 | + : "r" (1), "a" (p), "0" (*p) |
| 773 | + : "cc", "memory" ); | 677 | + : "cc", "memory" ); |
| 774 | + return ret; | 678 | + return ret; |
| 775 | +} | 679 | +} |
| 776 | +#endif | 680 | +#endif |
| @@ -781,15 +685,15 @@ Index: qemu/qemu_spinlock.h | |||
| 781 | + int ret; | 685 | + int ret; |
| 782 | + unsigned long one; | 686 | + unsigned long one; |
| 783 | + | 687 | + |
| 784 | + __asm__ __volatile__ ("0: mov 1,%2\n" | 688 | + __asm__ __volatile__ ("0: mov 1,%2\n" |
| 785 | + " ldl_l %0,%1\n" | 689 | + " ldl_l %0,%1\n" |
| 786 | + " stl_c %2,%1\n" | 690 | + " stl_c %2,%1\n" |
| 787 | + " beq %2,1f\n" | 691 | + " beq %2,1f\n" |
| 788 | + ".subsection 2\n" | 692 | + ".subsection 2\n" |
| 789 | + "1: br 0b\n" | 693 | + "1: br 0b\n" |
| 790 | + ".previous" | 694 | + ".previous" |
| 791 | + : "=r" (ret), "=m" (*p), "=r" (one) | 695 | + : "=r" (ret), "=m" (*p), "=r" (one) |
| 792 | + : "m" (*p)); | 696 | + : "m" (*p)); |
| 793 | + return ret; | 697 | + return ret; |
| 794 | +} | 698 | +} |
| 795 | +#endif | 699 | +#endif |
| @@ -797,14 +701,14 @@ Index: qemu/qemu_spinlock.h | |||
| 797 | +#ifdef __sparc__ | 701 | +#ifdef __sparc__ |
| 798 | +static inline int testandset (int *p) | 702 | +static inline int testandset (int *p) |
| 799 | +{ | 703 | +{ |
| 800 | + int ret; | 704 | + int ret; |
| 801 | + | 705 | + |
| 802 | + __asm__ __volatile__("ldstub [%1], %0" | 706 | + __asm__ __volatile__("ldstub [%1], %0" |
| 803 | + : "=r" (ret) | 707 | + : "=r" (ret) |
| 804 | + : "r" (p) | 708 | + : "r" (p) |
| 805 | + : "memory"); | 709 | + : "memory"); |
| 806 | + | 710 | + |
| 807 | + return (ret ? 1 : 0); | 711 | + return (ret ? 1 : 0); |
| 808 | +} | 712 | +} |
| 809 | +#endif | 713 | +#endif |
| 810 | + | 714 | + |
| @@ -815,7 +719,7 @@ Index: qemu/qemu_spinlock.h | |||
| 815 | + __asm__ __volatile__("swp %0, %1, [%2]" | 719 | + __asm__ __volatile__("swp %0, %1, [%2]" |
| 816 | + : "=r"(ret) | 720 | + : "=r"(ret) |
| 817 | + : "0"(1), "r"(spinlock)); | 721 | + : "0"(1), "r"(spinlock)); |
| 818 | + | 722 | + |
| 819 | + return ret; | 723 | + return ret; |
| 820 | +} | 724 | +} |
| 821 | +#endif | 725 | +#endif |
| @@ -841,28 +745,6 @@ Index: qemu/qemu_spinlock.h | |||
| 841 | +} | 745 | +} |
| 842 | +#endif | 746 | +#endif |
| 843 | + | 747 | + |
| 844 | +#ifdef __mips__ | ||
| 845 | +static inline int testandset (int *p) | ||
| 846 | +{ | ||
| 847 | + int ret; | ||
| 848 | + | ||
| 849 | + __asm__ __volatile__ ( | ||
| 850 | + " .set push \n" | ||
| 851 | + " .set noat \n" | ||
| 852 | + " .set mips2 \n" | ||
| 853 | + "1: li $1, 1 \n" | ||
| 854 | + " ll %0, %1 \n" | ||
| 855 | + " sc $1, %1 \n" | ||
| 856 | + " beqz $1, 1b \n" | ||
| 857 | + " .set pop " | ||
| 858 | + : "=r" (ret), "+R" (*p) | ||
| 859 | + : | ||
| 860 | + : "memory"); | ||
| 861 | + | ||
| 862 | + return ret; | ||
| 863 | +} | ||
| 864 | +#endif | ||
| 865 | + | ||
| 866 | +typedef int spinlock_t; | 748 | +typedef int spinlock_t; |
| 867 | + | 749 | + |
| 868 | +#define SPIN_LOCK_UNLOCKED 0 | 750 | +#define SPIN_LOCK_UNLOCKED 0 |
| @@ -897,4 +779,114 @@ Index: qemu/qemu_spinlock.h | |||
| 897 | +} | 779 | +} |
| 898 | +#endif | 780 | +#endif |
| 899 | + | 781 | + |
| 900 | +#endif /* ! _QEMU_SPINLOCK_H */ | 782 | +#endif |
| 783 | Index: qemu/target-arm/cpu.h | ||
| 784 | =================================================================== | ||
| 785 | --- qemu.orig/target-arm/cpu.h 2007-06-29 10:47:39.000000000 +0000 | ||
| 786 | +++ qemu/target-arm/cpu.h 2007-06-29 10:47:58.000000000 +0000 | ||
| 787 | @@ -37,6 +37,7 @@ | ||
| 788 | #define EXCP_IRQ 5 | ||
| 789 | #define EXCP_FIQ 6 | ||
| 790 | #define EXCP_BKPT 7 | ||
| 791 | +#define EXCP_KERNEL_TRAP 8 /* Jumped to kernel code page. */ | ||
| 792 | |||
| 793 | typedef void ARMWriteCPFunc(void *opaque, int cp_info, | ||
| 794 | int srcreg, int operand, uint32_t value); | ||
| 795 | @@ -97,6 +98,7 @@ | ||
| 796 | uint32_t c9_data; | ||
| 797 | uint32_t c13_fcse; /* FCSE PID. */ | ||
| 798 | uint32_t c13_context; /* Context ID. */ | ||
| 799 | + uint32_t c13_tls; /* Context ID. */ | ||
| 800 | uint32_t c15_cpar; /* XScale Coprocessor Access Register */ | ||
| 801 | } cp15; | ||
| 802 | |||
| 803 | @@ -169,6 +171,15 @@ | ||
| 804 | int cpu_arm_signal_handler(int host_signum, void *pinfo, | ||
| 805 | void *puc); | ||
| 806 | |||
| 807 | +void cpu_lock(void); | ||
| 808 | +void cpu_unlock(void); | ||
| 809 | +#if defined(USE_NPTL) | ||
| 810 | +static inline void cpu_set_tls(CPUARMState *env, void *newtls) | ||
| 811 | +{ | ||
| 812 | + env->cp15.c13_tls = (uint32_t)(long)newtls; | ||
| 813 | +} | ||
| 814 | +#endif | ||
| 815 | + | ||
| 816 | #define CPSR_M (0x1f) | ||
| 817 | #define CPSR_T (1 << 5) | ||
| 818 | #define CPSR_F (1 << 6) | ||
| 819 | @@ -180,7 +191,11 @@ | ||
| 820 | #define CPSR_J (1 << 24) | ||
| 821 | #define CPSR_IT_0_1 (3 << 25) | ||
| 822 | #define CPSR_Q (1 << 27) | ||
| 823 | -#define CPSR_NZCV (0xf << 28) | ||
| 824 | +#define CPSR_V (1 << 28) | ||
| 825 | +#define CPSR_C (1 << 29) | ||
| 826 | +#define CPSR_Z (1 << 30) | ||
| 827 | +#define CPSR_N (1 << 31) | ||
| 828 | +#define CPSR_NZCV (CPSR_N | CPSR_Z | CPSR_C | CPSR_V) | ||
| 829 | |||
| 830 | #define CACHED_CPSR_BITS (CPSR_T | CPSR_Q | CPSR_NZCV) | ||
| 831 | /* Return the current CPSR value. */ | ||
| 832 | Index: qemu/target-arm/exec.h | ||
| 833 | =================================================================== | ||
| 834 | --- qemu.orig/target-arm/exec.h 2007-06-29 10:47:39.000000000 +0000 | ||
| 835 | +++ qemu/target-arm/exec.h 2007-06-29 10:47:58.000000000 +0000 | ||
| 836 | @@ -68,8 +68,6 @@ | ||
| 837 | |||
| 838 | /* In op_helper.c */ | ||
| 839 | |||
| 840 | -void cpu_lock(void); | ||
| 841 | -void cpu_unlock(void); | ||
| 842 | void helper_set_cp(CPUState *, uint32_t, uint32_t); | ||
| 843 | uint32_t helper_get_cp(CPUState *, uint32_t); | ||
| 844 | void helper_set_cp15(CPUState *, uint32_t, uint32_t); | ||
| 845 | Index: qemu/target-arm/op.c | ||
| 846 | =================================================================== | ||
| 847 | --- qemu.orig/target-arm/op.c 2007-06-29 10:47:39.000000000 +0000 | ||
| 848 | +++ qemu/target-arm/op.c 2007-06-29 10:47:58.000000000 +0000 | ||
| 849 | @@ -891,6 +891,12 @@ | ||
| 850 | cpu_loop_exit(); | ||
| 851 | } | ||
| 852 | |||
| 853 | +void OPPROTO op_kernel_trap(void) | ||
| 854 | +{ | ||
| 855 | + env->exception_index = EXCP_KERNEL_TRAP; | ||
| 856 | + cpu_loop_exit(); | ||
| 857 | +} | ||
| 858 | + | ||
| 859 | /* VFP support. We follow the convention used for VFP instrunctions: | ||
| 860 | Single precition routines have a "s" suffix, double precision a | ||
| 861 | "d" suffix. */ | ||
| 862 | Index: qemu/target-arm/op_mem.h | ||
| 863 | =================================================================== | ||
| 864 | --- qemu.orig/target-arm/op_mem.h 2007-06-29 10:47:39.000000000 +0000 | ||
| 865 | +++ qemu/target-arm/op_mem.h 2007-06-29 10:47:58.000000000 +0000 | ||
| 866 | @@ -1,5 +1,6 @@ | ||
| 867 | /* ARM memory operations. */ | ||
| 868 | |||
| 869 | +void helper_ld(uint32_t); | ||
| 870 | /* Load from address T1 into T0. */ | ||
| 871 | #define MEM_LD_OP(name) \ | ||
| 872 | void OPPROTO glue(op_ld##name,MEMSUFFIX)(void) \ | ||
| 873 | Index: qemu/target-arm/translate.c | ||
| 874 | =================================================================== | ||
| 875 | --- qemu.orig/target-arm/translate.c 2007-06-29 10:47:39.000000000 +0000 | ||
| 876 | +++ qemu/target-arm/translate.c 2007-06-29 10:47:58.000000000 +0000 | ||
| 877 | @@ -3548,6 +3548,15 @@ | ||
| 878 | nb_gen_labels = 0; | ||
| 879 | lj = -1; | ||
| 880 | do { | ||
| 881 | +#ifdef CONFIG_USER_ONLY | ||
| 882 | + /* Intercept jump to the magic kernel page. */ | ||
| 883 | + if (dc->pc > 0xffff0000) { | ||
| 884 | + gen_op_kernel_trap(); | ||
| 885 | + dc->is_jmp = DISAS_UPDATE; | ||
| 886 | + break; | ||
| 887 | + } | ||
| 888 | +#endif | ||
| 889 | + | ||
| 890 | if (env->nb_breakpoints > 0) { | ||
| 891 | for(j = 0; j < env->nb_breakpoints; j++) { | ||
| 892 | if (env->breakpoints[j] == dc->pc) { | ||
diff --git a/meta/packages/qemu/qemu_cvs.bb b/meta/packages/qemu/qemu_cvs.bb index 4148a4835c..3392b8804e 100644 --- a/meta/packages/qemu/qemu_cvs.bb +++ b/meta/packages/qemu/qemu_cvs.bb | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | LICENSE = "GPL" | 1 | LICENSE = "GPL" |
| 2 | DEPENDS = "zlib" | 2 | DEPENDS = "zlib" |
| 3 | PV = "0.9.0+cvs${SRCDATE}" | 3 | PV = "0.9.0+cvs${SRCDATE}" |
| 4 | PR = "r0" | 4 | PR = "r1" |
| 5 | 5 | ||
| 6 | FILESDIR = "${WORKDIR}" | 6 | FILESDIR = "${WORKDIR}" |
| 7 | 7 | ||
| @@ -29,7 +29,9 @@ SRC_URI = "\ | |||
| 29 | file://66_tls_ld.patch;patch=1;pnum=0 \ | 29 | file://66_tls_ld.patch;patch=1;pnum=0 \ |
| 30 | file://91-oh-sdl-cursor.patch;patch=1;pnum=0 \ | 30 | file://91-oh-sdl-cursor.patch;patch=1;pnum=0 \ |
| 31 | file://93-oh-pl110-rgb.patch;patch=1;pnum=0 \ | 31 | file://93-oh-pl110-rgb.patch;patch=1;pnum=0 \ |
| 32 | file://94-oh-arm-nptl.patch;patch=1;pnum=1" | 32 | file://qemu-0.9.0-nptl.patch;patch=1 \ |
| 33 | file://qemu-0.9.0-nptl-update.patch;patch=1 \ | ||
| 34 | file://fix_segfault.patch;patch=1" | ||
| 33 | 35 | ||
| 34 | # svn://svn.o-hand.com/repos/misc/trunk/qemu-packaging/qemu;module=debian;proto=http;srcdate=20070119 \ | 36 | # svn://svn.o-hand.com/repos/misc/trunk/qemu-packaging/qemu;module=debian;proto=http;srcdate=20070119 \ |
| 35 | # file://debian/patches/21_net_soopts.patch;patch=1;pnum=0 \ | 37 | # file://debian/patches/21_net_soopts.patch;patch=1;pnum=0 \ |
| @@ -43,6 +45,7 @@ SRC_URI = "\ | |||
| 43 | S = "${WORKDIR}/qemu" | 45 | S = "${WORKDIR}/qemu" |
| 44 | 46 | ||
| 45 | #EXTRA_OECONF = "--disable-sdl" | 47 | #EXTRA_OECONF = "--disable-sdl" |
| 48 | #EXTRA_OECONF = "--disable-gfx-check --target-list=arm-linux-user" | ||
| 46 | EXTRA_OECONF = "--disable-gfx-check" | 49 | EXTRA_OECONF = "--disable-gfx-check" |
| 47 | 50 | ||
| 48 | inherit autotools | 51 | inherit autotools |
