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 e835e66e46..92fb6ddc28 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 a66737d9ce..0000000000 --- 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 bc02d31839..0000000000 --- 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 d79482d2f4..0000000000 --- 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 cd56541b71..0000000000 --- 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 15565ae11d..0000000000 --- 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 d42c44cebc..0000000000 --- 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 962f821523..0000000000 --- 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 845232cfca..0000000000 --- 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 e364bff731..0000000000 --- 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 9a67feac6b..0000000000 --- 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 097f55a09e..0000000000 --- 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 7d19817278..0000000000 --- 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 028e85a878..0000000000 --- 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 cbd3f873d8..0000000000 --- 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 b3d95a4534..0000000000 --- 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 3ec304a38c..0000000000 --- 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 9282ac4779..0000000000 --- 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 f15e001dd6..0000000000 --- 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 ee2b077602..0000000000 --- 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 224a8b813d..0000000000 --- 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 4813dd4e2b..0000000000 --- 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 ac68ebf460..0000000000 --- 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 1224fb4cbd..0000000000 --- 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 HcmV?d00001 literal 97991 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 -+#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 40264ed443..0000000000 --- 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 31c9da491d..0000000000 --- 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 fdd922605e..0000000000 --- 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 34282adc9d..0000000000 --- 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 6017df0f6d..0000000000 --- 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 95a7332ee8..0000000000 --- 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 5e8dd75b0e..0000000000 --- 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 3f733b6ab8..0000000000 --- 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 54ee3e0948..0000000000 --- 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 cea3afc7ff..0000000000 --- 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 9b1ace81a5..0000000000 --- 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 dfece800ac..0000000000 --- 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 3ec304a38c..0000000000 --- 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 783198d9e3..0000000000 --- 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 ee2b077602..0000000000 --- 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 443c330650..0000000000 --- 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 ebc996e873..0000000000 --- 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 4a87d8d637..0000000000 --- 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 c7f36d8110..0000000000 --- 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 b1b6649efc..0000000000 --- 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 126da88288..0000000000 --- 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 0e1038983b..f2bfbc9102 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 0000000000..df2aa84bb1 --- /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 0000000000..575dbfa0c9 --- /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 02f093abb9..40ab59c762 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 0000000000..57d41df4f6 --- /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 cc122ebdba..b254b2410a 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 3de26cd397..e6b23cbe1f 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.40.1