Index: qemu/qemu-0.12.5-mips.patch |
diff --git a/qemu/qemu-0.12.5-mips.patch b/qemu/qemu-0.12.5-mips.patch |
new file mode 100755 |
index 0000000000000000000000000000000000000000..2553bfc5a36f9ea6baa9cb1c4737f53805e82cfc |
--- /dev/null |
+++ b/qemu/qemu-0.12.5-mips.patch |
@@ -0,0 +1,494 @@ |
+diff -uNpr qemu-0.12.5/linux-user/main.c qemu-0.12.5_new/linux-user/main.c |
+--- qemu-0.12.5/linux-user/main.c 2010-07-22 14:39:04.000000000 +0200 |
++++ qemu-0.12.5_new/linux-user/main.c 2011-08-01 16:05:35.651884528 +0200 |
+@@ -33,6 +33,7 @@ |
+ |
+ |
+ #include "envlist.h" |
++#include <sys/resource.h> |
+ |
+ #define DEBUG_LOGFILE "/tmp/qemu.log" |
+ |
+@@ -1916,7 +1917,21 @@ static const uint8_t mips_syscall_args[] |
+ MIPS_SYS(sys_getcpu, 3) |
+ MIPS_SYS(sys_epoll_pwait, 6) |
+ MIPS_SYS(sys_ioprio_set, 3) |
+- MIPS_SYS(sys_ioprio_get, 2) |
++ MIPS_SYS(sys_ioprio_get, 2) /* 4315 */ |
++ MIPS_SYS(sys_utimensat, 4) |
++ MIPS_SYS(sys_signalfd, 3) |
++ MIPS_SYS(sys_timerfd, 0) |
++ MIPS_SYS(sys_eventfd, 2) |
++ MIPS_SYS(sys_fallocate, 4) /* 4320 */ |
++ MIPS_SYS(sys_timerfd_create, 2) |
++ MIPS_SYS(sys_timerfd_gettime, 2) |
++ MIPS_SYS(sys_timerfd_settime, 4) |
++ MIPS_SYS(sys_signalfd4, 4) |
++ MIPS_SYS(sys_eventfd, 2) /* 4325 */ |
++ MIPS_SYS(sys_epoll_create1, 1) |
++ MIPS_SYS(sys_dup3, 3) |
++ MIPS_SYS(do_pipe2, 2) |
++ MIPS_SYS(sys_inotify_init1, 1) |
+ }; |
+ |
+ #undef MIPS_SYS |
+@@ -2514,6 +2529,13 @@ void init_task_state(TaskState *ts) |
+ |
+ int main(int argc, char **argv, char **envp) |
+ { |
++ #if defined(TARGET_MIPS) |
++ { |
++ //stack size 5MB |
++ x86_stack_size = 5 * 1024 * 1024; |
++ } |
++ #endif //#if defined(TARGET_MIPS) |
++ |
+ const char *filename; |
+ const char *cpu_model; |
+ struct target_pt_regs regs1, *regs = ®s1; |
+@@ -2700,6 +2722,17 @@ int main(int argc, char **argv, char **e |
+ fprintf(stderr, "Unable to find CPU definition\n"); |
+ exit(1); |
+ } |
++ |
++#if defined(TARGET_MIPS) |
++ { |
++ //Set OPEN_MAX on 1024 |
++ struct rlimit rlim1; |
++ rlim1.rlim_cur=1024; |
++ rlim1.rlim_max=1024; |
++ setrlimit(5, &rlim1); |
++ } |
++#endif //#if defined(TARGET_MIPS) |
++ |
+ #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC) |
+ cpu_reset(env); |
+ #endif |
+diff -uNpr qemu-0.12.5/linux-user/strace.list qemu-0.12.5_new/linux-user/strace.list |
+--- qemu-0.12.5/linux-user/strace.list 2010-07-22 14:39:04.000000000 +0200 |
++++ qemu-0.12.5_new/linux-user/strace.list 2011-08-01 16:05:35.641884925 +0200 |
+@@ -1518,3 +1518,42 @@ |
+ #ifdef TARGET_NR_utimensat |
+ { TARGET_NR_utimensat, "utimensat", NULL, print_utimensat, NULL }, |
+ #endif |
++#ifdef TARGET_NR_signalfd |
++{ TARGET_NR_signalfd, "signalfd", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_timerfd |
++{ TARGET_NR_timerfd, "timerfd", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_eventfd |
++{ TARGET_NR_eventfd, "eventfd", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_fallocate |
++{ TARGET_NR_fallocate, "fallocate", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_timerfd_create |
++{ TARGET_NR_timerfd_create, "timerfd_create", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_timerfd_gettime |
++{ TARGET_NR_timerfd_gettime, "timerfd_gettime", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_timerfd_settime |
++{ TARGET_NR_timerfd_settime, "timerfd_settime", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_signalfd4 |
++{ TARGET_NR_signalfd4, "signalfd4", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_eventfd2 |
++{ TARGET_NR_eventfd2, "eventfd2", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_epoll_create1 |
++{ TARGET_NR_epoll_create1, "epoll_create1", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_dup3 |
++{ TARGET_NR_dup3, "dup3", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_pipe2 |
++{ TARGET_NR_pipe2, "pipe2", NULL, NULL, NULL }, |
++#endif |
++#ifdef TARGET_NR_inotify_init1 |
++{ TARGET_NR_inotify_init1, "inotify_init1", NULL, NULL, NULL }, |
++#endif |
+diff -uNpr qemu-0.12.5/linux-user/syscall.c qemu-0.12.5_new/linux-user/syscall.c |
+--- qemu-0.12.5/linux-user/syscall.c 2010-07-22 14:39:04.000000000 +0200 |
++++ qemu-0.12.5_new/linux-user/syscall.c 2011-08-01 16:08:35.253009379 +0200 |
+@@ -62,6 +62,9 @@ |
+ #ifdef CONFIG_EVENTFD |
+ #include <sys/eventfd.h> |
+ #endif |
++#include <sys/epoll.h> |
++#include <sys/timerfd.h> |
++#include <sys/signalfd.h> |
+ |
+ #define termios host_termios |
+ #define winsize host_winsize |
+@@ -967,7 +970,18 @@ static abi_long do_pipe(void *cpu_env, a |
+ return get_errno(ret); |
+ #if defined(TARGET_MIPS) |
+ ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1]; |
+- ret = host_pipe[0]; |
++ if(!flags) |
++ ret = host_pipe[0]; |
++ |
++ { |
++ unsigned short val1=0; |
++ val1 = (abi_long)(host_pipe[0] & 0xFFFFFFFF); |
++ |
++ abi_long *par; |
++ *(&par) = (abi_long *)((CPUMIPSState*)cpu_env)->active_tc.gpr[4]; |
++ par[0]= val1; |
++ par[1]= host_pipe[1]; |
++ } |
+ #elif defined(TARGET_SH4) |
+ ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; |
+ ret = host_pipe[0]; |
+@@ -2766,9 +2780,12 @@ static abi_long do_ipc(unsigned int call |
+ break; |
+ |
+ case IPCOP_semctl: |
+- ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr); |
+- break; |
+- |
++ { |
++ union target_semun *target_su; |
++ target_su=(union target_semun *)(abi_ulong)ptr; |
++ ret = do_semctl(first, second, third, *target_su); |
++ break; |
++ } |
+ case IPCOP_msgget: |
+ ret = get_errno(msgget(first, second)); |
+ break; |
+@@ -3925,6 +3942,12 @@ static inline abi_long target_truncate64 |
+ arg3 = arg4; |
+ } |
+ #endif |
++ |
++#ifdef TARGET_MIPS |
++ arg2 = arg3; |
++ arg3 = arg4; |
++#endif |
++ |
+ return get_errno(truncate64(arg1, target_offset64(arg2, arg3))); |
+ } |
+ #endif |
+@@ -3942,6 +3965,12 @@ static inline abi_long target_ftruncate6 |
+ arg3 = arg4; |
+ } |
+ #endif |
++ |
++#ifdef TARGET_MIPS |
++ arg2 = arg3; |
++ arg3 = arg4; |
++#endif |
++ |
+ return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3))); |
+ } |
+ #endif |
+@@ -5066,8 +5095,9 @@ abi_long do_syscall(void *cpu_env, int n |
+ struct rlimit rlim; |
+ if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) |
+ goto efault; |
+- rlim.rlim_cur = tswapl(target_rlim->rlim_cur); |
+- rlim.rlim_max = tswapl(target_rlim->rlim_max); |
++ rlim.rlim_cur = tswapl(target_rlim->rlim_cur) & 0xFFFFFFFF; |
++ rlim.rlim_max = tswapl(target_rlim->rlim_max) & 0xFFFFFFFF; |
++ |
+ unlock_user_struct(target_rlim, arg2, 0); |
+ ret = get_errno(setrlimit(resource, &rlim)); |
+ } |
+@@ -5083,8 +5113,8 @@ abi_long do_syscall(void *cpu_env, int n |
+ if (!is_error(ret)) { |
+ if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) |
+ goto efault; |
+- target_rlim->rlim_cur = tswapl(rlim.rlim_cur); |
+- target_rlim->rlim_max = tswapl(rlim.rlim_max); |
++ target_rlim->rlim_cur = tswapl(rlim.rlim_cur) & 0x7FFFFFFF; |
++ target_rlim->rlim_max = tswapl(rlim.rlim_max) & 0x7FFFFFFF; |
+ unlock_user_struct(target_rlim, arg2, 1); |
+ } |
+ } |
+@@ -6115,13 +6145,21 @@ abi_long do_syscall(void *cpu_env, int n |
+ case TARGET_NR_pread64: |
+ if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) |
+ goto efault; |
++#if defined(TARGET_MIPS) |
++ ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg5, arg4))); |
++#else |
+ ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5))); |
++#endif |
+ unlock_user(p, arg2, ret); |
+ break; |
+ case TARGET_NR_pwrite64: |
+ if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) |
+ goto efault; |
++#if defined(TARGET_MIPS) |
++ ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg5, arg4))); |
++#else |
+ ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5))); |
++#endif |
+ unlock_user(p, arg2, 0); |
+ break; |
+ #endif |
+@@ -6169,8 +6207,8 @@ abi_long do_syscall(void *cpu_env, int n |
+ struct target_rlimit *target_rlim; |
+ if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) |
+ goto efault; |
+- target_rlim->rlim_cur = tswapl(rlim.rlim_cur); |
+- target_rlim->rlim_max = tswapl(rlim.rlim_max); |
++ target_rlim->rlim_cur = tswapl(rlim.rlim_cur) & 0x7FFFFFFF; |
++ target_rlim->rlim_max = tswapl(rlim.rlim_max) & 0x7FFFFFFF; |
+ unlock_user_struct(target_rlim, arg2, 1); |
+ } |
+ break; |
+@@ -7032,6 +7070,108 @@ abi_long do_syscall(void *cpu_env, int n |
+ ret = get_errno(fallocate(arg1, arg2, arg3, arg4)); |
+ break; |
+ #endif |
++#if defined(TARGET_NR_signalfd) |
++ case TARGET_NR_signalfd: |
++ { |
++ target_sigset_t *target_mask; |
++ sigset_t mask; |
++ if (!lock_user_struct(VERIFY_READ, target_mask, arg2, 1)) |
++ goto efault; |
++ |
++ target_to_host_sigset(&mask, target_mask); |
++ |
++ unlock_user_struct(target_mask, arg2, 0); |
++ ret = get_errno(signalfd(arg1, &mask, arg3)); |
++ } |
++ break; |
++#endif |
++#if defined(TARGET_NR_timerfd) |
++ case TARGET_NR_timerfd: |
++ goto unimplemented; |
++ break; |
++#endif |
++#if defined(TARGET_NR_timerfd_create) |
++ case TARGET_NR_timerfd_create: |
++ ret = get_errno(timerfd_create(arg1, arg2)); |
++ break; |
++#endif |
++#if defined(TARGET_NR_timerfd_gettime) |
++ case TARGET_NR_timerfd_gettime: |
++ { |
++ struct itimerspec cur_timep_spec; |
++ struct target_itimerspec *target_cur_timep_spec; |
++ ret = get_errno(timerfd_gettime(arg1, &cur_timep_spec)); |
++ if (!is_error(ret)) { |
++ if (!lock_user_struct(VERIFY_WRITE, target_cur_timep_spec, arg2, 0)) |
++ goto efault; |
++ |
++ host_to_target_timespec((abi_long)&target_cur_timep_spec->it_interval, &cur_timep_spec.it_interval); |
++ host_to_target_timespec((abi_long)&target_cur_timep_spec->it_value, &cur_timep_spec.it_value); |
++ |
++ unlock_user_struct(target_cur_timep_spec, arg2, 1); |
++ } |
++ } |
++ break; |
++#endif |
++#if defined(TARGET_NR_timerfd_settime) |
++ case TARGET_NR_timerfd_settime: |
++ { |
++ int fd=arg1; |
++ int flags=arg2; |
++ |
++ struct itimerspec new_timep_spec; |
++ struct target_itimerspec *target_new_timep_spec; |
++ if (!lock_user_struct(VERIFY_READ, target_new_timep_spec, arg3, 1)) |
++ goto efault; |
++ |
++ target_to_host_timespec(&new_timep_spec.it_interval, (abi_long)&target_new_timep_spec->it_interval); |
++ target_to_host_timespec(&new_timep_spec.it_value, (abi_long)&target_new_timep_spec->it_value); |
++ |
++ unlock_user_struct(target_new_timep_spec, arg3, 0); |
++ |
++ struct itimerspec old_timep_spec; |
++ struct target_itimerspec *target_old_timep_spec; |
++ |
++ ret = get_errno(timerfd_settime(fd, flags, &new_timep_spec, &old_timep_spec)); |
++ |
++ if (!is_error(ret) && arg4) { |
++ if (!lock_user_struct(VERIFY_WRITE, target_old_timep_spec, arg4 + sizeof(struct target_itimerspec), 0)) |
++ goto efault; |
++ host_to_target_timespec((abi_long)&target_old_timep_spec->it_interval, &old_timep_spec.it_interval); |
++ host_to_target_timespec((abi_long)&target_old_timep_spec->it_value, &old_timep_spec.it_value); |
++ |
++ unlock_user_struct(target_old_timep_spec, arg4, 1); |
++ } |
++ |
++ } |
++ break; |
++#endif |
++#if defined(TARGET_NR_signalfd4) |
++ case TARGET_NR_signalfd4: |
++ { |
++ target_sigset_t *target_mask; |
++ sigset_t mask; |
++ if (!lock_user_struct(VERIFY_READ, target_mask, arg2, 1)) |
++ goto efault; |
++ |
++ target_to_host_sigset(&mask, target_mask); |
++ |
++ unlock_user_struct(target_mask, arg2, 0); |
++ ret = get_errno(signalfd(arg1, &mask, arg4)); |
++ } |
++ break; |
++#endif |
++#if defined(TARGET_NR_epoll_create1) |
++ case TARGET_NR_epoll_create1: |
++ ret = get_errno(epoll_create1(arg1)); |
++ break; |
++#endif |
++#if defined(TARGET_NR_inotify_init1) |
++ case TARGET_NR_inotify_init1: |
++ ret = get_errno(inotify_init1(arg1)); |
++ break; |
++#endif |
++ |
+ default: |
+ unimplemented: |
+ gemu_log("qemu: Unsupported syscall: %d\n", num); |
+diff -uNpr qemu-0.12.5/linux-user/syscall_defs.h qemu-0.12.5_new/linux-user/syscall_defs.h |
+--- qemu-0.12.5/linux-user/syscall_defs.h 2010-07-22 14:39:04.000000000 +0200 |
++++ qemu-0.12.5_new/linux-user/syscall_defs.h 2011-08-01 16:05:35.649884666 +0200 |
+@@ -2161,3 +2161,8 @@ struct target_mq_attr { |
+ #define FUTEX_CLOCK_REALTIME 256 |
+ #define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) |
+ |
++ |
++struct target_itimerspec { |
++ struct target_timespec it_interval; /* Interval for periodic timer */ |
++ struct target_timespec it_value; /* Initial expiration */ |
++}; |
+diff -ur qemu-0.12.5//target-mips/cpu.h qemu-mips.nacl/qemu-0.12.5//target-mips/cpu.h |
+--- qemu-0.12.5//target-mips/cpu.h 2010-07-22 14:39:04.000000000 +0200 |
++++ qemu-mips.nacl/qemu-0.12.5//target-mips/cpu.h 2012-06-15 12:18:16.951741355 +0200 |
+@@ -613,4 +613,45 @@ |
+ env->tls_value = newtls; |
+ } |
+ |
++static inline void compute_hflags(CPUState *env) |
++{ |
++ env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | |
++ MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | |
++ MIPS_HFLAG_UX); |
++ if (!(env->CP0_Status & (1 << CP0St_EXL)) && |
++ !(env->CP0_Status & (1 << CP0St_ERL)) && |
++ !(env->hflags & MIPS_HFLAG_DM)) { |
++ env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU; |
++ } |
++#if defined(TARGET_MIPS64) |
++ if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) || |
++ (env->CP0_Status & (1 << CP0St_PX)) || |
++ (env->CP0_Status & (1 << CP0St_UX))) |
++ env->hflags |= MIPS_HFLAG_64; |
++ if (env->CP0_Status & (1 << CP0St_UX)) |
++ env->hflags |= MIPS_HFLAG_UX; |
++#endif |
++ if ((env->CP0_Status & (1 << CP0St_CU0)) || |
++ !(env->hflags & MIPS_HFLAG_KSU)) |
++ env->hflags |= MIPS_HFLAG_CP0; |
++ if (env->CP0_Status & (1 << CP0St_CU1)) |
++ env->hflags |= MIPS_HFLAG_FPU; |
++ if (env->CP0_Status & (1 << CP0St_FR)) |
++ env->hflags |= MIPS_HFLAG_F64; |
++ if (env->insn_flags & ISA_MIPS32R2) { |
++ if (env->active_fpu.fcr0 & (1 << FCR0_F64)) |
++ env->hflags |= MIPS_HFLAG_COP1X; |
++ } else if (env->insn_flags & ISA_MIPS32) { |
++ if (env->hflags & MIPS_HFLAG_64) |
++ env->hflags |= MIPS_HFLAG_COP1X; |
++ } else if (env->insn_flags & ISA_MIPS4) { |
++ /* All supported MIPS IV CPUs use the XX (CU3) to enable |
++ and disable the MIPS IV extensions to the MIPS III ISA. |
++ Some other MIPS IV CPUs ignore the bit, so the check here |
++ would be too restrictive for them. */ |
++ if (env->CP0_Status & (1 << CP0St_CU3)) |
++ env->hflags |= MIPS_HFLAG_COP1X; |
++ } |
++} |
++ |
+ #endif /* !defined (__MIPS_CPU_H__) */ |
+diff -ur qemu-0.12.5//target-mips/exec.h qemu-mips.nacl/qemu-0.12.5//target-mips/exec.h |
+--- qemu-0.12.5//target-mips/exec.h 2010-07-22 14:39:04.000000000 +0200 |
++++ qemu-mips.nacl/qemu-0.12.5//target-mips/exec.h 2012-06-15 12:18:09.559741393 +0200 |
+@@ -51,45 +51,4 @@ |
+ return EXCP_HALTED; |
+ } |
+ |
+-static inline void compute_hflags(CPUState *env) |
+-{ |
+- env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | |
+- MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | |
+- MIPS_HFLAG_UX); |
+- if (!(env->CP0_Status & (1 << CP0St_EXL)) && |
+- !(env->CP0_Status & (1 << CP0St_ERL)) && |
+- !(env->hflags & MIPS_HFLAG_DM)) { |
+- env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU; |
+- } |
+-#if defined(TARGET_MIPS64) |
+- if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) || |
+- (env->CP0_Status & (1 << CP0St_PX)) || |
+- (env->CP0_Status & (1 << CP0St_UX))) |
+- env->hflags |= MIPS_HFLAG_64; |
+- if (env->CP0_Status & (1 << CP0St_UX)) |
+- env->hflags |= MIPS_HFLAG_UX; |
+-#endif |
+- if ((env->CP0_Status & (1 << CP0St_CU0)) || |
+- !(env->hflags & MIPS_HFLAG_KSU)) |
+- env->hflags |= MIPS_HFLAG_CP0; |
+- if (env->CP0_Status & (1 << CP0St_CU1)) |
+- env->hflags |= MIPS_HFLAG_FPU; |
+- if (env->CP0_Status & (1 << CP0St_FR)) |
+- env->hflags |= MIPS_HFLAG_F64; |
+- if (env->insn_flags & ISA_MIPS32R2) { |
+- if (env->active_fpu.fcr0 & (1 << FCR0_F64)) |
+- env->hflags |= MIPS_HFLAG_COP1X; |
+- } else if (env->insn_flags & ISA_MIPS32) { |
+- if (env->hflags & MIPS_HFLAG_64) |
+- env->hflags |= MIPS_HFLAG_COP1X; |
+- } else if (env->insn_flags & ISA_MIPS4) { |
+- /* All supported MIPS IV CPUs use the XX (CU3) to enable |
+- and disable the MIPS IV extensions to the MIPS III ISA. |
+- Some other MIPS IV CPUs ignore the bit, so the check here |
+- would be too restrictive for them. */ |
+- if (env->CP0_Status & (1 << CP0St_CU3)) |
+- env->hflags |= MIPS_HFLAG_COP1X; |
+- } |
+-} |
+- |
+ #endif /* !defined(__QEMU_MIPS_EXEC_H__) */ |
+diff -ur qemu-0.12.5//target-mips/translate.c qemu-mips.nacl/qemu-0.12.5//target-mips/translate.c |
+--- qemu-0.12.5//target-mips/translate.c 2010-07-22 14:39:04.000000000 +0200 |
++++ qemu-mips.nacl/qemu-0.12.5//target-mips/translate.c 2012-06-15 12:17:24.927743160 +0200 |
+@@ -8614,6 +8614,7 @@ |
+ /* Reset registers to their default values */ |
+ env->CP0_PRid = env->cpu_model->CP0_PRid; |
+ env->CP0_Config0 = env->cpu_model->CP0_Config0; |
++ env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0; |
+ #ifdef TARGET_WORDS_BIGENDIAN |
+ env->CP0_Config0 |= (1 << CP0C0_BE); |
+ #endif |
+@@ -8654,10 +8655,12 @@ |
+ |
+ #if defined(CONFIG_USER_ONLY) |
+ env->hflags = MIPS_HFLAG_UM; |
++ env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU); |
+ /* Enable access to the SYNCI_Step register. */ |
+ env->CP0_HWREna |= (1 << 1); |
+ if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
+ env->hflags |= MIPS_HFLAG_FPU; |
++ env->CP0_Status |= (1 << CP0St_CU1); |
+ } |
+ #ifdef TARGET_MIPS64 |
+ if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { |
+@@ -8701,6 +8704,7 @@ |
+ env->hflags |= MIPS_HFLAG_64; |
+ } |
+ #endif |
++ compute_hflags(env); |
+ env->exception_index = EXCP_NONE; |
+ } |
+ |