From 55be33fd92859684db70a605c33b2c99a2c1a0f3 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 5 Jan 2009 15:56:31 +0000 Subject: [PATCH] qemu: Upgrade to latest svn removing a ton of merged patches (yay) --- .../distro/include/poky-fixed-revisions.inc | 2 +- .../05_non-fatal_if_linux_hd_missing.patch | 17 - .../qemu-0.9.1+svn/06_exit_segfault.patch | 45 - .../qemu/qemu-0.9.1+svn/10_signal_jobs.patch | 26 - .../qemu-0.9.1+svn/11_signal_sigaction.patch | 21 - .../qemu/qemu-0.9.1+svn/31_syscalls.patch | 48 - .../qemu-0.9.1+svn/32_syscall_sysctl.patch | 55 - .../qemu-0.9.1+svn/33_syscall_ppc_clone.patch | 22 - .../qemu-0.9.1+svn/39_syscall_fadvise64.patch | 21 - .../qemu-0.9.1+svn/52_ne2000_return.patch | 17 - .../qemu-0.9.1+svn/61_safe_64bit_int.patch | 27 - .../qemu/qemu-0.9.1+svn/63_sparc_build.patch | 18 - .../64_ppc_asm_constraints.patch | 18 - .../qemu/qemu-0.9.1+svn/65_kfreebsd.patch | 35 - .../qemu/qemu-0.9.1+svn/66_tls_ld.patch | 55 - .../qemu-0.9.1+svn/91-oh-sdl-cursor.patch | 18 - .../configure_symlinkpath_fix.patch | 28 - .../qemu/qemu-0.9.1+svn/fix-dirent.patch | 20 - .../qemu/qemu-0.9.1+svn/fix_brk.patch | 59 - .../qemu-0.9.1+svn/fix_protection_bits.patch | 14 - .../qemu/qemu-0.9.1+svn/fix_segfault.patch | 37 - .../qemu/qemu-0.9.1+svn/no-strip.patch | 26 - .../qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch | 1100 -- .../qemu-0.9.1+svn/qemu-n800-support.patch | 2381 --- .../qemu-0.9.1+svn/revert_arm_tcg.patch.gz | Bin 97991 -> 0 bytes meta/packages/qemu/qemu-0.9.1+svn/series | 25 - .../workaround_bad_futex_headers.patch | 25 - .../02_snapshot_use_tmpdir.patch | 23 - .../04_do_not_print_rtc_freq_if_ok.patch | 26 - .../05_non-fatal_if_linux_hd_missing.patch | 17 - .../qemu-0.9.1+svnr4027/10_signal_jobs.patch | 26 - .../22_net_tuntap_stall.patch | 18 - .../qemu-0.9.1+svnr4027/31_syscalls.patch | 48 - .../32_syscall_sysctl.patch | 55 - .../33_syscall_ppc_clone.patch | 22 - .../39_syscall_fadvise64.patch | 21 - .../41_arm_fpa_sigfpe.patch | 104 - .../61_safe_64bit_int.patch | 27 - .../qemu-0.9.1+svnr4027/65_kfreebsd.patch | 35 - .../configure_symlinkpath_fix.patch | 28 - .../qemu/qemu-0.9.1+svnr4027/fix_brk.patch | 55 - .../fix_protection_bits.patch | 14 - .../qemu-0.9.1+svnr4027/fix_segfault.patch | 37 - .../qemu-0.9.0-nptl-update.patch | 219 - .../qemu-0.9.1+svnr4027/qemu-0.9.0-nptl.patch | 854 - .../qemu-amd64-32b-mapping-0.9.0.patch | 37 - .../qemu-n800-support.patch | 13970 ---------------- meta/packages/qemu/qemu-0.9.1+svnr4027/series | 25 - .../06_exit_segfault.patch | 0 .../11_signal_sigaction.patch | 0 .../22_net_tuntap_stall.patch | 10 +- .../qemu-0.9.1+svnr6190/31_syscalls.patch | 27 + .../52_ne2000_return.patch | 0 .../63_sparc_build.patch | 0 .../64_ppc_asm_constraints.patch | 0 .../66_tls_ld.patch | 0 .../91-oh-sdl-cursor.patch | 0 .../qemu/qemu-0.9.1+svnr6190/fix-dirent.patch | 12 + .../no-strip.patch | 0 .../qemu-amd64-32b-mapping-0.9.0.patch | 32 +- meta/packages/qemu/qemu-0.9.1+svnr6190/series | 13 + .../workaround_bad_futex_headers.patch | 19 +- meta/packages/qemu/qemu_svn.bb | 18 +- 63 files changed, 84 insertions(+), 19868 deletions(-) delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/05_non-fatal_if_linux_hd_missing.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/06_exit_segfault.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/10_signal_jobs.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/11_signal_sigaction.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/31_syscalls.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/32_syscall_sysctl.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/33_syscall_ppc_clone.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/39_syscall_fadvise64.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/52_ne2000_return.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/61_safe_64bit_int.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/63_sparc_build.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/64_ppc_asm_constraints.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/65_kfreebsd.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/66_tls_ld.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/91-oh-sdl-cursor.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/configure_symlinkpath_fix.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/fix-dirent.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/fix_brk.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/fix_protection_bits.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/fix_segfault.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/no-strip.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/qemu-n800-support.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/revert_arm_tcg.patch.gz delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/series delete mode 100644 meta/packages/qemu/qemu-0.9.1+svn/workaround_bad_futex_headers.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/02_snapshot_use_tmpdir.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/04_do_not_print_rtc_freq_if_ok.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/05_non-fatal_if_linux_hd_missing.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/10_signal_jobs.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/22_net_tuntap_stall.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/31_syscalls.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/32_syscall_sysctl.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/33_syscall_ppc_clone.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/39_syscall_fadvise64.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/41_arm_fpa_sigfpe.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/61_safe_64bit_int.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/65_kfreebsd.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/configure_symlinkpath_fix.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/fix_brk.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/fix_protection_bits.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/fix_segfault.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-0.9.0-nptl-update.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-0.9.0-nptl.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-amd64-32b-mapping-0.9.0.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-n800-support.patch delete mode 100644 meta/packages/qemu/qemu-0.9.1+svnr4027/series rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/06_exit_segfault.patch (100%) rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/11_signal_sigaction.patch (100%) rename meta/packages/qemu/{qemu-0.9.1+svn => qemu-0.9.1+svnr6190}/22_net_tuntap_stall.patch (64%) create mode 100644 meta/packages/qemu/qemu-0.9.1+svnr6190/31_syscalls.patch rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/52_ne2000_return.patch (100%) rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/63_sparc_build.patch (100%) rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/64_ppc_asm_constraints.patch (100%) rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/66_tls_ld.patch (100%) rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/91-oh-sdl-cursor.patch (100%) create mode 100644 meta/packages/qemu/qemu-0.9.1+svnr6190/fix-dirent.patch rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/no-strip.patch (100%) rename meta/packages/qemu/{qemu-0.9.1+svn => qemu-0.9.1+svnr6190}/qemu-amd64-32b-mapping-0.9.0.patch (52%) create mode 100644 meta/packages/qemu/qemu-0.9.1+svnr6190/series rename meta/packages/qemu/{qemu-0.9.1+svnr4027 => qemu-0.9.1+svnr6190}/workaround_bad_futex_headers.patch (52%) diff --git a/meta/conf/distro/include/poky-fixed-revisions.inc b/meta/conf/distro/include/poky-fixed-revisions.inc index e835e66e468..92fb6ddc28d 100644 --- a/meta/conf/distro/include/poky-fixed-revisions.inc +++ b/meta/conf/distro/include/poky-fixed-revisions.inc @@ -84,7 +84,7 @@ SRCREV_pn-oprofileui ?= "194" SRCREV_pn-libowl-av = "398" SRCREV_pn-owl-video = "394" SRCREV_pn-psplash ?= "412" -QEMUSRCREV = "4242" +QEMUSRCREV = "6190" SRCREV_pn-qemu-native ?= "${QEMUSRCREV}" SRCREV_pn-qemu-sdk ?= "${QEMUSRCREV}" SRCREV_pn-qemu ?= "${QEMUSRCREV}" diff --git a/meta/packages/qemu/qemu-0.9.1+svn/05_non-fatal_if_linux_hd_missing.patch b/meta/packages/qemu/qemu-0.9.1+svn/05_non-fatal_if_linux_hd_missing.patch deleted file mode 100644 index a66737d9ce7..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/05_non-fatal_if_linux_hd_missing.patch +++ /dev/null @@ -1,17 +0,0 @@ -#DPATCHLEVEL=1 ---- -# hw/pc.c | 1 - -# 1 file changed, 1 deletion(-) -# -Index: trunk/hw/pc.c -=================================================================== ---- trunk.orig/hw/pc.c 2008-04-24 20:15:46.000000000 +0100 -+++ trunk/hw/pc.c 2008-04-24 20:15:49.000000000 +0100 -@@ -399,7 +399,6 @@ - if (hda == -1) { - fprintf(stderr, "A disk image must be given for 'hda' when booting " - "a Linux kernel\n"); -- exit(1); - } - - memset(bootsect, 0, sizeof(bootsect)); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/06_exit_segfault.patch b/meta/packages/qemu/qemu-0.9.1+svn/06_exit_segfault.patch deleted file mode 100644 index bc02d318396..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/06_exit_segfault.patch +++ /dev/null @@ -1,45 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/main.c | 8 ++++---- -# 1 file changed, 4 insertions(+), 4 deletions(-) -# -Index: linux-user/main.c -=================================================================== ---- linux-user/main.c.orig 2008-04-24 20:15:46.000000000 +0100 -+++ linux-user/main.c 2008-04-24 20:15:53.000000000 +0100 -@@ -765,7 +765,7 @@ - default: - printf ("Unhandled trap: 0x%x\n", trapnr); - cpu_dump_state(env, stderr, fprintf, 0); -- exit (1); -+ _exit (1); - } - process_pending_signals (env); - } -@@ -1697,7 +1697,7 @@ - default: - printf ("Unhandled trap: 0x%x\n", trapnr); - cpu_dump_state(env, stderr, fprintf, 0); -- exit (1); -+ _exit (1); - } - process_pending_signals (env); - } -@@ -2026,7 +2026,7 @@ - for(item = cpu_log_items; item->mask != 0; item++) { - printf("%-10s %s\n", item->name, item->help); - } -- exit(1); -+ _exit(1); - } - cpu_set_log(mask); - } else if (!strcmp(r, "s")) { -@@ -2045,7 +2045,7 @@ - if (qemu_host_page_size == 0 || - (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { - fprintf(stderr, "page size must be a power of two\n"); -- exit(1); -+ _exit(1); - } - } else if (!strcmp(r, "g")) { - gdbstub_port = atoi(argv[optind++]); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/10_signal_jobs.patch b/meta/packages/qemu/qemu-0.9.1+svn/10_signal_jobs.patch deleted file mode 100644 index d79482d2f46..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/10_signal_jobs.patch +++ /dev/null @@ -1,26 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/signal.c | 7 ++++++- -# 1 file changed, 6 insertions(+), 1 deletion(-) -# -Index: linux-user/signal.c -=================================================================== ---- linux-user/signal.c.orig 2008-04-24 20:15:46.000000000 +0100 -+++ linux-user/signal.c 2008-04-24 20:15:55.000000000 +0100 -@@ -364,10 +364,15 @@ - k = &sigact_table[sig - 1]; - handler = k->sa._sa_handler; - if (handler == TARGET_SIG_DFL) { -+ if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) { -+ kill(getpid(),SIGSTOP); -+ return 0; -+ } else - /* default handler : ignore some signal. The other are fatal */ - if (sig != TARGET_SIGCHLD && - sig != TARGET_SIGURG && -- sig != TARGET_SIGWINCH) { -+ sig != TARGET_SIGWINCH && -+ sig != TARGET_SIGCONT) { - force_sig(sig); - } else { - return 0; /* indicate ignored */ diff --git a/meta/packages/qemu/qemu-0.9.1+svn/11_signal_sigaction.patch b/meta/packages/qemu/qemu-0.9.1+svn/11_signal_sigaction.patch deleted file mode 100644 index cd56541b717..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/11_signal_sigaction.patch +++ /dev/null @@ -1,21 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/signal.c | 5 +++++ -# 1 file changed, 5 insertions(+) -# -Index: linux-user/signal.c -=================================================================== ---- linux-user/signal.c.orig 2008-04-24 20:15:55.000000000 +0100 -+++ linux-user/signal.c 2008-04-24 20:15:57.000000000 +0100 -@@ -512,6 +512,11 @@ - - if (sig < 1 || sig > TARGET_NSIG || sig == SIGKILL || sig == SIGSTOP) - return -EINVAL; -+ -+ /* no point doing the stuff as those are not allowed for sigaction */ -+ if ((sig == TARGET_SIGKILL) || (sig == TARGET_SIGSTOP)) -+ return -EINVAL; -+ - k = &sigact_table[sig - 1]; - #if defined(DEBUG_SIGNAL) - fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", diff --git a/meta/packages/qemu/qemu-0.9.1+svn/31_syscalls.patch b/meta/packages/qemu/qemu-0.9.1+svn/31_syscalls.patch deleted file mode 100644 index 15565ae11d9..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/31_syscalls.patch +++ /dev/null @@ -1,48 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/syscall.c | 11 ++++++++--- -# 1 file changed, 8 insertions(+), 3 deletions(-) -# -Index: linux-user/syscall.c -=================================================================== ---- linux-user/syscall.c.orig 2008-04-24 20:15:46.000000000 +0100 -+++ linux-user/syscall.c 2008-04-24 20:15:59.000000000 +0100 -@@ -250,6 +250,7 @@ - extern int setresgid(gid_t, gid_t, gid_t); - extern int getresgid(gid_t *, gid_t *, gid_t *); - extern int setgroups(int, gid_t *); -+extern int uselib(const char*); - - #define ERRNO_TABLE_SIZE 1200 - -@@ -4041,7 +4042,8 @@ - #endif - #ifdef TARGET_NR_uselib - case TARGET_NR_uselib: -- goto unimplemented; -+ ret = get_errno(uselib(path((const char*)arg1))); -+ break; - #endif - #ifdef TARGET_NR_swapon - case TARGET_NR_swapon: -@@ -5322,7 +5324,9 @@ - goto unimplemented; - #ifdef TARGET_NR_mincore - case TARGET_NR_mincore: -- goto unimplemented; -+ /*page_unprotect_range((void*)arg3, ((size_t)arg2 + TARGET_PAGE_SIZE - 1) / TARGET_PAGE_SIZE);*/ -+ ret = get_errno(mincore((void*)arg1, (size_t)arg2, (unsigned char*)arg3)); -+ break; - #endif - #ifdef TARGET_NR_madvise - case TARGET_NR_madvise: -@@ -5462,7 +5466,8 @@ - break; - #ifdef TARGET_NR_readahead - case TARGET_NR_readahead: -- goto unimplemented; -+ ret = get_errno(readahead((int)arg1, (off64_t)arg2, (size_t)arg3)); -+ break; - #endif - #ifdef TARGET_NR_setxattr - case TARGET_NR_setxattr: diff --git a/meta/packages/qemu/qemu-0.9.1+svn/32_syscall_sysctl.patch b/meta/packages/qemu/qemu-0.9.1+svn/32_syscall_sysctl.patch deleted file mode 100644 index d42c44cebcf..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/32_syscall_sysctl.patch +++ /dev/null @@ -1,55 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/syscall.c | 32 +++++++++++++++++++++++++++++--- -# 1 file changed, 29 insertions(+), 3 deletions(-) -# -Index: linux-user/syscall.c -=================================================================== ---- linux-user/syscall.c.orig 2008-04-24 20:15:59.000000000 +0100 -+++ linux-user/syscall.c 2008-04-24 20:16:01.000000000 +0100 -@@ -52,6 +52,7 @@ - //#include - #include - #include -+#include - - #define termios host_termios - #define winsize host_winsize -@@ -4758,9 +4759,34 @@ - break; - #endif - case TARGET_NR__sysctl: -- /* We don't implement this, but ENOTDIR is always a safe -- return value. */ -- ret = -TARGET_ENOTDIR; -+ { -+ struct __sysctl_args *args = (struct __sysctl_args *) arg1; -+ int *name_target, *name, nlen, *oldlenp, oldlen, newlen, i; -+ void *oldval, *newval; -+ -+ name_target = (int *) tswapl((long) args->name); -+ nlen = tswapl(args->nlen); -+ oldval = (void *) tswapl((long) args->oldval); -+ oldlenp = (int *) tswapl((long) args->oldlenp); -+ oldlen = tswapl(*oldlenp); -+ newval = (void *) tswapl((long) args->newval); -+ newlen = tswapl(args->newlen); -+ -+ name = alloca(nlen * sizeof (int)); -+ for (i = 0; i < nlen; i++) -+ name[i] = tswapl(name_target[i]); -+ -+ if (nlen == 2 && name[0] == CTL_KERN && name[1] == KERN_VERSION) { -+ ret = get_errno( -+ sysctl(name, nlen, oldval, &oldlen, newval, newlen)); -+ if (!is_error(ret)) { -+ *oldlenp = tswapl(oldlen); -+ } -+ } else { -+ gemu_log("qemu: Unsupported sysctl name\n"); -+ ret = -ENOSYS; -+ } -+ } - break; - case TARGET_NR_sched_setparam: - { diff --git a/meta/packages/qemu/qemu-0.9.1+svn/33_syscall_ppc_clone.patch b/meta/packages/qemu/qemu-0.9.1+svn/33_syscall_ppc_clone.patch deleted file mode 100644 index 962f821523e..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/33_syscall_ppc_clone.patch +++ /dev/null @@ -1,22 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/syscall.c | 6 +----- -# 1 file changed, 1 insertion(+), 5 deletions(-) -# -Index: linux-user/syscall.c -=================================================================== ---- linux-user/syscall.c.orig 2008-04-24 20:16:01.000000000 +0100 -+++ linux-user/syscall.c 2008-04-24 20:16:02.000000000 +0100 -@@ -2760,11 +2760,7 @@ - if (!newsp) - newsp = env->gpr[1]; - new_env->gpr[1] = newsp; -- { -- int i; -- for (i = 7; i < 32; i++) -- new_env->gpr[i] = 0; -- } -+ new_env->gpr[3] = 0; - #elif defined(TARGET_SH4) - if (!newsp) - newsp = env->gregs[15]; diff --git a/meta/packages/qemu/qemu-0.9.1+svn/39_syscall_fadvise64.patch b/meta/packages/qemu/qemu-0.9.1+svn/39_syscall_fadvise64.patch deleted file mode 100644 index 845232cfcad..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/39_syscall_fadvise64.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- - linux-user/syscall.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -Index: linux-user/syscall.c -=================================================================== ---- linux-user/syscall.c.orig 2008-04-24 20:16:02.000000000 +0100 -+++ linux-user/syscall.c 2008-04-24 20:16:03.000000000 +0100 -@@ -5350,6 +5350,12 @@ - ret = get_errno(mincore((void*)arg1, (size_t)arg2, (unsigned char*)arg3)); - break; - #endif -+#ifdef TARGET_NR_fadvise64_64 -+ case TARGET_NR_fadvise64_64: -+ /* Just return success */ -+ ret = get_errno(0); -+ break; -+#endif - #ifdef TARGET_NR_madvise - case TARGET_NR_madvise: - /* A straight passthrough may not be safe because qemu sometimes diff --git a/meta/packages/qemu/qemu-0.9.1+svn/52_ne2000_return.patch b/meta/packages/qemu/qemu-0.9.1+svn/52_ne2000_return.patch deleted file mode 100644 index e364bff7310..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/52_ne2000_return.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- - hw/ne2000.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: trunk/hw/ne2000.c -=================================================================== ---- trunk.orig/hw/ne2000.c 2008-04-24 20:15:46.000000000 +0100 -+++ trunk/hw/ne2000.c 2008-04-24 20:16:05.000000000 +0100 -@@ -217,7 +217,7 @@ - NE2000State *s = opaque; - - if (s->cmd & E8390_STOP) -- return 1; -+ return 0; - return !ne2000_buffer_full(s); - } - diff --git a/meta/packages/qemu/qemu-0.9.1+svn/61_safe_64bit_int.patch b/meta/packages/qemu/qemu-0.9.1+svn/61_safe_64bit_int.patch deleted file mode 100644 index 9a67feac6ba..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/61_safe_64bit_int.patch +++ /dev/null @@ -1,27 +0,0 @@ -#DPATCHLEVEL=0 ---- -# dyngen-exec.h | 4 ++-- -# 1 file changed, 2 insertions(+), 2 deletions(-) -# -Index: dyngen-exec.h -=================================================================== ---- dyngen-exec.h.orig 2008-04-24 20:15:46.000000000 +0100 -+++ dyngen-exec.h 2008-04-24 20:16:06.000000000 +0100 -@@ -38,7 +38,7 @@ - // Linux/Sparc64 defines uint64_t - #if !(defined (__sparc_v9__) && defined(__linux__)) - /* XXX may be done for all 64 bits targets ? */ --#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) -+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) || defined(__sparc__) - typedef unsigned long uint64_t; - #else - typedef unsigned long long uint64_t; -@@ -55,7 +55,7 @@ - typedef signed int int32_t; - // Linux/Sparc64 defines int64_t - #if !(defined (__sparc_v9__) && defined(__linux__)) --#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) -+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) || defined(__sparc__) - typedef signed long int64_t; - #else - typedef signed long long int64_t; diff --git a/meta/packages/qemu/qemu-0.9.1+svn/63_sparc_build.patch b/meta/packages/qemu/qemu-0.9.1+svn/63_sparc_build.patch deleted file mode 100644 index 097f55a09eb..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/63_sparc_build.patch +++ /dev/null @@ -1,18 +0,0 @@ -#DPATCHLEVEL=0 ---- -# sparc.ld | 2 +- -# 1 file changed, 1 insertion(+), 1 deletion(-) -# -Index: sparc.ld -=================================================================== ---- sparc.ld.orig 2008-04-24 20:15:46.000000000 +0100 -+++ sparc.ld 2008-04-24 20:16:07.000000000 +0100 -@@ -6,7 +6,7 @@ - SECTIONS - { - /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -+ . = 0x60000000 + 0x400; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } diff --git a/meta/packages/qemu/qemu-0.9.1+svn/64_ppc_asm_constraints.patch b/meta/packages/qemu/qemu-0.9.1+svn/64_ppc_asm_constraints.patch deleted file mode 100644 index 7d19817278c..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/64_ppc_asm_constraints.patch +++ /dev/null @@ -1,18 +0,0 @@ -#DPATCHLEVEL=1 ---- -# cpu-all.h | 2 +- -# 1 file changed, 1 insertion(+), 1 deletion(-) -# -Index: trunk/cpu-all.h -=================================================================== ---- trunk.orig/cpu-all.h 2008-04-24 20:15:46.000000000 +0100 -+++ trunk/cpu-all.h 2008-04-24 20:16:08.000000000 +0100 -@@ -285,7 +285,7 @@ - static inline void stl_le_p(void *ptr, int v) - { - #ifdef __powerpc__ -- __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); -+ __asm__ __volatile__ ("stwbrx %0,0,%1" : : "r" (v), "r" (ptr) : "memory"); - #else - uint8_t *p = ptr; - p[0] = v; diff --git a/meta/packages/qemu/qemu-0.9.1+svn/65_kfreebsd.patch b/meta/packages/qemu/qemu-0.9.1+svn/65_kfreebsd.patch deleted file mode 100644 index 028e85a878e..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/65_kfreebsd.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- - configure | 6 ++++++ - vl.c | 2 ++ - 2 files changed, 8 insertions(+) - -Index: configure -=================================================================== ---- configure.orig 2008-04-24 20:15:46.000000000 +0100 -+++ configure 2008-04-24 20:16:09.000000000 +0100 -@@ -135,6 +135,12 @@ - kqemu="yes" - fi - ;; -+GNU/kFreeBSD) -+oss="yes" -+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then -+ kqemu="yes" -+fi -+;; - FreeBSD) - bsd="yes" - oss="yes" -Index: vl.c -=================================================================== ---- vl.c.orig 2008-04-24 20:15:58.000000000 +0100 -+++ vl.c 2008-04-24 20:16:09.000000000 +0100 -@@ -97,6 +97,8 @@ - #include - #endif - #endif -+#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__) -+#include - #else - #include - int inet_aton(const char *cp, struct in_addr *ia); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/66_tls_ld.patch b/meta/packages/qemu/qemu-0.9.1+svn/66_tls_ld.patch deleted file mode 100644 index cbd3f873d87..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/66_tls_ld.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- - arm.ld | 7 +++++++ - i386.ld | 7 +++++++ - 2 files changed, 14 insertions(+) - -Index: arm.ld -=================================================================== ---- arm.ld.orig 2008-04-24 20:15:45.000000000 +0100 -+++ arm.ld 2008-04-24 20:16:11.000000000 +0100 -@@ -26,6 +26,10 @@ - { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } - .rela.rodata : - { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } -+ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -+ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -+ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -+ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } -@@ -58,6 +62,9 @@ - .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } - __exidx_end = .; - .reginfo : { *(.reginfo) } -+ /* Thread Local Storage sections */ -+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN(0x100000) + (. & (0x100000 - 1)); -Index: i386.ld -=================================================================== ---- i386.ld.orig 2008-04-24 20:15:45.000000000 +0100 -+++ i386.ld 2008-04-24 20:16:11.000000000 +0100 -@@ -28,6 +28,10 @@ - { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } - .rela.rodata : - { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } -+ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -+ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -+ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -+ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } -@@ -53,6 +57,9 @@ - _etext = .; - PROVIDE (etext = .); - .fini : { *(.fini) } =0x47ff041f -+ /* Thread Local Storage sections */ -+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - . = ALIGN(32 / 8); - PROVIDE (__preinit_array_start = .); - .preinit_array : { *(.preinit_array) } diff --git a/meta/packages/qemu/qemu-0.9.1+svn/91-oh-sdl-cursor.patch b/meta/packages/qemu/qemu-0.9.1+svn/91-oh-sdl-cursor.patch deleted file mode 100644 index b3d95a45346..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/91-oh-sdl-cursor.patch +++ /dev/null @@ -1,18 +0,0 @@ -=== modified file 'sdl.c' ---- - sdl.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -Index: sdl.c -=================================================================== ---- sdl.c.orig 2008-04-24 20:15:45.000000000 +0100 -+++ sdl.c 2008-04-24 20:16:12.000000000 +0100 -@@ -247,7 +247,7 @@ - - if (kbd_mouse_is_absolute()) { - SDL_ShowCursor(1); -- SDL_SetCursor(sdl_cursor_hidden); -+ /* SDL_SetCursor(sdl_cursor_hidden); */ - } else { - SDL_ShowCursor(0); - } diff --git a/meta/packages/qemu/qemu-0.9.1+svn/configure_symlinkpath_fix.patch b/meta/packages/qemu/qemu-0.9.1+svn/configure_symlinkpath_fix.patch deleted file mode 100644 index 3ec304a38c9..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/configure_symlinkpath_fix.patch +++ /dev/null @@ -1,28 +0,0 @@ -Index: qemu-0.9.1/configure -=================================================================== ---- qemu-0.9.1.orig/configure 2008-01-24 15:33:13.000000000 +0000 -+++ qemu-0.9.1/configure 2008-01-24 15:45:50.000000000 +0000 -@@ -209,15 +209,17 @@ - - # find source path - source_path=`dirname "$0"` -+source_path_used="no" -+workdir=`pwd` -+workdir=`readlink -f $workdir` - if [ -z "$source_path" ]; then -- source_path=`pwd` -+ source_path=$workdir - else - source_path=`cd "$source_path"; pwd` --fi --if test "$source_path" = `pwd` ; then -- source_path_used="no" --else -- source_path_used="yes" -+ source_path=`readlink -f $source_path` -+ if test "$source_path" != "$workdir" ; then -+ source_path_used="yes" -+ fi - fi - - werror="no" diff --git a/meta/packages/qemu/qemu-0.9.1+svn/fix-dirent.patch b/meta/packages/qemu/qemu-0.9.1+svn/fix-dirent.patch deleted file mode 100644 index 9282ac47799..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/fix-dirent.patch +++ /dev/null @@ -1,20 +0,0 @@ -Index: trunk/linux-user/syscall.c -=================================================================== ---- trunk.orig/linux-user/syscall.c 2008-11-10 10:58:07.000000000 +0000 -+++ trunk/linux-user/syscall.c 2008-11-10 11:00:37.000000000 +0000 -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -76,7 +77,6 @@ - #include - #include - #include --#include - #include - - #include "qemu.h" diff --git a/meta/packages/qemu/qemu-0.9.1+svn/fix_brk.patch b/meta/packages/qemu/qemu-0.9.1+svn/fix_brk.patch deleted file mode 100644 index f15e001dd68..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/fix_brk.patch +++ /dev/null @@ -1,59 +0,0 @@ -Index: trunk/linux-user/syscall.c -=================================================================== ---- trunk.orig/linux-user/syscall.c 2008-04-24 20:16:24.000000000 +0100 -+++ trunk/linux-user/syscall.c 2008-04-24 20:16:32.000000000 +0100 -@@ -440,7 +440,7 @@ - if (!new_brk) - return target_brk; - if (new_brk < target_original_brk) -- return -TARGET_ENOMEM; -+ return target_brk; - - brk_page = HOST_PAGE_ALIGN(target_brk); - -@@ -455,12 +455,11 @@ - mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, - PROT_READ|PROT_WRITE, - MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); -- if (is_error(mapped_addr)) { -- return mapped_addr; -- } else { -+ -+ if (!is_error(mapped_addr)) - target_brk = new_brk; -- return target_brk; -- } -+ -+ return target_brk; - } - - static inline abi_long copy_from_user_fdset(fd_set *fds, -Index: trunk/linux-user/mmap.c -=================================================================== ---- trunk.orig/linux-user/mmap.c 2008-04-24 20:16:16.000000000 +0100 -+++ trunk/linux-user/mmap.c 2008-04-24 20:16:32.000000000 +0100 -@@ -264,6 +264,9 @@ - host_start += offset - host_offset; - start = h2g(host_start); - } else { -+ int flg; -+ target_ulong addr; -+ - if (start & ~TARGET_PAGE_MASK) { - errno = EINVAL; - return -1; -@@ -271,6 +274,14 @@ - end = start + len; - real_end = HOST_PAGE_ALIGN(end); - -+ for(addr = real_start; addr < real_end; addr += TARGET_PAGE_SIZE) { -+ flg = page_get_flags(addr); -+ if( flg & PAGE_RESERVED ) { -+ errno = ENXIO; -+ return -1; -+ } -+ } -+ - /* worst case: we cannot map the file because the offset is not - aligned, so we read it */ - if (!(flags & MAP_ANONYMOUS) && diff --git a/meta/packages/qemu/qemu-0.9.1+svn/fix_protection_bits.patch b/meta/packages/qemu/qemu-0.9.1+svn/fix_protection_bits.patch deleted file mode 100644 index ee2b077602f..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/fix_protection_bits.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: qemu-0.9.1/linux-user/mmap.c -=================================================================== ---- qemu-0.9.1.orig/linux-user/mmap.c 2008-04-16 14:10:26.000000000 +0100 -+++ qemu-0.9.1/linux-user/mmap.c 2008-04-16 14:10:51.000000000 +0100 -@@ -49,8 +49,7 @@ - end = start + len; - if (end < start) - return -EINVAL; -- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) -- return -EINVAL; -+ prot = prot & (PROT_READ | PROT_WRITE | PROT_EXEC); - if (len == 0) - return 0; - diff --git a/meta/packages/qemu/qemu-0.9.1+svn/fix_segfault.patch b/meta/packages/qemu/qemu-0.9.1+svn/fix_segfault.patch deleted file mode 100644 index 224a8b813d6..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/fix_segfault.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- - linux-user/syscall.c | 22 ---------------------- - 1 file changed, 22 deletions(-) - -Index: trunk/linux-user/syscall.c -=================================================================== ---- trunk.orig/linux-user/syscall.c 2008-04-24 20:16:21.000000000 +0100 -+++ trunk/linux-user/syscall.c 2008-04-24 20:16:24.000000000 +0100 -@@ -5728,28 +5728,6 @@ - goto unimplemented_nowarn; - #endif - --#ifdef TARGET_NR_clock_gettime -- case TARGET_NR_clock_gettime: -- { -- struct timespec ts; -- ret = get_errno(clock_gettime(arg1, &ts)); -- if (!is_error(ret)) { -- host_to_target_timespec(arg2, &ts); -- } -- break; -- } --#endif --#ifdef TARGET_NR_clock_getres -- case TARGET_NR_clock_getres: -- { -- struct timespec ts; -- ret = get_errno(clock_getres(arg1, &ts)); -- if (!is_error(ret)) { -- host_to_target_timespec(arg2, &ts); -- } -- break; -- } --#endif - - #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) - case TARGET_NR_set_tid_address: diff --git a/meta/packages/qemu/qemu-0.9.1+svn/no-strip.patch b/meta/packages/qemu/qemu-0.9.1+svn/no-strip.patch deleted file mode 100644 index 4813dd4e2b0..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/no-strip.patch +++ /dev/null @@ -1,26 +0,0 @@ -Index: trunk/Makefile -=================================================================== ---- trunk.orig/Makefile 2008-04-24 20:15:37.000000000 +0100 -+++ trunk/Makefile 2008-04-24 20:16:30.000000000 +0100 -@@ -196,7 +196,7 @@ - install: all $(if $(BUILD_DOCS),install-doc) - mkdir -p "$(DESTDIR)$(bindir)" - ifneq ($(TOOLS),) -- $(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)" -+ $(INSTALL) -m 755 $(TOOLS) "$(DESTDIR)$(bindir)" - endif - mkdir -p "$(DESTDIR)$(datadir)" - set -e; for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \ -Index: trunk/Makefile.target -=================================================================== ---- trunk.orig/Makefile.target 2008-04-24 20:15:37.000000000 +0100 -+++ trunk/Makefile.target 2008-04-24 20:16:30.000000000 +0100 -@@ -685,7 +685,7 @@ - - install: all - ifneq ($(PROGS),) -- $(INSTALL) -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)" -+ $(INSTALL) -m 755 $(PROGS) "$(DESTDIR)$(bindir)" - endif - - # Include automatically generated dependency files diff --git a/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch b/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch deleted file mode 100644 index ac68ebf460e..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch +++ /dev/null @@ -1,1100 +0,0 @@ ---- - configure | 25 ++++++ - exec-all.h | 165 ------------------------------------------ - linux-user/arm/syscall.h | 4 - - linux-user/main.c | 94 +++++++++++++++++++++--- - linux-user/qemu.h | 3 - linux-user/syscall.c | 91 ++++++++++++++++++++++- - qemu_spinlock.h | 181 +++++++++++++++++++++++++++++++++++++++++++++++ - target-arm/cpu.h | 10 ++ - target-arm/op.c | 6 + - target-arm/translate.c | 9 ++ - 10 files changed, 405 insertions(+), 183 deletions(-) - -Index: trunk/configure -=================================================================== ---- trunk.orig/configure 2008-04-24 20:16:52.000000000 +0100 -+++ trunk/configure 2008-04-24 20:16:53.000000000 +0100 -@@ -112,6 +112,7 @@ - build_docs="no" - uname_release="" - curses="yes" -+nptl="yes" - - # OS specific - targetos=`uname -s` -@@ -339,6 +340,8 @@ - ;; - *) echo "ERROR: unknown option $opt"; show_help="yes" - ;; -+ --disable-nptl) nptl="no" -+ ;; - esac - done - -@@ -436,6 +439,7 @@ - echo " --disable-linux-user disable all linux usermode emulation targets" - echo " --enable-darwin-user enable all darwin usermode emulation targets" - echo " --disable-darwin-user disable all darwin usermode emulation targets" -+echo " --disable-nptl disable usermode NPTL guest support" - echo " --fmod-lib path to FMOD library" - echo " --fmod-inc path to FMOD includes" - echo " --enable-uname-release=R Return R for uname -r in usermode emulation" -@@ -647,6 +651,23 @@ - } - EOF - -+# check NPTL support -+cat > $TMPC < -+void foo() -+{ -+#ifndef CLONE_SETTLS -+#error bork -+#endif -+} -+EOF -+ -+if $cc -c -o $TMPO $TMPC 2> /dev/null ; then -+ : -+else -+ nptl="no" -+fi -+ - ########################################## - # SDL probe - -@@ -845,6 +866,7 @@ - echo "Documentation $build_docs" - [ ! -z "$uname_release" ] && \ - echo "uname -r $uname_release" -+echo "NPTL support $nptl" - - if test $sdl_too_old = "yes"; then - echo "-> Your SDL version is too old - please upgrade to have SDL support" -@@ -1228,6 +1250,9 @@ - echo "#define TARGET_ARM 1" >> $config_h - echo "#define CONFIG_NO_DYNGEN_OP 1" >> $config_h - bflt="yes" -+ if test "$nptl" = "yes" ; then -+ echo "#define USE_NPTL 1" >> $config_h -+ fi - ;; - cris) - echo "TARGET_ARCH=cris" >> $config_mak -Index: trunk/exec-all.h -=================================================================== ---- trunk.orig/exec-all.h 2008-04-24 20:16:41.000000000 +0100 -+++ trunk/exec-all.h 2008-04-24 20:16:53.000000000 +0100 -@@ -303,217 +303,7 @@ - extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; - extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; - --#if defined(__hppa__) -- --typedef int spinlock_t[4]; -- --#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } -- --static inline void resetlock (spinlock_t *p) --{ -- (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; --} -- --#else -- --typedef int spinlock_t; -- --#define SPIN_LOCK_UNLOCKED 0 -- --static inline void resetlock (spinlock_t *p) --{ -- *p = SPIN_LOCK_UNLOCKED; --} -- --#endif -- --#if defined(__powerpc__) --static inline int testandset (int *p) --{ -- int ret; -- __asm__ __volatile__ ( -- "0: lwarx %0,0,%1\n" -- " xor. %0,%3,%0\n" -- " bne 1f\n" -- " stwcx. %2,0,%1\n" -- " bne- 0b\n" -- "1: " -- : "=&r" (ret) -- : "r" (p), "r" (1), "r" (0) -- : "cr0", "memory"); -- return ret; --} --#elif defined(__i386__) --static inline int testandset (int *p) --{ -- long int readval = 0; -- -- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" -- : "+m" (*p), "+a" (readval) -- : "r" (1) -- : "cc"); -- return readval; --} --#elif defined(__x86_64__) --static inline int testandset (int *p) --{ -- long int readval = 0; -- -- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" -- : "+m" (*p), "+a" (readval) -- : "r" (1) -- : "cc"); -- return readval; --} --#elif defined(__s390__) --static inline int testandset (int *p) --{ -- int ret; -- -- __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" -- " jl 0b" -- : "=&d" (ret) -- : "r" (1), "a" (p), "0" (*p) -- : "cc", "memory" ); -- return ret; --} --#elif defined(__alpha__) --static inline int testandset (int *p) --{ -- int ret; -- unsigned long one; -- -- __asm__ __volatile__ ("0: mov 1,%2\n" -- " ldl_l %0,%1\n" -- " stl_c %2,%1\n" -- " beq %2,1f\n" -- ".subsection 2\n" -- "1: br 0b\n" -- ".previous" -- : "=r" (ret), "=m" (*p), "=r" (one) -- : "m" (*p)); -- return ret; --} --#elif defined(__sparc__) --static inline int testandset (int *p) --{ -- int ret; -- -- __asm__ __volatile__("ldstub [%1], %0" -- : "=r" (ret) -- : "r" (p) -- : "memory"); -- -- return (ret ? 1 : 0); --} --#elif defined(__arm__) --static inline int testandset (int *spinlock) --{ -- register unsigned int ret; -- __asm__ __volatile__("swp %0, %1, [%2]" -- : "=r"(ret) -- : "0"(1), "r"(spinlock)); -- -- return ret; --} --#elif defined(__mc68000) --static inline int testandset (int *p) --{ -- char ret; -- __asm__ __volatile__("tas %1; sne %0" -- : "=r" (ret) -- : "m" (p) -- : "cc","memory"); -- return ret; --} --#elif defined(__hppa__) -- --/* Because malloc only guarantees 8-byte alignment for malloc'd data, -- and GCC only guarantees 8-byte alignment for stack locals, we can't -- be assured of 16-byte alignment for atomic lock data even if we -- specify "__attribute ((aligned(16)))" in the type declaration. So, -- we use a struct containing an array of four ints for the atomic lock -- type and dynamically select the 16-byte aligned int from the array -- for the semaphore. */ --#define __PA_LDCW_ALIGNMENT 16 --static inline void *ldcw_align (void *p) { -- unsigned long a = (unsigned long)p; -- a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); -- return (void *)a; --} -- --static inline int testandset (spinlock_t *p) --{ -- unsigned int ret; -- p = ldcw_align(p); -- __asm__ __volatile__("ldcw 0(%1),%0" -- : "=r" (ret) -- : "r" (p) -- : "memory" ); -- return !ret; --} -- --#elif defined(__ia64) -- --#include -- --static inline int testandset (int *p) --{ -- return __sync_lock_test_and_set (p, 1); --} --#elif defined(__mips__) --static inline int testandset (int *p) --{ -- int ret; -- -- __asm__ __volatile__ ( -- " .set push \n" -- " .set noat \n" -- " .set mips2 \n" -- "1: li $1, 1 \n" -- " ll %0, %1 \n" -- " sc $1, %1 \n" -- " beqz $1, 1b \n" -- " .set pop " -- : "=r" (ret), "+R" (*p) -- : -- : "memory"); -- -- return ret; --} --#else --#error unimplemented CPU support --#endif -- --#if defined(CONFIG_USER_ONLY) --static inline void spin_lock(spinlock_t *lock) --{ -- while (testandset(lock)); --} -- --static inline void spin_unlock(spinlock_t *lock) --{ -- resetlock(lock); --} -- --static inline int spin_trylock(spinlock_t *lock) --{ -- return !testandset(lock); --} --#else --static inline void spin_lock(spinlock_t *lock) --{ --} -- --static inline void spin_unlock(spinlock_t *lock) --{ --} -- --static inline int spin_trylock(spinlock_t *lock) --{ -- return 1; --} --#endif -+#include "qemu_spinlock.h" - - extern spinlock_t tb_lock; - -Index: trunk/linux-user/arm/syscall.h -=================================================================== ---- trunk.orig/linux-user/arm/syscall.h 2008-04-24 20:16:41.000000000 +0100 -+++ trunk/linux-user/arm/syscall.h 2008-04-24 20:16:53.000000000 +0100 -@@ -28,7 +28,9 @@ - #define ARM_SYSCALL_BASE 0x900000 - #define ARM_THUMB_SYSCALL 0 - --#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2) -+#define ARM_NR_BASE 0xf0000 -+#define ARM_NR_cacheflush (ARM_NR_BASE + 2) -+#define ARM_NR_set_tls (ARM_NR_BASE + 5) - - #define ARM_NR_semihosting 0x123456 - #define ARM_NR_thumb_semihosting 0xAB -Index: trunk/linux-user/main.c -=================================================================== ---- trunk.orig/linux-user/main.c 2008-04-24 20:16:47.000000000 +0100 -+++ trunk/linux-user/main.c 2008-04-24 20:17:38.000000000 +0100 -@@ -365,6 +365,50 @@ - } - } - -+/* Handle a jump to the kernel code page. */ -+static int -+do_kernel_trap(CPUARMState *env) -+{ -+ uint32_t addr; -+ uint32_t *ptr; -+ uint32_t cpsr; -+ -+ switch (env->regs[15]) { -+ case 0xffff0fc0: /* __kernel_cmpxchg */ -+ /* XXX: This only works between threads, not between processes. -+ Use native atomic operations. */ -+ /* ??? This probably breaks horribly if the access segfaults. */ -+ cpu_lock(); -+ ptr = (uint32_t *)env->regs[2]; -+ cpsr = cpsr_read(env); -+ if (*ptr == env->regs[0]) { -+ *ptr = env->regs[1]; -+ env->regs[0] = 0; -+ cpsr |= CPSR_C; -+ } else { -+ env->regs[0] = -1; -+ cpsr &= ~CPSR_C; -+ } -+ cpsr_write(env, cpsr, CPSR_C); -+ cpu_unlock(); -+ break; -+ case 0xffff0fe0: /* __kernel_get_tls */ -+ env->regs[0] = env->cp15.c13_tls2; -+ break; -+ default: -+ return 1; -+ } -+ /* Jump back to the caller. */ -+ addr = env->regs[14]; -+ if (addr & 1) { -+ env->thumb = 1; -+ addr &= ~1; -+ } -+ env->regs[15] = addr; -+ -+ return 0; -+} -+ - void cpu_loop(CPUARMState *env) - { - int trapnr; -@@ -475,10 +519,8 @@ - } - } - -- if (n == ARM_NR_cacheflush) { -- arm_cache_flush(env->regs[0], env->regs[1]); -- } else if (n == ARM_NR_semihosting -- || n == ARM_NR_thumb_semihosting) { -+ if (n == ARM_NR_semihosting -+ || n == ARM_NR_thumb_semihosting) { - env->regs[0] = do_arm_semihosting (env); - } else if (n == 0 || n >= ARM_SYSCALL_BASE - || (env->thumb && n == ARM_THUMB_SYSCALL)) { -@@ -489,14 +531,34 @@ - n -= ARM_SYSCALL_BASE; - env->eabi = 0; - } -- env->regs[0] = do_syscall(env, -- n, -- env->regs[0], -- env->regs[1], -- env->regs[2], -- env->regs[3], -- env->regs[4], -- env->regs[5]); -+ if ( n > ARM_NR_BASE) { -+ switch (n) -+ { -+ case ARM_NR_cacheflush: -+ arm_cache_flush(env->regs[0], env->regs[1]); -+ break; -+#ifdef USE_NPTL -+ case ARM_NR_set_tls: -+ cpu_set_tls(env, env->regs[0]); -+ env->regs[0] = 0; -+ break; -+#endif -+ default: -+ printf ("Error: Bad syscall: %x\n", n); -+ goto error; -+ } -+ } -+ else -+ { -+ env->regs[0] = do_syscall(env, -+ n, -+ env->regs[0], -+ env->regs[1], -+ env->regs[2], -+ env->regs[3], -+ env->regs[4], -+ env->regs[5]); -+ } - } else { - goto error; - } -@@ -535,6 +597,10 @@ - } - } - break; -+ case EXCP_KERNEL_TRAP: -+ if (do_kernel_trap(env)) -+ goto error; -+ break; - default: - error: - fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", -@@ -1994,6 +2060,11 @@ - int drop_ld_preload = 0, environ_count = 0; - char **target_environ, **wrk, **dst; - -+ char *assume_kernel = getenv("QEMU_ASSUME_KERNEL"); -+ -+ if (assume_kernel) -+ setenv("LD_ASSUME_KERNEL", assume_kernel, 1); -+ - if (argc <= 1) - usage(); - -@@ -2403,6 +2474,10 @@ - ts->heap_base = info->brk; - /* This will be filled in on the first SYS_HEAPINFO call. */ - ts->heap_limit = 0; -+ /* Register the magic kernel code page. The cpu will generate a -+ special exception when it tries to execute code here. We can't -+ put real code here because it may be in use by the host kernel. */ -+ page_set_flags(0xffff0000, 0xffff0fff, 0); - #endif - - if (gdbstub_port) { -Index: trunk/linux-user/qemu.h -=================================================================== ---- trunk.orig/linux-user/qemu.h 2008-04-24 20:16:41.000000000 +0100 -+++ trunk/linux-user/qemu.h 2008-04-24 20:16:53.000000000 +0100 -@@ -107,6 +107,9 @@ - uint32_t heap_base; - uint32_t heap_limit; - #endif -+#ifdef USE_NPTL -+ uint32_t *child_tidptr; -+#endif - int used; /* non zero if used */ - struct image_info *info; - uint8_t stack[0]; -Index: trunk/linux-user/syscall.c -=================================================================== ---- trunk.orig/linux-user/syscall.c 2008-04-24 20:16:50.000000000 +0100 -+++ trunk/linux-user/syscall.c 2008-04-24 20:19:52.000000000 +0100 -@@ -61,6 +61,7 @@ - #define tchars host_tchars /* same as target */ - #define ltchars host_ltchars /* same as target */ - -+#include - #include - #include - #include -@@ -71,9 +72,18 @@ - #include - - #include "qemu.h" -+#include "qemu_spinlock.h" - - //#define DEBUG - -+#ifdef USE_NPTL -+#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \ -+ CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID) -+#else -+/* XXX: Hardcode the above values. */ -+#define CLONE_NPTL_FLAGS2 0 -+#endif -+ - #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ - || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) - /* 16 bit uid wrappers emulation */ -@@ -2695,16 +2705,25 @@ - return 0; - } - #endif -- - #endif /* defined(TARGET_I386) */ - - /* this stack is the equivalent of the kernel stack associated with a - thread/process */ - #define NEW_STACK_SIZE 8192 - -+#ifdef USE_NPTL -+static spinlock_t nptl_lock = SPIN_LOCK_UNLOCKED; -+#endif -+ - static int clone_func(void *arg) - { - CPUState *env = arg; -+#ifdef HAVE_NPTL -+ /* Wait until the parent has finshed initializing the tls state. */ -+ while (!spin_trylock(&nptl_lock)) -+ usleep(1); -+ spin_unlock(&nptl_lock); -+#endif - cpu_loop(env); - /* never exits */ - return 0; -@@ -2712,15 +2731,27 @@ - - /* do_fork() Must return host values and target errnos (unlike most - do_*() functions). */ --int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) -+int do_fork(CPUState *env, unsigned int flags, unsigned long newsp, -+ uint32_t *parent_tidptr, void *newtls, -+ uint32_t *child_tidptr) - { - int ret; - TaskState *ts; - uint8_t *new_stack; - CPUState *new_env; -+#if defined(TARGET_I386) -+ uint64_t *new_gdt_table; -+#endif -+#ifdef USE_NPTL -+ unsigned int nptl_flags; - -+ if (flags & CLONE_PARENT_SETTID) -+ *parent_tidptr = gettid(); -+#endif - if (flags & CLONE_VM) { - ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); -+ if (!ts) -+ return -ENOMEM; - memset(ts, 0, sizeof(TaskState)); - new_stack = ts->stack; - ts->used = 1; -@@ -2732,6 +2763,29 @@ - #if defined(TARGET_I386) - if (!newsp) - newsp = env->regs[R_ESP]; -+ new_gdt_table = malloc(9 * 8); -+ if (!new_gdt_table) { -+ free(new_env); -+ return -ENOMEM; -+ } -+ /* Copy main GDT table from parent, but clear TLS entries */ -+ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); -+ memset(&new_gdt_table[6], 0, 3 * 8); -+ new_env->gdt.base = h2g(new_gdt_table); -+ if (flags & 0x00080000 /* CLONE_SETTLS */) { -+ ret = do_set_thread_area(new_env, new_env->regs[R_ESI]); -+ if (ret) { -+ free(new_gdt_table); -+ free(new_env); -+ return ret; -+ } -+ } -+ cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]); -+ cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]); -+ cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]); -+ cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]); -+ cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]); -+ cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]); - new_env->regs[R_ESP] = newsp; - new_env->regs[R_EAX] = 0; - #elif defined(TARGET_ARM) -@@ -2784,16 +2838,67 @@ - #error unsupported target CPU - #endif - new_env->opaque = ts; -+#ifdef USE_NPTL -+ nptl_flags = flags; -+ flags &= ~CLONE_NPTL_FLAGS2; -+ -+ if (nptl_flags & CLONE_CHILD_CLEARTID) { -+ ts->child_tidptr = child_tidptr; -+ } -+ -+ if (nptl_flags & CLONE_SETTLS) -+ cpu_set_tls (new_env, newtls); -+ -+ /* Grab the global cpu lock so that the thread setup appears -+ atomic. */ -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ spin_lock(&nptl_lock); -+ -+#else -+ if (flags & CLONE_NPTL_FLAGS2) -+ return -EINVAL; -+#endif -+ -+ if (CLONE_VFORK & flags) -+ flags ^= CLONE_VM; - #ifdef __ia64__ - ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); - #else - ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); - #endif -+#ifdef USE_NPTL -+ if (ret != -1) { -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ *child_tidptr = ret; -+ } -+ -+ /* Allow the child to continue. */ -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ spin_unlock(&nptl_lock); -+#endif - } else { - /* if no CLONE_VM, we consider it is a fork */ -- if ((flags & ~CSIGNAL) != 0) -+ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) - return -EINVAL; - ret = fork(); -+#ifdef USE_NPTL -+ /* There is a race condition here. The parent process could -+ theoretically read the TID in the child process before the child -+ tid is set. This would require using either ptrace -+ (not implemented) or having *_tidptr to point at a shared memory -+ mapping. We can't repeat the spinlock hack used above because -+ the child process gets its own copy of the lock. */ -+ if (ret == 0) { -+ /* Child Process. */ -+ if (flags & CLONE_CHILD_SETTID) -+ *child_tidptr = gettid(); -+ ts = (TaskState *)env->opaque; -+ if (flags & CLONE_CHILD_CLEARTID) -+ ts->child_tidptr = child_tidptr; -+ if (flags & CLONE_SETTLS) -+ cpu_set_tls (env, newtls); -+ } -+#endif - } - return ret; - } -@@ -3052,6 +3157,68 @@ - unlock_user_struct(target_ts, target_addr, 1); - } - -+static long do_futex(target_ulong uaddr, int op, uint32_t val, -+ target_ulong utime, target_ulong uaddr2, -+ uint32_t val3) -+{ -+ struct timespec host_utime; -+ unsigned long val2 = utime; -+ -+ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { -+ target_to_host_timespec(&host_utime, utime); -+ val2 = (unsigned long)&host_utime; -+ } -+ -+#ifdef BSWAP_NEEDED -+ switch(op) { -+ case FUTEX_CMP_REQUEUE: -+ val3 = tswap32(val3); -+ case FUTEX_REQUEUE: -+ val2 = tswap32(val2); -+ case FUTEX_WAIT: -+ case FUTEX_WAKE: -+ val = tswap32(val); -+ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ -+ case FUTEX_UNLOCK_PI: -+ break; -+ default: -+ gemu_log("qemu: Unsupported futex op %d\n", op); -+ return -ENOSYS; -+ } -+#if 0 /* No, it's worse than this */ -+ if (op == FUTEX_WAKE_OP) { -+ /* Need to munge the secondary operation (val3) */ -+ val3 = tswap32(val3); -+ int op2 = (val3 >> 28) & 7; -+ int cmp = (val3 >> 24) & 15; -+ int oparg = (val3 << 8) >> 20; -+ int cmparg = (val3 << 20) >> 20; -+ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); -+ -+ if (shift) -+ oparg = (oparg & 7) + 24 - (oparg & 24); -+ else oparg = -+ if (op2 == FUTEX_OP_ADD) { -+ gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n"); -+ return -ENOSYS; -+ } -+ if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE || -+ cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) { -+ gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg); -+ return -ENOSYS; -+ } -+ val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg; -+ } -+#endif -+#endif -+ return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); -+} -+ -+int do_set_tid_address(target_ulong tidptr) -+{ -+ return syscall(__NR_set_tid_address, g2h(tidptr)); -+} -+ - /* do_syscall() should always have a single exit point at the end so - that actions, such as logging of syscall results, can be performed. - All errnos that do_syscall() returns must be -TARGET_. */ -@@ -3076,7 +3243,7 @@ - _mcleanup(); - #endif - gdb_exit(cpu_env, arg1); -- /* XXX: should free thread stack and CPU env */ -+ /* XXX: should free thread stack, GDT and CPU env */ - _exit(arg1); - ret = 0; /* avoid warning */ - break; -@@ -3118,7 +3285,7 @@ - ret = do_brk(arg1); - break; - case TARGET_NR_fork: -- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); -+ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, NULL, NULL, NULL)); - break; - #ifdef TARGET_NR_waitpid - case TARGET_NR_waitpid: -@@ -4482,7 +4649,8 @@ - ret = get_errno(fsync(arg1)); - break; - case TARGET_NR_clone: -- ret = get_errno(do_fork(cpu_env, arg1, arg2)); -+ ret = get_errno(do_fork(cpu_env, arg1, arg2, (uint32_t *)arg3, -+ (void *)arg4, (uint32_t *)arg5)); - break; - #ifdef __NR_exit_group - /* new thread calls */ -@@ -4943,7 +5111,8 @@ - #endif - #ifdef TARGET_NR_vfork - case TARGET_NR_vfork: -- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); -+ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, -+ NULL, NULL, NULL)); - break; - #endif - #ifdef TARGET_NR_ugetrlimit -@@ -5521,6 +5690,9 @@ - #elif defined(TARGET_I386) && defined(TARGET_ABI32) - ret = do_set_thread_area(cpu_env, arg1); - break; -+#elif TARGET_i386 -+ ret = get_errno(do_set_thread_area(cpu_env, arg1)); -+ break; - #else - goto unimplemented_nowarn; - #endif -@@ -5538,6 +5710,12 @@ - goto unimplemented_nowarn; - #endif - -+#ifdef TARGET_NR_futex -+ case TARGET_NR_futex: -+ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6)); -+ break; -+#endif -+ - #ifdef TARGET_NR_clock_gettime - case TARGET_NR_clock_gettime: - { -Index: trunk/qemu_spinlock.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ trunk/qemu_spinlock.h 2008-04-24 20:16:53.000000000 +0100 -@@ -0,0 +1,250 @@ -+/* -+ * Atomic operation helper include -+ * -+ * Copyright (c) 2005 Fabrice Bellard -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+#ifndef QEMU_SPINLOCK_H -+#define QEMU_SPINLOCK_H -+ -+#ifdef __powerpc__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ __asm__ __volatile__ ( -+ "0: lwarx %0,0,%1\n" -+ " xor. %0,%3,%0\n" -+ " bne 1f\n" -+ " stwcx. %2,0,%1\n" -+ " bne- 0b\n" -+ "1: " -+ : "=&r" (ret) -+ : "r" (p), "r" (1), "r" (0) -+ : "cr0", "memory"); -+ return ret; -+} -+#endif -+ -+#ifdef __i386__ -+static inline int testandset (int *p) -+{ -+ long int readval = 0; -+ -+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" -+ : "+m" (*p), "+a" (readval) -+ : "r" (1) -+ : "cc"); -+ return readval; -+} -+#endif -+ -+#ifdef __x86_64__ -+static inline int testandset (int *p) -+{ -+ long int readval = 0; -+ -+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" -+ : "+m" (*p), "+a" (readval) -+ : "r" (1) -+ : "cc"); -+ return readval; -+} -+#endif -+ -+#ifdef __s390__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ -+ __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" -+ " jl 0b" -+ : "=&d" (ret) -+ : "r" (1), "a" (p), "0" (*p) -+ : "cc", "memory" ); -+ return ret; -+} -+#endif -+ -+#ifdef __alpha__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ unsigned long one; -+ -+ __asm__ __volatile__ ("0: mov 1,%2\n" -+ " ldl_l %0,%1\n" -+ " stl_c %2,%1\n" -+ " beq %2,1f\n" -+ ".subsection 2\n" -+ "1: br 0b\n" -+ ".previous" -+ : "=r" (ret), "=m" (*p), "=r" (one) -+ : "m" (*p)); -+ return ret; -+} -+#endif -+ -+#ifdef __sparc__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ -+ __asm__ __volatile__("ldstub [%1], %0" -+ : "=r" (ret) -+ : "r" (p) -+ : "memory"); -+ -+ return (ret ? 1 : 0); -+} -+#endif -+ -+#ifdef __arm__ -+static inline int testandset (int *spinlock) -+{ -+ register unsigned int ret; -+ __asm__ __volatile__("swp %0, %1, [%2]" -+ : "=r"(ret) -+ : "0"(1), "r"(spinlock)); -+ -+ return ret; -+} -+#endif -+ -+#ifdef __mc68000 -+static inline int testandset (int *p) -+{ -+ char ret; -+ __asm__ __volatile__("tas %1; sne %0" -+ : "=r" (ret) -+ : "m" (p) -+ : "cc","memory"); -+ return ret; -+} -+#endif -+ -+#ifdef __hppa__ -+/* Because malloc only guarantees 8-byte alignment for malloc'd data, -+ and GCC only guarantees 8-byte alignment for stack locals, we can't -+ be assured of 16-byte alignment for atomic lock data even if we -+ specify "__attribute ((aligned(16)))" in the type declaration. So, -+ we use a struct containing an array of four ints for the atomic lock -+ type and dynamically select the 16-byte aligned int from the array -+ for the semaphore. */ -+#define __PA_LDCW_ALIGNMENT 16 -+static inline void *ldcw_align (void *p) { -+ unsigned long a = (unsigned long)p; -+ a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); -+ return (void *)a; -+} -+ -+static inline int testandset (spinlock_t *p) -+{ -+ unsigned int ret; -+ p = ldcw_align(p); -+ __asm__ __volatile__("ldcw 0(%1),%0" -+ : "=r" (ret) -+ : "r" (p) -+ : "memory" ); -+ return !ret; -+} -+#endif -+ -+#ifdef __ia64 -+#include -+ -+static inline int testandset (int *p) -+{ -+ return __sync_lock_test_and_set (p, 1); -+} -+#endif -+ -+#ifdef __mips__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ -+ __asm__ __volatile__ ( -+ " .set push \n" -+ " .set noat \n" -+ " .set mips2 \n" -+ "1: li $1, 1 \n" -+ " ll %0, %1 \n" -+ " sc $1, %1 \n" -+ " beqz $1, 1b \n" -+ " .set pop " -+ : "=r" (ret), "+R" (*p) -+ : -+ : "memory"); -+ -+ return ret; -+} -+#endif -+ -+#if defined(__hppa__) -+ -+typedef int spinlock_t[4]; -+ -+#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } -+ -+static inline void resetlock (spinlock_t *p) -+{ -+ (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; -+} -+ -+#else -+ -+typedef int spinlock_t; -+ -+#define SPIN_LOCK_UNLOCKED 0 -+ -+static inline void resetlock (spinlock_t *p) -+{ -+ *p = SPIN_LOCK_UNLOCKED; -+} -+ -+#endif -+ -+#if defined(CONFIG_USER_ONLY) -+static inline void spin_lock(spinlock_t *lock) -+{ -+ while (testandset(lock)); -+} -+ -+static inline void spin_unlock(spinlock_t *lock) -+{ -+ resetlock(lock); -+} -+ -+static inline int spin_trylock(spinlock_t *lock) -+{ -+ return !testandset(lock); -+} -+#else -+static inline void spin_lock(spinlock_t *lock) -+{ -+} -+ -+static inline void spin_unlock(spinlock_t *lock) -+{ -+} -+ -+static inline int spin_trylock(spinlock_t *lock) -+{ -+ return 1; -+} -+#endif -+ -+#endif -Index: trunk/target-arm/cpu.h -=================================================================== ---- trunk.orig/target-arm/cpu.h 2008-04-24 20:16:41.000000000 +0100 -+++ trunk/target-arm/cpu.h 2008-04-24 20:16:53.000000000 +0100 -@@ -38,6 +38,7 @@ - #define EXCP_FIQ 6 - #define EXCP_BKPT 7 - #define EXCP_EXCEPTION_EXIT 8 /* Return from v7M exception. */ -+#define EXCP_KERNEL_TRAP 9 /* Jumped to kernel code page. */ - - #define ARMV7M_EXCP_RESET 1 - #define ARMV7M_EXCP_NMI 2 -@@ -218,6 +219,15 @@ - void cpu_lock(void); - void cpu_unlock(void); - -+void cpu_lock(void); -+void cpu_unlock(void); -+#if defined(USE_NPTL) -+static inline void cpu_set_tls(CPUARMState *env, void *newtls) -+{ -+ env->cp15.c13_tls2 = (uint32_t)(long)newtls; -+} -+#endif -+ - #define CPSR_M (0x1f) - #define CPSR_T (1 << 5) - #define CPSR_F (1 << 6) -Index: trunk/target-arm/translate.c -=================================================================== ---- trunk.orig/target-arm/translate.c 2008-04-24 20:16:41.000000000 +0100 -+++ trunk/target-arm/translate.c 2008-04-24 20:16:53.000000000 +0100 -@@ -8606,7 +8606,14 @@ - gen_exception(EXCP_EXCEPTION_EXIT); - } - #endif -- -+#ifdef CONFIG_USER_ONLY -+ /* Intercept jump to the magic kernel page. */ -+ if (dc->pc > 0xffff0000) { -+ gen_exception(EXCP_KERNEL_TRAP); -+ dc->is_jmp = DISAS_UPDATE; -+ break; -+ } -+#endif - if (env->nb_breakpoints > 0) { - for(j = 0; j < env->nb_breakpoints; j++) { - if (env->breakpoints[j] == dc->pc) { diff --git a/meta/packages/qemu/qemu-0.9.1+svn/qemu-n800-support.patch b/meta/packages/qemu/qemu-0.9.1+svn/qemu-n800-support.patch deleted file mode 100644 index 1224fb4cbde..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/qemu-n800-support.patch +++ /dev/null @@ -1,2381 +0,0 @@ -diff -urN 4242/cpu-all.h qemu-omap/cpu-all.h ---- 4242/cpu-all.h 2008-04-24 21:26:19.000000000 +0100 -+++ qemu-omap/cpu-all.h 2008-04-23 09:57:55.000000000 +0100 -@@ -816,7 +816,7 @@ - /* physical memory access */ - #define TLB_INVALID_MASK (1 << 3) - #define IO_MEM_SHIFT 4 --#define IO_MEM_NB_ENTRIES (1 << (TARGET_PAGE_BITS - IO_MEM_SHIFT)) -+#define IO_MEM_NB_ENTRIES (16 << (TARGET_PAGE_BITS - IO_MEM_SHIFT)) - - #define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */ - #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ -diff -urN 4242/exec.c qemu-omap/exec.c ---- 4242/exec.c 2008-04-24 18:11:49.000000000 +0100 -+++ qemu-omap/exec.c 2008-04-23 09:57:55.000000000 +0100 -@@ -1664,7 +1664,7 @@ - { - if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { - /* IO memory case */ -- address = vaddr | pd; -+ address = vaddr | (pd & ~TARGET_PAGE_MASK); - addend = paddr; - } else { - /* standard memory */ -@@ -1698,7 +1698,9 @@ - } else { - te->addr_read = -1; - } -- if (prot & PAGE_EXEC) { -+ if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { -+ te->addr_code = pd; -+ } else if (prot & PAGE_EXEC) { - te->addr_code = address; - } else { - te->addr_code = -1; -@@ -2493,7 +2495,9 @@ - if (io_index <= 0) { - if (io_mem_nb >= IO_MEM_NB_ENTRIES) - return -1; -- io_index = io_mem_nb++; -+ do io_index = io_mem_nb++; -+ while (((io_index << IO_MEM_SHIFT) & ~TARGET_PAGE_MASK) -+ <= IO_MEM_NOTDIRTY); - } else { - if (io_index >= IO_MEM_NB_ENTRIES) - return -1; -diff -urN 4242/hw/max7310.c qemu-omap/hw/max7310.c ---- 4242/hw/max7310.c 2008-04-24 18:11:49.000000000 +0100 -+++ qemu-omap/hw/max7310.c 2008-03-02 19:31:55.000000000 +0000 -@@ -134,8 +134,8 @@ - s->i2c_command_byte = 1; - break; - case I2C_FINISH: -- if (s->len == 1) - #ifdef VERBOSE -+ if (s->len == 1) - printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len); - #endif - break; -diff -urN 4242/hw/ndis.h qemu-omap/hw/ndis.h ---- 4242/hw/ndis.h 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-omap/hw/ndis.h 2008-04-23 09:57:56.000000000 +0100 -@@ -0,0 +1,217 @@ -+/* -+ * ndis.h -+ * -+ * ntddndis.h modified by Benedikt Spranger -+ * -+ * Thanks to the cygwin development team, -+ * espacially to Casper S. Hornstrup -+ * -+ * THIS SOFTWARE IS NOT COPYRIGHTED -+ * -+ * This source code is offered for use in the public domain. You may -+ * use, modify or distribute it freely. -+ * -+ * This code is distributed in the hope that it will be useful but -+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY -+ * DISCLAIMED. This includes but is not limited to warranties of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+ * -+ */ -+ -+#ifndef _LINUX_NDIS_H -+#define _LINUX_NDIS_H -+ -+ -+#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 -+#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A -+#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B -+ -+enum NDIS_DEVICE_POWER_STATE { -+ NdisDeviceStateUnspecified = 0, -+ NdisDeviceStateD0, -+ NdisDeviceStateD1, -+ NdisDeviceStateD2, -+ NdisDeviceStateD3, -+ NdisDeviceStateMaximum -+}; -+ -+struct NDIS_PM_WAKE_UP_CAPABILITIES { -+ enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; -+ enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; -+ enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; -+}; -+ -+/* NDIS_PNP_CAPABILITIES.Flags constants */ -+#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 -+#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 -+#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 -+ -+struct NDIS_PNP_CAPABILITIES { -+ __le32 Flags; -+ struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; -+}; -+ -+struct NDIS_PM_PACKET_PATTERN { -+ __le32 Priority; -+ __le32 Reserved; -+ __le32 MaskSize; -+ __le32 PatternOffset; -+ __le32 PatternSize; -+ __le32 PatternFlags; -+}; -+ -+ -+/* Required Object IDs (OIDs) */ -+#define OID_GEN_SUPPORTED_LIST 0x00010101 -+#define OID_GEN_HARDWARE_STATUS 0x00010102 -+#define OID_GEN_MEDIA_SUPPORTED 0x00010103 -+#define OID_GEN_MEDIA_IN_USE 0x00010104 -+#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 -+#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 -+#define OID_GEN_LINK_SPEED 0x00010107 -+#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 -+#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 -+#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A -+#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B -+#define OID_GEN_VENDOR_ID 0x0001010C -+#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D -+#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E -+#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F -+#define OID_GEN_DRIVER_VERSION 0x00010110 -+#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 -+#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 -+#define OID_GEN_MAC_OPTIONS 0x00010113 -+#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 -+#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 -+#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 -+#define OID_GEN_SUPPORTED_GUIDS 0x00010117 -+#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 -+#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 -+#define OID_GEN_MACHINE_NAME 0x0001021A -+#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B -+#define OID_GEN_VLAN_ID 0x0001021C -+ -+/* Optional OIDs */ -+#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 -+#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 -+ -+/* Required statistics OIDs */ -+#define OID_GEN_XMIT_OK 0x00020101 -+#define OID_GEN_RCV_OK 0x00020102 -+#define OID_GEN_XMIT_ERROR 0x00020103 -+#define OID_GEN_RCV_ERROR 0x00020104 -+#define OID_GEN_RCV_NO_BUFFER 0x00020105 -+ -+/* Optional statistics OIDs */ -+#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 -+#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -+#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 -+#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -+#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 -+#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -+#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 -+#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -+#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 -+#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -+#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B -+#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C -+#define OID_GEN_RCV_CRC_ERROR 0x0002020D -+#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E -+#define OID_GEN_GET_TIME_CAPS 0x0002020F -+#define OID_GEN_GET_NETCARD_TIME 0x00020210 -+#define OID_GEN_NETCARD_LOAD 0x00020211 -+#define OID_GEN_DEVICE_PROFILE 0x00020212 -+#define OID_GEN_INIT_TIME_MS 0x00020213 -+#define OID_GEN_RESET_COUNTS 0x00020214 -+#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 -+#define OID_GEN_FRIENDLY_NAME 0x00020216 -+#define OID_GEN_MINIPORT_INFO 0x00020217 -+#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 -+ -+/* IEEE 802.3 (Ethernet) OIDs */ -+#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 -+ -+#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -+#define OID_802_3_CURRENT_ADDRESS 0x01010102 -+#define OID_802_3_MULTICAST_LIST 0x01010103 -+#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 -+#define OID_802_3_MAC_OPTIONS 0x01010105 -+#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -+#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 -+#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 -+#define OID_802_3_XMIT_DEFERRED 0x01020201 -+#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -+#define OID_802_3_RCV_OVERRUN 0x01020203 -+#define OID_802_3_XMIT_UNDERRUN 0x01020204 -+#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 -+#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -+#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 -+ -+/* OID_GEN_MINIPORT_INFO constants */ -+#define NDIS_MINIPORT_BUS_MASTER 0x00000001 -+#define NDIS_MINIPORT_WDM_DRIVER 0x00000002 -+#define NDIS_MINIPORT_SG_LIST 0x00000004 -+#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 -+#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010 -+#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 -+#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 -+#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 -+#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 -+#define NDIS_MINIPORT_IS_NDIS_5 0x00000200 -+#define NDIS_MINIPORT_IS_CO 0x00000400 -+#define NDIS_MINIPORT_DESERIALIZE 0x00000800 -+#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 -+#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 -+#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000 -+#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000 -+#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 -+#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 -+#define NDIS_MINIPORT_HIDDEN 0x00040000 -+#define NDIS_MINIPORT_SWENUM 0x00080000 -+#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 -+#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 -+#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 -+#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 -+#define NDIS_MINIPORT_64BITS_DMA 0x01000000 -+ -+#define NDIS_MEDIUM_802_3 0x00000000 -+#define NDIS_MEDIUM_802_5 0x00000001 -+#define NDIS_MEDIUM_FDDI 0x00000002 -+#define NDIS_MEDIUM_WAN 0x00000003 -+#define NDIS_MEDIUM_LOCAL_TALK 0x00000004 -+#define NDIS_MEDIUM_DIX 0x00000005 -+#define NDIS_MEDIUM_ARCENT_RAW 0x00000006 -+#define NDIS_MEDIUM_ARCENT_878_2 0x00000007 -+#define NDIS_MEDIUM_ATM 0x00000008 -+#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009 -+#define NDIS_MEDIUM_IRDA 0x0000000A -+#define NDIS_MEDIUM_BPC 0x0000000B -+#define NDIS_MEDIUM_CO_WAN 0x0000000C -+#define NDIS_MEDIUM_1394 0x0000000D -+ -+#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 -+#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 -+#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 -+#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 -+#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 -+#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 -+#define NDIS_PACKET_TYPE_SMT 0x00000040 -+#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 -+#define NDIS_PACKET_TYPE_GROUP 0x00000100 -+#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 -+#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 -+#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 -+ -+#define NDIS_MEDIA_STATE_CONNECTED 0x00000000 -+#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001 -+ -+#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 -+#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 -+#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 -+#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 -+#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 -+#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 -+#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 -+#define NDIS_MAC_OPTION_RESERVED 0x80000000 -+ -+#endif /* _LINUX_NDIS_H */ -diff -urN 4242/hw/nseries.c qemu-omap/hw/nseries.c ---- 4242/hw/nseries.c 2008-04-24 18:11:49.000000000 +0100 -+++ qemu-omap/hw/nseries.c 2008-04-23 09:57:56.000000000 +0100 -@@ -602,6 +602,37 @@ - (void *) &config7, sizeof(config7)); - } - -+#if 0 -+static uint32_t n800_pinout[104] = { -+ 0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0, -+ 0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808, -+ 0x08080808, 0x180800c4, 0x00b80000, 0x08080808, -+ 0x080800bc, 0x00cc0808, 0x08081818, 0x18180128, -+ 0x01241800, 0x18181818, 0x000000f0, 0x01300000, -+ 0x00001b0b, 0x1b0f0138, 0x00e0181b, 0x1b031b0b, -+ 0x180f0078, 0x00740018, 0x0f0f0f1a, 0x00000080, -+ 0x007c0000, 0x00000000, 0x00000088, 0x00840000, -+ 0x00000000, 0x00000094, 0x00980300, 0x0f180003, -+ 0x0000008c, 0x00900f0f, 0x0f0f1b00, 0x0f00009c, -+ 0x01140000, 0x1b1b0f18, 0x0818013c, 0x01400008, -+ 0x00001818, 0x000b0110, 0x010c1800, 0x0b030b0f, -+ 0x181800f4, 0x00f81818, 0x00000018, 0x000000fc, -+ 0x00401808, 0x00000000, 0x0f1b0030, 0x003c0008, -+ 0x00000000, 0x00000038, 0x00340000, 0x00000000, -+ 0x1a080070, 0x00641a1a, 0x08080808, 0x08080060, -+ 0x005c0808, 0x08080808, 0x08080058, 0x00540808, -+ 0x08080808, 0x0808006c, 0x00680808, 0x08080808, -+ 0x000000a8, 0x00b00000, 0x08080808, 0x000000a0, -+ 0x00a40000, 0x00000000, 0x08ff0050, 0x004c0808, -+ 0xffffffff, 0xffff0048, 0x0044ffff, 0xffffffff, -+ 0x000000ac, 0x01040800, 0x08080b0f, 0x18180100, -+ 0x01081818, 0x0b0b1808, 0x1a0300e4, 0x012c0b1a, -+ 0x02020018, 0x0b000134, 0x011c0800, 0x0b1b1b00, -+ 0x0f0000c8, 0x00ec181b, 0x000f0f02, 0x00180118, -+ 0x01200000, 0x0f0b1b1b, 0x0f0200e8, 0x0000020b, -+}; -+#endif -+ - /* Setup sequence done by the bootloader */ - static void n800_boot_init(void *opaque) - { -@@ -942,3 +973,71 @@ - "Nokia N800 aka. RX-34 tablet (OMAP2420)", - n800_init, - }; -+ -+#if 0 -+/* cx3110x.c */ -+#define CY_ARM_INT 0x00 -+#define CY_ARM_INT_ENA 0x00 -+#define CY_HOST_INT 0x00 -+#define CY_HOST_INT_ENA 0x00 -+#define CY_HOST_INT_ACK 0x00 -+#define CY_GP1_COMM 0x00 -+#define CY_GP2_COMM 0x00 -+#define CY_DEV_CTRL_STA 0x00 -+#define CY_DMA_DATA 0x00 /* 16-bit */ -+#define CY_DMA_WR_CTRL 0x00 /* 16-bit */ -+#define CY_DMA_WR_LEN 0x00 /* 16-bit */ -+#define CY_DMA_WR_BASE 0x00 -+#define CY_DMA_RD_CTRL 0x00 /* 16-bit */ -+#define CY_DMA_RD_LEN 0x00 /* 16-bit */ -+#define CY_DMA_RD_BASE 0x00 -+ -+HW: -+(spi bus 1.0) -+ tsc2005 -+(spi bus 1.1) -+ lcd_mipid -+(spi bus 2.0) -+ cx3110x (WLAN) -+(spi somewhere?) -+ pc2400m (WiMAX) -+(i2c bus 0) -+ TLV320AIC33 (audio codec on i2c) -+ TCM825x (camera on i2c) -+ lp5521 (LED on i2c) -+ tsl2563 (light sensor, hwmon on i2c) -+ lm8323 (keypad on i2c) -+(i2c bus 1) -+ tmp105 (temperature sensor, hwmon on i2c) -+ menelaus (power on i2c) -+ -+GPIO 0: out hi -+GPIO 8: in hi -+GPIO 9: out hi -+GPIO 10: out lo -+GPIO 12: out lo -+GPIO 15: out lo -+GPIO 23: out hi -+GPIO 26: in hi, irq-186 rising -+GPIO 53: out lo -+GPIO 58: in hi, irq-218 low wakeup -+GPIO 62: out lo -+GPIO 64: out hi -+GPIO 65: in hi -+GPIO 66: out lo -+GPIO 93: out lo -+GPIO 94: in hi -+GPIO 95: out lo -+GPIO 96: out hi -+GPIO 101: out lo -+GPIO 102: in hi, irq-262 bothedge -+GPIO 106: in hi, irq-266 falling wakeup -+GPIO 107: in hi, irq-267 bothedge -+GPIO 108: in lo, irq-268 rising wakeup -+GPIO 109: in hi, irq-269 falling wakeup -+GPIO 110: in hi, irq-270 bothedge -+GPIO 111: in lo, irq-271 rising -+GPIO 112: out hi -+GPIO 118: out hi -+GPIO 125: in lo, irq-285 rising -+#endif -diff -urN 4242/hw/omap2.c qemu-omap/hw/omap2.c ---- 4242/hw/omap2.c 2008-04-24 18:11:49.000000000 +0100 -+++ qemu-omap/hw/omap2.c 2008-04-23 09:57:56.000000000 +0100 -@@ -3675,152 +3675,152 @@ - omap_findclk(s, "dss_l4_iclk")); - - /* All register mappings (includin those not currenlty implemented): -- * SystemControlMod 48000000 - 48000fff -- * SystemControlL4 48001000 - 48001fff -- * 32kHz Timer Mod 48004000 - 48004fff -- * 32kHz Timer L4 48005000 - 48005fff -- * PRCM ModA 48008000 - 480087ff -+ * SystemControlMod 48000000 - 48000fff (REV 0x00000010) -+ * SystemControlL4 48001000 - 48001fff (0x00200010, 0x01000200, 0x00000000) -+ * 32kHz Timer Mod 48004000 - 48004fff (REV 0x00000011) -+ * 32kHz Timer L4 48005000 - 48005fff (0x00200010, 0x01000200, 0x00000000) -+ * PRCM ModA 48008000 - 480087ff (REV 0x00000010) - * PRCM ModB 48008800 - 48008fff -- * PRCM L4 48009000 - 48009fff -- * TEST-BCM Mod 48012000 - 48012fff -- * TEST-BCM L4 48013000 - 48013fff -- * TEST-TAP Mod 48014000 - 48014fff -- * TEST-TAP L4 48015000 - 48015fff -- * GPIO1 Mod 48018000 - 48018fff -- * GPIO Top 48019000 - 48019fff -- * GPIO2 Mod 4801a000 - 4801afff -- * GPIO L4 4801b000 - 4801bfff -- * GPIO3 Mod 4801c000 - 4801cfff -- * GPIO4 Mod 4801e000 - 4801efff -- * WDTIMER1 Mod 48020000 - 48010fff -+ * PRCM L4 48009000 - 48009fff (0x00200010, 0x00000200, 0x00000000) -+ * TEST-BCM Mod 48012000 - 48012fff (REV 0x00000010) -+ * TEST-BCM L4 48013000 - 48013fff (0x00200010, 0x00000200, 0x00000000) -+ * TEST-TAP Mod 48014000 - 48014fff (REV 0x00000010) -+ * TEST-TAP L4 48015000 - 48015fff (0x00200010, 0x00000200, 0x00000000) -+ * GPIO1 Mod 48018000 - 48018fff (REV 0x00000018) -+ * GPIO Top 48019000 - 48019fff (REV 0x00000011) -+ * GPIO2 Mod 4801a000 - 4801afff (REV 0x00000018) -+ * GPIO L4 4801b000 - 4801bfff (0x00200010, 0x00000200, 0x00000000) -+ * GPIO3 Mod 4801c000 - 4801cfff (REV 0x00000018) -+ * GPIO4 Mod 4801e000 - 4801efff (REV 0x00000018) -+ * WDTIMER1 Mod 48020000 - 48010fff (REV Abort) - * WDTIMER Top 48021000 - 48011fff -- * WDTIMER2 Mod 48022000 - 48012fff -- * WDTIMER L4 48023000 - 48013fff -- * WDTIMER3 Mod 48024000 - 48014fff -- * WDTIMER3 L4 48025000 - 48015fff -- * WDTIMER4 Mod 48026000 - 48016fff -- * WDTIMER4 L4 48027000 - 48017fff -- * GPTIMER1 Mod 48028000 - 48018fff -- * GPTIMER1 L4 48029000 - 48019fff -- * GPTIMER2 Mod 4802a000 - 4801afff -- * GPTIMER2 L4 4802b000 - 4801bfff -+ * WDTIMER2 Mod 48022000 - 48012fff (REV 0x00000011) -+ * WDTIMER L4 48023000 - 48013fff (0x00200010, 0x00000200, 0x00000000) -+ * WDTIMER3 Mod 48024000 - 48014fff (REV 0x00000011) -+ * WDTIMER3 L4 48025000 - 48015fff (0x00200010, 0x00000200, 0x00000000) -+ * WDTIMER4 Mod 48026000 - 48016fff (REV 0x00000011) -+ * WDTIMER4 L4 48027000 - 48017fff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER1 Mod 48028000 - 48018fff (REV 0x00000013) -+ * GPTIMER1 L4 48029000 - 48019fff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER2 Mod 4802a000 - 4801afff (REV Abort) -+ * GPTIMER2 L4 4802b000 - 4801bfff (0x00200010, 0x00000200, 0x00000000) - * L4-Config AP 48040000 - 480407ff - * L4-Config IP 48040800 - 48040fff - * L4-Config LA 48041000 - 48041fff -- * ARM11ETB Mod 48048000 - 48049fff -- * ARM11ETB L4 4804a000 - 4804afff -- * DISPLAY Top 48050000 - 480503ff -- * DISPLAY DISPC 48050400 - 480507ff -- * DISPLAY RFBI 48050800 - 48050bff -- * DISPLAY VENC 48050c00 - 48050fff -- * DISPLAY L4 48051000 - 48051fff -- * CAMERA Top 48052000 - 480523ff -- * CAMERA core 48052400 - 480527ff -- * CAMERA DMA 48052800 - 48052bff -- * CAMERA MMU 48052c00 - 48052fff -- * CAMERA L4 48053000 - 48053fff -- * SDMA Mod 48056000 - 48056fff -- * SDMA L4 48057000 - 48057fff -- * SSI Top 48058000 - 48058fff -- * SSI GDD 48059000 - 48059fff -- * SSI Port1 4805a000 - 4805afff -- * SSI Port2 4805b000 - 4805bfff -- * SSI L4 4805c000 - 4805cfff -- * USB Mod 4805e000 - 480fefff -- * USB L4 4805f000 - 480fffff -- * WIN_TRACER1 Mod 48060000 - 48060fff -- * WIN_TRACER1 L4 48061000 - 48061fff -- * WIN_TRACER2 Mod 48062000 - 48062fff -- * WIN_TRACER2 L4 48063000 - 48063fff -- * WIN_TRACER3 Mod 48064000 - 48064fff -- * WIN_TRACER3 L4 48065000 - 48065fff -- * WIN_TRACER4 Top 48066000 - 480660ff -- * WIN_TRACER4 ETT 48066100 - 480661ff -- * WIN_TRACER4 WT 48066200 - 480662ff -- * WIN_TRACER4 L4 48067000 - 48067fff -- * XTI Mod 48068000 - 48068fff -- * XTI L4 48069000 - 48069fff -- * UART1 Mod 4806a000 - 4806afff -- * UART1 L4 4806b000 - 4806bfff -- * UART2 Mod 4806c000 - 4806cfff -- * UART2 L4 4806d000 - 4806dfff -- * UART3 Mod 4806e000 - 4806efff -- * UART3 L4 4806f000 - 4806ffff -- * I2C1 Mod 48070000 - 48070fff -- * I2C1 L4 48071000 - 48071fff -- * I2C2 Mod 48072000 - 48072fff -- * I2C2 L4 48073000 - 48073fff -- * McBSP1 Mod 48074000 - 48074fff -- * McBSP1 L4 48075000 - 48075fff -- * McBSP2 Mod 48076000 - 48076fff -- * McBSP2 L4 48077000 - 48077fff -- * GPTIMER3 Mod 48078000 - 48078fff -- * GPTIMER3 L4 48079000 - 48079fff -- * GPTIMER4 Mod 4807a000 - 4807afff -- * GPTIMER4 L4 4807b000 - 4807bfff -- * GPTIMER5 Mod 4807c000 - 4807cfff -- * GPTIMER5 L4 4807d000 - 4807dfff -- * GPTIMER6 Mod 4807e000 - 4807efff -- * GPTIMER6 L4 4807f000 - 4807ffff -- * GPTIMER7 Mod 48080000 - 48080fff -- * GPTIMER7 L4 48081000 - 48081fff -- * GPTIMER8 Mod 48082000 - 48082fff -- * GPTIMER8 L4 48083000 - 48083fff -- * GPTIMER9 Mod 48084000 - 48084fff -- * GPTIMER9 L4 48085000 - 48085fff -- * GPTIMER10 Mod 48086000 - 48086fff -- * GPTIMER10 L4 48087000 - 48087fff -- * GPTIMER11 Mod 48088000 - 48088fff -- * GPTIMER11 L4 48089000 - 48089fff -- * GPTIMER12 Mod 4808a000 - 4808afff -- * GPTIMER12 L4 4808b000 - 4808bfff -- * EAC Mod 48090000 - 48090fff -- * EAC L4 48091000 - 48091fff -- * FAC Mod 48092000 - 48092fff -- * FAC L4 48093000 - 48093fff -- * MAILBOX Mod 48094000 - 48094fff -- * MAILBOX L4 48095000 - 48095fff -- * SPI1 Mod 48098000 - 48098fff -- * SPI1 L4 48099000 - 48099fff -- * SPI2 Mod 4809a000 - 4809afff -- * SPI2 L4 4809b000 - 4809bfff -- * MMC/SDIO Mod 4809c000 - 4809cfff -- * MMC/SDIO L4 4809d000 - 4809dfff -- * MS_PRO Mod 4809e000 - 4809efff -- * MS_PRO L4 4809f000 - 4809ffff -- * RNG Mod 480a0000 - 480a0fff -- * RNG L4 480a1000 - 480a1fff -- * DES3DES Mod 480a2000 - 480a2fff -- * DES3DES L4 480a3000 - 480a3fff -- * SHA1MD5 Mod 480a4000 - 480a4fff -- * SHA1MD5 L4 480a5000 - 480a5fff -- * AES Mod 480a6000 - 480a6fff -- * AES L4 480a7000 - 480a7fff -- * PKA Mod 480a8000 - 480a9fff -- * PKA L4 480aa000 - 480aafff -- * MG Mod 480b0000 - 480b0fff -- * MG L4 480b1000 - 480b1fff -- * HDQ/1-wire Mod 480b2000 - 480b2fff -- * HDQ/1-wire L4 480b3000 - 480b3fff -- * MPU interrupt 480fe000 - 480fefff -- * IVA RAM 5c000000 - 5c01ffff -- * IVA ROM 5c020000 - 5c027fff -- * IMG_BUF_A 5c040000 - 5c040fff -- * IMG_BUF_B 5c042000 - 5c042fff -- * VLCDS 5c048000 - 5c0487ff -- * IMX_COEF 5c049000 - 5c04afff -- * IMX_CMD 5c051000 - 5c051fff -- * VLCDQ 5c053000 - 5c0533ff -- * VLCDH 5c054000 - 5c054fff -- * SEQ_CMD 5c055000 - 5c055fff -- * IMX_REG 5c056000 - 5c0560ff -- * VLCD_REG 5c056100 - 5c0561ff -- * SEQ_REG 5c056200 - 5c0562ff -- * IMG_BUF_REG 5c056300 - 5c0563ff -- * SEQIRQ_REG 5c056400 - 5c0564ff -- * OCP_REG 5c060000 - 5c060fff -- * SYSC_REG 5c070000 - 5c070fff -- * MMU_REG 5d000000 - 5d000fff -+ * ARM11ETB Mod 48048000 - 48049fff (REV 0x00000011) -+ * ARM11ETB L4 4804a000 - 4804afff (0x00200010, 0x00000200, 0x00000000) -+ * DISPLAY Top 48050000 - 480503ff (REV 0x00000003) -+ * DISPLAY DISPC 48050400 - 480507ff (REV 0x00000020) -+ * DISPLAY RFBI 48050800 - 48050bff (REV 0x00000010) -+ * DISPLAY VENC 48050c00 - 48050fff (REV Abort) -+ * DISPLAY L4 48051000 - 48051fff (0x00200010, 0x00000200, 0x00000100) -+ * CAMERA Top 48052000 - 480523ff (REV 0x00000020) -+ * CAMERA core 48052400 - 480527ff (REV 0x00000020) -+ * CAMERA DMA 48052800 - 48052bff (REV 0x00000020) -+ * CAMERA MMU 48052c00 - 48052fff (REV 0x00000010) -+ * CAMERA L4 48053000 - 48053fff (0x00200010, 0x00000200, 0x00000000) -+ * SDMA Mod 48056000 - 48056fff (REV 0x00000020) -+ * SDMA L4 48057000 - 48057fff (0x00200010, 0x00000200, 0x00000000) -+ * SSI Top 48058000 - 48058fff (REV Abort) -+ * SSI GDD 48059000 - 48059fff (REV Abort) -+ * SSI Port1 4805a000 - 4805afff (REV Abort) -+ * SSI Port2 4805b000 - 4805bfff (REV Abort) -+ * SSI L4 4805c000 - 4805cfff (0x00200010, 0x00000200, 0x00000100) -+ * USB Mod 4805e000 - 480fefff (REV Abort) -+ * USB L4 4805f000 - 480fffff (0x00200010, 0x01000200, 0x00000100) -+ * WIN_TRACER1 Mod 48060000 - 48060fff (REV 0x00000020) -+ * WIN_TRACER1 L4 48061000 - 48061fff (0x00200010, 0x00000200, 0x00000000) -+ * WIN_TRACER2 Mod 48062000 - 48062fff (REV 0x00000020) -+ * WIN_TRACER2 L4 48063000 - 48063fff (0x00200010, 0x00000200, 0x00000000) -+ * WIN_TRACER3 Mod 48064000 - 48064fff (REV 0x00000020) -+ * WIN_TRACER3 L4 48065000 - 48065fff (0x00200010, 0x00000200, 0x00000000) -+ * WIN_TRACER4 Top 48066000 - 480660ff (REV 0x00000011) -+ * WIN_TRACER4 ETT 48066100 - 480661ff (REV 0x00000011) -+ * WIN_TRACER4 WT 48066200 - 480662ff (REV 0x00000020) -+ * WIN_TRACER4 L4 48067000 - 48067fff (0x00200010, 0x00000200, 0x00000000) -+ * XTI Mod 48068000 - 48068fff (REV 0x00000010) -+ * XTI L4 48069000 - 48069fff (0x00200010, 0x00000200, 0x00000000) -+ * UART1 Mod 4806a000 - 4806afff (MVR Abort) -+ * UART1 L4 4806b000 - 4806bfff (0x00200010, 0x00000200, 0x00000000) -+ * UART2 Mod 4806c000 - 4806cfff (MVR Abort) -+ * UART2 L4 4806d000 - 4806dfff (0x00200010, 0x00000200, 0x00000000) -+ * UART3 Mod 4806e000 - 4806efff (MVR 0x20) -+ * UART3 L4 4806f000 - 4806ffff (0x00200010, 0x00000200, 0x00000000) -+ * I2C1 Mod 48070000 - 48070fff (REV 0x0034) -+ * I2C1 L4 48071000 - 48071fff (0x00200010, 0x01000200, 0x01000000) -+ * I2C2 Mod 48072000 - 48072fff (REV 0x0034) -+ * I2C2 L4 48073000 - 48073fff (0x00200010, 0x01000200, 0x01000000) -+ * McBSP1 Mod 48074000 - 48074fff (REV Abort) -+ * McBSP1 L4 48075000 - 48075fff (0x00200010, 0x01000200, 0x01000000) -+ * McBSP2 Mod 48076000 - 48076fff (REV Abort) -+ * McBSP2 L4 48077000 - 48077fff (0x00200010, 0x01000200, 0x01000000) -+ * GPTIMER3 Mod 48078000 - 48078fff (REV Abort) -+ * GPTIMER3 L4 48079000 - 48079fff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER4 Mod 4807a000 - 4807afff (REV Abort) -+ * GPTIMER4 L4 4807b000 - 4807bfff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER5 Mod 4807c000 - 4807cfff (REV Abort) -+ * GPTIMER5 L4 4807d000 - 4807dfff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER6 Mod 4807e000 - 4807efff (REV Abort) -+ * GPTIMER6 L4 4807f000 - 4807ffff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER7 Mod 48080000 - 48080fff (REV Abort) -+ * GPTIMER7 L4 48081000 - 48081fff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER8 Mod 48082000 - 48082fff (REV Abort) -+ * GPTIMER8 L4 48083000 - 48083fff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER9 Mod 48084000 - 48084fff (REV Abort) -+ * GPTIMER9 L4 48085000 - 48085fff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER10 Mod 48086000 - 48086fff (REV Abort) -+ * GPTIMER10 L4 48087000 - 48087fff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER11 Mod 48088000 - 48088fff (REV Abort) -+ * GPTIMER11 L4 48089000 - 48089fff (0x00200010, 0x00000200, 0x00000000) -+ * GPTIMER12 Mod 4808a000 - 4808afff (REV Abort) -+ * GPTIMER12 L4 4808b000 - 4808bfff (0x00200010, 0x00000200, 0x00000000) -+ * EAC Mod 48090000 - 48090fff (REV Abort) -+ * EAC L4 48091000 - 48091fff (0x00200010, 0x00000200, 0x00000000) -+ * FAC Mod 48092000 - 48092fff (REV Abort) -+ * FAC L4 48093000 - 48093fff (0x00200010, 0x00000200, 0x00000000) -+ * MAILBOX Mod 48094000 - 48094fff (REV 0x00000010) -+ * MAILBOX L4 48095000 - 48095fff (0x00200010, 0x00000200, 0x00000000) -+ * SPI1 Mod 48098000 - 48098fff (REV Abort) -+ * SPI1 L4 48099000 - 48099fff (0x00200010, 0x00000200, 0x00000000) -+ * SPI2 Mod 4809a000 - 4809afff (REV Abort) -+ * SPI2 L4 4809b000 - 4809bfff (0x00200010, 0x00000200, 0x00000000) -+ * MMC/SDIO Mod 4809c000 - 4809cfff (REV 0x0044) -+ * MMC/SDIO L4 4809d000 - 4809dfff (0x00200010, 0x01000200, 0x01000000) -+ * MS_PRO Mod 4809e000 - 4809efff (REV Abort) -+ * MS_PRO L4 4809f000 - 4809ffff (0x00200010, 0x01000200, 0x01000000) -+ * RNG Mod 480a0000 - 480a0fff (REV 0xFC066F93?) -+ * RNG L4 480a1000 - 480a1fff (0x00200010, 0x01000200, 0x00000000) -+ * DES3DES Mod 480a2000 - 480a2fff (REV 0x00000000?) -+ * DES3DES L4 480a3000 - 480a3fff (0x00200010, 0x01000200, 0x00000000) -+ * SHA1MD5 Mod 480a4000 - 480a4fff (REV 0x00000000?) -+ * SHA1MD5 L4 480a5000 - 480a5fff (0x00200010, 0x01000200, 0x00000000) -+ * AES Mod 480a6000 - 480a6fff (REV 0x00000000?) -+ * AES L4 480a7000 - 480a7fff (0x00200010, 0x00000200, 0x00000000) -+ * PKA Mod 480a8000 - 480a9fff (REV 0x00000000?) -+ * PKA L4 480aa000 - 480aafff (0x00200010, 0x00000200, 0x00000000) -+ * MG Mod 480b0000 - 480b0fff (REV Abort) -+ * MG L4 480b1000 - 480b1fff (0x00200010, 0x01000200, 0x01000000) -+ * HDQ/1-wire Mod 480b2000 - 480b2fff (REV 0x00000002) -+ * HDQ/1-wire L4 480b3000 - 480b3fff (0x00200010, 0x00000200, 0x00000000) -+ * MPU interrupt 480fe000 - 480fefff (REV 0x00000020) -+ * IVA RAM 5c000000 - 5c01ffff (REV Abort) -+ * IVA ROM 5c020000 - 5c027fff (REV Abort) -+ * IMG_BUF_A 5c040000 - 5c040fff (REV Abort) -+ * IMG_BUF_B 5c042000 - 5c042fff (REV Abort) -+ * VLCDS 5c048000 - 5c0487ff (REV Abort) -+ * IMX_COEF 5c049000 - 5c04afff (REV Abort) -+ * IMX_CMD 5c051000 - 5c051fff (REV Abort) -+ * VLCDQ 5c053000 - 5c0533ff (REV Abort) -+ * VLCDH 5c054000 - 5c054fff (REV Abort) -+ * SEQ_CMD 5c055000 - 5c055fff (REV Abort) -+ * IMX_REG 5c056000 - 5c0560ff (REV Abort) -+ * VLCD_REG 5c056100 - 5c0561ff (REV Abort) -+ * SEQ_REG 5c056200 - 5c0562ff (REV Abort) -+ * IMG_BUF_REG 5c056300 - 5c0563ff (REV Abort) -+ * SEQIRQ_REG 5c056400 - 5c0564ff (REV Abort) -+ * OCP_REG 5c060000 - 5c060fff (REV Abort) -+ * SYSC_REG 5c070000 - 5c070fff (REV Abort) -+ * MMU_REG 5d000000 - 5d000fff (REV Abort) - * sDMA R 68000400 - 680005ff - * sDMA W 68000600 - 680007ff - * Display Control 68000800 - 680009ff -@@ -3849,9 +3849,9 @@ - * GPMC (firewall) 68006000 - 680063ff - * GPMC (err login) 68006400 - 680067ff - * SMS (err login) 68006c00 - 68006fff -- * SMS registers 68008000 - 68008fff -- * SDRC registers 68009000 - 68009fff -- * GPMC registers 6800a000 6800afff -+ * SMS registers 68008000 - 68008fff (REV 0x00000020) -+ * SDRC registers 68009000 - 68009fff (REV 0x00000020) -+ * GPMC registers 6800a000 6800afff (REV 0x00000020) - */ - - qemu_register_reset(omap2_mpu_reset, s); -diff -urN 4242/hw/pc.c qemu-omap/hw/pc.c ---- 4242/hw/pc.c 2008-04-24 21:26:22.000000000 +0100 -+++ qemu-omap/hw/pc.c 2008-04-23 09:57:56.000000000 +0100 -@@ -445,6 +445,37 @@ - bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect)); - } - -+static int load_kernel(const char *filename, uint8_t *addr, -+ uint8_t *real_addr) -+{ -+ int fd, size; -+ int setup_sects; -+ -+ fd = open(filename, O_RDONLY | O_BINARY); -+ if (fd < 0) -+ return -1; -+ -+ /* load 16 bit code */ -+ if (read(fd, real_addr, 512) != 512) -+ goto fail; -+ setup_sects = real_addr[0x1F1]; -+ if (!setup_sects) -+ setup_sects = 4; -+ if (read(fd, real_addr + 512, setup_sects * 512) != -+ setup_sects * 512) -+ goto fail; -+ -+ /* load 32 bit code */ -+ size = read(fd, addr, 16 * 1024 * 1024); -+ if (size < 0) -+ goto fail; -+ close(fd); -+ return size; -+ fail: -+ close(fd); -+ return -1; -+} -+ - static long get_file_size(FILE *f) - { - long where, size; -diff -urN 4242/hw/tusb6010.c qemu-omap/hw/tusb6010.c ---- 4242/hw/tusb6010.c 2008-04-23 12:18:54.000000000 +0100 -+++ qemu-omap/hw/tusb6010.c 2008-04-23 09:57:56.000000000 +0100 -@@ -287,9 +287,6 @@ - /* TODO: How is this signalled? */ - } - --extern CPUReadMemoryFunc *musb_read[]; --extern CPUWriteMemoryFunc *musb_write[]; -- - static uint32_t tusb_async_readb(void *opaque, target_phys_addr_t addr) - { - struct tusb_s *s = (struct tusb_s *) opaque; -diff -urN 4242/hw/usb.h qemu-omap/hw/usb.h ---- 4242/hw/usb.h 2008-04-23 12:18:54.000000000 +0100 -+++ qemu-omap/hw/usb.h 2008-04-23 09:57:56.000000000 +0100 -@@ -219,6 +219,9 @@ - /* usb-msd.c */ - USBDevice *usb_msd_init(const char *filename); - -+/* usb-net.c */ -+USBDevice *usb_net_init(NICInfo *nd); -+ - /* usb-wacom.c */ - USBDevice *usb_wacom_init(void); - -@@ -254,3 +257,7 @@ - uint32_t musb_core_intr_get(struct musb_s *s); - void musb_core_intr_clear(struct musb_s *s, uint32_t mask); - void musb_set_size(struct musb_s *s, int epnum, int size, int is_tx); -+#ifdef NEED_CPU_H -+extern CPUReadMemoryFunc *musb_read[]; -+extern CPUWriteMemoryFunc *musb_write[]; -+#endif -diff -urN 4242/hw/usb-hub.c qemu-omap/hw/usb-hub.c ---- 4242/hw/usb-hub.c 2008-04-23 11:43:37.000000000 +0100 -+++ qemu-omap/hw/usb-hub.c 2008-04-23 09:57:56.000000000 +0100 -@@ -146,8 +146,8 @@ - 0x07, /* u8 ep_bLength; */ - 0x05, /* u8 ep_bDescriptorType; Endpoint */ - 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ -- 0x03, /* u8 ep_bmAttributes; Interrupt */ -- 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ -+ 0x03, /* u8 ep_bmAttributes; Interrupt */ -+ 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ - 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ - }; - -diff -urN 4242/hw/usb-net.c qemu-omap/hw/usb-net.c ---- 4242/hw/usb-net.c 1970-01-01 01:00:00.000000000 +0100 -+++ qemu-omap/hw/usb-net.c 2008-04-23 09:57:56.000000000 +0100 -@@ -0,0 +1,1334 @@ -+/* -+ * QEMU USB Net devices -+ * -+ * Copyright (c) 2006 Thomas Sailer -+ * based on usb-hid.c Copyright (c) 2005 Fabrice Bellard -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a copy -+ * of this software and associated documentation files (the "Software"), to deal -+ * in the Software without restriction, including without limitation the rights -+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+ * copies of the Software, and to permit persons to whom the Software is -+ * furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -+ * THE SOFTWARE. -+ */ -+ -+#include "qemu-common.h" -+#include "usb.h" -+#include "net.h" -+#include "../audio/sys-queue.h" -+ -+typedef uint32_t __le32; -+#include "ndis.h" -+ -+/*#define TRAFFIC_DEBUG*/ -+/* Thanks to NetChip Technologies for donating this product ID. -+ * It's for devices with only CDC Ethernet configurations. -+ */ -+#define CDC_VENDOR_NUM 0x0525 /* NetChip */ -+#define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */ -+/* For hardware that can talk RNDIS and either of the above protocols, -+ * use this ID ... the windows INF files will know it. -+ */ -+#define RNDIS_VENDOR_NUM 0x0525 /* NetChip */ -+#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ -+ -+#define STRING_MANUFACTURER 1 -+#define STRING_PRODUCT 2 -+#define STRING_ETHADDR 3 -+#define STRING_DATA 4 -+#define STRING_CONTROL 5 -+#define STRING_RNDIS_CONTROL 6 -+#define STRING_CDC 7 -+#define STRING_SUBSET 8 -+#define STRING_RNDIS 9 -+#define STRING_SERIALNUMBER 10 -+ -+#define DEV_CONFIG_VALUE 1 /* cdc or subset */ -+#define DEV_RNDIS_CONFIG_VALUE 2 /* rndis; optional */ -+ -+#define USB_CDC_SUBCLASS_ACM 0x02 -+#define USB_CDC_SUBCLASS_ETHERNET 0x06 -+ -+#define USB_CDC_PROTO_NONE 0 -+#define USB_CDC_ACM_PROTO_VENDOR 0xff -+ -+#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ -+#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ -+#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ -+#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ -+#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ -+ -+#define USB_DT_CS_INTERFACE 0x24 -+#define USB_DT_CS_ENDPOINT 0x25 -+ -+#define ClassInterfaceRequest \ -+ ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) -+#define ClassInterfaceOutRequest \ -+ ((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) -+ -+#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 -+#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 -+#define USB_CDC_REQ_SET_LINE_CODING 0x20 -+#define USB_CDC_REQ_GET_LINE_CODING 0x21 -+#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 -+#define USB_CDC_REQ_SEND_BREAK 0x23 -+#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 -+#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 -+#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 -+#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 -+#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 -+ -+#define USB_ENDPOINT_XFER_BULK 2 -+#define USB_ENDPOINT_XFER_INT 3 -+ -+#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ -+#define STATUS_BYTECOUNT 16 /* 8 byte header + data */ -+ -+#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ -+ -+/* -+ * mostly the same descriptor as the linux gadget rndis driver -+ */ -+static const uint8_t qemu_net_dev_descriptor[] = { -+ 0x12, /* u8 bLength; */ -+ USB_DT_DEVICE, /* u8 bDescriptorType; Device */ -+ 0x00, 0x02, /* u16 bcdUSB; v2.0 */ -+ USB_CLASS_COMM, /* u8 bDeviceClass; */ -+ 0x00, /* u8 bDeviceSubClass; */ -+ 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */ -+ 0x40, /* u8 bMaxPacketSize0 */ -+ RNDIS_VENDOR_NUM & 0xff, RNDIS_VENDOR_NUM >> 8, /* u16 idVendor; */ -+ RNDIS_PRODUCT_NUM & 0xff, RNDIS_PRODUCT_NUM >> 8, /* u16 idProduct; */ -+ 0x00, 0x00, /* u16 bcdDevice */ -+ STRING_MANUFACTURER, /* u8 iManufacturer; */ -+ STRING_PRODUCT, /* u8 iProduct; */ -+ STRING_SERIALNUMBER, /* u8 iSerialNumber; */ -+ 0x02 /* u8 bNumConfigurations; */ -+}; -+ -+static const uint8_t qemu_net_rndis_config_descriptor[] = { -+ /* Configuration Descriptor */ -+ 0x09, /* u8 bLength */ -+ USB_DT_CONFIG, /* u8 bDescriptorType */ -+ 0x43, 0x00, /* le16 wTotalLength */ -+ 0x02, /* u8 bNumInterfaces */ -+ DEV_RNDIS_CONFIG_VALUE, /* u8 bConfigurationValue */ -+ STRING_RNDIS, /* u8 iConfiguration */ -+ 0xc0, /* u8 bmAttributes */ -+ 0x32, /* u8 bMaxPower */ -+ /* RNDIS Control Interface */ -+ 0x09, /* u8 bLength */ -+ USB_DT_INTERFACE, /* u8 bDescriptorType */ -+ 0x00, /* u8 bInterfaceNumber */ -+ 0x00, /* u8 bAlternateSetting */ -+ 0x01, /* u8 bNumEndpoints */ -+ USB_CLASS_COMM, /* u8 bInterfaceClass */ -+ USB_CDC_SUBCLASS_ACM, /* u8 bInterfaceSubClass */ -+ USB_CDC_ACM_PROTO_VENDOR, /* u8 bInterfaceProtocol */ -+ STRING_RNDIS_CONTROL, /* u8 iInterface */ -+ /* Header Descriptor */ -+ 0x05, /* u8 bLength */ -+ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ -+ USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */ -+ 0x10, 0x01, /* le16 bcdCDC */ -+ /* Call Management Descriptor */ -+ 0x05, /* u8 bLength */ -+ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ -+ USB_CDC_CALL_MANAGEMENT_TYPE, /* u8 bDescriptorSubType */ -+ 0x00, /* u8 bmCapabilities */ -+ 0x01, /* u8 bDataInterface */ -+ /* ACM Descriptor */ -+ 0x04, /* u8 bLength */ -+ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ -+ USB_CDC_ACM_TYPE, /* u8 bDescriptorSubType */ -+ 0x00, /* u8 bmCapabilities */ -+ /* Union Descriptor */ -+ 0x05, /* u8 bLength */ -+ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ -+ USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */ -+ 0x00, /* u8 bMasterInterface0 */ -+ 0x01, /* u8 bSlaveInterface0 */ -+ /* Status Descriptor */ -+ 0x07, /* u8 bLength */ -+ USB_DT_ENDPOINT, /* u8 bDescriptorType */ -+ USB_DIR_IN | 1, /* u8 bEndpointAddress */ -+ USB_ENDPOINT_XFER_INT, /* u8 bmAttributes */ -+ STATUS_BYTECOUNT & 0xff, STATUS_BYTECOUNT >> 8, /* le16 wMaxPacketSize */ -+ 1 << LOG2_STATUS_INTERVAL_MSEC, /* u8 bInterval */ -+ /* RNDIS Data Interface */ -+ 0x09, /* u8 bLength */ -+ USB_DT_INTERFACE, /* u8 bDescriptorType */ -+ 0x01, /* u8 bInterfaceNumber */ -+ 0x00, /* u8 bAlternateSetting */ -+ 0x02, /* u8 bNumEndpoints */ -+ USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */ -+ 0x00, /* u8 bInterfaceSubClass */ -+ 0x00, /* u8 bInterfaceProtocol */ -+ STRING_DATA, /* u8 iInterface */ -+ /* Source Endpoint */ -+ 0x07, /* u8 bLength */ -+ USB_DT_ENDPOINT, /* u8 bDescriptorType */ -+ USB_DIR_IN | 2, /* u8 bEndpointAddress */ -+ USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */ -+ 0x40, 0x00, /* le16 wMaxPacketSize */ -+ 0x00, /* u8 bInterval */ -+ /* Sink Endpoint */ -+ 0x07, /* u8 bLength */ -+ USB_DT_ENDPOINT, /* u8 bDescriptorType */ -+ USB_DIR_OUT | 2, /* u8 bEndpointAddress */ -+ USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */ -+ 0x40, 0x00, /* le16 wMaxPacketSize */ -+ 0x00 /* u8 bInterval */ -+}; -+ -+static const uint8_t qemu_net_cdc_config_descriptor[] = { -+ /* Configuration Descriptor */ -+ 0x09, /* u8 bLength */ -+ USB_DT_CONFIG, /* u8 bDescriptorType */ -+ 0x50, 0x00, /* le16 wTotalLength */ -+ 0x02, /* u8 bNumInterfaces */ -+ DEV_CONFIG_VALUE, /* u8 bConfigurationValue */ -+ STRING_CDC, /* u8 iConfiguration */ -+ 0xc0, /* u8 bmAttributes */ -+ 0x32, /* u8 bMaxPower */ -+ /* CDC Control Interface */ -+ 0x09, /* u8 bLength */ -+ USB_DT_INTERFACE, /* u8 bDescriptorType */ -+ 0x00, /* u8 bInterfaceNumber */ -+ 0x00, /* u8 bAlternateSetting */ -+ 0x01, /* u8 bNumEndpoints */ -+ USB_CLASS_COMM, /* u8 bInterfaceClass */ -+ USB_CDC_SUBCLASS_ETHERNET, /* u8 bInterfaceSubClass */ -+ USB_CDC_PROTO_NONE, /* u8 bInterfaceProtocol */ -+ STRING_CONTROL, /* u8 iInterface */ -+ /* Header Descriptor */ -+ 0x05, /* u8 bLength */ -+ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ -+ USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */ -+ 0x10, 0x01, /* le16 bcdCDC */ -+ /* Union Descriptor */ -+ 0x05, /* u8 bLength */ -+ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ -+ USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */ -+ 0x00, /* u8 bMasterInterface0 */ -+ 0x01, /* u8 bSlaveInterface0 */ -+ /* Ethernet Descriptor */ -+ 0x0d, /* u8 bLength */ -+ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ -+ USB_CDC_ETHERNET_TYPE, /* u8 bDescriptorSubType */ -+ STRING_ETHADDR, /* u8 iMACAddress */ -+ 0x00, 0x00, 0x00, 0x00, /* le32 bmEthernetStatistics */ -+ ETH_FRAME_LEN & 0xff, ETH_FRAME_LEN >> 8, /* le16 wMaxSegmentSize */ -+ 0x00, 0x00, /* le16 wNumberMCFilters */ -+ 0x00, /* u8 bNumberPowerFilters */ -+ /* Status Descriptor */ -+ 0x07, /* u8 bLength */ -+ USB_DT_ENDPOINT, /* u8 bDescriptorType */ -+ USB_DIR_IN | 1, /* u8 bEndpointAddress */ -+ USB_ENDPOINT_XFER_INT, /* u8 bmAttributes */ -+ STATUS_BYTECOUNT & 0xff, STATUS_BYTECOUNT >> 8, /* le16 wMaxPacketSize */ -+ 1 << LOG2_STATUS_INTERVAL_MSEC, /* u8 bInterval */ -+ /* CDC Data (nop) Interface */ -+ 0x09, /* u8 bLength */ -+ USB_DT_INTERFACE, /* u8 bDescriptorType */ -+ 0x01, /* u8 bInterfaceNumber */ -+ 0x00, /* u8 bAlternateSetting */ -+ 0x00, /* u8 bNumEndpoints */ -+ USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */ -+ 0x00, /* u8 bInterfaceSubClass */ -+ 0x00, /* u8 bInterfaceProtocol */ -+ 0x00, /* u8 iInterface */ -+ /* CDC Data Interface */ -+ 0x09, /* u8 bLength */ -+ USB_DT_INTERFACE, /* u8 bDescriptorType */ -+ 0x01, /* u8 bInterfaceNumber */ -+ 0x01, /* u8 bAlternateSetting */ -+ 0x02, /* u8 bNumEndpoints */ -+ USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */ -+ 0x00, /* u8 bInterfaceSubClass */ -+ 0x00, /* u8 bInterfaceProtocol */ -+ STRING_DATA, /* u8 iInterface */ -+ /* Source Endpoint */ -+ 0x07, /* u8 bLength */ -+ USB_DT_ENDPOINT, /* u8 bDescriptorType */ -+ USB_DIR_IN | 2, /* u8 bEndpointAddress */ -+ USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */ -+ 0x40, 0x00, /* le16 wMaxPacketSize */ -+ 0x00, /* u8 bInterval */ -+ /* Sink Endpoint */ -+ 0x07, /* u8 bLength */ -+ USB_DT_ENDPOINT, /* u8 bDescriptorType */ -+ USB_DIR_OUT | 2, /* u8 bEndpointAddress */ -+ USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */ -+ 0x40, 0x00, /* le16 wMaxPacketSize */ -+ 0x00 /* u8 bInterval */ -+}; -+ -+/* -+ * RNDIS Status -+ */ -+ -+#define RNDIS_MAXIMUM_FRAME_SIZE 1518 -+#define RNDIS_MAX_TOTAL_SIZE 1558 -+ -+/* Remote NDIS Versions */ -+#define RNDIS_MAJOR_VERSION 1 -+#define RNDIS_MINOR_VERSION 0 -+ -+/* Status Values */ -+#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */ -+#define RNDIS_STATUS_FAILURE 0xC0000001U /* Unspecified error */ -+#define RNDIS_STATUS_INVALID_DATA 0xC0010015U /* Invalid data */ -+#define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBU /* Unsupported request */ -+#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */ -+#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */ -+ -+/* Message Set for Connectionless (802.3) Devices */ -+#define REMOTE_NDIS_PACKET_MSG 0x00000001U -+#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002U /* Initialize device */ -+#define REMOTE_NDIS_HALT_MSG 0x00000003U -+#define REMOTE_NDIS_QUERY_MSG 0x00000004U -+#define REMOTE_NDIS_SET_MSG 0x00000005U -+#define REMOTE_NDIS_RESET_MSG 0x00000006U -+#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007U -+#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008U -+ -+/* Message completion */ -+#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002U -+#define REMOTE_NDIS_QUERY_CMPLT 0x80000004U -+#define REMOTE_NDIS_SET_CMPLT 0x80000005U -+#define REMOTE_NDIS_RESET_CMPLT 0x80000006U -+#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008U -+ -+/* Device Flags */ -+#define RNDIS_DF_CONNECTIONLESS 0x00000001U -+#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U -+ -+#define RNDIS_MEDIUM_802_3 0x00000000U -+ -+/* from drivers/net/sk98lin/h/skgepnmi.h */ -+#define OID_PNP_CAPABILITIES 0xFD010100 -+#define OID_PNP_SET_POWER 0xFD010101 -+#define OID_PNP_QUERY_POWER 0xFD010102 -+#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 -+#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 -+#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 -+ -+typedef struct rndis_init_msg_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+ __le32 MajorVersion; -+ __le32 MinorVersion; -+ __le32 MaxTransferSize; -+} rndis_init_msg_type; -+ -+typedef struct rndis_init_cmplt_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+ __le32 Status; -+ __le32 MajorVersion; -+ __le32 MinorVersion; -+ __le32 DeviceFlags; -+ __le32 Medium; -+ __le32 MaxPacketsPerTransfer; -+ __le32 MaxTransferSize; -+ __le32 PacketAlignmentFactor; -+ __le32 AFListOffset; -+ __le32 AFListSize; -+} rndis_init_cmplt_type; -+ -+typedef struct rndis_halt_msg_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+} rndis_halt_msg_type; -+ -+typedef struct rndis_query_msg_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+ __le32 OID; -+ __le32 InformationBufferLength; -+ __le32 InformationBufferOffset; -+ __le32 DeviceVcHandle; -+} rndis_query_msg_type; -+ -+typedef struct rndis_query_cmplt_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+ __le32 Status; -+ __le32 InformationBufferLength; -+ __le32 InformationBufferOffset; -+} rndis_query_cmplt_type; -+ -+typedef struct rndis_set_msg_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+ __le32 OID; -+ __le32 InformationBufferLength; -+ __le32 InformationBufferOffset; -+ __le32 DeviceVcHandle; -+} rndis_set_msg_type; -+ -+typedef struct rndis_set_cmplt_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+ __le32 Status; -+} rndis_set_cmplt_type; -+ -+typedef struct rndis_reset_msg_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 Reserved; -+} rndis_reset_msg_type; -+ -+typedef struct rndis_reset_cmplt_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 Status; -+ __le32 AddressingReset; -+} rndis_reset_cmplt_type; -+ -+typedef struct rndis_indicate_status_msg_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 Status; -+ __le32 StatusBufferLength; -+ __le32 StatusBufferOffset; -+} rndis_indicate_status_msg_type; -+ -+typedef struct rndis_keepalive_msg_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+} rndis_keepalive_msg_type; -+ -+typedef struct rndis_keepalive_cmplt_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 RequestID; -+ __le32 Status; -+} rndis_keepalive_cmplt_type; -+ -+struct rndis_packet_msg_type -+{ -+ __le32 MessageType; -+ __le32 MessageLength; -+ __le32 DataOffset; -+ __le32 DataLength; -+ __le32 OOBDataOffset; -+ __le32 OOBDataLength; -+ __le32 NumOOBDataElements; -+ __le32 PerPacketInfoOffset; -+ __le32 PerPacketInfoLength; -+ __le32 VcHandle; -+ __le32 Reserved; -+}; -+ -+struct rndis_config_parameter -+{ -+ __le32 ParameterNameOffset; -+ __le32 ParameterNameLength; -+ __le32 ParameterType; -+ __le32 ParameterValueOffset; -+ __le32 ParameterValueLength; -+}; -+ -+/* implementation specific */ -+enum rndis_state -+{ -+ RNDIS_UNINITIALIZED, -+ RNDIS_INITIALIZED, -+ RNDIS_DATA_INITIALIZED, -+}; -+ -+static const uint32_t oid_supported_list[] = -+{ -+ /* the general stuff */ -+ OID_GEN_SUPPORTED_LIST, -+ OID_GEN_HARDWARE_STATUS, -+ OID_GEN_MEDIA_SUPPORTED, -+ OID_GEN_MEDIA_IN_USE, -+ OID_GEN_MAXIMUM_FRAME_SIZE, -+ OID_GEN_LINK_SPEED, -+ OID_GEN_TRANSMIT_BLOCK_SIZE, -+ OID_GEN_RECEIVE_BLOCK_SIZE, -+ OID_GEN_VENDOR_ID, -+ OID_GEN_VENDOR_DESCRIPTION, -+ OID_GEN_VENDOR_DRIVER_VERSION, -+ OID_GEN_CURRENT_PACKET_FILTER, -+ OID_GEN_MAXIMUM_TOTAL_SIZE, -+ OID_GEN_MEDIA_CONNECT_STATUS, -+ OID_GEN_PHYSICAL_MEDIUM, -+ /* the statistical stuff */ -+ OID_GEN_XMIT_OK, -+ OID_GEN_RCV_OK, -+ OID_GEN_XMIT_ERROR, -+ OID_GEN_RCV_ERROR, -+ OID_GEN_RCV_NO_BUFFER, -+ /* mandatory 802.3 */ -+ /* the general stuff */ -+ OID_802_3_PERMANENT_ADDRESS, -+ OID_802_3_CURRENT_ADDRESS, -+ OID_802_3_MULTICAST_LIST, -+ OID_802_3_MAC_OPTIONS, -+ OID_802_3_MAXIMUM_LIST_SIZE, -+ -+ /* the statistical stuff */ -+ OID_802_3_RCV_ERROR_ALIGNMENT, -+ OID_802_3_XMIT_ONE_COLLISION, -+ OID_802_3_XMIT_MORE_COLLISIONS -+}; -+ -+struct rndis_response { -+ TAILQ_ENTRY(rndis_response) entries; -+ uint32_t length; -+ uint8_t buf[0]; -+}; -+ -+ -+typedef struct USBNetState { -+ USBDevice dev; -+ -+ unsigned int rndis; -+ enum rndis_state rndis_state; -+ uint32_t medium; -+ uint32_t speed; -+ uint32_t media_state; -+ uint16_t filter; -+ uint32_t vendorid; -+ uint8_t mac[6]; -+ -+ unsigned int out_ptr; -+ uint8_t out_buf[2048]; -+ -+ USBPacket *inpkt; -+ unsigned int in_ptr, in_len; -+ uint8_t in_buf[2048]; -+ -+ VLANClientState *vc; -+ TAILQ_HEAD(rndis_resp_head, rndis_response) rndis_resp; -+} USBNetState; -+ -+ -+static int ndis_query(USBNetState *s, uint32_t oid, uint8_t *inbuf, unsigned int inlen, uint8_t *outbuf) -+{ -+ switch (oid) { -+ /* general oids (table 4-1) */ -+ /* mandatory */ -+ case OID_GEN_SUPPORTED_LIST: -+ { -+ unsigned int i, count = sizeof(oid_supported_list) / sizeof(uint32_t); -+ for (i = 0; i < count; i++) -+ ((__le32 *)outbuf)[i] = cpu_to_le32(oid_supported_list[i]); -+ return sizeof(oid_supported_list); -+ } -+ -+ /* mandatory */ -+ case OID_GEN_HARDWARE_STATUS: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_MEDIA_SUPPORTED: -+ *((__le32 *)outbuf) = cpu_to_le32(s->medium); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_MEDIA_IN_USE: -+ *((__le32 *)outbuf) = cpu_to_le32(s->medium); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_MAXIMUM_FRAME_SIZE: -+ *((__le32 *)outbuf) = cpu_to_le32(ETH_FRAME_LEN); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_LINK_SPEED: -+ *((__le32 *)outbuf) = cpu_to_le32(s->speed); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_TRANSMIT_BLOCK_SIZE: -+ *((__le32 *)outbuf) = cpu_to_le32(ETH_FRAME_LEN); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_RECEIVE_BLOCK_SIZE: -+ *((__le32 *)outbuf) = cpu_to_le32(ETH_FRAME_LEN); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_VENDOR_ID: -+ *((__le32 *)outbuf) = cpu_to_le32(0x1234); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_VENDOR_DESCRIPTION: -+ strcpy(outbuf, "QEMU USB RNDIS Net"); -+ return strlen(outbuf) + 1; -+ -+ case OID_GEN_VENDOR_DRIVER_VERSION: -+ *((__le32 *)outbuf) = cpu_to_le32(1); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_CURRENT_PACKET_FILTER: -+ *((__le32 *)outbuf) = cpu_to_le32(s->filter); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_MAXIMUM_TOTAL_SIZE: -+ *((__le32 *)outbuf) = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_MEDIA_CONNECT_STATUS: -+ *((__le32 *)outbuf) = cpu_to_le32(s->media_state); -+ return sizeof(__le32); -+ -+ case OID_GEN_PHYSICAL_MEDIUM: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ case OID_GEN_MAC_OPTIONS: -+ *((__le32 *)outbuf) = cpu_to_le32(NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_FULL_DUPLEX); -+ return sizeof(__le32); -+ -+ /* statistics OIDs (table 4-2) */ -+ /* mandatory */ -+ case OID_GEN_XMIT_OK: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_RCV_OK: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_XMIT_ERROR: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_RCV_ERROR: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_GEN_RCV_NO_BUFFER: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ /* ieee802.3 OIDs (table 4-3) */ -+ /* mandatory */ -+ case OID_802_3_PERMANENT_ADDRESS: -+ memcpy(outbuf, s->mac, 6); -+ return 6; -+ -+ /* mandatory */ -+ case OID_802_3_CURRENT_ADDRESS: -+ memcpy(outbuf, s->mac, 6); -+ return 6; -+ -+ /* mandatory */ -+ case OID_802_3_MULTICAST_LIST: -+ *((__le32 *)outbuf) = cpu_to_le32(0xE0000000); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_802_3_MAXIMUM_LIST_SIZE: -+ *((__le32 *)outbuf) = cpu_to_le32(1); -+ return sizeof(__le32); -+ -+ case OID_802_3_MAC_OPTIONS: -+ return 0; -+ -+ /* ieee802.3 statistics OIDs (table 4-4) */ -+ /* mandatory */ -+ case OID_802_3_RCV_ERROR_ALIGNMENT: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_802_3_XMIT_ONE_COLLISION: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ /* mandatory */ -+ case OID_802_3_XMIT_MORE_COLLISIONS: -+ *((__le32 *)outbuf) = cpu_to_le32(0); -+ return sizeof(__le32); -+ -+ default: -+ fprintf(stderr, "usbnet: unknown OID 0x%08x\n", oid); -+ return 0; -+ } -+ return -1; -+} -+ -+static int ndis_set(USBNetState *s, uint32_t oid, uint8_t *inbuf, unsigned int inlen) -+{ -+ switch (oid) { -+ case OID_GEN_CURRENT_PACKET_FILTER: -+ s->filter = le32_to_cpup((__le32 *)inbuf); -+ if (s->filter) { -+ s->rndis_state = RNDIS_DATA_INITIALIZED; -+ } else { -+ s->rndis_state = RNDIS_INITIALIZED; -+ } -+ return 0; -+ -+ case OID_802_3_MULTICAST_LIST: -+ return 0; -+ -+ } -+ return -1; -+} -+ -+static int rndis_get_response(USBNetState *s, uint8_t *buf) -+{ -+ int ret = 0; -+ struct rndis_response *r = s->rndis_resp.tqh_first; -+ if (!r) -+ return ret; -+ TAILQ_REMOVE(&s->rndis_resp, r, entries); -+ ret = r->length; -+ memcpy(buf, r->buf, r->length); -+ qemu_free(r); -+ return ret; -+} -+ -+static void *rndis_queue_response(USBNetState *s, unsigned int length) -+{ -+ struct rndis_response *r = qemu_mallocz(sizeof(struct rndis_response) + length); -+ if (!r) -+ return NULL; -+ TAILQ_INSERT_TAIL(&s->rndis_resp, r, entries); -+ r->length = length; -+ return &r->buf[0]; -+} -+ -+static void rndis_clear_responsequeue(USBNetState *s) -+{ -+ struct rndis_response *r; -+ -+ while ((r = s->rndis_resp.tqh_first)) { -+ TAILQ_REMOVE(&s->rndis_resp, r, entries); -+ qemu_free(r); -+ } -+} -+ -+static int rndis_init_response(USBNetState *s, rndis_init_msg_type *buf) -+{ -+ rndis_init_cmplt_type *resp = rndis_queue_response(s, sizeof(rndis_init_cmplt_type)); -+ if (!resp) -+ return USB_RET_STALL; -+ resp->MessageType = cpu_to_le32(REMOTE_NDIS_INITIALIZE_CMPLT); -+ resp->MessageLength = cpu_to_le32(sizeof(rndis_init_cmplt_type)); -+ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ -+ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); -+ resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION); -+ resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION); -+ resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS); -+ resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3); -+ resp->MaxPacketsPerTransfer = cpu_to_le32(1); -+ resp->MaxTransferSize = cpu_to_le32(ETH_FRAME_LEN + sizeof(struct rndis_packet_msg_type) + 22); -+ resp->PacketAlignmentFactor = cpu_to_le32(0); -+ resp->AFListOffset = cpu_to_le32(0); -+ resp->AFListSize = cpu_to_le32(0); -+ return 0; -+} -+ -+static int rndis_query_response(USBNetState *s, rndis_query_msg_type *buf, unsigned int length) -+{ -+ rndis_query_cmplt_type *resp; -+ uint8_t infobuf[sizeof(oid_supported_list)]; /* oid_supported_list is the largest data reply */ -+ uint32_t bufoffs, buflen; -+ int infobuflen; -+ unsigned int resplen; -+ bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8; -+ buflen = le32_to_cpu(buf->InformationBufferLength); -+ if (bufoffs + buflen > length) -+ return USB_RET_STALL; -+ infobuflen = ndis_query(s, le32_to_cpu(buf->OID), bufoffs + (uint8_t *)buf, buflen, infobuf); -+ resplen = sizeof(rndis_query_cmplt_type) + ((infobuflen < 0) ? 0 : infobuflen); -+ resp = rndis_queue_response(s, resplen); -+ if (!resp) -+ return USB_RET_STALL; -+ resp->MessageType = cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT); -+ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ -+ resp->MessageLength = cpu_to_le32(resplen); -+ if (infobuflen < 0) { -+ /* OID not supported */ -+ resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); -+ resp->InformationBufferLength = cpu_to_le32(0); -+ resp->InformationBufferOffset = cpu_to_le32(0); -+ return 0; -+ } -+ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); -+ resp->InformationBufferOffset = cpu_to_le32(infobuflen ? sizeof(rndis_query_cmplt_type) - 8 : 0); -+ resp->InformationBufferLength = cpu_to_le32(infobuflen); -+ memcpy(resp + 1, infobuf, infobuflen); -+ return 0; -+} -+ -+static int rndis_set_response(USBNetState *s, rndis_set_msg_type *buf, unsigned int length) -+{ -+ rndis_set_cmplt_type *resp = rndis_queue_response(s, sizeof(rndis_set_cmplt_type)); -+ uint32_t bufoffs, buflen; -+ if (!resp) -+ return USB_RET_STALL; -+ bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8; -+ buflen = le32_to_cpu(buf->InformationBufferLength); -+ if (bufoffs + buflen > length) -+ return USB_RET_STALL; -+ int ret = ndis_set(s, le32_to_cpu(buf->OID), bufoffs + (uint8_t *)buf, buflen); -+ resp->MessageType = cpu_to_le32(REMOTE_NDIS_SET_CMPLT); -+ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ -+ resp->MessageLength = cpu_to_le32(sizeof(rndis_set_cmplt_type)); -+ if (ret < 0) { -+ /* OID not supported */ -+ resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); -+ return 0; -+ } -+ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); -+ return 0; -+} -+ -+static int rndis_reset_response(USBNetState *s, rndis_reset_msg_type *buf) -+{ -+ rndis_reset_cmplt_type *resp = rndis_queue_response(s, sizeof(rndis_reset_cmplt_type)); -+ if (!resp) -+ return USB_RET_STALL; -+ resp->MessageType = cpu_to_le32(REMOTE_NDIS_RESET_CMPLT); -+ resp->MessageLength = cpu_to_le32(sizeof(rndis_reset_cmplt_type)); -+ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); -+ /* resent information */ -+ resp->AddressingReset = cpu_to_le32(1); -+ return 0; -+} -+ -+static int rndis_keepalive_response(USBNetState *s, rndis_keepalive_msg_type *buf) -+{ -+ rndis_keepalive_cmplt_type *resp = rndis_queue_response(s, sizeof(rndis_keepalive_cmplt_type)); -+ if (!resp) -+ return USB_RET_STALL; -+ resp->MessageType = cpu_to_le32(REMOTE_NDIS_KEEPALIVE_CMPLT); -+ resp->MessageLength = cpu_to_le32(sizeof(rndis_keepalive_cmplt_type)); -+ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ -+ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); -+ return 0; -+} -+ -+static int rndis_parse(USBNetState *s, uint8_t *data, int length) -+{ -+ uint32_t MsgType, MsgLength; -+ __le32 *tmp = (__le32 *)data; -+ MsgType = le32_to_cpup(tmp++); -+ MsgLength = le32_to_cpup(tmp++); -+ -+ switch (MsgType) { -+ case REMOTE_NDIS_INITIALIZE_MSG: -+ s->rndis_state = RNDIS_INITIALIZED; -+ return rndis_init_response(s, (rndis_init_msg_type *)data); -+ -+ case REMOTE_NDIS_HALT_MSG: -+ s->rndis_state = RNDIS_UNINITIALIZED; -+ return 0; -+ -+ case REMOTE_NDIS_QUERY_MSG: -+ return rndis_query_response(s, (rndis_query_msg_type *)data, length); -+ -+ case REMOTE_NDIS_SET_MSG: -+ return rndis_set_response(s, (rndis_set_msg_type *)data, length); -+ -+ case REMOTE_NDIS_RESET_MSG: -+ rndis_clear_responsequeue(s); -+ s->out_ptr = s->in_ptr = s->in_len = 0; -+ return rndis_reset_response(s, (rndis_reset_msg_type *)data); -+ -+ case REMOTE_NDIS_KEEPALIVE_MSG: -+ /* For USB: host does this every 5 seconds */ -+ return rndis_keepalive_response(s, (rndis_keepalive_msg_type *)data); -+ } -+ return USB_RET_STALL; -+} -+ -+static void usb_net_handle_reset(USBDevice *dev) -+{ -+} -+ -+static int usb_net_handle_control(USBDevice *dev, int request, int value, -+ int index, int length, uint8_t *data) -+{ -+ USBNetState *s = (USBNetState *)dev; -+ int ret = 0; -+ -+ switch(request) { -+ case DeviceRequest | USB_REQ_GET_STATUS: -+ data[0] = (1 << USB_DEVICE_SELF_POWERED) | -+ (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); -+ data[1] = 0x00; -+ ret = 2; -+ break; -+ -+ case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: -+ if (value == USB_DEVICE_REMOTE_WAKEUP) { -+ dev->remote_wakeup = 0; -+ } else { -+ goto fail; -+ } -+ ret = 0; -+ break; -+ -+ case DeviceOutRequest | USB_REQ_SET_FEATURE: -+ if (value == USB_DEVICE_REMOTE_WAKEUP) { -+ dev->remote_wakeup = 1; -+ } else { -+ goto fail; -+ } -+ ret = 0; -+ break; -+ -+ case DeviceOutRequest | USB_REQ_SET_ADDRESS: -+ dev->addr = value; -+ ret = 0; -+ break; -+ -+ case ClassInterfaceOutRequest | USB_CDC_SEND_ENCAPSULATED_COMMAND: -+ if (!s->rndis || value || index != 0) -+ goto fail; -+#if TRAFFIC_DEBUG -+ { -+ unsigned int i; -+ fprintf(stderr, "SEND_ENCAPSULATED_COMMAND:"); -+ for (i = 0; i < length; i++) { -+ if (!(i & 15)) -+ fprintf(stderr, "\n%04X:", i); -+ fprintf(stderr, " %02X", data[i]); -+ } -+ fprintf(stderr, "\n\n"); -+ } -+#endif -+ ret = rndis_parse(s, data, length); -+ break; -+ -+ case ClassInterfaceRequest | USB_CDC_GET_ENCAPSULATED_RESPONSE: -+ if (!s->rndis || value || index != 0) -+ goto fail; -+ ret = rndis_get_response(s, data); -+ if (!ret) { -+ data[0] = 0; -+ ret = 1; -+ } -+#if TRAFFIC_DEBUG -+ { -+ unsigned int i; -+ fprintf(stderr, "GET_ENCAPSULATED_RESPONSE:"); -+ for (i = 0; i < ret; i++) { -+ if (!(i & 15)) -+ fprintf(stderr, "\n%04X:", i); -+ fprintf(stderr, " %02X", data[i]); -+ } -+ fprintf(stderr, "\n\n"); -+ } -+#endif -+ break; -+ -+ case DeviceRequest | USB_REQ_GET_DESCRIPTOR: -+ switch(value >> 8) { -+ case USB_DT_DEVICE: -+ ret = sizeof(qemu_net_dev_descriptor); -+ memcpy(data, qemu_net_dev_descriptor, ret); -+ break; -+ -+ case USB_DT_CONFIG: -+ switch (value & 0xff) { -+ case 0: -+ ret = sizeof(qemu_net_rndis_config_descriptor); -+ memcpy(data, qemu_net_rndis_config_descriptor, -+ ret); -+ break; -+ -+ case 1: -+ ret = sizeof(qemu_net_cdc_config_descriptor); -+ memcpy(data, qemu_net_cdc_config_descriptor, -+ ret); -+ break; -+ -+ default: -+ goto fail; -+ } -+ data[2] = ret & 0xff; -+ data[3] = ret >> 8; -+ break; -+ -+ case USB_DT_STRING: -+ switch (value & 0xff) { -+ case 0: -+ /* language ids */ -+ data[0] = 4; -+ data[1] = 3; -+ data[2] = 0x09; -+ data[3] = 0x04; -+ ret = 4; -+ break; -+ -+ case STRING_MANUFACTURER: -+ ret = set_usb_string(data, "QEMU"); -+ break; -+ -+ case STRING_PRODUCT: -+ ret = set_usb_string(data, "RNDIS/QEMU USB Network Device"); -+ break; -+ -+ case STRING_ETHADDR: -+ ret = set_usb_string(data, "400102030405"); -+ break; -+ -+ case STRING_DATA: -+ ret = set_usb_string(data, "QEMU USB Net Data Interface"); -+ break; -+ -+ case STRING_CONTROL: -+ ret = set_usb_string(data, "QEMU USB Net Control Interface"); -+ break; -+ -+ case STRING_RNDIS_CONTROL: -+ ret = set_usb_string(data, "QEMU USB Net RNDIS Control Interface"); -+ break; -+ -+ case STRING_CDC: -+ ret = set_usb_string(data, "QEMU USB Net CDC"); -+ break; -+ -+ case STRING_SUBSET: -+ ret = set_usb_string(data, "QEMU USB Net Subset"); -+ break; -+ -+ case STRING_RNDIS: -+ ret = set_usb_string(data, "QEMU USB Net RNDIS"); -+ break; -+ -+ case STRING_SERIALNUMBER: -+ ret = set_usb_string(data, "1"); -+ break; -+ -+ default: -+ goto fail; -+ } -+ break; -+ -+ default: -+ goto fail; -+ } -+ break; -+ -+ case DeviceRequest | USB_REQ_GET_CONFIGURATION: -+ data[0] = s->rndis ? DEV_RNDIS_CONFIG_VALUE : DEV_CONFIG_VALUE; -+ ret = 1; -+ break; -+ -+ case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: -+ switch (value & 0xff) { -+ case DEV_CONFIG_VALUE: -+ s->rndis = 0; -+ break; -+ -+ case DEV_RNDIS_CONFIG_VALUE: -+ s->rndis = 1; -+ break; -+ -+ default: -+ goto fail; -+ } -+ ret = 0; -+ break; -+ -+ case DeviceRequest | USB_REQ_GET_INTERFACE: -+ case InterfaceRequest | USB_REQ_GET_INTERFACE: -+ data[0] = 0; -+ ret = 1; -+ break; -+ -+ case DeviceOutRequest | USB_REQ_SET_INTERFACE: -+ case InterfaceOutRequest | USB_REQ_SET_INTERFACE: -+ ret = 0; -+ break; -+ -+ default: -+ fail: -+ fprintf(stderr, "usbnet: failed control transaction: request 0x%x value 0x%x index 0x%x length 0x%x\n", -+ request, value, index, length); -+ ret = USB_RET_STALL; -+ break; -+ } -+ return ret; -+} -+ -+static int usb_net_handle_statusin(USBNetState *s, USBPacket *p) -+{ -+ int ret = 8; -+ if (p->len < 8) -+ return USB_RET_STALL; -+ ((__le32 *)p->data)[0] = cpu_to_le32(1); -+ ((__le32 *)p->data)[1] = cpu_to_le32(0); -+ if (!s->rndis_resp.tqh_first) -+ ret = USB_RET_NAK; -+#if DEBUG -+ fprintf(stderr, "usbnet: interrupt poll len %u return %d", p->len, ret); -+ { -+ int i; -+ fprintf(stderr, ":"); -+ for (i = 0; i < ret; i++) { -+ if (!(i & 15)) -+ fprintf(stderr, "\n%04X:", i); -+ fprintf(stderr, " %02X", p->data[i]); -+ } -+ fprintf(stderr, "\n\n"); -+ } -+#endif -+ return ret; -+} -+ -+static int usb_net_handle_datain(USBNetState *s, USBPacket *p) -+{ -+ int ret = USB_RET_NAK; -+ -+ if (s->in_ptr > s->in_len) { -+ s->in_ptr = s->in_len = 0; -+ ret = USB_RET_NAK; -+ return ret; -+ } -+ if (!s->in_len) { -+ ret = USB_RET_NAK; -+ return ret; -+ } -+ ret = s->in_len - s->in_ptr; -+ if (ret > p->len) -+ ret = p->len; -+ memcpy(p->data, &s->in_buf[s->in_ptr], ret); -+ s->in_ptr += ret; -+ if (s->in_ptr >= s->in_len && (s->rndis || (s->in_len & (64-1)) || !ret)) { -+ /* no short packet necessary */ -+ s->in_ptr = s->in_len = 0; -+ } -+#if TRAFFIC_DEBUG -+ fprintf(stderr, "usbnet: data in len %u return %d", p->len, ret); -+ { -+ int i; -+ fprintf(stderr, ":"); -+ for (i = 0; i < ret; i++) { -+ if (!(i & 15)) -+ fprintf(stderr, "\n%04X:", i); -+ fprintf(stderr, " %02X", p->data[i]); -+ } -+ fprintf(stderr, "\n\n"); -+ } -+#endif -+ return ret; -+} -+ -+static int usb_net_handle_dataout(USBNetState *s, USBPacket *p) -+{ -+ int ret = p->len; -+ int sz = sizeof(s->out_buf) - s->out_ptr; -+ struct rndis_packet_msg_type *msg = (struct rndis_packet_msg_type *)s->out_buf; -+ uint32_t len; -+ -+#if TRAFFIC_DEBUG -+ fprintf(stderr, "usbnet: data out len %u\n", p->len); -+ { -+ int i; -+ fprintf(stderr, ":"); -+ for (i = 0; i < p->len; i++) { -+ if (!(i & 15)) -+ fprintf(stderr, "\n%04X:", i); -+ fprintf(stderr, " %02X", p->data[i]); -+ } -+ fprintf(stderr, "\n\n"); -+ } -+#endif -+ if (sz > ret) -+ sz = ret; -+ memcpy(&s->out_buf[s->out_ptr], p->data, sz); -+ s->out_ptr += sz; -+ if (!s->rndis) { -+ if (ret < 64) { -+ qemu_send_packet(s->vc, s->out_buf, s->out_ptr); -+ s->out_ptr = 0; -+ } -+ return ret; -+ } -+ len = le32_to_cpu(msg->MessageLength); -+ if (s->out_ptr < 8 || s->out_ptr < len) -+ return ret; -+ if (le32_to_cpu(msg->MessageType) == REMOTE_NDIS_PACKET_MSG) { -+ uint32_t offs = 8 + le32_to_cpu(msg->DataOffset); -+ uint32_t size = le32_to_cpu(msg->DataLength); -+ if (offs + size <= len) -+ qemu_send_packet(s->vc, s->out_buf + offs, size); -+ } -+ s->out_ptr -= len; -+ memmove(s->out_buf, &s->out_buf[len], s->out_ptr); -+ return ret; -+} -+ -+static int usb_net_handle_data(USBDevice *dev, USBPacket *p) -+{ -+ USBNetState *s = (USBNetState *)dev; -+ int ret = 0; -+ -+ switch(p->pid) { -+ case USB_TOKEN_IN: -+ switch (p->devep) { -+ case 1: -+ ret = usb_net_handle_statusin(s, p); -+ break; -+ -+ case 2: -+ ret = usb_net_handle_datain(s, p); -+ break; -+ -+ default: -+ goto fail; -+ } -+ break; -+ -+ case USB_TOKEN_OUT: -+ switch (p->devep) { -+ case 2: -+ ret = usb_net_handle_dataout(s, p); -+ break; -+ -+ default: -+ goto fail; -+ } -+ break; -+ -+ default: -+ fail: -+ ret = USB_RET_STALL; -+ break; -+ } -+ if (ret == USB_RET_STALL) -+ fprintf(stderr, "usbnet: failed data transaction: pid 0x%x ep 0x%x len 0x%x\n", p->pid, p->devep, p->len); -+ return ret; -+} -+ -+static void usbnet_receive(void *opaque, const uint8_t *buf, int size) -+{ -+ USBNetState *s = opaque; -+ -+ if (s->rndis) { -+ struct rndis_packet_msg_type *msg = (struct rndis_packet_msg_type *)s->in_buf; -+ if (!s->rndis_state == RNDIS_DATA_INITIALIZED) -+ return; -+ if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf)) -+ return; -+ memset(msg, 0, sizeof(struct rndis_packet_msg_type)); -+ msg->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG); -+ msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type)); -+ msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8); -+ msg->DataLength = cpu_to_le32(size); -+ //msg->OOBDataOffset; -+ //msg->OOBDataLength; -+ //msg->NumOOBDataElements; -+ //msg->PerPacketInfoOffset; -+ //msg->PerPacketInfoLength; -+ //msg->VcHandle; -+ //msg->Reserved; -+ memcpy(msg + 1, buf, size); -+ s->in_len = size + sizeof(struct rndis_packet_msg_type); -+ } else { -+ if (size > sizeof(s->in_buf)) -+ return; -+ memcpy(s->in_buf, buf, size); -+ s->in_len = size; -+ } -+ s->in_ptr = 0; -+} -+ -+static int usbnet_can_receive(void *opaque) -+{ -+ USBNetState *s = opaque; -+ -+ if (s->rndis && !s->rndis_state == RNDIS_DATA_INITIALIZED) -+ return 1; -+ return !s->in_len; -+} -+ -+static void usb_net_handle_destroy(USBDevice *dev) -+{ -+ USBNetState *s = (USBNetState *)dev; -+ rndis_clear_responsequeue(s); -+ qemu_free(s); -+} -+ -+USBDevice *usb_net_init(NICInfo *nd) -+{ -+ USBNetState *s; -+ -+ s = qemu_mallocz(sizeof(USBNetState)); -+ if (!s) -+ return NULL; -+ s->dev.speed = USB_SPEED_FULL; -+ s->dev.handle_packet = usb_generic_handle_packet; -+ -+ s->dev.handle_reset = usb_net_handle_reset; -+ s->dev.handle_control = usb_net_handle_control; -+ s->dev.handle_data = usb_net_handle_data; -+ s->dev.handle_destroy = usb_net_handle_destroy; -+ -+ s->rndis = 1; -+ s->rndis_state = RNDIS_UNINITIALIZED; -+ s->medium = NDIS_MEDIUM_802_3; -+ s->speed = 1000000; /* 100MBps, in 100Bps units */ -+ s->media_state = NDIS_MEDIA_STATE_CONNECTED; -+ s->filter = 0; -+ s->vendorid = 0x1234; -+ memcpy(s->mac, nd->macaddr, 6); -+ TAILQ_INIT(&s->rndis_resp); -+ -+ pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Network Interface"); -+ s->vc = qemu_new_vlan_client(nd->vlan, usbnet_receive, usbnet_can_receive, s); -+ snprintf(s->vc->info_str, sizeof(s->vc->info_str), -+ "usbnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x", -+ s->mac[0], s->mac[1], s->mac[2], -+ s->mac[3], s->mac[4], s->mac[5]); -+ fprintf(stderr, "usbnet: initialized mac %02x:%02x:%02x:%02x:%02x:%02x\n", -+ s->mac[0], s->mac[1], s->mac[2], -+ s->mac[3], s->mac[4], s->mac[5]); -+ return (USBDevice *)s; -+} -diff -urN 4242/Makefile qemu-omap/Makefile ---- 4242/Makefile 2008-04-24 20:17:05.000000000 +0100 -+++ qemu-omap/Makefile 2008-04-23 09:57:55.000000000 +0100 -@@ -55,7 +55,8 @@ - OBJS+=tmp105.o - OBJS+=scsi-disk.o cdrom.o - OBJS+=scsi-generic.o --OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o usb-serial.o -+OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-net.o -+OBJS+=usb-wacom.o usb-serial.o - OBJS+=sd.o ssi-sd.o - - ifdef CONFIG_BRLAPI -diff -urN 4242/softmmu_template.h qemu-omap/softmmu_template.h ---- 4242/softmmu_template.h 2008-04-24 18:11:49.000000000 +0100 -+++ qemu-omap/softmmu_template.h 2008-04-23 09:57:56.000000000 +0100 -@@ -51,12 +51,15 @@ - int mmu_idx, - void *retaddr); - static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, -- target_ulong tlb_addr) -+ target_ulong tlb_addr, -+ target_ulong tlb_io) - { - DATA_TYPE res; - int index; - -- index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); -+ index = (tlb_addr & ~TARGET_PAGE_MASK) >> IO_MEM_SHIFT; -+ if (index > 4) -+ index = (tlb_io >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); - #if SHIFT <= 2 - res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr); - #else -@@ -95,7 +98,9 @@ - /* IO access */ - if ((addr & (DATA_SIZE - 1)) != 0) - goto do_unaligned_access; -- res = glue(io_read, SUFFIX)(physaddr, tlb_addr); -+ res = glue(io_read, SUFFIX)(physaddr, tlb_addr, -+ env->tlb_table[mmu_idx] -+ [index].addr_code); - } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - /* slow unaligned access (it spans two pages or IO) */ - do_unaligned_access: -@@ -147,7 +152,9 @@ - /* IO access */ - if ((addr & (DATA_SIZE - 1)) != 0) - goto do_unaligned_access; -- res = glue(io_read, SUFFIX)(physaddr, tlb_addr); -+ res = glue(io_read, SUFFIX)(physaddr, tlb_addr, -+ env->tlb_table[mmu_idx] -+ [index].addr_code); - } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - do_unaligned_access: - /* slow unaligned access (it spans two pages) */ -@@ -186,11 +193,14 @@ - static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, - DATA_TYPE val, - target_ulong tlb_addr, -- void *retaddr) -+ void *retaddr, -+ target_ulong tlb_io) - { - int index; - -- index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); -+ index = (tlb_addr & ~TARGET_PAGE_MASK) >> IO_MEM_SHIFT; -+ if (index > 4) -+ index = (tlb_io >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); - env->mem_write_vaddr = tlb_addr; - env->mem_write_pc = (unsigned long)retaddr; - #if SHIFT <= 2 -@@ -228,7 +238,8 @@ - if ((addr & (DATA_SIZE - 1)) != 0) - goto do_unaligned_access; - retaddr = GETPC(); -- glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr); -+ glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr, -+ env->tlb_table[mmu_idx][index].addr_code); - } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - do_unaligned_access: - retaddr = GETPC(); -@@ -278,7 +289,8 @@ - /* IO access */ - if ((addr & (DATA_SIZE - 1)) != 0) - goto do_unaligned_access; -- glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr); -+ glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr, -+ env->tlb_table[mmu_idx][index].addr_code); - } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - do_unaligned_access: - /* XXX: not efficient, but simple */ -diff -urN 4242/target-i386/cpu.h qemu-omap/target-i386/cpu.h ---- 4242/target-i386/cpu.h 2008-04-23 12:18:51.000000000 +0100 -+++ qemu-omap/target-i386/cpu.h 2008-04-23 09:57:56.000000000 +0100 -@@ -499,7 +499,7 @@ - SegmentCache idt; /* only base and limit are used */ - - target_ulong cr[9]; /* NOTE: cr1, cr5-7 are unused */ -- uint64_t a20_mask; -+ uint32_t a20_mask; - - /* FPU state */ - unsigned int fpstt; /* top of stack index */ -diff -urN 4242/target-i386/helper2.c qemu-omap/target-i386/helper2.c ---- 4242/target-i386/helper2.c 2008-04-23 12:18:51.000000000 +0100 -+++ qemu-omap/target-i386/helper2.c 2008-04-23 09:57:56.000000000 +0100 -@@ -377,7 +377,7 @@ - env->hflags |= HF_GIF_MASK; - - cpu_x86_update_cr0(env, 0x60000010); -- env->a20_mask = ~0x0; -+ env->a20_mask = 0xffffffff; - env->smbase = 0x30000; - - env->idt.limit = 0xffff; -@@ -695,7 +695,7 @@ - /* when a20 is changed, all the MMU mappings are invalid, so - we must flush everything */ - tlb_flush(env, 1); -- env->a20_mask = (~0x100000) | (a20_state << 20); -+ env->a20_mask = 0xffefffff | (a20_state << 20); - } - } - -@@ -800,8 +800,7 @@ - - #else - --/* Bits 52-62 of a PTE are reserved. Bit 63 is the NX bit. */ --#define PHYS_ADDR_MASK 0xffffffffff000L -+#define PHYS_ADDR_MASK 0xfffff000 - - /* return value: - -1 = cannot handle fault -@@ -813,10 +812,9 @@ - int is_write1, int mmu_idx, int is_softmmu) - { - uint64_t ptep, pte; -- target_ulong pde_addr, pte_addr; -+ uint32_t pdpe_addr, pde_addr, pte_addr; - int error_code, is_dirty, prot, page_size, ret, is_write, is_user; -- target_phys_addr_t paddr; -- uint32_t page_offset; -+ unsigned long paddr, page_offset; - target_ulong vaddr, virt_addr; - - is_user = mmu_idx == MMU_USER_IDX; -@@ -836,11 +834,12 @@ - - if (env->cr[4] & CR4_PAE_MASK) { - uint64_t pde, pdpe; -- target_ulong pdpe_addr; - -+ /* XXX: we only use 32 bit physical addresses */ - #ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { -- uint64_t pml4e_addr, pml4e; -+ uint32_t pml4e_addr; -+ uint64_t pml4e; - int32_t sext; - - /* test virtual address sign extension */ -@@ -1102,19 +1101,17 @@ - - target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) - { -- target_ulong pde_addr, pte_addr; -- uint64_t pte; -- target_phys_addr_t paddr; -- uint32_t page_offset; -- int page_size; -+ uint32_t pde_addr, pte_addr; -+ uint32_t pde, pte, paddr, page_offset, page_size; - - if (env->cr[4] & CR4_PAE_MASK) { -- target_ulong pdpe_addr; -- uint64_t pde, pdpe; -+ uint32_t pdpe_addr, pde_addr, pte_addr; -+ uint32_t pdpe; - -+ /* XXX: we only use 32 bit physical addresses */ - #ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { -- uint64_t pml4e_addr, pml4e; -+ uint32_t pml4e_addr, pml4e; - int32_t sext; - - /* test virtual address sign extension */ -@@ -1124,13 +1121,13 @@ - - pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) & - env->a20_mask; -- pml4e = ldq_phys(pml4e_addr); -+ pml4e = ldl_phys(pml4e_addr); - if (!(pml4e & PG_PRESENT_MASK)) - return -1; - - pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) & - env->a20_mask; -- pdpe = ldq_phys(pdpe_addr); -+ pdpe = ldl_phys(pdpe_addr); - if (!(pdpe & PG_PRESENT_MASK)) - return -1; - } else -@@ -1138,14 +1135,14 @@ - { - pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & - env->a20_mask; -- pdpe = ldq_phys(pdpe_addr); -+ pdpe = ldl_phys(pdpe_addr); - if (!(pdpe & PG_PRESENT_MASK)) - return -1; - } - - pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) & - env->a20_mask; -- pde = ldq_phys(pde_addr); -+ pde = ldl_phys(pde_addr); - if (!(pde & PG_PRESENT_MASK)) { - return -1; - } -@@ -1158,11 +1155,9 @@ - pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) & - env->a20_mask; - page_size = 4096; -- pte = ldq_phys(pte_addr); -+ pte = ldl_phys(pte_addr); - } - } else { -- uint32_t pde; -- - if (!(env->cr[0] & CR0_PG_MASK)) { - pte = addr; - page_size = 4096; -diff -urN 4242/vl.c qemu-omap/vl.c ---- 4242/vl.c 2008-04-24 21:26:21.000000000 +0100 -+++ qemu-omap/vl.c 2008-04-23 09:57:57.000000000 +0100 -@@ -5284,6 +5284,11 @@ - dev = usb_keyboard_init(); - } else if (strstart(devname, "disk:", &p)) { - dev = usb_msd_init(p); -+ } else if (strstart(devname, "net:", &p)) { -+ unsigned int nr = strtoul(p, NULL, 0); -+ if (nr >= (unsigned int) nb_nics || strcmp(nd_table[nr].model, "usb")) -+ return -1; -+ dev = usb_net_init(&nd_table[nr]); - } else if (!strcmp(devname, "wacom-tablet")) { - dev = usb_wacom_init(); - } else if (strstart(devname, "serial:", &p)) { diff --git a/meta/packages/qemu/qemu-0.9.1+svn/revert_arm_tcg.patch.gz b/meta/packages/qemu/qemu-0.9.1+svn/revert_arm_tcg.patch.gz deleted file mode 100644 index eb2a76c1672d382acb97dfb4b258a0dc8213220c..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc-jL100001 literal 97991 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 diff --git a/meta/packages/qemu/qemu-0.9.1+svn/series b/meta/packages/qemu/qemu-0.9.1+svn/series deleted file mode 100644 index fb110340c43..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/series +++ /dev/null @@ -1,25 +0,0 @@ -05_non-fatal_if_linux_hd_missing.patch -06_exit_segfault.patch -p0 -10_signal_jobs.patch -p0 -11_signal_sigaction.patch -p0 -22_net_tuntap_stall.patch -p0 -31_syscalls.patch -p0 -32_syscall_sysctl.patch -p0 -33_syscall_ppc_clone.patch -p0 -39_syscall_fadvise64.patch -p0 -52_ne2000_return.patch -61_safe_64bit_int.patch -p0 -63_sparc_build.patch -p0 -64_ppc_asm_constraints.patch -65_kfreebsd.patch -p0 -66_tls_ld.patch -p0 -91-oh-sdl-cursor.patch -p0 -qemu-0.9.0-nptl.patch -qemu-0.9.0-nptl-update.patch -qemu-amd64-32b-mapping-0.9.0.patch -workaround_bad_futex_headers.patch -p1 -fix_segfault.patch -no-strip.patch -fix_brk.patch -fix_protection_bits.patch -p1 -qemu-n800-support.patch -p1 diff --git a/meta/packages/qemu/qemu-0.9.1+svn/workaround_bad_futex_headers.patch b/meta/packages/qemu/qemu-0.9.1+svn/workaround_bad_futex_headers.patch deleted file mode 100644 index cc122ebdba4..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/workaround_bad_futex_headers.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- - linux-user/syscall.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -Index: qemu/linux-user/syscall.c -=================================================================== ---- qemu.orig/linux-user/syscall.c 2007-08-09 20:28:06.000000000 +0100 -+++ qemu/linux-user/syscall.c 2007-08-09 20:28:41.000000000 +0100 -@@ -61,7 +61,15 @@ - #define tchars host_tchars /* same as target */ - #define ltchars host_ltchars /* same as target */ - --#include -+#define FUTEX_WAIT 0 -+#define FUTEX_WAKE 1 -+#define FUTEX_FD 2 -+#define FUTEX_REQUEUE 3 -+#define FUTEX_CMP_REQUEUE 4 -+#define FUTEX_WAKE_OP 5 -+#define FUTEX_LOCK_PI 6 -+#define FUTEX_UNLOCK_PI 7 -+ - #include - #include - #include diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/02_snapshot_use_tmpdir.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/02_snapshot_use_tmpdir.patch deleted file mode 100644 index 40264ed443e..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/02_snapshot_use_tmpdir.patch +++ /dev/null @@ -1,23 +0,0 @@ -#DPATCHLEVEL=0 ---- -# block.c | 6 +++++- -# 1 file changed, 5 insertions(+), 1 deletion(-) -# -Index: block.c -=================================================================== ---- block.c.orig 2007-12-03 23:47:25.000000000 +0000 -+++ block.c 2007-12-03 23:47:31.000000000 +0000 -@@ -191,8 +191,12 @@ void get_tmp_filename(char *filename, in - void get_tmp_filename(char *filename, int size) - { - int fd; -+ char *tmpdir; - /* XXX: race condition possible */ -- pstrcpy(filename, size, "/tmp/vl.XXXXXX"); -+ tmpdir = getenv("TMPDIR"); -+ if (!tmpdir) -+ tmpdir = "/tmp"; -+ snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); - fd = mkstemp(filename); - close(fd); - } diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/04_do_not_print_rtc_freq_if_ok.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/04_do_not_print_rtc_freq_if_ok.patch deleted file mode 100644 index 31c9da491d3..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/04_do_not_print_rtc_freq_if_ok.patch +++ /dev/null @@ -1,26 +0,0 @@ -#DPATCHLEVEL=1 ---- -# vl.c | 5 ++++- -# 1 file changed, 4 insertions(+), 1 deletion(-) -# -Index: qemu/vl.c -=================================================================== ---- qemu.orig/vl.c 2007-12-03 15:44:35.000000000 +0000 -+++ qemu/vl.c 2007-12-03 15:51:03.000000000 +0000 -@@ -1289,12 +1289,15 @@ static void hpet_stop_timer(struct qemu_ - - static int rtc_start_timer(struct qemu_alarm_timer *t) - { -+ unsigned long current_rtc_freq = 0; - int rtc_fd; - - TFR(rtc_fd = open("/dev/rtc", O_RDONLY)); - if (rtc_fd < 0) - return -1; -- if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { -+ ioctl(rtc_fd, RTC_IRQP_READ, ¤t_rtc_freq); -+ if (current_rtc_freq != RTC_FREQ && -+ ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { - fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n" - "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n" - "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n"); diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/05_non-fatal_if_linux_hd_missing.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/05_non-fatal_if_linux_hd_missing.patch deleted file mode 100644 index fdd922605ee..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/05_non-fatal_if_linux_hd_missing.patch +++ /dev/null @@ -1,17 +0,0 @@ -#DPATCHLEVEL=1 ---- -# hw/pc.c | 1 - -# 1 file changed, 1 deletion(-) -# -Index: qemu/hw/pc.c -=================================================================== ---- qemu.orig/hw/pc.c 2007-12-03 23:47:25.000000000 +0000 -+++ qemu/hw/pc.c 2007-12-03 23:47:38.000000000 +0000 -@@ -385,7 +385,6 @@ static void generate_bootsect(uint32_t g - if (bs_table[0] == NULL) { - fprintf(stderr, "A disk image must be given for 'hda' when booting " - "a Linux kernel\n"); -- exit(1); - } - - memset(bootsect, 0, sizeof(bootsect)); diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/10_signal_jobs.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/10_signal_jobs.patch deleted file mode 100644 index 34282adc9d2..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/10_signal_jobs.patch +++ /dev/null @@ -1,26 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/signal.c | 7 ++++++- -# 1 file changed, 6 insertions(+), 1 deletion(-) -# -Index: linux-user/signal.c -=================================================================== ---- linux-user/signal.c.orig 2007-12-03 15:40:26.000000000 +0000 -+++ linux-user/signal.c 2007-12-03 15:55:49.000000000 +0000 -@@ -364,10 +364,15 @@ int queue_signal(int sig, target_siginfo - k = &sigact_table[sig - 1]; - handler = k->sa._sa_handler; - if (handler == TARGET_SIG_DFL) { -+ if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) { -+ kill(getpid(),SIGSTOP); -+ return 0; -+ } else - /* default handler : ignore some signal. The other are fatal */ - if (sig != TARGET_SIGCHLD && - sig != TARGET_SIGURG && -- sig != TARGET_SIGWINCH) { -+ sig != TARGET_SIGWINCH && -+ sig != TARGET_SIGCONT) { - force_sig(sig); - } else { - return 0; /* indicate ignored */ diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/22_net_tuntap_stall.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/22_net_tuntap_stall.patch deleted file mode 100644 index 6017df0f6d3..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/22_net_tuntap_stall.patch +++ /dev/null @@ -1,18 +0,0 @@ -#DPATCHLEVEL=0 ---- -# vl.c | 2 +- -# 1 file changed, 1 insertion(+), 1 deletion(-) -# -Index: vl.c -=================================================================== ---- vl.c.orig 2007-12-03 23:47:36.000000000 +0000 -+++ vl.c 2007-12-03 23:47:48.000000000 +0000 -@@ -4023,7 +4023,7 @@ static int tap_open(char *ifname, int if - return -1; - } - memset(&ifr, 0, sizeof(ifr)); -- ifr.ifr_flags = IFF_TAP | IFF_NO_PI; -+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE; - if (ifname[0] != '\0') - pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname); - else diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/31_syscalls.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/31_syscalls.patch deleted file mode 100644 index 95a7332ee89..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/31_syscalls.patch +++ /dev/null @@ -1,48 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/syscall.c | 11 ++++++++--- -# 1 file changed, 8 insertions(+), 3 deletions(-) -# -Index: linux-user/syscall.c -=================================================================== ---- linux-user/syscall.c.orig 2007-12-03 19:32:56.000000000 +0000 -+++ linux-user/syscall.c 2007-12-03 19:33:41.000000000 +0000 -@@ -250,6 +250,7 @@ extern int getresuid(uid_t *, uid_t *, u - extern int setresgid(gid_t, gid_t, gid_t); - extern int getresgid(gid_t *, gid_t *, gid_t *); - extern int setgroups(int, gid_t *); -+extern int uselib(const char*); - - #define ERRNO_TABLE_SIZE 1200 - -@@ -4024,7 +4025,8 @@ abi_long do_syscall(void *cpu_env, int n - #endif - #ifdef TARGET_NR_uselib - case TARGET_NR_uselib: -- goto unimplemented; -+ ret = get_errno(uselib(path((const char*)arg1))); -+ break; - #endif - #ifdef TARGET_NR_swapon - case TARGET_NR_swapon: -@@ -5289,7 +5291,9 @@ abi_long do_syscall(void *cpu_env, int n - goto unimplemented; - #ifdef TARGET_NR_mincore - case TARGET_NR_mincore: -- goto unimplemented; -+ /*page_unprotect_range((void*)arg3, ((size_t)arg2 + TARGET_PAGE_SIZE - 1) / TARGET_PAGE_SIZE);*/ -+ ret = get_errno(mincore((void*)arg1, (size_t)arg2, (unsigned char*)arg3)); -+ break; - #endif - #ifdef TARGET_NR_madvise - case TARGET_NR_madvise: -@@ -5429,7 +5433,8 @@ abi_long do_syscall(void *cpu_env, int n - break; - #ifdef TARGET_NR_readahead - case TARGET_NR_readahead: -- goto unimplemented; -+ ret = get_errno(readahead((int)arg1, (off64_t)arg2, (size_t)arg3)); -+ break; - #endif - #ifdef TARGET_NR_setxattr - case TARGET_NR_setxattr: diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/32_syscall_sysctl.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/32_syscall_sysctl.patch deleted file mode 100644 index 5e8dd75b0ea..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/32_syscall_sysctl.patch +++ /dev/null @@ -1,55 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/syscall.c | 32 +++++++++++++++++++++++++++++--- -# 1 file changed, 29 insertions(+), 3 deletions(-) -# -Index: linux-user/syscall.c -=================================================================== ---- linux-user/syscall.c.orig 2007-12-03 15:56:24.000000000 +0000 -+++ linux-user/syscall.c 2007-12-03 15:57:36.000000000 +0000 -@@ -52,6 +52,7 @@ - //#include - #include - #include -+#include - - #define termios host_termios - #define winsize host_winsize -@@ -4739,9 +4740,34 @@ abi_long do_syscall(void *cpu_env, int n - break; - #endif - case TARGET_NR__sysctl: -- /* We don't implement this, but ENOTDIR is always a safe -- return value. */ -- ret = -TARGET_ENOTDIR; -+ { -+ struct __sysctl_args *args = (struct __sysctl_args *) arg1; -+ int *name_target, *name, nlen, *oldlenp, oldlen, newlen, i; -+ void *oldval, *newval; -+ -+ name_target = (int *) tswapl((long) args->name); -+ nlen = tswapl(args->nlen); -+ oldval = (void *) tswapl((long) args->oldval); -+ oldlenp = (int *) tswapl((long) args->oldlenp); -+ oldlen = tswapl(*oldlenp); -+ newval = (void *) tswapl((long) args->newval); -+ newlen = tswapl(args->newlen); -+ -+ name = alloca(nlen * sizeof (int)); -+ for (i = 0; i < nlen; i++) -+ name[i] = tswapl(name_target[i]); -+ -+ if (nlen == 2 && name[0] == CTL_KERN && name[1] == KERN_VERSION) { -+ ret = get_errno( -+ sysctl(name, nlen, oldval, &oldlen, newval, newlen)); -+ if (!is_error(ret)) { -+ *oldlenp = tswapl(oldlen); -+ } -+ } else { -+ gemu_log("qemu: Unsupported sysctl name\n"); -+ ret = -ENOSYS; -+ } -+ } - break; - case TARGET_NR_sched_setparam: - { diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/33_syscall_ppc_clone.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/33_syscall_ppc_clone.patch deleted file mode 100644 index 3f733b6ab82..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/33_syscall_ppc_clone.patch +++ /dev/null @@ -1,22 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/syscall.c | 6 +----- -# 1 file changed, 1 insertion(+), 5 deletions(-) -# -Index: linux-user/syscall.c -=================================================================== ---- linux-user/syscall.c.orig 2007-12-03 15:58:11.000000000 +0000 -+++ linux-user/syscall.c 2007-12-03 15:58:46.000000000 +0000 -@@ -2750,11 +2750,7 @@ int do_fork(CPUState *env, unsigned int - if (!newsp) - newsp = env->gpr[1]; - new_env->gpr[1] = newsp; -- { -- int i; -- for (i = 7; i < 32; i++) -- new_env->gpr[i] = 0; -- } -+ new_env->gpr[3] = 0; - #elif defined(TARGET_SH4) - if (!newsp) - newsp = env->gregs[15]; diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/39_syscall_fadvise64.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/39_syscall_fadvise64.patch deleted file mode 100644 index 54ee3e0948a..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/39_syscall_fadvise64.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- - linux-user/syscall.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -Index: linux-user/syscall.c -=================================================================== ---- linux-user/syscall.c.orig 2007-12-03 19:33:47.000000000 +0000 -+++ linux-user/syscall.c 2007-12-03 19:33:48.000000000 +0000 -@@ -5317,6 +5317,12 @@ abi_long do_syscall(void *cpu_env, int n - ret = get_errno(mincore((void*)arg1, (size_t)arg2, (unsigned char*)arg3)); - break; - #endif -+#ifdef TARGET_NR_fadvise64_64 -+ case TARGET_NR_fadvise64_64: -+ /* Just return success */ -+ ret = get_errno(0); -+ break; -+#endif - #ifdef TARGET_NR_madvise - case TARGET_NR_madvise: - /* A straight passthrough may not be safe because qemu sometimes diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/41_arm_fpa_sigfpe.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/41_arm_fpa_sigfpe.patch deleted file mode 100644 index cea3afc7fff..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/41_arm_fpa_sigfpe.patch +++ /dev/null @@ -1,104 +0,0 @@ -#DPATCHLEVEL=0 ---- -# linux-user/main.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++- -# target-arm/nwfpe/fpa11.c | 7 ++++++ -# 2 files changed, 57 insertions(+), 1 deletion(-) -# -Index: linux-user/main.c -=================================================================== ---- linux-user/main.c.orig 2007-12-03 15:59:10.000000000 +0000 -+++ linux-user/main.c 2007-12-03 16:01:27.000000000 +0000 -@@ -377,18 +377,67 @@ void cpu_loop(CPUARMState *env) - { - TaskState *ts = env->opaque; - uint32_t opcode; -+ int rc; - - /* we handle the FPU emulation here, as Linux */ - /* we get the opcode */ - /* FIXME - what to do if get_user() fails? */ - get_user_u32(opcode, env->regs[15]); - -- if (EmulateAll(opcode, &ts->fpa, env) == 0) { -+ rc = EmulateAll(opcode, &ts->fpa, env); -+ if (rc == 0) { /* illegal instruction */ - info.si_signo = SIGILL; - info.si_errno = 0; - info.si_code = TARGET_ILL_ILLOPN; - info._sifields._sigfault._addr = env->regs[15]; - queue_signal(info.si_signo, &info); -+ } else if (rc < 0) { /* FP exception */ -+ int arm_fpe=0; -+ -+ /* translate softfloat flags to FPSR flags */ -+ if (-rc & float_flag_invalid) -+ arm_fpe |= BIT_IOC; -+ if (-rc & float_flag_divbyzero) -+ arm_fpe |= BIT_DZC; -+ if (-rc & float_flag_overflow) -+ arm_fpe |= BIT_OFC; -+ if (-rc & float_flag_underflow) -+ arm_fpe |= BIT_UFC; -+ if (-rc & float_flag_inexact) -+ arm_fpe |= BIT_IXC; -+ -+ FPSR fpsr = ts->fpa.fpsr; -+ //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe); -+ -+ if (fpsr & (arm_fpe << 16)) { /* exception enabled? */ -+ info.si_signo = SIGFPE; -+ info.si_errno = 0; -+ -+ /* ordered by priority, least first */ -+ if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES; -+ if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND; -+ if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF; -+ if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV; -+ if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV; -+ -+ info._sifields._sigfault._addr = env->regs[15]; -+ queue_signal(info.si_signo, &info); -+ } else { -+ env->regs[15] += 4; -+ } -+ -+ /* accumulate unenabled exceptions */ -+ if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC)) -+ fpsr |= BIT_IXC; -+ if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC)) -+ fpsr |= BIT_UFC; -+ if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC)) -+ fpsr |= BIT_OFC; -+ if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC)) -+ fpsr |= BIT_DZC; -+ if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC)) -+ fpsr |= BIT_IOC; -+ ts->fpa.fpsr=fpsr; - } else { - /* increment PC */ - env->regs[15] += 4; -Index: target-arm/nwfpe/fpa11.c -=================================================================== ---- target-arm/nwfpe/fpa11.c.orig 2007-12-03 15:40:26.000000000 +0000 -+++ target-arm/nwfpe/fpa11.c 2007-12-03 15:59:11.000000000 +0000 -@@ -162,6 +162,8 @@ unsigned int EmulateAll(unsigned int opc - fpa11->initflag = 1; - } - -+ set_float_exception_flags(0, &fpa11->fp_status); -+ - if (TEST_OPCODE(opcode,MASK_CPRT)) - { - //fprintf(stderr,"emulating CPRT\n"); -@@ -191,6 +193,11 @@ unsigned int EmulateAll(unsigned int opc - } - - // restore_flags(flags); -+ if(nRc == 1 && get_float_exception_flags(&fpa11->fp_status)) -+ { -+ //printf("fef 0x%x\n",float_exception_flags); -+ nRc=-get_float_exception_flags(&fpa11->fp_status); -+ } - - //printf("returning %d\n",nRc); - return(nRc); diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/61_safe_64bit_int.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/61_safe_64bit_int.patch deleted file mode 100644 index 9b1ace81a58..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/61_safe_64bit_int.patch +++ /dev/null @@ -1,27 +0,0 @@ -#DPATCHLEVEL=0 ---- -# dyngen-exec.h | 4 ++-- -# 1 file changed, 2 insertions(+), 2 deletions(-) -# -Index: dyngen-exec.h -=================================================================== ---- dyngen-exec.h.orig 2007-12-31 13:06:21.000000000 +0000 -+++ dyngen-exec.h 2007-12-31 13:08:54.000000000 +0000 -@@ -38,7 +38,7 @@ - // Linux/Sparc64 defines uint64_t - #if !(defined (__sparc_v9__) && defined(__linux__)) - /* XXX may be done for all 64 bits targets ? */ --#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) -+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) || defined(__sparc__) - typedef unsigned long uint64_t; - #else - typedef unsigned long long uint64_t; -@@ -55,7 +55,7 @@ - typedef signed int int32_t; - // Linux/Sparc64 defines int64_t - #if !(defined (__sparc_v9__) && defined(__linux__)) --#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) -+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) || defined(__sparc__) - typedef signed long int64_t; - #else - typedef signed long long int64_t; diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/65_kfreebsd.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/65_kfreebsd.patch deleted file mode 100644 index dfece800ac2..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/65_kfreebsd.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- - configure | 6 ++++++ - vl.c | 2 ++ - 2 files changed, 8 insertions(+) - -Index: configure -=================================================================== ---- configure.orig 2007-12-03 15:40:26.000000000 +0000 -+++ configure 2007-12-03 16:05:34.000000000 +0000 -@@ -129,6 +129,12 @@ if [ "$cpu" = "i386" -o "$cpu" = "x86_64 - kqemu="yes" - fi - ;; -+GNU/kFreeBSD) -+oss="yes" -+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then -+ kqemu="yes" -+fi -+;; - FreeBSD) - bsd="yes" - oss="yes" -Index: vl.c -=================================================================== ---- vl.c.orig 2007-12-03 16:05:32.000000000 +0000 -+++ vl.c 2007-12-03 16:05:34.000000000 +0000 -@@ -97,6 +97,8 @@ - #include - #endif - #endif -+#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__) -+#include - #else - #include - int inet_aton(const char *cp, struct in_addr *ia); diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/configure_symlinkpath_fix.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/configure_symlinkpath_fix.patch deleted file mode 100644 index 3ec304a38c9..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/configure_symlinkpath_fix.patch +++ /dev/null @@ -1,28 +0,0 @@ -Index: qemu-0.9.1/configure -=================================================================== ---- qemu-0.9.1.orig/configure 2008-01-24 15:33:13.000000000 +0000 -+++ qemu-0.9.1/configure 2008-01-24 15:45:50.000000000 +0000 -@@ -209,15 +209,17 @@ - - # find source path - source_path=`dirname "$0"` -+source_path_used="no" -+workdir=`pwd` -+workdir=`readlink -f $workdir` - if [ -z "$source_path" ]; then -- source_path=`pwd` -+ source_path=$workdir - else - source_path=`cd "$source_path"; pwd` --fi --if test "$source_path" = `pwd` ; then -- source_path_used="no" --else -- source_path_used="yes" -+ source_path=`readlink -f $source_path` -+ if test "$source_path" != "$workdir" ; then -+ source_path_used="yes" -+ fi - fi - - werror="no" diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_brk.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_brk.patch deleted file mode 100644 index 783198d9e39..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_brk.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- qemu/linux-user/syscall.c1 (revision 16) -+++ qemu/linux-user/syscall.c (working copy) -@@ -441,7 +441,7 @@ - if (!new_brk) - return target_brk; - if (new_brk < target_original_brk) -- return -TARGET_ENOMEM; -+ return target_brk; - - brk_page = HOST_PAGE_ALIGN(target_brk); - -@@ -456,12 +456,11 @@ - mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, - PROT_READ|PROT_WRITE, - MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); -- if (is_error(mapped_addr)) { -- return mapped_addr; -- } else { -+ -+ if (!is_error(mapped_addr)) - target_brk = new_brk; -- return target_brk; -- } -+ -+ return target_brk; - } - - static inline abi_long copy_from_user_fdset(fd_set *fds, ---- qemu/linux-user/mmap.c1 (revision 16) -+++ qemu/linux-user/mmap.c (working copy) -@@ -260,6 +259,9 @@ - host_start += offset - host_offset; - start = h2g(host_start); - } else { -+ int flg; -+ target_ulong addr; -+ - if (start & ~TARGET_PAGE_MASK) { - errno = EINVAL; - return -1; -@@ -267,6 +269,14 @@ - end = start + len; - real_end = HOST_PAGE_ALIGN(end); - -+ for(addr = real_start; addr < real_end; addr += TARGET_PAGE_SIZE) { -+ flg = page_get_flags(addr); -+ if( flg & PAGE_RESERVED ) { -+ errno = ENXIO; -+ return -1; -+ } -+ } -+ - /* worst case: we cannot map the file because the offset is not - aligned, so we read it */ - if (!(flags & MAP_ANONYMOUS) && diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_protection_bits.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_protection_bits.patch deleted file mode 100644 index ee2b077602f..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_protection_bits.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: qemu-0.9.1/linux-user/mmap.c -=================================================================== ---- qemu-0.9.1.orig/linux-user/mmap.c 2008-04-16 14:10:26.000000000 +0100 -+++ qemu-0.9.1/linux-user/mmap.c 2008-04-16 14:10:51.000000000 +0100 -@@ -49,8 +49,7 @@ - end = start + len; - if (end < start) - return -EINVAL; -- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) -- return -EINVAL; -+ prot = prot & (PROT_READ | PROT_WRITE | PROT_EXEC); - if (len == 0) - return 0; - diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_segfault.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_segfault.patch deleted file mode 100644 index 443c330650a..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/fix_segfault.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- - linux-user/syscall.c | 22 ---------------------- - 1 file changed, 22 deletions(-) - -Index: qemu/linux-user/syscall.c -=================================================================== ---- qemu.orig/linux-user/syscall.c 2007-12-03 23:40:11.000000000 +0000 -+++ qemu/linux-user/syscall.c 2007-12-03 23:40:21.000000000 +0000 -@@ -5695,28 +5695,6 @@ abi_long do_syscall(void *cpu_env, int n - goto unimplemented_nowarn; - #endif - --#ifdef TARGET_NR_clock_gettime -- case TARGET_NR_clock_gettime: -- { -- struct timespec ts; -- ret = get_errno(clock_gettime(arg1, &ts)); -- if (!is_error(ret)) { -- host_to_target_timespec(arg2, &ts); -- } -- break; -- } --#endif --#ifdef TARGET_NR_clock_getres -- case TARGET_NR_clock_getres: -- { -- struct timespec ts; -- ret = get_errno(clock_getres(arg1, &ts)); -- if (!is_error(ret)) { -- host_to_target_timespec(arg2, &ts); -- } -- break; -- } --#endif - - #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address) - case TARGET_NR_set_tid_address: diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-0.9.0-nptl-update.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-0.9.0-nptl-update.patch deleted file mode 100644 index ebc996e8731..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-0.9.0-nptl-update.patch +++ /dev/null @@ -1,219 +0,0 @@ ---- - linux-user/main.c | 7 ++- - linux-user/syscall.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 111 insertions(+), 10 deletions(-) - -Index: qemu/linux-user/main.c -=================================================================== ---- qemu.orig/linux-user/main.c 2007-12-03 19:34:09.000000000 +0000 -+++ qemu/linux-user/main.c 2007-12-03 23:44:45.000000000 +0000 -@@ -391,7 +391,7 @@ do_kernel_trap(CPUARMState *env) - cpu_unlock(); - break; - case 0xffff0fe0: /* __kernel_get_tls */ -- env->regs[0] = env->cp15.c13_tls; -+ env->regs[0] = env->cp15.c13_tls2; - break; - default: - return 1; -@@ -2037,6 +2037,11 @@ int main(int argc, char **argv) - int drop_ld_preload = 0, environ_count = 0; - char **target_environ, **wrk, **dst; - -+ char *assume_kernel = getenv("QEMU_ASSUME_KERNEL"); -+ -+ if (assume_kernel) -+ setenv("LD_ASSUME_KERNEL", assume_kernel, 1); -+ - if (argc <= 1) - usage(); - -Index: qemu/linux-user/syscall.c -=================================================================== ---- qemu.orig/linux-user/syscall.c 2007-12-03 19:34:09.000000000 +0000 -+++ qemu/linux-user/syscall.c 2007-12-03 23:46:54.000000000 +0000 -@@ -61,6 +61,7 @@ - #define tchars host_tchars /* same as target */ - #define ltchars host_ltchars /* same as target */ - -+#include - #include - #include - #include -@@ -2694,7 +2695,6 @@ abi_long do_arch_prctl(CPUX86State *env, - return 0; - } - #endif -- - #endif /* defined(TARGET_I386) */ - - /* this stack is the equivalent of the kernel stack associated with a -@@ -2729,16 +2729,19 @@ int do_fork(CPUState *env, unsigned int - TaskState *ts; - uint8_t *new_stack; - CPUState *new_env; -- -+#if defined(TARGET_I386) -+ uint64_t *new_gdt_table; -+#endif - #ifdef USE_NPTL - unsigned int nptl_flags; - - if (flags & CLONE_PARENT_SETTID) - *parent_tidptr = gettid(); - #endif -- - if (flags & CLONE_VM) { - ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); -+ if (!ts) -+ return -ENOMEM; - memset(ts, 0, sizeof(TaskState)); - new_stack = ts->stack; - ts->used = 1; -@@ -2750,6 +2753,29 @@ int do_fork(CPUState *env, unsigned int - #if defined(TARGET_I386) - if (!newsp) - newsp = env->regs[R_ESP]; -+ new_gdt_table = malloc(9 * 8); -+ if (!new_gdt_table) { -+ free(new_env); -+ return -ENOMEM; -+ } -+ /* Copy main GDT table from parent, but clear TLS entries */ -+ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); -+ memset(&new_gdt_table[6], 0, 3 * 8); -+ new_env->gdt.base = h2g(new_gdt_table); -+ if (flags & 0x00080000 /* CLONE_SETTLS */) { -+ ret = do_set_thread_area(new_env, new_env->regs[R_ESI]); -+ if (ret) { -+ free(new_gdt_table); -+ free(new_env); -+ return ret; -+ } -+ } -+ cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]); -+ cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]); -+ cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]); -+ cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]); -+ cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]); -+ cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]); - new_env->regs[R_ESP] = newsp; - new_env->regs[R_EAX] = 0; - #elif defined(TARGET_ARM) -@@ -3121,6 +3147,68 @@ static inline abi_long host_to_target_ti - unlock_user_struct(target_ts, target_addr, 1); - } - -+static long do_futex(target_ulong uaddr, int op, uint32_t val, -+ target_ulong utime, target_ulong uaddr2, -+ uint32_t val3) -+{ -+ struct timespec host_utime; -+ unsigned long val2 = utime; -+ -+ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { -+ target_to_host_timespec(&host_utime, utime); -+ val2 = (unsigned long)&host_utime; -+ } -+ -+#ifdef BSWAP_NEEDED -+ switch(op) { -+ case FUTEX_CMP_REQUEUE: -+ val3 = tswap32(val3); -+ case FUTEX_REQUEUE: -+ val2 = tswap32(val2); -+ case FUTEX_WAIT: -+ case FUTEX_WAKE: -+ val = tswap32(val); -+ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ -+ case FUTEX_UNLOCK_PI: -+ break; -+ default: -+ gemu_log("qemu: Unsupported futex op %d\n", op); -+ return -ENOSYS; -+ } -+#if 0 /* No, it's worse than this */ -+ if (op == FUTEX_WAKE_OP) { -+ /* Need to munge the secondary operation (val3) */ -+ val3 = tswap32(val3); -+ int op2 = (val3 >> 28) & 7; -+ int cmp = (val3 >> 24) & 15; -+ int oparg = (val3 << 8) >> 20; -+ int cmparg = (val3 << 20) >> 20; -+ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); -+ -+ if (shift) -+ oparg = (oparg & 7) + 24 - (oparg & 24); -+ else oparg = -+ if (op2 == FUTEX_OP_ADD) { -+ gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n"); -+ return -ENOSYS; -+ } -+ if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE || -+ cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) { -+ gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg); -+ return -ENOSYS; -+ } -+ val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg; -+ } -+#endif -+#endif -+ return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); -+} -+ -+int do_set_tid_address(target_ulong tidptr) -+{ -+ return syscall(__NR_set_tid_address, g2h(tidptr)); -+} -+ - /* do_syscall() should always have a single exit point at the end so - that actions, such as logging of syscall results, can be performed. - All errnos that do_syscall() returns must be -TARGET_. */ -@@ -3145,7 +3233,7 @@ abi_long do_syscall(void *cpu_env, int n - _mcleanup(); - #endif - gdb_exit(cpu_env, arg1); -- /* XXX: should free thread stack and CPU env */ -+ /* XXX: should free thread stack, GDT and CPU env */ - _exit(arg1); - ret = 0; /* avoid warning */ - break; -@@ -5569,6 +5657,9 @@ abi_long do_syscall(void *cpu_env, int n - #elif defined(TARGET_I386) && defined(TARGET_ABI32) - ret = do_set_thread_area(cpu_env, arg1); - break; -+#elif TARGET_i386 -+ ret = get_errno(do_set_thread_area(cpu_env, arg1)); -+ break; - #else - goto unimplemented_nowarn; - #endif -@@ -5586,6 +5677,16 @@ abi_long do_syscall(void *cpu_env, int n - goto unimplemented_nowarn; - #endif - -+#ifdef TARGET_NR_futex -+ case TARGET_NR_futex: -+ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6)); -+ break; -+#endif -+#ifdef TARGET_NR_set_robust_list -+ case TARGET_NR_set_robust_list: -+ goto unimplemented_nowarn; -+#endif -+ - #ifdef TARGET_NR_clock_gettime - case TARGET_NR_clock_gettime: - { -@@ -5627,11 +5728,6 @@ abi_long do_syscall(void *cpu_env, int n - break; - #endif - --#ifdef TARGET_NR_set_robust_list -- case TARGET_NR_set_robust_list: -- goto unimplemented_nowarn; --#endif -- - #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat) - case TARGET_NR_utimensat: - { diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-0.9.0-nptl.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-0.9.0-nptl.patch deleted file mode 100644 index 4a87d8d6371..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-0.9.0-nptl.patch +++ /dev/null @@ -1,854 +0,0 @@ -These are Paul Brook's patches to QEMU-0.8.2 to enable the running of single -ARM binaries under QEMU's user-emulation mode. Without them, QEMU-0.8.1 -immediately dies saying: - Error: f0005 - qemu: uncaught target signal 6 (Aborted) - exiting -while qemu-0.8.2 dies saying: - qemu: Unsupported syscall: 983045 - cannot set up thread-local storage: unknown error - -This file is a rediffing of the patches visible at -https://nowt.dyndns.org/patch.qemu_nptl on 27 Sept 2006 -which "patch" fails to apply automatically. -See also http://lists.gnu.org/archive/html/qemu-devel/2006-09/msg00194.html - - Martin Guy, 27 Sept 2006 - ---- - configure | 25 ++++++ - exec-all.h | 165 ------------------------------------------ - linux-user/arm/syscall.h | 4 - - linux-user/main.c | 94 +++++++++++++++++++++--- - linux-user/qemu.h | 3 - linux-user/syscall.c | 91 ++++++++++++++++++++++- - qemu_spinlock.h | 181 +++++++++++++++++++++++++++++++++++++++++++++++ - target-arm/cpu.h | 10 ++ - target-arm/op.c | 6 + - target-arm/translate.c | 9 ++ - 10 files changed, 405 insertions(+), 183 deletions(-) - -Index: qemu/configure -=================================================================== ---- qemu.orig/configure 2008-04-09 23:02:37.000000000 +0100 -+++ qemu/configure 2008-04-09 23:06:36.000000000 +0100 -@@ -109,6 +109,7 @@ - build_docs="no" - uname_release="" - curses="yes" -+nptl="yes" - - # OS specific - targetos=`uname -s` -@@ -334,6 +335,8 @@ - ;; - *) echo "ERROR: unknown option $opt"; show_help="yes" - ;; -+ --disable-nptl) nptl="no" -+ ;; - esac - done - -@@ -429,6 +432,7 @@ - echo " --disable-linux-user disable all linux usermode emulation targets" - echo " --enable-darwin-user enable all darwin usermode emulation targets" - echo " --disable-darwin-user disable all darwin usermode emulation targets" -+echo " --disable-nptl disable usermode NPTL guest support" - echo " --fmod-lib path to FMOD library" - echo " --fmod-inc path to FMOD includes" - echo " --enable-uname-release=R Return R for uname -r in usermode emulation" -@@ -595,6 +599,23 @@ - } - EOF - -+# check NPTL support -+cat > $TMPC < -+void foo() -+{ -+#ifndef CLONE_SETTLS -+#error bork -+#endif -+} -+EOF -+ -+if $cc -c -o $TMPO $TMPC 2> /dev/null ; then -+ : -+else -+ nptl="no" -+fi -+ - ########################################## - # SDL probe - -@@ -778,6 +799,7 @@ - echo "Documentation $build_docs" - [ ! -z "$uname_release" ] && \ - echo "uname -r $uname_release" -+echo "NPTL support $nptl" - - if test $sdl_too_old = "yes"; then - echo "-> Your SDL version is too old - please upgrade to have SDL support" -@@ -1115,6 +1137,9 @@ - echo "TARGET_ARCH=arm" >> $config_mak - echo "#define TARGET_ARCH \"arm\"" >> $config_h - echo "#define TARGET_ARM 1" >> $config_h -+ if test "$nptl" = "yes" ; then -+ echo "#define USE_NPTL 1" >> $config_h -+ fi - bflt="yes" - elif test "$target_cpu" = "sparc" ; then - echo "TARGET_ARCH=sparc" >> $config_mak -Index: qemu/exec-all.h -=================================================================== ---- qemu.orig/exec-all.h 2008-04-09 22:39:38.000000000 +0100 -+++ qemu/exec-all.h 2008-04-09 23:05:55.000000000 +0100 -@@ -297,170 +297,7 @@ - extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; - extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; - --#if defined(__powerpc__) --static inline int testandset (int *p) --{ -- int ret; -- __asm__ __volatile__ ( -- "0: lwarx %0,0,%1\n" -- " xor. %0,%3,%0\n" -- " bne 1f\n" -- " stwcx. %2,0,%1\n" -- " bne- 0b\n" -- "1: " -- : "=&r" (ret) -- : "r" (p), "r" (1), "r" (0) -- : "cr0", "memory"); -- return ret; --} --#elif defined(__i386__) --static inline int testandset (int *p) --{ -- long int readval = 0; -- -- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" -- : "+m" (*p), "+a" (readval) -- : "r" (1) -- : "cc"); -- return readval; --} --#elif defined(__x86_64__) --static inline int testandset (int *p) --{ -- long int readval = 0; -- -- __asm__ __volatile__ ("lock; cmpxchgl %2, %0" -- : "+m" (*p), "+a" (readval) -- : "r" (1) -- : "cc"); -- return readval; --} --#elif defined(__s390__) --static inline int testandset (int *p) --{ -- int ret; -- -- __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" -- " jl 0b" -- : "=&d" (ret) -- : "r" (1), "a" (p), "0" (*p) -- : "cc", "memory" ); -- return ret; --} --#elif defined(__alpha__) --static inline int testandset (int *p) --{ -- int ret; -- unsigned long one; -- -- __asm__ __volatile__ ("0: mov 1,%2\n" -- " ldl_l %0,%1\n" -- " stl_c %2,%1\n" -- " beq %2,1f\n" -- ".subsection 2\n" -- "1: br 0b\n" -- ".previous" -- : "=r" (ret), "=m" (*p), "=r" (one) -- : "m" (*p)); -- return ret; --} --#elif defined(__sparc__) --static inline int testandset (int *p) --{ -- int ret; -- -- __asm__ __volatile__("ldstub [%1], %0" -- : "=r" (ret) -- : "r" (p) -- : "memory"); -- -- return (ret ? 1 : 0); --} --#elif defined(__arm__) --static inline int testandset (int *spinlock) --{ -- register unsigned int ret; -- __asm__ __volatile__("swp %0, %1, [%2]" -- : "=r"(ret) -- : "0"(1), "r"(spinlock)); -- -- return ret; --} --#elif defined(__mc68000) --static inline int testandset (int *p) --{ -- char ret; -- __asm__ __volatile__("tas %1; sne %0" -- : "=r" (ret) -- : "m" (p) -- : "cc","memory"); -- return ret; --} --#elif defined(__ia64) -- --#include -- --static inline int testandset (int *p) --{ -- return __sync_lock_test_and_set (p, 1); --} --#elif defined(__mips__) --static inline int testandset (int *p) --{ -- int ret; -- -- __asm__ __volatile__ ( -- " .set push \n" -- " .set noat \n" -- " .set mips2 \n" -- "1: li $1, 1 \n" -- " ll %0, %1 \n" -- " sc $1, %1 \n" -- " beqz $1, 1b \n" -- " .set pop " -- : "=r" (ret), "+R" (*p) -- : -- : "memory"); -- -- return ret; --} --#else --#error unimplemented CPU support --#endif -- --typedef int spinlock_t; -- --#define SPIN_LOCK_UNLOCKED 0 -- --#if defined(CONFIG_USER_ONLY) --static inline void spin_lock(spinlock_t *lock) --{ -- while (testandset(lock)); --} -- --static inline void spin_unlock(spinlock_t *lock) --{ -- *lock = 0; --} -- --static inline int spin_trylock(spinlock_t *lock) --{ -- return !testandset(lock); --} --#else --static inline void spin_lock(spinlock_t *lock) --{ --} -- --static inline void spin_unlock(spinlock_t *lock) --{ --} -- --static inline int spin_trylock(spinlock_t *lock) --{ -- return 1; --} --#endif -+#include "qemu_spinlock.h" - - extern spinlock_t tb_lock; - -Index: qemu/linux-user/arm/syscall.h -=================================================================== ---- qemu.orig/linux-user/arm/syscall.h 2007-11-27 12:09:33.000000000 +0000 -+++ qemu/linux-user/arm/syscall.h 2008-04-09 23:05:55.000000000 +0100 -@@ -28,7 +28,9 @@ - #define ARM_SYSCALL_BASE 0x900000 - #define ARM_THUMB_SYSCALL 0 - --#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2) -+#define ARM_NR_BASE 0xf0000 -+#define ARM_NR_cacheflush (ARM_NR_BASE + 2) -+#define ARM_NR_set_tls (ARM_NR_BASE + 5) - - #define ARM_NR_semihosting 0x123456 - #define ARM_NR_thumb_semihosting 0xAB -Index: qemu/linux-user/main.c -=================================================================== ---- qemu.orig/linux-user/main.c 2008-04-09 23:02:37.000000000 +0100 -+++ qemu/linux-user/main.c 2008-04-09 23:05:55.000000000 +0100 -@@ -364,6 +364,50 @@ - } - } - -+/* Handle a jump to the kernel code page. */ -+static int -+do_kernel_trap(CPUARMState *env) -+{ -+ uint32_t addr; -+ uint32_t *ptr; -+ uint32_t cpsr; -+ -+ switch (env->regs[15]) { -+ case 0xffff0fc0: /* __kernel_cmpxchg */ -+ /* XXX: This only works between threads, not between processes. -+ Use native atomic operations. */ -+ /* ??? This probably breaks horribly if the access segfaults. */ -+ cpu_lock(); -+ ptr = (uint32_t *)env->regs[2]; -+ cpsr = cpsr_read(env); -+ if (*ptr == env->regs[0]) { -+ *ptr = env->regs[1]; -+ env->regs[0] = 0; -+ cpsr |= CPSR_C; -+ } else { -+ env->regs[0] = -1; -+ cpsr &= ~CPSR_C; -+ } -+ cpsr_write(env, cpsr, CPSR_C); -+ cpu_unlock(); -+ break; -+ case 0xffff0fe0: /* __kernel_get_tls */ -+ env->regs[0] = env->cp15.c13_tls; -+ break; -+ default: -+ return 1; -+ } -+ /* Jump back to the caller. */ -+ addr = env->regs[14]; -+ if (addr & 1) { -+ env->thumb = 1; -+ addr &= ~1; -+ } -+ env->regs[15] = addr; -+ -+ return 0; -+} -+ - void cpu_loop(CPUARMState *env) - { - int trapnr; -@@ -474,10 +518,8 @@ - } - } - -- if (n == ARM_NR_cacheflush) { -- arm_cache_flush(env->regs[0], env->regs[1]); -- } else if (n == ARM_NR_semihosting -- || n == ARM_NR_thumb_semihosting) { -+ if (n == ARM_NR_semihosting -+ || n == ARM_NR_thumb_semihosting) { - env->regs[0] = do_arm_semihosting (env); - } else if (n == 0 || n >= ARM_SYSCALL_BASE - || (env->thumb && n == ARM_THUMB_SYSCALL)) { -@@ -488,14 +530,34 @@ - n -= ARM_SYSCALL_BASE; - env->eabi = 0; - } -- env->regs[0] = do_syscall(env, -- n, -- env->regs[0], -- env->regs[1], -- env->regs[2], -- env->regs[3], -- env->regs[4], -- env->regs[5]); -+ if ( n > ARM_NR_BASE) { -+ switch (n) -+ { -+ case ARM_NR_cacheflush: -+ arm_cache_flush(env->regs[0], env->regs[1]); -+ break; -+#ifdef USE_NPTL -+ case ARM_NR_set_tls: -+ cpu_set_tls(env, env->regs[0]); -+ env->regs[0] = 0; -+ break; -+#endif -+ default: -+ printf ("Error: Bad syscall: %x\n", n); -+ goto error; -+ } -+ } -+ else -+ { -+ env->regs[0] = do_syscall(env, -+ n, -+ env->regs[0], -+ env->regs[1], -+ env->regs[2], -+ env->regs[3], -+ env->regs[4], -+ env->regs[5]); -+ } - } else { - goto error; - } -@@ -534,6 +596,10 @@ - } - } - break; -+ case EXCP_KERNEL_TRAP: -+ if (do_kernel_trap(env)) -+ goto error; -+ break; - default: - error: - fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", -@@ -2402,6 +2468,10 @@ - ts->heap_base = info->brk; - /* This will be filled in on the first SYS_HEAPINFO call. */ - ts->heap_limit = 0; -+ /* Register the magic kernel code page. The cpu will generate a -+ special exception when it tries to execute code here. We can't -+ put real code here because it may be in use by the host kernel. */ -+ page_set_flags(0xffff0000, 0xffff0fff, 0); - #endif - - if (gdbstub_port) { -Index: qemu/linux-user/qemu.h -=================================================================== ---- qemu.orig/linux-user/qemu.h 2008-01-02 15:48:21.000000000 +0000 -+++ qemu/linux-user/qemu.h 2008-04-09 23:05:55.000000000 +0100 -@@ -107,6 +107,9 @@ - uint32_t heap_base; - uint32_t heap_limit; - #endif -+#ifdef USE_NPTL -+ uint32_t *child_tidptr; -+#endif - int used; /* non zero if used */ - struct image_info *info; - uint8_t stack[0]; -Index: qemu/linux-user/syscall.c -=================================================================== ---- qemu.orig/linux-user/syscall.c 2008-04-09 23:02:38.000000000 +0100 -+++ qemu/linux-user/syscall.c 2008-04-09 23:05:55.000000000 +0100 -@@ -71,9 +71,18 @@ - #include - - #include "qemu.h" -+#include "qemu_spinlock.h" - - //#define DEBUG - -+#ifdef USE_NPTL -+#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \ -+ CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID) -+#else -+/* XXX: Hardcode the above values. */ -+#define CLONE_NPTL_FLAGS2 0 -+#endif -+ - #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ - || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) - /* 16 bit uid wrappers emulation */ -@@ -2702,9 +2711,19 @@ - thread/process */ - #define NEW_STACK_SIZE 8192 - -+#ifdef USE_NPTL -+static spinlock_t nptl_lock = SPIN_LOCK_UNLOCKED; -+#endif -+ - static int clone_func(void *arg) - { - CPUState *env = arg; -+#ifdef HAVE_NPTL -+ /* Wait until the parent has finshed initializing the tls state. */ -+ while (!spin_trylock(&nptl_lock)) -+ usleep(1); -+ spin_unlock(&nptl_lock); -+#endif - cpu_loop(env); - /* never exits */ - return 0; -@@ -2712,13 +2731,22 @@ - - /* do_fork() Must return host values and target errnos (unlike most - do_*() functions). */ --int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) -+int do_fork(CPUState *env, unsigned int flags, unsigned long newsp, -+ uint32_t *parent_tidptr, void *newtls, -+ uint32_t *child_tidptr) - { - int ret; - TaskState *ts; - uint8_t *new_stack; - CPUState *new_env; - -+#ifdef USE_NPTL -+ unsigned int nptl_flags; -+ -+ if (flags & CLONE_PARENT_SETTID) -+ *parent_tidptr = gettid(); -+#endif -+ - if (flags & CLONE_VM) { - ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); - memset(ts, 0, sizeof(TaskState)); -@@ -2784,16 +2812,67 @@ - #error unsupported target CPU - #endif - new_env->opaque = ts; -+#ifdef USE_NPTL -+ nptl_flags = flags; -+ flags &= ~CLONE_NPTL_FLAGS2; -+ -+ if (nptl_flags & CLONE_CHILD_CLEARTID) { -+ ts->child_tidptr = child_tidptr; -+ } -+ -+ if (nptl_flags & CLONE_SETTLS) -+ cpu_set_tls (new_env, newtls); -+ -+ /* Grab the global cpu lock so that the thread setup appears -+ atomic. */ -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ spin_lock(&nptl_lock); -+ -+#else -+ if (flags & CLONE_NPTL_FLAGS2) -+ return -EINVAL; -+#endif -+ -+ if (CLONE_VFORK & flags) -+ flags ^= CLONE_VM; - #ifdef __ia64__ - ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); - #else - ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); - #endif -+#ifdef USE_NPTL -+ if (ret != -1) { -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ *child_tidptr = ret; -+ } -+ -+ /* Allow the child to continue. */ -+ if (nptl_flags & CLONE_CHILD_SETTID) -+ spin_unlock(&nptl_lock); -+#endif - } else { - /* if no CLONE_VM, we consider it is a fork */ -- if ((flags & ~CSIGNAL) != 0) -+ if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) - return -EINVAL; - ret = fork(); -+#ifdef USE_NPTL -+ /* There is a race condition here. The parent process could -+ theoretically read the TID in the child process before the child -+ tid is set. This would require using either ptrace -+ (not implemented) or having *_tidptr to point at a shared memory -+ mapping. We can't repeat the spinlock hack used above because -+ the child process gets its own copy of the lock. */ -+ if (ret == 0) { -+ /* Child Process. */ -+ if (flags & CLONE_CHILD_SETTID) -+ *child_tidptr = gettid(); -+ ts = (TaskState *)env->opaque; -+ if (flags & CLONE_CHILD_CLEARTID) -+ ts->child_tidptr = child_tidptr; -+ if (flags & CLONE_SETTLS) -+ cpu_set_tls (env, newtls); -+ } -+#endif - } - return ret; - } -@@ -3118,7 +3197,7 @@ - ret = do_brk(arg1); - break; - case TARGET_NR_fork: -- ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); -+ ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, NULL, NULL, NULL)); - break; - #ifdef TARGET_NR_waitpid - case TARGET_NR_waitpid: -@@ -4481,7 +4560,8 @@ - ret = get_errno(fsync(arg1)); - break; - case TARGET_NR_clone: -- ret = get_errno(do_fork(cpu_env, arg1, arg2)); -+ ret = get_errno(do_fork(cpu_env, arg1, arg2, (uint32_t *)arg3, -+ (void *)arg4, (uint32_t *)arg5)); - break; - #ifdef __NR_exit_group - /* new thread calls */ -@@ -4928,7 +5008,8 @@ - #endif - #ifdef TARGET_NR_vfork - case TARGET_NR_vfork: -- ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); -+ ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0, -+ NULL, NULL, NULL)); - break; - #endif - #ifdef TARGET_NR_ugetrlimit -Index: qemu/qemu_spinlock.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ qemu/qemu_spinlock.h 2008-04-09 23:05:55.000000000 +0100 -@@ -0,0 +1,181 @@ -+/* -+ * Atomic operation helper include -+ * -+ * Copyright (c) 2005 Fabrice Bellard -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+#ifndef QEMU_SPINLOCK_H -+#define QEMU_SPINLOCK_H -+ -+#ifdef __powerpc__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ __asm__ __volatile__ ( -+ "0: lwarx %0,0,%1\n" -+ " xor. %0,%3,%0\n" -+ " bne 1f\n" -+ " stwcx. %2,0,%1\n" -+ " bne- 0b\n" -+ "1: " -+ : "=&r" (ret) -+ : "r" (p), "r" (1), "r" (0) -+ : "cr0", "memory"); -+ return ret; -+} -+#endif -+ -+#ifdef __i386__ -+static inline int testandset (int *p) -+{ -+ long int readval = 0; -+ -+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" -+ : "+m" (*p), "+a" (readval) -+ : "r" (1) -+ : "cc"); -+ return readval; -+} -+#endif -+ -+#ifdef __x86_64__ -+static inline int testandset (int *p) -+{ -+ long int readval = 0; -+ -+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0" -+ : "+m" (*p), "+a" (readval) -+ : "r" (1) -+ : "cc"); -+ return readval; -+} -+#endif -+ -+#ifdef __s390__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ -+ __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" -+ " jl 0b" -+ : "=&d" (ret) -+ : "r" (1), "a" (p), "0" (*p) -+ : "cc", "memory" ); -+ return ret; -+} -+#endif -+ -+#ifdef __alpha__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ unsigned long one; -+ -+ __asm__ __volatile__ ("0: mov 1,%2\n" -+ " ldl_l %0,%1\n" -+ " stl_c %2,%1\n" -+ " beq %2,1f\n" -+ ".subsection 2\n" -+ "1: br 0b\n" -+ ".previous" -+ : "=r" (ret), "=m" (*p), "=r" (one) -+ : "m" (*p)); -+ return ret; -+} -+#endif -+ -+#ifdef __sparc__ -+static inline int testandset (int *p) -+{ -+ int ret; -+ -+ __asm__ __volatile__("ldstub [%1], %0" -+ : "=r" (ret) -+ : "r" (p) -+ : "memory"); -+ -+ return (ret ? 1 : 0); -+} -+#endif -+ -+#ifdef __arm__ -+static inline int testandset (int *spinlock) -+{ -+ register unsigned int ret; -+ __asm__ __volatile__("swp %0, %1, [%2]" -+ : "=r"(ret) -+ : "0"(1), "r"(spinlock)); -+ -+ return ret; -+} -+#endif -+ -+#ifdef __mc68000 -+static inline int testandset (int *p) -+{ -+ char ret; -+ __asm__ __volatile__("tas %1; sne %0" -+ : "=r" (ret) -+ : "m" (p) -+ : "cc","memory"); -+ return ret; -+} -+#endif -+ -+#ifdef __ia64 -+#include -+ -+static inline int testandset (int *p) -+{ -+ return __sync_lock_test_and_set (p, 1); -+} -+#endif -+ -+typedef int spinlock_t; -+ -+#define SPIN_LOCK_UNLOCKED 0 -+ -+#if defined(CONFIG_USER_ONLY) -+static inline void spin_lock(spinlock_t *lock) -+{ -+ while (testandset(lock)); -+} -+ -+static inline void spin_unlock(spinlock_t *lock) -+{ -+ *lock = 0; -+} -+ -+static inline int spin_trylock(spinlock_t *lock) -+{ -+ return !testandset(lock); -+} -+#else -+static inline void spin_lock(spinlock_t *lock) -+{ -+} -+ -+static inline void spin_unlock(spinlock_t *lock) -+{ -+} -+ -+static inline int spin_trylock(spinlock_t *lock) -+{ -+ return 1; -+} -+#endif -+ -+#endif -Index: qemu/target-arm/cpu.h -=================================================================== ---- qemu.orig/target-arm/cpu.h 2007-11-27 12:09:57.000000000 +0000 -+++ qemu/target-arm/cpu.h 2008-04-09 23:05:55.000000000 +0100 -@@ -38,6 +38,7 @@ - #define EXCP_FIQ 6 - #define EXCP_BKPT 7 - #define EXCP_EXCEPTION_EXIT 8 /* Return from v7M exception. */ -+#define EXCP_KERNEL_TRAP 9 /* Jumped to kernel code page. */ - - #define ARMV7M_EXCP_RESET 1 - #define ARMV7M_EXCP_NMI 2 -@@ -222,6 +223,15 @@ - void cpu_lock(void); - void cpu_unlock(void); - -+void cpu_lock(void); -+void cpu_unlock(void); -+#if defined(USE_NPTL) -+static inline void cpu_set_tls(CPUARMState *env, void *newtls) -+{ -+ env->cp15.c13_tls2 = (uint32_t)(long)newtls; -+} -+#endif -+ - #define CPSR_M (0x1f) - #define CPSR_T (1 << 5) - #define CPSR_F (1 << 6) -Index: qemu/target-arm/op.c -=================================================================== ---- qemu.orig/target-arm/op.c 2008-04-09 22:40:01.000000000 +0100 -+++ qemu/target-arm/op.c 2008-04-09 23:05:55.000000000 +0100 -@@ -994,6 +994,12 @@ - cpu_loop_exit(); - } - -+void OPPROTO op_kernel_trap(void) -+{ -+ env->exception_index = EXCP_KERNEL_TRAP; -+ cpu_loop_exit(); -+} -+ - /* VFP support. We follow the convention used for VFP instrunctions: - Single precition routines have a "s" suffix, double precision a - "d" suffix. */ -Index: qemu/target-arm/translate.c -=================================================================== ---- qemu.orig/target-arm/translate.c 2008-04-09 22:40:01.000000000 +0100 -+++ qemu/target-arm/translate.c 2008-04-09 23:05:55.000000000 +0100 -@@ -7496,7 +7496,14 @@ - gen_op_exception_exit(); - } - #endif -- -+#ifdef CONFIG_USER_ONLY -+ /* Intercept jump to the magic kernel page. */ -+ if (dc->pc > 0xffff0000) { -+ gen_op_kernel_trap(); -+ dc->is_jmp = DISAS_UPDATE; -+ break; -+ } -+#endif - if (env->nb_breakpoints > 0) { - for(j = 0; j < env->nb_breakpoints; j++) { - if (env->breakpoints[j] == dc->pc) { diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-amd64-32b-mapping-0.9.0.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-amd64-32b-mapping-0.9.0.patch deleted file mode 100644 index c7f36d81102..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-amd64-32b-mapping-0.9.0.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- - linux-user/mmap.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -Index: qemu/linux-user/mmap.c -=================================================================== ---- qemu.orig/linux-user/mmap.c 2007-12-03 15:40:25.000000000 +0000 -+++ qemu/linux-user/mmap.c 2007-12-03 16:37:21.000000000 +0000 -@@ -29,6 +29,10 @@ - - //#define DEBUG_MMAP - -+#ifndef MAP_32BIT -+#define MAP_32BIT 0 -+#endif -+ - /* NOTE: all the constants are the HOST ones, but addresses are target. */ - int target_mprotect(abi_ulong start, abi_ulong len, int prot) - { -@@ -251,7 +255,7 @@ abi_long target_mmap(abi_ulong start, ab - especially important if qemu_host_page_size > - qemu_real_host_page_size */ - p = mmap(g2h(mmap_start), -- host_len, prot, flags | MAP_FIXED, fd, host_offset); -+ host_len, prot, flags | MAP_FIXED | MAP_32BIT, fd, host_offset); - if (p == MAP_FAILED) - return -1; - /* update start so that it points to the file position at 'offset' */ -@@ -406,7 +410,7 @@ abi_long target_mremap(abi_ulong old_add - unsigned long host_addr; - - /* XXX: use 5 args syscall */ -- host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags); -+ host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags | MAP_32BIT); - if (host_addr == -1) - return -1; - new_addr = h2g(host_addr); diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-n800-support.patch b/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-n800-support.patch deleted file mode 100644 index b1b6649efc2..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/qemu-n800-support.patch +++ /dev/null @@ -1,13970 +0,0 @@ -diff --git a/Makefile b/Makefile -index c36a978..cb0cf7b 100644 ---- a/Makefile -+++ b/Makefile -@@ -51,7 +51,8 @@ OBJS+=block.o - - OBJS+=irq.o - OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o --OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o -+OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o -+OBJS+=tmp105.o - OBJS+=scsi-disk.o cdrom.o - OBJS+=scsi-generic.o - OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o usb-serial.o -diff --git a/Makefile.target b/Makefile.target -index d1deda1..48f31bc 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -593,7 +593,9 @@ OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o - OBJS+= pflash_cfi01.o gumstix.o - OBJS+= spitz.o ide.o serial.o nand.o ecc.o - OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o -+OBJS+= omap2.o omap_dss.o - OBJS+= palm.o tsc210x.o -+OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o - OBJS+= mst_fpga.o mainstone.o - CPPFLAGS += -DHAS_AUDIO - endif -diff --git a/console.h b/console.h -index b8a5c6d..b45974e 100644 ---- a/console.h -+++ b/console.h -@@ -32,6 +32,12 @@ void kbd_put_keycode(int keycode); - void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); - int kbd_mouse_is_absolute(void); - -+struct mouse_transform_info_s { -+ int x; -+ int y; -+ int a[7]; -+}; -+ - void do_info_mice(void); - void do_mouse_set(int index); - -diff --git a/cpu-all.h b/cpu-all.h -index 7a7e655..c7c9611 100644 ---- a/cpu-all.h -+++ b/cpu-all.h -@@ -810,7 +810,7 @@ extern uint8_t *phys_ram_dirty; - /* physical memory access */ - #define TLB_INVALID_MASK (1 << 3) - #define IO_MEM_SHIFT 4 --#define IO_MEM_NB_ENTRIES (1 << (TARGET_PAGE_BITS - IO_MEM_SHIFT)) -+#define IO_MEM_NB_ENTRIES (16 << (TARGET_PAGE_BITS - IO_MEM_SHIFT)) - - #define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */ - #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ -diff --git a/exec.c b/exec.c -index e9a5918..c69f742 100644 ---- a/exec.c -+++ b/exec.c -@@ -1658,7 +1658,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, - { - if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { - /* IO memory case */ -- address = vaddr | pd; -+ address = vaddr | (pd & ~TARGET_PAGE_MASK); - addend = paddr; - } else { - /* standard memory */ -@@ -1692,7 +1692,9 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, - } else { - te->addr_read = -1; - } -- if (prot & PAGE_EXEC) { -+ if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { -+ te->addr_code = pd; -+ } else if (prot & PAGE_EXEC) { - te->addr_code = address; - } else { - te->addr_code = -1; -@@ -2487,7 +2489,9 @@ int cpu_register_io_memory(int io_index, - if (io_index <= 0) { - if (io_mem_nb >= IO_MEM_NB_ENTRIES) - return -1; -- io_index = io_mem_nb++; -+ do io_index = io_mem_nb++; -+ while (((io_index << IO_MEM_SHIFT) & ~TARGET_PAGE_MASK) -+ <= IO_MEM_NOTDIRTY); - } else { - if (io_index >= IO_MEM_NB_ENTRIES) - return -1; -diff --git a/hw/arm-misc.h b/hw/arm-misc.h -index 7914ff1..a1e0061 100644 ---- a/hw/arm-misc.h -+++ b/hw/arm-misc.h -@@ -21,10 +21,7 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, - const char *kernel_filename, const char *cpu_model); - - /* arm_boot.c */ -- --void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, -- const char *kernel_cmdline, const char *initrd_filename, -- int board_id, target_phys_addr_t loader_start); -+void arm_load_kernel(CPUState *env, struct arm_boot_info *info); - - /* armv7m_nvic.c */ - int system_clock_scale; -diff --git a/hw/arm_boot.c b/hw/arm_boot.c -index 8335e69..20b1512 100644 ---- a/hw/arm_boot.c -+++ b/hw/arm_boot.c -@@ -47,21 +47,18 @@ static void main_cpu_reset(void *opaque) - CPUState *env = opaque; - - cpu_reset(env); -- if (env->kernel_filename) -- arm_load_kernel(env, env->ram_size, env->kernel_filename, -- env->kernel_cmdline, env->initrd_filename, -- env->board_id, env->loader_start); -+ if (env->boot_info) -+ arm_load_kernel(env, env->boot_info); - - /* TODO: Reset secondary CPUs. */ - } - --static void set_kernel_args(uint32_t ram_size, int initrd_size, -- const char *kernel_cmdline, -- target_phys_addr_t loader_start) -+static void set_kernel_args(struct arm_boot_info *info, -+ int initrd_size, void *base) - { - uint32_t *p; - -- p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR); -+ p = (uint32_t *)(base + KERNEL_ARGS_ADDR); - /* ATAG_CORE */ - stl_raw(p++, 5); - stl_raw(p++, 0x54410001); -@@ -69,46 +66,55 @@ static void set_kernel_args(uint32_t ram_size, int initrd_size, - stl_raw(p++, 0x1000); - stl_raw(p++, 0); - /* ATAG_MEM */ -+ /* TODO: multiple chips */ - stl_raw(p++, 4); - stl_raw(p++, 0x54410002); -- stl_raw(p++, ram_size); -- stl_raw(p++, loader_start); -+ stl_raw(p++, info->ram_size); -+ stl_raw(p++, info->loader_start); - if (initrd_size) { - /* ATAG_INITRD2 */ - stl_raw(p++, 4); - stl_raw(p++, 0x54420005); -- stl_raw(p++, loader_start + INITRD_LOAD_ADDR); -+ stl_raw(p++, info->loader_start + INITRD_LOAD_ADDR); - stl_raw(p++, initrd_size); - } -- if (kernel_cmdline && *kernel_cmdline) { -+ if (info->kernel_cmdline && *info->kernel_cmdline) { - /* ATAG_CMDLINE */ - int cmdline_size; - -- cmdline_size = strlen(kernel_cmdline); -- memcpy (p + 2, kernel_cmdline, cmdline_size + 1); -+ cmdline_size = strlen(info->kernel_cmdline); -+ memcpy(p + 2, info->kernel_cmdline, cmdline_size + 1); - cmdline_size = (cmdline_size >> 2) + 1; - stl_raw(p++, cmdline_size + 2); - stl_raw(p++, 0x54410009); - p += cmdline_size; - } -+ if (info->atag_board) { -+ /* ATAG_BOARD */ -+ int atag_board_len; -+ -+ atag_board_len = (info->atag_board(info, p + 2) + 3) >> 2; -+ stl_raw(p++, 2 + atag_board_len); -+ stl_raw(p++, 0x414f4d50); -+ p += atag_board_len; -+ } - /* ATAG_END */ - stl_raw(p++, 0); - stl_raw(p++, 0); - } - --static void set_kernel_args_old(uint32_t ram_size, int initrd_size, -- const char *kernel_cmdline, -- target_phys_addr_t loader_start) -+static void set_kernel_args_old(struct arm_boot_info *info, -+ int initrd_size, void *base) - { - uint32_t *p; - unsigned char *s; - - /* see linux/include/asm-arm/setup.h */ -- p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR); -+ p = (uint32_t *)(base + KERNEL_ARGS_ADDR); - /* page_size */ - stl_raw(p++, 4096); - /* nr_pages */ -- stl_raw(p++, ram_size / 4096); -+ stl_raw(p++, info->ram_size / 4096); - /* ramdisk_size */ - stl_raw(p++, 0); - #define FLAG_READONLY 1 -@@ -142,7 +148,7 @@ static void set_kernel_args_old(uint32_t ram_size, int initrd_size, - stl_raw(p++, 0); - /* initrd_start */ - if (initrd_size) -- stl_raw(p++, loader_start + INITRD_LOAD_ADDR); -+ stl_raw(p++, info->loader_start + INITRD_LOAD_ADDR); - else - stl_raw(p++, 0); - /* initrd_size */ -@@ -159,17 +165,15 @@ static void set_kernel_args_old(uint32_t ram_size, int initrd_size, - stl_raw(p++, 0); - /* zero unused fields */ - memset(p, 0, 256 + 1024 - -- (p - ((uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR)))); -- s = phys_ram_base + KERNEL_ARGS_ADDR + 256 + 1024; -- if (kernel_cmdline) -- strcpy (s, kernel_cmdline); -+ (p - ((uint32_t *)(base + KERNEL_ARGS_ADDR)))); -+ s = base + KERNEL_ARGS_ADDR + 256 + 1024; -+ if (info->kernel_cmdline) -+ strcpy (s, info->kernel_cmdline); - else - stb_raw(s, 0); - } - --void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, -- const char *kernel_cmdline, const char *initrd_filename, -- int board_id, target_phys_addr_t loader_start) -+void arm_load_kernel(CPUState *env, struct arm_boot_info *info) - { - int kernel_size; - int initrd_size; -@@ -177,36 +181,41 @@ void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, - int is_linux = 0; - uint64_t elf_entry; - target_ulong entry; -+ uint32_t pd; -+ void *loader_phys; - - /* Load the kernel. */ -- if (!kernel_filename) { -+ if (!info->kernel_filename) { - fprintf(stderr, "Kernel image must be specified\n"); - exit(1); - } - -- if (!env->kernel_filename) { -- env->ram_size = ram_size; -- env->kernel_filename = kernel_filename; -- env->kernel_cmdline = kernel_cmdline; -- env->initrd_filename = initrd_filename; -- env->board_id = board_id; -- env->loader_start = loader_start; -+ if (!env->boot_info) { -+ if (info->nb_cpus == 0) -+ info->nb_cpus = 1; -+ env->boot_info = info; - qemu_register_reset(main_cpu_reset, env); - } -+ -+ pd = cpu_get_physical_page_desc(info->loader_start); -+ loader_phys = phys_ram_base + (pd & TARGET_PAGE_MASK) + -+ (info->loader_start & ~TARGET_PAGE_MASK); -+ - /* Assume that raw images are linux kernels, and ELF images are not. */ -- kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL); -+ kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL); - entry = elf_entry; - if (kernel_size < 0) { -- kernel_size = load_uboot(kernel_filename, &entry, &is_linux); -+ kernel_size = load_uboot(info->kernel_filename, &entry, &is_linux); - } - if (kernel_size < 0) { -- kernel_size = load_image(kernel_filename, -- phys_ram_base + KERNEL_LOAD_ADDR); -- entry = loader_start + KERNEL_LOAD_ADDR; -+ kernel_size = load_image(info->kernel_filename, -+ loader_phys + KERNEL_LOAD_ADDR); -+ entry = info->loader_start + KERNEL_LOAD_ADDR; - is_linux = 1; - } - if (kernel_size < 0) { -- fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); -+ fprintf(stderr, "qemu: could not load kernel '%s'\n", -+ info->kernel_filename); - exit(1); - } - if (!is_linux) { -@@ -214,30 +223,29 @@ void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, - env->regs[15] = entry & 0xfffffffe; - env->thumb = entry & 1; - } else { -- if (initrd_filename) { -- initrd_size = load_image(initrd_filename, -- phys_ram_base + INITRD_LOAD_ADDR); -+ if (info->initrd_filename) { -+ initrd_size = load_image(info->initrd_filename, -+ loader_phys + INITRD_LOAD_ADDR); - if (initrd_size < 0) { - fprintf(stderr, "qemu: could not load initrd '%s'\n", -- initrd_filename); -+ info->initrd_filename); - exit(1); - } - } else { - initrd_size = 0; - } -- bootloader[1] |= board_id & 0xff; -- bootloader[2] |= (board_id >> 8) & 0xff; -- bootloader[5] = loader_start + KERNEL_ARGS_ADDR; -+ bootloader[1] |= info->board_id & 0xff; -+ bootloader[2] |= (info->board_id >> 8) & 0xff; -+ bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR; - bootloader[6] = entry; - for (n = 0; n < sizeof(bootloader) / 4; n++) -- stl_raw(phys_ram_base + (n * 4), bootloader[n]); -- for (n = 0; n < sizeof(smpboot) / 4; n++) -- stl_raw(phys_ram_base + ram_size + (n * 4), smpboot[n]); -+ stl_raw(loader_phys + (n * 4), bootloader[n]); -+ if (info->nb_cpus > 1) -+ for (n = 0; n < sizeof(smpboot) / 4; n++) -+ stl_raw(loader_phys + info->ram_size + (n * 4), smpboot[n]); - if (old_param) -- set_kernel_args_old(ram_size, initrd_size, -- kernel_cmdline, loader_start); -+ set_kernel_args_old(info, initrd_size, loader_phys); - else -- set_kernel_args(ram_size, initrd_size, -- kernel_cmdline, loader_start); -+ set_kernel_args(info, initrd_size, loader_phys); - } - } -diff --git a/hw/blizzard.c b/hw/blizzard.c -new file mode 100644 -index 0000000..9046b5d ---- /dev/null -+++ b/hw/blizzard.c -@@ -0,0 +1,1001 @@ -+/* -+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller. -+ * -+ * Copyright (C) 2008 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+#include "qemu-common.h" -+#include "sysemu.h" -+#include "console.h" -+#include "devices.h" -+#include "vga_int.h" -+#include "pixel_ops.h" -+ -+typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int); -+ -+struct blizzard_s { -+ uint8_t reg; -+ uint32_t addr; -+ int swallow; -+ -+ int pll; -+ int pll_range; -+ int pll_ctrl; -+ uint8_t pll_mode; -+ uint8_t clksel; -+ int memenable; -+ int memrefresh; -+ uint8_t timing[3]; -+ int priority; -+ -+ uint8_t lcd_config; -+ int x; -+ int y; -+ int skipx; -+ int skipy; -+ uint8_t hndp; -+ uint8_t vndp; -+ uint8_t hsync; -+ uint8_t vsync; -+ uint8_t pclk; -+ uint8_t u; -+ uint8_t v; -+ uint8_t yrc[2]; -+ int ix[2]; -+ int iy[2]; -+ int ox[2]; -+ int oy[2]; -+ -+ int enable; -+ int blank; -+ int bpp; -+ int invalidate; -+ int mx[2]; -+ int my[2]; -+ uint8_t mode; -+ uint8_t effect; -+ uint8_t iformat; -+ uint8_t source; -+ DisplayState *state; -+ blizzard_fn_t *line_fn_tab[2]; -+ void *fb; -+ -+ uint8_t hssi_config[3]; -+ uint8_t tv_config; -+ uint8_t tv_timing[4]; -+ uint8_t vbi; -+ uint8_t tv_x; -+ uint8_t tv_y; -+ uint8_t tv_test; -+ uint8_t tv_filter_config; -+ uint8_t tv_filter_idx; -+ uint8_t tv_filter_coeff[0x20]; -+ uint8_t border_r; -+ uint8_t border_g; -+ uint8_t border_b; -+ uint8_t gamma_config; -+ uint8_t gamma_idx; -+ uint8_t gamma_lut[0x100]; -+ uint8_t matrix_ena; -+ uint8_t matrix_coeff[0x12]; -+ uint8_t matrix_r; -+ uint8_t matrix_g; -+ uint8_t matrix_b; -+ uint8_t pm; -+ uint8_t status; -+ uint8_t rgbgpio_dir; -+ uint8_t rgbgpio; -+ uint8_t gpio_dir; -+ uint8_t gpio; -+ uint8_t gpio_edge[2]; -+ uint8_t gpio_irq; -+ uint8_t gpio_pdown; -+ -+ struct { -+ int x; -+ int y; -+ int dx; -+ int dy; -+ int len; -+ int buflen; -+ void *buf; -+ void *data; -+ uint16_t *ptr; -+ int angle; -+ int pitch; -+ blizzard_fn_t line_fn; -+ } data; -+}; -+ -+/* Bytes(!) per pixel */ -+static const int blizzard_iformat_bpp[0x10] = { -+ 0, -+ 2, /* RGB 5:6:5*/ -+ 3, /* RGB 6:6:6 mode 1 */ -+ 3, /* RGB 8:8:8 mode 1 */ -+ 0, 0, -+ 4, /* RGB 6:6:6 mode 2 */ -+ 4, /* RGB 8:8:8 mode 2 */ -+ 0, /* YUV 4:2:2 */ -+ 0, /* YUV 4:2:0 */ -+ 0, 0, 0, 0, 0, 0, -+}; -+ -+static inline void blizzard_rgb2yuv(int r, int g, int b, -+ int *y, int *u, int *v) -+{ -+ *y = 0x10 + ((0x838 * r + 0x1022 * g + 0x322 * b) >> 13); -+ *u = 0x80 + ((0xe0e * b - 0x04c1 * r - 0x94e * g) >> 13); -+ *v = 0x80 + ((0xe0e * r - 0x0bc7 * g - 0x247 * b) >> 13); -+} -+ -+static void blizzard_window(struct blizzard_s *s) -+{ -+ uint8_t *src, *dst; -+ int bypp[2]; -+ int bypl[3]; -+ int y; -+ blizzard_fn_t fn = s->data.line_fn; -+ -+ if (!fn) -+ return; -+ if (s->mx[0] > s->data.x) -+ s->mx[0] = s->data.x; -+ if (s->my[0] > s->data.y) -+ s->my[0] = s->data.y; -+ if (s->mx[1] < s->data.x + s->data.dx) -+ s->mx[1] = s->data.x + s->data.dx; -+ if (s->my[1] < s->data.y + s->data.dy) -+ s->my[1] = s->data.y + s->data.dy; -+ -+ bypp[0] = s->bpp; -+ bypp[1] = (s->state->depth + 7) >> 3; -+ bypl[0] = bypp[0] * s->data.pitch; -+ bypl[1] = bypp[1] * s->x; -+ bypl[2] = bypp[0] * s->data.dx; -+ -+ src = s->data.data; -+ dst = s->fb + bypl[1] * s->data.y + bypp[1] * s->data.x; -+ for (y = s->data.dy; y > 0; y --, src += bypl[0], dst += bypl[1]) -+ fn(dst, src, bypl[2]); -+} -+ -+static int blizzard_transfer_setup(struct blizzard_s *s) -+{ -+ if (s->source > 3 || !s->bpp || -+ s->ix[1] < s->ix[0] || s->iy[1] < s->iy[0]) -+ return 0; -+ -+ s->data.angle = s->effect & 3; -+ s->data.line_fn = s->line_fn_tab[!!s->data.angle][s->iformat]; -+ s->data.x = s->ix[0]; -+ s->data.y = s->iy[0]; -+ s->data.dx = s->ix[1] - s->ix[0] + 1; -+ s->data.dy = s->iy[1] - s->iy[0] + 1; -+ s->data.len = s->bpp * s->data.dx * s->data.dy; -+ s->data.pitch = s->data.dx; -+ if (s->data.len > s->data.buflen) { -+ s->data.buf = realloc(s->data.buf, s->data.len); -+ s->data.buflen = s->data.len; -+ } -+ s->data.ptr = s->data.buf; -+ s->data.data = s->data.buf; -+ s->data.len /= 2; -+ return 1; -+} -+ -+static void blizzard_reset(struct blizzard_s *s) -+{ -+ s->reg = 0; -+ s->swallow = 0; -+ -+ s->pll = 9; -+ s->pll_range = 1; -+ s->pll_ctrl = 0x14; -+ s->pll_mode = 0x32; -+ s->clksel = 0x00; -+ s->memenable = 0; -+ s->memrefresh = 0x25c; -+ s->timing[0] = 0x3f; -+ s->timing[1] = 0x13; -+ s->timing[2] = 0x21; -+ s->priority = 0; -+ -+ s->lcd_config = 0x74; -+ s->x = 8; -+ s->y = 1; -+ s->skipx = 0; -+ s->skipy = 0; -+ s->hndp = 3; -+ s->vndp = 2; -+ s->hsync = 1; -+ s->vsync = 1; -+ s->pclk = 0x80; -+ -+ s->ix[0] = 0; -+ s->ix[1] = 0; -+ s->iy[0] = 0; -+ s->iy[1] = 0; -+ s->ox[0] = 0; -+ s->ox[1] = 0; -+ s->oy[0] = 0; -+ s->oy[1] = 0; -+ -+ s->yrc[0] = 0x00; -+ s->yrc[1] = 0x30; -+ s->u = 0; -+ s->v = 0; -+ -+ s->iformat = 3; -+ s->source = 0; -+ s->bpp = blizzard_iformat_bpp[s->iformat]; -+ -+ s->hssi_config[0] = 0x00; -+ s->hssi_config[1] = 0x00; -+ s->hssi_config[2] = 0x01; -+ s->tv_config = 0x00; -+ s->tv_timing[0] = 0x00; -+ s->tv_timing[1] = 0x00; -+ s->tv_timing[2] = 0x00; -+ s->tv_timing[3] = 0x00; -+ s->vbi = 0x10; -+ s->tv_x = 0x14; -+ s->tv_y = 0x03; -+ s->tv_test = 0x00; -+ s->tv_filter_config = 0x80; -+ s->tv_filter_idx = 0x00; -+ s->border_r = 0x10; -+ s->border_g = 0x80; -+ s->border_b = 0x80; -+ s->gamma_config = 0x00; -+ s->gamma_idx = 0x00; -+ s->matrix_ena = 0x00; -+ memset(&s->matrix_coeff, 0, sizeof(s->matrix_coeff)); -+ s->matrix_r = 0x00; -+ s->matrix_g = 0x00; -+ s->matrix_b = 0x00; -+ s->pm = 0x02; -+ s->status = 0x00; -+ s->rgbgpio_dir = 0x00; -+ s->gpio_dir = 0x00; -+ s->gpio_edge[0] = 0x00; -+ s->gpio_edge[1] = 0x00; -+ s->gpio_irq = 0x00; -+ s->gpio_pdown = 0xff; -+} -+ -+static inline void blizzard_invalidate_display(void *opaque) { -+ struct blizzard_s *s = (struct blizzard_s *) opaque; -+ -+ s->invalidate = 1; -+} -+ -+static uint16_t blizzard_reg_read(void *opaque, uint8_t reg) -+{ -+ struct blizzard_s *s = (struct blizzard_s *) opaque; -+ -+ switch (reg) { -+ case 0x00: /* Revision Code */ -+ return 0xa5; -+ -+ case 0x02: /* Configuration Readback */ -+ return 0x83; /* Macrovision OK, CNF[2:0] = 3 */ -+ -+ case 0x04: /* PLL M-Divider */ -+ return (s->pll - 1) | (1 << 7); -+ case 0x06: /* PLL Lock Range Control */ -+ return s->pll_range; -+ case 0x08: /* PLL Lock Synthesis Control 0 */ -+ return s->pll_ctrl & 0xff; -+ case 0x0a: /* PLL Lock Synthesis Control 1 */ -+ return s->pll_ctrl >> 8; -+ case 0x0c: /* PLL Mode Control 0 */ -+ return s->pll_mode; -+ -+ case 0x0e: /* Clock-Source Select */ -+ return s->clksel; -+ -+ case 0x10: /* Memory Controller Activate */ -+ case 0x14: /* Memory Controller Bank 0 Status Flag */ -+ return s->memenable; -+ -+ case 0x18: /* Auto-Refresh Interval Setting 0 */ -+ return s->memrefresh & 0xff; -+ case 0x1a: /* Auto-Refresh Interval Setting 1 */ -+ return s->memrefresh >> 8; -+ -+ case 0x1c: /* Power-On Sequence Timing Control */ -+ return s->timing[0]; -+ case 0x1e: /* Timing Control 0 */ -+ return s->timing[1]; -+ case 0x20: /* Timing Control 1 */ -+ return s->timing[2]; -+ -+ case 0x24: /* Arbitration Priority Control */ -+ return s->priority; -+ -+ case 0x28: /* LCD Panel Configuration */ -+ return s->lcd_config; -+ -+ case 0x2a: /* LCD Horizontal Display Width */ -+ return s->x >> 3; -+ case 0x2c: /* LCD Horizontal Non-display Period */ -+ return s->hndp; -+ case 0x2e: /* LCD Vertical Display Height 0 */ -+ return s->y & 0xff; -+ case 0x30: /* LCD Vertical Display Height 1 */ -+ return s->y >> 8; -+ case 0x32: /* LCD Vertical Non-display Period */ -+ return s->vndp; -+ case 0x34: /* LCD HS Pulse-width */ -+ return s->hsync; -+ case 0x36: /* LCd HS Pulse Start Position */ -+ return s->skipx >> 3; -+ case 0x38: /* LCD VS Pulse-width */ -+ return s->vsync; -+ case 0x3a: /* LCD VS Pulse Start Position */ -+ return s->skipy; -+ -+ case 0x3c: /* PCLK Polarity */ -+ return s->pclk; -+ -+ case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */ -+ return s->hssi_config[0]; -+ case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */ -+ return s->hssi_config[1]; -+ case 0x42: /* High-speed Serial Interface Tx Mode */ -+ return s->hssi_config[2]; -+ case 0x44: /* TV Display Configuration */ -+ return s->tv_config; -+ case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits */ -+ return s->tv_timing[(reg - 0x46) >> 1]; -+ case 0x4e: /* VBI: Closed Caption / XDS Control / Status */ -+ return s->vbi; -+ case 0x50: /* TV Horizontal Start Position */ -+ return s->tv_x; -+ case 0x52: /* TV Vertical Start Position */ -+ return s->tv_y; -+ case 0x54: /* TV Test Pattern Setting */ -+ return s->tv_test; -+ case 0x56: /* TV Filter Setting */ -+ return s->tv_filter_config; -+ case 0x58: /* TV Filter Coefficient Index */ -+ return s->tv_filter_idx; -+ case 0x5a: /* TV Filter Coefficient Data */ -+ if (s->tv_filter_idx < 0x20) -+ return s->tv_filter_coeff[s->tv_filter_idx ++]; -+ return 0; -+ -+ case 0x60: /* Input YUV/RGB Translate Mode 0 */ -+ return s->yrc[0]; -+ case 0x62: /* Input YUV/RGB Translate Mode 1 */ -+ return s->yrc[1]; -+ case 0x64: /* U Data Fix */ -+ return s->u; -+ case 0x66: /* V Data Fix */ -+ return s->v; -+ -+ case 0x68: /* Display Mode */ -+ return s->mode; -+ -+ case 0x6a: /* Special Effects */ -+ return s->effect; -+ -+ case 0x6c: /* Input Window X Start Position 0 */ -+ return s->ix[0] & 0xff; -+ case 0x6e: /* Input Window X Start Position 1 */ -+ return s->ix[0] >> 3; -+ case 0x70: /* Input Window Y Start Position 0 */ -+ return s->ix[0] & 0xff; -+ case 0x72: /* Input Window Y Start Position 1 */ -+ return s->ix[0] >> 3; -+ case 0x74: /* Input Window X End Position 0 */ -+ return s->ix[1] & 0xff; -+ case 0x76: /* Input Window X End Position 1 */ -+ return s->ix[1] >> 3; -+ case 0x78: /* Input Window Y End Position 0 */ -+ return s->ix[1] & 0xff; -+ case 0x7a: /* Input Window Y End Position 1 */ -+ return s->ix[1] >> 3; -+ case 0x7c: /* Output Window X Start Position 0 */ -+ return s->ox[0] & 0xff; -+ case 0x7e: /* Output Window X Start Position 1 */ -+ return s->ox[0] >> 3; -+ case 0x80: /* Output Window Y Start Position 0 */ -+ return s->oy[0] & 0xff; -+ case 0x82: /* Output Window Y Start Position 1 */ -+ return s->oy[0] >> 3; -+ case 0x84: /* Output Window X End Position 0 */ -+ return s->ox[1] & 0xff; -+ case 0x86: /* Output Window X End Position 1 */ -+ return s->ox[1] >> 3; -+ case 0x88: /* Output Window Y End Position 0 */ -+ return s->oy[1] & 0xff; -+ case 0x8a: /* Output Window Y End Position 1 */ -+ return s->oy[1] >> 3; -+ -+ case 0x8c: /* Input Data Format */ -+ return s->iformat; -+ case 0x8e: /* Data Source Select */ -+ return s->source; -+ case 0x90: /* Display Memory Data Port */ -+ return 0; -+ -+ case 0xa8: /* Border Color 0 */ -+ return s->border_r; -+ case 0xaa: /* Border Color 1 */ -+ return s->border_g; -+ case 0xac: /* Border Color 2 */ -+ return s->border_b; -+ -+ case 0xb4: /* Gamma Correction Enable */ -+ return s->gamma_config; -+ case 0xb6: /* Gamma Correction Table Index */ -+ return s->gamma_idx; -+ case 0xb8: /* Gamma Correction Table Data */ -+ return s->gamma_lut[s->gamma_idx ++]; -+ -+ case 0xba: /* 3x3 Matrix Enable */ -+ return s->matrix_ena; -+ case 0xbc ... 0xde: /* Coefficient Registers */ -+ return s->matrix_coeff[(reg - 0xbc) >> 1]; -+ case 0xe0: /* 3x3 Matrix Red Offset */ -+ return s->matrix_r; -+ case 0xe2: /* 3x3 Matrix Green Offset */ -+ return s->matrix_g; -+ case 0xe4: /* 3x3 Matrix Blue Offset */ -+ return s->matrix_b; -+ -+ case 0xe6: /* Power-save */ -+ return s->pm; -+ case 0xe8: /* Non-display Period Control / Status */ -+ return s->status | (1 << 5); -+ case 0xea: /* RGB Interface Control */ -+ return s->rgbgpio_dir; -+ case 0xec: /* RGB Interface Status */ -+ return s->rgbgpio; -+ case 0xee: /* General-purpose IO Pins Configuration */ -+ return s->gpio_dir; -+ case 0xf0: /* General-purpose IO Pins Status / Control */ -+ return s->gpio; -+ case 0xf2: /* GPIO Positive Edge Interrupt Trigger */ -+ return s->gpio_edge[0]; -+ case 0xf4: /* GPIO Negative Edge Interrupt Trigger */ -+ return s->gpio_edge[1]; -+ case 0xf6: /* GPIO Interrupt Status */ -+ return s->gpio_irq; -+ case 0xf8: /* GPIO Pull-down Control */ -+ return s->gpio_pdown; -+ -+ default: -+ fprintf(stderr, "%s: unknown register %02x\n", __FUNCTION__, reg); -+ return 0; -+ } -+} -+ -+static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value) -+{ -+ struct blizzard_s *s = (struct blizzard_s *) opaque; -+ -+ switch (reg) { -+ case 0x04: /* PLL M-Divider */ -+ s->pll = (value & 0x3f) + 1; -+ break; -+ case 0x06: /* PLL Lock Range Control */ -+ s->pll_range = value & 3; -+ break; -+ case 0x08: /* PLL Lock Synthesis Control 0 */ -+ s->pll_ctrl &= 0xf00; -+ s->pll_ctrl |= (value << 0) & 0x0ff; -+ break; -+ case 0x0a: /* PLL Lock Synthesis Control 1 */ -+ s->pll_ctrl &= 0x0ff; -+ s->pll_ctrl |= (value << 8) & 0xf00; -+ break; -+ case 0x0c: /* PLL Mode Control 0 */ -+ s->pll_mode = value & 0x77; -+ if ((value & 3) == 0 || (value & 3) == 3) -+ fprintf(stderr, "%s: wrong PLL Control bits (%i)\n", -+ __FUNCTION__, value & 3); -+ break; -+ -+ case 0x0e: /* Clock-Source Select */ -+ s->clksel = value & 0xff; -+ break; -+ -+ case 0x10: /* Memory Controller Activate */ -+ s->memenable = value & 1; -+ break; -+ case 0x14: /* Memory Controller Bank 0 Status Flag */ -+ break; -+ -+ case 0x18: /* Auto-Refresh Interval Setting 0 */ -+ s->memrefresh &= 0xf00; -+ s->memrefresh |= (value << 0) & 0x0ff; -+ break; -+ case 0x1a: /* Auto-Refresh Interval Setting 1 */ -+ s->memrefresh &= 0x0ff; -+ s->memrefresh |= (value << 8) & 0xf00; -+ break; -+ -+ case 0x1c: /* Power-On Sequence Timing Control */ -+ s->timing[0] = value & 0x7f; -+ break; -+ case 0x1e: /* Timing Control 0 */ -+ s->timing[1] = value & 0x17; -+ break; -+ case 0x20: /* Timing Control 1 */ -+ s->timing[2] = value & 0x35; -+ break; -+ -+ case 0x24: /* Arbitration Priority Control */ -+ s->priority = value & 1; -+ break; -+ -+ case 0x28: /* LCD Panel Configuration */ -+ s->lcd_config = value & 0xff; -+ if (value & (1 << 7)) -+ fprintf(stderr, "%s: data swap not supported!\n", __FUNCTION__); -+ break; -+ -+ case 0x2a: /* LCD Horizontal Display Width */ -+ s->x = value << 3; -+ break; -+ case 0x2c: /* LCD Horizontal Non-display Period */ -+ s->hndp = value & 0xff; -+ break; -+ case 0x2e: /* LCD Vertical Display Height 0 */ -+ s->y &= 0x300; -+ s->y |= (value << 0) & 0x0ff; -+ break; -+ case 0x30: /* LCD Vertical Display Height 1 */ -+ s->y &= 0x0ff; -+ s->y |= (value << 8) & 0x300; -+ break; -+ case 0x32: /* LCD Vertical Non-display Period */ -+ s->vndp = value & 0xff; -+ break; -+ case 0x34: /* LCD HS Pulse-width */ -+ s->hsync = value & 0xff; -+ break; -+ case 0x36: /* LCD HS Pulse Start Position */ -+ s->skipx = value & 0xff; -+ break; -+ case 0x38: /* LCD VS Pulse-width */ -+ s->vsync = value & 0xbf; -+ break; -+ case 0x3a: /* LCD VS Pulse Start Position */ -+ s->skipy = value & 0xff; -+ break; -+ -+ case 0x3c: /* PCLK Polarity */ -+ s->pclk = value & 0x82; -+ /* Affects calculation of s->hndp, s->hsync and s->skipx. */ -+ break; -+ -+ case 0x3e: /* High-speed Serial Interface Tx Configuration Port 0 */ -+ s->hssi_config[0] = value; -+ break; -+ case 0x40: /* High-speed Serial Interface Tx Configuration Port 1 */ -+ s->hssi_config[1] = value; -+ if (((value >> 4) & 3) == 3) -+ fprintf(stderr, "%s: Illegal active-data-links value\n", -+ __FUNCTION__); -+ break; -+ case 0x42: /* High-speed Serial Interface Tx Mode */ -+ s->hssi_config[2] = value & 0xbd; -+ break; -+ -+ case 0x44: /* TV Display Configuration */ -+ s->tv_config = value & 0xfe; -+ break; -+ case 0x46 ... 0x4c: /* TV Vertical Blanking Interval Data bits 0 */ -+ s->tv_timing[(reg - 0x46) >> 1] = value; -+ break; -+ case 0x4e: /* VBI: Closed Caption / XDS Control / Status */ -+ s->vbi = value; -+ break; -+ case 0x50: /* TV Horizontal Start Position */ -+ s->tv_x = value; -+ break; -+ case 0x52: /* TV Vertical Start Position */ -+ s->tv_y = value & 0x7f; -+ break; -+ case 0x54: /* TV Test Pattern Setting */ -+ s->tv_test = value; -+ break; -+ case 0x56: /* TV Filter Setting */ -+ s->tv_filter_config = value & 0xbf; -+ break; -+ case 0x58: /* TV Filter Coefficient Index */ -+ s->tv_filter_idx = value & 0x1f; -+ break; -+ case 0x5a: /* TV Filter Coefficient Data */ -+ if (s->tv_filter_idx < 0x20) -+ s->tv_filter_coeff[s->tv_filter_idx ++] = value; -+ break; -+ -+ case 0x60: /* Input YUV/RGB Translate Mode 0 */ -+ s->yrc[0] = value & 0xb0; -+ break; -+ case 0x62: /* Input YUV/RGB Translate Mode 1 */ -+ s->yrc[1] = value & 0x30; -+ break; -+ case 0x64: /* U Data Fix */ -+ s->u = value & 0xff; -+ break; -+ case 0x66: /* V Data Fix */ -+ s->v = value & 0xff; -+ break; -+ -+ case 0x68: /* Display Mode */ -+ if ((s->mode ^ value) & 3) -+ s->invalidate = 1; -+ s->mode = value & 0xb7; -+ s->enable = value & 1; -+ s->blank = (value >> 1) & 1; -+ if (value & (1 << 4)) -+ fprintf(stderr, "%s: Macrovision enable attempt!\n", __FUNCTION__); -+ break; -+ -+ case 0x6a: /* Special Effects */ -+ s->effect = value & 0xfb; -+ break; -+ -+ case 0x6c: /* Input Window X Start Position 0 */ -+ s->ix[0] &= 0x300; -+ s->ix[0] |= (value << 0) & 0x0ff; -+ break; -+ case 0x6e: /* Input Window X Start Position 1 */ -+ s->ix[0] &= 0x0ff; -+ s->ix[0] |= (value << 8) & 0x300; -+ break; -+ case 0x70: /* Input Window Y Start Position 0 */ -+ s->iy[0] &= 0x300; -+ s->iy[0] |= (value << 0) & 0x0ff; -+ break; -+ case 0x72: /* Input Window Y Start Position 1 */ -+ s->iy[0] &= 0x0ff; -+ s->iy[0] |= (value << 8) & 0x300; -+ break; -+ case 0x74: /* Input Window X End Position 0 */ -+ s->ix[1] &= 0x300; -+ s->ix[1] |= (value << 0) & 0x0ff; -+ break; -+ case 0x76: /* Input Window X End Position 1 */ -+ s->ix[1] &= 0x0ff; -+ s->ix[1] |= (value << 8) & 0x300; -+ break; -+ case 0x78: /* Input Window Y End Position 0 */ -+ s->iy[1] &= 0x300; -+ s->iy[1] |= (value << 0) & 0x0ff; -+ break; -+ case 0x7a: /* Input Window Y End Position 1 */ -+ s->iy[1] &= 0x0ff; -+ s->iy[1] |= (value << 8) & 0x300; -+ break; -+ case 0x7c: /* Output Window X Start Position 0 */ -+ s->ox[0] &= 0x300; -+ s->ox[0] |= (value << 0) & 0x0ff; -+ break; -+ case 0x7e: /* Output Window X Start Position 1 */ -+ s->ox[0] &= 0x0ff; -+ s->ox[0] |= (value << 8) & 0x300; -+ break; -+ case 0x80: /* Output Window Y Start Position 0 */ -+ s->oy[0] &= 0x300; -+ s->oy[0] |= (value << 0) & 0x0ff; -+ break; -+ case 0x82: /* Output Window Y Start Position 1 */ -+ s->oy[0] &= 0x0ff; -+ s->oy[0] |= (value << 8) & 0x300; -+ break; -+ case 0x84: /* Output Window X End Position 0 */ -+ s->ox[1] &= 0x300; -+ s->ox[1] |= (value << 0) & 0x0ff; -+ break; -+ case 0x86: /* Output Window X End Position 1 */ -+ s->ox[1] &= 0x0ff; -+ s->ox[1] |= (value << 8) & 0x300; -+ break; -+ case 0x88: /* Output Window Y End Position 0 */ -+ s->oy[1] &= 0x300; -+ s->oy[1] |= (value << 0) & 0x0ff; -+ break; -+ case 0x8a: /* Output Window Y End Position 1 */ -+ s->oy[1] &= 0x0ff; -+ s->oy[1] |= (value << 8) & 0x300; -+ break; -+ -+ case 0x8c: /* Input Data Format */ -+ s->iformat = value & 0xf; -+ s->bpp = blizzard_iformat_bpp[s->iformat]; -+ if (!s->bpp) -+ fprintf(stderr, "%s: Illegal or unsupported input format %x\n", -+ __FUNCTION__, s->iformat); -+ break; -+ case 0x8e: /* Data Source Select */ -+ s->source = value & 7; -+ /* Currently all windows will be "destructive overlays". */ -+ if ((!(s->effect & (1 << 3)) && (s->ix[0] != s->ox[0] || -+ s->iy[0] != s->oy[0] || -+ s->ix[1] != s->ox[1] || -+ s->iy[1] != s->oy[1])) || -+ !((s->ix[1] - s->ix[0]) & (s->iy[1] - s->iy[0]) & -+ (s->ox[1] - s->ox[0]) & (s->oy[1] - s->oy[0]) & 1)) -+ fprintf(stderr, "%s: Illegal input/output window positions\n", -+ __FUNCTION__); -+ -+ blizzard_transfer_setup(s); -+ break; -+ -+ case 0x90: /* Display Memory Data Port */ -+ if (!s->data.len && !blizzard_transfer_setup(s)) -+ break; -+ -+ *s->data.ptr ++ = value; -+ if (-- s->data.len == 0) -+ blizzard_window(s); -+ break; -+ -+ case 0xa8: /* Border Color 0 */ -+ s->border_r = value; -+ break; -+ case 0xaa: /* Border Color 1 */ -+ s->border_g = value; -+ break; -+ case 0xac: /* Border Color 2 */ -+ s->border_b = value; -+ break; -+ -+ case 0xb4: /* Gamma Correction Enable */ -+ s->gamma_config = value & 0x87; -+ break; -+ case 0xb6: /* Gamma Correction Table Index */ -+ s->gamma_idx = value; -+ break; -+ case 0xb8: /* Gamma Correction Table Data */ -+ s->gamma_lut[s->gamma_idx ++] = value; -+ break; -+ -+ case 0xba: /* 3x3 Matrix Enable */ -+ s->matrix_ena = value & 1; -+ break; -+ case 0xbc ... 0xde: /* Coefficient Registers */ -+ s->matrix_coeff[(reg - 0xbc) >> 1] = value & ((reg & 2) ? 0x80 : 0xff); -+ break; -+ case 0xe0: /* 3x3 Matrix Red Offset */ -+ s->matrix_r = value; -+ break; -+ case 0xe2: /* 3x3 Matrix Green Offset */ -+ s->matrix_g = value; -+ break; -+ case 0xe4: /* 3x3 Matrix Blue Offset */ -+ s->matrix_b = value; -+ break; -+ -+ case 0xe6: /* Power-save */ -+ s->pm = value & 0x83; -+ if (value & s->mode & 1) -+ fprintf(stderr, "%s: The display must be disabled before entering " -+ "Standby Mode\n", __FUNCTION__); -+ break; -+ case 0xe8: /* Non-display Period Control / Status */ -+ s->status = value & 0x1b; -+ break; -+ case 0xea: /* RGB Interface Control */ -+ s->rgbgpio_dir = value & 0x8f; -+ break; -+ case 0xec: /* RGB Interface Status */ -+ s->rgbgpio = value & 0xcf; -+ break; -+ case 0xee: /* General-purpose IO Pins Configuration */ -+ s->gpio_dir = value; -+ break; -+ case 0xf0: /* General-purpose IO Pins Status / Control */ -+ s->gpio = value; -+ break; -+ case 0xf2: /* GPIO Positive Edge Interrupt Trigger */ -+ s->gpio_edge[0] = value; -+ break; -+ case 0xf4: /* GPIO Negative Edge Interrupt Trigger */ -+ s->gpio_edge[1] = value; -+ break; -+ case 0xf6: /* GPIO Interrupt Status */ -+ s->gpio_irq &= value; -+ break; -+ case 0xf8: /* GPIO Pull-down Control */ -+ s->gpio_pdown = value; -+ break; -+ -+ default: -+ fprintf(stderr, "%s: unknown register %02x\n", __FUNCTION__, reg); -+ break; -+ } -+} -+ -+uint16_t s1d13745_read(void *opaque, int dc) -+{ -+ struct blizzard_s *s = (struct blizzard_s *) opaque; -+ uint16_t value = blizzard_reg_read(s, s->reg); -+ -+ if (s->swallow -- > 0) -+ return 0; -+ if (dc) -+ s->reg ++; -+ -+ return value; -+} -+ -+void s1d13745_write(void *opaque, int dc, uint16_t value) -+{ -+ struct blizzard_s *s = (struct blizzard_s *) opaque; -+ -+ if (s->swallow -- > 0) -+ return; -+ if (dc) { -+ blizzard_reg_write(s, s->reg, value); -+ -+ if (s->reg != 0x90 && s->reg != 0x5a && s->reg != 0xb8) -+ s->reg += 2; -+ } else -+ s->reg = value & 0xff; -+} -+ -+void s1d13745_write_block(void *opaque, int dc, -+ void *buf, size_t len, int pitch) -+{ -+ struct blizzard_s *s = (struct blizzard_s *) opaque; -+ -+ while (len > 0) { -+ if (s->reg == 0x90 && dc && -+ (s->data.len || blizzard_transfer_setup(s)) && -+ len >= (s->data.len << 1)) { -+ len -= s->data.len << 1; -+ s->data.len = 0; -+ s->data.data = buf; -+ if (pitch) -+ s->data.pitch = pitch; -+ blizzard_window(s); -+ s->data.data = s->data.buf; -+ continue; -+ } -+ -+ s1d13745_write(opaque, dc, *(uint16_t *) buf); -+ len -= 2; -+ buf += 2; -+ } -+ -+ return; -+} -+ -+static void blizzard_update_display(void *opaque) -+{ -+ struct blizzard_s *s = (struct blizzard_s *) opaque; -+ int y, bypp, bypl, bwidth; -+ uint8_t *src, *dst; -+ -+ if (!s->enable) -+ return; -+ -+ if (s->x != s->state->width || s->y != s->state->height) { -+ s->invalidate = 1; -+ dpy_resize(s->state, s->x, s->y); -+ } -+ -+ if (s->invalidate) { -+ s->invalidate = 0; -+ -+ if (s->blank) { -+ bypp = (s->state->depth + 7) >> 3; -+ memset(s->state->data, 0, bypp * s->x * s->y); -+ return; -+ } -+ -+ s->mx[0] = 0; -+ s->mx[1] = s->x; -+ s->my[0] = 0; -+ s->my[1] = s->y; -+ } -+ -+ if (s->mx[1] <= s->mx[0]) -+ return; -+ -+ bypp = (s->state->depth + 7) >> 3; -+ bypl = bypp * s->x; -+ bwidth = bypp * (s->mx[1] - s->mx[0]); -+ y = s->my[0]; -+ src = s->fb + bypl * y + bypp * s->mx[0]; -+ dst = s->state->data + bypl * y + bypp * s->mx[0]; -+ for (; y < s->my[1]; y ++, src += bypl, dst += bypl) -+ memcpy(dst, src, bwidth); -+ -+ dpy_update(s->state, s->mx[0], s->my[0], -+ s->mx[1] - s->mx[0], y - s->my[0]); -+ -+ s->mx[0] = s->x; -+ s->mx[1] = 0; -+ s->my[0] = s->y; -+ s->my[1] = 0; -+} -+ -+static void blizzard_screen_dump(void *opaque, const char *filename) { -+ struct blizzard_s *s = (struct blizzard_s *) opaque; -+ -+ blizzard_update_display(opaque); -+ if (s && s->state->data) -+ ppm_save(filename, s->state->data, s->x, s->y, s->state->linesize); -+} -+ -+#define DEPTH 8 -+#include "blizzard_template.h" -+#define DEPTH 15 -+#include "blizzard_template.h" -+#define DEPTH 16 -+#include "blizzard_template.h" -+#define DEPTH 24 -+#include "blizzard_template.h" -+#define DEPTH 32 -+#include "blizzard_template.h" -+ -+void *s1d13745_init(qemu_irq gpio_int, DisplayState *ds) -+{ -+ struct blizzard_s *s = (struct blizzard_s *) qemu_mallocz(sizeof(*s)); -+ -+ s->state = ds; -+ s->fb = qemu_malloc(0x180000); -+ -+ switch (s->state->depth) { -+ case 0: -+ s->line_fn_tab[0] = s->line_fn_tab[1] = -+ qemu_mallocz(sizeof(blizzard_fn_t) * 0x10); -+ break; -+ case 8: -+ s->line_fn_tab[0] = blizzard_draw_fn_8; -+ s->line_fn_tab[1] = blizzard_draw_fn_r_8; -+ break; -+ case 15: -+ s->line_fn_tab[0] = blizzard_draw_fn_15; -+ s->line_fn_tab[1] = blizzard_draw_fn_r_15; -+ break; -+ case 16: -+ s->line_fn_tab[0] = blizzard_draw_fn_16; -+ s->line_fn_tab[1] = blizzard_draw_fn_r_16; -+ break; -+ case 24: -+ s->line_fn_tab[0] = blizzard_draw_fn_24; -+ s->line_fn_tab[1] = blizzard_draw_fn_r_24; -+ break; -+ case 32: -+ s->line_fn_tab[0] = blizzard_draw_fn_32; -+ s->line_fn_tab[1] = blizzard_draw_fn_r_32; -+ break; -+ default: -+ fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__); -+ exit(1); -+ } -+ -+ blizzard_reset(s); -+ -+ graphic_console_init(s->state, blizzard_update_display, -+ blizzard_invalidate_display, blizzard_screen_dump, -+ NULL, s); -+ -+ return s; -+} -diff --git a/hw/blizzard_template.h b/hw/blizzard_template.h -new file mode 100644 -index 0000000..8c6451d ---- /dev/null -+++ b/hw/blizzard_template.h -@@ -0,0 +1,138 @@ -+/* -+ * QEMU Epson S1D13744/S1D13745 templates -+ * -+ * Copyright (C) 2008 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+#define SKIP_PIXEL(to) to += deststep -+#if DEPTH == 8 -+# define PIXEL_TYPE uint8_t -+# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to) -+# define COPY_PIXEL1(to, from) *to ++ = from -+#elif DEPTH == 15 || DEPTH == 16 -+# define PIXEL_TYPE uint16_t -+# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to) -+# define COPY_PIXEL1(to, from) *to ++ = from -+#elif DEPTH == 24 -+# define PIXEL_TYPE uint8_t -+# define COPY_PIXEL(to, from) \ -+ to[0] = from; to[1] = (from) >> 8; to[2] = (from) >> 16; SKIP_PIXEL(to) -+# define COPY_PIXEL1(to, from) \ -+ *to ++ = from; *to ++ = (from) >> 8; *to ++ = (from) >> 16 -+#elif DEPTH == 32 -+# define PIXEL_TYPE uint32_t -+# define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to) -+# define COPY_PIXEL1(to, from) *to ++ = from -+#else -+# error unknown bit depth -+#endif -+ -+#ifdef WORDS_BIGENDIAN -+# define SWAP_WORDS 1 -+#endif -+ -+static void glue(blizzard_draw_line16_, DEPTH)(PIXEL_TYPE *dest, -+ const uint16_t *src, unsigned int width) -+{ -+#if !defined(SWAP_WORDS) && DEPTH == 16 -+ memcpy(dest, src, width << 1); -+#else -+ uint16_t data; -+ unsigned int r, g, b; -+ const uint16_t *end = (void *) src + width; -+ while (src < end) { -+ data = lduw_raw(src ++); -+ b = (data & 0x1f) << 3; -+ data >>= 5; -+ g = (data & 0x3f) << 2; -+ data >>= 6; -+ r = (data & 0x1f) << 3; -+ data >>= 5; -+ COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); -+ } -+#endif -+} -+ -+static void glue(blizzard_draw_line24mode1_, DEPTH)(PIXEL_TYPE *dest, -+ const uint8_t *src, unsigned int width) -+{ -+ /* TODO: check if SDL 24-bit planes are not in the same format and -+ * if so, use memcpy */ -+ unsigned int r[2], g[2], b[2]; -+ const uint8_t *end = src + width; -+ while (src < end) { -+ g[0] = *src ++; -+ r[0] = *src ++; -+ r[1] = *src ++; -+ b[0] = *src ++; -+ COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[0], g[0], b[0])); -+ b[1] = *src ++; -+ g[1] = *src ++; -+ COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[1], g[1], b[1])); -+ } -+} -+ -+static void glue(blizzard_draw_line24mode2_, DEPTH)(PIXEL_TYPE *dest, -+ const uint8_t *src, unsigned int width) -+{ -+ unsigned int r, g, b; -+ const uint8_t *end = src + width; -+ while (src < end) { -+ r = *src ++; -+ src ++; -+ b = *src ++; -+ g = *src ++; -+ COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b)); -+ } -+} -+ -+/* No rotation */ -+static blizzard_fn_t glue(blizzard_draw_fn_, DEPTH)[0x10] = { -+ NULL, -+ /* RGB 5:6:5*/ -+ (blizzard_fn_t) glue(blizzard_draw_line16_, DEPTH), -+ /* RGB 6:6:6 mode 1 */ -+ (blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH), -+ /* RGB 8:8:8 mode 1 */ -+ (blizzard_fn_t) glue(blizzard_draw_line24mode1_, DEPTH), -+ NULL, NULL, -+ /* RGB 6:6:6 mode 2 */ -+ (blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH), -+ /* RGB 8:8:8 mode 2 */ -+ (blizzard_fn_t) glue(blizzard_draw_line24mode2_, DEPTH), -+ /* YUV 4:2:2 */ -+ NULL, -+ /* YUV 4:2:0 */ -+ NULL, -+ NULL, NULL, NULL, NULL, NULL, NULL, -+}; -+ -+/* 90deg, 180deg and 270deg rotation */ -+static blizzard_fn_t glue(blizzard_draw_fn_r_, DEPTH)[0x10] = { -+ /* TODO */ -+ [0 ... 0xf] = NULL, -+}; -+ -+#undef DEPTH -+#undef SKIP_PIXEL -+#undef COPY_PIXEL -+#undef COPY_PIXEL1 -+#undef PIXEL_TYPE -+ -+#undef SWAP_WORDS -diff --git a/hw/boards.h b/hw/boards.h -index affcaa6..408d1e8 100644 ---- a/hw/boards.h -+++ b/hw/boards.h -@@ -80,6 +80,9 @@ extern QEMUMachine terrierpda_machine; - /* palm.c */ - extern QEMUMachine palmte_machine; - -+/* nseries.c */ -+extern QEMUMachine n800_machine; -+ - /* gumstix.c */ - extern QEMUMachine connex_machine; - extern QEMUMachine verdex_machine; -diff --git a/hw/cbus.c b/hw/cbus.c -new file mode 100644 -index 0000000..001b007 ---- /dev/null -+++ b/hw/cbus.c -@@ -0,0 +1,565 @@ -+/* -+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma / -+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms. -+ * -+ * Copyright (C) 2008 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+#include "qemu-common.h" -+#include "irq.h" -+#include "devices.h" -+#include "sysemu.h" -+ -+//#define DEBUG -+ -+struct cbus_slave_s; -+struct cbus_priv_s { -+ struct cbus_s cbus; -+ -+ int sel; -+ int dat; -+ int clk; -+ int bit; -+ int dir; -+ uint16_t val; -+ qemu_irq dat_out; -+ -+ int addr; -+ int reg; -+ int rw; -+ enum { -+ cbus_address, -+ cbus_value, -+ } cycle; -+ -+ struct cbus_slave_s *slave[8]; -+}; -+ -+struct cbus_slave_s { -+ void *opaque; -+ void (*io)(void *opaque, int rw, int reg, uint16_t *val); -+ int addr; -+}; -+ -+static void cbus_io(struct cbus_priv_s *s) -+{ -+ if (s->slave[s->addr]) -+ s->slave[s->addr]->io(s->slave[s->addr]->opaque, -+ s->rw, s->reg, &s->val); -+ else -+ cpu_abort(cpu_single_env, "%s: bad slave address %i\n", -+ __FUNCTION__, s->addr); -+} -+ -+static void cbus_cycle(struct cbus_priv_s *s) -+{ -+ switch (s->cycle) { -+ case cbus_address: -+ s->addr = (s->val >> 6) & 7; -+ s->rw = (s->val >> 5) & 1; -+ s->reg = (s->val >> 0) & 0x1f; -+ -+ s->cycle = cbus_value; -+ s->bit = 15; -+ s->dir = !s->rw; -+ s->val = 0; -+ -+ if (s->rw) -+ cbus_io(s); -+ break; -+ -+ case cbus_value: -+ if (!s->rw) -+ cbus_io(s); -+ -+ s->cycle = cbus_address; -+ s->bit = 8; -+ s->dir = 1; -+ s->val = 0; -+ break; -+ } -+} -+ -+static void cbus_clk(void *opaque, int line, int level) -+{ -+ struct cbus_priv_s *s = (struct cbus_priv_s *) opaque; -+ -+ if (!s->sel && level && !s->clk) { -+ if (s->dir) -+ s->val |= s->dat << (s->bit --); -+ else -+ qemu_set_irq(s->dat_out, (s->val >> (s->bit --)) & 1); -+ -+ if (s->bit < 0) -+ cbus_cycle(s); -+ } -+ -+ s->clk = level; -+} -+ -+static void cbus_dat(void *opaque, int line, int level) -+{ -+ struct cbus_priv_s *s = (struct cbus_priv_s *) opaque; -+ -+ s->dat = level; -+} -+ -+static void cbus_sel(void *opaque, int line, int level) -+{ -+ struct cbus_priv_s *s = (struct cbus_priv_s *) opaque; -+ -+ if (!level) { -+ s->dir = 1; -+ s->bit = 8; -+ s->val = 0; -+ } -+ -+ s->sel = level; -+} -+ -+struct cbus_s *cbus_init(qemu_irq dat) -+{ -+ struct cbus_priv_s *s = (struct cbus_priv_s *) qemu_mallocz(sizeof(*s)); -+ -+ s->dat_out = dat; -+ s->cbus.clk = qemu_allocate_irqs(cbus_clk, s, 1)[0]; -+ s->cbus.dat = qemu_allocate_irqs(cbus_dat, s, 1)[0]; -+ s->cbus.sel = qemu_allocate_irqs(cbus_sel, s, 1)[0]; -+ -+ s->sel = 1; -+ s->clk = 0; -+ s->dat = 0; -+ -+ return &s->cbus; -+} -+ -+void cbus_attach(struct cbus_s *bus, void *slave_opaque) -+{ -+ struct cbus_slave_s *slave = (struct cbus_slave_s *) slave_opaque; -+ struct cbus_priv_s *s = (struct cbus_priv_s *) bus; -+ -+ s->slave[slave->addr] = slave; -+} -+ -+/* Retu/Vilma */ -+struct cbus_retu_s { -+ uint16_t irqst; -+ uint16_t irqen; -+ uint16_t cc[2]; -+ int channel; -+ uint16_t result[16]; -+ uint16_t sample; -+ -+ struct { -+ uint16_t cal; -+ } rtc; -+ -+ int is_vilma; -+ qemu_irq irq; -+ struct cbus_slave_s cbus; -+}; -+ -+static void retu_interrupt_update(struct cbus_retu_s *s) -+{ -+ qemu_set_irq(s->irq, s->irqst & ~s->irqen); -+} -+ -+#define RETU_REG_ASICR 0x00 /* (RO) ASIC ID & revision */ -+#define RETU_REG_IDR 0x01 /* (T) Interrupt ID */ -+#define RETU_REG_IMR 0x02 /* (RW) Interrupt mask */ -+#define RETU_REG_RTCDSR 0x03 /* (RW) RTC seconds register */ -+#define RETU_REG_RTCHMR 0x04 /* (RO) RTC hours and minutes reg */ -+#define RETU_REG_RTCHMAR 0x05 /* (RW) RTC hours and minutes set reg */ -+#define RETU_REG_RTCCALR 0x06 /* (RW) RTC calibration register */ -+#define RETU_REG_ADCR 0x08 /* (RW) ADC result register */ -+#define RETU_REG_ADCSCR 0x09 /* (RW) ADC sample control register */ -+#define RETU_REG_AFCR 0x0a /* (RW) AFC register */ -+#define RETU_REG_ANTIFR 0x0b /* (RW) AntiF register */ -+#define RETU_REG_CALIBR 0x0c /* (RW) CalibR register*/ -+#define RETU_REG_CCR1 0x0d /* (RW) Common control register 1 */ -+#define RETU_REG_CCR2 0x0e /* (RW) Common control register 2 */ -+#define RETU_REG_RCTRL_CLR 0x0f /* (T) Regulator clear register */ -+#define RETU_REG_RCTRL_SET 0x10 /* (T) Regulator set register */ -+#define RETU_REG_TXCR 0x11 /* (RW) TxC register */ -+#define RETU_REG_STATUS 0x16 /* (RO) Status register */ -+#define RETU_REG_WATCHDOG 0x17 /* (RW) Watchdog register */ -+#define RETU_REG_AUDTXR 0x18 /* (RW) Audio Codec Tx register */ -+#define RETU_REG_AUDPAR 0x19 /* (RW) AudioPA register */ -+#define RETU_REG_AUDRXR1 0x1a /* (RW) Audio receive register 1 */ -+#define RETU_REG_AUDRXR2 0x1b /* (RW) Autio receive register 2 */ -+#define RETU_REG_SGR1 0x1c /* (RW) */ -+#define RETU_REG_SCR1 0x1d /* (RW) */ -+#define RETU_REG_SGR2 0x1e /* (RW) */ -+#define RETU_REG_SCR2 0x1f /* (RW) */ -+ -+/* Retu Interrupt sources */ -+enum { -+ retu_int_pwr = 0, /* Power */ -+ retu_int_char = 1, /* Charger */ -+ retu_int_rtcs = 2, /* Seconds */ -+ retu_int_rtcm = 3, /* Minutes */ -+ retu_int_rtcd = 4, /* Days */ -+ retu_int_rtca = 5, /* Alarm */ -+ retu_int_hook = 6, /* Hook */ -+ retu_int_head = 7, /* Headset */ -+ retu_int_adcs = 8, /* ADC sample */ -+}; -+ -+/* Retu ADC channel wiring */ -+enum { -+ retu_adc_bsi = 1, /* BSI */ -+ retu_adc_batt_temp = 2, /* Battery temperature */ -+ retu_adc_chg_volt = 3, /* Charger voltage */ -+ retu_adc_head_det = 4, /* Headset detection */ -+ retu_adc_hook_det = 5, /* Hook detection */ -+ retu_adc_rf_gp = 6, /* RF GP */ -+ retu_adc_tx_det = 7, /* Wideband Tx detection */ -+ retu_adc_batt_volt = 8, /* Battery voltage */ -+ retu_adc_sens = 10, /* Light sensor */ -+ retu_adc_sens_temp = 11, /* Light sensor temperature */ -+ retu_adc_bbatt_volt = 12, /* Backup battery voltage */ -+ retu_adc_self_temp = 13, /* RETU temperature */ -+}; -+ -+static inline uint16_t retu_read(struct cbus_retu_s *s, int reg) -+{ -+#ifdef DEBUG -+ printf("RETU read at %02x\n", reg); -+#endif -+ -+ switch (reg) { -+ case RETU_REG_ASICR: -+ return 0x0015 | (s->is_vilma << 7); -+ -+ case RETU_REG_IDR: -+ return s->irqst; -+ -+ case RETU_REG_IMR: -+ return s->irqen; -+ -+ case RETU_REG_RTCDSR: -+ case RETU_REG_RTCHMR: -+ case RETU_REG_RTCHMAR: -+ /* TODO */ -+ return 0x0000; -+ -+ case RETU_REG_RTCCALR: -+ return s->rtc.cal; -+ -+ case RETU_REG_ADCR: -+ return (s->channel << 10) | s->result[s->channel]; -+ case RETU_REG_ADCSCR: -+ return s->sample; -+ -+ case RETU_REG_AFCR: -+ case RETU_REG_ANTIFR: -+ case RETU_REG_CALIBR: -+ /* TODO */ -+ return 0x0000; -+ -+ case RETU_REG_CCR1: -+ return s->cc[0]; -+ case RETU_REG_CCR2: -+ return s->cc[1]; -+ -+ case RETU_REG_RCTRL_CLR: -+ case RETU_REG_RCTRL_SET: -+ case RETU_REG_TXCR: -+ case RETU_REG_STATUS: -+ case RETU_REG_WATCHDOG: -+ case RETU_REG_AUDTXR: -+ case RETU_REG_AUDPAR: -+ case RETU_REG_AUDRXR1: -+ case RETU_REG_AUDRXR2: -+ case RETU_REG_SGR1: -+ case RETU_REG_SCR1: -+ case RETU_REG_SGR2: -+ case RETU_REG_SCR2: -+ /* TODO */ -+ return 0x0000; -+ -+ default: -+ cpu_abort(cpu_single_env, "%s: bad register %02x\n", -+ __FUNCTION__, reg); -+ } -+} -+ -+static inline void retu_write(struct cbus_retu_s *s, int reg, uint16_t val) -+{ -+#ifdef DEBUG -+ printf("RETU write of %04x at %02x\n", val, reg); -+#endif -+ -+ switch (reg) { -+ case RETU_REG_IDR: -+ s->irqst ^= val; -+ retu_interrupt_update(s); -+ break; -+ -+ case RETU_REG_IMR: -+ s->irqen = val; -+ retu_interrupt_update(s); -+ break; -+ -+ case RETU_REG_RTCDSR: -+ case RETU_REG_RTCHMAR: -+ /* TODO */ -+ break; -+ -+ case RETU_REG_RTCCALR: -+ s->rtc.cal = val; -+ break; -+ -+ case RETU_REG_ADCR: -+ s->channel = (val >> 10) & 0xf; -+ s->irqst |= 1 << retu_int_adcs; -+ retu_interrupt_update(s); -+ break; -+ case RETU_REG_ADCSCR: -+ s->sample &= ~val; -+ break; -+ -+ case RETU_REG_AFCR: -+ case RETU_REG_ANTIFR: -+ case RETU_REG_CALIBR: -+ -+ case RETU_REG_CCR1: -+ s->cc[0] = val; -+ break; -+ case RETU_REG_CCR2: -+ s->cc[1] = val; -+ -+ break; -+ case RETU_REG_RCTRL_CLR: -+ case RETU_REG_RCTRL_SET: -+ case RETU_REG_STATUS: -+ /* TODO */ -+ break; -+ -+ case RETU_REG_WATCHDOG: -+ if (val == 0 && (s->cc[0] & 2)) -+ qemu_system_shutdown_request(); -+ break; -+ -+ case RETU_REG_TXCR: -+ case RETU_REG_AUDTXR: -+ case RETU_REG_AUDPAR: -+ case RETU_REG_AUDRXR1: -+ case RETU_REG_AUDRXR2: -+ case RETU_REG_SGR1: -+ case RETU_REG_SCR1: -+ case RETU_REG_SGR2: -+ case RETU_REG_SCR2: -+ /* TODO */ -+ break; -+ -+ default: -+ cpu_abort(cpu_single_env, "%s: bad register %02x\n", -+ __FUNCTION__, reg); -+ } -+} -+ -+static void retu_io(void *opaque, int rw, int reg, uint16_t *val) -+{ -+ struct cbus_retu_s *s = (struct cbus_retu_s *) opaque; -+ -+ if (rw) -+ *val = retu_read(s, reg); -+ else -+ retu_write(s, reg, *val); -+} -+ -+void *retu_init(qemu_irq irq, int vilma) -+{ -+ struct cbus_retu_s *s = (struct cbus_retu_s *) qemu_mallocz(sizeof(*s)); -+ -+ s->irq = irq; -+ s->irqen = 0xffff; -+ s->irqst = 0x0000; -+ s->is_vilma = !!vilma; -+ s->rtc.cal = 0x01; -+ s->result[retu_adc_bsi] = 0x100; -+ s->result[retu_adc_batt_temp] = 0x100; -+ s->result[retu_adc_chg_volt] = 0x200; -+ s->result[retu_adc_batt_volt] = 0x240; -+ s->result[retu_adc_sens] = 0x100; -+ s->result[retu_adc_sens_temp] = 0x100; -+ s->result[retu_adc_bbatt_volt] = 0x200; -+ s->result[retu_adc_self_temp] = 0x100; -+ -+ s->cbus.opaque = s; -+ s->cbus.io = retu_io; -+ s->cbus.addr = 1; -+ -+ return &s->cbus; -+} -+ -+/* Tahvo/Betty */ -+struct cbus_tahvo_s { -+ uint16_t irqst; -+ uint16_t irqen; -+ uint8_t charger; -+ uint8_t backlight; -+ uint16_t usbr; -+ uint16_t power; -+ -+ int is_betty; -+ qemu_irq irq; -+ struct cbus_slave_s cbus; -+}; -+ -+static void tahvo_interrupt_update(struct cbus_tahvo_s *s) -+{ -+ qemu_set_irq(s->irq, s->irqst & ~s->irqen); -+} -+ -+#define TAHVO_REG_ASICR 0x00 /* (RO) ASIC ID & revision */ -+#define TAHVO_REG_IDR 0x01 /* (T) Interrupt ID */ -+#define TAHVO_REG_IDSR 0x02 /* (RO) Interrupt status */ -+#define TAHVO_REG_IMR 0x03 /* (RW) Interrupt mask */ -+#define TAHVO_REG_CHAPWMR 0x04 /* (RW) Charger PWM */ -+#define TAHVO_REG_LEDPWMR 0x05 /* (RW) LED PWM */ -+#define TAHVO_REG_USBR 0x06 /* (RW) USB control */ -+#define TAHVO_REG_RCR 0x07 /* (RW) Some kind of power management */ -+#define TAHVO_REG_CCR1 0x08 /* (RW) Common control register 1 */ -+#define TAHVO_REG_CCR2 0x09 /* (RW) Common control register 2 */ -+#define TAHVO_REG_TESTR1 0x0a /* (RW) Test register 1 */ -+#define TAHVO_REG_TESTR2 0x0b /* (RW) Test register 2 */ -+#define TAHVO_REG_NOPR 0x0c /* (RW) Number of periods */ -+#define TAHVO_REG_FRR 0x0d /* (RO) FR */ -+ -+static inline uint16_t tahvo_read(struct cbus_tahvo_s *s, int reg) -+{ -+#ifdef DEBUG -+ printf("TAHVO read at %02x\n", reg); -+#endif -+ -+ switch (reg) { -+ case TAHVO_REG_ASICR: -+ return 0x0021 | (s->is_betty ? 0x0b00 : 0x0300); -+ -+ case TAHVO_REG_IDR: -+ case TAHVO_REG_IDSR: /* XXX: what does this do? */ -+ return s->irqst; -+ -+ case TAHVO_REG_IMR: -+ return s->irqen; -+ -+ case TAHVO_REG_CHAPWMR: -+ return s->charger; -+ -+ case TAHVO_REG_LEDPWMR: -+ return s->backlight; -+ -+ case TAHVO_REG_USBR: -+ return s->usbr; -+ -+ case TAHVO_REG_RCR: -+ return s->power; -+ -+ case TAHVO_REG_CCR1: -+ case TAHVO_REG_CCR2: -+ case TAHVO_REG_TESTR1: -+ case TAHVO_REG_TESTR2: -+ case TAHVO_REG_NOPR: -+ case TAHVO_REG_FRR: -+ return 0x0000; -+ -+ default: -+ cpu_abort(cpu_single_env, "%s: bad register %02x\n", -+ __FUNCTION__, reg); -+ } -+} -+ -+static inline void tahvo_write(struct cbus_tahvo_s *s, int reg, uint16_t val) -+{ -+#ifdef DEBUG -+ printf("TAHVO write of %04x at %02x\n", val, reg); -+#endif -+ -+ switch (reg) { -+ case TAHVO_REG_IDR: -+ s->irqst ^= val; -+ tahvo_interrupt_update(s); -+ break; -+ -+ case TAHVO_REG_IMR: -+ s->irqen = val; -+ tahvo_interrupt_update(s); -+ break; -+ -+ case TAHVO_REG_CHAPWMR: -+ s->charger = val; -+ break; -+ -+ case TAHVO_REG_LEDPWMR: -+ if (s->backlight != (val & 0x7f)) { -+ s->backlight = val & 0x7f; -+ printf("%s: LCD backlight now at %i / 127\n", -+ __FUNCTION__, s->backlight); -+ } -+ break; -+ -+ case TAHVO_REG_USBR: -+ s->usbr = val; -+ break; -+ -+ case TAHVO_REG_RCR: -+ s->power = val; -+ break; -+ -+ case TAHVO_REG_CCR1: -+ case TAHVO_REG_CCR2: -+ case TAHVO_REG_TESTR1: -+ case TAHVO_REG_TESTR2: -+ case TAHVO_REG_NOPR: -+ case TAHVO_REG_FRR: -+ break; -+ -+ default: -+ cpu_abort(cpu_single_env, "%s: bad register %02x\n", -+ __FUNCTION__, reg); -+ } -+} -+ -+static void tahvo_io(void *opaque, int rw, int reg, uint16_t *val) -+{ -+ struct cbus_tahvo_s *s = (struct cbus_tahvo_s *) opaque; -+ -+ if (rw) -+ *val = tahvo_read(s, reg); -+ else -+ tahvo_write(s, reg, *val); -+} -+ -+void *tahvo_init(qemu_irq irq, int betty) -+{ -+ struct cbus_tahvo_s *s = (struct cbus_tahvo_s *) qemu_mallocz(sizeof(*s)); -+ -+ s->irq = irq; -+ s->irqen = 0xffff; -+ s->irqst = 0x0000; -+ s->is_betty = !!betty; -+ -+ s->cbus.opaque = s; -+ s->cbus.io = tahvo_io; -+ s->cbus.addr = 2; -+ -+ return &s->cbus; -+} -diff --git a/hw/devices.h b/hw/devices.h -index 07c673b..6f1d27b 100644 ---- a/hw/devices.h -+++ b/hw/devices.h -@@ -16,7 +16,38 @@ uint32_t ads7846_read(void *opaque); - void ads7846_write(void *opaque, uint32_t value); - struct ads7846_state_s *ads7846_init(qemu_irq penirq); - -+/* tsc210x.c */ -+struct uwire_slave_s; -+struct mouse_transform_info_s; -+struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio); -+struct uwire_slave_s *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, -+ qemu_irq dav, AudioState *audio); -+struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip); -+uint32_t tsc210x_txrx(void *opaque, uint32_t value); -+void tsc210x_set_transform(struct uwire_slave_s *chip, -+ struct mouse_transform_info_s *info); -+void tsc210x_key_event(struct uwire_slave_s *chip, int key, int down); -+ - /* stellaris_input.c */ - void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode); - -+/* blizzard.c */ -+void *s1d13745_init(qemu_irq gpio_int, DisplayState *ds); -+void s1d13745_write(void *opaque, int dc, uint16_t value); -+void s1d13745_write_block(void *opaque, int dc, -+ void *buf, size_t len, int pitch); -+uint16_t s1d13745_read(void *opaque, int dc); -+ -+/* cbus.c */ -+struct cbus_s { -+ qemu_irq clk; -+ qemu_irq dat; -+ qemu_irq sel; -+}; -+struct cbus_s *cbus_init(qemu_irq dat_out); -+void cbus_attach(struct cbus_s *bus, void *slave_opaque); -+ -+void *retu_init(qemu_irq irq, int vilma); -+void *tahvo_init(qemu_irq irq, int betty); -+ - #endif -diff --git a/hw/flash.h b/hw/flash.h -index 42d25fe..c000d33 100644 ---- a/hw/flash.h -+++ b/hw/flash.h -@@ -34,6 +34,11 @@ uint8_t nand_getio(struct nand_flash_s *s); - #define NAND_MFR_HYNIX 0xad - #define NAND_MFR_MICRON 0x2c - -+/* onenand.c */ -+void onenand_base_update(void *opaque, target_phys_addr_t new); -+void onenand_base_unmap(void *opaque); -+void *onenand_init(uint32_t id, int regshift, qemu_irq irq); -+ - /* ecc.c */ - struct ecc_state_s { - uint8_t cp; /* Column parity */ -diff --git a/hw/i2c.h b/hw/i2c.h -index 2897036..fae46b7 100644 ---- a/hw/i2c.h -+++ b/hw/i2c.h -@@ -71,4 +71,14 @@ uint32_t wm8750_adc_dat(void *opaque); - /* ssd0303.c */ - void ssd0303_init(DisplayState *ds, i2c_bus *bus, int address); - -+/* twl92230.c */ -+i2c_slave *twl92230_init(i2c_bus *bus, qemu_irq irq); -+qemu_irq *twl92230_gpio_in_get(i2c_slave *i2c); -+void twl92230_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler); -+ -+/* tmp105.c */ -+struct i2c_slave *tmp105_init(i2c_bus *bus, qemu_irq alarm); -+void tmp105_reset(i2c_slave *i2c); -+void tmp105_set(i2c_slave *i2c, int temp); -+ - #endif -diff --git a/hw/integratorcp.c b/hw/integratorcp.c -index 549cc25..f6e6364 100644 ---- a/hw/integratorcp.c -+++ b/hw/integratorcp.c -@@ -469,6 +469,11 @@ static void icp_control_init(uint32_t base) - - /* Board init. */ - -+static struct arm_boot_info integrator_binfo = { -+ .loader_start = 0x0, -+ .board_id = 0x113, -+}; -+ - static void integratorcp_init(int ram_size, int vga_ram_size, - const char *boot_device, DisplayState *ds, - const char *kernel_filename, const char *kernel_cmdline, -@@ -527,8 +532,11 @@ static void integratorcp_init(int ram_size, int vga_ram_size, - } - pl110_init(ds, 0xc0000000, pic[22], 0); - -- arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, -- initrd_filename, 0x113, 0x0); -+ integrator_binfo.ram_size = ram_size; -+ integrator_binfo.kernel_filename = kernel_filename; -+ integrator_binfo.kernel_cmdline = kernel_cmdline; -+ integrator_binfo.initrd_filename = initrd_filename; -+ arm_load_kernel(env, &integrator_binfo); - } - - QEMUMachine integratorcp_machine = { -diff --git a/hw/mainstone.c b/hw/mainstone.c -index 5856791..9564fc3 100644 ---- a/hw/mainstone.c -+++ b/hw/mainstone.c -@@ -59,12 +59,17 @@ static struct keymap map[0xE0] = { - - enum mainstone_model_e { mainstone }; - -+static struct arm_boot_info mainstone_binfo = { -+ .loader_start = PXA2XX_SDRAM_BASE, -+ .ram_size = 0x04000000, -+}; -+ - static void mainstone_common_init(int ram_size, int vga_ram_size, - DisplayState *ds, const char *kernel_filename, - const char *kernel_cmdline, const char *initrd_filename, - const char *cpu_model, enum mainstone_model_e model, int arm_id) - { -- uint32_t mainstone_ram = 0x04000000; -+ uint32_t mainstone_ram = mainstone_binfo.ram_size; - uint32_t mainstone_rom = 0x00800000; - uint32_t mainstone_flash = 0x02000000; - uint32_t sector_len = 256 * 1024; -@@ -90,7 +95,7 @@ static void mainstone_common_init(int ram_size, int vga_ram_size, - qemu_ram_alloc(mainstone_rom) | IO_MEM_ROM); - - /* Setup initial (reset) machine state */ -- cpu->env->regs[15] = PXA2XX_SDRAM_BASE; -+ cpu->env->regs[15] = mainstone_binfo.loader_start; - - /* There are two 32MiB flash devices on the board */ - for (i = 0; i < 2; i ++) { -@@ -121,8 +126,11 @@ static void mainstone_common_init(int ram_size, int vga_ram_size, - - smc91c111_init(&nd_table[0], MST_ETH_PHYS, mst_irq[ETHERNET_IRQ]); - -- arm_load_kernel(cpu->env, mainstone_ram, kernel_filename, kernel_cmdline, -- initrd_filename, arm_id, PXA2XX_SDRAM_BASE); -+ mainstone_binfo.kernel_filename = kernel_filename; -+ mainstone_binfo.kernel_cmdline = kernel_cmdline; -+ mainstone_binfo.initrd_filename = initrd_filename; -+ mainstone_binfo.board_id = arm_id; -+ arm_load_kernel(cpu->env, &mainstone_binfo); - } - - static void mainstone_init(int ram_size, int vga_ram_size, -diff --git a/hw/max7310.c b/hw/max7310.c -index 75e56c7..397950a 100644 ---- a/hw/max7310.c -+++ b/hw/max7310.c -@@ -134,8 +134,8 @@ static void max7310_event(i2c_slave *i2c, enum i2c_event event) - s->i2c_command_byte = 1; - break; - case I2C_FINISH: -- if (s->len == 1) - #ifdef VERBOSE -+ if (s->len == 1) - printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len); - #endif - break; -diff --git a/hw/nseries.c b/hw/nseries.c -new file mode 100644 -index 0000000..0425d46 ---- /dev/null -+++ b/hw/nseries.c -@@ -0,0 +1,870 @@ -+/* -+ * Nokia N-series internet tablets. -+ * -+ * Copyright (C) 2007 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+#include "qemu-common.h" -+#include "sysemu.h" -+#include "omap.h" -+#include "arm-misc.h" -+#include "irq.h" -+#include "console.h" -+#include "boards.h" -+#include "i2c.h" -+#include "devices.h" -+#include "flash.h" -+#include "hw.h" -+ -+/* Nokia N800 support */ -+struct n800_s { -+ struct omap_mpu_state_s *cpu; -+ -+ struct rfbi_chip_s blizzard; -+ struct uwire_slave_s *ts; -+ i2c_bus *i2c; -+ -+ int keymap[0x80]; -+}; -+ -+#define N800_MMC2_WP_GPIO 8 -+#define N800_CAM_TURN_GPIO 12 -+#define N800_BLIZZARD_POWERDOWN_GPIO 15 -+#define N800_MMC1_WP_GPIO 23 -+#define N800_ONENAND_GPIO 26 -+#define N800_BT_WKUP_GPIO 61 -+#define N800_STI_GPIO 62 -+#define N800_CBUS_SEL_GPIO 64 -+#define N800_CBUS_CLK_GPIO 65 -+#define N800_CBUS_DAT_GPIO 66 -+#define N800_WLAN_IRQ_GPIO 87 -+#define N800_BT_RESET_GPIO 92 -+#define N800_TEA5761_CS_GPIO 93 -+#define N800_UNKNOWN_GPIO 94 -+#define N800_CAM_ACT_GPIO 95 -+#define N800_MMC_CS_GPIO 96 -+#define N800_WLAN_PWR_GPIO 97 -+#define N800_BT_HOST_WKUP_GPIO 98 -+#define N800_TSC_TS_GPIO 103 -+#define N800_HEADPHONE_GPIO 107 -+#define N800_RETU_GPIO 108 -+#define N800_TSC_KP_IRQ_GPIO 109 -+#define N800_BAT_COVER_GPIO 110 -+#define N800_TAHVO_GPIO 111 -+#define N800_TSC_RESET_GPIO 119 -+#define N800_TMP105_GPIO 125 -+ -+#define XLDR_LL_UART 1 -+ -+#define N800_TMP105_ADDR 0x48 -+#define N800_MENELAUS_ADDR 0x72 -+ -+static void n800_mmc_cs_cb(void *opaque, int line, int level) -+{ -+ /* TODO: this seems to actually be connected to the menelaus, to -+ * which also both MMC slots connect. */ -+ omap_mmc_enable((struct omap_mmc_s *) opaque, !level); -+ -+ printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1); -+} -+ -+static void n800_gpio_setup(struct n800_s *s) -+{ -+ qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1); -+ omap2_gpio_out_set(s->cpu->gpif, N800_MMC_CS_GPIO, mmc_cs[0]); -+ -+ qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]); -+} -+ -+static void n800_nand_setup(struct n800_s *s) -+{ -+ /* Either ec40xx or ec48xx are OK for the ID */ -+ omap_gpmc_attach(s->cpu->gpmc, 0, 0, onenand_base_update, -+ onenand_base_unmap, -+ onenand_init(0xec4800, 1, -+ omap2_gpio_in_get(s->cpu->gpif, -+ N800_ONENAND_GPIO)[0])); -+} -+ -+static void n800_i2c_setup(struct n800_s *s) -+{ -+ qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N800_TMP105_GPIO)[0]; -+ -+ /* Attach the CPU on one end of our I2C bus. */ -+ s->i2c = omap_i2c_bus(s->cpu->i2c[0]); -+ -+ /* Attach a menelaus PM chip */ -+ i2c_set_slave_address( -+ twl92230_init(s->i2c, -+ s->cpu->irq[0][OMAP_INT_24XX_SYS_NIRQ]), -+ N800_MENELAUS_ADDR); -+ -+ /* Attach a TMP105 PM chip (A0 wired to ground) */ -+ i2c_set_slave_address(tmp105_init(s->i2c, tmp_irq), N800_TMP105_ADDR); -+} -+ -+/* Touchscreen and keypad controller */ -+static void n800_key_event(void *opaque, int keycode) -+{ -+ struct n800_s *s = (struct n800_s *) opaque; -+ int code = s->keymap[keycode & 0x7f]; -+ -+ if (code == -1) -+ return; -+ -+ tsc210x_key_event(s->ts, code, !(keycode & 0x80)); -+} -+ -+static const int n800_keys[16] = { -+ -1, -+ 72, /* Up */ -+ 63, /* Home (F5) */ -+ -1, -+ 75, /* Left */ -+ 28, /* Enter */ -+ 77, /* Right */ -+ -1, -+ 1, /* Cycle (ESC) */ -+ 80, /* Down */ -+ 62, /* Menu (F4) */ -+ -1, -+ 66, /* Zoom- (F8) */ -+ 64, /* FS (F6) */ -+ 65, /* Zoom+ (F7) */ -+ -1, -+}; -+ -+static struct mouse_transform_info_s n800_pointercal = { -+ .x = 800, -+ .y = 480, -+ .a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 }, -+}; -+ -+static void n800_tsc_setup(struct n800_s *s) -+{ -+ int i; -+ -+ /* XXX: are the three pins inverted inside the chip between the -+ * tsc and the cpu (N4111)? */ -+ qemu_irq penirq = 0; /* NC */ -+ qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0]; -+ qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0]; -+ -+ s->ts = tsc2301_init(penirq, kbirq, dav, 0); -+ -+ for (i = 0; i < 0x80; i ++) -+ s->keymap[i] = -1; -+ for (i = 0; i < 0x10; i ++) -+ if (n800_keys[i] >= 0) -+ s->keymap[n800_keys[i]] = i; -+ -+ qemu_add_kbd_event_handler(n800_key_event, s); -+ -+ tsc210x_set_transform(s->ts, &n800_pointercal); -+} -+ -+/* LCD MIPI DBI-C controller (URAL) */ -+struct mipid_s { -+ int resp[4]; -+ int param[4]; -+ int p; -+ int pm; -+ int cmd; -+ -+ int sleep; -+ int booster; -+ int te; -+ int selfcheck; -+ int partial; -+ int normal; -+ int vscr; -+ int invert; -+ int onoff; -+ int gamma; -+ uint32_t id; -+}; -+ -+static void mipid_reset(struct mipid_s *s) -+{ -+ if (!s->sleep) -+ fprintf(stderr, "%s: Display off\n", __FUNCTION__); -+ -+ s->pm = 0; -+ s->cmd = 0; -+ -+ s->sleep = 1; -+ s->booster = 0; -+ s->selfcheck = -+ (1 << 7) | /* Register loading OK. */ -+ (1 << 5) | /* The chip is attached. */ -+ (1 << 4); /* Display glass still in one piece. */ -+ s->te = 0; -+ s->partial = 0; -+ s->normal = 1; -+ s->vscr = 0; -+ s->invert = 0; -+ s->onoff = 1; -+ s->gamma = 0; -+} -+ -+static uint32_t mipid_txrx(void *opaque, uint32_t cmd) -+{ -+ struct mipid_s *s = (struct mipid_s *) opaque; -+ uint8_t ret; -+ -+ if (s->p >= sizeof(s->resp) / sizeof(*s->resp)) -+ ret = 0; -+ else -+ ret = s->resp[s->p ++]; -+ if (s->pm --> 0) -+ s->param[s->pm] = cmd; -+ else -+ s->cmd = cmd; -+ -+ switch (s->cmd) { -+ case 0x00: /* NOP */ -+ break; -+ -+ case 0x01: /* SWRESET */ -+ mipid_reset(s); -+ break; -+ -+ case 0x02: /* BSTROFF */ -+ s->booster = 0; -+ break; -+ case 0x03: /* BSTRON */ -+ s->booster = 1; -+ break; -+ -+ case 0x04: /* RDDID */ -+ s->p = 0; -+ s->resp[0] = (s->id >> 16) & 0xff; -+ s->resp[1] = (s->id >> 8) & 0xff; -+ s->resp[2] = (s->id >> 0) & 0xff; -+ break; -+ -+ case 0x06: /* RD_RED */ -+ case 0x07: /* RD_GREEN */ -+ /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so -+ * for the bootloader one needs to change this. */ -+ case 0x08: /* RD_BLUE */ -+ s->p = 0; -+ /* TODO: return first pixel components */ -+ s->resp[0] = 0x01; -+ break; -+ -+ case 0x09: /* RDDST */ -+ s->p = 0; -+ s->resp[0] = s->booster << 7; -+ s->resp[1] = (5 << 4) | (s->partial << 2) | -+ (s->sleep << 1) | s->normal; -+ s->resp[2] = (s->vscr << 7) | (s->invert << 5) | -+ (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2); -+ s->resp[3] = s->gamma << 6; -+ break; -+ -+ case 0x0a: /* RDDPM */ -+ s->p = 0; -+ s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) | -+ (s->partial << 5) | (s->sleep << 6) | (s->booster << 7); -+ break; -+ case 0x0b: /* RDDMADCTR */ -+ s->p = 0; -+ s->resp[0] = 0; -+ break; -+ case 0x0c: /* RDDCOLMOD */ -+ s->p = 0; -+ s->resp[0] = 5; /* 65K colours */ -+ break; -+ case 0x0d: /* RDDIM */ -+ s->p = 0; -+ s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma; -+ break; -+ case 0x0e: /* RDDSM */ -+ s->p = 0; -+ s->resp[0] = s->te << 7; -+ break; -+ case 0x0f: /* RDDSDR */ -+ s->p = 0; -+ s->resp[0] = s->selfcheck; -+ break; -+ -+ case 0x10: /* SLPIN */ -+ s->sleep = 1; -+ break; -+ case 0x11: /* SLPOUT */ -+ s->sleep = 0; -+ s->selfcheck ^= 1 << 6; /* POFF self-diagnosis Ok */ -+ break; -+ -+ case 0x12: /* PTLON */ -+ s->partial = 1; -+ s->normal = 0; -+ s->vscr = 0; -+ break; -+ case 0x13: /* NORON */ -+ s->partial = 0; -+ s->normal = 1; -+ s->vscr = 0; -+ break; -+ -+ case 0x20: /* INVOFF */ -+ s->invert = 0; -+ break; -+ case 0x21: /* INVON */ -+ s->invert = 1; -+ break; -+ -+ case 0x22: /* APOFF */ -+ case 0x23: /* APON */ -+ goto bad_cmd; -+ -+ case 0x25: /* WRCNTR */ -+ if (s->pm < 0) -+ s->pm = 1; -+ goto bad_cmd; -+ -+ case 0x26: /* GAMSET */ -+ if (!s->pm) -+ s->gamma = ffs(s->param[0] & 0xf) - 1; -+ else if (s->pm < 0) -+ s->pm = 1; -+ break; -+ -+ case 0x28: /* DISPOFF */ -+ s->onoff = 0; -+ fprintf(stderr, "%s: Display off\n", __FUNCTION__); -+ break; -+ case 0x29: /* DISPON */ -+ s->onoff = 1; -+ fprintf(stderr, "%s: Display on\n", __FUNCTION__); -+ break; -+ -+ case 0x2a: /* CASET */ -+ case 0x2b: /* RASET */ -+ case 0x2c: /* RAMWR */ -+ case 0x2d: /* RGBSET */ -+ case 0x2e: /* RAMRD */ -+ case 0x30: /* PTLAR */ -+ case 0x33: /* SCRLAR */ -+ goto bad_cmd; -+ -+ case 0x34: /* TEOFF */ -+ s->te = 0; -+ break; -+ case 0x35: /* TEON */ -+ if (!s->pm) -+ s->te = 1; -+ else if (s->pm < 0) -+ s->pm = 1; -+ break; -+ -+ case 0x36: /* MADCTR */ -+ goto bad_cmd; -+ -+ case 0x37: /* VSCSAD */ -+ s->partial = 0; -+ s->normal = 0; -+ s->vscr = 1; -+ break; -+ -+ case 0x38: /* IDMOFF */ -+ case 0x39: /* IDMON */ -+ case 0x3a: /* COLMOD */ -+ goto bad_cmd; -+ -+ case 0xb0: /* CLKINT / DISCTL */ -+ case 0xb1: /* CLKEXT */ -+ if (s->pm < 0) -+ s->pm = 2; -+ break; -+ -+ case 0xb4: /* FRMSEL */ -+ break; -+ -+ case 0xb5: /* FRM8SEL */ -+ case 0xb6: /* TMPRNG / INIESC */ -+ case 0xb7: /* TMPHIS / NOP2 */ -+ case 0xb8: /* TMPREAD / MADCTL */ -+ case 0xba: /* DISTCTR */ -+ case 0xbb: /* EPVOL */ -+ goto bad_cmd; -+ -+ case 0xbd: /* Unknown */ -+ s->p = 0; -+ s->resp[0] = 0; -+ s->resp[1] = 1; -+ break; -+ -+ case 0xc2: /* IFMOD */ -+ if (s->pm < 0) -+ s->pm = 2; -+ break; -+ -+ case 0xc6: /* PWRCTL */ -+ case 0xc7: /* PPWRCTL */ -+ case 0xd0: /* EPWROUT */ -+ case 0xd1: /* EPWRIN */ -+ case 0xd4: /* RDEV */ -+ case 0xd5: /* RDRR */ -+ goto bad_cmd; -+ -+ case 0xda: /* RDID1 */ -+ s->p = 0; -+ s->resp[0] = (s->id >> 16) & 0xff; -+ break; -+ case 0xdb: /* RDID2 */ -+ s->p = 0; -+ s->resp[0] = (s->id >> 8) & 0xff; -+ break; -+ case 0xdc: /* RDID3 */ -+ s->p = 0; -+ s->resp[0] = (s->id >> 0) & 0xff; -+ break; -+ -+ default: -+ bad_cmd: -+ fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, s->cmd); -+ break; -+ } -+ -+ return ret; -+} -+ -+static void *mipid_init(void) -+{ -+ struct mipid_s *s = (struct mipid_s *) qemu_mallocz(sizeof(*s)); -+ -+ s->id = 0x838f03; -+ mipid_reset(s); -+ -+ return s; -+} -+ -+static void n800_spi_setup(struct n800_s *s) -+{ -+ void *tsc2301 = s->ts->opaque; -+ void *mipid = mipid_init(); -+ -+ omap_mcspi_attach(s->cpu->mcspi[0], tsc210x_txrx, tsc2301, 0); -+ omap_mcspi_attach(s->cpu->mcspi[0], mipid_txrx, mipid, 1); -+} -+ -+/* This task is normally performed by the bootloader. If we're loading -+ * a kernel directly, we need to enable the Blizzard ourselves. */ -+static void n800_dss_init(struct rfbi_chip_s *chip) -+{ -+ chip->write(chip->opaque, 0, 0x2a); /* LCD Width register */ -+ chip->write(chip->opaque, 1, 0x64); -+ chip->write(chip->opaque, 0, 0x2c); /* LCD HNDP register */ -+ chip->write(chip->opaque, 1, 0x1e); -+ chip->write(chip->opaque, 0, 0x2e); /* LCD Height 0 register */ -+ chip->write(chip->opaque, 1, 0xe0); -+ chip->write(chip->opaque, 0, 0x30); /* LCD Height 1 register */ -+ chip->write(chip->opaque, 1, 0x01); -+ chip->write(chip->opaque, 0, 0x32); /* LCD VNDP register */ -+ chip->write(chip->opaque, 1, 0x06); -+ chip->write(chip->opaque, 0, 0x68); /* Display Mode register */ -+ chip->write(chip->opaque, 1, 1); /* Enable bit */ -+} -+ -+static void n800_dss_setup(struct n800_s *s, DisplayState *ds) -+{ -+ s->blizzard.opaque = s1d13745_init(0, ds); -+ s->blizzard.block = s1d13745_write_block; -+ s->blizzard.write = s1d13745_write; -+ s->blizzard.read = s1d13745_read; -+ -+ omap_rfbi_attach(s->cpu->dss, 0, &s->blizzard); -+} -+ -+static void n800_cbus_setup(struct n800_s *s) -+{ -+ qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N800_CBUS_DAT_GPIO)[0]; -+ qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N800_RETU_GPIO)[0]; -+ qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N800_TAHVO_GPIO)[0]; -+ -+ struct cbus_s *cbus = cbus_init(dat_out); -+ -+ omap2_gpio_out_set(s->cpu->gpif, N800_CBUS_CLK_GPIO, cbus->clk); -+ omap2_gpio_out_set(s->cpu->gpif, N800_CBUS_DAT_GPIO, cbus->dat); -+ omap2_gpio_out_set(s->cpu->gpif, N800_CBUS_SEL_GPIO, cbus->sel); -+ -+ cbus_attach(cbus, retu_init(retu_irq, 1)); -+ cbus_attach(cbus, tahvo_init(tahvo_irq, 1)); -+} -+ -+/* This task is normally performed by the bootloader. If we're loading -+ * a kernel directly, we need to set up GPMC mappings ourselves. */ -+static void n800_gpmc_init(struct n800_s *s) -+{ -+ uint32_t config7 = -+ (0xf << 8) | /* MASKADDRESS */ -+ (1 << 6) | /* CSVALID */ -+ (4 << 0); /* BASEADDRESS */ -+ -+ cpu_physical_memory_write(0x6800a078, /* GPMC_CONFIG7_0 */ -+ (void *) &config7, sizeof(config7)); -+} -+ -+#if 0 -+static uint32_t n800_pinout[104] = { -+ 0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0, -+ 0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808, -+ 0x08080808, 0x180800c4, 0x00b80000, 0x08080808, -+ 0x080800bc, 0x00cc0808, 0x08081818, 0x18180128, -+ 0x01241800, 0x18181818, 0x000000f0, 0x01300000, -+ 0x00001b0b, 0x1b0f0138, 0x00e0181b, 0x1b031b0b, -+ 0x180f0078, 0x00740018, 0x0f0f0f1a, 0x00000080, -+ 0x007c0000, 0x00000000, 0x00000088, 0x00840000, -+ 0x00000000, 0x00000094, 0x00980300, 0x0f180003, -+ 0x0000008c, 0x00900f0f, 0x0f0f1b00, 0x0f00009c, -+ 0x01140000, 0x1b1b0f18, 0x0818013c, 0x01400008, -+ 0x00001818, 0x000b0110, 0x010c1800, 0x0b030b0f, -+ 0x181800f4, 0x00f81818, 0x00000018, 0x000000fc, -+ 0x00401808, 0x00000000, 0x0f1b0030, 0x003c0008, -+ 0x00000000, 0x00000038, 0x00340000, 0x00000000, -+ 0x1a080070, 0x00641a1a, 0x08080808, 0x08080060, -+ 0x005c0808, 0x08080808, 0x08080058, 0x00540808, -+ 0x08080808, 0x0808006c, 0x00680808, 0x08080808, -+ 0x000000a8, 0x00b00000, 0x08080808, 0x000000a0, -+ 0x00a40000, 0x00000000, 0x08ff0050, 0x004c0808, -+ 0xffffffff, 0xffff0048, 0x0044ffff, 0xffffffff, -+ 0x000000ac, 0x01040800, 0x08080b0f, 0x18180100, -+ 0x01081818, 0x0b0b1808, 0x1a0300e4, 0x012c0b1a, -+ 0x02020018, 0x0b000134, 0x011c0800, 0x0b1b1b00, -+ 0x0f0000c8, 0x00ec181b, 0x000f0f02, 0x00180118, -+ 0x01200000, 0x0f0b1b1b, 0x0f0200e8, 0x0000020b, -+}; -+#endif -+ -+/* Setup sequence done by the bootloader */ -+static void n800_boot_init(void *opaque) -+{ -+ struct n800_s *s = (struct n800_s *) opaque; -+ uint32_t buf; -+ -+ /* PRCM setup */ -+#define omap_writel(addr, val) \ -+ buf = (val); \ -+ cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf)) -+ -+ omap_writel(0x48008060, 0x41); /* PRCM_CLKSRC_CTRL */ -+ omap_writel(0x48008070, 1); /* PRCM_CLKOUT_CTRL */ -+ omap_writel(0x48008078, 0); /* PRCM_CLKEMUL_CTRL */ -+ omap_writel(0x48008090, 0); /* PRCM_VOLTSETUP */ -+ omap_writel(0x48008094, 0); /* PRCM_CLKSSETUP */ -+ omap_writel(0x48008098, 0); /* PRCM_POLCTRL */ -+ omap_writel(0x48008140, 2); /* CM_CLKSEL_MPU */ -+ omap_writel(0x48008148, 0); /* CM_CLKSTCTRL_MPU */ -+ omap_writel(0x48008158, 1); /* RM_RSTST_MPU */ -+ omap_writel(0x480081c8, 0x15); /* PM_WKDEP_MPU */ -+ omap_writel(0x480081d4, 0x1d4); /* PM_EVGENCTRL_MPU */ -+ omap_writel(0x480081d8, 0); /* PM_EVEGENONTIM_MPU */ -+ omap_writel(0x480081dc, 0); /* PM_EVEGENOFFTIM_MPU */ -+ omap_writel(0x480081e0, 0xc); /* PM_PWSTCTRL_MPU */ -+ omap_writel(0x48008200, 0x047e7ff7); /* CM_FCLKEN1_CORE */ -+ omap_writel(0x48008204, 0x00000004); /* CM_FCLKEN2_CORE */ -+ omap_writel(0x48008210, 0x047e7ff1); /* CM_ICLKEN1_CORE */ -+ omap_writel(0x48008214, 0x00000004); /* CM_ICLKEN2_CORE */ -+ omap_writel(0x4800821c, 0x00000000); /* CM_ICLKEN4_CORE */ -+ omap_writel(0x48008230, 0); /* CM_AUTOIDLE1_CORE */ -+ omap_writel(0x48008234, 0); /* CM_AUTOIDLE2_CORE */ -+ omap_writel(0x48008238, 7); /* CM_AUTOIDLE3_CORE */ -+ omap_writel(0x4800823c, 0); /* CM_AUTOIDLE4_CORE */ -+ omap_writel(0x48008240, 0x04360626); /* CM_CLKSEL1_CORE */ -+ omap_writel(0x48008244, 0x00000014); /* CM_CLKSEL2_CORE */ -+ omap_writel(0x48008248, 0); /* CM_CLKSTCTRL_CORE */ -+ omap_writel(0x48008300, 0x00000000); /* CM_FCLKEN_GFX */ -+ omap_writel(0x48008310, 0x00000000); /* CM_ICLKEN_GFX */ -+ omap_writel(0x48008340, 0x00000001); /* CM_CLKSEL_GFX */ -+ omap_writel(0x48008400, 0x00000004); /* CM_FCLKEN_WKUP */ -+ omap_writel(0x48008410, 0x00000004); /* CM_ICLKEN_WKUP */ -+ omap_writel(0x48008440, 0x00000000); /* CM_CLKSEL_WKUP */ -+ omap_writel(0x48008500, 0x000000cf); /* CM_CLKEN_PLL */ -+ omap_writel(0x48008530, 0x0000000c); /* CM_AUTOIDLE_PLL */ -+ omap_writel(0x48008540, /* CM_CLKSEL1_PLL */ -+ (0x78 << 12) | (6 << 8)); -+ omap_writel(0x48008544, 2); /* CM_CLKSEL2_PLL */ -+ -+ /* GPMC setup */ -+ n800_gpmc_init(s); -+ -+ /* Video setup */ -+ n800_dss_init(&s->blizzard); -+ -+ /* CPU setup */ -+ s->cpu->env->regs[15] = s->cpu->env->boot_info->loader_start; -+} -+ -+#define OMAP_TAG_NOKIA_BT 0x4e01 -+#define OMAP_TAG_WLAN_CX3110X 0x4e02 -+#define OMAP_TAG_CBUS 0x4e03 -+#define OMAP_TAG_EM_ASIC_BB5 0x4e04 -+ -+static int n800_atag_setup(struct arm_boot_info *info, void *p) -+{ -+ uint8_t *b; -+ uint16_t *w; -+ uint32_t *l; -+ -+ w = p; -+ -+ stw_raw(w ++, OMAP_TAG_UART); /* u16 tag */ -+ stw_raw(w ++, 4); /* u16 len */ -+ stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */ -+ w ++; -+ -+ stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5); /* u16 tag */ -+ stw_raw(w ++, 4); /* u16 len */ -+ stw_raw(w ++, N800_RETU_GPIO); /* s16 retu_irq_gpio */ -+ stw_raw(w ++, N800_TAHVO_GPIO); /* s16 tahvo_irq_gpio */ -+ -+ stw_raw(w ++, OMAP_TAG_CBUS); /* u16 tag */ -+ stw_raw(w ++, 8); /* u16 len */ -+ stw_raw(w ++, N800_CBUS_CLK_GPIO); /* s16 clk_gpio */ -+ stw_raw(w ++, N800_CBUS_DAT_GPIO); /* s16 dat_gpio */ -+ stw_raw(w ++, N800_CBUS_SEL_GPIO); /* s16 sel_gpio */ -+ w ++; -+ -+ stw_raw(w ++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */ -+ stw_raw(w ++, 20); /* u16 len */ -+ strcpy((void *) w, "bat_cover"); /* char name[12] */ -+ w += 6; -+ stw_raw(w ++, N800_BAT_COVER_GPIO); /* u16 gpio */ -+ stw_raw(w ++, 0x01); -+ stw_raw(w ++, 0); -+ stw_raw(w ++, 0); -+ -+ stw_raw(w ++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */ -+ stw_raw(w ++, 20); /* u16 len */ -+ strcpy((void *) w, "cam_act"); /* char name[12] */ -+ w += 6; -+ stw_raw(w ++, N800_CAM_ACT_GPIO); /* u16 gpio */ -+ stw_raw(w ++, 0x20); -+ stw_raw(w ++, 0); -+ stw_raw(w ++, 0); -+ -+ stw_raw(w ++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */ -+ stw_raw(w ++, 20); /* u16 len */ -+ strcpy((void *) w, "cam_turn"); /* char name[12] */ -+ w += 6; -+ stw_raw(w ++, N800_CAM_TURN_GPIO); /* u16 gpio */ -+ stw_raw(w ++, 0x21); -+ stw_raw(w ++, 0); -+ stw_raw(w ++, 0); -+ -+ stw_raw(w ++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */ -+ stw_raw(w ++, 20); /* u16 len */ -+ strcpy((void *) w, "headphone"); /* char name[12] */ -+ w += 6; -+ stw_raw(w ++, N800_HEADPHONE_GPIO); /* u16 gpio */ -+ stw_raw(w ++, 0x11); -+ stw_raw(w ++, 0); -+ stw_raw(w ++, 0); -+ -+ stw_raw(w ++, OMAP_TAG_NOKIA_BT); /* u16 tag */ -+ stw_raw(w ++, 12); /* u16 len */ -+ b = (void *) w; -+ stb_raw(b ++, 0x01); /* u8 chip_type (CSR) */ -+ stb_raw(b ++, N800_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */ -+ stb_raw(b ++, N800_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */ -+ stb_raw(b ++, N800_BT_RESET_GPIO); /* u8 reset_gpio */ -+ stb_raw(b ++, 1); /* u8 bt_uart */ -+ memset(b, 0, 6); /* u8 bd_addr[6] */ -+ b += 6; -+ stb_raw(b ++, 0x02); /* u8 bt_sysclk (38.4) */ -+ w = (void *) b; -+ -+ stw_raw(w ++, OMAP_TAG_WLAN_CX3110X); /* u16 tag */ -+ stw_raw(w ++, 8); /* u16 len */ -+ stw_raw(w ++, 0x25); /* u8 chip_type */ -+ stw_raw(w ++, N800_WLAN_PWR_GPIO); /* s16 power_gpio */ -+ stw_raw(w ++, N800_WLAN_IRQ_GPIO); /* s16 irq_gpio */ -+ stw_raw(w ++, -1); /* s16 spi_cs_gpio */ -+ -+ stw_raw(w ++, OMAP_TAG_MMC); /* u16 tag */ -+ stw_raw(w ++, 16); /* u16 len */ -+ stw_raw(w ++, 0xf); /* unsigned flags */ -+ stw_raw(w ++, -1); /* s16 power_pin */ -+ stw_raw(w ++, -1); /* s16 switch_pin */ -+ stw_raw(w ++, -1); /* s16 wp_pin */ -+ stw_raw(w ++, 0); /* unsigned flags */ -+ stw_raw(w ++, 0); /* s16 power_pin */ -+ stw_raw(w ++, 0); /* s16 switch_pin */ -+ stw_raw(w ++, 0); /* s16 wp_pin */ -+ -+ stw_raw(w ++, OMAP_TAG_TEA5761); /* u16 tag */ -+ stw_raw(w ++, 4); /* u16 len */ -+ stw_raw(w ++, N800_TEA5761_CS_GPIO); /* u16 enable_gpio */ -+ w ++; -+ -+ stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */ -+ stw_raw(w ++, 28); /* u16 len */ -+ strcpy((void *) w, "bootloader"); /* char name[16] */ -+ l = (void *) (w + 8); -+ stl_raw(l ++, 0x00020000); /* unsigned int size */ -+ stl_raw(l ++, 0x00000000); /* unsigned int offset */ -+ stl_raw(l ++, 0x3); /* unsigned int mask_flags */ -+ w = (void *) l; -+ -+ stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */ -+ stw_raw(w ++, 28); /* u16 len */ -+ strcpy((void *) w, "config"); /* char name[16] */ -+ l = (void *) (w + 8); -+ stl_raw(l ++, 0x00060000); /* unsigned int size */ -+ stl_raw(l ++, 0x00020000); /* unsigned int offset */ -+ stl_raw(l ++, 0x0); /* unsigned int mask_flags */ -+ w = (void *) l; -+ -+ stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */ -+ stw_raw(w ++, 28); /* u16 len */ -+ strcpy((void *) w, "kernel"); /* char name[16] */ -+ l = (void *) (w + 8); -+ stl_raw(l ++, 0x00200000); /* unsigned int size */ -+ stl_raw(l ++, 0x00080000); /* unsigned int offset */ -+ stl_raw(l ++, 0x0); /* unsigned int mask_flags */ -+ w = (void *) l; -+ -+ stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */ -+ stw_raw(w ++, 28); /* u16 len */ -+ strcpy((void *) w, "initfs"); /* char name[16] */ -+ l = (void *) (w + 8); -+ stl_raw(l ++, 0x00200000); /* unsigned int size */ -+ stl_raw(l ++, 0x00280000); /* unsigned int offset */ -+ stl_raw(l ++, 0x3); /* unsigned int mask_flags */ -+ w = (void *) l; -+ -+ stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */ -+ stw_raw(w ++, 28); /* u16 len */ -+ strcpy((void *) w, "rootfs"); /* char name[16] */ -+ l = (void *) (w + 8); -+ stl_raw(l ++, 0x0fb80000); /* unsigned int size */ -+ stl_raw(l ++, 0x00480000); /* unsigned int offset */ -+ stl_raw(l ++, 0x3); /* unsigned int mask_flags */ -+ w = (void *) l; -+ -+ stw_raw(w ++, OMAP_TAG_BOOT_REASON); /* u16 tag */ -+ stw_raw(w ++, 12); /* u16 len */ -+#if 0 -+ strcpy((void *) w, "por"); /* char reason_str[12] */ -+ strcpy((void *) w, "charger"); /* char reason_str[12] */ -+ strcpy((void *) w, "32wd_to"); /* char reason_str[12] */ -+ strcpy((void *) w, "sw_rst"); /* char reason_str[12] */ -+ strcpy((void *) w, "mbus"); /* char reason_str[12] */ -+ strcpy((void *) w, "unknown"); /* char reason_str[12] */ -+ strcpy((void *) w, "swdg_to"); /* char reason_str[12] */ -+ strcpy((void *) w, "sec_vio"); /* char reason_str[12] */ -+ strcpy((void *) w, "pwr_key"); /* char reason_str[12] */ -+ strcpy((void *) w, "rtc_alarm"); /* char reason_str[12] */ -+#else -+ strcpy((void *) w, "pwr_key"); /* char reason_str[12] */ -+#endif -+ w += 6; -+ -+ stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */ -+ stw_raw(w ++, 24); /* u16 len */ -+ strcpy((void *) w, "product"); /* char component[12] */ -+ w += 6; -+ strcpy((void *) w, "RX-34"); /* char version[12] */ -+ w += 6; -+ -+ stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */ -+ stw_raw(w ++, 24); /* u16 len */ -+ strcpy((void *) w, "hw-build"); /* char component[12] */ -+ w += 6; -+ strcpy((void *) w, "QEMU"); /* char version[12] */ -+ w += 6; -+ -+ stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */ -+ stw_raw(w ++, 24); /* u16 len */ -+ strcpy((void *) w, "nolo"); /* char component[12] */ -+ w += 6; -+ strcpy((void *) w, "1.1.6-qemu"); /* char version[12] */ -+ w += 6; -+ -+ stw_raw(w ++, OMAP_TAG_LCD); /* u16 tag */ -+ stw_raw(w ++, 36); /* u16 len */ -+ strcpy((void *) w, "QEMU LCD panel"); /* char panel_name[16] */ -+ w += 8; -+ strcpy((void *) w, "blizzard"); /* char ctrl_name[16] */ -+ w += 8; -+ stw_raw(w ++, 5); /* TODO s16 nreset_gpio */ -+ stw_raw(w ++, 16); /* u8 data_lines */ -+ -+ return (void *) w - p; -+} -+ -+static struct arm_boot_info n800_binfo = { -+ .loader_start = OMAP2_Q2_BASE, -+ /* Actually two chips of 0x4000000 bytes each */ -+ .ram_size = 0x08000000, -+ .board_id = 0x4f7, -+ .atag_board = n800_atag_setup, -+}; -+ -+static void n800_init(int ram_size, int vga_ram_size, -+ const char *boot_device, DisplayState *ds, -+ const char *kernel_filename, const char *kernel_cmdline, -+ const char *initrd_filename, const char *cpu_model) -+{ -+ struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s)); -+ int sdram_size = n800_binfo.ram_size; -+ int onenandram_size = 0x00010000; -+ -+ if (ram_size < sdram_size + onenandram_size + OMAP242X_SRAM_SIZE) { -+ fprintf(stderr, "This architecture uses %i bytes of memory\n", -+ sdram_size + onenandram_size + OMAP242X_SRAM_SIZE); -+ exit(1); -+ } -+ -+ s->cpu = omap2420_mpu_init(sdram_size, NULL, cpu_model); -+ -+ n800_gpio_setup(s); -+ n800_nand_setup(s); -+ n800_i2c_setup(s); -+ n800_tsc_setup(s); -+ n800_spi_setup(s); -+ n800_dss_setup(s, ds); -+ n800_cbus_setup(s); -+ -+ /* Setup initial (reset) machine state */ -+ -+ /* Start at the OneNAND bootloader. */ -+ s->cpu->env->regs[15] = 0; -+ -+ if (kernel_filename) { -+ /* Or at the linux loader. */ -+ n800_binfo.kernel_filename = kernel_filename; -+ n800_binfo.kernel_cmdline = kernel_cmdline; -+ n800_binfo.initrd_filename = initrd_filename; -+ arm_load_kernel(s->cpu->env, &n800_binfo); -+ -+ qemu_register_reset(n800_boot_init, s); -+ n800_boot_init(s); -+ } -+ -+ dpy_resize(ds, 800, 480); -+} -+ -+QEMUMachine n800_machine = { -+ "n800", -+ "Nokia N800 aka. RX-34 tablet (OMAP2420)", -+ n800_init, -+}; -diff --git a/hw/omap.h b/hw/omap.h -index ecfd54d..de838c9 100644 ---- a/hw/omap.h -+++ b/hw/omap.h -@@ -22,6 +22,7 @@ - # define hw_omap_h "omap.h" - - # define OMAP_EMIFS_BASE 0x00000000 -+# define OMAP2_Q0_BASE 0x00000000 - # define OMAP_CS0_BASE 0x00000000 - # define OMAP_CS1_BASE 0x04000000 - # define OMAP_CS2_BASE 0x08000000 -@@ -29,18 +30,26 @@ - # define OMAP_EMIFF_BASE 0x10000000 - # define OMAP_IMIF_BASE 0x20000000 - # define OMAP_LOCALBUS_BASE 0x30000000 -+# define OMAP2_Q1_BASE 0x40000000 -+# define OMAP2_L4_BASE 0x48000000 -+# define OMAP2_SRAM_BASE 0x40200000 -+# define OMAP2_L3_BASE 0x68000000 -+# define OMAP2_Q2_BASE 0x80000000 -+# define OMAP2_Q3_BASE 0xc0000000 - # define OMAP_MPUI_BASE 0xe1000000 - - # define OMAP730_SRAM_SIZE 0x00032000 - # define OMAP15XX_SRAM_SIZE 0x00030000 - # define OMAP16XX_SRAM_SIZE 0x00004000 - # define OMAP1611_SRAM_SIZE 0x0003e800 -+# define OMAP242X_SRAM_SIZE 0x000a0000 -+# define OMAP243X_SRAM_SIZE 0x00010000 - # define OMAP_CS0_SIZE 0x04000000 - # define OMAP_CS1_SIZE 0x04000000 - # define OMAP_CS2_SIZE 0x04000000 - # define OMAP_CS3_SIZE 0x04000000 - --/* omap1_clk.c */ -+/* omap_clk.c */ - struct omap_mpu_state_s; - typedef struct clk *omap_clk; - omap_clk omap_findclk(struct omap_mpu_state_s *mpu, const char *name); -@@ -55,14 +64,41 @@ int64_t omap_clk_getrate(omap_clk clk); - void omap_clk_reparent(omap_clk clk, omap_clk parent); - - /* omap[123].c */ -+struct omap_l4_s; -+struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num); -+ -+struct omap_target_agent_s; -+struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs); -+target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region, -+ int iotype); -+ - struct omap_intr_handler_s; - struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, -- unsigned long size, unsigned char nbanks, -+ unsigned long size, unsigned char nbanks, qemu_irq **pins, - qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk); -- --struct omap_target_agent_s; --static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, -- int region, int iotype) { return 0; } -+struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base, -+ int size, int nbanks, qemu_irq **pins, -+ qemu_irq parent_irq, qemu_irq parent_fiq, -+ omap_clk fclk, omap_clk iclk); -+void omap_inth_reset(struct omap_intr_handler_s *s); -+ -+struct omap_prcm_s; -+struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta, -+ qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int, -+ struct omap_mpu_state_s *mpu); -+ -+struct omap_sysctl_s; -+struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta, -+ omap_clk iclk, struct omap_mpu_state_s *mpu); -+ -+struct omap_sdrc_s; -+struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base); -+ -+struct omap_gpmc_s; -+struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq); -+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype, -+ void (*base_upd)(void *opaque, target_phys_addr_t new), -+ void (*unmap)(void *opaque), void *opaque); - - /* - * Common IRQ numbers for level 1 interrupt handler -@@ -295,10 +331,20 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, - * OMAP-24xx common IRQ numbers - */ - # define OMAP_INT_24XX_SYS_NIRQ 7 -+# define OMAP_INT_24XX_L3_IRQ 10 -+# define OMAP_INT_24XX_PRCM_MPU_IRQ 11 - # define OMAP_INT_24XX_SDMA_IRQ0 12 - # define OMAP_INT_24XX_SDMA_IRQ1 13 - # define OMAP_INT_24XX_SDMA_IRQ2 14 - # define OMAP_INT_24XX_SDMA_IRQ3 15 -+# define OMAP_INT_243X_MCBSP2_IRQ 16 -+# define OMAP_INT_243X_MCBSP3_IRQ 17 -+# define OMAP_INT_243X_MCBSP4_IRQ 18 -+# define OMAP_INT_243X_MCBSP5_IRQ 19 -+# define OMAP_INT_24XX_GPMC_IRQ 20 -+# define OMAP_INT_24XX_GUFFAW_IRQ 21 -+# define OMAP_INT_24XX_IVA_IRQ 22 -+# define OMAP_INT_24XX_EAC_IRQ 23 - # define OMAP_INT_24XX_CAM_IRQ 24 - # define OMAP_INT_24XX_DSS_IRQ 25 - # define OMAP_INT_24XX_MAIL_U0_MPU 26 -@@ -308,8 +354,10 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, - # define OMAP_INT_24XX_GPIO_BANK2 30 - # define OMAP_INT_24XX_GPIO_BANK3 31 - # define OMAP_INT_24XX_GPIO_BANK4 32 --# define OMAP_INT_24XX_GPIO_BANK5 33 -+# define OMAP_INT_243X_GPIO_BANK5 33 - # define OMAP_INT_24XX_MAIL_U3_MPU 34 -+# define OMAP_INT_24XX_WDT3 35 -+# define OMAP_INT_24XX_WDT4 36 - # define OMAP_INT_24XX_GPTIMER1 37 - # define OMAP_INT_24XX_GPTIMER2 38 - # define OMAP_INT_24XX_GPTIMER3 39 -@@ -322,10 +370,24 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, - # define OMAP_INT_24XX_GPTIMER10 46 - # define OMAP_INT_24XX_GPTIMER11 47 - # define OMAP_INT_24XX_GPTIMER12 48 -+# define OMAP_INT_24XX_PKA_IRQ 50 -+# define OMAP_INT_24XX_SHA1MD5_IRQ 51 -+# define OMAP_INT_24XX_RNG_IRQ 52 -+# define OMAP_INT_24XX_MG_IRQ 53 -+# define OMAP_INT_24XX_I2C1_IRQ 56 -+# define OMAP_INT_24XX_I2C2_IRQ 57 - # define OMAP_INT_24XX_MCBSP1_IRQ_TX 59 - # define OMAP_INT_24XX_MCBSP1_IRQ_RX 60 - # define OMAP_INT_24XX_MCBSP2_IRQ_TX 62 - # define OMAP_INT_24XX_MCBSP2_IRQ_RX 63 -+# define OMAP_INT_243X_MCBSP1_IRQ 64 -+# define OMAP_INT_24XX_MCSPI1_IRQ 65 -+# define OMAP_INT_24XX_MCSPI2_IRQ 66 -+# define OMAP_INT_24XX_SSI1_IRQ0 67 -+# define OMAP_INT_24XX_SSI1_IRQ1 68 -+# define OMAP_INT_24XX_SSI2_IRQ0 69 -+# define OMAP_INT_24XX_SSI2_IRQ1 70 -+# define OMAP_INT_24XX_SSI_GDD_IRQ 71 - # define OMAP_INT_24XX_UART1_IRQ 72 - # define OMAP_INT_24XX_UART2_IRQ 73 - # define OMAP_INT_24XX_UART3_IRQ 74 -@@ -335,10 +397,15 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, - # define OMAP_INT_24XX_USB_IRQ_HGEN 78 - # define OMAP_INT_24XX_USB_IRQ_HSOF 79 - # define OMAP_INT_24XX_USB_IRQ_OTG 80 -+# define OMAP_INT_24XX_VLYNQ_IRQ 81 - # define OMAP_INT_24XX_MMC_IRQ 83 -+# define OMAP_INT_24XX_MS_IRQ 84 -+# define OMAP_INT_24XX_FAC_IRQ 85 -+# define OMAP_INT_24XX_MCSPI3_IRQ 91 - # define OMAP_INT_243X_HS_USB_MC 92 - # define OMAP_INT_243X_HS_USB_DMA 93 - # define OMAP_INT_243X_CARKIT 94 -+# define OMAP_INT_34XX_GPTIMER12 95 - - /* omap_dma.c */ - enum omap_dma_model { -@@ -352,6 +419,9 @@ struct omap_dma_s; - struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs, - qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk, - enum omap_dma_model model); -+struct omap_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs, -+ struct omap_mpu_state_s *mpu, int fifo, -+ int chans, omap_clk iclk, omap_clk fclk); - void omap_dma_reset(struct omap_dma_s *s); - - struct dma_irq_map { -@@ -367,7 +437,7 @@ enum omap_dma_port { - tipb, - local, /* omap16xx: ocp_t2 */ - tipb_mpui, -- omap_dma_port_last, -+ __omap_dma_port_last, - }; - - typedef enum { -@@ -488,11 +558,83 @@ struct omap_dma_lcd_channel_s { - # define OMAP_DMA_MMC2_RX 55 - # define OMAP_DMA_CRYPTO_DES_OUT 56 - -+/* -+ * DMA request numbers for the OMAP2 -+ */ -+# define OMAP24XX_DMA_NO_DEVICE 0 -+# define OMAP24XX_DMA_XTI_DMA 1 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_EXT_DMAREQ0 2 -+# define OMAP24XX_DMA_EXT_DMAREQ1 3 -+# define OMAP24XX_DMA_GPMC 4 -+# define OMAP24XX_DMA_GFX 5 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_DSS 6 -+# define OMAP24XX_DMA_VLYNQ_TX 7 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_CWT 8 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_AES_TX 9 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_AES_RX 10 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_DES_TX 11 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_DES_RX 12 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_SHA1MD5_RX 13 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_EXT_DMAREQ2 14 -+# define OMAP24XX_DMA_EXT_DMAREQ3 15 -+# define OMAP24XX_DMA_EXT_DMAREQ4 16 -+# define OMAP24XX_DMA_EAC_AC_RD 17 -+# define OMAP24XX_DMA_EAC_AC_WR 18 -+# define OMAP24XX_DMA_EAC_MD_UL_RD 19 -+# define OMAP24XX_DMA_EAC_MD_UL_WR 20 -+# define OMAP24XX_DMA_EAC_MD_DL_RD 21 -+# define OMAP24XX_DMA_EAC_MD_DL_WR 22 -+# define OMAP24XX_DMA_EAC_BT_UL_RD 23 -+# define OMAP24XX_DMA_EAC_BT_UL_WR 24 -+# define OMAP24XX_DMA_EAC_BT_DL_RD 25 -+# define OMAP24XX_DMA_EAC_BT_DL_WR 26 -+# define OMAP24XX_DMA_I2C1_TX 27 -+# define OMAP24XX_DMA_I2C1_RX 28 -+# define OMAP24XX_DMA_I2C2_TX 29 -+# define OMAP24XX_DMA_I2C2_RX 30 -+# define OMAP24XX_DMA_MCBSP1_TX 31 -+# define OMAP24XX_DMA_MCBSP1_RX 32 -+# define OMAP24XX_DMA_MCBSP2_TX 33 -+# define OMAP24XX_DMA_MCBSP2_RX 34 -+# define OMAP24XX_DMA_SPI1_TX0 35 -+# define OMAP24XX_DMA_SPI1_RX0 36 -+# define OMAP24XX_DMA_SPI1_TX1 37 -+# define OMAP24XX_DMA_SPI1_RX1 38 -+# define OMAP24XX_DMA_SPI1_TX2 39 -+# define OMAP24XX_DMA_SPI1_RX2 40 -+# define OMAP24XX_DMA_SPI1_TX3 41 -+# define OMAP24XX_DMA_SPI1_RX3 42 -+# define OMAP24XX_DMA_SPI2_TX0 43 -+# define OMAP24XX_DMA_SPI2_RX0 44 -+# define OMAP24XX_DMA_SPI2_TX1 45 -+# define OMAP24XX_DMA_SPI2_RX1 46 -+ -+# define OMAP24XX_DMA_UART1_TX 49 -+# define OMAP24XX_DMA_UART1_RX 50 -+# define OMAP24XX_DMA_UART2_TX 51 -+# define OMAP24XX_DMA_UART2_RX 52 -+# define OMAP24XX_DMA_UART3_TX 53 -+# define OMAP24XX_DMA_UART3_RX 54 -+# define OMAP24XX_DMA_USB_W2FC_TX0 55 -+# define OMAP24XX_DMA_USB_W2FC_RX0 56 -+# define OMAP24XX_DMA_USB_W2FC_TX1 57 -+# define OMAP24XX_DMA_USB_W2FC_RX1 58 -+# define OMAP24XX_DMA_USB_W2FC_TX2 59 -+# define OMAP24XX_DMA_USB_W2FC_RX2 60 -+# define OMAP24XX_DMA_MMC1_TX 61 -+# define OMAP24XX_DMA_MMC1_RX 62 -+# define OMAP24XX_DMA_MS 63 /* Not in OMAP2420 */ -+# define OMAP24XX_DMA_EXT_DMAREQ5 64 -+ - /* omap[123].c */ - struct omap_mpu_timer_s; - struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base, - qemu_irq irq, omap_clk clk); - -+struct omap_gp_timer_s; -+struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta, -+ qemu_irq irq, omap_clk fclk, omap_clk iclk); -+ - struct omap_watchdog_timer_s; - struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base, - qemu_irq irq, omap_clk clk); -@@ -501,13 +643,21 @@ struct omap_32khz_timer_s; - struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base, - qemu_irq irq, omap_clk clk); - -+void omap_synctimer_init(struct omap_target_agent_s *ta, -+ struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk); -+ - struct omap_tipb_bridge_s; - struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base, - qemu_irq abort_irq, omap_clk clk); - - struct omap_uart_s; - struct omap_uart_s *omap_uart_init(target_phys_addr_t base, -- qemu_irq irq, omap_clk clk, CharDriverState *chr); -+ qemu_irq irq, omap_clk fclk, omap_clk iclk, -+ qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr); -+struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta, -+ qemu_irq irq, omap_clk fclk, omap_clk iclk, -+ qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr); -+void omap_uart_reset(struct omap_uart_s *s); - - struct omap_mpuio_s; - struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base, -@@ -523,6 +673,12 @@ struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base, - qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s); - void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler); - -+struct omap_gpif_s; -+struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta, -+ qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules); -+qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start); -+void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler); -+ - struct uwire_slave_s { - uint16_t (*receive)(void *opaque); - void (*send)(void *opaque, uint16_t data); -@@ -534,6 +690,13 @@ struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base, - void omap_uwire_attach(struct omap_uwire_s *s, - struct uwire_slave_s *slave, int chipselect); - -+struct omap_mcspi_s; -+struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum, -+ qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk); -+void omap_mcspi_attach(struct omap_mcspi_s *s, -+ uint32_t (*txrx)(void *opaque, uint32_t), void *opaque, -+ int chipselect); -+ - struct omap_rtc_s; - struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base, - qemu_irq *irq, omap_clk clk); -@@ -570,6 +733,9 @@ void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave); - struct omap_lpg_s; - struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk); - -+void omap_tap_init(struct omap_target_agent_s *ta, -+ struct omap_mpu_state_s *mpu); -+ - /* omap_lcdc.c */ - struct omap_lcd_panel_s; - void omap_lcdc_reset(struct omap_lcd_panel_s *s); -@@ -577,13 +743,33 @@ struct omap_lcd_panel_s *omap_lcdc_init(target_phys_addr_t base, qemu_irq irq, - struct omap_dma_lcd_channel_s *dma, DisplayState *ds, - ram_addr_t imif_base, ram_addr_t emiff_base, omap_clk clk); - -+/* omap_dss.c */ -+struct rfbi_chip_s { -+ void *opaque; -+ void (*write)(void *opaque, int dc, uint16_t value); -+ void (*block)(void *opaque, int dc, void *buf, size_t len, int pitch); -+ uint16_t (*read)(void *opaque, int dc); -+}; -+struct omap_dss_s; -+void omap_dss_reset(struct omap_dss_s *s); -+struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta, -+ target_phys_addr_t l3_base, DisplayState *ds, -+ qemu_irq irq, qemu_irq drq, -+ omap_clk fck1, omap_clk fck2, omap_clk ck54m, -+ omap_clk ick1, omap_clk ick2); -+void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip); -+ - /* omap_mmc.c */ - struct omap_mmc_s; - struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, - BlockDriverState *bd, - qemu_irq irq, qemu_irq dma[], omap_clk clk); -+struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta, -+ BlockDriverState *bd, qemu_irq irq, qemu_irq dma[], -+ omap_clk fclk, omap_clk iclk); - void omap_mmc_reset(struct omap_mmc_s *s); - void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover); -+void omap_mmc_enable(struct omap_mmc_s *s, int enable); - - /* omap_i2c.c */ - struct omap_i2c_s; -@@ -596,14 +782,37 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s); - - # define cpu_is_omap310(cpu) (cpu->mpu_model == omap310) - # define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510) -+# define cpu_is_omap1610(cpu) (cpu->mpu_model == omap1610) -+# define cpu_is_omap1710(cpu) (cpu->mpu_model == omap1710) -+# define cpu_is_omap2410(cpu) (cpu->mpu_model == omap2410) -+# define cpu_is_omap2420(cpu) (cpu->mpu_model == omap2420) -+# define cpu_is_omap2430(cpu) (cpu->mpu_model == omap2430) -+# define cpu_is_omap3430(cpu) (cpu->mpu_model == omap3430) -+ - # define cpu_is_omap15xx(cpu) \ - (cpu_is_omap310(cpu) || cpu_is_omap1510(cpu)) --# define cpu_class_omap1(cpu) 1 -+# define cpu_is_omap16xx(cpu) \ -+ (cpu_is_omap1610(cpu) || cpu_is_omap1710(cpu)) -+# define cpu_is_omap24xx(cpu) \ -+ (cpu_is_omap2410(cpu) || cpu_is_omap2420(cpu) || cpu_is_omap2430(cpu)) -+ -+# define cpu_class_omap1(cpu) \ -+ (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu)) -+# define cpu_class_omap2(cpu) cpu_is_omap24xx(cpu) -+# define cpu_class_omap3(cpu) cpu_is_omap3430(cpu) - - struct omap_mpu_state_s { -- enum omap1_mpu_model { -+ enum omap_mpu_model { - omap310, - omap1510, -+ omap1610, -+ omap1710, -+ omap2410, -+ omap2420, -+ omap2422, -+ omap2423, -+ omap2430, -+ omap3430, - } mpu_model; - - CPUState *env; -@@ -620,7 +829,7 @@ struct omap_mpu_state_s { - target_phys_addr_t offset, uint32_t value); - int (*addr_valid)(struct omap_mpu_state_s *s, - target_phys_addr_t addr); -- } port[omap_dma_port_last]; -+ } port[__omap_dma_port_last]; - - unsigned long sdram_size; - unsigned long sram_size; -@@ -656,7 +865,7 @@ struct omap_mpu_state_s { - omap_clk clk; - } pwt; - -- struct omap_i2c_s *i2c; -+ struct omap_i2c_s *i2c[2]; - - struct omap_rtc_s *rtc; - -@@ -722,7 +931,38 @@ struct omap_mpu_state_s { - uint16_t dsp_idlect2; - uint16_t dsp_rstct2; - } clkm; --} *omap310_mpu_init(unsigned long sdram_size, -+ -+ /* OMAP2-only peripherals */ -+ struct omap_l4_s *l4; -+ -+ struct omap_gp_timer_s *gptimer[12]; -+ -+ target_phys_addr_t tap_base; -+ -+ struct omap_synctimer_s { -+ target_phys_addr_t base; -+ uint32_t val; -+ uint16_t readh; -+ } synctimer; -+ -+ struct omap_prcm_s *prcm; -+ struct omap_sdrc_s *sdrc; -+ struct omap_gpmc_s *gpmc; -+ struct omap_sysctl_s *sysc; -+ -+ struct omap_gpif_s *gpif; -+ -+ struct omap_mcspi_s *mcspi[2]; -+ -+ struct omap_dss_s *dss; -+}; -+ -+/* omap1.c */ -+struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, -+ DisplayState *ds, const char *core); -+ -+/* omap2.c */ -+struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, - DisplayState *ds, const char *core); - - # if TARGET_PHYS_ADDR_BITS == 32 -@@ -743,24 +983,46 @@ uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr); - void omap_badwidth_write32(void *opaque, target_phys_addr_t addr, - uint32_t value); - -+void omap_mpu_wakeup(void *opaque, int irq, int req); -+ - # define OMAP_BAD_REG(paddr) \ -- printf("%s: Bad register " OMAP_FMT_plx "\n", __FUNCTION__, paddr) -+ fprintf(stderr, "%s: Bad register " OMAP_FMT_plx "\n", \ -+ __FUNCTION__, paddr) - # define OMAP_RO_REG(paddr) \ -- printf("%s: Read-only register " OMAP_FMT_plx "\n", \ -+ fprintf(stderr, "%s: Read-only register " OMAP_FMT_plx "\n", \ - __FUNCTION__, paddr) - -+/* OMAP-specific Linux bootloader tags for the ATAG_BOARD area -+ (Board-specifc tags are not here) */ -+#define OMAP_TAG_CLOCK 0x4f01 -+#define OMAP_TAG_MMC 0x4f02 -+#define OMAP_TAG_SERIAL_CONSOLE 0x4f03 -+#define OMAP_TAG_USB 0x4f04 -+#define OMAP_TAG_LCD 0x4f05 -+#define OMAP_TAG_GPIO_SWITCH 0x4f06 -+#define OMAP_TAG_UART 0x4f07 -+#define OMAP_TAG_FBMEM 0x4f08 -+#define OMAP_TAG_STI_CONSOLE 0x4f09 -+#define OMAP_TAG_CAMERA_SENSOR 0x4f0a -+#define OMAP_TAG_PARTITION 0x4f0b -+#define OMAP_TAG_TEA5761 0x4f10 -+#define OMAP_TAG_TMP105 0x4f11 -+#define OMAP_TAG_BOOT_REASON 0x4f80 -+#define OMAP_TAG_FLASH_PART_STR 0x4f81 -+#define OMAP_TAG_VERSION_STR 0x4f82 -+ - # define TCMI_VERBOSE 1 - //# define MEM_VERBOSE 1 - - # ifdef TCMI_VERBOSE - # define OMAP_8B_REG(paddr) \ -- printf("%s: 8-bit register " OMAP_FMT_plx "\n", \ -+ fprintf(stderr, "%s: 8-bit register " OMAP_FMT_plx "\n", \ - __FUNCTION__, paddr) - # define OMAP_16B_REG(paddr) \ -- printf("%s: 16-bit register " OMAP_FMT_plx "\n", \ -+ fprintf(stderr, "%s: 16-bit register " OMAP_FMT_plx "\n", \ - __FUNCTION__, paddr) - # define OMAP_32B_REG(paddr) \ -- printf("%s: 32-bit register " OMAP_FMT_plx "\n", \ -+ fprintf(stderr, "%s: 32-bit register " OMAP_FMT_plx "\n", \ - __FUNCTION__, paddr) - # else - # define OMAP_8B_REG(paddr) -@@ -863,10 +1125,4 @@ inline static int debug_register_io_memory(int io_index, - # define cpu_register_io_memory debug_register_io_memory - # endif - --/* Not really omap specific, but is the only thing that uses the -- uwire interface. */ --/* tsc210x.c */ --struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio); --struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip); -- - #endif /* hw_omap_h */ -diff --git a/hw/omap1.c b/hw/omap1.c -index 3888e80..d81cbce 100644 ---- a/hw/omap1.c -+++ b/hw/omap1.c -@@ -23,10 +23,11 @@ - #include "omap.h" - #include "sysemu.h" - #include "qemu-timer.h" -+#include "qemu-char.h" - /* We use pc-style serial ports. */ - #include "pc.h" - --/* Should signal the TCMI */ -+/* Should signal the TCMI/GPMC */ - uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr) - { - uint8_t ret; -@@ -86,6 +87,7 @@ struct omap_intr_handler_bank_s { - uint32_t mask; - uint32_t fiq; - uint32_t sens_edge; -+ uint32_t swi; - unsigned char priority[32]; - }; - -@@ -94,11 +96,14 @@ struct omap_intr_handler_s { - qemu_irq parent_intr[2]; - target_phys_addr_t base; - unsigned char nbanks; -+ int level_only; - - /* state */ - uint32_t new_agr[2]; - int sir_intr[2]; -- struct omap_intr_handler_bank_s banks[]; -+ int autoidle; -+ uint32_t mask; -+ struct omap_intr_handler_bank_s bank[]; - }; - - static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq) -@@ -113,11 +118,11 @@ static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq) - * If all interrupts have the same priority, the default order is IRQ_N, - * IRQ_N-1,...,IRQ_0. */ - for (j = 0; j < s->nbanks; ++j) { -- level = s->banks[j].irqs & ~s->banks[j].mask & -- (is_fiq ? s->banks[j].fiq : ~s->banks[j].fiq); -+ level = s->bank[j].irqs & ~s->bank[j].mask & -+ (is_fiq ? s->bank[j].fiq : ~s->bank[j].fiq); - for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, - level >>= f) { -- p = s->banks[j].priority[i]; -+ p = s->bank[j].priority[i]; - if (p <= p_intr) { - p_intr = p; - sir_intr = 32 * j + i; -@@ -134,10 +139,10 @@ static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq) - uint32_t has_intr = 0; - - for (i = 0; i < s->nbanks; ++i) -- has_intr |= s->banks[i].irqs & ~s->banks[i].mask & -- (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq); -+ has_intr |= s->bank[i].irqs & ~s->bank[i].mask & -+ (is_fiq ? s->bank[i].fiq : ~s->bank[i].fiq); - -- if (s->new_agr[is_fiq] && has_intr) { -+ if (s->new_agr[is_fiq] & has_intr & s->mask) { - s->new_agr[is_fiq] = 0; - omap_inth_sir_update(s, is_fiq); - qemu_set_irq(s->parent_intr[is_fiq], 1); -@@ -152,13 +157,13 @@ static void omap_set_intr(void *opaque, int irq, int req) - struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque; - uint32_t rise; - -- struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5]; -+ struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5]; - int n = irq & 31; - - if (req) { - rise = ~bank->irqs & (1 << n); - if (~bank->sens_edge & (1 << n)) -- rise &= ~bank->inputs & (1 << n); -+ rise &= ~bank->inputs; - - bank->inputs |= (1 << n); - if (rise) { -@@ -173,13 +178,33 @@ static void omap_set_intr(void *opaque, int irq, int req) - } - } - -+/* Simplified version with no edge detection */ -+static void omap_set_intr_noedge(void *opaque, int irq, int req) -+{ -+ struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque; -+ uint32_t rise; -+ -+ struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5]; -+ int n = irq & 31; -+ -+ if (req) { -+ rise = ~bank->inputs & (1 << n); -+ if (rise) { -+ bank->irqs |= bank->inputs |= rise; -+ omap_inth_update(ih, 0); -+ omap_inth_update(ih, 1); -+ } -+ } else -+ bank->irqs = (bank->inputs &= ~(1 << n)) | bank->swi; -+} -+ - static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr) - { - struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; - int i, offset = addr - s->base; - int bank_no = offset >> 8; - int line_no; -- struct omap_intr_handler_bank_s *bank = &s->banks[bank_no]; -+ struct omap_intr_handler_bank_s *bank = &s->bank[bank_no]; - offset &= 0xff; - - switch (offset) { -@@ -194,7 +219,7 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr) - if (bank_no != 0) - break; - line_no = s->sir_intr[(offset - 0x10) >> 2]; -- bank = &s->banks[line_no >> 5]; -+ bank = &s->bank[line_no >> 5]; - i = line_no & 31; - if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE) - bank->irqs &= ~(1 << i); -@@ -256,7 +281,7 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr, - struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; - int i, offset = addr - s->base; - int bank_no = offset >> 8; -- struct omap_intr_handler_bank_s *bank = &s->banks[bank_no]; -+ struct omap_intr_handler_bank_s *bank = &s->bank[bank_no]; - offset &= 0xff; - - switch (offset) { -@@ -360,25 +385,31 @@ void omap_inth_reset(struct omap_intr_handler_s *s) - int i; - - for (i = 0; i < s->nbanks; ++i){ -- s->banks[i].irqs = 0x00000000; -- s->banks[i].mask = 0xffffffff; -- s->banks[i].sens_edge = 0x00000000; -- s->banks[i].fiq = 0x00000000; -- s->banks[i].inputs = 0x00000000; -- memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority)); -+ s->bank[i].irqs = 0x00000000; -+ s->bank[i].mask = 0xffffffff; -+ s->bank[i].sens_edge = 0x00000000; -+ s->bank[i].fiq = 0x00000000; -+ s->bank[i].inputs = 0x00000000; -+ s->bank[i].swi = 0x00000000; -+ memset(s->bank[i].priority, 0, sizeof(s->bank[i].priority)); -+ -+ if (s->level_only) -+ s->bank[i].sens_edge = 0xffffffff; - } - - s->new_agr[0] = ~0; - s->new_agr[1] = ~0; - s->sir_intr[0] = 0; - s->sir_intr[1] = 0; -+ s->autoidle = 0; -+ s->mask = ~0; - - qemu_set_irq(s->parent_intr[0], 0); - qemu_set_irq(s->parent_intr[1], 0); - } - - struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, -- unsigned long size, unsigned char nbanks, -+ unsigned long size, unsigned char nbanks, qemu_irq **pins, - qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk) - { - int iomemtype; -@@ -391,6 +422,8 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, - s->base = base; - s->nbanks = nbanks; - s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32); -+ if (pins) -+ *pins = s->pins; - - omap_inth_reset(s); - -@@ -401,6 +434,227 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, - return s; - } - -+static uint32_t omap2_inth_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; -+ int offset = addr - s->base; -+ int bank_no, line_no; -+ struct omap_intr_handler_bank_s *bank = 0; -+ -+ if ((offset & 0xf80) == 0x80) { -+ bank_no = (offset & 0x60) >> 5; -+ if (bank_no < s->nbanks) { -+ offset &= ~0x60; -+ bank = &s->bank[bank_no]; -+ } -+ } -+ -+ switch (offset) { -+ case 0x00: /* INTC_REVISION */ -+ return 0x21; -+ -+ case 0x10: /* INTC_SYSCONFIG */ -+ return (s->autoidle >> 2) & 1; -+ -+ case 0x14: /* INTC_SYSSTATUS */ -+ return 1; /* RESETDONE */ -+ -+ case 0x40: /* INTC_SIR_IRQ */ -+ return s->sir_intr[0]; -+ -+ case 0x44: /* INTC_SIR_FIQ */ -+ return s->sir_intr[1]; -+ -+ case 0x48: /* INTC_CONTROL */ -+ return (!s->mask) << 2; /* GLOBALMASK */ -+ -+ case 0x4c: /* INTC_PROTECTION */ -+ return 0; -+ -+ case 0x50: /* INTC_IDLE */ -+ return s->autoidle & 3; -+ -+ /* Per-bank registers */ -+ case 0x80: /* INTC_ITR */ -+ return bank->inputs; -+ -+ case 0x84: /* INTC_MIR */ -+ return bank->mask; -+ -+ case 0x88: /* INTC_MIR_CLEAR */ -+ case 0x8c: /* INTC_MIR_SET */ -+ return 0; -+ -+ case 0x90: /* INTC_ISR_SET */ -+ return bank->swi; -+ -+ case 0x94: /* INTC_ISR_CLEAR */ -+ return 0; -+ -+ case 0x98: /* INTC_PENDING_IRQ */ -+ return bank->irqs & ~bank->mask & ~bank->fiq; -+ -+ case 0x9c: /* INTC_PENDING_FIQ */ -+ return bank->irqs & ~bank->mask & bank->fiq; -+ -+ /* Per-line registers */ -+ case 0x100 ... 0x300: /* INTC_ILR */ -+ bank_no = (offset - 0x100) >> 7; -+ if (bank_no > s->nbanks) -+ break; -+ bank = &s->bank[bank_no]; -+ line_no = (offset & 0x7f) >> 2; -+ return (bank->priority[line_no] << 2) | -+ ((bank->fiq >> line_no) & 1); -+ } -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap2_inth_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; -+ int offset = addr - s->base; -+ int bank_no, line_no; -+ struct omap_intr_handler_bank_s *bank = 0; -+ -+ if ((offset & 0xf80) == 0x80) { -+ bank_no = (offset & 0x60) >> 5; -+ if (bank_no < s->nbanks) { -+ offset &= ~0x60; -+ bank = &s->bank[bank_no]; -+ } -+ } -+ -+ switch (offset) { -+ case 0x10: /* INTC_SYSCONFIG */ -+ s->autoidle &= 4; -+ s->autoidle |= (value & 1) << 2; -+ if (value & 2) /* SOFTRESET */ -+ omap_inth_reset(s); -+ return; -+ -+ case 0x48: /* INTC_CONTROL */ -+ s->mask = (value & 4) ? 0 : ~0; /* GLOBALMASK */ -+ if (value & 2) { /* NEWFIQAGR */ -+ qemu_set_irq(s->parent_intr[1], 0); -+ s->new_agr[1] = ~0; -+ omap_inth_update(s, 1); -+ } -+ if (value & 1) { /* NEWIRQAGR */ -+ qemu_set_irq(s->parent_intr[0], 0); -+ s->new_agr[0] = ~0; -+ omap_inth_update(s, 0); -+ } -+ return; -+ -+ case 0x4c: /* INTC_PROTECTION */ -+ /* TODO: Make a bitmap (or sizeof(char)map) of access privileges -+ * for every register, see Chapter 3 and 4 for privileged mode. */ -+ if (value & 1) -+ fprintf(stderr, "%s: protection mode enable attempt\n", -+ __FUNCTION__); -+ return; -+ -+ case 0x50: /* INTC_IDLE */ -+ s->autoidle &= ~3; -+ s->autoidle |= value & 3; -+ return; -+ -+ /* Per-bank registers */ -+ case 0x84: /* INTC_MIR */ -+ bank->mask = value; -+ omap_inth_update(s, 0); -+ omap_inth_update(s, 1); -+ return; -+ -+ case 0x88: /* INTC_MIR_CLEAR */ -+ bank->mask &= ~value; -+ omap_inth_update(s, 0); -+ omap_inth_update(s, 1); -+ return; -+ -+ case 0x8c: /* INTC_MIR_SET */ -+ bank->mask |= value; -+ return; -+ -+ case 0x90: /* INTC_ISR_SET */ -+ bank->irqs |= bank->swi |= value; -+ omap_inth_update(s, 0); -+ omap_inth_update(s, 1); -+ return; -+ -+ case 0x94: /* INTC_ISR_CLEAR */ -+ bank->swi &= ~value; -+ bank->irqs = bank->swi & bank->inputs; -+ return; -+ -+ /* Per-line registers */ -+ case 0x100 ... 0x300: /* INTC_ILR */ -+ bank_no = (offset - 0x100) >> 7; -+ if (bank_no > s->nbanks) -+ break; -+ bank = &s->bank[bank_no]; -+ line_no = (offset & 0x7f) >> 2; -+ bank->priority[line_no] = (value >> 2) & 0x3f; -+ bank->fiq &= ~(1 << line_no); -+ bank->fiq |= (value & 1) << line_no; -+ return; -+ -+ case 0x00: /* INTC_REVISION */ -+ case 0x14: /* INTC_SYSSTATUS */ -+ case 0x40: /* INTC_SIR_IRQ */ -+ case 0x44: /* INTC_SIR_FIQ */ -+ case 0x80: /* INTC_ITR */ -+ case 0x98: /* INTC_PENDING_IRQ */ -+ case 0x9c: /* INTC_PENDING_FIQ */ -+ OMAP_RO_REG(addr); -+ return; -+ } -+ OMAP_BAD_REG(addr); -+} -+ -+static CPUReadMemoryFunc *omap2_inth_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap2_inth_read, -+}; -+ -+static CPUWriteMemoryFunc *omap2_inth_writefn[] = { -+ omap2_inth_write, -+ omap2_inth_write, -+ omap2_inth_write, -+}; -+ -+struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base, -+ int size, int nbanks, qemu_irq **pins, -+ qemu_irq parent_irq, qemu_irq parent_fiq, -+ omap_clk fclk, omap_clk iclk) -+{ -+ int iomemtype; -+ struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) -+ qemu_mallocz(sizeof(struct omap_intr_handler_s) + -+ sizeof(struct omap_intr_handler_bank_s) * nbanks); -+ -+ s->parent_intr[0] = parent_irq; -+ s->parent_intr[1] = parent_fiq; -+ s->base = base; -+ s->nbanks = nbanks; -+ s->level_only = 1; -+ s->pins = qemu_allocate_irqs(omap_set_intr_noedge, s, nbanks * 32); -+ if (pins) -+ *pins = s->pins; -+ -+ omap_inth_reset(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap2_inth_readfn, -+ omap2_inth_writefn, s); -+ cpu_register_physical_memory(s->base, size, iomemtype); -+ -+ return s; -+} -+ - /* MPU OS timers */ - struct omap_mpu_timer_s { - qemu_irq irq; -@@ -1289,6 +1543,8 @@ static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr) - return 0x03310315; - case omap1510: - return 0x03310115; -+ default: -+ cpu_abort(cpu_single_env, "%s: bad mpu model\n", __FUNCTION__); - } - break; - -@@ -1298,6 +1554,8 @@ static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr) - return 0xfb57402f; - case omap1510: - return 0xfb47002f; -+ default: -+ cpu_abort(cpu_single_env, "%s: bad mpu model\n", __FUNCTION__); - } - break; - } -@@ -1722,19 +1980,116 @@ static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base, - /* UARTs */ - struct omap_uart_s { - SerialState *serial; /* TODO */ -+ struct omap_target_agent_s *ta; -+ target_phys_addr_t base; -+ -+ uint8_t eblr; -+ uint8_t syscontrol; -+ uint8_t wkup; -+ uint8_t cfps; - }; - --static void omap_uart_reset(struct omap_uart_s *s) -+void omap_uart_reset(struct omap_uart_s *s) - { -+ s->eblr = 0x00; -+ s->syscontrol = 0; -+ s->wkup = 0x3f; -+ s->cfps = 0x69; - } - - struct omap_uart_s *omap_uart_init(target_phys_addr_t base, -- qemu_irq irq, omap_clk clk, CharDriverState *chr) -+ qemu_irq irq, omap_clk fclk, omap_clk iclk, -+ qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr) - { - struct omap_uart_s *s = (struct omap_uart_s *) - qemu_mallocz(sizeof(struct omap_uart_s)); -- if (chr) -- s->serial = serial_mm_init(base, 2, irq, chr, 1); -+ -+ s->serial = serial_mm_init(base, 2, irq, chr ?: qemu_chr_open("null"), 1); -+ -+ return s; -+} -+ -+static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_uart_s *s = (struct omap_uart_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x48: /* EBLR */ -+ return s->eblr; -+ case 0x50: /* MVR */ -+ return 0x30; -+ case 0x54: /* SYSC */ -+ return s->syscontrol; -+ case 0x58: /* SYSS */ -+ return 1; -+ case 0x5c: /* WER */ -+ return s->wkup; -+ case 0x60: /* CFPS */ -+ return s->cfps; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_uart_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_uart_s *s = (struct omap_uart_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x48: /* EBLR */ -+ s->eblr = value & 0xff; -+ break; -+ case 0x50: /* MVR */ -+ case 0x58: /* SYSS */ -+ OMAP_RO_REG(addr); -+ break; -+ case 0x54: /* SYSC */ -+ s->syscontrol = value & 0x1d; -+ if (value & 2) -+ omap_uart_reset(s); -+ break; -+ case 0x5c: /* WER */ -+ s->wkup = value & 0x7f; -+ break; -+ case 0x60: /* CFPS */ -+ s->cfps = value & 0xff; -+ break; -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static CPUReadMemoryFunc *omap_uart_readfn[] = { -+ omap_uart_read, -+ omap_uart_read, -+ omap_badwidth_read8, -+}; -+ -+static CPUWriteMemoryFunc *omap_uart_writefn[] = { -+ omap_uart_write, -+ omap_uart_write, -+ omap_badwidth_write8, -+}; -+ -+struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta, -+ qemu_irq irq, omap_clk fclk, omap_clk iclk, -+ qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr) -+{ -+ target_phys_addr_t base = omap_l4_attach(ta, 0, 0); -+ struct omap_uart_s *s = omap_uart_init(base, irq, -+ fclk, iclk, txdma, rxdma, chr); -+ int iomemtype = cpu_register_io_memory(0, omap_uart_readfn, -+ omap_uart_writefn, s); -+ -+ s->ta = ta; -+ s->base = base; -+ -+ cpu_register_physical_memory(s->base + 0x20, 0x100, iomemtype); -+ - return s; - } - -@@ -2778,9 +3133,11 @@ struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base, - void omap_uwire_attach(struct omap_uwire_s *s, - struct uwire_slave_s *slave, int chipselect) - { -- if (chipselect < 0 || chipselect > 3) -- cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__, -- chipselect); -+ if (chipselect < 0 || chipselect > 3) { -+ fprintf(stderr, "%s: Bad chipselect %i\n", -+ __FUNCTION__, chipselect); -+ exit(-1); -+ } - - s->chip[chipselect] = slave; - } -@@ -4123,7 +4481,7 @@ static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu) - } - - /* General chip reset */ --static void omap_mpu_reset(void *opaque) -+static void omap1_mpu_reset(void *opaque) - { - struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque; - -@@ -4153,7 +4511,7 @@ static void omap_mpu_reset(void *opaque) - omap_uwire_reset(mpu->microwire); - omap_pwl_reset(mpu); - omap_pwt_reset(mpu); -- omap_i2c_reset(mpu->i2c); -+ omap_i2c_reset(mpu->i2c[0]); - omap_rtc_reset(mpu->rtc); - omap_mcbsp_reset(mpu->mcbsp1); - omap_mcbsp_reset(mpu->mcbsp2); -@@ -4205,7 +4563,7 @@ static void omap_setup_dsp_mapping(const struct omap_map_s *map) - } - } - --static void omap_mpu_wakeup(void *opaque, int irq, int req) -+void omap_mpu_wakeup(void *opaque, int irq, int req) - { - struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque; - -@@ -4213,7 +4571,7 @@ static void omap_mpu_wakeup(void *opaque, int irq, int req) - cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB); - } - --static const struct dma_irq_map omap_dma_irq_map[] = { -+static const struct dma_irq_map omap1_dma_irq_map[] = { - { 0, OMAP_INT_DMA_CH0_6 }, - { 0, OMAP_INT_DMA_CH1_7 }, - { 0, OMAP_INT_DMA_CH2_8 }, -@@ -4307,17 +4665,16 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, - omap_clkm_init(0xfffece00, 0xe1008000, s); - - cpu_irq = arm_pic_init_cpu(s->env); -- s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, -+ s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0], - cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ], - omap_findclk(s, "arminth_ck")); -- s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, -+ s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1], - s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL, - omap_findclk(s, "arminth_ck")); -- s->irq[0] = s->ih[0]->pins; -- s->irq[1] = s->ih[1]->pins; - - for (i = 0; i < 6; i ++) -- dma_irqs[i] = s->irq[omap_dma_irq_map[i].ih][omap_dma_irq_map[i].intr]; -+ dma_irqs[i] = -+ s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr]; - s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD], - s, omap_findclk(s, "dma_ck"), omap_dma_3_1); - -@@ -4367,12 +4724,18 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, - - s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1], - omap_findclk(s, "uart1_ck"), -+ omap_findclk(s, "uart1_ck"), -+ s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX], - serial_hds[0]); - s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2], - omap_findclk(s, "uart2_ck"), -+ omap_findclk(s, "uart2_ck"), -+ s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX], - serial_hds[0] ? serial_hds[1] : 0); - s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3], - omap_findclk(s, "uart3_ck"), -+ omap_findclk(s, "uart3_ck"), -+ s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX], - serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0); - - omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1")); -@@ -4401,7 +4764,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, - omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck")); - omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck")); - -- s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C], -+ s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C], - &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck")); - - s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER], -@@ -4435,7 +4798,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, - omap_setup_dsp_mapping(omap15xx_dsp_mm); - omap_setup_mpui_io(s); - -- qemu_register_reset(omap_mpu_reset, s); -+ qemu_register_reset(omap1_mpu_reset, s); - - return s; - } -diff --git a/hw/omap2.c b/hw/omap2.c -new file mode 100644 -index 0000000..1e51197 ---- /dev/null -+++ b/hw/omap2.c -@@ -0,0 +1,3872 @@ -+/* -+ * TI OMAP processors emulation. -+ * -+ * Copyright (C) 2007-2008 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+#include "hw.h" -+#include "arm-misc.h" -+#include "omap.h" -+#include "sysemu.h" -+#include "qemu-timer.h" -+#include "qemu-char.h" -+#include "flash.h" -+/* We use pc-style serial ports. */ -+#include "pc.h" -+ -+/* GP timers */ -+struct omap_gp_timer_s { -+ qemu_irq irq; -+ qemu_irq wkup; -+ qemu_irq in; -+ qemu_irq out; -+ omap_clk clk; -+ target_phys_addr_t base; -+ QEMUTimer *timer; -+ QEMUTimer *match; -+ struct omap_target_agent_s *ta; -+ -+ int in_val; -+ int out_val; -+ int64_t time; -+ int64_t rate; -+ int64_t ticks_per_sec; -+ -+ int16_t config; -+ int status; -+ int it_ena; -+ int wu_ena; -+ int enable; -+ int inout; -+ int capt2; -+ int pt; -+ enum { -+ gpt_trigger_none, gpt_trigger_overflow, gpt_trigger_both -+ } trigger; -+ enum { -+ gpt_capture_none, gpt_capture_rising, -+ gpt_capture_falling, gpt_capture_both -+ } capture; -+ int scpwm; -+ int ce; -+ int pre; -+ int ptv; -+ int ar; -+ int st; -+ int posted; -+ uint32_t val; -+ uint32_t load_val; -+ uint32_t capture_val[2]; -+ uint32_t match_val; -+ int capt_num; -+ -+ uint16_t writeh; /* LSB */ -+ uint16_t readh; /* MSB */ -+}; -+ -+#define GPT_TCAR_IT (1 << 2) -+#define GPT_OVF_IT (1 << 1) -+#define GPT_MAT_IT (1 << 0) -+ -+static inline void omap_gp_timer_intr(struct omap_gp_timer_s *timer, int it) -+{ -+ if (timer->it_ena & it) { -+ if (!timer->status) -+ qemu_irq_raise(timer->irq); -+ -+ timer->status |= it; -+ /* Or are the status bits set even when masked? -+ * i.e. is masking applied before or after the status register? */ -+ } -+ -+ if (timer->wu_ena & it) -+ qemu_irq_pulse(timer->wkup); -+} -+ -+static inline void omap_gp_timer_out(struct omap_gp_timer_s *timer, int level) -+{ -+ if (!timer->inout && timer->out_val != level) { -+ timer->out_val = level; -+ qemu_set_irq(timer->out, level); -+ } -+} -+ -+static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer) -+{ -+ uint64_t distance; -+ -+ if (timer->st && timer->rate) { -+ distance = qemu_get_clock(vm_clock) - timer->time; -+ distance = muldiv64(distance, timer->rate, timer->ticks_per_sec); -+ -+ if (distance >= 0xffffffff - timer->val) -+ return 0xffffffff; -+ else -+ return timer->val + distance; -+ } else -+ return timer->val; -+} -+ -+static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer) -+{ -+ if (timer->st) { -+ timer->val = omap_gp_timer_read(timer); -+ timer->time = qemu_get_clock(vm_clock); -+ } -+} -+ -+static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer) -+{ -+ int64_t expires, matches; -+ -+ if (timer->st && timer->rate) { -+ expires = muldiv64(0x100000000ll - timer->val, -+ timer->ticks_per_sec, timer->rate); -+ qemu_mod_timer(timer->timer, timer->time + expires); -+ -+ if (timer->ce && timer->match_val >= timer->val) { -+ matches = muldiv64(timer->match_val - timer->val, -+ timer->ticks_per_sec, timer->rate); -+ qemu_mod_timer(timer->match, timer->time + matches); -+ } else -+ qemu_del_timer(timer->match); -+ } else { -+ qemu_del_timer(timer->timer); -+ qemu_del_timer(timer->match); -+ omap_gp_timer_out(timer, timer->scpwm); -+ } -+} -+ -+static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer) -+{ -+ if (timer->pt) -+ /* TODO in overflow-and-match mode if the first event to -+ * occurs is the match, don't toggle. */ -+ omap_gp_timer_out(timer, !timer->out_val); -+ else -+ /* TODO inverted pulse on timer->out_val == 1? */ -+ qemu_irq_pulse(timer->out); -+} -+ -+static void omap_gp_timer_tick(void *opaque) -+{ -+ struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque; -+ -+ if (!timer->ar) { -+ timer->st = 0; -+ timer->val = 0; -+ } else { -+ timer->val = timer->load_val; -+ timer->time = qemu_get_clock(vm_clock); -+ } -+ -+ if (timer->trigger == gpt_trigger_overflow || -+ timer->trigger == gpt_trigger_both) -+ omap_gp_timer_trigger(timer); -+ -+ omap_gp_timer_intr(timer, GPT_OVF_IT); -+ omap_gp_timer_update(timer); -+} -+ -+static void omap_gp_timer_match(void *opaque) -+{ -+ struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque; -+ -+ if (timer->trigger == gpt_trigger_both) -+ omap_gp_timer_trigger(timer); -+ -+ omap_gp_timer_intr(timer, GPT_MAT_IT); -+} -+ -+static void omap_gp_timer_input(void *opaque, int line, int on) -+{ -+ struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque; -+ int trigger; -+ -+ switch (s->capture) { -+ default: -+ case gpt_capture_none: -+ trigger = 0; -+ break; -+ case gpt_capture_rising: -+ trigger = !s->in_val && on; -+ break; -+ case gpt_capture_falling: -+ trigger = s->in_val && !on; -+ break; -+ case gpt_capture_both: -+ trigger = (s->in_val == !on); -+ break; -+ } -+ s->in_val = on; -+ -+ if (s->inout && trigger && s->capt_num < 2) { -+ s->capture_val[s->capt_num] = omap_gp_timer_read(s); -+ -+ if (s->capt2 == s->capt_num ++) -+ omap_gp_timer_intr(s, GPT_TCAR_IT); -+ } -+} -+ -+static void omap_gp_timer_clk_update(void *opaque, int line, int on) -+{ -+ struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque; -+ -+ omap_gp_timer_sync(timer); -+ timer->rate = on ? omap_clk_getrate(timer->clk) : 0; -+ omap_gp_timer_update(timer); -+} -+ -+static void omap_gp_timer_clk_setup(struct omap_gp_timer_s *timer) -+{ -+ omap_clk_adduser(timer->clk, -+ qemu_allocate_irqs(omap_gp_timer_clk_update, timer, 1)[0]); -+ timer->rate = omap_clk_getrate(timer->clk); -+} -+ -+static void omap_gp_timer_reset(struct omap_gp_timer_s *s) -+{ -+ s->config = 0x000; -+ s->status = 0; -+ s->it_ena = 0; -+ s->wu_ena = 0; -+ s->inout = 0; -+ s->capt2 = 0; -+ s->capt_num = 0; -+ s->pt = 0; -+ s->trigger = gpt_trigger_none; -+ s->capture = gpt_capture_none; -+ s->scpwm = 0; -+ s->ce = 0; -+ s->pre = 0; -+ s->ptv = 0; -+ s->ar = 0; -+ s->st = 0; -+ s->posted = 1; -+ s->val = 0x00000000; -+ s->load_val = 0x00000000; -+ s->capture_val[0] = 0x00000000; -+ s->capture_val[1] = 0x00000000; -+ s->match_val = 0x00000000; -+ omap_gp_timer_update(s); -+} -+ -+static uint32_t omap_gp_timer_readw(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x00: /* TIDR */ -+ return 0x21; -+ -+ case 0x10: /* TIOCP_CFG */ -+ return s->config; -+ -+ case 0x14: /* TISTAT */ -+ /* ??? When's this bit reset? */ -+ return 1; /* RESETDONE */ -+ -+ case 0x18: /* TISR */ -+ return s->status; -+ -+ case 0x1c: /* TIER */ -+ return s->it_ena; -+ -+ case 0x20: /* TWER */ -+ return s->wu_ena; -+ -+ case 0x24: /* TCLR */ -+ return (s->inout << 14) | -+ (s->capt2 << 13) | -+ (s->pt << 12) | -+ (s->trigger << 10) | -+ (s->capture << 8) | -+ (s->scpwm << 7) | -+ (s->ce << 6) | -+ (s->pre << 5) | -+ (s->ptv << 2) | -+ (s->ar << 1) | -+ (s->st << 0); -+ -+ case 0x28: /* TCRR */ -+ return omap_gp_timer_read(s); -+ -+ case 0x2c: /* TLDR */ -+ return s->load_val; -+ -+ case 0x30: /* TTGR */ -+ return 0xffffffff; -+ -+ case 0x34: /* TWPS */ -+ return 0x00000000; /* No posted writes pending. */ -+ -+ case 0x38: /* TMAR */ -+ return s->match_val; -+ -+ case 0x3c: /* TCAR1 */ -+ return s->capture_val[0]; -+ -+ case 0x40: /* TSICR */ -+ return s->posted << 2; -+ -+ case 0x44: /* TCAR2 */ -+ return s->capture_val[1]; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static uint32_t omap_gp_timer_readh(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque; -+ uint32_t ret; -+ -+ if (addr & 2) -+ return s->readh; -+ else { -+ ret = omap_gp_timer_readw(opaque, addr); -+ s->readh = ret >> 16; -+ return ret & 0xffff; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_gp_timer_readfn[] = { -+ omap_badwidth_read32, -+ omap_gp_timer_readh, -+ omap_gp_timer_readw, -+}; -+ -+static void omap_gp_timer_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x00: /* TIDR */ -+ case 0x14: /* TISTAT */ -+ case 0x34: /* TWPS */ -+ case 0x3c: /* TCAR1 */ -+ case 0x44: /* TCAR2 */ -+ OMAP_RO_REG(addr); -+ break; -+ -+ case 0x10: /* TIOCP_CFG */ -+ s->config = value & 0x33d; -+ if (((value >> 3) & 3) == 3) /* IDLEMODE */ -+ fprintf(stderr, "%s: illegal IDLEMODE value in TIOCP_CFG\n", -+ __FUNCTION__); -+ if (value & 2) /* SOFTRESET */ -+ omap_gp_timer_reset(s); -+ break; -+ -+ case 0x18: /* TISR */ -+ if (value & GPT_TCAR_IT) -+ s->capt_num = 0; -+ if (s->status && !(s->status &= ~value)) -+ qemu_irq_lower(s->irq); -+ break; -+ -+ case 0x1c: /* TIER */ -+ s->it_ena = value & 7; -+ break; -+ -+ case 0x20: /* TWER */ -+ s->wu_ena = value & 7; -+ break; -+ -+ case 0x24: /* TCLR */ -+ omap_gp_timer_sync(s); -+ s->inout = (value >> 14) & 1; -+ s->capt2 = (value >> 13) & 1; -+ s->pt = (value >> 12) & 1; -+ s->trigger = (value >> 10) & 3; -+ if (s->capture == gpt_capture_none && -+ ((value >> 8) & 3) != gpt_capture_none) -+ s->capt_num = 0; -+ s->capture = (value >> 8) & 3; -+ s->scpwm = (value >> 7) & 1; -+ s->ce = (value >> 6) & 1; -+ s->pre = (value >> 5) & 1; -+ s->ptv = (value >> 2) & 7; -+ s->ar = (value >> 1) & 1; -+ s->st = (value >> 0) & 1; -+ if (s->inout && s->trigger != gpt_trigger_none) -+ fprintf(stderr, "%s: GP timer pin must be an output " -+ "for this trigger mode\n", __FUNCTION__); -+ if (!s->inout && s->capture != gpt_capture_none) -+ fprintf(stderr, "%s: GP timer pin must be an input " -+ "for this capture mode\n", __FUNCTION__); -+ if (s->trigger == gpt_trigger_none) -+ omap_gp_timer_out(s, s->scpwm); -+ /* TODO: make sure this doesn't overflow 32-bits */ -+ s->ticks_per_sec = ticks_per_sec << (s->pre ? s->ptv + 1 : 0); -+ omap_gp_timer_update(s); -+ break; -+ -+ case 0x28: /* TCRR */ -+ s->time = qemu_get_clock(vm_clock); -+ s->val = value; -+ omap_gp_timer_update(s); -+ break; -+ -+ case 0x2c: /* TLDR */ -+ s->load_val = value; -+ break; -+ -+ case 0x30: /* TTGR */ -+ s->time = qemu_get_clock(vm_clock); -+ s->val = s->load_val; -+ omap_gp_timer_update(s); -+ break; -+ -+ case 0x38: /* TMAR */ -+ omap_gp_timer_sync(s); -+ s->match_val = value; -+ omap_gp_timer_update(s); -+ break; -+ -+ case 0x40: /* TSICR */ -+ s->posted = (value >> 2) & 1; -+ if (value & 2) /* How much exactly are we supposed to reset? */ -+ omap_gp_timer_reset(s); -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static void omap_gp_timer_writeh(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque; -+ -+ if (addr & 2) -+ return omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh); -+ else -+ s->writeh = (uint16_t) value; -+} -+ -+static CPUWriteMemoryFunc *omap_gp_timer_writefn[] = { -+ omap_badwidth_write32, -+ omap_gp_timer_writeh, -+ omap_gp_timer_write, -+}; -+ -+struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta, -+ qemu_irq irq, omap_clk fclk, omap_clk iclk) -+{ -+ int iomemtype; -+ struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) -+ qemu_mallocz(sizeof(struct omap_gp_timer_s)); -+ -+ s->ta = ta; -+ s->irq = irq; -+ s->clk = fclk; -+ s->timer = qemu_new_timer(vm_clock, omap_gp_timer_tick, s); -+ s->match = qemu_new_timer(vm_clock, omap_gp_timer_match, s); -+ s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0]; -+ omap_gp_timer_reset(s); -+ omap_gp_timer_clk_setup(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap_gp_timer_readfn, -+ omap_gp_timer_writefn, s); -+ s->base = omap_l4_attach(ta, 0, iomemtype); -+ -+ return s; -+} -+ -+/* 32-kHz Sync Timer of the OMAP2 */ -+static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) { -+ return muldiv64(qemu_get_clock(vm_clock), 0x8000, ticks_per_sec); -+} -+ -+static void omap_synctimer_reset(struct omap_synctimer_s *s) -+{ -+ s->val = omap_synctimer_read(s); -+} -+ -+static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x00: /* 32KSYNCNT_REV */ -+ return 0x21; -+ -+ case 0x10: /* CR */ -+ return omap_synctimer_read(s) - s->val; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque; -+ uint32_t ret; -+ -+ if (addr & 2) -+ return s->readh; -+ else { -+ ret = omap_synctimer_readw(opaque, addr); -+ s->readh = ret >> 16; -+ return ret & 0xffff; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_synctimer_readfn[] = { -+ omap_badwidth_read32, -+ omap_synctimer_readh, -+ omap_synctimer_readw, -+}; -+ -+static void omap_synctimer_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ OMAP_BAD_REG(addr); -+} -+ -+static CPUWriteMemoryFunc *omap_synctimer_writefn[] = { -+ omap_badwidth_write32, -+ omap_synctimer_write, -+ omap_synctimer_write, -+}; -+ -+void omap_synctimer_init(struct omap_target_agent_s *ta, -+ struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk) -+{ -+ struct omap_synctimer_s *s = &mpu->synctimer; -+ -+ omap_synctimer_reset(s); -+ s->base = omap_l4_attach(ta, 0, cpu_register_io_memory(0, -+ omap_synctimer_readfn, omap_synctimer_writefn, s)); -+} -+ -+/* General-Purpose Interface of OMAP2 */ -+struct omap2_gpio_s { -+ target_phys_addr_t base; -+ qemu_irq irq[2]; -+ qemu_irq wkup; -+ qemu_irq *in; -+ qemu_irq handler[32]; -+ -+ uint8_t config[2]; -+ uint32_t inputs; -+ uint32_t outputs; -+ uint32_t dir; -+ uint32_t level[2]; -+ uint32_t edge[2]; -+ uint32_t mask[2]; -+ uint32_t wumask; -+ uint32_t ints[2]; -+ uint32_t debounce; -+ uint8_t delay; -+}; -+ -+static inline void omap_gpio_module_int_update(struct omap2_gpio_s *s, -+ int line) -+{ -+ qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]); -+} -+ -+static void omap_gpio_module_wake(struct omap2_gpio_s *s, int line) -+{ -+ if (!(s->config[0] & (1 << 2))) /* ENAWAKEUP */ -+ return; -+ if (!(s->config[0] & (3 << 3))) /* Force Idle */ -+ return; -+ if (!(s->wumask & (1 << line))) -+ return; -+ -+ qemu_irq_raise(s->wkup); -+} -+ -+static inline void omap_gpio_module_out_update(struct omap2_gpio_s *s, -+ uint32_t diff) -+{ -+ int ln; -+ -+ s->outputs ^= diff; -+ diff &= ~s->dir; -+ while ((ln = ffs(diff))) { -+ ln --; -+ qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1); -+ diff &= ~(1 << ln); -+ } -+} -+ -+static void omap_gpio_module_level_update(struct omap2_gpio_s *s, int line) -+{ -+ s->ints[line] |= s->dir & -+ ((s->inputs & s->level[1]) | (~s->inputs & s->level[0])); -+ omap_gpio_module_int_update(s, line); -+} -+ -+static inline void omap_gpio_module_int(struct omap2_gpio_s *s, int line) -+{ -+ s->ints[0] |= 1 << line; -+ omap_gpio_module_int_update(s, 0); -+ s->ints[1] |= 1 << line; -+ omap_gpio_module_int_update(s, 1); -+ omap_gpio_module_wake(s, line); -+} -+ -+static void omap_gpio_module_set(void *opaque, int line, int level) -+{ -+ struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; -+ -+ if (level) { -+ if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1])) -+ omap_gpio_module_int(s, line); -+ s->inputs |= 1 << line; -+ } else { -+ if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0])) -+ omap_gpio_module_int(s, line); -+ s->inputs &= ~(1 << line); -+ } -+} -+ -+static void omap_gpio_module_reset(struct omap2_gpio_s *s) -+{ -+ s->config[0] = 0; -+ s->config[1] = 2; -+ s->ints[0] = 0; -+ s->ints[1] = 0; -+ s->mask[0] = 0; -+ s->mask[1] = 0; -+ s->wumask = 0; -+ s->dir = ~0; -+ s->level[0] = 0; -+ s->level[1] = 0; -+ s->edge[0] = 0; -+ s->edge[1] = 0; -+ s->debounce = 0; -+ s->delay = 0; -+} -+ -+static uint32_t omap_gpio_module_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x00: /* GPIO_REVISION */ -+ return 0x18; -+ -+ case 0x10: /* GPIO_SYSCONFIG */ -+ return s->config[0]; -+ -+ case 0x14: /* GPIO_SYSSTATUS */ -+ return 0x01; -+ -+ case 0x18: /* GPIO_IRQSTATUS1 */ -+ return s->ints[0]; -+ -+ case 0x1c: /* GPIO_IRQENABLE1 */ -+ case 0x60: /* GPIO_CLEARIRQENABLE1 */ -+ case 0x64: /* GPIO_SETIRQENABLE1 */ -+ return s->mask[0]; -+ -+ case 0x20: /* GPIO_WAKEUPENABLE */ -+ case 0x80: /* GPIO_CLEARWKUENA */ -+ case 0x84: /* GPIO_SETWKUENA */ -+ return s->wumask; -+ -+ case 0x28: /* GPIO_IRQSTATUS2 */ -+ return s->ints[1]; -+ -+ case 0x2c: /* GPIO_IRQENABLE2 */ -+ case 0x70: /* GPIO_CLEARIRQENABLE2 */ -+ case 0x74: /* GPIO_SETIREQNEABLE2 */ -+ return s->mask[1]; -+ -+ case 0x30: /* GPIO_CTRL */ -+ return s->config[1]; -+ -+ case 0x34: /* GPIO_OE */ -+ return s->dir; -+ -+ case 0x38: /* GPIO_DATAIN */ -+ return s->inputs; -+ -+ case 0x3c: /* GPIO_DATAOUT */ -+ case 0x90: /* GPIO_CLEARDATAOUT */ -+ case 0x94: /* GPIO_SETDATAOUT */ -+ return s->outputs; -+ -+ case 0x40: /* GPIO_LEVELDETECT0 */ -+ return s->level[0]; -+ -+ case 0x44: /* GPIO_LEVELDETECT1 */ -+ return s->level[1]; -+ -+ case 0x48: /* GPIO_RISINGDETECT */ -+ return s->edge[0]; -+ -+ case 0x4c: /* GPIO_FALLINGDETECT */ -+ return s->edge[1]; -+ -+ case 0x50: /* GPIO_DEBOUNCENABLE */ -+ return s->debounce; -+ -+ case 0x54: /* GPIO_DEBOUNCINGTIME */ -+ return s->delay; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_gpio_module_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; -+ int offset = addr - s->base; -+ uint32_t diff; -+ int ln; -+ -+ switch (offset) { -+ case 0x00: /* GPIO_REVISION */ -+ case 0x14: /* GPIO_SYSSTATUS */ -+ case 0x38: /* GPIO_DATAIN */ -+ OMAP_RO_REG(addr); -+ break; -+ -+ case 0x10: /* GPIO_SYSCONFIG */ -+ if (((value >> 3) & 3) == 3) -+ fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__); -+ if (value & 2) -+ omap_gpio_module_reset(s); -+ s->config[0] = value & 0x1d; -+ break; -+ -+ case 0x18: /* GPIO_IRQSTATUS1 */ -+ if (s->ints[0] & value) { -+ s->ints[0] &= ~value; -+ omap_gpio_module_level_update(s, 0); -+ } -+ break; -+ -+ case 0x1c: /* GPIO_IRQENABLE1 */ -+ s->mask[0] = value; -+ omap_gpio_module_int_update(s, 0); -+ break; -+ -+ case 0x20: /* GPIO_WAKEUPENABLE */ -+ s->wumask = value; -+ break; -+ -+ case 0x28: /* GPIO_IRQSTATUS2 */ -+ if (s->ints[1] & value) { -+ s->ints[1] &= ~value; -+ omap_gpio_module_level_update(s, 1); -+ } -+ break; -+ -+ case 0x2c: /* GPIO_IRQENABLE2 */ -+ s->mask[1] = value; -+ omap_gpio_module_int_update(s, 1); -+ break; -+ -+ case 0x30: /* GPIO_CTRL */ -+ s->config[1] = value & 7; -+ break; -+ -+ case 0x34: /* GPIO_OE */ -+ diff = s->outputs & (s->dir ^ value); -+ s->dir = value; -+ -+ value = s->outputs & ~s->dir; -+ while ((ln = ffs(diff))) { -+ diff &= ~(1 <<-- ln); -+ qemu_set_irq(s->handler[ln], (value >> ln) & 1); -+ } -+ -+ omap_gpio_module_level_update(s, 0); -+ omap_gpio_module_level_update(s, 1); -+ break; -+ -+ case 0x3c: /* GPIO_DATAOUT */ -+ omap_gpio_module_out_update(s, s->outputs ^ value); -+ break; -+ -+ case 0x40: /* GPIO_LEVELDETECT0 */ -+ s->level[0] = value; -+ omap_gpio_module_level_update(s, 0); -+ omap_gpio_module_level_update(s, 1); -+ break; -+ -+ case 0x44: /* GPIO_LEVELDETECT1 */ -+ s->level[1] = value; -+ omap_gpio_module_level_update(s, 0); -+ omap_gpio_module_level_update(s, 1); -+ break; -+ -+ case 0x48: /* GPIO_RISINGDETECT */ -+ s->edge[0] = value; -+ break; -+ -+ case 0x4c: /* GPIO_FALLINGDETECT */ -+ s->edge[1] = value; -+ break; -+ -+ case 0x50: /* GPIO_DEBOUNCENABLE */ -+ s->debounce = value; -+ break; -+ -+ case 0x54: /* GPIO_DEBOUNCINGTIME */ -+ s->delay = value; -+ break; -+ -+ case 0x60: /* GPIO_CLEARIRQENABLE1 */ -+ s->mask[0] &= ~value; -+ omap_gpio_module_int_update(s, 0); -+ break; -+ -+ case 0x64: /* GPIO_SETIRQENABLE1 */ -+ s->mask[0] |= value; -+ omap_gpio_module_int_update(s, 0); -+ break; -+ -+ case 0x70: /* GPIO_CLEARIRQENABLE2 */ -+ s->mask[1] &= ~value; -+ omap_gpio_module_int_update(s, 1); -+ break; -+ -+ case 0x74: /* GPIO_SETIREQNEABLE2 */ -+ s->mask[1] |= value; -+ omap_gpio_module_int_update(s, 1); -+ break; -+ -+ case 0x80: /* GPIO_CLEARWKUENA */ -+ s->wumask &= ~value; -+ break; -+ -+ case 0x84: /* GPIO_SETWKUENA */ -+ s->wumask |= value; -+ break; -+ -+ case 0x90: /* GPIO_CLEARDATAOUT */ -+ omap_gpio_module_out_update(s, s->outputs & value); -+ break; -+ -+ case 0x94: /* GPIO_SETDATAOUT */ -+ omap_gpio_module_out_update(s, ~s->outputs & value); -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+} -+ -+static uint32_t omap_gpio_module_readp(void *opaque, target_phys_addr_t addr) -+{ -+ return omap_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3); -+} -+ -+static void omap_gpio_module_writep(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque; -+ int offset = addr - s->base; -+ uint32_t cur = 0; -+ uint32_t mask = 0xffff; -+ -+ switch (offset & ~3) { -+ case 0x00: /* GPIO_REVISION */ -+ case 0x14: /* GPIO_SYSSTATUS */ -+ case 0x38: /* GPIO_DATAIN */ -+ OMAP_RO_REG(addr); -+ break; -+ -+ case 0x10: /* GPIO_SYSCONFIG */ -+ case 0x1c: /* GPIO_IRQENABLE1 */ -+ case 0x20: /* GPIO_WAKEUPENABLE */ -+ case 0x2c: /* GPIO_IRQENABLE2 */ -+ case 0x30: /* GPIO_CTRL */ -+ case 0x34: /* GPIO_OE */ -+ case 0x3c: /* GPIO_DATAOUT */ -+ case 0x40: /* GPIO_LEVELDETECT0 */ -+ case 0x44: /* GPIO_LEVELDETECT1 */ -+ case 0x48: /* GPIO_RISINGDETECT */ -+ case 0x4c: /* GPIO_FALLINGDETECT */ -+ case 0x50: /* GPIO_DEBOUNCENABLE */ -+ case 0x54: /* GPIO_DEBOUNCINGTIME */ -+ cur = omap_gpio_module_read(opaque, addr & ~3) & -+ ~(mask << ((addr & 3) << 3)); -+ -+ /* Fall through. */ -+ case 0x18: /* GPIO_IRQSTATUS1 */ -+ case 0x28: /* GPIO_IRQSTATUS2 */ -+ case 0x60: /* GPIO_CLEARIRQENABLE1 */ -+ case 0x64: /* GPIO_SETIRQENABLE1 */ -+ case 0x70: /* GPIO_CLEARIRQENABLE2 */ -+ case 0x74: /* GPIO_SETIREQNEABLE2 */ -+ case 0x80: /* GPIO_CLEARWKUENA */ -+ case 0x84: /* GPIO_SETWKUENA */ -+ case 0x90: /* GPIO_CLEARDATAOUT */ -+ case 0x94: /* GPIO_SETDATAOUT */ -+ value <<= (addr & 3) << 3; -+ omap_gpio_module_write(opaque, addr, cur | value); -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_gpio_module_readfn[] = { -+ omap_gpio_module_readp, -+ omap_gpio_module_readp, -+ omap_gpio_module_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_gpio_module_writefn[] = { -+ omap_gpio_module_writep, -+ omap_gpio_module_writep, -+ omap_gpio_module_write, -+}; -+ -+static void omap_gpio_module_init(struct omap2_gpio_s *s, -+ struct omap_target_agent_s *ta, int region, -+ qemu_irq mpu, qemu_irq dsp, qemu_irq wkup, -+ omap_clk fclk, omap_clk iclk) -+{ -+ int iomemtype; -+ -+ s->irq[0] = mpu; -+ s->irq[1] = dsp; -+ s->wkup = wkup; -+ s->in = qemu_allocate_irqs(omap_gpio_module_set, s, 32); -+ -+ iomemtype = cpu_register_io_memory(0, omap_gpio_module_readfn, -+ omap_gpio_module_writefn, s); -+ s->base = omap_l4_attach(ta, region, iomemtype); -+} -+ -+struct omap_gpif_s { -+ struct omap2_gpio_s module[5]; -+ int modules; -+ -+ target_phys_addr_t topbase; -+ int autoidle; -+ int gpo; -+}; -+ -+static void omap_gpif_reset(struct omap_gpif_s *s) -+{ -+ int i; -+ -+ for (i = 0; i < s->modules; i ++) -+ omap_gpio_module_reset(s->module + i); -+ -+ s->autoidle = 0; -+ s->gpo = 0; -+} -+ -+static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_gpif_s *s = (struct omap_gpif_s *) opaque; -+ int offset = addr - s->topbase; -+ -+ switch (offset) { -+ case 0x00: /* IPGENERICOCPSPL_REVISION */ -+ return 0x18; -+ -+ case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */ -+ return s->autoidle; -+ -+ case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */ -+ return 0x01; -+ -+ case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */ -+ return 0x00; -+ -+ case 0x40: /* IPGENERICOCPSPL_GPO */ -+ return s->gpo; -+ -+ case 0x50: /* IPGENERICOCPSPL_GPI */ -+ return 0x00; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_gpif_s *s = (struct omap_gpif_s *) opaque; -+ int offset = addr - s->topbase; -+ -+ switch (offset) { -+ case 0x00: /* IPGENERICOCPSPL_REVISION */ -+ case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */ -+ case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */ -+ case 0x50: /* IPGENERICOCPSPL_GPI */ -+ OMAP_RO_REG(addr); -+ break; -+ -+ case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */ -+ if (value & (1 << 1)) /* SOFTRESET */ -+ omap_gpif_reset(s); -+ s->autoidle = value & 1; -+ break; -+ -+ case 0x40: /* IPGENERICOCPSPL_GPO */ -+ s->gpo = value & 1; -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_gpif_top_readfn[] = { -+ omap_gpif_top_read, -+ omap_gpif_top_read, -+ omap_gpif_top_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_gpif_top_writefn[] = { -+ omap_gpif_top_write, -+ omap_gpif_top_write, -+ omap_gpif_top_write, -+}; -+ -+struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta, -+ qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules) -+{ -+ int iomemtype, i; -+ struct omap_gpif_s *s = (struct omap_gpif_s *) -+ qemu_mallocz(sizeof(struct omap_gpif_s)); -+ int region[4] = { 0, 2, 4, 5 }; -+ -+ s->modules = modules; -+ for (i = 0; i < modules; i ++) -+ omap_gpio_module_init(s->module + i, ta, region[i], -+ irq[i], 0, 0, fclk[i], iclk); -+ -+ omap_gpif_reset(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap_gpif_top_readfn, -+ omap_gpif_top_writefn, s); -+ s->topbase = omap_l4_attach(ta, 1, iomemtype); -+ -+ return s; -+} -+ -+qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start) -+{ -+ if (start >= s->modules * 32 || start < 0) -+ cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", -+ __FUNCTION__, start); -+ return s->module[start >> 5].in + (start & 31); -+} -+ -+void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler) -+{ -+ if (line >= s->modules * 32 || line < 0) -+ cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line); -+ s->module[line >> 5].handler[line & 31] = handler; -+} -+ -+/* Multichannel SPI */ -+struct omap_mcspi_s { -+ target_phys_addr_t base; -+ qemu_irq irq; -+ int chnum; -+ -+ uint32_t sysconfig; -+ uint32_t systest; -+ uint32_t irqst; -+ uint32_t irqen; -+ uint32_t wken; -+ uint32_t control; -+ -+ struct omap_mcspi_ch_s { -+ qemu_irq txdrq; -+ qemu_irq rxdrq; -+ uint32_t (*txrx)(void *opaque, uint32_t); -+ void *opaque; -+ -+ uint32_t tx; -+ uint32_t rx; -+ -+ uint32_t config; -+ uint32_t status; -+ uint32_t control; -+ } ch[4]; -+}; -+ -+static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s) -+{ -+ qemu_set_irq(s->irq, s->irqst & s->irqen); -+} -+ -+static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch) -+{ -+ qemu_set_irq(ch->txdrq, -+ (ch->control & 1) && /* EN */ -+ (ch->config & (1 << 14)) && /* DMAW */ -+ (ch->status & (1 << 1)) && /* TXS */ -+ ((ch->config >> 12) & 3) != 1); /* TRM */ -+ qemu_set_irq(ch->rxdrq, -+ (ch->control & 1) && /* EN */ -+ (ch->config & (1 << 15)) && /* DMAW */ -+ (ch->status & (1 << 0)) && /* RXS */ -+ ((ch->config >> 12) & 3) != 2); /* TRM */ -+} -+ -+static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum) -+{ -+ struct omap_mcspi_ch_s *ch = s->ch + chnum; -+ -+ if (!(ch->control & 1)) /* EN */ -+ return; -+ if ((ch->status & (1 << 0)) && /* RXS */ -+ ((ch->config >> 12) & 3) != 2 && /* TRM */ -+ !(ch->config & (1 << 19))) /* TURBO */ -+ goto intr_update; -+ if ((ch->status & (1 << 1)) && /* TXS */ -+ ((ch->config >> 12) & 3) != 1) /* TRM */ -+ goto intr_update; -+ -+ if (!(s->control & 1) || /* SINGLE */ -+ (ch->config & (1 << 20))) { /* FORCE */ -+ if (ch->txrx) -+ ch->rx = ch->txrx(ch->opaque, ch->tx); -+ } -+ -+ ch->tx = 0; -+ ch->status |= 1 << 2; /* EOT */ -+ ch->status |= 1 << 1; /* TXS */ -+ if (((ch->config >> 12) & 3) != 2) /* TRM */ -+ ch->status |= 1 << 0; /* RXS */ -+ -+intr_update: -+ if ((ch->status & (1 << 0)) && /* RXS */ -+ ((ch->config >> 12) & 3) != 2 && /* TRM */ -+ !(ch->config & (1 << 19))) /* TURBO */ -+ s->irqst |= 1 << (2 + 4 * chnum); /* RX_FULL */ -+ if ((ch->status & (1 << 1)) && /* TXS */ -+ ((ch->config >> 12) & 3) != 1) /* TRM */ -+ s->irqst |= 1 << (0 + 4 * chnum); /* TX_EMPTY */ -+ omap_mcspi_interrupt_update(s); -+ omap_mcspi_dmarequest_update(ch); -+} -+ -+static void omap_mcspi_reset(struct omap_mcspi_s *s) -+{ -+ int ch; -+ -+ s->sysconfig = 0; -+ s->systest = 0; -+ s->irqst = 0; -+ s->irqen = 0; -+ s->wken = 0; -+ s->control = 4; -+ -+ for (ch = 0; ch < 4; ch ++) { -+ s->ch[ch].config = 0x060000; -+ s->ch[ch].status = 2; /* TXS */ -+ s->ch[ch].control = 0; -+ -+ omap_mcspi_dmarequest_update(s->ch + ch); -+ } -+ -+ omap_mcspi_interrupt_update(s); -+} -+ -+static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque; -+ int offset = addr - s->base; -+ int ch = 0; -+ uint32_t ret; -+ -+ switch (offset) { -+ case 0x00: /* MCSPI_REVISION */ -+ return 0x91; -+ -+ case 0x10: /* MCSPI_SYSCONFIG */ -+ return s->sysconfig; -+ -+ case 0x14: /* MCSPI_SYSSTATUS */ -+ return 1; /* RESETDONE */ -+ -+ case 0x18: /* MCSPI_IRQSTATUS */ -+ return s->irqst; -+ -+ case 0x1c: /* MCSPI_IRQENABLE */ -+ return s->irqen; -+ -+ case 0x20: /* MCSPI_WAKEUPENABLE */ -+ return s->wken; -+ -+ case 0x24: /* MCSPI_SYST */ -+ return s->systest; -+ -+ case 0x28: /* MCSPI_MODULCTRL */ -+ return s->control; -+ -+ case 0x68: ch ++; -+ case 0x54: ch ++; -+ case 0x40: ch ++; -+ case 0x2c: /* MCSPI_CHCONF */ -+ return s->ch[ch].config; -+ -+ case 0x6c: ch ++; -+ case 0x58: ch ++; -+ case 0x44: ch ++; -+ case 0x30: /* MCSPI_CHSTAT */ -+ return s->ch[ch].status; -+ -+ case 0x70: ch ++; -+ case 0x5c: ch ++; -+ case 0x48: ch ++; -+ case 0x34: /* MCSPI_CHCTRL */ -+ return s->ch[ch].control; -+ -+ case 0x74: ch ++; -+ case 0x60: ch ++; -+ case 0x4c: ch ++; -+ case 0x38: /* MCSPI_TX */ -+ return s->ch[ch].tx; -+ -+ case 0x78: ch ++; -+ case 0x64: ch ++; -+ case 0x50: ch ++; -+ case 0x3c: /* MCSPI_RX */ -+ s->ch[ch].status &= ~(1 << 0); /* RXS */ -+ ret = s->ch[ch].rx; -+ omap_mcspi_transfer_run(s, ch); -+ return ret; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_mcspi_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque; -+ int offset = addr - s->base; -+ int ch = 0; -+ -+ switch (offset) { -+ case 0x00: /* MCSPI_REVISION */ -+ case 0x14: /* MCSPI_SYSSTATUS */ -+ case 0x30: /* MCSPI_CHSTAT0 */ -+ case 0x3c: /* MCSPI_RX0 */ -+ case 0x44: /* MCSPI_CHSTAT1 */ -+ case 0x50: /* MCSPI_RX1 */ -+ case 0x58: /* MCSPI_CHSTAT2 */ -+ case 0x64: /* MCSPI_RX2 */ -+ case 0x6c: /* MCSPI_CHSTAT3 */ -+ case 0x78: /* MCSPI_RX3 */ -+ OMAP_RO_REG(addr); -+ return; -+ -+ case 0x10: /* MCSPI_SYSCONFIG */ -+ if (value & (1 << 1)) /* SOFTRESET */ -+ omap_mcspi_reset(s); -+ s->sysconfig = value & 0x31d; -+ break; -+ -+ case 0x18: /* MCSPI_IRQSTATUS */ -+ if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) { -+ s->irqst &= ~value; -+ omap_mcspi_interrupt_update(s); -+ } -+ break; -+ -+ case 0x1c: /* MCSPI_IRQENABLE */ -+ s->irqen = value & 0x1777f; -+ omap_mcspi_interrupt_update(s); -+ break; -+ -+ case 0x20: /* MCSPI_WAKEUPENABLE */ -+ s->wken = value & 1; -+ break; -+ -+ case 0x24: /* MCSPI_SYST */ -+ if (s->control & (1 << 3)) /* SYSTEM_TEST */ -+ if (value & (1 << 11)) { /* SSB */ -+ s->irqst |= 0x1777f; -+ omap_mcspi_interrupt_update(s); -+ } -+ s->systest = value & 0xfff; -+ break; -+ -+ case 0x28: /* MCSPI_MODULCTRL */ -+ if (value & (1 << 3)) /* SYSTEM_TEST */ -+ if (s->systest & (1 << 11)) { /* SSB */ -+ s->irqst |= 0x1777f; -+ omap_mcspi_interrupt_update(s); -+ } -+ s->control = value & 0xf; -+ break; -+ -+ case 0x68: ch ++; -+ case 0x54: ch ++; -+ case 0x40: ch ++; -+ case 0x2c: /* MCSPI_CHCONF */ -+ if ((value ^ s->ch[ch].config) & (3 << 14)) /* DMAR | DMAW */ -+ omap_mcspi_dmarequest_update(s->ch + ch); -+ if (((value >> 12) & 3) == 3) /* TRM */ -+ fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__); -+ if (((value >> 7) & 0x1f) < 3) /* WL */ -+ fprintf(stderr, "%s: invalid WL value (%i)\n", -+ __FUNCTION__, (value >> 7) & 0x1f); -+ s->ch[ch].config = value & 0x7fffff; -+ break; -+ -+ case 0x70: ch ++; -+ case 0x5c: ch ++; -+ case 0x48: ch ++; -+ case 0x34: /* MCSPI_CHCTRL */ -+ if (value & ~s->ch[ch].control & 1) { /* EN */ -+ s->ch[ch].control |= 1; -+ omap_mcspi_transfer_run(s, ch); -+ } else -+ s->ch[ch].control = value & 1; -+ break; -+ -+ case 0x74: ch ++; -+ case 0x60: ch ++; -+ case 0x4c: ch ++; -+ case 0x38: /* MCSPI_TX */ -+ s->ch[ch].tx = value; -+ s->ch[ch].status &= ~(1 << 1); /* TXS */ -+ omap_mcspi_transfer_run(s, ch); -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_mcspi_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_mcspi_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_mcspi_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_mcspi_write, -+}; -+ -+struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum, -+ qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk) -+{ -+ int iomemtype; -+ struct omap_mcspi_s *s = (struct omap_mcspi_s *) -+ qemu_mallocz(sizeof(struct omap_mcspi_s)); -+ struct omap_mcspi_ch_s *ch = s->ch; -+ -+ s->irq = irq; -+ s->chnum = chnum; -+ while (chnum --) { -+ ch->txdrq = *drq ++; -+ ch->rxdrq = *drq ++; -+ ch ++; -+ } -+ omap_mcspi_reset(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap_mcspi_readfn, -+ omap_mcspi_writefn, s); -+ s->base = omap_l4_attach(ta, 0, iomemtype); -+ -+ return s; -+} -+ -+void omap_mcspi_attach(struct omap_mcspi_s *s, -+ uint32_t (*txrx)(void *opaque, uint32_t), void *opaque, -+ int chipselect) -+{ -+ if (chipselect < 0 || chipselect >= s->chnum) -+ cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", -+ __FUNCTION__, chipselect); -+ -+ s->ch[chipselect].txrx = txrx; -+ s->ch[chipselect].opaque = opaque; -+} -+ -+/* L4 Interconnect */ -+struct omap_target_agent_s { -+ struct omap_l4_s *bus; -+ int regions; -+ struct omap_l4_region_s *start; -+ target_phys_addr_t base; -+ uint32_t component; -+ uint32_t control; -+ uint32_t status; -+}; -+ -+struct omap_l4_s { -+ target_phys_addr_t base; -+ int ta_num; -+ struct omap_target_agent_s ta[0]; -+}; -+ -+struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num) -+{ -+ struct omap_l4_s *bus = qemu_mallocz( -+ sizeof(*bus) + ta_num * sizeof(*bus->ta)); -+ -+ bus->ta_num = ta_num; -+ bus->base = base; -+ -+ return bus; -+} -+ -+static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque; -+ target_phys_addr_t reg = addr - s->base; -+ -+ switch (reg) { -+ case 0x00: /* COMPONENT */ -+ return s->component; -+ -+ case 0x20: /* AGENT_CONTROL */ -+ return s->control; -+ -+ case 0x28: /* AGENT_STATUS */ -+ return s->status; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_l4ta_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque; -+ target_phys_addr_t reg = addr - s->base; -+ -+ switch (reg) { -+ case 0x00: /* COMPONENT */ -+ case 0x28: /* AGENT_STATUS */ -+ OMAP_RO_REG(addr); -+ break; -+ -+ case 0x20: /* AGENT_CONTROL */ -+ s->control = value & 0x01000700; -+ if (value & 1) /* OCP_RESET */ -+ s->status &= ~1; /* REQ_TIMEOUT */ -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static CPUReadMemoryFunc *omap_l4ta_readfn[] = { -+ omap_badwidth_read16, -+ omap_l4ta_read, -+ omap_badwidth_read16, -+}; -+ -+static CPUWriteMemoryFunc *omap_l4ta_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_l4ta_write, -+}; -+ -+#define L4TA(n) (n) -+#define L4TAO(n) ((n) + 39) -+ -+static struct omap_l4_region_s { -+ target_phys_addr_t offset; -+ size_t size; -+ int access; -+} omap_l4_region[125] = { -+ [ 1] = { 0x40800, 0x800, 32 }, /* Initiator agent */ -+ [ 2] = { 0x41000, 0x1000, 32 }, /* Link agent */ -+ [ 0] = { 0x40000, 0x800, 32 }, /* Address and protection */ -+ [ 3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */ -+ [ 4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */ -+ [ 5] = { 0x04000, 0x1000, 32 | 16 }, /* 32K Timer */ -+ [ 6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */ -+ [ 7] = { 0x08000, 0x800, 32 }, /* PRCM Region A */ -+ [ 8] = { 0x08800, 0x800, 32 }, /* PRCM Region B */ -+ [ 9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */ -+ [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */ -+ [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */ -+ [ 12] = { 0x14000, 0x1000, 32 }, /* Test/emulation (TAP) */ -+ [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */ -+ [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */ -+ [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */ -+ [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */ -+ [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */ -+ [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */ -+ [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */ -+ [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */ -+ [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */ -+ [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */ -+ [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */ -+ [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */ -+ [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */ -+ [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */ -+ [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */ -+ [ 28] = { 0x50000, 0x400, 32 | 16 | 8 }, /* Display top */ -+ [ 29] = { 0x50400, 0x400, 32 | 16 | 8 }, /* Display control */ -+ [ 30] = { 0x50800, 0x400, 32 | 16 | 8 }, /* Display RFBI */ -+ [ 31] = { 0x50c00, 0x400, 32 | 16 | 8 }, /* Display encoder */ -+ [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */ -+ [ 33] = { 0x52000, 0x400, 32 | 16 | 8 }, /* Camera top */ -+ [ 34] = { 0x52400, 0x400, 32 | 16 | 8 }, /* Camera core */ -+ [ 35] = { 0x52800, 0x400, 32 | 16 | 8 }, /* Camera DMA */ -+ [ 36] = { 0x52c00, 0x400, 32 | 16 | 8 }, /* Camera MMU */ -+ [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */ -+ [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */ -+ [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */ -+ [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */ -+ [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */ -+ [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */ -+ [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */ -+ [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */ -+ [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */ -+ [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */ -+ [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */ -+ [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */ -+ [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */ -+ [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */ -+ [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */ -+ [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */ -+ [ 53] = { 0x66000, 0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */ -+ [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */ -+ [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */ -+ [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */ -+ [ 57] = { 0x6a000, 0x1000, 16 | 8 }, /* UART1 */ -+ [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */ -+ [ 59] = { 0x6c000, 0x1000, 16 | 8 }, /* UART2 */ -+ [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */ -+ [ 61] = { 0x6e000, 0x1000, 16 | 8 }, /* UART3 */ -+ [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */ -+ [ 63] = { 0x70000, 0x1000, 16 }, /* I2C1 */ -+ [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */ -+ [ 65] = { 0x72000, 0x1000, 16 }, /* I2C2 */ -+ [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */ -+ [ 67] = { 0x74000, 0x1000, 16 }, /* McBSP1 */ -+ [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */ -+ [ 69] = { 0x76000, 0x1000, 16 }, /* McBSP2 */ -+ [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */ -+ [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */ -+ [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */ -+ [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */ -+ [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */ -+ [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */ -+ [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */ -+ [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */ -+ [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */ -+ [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */ -+ [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */ -+ [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */ -+ [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */ -+ [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */ -+ [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */ -+ [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */ -+ [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */ -+ [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */ -+ [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */ -+ [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */ -+ [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */ -+ [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */ -+ [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */ -+ [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */ -+ [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */ -+ [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */ -+ [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */ -+ [ 97] = { 0x90000, 0x1000, 16 }, /* EAC */ -+ [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */ -+ [ 99] = { 0x92000, 0x1000, 16 }, /* FAC */ -+ [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */ -+ [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */ -+ [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */ -+ [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */ -+ [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */ -+ [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */ -+ [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */ -+ [107] = { 0x9c000, 0x1000, 16 | 8 }, /* MMC SDIO */ -+ [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */ -+ [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */ -+ [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */ -+ [111] = { 0xa0000, 0x1000, 32 }, /* RNG */ -+ [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */ -+ [113] = { 0xa2000, 0x1000, 32 }, /* DES3DES */ -+ [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */ -+ [115] = { 0xa4000, 0x1000, 32 }, /* SHA1MD5 */ -+ [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */ -+ [117] = { 0xa6000, 0x1000, 32 }, /* AES */ -+ [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */ -+ [119] = { 0xa8000, 0x2000, 32 }, /* PKA */ -+ [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */ -+ [121] = { 0xb0000, 0x1000, 32 }, /* MG */ -+ [122] = { 0xb1000, 0x1000, 32 | 16 | 8 }, -+ [123] = { 0xb2000, 0x1000, 32 }, /* HDQ/1-Wire */ -+ [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */ -+}; -+ -+static struct omap_l4_agent_info_s { -+ int ta; -+ int region; -+ int regions; -+ int ta_region; -+} omap_l4_agent_info[54] = { -+ { 0, 0, 3, 2 }, /* L4IA initiatior agent */ -+ { L4TAO(1), 3, 2, 1 }, /* Control and pinout module */ -+ { L4TAO(2), 5, 2, 1 }, /* 32K timer */ -+ { L4TAO(3), 7, 3, 2 }, /* PRCM */ -+ { L4TA(1), 10, 2, 1 }, /* BCM */ -+ { L4TA(2), 12, 2, 1 }, /* Test JTAG */ -+ { L4TA(3), 14, 6, 3 }, /* Quad GPIO */ -+ { L4TA(4), 20, 4, 3 }, /* WD timer 1/2 */ -+ { L4TA(7), 24, 2, 1 }, /* GP timer 1 */ -+ { L4TA(9), 26, 2, 1 }, /* ATM11 ETB */ -+ { L4TA(10), 28, 5, 4 }, /* Display subsystem */ -+ { L4TA(11), 33, 5, 4 }, /* Camera subsystem */ -+ { L4TA(12), 38, 2, 1 }, /* sDMA */ -+ { L4TA(13), 40, 5, 4 }, /* SSI */ -+ { L4TAO(4), 45, 2, 1 }, /* USB */ -+ { L4TA(14), 47, 2, 1 }, /* Win Tracer1 */ -+ { L4TA(15), 49, 2, 1 }, /* Win Tracer2 */ -+ { L4TA(16), 51, 2, 1 }, /* Win Tracer3 */ -+ { L4TA(17), 53, 2, 1 }, /* Win Tracer4 */ -+ { L4TA(18), 55, 2, 1 }, /* XTI */ -+ { L4TA(19), 57, 2, 1 }, /* UART1 */ -+ { L4TA(20), 59, 2, 1 }, /* UART2 */ -+ { L4TA(21), 61, 2, 1 }, /* UART3 */ -+ { L4TAO(5), 63, 2, 1 }, /* I2C1 */ -+ { L4TAO(6), 65, 2, 1 }, /* I2C2 */ -+ { L4TAO(7), 67, 2, 1 }, /* McBSP1 */ -+ { L4TAO(8), 69, 2, 1 }, /* McBSP2 */ -+ { L4TA(5), 71, 2, 1 }, /* WD Timer 3 (DSP) */ -+ { L4TA(6), 73, 2, 1 }, /* WD Timer 4 (IVA) */ -+ { L4TA(8), 75, 2, 1 }, /* GP Timer 2 */ -+ { L4TA(22), 77, 2, 1 }, /* GP Timer 3 */ -+ { L4TA(23), 79, 2, 1 }, /* GP Timer 4 */ -+ { L4TA(24), 81, 2, 1 }, /* GP Timer 5 */ -+ { L4TA(25), 83, 2, 1 }, /* GP Timer 6 */ -+ { L4TA(26), 85, 2, 1 }, /* GP Timer 7 */ -+ { L4TA(27), 87, 2, 1 }, /* GP Timer 8 */ -+ { L4TA(28), 89, 2, 1 }, /* GP Timer 9 */ -+ { L4TA(29), 91, 2, 1 }, /* GP Timer 10 */ -+ { L4TA(30), 93, 2, 1 }, /* GP Timer 11 */ -+ { L4TA(31), 95, 2, 1 }, /* GP Timer 12 */ -+ { L4TA(32), 97, 2, 1 }, /* EAC */ -+ { L4TA(33), 99, 2, 1 }, /* FAC */ -+ { L4TA(34), 101, 2, 1 }, /* IPC */ -+ { L4TA(35), 103, 2, 1 }, /* SPI1 */ -+ { L4TA(36), 105, 2, 1 }, /* SPI2 */ -+ { L4TAO(9), 107, 2, 1 }, /* MMC SDIO */ -+ { L4TAO(10), 109, 2, 1 }, -+ { L4TAO(11), 111, 2, 1 }, /* RNG */ -+ { L4TAO(12), 113, 2, 1 }, /* DES3DES */ -+ { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */ -+ { L4TA(37), 117, 2, 1 }, /* AES */ -+ { L4TA(38), 119, 2, 1 }, /* PKA */ -+ { -1, 121, 2, 1 }, -+ { L4TA(39), 123, 2, 1 }, /* HDQ/1-Wire */ -+}; -+ -+#define omap_l4ta(bus, cs) omap_l4ta_get(bus, L4TA(cs)) -+#define omap_l4tao(bus, cs) omap_l4ta_get(bus, L4TAO(cs)) -+ -+struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs) -+{ -+ int i, iomemtype; -+ struct omap_target_agent_s *ta = 0; -+ struct omap_l4_agent_info_s *info = 0; -+ -+ for (i = 0; i < bus->ta_num; i ++) -+ if (omap_l4_agent_info[i].ta == cs) { -+ ta = &bus->ta[i]; -+ info = &omap_l4_agent_info[i]; -+ break; -+ } -+ if (!ta) { -+ fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs); -+ exit(-1); -+ } -+ -+ ta->bus = bus; -+ ta->start = &omap_l4_region[info->region]; -+ ta->regions = info->regions; -+ ta->base = bus->base + ta->start[info->ta_region].offset; -+ -+ ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0); -+ ta->status = 0x00000000; -+ ta->control = 0x00000200; /* XXX 01000200 for L4TAO */ -+ -+ iomemtype = cpu_register_io_memory(0, omap_l4ta_readfn, -+ omap_l4ta_writefn, ta); -+ cpu_register_physical_memory(ta->base, 0x200, iomemtype); -+ -+ return ta; -+} -+ -+target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region, -+ int iotype) -+{ -+ target_phys_addr_t base; -+ size_t size; -+ -+ if (region < 0 || region >= ta->regions) { -+ fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region); -+ exit(-1); -+ } -+ -+ base = ta->bus->base + ta->start[region].offset; -+ size = ta->start[region].size; -+ if (iotype) -+ cpu_register_physical_memory(base, size, iotype); -+ -+ return base; -+} -+ -+/* TEST-Chip-level TAP */ -+static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; -+ target_phys_addr_t reg = addr - s->tap_base; -+ -+ switch (reg) { -+ case 0x204: /* IDCODE_reg */ -+ switch (s->mpu_model) { -+ case omap2420: -+ case omap2422: -+ case omap2423: -+ return 0x5b5d902f; /* ES 2.2 */ -+ case omap2430: -+ return 0x5b68a02f; /* ES 2.2 */ -+ case omap3430: -+ return 0x1b7ae02f; /* ES 2 */ -+ default: -+ cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__); -+ } -+ -+ case 0x208: /* PRODUCTION_ID_reg for OMAP2 */ -+ case 0x210: /* PRODUCTION_ID_reg for OMAP3 */ -+ switch (s->mpu_model) { -+ case omap2420: -+ return 0x000200f0; /* POP ESHS2.1.1 in N91/93/95, ES2 in N800 */ -+ case omap2422: -+ return 0x000400f0; -+ case omap2423: -+ return 0x000800f0; -+ case omap2430: -+ return 0x000000f0; -+ case omap3430: -+ return 0x000000f0; -+ default: -+ cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__); -+ } -+ -+ case 0x218: /* DIE_ID_reg */ -+ return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0); -+ case 0x21c: /* DIE_ID_reg */ -+ return ( 5 << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0); -+ case 0x220: /* DIE_ID_reg */ -+ return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0); -+ case 0x224: /* DIE_ID_reg */ -+ return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0); -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_tap_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ OMAP_BAD_REG(addr); -+} -+ -+static CPUReadMemoryFunc *omap_tap_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_tap_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_tap_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_tap_write, -+}; -+ -+void omap_tap_init(struct omap_target_agent_s *ta, -+ struct omap_mpu_state_s *mpu) -+{ -+ mpu->tap_base = omap_l4_attach(ta, 0, cpu_register_io_memory(0, -+ omap_tap_readfn, omap_tap_writefn, mpu)); -+} -+ -+/* Power, Reset, and Clock Management */ -+struct omap_prcm_s { -+ target_phys_addr_t base; -+ qemu_irq irq[3]; -+ struct omap_mpu_state_s *mpu; -+ -+ uint32_t irqst[3]; -+ uint32_t irqen[3]; -+ -+ uint32_t sysconfig; -+ uint32_t voltctrl; -+ uint32_t scratch[20]; -+ -+ uint32_t clksrc[1]; -+ uint32_t clkout[1]; -+ uint32_t clkemul[1]; -+ uint32_t clkpol[1]; -+ uint32_t clksel[8]; -+ uint32_t clken[12]; -+ uint32_t clkctrl[4]; -+ uint32_t clkidle[7]; -+ uint32_t setuptime[2]; -+ -+ uint32_t wkup[3]; -+ uint32_t wken[3]; -+ uint32_t wkst[3]; -+ uint32_t rst[4]; -+ uint32_t rstctrl[1]; -+ uint32_t power[4]; -+ uint32_t rsttime_wkup; -+ -+ uint32_t ev; -+ uint32_t evtime[2]; -+}; -+ -+static void omap_prcm_int_update(struct omap_prcm_s *s, int dom) -+{ -+ qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]); -+ /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */ -+} -+ -+static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_prcm_s *s = (struct omap_prcm_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x000: /* PRCM_REVISION */ -+ return 0x10; -+ -+ case 0x010: /* PRCM_SYSCONFIG */ -+ return s->sysconfig; -+ -+ case 0x018: /* PRCM_IRQSTATUS_MPU */ -+ return s->irqst[0]; -+ -+ case 0x01c: /* PRCM_IRQENABLE_MPU */ -+ return s->irqen[0]; -+ -+ case 0x050: /* PRCM_VOLTCTRL */ -+ return s->voltctrl; -+ case 0x054: /* PRCM_VOLTST */ -+ return s->voltctrl & 3; -+ -+ case 0x060: /* PRCM_CLKSRC_CTRL */ -+ return s->clksrc[0]; -+ case 0x070: /* PRCM_CLKOUT_CTRL */ -+ return s->clkout[0]; -+ case 0x078: /* PRCM_CLKEMUL_CTRL */ -+ return s->clkemul[0]; -+ case 0x080: /* PRCM_CLKCFG_CTRL */ -+ case 0x084: /* PRCM_CLKCFG_STATUS */ -+ return 0; -+ -+ case 0x090: /* PRCM_VOLTSETUP */ -+ return s->setuptime[0]; -+ -+ case 0x094: /* PRCM_CLKSSETUP */ -+ return s->setuptime[1]; -+ -+ case 0x098: /* PRCM_POLCTRL */ -+ return s->clkpol[0]; -+ -+ case 0x0b0: /* GENERAL_PURPOSE1 */ -+ case 0x0b4: /* GENERAL_PURPOSE2 */ -+ case 0x0b8: /* GENERAL_PURPOSE3 */ -+ case 0x0bc: /* GENERAL_PURPOSE4 */ -+ case 0x0c0: /* GENERAL_PURPOSE5 */ -+ case 0x0c4: /* GENERAL_PURPOSE6 */ -+ case 0x0c8: /* GENERAL_PURPOSE7 */ -+ case 0x0cc: /* GENERAL_PURPOSE8 */ -+ case 0x0d0: /* GENERAL_PURPOSE9 */ -+ case 0x0d4: /* GENERAL_PURPOSE10 */ -+ case 0x0d8: /* GENERAL_PURPOSE11 */ -+ case 0x0dc: /* GENERAL_PURPOSE12 */ -+ case 0x0e0: /* GENERAL_PURPOSE13 */ -+ case 0x0e4: /* GENERAL_PURPOSE14 */ -+ case 0x0e8: /* GENERAL_PURPOSE15 */ -+ case 0x0ec: /* GENERAL_PURPOSE16 */ -+ case 0x0f0: /* GENERAL_PURPOSE17 */ -+ case 0x0f4: /* GENERAL_PURPOSE18 */ -+ case 0x0f8: /* GENERAL_PURPOSE19 */ -+ case 0x0fc: /* GENERAL_PURPOSE20 */ -+ return s->scratch[(offset - 0xb0) >> 2]; -+ -+ case 0x140: /* CM_CLKSEL_MPU */ -+ return s->clksel[0]; -+ case 0x148: /* CM_CLKSTCTRL_MPU */ -+ return s->clkctrl[0]; -+ -+ case 0x158: /* RM_RSTST_MPU */ -+ return s->rst[0]; -+ case 0x1c8: /* PM_WKDEP_MPU */ -+ return s->wkup[0]; -+ case 0x1d4: /* PM_EVGENCTRL_MPU */ -+ return s->ev; -+ case 0x1d8: /* PM_EVEGENONTIM_MPU */ -+ return s->evtime[0]; -+ case 0x1dc: /* PM_EVEGENOFFTIM_MPU */ -+ return s->evtime[1]; -+ case 0x1e0: /* PM_PWSTCTRL_MPU */ -+ return s->power[0]; -+ case 0x1e4: /* PM_PWSTST_MPU */ -+ return 0; -+ -+ case 0x200: /* CM_FCLKEN1_CORE */ -+ return s->clken[0]; -+ case 0x204: /* CM_FCLKEN2_CORE */ -+ return s->clken[1]; -+ case 0x210: /* CM_ICLKEN1_CORE */ -+ return s->clken[2]; -+ case 0x214: /* CM_ICLKEN2_CORE */ -+ return s->clken[3]; -+ case 0x21c: /* CM_ICLKEN4_CORE */ -+ return s->clken[4]; -+ -+ case 0x220: /* CM_IDLEST1_CORE */ -+ /* TODO: check the actual iclk status */ -+ return 0x7ffffff9; -+ case 0x224: /* CM_IDLEST2_CORE */ -+ /* TODO: check the actual iclk status */ -+ return 0x00000007; -+ case 0x22c: /* CM_IDLEST4_CORE */ -+ /* TODO: check the actual iclk status */ -+ return 0x0000001f; -+ -+ case 0x230: /* CM_AUTOIDLE1_CORE */ -+ return s->clkidle[0]; -+ case 0x234: /* CM_AUTOIDLE2_CORE */ -+ return s->clkidle[1]; -+ case 0x238: /* CM_AUTOIDLE3_CORE */ -+ return s->clkidle[2]; -+ case 0x23c: /* CM_AUTOIDLE4_CORE */ -+ return s->clkidle[3]; -+ -+ case 0x240: /* CM_CLKSEL1_CORE */ -+ return s->clksel[1]; -+ case 0x244: /* CM_CLKSEL2_CORE */ -+ return s->clksel[2]; -+ -+ case 0x248: /* CM_CLKSTCTRL_CORE */ -+ return s->clkctrl[1]; -+ -+ case 0x2a0: /* PM_WKEN1_CORE */ -+ return s->wken[0]; -+ case 0x2a4: /* PM_WKEN2_CORE */ -+ return s->wken[1]; -+ -+ case 0x2b0: /* PM_WKST1_CORE */ -+ return s->wkst[0]; -+ case 0x2b4: /* PM_WKST2_CORE */ -+ return s->wkst[1]; -+ case 0x2c8: /* PM_WKDEP_CORE */ -+ return 0x1e; -+ -+ case 0x2e0: /* PM_PWSTCTRL_CORE */ -+ return s->power[1]; -+ case 0x2e4: /* PM_PWSTST_CORE */ -+ return 0x000030 | (s->power[1] & 0xfc00); -+ -+ case 0x300: /* CM_FCLKEN_GFX */ -+ return s->clken[5]; -+ case 0x310: /* CM_ICLKEN_GFX */ -+ return s->clken[6]; -+ case 0x320: /* CM_IDLEST_GFX */ -+ /* TODO: check the actual iclk status */ -+ return 0x00000001; -+ case 0x340: /* CM_CLKSEL_GFX */ -+ return s->clksel[3]; -+ case 0x348: /* CM_CLKSTCTRL_GFX */ -+ return s->clkctrl[2]; -+ case 0x350: /* RM_RSTCTRL_GFX */ -+ return s->rstctrl[0]; -+ case 0x358: /* RM_RSTST_GFX */ -+ return s->rst[1]; -+ case 0x3c8: /* PM_WKDEP_GFX */ -+ return s->wkup[1]; -+ -+ case 0x3e0: /* PM_PWSTCTRL_GFX */ -+ return s->power[2]; -+ case 0x3e4: /* PM_PWSTST_GFX */ -+ return s->power[2] & 3; -+ -+ case 0x400: /* CM_FCLKEN_WKUP */ -+ return s->clken[7]; -+ case 0x410: /* CM_ICLKEN_WKUP */ -+ return s->clken[8]; -+ case 0x420: /* CM_IDLEST_WKUP */ -+ /* TODO: check the actual iclk status */ -+ return 0x0000003f; -+ case 0x430: /* CM_AUTOIDLE_WKUP */ -+ return s->clkidle[4]; -+ case 0x440: /* CM_CLKSEL_WKUP */ -+ return s->clksel[4]; -+ case 0x450: /* RM_RSTCTRL_WKUP */ -+ return 0; -+ case 0x454: /* RM_RSTTIME_WKUP */ -+ return s->rsttime_wkup; -+ case 0x458: /* RM_RSTST_WKUP */ -+ return s->rst[2]; -+ case 0x4a0: /* PM_WKEN_WKUP */ -+ return s->wken[2]; -+ case 0x4b0: /* PM_WKST_WKUP */ -+ return s->wkst[2]; -+ -+ case 0x500: /* CM_CLKEN_PLL */ -+ return s->clken[9]; -+ case 0x520: /* CM_IDLEST_CKGEN */ -+ /* Core uses 32-kHz clock */ -+ if (!(s->clksel[6] & 3)) -+ return 0x00000377; -+ /* DPLL not in lock mode, core uses ref_clk */ -+ if ((s->clken[9] & 3) != 3) -+ return 0x00000375; -+ /* Core uses DPLL */ -+ return 0x00000376; -+ case 0x530: /* CM_AUTOIDLE_PLL */ -+ return s->clkidle[5]; -+ case 0x540: /* CM_CLKSEL1_PLL */ -+ return s->clksel[5]; -+ case 0x544: /* CM_CLKSEL2_PLL */ -+ return s->clksel[6]; -+ -+ case 0x800: /* CM_FCLKEN_DSP */ -+ return s->clken[10]; -+ case 0x810: /* CM_ICLKEN_DSP */ -+ return s->clken[11]; -+ case 0x820: /* CM_IDLEST_DSP */ -+ /* TODO: check the actual iclk status */ -+ return 0x00000103; -+ case 0x830: /* CM_AUTOIDLE_DSP */ -+ return s->clkidle[6]; -+ case 0x840: /* CM_CLKSEL_DSP */ -+ return s->clksel[7]; -+ case 0x848: /* CM_CLKSTCTRL_DSP */ -+ return s->clkctrl[3]; -+ case 0x850: /* RM_RSTCTRL_DSP */ -+ return 0; -+ case 0x858: /* RM_RSTST_DSP */ -+ return s->rst[3]; -+ case 0x8c8: /* PM_WKDEP_DSP */ -+ return s->wkup[2]; -+ case 0x8e0: /* PM_PWSTCTRL_DSP */ -+ return s->power[3]; -+ case 0x8e4: /* PM_PWSTST_DSP */ -+ return 0x008030 | (s->power[3] & 0x3003); -+ -+ case 0x8f0: /* PRCM_IRQSTATUS_DSP */ -+ return s->irqst[1]; -+ case 0x8f4: /* PRCM_IRQENABLE_DSP */ -+ return s->irqen[1]; -+ -+ case 0x8f8: /* PRCM_IRQSTATUS_IVA */ -+ return s->irqst[2]; -+ case 0x8fc: /* PRCM_IRQENABLE_IVA */ -+ return s->irqen[2]; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_prcm_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_prcm_s *s = (struct omap_prcm_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x000: /* PRCM_REVISION */ -+ case 0x054: /* PRCM_VOLTST */ -+ case 0x084: /* PRCM_CLKCFG_STATUS */ -+ case 0x1e4: /* PM_PWSTST_MPU */ -+ case 0x220: /* CM_IDLEST1_CORE */ -+ case 0x224: /* CM_IDLEST2_CORE */ -+ case 0x22c: /* CM_IDLEST4_CORE */ -+ case 0x2c8: /* PM_WKDEP_CORE */ -+ case 0x2e4: /* PM_PWSTST_CORE */ -+ case 0x320: /* CM_IDLEST_GFX */ -+ case 0x3e4: /* PM_PWSTST_GFX */ -+ case 0x420: /* CM_IDLEST_WKUP */ -+ case 0x520: /* CM_IDLEST_CKGEN */ -+ case 0x820: /* CM_IDLEST_DSP */ -+ case 0x8e4: /* PM_PWSTST_DSP */ -+ OMAP_RO_REG(addr); -+ return; -+ -+ case 0x010: /* PRCM_SYSCONFIG */ -+ s->sysconfig = value & 1; -+ break; -+ -+ case 0x018: /* PRCM_IRQSTATUS_MPU */ -+ s->irqst[0] &= ~value; -+ omap_prcm_int_update(s, 0); -+ break; -+ case 0x01c: /* PRCM_IRQENABLE_MPU */ -+ s->irqen[0] = value & 0x3f; -+ omap_prcm_int_update(s, 0); -+ break; -+ -+ case 0x050: /* PRCM_VOLTCTRL */ -+ s->voltctrl = value & 0xf1c3; -+ break; -+ -+ case 0x060: /* PRCM_CLKSRC_CTRL */ -+ s->clksrc[0] = value & 0xdb; -+ /* TODO update clocks */ -+ break; -+ -+ case 0x070: /* PRCM_CLKOUT_CTRL */ -+ s->clkout[0] = value & 0xbbbb; -+ /* TODO update clocks */ -+ break; -+ -+ case 0x078: /* PRCM_CLKEMUL_CTRL */ -+ s->clkemul[0] = value & 1; -+ /* TODO update clocks */ -+ break; -+ -+ case 0x080: /* PRCM_CLKCFG_CTRL */ -+ break; -+ -+ case 0x090: /* PRCM_VOLTSETUP */ -+ s->setuptime[0] = value & 0xffff; -+ break; -+ case 0x094: /* PRCM_CLKSSETUP */ -+ s->setuptime[1] = value & 0xffff; -+ break; -+ -+ case 0x098: /* PRCM_POLCTRL */ -+ s->clkpol[0] = value & 0x701; -+ break; -+ -+ case 0x0b0: /* GENERAL_PURPOSE1 */ -+ case 0x0b4: /* GENERAL_PURPOSE2 */ -+ case 0x0b8: /* GENERAL_PURPOSE3 */ -+ case 0x0bc: /* GENERAL_PURPOSE4 */ -+ case 0x0c0: /* GENERAL_PURPOSE5 */ -+ case 0x0c4: /* GENERAL_PURPOSE6 */ -+ case 0x0c8: /* GENERAL_PURPOSE7 */ -+ case 0x0cc: /* GENERAL_PURPOSE8 */ -+ case 0x0d0: /* GENERAL_PURPOSE9 */ -+ case 0x0d4: /* GENERAL_PURPOSE10 */ -+ case 0x0d8: /* GENERAL_PURPOSE11 */ -+ case 0x0dc: /* GENERAL_PURPOSE12 */ -+ case 0x0e0: /* GENERAL_PURPOSE13 */ -+ case 0x0e4: /* GENERAL_PURPOSE14 */ -+ case 0x0e8: /* GENERAL_PURPOSE15 */ -+ case 0x0ec: /* GENERAL_PURPOSE16 */ -+ case 0x0f0: /* GENERAL_PURPOSE17 */ -+ case 0x0f4: /* GENERAL_PURPOSE18 */ -+ case 0x0f8: /* GENERAL_PURPOSE19 */ -+ case 0x0fc: /* GENERAL_PURPOSE20 */ -+ s->scratch[(offset - 0xb0) >> 2] = value; -+ break; -+ -+ case 0x140: /* CM_CLKSEL_MPU */ -+ s->clksel[0] = value & 0x1f; -+ /* TODO update clocks */ -+ break; -+ case 0x148: /* CM_CLKSTCTRL_MPU */ -+ s->clkctrl[0] = value & 0x1f; -+ break; -+ -+ case 0x158: /* RM_RSTST_MPU */ -+ s->rst[0] &= ~value; -+ break; -+ case 0x1c8: /* PM_WKDEP_MPU */ -+ s->wkup[0] = value & 0x15; -+ break; -+ -+ case 0x1d4: /* PM_EVGENCTRL_MPU */ -+ s->ev = value & 0x1f; -+ break; -+ case 0x1d8: /* PM_EVEGENONTIM_MPU */ -+ s->evtime[0] = value; -+ break; -+ case 0x1dc: /* PM_EVEGENOFFTIM_MPU */ -+ s->evtime[1] = value; -+ break; -+ -+ case 0x1e0: /* PM_PWSTCTRL_MPU */ -+ s->power[0] = value & 0xc0f; -+ break; -+ -+ case 0x200: /* CM_FCLKEN1_CORE */ -+ s->clken[0] = value & 0xbfffffff; -+ /* TODO update clocks */ -+ break; -+ case 0x204: /* CM_FCLKEN2_CORE */ -+ s->clken[1] = value & 0x00000007; -+ /* TODO update clocks */ -+ break; -+ case 0x210: /* CM_ICLKEN1_CORE */ -+ s->clken[2] = value & 0xfffffff9; -+ /* TODO update clocks */ -+ break; -+ case 0x214: /* CM_ICLKEN2_CORE */ -+ s->clken[3] = value & 0x00000007; -+ /* TODO update clocks */ -+ break; -+ case 0x21c: /* CM_ICLKEN4_CORE */ -+ s->clken[4] = value & 0x0000001f; -+ /* TODO update clocks */ -+ break; -+ -+ case 0x230: /* CM_AUTOIDLE1_CORE */ -+ s->clkidle[0] = value & 0xfffffff9; -+ /* TODO update clocks */ -+ break; -+ case 0x234: /* CM_AUTOIDLE2_CORE */ -+ s->clkidle[1] = value & 0x00000007; -+ /* TODO update clocks */ -+ break; -+ case 0x238: /* CM_AUTOIDLE3_CORE */ -+ s->clkidle[2] = value & 0x00000007; -+ /* TODO update clocks */ -+ break; -+ case 0x23c: /* CM_AUTOIDLE4_CORE */ -+ s->clkidle[3] = value & 0x0000001f; -+ /* TODO update clocks */ -+ break; -+ -+ case 0x240: /* CM_CLKSEL1_CORE */ -+ s->clksel[1] = value & 0x0fffbf7f; -+ /* TODO update clocks */ -+ break; -+ -+ case 0x244: /* CM_CLKSEL2_CORE */ -+ s->clksel[2] = value & 0x00fffffc; -+ /* TODO update clocks */ -+ break; -+ -+ case 0x248: /* CM_CLKSTCTRL_CORE */ -+ s->clkctrl[1] = value & 0x7; -+ break; -+ -+ case 0x2a0: /* PM_WKEN1_CORE */ -+ s->wken[0] = value & 0x04667ff8; -+ break; -+ case 0x2a4: /* PM_WKEN2_CORE */ -+ s->wken[1] = value & 0x00000005; -+ break; -+ -+ case 0x2b0: /* PM_WKST1_CORE */ -+ s->wkst[0] &= ~value; -+ break; -+ case 0x2b4: /* PM_WKST2_CORE */ -+ s->wkst[1] &= ~value; -+ break; -+ -+ case 0x2e0: /* PM_PWSTCTRL_CORE */ -+ s->power[1] = (value & 0x00fc3f) | (1 << 2); -+ break; -+ -+ case 0x300: /* CM_FCLKEN_GFX */ -+ s->clken[5] = value & 6; -+ /* TODO update clocks */ -+ break; -+ case 0x310: /* CM_ICLKEN_GFX */ -+ s->clken[6] = value & 1; -+ /* TODO update clocks */ -+ break; -+ case 0x340: /* CM_CLKSEL_GFX */ -+ s->clksel[3] = value & 7; -+ /* TODO update clocks */ -+ break; -+ case 0x348: /* CM_CLKSTCTRL_GFX */ -+ s->clkctrl[2] = value & 1; -+ break; -+ case 0x350: /* RM_RSTCTRL_GFX */ -+ s->rstctrl[0] = value & 1; -+ /* TODO: reset */ -+ break; -+ case 0x358: /* RM_RSTST_GFX */ -+ s->rst[1] &= ~value; -+ break; -+ case 0x3c8: /* PM_WKDEP_GFX */ -+ s->wkup[1] = value & 0x13; -+ break; -+ case 0x3e0: /* PM_PWSTCTRL_GFX */ -+ s->power[2] = (value & 0x00c0f) | (3 << 2); -+ break; -+ -+ case 0x400: /* CM_FCLKEN_WKUP */ -+ s->clken[7] = value & 0xd; -+ /* TODO update clocks */ -+ break; -+ case 0x410: /* CM_ICLKEN_WKUP */ -+ s->clken[8] = value & 0x3f; -+ /* TODO update clocks */ -+ break; -+ case 0x430: /* CM_AUTOIDLE_WKUP */ -+ s->clkidle[4] = value & 0x0000003f; -+ /* TODO update clocks */ -+ break; -+ case 0x440: /* CM_CLKSEL_WKUP */ -+ s->clksel[4] = value & 3; -+ /* TODO update clocks */ -+ break; -+ case 0x450: /* RM_RSTCTRL_WKUP */ -+ /* TODO: reset */ -+ if (value & 2) -+ qemu_system_reset_request(); -+ break; -+ case 0x454: /* RM_RSTTIME_WKUP */ -+ s->rsttime_wkup = value & 0x1fff; -+ break; -+ case 0x458: /* RM_RSTST_WKUP */ -+ s->rst[2] &= ~value; -+ break; -+ case 0x4a0: /* PM_WKEN_WKUP */ -+ s->wken[2] = value & 0x00000005; -+ break; -+ case 0x4b0: /* PM_WKST_WKUP */ -+ s->wkst[2] &= ~value; -+ break; -+ -+ case 0x500: /* CM_CLKEN_PLL */ -+ s->clken[9] = value & 0xcf; -+ /* TODO update clocks */ -+ break; -+ case 0x530: /* CM_AUTOIDLE_PLL */ -+ s->clkidle[5] = value & 0x000000cf; -+ /* TODO update clocks */ -+ break; -+ case 0x540: /* CM_CLKSEL1_PLL */ -+ s->clksel[5] = value & 0x03bfff28; -+ /* TODO update clocks */ -+ break; -+ case 0x544: /* CM_CLKSEL2_PLL */ -+ s->clksel[6] = value & 3; -+ /* TODO update clocks */ -+ break; -+ -+ case 0x800: /* CM_FCLKEN_DSP */ -+ s->clken[10] = value & 0x501; -+ /* TODO update clocks */ -+ break; -+ case 0x810: /* CM_ICLKEN_DSP */ -+ s->clken[11] = value & 0x2; -+ /* TODO update clocks */ -+ break; -+ case 0x830: /* CM_AUTOIDLE_DSP */ -+ s->clkidle[6] = value & 0x2; -+ /* TODO update clocks */ -+ break; -+ case 0x840: /* CM_CLKSEL_DSP */ -+ s->clksel[7] = value & 0x3fff; -+ /* TODO update clocks */ -+ break; -+ case 0x848: /* CM_CLKSTCTRL_DSP */ -+ s->clkctrl[3] = value & 0x101; -+ break; -+ case 0x850: /* RM_RSTCTRL_DSP */ -+ /* TODO: reset */ -+ break; -+ case 0x858: /* RM_RSTST_DSP */ -+ s->rst[3] &= ~value; -+ break; -+ case 0x8c8: /* PM_WKDEP_DSP */ -+ s->wkup[2] = value & 0x13; -+ break; -+ case 0x8e0: /* PM_PWSTCTRL_DSP */ -+ s->power[3] = (value & 0x03017) | (3 << 2); -+ break; -+ -+ case 0x8f0: /* PRCM_IRQSTATUS_DSP */ -+ s->irqst[1] &= ~value; -+ omap_prcm_int_update(s, 1); -+ break; -+ case 0x8f4: /* PRCM_IRQENABLE_DSP */ -+ s->irqen[1] = value & 0x7; -+ omap_prcm_int_update(s, 1); -+ break; -+ -+ case 0x8f8: /* PRCM_IRQSTATUS_IVA */ -+ s->irqst[2] &= ~value; -+ omap_prcm_int_update(s, 2); -+ break; -+ case 0x8fc: /* PRCM_IRQENABLE_IVA */ -+ s->irqen[2] = value & 0x7; -+ omap_prcm_int_update(s, 2); -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_prcm_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_prcm_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_prcm_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_prcm_write, -+}; -+ -+static void omap_prcm_reset(struct omap_prcm_s *s) -+{ -+ s->sysconfig = 0; -+ s->irqst[0] = 0; -+ s->irqst[1] = 0; -+ s->irqst[2] = 0; -+ s->irqen[0] = 0; -+ s->irqen[1] = 0; -+ s->irqen[2] = 0; -+ s->voltctrl = 0x1040; -+ s->ev = 0x14; -+ s->evtime[0] = 0; -+ s->evtime[1] = 0; -+ s->clkctrl[0] = 0; -+ s->clkctrl[1] = 0; -+ s->clkctrl[2] = 0; -+ s->clkctrl[3] = 0; -+ s->clken[1] = 7; -+ s->clken[3] = 7; -+ s->clken[4] = 0; -+ s->clken[5] = 0; -+ s->clken[6] = 0; -+ s->clken[7] = 0xc; -+ s->clken[8] = 0x3e; -+ s->clken[9] = 0x0d; -+ s->clken[10] = 0; -+ s->clken[11] = 0; -+ s->clkidle[0] = 0; -+ s->clkidle[2] = 7; -+ s->clkidle[3] = 0; -+ s->clkidle[4] = 0; -+ s->clkidle[5] = 0x0c; -+ s->clkidle[6] = 0; -+ s->clksel[0] = 0x01; -+ s->clksel[1] = 0x02100121; -+ s->clksel[2] = 0x00000000; -+ s->clksel[3] = 0x01; -+ s->clksel[4] = 0; -+ s->clksel[7] = 0x0121; -+ s->wkup[0] = 0x15; -+ s->wkup[1] = 0x13; -+ s->wkup[2] = 0x13; -+ s->wken[0] = 0x04667ff8; -+ s->wken[1] = 0x00000005; -+ s->wken[2] = 5; -+ s->wkst[0] = 0; -+ s->wkst[1] = 0; -+ s->wkst[2] = 0; -+ s->power[0] = 0x00c; -+ s->power[1] = 4; -+ s->power[2] = 0x0000c; -+ s->power[3] = 0x14; -+ s->rstctrl[0] = 1; -+ s->rst[3] = 1; -+} -+ -+static void omap_prcm_coldreset(struct omap_prcm_s *s) -+{ -+ s->setuptime[0] = 0; -+ s->setuptime[1] = 0; -+ memset(&s->scratch, 0, sizeof(s->scratch)); -+ s->rst[0] = 0x01; -+ s->rst[1] = 0x00; -+ s->rst[2] = 0x01; -+ s->clken[0] = 0; -+ s->clken[2] = 0; -+ s->clkidle[1] = 0; -+ s->clksel[5] = 0; -+ s->clksel[6] = 2; -+ s->clksrc[0] = 0x43; -+ s->clkout[0] = 0x0303; -+ s->clkemul[0] = 0; -+ s->clkpol[0] = 0x100; -+ s->rsttime_wkup = 0x1002; -+ -+ omap_prcm_reset(s); -+} -+ -+struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta, -+ qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int, -+ struct omap_mpu_state_s *mpu) -+{ -+ int iomemtype; -+ struct omap_prcm_s *s = (struct omap_prcm_s *) -+ qemu_mallocz(sizeof(struct omap_prcm_s)); -+ -+ s->irq[0] = mpu_int; -+ s->irq[1] = dsp_int; -+ s->irq[2] = iva_int; -+ s->mpu = mpu; -+ omap_prcm_coldreset(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap_prcm_readfn, -+ omap_prcm_writefn, s); -+ s->base = omap_l4_attach(ta, 0, iomemtype); -+ omap_l4_attach(ta, 1, iomemtype); -+ -+ return s; -+} -+ -+/* System and Pinout control */ -+struct omap_sysctl_s { -+ target_phys_addr_t base; -+ struct omap_mpu_state_s *mpu; -+ -+ uint32_t sysconfig; -+ uint32_t devconfig; -+ uint32_t psaconfig; -+ uint32_t padconf[0x45]; -+ uint8_t obs; -+ uint32_t msuspendmux[5]; -+}; -+ -+static uint32_t omap_sysctl_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x000: /* CONTROL_REVISION */ -+ return 0x20; -+ -+ case 0x010: /* CONTROL_SYSCONFIG */ -+ return s->sysconfig; -+ -+ case 0x030 ... 0x140: /* CONTROL_PADCONF - only used in the POP */ -+ return s->padconf[(offset - 0x30) >> 2]; -+ -+ case 0x270: /* CONTROL_DEBOBS */ -+ return s->obs; -+ -+ case 0x274: /* CONTROL_DEVCONF */ -+ return s->devconfig; -+ -+ case 0x28c: /* CONTROL_EMU_SUPPORT */ -+ return 0; -+ -+ case 0x290: /* CONTROL_MSUSPENDMUX_0 */ -+ return s->msuspendmux[0]; -+ case 0x294: /* CONTROL_MSUSPENDMUX_1 */ -+ return s->msuspendmux[1]; -+ case 0x298: /* CONTROL_MSUSPENDMUX_2 */ -+ return s->msuspendmux[2]; -+ case 0x29c: /* CONTROL_MSUSPENDMUX_3 */ -+ return s->msuspendmux[3]; -+ case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */ -+ return s->msuspendmux[4]; -+ case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */ -+ return 0; -+ -+ case 0x2b8: /* CONTROL_PSA_CTRL */ -+ return s->psaconfig; -+ case 0x2bc: /* CONTROL_PSA_CMD */ -+ case 0x2c0: /* CONTROL_PSA_VALUE */ -+ return 0; -+ -+ case 0x2b0: /* CONTROL_SEC_CTRL */ -+ return 0x800000f1; -+ case 0x2d0: /* CONTROL_SEC_EMU */ -+ return 0x80000015; -+ case 0x2d4: /* CONTROL_SEC_TAP */ -+ return 0x8000007f; -+ case 0x2b4: /* CONTROL_SEC_TEST */ -+ case 0x2f0: /* CONTROL_SEC_STATUS */ -+ case 0x2f4: /* CONTROL_SEC_ERR_STATUS */ -+ /* Secure mode is not present on general-pusrpose device. Outside -+ * secure mode these values cannot be read or written. */ -+ return 0; -+ -+ case 0x2d8: /* CONTROL_OCM_RAM_PERM */ -+ return 0xff; -+ case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */ -+ case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */ -+ case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */ -+ /* No secure mode so no Extended Secure RAM present. */ -+ return 0; -+ -+ case 0x2f8: /* CONTROL_STATUS */ -+ /* Device Type => General-purpose */ -+ return 0x0300; -+ case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */ -+ -+ case 0x300: /* CONTROL_RPUB_KEY_H_0 */ -+ case 0x304: /* CONTROL_RPUB_KEY_H_1 */ -+ case 0x308: /* CONTROL_RPUB_KEY_H_2 */ -+ case 0x30c: /* CONTROL_RPUB_KEY_H_3 */ -+ return 0xdecafbad; -+ -+ case 0x310: /* CONTROL_RAND_KEY_0 */ -+ case 0x314: /* CONTROL_RAND_KEY_1 */ -+ case 0x318: /* CONTROL_RAND_KEY_2 */ -+ case 0x31c: /* CONTROL_RAND_KEY_3 */ -+ case 0x320: /* CONTROL_CUST_KEY_0 */ -+ case 0x324: /* CONTROL_CUST_KEY_1 */ -+ case 0x330: /* CONTROL_TEST_KEY_0 */ -+ case 0x334: /* CONTROL_TEST_KEY_1 */ -+ case 0x338: /* CONTROL_TEST_KEY_2 */ -+ case 0x33c: /* CONTROL_TEST_KEY_3 */ -+ case 0x340: /* CONTROL_TEST_KEY_4 */ -+ case 0x344: /* CONTROL_TEST_KEY_5 */ -+ case 0x348: /* CONTROL_TEST_KEY_6 */ -+ case 0x34c: /* CONTROL_TEST_KEY_7 */ -+ case 0x350: /* CONTROL_TEST_KEY_8 */ -+ case 0x354: /* CONTROL_TEST_KEY_9 */ -+ /* Can only be accessed in secure mode and when C_FieldAccEnable -+ * bit is set in CONTROL_SEC_CTRL. -+ * TODO: otherwise an interconnect access error is generated. */ -+ return 0; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_sysctl_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x000: /* CONTROL_REVISION */ -+ case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */ -+ case 0x2c0: /* CONTROL_PSA_VALUE */ -+ case 0x2f8: /* CONTROL_STATUS */ -+ case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */ -+ case 0x300: /* CONTROL_RPUB_KEY_H_0 */ -+ case 0x304: /* CONTROL_RPUB_KEY_H_1 */ -+ case 0x308: /* CONTROL_RPUB_KEY_H_2 */ -+ case 0x30c: /* CONTROL_RPUB_KEY_H_3 */ -+ case 0x310: /* CONTROL_RAND_KEY_0 */ -+ case 0x314: /* CONTROL_RAND_KEY_1 */ -+ case 0x318: /* CONTROL_RAND_KEY_2 */ -+ case 0x31c: /* CONTROL_RAND_KEY_3 */ -+ case 0x320: /* CONTROL_CUST_KEY_0 */ -+ case 0x324: /* CONTROL_CUST_KEY_1 */ -+ case 0x330: /* CONTROL_TEST_KEY_0 */ -+ case 0x334: /* CONTROL_TEST_KEY_1 */ -+ case 0x338: /* CONTROL_TEST_KEY_2 */ -+ case 0x33c: /* CONTROL_TEST_KEY_3 */ -+ case 0x340: /* CONTROL_TEST_KEY_4 */ -+ case 0x344: /* CONTROL_TEST_KEY_5 */ -+ case 0x348: /* CONTROL_TEST_KEY_6 */ -+ case 0x34c: /* CONTROL_TEST_KEY_7 */ -+ case 0x350: /* CONTROL_TEST_KEY_8 */ -+ case 0x354: /* CONTROL_TEST_KEY_9 */ -+ OMAP_RO_REG(addr); -+ return; -+ -+ case 0x010: /* CONTROL_SYSCONFIG */ -+ s->sysconfig = value & 0x1e; -+ break; -+ -+ case 0x030 ... 0x140: /* CONTROL_PADCONF - only used in the POP */ -+ /* XXX: should check constant bits */ -+ s->padconf[(offset - 0x30) >> 2] = value & 0x1f1f1f1f; -+ break; -+ -+ case 0x270: /* CONTROL_DEBOBS */ -+ s->obs = value & 0xff; -+ break; -+ -+ case 0x274: /* CONTROL_DEVCONF */ -+ s->devconfig = value & 0xffffc7ff; -+ break; -+ -+ case 0x28c: /* CONTROL_EMU_SUPPORT */ -+ break; -+ -+ case 0x290: /* CONTROL_MSUSPENDMUX_0 */ -+ s->msuspendmux[0] = value & 0x3fffffff; -+ break; -+ case 0x294: /* CONTROL_MSUSPENDMUX_1 */ -+ s->msuspendmux[1] = value & 0x3fffffff; -+ break; -+ case 0x298: /* CONTROL_MSUSPENDMUX_2 */ -+ s->msuspendmux[2] = value & 0x3fffffff; -+ break; -+ case 0x29c: /* CONTROL_MSUSPENDMUX_3 */ -+ s->msuspendmux[3] = value & 0x3fffffff; -+ break; -+ case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */ -+ s->msuspendmux[4] = value & 0x3fffffff; -+ break; -+ -+ case 0x2b8: /* CONTROL_PSA_CTRL */ -+ s->psaconfig = value & 0x1c; -+ s->psaconfig |= (value & 0x20) ? 2 : 1; -+ break; -+ case 0x2bc: /* CONTROL_PSA_CMD */ -+ break; -+ -+ case 0x2b0: /* CONTROL_SEC_CTRL */ -+ case 0x2b4: /* CONTROL_SEC_TEST */ -+ case 0x2d0: /* CONTROL_SEC_EMU */ -+ case 0x2d4: /* CONTROL_SEC_TAP */ -+ case 0x2d8: /* CONTROL_OCM_RAM_PERM */ -+ case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */ -+ case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */ -+ case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */ -+ case 0x2f0: /* CONTROL_SEC_STATUS */ -+ case 0x2f4: /* CONTROL_SEC_ERR_STATUS */ -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_sysctl_readfn[] = { -+ omap_badwidth_read32, /* TODO */ -+ omap_badwidth_read32, /* TODO */ -+ omap_sysctl_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_sysctl_writefn[] = { -+ omap_badwidth_write32, /* TODO */ -+ omap_badwidth_write32, /* TODO */ -+ omap_sysctl_write, -+}; -+ -+static void omap_sysctl_reset(struct omap_sysctl_s *s) -+{ -+ /* (power-on reset) */ -+ s->sysconfig = 0; -+ s->obs = 0; -+ s->devconfig = 0x0c000000; -+ s->msuspendmux[0] = 0x00000000; -+ s->msuspendmux[1] = 0x00000000; -+ s->msuspendmux[2] = 0x00000000; -+ s->msuspendmux[3] = 0x00000000; -+ s->msuspendmux[4] = 0x00000000; -+ s->psaconfig = 1; -+ -+ s->padconf[0x00] = 0x000f0f0f; -+ s->padconf[0x01] = 0x00000000; -+ s->padconf[0x02] = 0x00000000; -+ s->padconf[0x03] = 0x00000000; -+ s->padconf[0x04] = 0x00000000; -+ s->padconf[0x05] = 0x00000000; -+ s->padconf[0x06] = 0x00000000; -+ s->padconf[0x07] = 0x00000000; -+ s->padconf[0x08] = 0x08080800; -+ s->padconf[0x09] = 0x08080808; -+ s->padconf[0x0a] = 0x08080808; -+ s->padconf[0x0b] = 0x08080808; -+ s->padconf[0x0c] = 0x08080808; -+ s->padconf[0x0d] = 0x08080800; -+ s->padconf[0x0e] = 0x08080808; -+ s->padconf[0x0f] = 0x08080808; -+ s->padconf[0x10] = 0x18181808; /* | 0x07070700 if SBoot3 */ -+ s->padconf[0x11] = 0x18181818; /* | 0x07070707 if SBoot3 */ -+ s->padconf[0x12] = 0x18181818; /* | 0x07070707 if SBoot3 */ -+ s->padconf[0x13] = 0x18181818; /* | 0x07070707 if SBoot3 */ -+ s->padconf[0x14] = 0x18181818; /* | 0x00070707 if SBoot3 */ -+ s->padconf[0x15] = 0x18181818; -+ s->padconf[0x16] = 0x18181818; /* | 0x07000000 if SBoot3 */ -+ s->padconf[0x17] = 0x1f001f00; -+ s->padconf[0x18] = 0x1f1f1f1f; -+ s->padconf[0x19] = 0x00000000; -+ s->padconf[0x1a] = 0x1f180000; -+ s->padconf[0x1b] = 0x00001f1f; -+ s->padconf[0x1c] = 0x1f001f00; -+ s->padconf[0x1d] = 0x00000000; -+ s->padconf[0x1e] = 0x00000000; -+ s->padconf[0x1f] = 0x08000000; -+ s->padconf[0x20] = 0x08080808; -+ s->padconf[0x21] = 0x08080808; -+ s->padconf[0x22] = 0x0f080808; -+ s->padconf[0x23] = 0x0f0f0f0f; -+ s->padconf[0x24] = 0x000f0f0f; -+ s->padconf[0x25] = 0x1f1f1f0f; -+ s->padconf[0x26] = 0x080f0f1f; -+ s->padconf[0x27] = 0x070f1808; -+ s->padconf[0x28] = 0x0f070707; -+ s->padconf[0x29] = 0x000f0f1f; -+ s->padconf[0x2a] = 0x0f0f0f1f; -+ s->padconf[0x2b] = 0x08000000; -+ s->padconf[0x2c] = 0x0000001f; -+ s->padconf[0x2d] = 0x0f0f1f00; -+ s->padconf[0x2e] = 0x1f1f0f0f; -+ s->padconf[0x2f] = 0x0f1f1f1f; -+ s->padconf[0x30] = 0x0f0f0f0f; -+ s->padconf[0x31] = 0x0f1f0f1f; -+ s->padconf[0x32] = 0x0f0f0f0f; -+ s->padconf[0x33] = 0x0f1f0f1f; -+ s->padconf[0x34] = 0x1f1f0f0f; -+ s->padconf[0x35] = 0x0f0f1f1f; -+ s->padconf[0x36] = 0x0f0f1f0f; -+ s->padconf[0x37] = 0x0f0f0f0f; -+ s->padconf[0x38] = 0x1f18180f; -+ s->padconf[0x39] = 0x1f1f1f1f; -+ s->padconf[0x3a] = 0x00001f1f; -+ s->padconf[0x3b] = 0x00000000; -+ s->padconf[0x3c] = 0x00000000; -+ s->padconf[0x3d] = 0x0f0f0f0f; -+ s->padconf[0x3e] = 0x18000f0f; -+ s->padconf[0x3f] = 0x00070000; -+ s->padconf[0x40] = 0x00000707; -+ s->padconf[0x41] = 0x0f1f0700; -+ s->padconf[0x42] = 0x1f1f070f; -+ s->padconf[0x43] = 0x0008081f; -+ s->padconf[0x44] = 0x00000800; -+} -+ -+struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta, -+ omap_clk iclk, struct omap_mpu_state_s *mpu) -+{ -+ int iomemtype; -+ struct omap_sysctl_s *s = (struct omap_sysctl_s *) -+ qemu_mallocz(sizeof(struct omap_sysctl_s)); -+ -+ s->mpu = mpu; -+ omap_sysctl_reset(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap_sysctl_readfn, -+ omap_sysctl_writefn, s); -+ s->base = omap_l4_attach(ta, 0, iomemtype); -+ omap_l4_attach(ta, 0, iomemtype); -+ -+ return s; -+} -+ -+/* SDRAM Controller Subsystem */ -+struct omap_sdrc_s { -+ target_phys_addr_t base; -+ -+ uint8_t config; -+}; -+ -+static void omap_sdrc_reset(struct omap_sdrc_s *s) -+{ -+ s->config = 0x10; -+} -+ -+static uint32_t omap_sdrc_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x00: /* SDRC_REVISION */ -+ return 0x20; -+ -+ case 0x10: /* SDRC_SYSCONFIG */ -+ return s->config; -+ -+ case 0x14: /* SDRC_SYSSTATUS */ -+ return 1; /* RESETDONE */ -+ -+ case 0x40: /* SDRC_CS_CFG */ -+ case 0x44: /* SDRC_SHARING */ -+ case 0x48: /* SDRC_ERR_ADDR */ -+ case 0x4c: /* SDRC_ERR_TYPE */ -+ case 0x60: /* SDRC_DLLA_SCTRL */ -+ case 0x64: /* SDRC_DLLA_STATUS */ -+ case 0x68: /* SDRC_DLLB_CTRL */ -+ case 0x6c: /* SDRC_DLLB_STATUS */ -+ case 0x70: /* SDRC_POWER */ -+ case 0x80: /* SDRC_MCFG_0 */ -+ case 0x84: /* SDRC_MR_0 */ -+ case 0x88: /* SDRC_EMR1_0 */ -+ case 0x8c: /* SDRC_EMR2_0 */ -+ case 0x90: /* SDRC_EMR3_0 */ -+ case 0x94: /* SDRC_DCDL1_CTRL */ -+ case 0x98: /* SDRC_DCDL2_CTRL */ -+ case 0x9c: /* SDRC_ACTIM_CTRLA_0 */ -+ case 0xa0: /* SDRC_ACTIM_CTRLB_0 */ -+ case 0xa4: /* SDRC_RFR_CTRL_0 */ -+ case 0xa8: /* SDRC_MANUAL_0 */ -+ case 0xb0: /* SDRC_MCFG_1 */ -+ case 0xb4: /* SDRC_MR_1 */ -+ case 0xb8: /* SDRC_EMR1_1 */ -+ case 0xbc: /* SDRC_EMR2_1 */ -+ case 0xc0: /* SDRC_EMR3_1 */ -+ case 0xc4: /* SDRC_ACTIM_CTRLA_1 */ -+ case 0xc8: /* SDRC_ACTIM_CTRLB_1 */ -+ case 0xd4: /* SDRC_RFR_CTRL_1 */ -+ case 0xd8: /* SDRC_MANUAL_1 */ -+ return 0x00; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_sdrc_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque; -+ int offset = addr - s->base; -+ -+ switch (offset) { -+ case 0x00: /* SDRC_REVISION */ -+ case 0x14: /* SDRC_SYSSTATUS */ -+ case 0x48: /* SDRC_ERR_ADDR */ -+ case 0x64: /* SDRC_DLLA_STATUS */ -+ case 0x6c: /* SDRC_DLLB_STATUS */ -+ OMAP_RO_REG(addr); -+ return; -+ -+ case 0x10: /* SDRC_SYSCONFIG */ -+ if ((value >> 3) != 0x2) -+ fprintf(stderr, "%s: bad SDRAM idle mode %i\n", -+ __FUNCTION__, value >> 3); -+ if (value & 2) -+ omap_sdrc_reset(s); -+ s->config = value & 0x18; -+ break; -+ -+ case 0x40: /* SDRC_CS_CFG */ -+ case 0x44: /* SDRC_SHARING */ -+ case 0x4c: /* SDRC_ERR_TYPE */ -+ case 0x60: /* SDRC_DLLA_SCTRL */ -+ case 0x68: /* SDRC_DLLB_CTRL */ -+ case 0x70: /* SDRC_POWER */ -+ case 0x80: /* SDRC_MCFG_0 */ -+ case 0x84: /* SDRC_MR_0 */ -+ case 0x88: /* SDRC_EMR1_0 */ -+ case 0x8c: /* SDRC_EMR2_0 */ -+ case 0x90: /* SDRC_EMR3_0 */ -+ case 0x94: /* SDRC_DCDL1_CTRL */ -+ case 0x98: /* SDRC_DCDL2_CTRL */ -+ case 0x9c: /* SDRC_ACTIM_CTRLA_0 */ -+ case 0xa0: /* SDRC_ACTIM_CTRLB_0 */ -+ case 0xa4: /* SDRC_RFR_CTRL_0 */ -+ case 0xa8: /* SDRC_MANUAL_0 */ -+ case 0xb0: /* SDRC_MCFG_1 */ -+ case 0xb4: /* SDRC_MR_1 */ -+ case 0xb8: /* SDRC_EMR1_1 */ -+ case 0xbc: /* SDRC_EMR2_1 */ -+ case 0xc0: /* SDRC_EMR3_1 */ -+ case 0xc4: /* SDRC_ACTIM_CTRLA_1 */ -+ case 0xc8: /* SDRC_ACTIM_CTRLB_1 */ -+ case 0xd4: /* SDRC_RFR_CTRL_1 */ -+ case 0xd8: /* SDRC_MANUAL_1 */ -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_sdrc_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_sdrc_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_sdrc_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_sdrc_write, -+}; -+ -+struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base) -+{ -+ int iomemtype; -+ struct omap_sdrc_s *s = (struct omap_sdrc_s *) -+ qemu_mallocz(sizeof(struct omap_sdrc_s)); -+ -+ s->base = base; -+ omap_sdrc_reset(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap_sdrc_readfn, -+ omap_sdrc_writefn, s); -+ cpu_register_physical_memory(s->base, 0x1000, iomemtype); -+ -+ return s; -+} -+ -+/* General-Purpose Memory Controller */ -+struct omap_gpmc_s { -+ target_phys_addr_t base; -+ qemu_irq irq; -+ -+ uint8_t sysconfig; -+ uint16_t irqst; -+ uint16_t irqen; -+ uint16_t timeout; -+ uint16_t config; -+ uint32_t prefconfig[2]; -+ int prefcontrol; -+ int preffifo; -+ int prefcount; -+ struct omap_gpmc_cs_file_s { -+ uint32_t config[7]; -+ target_phys_addr_t base; -+ size_t size; -+ int iomemtype; -+ void (*base_update)(void *opaque, target_phys_addr_t new); -+ void (*unmap)(void *opaque); -+ void *opaque; -+ } cs_file[8]; -+ int ecc_cs; -+ int ecc_ptr; -+ uint32_t ecc_cfg; -+ struct ecc_state_s ecc[9]; -+}; -+ -+static void omap_gpmc_int_update(struct omap_gpmc_s *s) -+{ -+ qemu_set_irq(s->irq, s->irqen & s->irqst); -+} -+ -+static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask) -+{ -+ /* TODO: check for overlapping regions and report access errors */ -+ if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) || -+ (base < 0 || base >= 0x40) || -+ (base & 0x0f & ~mask)) { -+ fprintf(stderr, "%s: wrong cs address mapping/decoding!\n", -+ __FUNCTION__); -+ return; -+ } -+ -+ if (!f->opaque) -+ return; -+ -+ f->base = base << 24; -+ f->size = (0x0fffffff & ~(mask << 24)) + 1; -+ /* TODO: rather than setting the size of the mapping (which should be -+ * constant), the mask should cause wrapping of the address space, so -+ * that the same memory becomes accessible at every size bytes -+ * starting from base. */ -+ if (f->iomemtype) -+ cpu_register_physical_memory(f->base, f->size, f->iomemtype); -+ -+ if (f->base_update) -+ f->base_update(f->opaque, f->base); -+} -+ -+static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f) -+{ -+ if (f->size) { -+ if (f->unmap) -+ f->unmap(f->opaque); -+ if (f->iomemtype) -+ cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED); -+ f->base = 0; -+ f->size = 0; -+ } -+} -+ -+static void omap_gpmc_reset(struct omap_gpmc_s *s) -+{ -+ int i; -+ -+ s->sysconfig = 0; -+ s->irqst = 0; -+ s->irqen = 0; -+ omap_gpmc_int_update(s); -+ s->timeout = 0; -+ s->config = 0xa00; -+ s->prefconfig[0] = 0x00004000; -+ s->prefconfig[1] = 0x00000000; -+ s->prefcontrol = 0; -+ s->preffifo = 0; -+ s->prefcount = 0; -+ for (i = 0; i < 8; i ++) { -+ if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */ -+ omap_gpmc_cs_unmap(s->cs_file + i); -+ s->cs_file[i].config[0] = i ? 1 << 12 : 0; -+ s->cs_file[i].config[1] = 0x101001; -+ s->cs_file[i].config[2] = 0x020201; -+ s->cs_file[i].config[3] = 0x10031003; -+ s->cs_file[i].config[4] = 0x10f1111; -+ s->cs_file[i].config[5] = 0; -+ s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6); -+ if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */ -+ omap_gpmc_cs_map(&s->cs_file[i], -+ s->cs_file[i].config[6] & 0x1f, /* MASKADDR */ -+ (s->cs_file[i].config[6] >> 8 & 0xf)); /* BASEADDR */ -+ } -+ omap_gpmc_cs_map(s->cs_file, 0, 0xf); -+ s->ecc_cs = 0; -+ s->ecc_ptr = 0; -+ s->ecc_cfg = 0x3fcff000; -+ for (i = 0; i < 9; i ++) -+ ecc_reset(&s->ecc[i]); -+} -+ -+static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque; -+ int offset = addr - s->base; -+ int cs; -+ struct omap_gpmc_cs_file_s *f; -+ -+ switch (offset) { -+ case 0x000: /* GPMC_REVISION */ -+ return 0x20; -+ -+ case 0x010: /* GPMC_SYSCONFIG */ -+ return s->sysconfig; -+ -+ case 0x014: /* GPMC_SYSSTATUS */ -+ return 1; /* RESETDONE */ -+ -+ case 0x018: /* GPMC_IRQSTATUS */ -+ return s->irqst; -+ -+ case 0x01c: /* GPMC_IRQENABLE */ -+ return s->irqen; -+ -+ case 0x040: /* GPMC_TIMEOUT_CONTROL */ -+ return s->timeout; -+ -+ case 0x044: /* GPMC_ERR_ADDRESS */ -+ case 0x048: /* GPMC_ERR_TYPE */ -+ return 0; -+ -+ case 0x050: /* GPMC_CONFIG */ -+ return s->config; -+ -+ case 0x054: /* GPMC_STATUS */ -+ return 0x001; -+ -+ case 0x060 ... 0x1d4: -+ cs = (offset - 0x060) / 0x30; -+ offset -= cs * 0x30; -+ f = s->cs_file + cs; -+ switch (offset - cs * 0x30) { -+ case 0x60: /* GPMC_CONFIG1 */ -+ return f->config[0]; -+ case 0x64: /* GPMC_CONFIG2 */ -+ return f->config[1]; -+ case 0x68: /* GPMC_CONFIG3 */ -+ return f->config[2]; -+ case 0x6c: /* GPMC_CONFIG4 */ -+ return f->config[3]; -+ case 0x70: /* GPMC_CONFIG5 */ -+ return f->config[4]; -+ case 0x74: /* GPMC_CONFIG6 */ -+ return f->config[5]; -+ case 0x78: /* GPMC_CONFIG7 */ -+ return f->config[6]; -+ case 0x84: /* GPMC_NAND_DATA */ -+ return 0; -+ } -+ break; -+ -+ case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */ -+ return s->prefconfig[0]; -+ case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */ -+ return s->prefconfig[1]; -+ case 0x1ec: /* GPMC_PREFETCH_CONTROL */ -+ return s->prefcontrol; -+ case 0x1f0: /* GPMC_PREFETCH_STATUS */ -+ return (s->preffifo << 24) | -+ ((s->preffifo > -+ ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) | -+ s->prefcount; -+ -+ case 0x1f4: /* GPMC_ECC_CONFIG */ -+ return s->ecc_cs; -+ case 0x1f8: /* GPMC_ECC_CONTROL */ -+ return s->ecc_ptr; -+ case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */ -+ return s->ecc_cfg; -+ case 0x200 ... 0x220: /* GPMC_ECC_RESULT */ -+ cs = (offset & 0x1f) >> 2; -+ /* TODO: check correctness */ -+ return -+ ((s->ecc[cs].cp & 0x07) << 0) | -+ ((s->ecc[cs].cp & 0x38) << 13) | -+ ((s->ecc[cs].lp[0] & 0x1ff) << 3) | -+ ((s->ecc[cs].lp[1] & 0x1ff) << 19); -+ -+ case 0x230: /* GPMC_TESTMODE_CTRL */ -+ return 0; -+ case 0x234: /* GPMC_PSA_LSB */ -+ case 0x238: /* GPMC_PSA_MSB */ -+ return 0x00000000; -+ } -+ -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_gpmc_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque; -+ int offset = addr - s->base; -+ int cs; -+ struct omap_gpmc_cs_file_s *f; -+ -+ switch (offset) { -+ case 0x000: /* GPMC_REVISION */ -+ case 0x014: /* GPMC_SYSSTATUS */ -+ case 0x054: /* GPMC_STATUS */ -+ case 0x1f0: /* GPMC_PREFETCH_STATUS */ -+ case 0x200 ... 0x220: /* GPMC_ECC_RESULT */ -+ case 0x234: /* GPMC_PSA_LSB */ -+ case 0x238: /* GPMC_PSA_MSB */ -+ OMAP_RO_REG(addr); -+ break; -+ -+ case 0x010: /* GPMC_SYSCONFIG */ -+ if ((value >> 3) == 0x3) -+ fprintf(stderr, "%s: bad SDRAM idle mode %i\n", -+ __FUNCTION__, value >> 3); -+ if (value & 2) -+ omap_gpmc_reset(s); -+ s->sysconfig = value & 0x19; -+ break; -+ -+ case 0x018: /* GPMC_IRQSTATUS */ -+ s->irqen = ~value; -+ omap_gpmc_int_update(s); -+ break; -+ -+ case 0x01c: /* GPMC_IRQENABLE */ -+ s->irqen = value & 0xf03; -+ omap_gpmc_int_update(s); -+ break; -+ -+ case 0x040: /* GPMC_TIMEOUT_CONTROL */ -+ s->timeout = value & 0x1ff1; -+ break; -+ -+ case 0x044: /* GPMC_ERR_ADDRESS */ -+ case 0x048: /* GPMC_ERR_TYPE */ -+ break; -+ -+ case 0x050: /* GPMC_CONFIG */ -+ s->config = value & 0xf13; -+ break; -+ -+ case 0x060 ... 0x1d4: -+ cs = (offset - 0x060) / 0x30; -+ offset -= cs * 0x30; -+ f = s->cs_file + cs; -+ switch (offset - cs * 0x30) { -+ case 0x60: /* GPMC_CONFIG1 */ -+ f->config[0] = value & 0xffef3e13; -+ break; -+ case 0x64: /* GPMC_CONFIG2 */ -+ f->config[1] = value & 0x001f1f8f; -+ break; -+ case 0x68: /* GPMC_CONFIG3 */ -+ f->config[2] = value & 0x001f1f8f; -+ break; -+ case 0x6c: /* GPMC_CONFIG4 */ -+ f->config[3] = value & 0x1f8f1f8f; -+ break; -+ case 0x70: /* GPMC_CONFIG5 */ -+ f->config[4] = value & 0x0f1f1f1f; -+ break; -+ case 0x74: /* GPMC_CONFIG6 */ -+ f->config[5] = value & 0x00000fcf; -+ break; -+ case 0x78: /* GPMC_CONFIG7 */ -+ if ((f->config[6] ^ value) & 0xf7f) { -+ if (f->config[6] & (1 << 6)) /* CSVALID */ -+ omap_gpmc_cs_unmap(f); -+ if (value & (1 << 6)) /* CSVALID */ -+ omap_gpmc_cs_map(f, value & 0x1f, /* MASKADDR */ -+ (value >> 8 & 0xf)); /* BASEADDR */ -+ } -+ f->config[6] = value & 0x00000f7f; -+ break; -+ case 0x7c: /* GPMC_NAND_COMMAND */ -+ case 0x80: /* GPMC_NAND_ADDRESS */ -+ case 0x84: /* GPMC_NAND_DATA */ -+ break; -+ -+ default: -+ goto bad_reg; -+ } -+ break; -+ -+ case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */ -+ s->prefconfig[0] = value & 0x7f8f7fbf; -+ /* TODO: update interrupts, fifos, dmas */ -+ break; -+ -+ case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */ -+ s->prefconfig[1] = value & 0x3fff; -+ break; -+ -+ case 0x1ec: /* GPMC_PREFETCH_CONTROL */ -+ s->prefcontrol = value & 1; -+ if (s->prefcontrol) { -+ if (s->prefconfig[0] & 1) -+ s->preffifo = 0x40; -+ else -+ s->preffifo = 0x00; -+ } -+ /* TODO: start */ -+ break; -+ -+ case 0x1f4: /* GPMC_ECC_CONFIG */ -+ s->ecc_cs = 0x8f; -+ break; -+ case 0x1f8: /* GPMC_ECC_CONTROL */ -+ if (value & (1 << 8)) -+ for (cs = 0; cs < 9; cs ++) -+ ecc_reset(&s->ecc[cs]); -+ s->ecc_ptr = value & 0xf; -+ if (s->ecc_ptr == 0 || s->ecc_ptr > 9) { -+ s->ecc_ptr = 0; -+ s->ecc_cs &= ~1; -+ } -+ break; -+ case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */ -+ s->ecc_cfg = value & 0x3fcff1ff; -+ break; -+ case 0x230: /* GPMC_TESTMODE_CTRL */ -+ if (value & 7) -+ fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__); -+ break; -+ -+ default: -+ bad_reg: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+} -+ -+static CPUReadMemoryFunc *omap_gpmc_readfn[] = { -+ omap_badwidth_read32, /* TODO */ -+ omap_badwidth_read32, /* TODO */ -+ omap_gpmc_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_gpmc_writefn[] = { -+ omap_badwidth_write32, /* TODO */ -+ omap_badwidth_write32, /* TODO */ -+ omap_gpmc_write, -+}; -+ -+struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq) -+{ -+ int iomemtype; -+ struct omap_gpmc_s *s = (struct omap_gpmc_s *) -+ qemu_mallocz(sizeof(struct omap_gpmc_s)); -+ -+ s->base = base; -+ omap_gpmc_reset(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap_gpmc_readfn, -+ omap_gpmc_writefn, s); -+ cpu_register_physical_memory(s->base, 0x1000, iomemtype); -+ -+ return s; -+} -+ -+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype, -+ void (*base_upd)(void *opaque, target_phys_addr_t new), -+ void (*unmap)(void *opaque), void *opaque) -+{ -+ struct omap_gpmc_cs_file_s *f; -+ -+ if (cs < 0 || cs >= 8) { -+ fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs); -+ exit(-1); -+ } -+ f = &s->cs_file[cs]; -+ -+ f->iomemtype = iomemtype; -+ f->base_update = base_upd; -+ f->unmap = unmap; -+ f->opaque = opaque; -+ -+ if (f->config[6] & (1 << 6)) /* CSVALID */ -+ omap_gpmc_cs_map(f, f->config[6] & 0x1f, /* MASKADDR */ -+ (f->config[6] >> 8 & 0xf)); /* BASEADDR */ -+} -+ -+/* General chip reset */ -+static void omap2_mpu_reset(void *opaque) -+{ -+ struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque; -+ -+ omap_inth_reset(mpu->ih[0]); -+ omap_dma_reset(mpu->dma); -+ omap_prcm_reset(mpu->prcm); -+ omap_sysctl_reset(mpu->sysc); -+ omap_gp_timer_reset(mpu->gptimer[0]); -+ omap_gp_timer_reset(mpu->gptimer[1]); -+ omap_gp_timer_reset(mpu->gptimer[2]); -+ omap_gp_timer_reset(mpu->gptimer[3]); -+ omap_gp_timer_reset(mpu->gptimer[4]); -+ omap_gp_timer_reset(mpu->gptimer[5]); -+ omap_gp_timer_reset(mpu->gptimer[6]); -+ omap_gp_timer_reset(mpu->gptimer[7]); -+ omap_gp_timer_reset(mpu->gptimer[8]); -+ omap_gp_timer_reset(mpu->gptimer[9]); -+ omap_gp_timer_reset(mpu->gptimer[10]); -+ omap_gp_timer_reset(mpu->gptimer[11]); -+ omap_synctimer_reset(&mpu->synctimer); -+ omap_sdrc_reset(mpu->sdrc); -+ omap_gpmc_reset(mpu->gpmc); -+ omap_dss_reset(mpu->dss); -+#if 0 -+ omap_wd_timer_reset(mpu->wdt); -+ omap_ulpd_pm_reset(mpu); -+ omap_pin_cfg_reset(mpu); -+ omap_mpui_reset(mpu); -+ omap_tipb_bridge_reset(mpu->private_tipb); -+ omap_tipb_bridge_reset(mpu->public_tipb); -+ omap_dpll_reset(&mpu->dpll[0]); -+ omap_dpll_reset(&mpu->dpll[1]); -+ omap_dpll_reset(&mpu->dpll[2]); -+#endif -+ omap_uart_reset(mpu->uart[0]); -+ omap_uart_reset(mpu->uart[1]); -+ omap_uart_reset(mpu->uart[2]); -+ omap_mmc_reset(mpu->mmc); -+ omap_gpif_reset(mpu->gpif); -+ omap_mcspi_reset(mpu->mcspi[0]); -+ omap_mcspi_reset(mpu->mcspi[1]); -+#if 0 -+ omap_pwl_reset(mpu); -+ omap_pwt_reset(mpu); -+#endif -+ omap_i2c_reset(mpu->i2c[0]); -+ omap_i2c_reset(mpu->i2c[1]); -+#if 0 -+ omap_rtc_reset(mpu->rtc); -+ omap_mcbsp_reset(mpu->mcbsp1); -+ omap_mcbsp_reset(mpu->mcbsp2); -+ omap_mcbsp_reset(mpu->mcbsp3); -+ omap_lpg_reset(mpu->led[0]); -+ omap_lpg_reset(mpu->led[1]); -+ omap_clkm_reset(mpu); -+#endif -+ cpu_reset(mpu->env); -+} -+ -+static int omap2_validate_addr(struct omap_mpu_state_s *s, -+ target_phys_addr_t addr) -+{ -+ return 1; -+} -+ -+static const struct dma_irq_map omap2_dma_irq_map[] = { -+ { 0, OMAP_INT_24XX_SDMA_IRQ0 }, -+ { 0, OMAP_INT_24XX_SDMA_IRQ1 }, -+ { 0, OMAP_INT_24XX_SDMA_IRQ2 }, -+ { 0, OMAP_INT_24XX_SDMA_IRQ3 }, -+}; -+ -+struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size, -+ DisplayState *ds, const char *core) -+{ -+ struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) -+ qemu_mallocz(sizeof(struct omap_mpu_state_s)); -+ ram_addr_t sram_base, q3_base; -+ qemu_irq *cpu_irq; -+ qemu_irq dma_irqs[4]; -+ omap_clk gpio_clks[4]; -+ int sdindex; -+ int i; -+ -+ /* Core */ -+ s->mpu_model = omap2420; -+ s->env = cpu_init(core ?: "arm1136-r2"); -+ if (!s->env) { -+ fprintf(stderr, "Unable to find CPU definition\n"); -+ exit(1); -+ } -+ s->sdram_size = sdram_size; -+ s->sram_size = OMAP242X_SRAM_SIZE; -+ -+ s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0]; -+ -+ /* Clocks */ -+ omap_clk_init(s); -+ -+ /* Memory-mapped stuff */ -+ cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size, -+ (q3_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM); -+ cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size, -+ (sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM); -+ -+ s->l4 = omap_l4_init(OMAP2_L4_BASE, 54); -+ -+ /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */ -+ cpu_irq = arm_pic_init_cpu(s->env); -+ s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0], -+ cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ], -+ omap_findclk(s, "mpu_intc_fclk"), -+ omap_findclk(s, "mpu_intc_iclk")); -+ -+ s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3), -+ s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s); -+ -+ s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1), -+ omap_findclk(s, "omapctrl_iclk"), s); -+ -+ for (i = 0; i < 4; i ++) -+ dma_irqs[i] = -+ s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr]; -+ s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32, -+ omap_findclk(s, "sdma_iclk"), -+ omap_findclk(s, "sdma_fclk")); -+ s->port->addr_valid = omap2_validate_addr; -+ -+ s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19), -+ s->irq[0][OMAP_INT_24XX_UART1_IRQ], -+ omap_findclk(s, "uart1_fclk"), -+ omap_findclk(s, "uart1_iclk"), -+ s->drq[OMAP24XX_DMA_UART1_TX], -+ s->drq[OMAP24XX_DMA_UART1_RX], serial_hds[0]); -+ s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20), -+ s->irq[0][OMAP_INT_24XX_UART2_IRQ], -+ omap_findclk(s, "uart2_fclk"), -+ omap_findclk(s, "uart2_iclk"), -+ s->drq[OMAP24XX_DMA_UART2_TX], -+ s->drq[OMAP24XX_DMA_UART2_RX], -+ serial_hds[0] ? serial_hds[1] : 0); -+ s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21), -+ s->irq[0][OMAP_INT_24XX_UART3_IRQ], -+ omap_findclk(s, "uart3_fclk"), -+ omap_findclk(s, "uart3_iclk"), -+ s->drq[OMAP24XX_DMA_UART3_TX], -+ s->drq[OMAP24XX_DMA_UART3_RX], -+ serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0); -+ -+ s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7), -+ s->irq[0][OMAP_INT_24XX_GPTIMER1], -+ omap_findclk(s, "wu_gpt1_clk"), -+ omap_findclk(s, "wu_l4_iclk")); -+ s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8), -+ s->irq[0][OMAP_INT_24XX_GPTIMER2], -+ omap_findclk(s, "core_gpt2_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22), -+ s->irq[0][OMAP_INT_24XX_GPTIMER3], -+ omap_findclk(s, "core_gpt3_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23), -+ s->irq[0][OMAP_INT_24XX_GPTIMER4], -+ omap_findclk(s, "core_gpt4_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24), -+ s->irq[0][OMAP_INT_24XX_GPTIMER5], -+ omap_findclk(s, "core_gpt5_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25), -+ s->irq[0][OMAP_INT_24XX_GPTIMER6], -+ omap_findclk(s, "core_gpt6_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26), -+ s->irq[0][OMAP_INT_24XX_GPTIMER7], -+ omap_findclk(s, "core_gpt7_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27), -+ s->irq[0][OMAP_INT_24XX_GPTIMER8], -+ omap_findclk(s, "core_gpt8_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28), -+ s->irq[0][OMAP_INT_24XX_GPTIMER9], -+ omap_findclk(s, "core_gpt9_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29), -+ s->irq[0][OMAP_INT_24XX_GPTIMER10], -+ omap_findclk(s, "core_gpt10_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30), -+ s->irq[0][OMAP_INT_24XX_GPTIMER11], -+ omap_findclk(s, "core_gpt11_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31), -+ s->irq[0][OMAP_INT_24XX_GPTIMER12], -+ omap_findclk(s, "core_gpt12_clk"), -+ omap_findclk(s, "core_l4_iclk")); -+ -+ omap_tap_init(omap_l4ta(s->l4, 2), s); -+ -+ omap_synctimer_init(omap_l4tao(s->l4, 2), s, -+ omap_findclk(s, "clk32-kHz"), -+ omap_findclk(s, "core_l4_iclk")); -+ -+ s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5), -+ s->irq[0][OMAP_INT_24XX_I2C1_IRQ], -+ &s->drq[OMAP24XX_DMA_I2C1_TX], -+ omap_findclk(s, "i2c1.fclk"), -+ omap_findclk(s, "i2c1.iclk")); -+ s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6), -+ s->irq[0][OMAP_INT_24XX_I2C2_IRQ], -+ &s->drq[OMAP24XX_DMA_I2C2_TX], -+ omap_findclk(s, "i2c2.fclk"), -+ omap_findclk(s, "i2c2.iclk")); -+ -+ gpio_clks[0] = omap_findclk(s, "gpio1_dbclk"); -+ gpio_clks[1] = omap_findclk(s, "gpio2_dbclk"); -+ gpio_clks[2] = omap_findclk(s, "gpio3_dbclk"); -+ gpio_clks[3] = omap_findclk(s, "gpio4_dbclk"); -+ s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3), -+ &s->irq[0][OMAP_INT_24XX_GPIO_BANK1], -+ gpio_clks, omap_findclk(s, "gpio_iclk"), 4); -+ -+ s->sdrc = omap_sdrc_init(0x68009000); -+ s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]); -+ -+ sdindex = drive_get_index(IF_SD, 0, 0); -+ if (sdindex == -1) { -+ fprintf(stderr, "qemu: missing SecureDigital device\n"); -+ exit(1); -+ } -+ s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), drives_table[sdindex].bdrv, -+ s->irq[0][OMAP_INT_24XX_MMC_IRQ], -+ &s->drq[OMAP24XX_DMA_MMC1_TX], -+ omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk")); -+ -+ s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4, -+ s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ], -+ &s->drq[OMAP24XX_DMA_SPI1_TX0], -+ omap_findclk(s, "spi1_fclk"), -+ omap_findclk(s, "spi1_iclk")); -+ s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2, -+ s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ], -+ &s->drq[OMAP24XX_DMA_SPI2_TX0], -+ omap_findclk(s, "spi2_fclk"), -+ omap_findclk(s, "spi2_iclk")); -+ -+ s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800, ds, -+ /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */ -+ s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS], -+ omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"), -+ omap_findclk(s, "dss_54m_clk"), -+ omap_findclk(s, "dss_l3_iclk"), -+ omap_findclk(s, "dss_l4_iclk")); -+ -+ /* Register mappings not currenlty implemented: -+ * SystemControlMod 48000000 - 48000fff -+ * SystemControlL4 48001000 - 48001fff -+ * 32kHz Timer Mod 48004000 - 48004fff -+ * 32kHz Timer L4 48005000 - 48005fff -+ * PRCM ModA 48008000 - 480087ff -+ * PRCM ModB 48008800 - 48008fff -+ * PRCM L4 48009000 - 48009fff -+ * TEST-BCM Mod 48012000 - 48012fff -+ * TEST-BCM L4 48013000 - 48013fff -+ * TEST-TAP Mod 48014000 - 48014fff -+ * TEST-TAP L4 48015000 - 48015fff -+ * GPIO1 Mod 48018000 - 48018fff -+ * GPIO Top 48019000 - 48019fff -+ * GPIO2 Mod 4801a000 - 4801afff -+ * GPIO L4 4801b000 - 4801bfff -+ * GPIO3 Mod 4801c000 - 4801cfff -+ * GPIO4 Mod 4801e000 - 4801efff -+ * WDTIMER1 Mod 48020000 - 48010fff -+ * WDTIMER Top 48021000 - 48011fff -+ * WDTIMER2 Mod 48022000 - 48012fff -+ * WDTIMER L4 48023000 - 48013fff -+ * WDTIMER3 Mod 48024000 - 48014fff -+ * WDTIMER3 L4 48025000 - 48015fff -+ * WDTIMER4 Mod 48026000 - 48016fff -+ * WDTIMER4 L4 48027000 - 48017fff -+ * GPTIMER1 Mod 48028000 - 48018fff -+ * GPTIMER1 L4 48029000 - 48019fff -+ * GPTIMER2 Mod 4802a000 - 4801afff -+ * GPTIMER2 L4 4802b000 - 4801bfff -+ * L4-Config AP 48040000 - 480407ff -+ * L4-Config IP 48040800 - 48040fff -+ * L4-Config LA 48041000 - 48041fff -+ * ARM11ETB Mod 48048000 - 48049fff -+ * ARM11ETB L4 4804a000 - 4804afff -+ * DISPLAY Top 48050000 - 480503ff -+ * DISPLAY DISPC 48050400 - 480507ff -+ * DISPLAY RFBI 48050800 - 48050bff -+ * DISPLAY VENC 48050c00 - 48050fff -+ * DISPLAY L4 48051000 - 48051fff -+ * CAMERA Top 48052000 - 480523ff -+ * CAMERA core 48052400 - 480527ff -+ * CAMERA DMA 48052800 - 48052bff -+ * CAMERA MMU 48052c00 - 48052fff -+ * CAMERA L4 48053000 - 48053fff -+ * SDMA Mod 48056000 - 48056fff -+ * SDMA L4 48057000 - 48057fff -+ * SSI Top 48058000 - 48058fff -+ * SSI GDD 48059000 - 48059fff -+ * SSI Port1 4805a000 - 4805afff -+ * SSI Port2 4805b000 - 4805bfff -+ * SSI L4 4805c000 - 4805cfff -+ * USB Mod 4805e000 - 480fefff -+ * USB L4 4805f000 - 480fffff -+ * WIN_TRACER1 Mod 48060000 - 48060fff -+ * WIN_TRACER1 L4 48061000 - 48061fff -+ * WIN_TRACER2 Mod 48062000 - 48062fff -+ * WIN_TRACER2 L4 48063000 - 48063fff -+ * WIN_TRACER3 Mod 48064000 - 48064fff -+ * WIN_TRACER3 L4 48065000 - 48065fff -+ * WIN_TRACER4 Top 48066000 - 480660ff -+ * WIN_TRACER4 ETT 48066100 - 480661ff -+ * WIN_TRACER4 WT 48066200 - 480662ff -+ * WIN_TRACER4 L4 48067000 - 48067fff -+ * XTI Mod 48068000 - 48068fff -+ * XTI L4 48069000 - 48069fff -+ * UART1 Mod 4806a000 - 4806afff -+ * UART1 L4 4806b000 - 4806bfff -+ * UART2 Mod 4806c000 - 4806cfff -+ * UART2 L4 4806d000 - 4806dfff -+ * UART3 Mod 4806e000 - 4806efff -+ * UART3 L4 4806f000 - 4806ffff -+ * I2C1 Mod 48070000 - 48070fff -+ * I2C1 L4 48071000 - 48071fff -+ * I2C2 Mod 48072000 - 48072fff -+ * I2C2 L4 48073000 - 48073fff -+ * McBSP1 Mod 48074000 - 48074fff -+ * McBSP1 L4 48075000 - 48075fff -+ * McBSP2 Mod 48076000 - 48076fff -+ * McBSP2 L4 48077000 - 48077fff -+ * GPTIMER3 Mod 48078000 - 48078fff -+ * GPTIMER3 L4 48079000 - 48079fff -+ * GPTIMER4 Mod 4807a000 - 4807afff -+ * GPTIMER4 L4 4807b000 - 4807bfff -+ * GPTIMER5 Mod 4807c000 - 4807cfff -+ * GPTIMER5 L4 4807d000 - 4807dfff -+ * GPTIMER6 Mod 4807e000 - 4807efff -+ * GPTIMER6 L4 4807f000 - 4807ffff -+ * GPTIMER7 Mod 48080000 - 48080fff -+ * GPTIMER7 L4 48081000 - 48081fff -+ * GPTIMER8 Mod 48082000 - 48082fff -+ * GPTIMER8 L4 48083000 - 48083fff -+ * GPTIMER9 Mod 48084000 - 48084fff -+ * GPTIMER9 L4 48085000 - 48085fff -+ * GPTIMER10 Mod 48086000 - 48086fff -+ * GPTIMER10 L4 48087000 - 48087fff -+ * GPTIMER11 Mod 48088000 - 48088fff -+ * GPTIMER11 L4 48089000 - 48089fff -+ * GPTIMER12 Mod 4808a000 - 4808afff -+ * GPTIMER12 L4 4808b000 - 4808bfff -+ * EAC Mod 48090000 - 48090fff -+ * EAC L4 48091000 - 48091fff -+ * FAC Mod 48092000 - 48092fff -+ * FAC L4 48093000 - 48093fff -+ * MAILBOX Mod 48094000 - 48094fff -+ * MAILBOX L4 48095000 - 48095fff -+ * SPI1 Mod 48098000 - 48098fff -+ * SPI1 L4 48099000 - 48099fff -+ * SPI2 Mod 4809a000 - 4809afff -+ * SPI2 L4 4809b000 - 4809bfff -+ * MMC/SDIO Mod 4809c000 - 4809cfff -+ * MMC/SDIO L4 4809d000 - 4809dfff -+ * MS_PRO Mod 4809e000 - 4809efff -+ * MS_PRO L4 4809f000 - 4809ffff -+ * RNG Mod 480a0000 - 480a0fff -+ * RNG L4 480a1000 - 480a1fff -+ * DES3DES Mod 480a2000 - 480a2fff -+ * DES3DES L4 480a3000 - 480a3fff -+ * SHA1MD5 Mod 480a4000 - 480a4fff -+ * SHA1MD5 L4 480a5000 - 480a5fff -+ * AES Mod 480a6000 - 480a6fff -+ * AES L4 480a7000 - 480a7fff -+ * PKA Mod 480a8000 - 480a9fff -+ * PKA L4 480aa000 - 480aafff -+ * MG Mod 480b0000 - 480b0fff -+ * MG L4 480b1000 - 480b1fff -+ * HDQ/1-wire Mod 480b2000 - 480b2fff -+ * HDQ/1-wire L4 480b3000 - 480b3fff -+ * MPU interrupt 480fe000 - 480fefff -+ * IVA RAM 5c000000 - 5c01ffff -+ * IVA ROM 5c020000 - 5c027fff -+ * IMG_BUF_A 5c040000 - 5c040fff -+ * IMG_BUF_B 5c042000 - 5c042fff -+ * VLCDS 5c048000 - 5c0487ff -+ * IMX_COEF 5c049000 - 5c04afff -+ * IMX_CMD 5c051000 - 5c051fff -+ * VLCDQ 5c053000 - 5c0533ff -+ * VLCDH 5c054000 - 5c054fff -+ * SEQ_CMD 5c055000 - 5c055fff -+ * IMX_REG 5c056000 - 5c0560ff -+ * VLCD_REG 5c056100 - 5c0561ff -+ * SEQ_REG 5c056200 - 5c0562ff -+ * IMG_BUF_REG 5c056300 - 5c0563ff -+ * SEQIRQ_REG 5c056400 - 5c0564ff -+ * OCP_REG 5c060000 - 5c060fff -+ * SYSC_REG 5c070000 - 5c070fff -+ * MMU_REG 5d000000 - 5d000fff -+ * sDMA R 68000400 - 680005ff -+ * sDMA W 68000600 - 680007ff -+ * Display Control 68000800 - 680009ff -+ * DSP subsystem 68000a00 - 68000bff -+ * MPU subsystem 68000c00 - 68000dff -+ * IVA subsystem 68001000 - 680011ff -+ * USB 68001200 - 680013ff -+ * Camera 68001400 - 680015ff -+ * VLYNQ (firewall) 68001800 - 68001bff -+ * VLYNQ 68001e00 - 68001fff -+ * SSI 68002000 - 680021ff -+ * L4 68002400 - 680025ff -+ * DSP (firewall) 68002800 - 68002bff -+ * DSP subsystem 68002e00 - 68002fff -+ * IVA (firewall) 68003000 - 680033ff -+ * IVA 68003600 - 680037ff -+ * GFX 68003a00 - 68003bff -+ * CMDWR emulation 68003c00 - 68003dff -+ * SMS 68004000 - 680041ff -+ * OCM 68004200 - 680043ff -+ * GPMC 68004400 - 680045ff -+ * RAM (firewall) 68005000 - 680053ff -+ * RAM (err login) 68005400 - 680057ff -+ * ROM (firewall) 68005800 - 68005bff -+ * ROM (err login) 68005c00 - 68005fff -+ * GPMC (firewall) 68006000 - 680063ff -+ * GPMC (err login) 68006400 - 680067ff -+ * SMS (err login) 68006c00 - 68006fff -+ * SMS registers 68008000 - 68008fff -+ * SDRC registers 68009000 - 68009fff -+ * GPMC registers 6800a000 6800afff -+ */ -+ -+ qemu_register_reset(omap2_mpu_reset, s); -+ -+ return s; -+} -diff --git a/hw/omap_clk.c b/hw/omap_clk.c -index 37daec2..da03e15 100644 ---- a/hw/omap_clk.c -+++ b/hw/omap_clk.c -@@ -34,6 +34,9 @@ struct clk { - #define CLOCK_IN_OMAP730 (1 << 11) - #define CLOCK_IN_OMAP1510 (1 << 12) - #define CLOCK_IN_OMAP16XX (1 << 13) -+#define CLOCK_IN_OMAP242X (1 << 14) -+#define CLOCK_IN_OMAP243X (1 << 15) -+#define CLOCK_IN_OMAP343X (1 << 16) - uint32_t flags; - int id; - -@@ -55,7 +58,8 @@ static struct clk xtal_osc12m = { - static struct clk xtal_osc32k = { - .name = "xtal_osc_32k", - .rate = 32768, -- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, -+ .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | -+ CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, - }; - - static struct clk ck_ref = { -@@ -502,11 +506,441 @@ static struct clk i2c_ick = { - static struct clk clk32k = { - .name = "clk32-kHz", - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | -- ALWAYS_ENABLED, -- .parent = &xtal_osc32k, -+ CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, -+ .parent = &xtal_osc32k, -+}; -+ -+static struct clk apll_96m = { -+ .name = "apll_96m", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, -+ .rate = 96000000, -+ /*.parent = sys.xtalin */ -+}; -+ -+static struct clk apll_54m = { -+ .name = "apll_54m", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, -+ .rate = 54000000, -+ /*.parent = sys.xtalin */ -+}; -+ -+static struct clk sys_clk = { -+ .name = "sys_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, -+ .rate = 32768, -+ /*.parent = sys.xtalin */ -+}; -+ -+static struct clk sleep_clk = { -+ .name = "sleep_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, -+ .rate = 32768, -+ /*.parent = sys.xtalin */ -+}; -+ -+static struct clk dpll_ck = { -+ .name = "dpll", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, -+ /*.parent = sys.xtalin */ -+}; -+ -+static struct clk dpll_x2_ck = { -+ .name = "dpll_x2", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, -+ /*.parent = sys.xtalin */ -+}; -+ -+static struct clk wdt1_sys_clk = { -+ .name = "wdt1_sys_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED, -+ .rate = 32768, -+ /*.parent = sys.xtalin */ -+}; -+ -+static struct clk func_96m_clk = { -+ .name = "func_96m_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .divisor = 1, -+ .parent = &apll_96m, -+}; -+ -+static struct clk func_48m_clk = { -+ .name = "func_48m_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .divisor = 2, -+ .parent = &apll_96m, -+}; -+ -+static struct clk func_12m_clk = { -+ .name = "func_12m_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .divisor = 8, -+ .parent = &apll_96m, -+}; -+ -+static struct clk func_54m_clk = { -+ .name = "func_54m_clk", -+ .flags = CLOCK_IN_OMAP242X, -+ .divisor = 1, -+ .parent = &apll_54m, -+}; -+ -+static struct clk sys_clkout = { -+ .name = "clkout", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk sys_clkout2 = { -+ .name = "clkout2", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_clk = { -+ .name = "core_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &dpll_ck, -+}; -+ -+static struct clk l3_clk = { -+ .name = "l3_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_clk, -+}; -+ -+static struct clk core_l4_iclk = { -+ .name = "core_l4_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &l3_clk, -+}; -+ -+static struct clk wu_l4_iclk = { -+ .name = "wu_l4_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &l3_clk, -+}; -+ -+static struct clk core_l3_iclk = { -+ .name = "core_l3_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_clk, -+}; -+ -+static struct clk core_l4_usb_clk = { -+ .name = "core_l4_usb_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &l3_clk, -+}; -+ -+static struct clk wu_gpt1_clk = { -+ .name = "wu_gpt1_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk wu_32k_clk = { -+ .name = "wu_32k_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk uart1_fclk = { -+ .name = "uart1_fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_48m_clk, -+}; -+ -+static struct clk uart1_iclk = { -+ .name = "uart1_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+}; -+ -+static struct clk uart2_fclk = { -+ .name = "uart2_fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_48m_clk, -+}; -+ -+static struct clk uart2_iclk = { -+ .name = "uart2_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+}; -+ -+static struct clk uart3_fclk = { -+ .name = "uart3_fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_48m_clk, -+}; -+ -+static struct clk uart3_iclk = { -+ .name = "uart3_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+}; -+ -+static struct clk mpu_fclk = { -+ .name = "mpu_fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_clk, -+}; -+ -+static struct clk mpu_iclk = { -+ .name = "mpu_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_clk, -+}; -+ -+static struct clk int_m_fclk = { -+ .name = "int_m_fclk", -+ .alias = "mpu_intc_fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_clk, -+}; -+ -+static struct clk int_m_iclk = { -+ .name = "int_m_iclk", -+ .alias = "mpu_intc_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_clk, -+}; -+ -+static struct clk core_gpt2_clk = { -+ .name = "core_gpt2_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt3_clk = { -+ .name = "core_gpt3_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt4_clk = { -+ .name = "core_gpt4_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt5_clk = { -+ .name = "core_gpt5_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt6_clk = { -+ .name = "core_gpt6_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt7_clk = { -+ .name = "core_gpt7_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt8_clk = { -+ .name = "core_gpt8_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt9_clk = { -+ .name = "core_gpt9_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt10_clk = { -+ .name = "core_gpt10_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt11_clk = { -+ .name = "core_gpt11_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk core_gpt12_clk = { -+ .name = "core_gpt12_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+}; -+ -+static struct clk mcbsp1_clk = { -+ .name = "mcbsp1_cg", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .divisor = 2, -+ .parent = &func_96m_clk, -+}; -+ -+static struct clk mcbsp2_clk = { -+ .name = "mcbsp2_cg", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .divisor = 2, -+ .parent = &func_96m_clk, -+}; -+ -+static struct clk emul_clk = { -+ .name = "emul_ck", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_54m_clk, -+}; -+ -+static struct clk sdma_fclk = { -+ .name = "sdma_fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &l3_clk, -+}; -+ -+static struct clk sdma_iclk = { -+ .name = "sdma_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l3_iclk, /* core_l4_iclk for the configuration port */ -+}; -+ -+static struct clk i2c1_fclk = { -+ .name = "i2c1.fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_12m_clk, -+ .divisor = 1, -+}; -+ -+static struct clk i2c1_iclk = { -+ .name = "i2c1.iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+}; -+ -+static struct clk i2c2_fclk = { -+ .name = "i2c2.fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_12m_clk, -+ .divisor = 1, -+}; -+ -+static struct clk i2c2_iclk = { -+ .name = "i2c2.iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+}; -+ -+static struct clk gpio_dbclk[4] = { -+ { -+ .name = "gpio1_dbclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &wu_32k_clk, -+ }, { -+ .name = "gpio2_dbclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &wu_32k_clk, -+ }, { -+ .name = "gpio3_dbclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &wu_32k_clk, -+ }, { -+ .name = "gpio4_dbclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &wu_32k_clk, -+ }, -+}; -+ -+static struct clk gpio_iclk = { -+ .name = "gpio_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &wu_l4_iclk, -+}; -+ -+static struct clk mmc_fck = { -+ .name = "mmc_fclk", -+ .flags = CLOCK_IN_OMAP242X, -+ .parent = &func_96m_clk, -+}; -+ -+static struct clk mmc_ick = { -+ .name = "mmc_iclk", -+ .flags = CLOCK_IN_OMAP242X, -+ .parent = &core_l4_iclk, -+}; -+ -+static struct clk spi_fclk[3] = { -+ { -+ .name = "spi1_fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_48m_clk, -+ }, { -+ .name = "spi2_fclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_48m_clk, -+ }, { -+ .name = "spi3_fclk", -+ .flags = CLOCK_IN_OMAP243X, -+ .parent = &func_48m_clk, -+ }, -+}; -+ -+static struct clk dss_clk[2] = { -+ { -+ .name = "dss_clk1", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_clk, -+ }, { -+ .name = "dss_clk2", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &sys_clk, -+ }, -+}; -+ -+static struct clk dss_54m_clk = { -+ .name = "dss_54m_clk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &func_54m_clk, -+}; -+ -+static struct clk dss_l3_iclk = { -+ .name = "dss_l3_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l3_iclk, -+}; -+ -+static struct clk dss_l4_iclk = { -+ .name = "dss_l4_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+}; -+ -+static struct clk spi_iclk[3] = { -+ { -+ .name = "spi1_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+ }, { -+ .name = "spi2_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+ }, { -+ .name = "spi3_iclk", -+ .flags = CLOCK_IN_OMAP243X, -+ .parent = &core_l4_iclk, -+ }, -+}; -+ -+static struct clk omapctrl_clk = { -+ .name = "omapctrl_iclk", -+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, -+ /* XXX Should be in WKUP domain */ -+ .parent = &core_l4_iclk, - }; - - static struct clk *onchip_clks[] = { -+ /* OMAP 1 */ -+ - /* non-ULPD clocks */ - &xtal_osc12m, - &xtal_osc32k, -@@ -572,6 +1006,80 @@ static struct clk *onchip_clks[] = { - /* Virtual clocks */ - &i2c_fck, - &i2c_ick, -+ -+ /* OMAP 2 */ -+ -+ &apll_96m, -+ &apll_54m, -+ &sys_clk, -+ &sleep_clk, -+ &dpll_ck, -+ &dpll_x2_ck, -+ &wdt1_sys_clk, -+ &func_96m_clk, -+ &func_48m_clk, -+ &func_12m_clk, -+ &func_54m_clk, -+ &sys_clkout, -+ &sys_clkout2, -+ &core_clk, -+ &l3_clk, -+ &core_l4_iclk, -+ &wu_l4_iclk, -+ &core_l3_iclk, -+ &core_l4_usb_clk, -+ &wu_gpt1_clk, -+ &wu_32k_clk, -+ &uart1_fclk, -+ &uart1_iclk, -+ &uart2_fclk, -+ &uart2_iclk, -+ &uart3_fclk, -+ &uart3_iclk, -+ &mpu_fclk, -+ &mpu_iclk, -+ &int_m_fclk, -+ &int_m_iclk, -+ &core_gpt2_clk, -+ &core_gpt3_clk, -+ &core_gpt4_clk, -+ &core_gpt5_clk, -+ &core_gpt6_clk, -+ &core_gpt7_clk, -+ &core_gpt8_clk, -+ &core_gpt9_clk, -+ &core_gpt10_clk, -+ &core_gpt11_clk, -+ &core_gpt12_clk, -+ &mcbsp1_clk, -+ &mcbsp2_clk, -+ &emul_clk, -+ &sdma_fclk, -+ &sdma_iclk, -+ &i2c1_fclk, -+ &i2c1_iclk, -+ &i2c2_fclk, -+ &i2c2_iclk, -+ &gpio_dbclk[0], -+ &gpio_dbclk[1], -+ &gpio_dbclk[2], -+ &gpio_dbclk[3], -+ &gpio_iclk, -+ &mmc_fck, -+ &mmc_ick, -+ &spi_fclk[0], -+ &spi_iclk[0], -+ &spi_fclk[1], -+ &spi_iclk[1], -+ &spi_fclk[2], -+ &spi_iclk[2], -+ &dss_clk[0], -+ &dss_clk[1], -+ &dss_54m_clk, -+ &dss_l3_iclk, -+ &dss_l4_iclk, -+ &omapctrl_clk, -+ - 0 - }; - -@@ -727,6 +1235,12 @@ void omap_clk_init(struct omap_mpu_state_s *mpu) - flag = CLOCK_IN_OMAP310; - else if (cpu_is_omap1510(mpu)) - flag = CLOCK_IN_OMAP1510; -+ else if (cpu_is_omap2410(mpu) || cpu_is_omap2420(mpu)) -+ flag = CLOCK_IN_OMAP242X; -+ else if (cpu_is_omap2430(mpu)) -+ flag = CLOCK_IN_OMAP243X; -+ else if (cpu_is_omap3430(mpu)) -+ flag = CLOCK_IN_OMAP243X; - else - return; - -diff --git a/hw/omap_dma.c b/hw/omap_dma.c -index 1835826..6c0bd82 100644 ---- a/hw/omap_dma.c -+++ b/hw/omap_dma.c -@@ -28,12 +28,15 @@ struct omap_dma_channel_s { - /* transfer data */ - int burst[2]; - int pack[2]; -+ int endian[2]; -+ int endian_lock[2]; -+ int translate[2]; - enum omap_dma_port port[2]; - target_phys_addr_t addr[2]; - omap_dma_addressing_t mode[2]; -- uint16_t elements; -+ uint32_t elements; - uint16_t frames; -- int16_t frame_index[2]; -+ int32_t frame_index[2]; - int16_t element_index[2]; - int data_type; - -@@ -41,6 +44,7 @@ struct omap_dma_channel_s { - int transparent_copy; - int constant_fill; - uint32_t color; -+ int prefetch; - - /* auto init and linked channel data */ - int end_prog; -@@ -52,11 +56,13 @@ struct omap_dma_channel_s { - /* interruption data */ - int interrupts; - int status; -+ int cstatus; - - /* state data */ - int active; - int enable; - int sync; -+ int src_sync; - int pending_request; - int waiting_end_prog; - uint16_t cpc; -@@ -75,16 +81,21 @@ struct omap_dma_channel_s { - target_phys_addr_t src, dest; - int frame; - int element; -+ int pck_element; - int frame_delta[2]; - int elem_delta[2]; - int frames; - int elements; -+ int pck_elements; - } active_set; - - /* unused parameters */ -+ int write_mode; - int priority; - int interleave_disabled; - int type; -+ int suspend; -+ int buf_disable; - }; - - struct omap_dma_s { -@@ -93,15 +104,21 @@ struct omap_dma_s { - target_phys_addr_t base; - omap_clk clk; - int64_t delay; -- uint32_t drq; -+ uint64_t drq; -+ qemu_irq irq[4]; -+ void (*intr_update)(struct omap_dma_s *s); - enum omap_dma_model model; - int omap_3_1_mapping_disabled; - -- uint16_t gcr; -+ uint32_t gcr; -+ uint32_t ocp; -+ uint32_t caps[5]; -+ uint32_t irqen[4]; -+ uint32_t irqstat[4]; - int run_count; - - int chans; -- struct omap_dma_channel_s ch[16]; -+ struct omap_dma_channel_s ch[32]; - struct omap_dma_lcd_channel_s lcd_ch; - }; - -@@ -113,23 +130,13 @@ struct omap_dma_s { - #define LAST_FRAME_INTR (1 << 4) - #define END_BLOCK_INTR (1 << 5) - #define SYNC (1 << 6) -+#define END_PKT_INTR (1 << 7) -+#define TRANS_ERR_INTR (1 << 8) -+#define MISALIGN_INTR (1 << 11) - --static void omap_dma_interrupts_update(struct omap_dma_s *s) -+static inline void omap_dma_interrupts_update(struct omap_dma_s *s) - { -- struct omap_dma_channel_s *ch = s->ch; -- int i; -- -- if (s->omap_3_1_mapping_disabled) { -- for (i = 0; i < s->chans; i ++, ch ++) -- if (ch->status) -- qemu_irq_raise(ch->irq); -- } else { -- /* First three interrupts are shared between two channels each. */ -- for (i = 0; i < 6; i ++, ch ++) { -- if (ch->status || (ch->sibling && ch->sibling->status)) -- qemu_irq_raise(ch->irq); -- } -- } -+ return s->intr_update(s); - } - - static void omap_dma_channel_load(struct omap_dma_s *s, -@@ -148,8 +155,10 @@ static void omap_dma_channel_load(struct omap_dma_s *s, - a->dest = ch->addr[1]; - a->frames = ch->frames; - a->elements = ch->elements; -+ a->pck_elements = ch->frame_index[!ch->src_sync]; - a->frame = 0; - a->element = 0; -+ a->pck_element = 0; - - if (unlikely(!ch->elements || !ch->frames)) { - printf("%s: bad DMA request\n", __FUNCTION__); -@@ -202,16 +211,15 @@ static void omap_dma_deactivate_channel(struct omap_dma_s *s, - /* Update cpc */ - ch->cpc = ch->active_set.dest & 0xffff; - -- if (ch->pending_request && !ch->waiting_end_prog) { -+ if (ch->pending_request && !ch->waiting_end_prog && ch->enable) { - /* Don't deactivate the channel */ - ch->pending_request = 0; -- if (ch->enable) -- return; -+ return; - } - - /* Don't deactive the channel if it is synchronized and the DMA request is - active */ -- if (ch->sync && (s->drq & (1 << ch->sync)) && ch->enable) -+ if (ch->sync && ch->enable && (s->drq & (1 << ch->sync))) - return; - - if (ch->active) { -@@ -231,6 +239,9 @@ static void omap_dma_enable_channel(struct omap_dma_s *s, - ch->enable = 1; - ch->waiting_end_prog = 0; - omap_dma_channel_load(s, ch); -+ /* TODO: theoretically if ch->sync && ch->prefetch && -+ * !s->drq[ch->sync], we should also activate and fetch from source -+ * and then stall until signalled. */ - if ((!ch->sync) || (s->drq & (1 << ch->sync))) - omap_dma_activate_channel(s, ch); - } -@@ -259,16 +270,47 @@ static void omap_dma_channel_end_prog(struct omap_dma_s *s, - } - } - -+static void omap_dma_interrupts_3_1_update(struct omap_dma_s *s) -+{ -+ struct omap_dma_channel_s *ch = s->ch; -+ -+ /* First three interrupts are shared between two channels each. */ -+ if (ch[0].status | ch[6].status) -+ qemu_irq_raise(ch[0].irq); -+ if (ch[1].status | ch[7].status) -+ qemu_irq_raise(ch[1].irq); -+ if (ch[2].status | ch[8].status) -+ qemu_irq_raise(ch[2].irq); -+ if (ch[3].status) -+ qemu_irq_raise(ch[3].irq); -+ if (ch[4].status) -+ qemu_irq_raise(ch[4].irq); -+ if (ch[5].status) -+ qemu_irq_raise(ch[5].irq); -+} -+ -+static void omap_dma_interrupts_3_2_update(struct omap_dma_s *s) -+{ -+ struct omap_dma_channel_s *ch = s->ch; -+ int i; -+ -+ for (i = s->chans; i; ch ++, i --) -+ if (ch->status) -+ qemu_irq_raise(ch->irq); -+} -+ - static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s) - { - s->omap_3_1_mapping_disabled = 0; - s->chans = 9; -+ s->intr_update = omap_dma_interrupts_3_1_update; - } - - static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s) - { - s->omap_3_1_mapping_disabled = 1; - s->chans = 16; -+ s->intr_update = omap_dma_interrupts_3_2_update; - } - - static void omap_dma_process_request(struct omap_dma_s *s, int request) -@@ -358,6 +400,22 @@ static void omap_dma_channel_run(struct omap_dma_s *s) - if (ch->interrupts & HALF_FRAME_INTR) - ch->status |= HALF_FRAME_INTR; - -+ if (ch->fs && ch->bs) { -+ a->pck_element ++; -+ /* Check if a full packet has beed transferred. */ -+ if (a->pck_element == a->pck_elements) { -+ a->pck_element = 0; -+ -+ /* Set the END_PKT interrupt */ -+ if ((ch->interrupts & END_PKT_INTR) && !ch->src_sync) -+ ch->status |= END_PKT_INTR; -+ -+ /* If the channel is packet-synchronized, deactivate it */ -+ if (ch->sync) -+ omap_dma_deactivate_channel(s, ch); -+ } -+ } -+ - if (a->element == a->elements) { - /* End of Frame */ - a->element = 0; -@@ -366,7 +424,7 @@ static void omap_dma_channel_run(struct omap_dma_s *s) - a->frame ++; - - /* If the channel is frame synchronized, deactivate it */ -- if (ch->sync && ch->fs) -+ if (ch->sync && ch->fs && !ch->bs) - omap_dma_deactivate_channel(s, ch); - - /* If the channel is async, update cpc */ -@@ -414,50 +472,62 @@ void omap_dma_reset(struct omap_dma_s *s) - int i; - - qemu_del_timer(s->tm); -- s->gcr = 0x0004; -+ if (s->model < omap_dma_4) -+ s->gcr = 0x0004; -+ else -+ s->gcr = 0x00010010; -+ s->ocp = 0x00000000; -+ memset(&s->irqstat, 0, sizeof(s->irqstat)); -+ memset(&s->irqen, 0, sizeof(s->irqen)); - s->drq = 0x00000000; - s->run_count = 0; - s->lcd_ch.src = emiff; - s->lcd_ch.condition = 0; - s->lcd_ch.interrupts = 0; - s->lcd_ch.dual = 0; -- omap_dma_enable_3_1_mapping(s); -+ if (s->model < omap_dma_4) -+ omap_dma_enable_3_1_mapping(s); - for (i = 0; i < s->chans; i ++) { -+ s->ch[i].suspend = 0; -+ s->ch[i].prefetch = 0; -+ s->ch[i].buf_disable = 0; -+ s->ch[i].src_sync = 0; - memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst)); - memset(&s->ch[i].port, 0, sizeof(s->ch[i].port)); - memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode)); -- memset(&s->ch[i].elements, 0, sizeof(s->ch[i].elements)); -- memset(&s->ch[i].frames, 0, sizeof(s->ch[i].frames)); - memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index)); - memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index)); -- memset(&s->ch[i].data_type, 0, sizeof(s->ch[i].data_type)); -- memset(&s->ch[i].transparent_copy, 0, -- sizeof(s->ch[i].transparent_copy)); -- memset(&s->ch[i].constant_fill, 0, sizeof(s->ch[i].constant_fill)); -- memset(&s->ch[i].color, 0, sizeof(s->ch[i].color)); -- memset(&s->ch[i].end_prog, 0, sizeof(s->ch[i].end_prog)); -- memset(&s->ch[i].repeat, 0, sizeof(s->ch[i].repeat)); -- memset(&s->ch[i].auto_init, 0, sizeof(s->ch[i].auto_init)); -- memset(&s->ch[i].link_enabled, 0, sizeof(s->ch[i].link_enabled)); -- memset(&s->ch[i].link_next_ch, 0, sizeof(s->ch[i].link_next_ch)); -- s->ch[i].interrupts = 0x0003; -- memset(&s->ch[i].status, 0, sizeof(s->ch[i].status)); -- memset(&s->ch[i].active, 0, sizeof(s->ch[i].active)); -- memset(&s->ch[i].enable, 0, sizeof(s->ch[i].enable)); -- memset(&s->ch[i].sync, 0, sizeof(s->ch[i].sync)); -- memset(&s->ch[i].pending_request, 0, sizeof(s->ch[i].pending_request)); -- memset(&s->ch[i].waiting_end_prog, 0, -- sizeof(s->ch[i].waiting_end_prog)); -- memset(&s->ch[i].cpc, 0, sizeof(s->ch[i].cpc)); -- memset(&s->ch[i].fs, 0, sizeof(s->ch[i].fs)); -- memset(&s->ch[i].bs, 0, sizeof(s->ch[i].bs)); -- memset(&s->ch[i].omap_3_1_compatible_disable, 0, -- sizeof(s->ch[i].omap_3_1_compatible_disable)); -+ memset(&s->ch[i].endian, 0, sizeof(s->ch[i].endian)); -+ memset(&s->ch[i].endian_lock, 0, sizeof(s->ch[i].endian_lock)); -+ memset(&s->ch[i].translate, 0, sizeof(s->ch[i].translate)); -+ s->ch[i].write_mode = 0; -+ s->ch[i].data_type = 0; -+ s->ch[i].transparent_copy = 0; -+ s->ch[i].constant_fill = 0; -+ s->ch[i].color = 0x00000000; -+ s->ch[i].end_prog = 0; -+ s->ch[i].repeat = 0; -+ s->ch[i].auto_init = 0; -+ s->ch[i].link_enabled = 0; -+ if (s->model < omap_dma_4) -+ s->ch[i].interrupts = 0x0003; -+ else -+ s->ch[i].interrupts = 0x0000; -+ s->ch[i].status = 0; -+ s->ch[i].cstatus = 0; -+ s->ch[i].active = 0; -+ s->ch[i].enable = 0; -+ s->ch[i].sync = 0; -+ s->ch[i].pending_request = 0; -+ s->ch[i].waiting_end_prog = 0; -+ s->ch[i].cpc = 0x0000; -+ s->ch[i].fs = 0; -+ s->ch[i].bs = 0; -+ s->ch[i].omap_3_1_compatible_disable = 0; - memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set)); -- memset(&s->ch[i].priority, 0, sizeof(s->ch[i].priority)); -- memset(&s->ch[i].interleave_disabled, 0, -- sizeof(s->ch[i].interleave_disabled)); -- memset(&s->ch[i].type, 0, sizeof(s->ch[i].type)); -+ s->ch[i].priority = 0; -+ s->ch[i].interleave_disabled = 0; -+ s->ch[i].type = 0; - } - } - -@@ -476,7 +546,7 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, - break; - - case 0x02: /* SYS_DMA_CCR_CH0 */ -- if (s->model == omap_dma_3_1) -+ if (s->model <= omap_dma_3_1) - *value = 0 << 10; /* FIFO_FLUSH reads as 0 */ - else - *value = ch->omap_3_1_compatible_disable << 10; -@@ -596,11 +666,11 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, - ch->burst[0] = (value & 0x0180) >> 7; - ch->pack[0] = (value & 0x0040) >> 6; - ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2); -- ch->data_type = (1 << (value & 3)); -- if (ch->port[0] >= omap_dma_port_last) -+ ch->data_type = 1 << (value & 3); -+ if (ch->port[0] >= __omap_dma_port_last) - printf("%s: invalid DMA port %i\n", __FUNCTION__, - ch->port[0]); -- if (ch->port[1] >= omap_dma_port_last) -+ if (ch->port[1] >= __omap_dma_port_last) - printf("%s: invalid DMA port %i\n", __FUNCTION__, - ch->port[1]); - if ((value & 3) == 3) -@@ -611,7 +681,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, - ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14); - ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12); - ch->end_prog = (value & 0x0800) >> 11; -- if (s->model > omap_dma_3_1) -+ if (s->model >= omap_dma_3_2) - ch->omap_3_1_compatible_disable = (value >> 10) & 0x1; - ch->repeat = (value & 0x0200) >> 9; - ch->auto_init = (value & 0x0100) >> 8; -@@ -630,7 +700,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, - break; - - case 0x04: /* SYS_DMA_CICR_CH0 */ -- ch->interrupts = value; -+ ch->interrupts = value & 0x3f; - break; - - case 0x06: /* SYS_DMA_CSR_CH0 */ -@@ -696,7 +766,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, - break; - - case 0x24: /* DMA_CCR2 */ -- ch->bs = (value >> 2) & 0x1; -+ ch->bs = (value >> 2) & 0x1; - ch->transparent_copy = (value >> 1) & 0x1; - ch->constant_fill = value & 0x1; - break; -@@ -1126,48 +1196,29 @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset, - break; - - case 0x44e: /* DMA_CAPS_0_U */ -- *ret = (1 << 3) | /* Constant Fill Capacity */ -- (1 << 2); /* Transparent BLT Capacity */ -+ *ret = (s->caps[0] >> 16) & 0xffff; - break; -- - case 0x450: /* DMA_CAPS_0_L */ -- case 0x452: /* DMA_CAPS_1_U */ -- *ret = 0; -+ *ret = (s->caps[0] >> 0) & 0xffff; - break; - -+ case 0x452: /* DMA_CAPS_1_U */ -+ *ret = (s->caps[1] >> 16) & 0xffff; -+ break; - case 0x454: /* DMA_CAPS_1_L */ -- *ret = (1 << 1); /* 1-bit palletized capability */ -+ *ret = (s->caps[1] >> 0) & 0xffff; - break; - - case 0x456: /* DMA_CAPS_2 */ -- *ret = (1 << 8) | /* SSDIC */ -- (1 << 7) | /* DDIAC */ -- (1 << 6) | /* DSIAC */ -- (1 << 5) | /* DPIAC */ -- (1 << 4) | /* DCAC */ -- (1 << 3) | /* SDIAC */ -- (1 << 2) | /* SSIAC */ -- (1 << 1) | /* SPIAC */ -- 1; /* SCAC */ -+ *ret = s->caps[2]; - break; - - case 0x458: /* DMA_CAPS_3 */ -- *ret = (1 << 5) | /* CCC */ -- (1 << 4) | /* IC */ -- (1 << 3) | /* ARC */ -- (1 << 2) | /* AEC */ -- (1 << 1) | /* FSC */ -- 1; /* ESC */ -+ *ret = s->caps[3]; - break; - - case 0x45a: /* DMA_CAPS_4 */ -- *ret = (1 << 6) | /* SSC */ -- (1 << 5) | /* BIC */ -- (1 << 4) | /* LFIC */ -- (1 << 3) | /* FIC */ -- (1 << 2) | /* HFIC */ -- (1 << 1) | /* EDIC */ -- 1; /* TOIC */ -+ *ret = s->caps[4]; - break; - - case 0x460: /* DMA_PCh2_SR */ -@@ -1193,7 +1244,7 @@ static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr) - - switch (offset) { - case 0x300 ... 0x3fe: -- if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) { -+ if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) { - if (omap_dma_3_1_lcd_read(&s->lcd_ch, offset, &ret)) - break; - return ret; -@@ -1207,7 +1258,7 @@ static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr) - return ret; - - case 0x404 ... 0x4fe: -- if (s->model == omap_dma_3_1) -+ if (s->model <= omap_dma_3_1) - break; - /* Fall through. */ - case 0x400: -@@ -1236,7 +1287,7 @@ static void omap_dma_write(void *opaque, target_phys_addr_t addr, - - switch (offset) { - case 0x300 ... 0x3fe: -- if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) { -+ if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) { - if (omap_dma_3_1_lcd_write(&s->lcd_ch, offset, value)) - break; - return; -@@ -1250,7 +1301,7 @@ static void omap_dma_write(void *opaque, target_phys_addr_t addr, - return; - - case 0x404 ... 0x4fe: -- if (s->model == omap_dma_3_1) -+ if (s->model <= omap_dma_3_1) - break; - case 0x400: - /* Fall through. */ -@@ -1285,7 +1336,7 @@ static CPUWriteMemoryFunc *omap_dma_writefn[] = { - static void omap_dma_request(void *opaque, int drq, int req) - { - struct omap_dma_s *s = (struct omap_dma_s *) opaque; -- /* The request pins are level triggered. */ -+ /* The request pins are level triggered in QEMU. */ - if (req) { - if (~s->drq & (1 << drq)) { - s->drq |= 1 << drq; -@@ -1310,6 +1361,52 @@ static void omap_dma_clk_update(void *opaque, int line, int on) - } - } - -+static void omap_dma_setcaps(struct omap_dma_s *s) -+{ -+ switch (s->model) { -+ default: -+ case omap_dma_3_1: -+ break; -+ case omap_dma_3_2: -+ case omap_dma_4: -+ /* XXX Only available for sDMA */ -+ s->caps[0] = -+ (1 << 19) | /* Constant Fill Capability */ -+ (1 << 18); /* Transparent BLT Capability */ -+ s->caps[1] = -+ (1 << 1); /* 1-bit palettized capability (DMA 3.2 only) */ -+ s->caps[2] = -+ (1 << 8) | /* SEPARATE_SRC_AND_DST_INDEX_CPBLTY */ -+ (1 << 7) | /* DST_DOUBLE_INDEX_ADRS_CPBLTY */ -+ (1 << 6) | /* DST_SINGLE_INDEX_ADRS_CPBLTY */ -+ (1 << 5) | /* DST_POST_INCRMNT_ADRS_CPBLTY */ -+ (1 << 4) | /* DST_CONST_ADRS_CPBLTY */ -+ (1 << 3) | /* SRC_DOUBLE_INDEX_ADRS_CPBLTY */ -+ (1 << 2) | /* SRC_SINGLE_INDEX_ADRS_CPBLTY */ -+ (1 << 1) | /* SRC_POST_INCRMNT_ADRS_CPBLTY */ -+ (1 << 0); /* SRC_CONST_ADRS_CPBLTY */ -+ s->caps[3] = -+ (1 << 6) | /* BLOCK_SYNCHR_CPBLTY (DMA 4 only) */ -+ (1 << 7) | /* PKT_SYNCHR_CPBLTY (DMA 4 only) */ -+ (1 << 5) | /* CHANNEL_CHAINING_CPBLTY */ -+ (1 << 4) | /* LCh_INTERLEAVE_CPBLTY */ -+ (1 << 3) | /* AUTOINIT_REPEAT_CPBLTY (DMA 3.2 only) */ -+ (1 << 2) | /* AUTOINIT_ENDPROG_CPBLTY (DMA 3.2 only) */ -+ (1 << 1) | /* FRAME_SYNCHR_CPBLTY */ -+ (1 << 0); /* ELMNT_SYNCHR_CPBLTY */ -+ s->caps[4] = -+ (1 << 7) | /* PKT_INTERRUPT_CPBLTY (DMA 4 only) */ -+ (1 << 6) | /* SYNC_STATUS_CPBLTY */ -+ (1 << 5) | /* BLOCK_INTERRUPT_CPBLTY */ -+ (1 << 4) | /* LAST_FRAME_INTERRUPT_CPBLTY */ -+ (1 << 3) | /* FRAME_INTERRUPT_CPBLTY */ -+ (1 << 2) | /* HALF_FRAME_INTERRUPT_CPBLTY */ -+ (1 << 1) | /* EVENT_DROP_INTERRUPT_CPBLTY */ -+ (1 << 0); /* TIMEOUT_INTERRUPT_CPBLTY (DMA 3.2 only) */ -+ break; -+ } -+} -+ - struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs, - qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk, - enum omap_dma_model model) -@@ -1318,7 +1415,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs, - struct omap_dma_s *s = (struct omap_dma_s *) - qemu_mallocz(sizeof(struct omap_dma_s)); - -- if (model == omap_dma_3_1) { -+ if (model <= omap_dma_3_1) { - num_irqs = 6; - memsize = 0x800; - } else { -@@ -1331,6 +1428,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs, - s->clk = clk; - s->lcd_ch.irq = lcd_irq; - s->lcd_ch.mpu = mpu; -+ omap_dma_setcaps(s); - while (num_irqs --) - s->ch[num_irqs].irq = irqs[num_irqs]; - for (i = 0; i < 3; i ++) { -@@ -1350,6 +1448,393 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs, - return s; - } - -+static void omap_dma_interrupts_4_update(struct omap_dma_s *s) -+{ -+ struct omap_dma_channel_s *ch = s->ch; -+ uint32_t bmp, bit; -+ -+ for (bmp = 0, bit = 1; bit; ch ++, bit <<= 1) -+ if (ch->status) { -+ bmp |= bit; -+ ch->cstatus |= ch->status; -+ ch->status = 0; -+ } -+ if ((s->irqstat[0] |= s->irqen[0] & bmp)) -+ qemu_irq_raise(s->irq[0]); -+ if ((s->irqstat[1] |= s->irqen[1] & bmp)) -+ qemu_irq_raise(s->irq[1]); -+ if ((s->irqstat[2] |= s->irqen[2] & bmp)) -+ qemu_irq_raise(s->irq[2]); -+ if ((s->irqstat[3] |= s->irqen[3] & bmp)) -+ qemu_irq_raise(s->irq[3]); -+} -+ -+static uint32_t omap_dma4_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_dma_s *s = (struct omap_dma_s *) opaque; -+ int irqn = 0, chnum, offset = addr - s->base; -+ struct omap_dma_channel_s *ch; -+ -+ switch (offset) { -+ case 0x00: /* DMA4_REVISION */ -+ return 0x40; -+ -+ case 0x14: /* DMA4_IRQSTATUS_L3 */ -+ irqn ++; -+ case 0x10: /* DMA4_IRQSTATUS_L2 */ -+ irqn ++; -+ case 0x0c: /* DMA4_IRQSTATUS_L1 */ -+ irqn ++; -+ case 0x08: /* DMA4_IRQSTATUS_L0 */ -+ return s->irqstat[irqn]; -+ -+ case 0x24: /* DMA4_IRQENABLE_L3 */ -+ irqn ++; -+ case 0x20: /* DMA4_IRQENABLE_L2 */ -+ irqn ++; -+ case 0x1c: /* DMA4_IRQENABLE_L1 */ -+ irqn ++; -+ case 0x18: /* DMA4_IRQENABLE_L0 */ -+ return s->irqen[irqn]; -+ -+ case 0x28: /* DMA4_SYSSTATUS */ -+ return 1; /* RESETDONE */ -+ -+ case 0x2c: /* DMA4_OCP_SYSCONFIG */ -+ return s->ocp; -+ -+ case 0x64: /* DMA4_CAPS_0 */ -+ return s->caps[0]; -+ case 0x6c: /* DMA4_CAPS_2 */ -+ return s->caps[2]; -+ case 0x70: /* DMA4_CAPS_3 */ -+ return s->caps[3]; -+ case 0x74: /* DMA4_CAPS_4 */ -+ return s->caps[4]; -+ -+ case 0x78: /* DMA4_GCR */ -+ return s->gcr; -+ -+ case 0x80 ... 0xfff: -+ offset -= 0x80; -+ chnum = offset / 0x60; -+ ch = s->ch + chnum; -+ offset -= chnum * 0x60; -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return 0; -+ } -+ -+ /* Per-channel registers */ -+ switch (offset) { -+ case 0x00: /* DMA4_CCR */ -+ return (ch->buf_disable << 25) | -+ (ch->src_sync << 24) | -+ (ch->prefetch << 23) | -+ ((ch->sync & 0x60) << 14) | -+ (ch->bs << 18) | -+ (ch->transparent_copy << 17) | -+ (ch->constant_fill << 16) | -+ (ch->mode[1] << 14) | -+ (ch->mode[0] << 12) | -+ (0 << 10) | (0 << 9) | -+ (ch->suspend << 8) | -+ (ch->enable << 7) | -+ (ch->priority << 6) | -+ (ch->fs << 5) | (ch->sync & 0x1f); -+ -+ case 0x04: /* DMA4_CLNK_CTRL */ -+ return (ch->link_enabled << 15) | ch->link_next_ch; -+ -+ case 0x08: /* DMA4_CICR */ -+ return ch->interrupts; -+ -+ case 0x0c: /* DMA4_CSR */ -+ return ch->cstatus; -+ -+ case 0x10: /* DMA4_CSDP */ -+ return (ch->endian[0] << 21) | -+ (ch->endian_lock[0] << 20) | -+ (ch->endian[1] << 19) | -+ (ch->endian_lock[1] << 18) | -+ (ch->write_mode << 16) | -+ (ch->burst[1] << 14) | -+ (ch->pack[1] << 13) | -+ (ch->translate[1] << 9) | -+ (ch->burst[0] << 7) | -+ (ch->pack[0] << 6) | -+ (ch->translate[0] << 2) | -+ (ch->data_type >> 1); -+ -+ case 0x14: /* DMA4_CEN */ -+ return ch->elements; -+ -+ case 0x18: /* DMA4_CFN */ -+ return ch->frames; -+ -+ case 0x1c: /* DMA4_CSSA */ -+ return ch->addr[0]; -+ -+ case 0x20: /* DMA4_CDSA */ -+ return ch->addr[1]; -+ -+ case 0x24: /* DMA4_CSEI */ -+ return ch->element_index[0]; -+ -+ case 0x28: /* DMA4_CSFI */ -+ return ch->frame_index[0]; -+ -+ case 0x2c: /* DMA4_CDEI */ -+ return ch->element_index[1]; -+ -+ case 0x30: /* DMA4_CDFI */ -+ return ch->frame_index[1]; -+ -+ case 0x34: /* DMA4_CSAC */ -+ return ch->active_set.src & 0xffff; -+ -+ case 0x38: /* DMA4_CDAC */ -+ return ch->active_set.dest & 0xffff; -+ -+ case 0x3c: /* DMA4_CCEN */ -+ return ch->active_set.element; -+ -+ case 0x40: /* DMA4_CCFN */ -+ return ch->active_set.frame; -+ -+ case 0x44: /* DMA4_COLOR */ -+ /* XXX only in sDMA */ -+ return ch->color; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return 0; -+ } -+} -+ -+static void omap_dma4_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_dma_s *s = (struct omap_dma_s *) opaque; -+ int chnum, irqn = 0, offset = addr - s->base; -+ struct omap_dma_channel_s *ch; -+ -+ switch (offset) { -+ case 0x14: /* DMA4_IRQSTATUS_L3 */ -+ irqn ++; -+ case 0x10: /* DMA4_IRQSTATUS_L2 */ -+ irqn ++; -+ case 0x0c: /* DMA4_IRQSTATUS_L1 */ -+ irqn ++; -+ case 0x08: /* DMA4_IRQSTATUS_L0 */ -+ s->irqstat[irqn] &= ~value; -+ if (!s->irqstat[irqn]) -+ qemu_irq_lower(s->irq[irqn]); -+ return; -+ -+ case 0x24: /* DMA4_IRQENABLE_L3 */ -+ irqn ++; -+ case 0x20: /* DMA4_IRQENABLE_L2 */ -+ irqn ++; -+ case 0x1c: /* DMA4_IRQENABLE_L1 */ -+ irqn ++; -+ case 0x18: /* DMA4_IRQENABLE_L0 */ -+ s->irqen[irqn] = value; -+ return; -+ -+ case 0x2c: /* DMA4_OCP_SYSCONFIG */ -+ if (value & 2) /* SOFTRESET */ -+ omap_dma_reset(s); -+ s->ocp = value & 0x3321; -+ if (((s->ocp >> 12) & 3) == 3) /* MIDLEMODE */ -+ fprintf(stderr, "%s: invalid DMA power mode\n", __FUNCTION__); -+ return; -+ -+ case 0x78: /* DMA4_GCR */ -+ s->gcr = value & 0x00ff00ff; -+ if ((value & 0xff) == 0x00) /* MAX_CHANNEL_FIFO_DEPTH */ -+ fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __FUNCTION__); -+ return; -+ -+ case 0x80 ... 0xfff: -+ offset -= 0x80; -+ chnum = offset / 0x60; -+ ch = s->ch + chnum; -+ offset -= chnum * 0x60; -+ break; -+ -+ case 0x00: /* DMA4_REVISION */ -+ case 0x28: /* DMA4_SYSSTATUS */ -+ case 0x64: /* DMA4_CAPS_0 */ -+ case 0x6c: /* DMA4_CAPS_2 */ -+ case 0x70: /* DMA4_CAPS_3 */ -+ case 0x74: /* DMA4_CAPS_4 */ -+ OMAP_RO_REG(addr); -+ return; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ return; -+ } -+ -+ /* Per-channel registers */ -+ switch (offset) { -+ case 0x00: /* DMA4_CCR */ -+ ch->buf_disable = (value >> 25) & 1; -+ ch->src_sync = (value >> 24) & 1; /* XXX For CamDMA must be 1 */ -+ if (ch->buf_disable && !ch->src_sync) -+ fprintf(stderr, "%s: Buffering disable is not allowed in " -+ "destination synchronised mode\n", __FUNCTION__); -+ ch->prefetch = (value >> 23) & 1; -+ ch->bs = (value >> 18) & 1; -+ ch->transparent_copy = (value >> 17) & 1; -+ ch->constant_fill = (value >> 16) & 1; -+ ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14); -+ ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12); -+ ch->suspend = (value & 0x0100) >> 8; -+ ch->priority = (value & 0x0040) >> 6; -+ ch->fs = (value & 0x0020) >> 5; -+ if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1]) -+ fprintf(stderr, "%s: For a packet transfer at least one port " -+ "must be constant-addressed\n", __FUNCTION__); -+ ch->sync = (value & 0x001f) | ((value >> 14) & 0x0060); -+ /* XXX must be 0x01 for CamDMA */ -+ -+ if (value & 0x0080) -+ omap_dma_enable_channel(s, ch); -+ else -+ omap_dma_disable_channel(s, ch); -+ -+ break; -+ -+ case 0x04: /* DMA4_CLNK_CTRL */ -+ ch->link_enabled = (value >> 15) & 0x1; -+ ch->link_next_ch = value & 0x1f; -+ break; -+ -+ case 0x08: /* DMA4_CICR */ -+ ch->interrupts = value & 0x09be; -+ break; -+ -+ case 0x0c: /* DMA4_CSR */ -+ ch->cstatus &= ~value; -+ break; -+ -+ case 0x10: /* DMA4_CSDP */ -+ ch->endian[0] =(value >> 21) & 1; -+ ch->endian_lock[0] =(value >> 20) & 1; -+ ch->endian[1] =(value >> 19) & 1; -+ ch->endian_lock[1] =(value >> 18) & 1; -+ if (ch->endian[0] != ch->endian[1]) -+ fprintf(stderr, "%s: DMA endianned conversion enable attempt\n", -+ __FUNCTION__); -+ ch->write_mode = (value >> 16) & 3; -+ ch->burst[1] = (value & 0xc000) >> 14; -+ ch->pack[1] = (value & 0x2000) >> 13; -+ ch->translate[1] = (value & 0x1e00) >> 9; -+ ch->burst[0] = (value & 0x0180) >> 7; -+ ch->pack[0] = (value & 0x0040) >> 6; -+ ch->translate[0] = (value & 0x003c) >> 2; -+ if (ch->translate[0] | ch->translate[1]) -+ fprintf(stderr, "%s: bad MReqAddressTranslate sideband signal\n", -+ __FUNCTION__); -+ ch->data_type = 1 << (value & 3); -+ if ((value & 3) == 3) -+ printf("%s: bad data_type for DMA channel\n", __FUNCTION__); -+ break; -+ -+ case 0x14: /* DMA4_CEN */ -+ ch->elements = value & 0xffffff; -+ break; -+ -+ case 0x18: /* DMA4_CFN */ -+ ch->frames = value & 0xffff; -+ break; -+ -+ case 0x1c: /* DMA4_CSSA */ -+ ch->addr[0] = (target_phys_addr_t) (uint32_t) value; -+ break; -+ -+ case 0x20: /* DMA4_CDSA */ -+ ch->addr[1] = (target_phys_addr_t) (uint32_t) value; -+ break; -+ -+ case 0x24: /* DMA4_CSEI */ -+ ch->element_index[0] = (int16_t) value; -+ break; -+ -+ case 0x28: /* DMA4_CSFI */ -+ ch->frame_index[0] = (int32_t) value; -+ break; -+ -+ case 0x2c: /* DMA4_CDEI */ -+ ch->element_index[1] = (int16_t) value; -+ break; -+ -+ case 0x30: /* DMA4_CDFI */ -+ ch->frame_index[1] = (int32_t) value; -+ break; -+ -+ case 0x44: /* DMA4_COLOR */ -+ /* XXX only in sDMA */ -+ ch->color = value; -+ break; -+ -+ case 0x34: /* DMA4_CSAC */ -+ case 0x38: /* DMA4_CDAC */ -+ case 0x3c: /* DMA4_CCEN */ -+ case 0x40: /* DMA4_CCFN */ -+ OMAP_RO_REG(addr); -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static CPUReadMemoryFunc *omap_dma4_readfn[] = { -+ omap_badwidth_read16, -+ omap_dma4_read, -+ omap_dma4_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_dma4_writefn[] = { -+ omap_badwidth_write16, -+ omap_dma4_write, -+ omap_dma4_write, -+}; -+ -+struct omap_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs, -+ struct omap_mpu_state_s *mpu, int fifo, -+ int chans, omap_clk iclk, omap_clk fclk) -+{ -+ int iomemtype; -+ struct omap_dma_s *s = (struct omap_dma_s *) -+ qemu_mallocz(sizeof(struct omap_dma_s)); -+ -+ s->base = base; -+ s->model = omap_dma_4; -+ s->chans = chans; -+ s->mpu = mpu; -+ s->clk = fclk; -+ memcpy(&s->irq, irqs, sizeof(s->irq)); -+ s->intr_update = omap_dma_interrupts_4_update; -+ omap_dma_setcaps(s); -+ s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s); -+ omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]); -+ mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 64); -+ omap_dma_reset(s); -+ omap_dma_clk_update(s, 0, 1); -+ -+ iomemtype = cpu_register_io_memory(0, omap_dma4_readfn, -+ omap_dma4_writefn, s); -+ cpu_register_physical_memory(s->base, 0x1000, iomemtype); -+ -+ return s; -+} -+ - struct omap_dma_lcd_channel_s *omap_dma_get_lcdch(struct omap_dma_s *s) - { - return &s->lcd_ch; -diff --git a/hw/omap_dss.c b/hw/omap_dss.c -new file mode 100644 -index 0000000..1c16802 ---- /dev/null -+++ b/hw/omap_dss.c -@@ -0,0 +1,1088 @@ -+/* -+ * OMAP2 Display Subsystem. -+ * -+ * Copyright (C) 2008 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+#include "hw.h" -+#include "console.h" -+#include "omap.h" -+ -+struct omap_dss_s { -+ target_phys_addr_t diss_base; -+ target_phys_addr_t disc_base; -+ target_phys_addr_t rfbi_base; -+ target_phys_addr_t venc_base; -+ target_phys_addr_t im3_base; -+ qemu_irq irq; -+ qemu_irq drq; -+ DisplayState *state; -+ -+ int autoidle; -+ int control; -+ int enable; -+ -+ struct omap_dss_panel_s { -+ int enable; -+ int nx; -+ int ny; -+ -+ int x; -+ int y; -+ } dig, lcd; -+ -+ struct { -+ uint32_t idlemode; -+ uint32_t irqst; -+ uint32_t irqen; -+ uint32_t control; -+ uint32_t config; -+ uint32_t capable; -+ uint32_t timing[3]; -+ int line; -+ uint32_t bg[2]; -+ uint32_t trans[2]; -+ -+ struct omap_dss_plane_s { -+ int enable; -+ int bpp; -+ int posx; -+ int posy; -+ int nx; -+ int ny; -+ -+ target_phys_addr_t addr[3]; -+ -+ uint32_t attr; -+ uint32_t tresh; -+ int rowinc; -+ int colinc; -+ int wininc; -+ } l[3]; -+ -+ int invalidate; -+ uint16_t palette[256]; -+ } dispc; -+ -+ struct { -+ int idlemode; -+ uint32_t control; -+ int enable; -+ int pixels; -+ int busy; -+ int skiplines; -+ uint16_t rxbuf; -+ uint32_t config[2]; -+ uint32_t time[4]; -+ uint32_t data[6]; -+ uint16_t vsync; -+ uint16_t hsync; -+ struct rfbi_chip_s *chip[2]; -+ } rfbi; -+}; -+ -+static void omap_dispc_interrupt_update(struct omap_dss_s *s) -+{ -+ qemu_set_irq(s->irq, s->dispc.irqst & s->dispc.irqen); -+} -+ -+static void omap_rfbi_reset(struct omap_dss_s *s) -+{ -+ s->rfbi.idlemode = 0; -+ s->rfbi.control = 2; -+ s->rfbi.enable = 0; -+ s->rfbi.pixels = 0; -+ s->rfbi.skiplines = 0; -+ s->rfbi.busy = 0; -+ s->rfbi.config[0] = 0x00310000; -+ s->rfbi.config[1] = 0x00310000; -+ s->rfbi.time[0] = 0; -+ s->rfbi.time[1] = 0; -+ s->rfbi.time[2] = 0; -+ s->rfbi.time[3] = 0; -+ s->rfbi.data[0] = 0; -+ s->rfbi.data[1] = 0; -+ s->rfbi.data[2] = 0; -+ s->rfbi.data[3] = 0; -+ s->rfbi.data[4] = 0; -+ s->rfbi.data[5] = 0; -+ s->rfbi.vsync = 0; -+ s->rfbi.hsync = 0; -+} -+ -+void omap_dss_reset(struct omap_dss_s *s) -+{ -+ s->autoidle = 0; -+ s->control = 0; -+ s->enable = 0; -+ -+ s->dig.enable = 0; -+ s->dig.nx = 1; -+ s->dig.ny = 1; -+ -+ s->lcd.enable = 0; -+ s->lcd.nx = 1; -+ s->lcd.ny = 1; -+ -+ s->dispc.idlemode = 0; -+ s->dispc.irqst = 0; -+ s->dispc.irqen = 0; -+ s->dispc.control = 0; -+ s->dispc.config = 0; -+ s->dispc.capable = 0x161; -+ s->dispc.timing[0] = 0; -+ s->dispc.timing[1] = 0; -+ s->dispc.timing[2] = 0; -+ s->dispc.line = 0; -+ s->dispc.bg[0] = 0; -+ s->dispc.bg[1] = 0; -+ s->dispc.trans[0] = 0; -+ s->dispc.trans[1] = 0; -+ -+ s->dispc.l[0].enable = 0; -+ s->dispc.l[0].bpp = 0; -+ s->dispc.l[0].addr[0] = 0; -+ s->dispc.l[0].addr[1] = 0; -+ s->dispc.l[0].addr[2] = 0; -+ s->dispc.l[0].posx = 0; -+ s->dispc.l[0].posy = 0; -+ s->dispc.l[0].nx = 1; -+ s->dispc.l[0].ny = 1; -+ s->dispc.l[0].attr = 0; -+ s->dispc.l[0].tresh = 0; -+ s->dispc.l[0].rowinc = 1; -+ s->dispc.l[0].colinc = 1; -+ s->dispc.l[0].wininc = 0; -+ -+ omap_rfbi_reset(s); -+ omap_dispc_interrupt_update(s); -+} -+ -+static uint32_t omap_diss_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->diss_base; -+ -+ switch (offset) { -+ case 0x00: /* DSS_REVISIONNUMBER */ -+ return 0x20; -+ -+ case 0x10: /* DSS_SYSCONFIG */ -+ return s->autoidle; -+ -+ case 0x14: /* DSS_SYSSTATUS */ -+ return 1; /* RESETDONE */ -+ -+ case 0x40: /* DSS_CONTROL */ -+ return s->control; -+ -+ case 0x50: /* DSS_PSA_LCD_REG_1 */ -+ case 0x54: /* DSS_PSA_LCD_REG_2 */ -+ case 0x58: /* DSS_PSA_VIDEO_REG */ -+ /* TODO: fake some values when appropriate s->control bits are set */ -+ return 0; -+ -+ case 0x5c: /* DSS_STATUS */ -+ return 1 + (s->control & 1); -+ -+ default: -+ break; -+ } -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_diss_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->diss_base; -+ -+ switch (offset) { -+ case 0x00: /* DSS_REVISIONNUMBER */ -+ case 0x14: /* DSS_SYSSTATUS */ -+ case 0x50: /* DSS_PSA_LCD_REG_1 */ -+ case 0x54: /* DSS_PSA_LCD_REG_2 */ -+ case 0x58: /* DSS_PSA_VIDEO_REG */ -+ case 0x5c: /* DSS_STATUS */ -+ OMAP_RO_REG(addr); -+ break; -+ -+ case 0x10: /* DSS_SYSCONFIG */ -+ if (value & 2) /* SOFTRESET */ -+ omap_dss_reset(s); -+ s->autoidle = value & 1; -+ break; -+ -+ case 0x40: /* DSS_CONTROL */ -+ s->control = value & 0x3dd; -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static CPUReadMemoryFunc *omap_diss1_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_diss_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_diss1_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_diss_write, -+}; -+ -+static uint32_t omap_disc_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->disc_base; -+ -+ switch (offset) { -+ case 0x000: /* DISPC_REVISION */ -+ return 0x20; -+ -+ case 0x010: /* DISPC_SYSCONFIG */ -+ return s->dispc.idlemode; -+ -+ case 0x014: /* DISPC_SYSSTATUS */ -+ return 1; /* RESETDONE */ -+ -+ case 0x018: /* DISPC_IRQSTATUS */ -+ return s->dispc.irqst; -+ -+ case 0x01c: /* DISPC_IRQENABLE */ -+ return s->dispc.irqen; -+ -+ case 0x040: /* DISPC_CONTROL */ -+ return s->dispc.control; -+ -+ case 0x044: /* DISPC_CONFIG */ -+ return s->dispc.config; -+ -+ case 0x048: /* DISPC_CAPABLE */ -+ return s->dispc.capable; -+ -+ case 0x04c: /* DISPC_DEFAULT_COLOR0 */ -+ return s->dispc.bg[0]; -+ case 0x050: /* DISPC_DEFAULT_COLOR1 */ -+ return s->dispc.bg[1]; -+ case 0x054: /* DISPC_TRANS_COLOR0 */ -+ return s->dispc.trans[0]; -+ case 0x058: /* DISPC_TRANS_COLOR1 */ -+ return s->dispc.trans[1]; -+ -+ case 0x05c: /* DISPC_LINE_STATUS */ -+ return 0x7ff; -+ case 0x060: /* DISPC_LINE_NUMBER */ -+ return s->dispc.line; -+ -+ case 0x064: /* DISPC_TIMING_H */ -+ return s->dispc.timing[0]; -+ case 0x068: /* DISPC_TIMING_V */ -+ return s->dispc.timing[1]; -+ case 0x06c: /* DISPC_POL_FREQ */ -+ return s->dispc.timing[2]; -+ case 0x070: /* DISPC_DIVISOR */ -+ return s->dispc.timing[3]; -+ -+ case 0x078: /* DISPC_SIZE_DIG */ -+ return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1); -+ case 0x07c: /* DISPC_SIZE_LCD */ -+ return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1); -+ -+ case 0x080: /* DISPC_GFX_BA0 */ -+ return s->dispc.l[0].addr[0]; -+ case 0x084: /* DISPC_GFX_BA1 */ -+ return s->dispc.l[0].addr[1]; -+ case 0x088: /* DISPC_GFX_POSITION */ -+ return (s->dispc.l[0].posy << 16) | s->dispc.l[0].posx; -+ case 0x08c: /* DISPC_GFX_SIZE */ -+ return ((s->dispc.l[0].ny - 1) << 16) | (s->dispc.l[0].nx - 1); -+ case 0x0a0: /* DISPC_GFX_ATTRIBUTES */ -+ return s->dispc.l[0].attr; -+ case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */ -+ return s->dispc.l[0].tresh; -+ case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */ -+ return 256; -+ case 0x0ac: /* DISPC_GFX_ROW_INC */ -+ return s->dispc.l[0].rowinc; -+ case 0x0b0: /* DISPC_GFX_PIXEL_INC */ -+ return s->dispc.l[0].colinc; -+ case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */ -+ return s->dispc.l[0].wininc; -+ case 0x0b8: /* DISPC_GFX_TABLE_BA */ -+ return s->dispc.l[0].addr[2]; -+ -+ case 0x0bc: /* DISPC_VID1_BA0 */ -+ case 0x0c0: /* DISPC_VID1_BA1 */ -+ case 0x0c4: /* DISPC_VID1_POSITION */ -+ case 0x0c8: /* DISPC_VID1_SIZE */ -+ case 0x0cc: /* DISPC_VID1_ATTRIBUTES */ -+ case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */ -+ case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */ -+ case 0x0d8: /* DISPC_VID1_ROW_INC */ -+ case 0x0dc: /* DISPC_VID1_PIXEL_INC */ -+ case 0x0e0: /* DISPC_VID1_FIR */ -+ case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */ -+ case 0x0e8: /* DISPC_VID1_ACCU0 */ -+ case 0x0ec: /* DISPC_VID1_ACCU1 */ -+ case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */ -+ case 0x14c: /* DISPC_VID2_BA0 */ -+ case 0x150: /* DISPC_VID2_BA1 */ -+ case 0x154: /* DISPC_VID2_POSITION */ -+ case 0x158: /* DISPC_VID2_SIZE */ -+ case 0x15c: /* DISPC_VID2_ATTRIBUTES */ -+ case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */ -+ case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */ -+ case 0x168: /* DISPC_VID2_ROW_INC */ -+ case 0x16c: /* DISPC_VID2_PIXEL_INC */ -+ case 0x170: /* DISPC_VID2_FIR */ -+ case 0x174: /* DISPC_VID2_PICTURE_SIZE */ -+ case 0x178: /* DISPC_VID2_ACCU0 */ -+ case 0x17c: /* DISPC_VID2_ACCU1 */ -+ case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */ -+ case 0x1d4: /* DISPC_DATA_CYCLE1 */ -+ case 0x1d8: /* DISPC_DATA_CYCLE2 */ -+ case 0x1dc: /* DISPC_DATA_CYCLE3 */ -+ return 0; -+ -+ default: -+ break; -+ } -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_disc_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->disc_base; -+ -+ switch (offset) { -+ case 0x010: /* DISPC_SYSCONFIG */ -+ if (value & 2) /* SOFTRESET */ -+ omap_dss_reset(s); -+ s->dispc.idlemode = value & 0x301b; -+ break; -+ -+ case 0x018: /* DISPC_IRQSTATUS */ -+ s->dispc.irqst &= ~value; -+ omap_dispc_interrupt_update(s); -+ break; -+ -+ case 0x01c: /* DISPC_IRQENABLE */ -+ s->dispc.irqen = value & 0xffff; -+ omap_dispc_interrupt_update(s); -+ break; -+ -+ case 0x040: /* DISPC_CONTROL */ -+ s->dispc.control = value & 0x07ff9fff; -+ s->dig.enable = (value >> 1) & 1; -+ s->lcd.enable = (value >> 0) & 1; -+ if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */ -+ if (~((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1)) -+ fprintf(stderr, "%s: Overlay Optimization when no overlay " -+ "region effectively exists leads to " -+ "unpredictable behaviour!\n", __FUNCTION__); -+ if (value & (1 << 6)) { /* GODIGITAL */ -+ //// Shadows: -+ //// s->dispc.config -+ //// s->dispc.capable -+ //// s->dispc.bg[0] -+ //// s->dispc.bg[1] -+ //// s->dispc.trans[0] -+ //// s->dispc.trans[1] -+ //// s->dispc.line -+ //// s->dispc.timing[0] -+ //// s->dispc.timing[1] -+ //// s->dispc.timing[2] -+ //// s->dispc.timing[3] -+ //// s->lcd.nx -+ //// s->lcd.ny -+ //// s->dig.nx -+ //// s->dig.ny -+ //// s->dispc.l[0].addr[0] -+ //// s->dispc.l[0].addr[1] -+ //// s->dispc.l[0].addr[2] -+ //// s->dispc.l[0].posx -+ //// s->dispc.l[0].posy -+ //// s->dispc.l[0].nx -+ //// s->dispc.l[0].ny -+ //// s->dispc.l[0].tresh -+ //// s->dispc.l[0].rowinc -+ //// s->dispc.l[0].colinc -+ //// s->dispc.l[0].wininc -+ } -+ if (value & (1 << 5)) { /* GOLCD */ -+ } -+ s->dispc.invalidate = 1; -+ break; -+ -+ case 0x044: /* DISPC_CONFIG */ -+ s->dispc.config = value & 0x3fff; -+ //// bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded -+ //// bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded -+ s->dispc.invalidate = 1; -+ break; -+ -+ case 0x048: /* DISPC_CAPABLE */ -+ s->dispc.capable = value & 0x3ff; -+ break; -+ -+ case 0x04c: /* DISPC_DEFAULT_COLOR0 */ -+ s->dispc.bg[0] = value & 0xffffff; -+ s->dispc.invalidate = 1; -+ break; -+ case 0x050: /* DISPC_DEFAULT_COLOR1 */ -+ s->dispc.bg[1] = value & 0xffffff; -+ s->dispc.invalidate = 1; -+ break; -+ case 0x054: /* DISPC_TRANS_COLOR0 */ -+ s->dispc.trans[0] = value & 0xffffff; -+ s->dispc.invalidate = 1; -+ break; -+ case 0x058: /* DISPC_TRANS_COLOR1 */ -+ s->dispc.trans[1] = value & 0xffffff; -+ s->dispc.invalidate = 1; -+ break; -+ -+ case 0x060: /* DISPC_LINE_NUMBER */ -+ s->dispc.line = value & 0x7ff; -+ break; -+ -+ case 0x064: /* DISPC_TIMING_H */ -+ s->dispc.timing[0] = value & 0x0ff0ff3f; -+ break; -+ case 0x068: /* DISPC_TIMING_V */ -+ s->dispc.timing[1] = value & 0x0ff0ff3f; -+ break; -+ case 0x06c: /* DISPC_POL_FREQ */ -+ s->dispc.timing[2] = value & 0x0003ffff; -+ break; -+ case 0x070: /* DISPC_DIVISOR */ -+ s->dispc.timing[3] = value & 0x00ff00ff; -+ break; -+ -+ case 0x078: /* DISPC_SIZE_DIG */ -+ s->dig.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */ -+ s->dig.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */ -+ s->dispc.invalidate = 1; -+ break; -+ case 0x07c: /* DISPC_SIZE_LCD */ -+ s->lcd.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */ -+ s->lcd.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */ -+ s->dispc.invalidate = 1; -+ break; -+ case 0x080: /* DISPC_GFX_BA0 */ -+ s->dispc.l[0].addr[0] = (target_phys_addr_t) value; -+ s->dispc.invalidate = 1; -+ break; -+ case 0x084: /* DISPC_GFX_BA1 */ -+ s->dispc.l[0].addr[1] = (target_phys_addr_t) value; -+ s->dispc.invalidate = 1; -+ break; -+ case 0x088: /* DISPC_GFX_POSITION */ -+ s->dispc.l[0].posx = ((value >> 0) & 0x7ff); /* GFXPOSX */ -+ s->dispc.l[0].posy = ((value >> 16) & 0x7ff); /* GFXPOSY */ -+ s->dispc.invalidate = 1; -+ break; -+ case 0x08c: /* DISPC_GFX_SIZE */ -+ s->dispc.l[0].nx = ((value >> 0) & 0x7ff) + 1; /* GFXSIZEX */ -+ s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1; /* GFXSIZEY */ -+ s->dispc.invalidate = 1; -+ break; -+ case 0x0a0: /* DISPC_GFX_ATTRIBUTES */ -+ s->dispc.l[0].attr = value & 0x7ff; -+ if (value & (3 << 9)) -+ fprintf(stderr, "%s: Big-endian pixel format not supported\n", -+ __FUNCTION__); -+ s->dispc.l[0].enable = value & 1; -+ s->dispc.l[0].bpp = (value >> 1) & 0xf; -+ s->dispc.invalidate = 1; -+ break; -+ case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */ -+ s->dispc.l[0].tresh = value & 0x01ff01ff; -+ break; -+ case 0x0ac: /* DISPC_GFX_ROW_INC */ -+ s->dispc.l[0].rowinc = value; -+ s->dispc.invalidate = 1; -+ break; -+ case 0x0b0: /* DISPC_GFX_PIXEL_INC */ -+ s->dispc.l[0].colinc = value; -+ s->dispc.invalidate = 1; -+ break; -+ case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */ -+ s->dispc.l[0].wininc = value; -+ break; -+ case 0x0b8: /* DISPC_GFX_TABLE_BA */ -+ s->dispc.l[0].addr[2] = (target_phys_addr_t) value; -+ s->dispc.invalidate = 1; -+ break; -+ -+ case 0x0bc: /* DISPC_VID1_BA0 */ -+ case 0x0c0: /* DISPC_VID1_BA1 */ -+ case 0x0c4: /* DISPC_VID1_POSITION */ -+ case 0x0c8: /* DISPC_VID1_SIZE */ -+ case 0x0cc: /* DISPC_VID1_ATTRIBUTES */ -+ case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */ -+ case 0x0d8: /* DISPC_VID1_ROW_INC */ -+ case 0x0dc: /* DISPC_VID1_PIXEL_INC */ -+ case 0x0e0: /* DISPC_VID1_FIR */ -+ case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */ -+ case 0x0e8: /* DISPC_VID1_ACCU0 */ -+ case 0x0ec: /* DISPC_VID1_ACCU1 */ -+ case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */ -+ case 0x14c: /* DISPC_VID2_BA0 */ -+ case 0x150: /* DISPC_VID2_BA1 */ -+ case 0x154: /* DISPC_VID2_POSITION */ -+ case 0x158: /* DISPC_VID2_SIZE */ -+ case 0x15c: /* DISPC_VID2_ATTRIBUTES */ -+ case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */ -+ case 0x168: /* DISPC_VID2_ROW_INC */ -+ case 0x16c: /* DISPC_VID2_PIXEL_INC */ -+ case 0x170: /* DISPC_VID2_FIR */ -+ case 0x174: /* DISPC_VID2_PICTURE_SIZE */ -+ case 0x178: /* DISPC_VID2_ACCU0 */ -+ case 0x17c: /* DISPC_VID2_ACCU1 */ -+ case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */ -+ case 0x1d4: /* DISPC_DATA_CYCLE1 */ -+ case 0x1d8: /* DISPC_DATA_CYCLE2 */ -+ case 0x1dc: /* DISPC_DATA_CYCLE3 */ -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static CPUReadMemoryFunc *omap_disc1_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_disc_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_disc1_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_disc_write, -+}; -+ -+static void *omap_rfbi_get_buffer(struct omap_dss_s *s) -+{ -+ target_phys_addr_t fb; -+ uint32_t pd; -+ -+ /* TODO */ -+ fb = s->dispc.l[0].addr[0]; -+ -+ pd = cpu_get_physical_page_desc(fb); -+ if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) -+ /* TODO */ -+ cpu_abort(cpu_single_env, "%s: framebuffer outside RAM!\n", -+ __FUNCTION__); -+ else -+ return phys_ram_base + -+ (pd & TARGET_PAGE_MASK) + -+ (fb & ~TARGET_PAGE_MASK); -+} -+ -+static void omap_rfbi_transfer_stop(struct omap_dss_s *s) -+{ -+ if (!s->rfbi.busy) -+ return; -+ -+ /* TODO: in non-Bypass mode we probably need to just deassert the DRQ. */ -+ -+ s->rfbi.busy = 0; -+} -+ -+static void omap_rfbi_transfer_start(struct omap_dss_s *s) -+{ -+ void *data; -+ size_t len; -+ int pitch; -+ -+ if (!s->rfbi.enable || s->rfbi.busy) -+ return; -+ -+ if (s->rfbi.control & (1 << 1)) { /* BYPASS */ -+ /* TODO: in non-Bypass mode we probably need to just assert the -+ * DRQ and wait for DMA to write the pixels. */ -+ fprintf(stderr, "%s: Bypass mode unimplemented\n", __FUNCTION__); -+ return; -+ } -+ -+ if (!(s->dispc.control & (1 << 11))) /* RFBIMODE */ -+ return; -+ /* TODO: check that LCD output is enabled in DISPC. */ -+ -+ s->rfbi.busy = 1; -+ -+ data = omap_rfbi_get_buffer(s); -+ -+ /* TODO bpp */ -+ len = s->rfbi.pixels * 2; -+ s->rfbi.pixels = 0; -+ -+ /* TODO: negative values */ -+ pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2; -+ -+ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) -+ s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch); -+ if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) -+ s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch); -+ -+ omap_rfbi_transfer_stop(s); -+ -+ /* TODO */ -+ s->dispc.irqst |= 1; /* FRAMEDONE */ -+ omap_dispc_interrupt_update(s); -+} -+ -+static uint32_t omap_rfbi_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->rfbi_base; -+ -+ switch (offset) { -+ case 0x00: /* RFBI_REVISION */ -+ return 0x10; -+ -+ case 0x10: /* RFBI_SYSCONFIG */ -+ return s->rfbi.idlemode; -+ -+ case 0x14: /* RFBI_SYSSTATUS */ -+ return 1 | (s->rfbi.busy << 8); /* RESETDONE */ -+ -+ case 0x40: /* RFBI_CONTROL */ -+ return s->rfbi.control; -+ -+ case 0x44: /* RFBI_PIXELCNT */ -+ return s->rfbi.pixels; -+ -+ case 0x48: /* RFBI_LINE_NUMBER */ -+ return s->rfbi.skiplines; -+ -+ case 0x58: /* RFBI_READ */ -+ case 0x5c: /* RFBI_STATUS */ -+ return s->rfbi.rxbuf; -+ -+ case 0x60: /* RFBI_CONFIG0 */ -+ return s->rfbi.config[0]; -+ case 0x64: /* RFBI_ONOFF_TIME0 */ -+ return s->rfbi.time[0]; -+ case 0x68: /* RFBI_CYCLE_TIME0 */ -+ return s->rfbi.time[1]; -+ case 0x6c: /* RFBI_DATA_CYCLE1_0 */ -+ return s->rfbi.data[0]; -+ case 0x70: /* RFBI_DATA_CYCLE2_0 */ -+ return s->rfbi.data[1]; -+ case 0x74: /* RFBI_DATA_CYCLE3_0 */ -+ return s->rfbi.data[2]; -+ -+ case 0x78: /* RFBI_CONFIG1 */ -+ return s->rfbi.config[1]; -+ case 0x7c: /* RFBI_ONOFF_TIME1 */ -+ return s->rfbi.time[2]; -+ case 0x80: /* RFBI_CYCLE_TIME1 */ -+ return s->rfbi.time[3]; -+ case 0x84: /* RFBI_DATA_CYCLE1_1 */ -+ return s->rfbi.data[3]; -+ case 0x88: /* RFBI_DATA_CYCLE2_1 */ -+ return s->rfbi.data[4]; -+ case 0x8c: /* RFBI_DATA_CYCLE3_1 */ -+ return s->rfbi.data[5]; -+ -+ case 0x90: /* RFBI_VSYNC_WIDTH */ -+ return s->rfbi.vsync; -+ case 0x94: /* RFBI_HSYNC_WIDTH */ -+ return s->rfbi.hsync; -+ } -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_rfbi_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->rfbi_base; -+ -+ switch (offset) { -+ case 0x10: /* RFBI_SYSCONFIG */ -+ if (value & 2) /* SOFTRESET */ -+ omap_rfbi_reset(s); -+ s->rfbi.idlemode = value & 0x19; -+ break; -+ -+ case 0x40: /* RFBI_CONTROL */ -+ s->rfbi.control = value & 0xf; -+ s->rfbi.enable = value & 1; -+ if (value & (1 << 4) && /* ITE */ -+ !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc)) -+ omap_rfbi_transfer_start(s); -+ break; -+ -+ case 0x44: /* RFBI_PIXELCNT */ -+ s->rfbi.pixels = value; -+ break; -+ -+ case 0x48: /* RFBI_LINE_NUMBER */ -+ s->rfbi.skiplines = value & 0x7ff; -+ break; -+ -+ case 0x4c: /* RFBI_CMD */ -+ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) -+ s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff); -+ if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) -+ s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff); -+ break; -+ case 0x50: /* RFBI_PARAM */ -+ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) -+ s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff); -+ if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) -+ s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff); -+ break; -+ case 0x54: /* RFBI_DATA */ -+ /* TODO: take into account the format set up in s->rfbi.config[?] and -+ * s->rfbi.data[?], but special-case the most usual scenario so that -+ * speed doesn't suffer. */ -+ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) { -+ s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff); -+ s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16); -+ } -+ if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) { -+ s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff); -+ s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16); -+ } -+ if (!-- s->rfbi.pixels) -+ omap_rfbi_transfer_stop(s); -+ break; -+ case 0x58: /* RFBI_READ */ -+ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) -+ s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1); -+ else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) -+ s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1); -+ if (!-- s->rfbi.pixels) -+ omap_rfbi_transfer_stop(s); -+ break; -+ -+ case 0x5c: /* RFBI_STATUS */ -+ if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) -+ s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0); -+ else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) -+ s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0); -+ if (!-- s->rfbi.pixels) -+ omap_rfbi_transfer_stop(s); -+ break; -+ -+ case 0x60: /* RFBI_CONFIG0 */ -+ s->rfbi.config[0] = value & 0x003f1fff; -+ break; -+ -+ case 0x64: /* RFBI_ONOFF_TIME0 */ -+ s->rfbi.time[0] = value & 0x3fffffff; -+ break; -+ case 0x68: /* RFBI_CYCLE_TIME0 */ -+ s->rfbi.time[1] = value & 0x0fffffff; -+ break; -+ case 0x6c: /* RFBI_DATA_CYCLE1_0 */ -+ s->rfbi.data[0] = value & 0x0f1f0f1f; -+ break; -+ case 0x70: /* RFBI_DATA_CYCLE2_0 */ -+ s->rfbi.data[1] = value & 0x0f1f0f1f; -+ break; -+ case 0x74: /* RFBI_DATA_CYCLE3_0 */ -+ s->rfbi.data[2] = value & 0x0f1f0f1f; -+ break; -+ case 0x78: /* RFBI_CONFIG1 */ -+ s->rfbi.config[1] = value & 0x003f1fff; -+ break; -+ -+ case 0x7c: /* RFBI_ONOFF_TIME1 */ -+ s->rfbi.time[2] = value & 0x3fffffff; -+ break; -+ case 0x80: /* RFBI_CYCLE_TIME1 */ -+ s->rfbi.time[3] = value & 0x0fffffff; -+ break; -+ case 0x84: /* RFBI_DATA_CYCLE1_1 */ -+ s->rfbi.data[3] = value & 0x0f1f0f1f; -+ break; -+ case 0x88: /* RFBI_DATA_CYCLE2_1 */ -+ s->rfbi.data[4] = value & 0x0f1f0f1f; -+ break; -+ case 0x8c: /* RFBI_DATA_CYCLE3_1 */ -+ s->rfbi.data[5] = value & 0x0f1f0f1f; -+ break; -+ -+ case 0x90: /* RFBI_VSYNC_WIDTH */ -+ s->rfbi.vsync = value & 0xffff; -+ break; -+ case 0x94: /* RFBI_HSYNC_WIDTH */ -+ s->rfbi.hsync = value & 0xffff; -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static CPUReadMemoryFunc *omap_rfbi1_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_rfbi_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_rfbi1_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_rfbi_write, -+}; -+ -+static uint32_t omap_venc_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->venc_base; -+ -+ switch (offset) { -+ case 0x00: /* REV_ID */ -+ case 0x04: /* STATUS */ -+ case 0x08: /* F_CONTROL */ -+ case 0x10: /* VIDOUT_CTRL */ -+ case 0x14: /* SYNC_CTRL */ -+ case 0x1c: /* LLEN */ -+ case 0x20: /* FLENS */ -+ case 0x24: /* HFLTR_CTRL */ -+ case 0x28: /* CC_CARR_WSS_CARR */ -+ case 0x2c: /* C_PHASE */ -+ case 0x30: /* GAIN_U */ -+ case 0x34: /* GAIN_V */ -+ case 0x38: /* GAIN_Y */ -+ case 0x3c: /* BLACK_LEVEL */ -+ case 0x40: /* BLANK_LEVEL */ -+ case 0x44: /* X_COLOR */ -+ case 0x48: /* M_CONTROL */ -+ case 0x4c: /* BSTAMP_WSS_DATA */ -+ case 0x50: /* S_CARR */ -+ case 0x54: /* LINE21 */ -+ case 0x58: /* LN_SEL */ -+ case 0x5c: /* L21__WC_CTL */ -+ case 0x60: /* HTRIGGER_VTRIGGER */ -+ case 0x64: /* SAVID__EAVID */ -+ case 0x68: /* FLEN__FAL */ -+ case 0x6c: /* LAL__PHASE_RESET */ -+ case 0x70: /* HS_INT_START_STOP_X */ -+ case 0x74: /* HS_EXT_START_STOP_X */ -+ case 0x78: /* VS_INT_START_X */ -+ case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */ -+ case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */ -+ case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */ -+ case 0x88: /* VS_EXT_STOP_Y */ -+ case 0x90: /* AVID_START_STOP_X */ -+ case 0x94: /* AVID_START_STOP_Y */ -+ case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */ -+ case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */ -+ case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */ -+ case 0xb0: /* TVDETGP_INT_START_STOP_X */ -+ case 0xb4: /* TVDETGP_INT_START_STOP_Y */ -+ case 0xb8: /* GEN_CTRL */ -+ case 0xc4: /* DAC_TST__DAC_A */ -+ case 0xc8: /* DAC_B__DAC_C */ -+ return 0; -+ -+ default: -+ break; -+ } -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_venc_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->venc_base; -+ -+ switch (offset) { -+ case 0x08: /* F_CONTROL */ -+ case 0x10: /* VIDOUT_CTRL */ -+ case 0x14: /* SYNC_CTRL */ -+ case 0x1c: /* LLEN */ -+ case 0x20: /* FLENS */ -+ case 0x24: /* HFLTR_CTRL */ -+ case 0x28: /* CC_CARR_WSS_CARR */ -+ case 0x2c: /* C_PHASE */ -+ case 0x30: /* GAIN_U */ -+ case 0x34: /* GAIN_V */ -+ case 0x38: /* GAIN_Y */ -+ case 0x3c: /* BLACK_LEVEL */ -+ case 0x40: /* BLANK_LEVEL */ -+ case 0x44: /* X_COLOR */ -+ case 0x48: /* M_CONTROL */ -+ case 0x4c: /* BSTAMP_WSS_DATA */ -+ case 0x50: /* S_CARR */ -+ case 0x54: /* LINE21 */ -+ case 0x58: /* LN_SEL */ -+ case 0x5c: /* L21__WC_CTL */ -+ case 0x60: /* HTRIGGER_VTRIGGER */ -+ case 0x64: /* SAVID__EAVID */ -+ case 0x68: /* FLEN__FAL */ -+ case 0x6c: /* LAL__PHASE_RESET */ -+ case 0x70: /* HS_INT_START_STOP_X */ -+ case 0x74: /* HS_EXT_START_STOP_X */ -+ case 0x78: /* VS_INT_START_X */ -+ case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */ -+ case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */ -+ case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */ -+ case 0x88: /* VS_EXT_STOP_Y */ -+ case 0x90: /* AVID_START_STOP_X */ -+ case 0x94: /* AVID_START_STOP_Y */ -+ case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */ -+ case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */ -+ case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */ -+ case 0xb0: /* TVDETGP_INT_START_STOP_X */ -+ case 0xb4: /* TVDETGP_INT_START_STOP_Y */ -+ case 0xb8: /* GEN_CTRL */ -+ case 0xc4: /* DAC_TST__DAC_A */ -+ case 0xc8: /* DAC_B__DAC_C */ -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static CPUReadMemoryFunc *omap_venc1_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_venc_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_venc1_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_venc_write, -+}; -+ -+static uint32_t omap_im3_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->im3_base; -+ -+ switch (offset) { -+ case 0x0a8: /* SBIMERRLOGA */ -+ case 0x0b0: /* SBIMERRLOG */ -+ case 0x190: /* SBIMSTATE */ -+ case 0x198: /* SBTMSTATE_L */ -+ case 0x19c: /* SBTMSTATE_H */ -+ case 0x1a8: /* SBIMCONFIG_L */ -+ case 0x1ac: /* SBIMCONFIG_H */ -+ case 0x1f8: /* SBID_L */ -+ case 0x1fc: /* SBID_H */ -+ return 0; -+ -+ default: -+ break; -+ } -+ OMAP_BAD_REG(addr); -+ return 0; -+} -+ -+static void omap_im3_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct omap_dss_s *s = (struct omap_dss_s *) opaque; -+ int offset = addr - s->im3_base; -+ -+ switch (offset) { -+ case 0x0b0: /* SBIMERRLOG */ -+ case 0x190: /* SBIMSTATE */ -+ case 0x198: /* SBTMSTATE_L */ -+ case 0x19c: /* SBTMSTATE_H */ -+ case 0x1a8: /* SBIMCONFIG_L */ -+ case 0x1ac: /* SBIMCONFIG_H */ -+ break; -+ -+ default: -+ OMAP_BAD_REG(addr); -+ } -+} -+ -+static CPUReadMemoryFunc *omap_im3_readfn[] = { -+ omap_badwidth_read32, -+ omap_badwidth_read32, -+ omap_im3_read, -+}; -+ -+static CPUWriteMemoryFunc *omap_im3_writefn[] = { -+ omap_badwidth_write32, -+ omap_badwidth_write32, -+ omap_im3_write, -+}; -+ -+struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta, -+ target_phys_addr_t l3_base, DisplayState *ds, -+ qemu_irq irq, qemu_irq drq, -+ omap_clk fck1, omap_clk fck2, omap_clk ck54m, -+ omap_clk ick1, omap_clk ick2) -+{ -+ int iomemtype[5]; -+ struct omap_dss_s *s = (struct omap_dss_s *) -+ qemu_mallocz(sizeof(struct omap_dss_s)); -+ -+ s->irq = irq; -+ s->drq = drq; -+ s->state = ds; -+ omap_dss_reset(s); -+ -+ iomemtype[0] = cpu_register_io_memory(0, omap_diss1_readfn, -+ omap_diss1_writefn, s); -+ iomemtype[1] = cpu_register_io_memory(0, omap_disc1_readfn, -+ omap_disc1_writefn, s); -+ iomemtype[2] = cpu_register_io_memory(0, omap_rfbi1_readfn, -+ omap_rfbi1_writefn, s); -+ iomemtype[3] = cpu_register_io_memory(0, omap_venc1_readfn, -+ omap_venc1_writefn, s); -+ iomemtype[4] = cpu_register_io_memory(0, omap_im3_readfn, -+ omap_im3_writefn, s); -+ s->diss_base = omap_l4_attach(ta, 0, iomemtype[0]); -+ s->disc_base = omap_l4_attach(ta, 1, iomemtype[1]); -+ s->rfbi_base = omap_l4_attach(ta, 2, iomemtype[2]); -+ s->venc_base = omap_l4_attach(ta, 3, iomemtype[3]); -+ s->im3_base = l3_base; -+ cpu_register_physical_memory(s->im3_base, 0x1000, iomemtype[4]); -+ -+#if 0 -+ if (ds) -+ graphic_console_init(ds, omap_update_display, -+ omap_invalidate_display, omap_screen_dump, s); -+#endif -+ -+ return s; -+} -+ -+void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip) -+{ -+ if (cs < 0 || cs > 1) -+ cpu_abort(cpu_single_env, "%s: wrong CS %i\n", __FUNCTION__, cs); -+ s->rfbi.chip[cs] = chip; -+} -diff --git a/hw/omap_i2c.c b/hw/omap_i2c.c -index de63309..9915676 100644 ---- a/hw/omap_i2c.c -+++ b/hw/omap_i2c.c -@@ -150,6 +150,8 @@ static void omap_i2c_fifo_run(struct omap_i2c_s *s) - } - if (ack && s->count_cur) - s->stat |= 1 << 4; /* XRDY */ -+ else -+ s->stat &= ~(1 << 4); /* XRDY */ - if (!s->count_cur) { - s->stat |= 1 << 2; /* ARDY */ - s->control &= ~(1 << 10); /* MST */ -@@ -161,6 +163,8 @@ static void omap_i2c_fifo_run(struct omap_i2c_s *s) - } - if (s->rxlen) - s->stat |= 1 << 3; /* RRDY */ -+ else -+ s->stat &= ~(1 << 3); /* RRDY */ - } - if (!s->count_cur) { - if ((s->control >> 1) & 1) { /* STP */ -@@ -321,7 +325,8 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr, - return; - } - -- s->stat &= ~(value & 0x3f); -+ /* RRDY and XRDY are reset by hardware. (in all versions???) */ -+ s->stat &= ~(value & 0x27); - omap_i2c_interrupts_update(s); - break; - -@@ -376,11 +381,13 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr, - break; - } - if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */ -- printf("%s: I^2C slave mode not supported\n", __FUNCTION__); -+ fprintf(stderr, "%s: I^2C slave mode not supported\n", -+ __FUNCTION__); - break; - } - if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */ -- printf("%s: 10-bit addressing mode not supported\n", __FUNCTION__); -+ fprintf(stderr, "%s: 10-bit addressing mode not supported\n", -+ __FUNCTION__); - break; - } - if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */ -@@ -427,7 +434,7 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr, - omap_i2c_interrupts_update(s); - } - if (value & (1 << 15)) /* ST_EN */ -- printf("%s: System Test not supported\n", __FUNCTION__); -+ fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__); - break; - - default: -diff --git a/hw/omap_mmc.c b/hw/omap_mmc.c -index 6fbbb84..e46289a 100644 ---- a/hw/omap_mmc.c -+++ b/hw/omap_mmc.c -@@ -26,19 +26,24 @@ struct omap_mmc_s { - target_phys_addr_t base; - qemu_irq irq; - qemu_irq *dma; -+ qemu_irq coverswitch; - omap_clk clk; - SDState *card; - uint16_t last_cmd; - uint16_t sdio; - uint16_t rsp[8]; - uint32_t arg; -+ int lines; - int dw; - int mode; - int enable; -+ int be; -+ int rev; - uint16_t status; - uint16_t mask; - uint8_t cto; - uint16_t dto; -+ int clkdiv; - uint16_t fifo[32]; - int fifo_start; - int fifo_len; -@@ -53,6 +58,11 @@ struct omap_mmc_s { - - int ddir; - int transfer; -+ -+ int cdet_wakeup; -+ int cdet_enable; -+ int cdet_state; -+ qemu_irq cdet; - }; - - static void omap_mmc_interrupts_update(struct omap_mmc_s *s) -@@ -107,6 +117,11 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir, - struct sd_request_s request; - uint8_t response[16]; - -+ if (init && cmd == 0) { -+ host->status |= 0x0001; -+ return; -+ } -+ - if (resptype == sd_r1 && busy) - resptype = sd_r1b; - -@@ -265,6 +280,34 @@ static void omap_mmc_update(void *opaque) - omap_mmc_interrupts_update(s); - } - -+void omap_mmc_reset(struct omap_mmc_s *host) -+{ -+ host->last_cmd = 0; -+ memset(host->rsp, 0, sizeof(host->rsp)); -+ host->arg = 0; -+ host->dw = 0; -+ host->mode = 0; -+ host->enable = 0; -+ host->status = 0; -+ host->mask = 0; -+ host->cto = 0; -+ host->dto = 0; -+ host->fifo_len = 0; -+ host->blen = 0; -+ host->blen_counter = 0; -+ host->nblk = 0; -+ host->nblk_counter = 0; -+ host->tx_dma = 0; -+ host->rx_dma = 0; -+ host->ae_level = 0x00; -+ host->af_level = 0x1f; -+ host->transfer = 0; -+ host->cdet_wakeup = 0; -+ host->cdet_enable = 0; -+ qemu_set_irq(host->coverswitch, host->cdet_state); -+ host->clkdiv = 0; -+} -+ - static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset) - { - uint16_t i; -@@ -282,7 +325,8 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset) - return s->arg >> 16; - - case 0x0c: /* MMC_CON */ -- return (s->dw << 15) | (s->mode << 12) | (s->enable << 11); -+ return (s->dw << 15) | (s->mode << 12) | (s->enable << 11) | -+ (s->be << 10) | s->clkdiv; - - case 0x10: /* MMC_STAT */ - return s->status; -@@ -324,12 +368,12 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset) - case 0x30: /* MMC_SPI */ - return 0x0000; - case 0x34: /* MMC_SDIO */ -- return s->sdio; -+ return (s->cdet_wakeup << 2) | (s->cdet_enable) | s->sdio; - case 0x38: /* MMC_SYST */ - return 0x0000; - - case 0x3c: /* MMC_REV */ -- return 0x0001; -+ return s->rev; - - case 0x40: /* MMC_RSP0 */ - case 0x44: /* MMC_RSP1 */ -@@ -340,6 +384,13 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset) - case 0x58: /* MMC_RSP6 */ - case 0x5c: /* MMC_RSP7 */ - return s->rsp[(offset - 0x40) >> 2]; -+ -+ /* OMAP2-specific */ -+ case 0x60: /* MMC_IOSR */ -+ case 0x64: /* MMC_SYSC */ -+ return 0; -+ case 0x68: /* MMC_SYSS */ -+ return 1; /* RSTD */ - } - - OMAP_BAD_REG(offset); -@@ -383,10 +434,16 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset, - s->dw = (value >> 15) & 1; - s->mode = (value >> 12) & 3; - s->enable = (value >> 11) & 1; -+ s->be = (value >> 10) & 1; -+ s->clkdiv = (value >> 0) & (s->rev >= 2 ? 0x3ff : 0xff); - if (s->mode != 0) - printf("SD mode %i unimplemented!\n", s->mode); -- if (s->dw != 0) -+ if (s->be != 0) -+ printf("SD FIFO byte sex unimplemented!\n"); -+ if (s->dw != 0 && s->lines < 4) - printf("4-bit SD bus enabled\n"); -+ if (!s->enable) -+ omap_mmc_reset(s); - break; - - case 0x10: /* MMC_STAT */ -@@ -395,13 +452,13 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset, - break; - - case 0x14: /* MMC_IE */ -- s->mask = value; -+ s->mask = value & 0x7fff; - omap_mmc_interrupts_update(s); - break; - - case 0x18: /* MMC_CTO */ - s->cto = value & 0xff; -- if (s->cto > 0xfd) -+ if (s->cto > 0xfd && s->rev <= 1) - printf("MMC: CTO of 0xff and 0xfe cannot be used!\n"); - break; - -@@ -446,10 +503,12 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset, - break; - - /* SPI, SDIO and TEST modes unimplemented */ -- case 0x30: /* MMC_SPI */ -+ case 0x30: /* MMC_SPI (OMAP1 only) */ - break; - case 0x34: /* MMC_SDIO */ -- s->sdio = value & 0x2020; -+ s->sdio = value & (s->rev >= 2 ? 0xfbf3 : 0x2020); -+ s->cdet_wakeup = (value >> 9) & 1; -+ s->cdet_enable = (value >> 2) & 1; - break; - case 0x38: /* MMC_SYST */ - break; -@@ -466,6 +525,19 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset, - OMAP_RO_REG(offset); - break; - -+ /* OMAP2-specific */ -+ case 0x60: /* MMC_IOSR */ -+ if (value & 0xf) -+ printf("MMC: SDIO bits used!\n"); -+ break; -+ case 0x64: /* MMC_SYSC */ -+ if (value & (1 << 2)) /* SRTS */ -+ omap_mmc_reset(s); -+ break; -+ case 0x68: /* MMC_SYSS */ -+ OMAP_RO_REG(offset); -+ break; -+ - default: - OMAP_BAD_REG(offset); - } -@@ -483,28 +555,21 @@ static CPUWriteMemoryFunc *omap_mmc_writefn[] = { - omap_badwidth_write16, - }; - --void omap_mmc_reset(struct omap_mmc_s *host) -+static void omap_mmc_cover_cb(void *opaque, int line, int level) - { -- host->last_cmd = 0; -- memset(host->rsp, 0, sizeof(host->rsp)); -- host->arg = 0; -- host->dw = 0; -- host->mode = 0; -- host->enable = 0; -- host->status = 0; -- host->mask = 0; -- host->cto = 0; -- host->dto = 0; -- host->fifo_len = 0; -- host->blen = 0; -- host->blen_counter = 0; -- host->nblk = 0; -- host->nblk_counter = 0; -- host->tx_dma = 0; -- host->rx_dma = 0; -- host->ae_level = 0x00; -- host->af_level = 0x1f; -- host->transfer = 0; -+ struct omap_mmc_s *host = (struct omap_mmc_s *) opaque; -+ -+ if (!host->cdet_state && level) { -+ host->status |= 0x0002; -+ omap_mmc_interrupts_update(host); -+ if (host->cdet_wakeup) -+ /* TODO: Assert wake-up */; -+ } -+ -+ if (host->cdet_state != level) { -+ qemu_set_irq(host->coverswitch, level); -+ host->cdet_state = level; -+ } - } - - struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, -@@ -519,6 +584,10 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, - s->base = base; - s->dma = dma; - s->clk = clk; -+ s->lines = 1; /* TODO: needs to be settable per-board */ -+ s->rev = 1; -+ -+ omap_mmc_reset(s); - - iomemtype = cpu_register_io_memory(0, omap_mmc_readfn, - omap_mmc_writefn, s); -@@ -530,7 +599,46 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, - return s; - } - -+struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta, -+ BlockDriverState *bd, qemu_irq irq, qemu_irq dma[], -+ omap_clk fclk, omap_clk iclk) -+{ -+ int iomemtype; -+ struct omap_mmc_s *s = (struct omap_mmc_s *) -+ qemu_mallocz(sizeof(struct omap_mmc_s)); -+ -+ s->irq = irq; -+ s->dma = dma; -+ s->clk = fclk; -+ s->lines = 4; -+ s->rev = 2; -+ -+ omap_mmc_reset(s); -+ -+ iomemtype = cpu_register_io_memory(0, omap_mmc_readfn, -+ omap_mmc_writefn, s); -+ s->base = omap_l4_attach(ta, 0, iomemtype); -+ -+ /* Instantiate the storage */ -+ s->card = sd_init(bd, 0); -+ -+ s->cdet = qemu_allocate_irqs(omap_mmc_cover_cb, s, 1)[0]; -+ sd_set_cb(s->card, 0, s->cdet); -+ -+ return s; -+} -+ - void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover) - { -- sd_set_cb(s->card, ro, cover); -+ if (s->cdet) { -+ sd_set_cb(s->card, ro, s->cdet); -+ s->coverswitch = cover; -+ qemu_set_irq(cover, s->cdet_state); -+ } else -+ sd_set_cb(s->card, ro, cover); -+} -+ -+void omap_mmc_enable(struct omap_mmc_s *s, int enable) -+{ -+ sd_enable(s->card, enable); - } -diff --git a/hw/onenand.c b/hw/onenand.c -new file mode 100644 -index 0000000..549d392 ---- /dev/null -+++ b/hw/onenand.c -@@ -0,0 +1,642 @@ -+/* -+ * OneNAND flash memories emulation. -+ * -+ * Copyright (C) 2008 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+#include "qemu-common.h" -+#include "flash.h" -+#include "irq.h" -+#include "sysemu.h" -+#include "block.h" -+ -+/* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */ -+#define PAGE_SHIFT 11 -+ -+/* Fixed */ -+#define BLOCK_SHIFT (PAGE_SHIFT + 6) -+ -+struct onenand_s { -+ uint32_t id; -+ int shift; -+ target_phys_addr_t base; -+ qemu_irq intr; -+ qemu_irq rdy; -+ BlockDriverState *bdrv; -+ BlockDriverState *bdrv_cur; -+ uint8_t *image; -+ uint8_t *otp; -+ uint8_t *current; -+ ram_addr_t ram; -+ uint8_t *boot[2]; -+ uint8_t *data[2][2]; -+ int iomemtype; -+ int cycle; -+ int otpmode; -+ -+ uint16_t addr[8]; -+ uint16_t unladdr[8]; -+ int bufaddr; -+ int count; -+ uint16_t command; -+ uint16_t config[2]; -+ uint16_t status; -+ uint16_t intstatus; -+ uint16_t wpstatus; -+ -+ struct ecc_state_s ecc; -+ -+ int density_mask; -+ int secs; -+ int secs_cur; -+ int blocks; -+ uint8_t *blockwp; -+}; -+ -+enum { -+ ONEN_BUF_BLOCK = 0, -+ ONEN_BUF_BLOCK2 = 1, -+ ONEN_BUF_DEST_BLOCK = 2, -+ ONEN_BUF_DEST_PAGE = 3, -+ ONEN_BUF_PAGE = 7, -+}; -+ -+enum { -+ ONEN_ERR_CMD = 1 << 10, -+ ONEN_ERR_ERASE = 1 << 11, -+ ONEN_ERR_PROG = 1 << 12, -+ ONEN_ERR_LOAD = 1 << 13, -+}; -+ -+enum { -+ ONEN_INT_RESET = 1 << 4, -+ ONEN_INT_ERASE = 1 << 5, -+ ONEN_INT_PROG = 1 << 6, -+ ONEN_INT_LOAD = 1 << 7, -+ ONEN_INT = 1 << 15, -+}; -+ -+enum { -+ ONEN_LOCK_LOCKTIGHTEN = 1 << 0, -+ ONEN_LOCK_LOCKED = 1 << 1, -+ ONEN_LOCK_UNLOCKED = 1 << 2, -+}; -+ -+void onenand_base_update(void *opaque, target_phys_addr_t new) -+{ -+ struct onenand_s *s = (struct onenand_s *) opaque; -+ -+ s->base = new; -+ -+ /* XXX: We should use IO_MEM_ROMD but we broke it earlier... -+ * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to -+ * write boot commands. Also take note of the BWPS bit. */ -+ cpu_register_physical_memory(s->base + (0x0000 << s->shift), -+ 0x0200 << s->shift, s->iomemtype); -+ cpu_register_physical_memory(s->base + (0x0200 << s->shift), -+ 0xbe00 << s->shift, -+ (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM); -+ if (s->iomemtype) -+ cpu_register_physical_memory(s->base + (0xc000 << s->shift), -+ 0x4000 << s->shift, s->iomemtype); -+} -+ -+void onenand_base_unmap(void *opaque) -+{ -+ struct onenand_s *s = (struct onenand_s *) opaque; -+ -+ cpu_register_physical_memory(s->base, -+ 0x10000 << s->shift, IO_MEM_UNASSIGNED); -+} -+ -+static void onenand_intr_update(struct onenand_s *s) -+{ -+ qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1); -+} -+ -+/* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */ -+static void onenand_reset(struct onenand_s *s, int cold) -+{ -+ memset(&s->addr, 0, sizeof(s->addr)); -+ s->command = 0; -+ s->count = 1; -+ s->bufaddr = 0; -+ s->config[0] = 0x40c0; -+ s->config[1] = 0x0000; -+ onenand_intr_update(s); -+ qemu_irq_raise(s->rdy); -+ s->status = 0x0000; -+ s->intstatus = cold ? 0x8080 : 0x8010; -+ s->unladdr[0] = 0; -+ s->unladdr[1] = 0; -+ s->wpstatus = 0x0002; -+ s->cycle = 0; -+ s->otpmode = 0; -+ s->bdrv_cur = s->bdrv; -+ s->current = s->image; -+ s->secs_cur = s->secs; -+ -+ if (cold) { -+ /* Lock the whole flash */ -+ memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks); -+ -+ if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0) -+ cpu_abort(cpu_single_env, "%s: Loading the BootRAM failed.\n", -+ __FUNCTION__); -+ } -+} -+ -+static inline int onenand_load_main(struct onenand_s *s, int sec, int secn, -+ void *dest) -+{ -+ if (s->bdrv_cur) -+ return bdrv_read(s->bdrv_cur, sec, dest, secn) < 0; -+ else if (sec + secn > s->secs_cur) -+ return 1; -+ -+ memcpy(dest, s->current + (sec << 9), secn << 9); -+ -+ return 0; -+} -+ -+static inline int onenand_prog_main(struct onenand_s *s, int sec, int secn, -+ void *src) -+{ -+ if (s->bdrv_cur) -+ return bdrv_write(s->bdrv_cur, sec, src, secn) < 0; -+ else if (sec + secn > s->secs_cur) -+ return 1; -+ -+ memcpy(s->current + (sec << 9), src, secn << 9); -+ -+ return 0; -+} -+ -+static inline int onenand_load_spare(struct onenand_s *s, int sec, int secn, -+ void *dest) -+{ -+ uint8_t buf[512]; -+ -+ if (s->bdrv_cur) { -+ if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0) -+ return 1; -+ memcpy(dest, buf + ((sec & 31) << 4), secn << 4); -+ } else if (sec + secn > s->secs_cur) -+ return 1; -+ else -+ memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4); -+ -+ return 0; -+} -+ -+static inline int onenand_prog_spare(struct onenand_s *s, int sec, int secn, -+ void *src) -+{ -+ uint8_t buf[512]; -+ -+ if (s->bdrv_cur) { -+ if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0) -+ return 1; -+ memcpy(buf + ((sec & 31) << 4), src, secn << 4); -+ return bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0; -+ } else if (sec + secn > s->secs_cur) -+ return 1; -+ -+ memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4); -+ -+ return 0; -+} -+ -+static inline int onenand_erase(struct onenand_s *s, int sec, int num) -+{ -+ /* TODO: optimise */ -+ uint8_t buf[512]; -+ -+ memset(buf, 0xff, sizeof(buf)); -+ for (; num > 0; num --, sec ++) { -+ if (onenand_prog_main(s, sec, 1, buf)) -+ return 1; -+ if (onenand_prog_spare(s, sec, 1, buf)) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static void onenand_command(struct onenand_s *s, int cmd) -+{ -+ int b; -+ int sec; -+ void *buf; -+#define SETADDR(block, page) \ -+ sec = (s->addr[page] & 3) + \ -+ ((((s->addr[page] >> 2) & 0x3f) + \ -+ (((s->addr[block] & 0xfff) | \ -+ (s->addr[block] >> 15 ? \ -+ s->density_mask : 0)) << 6)) << (PAGE_SHIFT - 9)); -+#define SETBUF_M() \ -+ buf = (s->bufaddr & 8) ? \ -+ s->data[(s->bufaddr >> 2) & 1][0] : s->boot[0]; \ -+ buf += (s->bufaddr & 3) << 9; -+#define SETBUF_S() \ -+ buf = (s->bufaddr & 8) ? \ -+ s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1]; \ -+ buf += (s->bufaddr & 3) << 4; -+ -+ switch (cmd) { -+ case 0x00: /* Load single/multiple sector data unit into buffer */ -+ SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE) -+ -+ SETBUF_M() -+ if (onenand_load_main(s, sec, s->count, buf)) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD; -+ -+#if 0 -+ SETBUF_S() -+ if (onenand_load_spare(s, sec, s->count, buf)) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD; -+#endif -+ -+ /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages) -+ * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages) -+ * then we need two split the read/write into two chunks. -+ */ -+ s->intstatus |= ONEN_INT | ONEN_INT_LOAD; -+ break; -+ case 0x13: /* Load single/multiple spare sector into buffer */ -+ SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE) -+ -+ SETBUF_S() -+ if (onenand_load_spare(s, sec, s->count, buf)) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_LOAD; -+ -+ /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages) -+ * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages) -+ * then we need two split the read/write into two chunks. -+ */ -+ s->intstatus |= ONEN_INT | ONEN_INT_LOAD; -+ break; -+ case 0x80: /* Program single/multiple sector data unit from buffer */ -+ SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE) -+ -+ SETBUF_M() -+ if (onenand_prog_main(s, sec, s->count, buf)) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG; -+ -+#if 0 -+ SETBUF_S() -+ if (onenand_prog_spare(s, sec, s->count, buf)) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG; -+#endif -+ -+ /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages) -+ * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages) -+ * then we need two split the read/write into two chunks. -+ */ -+ s->intstatus |= ONEN_INT | ONEN_INT_PROG; -+ break; -+ case 0x1a: /* Program single/multiple spare area sector from buffer */ -+ SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE) -+ -+ SETBUF_S() -+ if (onenand_prog_spare(s, sec, s->count, buf)) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG; -+ -+ /* TODO: if (s->bufaddr & 3) + s->count was > 4 (2k-pages) -+ * or if (s->bufaddr & 1) + s->count was > 2 (1k-pages) -+ * then we need two split the read/write into two chunks. -+ */ -+ s->intstatus |= ONEN_INT | ONEN_INT_PROG; -+ break; -+ case 0x1b: /* Copy-back program */ -+ SETBUF_S() -+ -+ SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE) -+ if (onenand_load_main(s, sec, s->count, buf)) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG; -+ -+ SETADDR(ONEN_BUF_DEST_BLOCK, ONEN_BUF_DEST_PAGE) -+ if (onenand_prog_main(s, sec, s->count, buf)) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_PROG; -+ -+ /* TODO: spare areas */ -+ -+ s->intstatus |= ONEN_INT | ONEN_INT_PROG; -+ break; -+ -+ case 0x23: /* Unlock NAND array block(s) */ -+ s->intstatus |= ONEN_INT; -+ -+ /* XXX the previous (?) area should be locked automatically */ -+ for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) { -+ if (b >= s->blocks) { -+ s->status |= ONEN_ERR_CMD; -+ break; -+ } -+ if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN) -+ break; -+ -+ s->wpstatus = s->blockwp[b] = ONEN_LOCK_UNLOCKED; -+ } -+ break; -+ case 0x2a: /* Lock NAND array block(s) */ -+ s->intstatus |= ONEN_INT; -+ -+ for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) { -+ if (b >= s->blocks) { -+ s->status |= ONEN_ERR_CMD; -+ break; -+ } -+ if (s->blockwp[b] == ONEN_LOCK_LOCKTIGHTEN) -+ break; -+ -+ s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKED; -+ } -+ break; -+ case 0x2c: /* Lock-tight NAND array block(s) */ -+ s->intstatus |= ONEN_INT; -+ -+ for (b = s->unladdr[0]; b <= s->unladdr[1]; b ++) { -+ if (b >= s->blocks) { -+ s->status |= ONEN_ERR_CMD; -+ break; -+ } -+ if (s->blockwp[b] == ONEN_LOCK_UNLOCKED) -+ continue; -+ -+ s->wpstatus = s->blockwp[b] = ONEN_LOCK_LOCKTIGHTEN; -+ } -+ break; -+ -+ case 0x71: /* Erase-Verify-Read */ -+ s->intstatus |= ONEN_INT; -+ break; -+ case 0x95: /* Multi-block erase */ -+ qemu_irq_pulse(s->intr); -+ /* Fall through. */ -+ case 0x94: /* Block erase */ -+ sec = ((s->addr[ONEN_BUF_BLOCK] & 0xfff) | -+ (s->addr[ONEN_BUF_BLOCK] >> 15 ? s->density_mask : 0)) -+ << (BLOCK_SHIFT - 9); -+ if (onenand_erase(s, sec, 1 << (BLOCK_SHIFT - 9))) -+ s->status |= ONEN_ERR_CMD | ONEN_ERR_ERASE; -+ -+ s->intstatus |= ONEN_INT | ONEN_INT_ERASE; -+ break; -+ case 0xb0: /* Erase suspend */ -+ break; -+ case 0x30: /* Erase resume */ -+ s->intstatus |= ONEN_INT | ONEN_INT_ERASE; -+ break; -+ -+ case 0xf0: /* Reset NAND Flash core */ -+ onenand_reset(s, 0); -+ break; -+ case 0xf3: /* Reset OneNAND */ -+ onenand_reset(s, 0); -+ break; -+ -+ case 0x65: /* OTP Access */ -+ s->intstatus |= ONEN_INT; -+ s->bdrv_cur = 0; -+ s->current = s->otp; -+ s->secs_cur = 1 << (BLOCK_SHIFT - 9); -+ s->addr[ONEN_BUF_BLOCK] = 0; -+ s->otpmode = 1; -+ break; -+ -+ default: -+ s->status |= ONEN_ERR_CMD; -+ s->intstatus |= ONEN_INT; -+ fprintf(stderr, "%s: unknown OneNAND command %x\n", -+ __FUNCTION__, cmd); -+ } -+ -+ onenand_intr_update(s); -+} -+ -+static uint32_t onenand_read(void *opaque, target_phys_addr_t addr) -+{ -+ struct onenand_s *s = (struct onenand_s *) opaque; -+ int offset = (addr - s->base) >> s->shift; -+ -+ switch (offset) { -+ case 0x0000 ... 0xc000: -+ return lduw_le_p(s->boot[0] + (addr - s->base)); -+ -+ case 0xf000: /* Manufacturer ID */ -+ return (s->id >> 16) & 0xff; -+ case 0xf001: /* Device ID */ -+ return (s->id >> 8) & 0xff; -+ /* TODO: get the following values from a real chip! */ -+ case 0xf002: /* Version ID */ -+ return (s->id >> 0) & 0xff; -+ case 0xf003: /* Data Buffer size */ -+ return 1 << PAGE_SHIFT; -+ case 0xf004: /* Boot Buffer size */ -+ return 0x200; -+ case 0xf005: /* Amount of buffers */ -+ return 1 | (2 << 8); -+ case 0xf006: /* Technology */ -+ return 0; -+ -+ case 0xf100 ... 0xf107: /* Start addresses */ -+ return s->addr[offset - 0xf100]; -+ -+ case 0xf200: /* Start buffer */ -+ return (s->bufaddr << 8) | ((s->count - 1) & (1 << (PAGE_SHIFT - 10))); -+ -+ case 0xf220: /* Command */ -+ return s->command; -+ case 0xf221: /* System Configuration 1 */ -+ return s->config[0] & 0xffe0; -+ case 0xf222: /* System Configuration 2 */ -+ return s->config[1]; -+ -+ case 0xf240: /* Controller Status */ -+ return s->status; -+ case 0xf241: /* Interrupt */ -+ return s->intstatus; -+ case 0xf24c: /* Unlock Start Block Address */ -+ return s->unladdr[0]; -+ case 0xf24d: /* Unlock End Block Address */ -+ return s->unladdr[1]; -+ case 0xf24e: /* Write Protection Status */ -+ return s->wpstatus; -+ -+ case 0xff00: /* ECC Status */ -+ return 0x00; -+ case 0xff01: /* ECC Result of main area data */ -+ case 0xff02: /* ECC Result of spare area data */ -+ case 0xff03: /* ECC Result of main area data */ -+ case 0xff04: /* ECC Result of spare area data */ -+ cpu_abort(cpu_single_env, "%s: imeplement ECC\n", __FUNCTION__); -+ return 0x0000; -+ } -+ -+ fprintf(stderr, "%s: unknown OneNAND register %x\n", -+ __FUNCTION__, offset); -+ return 0; -+} -+ -+static void onenand_write(void *opaque, target_phys_addr_t addr, -+ uint32_t value) -+{ -+ struct onenand_s *s = (struct onenand_s *) opaque; -+ int offset = (addr - s->base) >> s->shift; -+ int sec; -+ -+ switch (offset) { -+ case 0x0000 ... 0x01ff: -+ case 0x8000 ... 0x800f: -+ if (s->cycle) { -+ s->cycle = 0; -+ -+ if (value == 0x0000) { -+ SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE) -+ onenand_load_main(s, sec, -+ 1 << (PAGE_SHIFT - 9), s->data[0][0]); -+ s->addr[ONEN_BUF_PAGE] += 4; -+ s->addr[ONEN_BUF_PAGE] &= 0xff; -+ } -+ break; -+ } -+ -+ switch (value) { -+ case 0x00f0: /* Reset OneNAND */ -+ onenand_reset(s, 0); -+ break; -+ -+ case 0x00e0: /* Load Data into Buffer */ -+ s->cycle = 1; -+ break; -+ -+ case 0x0090: /* Read Identification Data */ -+ memset(s->boot[0], 0, 3 << s->shift); -+ s->boot[0][0 << s->shift] = (s->id >> 16) & 0xff; -+ s->boot[0][1 << s->shift] = (s->id >> 8) & 0xff; -+ s->boot[0][2 << s->shift] = s->wpstatus & 0xff; -+ break; -+ -+ default: -+ fprintf(stderr, "%s: unknown OneNAND boot command %x\n", -+ __FUNCTION__, value); -+ } -+ break; -+ -+ case 0xf100 ... 0xf107: /* Start addresses */ -+ s->addr[offset - 0xf100] = value; -+ break; -+ -+ case 0xf200: /* Start buffer */ -+ s->bufaddr = (value >> 8) & 0xf; -+ if (PAGE_SHIFT == 11) -+ s->count = (value & 3) ?: 4; -+ else if (PAGE_SHIFT == 10) -+ s->count = (value & 1) ?: 2; -+ break; -+ -+ case 0xf220: /* Command */ -+ if (s->intstatus & (1 << 15)) -+ break; -+ s->command = value; -+ onenand_command(s, s->command); -+ break; -+ case 0xf221: /* System Configuration 1 */ -+ s->config[0] = value; -+ onenand_intr_update(s); -+ qemu_set_irq(s->rdy, (s->config[0] >> 7) & 1); -+ break; -+ case 0xf222: /* System Configuration 2 */ -+ s->config[1] = value; -+ break; -+ -+ case 0xf241: /* Interrupt */ -+ s->intstatus &= value; -+ if ((1 << 15) & ~s->intstatus) -+ s->status &= ~(ONEN_ERR_CMD | ONEN_ERR_ERASE | -+ ONEN_ERR_PROG | ONEN_ERR_LOAD); -+ onenand_intr_update(s); -+ break; -+ case 0xf24c: /* Unlock Start Block Address */ -+ s->unladdr[0] = value & (s->blocks - 1); -+ /* For some reason we have to set the end address to by default -+ * be same as start because the software forgets to write anything -+ * in there. */ -+ s->unladdr[1] = value & (s->blocks - 1); -+ break; -+ case 0xf24d: /* Unlock End Block Address */ -+ s->unladdr[1] = value & (s->blocks - 1); -+ break; -+ -+ default: -+ fprintf(stderr, "%s: unknown OneNAND register %x\n", -+ __FUNCTION__, offset); -+ } -+} -+ -+static CPUReadMemoryFunc *onenand_readfn[] = { -+ onenand_read, /* TODO */ -+ onenand_read, -+ onenand_read, -+}; -+ -+static CPUWriteMemoryFunc *onenand_writefn[] = { -+ onenand_write, /* TODO */ -+ onenand_write, -+ onenand_write, -+}; -+ -+void *onenand_init(uint32_t id, int regshift, qemu_irq irq) -+{ -+ struct onenand_s *s = (struct onenand_s *) qemu_mallocz(sizeof(*s)); -+ int bdrv_index = drive_get_index(IF_MTD, 0, 0); -+ uint32_t size = 1 << (24 + ((id >> 12) & 7)); -+ void *ram; -+ -+ s->shift = regshift; -+ s->intr = irq; -+ s->rdy = 0; -+ s->id = id; -+ s->blocks = size >> BLOCK_SHIFT; -+ s->secs = size >> 9; -+ s->blockwp = qemu_malloc(s->blocks); -+ s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0; -+ s->iomemtype = cpu_register_io_memory(0, onenand_readfn, -+ onenand_writefn, s); -+ if (bdrv_index == -1) -+ s->image = memset(qemu_malloc(size + (size >> 5)), -+ 0xff, size + (size >> 5)); -+ else -+ s->bdrv = drives_table[bdrv_index].bdrv; -+ s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT), -+ 0xff, (64 + 2) << PAGE_SHIFT); -+ s->ram = qemu_ram_alloc(0xc000 << s->shift); -+ ram = phys_ram_base + s->ram; -+ s->boot[0] = ram + (0x0000 << s->shift); -+ s->boot[1] = ram + (0x8000 << s->shift); -+ s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift); -+ s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift); -+ s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift); -+ s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift); -+ -+ onenand_reset(s, 1); -+ -+ return s; -+} -diff --git a/hw/palm.c b/hw/palm.c -index 9400ea7..8b767e2 100644 ---- a/hw/palm.c -+++ b/hw/palm.c -@@ -25,6 +25,7 @@ - #include "omap.h" - #include "boards.h" - #include "arm-misc.h" -+#include "devices.h" - - static uint32_t static_readb(void *opaque, target_phys_addr_t offset) - { -@@ -32,12 +33,14 @@ static uint32_t static_readb(void *opaque, target_phys_addr_t offset) - return *val >> ((offset & 3) << 3); - } - --static uint32_t static_readh(void *opaque, target_phys_addr_t offset) { -+static uint32_t static_readh(void *opaque, target_phys_addr_t offset) -+{ - uint32_t *val = (uint32_t *) opaque; - return *val >> ((offset & 1) << 3); - } - --static uint32_t static_readw(void *opaque, target_phys_addr_t offset) { -+static uint32_t static_readw(void *opaque, target_phys_addr_t offset) -+{ - uint32_t *val = (uint32_t *) opaque; - return *val >> ((offset & 0) << 3); - } -@@ -183,6 +186,12 @@ static void palmte_gpio_setup(struct omap_mpu_state_s *cpu) - qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[11]); - } - -+static struct arm_boot_info palmte_binfo = { -+ .loader_start = OMAP_EMIFF_BASE, -+ .ram_size = 0x02000000, -+ .board_id = 0x331, -+}; -+ - static void palmte_init(int ram_size, int vga_ram_size, - const char *boot_device, DisplayState *ds, - const char *kernel_filename, const char *kernel_cmdline, -@@ -190,7 +199,7 @@ static void palmte_init(int ram_size, int vga_ram_size, - { - struct omap_mpu_state_s *cpu; - int flash_size = 0x00800000; -- int sdram_size = 0x02000000; -+ int sdram_size = palmte_binfo.ram_size; - int io; - static uint32_t cs0val = 0xffffffff; - static uint32_t cs1val = 0x0000e1a0; -@@ -250,10 +259,12 @@ static void palmte_init(int ram_size, int vga_ram_size, - /* Load the kernel. */ - if (kernel_filename) { - /* Start at bootloader. */ -- cpu->env->regs[15] = OMAP_EMIFF_BASE; -+ cpu->env->regs[15] = palmte_binfo.loader_start; - -- arm_load_kernel(cpu->env, sdram_size, kernel_filename, kernel_cmdline, -- initrd_filename, 0x331, OMAP_EMIFF_BASE); -+ palmte_binfo.kernel_filename = kernel_filename; -+ palmte_binfo.kernel_cmdline = kernel_cmdline; -+ palmte_binfo.initrd_filename = initrd_filename; -+ arm_load_kernel(cpu->env, &palmte_binfo); - } - - dpy_resize(ds, 320, 320); -diff --git a/hw/realview.c b/hw/realview.c -index 29579d8..acf3b9e 100644 ---- a/hw/realview.c -+++ b/hw/realview.c -@@ -18,6 +18,11 @@ - - /* Board init. */ - -+static struct arm_boot_info realview_binfo = { -+ .loader_start = 0x0, -+ .board_id = 0x33b, -+}; -+ - static void realview_init(int ram_size, int vga_ram_size, - const char *boot_device, DisplayState *ds, - const char *kernel_filename, const char *kernel_cmdline, -@@ -177,8 +182,12 @@ static void realview_init(int ram_size, int vga_ram_size, - /* 0x68000000 PCI mem 1. */ - /* 0x6c000000 PCI mem 2. */ - -- arm_load_kernel(first_cpu, ram_size, kernel_filename, kernel_cmdline, -- initrd_filename, 0x33b, 0x0); -+ realview_binfo.ram_size = ram_size; -+ realview_binfo.kernel_filename = kernel_filename; -+ realview_binfo.kernel_cmdline = kernel_cmdline; -+ realview_binfo.initrd_filename = initrd_filename; -+ realview_binfo.nb_cpus = ncpu; -+ arm_load_kernel(first_cpu, &realview_binfo); - - /* ??? Hack to map an additional page of ram for the secondary CPU - startup code. I guess this works on real hardware because the -diff --git a/hw/sd.c b/hw/sd.c -index 1f71d85..de7dd89 100644 ---- a/hw/sd.c -+++ b/hw/sd.c -@@ -37,7 +37,7 @@ - - #ifdef DEBUG_SD - #define DPRINTF(fmt, args...) \ --do { printf("SD: " fmt , ##args); } while (0) -+do { fprintf(stderr, "SD: " fmt , ##args); } while (0) - #else - #define DPRINTF(fmt, args...) do {} while(0) - #endif -@@ -99,6 +99,8 @@ struct SDState { - qemu_irq inserted_cb; - BlockDriverState *bdrv; - uint8_t *buf; -+ -+ int enable; - }; - - static void sd_set_status(SDState *sd) -@@ -530,7 +532,7 @@ static void sd_lock_command(SDState *sd) - sd->card_status &= ~CARD_IS_LOCKED; - sd->pwd_len = 0; - /* Erasing the entire card here! */ -- printf("SD: Card force-erased by CMD42\n"); -+ fprintf(stderr, "SD: Card force-erased by CMD42\n"); - return; - } - -@@ -1076,7 +1078,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, - return sd_r1; - - case 56: /* CMD56: GEN_CMD */ -- printf("SD: GEN_CMD 0x%08x\n", req.arg); -+ fprintf(stderr, "SD: GEN_CMD 0x%08x\n", req.arg); - - switch (sd->state) { - case sd_transfer_state: -@@ -1096,18 +1098,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, - bad_cmd: - sd->card_status |= ILLEGAL_COMMAND; - -- printf("SD: Unknown CMD%i\n", req.cmd); -+ fprintf(stderr, "SD: Unknown CMD%i\n", req.cmd); - return sd_r0; - - unimplemented_cmd: - /* Commands that are recognised but not yet implemented in SPI mode. */ - sd->card_status |= ILLEGAL_COMMAND; -- printf ("SD: CMD%i not implemented in SPI mode\n", req.cmd); -+ fprintf(stderr, "SD: CMD%i not implemented in SPI mode\n", req.cmd); - return sd_r0; - } - - sd->card_status |= ILLEGAL_COMMAND; -- printf("SD: CMD%i in a wrong state\n", req.cmd); -+ fprintf(stderr, "SD: CMD%i in a wrong state\n", req.cmd); - return sd_r0; - } - -@@ -1217,7 +1219,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd, - return sd_normal_command(sd, req); - } - -- printf("SD: ACMD%i in a wrong state\n", req.cmd); -+ fprintf(stderr, "SD: ACMD%i in a wrong state\n", req.cmd); - return sd_r0; - } - -@@ -1227,7 +1229,7 @@ int sd_do_command(SDState *sd, struct sd_request_s *req, - sd_rsp_type_t rtype; - int rsplen; - -- if (!bdrv_is_inserted(sd->bdrv)) { -+ if (!bdrv_is_inserted(sd->bdrv) || !sd->enable) { - return 0; - } - -@@ -1247,7 +1249,7 @@ int sd_do_command(SDState *sd, struct sd_request_s *req, - sd_cmd_class[req->cmd] == 7 || - req->cmd == 16 || req->cmd == 55))) { - sd->card_status |= ILLEGAL_COMMAND; -- printf("SD: Card is locked\n"); -+ fprintf(stderr, "SD: Card is locked\n"); - return 0; - } - -@@ -1321,7 +1323,7 @@ static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len) - uint32_t end = addr + len; - - if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { -- printf("sd_blk_read: read error on host side\n"); -+ fprintf(stderr, "sd_blk_read: read error on host side\n"); - return; - } - -@@ -1329,7 +1331,7 @@ static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len) - memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511)); - - if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) { -- printf("sd_blk_read: read error on host side\n"); -+ fprintf(stderr, "sd_blk_read: read error on host side\n"); - return; - } - memcpy(sd->data + 512 - (addr & 511), sd->buf, end & 511); -@@ -1343,28 +1345,28 @@ static void sd_blk_write(SDState *sd, uint32_t addr, uint32_t len) - - if ((addr & 511) || len < 512) - if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { -- printf("sd_blk_write: read error on host side\n"); -+ fprintf(stderr, "sd_blk_write: read error on host side\n"); - return; - } - - if (end > (addr & ~511) + 512) { - memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511)); - if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) { -- printf("sd_blk_write: write error on host side\n"); -+ fprintf(stderr, "sd_blk_write: write error on host side\n"); - return; - } - - if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) { -- printf("sd_blk_write: read error on host side\n"); -+ fprintf(stderr, "sd_blk_write: read error on host side\n"); - return; - } - memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511); - if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1) -- printf("sd_blk_write: write error on host side\n"); -+ fprintf(stderr, "sd_blk_write: write error on host side\n"); - } else { - memcpy(sd->buf + (addr & 511), sd->data, len); - if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) -- printf("sd_blk_write: write error on host side\n"); -+ fprintf(stderr, "sd_blk_write: write error on host side\n"); - } - } - -@@ -1377,11 +1379,11 @@ void sd_write_data(SDState *sd, uint8_t value) - { - int i; - -- if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv)) -+ if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable) - return; - - if (sd->state != sd_receivingdata_state) { -- printf("sd_write_data: not in Receiving-Data state\n"); -+ fprintf(stderr, "sd_write_data: not in Receiving-Data state\n"); - return; - } - -@@ -1489,7 +1491,7 @@ void sd_write_data(SDState *sd, uint8_t value) - break; - - default: -- printf("sd_write_data: unknown command\n"); -+ fprintf(stderr, "sd_write_data: unknown command\n"); - break; - } - } -@@ -1499,11 +1501,11 @@ uint8_t sd_read_data(SDState *sd) - /* TODO: Append CRCs */ - uint8_t ret; - -- if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv)) -+ if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable) - return 0x00; - - if (sd->state != sd_sendingdata_state) { -- printf("sd_read_data: not in Sending-Data state\n"); -+ fprintf(stderr, "sd_read_data: not in Sending-Data state\n"); - return 0x00; - } - -@@ -1603,7 +1605,7 @@ uint8_t sd_read_data(SDState *sd) - break; - - default: -- printf("sd_read_data: unknown command\n"); -+ fprintf(stderr, "sd_read_data: unknown command\n"); - return 0x00; - } - -@@ -1614,3 +1616,8 @@ int sd_data_ready(SDState *sd) - { - return sd->state == sd_sendingdata_state; - } -+ -+void sd_enable(SDState *sd, int enable) -+{ -+ sd->enable = enable; -+} -diff --git a/hw/sd.h b/hw/sd.h -index 85f110f..cb7bc9c 100644 ---- a/hw/sd.h -+++ b/hw/sd.h -@@ -74,6 +74,7 @@ void sd_write_data(SDState *sd, uint8_t value); - uint8_t sd_read_data(SDState *sd); - void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert); - int sd_data_ready(SDState *sd); -+void sd_enable(SDState *sd, int enable); - - /* ssi-sd.c */ - int ssi_sd_xfer(void *opaque, int val); -diff --git a/hw/spitz.c b/hw/spitz.c -index 159c633..b059f9a 100644 ---- a/hw/spitz.c -+++ b/hw/spitz.c -@@ -1180,12 +1180,17 @@ static void sl_bootparam_write(uint32_t ptr) - /* Board init. */ - enum spitz_model_e { spitz, akita, borzoi, terrier }; - -+static struct arm_boot_info spitz_binfo = { -+ .loader_start = PXA2XX_SDRAM_BASE, -+ .ram_size = 0x04000000, -+}; -+ - static void spitz_common_init(int ram_size, int vga_ram_size, - DisplayState *ds, const char *kernel_filename, - const char *kernel_cmdline, const char *initrd_filename, - const char *cpu_model, enum spitz_model_e model, int arm_id) - { -- uint32_t spitz_ram = 0x04000000; -+ uint32_t spitz_ram = spitz_binfo.ram_size; - uint32_t spitz_rom = 0x00800000; - struct pxa2xx_state_s *cpu; - struct scoop_info_s *scp; -@@ -1230,10 +1235,13 @@ static void spitz_common_init(int ram_size, int vga_ram_size, - spitz_microdrive_attach(cpu); - - /* Setup initial (reset) machine state */ -- cpu->env->regs[15] = PXA2XX_SDRAM_BASE; -+ cpu->env->regs[15] = spitz_binfo.loader_start; - -- arm_load_kernel(cpu->env, spitz_ram, kernel_filename, kernel_cmdline, -- initrd_filename, arm_id, PXA2XX_SDRAM_BASE); -+ spitz_binfo.kernel_filename = kernel_filename; -+ spitz_binfo.kernel_cmdline = kernel_cmdline; -+ spitz_binfo.initrd_filename = initrd_filename; -+ spitz_binfo.board_id = arm_id; -+ arm_load_kernel(cpu->env, &spitz_binfo); - sl_bootparam_write(SL_PXA_PARAM_BASE - PXA2XX_SDRAM_BASE); - } - -diff --git a/hw/tmp105.c b/hw/tmp105.c -new file mode 100644 -index 0000000..d9a3900 ---- /dev/null -+++ b/hw/tmp105.c -@@ -0,0 +1,249 @@ -+/* -+ * Texas Instruments TMP105 temperature sensor. -+ * -+ * Copyright (C) 2008 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+#include "hw.h" -+#include "i2c.h" -+ -+struct tmp105_s { -+ i2c_slave i2c; -+ int len; -+ uint8_t buf[2]; -+ qemu_irq pin; -+ -+ uint8_t pointer; -+ uint8_t config; -+ int16_t temperature; -+ int16_t limit[2]; -+ int faults; -+ int alarm; -+}; -+ -+static void tmp105_interrupt_update(struct tmp105_s *s) -+{ -+ qemu_set_irq(s->pin, s->alarm ^ ((~s->config >> 2) & 1)); /* POL */ -+} -+ -+static void tmp105_alarm_update(struct tmp105_s *s) -+{ -+ if ((s->config >> 0) & 1) { /* SD */ -+ if ((s->config >> 7) & 1) /* OS */ -+ s->config &= ~(1 << 7); /* OS */ -+ else -+ return; -+ } -+ -+ if ((s->config >> 1) & 1) { /* TM */ -+ if (s->temperature >= s->limit[1]) -+ s->alarm = 1; -+ else if (s->temperature < s->limit[0]) -+ s->alarm = 1; -+ } else { -+ if (s->temperature >= s->limit[1]) -+ s->alarm = 1; -+ else if (s->temperature < s->limit[0]) -+ s->alarm = 0; -+ } -+ -+ tmp105_interrupt_update(s); -+} -+ -+/* Units are 0.001 centigrades relative to 0 C. */ -+void tmp105_set(i2c_slave *i2c, int temp) -+{ -+ struct tmp105_s *s = (struct tmp105_s *) i2c; -+ -+ if (temp >= 128000 || temp < -128000) { -+ fprintf(stderr, "%s: values is out of range (%i.%03i C)\n", -+ __FUNCTION__, temp / 1000, temp % 1000); -+ exit(-1); -+ } -+ -+ s->temperature = ((int16_t) (temp * 0x800 / 128000)) << 4; -+ -+ tmp105_alarm_update(s); -+} -+ -+static const int tmp105_faultq[4] = { 1, 2, 4, 6 }; -+ -+static void tmp105_read(struct tmp105_s *s) -+{ -+ s->len = 0; -+ -+ if ((s->config >> 1) & 1) { /* TM */ -+ s->alarm = 0; -+ tmp105_interrupt_update(s); -+ } -+ -+ switch (s->pointer & 3) { -+ case 0: /* Temperature */ -+ s->buf[s->len ++] = (((uint16_t) s->temperature) >> 8); -+ s->buf[s->len ++] = (((uint16_t) s->temperature) >> 0) & -+ (0xf0 << ((~s->config >> 5) & 3)); /* R */ -+ break; -+ -+ case 1: /* Configuration */ -+ s->buf[s->len ++] = s->config; -+ break; -+ -+ case 2: /* T_LOW */ -+ s->buf[s->len ++] = ((uint16_t) s->limit[0]) >> 8; -+ s->buf[s->len ++] = ((uint16_t) s->limit[0]) >> 0; -+ break; -+ -+ case 3: /* T_HIGH */ -+ s->buf[s->len ++] = ((uint16_t) s->limit[1]) >> 8; -+ s->buf[s->len ++] = ((uint16_t) s->limit[1]) >> 0; -+ break; -+ } -+} -+ -+static void tmp105_write(struct tmp105_s *s) -+{ -+ switch (s->pointer & 3) { -+ case 0: /* Temperature */ -+ break; -+ -+ case 1: /* Configuration */ -+ if (s->buf[0] & ~s->config & (1 << 0)) /* SD */ -+ printf("%s: TMP105 shutdown\n", __FUNCTION__); -+ s->config = s->buf[0]; -+ s->faults = tmp105_faultq[(s->config >> 3) & 3]; /* F */ -+ tmp105_alarm_update(s); -+ break; -+ -+ case 2: /* T_LOW */ -+ case 3: /* T_HIGH */ -+ if (s->len >= 3) -+ s->limit[s->pointer & 1] = (int16_t) -+ ((((uint16_t) s->buf[0]) << 8) | s->buf[1]); -+ tmp105_alarm_update(s); -+ break; -+ } -+} -+ -+static int tmp105_rx(i2c_slave *i2c) -+{ -+ struct tmp105_s *s = (struct tmp105_s *) i2c; -+ -+ if (s->len < 2) -+ return s->buf[s->len ++]; -+ else -+ return 0xff; -+} -+ -+static int tmp105_tx(i2c_slave *i2c, uint8_t data) -+{ -+ struct tmp105_s *s = (struct tmp105_s *) i2c; -+ -+ if (!s->len ++) -+ s->pointer = data; -+ else { -+ if (s->len <= 2) -+ s->buf[s->len - 1] = data; -+ tmp105_write(s); -+ } -+ -+ return 0; -+} -+ -+static void tmp105_event(i2c_slave *i2c, enum i2c_event event) -+{ -+ struct tmp105_s *s = (struct tmp105_s *) i2c; -+ -+ if (event == I2C_START_RECV) -+ tmp105_read(s); -+ -+ s->len = 0; -+} -+ -+static void tmp105_save(QEMUFile *f, void *opaque) -+{ -+ struct tmp105_s *s = (struct tmp105_s *) opaque; -+ -+ qemu_put_byte(f, s->len); -+ qemu_put_8s(f, &s->buf[0]); -+ qemu_put_8s(f, &s->buf[1]); -+ -+ qemu_put_8s(f, &s->pointer); -+ qemu_put_8s(f, &s->config); -+ qemu_put_be16s(f, &s->temperature); -+ qemu_put_be16s(f, &s->limit[0]); -+ qemu_put_be16s(f, &s->limit[1]); -+ qemu_put_byte(f, s->alarm); -+ s->faults = tmp105_faultq[(s->config >> 3) & 3]; /* F */ -+ -+ i2c_slave_save(f, &s->i2c); -+} -+ -+static int tmp105_load(QEMUFile *f, void *opaque, int version_id) -+{ -+ struct tmp105_s *s = (struct tmp105_s *) opaque; -+ -+ s->len = qemu_get_byte(f); -+ qemu_get_8s(f, &s->buf[0]); -+ qemu_get_8s(f, &s->buf[1]); -+ -+ qemu_get_8s(f, &s->pointer); -+ qemu_get_8s(f, &s->config); -+ qemu_get_be16s(f, &s->temperature); -+ qemu_get_be16s(f, &s->limit[0]); -+ qemu_get_be16s(f, &s->limit[1]); -+ s->alarm = qemu_get_byte(f); -+ -+ tmp105_interrupt_update(s); -+ -+ i2c_slave_load(f, &s->i2c); -+ return 0; -+} -+ -+void tmp105_reset(i2c_slave *i2c) -+{ -+ struct tmp105_s *s = (struct tmp105_s *) i2c; -+ -+ s->temperature = 0; -+ s->pointer = 0; -+ s->config = 0; -+ s->faults = tmp105_faultq[(s->config >> 3) & 3]; -+ s->alarm = 0; -+ -+ tmp105_interrupt_update(s); -+} -+ -+static int tmp105_iid = 0; -+ -+struct i2c_slave *tmp105_init(i2c_bus *bus, qemu_irq alarm) -+{ -+ struct tmp105_s *s = (struct tmp105_s *) -+ i2c_slave_init(bus, 0, sizeof(struct tmp105_s)); -+ -+ s->i2c.event = tmp105_event; -+ s->i2c.recv = tmp105_rx; -+ s->i2c.send = tmp105_tx; -+ s->pin = alarm; -+ -+ tmp105_reset(&s->i2c); -+ -+ register_savevm("TMP105", tmp105_iid ++, 0, -+ tmp105_save, tmp105_load, s); -+ -+ return &s->i2c; -+} -diff --git a/hw/tsc210x.c b/hw/tsc210x.c -index 96956a4..1654b8b 100644 ---- a/hw/tsc210x.c -+++ b/hw/tsc210x.c -@@ -2,6 +2,7 @@ - * TI TSC2102 (touchscreen/sensors/audio controller) emulator. - * - * Copyright (c) 2006 Andrzej Zaborowski -+ * Copyright (C) 2008 Nokia Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as -@@ -35,12 +36,15 @@ - - struct tsc210x_state_s { - qemu_irq pint; -+ qemu_irq kbint; -+ qemu_irq davint; - QEMUTimer *timer; - QEMUSoundCard card; - struct uwire_slave_s chip; - struct i2s_codec_s codec; - uint8_t in_fifo[16384]; - uint8_t out_fifo[16384]; -+ uint16_t model; - - int x, y; - int pressure; -@@ -64,7 +68,7 @@ struct tsc210x_state_s { - uint16_t audio_ctrl1; - uint16_t audio_ctrl2; - uint16_t audio_ctrl3; -- uint16_t pll[2]; -+ uint16_t pll[3]; - uint16_t volume; - int64_t volume_change; - int softstep; -@@ -78,6 +82,17 @@ struct tsc210x_state_s { - int i2s_rx_rate; - int i2s_tx_rate; - AudioState *audio; -+ -+ int tr[8]; -+ -+ struct { -+ uint16_t down; -+ uint16_t mask; -+ int scan; -+ int debounce; -+ int mode; -+ int intr; -+ } kb; - }; - - static const int resolution[4] = { 12, 8, 10, 12 }; -@@ -118,17 +133,10 @@ static const uint16_t mode_regs[16] = { - 0x0000, /* Y+, X- drivers */ - }; - --/* -- * Convert screen coordinates to arbitrary values that the -- * touchscreen in my Palm Tungsten E device returns. -- * This shouldn't really matter (because the guest system -- * should calibrate the touchscreen anyway), but let's -- * imitate some real hardware. -- */ --#define X_TRANSFORM(value) \ -- ((3850 - ((int) (value) * (3850 - 250) / 32768)) << 4) --#define Y_TRANSFORM(value) \ -- ((150 + ((int) (value) * (3037 - 150) / 32768)) << 4) -+#define X_TRANSFORM(s) \ -+ ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3]) -+#define Y_TRANSFORM(s) \ -+ ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7]) - #define Z1_TRANSFORM(s) \ - ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4) - #define Z2_TRANSFORM(s) \ -@@ -161,6 +169,7 @@ static void tsc210x_reset(struct tsc210x_state_s *s) - s->audio_ctrl3 = 0x0000; - s->pll[0] = 0x1004; - s->pll[1] = 0x0000; -+ s->pll[2] = 0x1fff; - s->volume = 0xffff; - s->dac_power = 0x8540; - s->softstep = 1; -@@ -190,7 +199,15 @@ static void tsc210x_reset(struct tsc210x_state_s *s) - s->i2s_tx_rate = 0; - s->i2s_rx_rate = 0; - -+ s->kb.scan = 1; -+ s->kb.debounce = 0; -+ s->kb.mask = 0x0000; -+ s->kb.mode = 3; -+ s->kb.intr = 0; -+ - qemu_set_irq(s->pint, !s->irq); -+ qemu_set_irq(s->davint, !s->dav); -+ qemu_irq_raise(s->kbint); - } - - struct tsc210x_rate_info_s { -@@ -344,13 +361,13 @@ static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg) - switch (reg) { - case 0x00: /* X */ - s->dav &= 0xfbff; -- return TSC_CUT_RESOLUTION(X_TRANSFORM(s->x), s->precision) + -+ return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) + - (s->noise & 3); - - case 0x01: /* Y */ - s->noise ++; - s->dav &= 0xfdff; -- return TSC_CUT_RESOLUTION(Y_TRANSFORM(s->y), s->precision) ^ -+ return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^ - (s->noise & 3); - - case 0x02: /* Z1 */ -@@ -364,6 +381,14 @@ static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg) - (s->noise & 3); - - case 0x04: /* KPData */ -+ if ((s->model & 0xff00) == 0x2300) { -+ if (s->kb.intr && (s->kb.mode & 2)) { -+ s->kb.intr = 0; -+ qemu_irq_raise(s->kbint); -+ } -+ return s->kb.down; -+ } -+ - return 0xffff; - - case 0x05: /* BAT1 */ -@@ -414,9 +439,19 @@ static uint16_t tsc2102_control_register_read( - return (s->pressure << 15) | ((!s->busy) << 14) | - (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter; - -- case 0x01: /* Status */ -- return (s->pin_func << 14) | ((!s->enabled) << 13) | -- (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav; -+ case 0x01: /* Status / Keypad Control */ -+ if ((s->model & 0xff00) == 0x2100) -+ return (s->pin_func << 14) | ((!s->enabled) << 13) | -+ (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav; -+ else -+ return (s->kb.intr << 15) | ((s->kb.scan || !s->kb.down) << 14) | -+ (s->kb.debounce << 11); -+ -+ case 0x02: /* DAC Control */ -+ if ((s->model & 0xff00) == 0x2300) -+ return s->dac_power & 0x8000; -+ else -+ goto bad_reg; - - case 0x03: /* Reference */ - return s->ref; -@@ -427,7 +462,18 @@ static uint16_t tsc2102_control_register_read( - case 0x05: /* Configuration */ - return s->timing; - -+ case 0x06: /* Secondary configuration */ -+ if ((s->model & 0xff00) == 0x2100) -+ goto bad_reg; -+ return ((!s->dav) << 15) | ((s->kb.mode & 1) << 14) | s->pll[2]; -+ -+ case 0x10: /* Keypad Mask */ -+ if ((s->model & 0xff00) == 0x2100) -+ goto bad_reg; -+ return s->kb.mask; -+ - default: -+ bad_reg: - #ifdef TSC_VERBOSE - fprintf(stderr, "tsc2102_control_register_read: " - "no such register: 0x%02x\n", reg); -@@ -556,10 +602,27 @@ static void tsc2102_control_register_write( - s->filter = value & 0xff; - return; - -- case 0x01: /* Status */ -- s->pin_func = value >> 14; -+ case 0x01: /* Status / Keypad Control */ -+ if ((s->model & 0xff00) == 0x2100) -+ s->pin_func = value >> 14; -+ else { -+ s->kb.scan = (value >> 14) & 1; -+ s->kb.debounce = (value >> 11) & 7; -+ if (s->kb.intr && s->kb.scan) { -+ s->kb.intr = 0; -+ qemu_irq_raise(s->kbint); -+ } -+ } - return; - -+ case 0x02: /* DAC Control */ -+ if ((s->model & 0xff00) == 0x2300) { -+ s->dac_power &= 0x7fff; -+ s->dac_power |= 0x8000 & value; -+ } else -+ goto bad_reg; -+ break; -+ - case 0x03: /* Reference */ - s->ref = value & 0x1f; - return; -@@ -586,7 +649,21 @@ static void tsc2102_control_register_write( - #endif - return; - -+ case 0x06: /* Secondary configuration */ -+ if ((s->model & 0xff00) == 0x2100) -+ goto bad_reg; -+ s->kb.mode = value >> 14; -+ s->pll[2] = value & 0x3ffff; -+ return; -+ -+ case 0x10: /* Keypad Mask */ -+ if ((s->model & 0xff00) == 0x2100) -+ goto bad_reg; -+ s->kb.mask = value; -+ return; -+ - default: -+ bad_reg: - #ifdef TSC_VERBOSE - fprintf(stderr, "tsc2102_control_register_write: " - "no such register: 0x%02x\n", reg); -@@ -785,7 +862,7 @@ static void tsc210x_pin_update(struct tsc210x_state_s *s) - return; - } - -- if (!s->enabled || s->busy) -+ if (!s->enabled || s->busy || s->dav) - return; - - s->busy = 1; -@@ -805,6 +882,8 @@ static uint16_t tsc210x_read(struct tsc210x_state_s *s) - switch (s->page) { - case TSC_DATA_REGISTERS_PAGE: - ret = tsc2102_data_register_read(s, s->offset); -+ if (!s->dav) -+ qemu_irq_raise(s->davint); - break; - case TSC_CONTROL_REGISTERS_PAGE: - ret = tsc2102_control_register_read(s, s->offset); -@@ -859,6 +938,22 @@ static void tsc210x_write(struct tsc210x_state_s *s, uint16_t value) - } - } - -+uint32_t tsc210x_txrx(void *opaque, uint32_t value) -+{ -+ struct tsc210x_state_s *s = opaque; -+ uint32_t ret = 0; -+ -+ /* TODO: sequential reads etc - how do we make sure the host doesn't -+ * unintentionally read out a conversion result from a register while -+ * transmitting the command word of the next command? */ -+ if (!value || (s->state && s->command)) -+ ret = tsc210x_read(s); -+ if (value || (s->state && !s->command)) -+ tsc210x_write(s, value); -+ -+ return ret; -+} -+ - static void tsc210x_timer_tick(void *opaque) - { - struct tsc210x_state_s *s = opaque; -@@ -871,6 +966,7 @@ static void tsc210x_timer_tick(void *opaque) - s->busy = 0; - s->dav |= mode_regs[s->function]; - tsc210x_pin_update(s); -+ qemu_irq_lower(s->davint); - } - - static void tsc210x_touchscreen_event(void *opaque, -@@ -1001,6 +1097,7 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id) - - s->busy = qemu_timer_pending(s->timer); - qemu_set_irq(s->pint, !s->irq); -+ qemu_set_irq(s->davint, !s->dav); - - return 0; - } -@@ -1020,9 +1117,19 @@ struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio) - s->precision = s->nextprecision = 0; - s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s); - s->pint = pint; -+ s->model = 0x2102; - s->name = "tsc2102"; - s->audio = audio; - -+ s->tr[0] = 0; -+ s->tr[1] = 1; -+ s->tr[2] = 0; -+ s->tr[3] = 1; -+ s->tr[4] = 1; -+ s->tr[5] = 0; -+ s->tr[6] = 0; -+ s->tr[7] = 1; -+ - s->chip.opaque = s; - s->chip.send = (void *) tsc210x_write; - s->chip.receive = (void *) tsc210x_read; -@@ -1048,9 +1155,147 @@ struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio) - return &s->chip; - } - -+struct uwire_slave_s *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, -+ qemu_irq dav, AudioState *audio) -+{ -+ struct tsc210x_state_s *s; -+ -+ s = (struct tsc210x_state_s *) -+ qemu_mallocz(sizeof(struct tsc210x_state_s)); -+ memset(s, 0, sizeof(struct tsc210x_state_s)); -+ s->x = 400; -+ s->y = 240; -+ s->pressure = 0; -+ s->precision = s->nextprecision = 0; -+ s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s); -+ s->pint = penirq; -+ s->kbint = kbirq; -+ s->davint = dav; -+ s->model = 0x2301; -+ s->name = "tsc2301"; -+ s->audio = audio; -+ -+ s->tr[0] = 0; -+ s->tr[1] = 1; -+ s->tr[2] = 0; -+ s->tr[3] = 1; -+ s->tr[4] = 1; -+ s->tr[5] = 0; -+ s->tr[6] = 0; -+ s->tr[7] = 1; -+ -+ s->chip.opaque = s; -+ s->chip.send = (void *) tsc210x_write; -+ s->chip.receive = (void *) tsc210x_read; -+ -+ s->codec.opaque = s; -+ s->codec.tx_swallow = (void *) tsc210x_i2s_swallow; -+ s->codec.set_rate = (void *) tsc210x_i2s_set_rate; -+ s->codec.in.fifo = s->in_fifo; -+ s->codec.out.fifo = s->out_fifo; -+ -+ tsc210x_reset(s); -+ -+ qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1, -+ "QEMU TSC2301-driven Touchscreen"); -+ -+ if (s->audio) -+ AUD_register_card(s->audio, s->name, &s->card); -+ -+ qemu_register_reset((void *) tsc210x_reset, s); -+ register_savevm(s->name, tsc2102_iid ++, 0, -+ tsc210x_save, tsc210x_load, s); -+ -+ return &s->chip; -+} -+ - struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip) - { - struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque; - - return &s->codec; - } -+ -+/* -+ * Use tslib generated calibration data to generate ADC input values -+ * from the touchscreen. Assuming 12-bit precision was used during -+ * tslib calibration. -+ */ -+void tsc210x_set_transform(struct uwire_slave_s *chip, -+ struct mouse_transform_info_s *info) -+{ -+ struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque; -+#if 0 -+ int64_t ltr[8]; -+ -+ ltr[0] = (int64_t) info->a[1] * info->y; -+ ltr[1] = (int64_t) info->a[4] * info->x; -+ ltr[2] = (int64_t) info->a[1] * info->a[3] - -+ (int64_t) info->a[4] * info->a[0]; -+ ltr[3] = (int64_t) info->a[2] * info->a[4] - -+ (int64_t) info->a[5] * info->a[1]; -+ ltr[4] = (int64_t) info->a[0] * info->y; -+ ltr[5] = (int64_t) info->a[3] * info->x; -+ ltr[6] = (int64_t) info->a[4] * info->a[0] - -+ (int64_t) info->a[1] * info->a[3]; -+ ltr[7] = (int64_t) info->a[2] * info->a[3] - -+ (int64_t) info->a[5] * info->a[0]; -+ -+ /* Avoid integer overflow */ -+ s->tr[0] = ltr[0] >> 11; -+ s->tr[1] = ltr[1] >> 11; -+ s->tr[2] = muldiv64(ltr[2], 1, info->a[6]); -+ s->tr[3] = muldiv64(ltr[3], 1 << 4, ltr[2]); -+ s->tr[4] = ltr[4] >> 11; -+ s->tr[5] = ltr[5] >> 11; -+ s->tr[6] = muldiv64(ltr[6], 1, info->a[6]); -+ s->tr[7] = muldiv64(ltr[7], 1 << 4, ltr[6]); -+#else -+ -+ if (abs(info->a[0]) > abs(info->a[1])) { -+ s->tr[0] = 0; -+ s->tr[1] = -info->a[6] * info->x; -+ s->tr[2] = info->a[0]; -+ s->tr[3] = -info->a[2] / info->a[0]; -+ s->tr[4] = info->a[6] * info->y; -+ s->tr[5] = 0; -+ s->tr[6] = info->a[4]; -+ s->tr[7] = -info->a[5] / info->a[4]; -+ } else { -+ s->tr[0] = info->a[6] * info->y; -+ s->tr[1] = 0; -+ s->tr[2] = info->a[1]; -+ s->tr[3] = -info->a[2] / info->a[1]; -+ s->tr[4] = 0; -+ s->tr[5] = -info->a[6] * info->x; -+ s->tr[6] = info->a[3]; -+ s->tr[7] = -info->a[5] / info->a[3]; -+ } -+ -+ s->tr[0] >>= 11; -+ s->tr[1] >>= 11; -+ s->tr[3] <<= 4; -+ s->tr[4] >>= 11; -+ s->tr[5] >>= 11; -+ s->tr[7] <<= 4; -+#endif -+} -+ -+void tsc210x_key_event(struct uwire_slave_s *chip, int key, int down) -+{ -+ struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque; -+ -+ if (down) -+ s->kb.down |= 1 << key; -+ else -+ s->kb.down &= ~(1 << key); -+ -+ if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) { -+ s->kb.intr = 1; -+ qemu_irq_lower(s->kbint); -+ } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) && -+ !(s->kb.mode & 1)) { -+ s->kb.intr = 0; -+ qemu_irq_raise(s->kbint); -+ } -+} -diff --git a/hw/twl92230.c b/hw/twl92230.c -new file mode 100644 -index 0000000..11a5d1a ---- /dev/null -+++ b/hw/twl92230.c -@@ -0,0 +1,923 @@ -+/* -+ * TI TWL92230C energy-management companion device for the OMAP24xx. -+ * Aka. Menelaus (N4200 MENELAUS1_V2.2) -+ * -+ * Copyright (C) 2008 Nokia Corporation -+ * Written by Andrzej Zaborowski -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, -+ * MA 02111-1307 USA -+ */ -+ -+#include "hw.h" -+#include "qemu-timer.h" -+#include "i2c.h" -+#include "sysemu.h" -+#include "console.h" -+ -+#define VERBOSE 1 -+ -+struct menelaus_s { -+ i2c_slave i2c; -+ qemu_irq irq; -+ -+ int firstbyte; -+ uint8_t reg; -+ -+ uint8_t vcore[5]; -+ uint8_t dcdc[3]; -+ uint8_t ldo[8]; -+ uint8_t sleep[2]; -+ uint8_t osc; -+ uint8_t detect; -+ uint16_t mask; -+ uint16_t status; -+ uint8_t dir; -+ uint8_t inputs; -+ uint8_t outputs; -+ uint8_t bbsms; -+ uint8_t pull[4]; -+ uint8_t mmc_ctrl[3]; -+ uint8_t mmc_debounce; -+ struct { -+ uint8_t ctrl; -+ uint16_t comp; -+ QEMUTimer *hz; -+ int64_t next; -+ struct tm tm; -+ struct tm new; -+ struct tm alm; -+ time_t sec; -+ time_t alm_sec; -+ time_t next_comp; -+ struct tm *(*gettime)(const time_t *timep, struct tm *result); -+ } rtc; -+ qemu_irq handler[3]; -+ qemu_irq *in; -+ int pwrbtn_state; -+ qemu_irq pwrbtn; -+}; -+ -+static inline void menelaus_update(struct menelaus_s *s) -+{ -+ qemu_set_irq(s->irq, s->status & ~s->mask); -+} -+ -+static inline void menelaus_rtc_start(struct menelaus_s *s) -+{ -+ s->rtc.next =+ qemu_get_clock(rt_clock); -+ qemu_mod_timer(s->rtc.hz, s->rtc.next); -+} -+ -+static inline void menelaus_rtc_stop(struct menelaus_s *s) -+{ -+ qemu_del_timer(s->rtc.hz); -+ s->rtc.next =- qemu_get_clock(rt_clock); -+ if (s->rtc.next < 1) -+ s->rtc.next = 1; -+} -+ -+static void menelaus_rtc_update(struct menelaus_s *s) -+{ -+ s->rtc.gettime(&s->rtc.sec, &s->rtc.tm); -+} -+ -+static void menelaus_alm_update(struct menelaus_s *s) -+{ -+ if ((s->rtc.ctrl & 3) == 3) -+ s->rtc.alm_sec = mktime(&s->rtc.alm); -+} -+ -+static void menelaus_rtc_hz(void *opaque) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) opaque; -+ -+ s->rtc.sec ++; -+ s->rtc.next += 1000; -+ qemu_mod_timer(s->rtc.hz, s->rtc.next); -+ if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */ -+ menelaus_rtc_update(s); -+ if (((s->rtc.ctrl >> 3) & 3) == 1 && !s->rtc.tm.tm_sec) -+ s->status |= 1 << 8; /* RTCTMR */ -+ else if (((s->rtc.ctrl >> 3) & 3) == 2 && !s->rtc.tm.tm_min) -+ s->status |= 1 << 8; /* RTCTMR */ -+ else if (!s->rtc.tm.tm_hour) -+ s->status |= 1 << 8; /* RTCTMR */ -+ } else -+ s->status |= 1 << 8; /* RTCTMR */ -+ if ((s->rtc.ctrl >> 1) & 1) { /* RTC_AL_EN */ -+ if (s->rtc.sec == s->rtc.alm_sec) -+ s->status |= 1 << 9; /* RTCALM */ -+ /* TODO: wake-up */ -+ } -+ if (s->rtc.next_comp >= s->rtc.sec) { -+ s->rtc.next -= muldiv64((int16_t) s->rtc.comp, 1000, 0x8000); -+ s->rtc.next_comp = s->rtc.sec + 3600; -+ } -+ menelaus_update(s); -+} -+ -+void menelaus_reset(i2c_slave *i2c) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) i2c; -+ time_t ti; -+ s->reg = 0x00; -+ -+ s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */ -+ s->vcore[1] = 0x05; -+ s->vcore[2] = 0x02; -+ s->vcore[3] = 0x0c; -+ s->vcore[4] = 0x03; -+ s->dcdc[0] = 0x33; /* Depends on wiring */ -+ s->dcdc[1] = 0x03; -+ s->dcdc[2] = 0x00; -+ s->ldo[0] = 0x95; -+ s->ldo[1] = 0x7e; -+ s->ldo[2] = 0x00; -+ s->ldo[3] = 0x00; /* Depends on wiring */ -+ s->ldo[4] = 0x03; /* Depends on wiring */ -+ s->ldo[5] = 0x00; -+ s->ldo[6] = 0x00; -+ s->ldo[7] = 0x00; -+ s->sleep[0] = 0x00; -+ s->sleep[1] = 0x00; -+ s->osc = 0x01; -+ s->detect = 0x09; -+ s->mask = 0x0fff; -+ s->status = 0; -+ s->dir = 0x07; -+ s->outputs = 0x00; -+ s->bbsms = 0x00; -+ s->pull[0] = 0x00; -+ s->pull[1] = 0x00; -+ s->pull[2] = 0x00; -+ s->pull[3] = 0x00; -+ s->mmc_ctrl[0] = 0x03; -+ s->mmc_ctrl[1] = 0xc0; -+ s->mmc_ctrl[2] = 0x00; -+ s->mmc_debounce = 0x05; -+ -+ time(&ti); -+ if (s->rtc.ctrl & 1) -+ menelaus_rtc_stop(s); -+ s->rtc.ctrl = 0x00; -+ s->rtc.comp = 0x0000; -+ s->rtc.next = 1000; -+ s->rtc.sec = ti; -+ s->rtc.next_comp = s->rtc.sec + 1800; -+ s->rtc.alm.tm_sec = 0x00; -+ s->rtc.alm.tm_min = 0x00; -+ s->rtc.alm.tm_hour = 0x00; -+ s->rtc.alm.tm_mday = 0x01; -+ s->rtc.alm.tm_mon = 0x00; -+ s->rtc.alm.tm_year = 2004; -+ menelaus_update(s); -+} -+ -+static inline uint8_t to_bcd(int val) -+{ -+ return ((val / 10) << 4) | (val % 10); -+} -+ -+static inline int from_bcd(uint8_t val) -+{ -+ return ((val >> 4) * 10) + (val & 0x0f); -+} -+ -+static void menelaus_gpio_set(void *opaque, int line, int level) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) opaque; -+ -+ /* No interrupt generated */ -+ s->inputs &= ~(1 << line); -+ s->inputs |= level << line; -+} -+ -+static void menelaus_pwrbtn_set(void *opaque, int line, int level) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) opaque; -+ -+ if (!s->pwrbtn_state && level) { -+ s->status |= 1 << 11; /* PSHBTN */ -+ menelaus_update(s); -+ } -+ s->pwrbtn_state = level; -+} -+ -+#define MENELAUS_REV 0x01 -+#define MENELAUS_VCORE_CTRL1 0x02 -+#define MENELAUS_VCORE_CTRL2 0x03 -+#define MENELAUS_VCORE_CTRL3 0x04 -+#define MENELAUS_VCORE_CTRL4 0x05 -+#define MENELAUS_VCORE_CTRL5 0x06 -+#define MENELAUS_DCDC_CTRL1 0x07 -+#define MENELAUS_DCDC_CTRL2 0x08 -+#define MENELAUS_DCDC_CTRL3 0x09 -+#define MENELAUS_LDO_CTRL1 0x0a -+#define MENELAUS_LDO_CTRL2 0x0b -+#define MENELAUS_LDO_CTRL3 0x0c -+#define MENELAUS_LDO_CTRL4 0x0d -+#define MENELAUS_LDO_CTRL5 0x0e -+#define MENELAUS_LDO_CTRL6 0x0f -+#define MENELAUS_LDO_CTRL7 0x10 -+#define MENELAUS_LDO_CTRL8 0x11 -+#define MENELAUS_SLEEP_CTRL1 0x12 -+#define MENELAUS_SLEEP_CTRL2 0x13 -+#define MENELAUS_DEVICE_OFF 0x14 -+#define MENELAUS_OSC_CTRL 0x15 -+#define MENELAUS_DETECT_CTRL 0x16 -+#define MENELAUS_INT_MASK1 0x17 -+#define MENELAUS_INT_MASK2 0x18 -+#define MENELAUS_INT_STATUS1 0x19 -+#define MENELAUS_INT_STATUS2 0x1a -+#define MENELAUS_INT_ACK1 0x1b -+#define MENELAUS_INT_ACK2 0x1c -+#define MENELAUS_GPIO_CTRL 0x1d -+#define MENELAUS_GPIO_IN 0x1e -+#define MENELAUS_GPIO_OUT 0x1f -+#define MENELAUS_BBSMS 0x20 -+#define MENELAUS_RTC_CTRL 0x21 -+#define MENELAUS_RTC_UPDATE 0x22 -+#define MENELAUS_RTC_SEC 0x23 -+#define MENELAUS_RTC_MIN 0x24 -+#define MENELAUS_RTC_HR 0x25 -+#define MENELAUS_RTC_DAY 0x26 -+#define MENELAUS_RTC_MON 0x27 -+#define MENELAUS_RTC_YR 0x28 -+#define MENELAUS_RTC_WKDAY 0x29 -+#define MENELAUS_RTC_AL_SEC 0x2a -+#define MENELAUS_RTC_AL_MIN 0x2b -+#define MENELAUS_RTC_AL_HR 0x2c -+#define MENELAUS_RTC_AL_DAY 0x2d -+#define MENELAUS_RTC_AL_MON 0x2e -+#define MENELAUS_RTC_AL_YR 0x2f -+#define MENELAUS_RTC_COMP_MSB 0x30 -+#define MENELAUS_RTC_COMP_LSB 0x31 -+#define MENELAUS_S1_PULL_EN 0x32 -+#define MENELAUS_S1_PULL_DIR 0x33 -+#define MENELAUS_S2_PULL_EN 0x34 -+#define MENELAUS_S2_PULL_DIR 0x35 -+#define MENELAUS_MCT_CTRL1 0x36 -+#define MENELAUS_MCT_CTRL2 0x37 -+#define MENELAUS_MCT_CTRL3 0x38 -+#define MENELAUS_MCT_PIN_ST 0x39 -+#define MENELAUS_DEBOUNCE1 0x3a -+ -+static uint8_t menelaus_read(void *opaque, uint8_t addr) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) opaque; -+ int reg = 0; -+ -+ switch (addr) { -+ case MENELAUS_REV: -+ return 0x22; -+ -+ case MENELAUS_VCORE_CTRL5: reg ++; -+ case MENELAUS_VCORE_CTRL4: reg ++; -+ case MENELAUS_VCORE_CTRL3: reg ++; -+ case MENELAUS_VCORE_CTRL2: reg ++; -+ case MENELAUS_VCORE_CTRL1: -+ return s->vcore[reg]; -+ -+ case MENELAUS_DCDC_CTRL3: reg ++; -+ case MENELAUS_DCDC_CTRL2: reg ++; -+ case MENELAUS_DCDC_CTRL1: -+ return s->dcdc[reg]; -+ -+ case MENELAUS_LDO_CTRL8: reg ++; -+ case MENELAUS_LDO_CTRL7: reg ++; -+ case MENELAUS_LDO_CTRL6: reg ++; -+ case MENELAUS_LDO_CTRL5: reg ++; -+ case MENELAUS_LDO_CTRL4: reg ++; -+ case MENELAUS_LDO_CTRL3: reg ++; -+ case MENELAUS_LDO_CTRL2: reg ++; -+ case MENELAUS_LDO_CTRL1: -+ return s->ldo[reg]; -+ -+ case MENELAUS_SLEEP_CTRL2: reg ++; -+ case MENELAUS_SLEEP_CTRL1: -+ return s->sleep[reg]; -+ -+ case MENELAUS_DEVICE_OFF: -+ return 0; -+ -+ case MENELAUS_OSC_CTRL: -+ return s->osc | (1 << 7); /* CLK32K_GOOD */ -+ -+ case MENELAUS_DETECT_CTRL: -+ return s->detect; -+ -+ case MENELAUS_INT_MASK1: -+ return (s->mask >> 0) & 0xff; -+ case MENELAUS_INT_MASK2: -+ return (s->mask >> 8) & 0xff; -+ -+ case MENELAUS_INT_STATUS1: -+ return (s->status >> 0) & 0xff; -+ case MENELAUS_INT_STATUS2: -+ return (s->status >> 8) & 0xff; -+ -+ case MENELAUS_INT_ACK1: -+ case MENELAUS_INT_ACK2: -+ return 0; -+ -+ case MENELAUS_GPIO_CTRL: -+ return s->dir; -+ case MENELAUS_GPIO_IN: -+ return s->inputs | (~s->dir & s->outputs); -+ case MENELAUS_GPIO_OUT: -+ return s->outputs; -+ -+ case MENELAUS_BBSMS: -+ return s->bbsms; -+ -+ case MENELAUS_RTC_CTRL: -+ return s->rtc.ctrl; -+ case MENELAUS_RTC_UPDATE: -+ return 0x00; -+ case MENELAUS_RTC_SEC: -+ menelaus_rtc_update(s); -+ return to_bcd(s->rtc.tm.tm_sec); -+ case MENELAUS_RTC_MIN: -+ menelaus_rtc_update(s); -+ return to_bcd(s->rtc.tm.tm_min); -+ case MENELAUS_RTC_HR: -+ menelaus_rtc_update(s); -+ if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */ -+ return to_bcd((s->rtc.tm.tm_hour % 12) + 1) | -+ (!!(s->rtc.tm.tm_hour >= 12) << 7); /* PM_nAM */ -+ else -+ return to_bcd(s->rtc.tm.tm_hour); -+ case MENELAUS_RTC_DAY: -+ menelaus_rtc_update(s); -+ return to_bcd(s->rtc.tm.tm_mday); -+ case MENELAUS_RTC_MON: -+ menelaus_rtc_update(s); -+ return to_bcd(s->rtc.tm.tm_mon + 1); -+ case MENELAUS_RTC_YR: -+ menelaus_rtc_update(s); -+ return to_bcd(s->rtc.tm.tm_year - 2000); -+ case MENELAUS_RTC_WKDAY: -+ menelaus_rtc_update(s); -+ return to_bcd(s->rtc.tm.tm_wday); -+ case MENELAUS_RTC_AL_SEC: -+ return to_bcd(s->rtc.alm.tm_sec); -+ case MENELAUS_RTC_AL_MIN: -+ return to_bcd(s->rtc.alm.tm_min); -+ case MENELAUS_RTC_AL_HR: -+ if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */ -+ return to_bcd((s->rtc.alm.tm_hour % 12) + 1) | -+ (!!(s->rtc.alm.tm_hour >= 12) << 7);/* AL_PM_nAM */ -+ else -+ return to_bcd(s->rtc.alm.tm_hour); -+ case MENELAUS_RTC_AL_DAY: -+ return to_bcd(s->rtc.alm.tm_mday); -+ case MENELAUS_RTC_AL_MON: -+ return to_bcd(s->rtc.alm.tm_mon + 1); -+ case MENELAUS_RTC_AL_YR: -+ return to_bcd(s->rtc.alm.tm_year - 2000); -+ case MENELAUS_RTC_COMP_MSB: -+ return (s->rtc.comp >> 8) & 0xff; -+ case MENELAUS_RTC_COMP_LSB: -+ return (s->rtc.comp >> 0) & 0xff; -+ -+ case MENELAUS_S1_PULL_EN: -+ return s->pull[0]; -+ case MENELAUS_S1_PULL_DIR: -+ return s->pull[1]; -+ case MENELAUS_S2_PULL_EN: -+ return s->pull[2]; -+ case MENELAUS_S2_PULL_DIR: -+ return s->pull[3]; -+ -+ case MENELAUS_MCT_CTRL3: reg ++; -+ case MENELAUS_MCT_CTRL2: reg ++; -+ case MENELAUS_MCT_CTRL1: -+ return s->mmc_ctrl[reg]; -+ case MENELAUS_MCT_PIN_ST: -+ /* TODO: return the real Card Detect */ -+ return 0; -+ case MENELAUS_DEBOUNCE1: -+ return s->mmc_debounce; -+ -+ default: -+#ifdef VERBOSE -+ printf("%s: unknown register %02x\n", __FUNCTION__, addr); -+#endif -+ break; -+ } -+ return 0; -+} -+ -+static void menelaus_write(void *opaque, uint8_t addr, uint8_t value) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) opaque; -+ int line; -+ int reg = 0; -+ struct tm tm; -+ -+ switch (addr) { -+ case MENELAUS_VCORE_CTRL1: -+ s->vcore[0] = (value & 0xe) | MIN(value & 0x1f, 0x12); -+ break; -+ case MENELAUS_VCORE_CTRL2: -+ s->vcore[1] = value; -+ break; -+ case MENELAUS_VCORE_CTRL3: -+ s->vcore[2] = MIN(value & 0x1f, 0x12); -+ break; -+ case MENELAUS_VCORE_CTRL4: -+ s->vcore[3] = MIN(value & 0x1f, 0x12); -+ break; -+ case MENELAUS_VCORE_CTRL5: -+ s->vcore[4] = value & 3; -+ /* XXX -+ * auto set to 3 on M_Active, nRESWARM -+ * auto set to 0 on M_WaitOn, M_Backup -+ */ -+ break; -+ -+ case MENELAUS_DCDC_CTRL1: -+ s->dcdc[0] = value & 0x3f; -+ break; -+ case MENELAUS_DCDC_CTRL2: -+ s->dcdc[1] = value & 0x07; -+ /* XXX -+ * auto set to 3 on M_Active, nRESWARM -+ * auto set to 0 on M_WaitOn, M_Backup -+ */ -+ break; -+ case MENELAUS_DCDC_CTRL3: -+ s->dcdc[2] = value & 0x07; -+ break; -+ -+ case MENELAUS_LDO_CTRL1: -+ s->ldo[0] = value; -+ break; -+ case MENELAUS_LDO_CTRL2: -+ s->ldo[1] = value & 0x7f; -+ /* XXX -+ * auto set to 0x7e on M_WaitOn, M_Backup -+ */ -+ break; -+ case MENELAUS_LDO_CTRL3: -+ s->ldo[2] = value & 3; -+ /* XXX -+ * auto set to 3 on M_Active, nRESWARM -+ * auto set to 0 on M_WaitOn, M_Backup -+ */ -+ break; -+ case MENELAUS_LDO_CTRL4: -+ s->ldo[3] = value & 3; -+ /* XXX -+ * auto set to 3 on M_Active, nRESWARM -+ * auto set to 0 on M_WaitOn, M_Backup -+ */ -+ break; -+ case MENELAUS_LDO_CTRL5: -+ s->ldo[4] = value & 3; -+ /* XXX -+ * auto set to 3 on M_Active, nRESWARM -+ * auto set to 0 on M_WaitOn, M_Backup -+ */ -+ break; -+ case MENELAUS_LDO_CTRL6: -+ s->ldo[5] = value & 3; -+ break; -+ case MENELAUS_LDO_CTRL7: -+ s->ldo[6] = value & 3; -+ break; -+ case MENELAUS_LDO_CTRL8: -+ s->ldo[7] = value & 3; -+ break; -+ -+ case MENELAUS_SLEEP_CTRL2: reg ++; -+ case MENELAUS_SLEEP_CTRL1: -+ s->sleep[reg] = value; -+ break; -+ -+ case MENELAUS_DEVICE_OFF: -+ if (value & 1) -+ menelaus_reset(&s->i2c); -+ break; -+ -+ case MENELAUS_OSC_CTRL: -+ s->osc = value & 7; -+ break; -+ -+ case MENELAUS_DETECT_CTRL: -+ s->detect = value & 0x7f; -+ break; -+ -+ case MENELAUS_INT_MASK1: -+ s->mask &= 0xf00; -+ s->mask |= value << 0; -+ menelaus_update(s); -+ break; -+ case MENELAUS_INT_MASK2: -+ s->mask &= 0x0ff; -+ s->mask |= value << 8; -+ menelaus_update(s); -+ break; -+ -+ case MENELAUS_INT_ACK1: -+ s->status &= ~(((uint16_t) value) << 0); -+ menelaus_update(s); -+ break; -+ case MENELAUS_INT_ACK2: -+ s->status &= ~(((uint16_t) value) << 8); -+ menelaus_update(s); -+ break; -+ -+ case MENELAUS_GPIO_CTRL: -+ for (line = 0; line < 3; line ++) -+ if (((s->dir ^ value) >> line) & 1) -+ if (s->handler[line]) -+ qemu_set_irq(s->handler[line], -+ ((s->outputs & ~s->dir) >> line) & 1); -+ s->dir = value & 0x67; -+ break; -+ case MENELAUS_GPIO_OUT: -+ for (line = 0; line < 3; line ++) -+ if ((((s->outputs ^ value) & ~s->dir) >> line) & 1) -+ if (s->handler[line]) -+ qemu_set_irq(s->handler[line], (s->outputs >> line) & 1); -+ s->outputs = value & 0x07; -+ break; -+ -+ case MENELAUS_BBSMS: -+ s->bbsms = 0x0d; -+ break; -+ -+ case MENELAUS_RTC_CTRL: -+ if ((s->rtc.ctrl ^ value) & 1) { /* RTC_EN */ -+ if (value & 1) -+ menelaus_rtc_start(s); -+ else -+ menelaus_rtc_stop(s); -+ } -+ s->rtc.ctrl = value & 0x1f; -+ menelaus_alm_update(s); -+ break; -+ case MENELAUS_RTC_UPDATE: -+ menelaus_rtc_update(s); -+ memcpy(&tm, &s->rtc.tm, sizeof(tm)); -+ switch (value & 0xf) { -+ case 0: -+ break; -+ case 1: -+ tm.tm_sec = s->rtc.new.tm_sec; -+ break; -+ case 2: -+ tm.tm_min = s->rtc.new.tm_min; -+ break; -+ case 3: -+ if (s->rtc.new.tm_hour > 23) -+ goto rtc_badness; -+ tm.tm_hour = s->rtc.new.tm_hour; -+ break; -+ case 4: -+ if (s->rtc.new.tm_mday < 1) -+ goto rtc_badness; -+ /* TODO check range */ -+ tm.tm_mday = s->rtc.new.tm_mday; -+ break; -+ case 5: -+ if (s->rtc.new.tm_mon < 0 || s->rtc.new.tm_mon > 11) -+ goto rtc_badness; -+ tm.tm_mon = s->rtc.new.tm_mon; -+ break; -+ case 6: -+ tm.tm_year = s->rtc.new.tm_year; -+ break; -+ case 7: -+ /* TODO set .tm_mday instead */ -+ tm.tm_wday = s->rtc.new.tm_wday; -+ break; -+ case 8: -+ if (s->rtc.new.tm_hour > 23) -+ goto rtc_badness; -+ if (s->rtc.new.tm_mday < 1) -+ goto rtc_badness; -+ if (s->rtc.new.tm_mon < 0 || s->rtc.new.tm_mon > 11) -+ goto rtc_badness; -+ tm.tm_sec = s->rtc.new.tm_sec; -+ tm.tm_min = s->rtc.new.tm_min; -+ tm.tm_hour = s->rtc.new.tm_hour; -+ tm.tm_mday = s->rtc.new.tm_mday; -+ tm.tm_mon = s->rtc.new.tm_mon; -+ tm.tm_year = s->rtc.new.tm_year; -+ break; -+ rtc_badness: -+ default: -+ fprintf(stderr, "%s: bad RTC_UPDATE value %02x\n", -+ __FUNCTION__, value); -+ s->status |= 1 << 10; /* RTCERR */ -+ menelaus_update(s); -+ } -+ s->rtc.sec += difftime(mktime(&tm), mktime(&s->rtc.tm)); -+ break; -+ case MENELAUS_RTC_SEC: -+ s->rtc.tm.tm_sec = from_bcd(value & 0x7f); -+ break; -+ case MENELAUS_RTC_MIN: -+ s->rtc.tm.tm_min = from_bcd(value & 0x7f); -+ break; -+ case MENELAUS_RTC_HR: -+ s->rtc.tm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */ -+ MIN(from_bcd(value & 0x3f), 12) + ((value >> 7) ? 11 : -1) : -+ from_bcd(value & 0x3f); -+ break; -+ case MENELAUS_RTC_DAY: -+ s->rtc.tm.tm_mday = from_bcd(value); -+ break; -+ case MENELAUS_RTC_MON: -+ s->rtc.tm.tm_mon = MAX(1, from_bcd(value)) - 1; -+ break; -+ case MENELAUS_RTC_YR: -+ s->rtc.tm.tm_year = 2000 + from_bcd(value); -+ break; -+ case MENELAUS_RTC_WKDAY: -+ s->rtc.tm.tm_mday = from_bcd(value); -+ break; -+ case MENELAUS_RTC_AL_SEC: -+ s->rtc.alm.tm_sec = from_bcd(value & 0x7f); -+ menelaus_alm_update(s); -+ break; -+ case MENELAUS_RTC_AL_MIN: -+ s->rtc.alm.tm_min = from_bcd(value & 0x7f); -+ menelaus_alm_update(s); -+ break; -+ case MENELAUS_RTC_AL_HR: -+ s->rtc.alm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */ -+ MIN(from_bcd(value & 0x3f), 12) + ((value >> 7) ? 11 : -1) : -+ from_bcd(value & 0x3f); -+ menelaus_alm_update(s); -+ break; -+ case MENELAUS_RTC_AL_DAY: -+ s->rtc.alm.tm_mday = from_bcd(value); -+ menelaus_alm_update(s); -+ break; -+ case MENELAUS_RTC_AL_MON: -+ s->rtc.alm.tm_mon = MAX(1, from_bcd(value)) - 1; -+ menelaus_alm_update(s); -+ break; -+ case MENELAUS_RTC_AL_YR: -+ s->rtc.alm.tm_year = 2000 + from_bcd(value); -+ menelaus_alm_update(s); -+ break; -+ case MENELAUS_RTC_COMP_MSB: -+ s->rtc.comp &= 0xff; -+ s->rtc.comp |= value << 8; -+ break; -+ case MENELAUS_RTC_COMP_LSB: -+ s->rtc.comp &= 0xff << 8; -+ s->rtc.comp |= value; -+ break; -+ -+ case MENELAUS_S1_PULL_EN: -+ s->pull[0] = value; -+ break; -+ case MENELAUS_S1_PULL_DIR: -+ s->pull[1] = value & 0x1f; -+ break; -+ case MENELAUS_S2_PULL_EN: -+ s->pull[2] = value; -+ break; -+ case MENELAUS_S2_PULL_DIR: -+ s->pull[3] = value & 0x1f; -+ break; -+ -+ case MENELAUS_MCT_CTRL1: -+ s->mmc_ctrl[0] = value & 0x7f; -+ break; -+ case MENELAUS_MCT_CTRL2: -+ s->mmc_ctrl[1] = value; -+ /* TODO update Card Detect interrupts */ -+ break; -+ case MENELAUS_MCT_CTRL3: -+ s->mmc_ctrl[2] = value & 0xf; -+ break; -+ case MENELAUS_DEBOUNCE1: -+ s->mmc_debounce = value & 0x3f; -+ break; -+ -+ default: -+#ifdef VERBOSE -+ printf("%s: unknown register %02x\n", __FUNCTION__, addr); -+#endif -+ } -+} -+ -+static void menelaus_event(i2c_slave *i2c, enum i2c_event event) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) i2c; -+ -+ if (event == I2C_START_SEND) -+ s->firstbyte = 1; -+} -+ -+static int menelaus_tx(i2c_slave *i2c, uint8_t data) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) i2c; -+ /* Interpret register address byte */ -+ if (s->firstbyte) { -+ s->reg = data; -+ s->firstbyte = 0; -+ } else -+ menelaus_write(s, s->reg ++, data); -+ -+ return 0; -+} -+ -+static int menelaus_rx(i2c_slave *i2c) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) i2c; -+ -+ return menelaus_read(s, s->reg ++); -+} -+ -+static void tm_put(QEMUFile *f, struct tm *tm) { -+ qemu_put_be16(f, tm->tm_sec); -+ qemu_put_be16(f, tm->tm_min); -+ qemu_put_be16(f, tm->tm_hour); -+ qemu_put_be16(f, tm->tm_mday); -+ qemu_put_be16(f, tm->tm_min); -+ qemu_put_be16(f, tm->tm_year); -+} -+ -+static void tm_get(QEMUFile *f, struct tm *tm) { -+ tm->tm_sec = qemu_get_be16(f); -+ tm->tm_min = qemu_get_be16(f); -+ tm->tm_hour = qemu_get_be16(f); -+ tm->tm_mday = qemu_get_be16(f); -+ tm->tm_min = qemu_get_be16(f); -+ tm->tm_year = qemu_get_be16(f); -+} -+ -+static void menelaus_save(QEMUFile *f, void *opaque) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) opaque; -+ -+ qemu_put_be32(f, s->firstbyte); -+ qemu_put_8s(f, &s->reg); -+ -+ qemu_put_8s(f, &s->vcore[0]); -+ qemu_put_8s(f, &s->vcore[1]); -+ qemu_put_8s(f, &s->vcore[2]); -+ qemu_put_8s(f, &s->vcore[3]); -+ qemu_put_8s(f, &s->vcore[4]); -+ qemu_put_8s(f, &s->dcdc[3]); -+ qemu_put_8s(f, &s->dcdc[3]); -+ qemu_put_8s(f, &s->dcdc[3]); -+ qemu_put_8s(f, &s->ldo[0]); -+ qemu_put_8s(f, &s->ldo[1]); -+ qemu_put_8s(f, &s->ldo[2]); -+ qemu_put_8s(f, &s->ldo[3]); -+ qemu_put_8s(f, &s->ldo[4]); -+ qemu_put_8s(f, &s->ldo[5]); -+ qemu_put_8s(f, &s->ldo[6]); -+ qemu_put_8s(f, &s->ldo[7]); -+ qemu_put_8s(f, &s->sleep[0]); -+ qemu_put_8s(f, &s->sleep[1]); -+ qemu_put_8s(f, &s->osc); -+ qemu_put_8s(f, &s->detect); -+ qemu_put_be16s(f, &s->mask); -+ qemu_put_be16s(f, &s->status); -+ qemu_put_8s(f, &s->dir); -+ qemu_put_8s(f, &s->inputs); -+ qemu_put_8s(f, &s->outputs); -+ qemu_put_8s(f, &s->bbsms); -+ qemu_put_8s(f, &s->pull[0]); -+ qemu_put_8s(f, &s->pull[1]); -+ qemu_put_8s(f, &s->pull[2]); -+ qemu_put_8s(f, &s->pull[3]); -+ qemu_put_8s(f, &s->mmc_ctrl[0]); -+ qemu_put_8s(f, &s->mmc_ctrl[1]); -+ qemu_put_8s(f, &s->mmc_ctrl[2]); -+ qemu_put_8s(f, &s->mmc_debounce); -+ qemu_put_8s(f, &s->rtc.ctrl); -+ qemu_put_be16s(f, &s->rtc.comp); -+ /* Should be <= 1000 */ -+ qemu_put_be16(f, s->rtc.next - qemu_get_clock(rt_clock)); -+ tm_put(f, &s->rtc.new); -+ tm_put(f, &s->rtc.alm); -+ qemu_put_byte(f, s->pwrbtn_state); -+ -+ i2c_slave_save(f, &s->i2c); -+} -+ -+static int menelaus_load(QEMUFile *f, void *opaque, int version_id) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) opaque; -+ -+ s->firstbyte = qemu_get_be32(f); -+ qemu_get_8s(f, &s->reg); -+ -+ if (s->rtc.ctrl & 1) /* RTC_EN */ -+ menelaus_rtc_stop(s); -+ qemu_get_8s(f, &s->vcore[0]); -+ qemu_get_8s(f, &s->vcore[1]); -+ qemu_get_8s(f, &s->vcore[2]); -+ qemu_get_8s(f, &s->vcore[3]); -+ qemu_get_8s(f, &s->vcore[4]); -+ qemu_get_8s(f, &s->dcdc[3]); -+ qemu_get_8s(f, &s->dcdc[3]); -+ qemu_get_8s(f, &s->dcdc[3]); -+ qemu_get_8s(f, &s->ldo[0]); -+ qemu_get_8s(f, &s->ldo[1]); -+ qemu_get_8s(f, &s->ldo[2]); -+ qemu_get_8s(f, &s->ldo[3]); -+ qemu_get_8s(f, &s->ldo[4]); -+ qemu_get_8s(f, &s->ldo[5]); -+ qemu_get_8s(f, &s->ldo[6]); -+ qemu_get_8s(f, &s->ldo[7]); -+ qemu_get_8s(f, &s->sleep[0]); -+ qemu_get_8s(f, &s->sleep[1]); -+ qemu_get_8s(f, &s->osc); -+ qemu_get_8s(f, &s->detect); -+ qemu_get_be16s(f, &s->mask); -+ qemu_get_be16s(f, &s->status); -+ qemu_get_8s(f, &s->dir); -+ qemu_get_8s(f, &s->inputs); -+ qemu_get_8s(f, &s->outputs); -+ qemu_get_8s(f, &s->bbsms); -+ qemu_get_8s(f, &s->pull[0]); -+ qemu_get_8s(f, &s->pull[1]); -+ qemu_get_8s(f, &s->pull[2]); -+ qemu_get_8s(f, &s->pull[3]); -+ qemu_get_8s(f, &s->mmc_ctrl[0]); -+ qemu_get_8s(f, &s->mmc_ctrl[1]); -+ qemu_get_8s(f, &s->mmc_ctrl[2]); -+ qemu_get_8s(f, &s->mmc_debounce); -+ qemu_get_8s(f, &s->rtc.ctrl); -+ qemu_get_be16s(f, &s->rtc.comp); -+ s->rtc.next = qemu_get_be16(f); -+ tm_get(f, &s->rtc.new); -+ tm_get(f, &s->rtc.alm); -+ s->pwrbtn_state = qemu_get_byte(f); -+ menelaus_alm_update(s); -+ menelaus_update(s); -+ if (s->rtc.ctrl & 1) /* RTC_EN */ -+ menelaus_rtc_start(s); -+ -+ i2c_slave_load(f, &s->i2c); -+ return 0; -+} -+ -+static int menelaus_iid = 0; -+ -+i2c_slave *twl92230_init(i2c_bus *bus, qemu_irq irq) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) -+ i2c_slave_init(bus, 0, sizeof(struct menelaus_s)); -+ -+ s->i2c.event = menelaus_event; -+ s->i2c.recv = menelaus_rx; -+ s->i2c.send = menelaus_tx; -+ -+ /* TODO: use the qemu gettime functions */ -+ s->rtc.gettime = localtime_r; -+ -+ s->irq = irq; -+ s->rtc.hz = qemu_new_timer(rt_clock, menelaus_rtc_hz, s); -+ s->in = qemu_allocate_irqs(menelaus_gpio_set, s, 3); -+ s->pwrbtn = qemu_allocate_irqs(menelaus_pwrbtn_set, s, 1)[0]; -+ -+ menelaus_reset(&s->i2c); -+ -+ register_savevm("menelaus", menelaus_iid ++, -+ 0, menelaus_save, menelaus_load, s); -+ -+ return &s->i2c; -+} -+ -+qemu_irq *twl92230_gpio_in_get(i2c_slave *i2c) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) i2c; -+ -+ return s->in; -+} -+ -+void twl92230_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler) -+{ -+ struct menelaus_s *s = (struct menelaus_s *) i2c; -+ -+ if (line >= 3 || line < 0) { -+ fprintf(stderr, "%s: No GPO line %i\n", __FUNCTION__, line); -+ exit(-1); -+ } -+ s->handler[line] = handler; -+} -diff --git a/hw/versatilepb.c b/hw/versatilepb.c -index da6e4ec..ecc0037 100644 ---- a/hw/versatilepb.c -+++ b/hw/versatilepb.c -@@ -157,6 +157,8 @@ static qemu_irq *vpb_sic_init(uint32_t base, qemu_irq *parent, int irq) - peripherans and expansion busses. For now we emulate a subset of the - PB peripherals and just change the board ID. */ - -+static struct arm_boot_info versatile_binfo; -+ - static void versatile_init(int ram_size, int vga_ram_size, - const char *boot_device, DisplayState *ds, - const char *kernel_filename, const char *kernel_cmdline, -@@ -283,8 +285,12 @@ static void versatile_init(int ram_size, int vga_ram_size, - /* 0x101f3000 UART2. */ - /* 0x101f4000 SSPI. */ - -- arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, -- initrd_filename, board_id, 0x0); -+ versatile_binfo.ram_size = ram_size; -+ versatile_binfo.kernel_filename = kernel_filename; -+ versatile_binfo.kernel_cmdline = kernel_cmdline; -+ versatile_binfo.initrd_filename = initrd_filename; -+ versatile_binfo.board_id = board_id; -+ arm_load_kernel(env, &versatile_binfo); - } - - static void vpb_init(int ram_size, int vga_ram_size, -diff --git a/softmmu_template.h b/softmmu_template.h -index 0a4bc7e..d480f34 100644 ---- a/softmmu_template.h -+++ b/softmmu_template.h -@@ -51,12 +51,15 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, - int mmu_idx, - void *retaddr); - static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, -- target_ulong tlb_addr) -+ target_ulong tlb_addr, -+ target_ulong tlb_io) - { - DATA_TYPE res; - int index; - -- index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); -+ index = (tlb_addr & ~TARGET_PAGE_MASK) >> IO_MEM_SHIFT; -+ if (index > 4) -+ index = (tlb_io >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); - #if SHIFT <= 2 - res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr); - #else -@@ -95,7 +98,9 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, - /* IO access */ - if ((addr & (DATA_SIZE - 1)) != 0) - goto do_unaligned_access; -- res = glue(io_read, SUFFIX)(physaddr, tlb_addr); -+ res = glue(io_read, SUFFIX)(physaddr, tlb_addr, -+ env->tlb_table[mmu_idx] -+ [index].addr_code); - } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - /* slow unaligned access (it spans two pages or IO) */ - do_unaligned_access: -@@ -147,7 +152,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, - /* IO access */ - if ((addr & (DATA_SIZE - 1)) != 0) - goto do_unaligned_access; -- res = glue(io_read, SUFFIX)(physaddr, tlb_addr); -+ res = glue(io_read, SUFFIX)(physaddr, tlb_addr, -+ env->tlb_table[mmu_idx] -+ [index].addr_code); - } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - do_unaligned_access: - /* slow unaligned access (it spans two pages) */ -@@ -186,11 +193,14 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, - static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, - DATA_TYPE val, - target_ulong tlb_addr, -- void *retaddr) -+ void *retaddr, -+ target_ulong tlb_io) - { - int index; - -- index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); -+ index = (tlb_addr & ~TARGET_PAGE_MASK) >> IO_MEM_SHIFT; -+ if (index > 4) -+ index = (tlb_io >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); - env->mem_write_vaddr = tlb_addr; - env->mem_write_pc = (unsigned long)retaddr; - #if SHIFT <= 2 -@@ -228,7 +238,8 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, - if ((addr & (DATA_SIZE - 1)) != 0) - goto do_unaligned_access; - retaddr = GETPC(); -- glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr); -+ glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr, -+ env->tlb_table[mmu_idx][index].addr_code); - } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - do_unaligned_access: - retaddr = GETPC(); -@@ -278,7 +289,8 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, - /* IO access */ - if ((addr & (DATA_SIZE - 1)) != 0) - goto do_unaligned_access; -- glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr); -+ glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr, -+ env->tlb_table[mmu_idx][index].addr_code); - } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { - do_unaligned_access: - /* XXX: not efficient, but simple */ -diff --git a/target-arm/cpu.h b/target-arm/cpu.h -index b284a21..633b335 100644 ---- a/target-arm/cpu.h -+++ b/target-arm/cpu.h -@@ -198,12 +198,16 @@ typedef struct CPUARMState { - CPU_COMMON - - /* These fields after the common ones so they are preserved on reset. */ -- int ram_size; -- const char *kernel_filename; -- const char *kernel_cmdline; -- const char *initrd_filename; -- int board_id; -- target_phys_addr_t loader_start; -+ struct arm_boot_info { -+ int ram_size; -+ const char *kernel_filename; -+ const char *kernel_cmdline; -+ const char *initrd_filename; -+ target_phys_addr_t loader_start; -+ int nb_cpus; -+ int board_id; -+ int (*atag_board)(struct arm_boot_info *info, void *p); -+ } *boot_info; - } CPUARMState; - - CPUARMState *cpu_arm_init(const char *cpu_model); -@@ -377,6 +381,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, - #define ARM_CPUID_PXA270_C0 0x69054114 - #define ARM_CPUID_PXA270_C5 0x69054117 - #define ARM_CPUID_ARM1136 0x4117b363 -+#define ARM_CPUID_ARM1136_R2 0x4107b362 - #define ARM_CPUID_ARM11MPCORE 0x410fb022 - #define ARM_CPUID_CORTEXA8 0x410fc080 - #define ARM_CPUID_CORTEXM3 0x410fc231 -diff --git a/target-arm/helper.c b/target-arm/helper.c -index 86470db..0709129 100644 ---- a/target-arm/helper.c -+++ b/target-arm/helper.c -@@ -53,6 +53,9 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id) - env->cp15.c0_cachetype = 0x1dd20d2; - env->cp15.c1_sys = 0x00090078; - break; -+ case ARM_CPUID_ARM1136_R2: -+ /* TODO! */ -+ env->GE = 0x5; - case ARM_CPUID_ARM1136: - set_feature(env, ARM_FEATURE_V6); - set_feature(env, ARM_FEATURE_VFP); -@@ -198,6 +201,7 @@ static const struct arm_cpu_t arm_cpu_names[] = { - { ARM_CPUID_ARM946, "arm946"}, - { ARM_CPUID_ARM1026, "arm1026"}, - { ARM_CPUID_ARM1136, "arm1136"}, -+ { ARM_CPUID_ARM1136_R2, "arm1136-r2"}, - { ARM_CPUID_ARM11MPCORE, "arm11mpcore"}, - { ARM_CPUID_CORTEXM3, "cortex-m3"}, - { ARM_CPUID_CORTEXA8, "cortex-a8"}, -@@ -1539,6 +1543,7 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn) - case ARM_CPUID_ARM1026: - return 1; - case ARM_CPUID_ARM1136: -+ case ARM_CPUID_ARM1136_R2: - return 7; - case ARM_CPUID_ARM11MPCORE: - return 1; -@@ -1721,6 +1726,10 @@ uint32_t helper_get_cp15(CPUState *env, uint32_t insn) - case 8: /* TI925T_status */ - return 0; - } -+ /* TODO: Peripheral port remap register: -+ * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt -+ * controller base address at $rn & ~0xfff and map size of -+ * 0x200 << ($rn & 0xfff), when MMU is off. */ - goto bad_reg; - } - return 0; -diff --git a/vl.c b/vl.c -index d371af7..76d8def 100644 ---- a/vl.c -+++ b/vl.c -@@ -8006,6 +8006,7 @@ static void register_machines(void) - qemu_register_machine(&borzoipda_machine); - qemu_register_machine(&terrierpda_machine); - qemu_register_machine(&palmte_machine); -+ qemu_register_machine(&n800_machine); - qemu_register_machine(&lm3s811evb_machine); - qemu_register_machine(&lm3s6965evb_machine); - qemu_register_machine(&connex_machine); diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/series b/meta/packages/qemu/qemu-0.9.1+svnr4027/series deleted file mode 100644 index 126da882884..00000000000 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/series +++ /dev/null @@ -1,25 +0,0 @@ -02_snapshot_use_tmpdir.patch -p0 -05_non-fatal_if_linux_hd_missing.patch -p1 -06_exit_segfault.patch -p0 -10_signal_jobs.patch -p0 -11_signal_sigaction.patch -p0 -22_net_tuntap_stall.patch -p0 -31_syscalls.patch -p0 -32_syscall_sysctl.patch -p0 -33_syscall_ppc_clone.patch -p0 -39_syscall_fadvise64.patch -p0 -41_arm_fpa_sigfpe.patch -p0 -52_ne2000_return.patch -p1 -61_safe_64bit_int.patch -p0 -63_sparc_build.patch -p0 -64_ppc_asm_constraints.patch -p1 -65_kfreebsd.patch -p0 -66_tls_ld.patch -p0 -91-oh-sdl-cursor.patch -p0 -qemu-0.9.0-nptl.patch -p1 -qemu-0.9.0-nptl-update.patch -p1 -qemu-amd64-32b-mapping-0.9.0.patch -p1 -workaround_bad_futex_headers.patch -p1 -fix_segfault.patch -p1 -no-strip.patch -p1 -qemu-n800-support.patch -p1 diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/06_exit_segfault.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/06_exit_segfault.patch similarity index 100% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/06_exit_segfault.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/06_exit_segfault.patch diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/11_signal_sigaction.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/11_signal_sigaction.patch similarity index 100% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/11_signal_sigaction.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/11_signal_sigaction.patch diff --git a/meta/packages/qemu/qemu-0.9.1+svn/22_net_tuntap_stall.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/22_net_tuntap_stall.patch similarity index 64% rename from meta/packages/qemu/qemu-0.9.1+svn/22_net_tuntap_stall.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/22_net_tuntap_stall.patch index 0e1038983bc..f2bfbc9102b 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/22_net_tuntap_stall.patch +++ b/meta/packages/qemu/qemu-0.9.1+svnr6190/22_net_tuntap_stall.patch @@ -3,16 +3,16 @@ # vl.c | 2 +- # 1 file changed, 1 insertion(+), 1 deletion(-) # -Index: vl.c +Index: net.c =================================================================== ---- vl.c.orig 2008-04-24 20:15:46.000000000 +0100 -+++ vl.c 2008-04-24 20:15:58.000000000 +0100 -@@ -4155,7 +4155,7 @@ +--- net.c.orig 2009-01-05 11:27:29.000000000 +0000 ++++ net.c 2009-01-05 11:27:40.000000000 +0000 +@@ -852,7 +852,7 @@ return -1; } memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; -+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE; ++ ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE;; if (ifname[0] != '\0') pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname); else diff --git a/meta/packages/qemu/qemu-0.9.1+svnr6190/31_syscalls.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/31_syscalls.patch new file mode 100644 index 00000000000..df2aa84bb17 --- /dev/null +++ b/meta/packages/qemu/qemu-0.9.1+svnr6190/31_syscalls.patch @@ -0,0 +1,27 @@ +#DPATCHLEVEL=0 +--- +# linux-user/syscall.c | 11 ++++++++--- +# 1 file changed, 8 insertions(+), 3 deletions(-) +# +Index: linux-user/syscall.c +=================================================================== +--- linux-user/syscall.c.orig 2009-01-05 12:32:37.000000000 +0000 ++++ linux-user/syscall.c 2009-01-05 12:32:37.000000000 +0000 +@@ -298,6 +298,7 @@ + extern int setfsuid(int); + extern int setfsgid(int); + extern int setgroups(int, gid_t *); ++extern int uselib(const char*); + + #define ERRNO_TABLE_SIZE 1200 + +@@ -4397,7 +4398,8 @@ + #endif + #ifdef TARGET_NR_uselib + case TARGET_NR_uselib: +- goto unimplemented; ++ ret = get_errno(uselib(path((const char*)arg1))); ++ break; + #endif + #ifdef TARGET_NR_swapon + case TARGET_NR_swapon: diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/52_ne2000_return.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/52_ne2000_return.patch similarity index 100% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/52_ne2000_return.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/52_ne2000_return.patch diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/63_sparc_build.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/63_sparc_build.patch similarity index 100% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/63_sparc_build.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/63_sparc_build.patch diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/64_ppc_asm_constraints.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/64_ppc_asm_constraints.patch similarity index 100% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/64_ppc_asm_constraints.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/64_ppc_asm_constraints.patch diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/66_tls_ld.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/66_tls_ld.patch similarity index 100% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/66_tls_ld.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/66_tls_ld.patch diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/91-oh-sdl-cursor.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/91-oh-sdl-cursor.patch similarity index 100% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/91-oh-sdl-cursor.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/91-oh-sdl-cursor.patch diff --git a/meta/packages/qemu/qemu-0.9.1+svnr6190/fix-dirent.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/fix-dirent.patch new file mode 100644 index 00000000000..575dbfa0c97 --- /dev/null +++ b/meta/packages/qemu/qemu-0.9.1+svnr6190/fix-dirent.patch @@ -0,0 +1,12 @@ +Index: trunk/linux-user/syscall.c +=================================================================== +--- trunk.orig/linux-user/syscall.c 2009-01-05 12:51:52.000000000 +0000 ++++ trunk/linux-user/syscall.c 2009-01-05 12:51:52.000000000 +0000 +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/no-strip.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/no-strip.patch similarity index 100% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/no-strip.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/no-strip.patch diff --git a/meta/packages/qemu/qemu-0.9.1+svn/qemu-amd64-32b-mapping-0.9.0.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/qemu-amd64-32b-mapping-0.9.0.patch similarity index 52% rename from meta/packages/qemu/qemu-0.9.1+svn/qemu-amd64-32b-mapping-0.9.0.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/qemu-amd64-32b-mapping-0.9.0.patch index 02f093abb9d..40ab59c7629 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/qemu-amd64-32b-mapping-0.9.0.patch +++ b/meta/packages/qemu/qemu-0.9.1+svnr6190/qemu-amd64-32b-mapping-0.9.0.patch @@ -4,11 +4,11 @@ Index: trunk/linux-user/mmap.c =================================================================== ---- trunk.orig/linux-user/mmap.c 2008-04-24 20:15:37.000000000 +0100 -+++ trunk/linux-user/mmap.c 2008-04-24 20:16:16.000000000 +0100 -@@ -29,6 +29,10 @@ - - //#define DEBUG_MMAP +--- trunk.orig/linux-user/mmap.c 2009-01-05 11:09:58.000000000 +0000 ++++ trunk/linux-user/mmap.c 2009-01-05 12:46:33.000000000 +0000 +@@ -122,6 +122,10 @@ + munmap(p, *p); + } +#ifndef MAP_32BIT +#define MAP_32BIT 0 @@ -17,21 +17,21 @@ Index: trunk/linux-user/mmap.c /* NOTE: all the constants are the HOST ones, but addresses are target. */ int target_mprotect(abi_ulong start, abi_ulong len, int prot) { -@@ -251,7 +255,7 @@ +@@ -365,7 +369,7 @@ especially important if qemu_host_page_size > qemu_real_host_page_size */ p = mmap(g2h(mmap_start), - host_len, prot, flags | MAP_FIXED, fd, host_offset); + host_len, prot, flags | MAP_FIXED | MAP_32BIT, fd, host_offset); if (p == MAP_FAILED) - return -1; + goto fail; /* update start so that it points to the file position at 'offset' */ -@@ -406,7 +410,7 @@ - unsigned long host_addr; - - /* XXX: use 5 args syscall */ -- host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags); -+ host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags | MAP_32BIT); - if (host_addr == -1) - return -1; - new_addr = h2g(host_addr); +@@ -567,7 +571,7 @@ + flags | MREMAP_FIXED, + g2h(mmap_start)); + } else { +- host_addr = mremap(g2h(old_addr), old_size, new_size, flags); ++ host_addr = mremap(g2h(old_addr), old_size, new_size, flags | MAP_32BIT); + /* Check if address fits target address space */ + if ((unsigned long)host_addr + new_size > (abi_ulong)-1) { + /* Revert mremap() changes */ diff --git a/meta/packages/qemu/qemu-0.9.1+svnr6190/series b/meta/packages/qemu/qemu-0.9.1+svnr6190/series new file mode 100644 index 00000000000..57d41df4f68 --- /dev/null +++ b/meta/packages/qemu/qemu-0.9.1+svnr6190/series @@ -0,0 +1,13 @@ +06_exit_segfault.patch -p0 +11_signal_sigaction.patch -p0 +22_net_tuntap_stall.patch -p0 +31_syscalls.patch -p0 +52_ne2000_return.patch -p1 +63_sparc_build.patch -p0 +64_ppc_asm_constraints.patch -p1 +66_tls_ld.patch -p0 +91-oh-sdl-cursor.patch -p0 +qemu-amd64-32b-mapping-0.9.0.patch -p1 +workaround_bad_futex_headers.patch -p1 +no-strip.patch -p1 +fix-dirent.patch -p1 diff --git a/meta/packages/qemu/qemu-0.9.1+svnr4027/workaround_bad_futex_headers.patch b/meta/packages/qemu/qemu-0.9.1+svnr6190/workaround_bad_futex_headers.patch similarity index 52% rename from meta/packages/qemu/qemu-0.9.1+svnr4027/workaround_bad_futex_headers.patch rename to meta/packages/qemu/qemu-0.9.1+svnr6190/workaround_bad_futex_headers.patch index cc122ebdba4..b254b2410a2 100644 --- a/meta/packages/qemu/qemu-0.9.1+svnr4027/workaround_bad_futex_headers.patch +++ b/meta/packages/qemu/qemu-0.9.1+svnr6190/workaround_bad_futex_headers.patch @@ -2,15 +2,14 @@ linux-user/syscall.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) -Index: qemu/linux-user/syscall.c +Index: trunk/linux-user/syscall.c =================================================================== ---- qemu.orig/linux-user/syscall.c 2007-08-09 20:28:06.000000000 +0100 -+++ qemu/linux-user/syscall.c 2007-08-09 20:28:41.000000000 +0100 -@@ -61,7 +61,15 @@ - #define tchars host_tchars /* same as target */ - #define ltchars host_ltchars /* same as target */ +--- trunk.orig/linux-user/syscall.c 2009-01-05 12:47:06.000000000 +0000 ++++ trunk/linux-user/syscall.c 2009-01-05 12:48:04.000000000 +0000 +@@ -87,6 +87,15 @@ + #define CLONE_NPTL_FLAGS2 0 + #endif --#include +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 +#define FUTEX_FD 2 @@ -20,6 +19,6 @@ Index: qemu/linux-user/syscall.c +#define FUTEX_LOCK_PI 6 +#define FUTEX_UNLOCK_PI 7 + - #include - #include - #include + //#define DEBUG + + #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ diff --git a/meta/packages/qemu/qemu_svn.bb b/meta/packages/qemu/qemu_svn.bb index 3de26cd3976..e6b23cbe1f0 100644 --- a/meta/packages/qemu/qemu_svn.bb +++ b/meta/packages/qemu/qemu_svn.bb @@ -1,40 +1,24 @@ LICENSE = "GPL" DEPENDS = "zlib" PV = "0.9.1+svnr${SRCREV}" -PR = "r13" +PR = "r14" FILESPATH = "${FILE_DIRNAME}/qemu-${PV}/:${FILE_DIRNAME}/qemu-0.9.1+svn/" SRC_URI = "\ svn://svn.savannah.nongnu.org/qemu;module=trunk \ - file://02_snapshot_use_tmpdir.patch;patch=1;pnum=0;maxrev=4028 \ - file://05_non-fatal_if_linux_hd_missing.patch;patch=1;pnum=1 \ file://06_exit_segfault.patch;patch=1;pnum=0 \ - file://10_signal_jobs.patch;patch=1;pnum=0 \ file://11_signal_sigaction.patch;patch=1;pnum=0 \ file://22_net_tuntap_stall.patch;patch=1;pnum=0 \ file://31_syscalls.patch;patch=1;pnum=0 \ - file://32_syscall_sysctl.patch;patch=1;pnum=0 \ - file://33_syscall_ppc_clone.patch;patch=1;pnum=0 \ - file://39_syscall_fadvise64.patch;patch=1;pnum=0 \ - file://41_arm_fpa_sigfpe.patch;patch=1;pnum=0;maxrev=4028 \ file://52_ne2000_return.patch;patch=1;pnum=1 \ - file://61_safe_64bit_int.patch;patch=1;pnum=0 \ file://63_sparc_build.patch;patch=1;pnum=0 \ file://64_ppc_asm_constraints.patch;patch=1;pnum=1 \ - file://65_kfreebsd.patch;patch=1;pnum=0 \ file://66_tls_ld.patch;patch=1;pnum=0 \ file://91-oh-sdl-cursor.patch;patch=1;pnum=0 \ - file://qemu-0.9.0-nptl.patch;patch=1 \ - file://qemu-0.9.0-nptl-update.patch;patch=1;maxrev=4028 \ file://qemu-amd64-32b-mapping-0.9.0.patch;patch=1 \ file://workaround_bad_futex_headers.patch;patch=1 \ - file://fix_segfault.patch;patch=1 \ file://no-strip.patch;patch=1 \ - file://fix_brk.patch;patch=1 \ - file://fix_protection_bits.patch;patch=1 \ - file://revert_arm_tcg.patch.gz;patch=1;minrev=4242 \ - file://qemu-n800-support.patch;patch=1 \ file://fix-dirent.patch;patch=1" S = "${WORKDIR}/trunk" -- 2.47.3