summaryrefslogtreecommitdiff
path: root/meta
diff options
context:
space:
mode:
Diffstat (limited to 'meta')
-rw-r--r--meta/conf/distro/poky.conf6
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/02_snapshot_use_tmpdir.patch23
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/04_do_not_print_rtc_freq_if_ok.patch26
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/05_non-fatal_if_linux_hd_missing.patch17
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/06_exit_segfault.patch45
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/10_signal_jobs.patch26
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/11_signal_sigaction.patch21
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/22_net_tuntap_stall.patch18
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/31_syscalls.patch48
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/32_syscall_sysctl.patch55
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/33_syscall_ppc_clone.patch22
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/39_syscall_fadvise64.patch21
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/41_arm_fpa_sigfpe.patch104
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/52_ne2000_return.patch17
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/61_safe_64bit_int.patch27
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/63_sparc_build.patch18
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/64_ppc_asm_constraints.patch18
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/65_kfreebsd.patch35
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/66_tls_ld.patch55
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/91-oh-sdl-cursor.patch18
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/configure_symlinkpath_fix.patch28
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/disable-error-in-configure.patch17
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/fix_segfault.patch37
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/no-strip.patch22
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-0.9.0-nptl-update.patch219
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-0.9.0-nptl.patch854
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-amd64-32b-mapping-0.9.0.patch37
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-n800-support.patch13970
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/series25
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/workaround_bad_futex_headers.patch25
-rw-r--r--meta/packages/qemu/qemu-0.9.1+cvs20080307/writev_fix.patch17
-rw-r--r--meta/packages/qemu/qemu-native_cvs.bb2
-rw-r--r--meta/packages/qemu/qemu-sdk_cvs.bb4
-rw-r--r--meta/packages/qemu/qemu_cvs.bb47
34 files changed, 3 insertions, 15921 deletions
diff --git a/meta/conf/distro/poky.conf b/meta/conf/distro/poky.conf
index c342c3117..44b5ec797 100644
--- a/meta/conf/distro/poky.conf
+++ b/meta/conf/distro/poky.conf
@@ -149,9 +149,9 @@ SRCREV_pn-opkg ?= "4209"
SRCREV_pn-opkg-native ?= "4209"
SRCREV_pn-opkg-sdk ?= "4209"
SRCREV_pn-libxosd ?= "627"
-SRCDATE_pn-qemu-native ?= "20080307"
-SRCDATE_pn-qemu-sdk ?= "20080307"
-SRCDATE_pn-qemu ?= "20080307"
+SRCREV_pn-qemu-native ?= "4027"
+SRCREV_pn-qemu-sdk ?= "4027"
+SRCREV_pn-qemu ?= "4027"
SRCREV_pn-vincent ?= "246"
# Previously floating revisions
diff --git a/meta/packages/qemu/qemu-0.9.1+cvs20080307/02_snapshot_use_tmpdir.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/02_snapshot_use_tmpdir.patch
deleted file mode 100644
index 40264ed44..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/04_do_not_print_rtc_freq_if_ok.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/04_do_not_print_rtc_freq_if_ok.patch
deleted file mode 100644
index 31c9da491..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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, &current_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+cvs20080307/05_non-fatal_if_linux_hd_missing.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/05_non-fatal_if_linux_hd_missing.patch
deleted file mode 100644
index fdd922605..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/06_exit_segfault.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/06_exit_segfault.patch
deleted file mode 100644
index 06123d062..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 2007-12-03 23:47:25.000000000 +0000
-+++ linux-user/main.c 2007-12-03 23:47:41.000000000 +0000
-@@ -714,7 +714,7 @@ void cpu_loop (CPUSPARCState *env)
- default:
- printf ("Unhandled trap: 0x%x\n", trapnr);
- cpu_dump_state(env, stderr, fprintf, 0);
-- exit (1);
-+ _exit (1);
- }
- process_pending_signals (env);
- }
-@@ -1634,7 +1634,7 @@ void cpu_loop (CPUState *env)
- default:
- printf ("Unhandled trap: 0x%x\n", trapnr);
- cpu_dump_state(env, stderr, fprintf, 0);
-- exit (1);
-+ _exit (1);
- }
- process_pending_signals (env);
- }
-@@ -1954,7 +1954,7 @@ int main(int argc, char **argv)
- 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")) {
-@@ -1973,7 +1973,7 @@ int main(int argc, char **argv)
- 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+cvs20080307/10_signal_jobs.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/10_signal_jobs.patch
deleted file mode 100644
index 34282adc9..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/11_signal_sigaction.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/11_signal_sigaction.patch
deleted file mode 100644
index 33c5e8b12..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 2007-12-03 23:47:44.000000000 +0000
-+++ linux-user/signal.c 2007-12-03 23:47:46.000000000 +0000
-@@ -512,6 +512,11 @@ int do_sigaction(int sig, const struct t
-
- 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+cvs20080307/22_net_tuntap_stall.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/22_net_tuntap_stall.patch
deleted file mode 100644
index 6017df0f6..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/31_syscalls.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/31_syscalls.patch
deleted file mode 100644
index 95a7332ee..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/32_syscall_sysctl.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/32_syscall_sysctl.patch
deleted file mode 100644
index 5e8dd75b0..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 <sys/user.h>
- #include <netinet/ip.h>
- #include <netinet/tcp.h>
-+#include <sys/sysctl.h>
-
- #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+cvs20080307/33_syscall_ppc_clone.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/33_syscall_ppc_clone.patch
deleted file mode 100644
index 3f733b6ab..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/39_syscall_fadvise64.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/39_syscall_fadvise64.patch
deleted file mode 100644
index 54ee3e094..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/41_arm_fpa_sigfpe.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/41_arm_fpa_sigfpe.patch
deleted file mode 100644
index cea3afc7f..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/52_ne2000_return.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/52_ne2000_return.patch
deleted file mode 100644
index e4ea33f2c..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/52_ne2000_return.patch
+++ /dev/null
@@ -1,17 +0,0 @@
----
- hw/ne2000.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: qemu/hw/ne2000.c
-===================================================================
---- qemu.orig/hw/ne2000.c 2007-12-03 19:32:52.000000000 +0000
-+++ qemu/hw/ne2000.c 2007-12-03 19:33:55.000000000 +0000
-@@ -217,7 +217,7 @@ static int ne2000_can_receive(void *opaq
- 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+cvs20080307/61_safe_64bit_int.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/61_safe_64bit_int.patch
deleted file mode 100644
index 9b1ace81a..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/63_sparc_build.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/63_sparc_build.patch
deleted file mode 100644
index 37b38f641..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 2007-12-03 15:40:26.000000000 +0000
-+++ sparc.ld 2007-12-03 16:05:06.000000000 +0000
-@@ -6,7 +6,7 @@ ENTRY(_start)
- 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+cvs20080307/64_ppc_asm_constraints.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/64_ppc_asm_constraints.patch
deleted file mode 100644
index e4858b79d..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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: qemu/cpu-all.h
-===================================================================
---- qemu.orig/cpu-all.h 2007-06-13 11:48:22.000000000 +0100
-+++ qemu/cpu-all.h 2007-06-13 11:51:56.000000000 +0100
-@@ -250,7 +250,7 @@ static inline void stw_le_p(void *ptr, i
- 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+cvs20080307/65_kfreebsd.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/65_kfreebsd.patch
deleted file mode 100644
index dfece800a..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 <stropts.h>
- #endif
- #endif
-+#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__)
-+#include <freebsd/stdlib.h>
- #else
- #include <winsock2.h>
- int inet_aton(const char *cp, struct in_addr *ia);
diff --git a/meta/packages/qemu/qemu-0.9.1+cvs20080307/66_tls_ld.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/66_tls_ld.patch
deleted file mode 100644
index 54e02eff8..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 2007-06-13 11:48:22.000000000 +0100
-+++ arm.ld 2007-06-13 11:51:56.000000000 +0100
-@@ -26,6 +26,10 @@ SECTIONS
- { *(.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 @@ SECTIONS
- .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 2007-06-13 11:48:22.000000000 +0100
-+++ i386.ld 2007-06-13 11:51:56.000000000 +0100
-@@ -28,6 +28,10 @@ SECTIONS
- { *(.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 @@ SECTIONS
- _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+cvs20080307/91-oh-sdl-cursor.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/91-oh-sdl-cursor.patch
deleted file mode 100644
index 0d60c1c30..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 2007-12-03 19:32:15.000000000 +0000
-+++ sdl.c 2007-12-03 19:34:04.000000000 +0000
-@@ -247,7 +247,7 @@ static void sdl_hide_cursor(void)
-
- 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+cvs20080307/configure_symlinkpath_fix.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/configure_symlinkpath_fix.patch
deleted file mode 100644
index 3ec304a38..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/disable-error-in-configure.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/disable-error-in-configure.patch
deleted file mode 100644
index 017f9f635..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/disable-error-in-configure.patch
+++ /dev/null
@@ -1,17 +0,0 @@
----
- configure | 2 --
- 1 file changed, 2 deletions(-)
-
-Index: qemu/configure
-===================================================================
---- qemu.orig/configure 2007-12-03 16:38:38.000000000 +0000
-+++ qemu/configure 2007-12-03 16:38:39.000000000 +0000
-@@ -323,8 +323,6 @@ for opt do
- ;;
- --disable-werror) werror="no"
- ;;
-- *) echo "ERROR: unknown option $opt"; show_help="yes"
-- ;;
- --disable-nptl) nptl="no"
- ;;
- esac
diff --git a/meta/packages/qemu/qemu-0.9.1+cvs20080307/fix_segfault.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/fix_segfault.patch
deleted file mode 100644
index 443c33065..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/no-strip.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/no-strip.patch
deleted file mode 100644
index fc69b37e1..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/no-strip.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- qemu.orig/Makefile 2008-01-29 23:16:27.000000000 -0800
-+++ qemu-0.9.1/Makefile 2008-01-29 23:16:38.000000000 -0800
-@@ -174,7 +174,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)"
- for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
---- qemu.orig/Makefile.target 2008-01-29 23:16:27.000000000 -0800
-+++ qemu-0.9.1/Makefile.target 2008-01-29 23:17:33.000000000 -0800
-@@ -632,7 +632,7 @@
-
- install: all
- ifneq ($(PROGS),)
-- $(INSTALL) -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)"
-+ $(INSTALL) -m 755 $(PROGS) "$(DESTDIR)$(bindir)"
- endif
-
- ifneq ($(wildcard .depend),)
diff --git a/meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-0.9.0-nptl-update.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-0.9.0-nptl-update.patch
deleted file mode 100644
index ebc996e87..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 <linux/futex.h>
- #include <linux/termios.h>
- #include <linux/unistd.h>
- #include <linux/utsname.h>
-@@ -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_<errcode>. */
-@@ -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+cvs20080307/qemu-0.9.0-nptl.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-0.9.0-nptl.patch
deleted file mode 100644
index 4a87d8d63..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 <<EOF
-+#include <sched.h>
-+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 <ia64intrin.h>
--
--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 <linux/kd.h>
-
- #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 <ia64intrin.h>
-+
-+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+cvs20080307/qemu-amd64-32b-mapping-0.9.0.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-amd64-32b-mapping-0.9.0.patch
deleted file mode 100644
index c7f36d811..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/qemu-n800-support.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/qemu-n800-support.patch
deleted file mode 100644
index b1b6649ef..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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 <andrew@openedhand.com>
-+ *
-+ * 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 <andrew@openedhand.com>
-+ *
-+ * 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 <andrew@openedhand.com>
-+ *
-+ * 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 <andrew@openedhand.com>
-+ *
-+ * 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 <andrew@openedhand.com>
-+ *
-+ * 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 <i>size</i> bytes
-+ * starting from <i>base</i>. */
-+ 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 <andrew@openedhand.com>
-+ *
-+ * 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 <andrew@openedhand.com>
-+ *
-+ * 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 <andrew@openedhand.com>
-+ *
-+ * 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 <balrog@zabor.org>
-+ * 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 <andrew@openedhand.com>
-+ *
-+ * 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+cvs20080307/series b/meta/packages/qemu/qemu-0.9.1+cvs20080307/series
deleted file mode 100644
index 126da8828..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/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+cvs20080307/workaround_bad_futex_headers.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/workaround_bad_futex_headers.patch
deleted file mode 100644
index cc122ebdb..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/workaround_bad_futex_headers.patch
+++ /dev/null
@@ -1,25 +0,0 @@
----
- linux-user/syscall.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
-Index: qemu/linux-user/syscall.c
-===================================================================
---- qemu.orig/linux-user/syscall.c 2007-08-09 20:28:06.000000000 +0100
-+++ qemu/linux-user/syscall.c 2007-08-09 20:28:41.000000000 +0100
-@@ -61,7 +61,15 @@
- #define tchars host_tchars /* same as target */
- #define ltchars host_ltchars /* same as target */
-
--#include <linux/futex.h>
-+#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 <linux/termios.h>
- #include <linux/unistd.h>
- #include <linux/utsname.h>
diff --git a/meta/packages/qemu/qemu-0.9.1+cvs20080307/writev_fix.patch b/meta/packages/qemu/qemu-0.9.1+cvs20080307/writev_fix.patch
deleted file mode 100644
index e0ed4af97..000000000
--- a/meta/packages/qemu/qemu-0.9.1+cvs20080307/writev_fix.patch
+++ /dev/null
@@ -1,17 +0,0 @@
----
- linux-user/syscall.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-Index: qemu-0.9.1/linux-user/syscall.c
-===================================================================
---- qemu-0.9.1.orig/linux-user/syscall.c 2008-02-03 00:00:00.000000000 +0000
-+++ qemu-0.9.1/linux-user/syscall.c 2008-02-03 00:00:38.000000000 +0000
-@@ -1048,7 +1048,7 @@ static abi_long lock_iovec(int type, str
- base = tswapl(target_vec[i].iov_base);
- vec[i].iov_len = tswapl(target_vec[i].iov_len);
- vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
-- if (!vec[i].iov_base)
-+ if (!vec[i].iov_base && vec[i].iov_len)
- goto fail;
- }
- unlock_user (target_vec, target_addr, 0);
diff --git a/meta/packages/qemu/qemu-native_cvs.bb b/meta/packages/qemu/qemu-native_cvs.bb
deleted file mode 100644
index c9db5e35b..000000000
--- a/meta/packages/qemu/qemu-native_cvs.bb
+++ /dev/null
@@ -1,2 +0,0 @@
-require qemu_cvs.bb
-require qemu-native.inc
diff --git a/meta/packages/qemu/qemu-sdk_cvs.bb b/meta/packages/qemu/qemu-sdk_cvs.bb
deleted file mode 100644
index e93e6bb75..000000000
--- a/meta/packages/qemu/qemu-sdk_cvs.bb
+++ /dev/null
@@ -1,4 +0,0 @@
-require qemu_${PV}.bb
-require qemu-sdk.inc
-
-EXTRA_OECONF += "--target-list=arm-linux-user,arm-softmmu"
diff --git a/meta/packages/qemu/qemu_cvs.bb b/meta/packages/qemu/qemu_cvs.bb
deleted file mode 100644
index f21efbc14..000000000
--- a/meta/packages/qemu/qemu_cvs.bb
+++ /dev/null
@@ -1,47 +0,0 @@
-LICENSE = "GPL"
-DEPENDS = "zlib"
-PV = "0.9.1+cvs${SRCDATE}"
-PR = "r2"
-
-FILESPATH = "${FILE_DIRNAME}/qemu-${PV}"
-FILESDIR = "${WORKDIR}"
-
-SRC_URI = "\
- cvs://anonymous@cvs.savannah.nongnu.org/sources/qemu;method=pserver;rsh=ssh;module=qemu \
- file://02_snapshot_use_tmpdir.patch;patch=1;pnum=0 \
- 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 \
- 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 \
- 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://qemu-n800-support.patch;patch=1"
-
-S = "${WORKDIR}/qemu"
-
-#EXTRA_OECONF += "--disable-sdl"
-#EXTRA_OECONF += "--target-list=arm-linux-user,arm-softmmu"
-EXTRA_OECONF += "--disable-gfx-check"
-
-inherit autotools
-
-do_configure() {
- ${S}/configure --prefix=${prefix} ${EXTRA_OECONF}
-}