diff options
Diffstat (limited to 'meta')
31 files changed, 2648 insertions, 14376 deletions
diff --git a/meta/conf/distro/poky.conf b/meta/conf/distro/poky.conf index 44b5ec797..fb176d0f9 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" -SRCREV_pn-qemu-native ?= "4027" -SRCREV_pn-qemu-sdk ?= "4027" -SRCREV_pn-qemu ?= "4027" +SRCREV_pn-qemu-native ?= "4242" +SRCREV_pn-qemu-sdk ?= "4242" +SRCREV_pn-qemu ?= "4242" SRCREV_pn-vincent ?= "246" # Previously floating revisions diff --git a/meta/packages/qemu/qemu-0.9.1+svn/02_snapshot_use_tmpdir.patch b/meta/packages/qemu/qemu-0.9.1+svn/02_snapshot_use_tmpdir.patch deleted file mode 100644 index 40264ed44..000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/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+svn/04_do_not_print_rtc_freq_if_ok.patch b/meta/packages/qemu/qemu-0.9.1+svn/04_do_not_print_rtc_freq_if_ok.patch deleted file mode 100644 index 31c9da491..000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/04_do_not_print_rtc_freq_if_ok.patch +++ /dev/null @@ -1,26 +0,0 @@ -#DPATCHLEVEL=1 ---- -# vl.c | 5 ++++- -# 1 file changed, 4 insertions(+), 1 deletion(-) -# -Index: qemu/vl.c -=================================================================== ---- qemu.orig/vl.c 2007-12-03 15:44:35.000000000 +0000 -+++ qemu/vl.c 2007-12-03 15:51:03.000000000 +0000 -@@ -1289,12 +1289,15 @@ static void hpet_stop_timer(struct qemu_ - - static int rtc_start_timer(struct qemu_alarm_timer *t) - { -+ unsigned long current_rtc_freq = 0; - int rtc_fd; - - TFR(rtc_fd = open("/dev/rtc", O_RDONLY)); - if (rtc_fd < 0) - return -1; -- if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { -+ ioctl(rtc_fd, RTC_IRQP_READ, ¤t_rtc_freq); -+ if (current_rtc_freq != RTC_FREQ && -+ ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { - fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n" - "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n" - "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n"); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/05_non-fatal_if_linux_hd_missing.patch b/meta/packages/qemu/qemu-0.9.1+svn/05_non-fatal_if_linux_hd_missing.patch index fdd922605..a66737d9c 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/05_non-fatal_if_linux_hd_missing.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/05_non-fatal_if_linux_hd_missing.patch @@ -3,12 +3,12 @@ # hw/pc.c | 1 - # 1 file changed, 1 deletion(-) # -Index: qemu/hw/pc.c +Index: trunk/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) { +--- trunk.orig/hw/pc.c 2008-04-24 20:15:46.000000000 +0100 ++++ trunk/hw/pc.c 2008-04-24 20:15:49.000000000 +0100 +@@ -399,7 +399,6 @@ + if (hda == -1) { fprintf(stderr, "A disk image must be given for 'hda' when booting " "a Linux kernel\n"); - exit(1); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/06_exit_segfault.patch b/meta/packages/qemu/qemu-0.9.1+svn/06_exit_segfault.patch index 06123d062..bc02d3183 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/06_exit_segfault.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/06_exit_segfault.patch @@ -5,9 +5,9 @@ # 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) +--- linux-user/main.c.orig 2008-04-24 20:15:46.000000000 +0100 ++++ linux-user/main.c 2008-04-24 20:15:53.000000000 +0100 +@@ -765,7 +765,7 @@ default: printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(env, stderr, fprintf, 0); @@ -16,7 +16,7 @@ Index: linux-user/main.c } process_pending_signals (env); } -@@ -1634,7 +1634,7 @@ void cpu_loop (CPUState *env) +@@ -1697,7 +1697,7 @@ default: printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(env, stderr, fprintf, 0); @@ -25,7 +25,7 @@ Index: linux-user/main.c } process_pending_signals (env); } -@@ -1954,7 +1954,7 @@ int main(int argc, char **argv) +@@ -2026,7 +2026,7 @@ for(item = cpu_log_items; item->mask != 0; item++) { printf("%-10s %s\n", item->name, item->help); } @@ -34,7 +34,7 @@ Index: linux-user/main.c } cpu_set_log(mask); } else if (!strcmp(r, "s")) { -@@ -1973,7 +1973,7 @@ int main(int argc, char **argv) +@@ -2045,7 +2045,7 @@ if (qemu_host_page_size == 0 || (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { fprintf(stderr, "page size must be a power of two\n"); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/10_signal_jobs.patch b/meta/packages/qemu/qemu-0.9.1+svn/10_signal_jobs.patch index 34282adc9..d79482d2f 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/10_signal_jobs.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/10_signal_jobs.patch @@ -5,9 +5,9 @@ # 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 +--- linux-user/signal.c.orig 2008-04-24 20:15:46.000000000 +0100 ++++ linux-user/signal.c 2008-04-24 20:15:55.000000000 +0100 +@@ -364,10 +364,15 @@ k = &sigact_table[sig - 1]; handler = k->sa._sa_handler; if (handler == TARGET_SIG_DFL) { diff --git a/meta/packages/qemu/qemu-0.9.1+svn/11_signal_sigaction.patch b/meta/packages/qemu/qemu-0.9.1+svn/11_signal_sigaction.patch index 33c5e8b12..cd56541b7 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/11_signal_sigaction.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/11_signal_sigaction.patch @@ -5,9 +5,9 @@ # 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 +--- linux-user/signal.c.orig 2008-04-24 20:15:55.000000000 +0100 ++++ linux-user/signal.c 2008-04-24 20:15:57.000000000 +0100 +@@ -512,6 +512,11 @@ if (sig < 1 || sig > TARGET_NSIG || sig == SIGKILL || sig == SIGSTOP) return -EINVAL; diff --git a/meta/packages/qemu/qemu-0.9.1+svn/22_net_tuntap_stall.patch b/meta/packages/qemu/qemu-0.9.1+svn/22_net_tuntap_stall.patch index 6017df0f6..0e1038983 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/22_net_tuntap_stall.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/22_net_tuntap_stall.patch @@ -5,9 +5,9 @@ # 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 +--- vl.c.orig 2008-04-24 20:15:46.000000000 +0100 ++++ vl.c 2008-04-24 20:15:58.000000000 +0100 +@@ -4155,7 +4155,7 @@ return -1; } memset(&ifr, 0, sizeof(ifr)); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/31_syscalls.patch b/meta/packages/qemu/qemu-0.9.1+svn/31_syscalls.patch index 95a7332ee..15565ae11 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/31_syscalls.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/31_syscalls.patch @@ -5,9 +5,9 @@ # 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 +--- linux-user/syscall.c.orig 2008-04-24 20:15:46.000000000 +0100 ++++ linux-user/syscall.c 2008-04-24 20:15:59.000000000 +0100 +@@ -250,6 +250,7 @@ extern int setresgid(gid_t, gid_t, gid_t); extern int getresgid(gid_t *, gid_t *, gid_t *); extern int setgroups(int, gid_t *); @@ -15,7 +15,7 @@ Index: linux-user/syscall.c #define ERRNO_TABLE_SIZE 1200 -@@ -4024,7 +4025,8 @@ abi_long do_syscall(void *cpu_env, int n +@@ -4041,7 +4042,8 @@ #endif #ifdef TARGET_NR_uselib case TARGET_NR_uselib: @@ -25,7 +25,7 @@ Index: linux-user/syscall.c #endif #ifdef TARGET_NR_swapon case TARGET_NR_swapon: -@@ -5289,7 +5291,9 @@ abi_long do_syscall(void *cpu_env, int n +@@ -5322,7 +5324,9 @@ goto unimplemented; #ifdef TARGET_NR_mincore case TARGET_NR_mincore: @@ -36,7 +36,7 @@ Index: linux-user/syscall.c #endif #ifdef TARGET_NR_madvise case TARGET_NR_madvise: -@@ -5429,7 +5433,8 @@ abi_long do_syscall(void *cpu_env, int n +@@ -5462,7 +5466,8 @@ break; #ifdef TARGET_NR_readahead case TARGET_NR_readahead: diff --git a/meta/packages/qemu/qemu-0.9.1+svn/32_syscall_sysctl.patch b/meta/packages/qemu/qemu-0.9.1+svn/32_syscall_sysctl.patch index 5e8dd75b0..d42c44ceb 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/32_syscall_sysctl.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/32_syscall_sysctl.patch @@ -5,8 +5,8 @@ # 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 +--- linux-user/syscall.c.orig 2008-04-24 20:15:59.000000000 +0100 ++++ linux-user/syscall.c 2008-04-24 20:16:01.000000000 +0100 @@ -52,6 +52,7 @@ //#include <sys/user.h> #include <netinet/ip.h> @@ -15,7 +15,7 @@ Index: linux-user/syscall.c #define termios host_termios #define winsize host_winsize -@@ -4739,9 +4740,34 @@ abi_long do_syscall(void *cpu_env, int n +@@ -4758,9 +4759,34 @@ break; #endif case TARGET_NR__sysctl: diff --git a/meta/packages/qemu/qemu-0.9.1+svn/33_syscall_ppc_clone.patch b/meta/packages/qemu/qemu-0.9.1+svn/33_syscall_ppc_clone.patch index 3f733b6ab..962f82152 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/33_syscall_ppc_clone.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/33_syscall_ppc_clone.patch @@ -5,9 +5,9 @@ # 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 +--- linux-user/syscall.c.orig 2008-04-24 20:16:01.000000000 +0100 ++++ linux-user/syscall.c 2008-04-24 20:16:02.000000000 +0100 +@@ -2760,11 +2760,7 @@ if (!newsp) newsp = env->gpr[1]; new_env->gpr[1] = newsp; diff --git a/meta/packages/qemu/qemu-0.9.1+svn/39_syscall_fadvise64.patch b/meta/packages/qemu/qemu-0.9.1+svn/39_syscall_fadvise64.patch index 54ee3e094..845232cfc 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/39_syscall_fadvise64.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/39_syscall_fadvise64.patch @@ -4,9 +4,9 @@ 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 +--- linux-user/syscall.c.orig 2008-04-24 20:16:02.000000000 +0100 ++++ linux-user/syscall.c 2008-04-24 20:16:03.000000000 +0100 +@@ -5350,6 +5350,12 @@ ret = get_errno(mincore((void*)arg1, (size_t)arg2, (unsigned char*)arg3)); break; #endif diff --git a/meta/packages/qemu/qemu-0.9.1+svn/41_arm_fpa_sigfpe.patch b/meta/packages/qemu/qemu-0.9.1+svn/41_arm_fpa_sigfpe.patch deleted file mode 100644 index cea3afc7f..000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/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+svn/52_ne2000_return.patch b/meta/packages/qemu/qemu-0.9.1+svn/52_ne2000_return.patch index e4ea33f2c..e364bff73 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/52_ne2000_return.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/52_ne2000_return.patch @@ -2,11 +2,11 @@ hw/ne2000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -Index: qemu/hw/ne2000.c +Index: trunk/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 +--- trunk.orig/hw/ne2000.c 2008-04-24 20:15:46.000000000 +0100 ++++ trunk/hw/ne2000.c 2008-04-24 20:16:05.000000000 +0100 +@@ -217,7 +217,7 @@ NE2000State *s = opaque; if (s->cmd & E8390_STOP) diff --git a/meta/packages/qemu/qemu-0.9.1+svn/61_safe_64bit_int.patch b/meta/packages/qemu/qemu-0.9.1+svn/61_safe_64bit_int.patch index 9b1ace81a..9a67feac6 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/61_safe_64bit_int.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/61_safe_64bit_int.patch @@ -5,8 +5,8 @@ # 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 +--- dyngen-exec.h.orig 2008-04-24 20:15:46.000000000 +0100 ++++ dyngen-exec.h 2008-04-24 20:16:06.000000000 +0100 @@ -38,7 +38,7 @@ // Linux/Sparc64 defines uint64_t #if !(defined (__sparc_v9__) && defined(__linux__)) diff --git a/meta/packages/qemu/qemu-0.9.1+svn/63_sparc_build.patch b/meta/packages/qemu/qemu-0.9.1+svn/63_sparc_build.patch index 37b38f641..097f55a09 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/63_sparc_build.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/63_sparc_build.patch @@ -5,9 +5,9 @@ # 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) +--- sparc.ld.orig 2008-04-24 20:15:46.000000000 +0100 ++++ sparc.ld 2008-04-24 20:16:07.000000000 +0100 +@@ -6,7 +6,7 @@ SECTIONS { /* Read-only sections, merged into text segment: */ diff --git a/meta/packages/qemu/qemu-0.9.1+svn/64_ppc_asm_constraints.patch b/meta/packages/qemu/qemu-0.9.1+svn/64_ppc_asm_constraints.patch index e4858b79d..7d1981727 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/64_ppc_asm_constraints.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/64_ppc_asm_constraints.patch @@ -3,11 +3,11 @@ # cpu-all.h | 2 +- # 1 file changed, 1 insertion(+), 1 deletion(-) # -Index: qemu/cpu-all.h +Index: trunk/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 +--- trunk.orig/cpu-all.h 2008-04-24 20:15:46.000000000 +0100 ++++ trunk/cpu-all.h 2008-04-24 20:16:08.000000000 +0100 +@@ -285,7 +285,7 @@ static inline void stl_le_p(void *ptr, int v) { #ifdef __powerpc__ diff --git a/meta/packages/qemu/qemu-0.9.1+svn/65_kfreebsd.patch b/meta/packages/qemu/qemu-0.9.1+svn/65_kfreebsd.patch index dfece800a..028e85a87 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/65_kfreebsd.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/65_kfreebsd.patch @@ -5,9 +5,9 @@ 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 +--- configure.orig 2008-04-24 20:15:46.000000000 +0100 ++++ configure 2008-04-24 20:16:09.000000000 +0100 +@@ -135,6 +135,12 @@ kqemu="yes" fi ;; @@ -22,8 +22,8 @@ Index: configure 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 +--- vl.c.orig 2008-04-24 20:15:58.000000000 +0100 ++++ vl.c 2008-04-24 20:16:09.000000000 +0100 @@ -97,6 +97,8 @@ #include <stropts.h> #endif diff --git a/meta/packages/qemu/qemu-0.9.1+svn/66_tls_ld.patch b/meta/packages/qemu/qemu-0.9.1+svn/66_tls_ld.patch index 54e02eff8..cbd3f873d 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/66_tls_ld.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/66_tls_ld.patch @@ -5,9 +5,9 @@ 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 +--- arm.ld.orig 2008-04-24 20:15:45.000000000 +0100 ++++ arm.ld 2008-04-24 20:16:11.000000000 +0100 +@@ -26,6 +26,10 @@ { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } @@ -18,7 +18,7 @@ Index: arm.ld .rel.got : { *(.rel.got) } .rela.got : { *(.rela.got) } .rel.ctors : { *(.rel.ctors) } -@@ -58,6 +62,9 @@ SECTIONS +@@ -58,6 +62,9 @@ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; .reginfo : { *(.reginfo) } @@ -30,9 +30,9 @@ Index: arm.ld . = 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 +--- i386.ld.orig 2008-04-24 20:15:45.000000000 +0100 ++++ i386.ld 2008-04-24 20:16:11.000000000 +0100 +@@ -28,6 +28,10 @@ { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } @@ -43,7 +43,7 @@ Index: i386.ld .rel.got : { *(.rel.got) } .rela.got : { *(.rela.got) } .rel.ctors : { *(.rel.ctors) } -@@ -53,6 +57,9 @@ SECTIONS +@@ -53,6 +57,9 @@ _etext = .; PROVIDE (etext = .); .fini : { *(.fini) } =0x47ff041f diff --git a/meta/packages/qemu/qemu-0.9.1+svn/91-oh-sdl-cursor.patch b/meta/packages/qemu/qemu-0.9.1+svn/91-oh-sdl-cursor.patch index 0d60c1c30..b3d95a453 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/91-oh-sdl-cursor.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/91-oh-sdl-cursor.patch @@ -5,9 +5,9 @@ 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) +--- sdl.c.orig 2008-04-24 20:15:45.000000000 +0100 ++++ sdl.c 2008-04-24 20:16:12.000000000 +0100 +@@ -247,7 +247,7 @@ if (kbd_mouse_is_absolute()) { SDL_ShowCursor(1); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/fix_brk.patch b/meta/packages/qemu/qemu-0.9.1+svn/fix_brk.patch index 783198d9e..f15e001dd 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/fix_brk.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/fix_brk.patch @@ -1,6 +1,8 @@ ---- qemu/linux-user/syscall.c1 (revision 16) -+++ qemu/linux-user/syscall.c (working copy) -@@ -441,7 +441,7 @@ +Index: trunk/linux-user/syscall.c +=================================================================== +--- trunk.orig/linux-user/syscall.c 2008-04-24 20:16:24.000000000 +0100 ++++ trunk/linux-user/syscall.c 2008-04-24 20:16:32.000000000 +0100 +@@ -440,7 +440,7 @@ if (!new_brk) return target_brk; if (new_brk < target_original_brk) @@ -9,7 +11,7 @@ brk_page = HOST_PAGE_ALIGN(target_brk); -@@ -456,12 +456,11 @@ +@@ -455,12 +455,11 @@ mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); @@ -26,9 +28,11 @@ } static inline abi_long copy_from_user_fdset(fd_set *fds, ---- qemu/linux-user/mmap.c1 (revision 16) -+++ qemu/linux-user/mmap.c (working copy) -@@ -260,6 +259,9 @@ +Index: trunk/linux-user/mmap.c +=================================================================== +--- trunk.orig/linux-user/mmap.c 2008-04-24 20:16:16.000000000 +0100 ++++ trunk/linux-user/mmap.c 2008-04-24 20:16:32.000000000 +0100 +@@ -264,6 +264,9 @@ host_start += offset - host_offset; start = h2g(host_start); } else { @@ -38,7 +42,7 @@ if (start & ~TARGET_PAGE_MASK) { errno = EINVAL; return -1; -@@ -267,6 +269,14 @@ +@@ -271,6 +274,14 @@ end = start + len; real_end = HOST_PAGE_ALIGN(end); diff --git a/meta/packages/qemu/qemu-0.9.1+svn/fix_segfault.patch b/meta/packages/qemu/qemu-0.9.1+svn/fix_segfault.patch index 443c33065..224a8b813 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/fix_segfault.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/fix_segfault.patch @@ -2,11 +2,11 @@ linux-user/syscall.c | 22 ---------------------- 1 file changed, 22 deletions(-) -Index: qemu/linux-user/syscall.c +Index: trunk/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 +--- trunk.orig/linux-user/syscall.c 2008-04-24 20:16:21.000000000 +0100 ++++ trunk/linux-user/syscall.c 2008-04-24 20:16:24.000000000 +0100 +@@ -5728,28 +5728,6 @@ goto unimplemented_nowarn; #endif diff --git a/meta/packages/qemu/qemu-0.9.1+svn/no-strip.patch b/meta/packages/qemu/qemu-0.9.1+svn/no-strip.patch index fc69b37e1..4813dd4e2 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/no-strip.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/no-strip.patch @@ -1,6 +1,8 @@ ---- 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 @@ +Index: trunk/Makefile +=================================================================== +--- trunk.orig/Makefile 2008-04-24 20:15:37.000000000 +0100 ++++ trunk/Makefile 2008-04-24 20:16:30.000000000 +0100 +@@ -196,7 +196,7 @@ install: all $(if $(BUILD_DOCS),install-doc) mkdir -p "$(DESTDIR)$(bindir)" ifneq ($(TOOLS),) @@ -8,10 +10,12 @@ + $(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 @@ + set -e; for x in bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \ +Index: trunk/Makefile.target +=================================================================== +--- trunk.orig/Makefile.target 2008-04-24 20:15:37.000000000 +0100 ++++ trunk/Makefile.target 2008-04-24 20:16:30.000000000 +0100 +@@ -685,7 +685,7 @@ install: all ifneq ($(PROGS),) @@ -19,4 +23,4 @@ + $(INSTALL) -m 755 $(PROGS) "$(DESTDIR)$(bindir)" endif - ifneq ($(wildcard .depend),) + # Include automatically generated dependency files diff --git a/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl-update.patch b/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl-update.patch deleted file mode 100644 index ebc996e87..000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/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+svn/qemu-0.9.0-nptl.patch b/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch index 4a87d8d63..ac68ebf46 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/qemu-0.9.0-nptl.patch @@ -1,19 +1,3 @@ -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 ------------------------------------------ @@ -27,11 +11,11 @@ See also http://lists.gnu.org/archive/html/qemu-devel/2006-09/msg00194.html target-arm/translate.c | 9 ++ 10 files changed, 405 insertions(+), 183 deletions(-) -Index: qemu/configure +Index: trunk/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 @@ +--- trunk.orig/configure 2008-04-24 20:16:52.000000000 +0100 ++++ trunk/configure 2008-04-24 20:16:53.000000000 +0100 +@@ -112,6 +112,7 @@ build_docs="no" uname_release="" curses="yes" @@ -39,7 +23,7 @@ Index: qemu/configure # OS specific targetos=`uname -s` -@@ -334,6 +335,8 @@ +@@ -339,6 +340,8 @@ ;; *) echo "ERROR: unknown option $opt"; show_help="yes" ;; @@ -48,7 +32,7 @@ Index: qemu/configure esac done -@@ -429,6 +432,7 @@ +@@ -436,6 +439,7 @@ echo " --disable-linux-user disable all linux usermode emulation targets" echo " --enable-darwin-user enable all darwin usermode emulation targets" echo " --disable-darwin-user disable all darwin usermode emulation targets" @@ -56,7 +40,7 @@ Index: qemu/configure 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 @@ +@@ -647,6 +651,23 @@ } EOF @@ -80,7 +64,7 @@ Index: qemu/configure ########################################## # SDL probe -@@ -778,6 +799,7 @@ +@@ -845,6 +866,7 @@ echo "Documentation $build_docs" [ ! -z "$uname_release" ] && \ echo "uname -r $uname_release" @@ -88,24 +72,48 @@ Index: qemu/configure 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 +@@ -1228,6 +1250,9 @@ + echo "#define TARGET_ARM 1" >> $config_h + echo "#define CONFIG_NO_DYNGEN_OP 1" >> $config_h + bflt="yes" ++ if test "$nptl" = "yes" ; then ++ echo "#define USE_NPTL 1" >> $config_h ++ fi + ;; + cris) + echo "TARGET_ARCH=cris" >> $config_mak +Index: trunk/exec-all.h =================================================================== ---- 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 @@ +--- trunk.orig/exec-all.h 2008-04-24 20:16:41.000000000 +0100 ++++ trunk/exec-all.h 2008-04-24 20:16:53.000000000 +0100 +@@ -303,217 +303,7 @@ extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; +-#if defined(__hppa__) +- +-typedef int spinlock_t[4]; +- +-#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } +- +-static inline void resetlock (spinlock_t *p) +-{ +- (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; +-} +- +-#else +- +-typedef int spinlock_t; +- +-#define SPIN_LOCK_UNLOCKED 0 +- +-static inline void resetlock (spinlock_t *p) +-{ +- *p = SPIN_LOCK_UNLOCKED; +-} +- +-#endif +- -#if defined(__powerpc__) -static inline int testandset (int *p) -{ @@ -205,6 +213,33 @@ Index: qemu/exec-all.h - : "cc","memory"); - return ret; -} +-#elif defined(__hppa__) +- +-/* Because malloc only guarantees 8-byte alignment for malloc'd data, +- and GCC only guarantees 8-byte alignment for stack locals, we can't +- be assured of 16-byte alignment for atomic lock data even if we +- specify "__attribute ((aligned(16)))" in the type declaration. So, +- we use a struct containing an array of four ints for the atomic lock +- type and dynamically select the 16-byte aligned int from the array +- for the semaphore. */ +-#define __PA_LDCW_ALIGNMENT 16 +-static inline void *ldcw_align (void *p) { +- unsigned long a = (unsigned long)p; +- a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); +- return (void *)a; +-} +- +-static inline int testandset (spinlock_t *p) +-{ +- unsigned int ret; +- p = ldcw_align(p); +- __asm__ __volatile__("ldcw 0(%1),%0" +- : "=r" (ret) +- : "r" (p) +- : "memory" ); +- return !ret; +-} +- -#elif defined(__ia64) - -#include <ia64intrin.h> @@ -237,10 +272,6 @@ Index: qemu/exec-all.h -#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) -{ @@ -249,7 +280,7 @@ Index: qemu/exec-all.h - -static inline void spin_unlock(spinlock_t *lock) -{ -- *lock = 0; +- resetlock(lock); -} - -static inline int spin_trylock(spinlock_t *lock) @@ -274,10 +305,10 @@ Index: qemu/exec-all.h extern spinlock_t tb_lock; -Index: qemu/linux-user/arm/syscall.h +Index: trunk/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 +--- trunk.orig/linux-user/arm/syscall.h 2008-04-24 20:16:41.000000000 +0100 ++++ trunk/linux-user/arm/syscall.h 2008-04-24 20:16:53.000000000 +0100 @@ -28,7 +28,9 @@ #define ARM_SYSCALL_BASE 0x900000 #define ARM_THUMB_SYSCALL 0 @@ -289,11 +320,11 @@ Index: qemu/linux-user/arm/syscall.h #define ARM_NR_semihosting 0x123456 #define ARM_NR_thumb_semihosting 0xAB -Index: qemu/linux-user/main.c +Index: trunk/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 @@ +--- trunk.orig/linux-user/main.c 2008-04-24 20:16:47.000000000 +0100 ++++ trunk/linux-user/main.c 2008-04-24 20:17:38.000000000 +0100 +@@ -365,6 +365,50 @@ } } @@ -325,7 +356,7 @@ Index: qemu/linux-user/main.c + 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; @@ -344,7 +375,7 @@ Index: qemu/linux-user/main.c void cpu_loop(CPUARMState *env) { int trapnr; -@@ -474,10 +518,8 @@ +@@ -475,10 +519,8 @@ } } @@ -357,7 +388,7 @@ Index: qemu/linux-user/main.c 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 @@ +@@ -489,14 +531,34 @@ n -= ARM_SYSCALL_BASE; env->eabi = 0; } @@ -400,7 +431,7 @@ Index: qemu/linux-user/main.c } else { goto error; } -@@ -534,6 +596,10 @@ +@@ -535,6 +597,10 @@ } } break; @@ -411,7 +442,19 @@ Index: qemu/linux-user/main.c default: error: fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", -@@ -2402,6 +2468,10 @@ +@@ -1994,6 +2060,11 @@ + int drop_ld_preload = 0, environ_count = 0; + char **target_environ, **wrk, **dst; + ++ char *assume_kernel = getenv("QEMU_ASSUME_KERNEL"); ++ ++ if (assume_kernel) ++ setenv("LD_ASSUME_KERNEL", assume_kernel, 1); ++ + if (argc <= 1) + usage(); + +@@ -2403,6 +2474,10 @@ ts->heap_base = info->brk; /* This will be filled in on the first SYS_HEAPINFO call. */ ts->heap_limit = 0; @@ -422,10 +465,10 @@ Index: qemu/linux-user/main.c #endif if (gdbstub_port) { -Index: qemu/linux-user/qemu.h +Index: trunk/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 +--- trunk.orig/linux-user/qemu.h 2008-04-24 20:16:41.000000000 +0100 ++++ trunk/linux-user/qemu.h 2008-04-24 20:16:53.000000000 +0100 @@ -107,6 +107,9 @@ uint32_t heap_base; uint32_t heap_limit; @@ -436,11 +479,19 @@ Index: qemu/linux-user/qemu.h int used; /* non zero if used */ struct image_info *info; uint8_t stack[0]; -Index: qemu/linux-user/syscall.c +Index: trunk/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 @@ +--- trunk.orig/linux-user/syscall.c 2008-04-24 20:16:50.000000000 +0100 ++++ trunk/linux-user/syscall.c 2008-04-24 20:19:52.000000000 +0100 +@@ -61,6 +61,7 @@ + #define tchars host_tchars /* same as target */ + #define ltchars host_ltchars /* same as target */ + ++#include <linux/futex.h> + #include <linux/termios.h> + #include <linux/unistd.h> + #include <linux/utsname.h> +@@ -71,9 +72,18 @@ #include <linux/kd.h> #include "qemu.h" @@ -459,7 +510,14 @@ Index: qemu/linux-user/syscall.c #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 @@ +@@ -2695,16 +2705,25 @@ + return 0; + } + #endif +- + #endif /* defined(TARGET_I386) */ + + /* this stack is the equivalent of the kernel stack associated with a thread/process */ #define NEW_STACK_SIZE 8192 @@ -479,7 +537,7 @@ Index: qemu/linux-user/syscall.c cpu_loop(env); /* never exits */ return 0; -@@ -2712,13 +2731,22 @@ +@@ -2712,15 +2731,27 @@ /* do_fork() Must return host values and target errnos (unlike most do_*() functions). */ @@ -492,18 +550,53 @@ Index: qemu/linux-user/syscall.c 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)); -@@ -2784,16 +2812,67 @@ + new_stack = ts->stack; + ts->used = 1; +@@ -2732,6 +2763,29 @@ + #if defined(TARGET_I386) + if (!newsp) + newsp = env->regs[R_ESP]; ++ new_gdt_table = malloc(9 * 8); ++ if (!new_gdt_table) { ++ free(new_env); ++ return -ENOMEM; ++ } ++ /* Copy main GDT table from parent, but clear TLS entries */ ++ memcpy(new_gdt_table, g2h(env->gdt.base), 6 * 8); ++ memset(&new_gdt_table[6], 0, 3 * 8); ++ new_env->gdt.base = h2g(new_gdt_table); ++ if (flags & 0x00080000 /* CLONE_SETTLS */) { ++ ret = do_set_thread_area(new_env, new_env->regs[R_ESI]); ++ if (ret) { ++ free(new_gdt_table); ++ free(new_env); ++ return ret; ++ } ++ } ++ cpu_x86_load_seg(env, R_CS, new_env->regs[R_CS]); ++ cpu_x86_load_seg(env, R_DS, new_env->regs[R_DS]); ++ cpu_x86_load_seg(env, R_ES, new_env->regs[R_ES]); ++ cpu_x86_load_seg(env, R_SS, new_env->regs[R_SS]); ++ cpu_x86_load_seg(env, R_FS, new_env->regs[R_FS]); ++ cpu_x86_load_seg(env, R_GS, new_env->regs[R_GS]); + new_env->regs[R_ESP] = newsp; + new_env->regs[R_EAX] = 0; + #elif defined(TARGET_ARM) +@@ -2784,16 +2838,67 @@ #error unsupported target CPU #endif new_env->opaque = ts; @@ -572,7 +665,85 @@ Index: qemu/linux-user/syscall.c } return ret; } -@@ -3118,7 +3197,7 @@ +@@ -3052,6 +3157,68 @@ + unlock_user_struct(target_ts, target_addr, 1); + } + ++static long do_futex(target_ulong uaddr, int op, uint32_t val, ++ target_ulong utime, target_ulong uaddr2, ++ uint32_t val3) ++{ ++ struct timespec host_utime; ++ unsigned long val2 = utime; ++ ++ if (utime && (op == FUTEX_WAIT || op == FUTEX_LOCK_PI)) { ++ target_to_host_timespec(&host_utime, utime); ++ val2 = (unsigned long)&host_utime; ++ } ++ ++#ifdef BSWAP_NEEDED ++ switch(op) { ++ case FUTEX_CMP_REQUEUE: ++ val3 = tswap32(val3); ++ case FUTEX_REQUEUE: ++ val2 = tswap32(val2); ++ case FUTEX_WAIT: ++ case FUTEX_WAKE: ++ val = tswap32(val); ++ case FUTEX_LOCK_PI: /* This one's icky, but comes out OK */ ++ case FUTEX_UNLOCK_PI: ++ break; ++ default: ++ gemu_log("qemu: Unsupported futex op %d\n", op); ++ return -ENOSYS; ++ } ++#if 0 /* No, it's worse than this */ ++ if (op == FUTEX_WAKE_OP) { ++ /* Need to munge the secondary operation (val3) */ ++ val3 = tswap32(val3); ++ int op2 = (val3 >> 28) & 7; ++ int cmp = (val3 >> 24) & 15; ++ int oparg = (val3 << 8) >> 20; ++ int cmparg = (val3 << 20) >> 20; ++ int shift = val3 & (FUTEX_OP_OPARG_SHIFT << 28); ++ ++ if (shift) ++ oparg = (oparg & 7) + 24 - (oparg & 24); ++ else oparg = ++ if (op2 == FUTEX_OP_ADD) { ++ gemu_log("qemu: Unsupported wrong-endian FUTEX_OP_ADD\n"); ++ return -ENOSYS; ++ } ++ if (cmparg == FUTEX_OP_CMP_LT || cmparg == FUTEX_OP_CMP_GE || ++ cmparg == FUTEX_OP_CMP_LE || cmparg == FUTEX_OP_CMP_GT) { ++ gemu_log("qemu: Unsupported wrong-endian futex cmparg %d\n", cmparg); ++ return -ENOSYS; ++ } ++ val3 = shift | (op2<<28) | (cmp<<24) | (oparg<<12) | cmparg; ++ } ++#endif ++#endif ++ return syscall(__NR_futex, g2h(uaddr), op, val, val2, g2h(uaddr2), val3); ++} ++ ++int do_set_tid_address(target_ulong tidptr) ++{ ++ return syscall(__NR_set_tid_address, g2h(tidptr)); ++} ++ + /* do_syscall() should always have a single exit point at the end so + that actions, such as logging of syscall results, can be performed. + All errnos that do_syscall() returns must be -TARGET_<errcode>. */ +@@ -3076,7 +3243,7 @@ + _mcleanup(); + #endif + gdb_exit(cpu_env, arg1); +- /* XXX: should free thread stack and CPU env */ ++ /* XXX: should free thread stack, GDT and CPU env */ + _exit(arg1); + ret = 0; /* avoid warning */ + break; +@@ -3118,7 +3285,7 @@ ret = do_brk(arg1); break; case TARGET_NR_fork: @@ -581,7 +752,7 @@ Index: qemu/linux-user/syscall.c break; #ifdef TARGET_NR_waitpid case TARGET_NR_waitpid: -@@ -4481,7 +4560,8 @@ +@@ -4482,7 +4649,8 @@ ret = get_errno(fsync(arg1)); break; case TARGET_NR_clone: @@ -591,7 +762,7 @@ Index: qemu/linux-user/syscall.c break; #ifdef __NR_exit_group /* new thread calls */ -@@ -4928,7 +5008,8 @@ +@@ -4943,7 +5111,8 @@ #endif #ifdef TARGET_NR_vfork case TARGET_NR_vfork: @@ -601,11 +772,34 @@ Index: qemu/linux-user/syscall.c break; #endif #ifdef TARGET_NR_ugetrlimit -Index: qemu/qemu_spinlock.h +@@ -5521,6 +5690,9 @@ + #elif defined(TARGET_I386) && defined(TARGET_ABI32) + ret = do_set_thread_area(cpu_env, arg1); + break; ++#elif TARGET_i386 ++ ret = get_errno(do_set_thread_area(cpu_env, arg1)); ++ break; + #else + goto unimplemented_nowarn; + #endif +@@ -5538,6 +5710,12 @@ + goto unimplemented_nowarn; + #endif + ++#ifdef TARGET_NR_futex ++ case TARGET_NR_futex: ++ ret = get_errno(do_futex(arg1, arg2, arg3, arg4, arg5, arg6)); ++ break; ++#endif ++ + #ifdef TARGET_NR_clock_gettime + case TARGET_NR_clock_gettime: + { +Index: trunk/qemu_spinlock.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ qemu/qemu_spinlock.h 2008-04-09 23:05:55.000000000 +0100 -@@ -0,0 +1,181 @@ ++++ trunk/qemu_spinlock.h 2008-04-24 20:16:53.000000000 +0100 +@@ -0,0 +1,250 @@ +/* + * Atomic operation helper include + * @@ -743,6 +937,33 @@ Index: qemu/qemu_spinlock.h +} +#endif + ++#ifdef __hppa__ ++/* Because malloc only guarantees 8-byte alignment for malloc'd data, ++ and GCC only guarantees 8-byte alignment for stack locals, we can't ++ be assured of 16-byte alignment for atomic lock data even if we ++ specify "__attribute ((aligned(16)))" in the type declaration. So, ++ we use a struct containing an array of four ints for the atomic lock ++ type and dynamically select the 16-byte aligned int from the array ++ for the semaphore. */ ++#define __PA_LDCW_ALIGNMENT 16 ++static inline void *ldcw_align (void *p) { ++ unsigned long a = (unsigned long)p; ++ a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); ++ return (void *)a; ++} ++ ++static inline int testandset (spinlock_t *p) ++{ ++ unsigned int ret; ++ p = ldcw_align(p); ++ __asm__ __volatile__("ldcw 0(%1),%0" ++ : "=r" (ret) ++ : "r" (p) ++ : "memory" ); ++ return !ret; ++} ++#endif ++ +#ifdef __ia64 +#include <ia64intrin.h> + @@ -752,10 +973,52 @@ Index: qemu/qemu_spinlock.h +} +#endif + ++#ifdef __mips__ ++static inline int testandset (int *p) ++{ ++ int ret; ++ ++ __asm__ __volatile__ ( ++ " .set push \n" ++ " .set noat \n" ++ " .set mips2 \n" ++ "1: li $1, 1 \n" ++ " ll %0, %1 \n" ++ " sc $1, %1 \n" ++ " beqz $1, 1b \n" ++ " .set pop " ++ : "=r" (ret), "+R" (*p) ++ : ++ : "memory"); ++ ++ return ret; ++} ++#endif ++ ++#if defined(__hppa__) ++ ++typedef int spinlock_t[4]; ++ ++#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } ++ ++static inline void resetlock (spinlock_t *p) ++{ ++ (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; ++} ++ ++#else ++ +typedef int spinlock_t; + +#define SPIN_LOCK_UNLOCKED 0 + ++static inline void resetlock (spinlock_t *p) ++{ ++ *p = SPIN_LOCK_UNLOCKED; ++} ++ ++#endif ++ +#if defined(CONFIG_USER_ONLY) +static inline void spin_lock(spinlock_t *lock) +{ @@ -764,7 +1027,7 @@ Index: qemu/qemu_spinlock.h + +static inline void spin_unlock(spinlock_t *lock) +{ -+ *lock = 0; ++ resetlock(lock); +} + +static inline int spin_trylock(spinlock_t *lock) @@ -787,10 +1050,10 @@ Index: qemu/qemu_spinlock.h +#endif + +#endif -Index: qemu/target-arm/cpu.h +Index: trunk/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 +--- trunk.orig/target-arm/cpu.h 2008-04-24 20:16:41.000000000 +0100 ++++ trunk/target-arm/cpu.h 2008-04-24 20:16:53.000000000 +0100 @@ -38,6 +38,7 @@ #define EXCP_FIQ 6 #define EXCP_BKPT 7 @@ -799,7 +1062,7 @@ Index: qemu/target-arm/cpu.h #define ARMV7M_EXCP_RESET 1 #define ARMV7M_EXCP_NMI 2 -@@ -222,6 +223,15 @@ +@@ -218,6 +219,15 @@ void cpu_lock(void); void cpu_unlock(void); @@ -815,36 +1078,19 @@ Index: qemu/target-arm/cpu.h #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 +Index: trunk/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(); +--- trunk.orig/target-arm/translate.c 2008-04-24 20:16:41.000000000 +0100 ++++ trunk/target-arm/translate.c 2008-04-24 20:16:53.000000000 +0100 +@@ -8606,7 +8606,14 @@ + gen_exception(EXCP_EXCEPTION_EXIT); } #endif - +#ifdef CONFIG_USER_ONLY + /* Intercept jump to the magic kernel page. */ + if (dc->pc > 0xffff0000) { -+ gen_op_kernel_trap(); ++ gen_exception(EXCP_KERNEL_TRAP); + dc->is_jmp = DISAS_UPDATE; + break; + } diff --git a/meta/packages/qemu/qemu-0.9.1+svn/qemu-amd64-32b-mapping-0.9.0.patch b/meta/packages/qemu/qemu-0.9.1+svn/qemu-amd64-32b-mapping-0.9.0.patch index c7f36d811..02f093abb 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/qemu-amd64-32b-mapping-0.9.0.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/qemu-amd64-32b-mapping-0.9.0.patch @@ -2,10 +2,10 @@ linux-user/mmap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) -Index: qemu/linux-user/mmap.c +Index: trunk/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 +--- trunk.orig/linux-user/mmap.c 2008-04-24 20:15:37.000000000 +0100 ++++ trunk/linux-user/mmap.c 2008-04-24 20:16:16.000000000 +0100 @@ -29,6 +29,10 @@ //#define DEBUG_MMAP @@ -17,7 +17,7 @@ Index: qemu/linux-user/mmap.c /* NOTE: all the constants are the HOST ones, but addresses are target. */ int target_mprotect(abi_ulong start, abi_ulong len, int prot) { -@@ -251,7 +255,7 @@ abi_long target_mmap(abi_ulong start, ab +@@ -251,7 +255,7 @@ especially important if qemu_host_page_size > qemu_real_host_page_size */ p = mmap(g2h(mmap_start), @@ -26,7 +26,7 @@ Index: qemu/linux-user/mmap.c 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 +@@ -406,7 +410,7 @@ unsigned long host_addr; /* XXX: use 5 args syscall */ diff --git a/meta/packages/qemu/qemu-0.9.1+svn/qemu-n800-support.patch b/meta/packages/qemu/qemu-0.9.1+svn/qemu-n800-support.patch index b1b6649ef..1224fb4cb 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/qemu-n800-support.patch +++ b/meta/packages/qemu/qemu-0.9.1+svn/qemu-n800-support.patch @@ -1,53 +1,7 @@ -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; +diff -urN 4242/cpu-all.h qemu-omap/cpu-all.h +--- 4242/cpu-all.h 2008-04-24 21:26:19.000000000 +0100 ++++ qemu-omap/cpu-all.h 2008-04-23 09:57:55.000000000 +0100 +@@ -816,7 +816,7 @@ /* physical memory access */ #define TLB_INVALID_MASK (1 << 3) #define IO_MEM_SHIFT 4 @@ -56,11 +10,10 @@ index 7a7e655..c7c9611 100644 #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, +diff -urN 4242/exec.c qemu-omap/exec.c +--- 4242/exec.c 2008-04-24 18:11:49.000000000 +0100 ++++ qemu-omap/exec.c 2008-04-23 09:57:55.000000000 +0100 +@@ -1664,7 +1664,7 @@ { if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { /* IO memory case */ @@ -69,7 +22,7 @@ index e9a5918..c69f742 100644 addend = paddr; } else { /* standard memory */ -@@ -1692,7 +1692,9 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, +@@ -1698,7 +1698,9 @@ } else { te->addr_read = -1; } @@ -80,7 +33,7 @@ index e9a5918..c69f742 100644 te->addr_code = address; } else { te->addr_code = -1; -@@ -2487,7 +2489,9 @@ int cpu_register_io_memory(int io_index, +@@ -2493,7 +2495,9 @@ if (io_index <= 0) { if (io_mem_nb >= IO_MEM_NB_ENTRIES) return -1; @@ -91,2147 +44,10 @@ index e9a5918..c69f742 100644 } 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) +diff -urN 4242/hw/max7310.c qemu-omap/hw/max7310.c +--- 4242/hw/max7310.c 2008-04-24 18:11:49.000000000 +0100 ++++ qemu-omap/hw/max7310.c 2008-03-02 19:31:55.000000000 +0000 +@@ -134,8 +134,8 @@ s->i2c_command_byte = 1; break; case I2C_FINISH: @@ -2241,537 +57,234 @@ index 75e56c7..397950a 100644 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 @@ +diff -urN 4242/hw/ndis.h qemu-omap/hw/ndis.h +--- 4242/hw/ndis.h 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-omap/hw/ndis.h 2008-04-23 09:57:56.000000000 +0100 +@@ -0,0 +1,217 @@ +/* -+ * Nokia N-series internet tablets. -+ * -+ * Copyright (C) 2007 Nokia Corporation -+ * Written by Andrzej Zaborowski <andrew@openedhand.com> ++ * ndis.h ++ * ++ * ntddndis.h modified by Benedikt Spranger <b.spranger@pengutronix.de> ++ * ++ * Thanks to the cygwin development team, ++ * espacially to Casper S. Hornstrup <chorns@users.sourceforge.net> ++ * ++ * THIS SOFTWARE IS NOT COPYRIGHTED + * -+ * 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 source code is offered for use in the public domain. You may ++ * use, modify or distribute it freely. + * -+ * 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. ++ * This code is distributed in the hope that it will be useful but ++ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY ++ * DISCLAIMED. This includes but is not limited to warranties of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * -+ * 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)); -+} -+ ++#ifndef _LINUX_NDIS_H ++#define _LINUX_NDIS_H ++ ++ ++#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 ++#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A ++#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B ++ ++enum NDIS_DEVICE_POWER_STATE { ++ NdisDeviceStateUnspecified = 0, ++ NdisDeviceStateD0, ++ NdisDeviceStateD1, ++ NdisDeviceStateD2, ++ NdisDeviceStateD3, ++ NdisDeviceStateMaximum ++}; ++ ++struct NDIS_PM_WAKE_UP_CAPABILITIES { ++ enum NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp; ++ enum NDIS_DEVICE_POWER_STATE MinPatternWakeUp; ++ enum NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp; ++}; ++ ++/* NDIS_PNP_CAPABILITIES.Flags constants */ ++#define NDIS_DEVICE_WAKE_UP_ENABLE 0x00000001 ++#define NDIS_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 ++#define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 ++ ++struct NDIS_PNP_CAPABILITIES { ++ __le32 Flags; ++ struct NDIS_PM_WAKE_UP_CAPABILITIES WakeUpCapabilities; ++}; ++ ++struct NDIS_PM_PACKET_PATTERN { ++ __le32 Priority; ++ __le32 Reserved; ++ __le32 MaskSize; ++ __le32 PatternOffset; ++ __le32 PatternSize; ++ __le32 PatternFlags; ++}; ++ ++ ++/* Required Object IDs (OIDs) */ ++#define OID_GEN_SUPPORTED_LIST 0x00010101 ++#define OID_GEN_HARDWARE_STATUS 0x00010102 ++#define OID_GEN_MEDIA_SUPPORTED 0x00010103 ++#define OID_GEN_MEDIA_IN_USE 0x00010104 ++#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 ++#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 ++#define OID_GEN_LINK_SPEED 0x00010107 ++#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 ++#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 ++#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A ++#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B ++#define OID_GEN_VENDOR_ID 0x0001010C ++#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D ++#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E ++#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F ++#define OID_GEN_DRIVER_VERSION 0x00010110 ++#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 ++#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 ++#define OID_GEN_MAC_OPTIONS 0x00010113 ++#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 ++#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 ++#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 ++#define OID_GEN_SUPPORTED_GUIDS 0x00010117 ++#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 ++#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 ++#define OID_GEN_MACHINE_NAME 0x0001021A ++#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B ++#define OID_GEN_VLAN_ID 0x0001021C ++ ++/* Optional OIDs */ ++#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 ++#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 ++ ++/* Required statistics OIDs */ ++#define OID_GEN_XMIT_OK 0x00020101 ++#define OID_GEN_RCV_OK 0x00020102 ++#define OID_GEN_XMIT_ERROR 0x00020103 ++#define OID_GEN_RCV_ERROR 0x00020104 ++#define OID_GEN_RCV_NO_BUFFER 0x00020105 ++ ++/* Optional statistics OIDs */ ++#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 ++#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 ++#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 ++#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 ++#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 ++#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 ++#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 ++#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 ++#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 ++#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A ++#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B ++#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C ++#define OID_GEN_RCV_CRC_ERROR 0x0002020D ++#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E ++#define OID_GEN_GET_TIME_CAPS 0x0002020F ++#define OID_GEN_GET_NETCARD_TIME 0x00020210 ++#define OID_GEN_NETCARD_LOAD 0x00020211 ++#define OID_GEN_DEVICE_PROFILE 0x00020212 ++#define OID_GEN_INIT_TIME_MS 0x00020213 ++#define OID_GEN_RESET_COUNTS 0x00020214 ++#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215 ++#define OID_GEN_FRIENDLY_NAME 0x00020216 ++#define OID_GEN_MINIPORT_INFO 0x00020217 ++#define OID_GEN_RESET_VERIFY_PARAMETERS 0x00020218 ++ ++/* IEEE 802.3 (Ethernet) OIDs */ ++#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 ++ ++#define OID_802_3_PERMANENT_ADDRESS 0x01010101 ++#define OID_802_3_CURRENT_ADDRESS 0x01010102 ++#define OID_802_3_MULTICAST_LIST 0x01010103 ++#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 ++#define OID_802_3_MAC_OPTIONS 0x01010105 ++#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 ++#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 ++#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 ++#define OID_802_3_XMIT_DEFERRED 0x01020201 ++#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 ++#define OID_802_3_RCV_OVERRUN 0x01020203 ++#define OID_802_3_XMIT_UNDERRUN 0x01020204 ++#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 ++#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 ++#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 ++ ++/* OID_GEN_MINIPORT_INFO constants */ ++#define NDIS_MINIPORT_BUS_MASTER 0x00000001 ++#define NDIS_MINIPORT_WDM_DRIVER 0x00000002 ++#define NDIS_MINIPORT_SG_LIST 0x00000004 ++#define NDIS_MINIPORT_SUPPORTS_MEDIA_QUERY 0x00000008 ++#define NDIS_MINIPORT_INDICATES_PACKETS 0x00000010 ++#define NDIS_MINIPORT_IGNORE_PACKET_QUEUE 0x00000020 ++#define NDIS_MINIPORT_IGNORE_REQUEST_QUEUE 0x00000040 ++#define NDIS_MINIPORT_IGNORE_TOKEN_RING_ERRORS 0x00000080 ++#define NDIS_MINIPORT_INTERMEDIATE_DRIVER 0x00000100 ++#define NDIS_MINIPORT_IS_NDIS_5 0x00000200 ++#define NDIS_MINIPORT_IS_CO 0x00000400 ++#define NDIS_MINIPORT_DESERIALIZE 0x00000800 ++#define NDIS_MINIPORT_REQUIRES_MEDIA_POLLING 0x00001000 ++#define NDIS_MINIPORT_SUPPORTS_MEDIA_SENSE 0x00002000 ++#define NDIS_MINIPORT_NETBOOT_CARD 0x00004000 ++#define NDIS_MINIPORT_PM_SUPPORTED 0x00008000 ++#define NDIS_MINIPORT_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00010000 ++#define NDIS_MINIPORT_USES_SAFE_BUFFER_APIS 0x00020000 ++#define NDIS_MINIPORT_HIDDEN 0x00040000 ++#define NDIS_MINIPORT_SWENUM 0x00080000 ++#define NDIS_MINIPORT_SURPRISE_REMOVE_OK 0x00100000 ++#define NDIS_MINIPORT_NO_HALT_ON_SUSPEND 0x00200000 ++#define NDIS_MINIPORT_HARDWARE_DEVICE 0x00400000 ++#define NDIS_MINIPORT_SUPPORTS_CANCEL_SEND_PACKETS 0x00800000 ++#define NDIS_MINIPORT_64BITS_DMA 0x01000000 ++ ++#define NDIS_MEDIUM_802_3 0x00000000 ++#define NDIS_MEDIUM_802_5 0x00000001 ++#define NDIS_MEDIUM_FDDI 0x00000002 ++#define NDIS_MEDIUM_WAN 0x00000003 ++#define NDIS_MEDIUM_LOCAL_TALK 0x00000004 ++#define NDIS_MEDIUM_DIX 0x00000005 ++#define NDIS_MEDIUM_ARCENT_RAW 0x00000006 ++#define NDIS_MEDIUM_ARCENT_878_2 0x00000007 ++#define NDIS_MEDIUM_ATM 0x00000008 ++#define NDIS_MEDIUM_WIRELESS_LAN 0x00000009 ++#define NDIS_MEDIUM_IRDA 0x0000000A ++#define NDIS_MEDIUM_BPC 0x0000000B ++#define NDIS_MEDIUM_CO_WAN 0x0000000C ++#define NDIS_MEDIUM_1394 0x0000000D ++ ++#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 ++#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 ++#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 ++#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 ++#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 ++#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 ++#define NDIS_PACKET_TYPE_SMT 0x00000040 ++#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 ++#define NDIS_PACKET_TYPE_GROUP 0x00000100 ++#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200 ++#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400 ++#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800 ++ ++#define NDIS_MEDIA_STATE_CONNECTED 0x00000000 ++#define NDIS_MEDIA_STATE_DISCONNECTED 0x00000001 ++ ++#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 ++#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 ++#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 ++#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 ++#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 ++#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 ++#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 ++#define NDIS_MAC_OPTION_RESERVED 0x80000000 ++ ++#endif /* _LINUX_NDIS_H */ +diff -urN 4242/hw/nseries.c qemu-omap/hw/nseries.c +--- 4242/hw/nseries.c 2008-04-24 18:11:49.000000000 +0100 ++++ qemu-omap/hw/nseries.c 2008-04-23 09:57:56.000000000 +0100 +@@ -602,6 +602,37 @@ + (void *) &config7, sizeof(config7)); + } + +#if 0 +static uint32_t n800_pinout[104] = { + 0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0, @@ -2803,11007 +316,1835 @@ index 0000000..0425d46 +}; +#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) + /* Setup sequence done by the bootloader */ + static void n800_boot_init(void *opaque) { - 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[]; +@@ -942,3 +973,71 @@ + "Nokia N800 aka. RX-34 tablet (OMAP2420)", + n800_init, }; - - 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); ++/* cx3110x.c */ ++#define CY_ARM_INT 0x00 ++#define CY_ARM_INT_ENA 0x00 ++#define CY_HOST_INT 0x00 ++#define CY_HOST_INT_ENA 0x00 ++#define CY_HOST_INT_ACK 0x00 ++#define CY_GP1_COMM 0x00 ++#define CY_GP2_COMM 0x00 ++#define CY_DEV_CTRL_STA 0x00 ++#define CY_DMA_DATA 0x00 /* 16-bit */ ++#define CY_DMA_WR_CTRL 0x00 /* 16-bit */ ++#define CY_DMA_WR_LEN 0x00 /* 16-bit */ ++#define CY_DMA_WR_BASE 0x00 ++#define CY_DMA_RD_CTRL 0x00 /* 16-bit */ ++#define CY_DMA_RD_LEN 0x00 /* 16-bit */ ++#define CY_DMA_RD_BASE 0x00 ++ ++HW: ++(spi bus 1.0) ++ tsc2005 ++(spi bus 1.1) ++ lcd_mipid ++(spi bus 2.0) ++ cx3110x (WLAN) ++(spi somewhere?) ++ pc2400m (WiMAX) ++(i2c bus 0) ++ TLV320AIC33 (audio codec on i2c) ++ TCM825x (camera on i2c) ++ lp5521 (LED on i2c) ++ tsl2563 (light sensor, hwmon on i2c) ++ lm8323 (keypad on i2c) ++(i2c bus 1) ++ tmp105 (temperature sensor, hwmon on i2c) ++ menelaus (power on i2c) ++ ++GPIO 0: out hi ++GPIO 8: in hi ++GPIO 9: out hi ++GPIO 10: out lo ++GPIO 12: out lo ++GPIO 15: out lo ++GPIO 23: out hi ++GPIO 26: in hi, irq-186 rising ++GPIO 53: out lo ++GPIO 58: in hi, irq-218 low wakeup ++GPIO 62: out lo ++GPIO 64: out hi ++GPIO 65: in hi ++GPIO 66: out lo ++GPIO 93: out lo ++GPIO 94: in hi ++GPIO 95: out lo ++GPIO 96: out hi ++GPIO 101: out lo ++GPIO 102: in hi, irq-262 bothedge ++GPIO 106: in hi, irq-266 falling wakeup ++GPIO 107: in hi, irq-267 bothedge ++GPIO 108: in lo, irq-268 rising wakeup ++GPIO 109: in hi, irq-269 falling wakeup ++GPIO 110: in hi, irq-270 bothedge ++GPIO 111: in lo, irq-271 rising ++GPIO 112: out hi ++GPIO 118: out hi ++GPIO 125: in lo, irq-285 rising +#endif -+ 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; +diff -urN 4242/hw/omap2.c qemu-omap/hw/omap2.c +--- 4242/hw/omap2.c 2008-04-24 18:11:49.000000000 +0100 ++++ qemu-omap/hw/omap2.c 2008-04-23 09:57:56.000000000 +0100 +@@ -3675,152 +3675,152 @@ + omap_findclk(s, "dss_l4_iclk")); + + /* All register mappings (includin those not currenlty implemented): +- * SystemControlMod 48000000 - 48000fff +- * SystemControlL4 48001000 - 48001fff +- * 32kHz Timer Mod 48004000 - 48004fff +- * 32kHz Timer L4 48005000 - 48005fff +- * PRCM ModA 48008000 - 480087ff ++ * SystemControlMod 48000000 - 48000fff (REV 0x00000010) ++ * SystemControlL4 48001000 - 48001fff (0x00200010, 0x01000200, 0x00000000) ++ * 32kHz Timer Mod 48004000 - 48004fff (REV 0x00000011) ++ * 32kHz Timer L4 48005000 - 48005fff (0x00200010, 0x01000200, 0x00000000) ++ * PRCM ModA 48008000 - 480087ff (REV 0x00000010) + * PRCM ModB 48008800 - 48008fff +- * PRCM L4 48009000 - 48009fff +- * TEST-BCM Mod 48012000 - 48012fff +- * TEST-BCM L4 48013000 - 48013fff +- * TEST-TAP Mod 48014000 - 48014fff +- * TEST-TAP L4 48015000 - 48015fff +- * GPIO1 Mod 48018000 - 48018fff +- * GPIO Top 48019000 - 48019fff +- * GPIO2 Mod 4801a000 - 4801afff +- * GPIO L4 4801b000 - 4801bfff +- * GPIO3 Mod 4801c000 - 4801cfff +- * GPIO4 Mod 4801e000 - 4801efff +- * WDTIMER1 Mod 48020000 - 48010fff ++ * PRCM L4 48009000 - 48009fff (0x00200010, 0x00000200, 0x00000000) ++ * TEST-BCM Mod 48012000 - 48012fff (REV 0x00000010) ++ * TEST-BCM L4 48013000 - 48013fff (0x00200010, 0x00000200, 0x00000000) ++ * TEST-TAP Mod 48014000 - 48014fff (REV 0x00000010) ++ * TEST-TAP L4 48015000 - 48015fff (0x00200010, 0x00000200, 0x00000000) ++ * GPIO1 Mod 48018000 - 48018fff (REV 0x00000018) ++ * GPIO Top 48019000 - 48019fff (REV 0x00000011) ++ * GPIO2 Mod 4801a000 - 4801afff (REV 0x00000018) ++ * GPIO L4 4801b000 - 4801bfff (0x00200010, 0x00000200, 0x00000000) ++ * GPIO3 Mod 4801c000 - 4801cfff (REV 0x00000018) ++ * GPIO4 Mod 4801e000 - 4801efff (REV 0x00000018) ++ * WDTIMER1 Mod 48020000 - 48010fff (REV Abort) + * WDTIMER Top 48021000 - 48011fff +- * WDTIMER2 Mod 48022000 - 48012fff +- * WDTIMER L4 48023000 - 48013fff +- * WDTIMER3 Mod 48024000 - 48014fff +- * WDTIMER3 L4 48025000 - 48015fff +- * WDTIMER4 Mod 48026000 - 48016fff +- * WDTIMER4 L4 48027000 - 48017fff +- * GPTIMER1 Mod 48028000 - 48018fff +- * GPTIMER1 L4 48029000 - 48019fff +- * GPTIMER2 Mod 4802a000 - 4801afff +- * GPTIMER2 L4 4802b000 - 4801bfff ++ * WDTIMER2 Mod 48022000 - 48012fff (REV 0x00000011) ++ * WDTIMER L4 48023000 - 48013fff (0x00200010, 0x00000200, 0x00000000) ++ * WDTIMER3 Mod 48024000 - 48014fff (REV 0x00000011) ++ * WDTIMER3 L4 48025000 - 48015fff (0x00200010, 0x00000200, 0x00000000) ++ * WDTIMER4 Mod 48026000 - 48016fff (REV 0x00000011) ++ * WDTIMER4 L4 48027000 - 48017fff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER1 Mod 48028000 - 48018fff (REV 0x00000013) ++ * GPTIMER1 L4 48029000 - 48019fff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER2 Mod 4802a000 - 4801afff (REV Abort) ++ * GPTIMER2 L4 4802b000 - 4801bfff (0x00200010, 0x00000200, 0x00000000) + * L4-Config AP 48040000 - 480407ff + * L4-Config IP 48040800 - 48040fff + * L4-Config LA 48041000 - 48041fff +- * ARM11ETB Mod 48048000 - 48049fff +- * ARM11ETB L4 4804a000 - 4804afff +- * DISPLAY Top 48050000 - 480503ff +- * DISPLAY DISPC 48050400 - 480507ff +- * DISPLAY RFBI 48050800 - 48050bff +- * DISPLAY VENC 48050c00 - 48050fff +- * DISPLAY L4 48051000 - 48051fff +- * CAMERA Top 48052000 - 480523ff +- * CAMERA core 48052400 - 480527ff +- * CAMERA DMA 48052800 - 48052bff +- * CAMERA MMU 48052c00 - 48052fff +- * CAMERA L4 48053000 - 48053fff +- * SDMA Mod 48056000 - 48056fff +- * SDMA L4 48057000 - 48057fff +- * SSI Top 48058000 - 48058fff +- * SSI GDD 48059000 - 48059fff +- * SSI Port1 4805a000 - 4805afff +- * SSI Port2 4805b000 - 4805bfff +- * SSI L4 4805c000 - 4805cfff +- * USB Mod 4805e000 - 480fefff +- * USB L4 4805f000 - 480fffff +- * WIN_TRACER1 Mod 48060000 - 48060fff +- * WIN_TRACER1 L4 48061000 - 48061fff +- * WIN_TRACER2 Mod 48062000 - 48062fff +- * WIN_TRACER2 L4 48063000 - 48063fff +- * WIN_TRACER3 Mod 48064000 - 48064fff +- * WIN_TRACER3 L4 48065000 - 48065fff +- * WIN_TRACER4 Top 48066000 - 480660ff +- * WIN_TRACER4 ETT 48066100 - 480661ff +- * WIN_TRACER4 WT 48066200 - 480662ff +- * WIN_TRACER4 L4 48067000 - 48067fff +- * XTI Mod 48068000 - 48068fff +- * XTI L4 48069000 - 48069fff +- * UART1 Mod 4806a000 - 4806afff +- * UART1 L4 4806b000 - 4806bfff +- * UART2 Mod 4806c000 - 4806cfff +- * UART2 L4 4806d000 - 4806dfff +- * UART3 Mod 4806e000 - 4806efff +- * UART3 L4 4806f000 - 4806ffff +- * I2C1 Mod 48070000 - 48070fff +- * I2C1 L4 48071000 - 48071fff +- * I2C2 Mod 48072000 - 48072fff +- * I2C2 L4 48073000 - 48073fff +- * McBSP1 Mod 48074000 - 48074fff +- * McBSP1 L4 48075000 - 48075fff +- * McBSP2 Mod 48076000 - 48076fff +- * McBSP2 L4 48077000 - 48077fff +- * GPTIMER3 Mod 48078000 - 48078fff +- * GPTIMER3 L4 48079000 - 48079fff +- * GPTIMER4 Mod 4807a000 - 4807afff +- * GPTIMER4 L4 4807b000 - 4807bfff +- * GPTIMER5 Mod 4807c000 - 4807cfff +- * GPTIMER5 L4 4807d000 - 4807dfff +- * GPTIMER6 Mod 4807e000 - 4807efff +- * GPTIMER6 L4 4807f000 - 4807ffff +- * GPTIMER7 Mod 48080000 - 48080fff +- * GPTIMER7 L4 48081000 - 48081fff +- * GPTIMER8 Mod 48082000 - 48082fff +- * GPTIMER8 L4 48083000 - 48083fff +- * GPTIMER9 Mod 48084000 - 48084fff +- * GPTIMER9 L4 48085000 - 48085fff +- * GPTIMER10 Mod 48086000 - 48086fff +- * GPTIMER10 L4 48087000 - 48087fff +- * GPTIMER11 Mod 48088000 - 48088fff +- * GPTIMER11 L4 48089000 - 48089fff +- * GPTIMER12 Mod 4808a000 - 4808afff +- * GPTIMER12 L4 4808b000 - 4808bfff +- * EAC Mod 48090000 - 48090fff +- * EAC L4 48091000 - 48091fff +- * FAC Mod 48092000 - 48092fff +- * FAC L4 48093000 - 48093fff +- * MAILBOX Mod 48094000 - 48094fff +- * MAILBOX L4 48095000 - 48095fff +- * SPI1 Mod 48098000 - 48098fff +- * SPI1 L4 48099000 - 48099fff +- * SPI2 Mod 4809a000 - 4809afff +- * SPI2 L4 4809b000 - 4809bfff +- * MMC/SDIO Mod 4809c000 - 4809cfff +- * MMC/SDIO L4 4809d000 - 4809dfff +- * MS_PRO Mod 4809e000 - 4809efff +- * MS_PRO L4 4809f000 - 4809ffff +- * RNG Mod 480a0000 - 480a0fff +- * RNG L4 480a1000 - 480a1fff +- * DES3DES Mod 480a2000 - 480a2fff +- * DES3DES L4 480a3000 - 480a3fff +- * SHA1MD5 Mod 480a4000 - 480a4fff +- * SHA1MD5 L4 480a5000 - 480a5fff +- * AES Mod 480a6000 - 480a6fff +- * AES L4 480a7000 - 480a7fff +- * PKA Mod 480a8000 - 480a9fff +- * PKA L4 480aa000 - 480aafff +- * MG Mod 480b0000 - 480b0fff +- * MG L4 480b1000 - 480b1fff +- * HDQ/1-wire Mod 480b2000 - 480b2fff +- * HDQ/1-wire L4 480b3000 - 480b3fff +- * MPU interrupt 480fe000 - 480fefff +- * IVA RAM 5c000000 - 5c01ffff +- * IVA ROM 5c020000 - 5c027fff +- * IMG_BUF_A 5c040000 - 5c040fff +- * IMG_BUF_B 5c042000 - 5c042fff +- * VLCDS 5c048000 - 5c0487ff +- * IMX_COEF 5c049000 - 5c04afff +- * IMX_CMD 5c051000 - 5c051fff +- * VLCDQ 5c053000 - 5c0533ff +- * VLCDH 5c054000 - 5c054fff +- * SEQ_CMD 5c055000 - 5c055fff +- * IMX_REG 5c056000 - 5c0560ff +- * VLCD_REG 5c056100 - 5c0561ff +- * SEQ_REG 5c056200 - 5c0562ff +- * IMG_BUF_REG 5c056300 - 5c0563ff +- * SEQIRQ_REG 5c056400 - 5c0564ff +- * OCP_REG 5c060000 - 5c060fff +- * SYSC_REG 5c070000 - 5c070fff +- * MMU_REG 5d000000 - 5d000fff ++ * ARM11ETB Mod 48048000 - 48049fff (REV 0x00000011) ++ * ARM11ETB L4 4804a000 - 4804afff (0x00200010, 0x00000200, 0x00000000) ++ * DISPLAY Top 48050000 - 480503ff (REV 0x00000003) ++ * DISPLAY DISPC 48050400 - 480507ff (REV 0x00000020) ++ * DISPLAY RFBI 48050800 - 48050bff (REV 0x00000010) ++ * DISPLAY VENC 48050c00 - 48050fff (REV Abort) ++ * DISPLAY L4 48051000 - 48051fff (0x00200010, 0x00000200, 0x00000100) ++ * CAMERA Top 48052000 - 480523ff (REV 0x00000020) ++ * CAMERA core 48052400 - 480527ff (REV 0x00000020) ++ * CAMERA DMA 48052800 - 48052bff (REV 0x00000020) ++ * CAMERA MMU 48052c00 - 48052fff (REV 0x00000010) ++ * CAMERA L4 48053000 - 48053fff (0x00200010, 0x00000200, 0x00000000) ++ * SDMA Mod 48056000 - 48056fff (REV 0x00000020) ++ * SDMA L4 48057000 - 48057fff (0x00200010, 0x00000200, 0x00000000) ++ * SSI Top 48058000 - 48058fff (REV Abort) ++ * SSI GDD 48059000 - 48059fff (REV Abort) ++ * SSI Port1 4805a000 - 4805afff (REV Abort) ++ * SSI Port2 4805b000 - 4805bfff (REV Abort) ++ * SSI L4 4805c000 - 4805cfff (0x00200010, 0x00000200, 0x00000100) ++ * USB Mod 4805e000 - 480fefff (REV Abort) ++ * USB L4 4805f000 - 480fffff (0x00200010, 0x01000200, 0x00000100) ++ * WIN_TRACER1 Mod 48060000 - 48060fff (REV 0x00000020) ++ * WIN_TRACER1 L4 48061000 - 48061fff (0x00200010, 0x00000200, 0x00000000) ++ * WIN_TRACER2 Mod 48062000 - 48062fff (REV 0x00000020) ++ * WIN_TRACER2 L4 48063000 - 48063fff (0x00200010, 0x00000200, 0x00000000) ++ * WIN_TRACER3 Mod 48064000 - 48064fff (REV 0x00000020) ++ * WIN_TRACER3 L4 48065000 - 48065fff (0x00200010, 0x00000200, 0x00000000) ++ * WIN_TRACER4 Top 48066000 - 480660ff (REV 0x00000011) ++ * WIN_TRACER4 ETT 48066100 - 480661ff (REV 0x00000011) ++ * WIN_TRACER4 WT 48066200 - 480662ff (REV 0x00000020) ++ * WIN_TRACER4 L4 48067000 - 48067fff (0x00200010, 0x00000200, 0x00000000) ++ * XTI Mod 48068000 - 48068fff (REV 0x00000010) ++ * XTI L4 48069000 - 48069fff (0x00200010, 0x00000200, 0x00000000) ++ * UART1 Mod 4806a000 - 4806afff (MVR Abort) ++ * UART1 L4 4806b000 - 4806bfff (0x00200010, 0x00000200, 0x00000000) ++ * UART2 Mod 4806c000 - 4806cfff (MVR Abort) ++ * UART2 L4 4806d000 - 4806dfff (0x00200010, 0x00000200, 0x00000000) ++ * UART3 Mod 4806e000 - 4806efff (MVR 0x20) ++ * UART3 L4 4806f000 - 4806ffff (0x00200010, 0x00000200, 0x00000000) ++ * I2C1 Mod 48070000 - 48070fff (REV 0x0034) ++ * I2C1 L4 48071000 - 48071fff (0x00200010, 0x01000200, 0x01000000) ++ * I2C2 Mod 48072000 - 48072fff (REV 0x0034) ++ * I2C2 L4 48073000 - 48073fff (0x00200010, 0x01000200, 0x01000000) ++ * McBSP1 Mod 48074000 - 48074fff (REV Abort) ++ * McBSP1 L4 48075000 - 48075fff (0x00200010, 0x01000200, 0x01000000) ++ * McBSP2 Mod 48076000 - 48076fff (REV Abort) ++ * McBSP2 L4 48077000 - 48077fff (0x00200010, 0x01000200, 0x01000000) ++ * GPTIMER3 Mod 48078000 - 48078fff (REV Abort) ++ * GPTIMER3 L4 48079000 - 48079fff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER4 Mod 4807a000 - 4807afff (REV Abort) ++ * GPTIMER4 L4 4807b000 - 4807bfff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER5 Mod 4807c000 - 4807cfff (REV Abort) ++ * GPTIMER5 L4 4807d000 - 4807dfff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER6 Mod 4807e000 - 4807efff (REV Abort) ++ * GPTIMER6 L4 4807f000 - 4807ffff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER7 Mod 48080000 - 48080fff (REV Abort) ++ * GPTIMER7 L4 48081000 - 48081fff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER8 Mod 48082000 - 48082fff (REV Abort) ++ * GPTIMER8 L4 48083000 - 48083fff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER9 Mod 48084000 - 48084fff (REV Abort) ++ * GPTIMER9 L4 48085000 - 48085fff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER10 Mod 48086000 - 48086fff (REV Abort) ++ * GPTIMER10 L4 48087000 - 48087fff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER11 Mod 48088000 - 48088fff (REV Abort) ++ * GPTIMER11 L4 48089000 - 48089fff (0x00200010, 0x00000200, 0x00000000) ++ * GPTIMER12 Mod 4808a000 - 4808afff (REV Abort) ++ * GPTIMER12 L4 4808b000 - 4808bfff (0x00200010, 0x00000200, 0x00000000) ++ * EAC Mod 48090000 - 48090fff (REV Abort) ++ * EAC L4 48091000 - 48091fff (0x00200010, 0x00000200, 0x00000000) ++ * FAC Mod 48092000 - 48092fff (REV Abort) ++ * FAC L4 48093000 - 48093fff (0x00200010, 0x00000200, 0x00000000) ++ * MAILBOX Mod 48094000 - 48094fff (REV 0x00000010) ++ * MAILBOX L4 48095000 - 48095fff (0x00200010, 0x00000200, 0x00000000) ++ * SPI1 Mod 48098000 - 48098fff (REV Abort) ++ * SPI1 L4 48099000 - 48099fff (0x00200010, 0x00000200, 0x00000000) ++ * SPI2 Mod 4809a000 - 4809afff (REV Abort) ++ * SPI2 L4 4809b000 - 4809bfff (0x00200010, 0x00000200, 0x00000000) ++ * MMC/SDIO Mod 4809c000 - 4809cfff (REV 0x0044) ++ * MMC/SDIO L4 4809d000 - 4809dfff (0x00200010, 0x01000200, 0x01000000) ++ * MS_PRO Mod 4809e000 - 4809efff (REV Abort) ++ * MS_PRO L4 4809f000 - 4809ffff (0x00200010, 0x01000200, 0x01000000) ++ * RNG Mod 480a0000 - 480a0fff (REV 0xFC066F93?) ++ * RNG L4 480a1000 - 480a1fff (0x00200010, 0x01000200, 0x00000000) ++ * DES3DES Mod 480a2000 - 480a2fff (REV 0x00000000?) ++ * DES3DES L4 480a3000 - 480a3fff (0x00200010, 0x01000200, 0x00000000) ++ * SHA1MD5 Mod 480a4000 - 480a4fff (REV 0x00000000?) ++ * SHA1MD5 L4 480a5000 - 480a5fff (0x00200010, 0x01000200, 0x00000000) ++ * AES Mod 480a6000 - 480a6fff (REV 0x00000000?) ++ * AES L4 480a7000 - 480a7fff (0x00200010, 0x00000200, 0x00000000) ++ * PKA Mod 480a8000 - 480a9fff (REV 0x00000000?) ++ * PKA L4 480aa000 - 480aafff (0x00200010, 0x00000200, 0x00000000) ++ * MG Mod 480b0000 - 480b0fff (REV Abort) ++ * MG L4 480b1000 - 480b1fff (0x00200010, 0x01000200, 0x01000000) ++ * HDQ/1-wire Mod 480b2000 - 480b2fff (REV 0x00000002) ++ * HDQ/1-wire L4 480b3000 - 480b3fff (0x00200010, 0x00000200, 0x00000000) ++ * MPU interrupt 480fe000 - 480fefff (REV 0x00000020) ++ * IVA RAM 5c000000 - 5c01ffff (REV Abort) ++ * IVA ROM 5c020000 - 5c027fff (REV Abort) ++ * IMG_BUF_A 5c040000 - 5c040fff (REV Abort) ++ * IMG_BUF_B 5c042000 - 5c042fff (REV Abort) ++ * VLCDS 5c048000 - 5c0487ff (REV Abort) ++ * IMX_COEF 5c049000 - 5c04afff (REV Abort) ++ * IMX_CMD 5c051000 - 5c051fff (REV Abort) ++ * VLCDQ 5c053000 - 5c0533ff (REV Abort) ++ * VLCDH 5c054000 - 5c054fff (REV Abort) ++ * SEQ_CMD 5c055000 - 5c055fff (REV Abort) ++ * IMX_REG 5c056000 - 5c0560ff (REV Abort) ++ * VLCD_REG 5c056100 - 5c0561ff (REV Abort) ++ * SEQ_REG 5c056200 - 5c0562ff (REV Abort) ++ * IMG_BUF_REG 5c056300 - 5c0563ff (REV Abort) ++ * SEQIRQ_REG 5c056400 - 5c0564ff (REV Abort) ++ * OCP_REG 5c060000 - 5c060fff (REV Abort) ++ * SYSC_REG 5c070000 - 5c070fff (REV Abort) ++ * MMU_REG 5d000000 - 5d000fff (REV Abort) + * sDMA R 68000400 - 680005ff + * sDMA W 68000600 - 680007ff + * Display Control 68000800 - 680009ff +@@ -3849,9 +3849,9 @@ + * GPMC (firewall) 68006000 - 680063ff + * GPMC (err login) 68006400 - 680067ff + * SMS (err login) 68006c00 - 68006fff +- * SMS registers 68008000 - 68008fff +- * SDRC registers 68009000 - 68009fff +- * GPMC registers 6800a000 6800afff ++ * SMS registers 68008000 - 68008fff (REV 0x00000020) ++ * SDRC registers 68009000 - 68009fff (REV 0x00000020) ++ * GPMC registers 6800a000 6800afff (REV 0x00000020) + */ + + qemu_register_reset(omap2_mpu_reset, s); +diff -urN 4242/hw/pc.c qemu-omap/hw/pc.c +--- 4242/hw/pc.c 2008-04-24 21:26:22.000000000 +0100 ++++ qemu-omap/hw/pc.c 2008-04-23 09:57:56.000000000 +0100 +@@ -445,6 +445,37 @@ + bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect)); } - static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s) ++static int load_kernel(const char *filename, uint8_t *addr, ++ uint8_t *real_addr) ++{ ++ int fd, size; ++ int setup_sects; ++ ++ fd = open(filename, O_RDONLY | O_BINARY); ++ if (fd < 0) ++ return -1; ++ ++ /* load 16 bit code */ ++ if (read(fd, real_addr, 512) != 512) ++ goto fail; ++ setup_sects = real_addr[0x1F1]; ++ if (!setup_sects) ++ setup_sects = 4; ++ if (read(fd, real_addr + 512, setup_sects * 512) != ++ setup_sects * 512) ++ goto fail; ++ ++ /* load 32 bit code */ ++ size = read(fd, addr, 16 * 1024 * 1024); ++ if (size < 0) ++ goto fail; ++ close(fd); ++ return size; ++ fail: ++ close(fd); ++ return -1; ++} ++ + static long get_file_size(FILE *f) { - s->omap_3_1_mapping_disabled = 1; - s->chans = 16; -+ s->intr_update = omap_dma_interrupts_3_2_update; + long where, size; +diff -urN 4242/hw/tusb6010.c qemu-omap/hw/tusb6010.c +--- 4242/hw/tusb6010.c 2008-04-23 12:18:54.000000000 +0100 ++++ qemu-omap/hw/tusb6010.c 2008-04-23 09:57:56.000000000 +0100 +@@ -287,9 +287,6 @@ + /* TODO: How is this signalled? */ } - 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; +-extern CPUReadMemoryFunc *musb_read[]; +-extern CPUWriteMemoryFunc *musb_write[]; - - 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) + static uint32_t tusb_async_readb(void *opaque, target_phys_addr_t addr) { - 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); + struct tusb_s *s = (struct tusb_s *) opaque; +diff -urN 4242/hw/usb.h qemu-omap/hw/usb.h +--- 4242/hw/usb.h 2008-04-23 12:18:54.000000000 +0100 ++++ qemu-omap/hw/usb.h 2008-04-23 09:57:56.000000000 +0100 +@@ -219,6 +219,9 @@ + /* usb-msd.c */ + USBDevice *usb_msd_init(const char *filename); + ++/* usb-net.c */ ++USBDevice *usb_net_init(NICInfo *nd); ++ + /* usb-wacom.c */ + USBDevice *usb_wacom_init(void); + +@@ -254,3 +257,7 @@ + uint32_t musb_core_intr_get(struct musb_s *s); + void musb_core_intr_clear(struct musb_s *s, uint32_t mask); + void musb_set_size(struct musb_s *s, int epnum, int size, int is_tx); ++#ifdef NEED_CPU_H ++extern CPUReadMemoryFunc *musb_read[]; ++extern CPUWriteMemoryFunc *musb_write[]; +#endif -+ -+ 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; +diff -urN 4242/hw/usb-hub.c qemu-omap/hw/usb-hub.c +--- 4242/hw/usb-hub.c 2008-04-23 11:43:37.000000000 +0100 ++++ qemu-omap/hw/usb-hub.c 2008-04-23 09:57:56.000000000 +0100 +@@ -146,8 +146,8 @@ + 0x07, /* u8 ep_bLength; */ + 0x05, /* u8 ep_bDescriptorType; Endpoint */ + 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ +- 0x03, /* u8 ep_bmAttributes; Interrupt */ +- 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ ++ 0x03, /* u8 ep_bmAttributes; Interrupt */ ++ 0x02, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ + 0xff /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ }; - 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 @@ +diff -urN 4242/hw/usb-net.c qemu-omap/hw/usb-net.c +--- 4242/hw/usb-net.c 1970-01-01 01:00:00.000000000 +0100 ++++ qemu-omap/hw/usb-net.c 2008-04-23 09:57:56.000000000 +0100 +@@ -0,0 +1,1334 @@ +/* -+ * OneNAND flash memories emulation. -+ * -+ * Copyright (C) 2008 Nokia Corporation -+ * Written by Andrzej Zaborowski <andrew@openedhand.com> ++ * QEMU USB Net devices ++ * ++ * Copyright (c) 2006 Thomas Sailer ++ * based on usb-hid.c Copyright (c) 2005 Fabrice Bellard ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: + * -+ * 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. ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. + * -+ * 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 ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++ * THE SOFTWARE. + */ + +#include "qemu-common.h" -+#include "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; - } ++#include "usb.h" ++#include "net.h" ++#include "../audio/sys-queue.h" + -+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, -+}; ++typedef uint32_t __le32; ++#include "ndis.h" + - 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 ++/*#define TRAFFIC_DEBUG*/ ++/* Thanks to NetChip Technologies for donating this product ID. ++ * It's for devices with only CDC Ethernet configurations. + */ -+ -+#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. ++#define CDC_VENDOR_NUM 0x0525 /* NetChip */ ++#define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */ ++/* For hardware that can talk RNDIS and either of the above protocols, ++ * use this ID ... the windows INF files will know it. + */ -+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 -+} ++#define RNDIS_VENDOR_NUM 0x0525 /* NetChip */ ++#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ ++ ++#define STRING_MANUFACTURER 1 ++#define STRING_PRODUCT 2 ++#define STRING_ETHADDR 3 ++#define STRING_DATA 4 ++#define STRING_CONTROL 5 ++#define STRING_RNDIS_CONTROL 6 ++#define STRING_CDC 7 ++#define STRING_SUBSET 8 ++#define STRING_RNDIS 9 ++#define STRING_SERIALNUMBER 10 ++ ++#define DEV_CONFIG_VALUE 1 /* cdc or subset */ ++#define DEV_RNDIS_CONFIG_VALUE 2 /* rndis; optional */ ++ ++#define USB_CDC_SUBCLASS_ACM 0x02 ++#define USB_CDC_SUBCLASS_ETHERNET 0x06 ++ ++#define USB_CDC_PROTO_NONE 0 ++#define USB_CDC_ACM_PROTO_VENDOR 0xff ++ ++#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ ++#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ ++#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ ++#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ ++#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ ++ ++#define USB_DT_CS_INTERFACE 0x24 ++#define USB_DT_CS_ENDPOINT 0x25 ++ ++#define ClassInterfaceRequest \ ++ ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) ++#define ClassInterfaceOutRequest \ ++ ((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) ++ ++#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 ++#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 ++#define USB_CDC_REQ_SET_LINE_CODING 0x20 ++#define USB_CDC_REQ_GET_LINE_CODING 0x21 ++#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 ++#define USB_CDC_REQ_SEND_BREAK 0x23 ++#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 ++#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 ++#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 ++#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 ++#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 ++ ++#define USB_ENDPOINT_XFER_BULK 2 ++#define USB_ENDPOINT_XFER_INT 3 ++ ++#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ ++#define STATUS_BYTECOUNT 16 /* 8 byte header + data */ ++ ++#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ + -+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 ++ * mostly the same descriptor as the linux gadget rndis driver + */ -+ -+#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 const uint8_t qemu_net_dev_descriptor[] = { ++ 0x12, /* u8 bLength; */ ++ USB_DT_DEVICE, /* u8 bDescriptorType; Device */ ++ 0x00, 0x02, /* u16 bcdUSB; v2.0 */ ++ USB_CLASS_COMM, /* u8 bDeviceClass; */ ++ 0x00, /* u8 bDeviceSubClass; */ ++ 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */ ++ 0x40, /* u8 bMaxPacketSize0 */ ++ RNDIS_VENDOR_NUM & 0xff, RNDIS_VENDOR_NUM >> 8, /* u16 idVendor; */ ++ RNDIS_PRODUCT_NUM & 0xff, RNDIS_PRODUCT_NUM >> 8, /* u16 idProduct; */ ++ 0x00, 0x00, /* u16 bcdDevice */ ++ STRING_MANUFACTURER, /* u8 iManufacturer; */ ++ STRING_PRODUCT, /* u8 iProduct; */ ++ STRING_SERIALNUMBER, /* u8 iSerialNumber; */ ++ 0x02 /* u8 bNumConfigurations; */ ++}; ++ ++static const uint8_t qemu_net_rndis_config_descriptor[] = { ++ /* Configuration Descriptor */ ++ 0x09, /* u8 bLength */ ++ USB_DT_CONFIG, /* u8 bDescriptorType */ ++ 0x43, 0x00, /* le16 wTotalLength */ ++ 0x02, /* u8 bNumInterfaces */ ++ DEV_RNDIS_CONFIG_VALUE, /* u8 bConfigurationValue */ ++ STRING_RNDIS, /* u8 iConfiguration */ ++ 0xc0, /* u8 bmAttributes */ ++ 0x32, /* u8 bMaxPower */ ++ /* RNDIS Control Interface */ ++ 0x09, /* u8 bLength */ ++ USB_DT_INTERFACE, /* u8 bDescriptorType */ ++ 0x00, /* u8 bInterfaceNumber */ ++ 0x00, /* u8 bAlternateSetting */ ++ 0x01, /* u8 bNumEndpoints */ ++ USB_CLASS_COMM, /* u8 bInterfaceClass */ ++ USB_CDC_SUBCLASS_ACM, /* u8 bInterfaceSubClass */ ++ USB_CDC_ACM_PROTO_VENDOR, /* u8 bInterfaceProtocol */ ++ STRING_RNDIS_CONTROL, /* u8 iInterface */ ++ /* Header Descriptor */ ++ 0x05, /* u8 bLength */ ++ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ ++ USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */ ++ 0x10, 0x01, /* le16 bcdCDC */ ++ /* Call Management Descriptor */ ++ 0x05, /* u8 bLength */ ++ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ ++ USB_CDC_CALL_MANAGEMENT_TYPE, /* u8 bDescriptorSubType */ ++ 0x00, /* u8 bmCapabilities */ ++ 0x01, /* u8 bDataInterface */ ++ /* ACM Descriptor */ ++ 0x04, /* u8 bLength */ ++ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ ++ USB_CDC_ACM_TYPE, /* u8 bDescriptorSubType */ ++ 0x00, /* u8 bmCapabilities */ ++ /* Union Descriptor */ ++ 0x05, /* u8 bLength */ ++ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ ++ USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */ ++ 0x00, /* u8 bMasterInterface0 */ ++ 0x01, /* u8 bSlaveInterface0 */ ++ /* Status Descriptor */ ++ 0x07, /* u8 bLength */ ++ USB_DT_ENDPOINT, /* u8 bDescriptorType */ ++ USB_DIR_IN | 1, /* u8 bEndpointAddress */ ++ USB_ENDPOINT_XFER_INT, /* u8 bmAttributes */ ++ STATUS_BYTECOUNT & 0xff, STATUS_BYTECOUNT >> 8, /* le16 wMaxPacketSize */ ++ 1 << LOG2_STATUS_INTERVAL_MSEC, /* u8 bInterval */ ++ /* RNDIS Data Interface */ ++ 0x09, /* u8 bLength */ ++ USB_DT_INTERFACE, /* u8 bDescriptorType */ ++ 0x01, /* u8 bInterfaceNumber */ ++ 0x00, /* u8 bAlternateSetting */ ++ 0x02, /* u8 bNumEndpoints */ ++ USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */ ++ 0x00, /* u8 bInterfaceSubClass */ ++ 0x00, /* u8 bInterfaceProtocol */ ++ STRING_DATA, /* u8 iInterface */ ++ /* Source Endpoint */ ++ 0x07, /* u8 bLength */ ++ USB_DT_ENDPOINT, /* u8 bDescriptorType */ ++ USB_DIR_IN | 2, /* u8 bEndpointAddress */ ++ USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */ ++ 0x40, 0x00, /* le16 wMaxPacketSize */ ++ 0x00, /* u8 bInterval */ ++ /* Sink Endpoint */ ++ 0x07, /* u8 bLength */ ++ USB_DT_ENDPOINT, /* u8 bDescriptorType */ ++ USB_DIR_OUT | 2, /* u8 bEndpointAddress */ ++ USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */ ++ 0x40, 0x00, /* le16 wMaxPacketSize */ ++ 0x00 /* u8 bInterval */ ++}; ++ ++static const uint8_t qemu_net_cdc_config_descriptor[] = { ++ /* Configuration Descriptor */ ++ 0x09, /* u8 bLength */ ++ USB_DT_CONFIG, /* u8 bDescriptorType */ ++ 0x50, 0x00, /* le16 wTotalLength */ ++ 0x02, /* u8 bNumInterfaces */ ++ DEV_CONFIG_VALUE, /* u8 bConfigurationValue */ ++ STRING_CDC, /* u8 iConfiguration */ ++ 0xc0, /* u8 bmAttributes */ ++ 0x32, /* u8 bMaxPower */ ++ /* CDC Control Interface */ ++ 0x09, /* u8 bLength */ ++ USB_DT_INTERFACE, /* u8 bDescriptorType */ ++ 0x00, /* u8 bInterfaceNumber */ ++ 0x00, /* u8 bAlternateSetting */ ++ 0x01, /* u8 bNumEndpoints */ ++ USB_CLASS_COMM, /* u8 bInterfaceClass */ ++ USB_CDC_SUBCLASS_ETHERNET, /* u8 bInterfaceSubClass */ ++ USB_CDC_PROTO_NONE, /* u8 bInterfaceProtocol */ ++ STRING_CONTROL, /* u8 iInterface */ ++ /* Header Descriptor */ ++ 0x05, /* u8 bLength */ ++ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ ++ USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */ ++ 0x10, 0x01, /* le16 bcdCDC */ ++ /* Union Descriptor */ ++ 0x05, /* u8 bLength */ ++ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ ++ USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */ ++ 0x00, /* u8 bMasterInterface0 */ ++ 0x01, /* u8 bSlaveInterface0 */ ++ /* Ethernet Descriptor */ ++ 0x0d, /* u8 bLength */ ++ USB_DT_CS_INTERFACE, /* u8 bDescriptorType */ ++ USB_CDC_ETHERNET_TYPE, /* u8 bDescriptorSubType */ ++ STRING_ETHADDR, /* u8 iMACAddress */ ++ 0x00, 0x00, 0x00, 0x00, /* le32 bmEthernetStatistics */ ++ ETH_FRAME_LEN & 0xff, ETH_FRAME_LEN >> 8, /* le16 wMaxSegmentSize */ ++ 0x00, 0x00, /* le16 wNumberMCFilters */ ++ 0x00, /* u8 bNumberPowerFilters */ ++ /* Status Descriptor */ ++ 0x07, /* u8 bLength */ ++ USB_DT_ENDPOINT, /* u8 bDescriptorType */ ++ USB_DIR_IN | 1, /* u8 bEndpointAddress */ ++ USB_ENDPOINT_XFER_INT, /* u8 bmAttributes */ ++ STATUS_BYTECOUNT & 0xff, STATUS_BYTECOUNT >> 8, /* le16 wMaxPacketSize */ ++ 1 << LOG2_STATUS_INTERVAL_MSEC, /* u8 bInterval */ ++ /* CDC Data (nop) Interface */ ++ 0x09, /* u8 bLength */ ++ USB_DT_INTERFACE, /* u8 bDescriptorType */ ++ 0x01, /* u8 bInterfaceNumber */ ++ 0x00, /* u8 bAlternateSetting */ ++ 0x00, /* u8 bNumEndpoints */ ++ USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */ ++ 0x00, /* u8 bInterfaceSubClass */ ++ 0x00, /* u8 bInterfaceProtocol */ ++ 0x00, /* u8 iInterface */ ++ /* CDC Data Interface */ ++ 0x09, /* u8 bLength */ ++ USB_DT_INTERFACE, /* u8 bDescriptorType */ ++ 0x01, /* u8 bInterfaceNumber */ ++ 0x01, /* u8 bAlternateSetting */ ++ 0x02, /* u8 bNumEndpoints */ ++ USB_CLASS_CDC_DATA, /* u8 bInterfaceClass */ ++ 0x00, /* u8 bInterfaceSubClass */ ++ 0x00, /* u8 bInterfaceProtocol */ ++ STRING_DATA, /* u8 iInterface */ ++ /* Source Endpoint */ ++ 0x07, /* u8 bLength */ ++ USB_DT_ENDPOINT, /* u8 bDescriptorType */ ++ USB_DIR_IN | 2, /* u8 bEndpointAddress */ ++ USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */ ++ 0x40, 0x00, /* le16 wMaxPacketSize */ ++ 0x00, /* u8 bInterval */ ++ /* Sink Endpoint */ ++ 0x07, /* u8 bLength */ ++ USB_DT_ENDPOINT, /* u8 bDescriptorType */ ++ USB_DIR_OUT | 2, /* u8 bEndpointAddress */ ++ USB_ENDPOINT_XFER_BULK, /* u8 bmAttributes */ ++ 0x40, 0x00, /* le16 wMaxPacketSize */ ++ 0x00 /* u8 bInterval */ +}; + -+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; ++/* ++ * RNDIS Status ++ */ + -+ case MENELAUS_INT_ACK1: -+ case MENELAUS_INT_ACK2: ++#define RNDIS_MAXIMUM_FRAME_SIZE 1518 ++#define RNDIS_MAX_TOTAL_SIZE 1558 ++ ++/* Remote NDIS Versions */ ++#define RNDIS_MAJOR_VERSION 1 ++#define RNDIS_MINOR_VERSION 0 ++ ++/* Status Values */ ++#define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */ ++#define RNDIS_STATUS_FAILURE 0xC0000001U /* Unspecified error */ ++#define RNDIS_STATUS_INVALID_DATA 0xC0010015U /* Invalid data */ ++#define RNDIS_STATUS_NOT_SUPPORTED 0xC00000BBU /* Unsupported request */ ++#define RNDIS_STATUS_MEDIA_CONNECT 0x4001000BU /* Device connected */ ++#define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000CU /* Device disconnected */ ++ ++/* Message Set for Connectionless (802.3) Devices */ ++#define REMOTE_NDIS_PACKET_MSG 0x00000001U ++#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002U /* Initialize device */ ++#define REMOTE_NDIS_HALT_MSG 0x00000003U ++#define REMOTE_NDIS_QUERY_MSG 0x00000004U ++#define REMOTE_NDIS_SET_MSG 0x00000005U ++#define REMOTE_NDIS_RESET_MSG 0x00000006U ++#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007U ++#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008U ++ ++/* Message completion */ ++#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002U ++#define REMOTE_NDIS_QUERY_CMPLT 0x80000004U ++#define REMOTE_NDIS_SET_CMPLT 0x80000005U ++#define REMOTE_NDIS_RESET_CMPLT 0x80000006U ++#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008U ++ ++/* Device Flags */ ++#define RNDIS_DF_CONNECTIONLESS 0x00000001U ++#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002U ++ ++#define RNDIS_MEDIUM_802_3 0x00000000U ++ ++/* from drivers/net/sk98lin/h/skgepnmi.h */ ++#define OID_PNP_CAPABILITIES 0xFD010100 ++#define OID_PNP_SET_POWER 0xFD010101 ++#define OID_PNP_QUERY_POWER 0xFD010102 ++#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 ++#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 ++#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 ++ ++typedef struct rndis_init_msg_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++ __le32 MajorVersion; ++ __le32 MinorVersion; ++ __le32 MaxTransferSize; ++} rndis_init_msg_type; ++ ++typedef struct rndis_init_cmplt_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++ __le32 Status; ++ __le32 MajorVersion; ++ __le32 MinorVersion; ++ __le32 DeviceFlags; ++ __le32 Medium; ++ __le32 MaxPacketsPerTransfer; ++ __le32 MaxTransferSize; ++ __le32 PacketAlignmentFactor; ++ __le32 AFListOffset; ++ __le32 AFListSize; ++} rndis_init_cmplt_type; ++ ++typedef struct rndis_halt_msg_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++} rndis_halt_msg_type; ++ ++typedef struct rndis_query_msg_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++ __le32 OID; ++ __le32 InformationBufferLength; ++ __le32 InformationBufferOffset; ++ __le32 DeviceVcHandle; ++} rndis_query_msg_type; ++ ++typedef struct rndis_query_cmplt_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++ __le32 Status; ++ __le32 InformationBufferLength; ++ __le32 InformationBufferOffset; ++} rndis_query_cmplt_type; ++ ++typedef struct rndis_set_msg_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++ __le32 OID; ++ __le32 InformationBufferLength; ++ __le32 InformationBufferOffset; ++ __le32 DeviceVcHandle; ++} rndis_set_msg_type; ++ ++typedef struct rndis_set_cmplt_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++ __le32 Status; ++} rndis_set_cmplt_type; ++ ++typedef struct rndis_reset_msg_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 Reserved; ++} rndis_reset_msg_type; ++ ++typedef struct rndis_reset_cmplt_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 Status; ++ __le32 AddressingReset; ++} rndis_reset_cmplt_type; ++ ++typedef struct rndis_indicate_status_msg_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 Status; ++ __le32 StatusBufferLength; ++ __le32 StatusBufferOffset; ++} rndis_indicate_status_msg_type; ++ ++typedef struct rndis_keepalive_msg_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++} rndis_keepalive_msg_type; ++ ++typedef struct rndis_keepalive_cmplt_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 RequestID; ++ __le32 Status; ++} rndis_keepalive_cmplt_type; ++ ++struct rndis_packet_msg_type ++{ ++ __le32 MessageType; ++ __le32 MessageLength; ++ __le32 DataOffset; ++ __le32 DataLength; ++ __le32 OOBDataOffset; ++ __le32 OOBDataLength; ++ __le32 NumOOBDataElements; ++ __le32 PerPacketInfoOffset; ++ __le32 PerPacketInfoLength; ++ __le32 VcHandle; ++ __le32 Reserved; ++}; ++ ++struct rndis_config_parameter ++{ ++ __le32 ParameterNameOffset; ++ __le32 ParameterNameLength; ++ __le32 ParameterType; ++ __le32 ParameterValueOffset; ++ __le32 ParameterValueLength; ++}; ++ ++/* implementation specific */ ++enum rndis_state ++{ ++ RNDIS_UNINITIALIZED, ++ RNDIS_INITIALIZED, ++ RNDIS_DATA_INITIALIZED, ++}; ++ ++static const uint32_t oid_supported_list[] = ++{ ++ /* the general stuff */ ++ OID_GEN_SUPPORTED_LIST, ++ OID_GEN_HARDWARE_STATUS, ++ OID_GEN_MEDIA_SUPPORTED, ++ OID_GEN_MEDIA_IN_USE, ++ OID_GEN_MAXIMUM_FRAME_SIZE, ++ OID_GEN_LINK_SPEED, ++ OID_GEN_TRANSMIT_BLOCK_SIZE, ++ OID_GEN_RECEIVE_BLOCK_SIZE, ++ OID_GEN_VENDOR_ID, ++ OID_GEN_VENDOR_DESCRIPTION, ++ OID_GEN_VENDOR_DRIVER_VERSION, ++ OID_GEN_CURRENT_PACKET_FILTER, ++ OID_GEN_MAXIMUM_TOTAL_SIZE, ++ OID_GEN_MEDIA_CONNECT_STATUS, ++ OID_GEN_PHYSICAL_MEDIUM, ++ /* the statistical stuff */ ++ OID_GEN_XMIT_OK, ++ OID_GEN_RCV_OK, ++ OID_GEN_XMIT_ERROR, ++ OID_GEN_RCV_ERROR, ++ OID_GEN_RCV_NO_BUFFER, ++ /* mandatory 802.3 */ ++ /* the general stuff */ ++ OID_802_3_PERMANENT_ADDRESS, ++ OID_802_3_CURRENT_ADDRESS, ++ OID_802_3_MULTICAST_LIST, ++ OID_802_3_MAC_OPTIONS, ++ OID_802_3_MAXIMUM_LIST_SIZE, ++ ++ /* the statistical stuff */ ++ OID_802_3_RCV_ERROR_ALIGNMENT, ++ OID_802_3_XMIT_ONE_COLLISION, ++ OID_802_3_XMIT_MORE_COLLISIONS ++}; ++ ++struct rndis_response { ++ TAILQ_ENTRY(rndis_response) entries; ++ uint32_t length; ++ uint8_t buf[0]; ++}; ++ ++ ++typedef struct USBNetState { ++ USBDevice dev; ++ ++ unsigned int rndis; ++ enum rndis_state rndis_state; ++ uint32_t medium; ++ uint32_t speed; ++ uint32_t media_state; ++ uint16_t filter; ++ uint32_t vendorid; ++ uint8_t mac[6]; ++ ++ unsigned int out_ptr; ++ uint8_t out_buf[2048]; ++ ++ USBPacket *inpkt; ++ unsigned int in_ptr, in_len; ++ uint8_t in_buf[2048]; ++ ++ VLANClientState *vc; ++ TAILQ_HEAD(rndis_resp_head, rndis_response) rndis_resp; ++} USBNetState; ++ ++ ++static int ndis_query(USBNetState *s, uint32_t oid, uint8_t *inbuf, unsigned int inlen, uint8_t *outbuf) ++{ ++ switch (oid) { ++ /* general oids (table 4-1) */ ++ /* mandatory */ ++ case OID_GEN_SUPPORTED_LIST: ++ { ++ unsigned int i, count = sizeof(oid_supported_list) / sizeof(uint32_t); ++ for (i = 0; i < count; i++) ++ ((__le32 *)outbuf)[i] = cpu_to_le32(oid_supported_list[i]); ++ return sizeof(oid_supported_list); ++ } ++ ++ /* mandatory */ ++ case OID_GEN_HARDWARE_STATUS: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_MEDIA_SUPPORTED: ++ *((__le32 *)outbuf) = cpu_to_le32(s->medium); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_MEDIA_IN_USE: ++ *((__le32 *)outbuf) = cpu_to_le32(s->medium); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_MAXIMUM_FRAME_SIZE: ++ *((__le32 *)outbuf) = cpu_to_le32(ETH_FRAME_LEN); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_LINK_SPEED: ++ *((__le32 *)outbuf) = cpu_to_le32(s->speed); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_TRANSMIT_BLOCK_SIZE: ++ *((__le32 *)outbuf) = cpu_to_le32(ETH_FRAME_LEN); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_RECEIVE_BLOCK_SIZE: ++ *((__le32 *)outbuf) = cpu_to_le32(ETH_FRAME_LEN); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_VENDOR_ID: ++ *((__le32 *)outbuf) = cpu_to_le32(0x1234); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_VENDOR_DESCRIPTION: ++ strcpy(outbuf, "QEMU USB RNDIS Net"); ++ return strlen(outbuf) + 1; ++ ++ case OID_GEN_VENDOR_DRIVER_VERSION: ++ *((__le32 *)outbuf) = cpu_to_le32(1); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_CURRENT_PACKET_FILTER: ++ *((__le32 *)outbuf) = cpu_to_le32(s->filter); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_MAXIMUM_TOTAL_SIZE: ++ *((__le32 *)outbuf) = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_MEDIA_CONNECT_STATUS: ++ *((__le32 *)outbuf) = cpu_to_le32(s->media_state); ++ return sizeof(__le32); ++ ++ case OID_GEN_PHYSICAL_MEDIUM: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ case OID_GEN_MAC_OPTIONS: ++ *((__le32 *)outbuf) = cpu_to_le32(NDIS_MAC_OPTION_RECEIVE_SERIALIZED | NDIS_MAC_OPTION_FULL_DUPLEX); ++ return sizeof(__le32); ++ ++ /* statistics OIDs (table 4-2) */ ++ /* mandatory */ ++ case OID_GEN_XMIT_OK: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_RCV_OK: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_XMIT_ERROR: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_RCV_ERROR: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_GEN_RCV_NO_BUFFER: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ /* ieee802.3 OIDs (table 4-3) */ ++ /* mandatory */ ++ case OID_802_3_PERMANENT_ADDRESS: ++ memcpy(outbuf, s->mac, 6); ++ return 6; ++ ++ /* mandatory */ ++ case OID_802_3_CURRENT_ADDRESS: ++ memcpy(outbuf, s->mac, 6); ++ return 6; ++ ++ /* mandatory */ ++ case OID_802_3_MULTICAST_LIST: ++ *((__le32 *)outbuf) = cpu_to_le32(0xE0000000); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_802_3_MAXIMUM_LIST_SIZE: ++ *((__le32 *)outbuf) = cpu_to_le32(1); ++ return sizeof(__le32); ++ ++ case OID_802_3_MAC_OPTIONS: ++ return 0; ++ ++ /* ieee802.3 statistics OIDs (table 4-4) */ ++ /* mandatory */ ++ case OID_802_3_RCV_ERROR_ALIGNMENT: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_802_3_XMIT_ONE_COLLISION: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ /* mandatory */ ++ case OID_802_3_XMIT_MORE_COLLISIONS: ++ *((__le32 *)outbuf) = cpu_to_le32(0); ++ return sizeof(__le32); ++ ++ default: ++ fprintf(stderr, "usbnet: unknown OID 0x%08x\n", oid); ++ return 0; ++ } ++ return -1; ++} ++ ++static int ndis_set(USBNetState *s, uint32_t oid, uint8_t *inbuf, unsigned int inlen) ++{ ++ switch (oid) { ++ case OID_GEN_CURRENT_PACKET_FILTER: ++ s->filter = le32_to_cpup((__le32 *)inbuf); ++ if (s->filter) { ++ s->rndis_state = RNDIS_DATA_INITIALIZED; ++ } else { ++ s->rndis_state = RNDIS_INITIALIZED; ++ } ++ return 0; ++ ++ case OID_802_3_MULTICAST_LIST: ++ return 0; ++ ++ } ++ return -1; ++} ++ ++static int rndis_get_response(USBNetState *s, uint8_t *buf) ++{ ++ int ret = 0; ++ struct rndis_response *r = s->rndis_resp.tqh_first; ++ if (!r) ++ return ret; ++ TAILQ_REMOVE(&s->rndis_resp, r, entries); ++ ret = r->length; ++ memcpy(buf, r->buf, r->length); ++ qemu_free(r); ++ return ret; ++} ++ ++static void *rndis_queue_response(USBNetState *s, unsigned int length) ++{ ++ struct rndis_response *r = qemu_mallocz(sizeof(struct rndis_response) + length); ++ if (!r) ++ return NULL; ++ TAILQ_INSERT_TAIL(&s->rndis_resp, r, entries); ++ r->length = length; ++ return &r->buf[0]; ++} ++ ++static void rndis_clear_responsequeue(USBNetState *s) ++{ ++ struct rndis_response *r; ++ ++ while ((r = s->rndis_resp.tqh_first)) { ++ TAILQ_REMOVE(&s->rndis_resp, r, entries); ++ qemu_free(r); ++ } ++} ++ ++static int rndis_init_response(USBNetState *s, rndis_init_msg_type *buf) ++{ ++ rndis_init_cmplt_type *resp = rndis_queue_response(s, sizeof(rndis_init_cmplt_type)); ++ if (!resp) ++ return USB_RET_STALL; ++ resp->MessageType = cpu_to_le32(REMOTE_NDIS_INITIALIZE_CMPLT); ++ resp->MessageLength = cpu_to_le32(sizeof(rndis_init_cmplt_type)); ++ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ ++ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); ++ resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION); ++ resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION); ++ resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS); ++ resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3); ++ resp->MaxPacketsPerTransfer = cpu_to_le32(1); ++ resp->MaxTransferSize = cpu_to_le32(ETH_FRAME_LEN + sizeof(struct rndis_packet_msg_type) + 22); ++ resp->PacketAlignmentFactor = cpu_to_le32(0); ++ resp->AFListOffset = cpu_to_le32(0); ++ resp->AFListSize = cpu_to_le32(0); + return 0; ++} + -+ 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; ++static int rndis_query_response(USBNetState *s, rndis_query_msg_type *buf, unsigned int length) ++{ ++ rndis_query_cmplt_type *resp; ++ uint8_t infobuf[sizeof(oid_supported_list)]; /* oid_supported_list is the largest data reply */ ++ uint32_t bufoffs, buflen; ++ int infobuflen; ++ unsigned int resplen; ++ bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8; ++ buflen = le32_to_cpu(buf->InformationBufferLength); ++ if (bufoffs + buflen > length) ++ return USB_RET_STALL; ++ infobuflen = ndis_query(s, le32_to_cpu(buf->OID), bufoffs + (uint8_t *)buf, buflen, infobuf); ++ resplen = sizeof(rndis_query_cmplt_type) + ((infobuflen < 0) ? 0 : infobuflen); ++ resp = rndis_queue_response(s, resplen); ++ if (!resp) ++ return USB_RET_STALL; ++ resp->MessageType = cpu_to_le32(REMOTE_NDIS_QUERY_CMPLT); ++ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ ++ resp->MessageLength = cpu_to_le32(resplen); ++ if (infobuflen < 0) { ++ /* OID not supported */ ++ resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); ++ resp->InformationBufferLength = cpu_to_le32(0); ++ resp->InformationBufferOffset = cpu_to_le32(0); ++ return 0; ++ } ++ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); ++ resp->InformationBufferOffset = cpu_to_le32(infobuflen ? sizeof(rndis_query_cmplt_type) - 8 : 0); ++ resp->InformationBufferLength = cpu_to_le32(infobuflen); ++ memcpy(resp + 1, infobuf, infobuflen); ++ return 0; ++} ++ ++static int rndis_set_response(USBNetState *s, rndis_set_msg_type *buf, unsigned int length) ++{ ++ rndis_set_cmplt_type *resp = rndis_queue_response(s, sizeof(rndis_set_cmplt_type)); ++ uint32_t bufoffs, buflen; ++ if (!resp) ++ return USB_RET_STALL; ++ bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8; ++ buflen = le32_to_cpu(buf->InformationBufferLength); ++ if (bufoffs + buflen > length) ++ return USB_RET_STALL; ++ int ret = ndis_set(s, le32_to_cpu(buf->OID), bufoffs + (uint8_t *)buf, buflen); ++ resp->MessageType = cpu_to_le32(REMOTE_NDIS_SET_CMPLT); ++ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ ++ resp->MessageLength = cpu_to_le32(sizeof(rndis_set_cmplt_type)); ++ if (ret < 0) { ++ /* OID not supported */ ++ resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED); ++ return 0; ++ } ++ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); ++ return 0; ++} ++ ++static int rndis_reset_response(USBNetState *s, rndis_reset_msg_type *buf) ++{ ++ rndis_reset_cmplt_type *resp = rndis_queue_response(s, sizeof(rndis_reset_cmplt_type)); ++ if (!resp) ++ return USB_RET_STALL; ++ resp->MessageType = cpu_to_le32(REMOTE_NDIS_RESET_CMPLT); ++ resp->MessageLength = cpu_to_le32(sizeof(rndis_reset_cmplt_type)); ++ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); ++ /* resent information */ ++ resp->AddressingReset = cpu_to_le32(1); ++ return 0; ++} ++ ++static int rndis_keepalive_response(USBNetState *s, rndis_keepalive_msg_type *buf) ++{ ++ rndis_keepalive_cmplt_type *resp = rndis_queue_response(s, sizeof(rndis_keepalive_cmplt_type)); ++ if (!resp) ++ return USB_RET_STALL; ++ resp->MessageType = cpu_to_le32(REMOTE_NDIS_KEEPALIVE_CMPLT); ++ resp->MessageLength = cpu_to_le32(sizeof(rndis_keepalive_cmplt_type)); ++ resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ ++ resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS); ++ return 0; ++} ++ ++static int rndis_parse(USBNetState *s, uint8_t *data, int length) ++{ ++ uint32_t MsgType, MsgLength; ++ __le32 *tmp = (__le32 *)data; ++ MsgType = le32_to_cpup(tmp++); ++ MsgLength = le32_to_cpup(tmp++); ++ ++ switch (MsgType) { ++ case REMOTE_NDIS_INITIALIZE_MSG: ++ s->rndis_state = RNDIS_INITIALIZED; ++ return rndis_init_response(s, (rndis_init_msg_type *)data); ++ ++ case REMOTE_NDIS_HALT_MSG: ++ s->rndis_state = RNDIS_UNINITIALIZED; ++ return 0; + -+ default: -+#ifdef VERBOSE -+ printf("%s: unknown register %02x\n", __FUNCTION__, addr); ++ case REMOTE_NDIS_QUERY_MSG: ++ return rndis_query_response(s, (rndis_query_msg_type *)data, length); ++ ++ case REMOTE_NDIS_SET_MSG: ++ return rndis_set_response(s, (rndis_set_msg_type *)data, length); ++ ++ case REMOTE_NDIS_RESET_MSG: ++ rndis_clear_responsequeue(s); ++ s->out_ptr = s->in_ptr = s->in_len = 0; ++ return rndis_reset_response(s, (rndis_reset_msg_type *)data); ++ ++ case REMOTE_NDIS_KEEPALIVE_MSG: ++ /* For USB: host does this every 5 seconds */ ++ return rndis_keepalive_response(s, (rndis_keepalive_msg_type *)data); ++ } ++ return USB_RET_STALL; ++} ++ ++static void usb_net_handle_reset(USBDevice *dev) ++{ ++} ++ ++static int usb_net_handle_control(USBDevice *dev, int request, int value, ++ int index, int length, uint8_t *data) ++{ ++ USBNetState *s = (USBNetState *)dev; ++ int ret = 0; ++ ++ switch(request) { ++ case DeviceRequest | USB_REQ_GET_STATUS: ++ data[0] = (1 << USB_DEVICE_SELF_POWERED) | ++ (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); ++ data[1] = 0x00; ++ ret = 2; ++ break; ++ ++ case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: ++ if (value == USB_DEVICE_REMOTE_WAKEUP) { ++ dev->remote_wakeup = 0; ++ } else { ++ goto fail; ++ } ++ ret = 0; ++ break; ++ ++ case DeviceOutRequest | USB_REQ_SET_FEATURE: ++ if (value == USB_DEVICE_REMOTE_WAKEUP) { ++ dev->remote_wakeup = 1; ++ } else { ++ goto fail; ++ } ++ ret = 0; ++ break; ++ ++ case DeviceOutRequest | USB_REQ_SET_ADDRESS: ++ dev->addr = value; ++ ret = 0; ++ break; ++ ++ case ClassInterfaceOutRequest | USB_CDC_SEND_ENCAPSULATED_COMMAND: ++ if (!s->rndis || value || index != 0) ++ goto fail; ++#if TRAFFIC_DEBUG ++ { ++ unsigned int i; ++ fprintf(stderr, "SEND_ENCAPSULATED_COMMAND:"); ++ for (i = 0; i < length; i++) { ++ if (!(i & 15)) ++ fprintf(stderr, "\n%04X:", i); ++ fprintf(stderr, " %02X", data[i]); ++ } ++ fprintf(stderr, "\n\n"); ++ } +#endif -+ 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); ++ ret = rndis_parse(s, data, length); ++ break; ++ ++ case ClassInterfaceRequest | USB_CDC_GET_ENCAPSULATED_RESPONSE: ++ if (!s->rndis || value || index != 0) ++ goto fail; ++ ret = rndis_get_response(s, data); ++ if (!ret) { ++ data[0] = 0; ++ ret = 1; ++ } ++#if TRAFFIC_DEBUG ++ { ++ unsigned int i; ++ fprintf(stderr, "GET_ENCAPSULATED_RESPONSE:"); ++ for (i = 0; i < ret; i++) { ++ if (!(i & 15)) ++ fprintf(stderr, "\n%04X:", i); ++ fprintf(stderr, " %02X", data[i]); ++ } ++ fprintf(stderr, "\n\n"); ++ } +#endif -+ } -+} -+ -+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, ++ break; ++ ++ case DeviceRequest | USB_REQ_GET_DESCRIPTOR: ++ switch(value >> 8) { ++ case USB_DT_DEVICE: ++ ret = sizeof(qemu_net_dev_descriptor); ++ memcpy(data, qemu_net_dev_descriptor, ret); ++ break; ++ ++ case USB_DT_CONFIG: ++ switch (value & 0xff) { ++ case 0: ++ ret = sizeof(qemu_net_rndis_config_descriptor); ++ memcpy(data, qemu_net_rndis_config_descriptor, ++ ret); ++ break; ++ ++ case 1: ++ ret = sizeof(qemu_net_cdc_config_descriptor); ++ memcpy(data, qemu_net_cdc_config_descriptor, ++ ret); ++ break; ++ ++ default: ++ goto fail; ++ } ++ data[2] = ret & 0xff; ++ data[3] = ret >> 8; ++ break; ++ ++ case USB_DT_STRING: ++ switch (value & 0xff) { ++ case 0: ++ /* language ids */ ++ data[0] = 4; ++ data[1] = 3; ++ data[2] = 0x09; ++ data[3] = 0x04; ++ ret = 4; ++ break; ++ ++ case STRING_MANUFACTURER: ++ ret = set_usb_string(data, "QEMU"); ++ break; ++ ++ case STRING_PRODUCT: ++ ret = set_usb_string(data, "RNDIS/QEMU USB Network Device"); ++ break; ++ ++ case STRING_ETHADDR: ++ ret = set_usb_string(data, "400102030405"); ++ break; ++ ++ case STRING_DATA: ++ ret = set_usb_string(data, "QEMU USB Net Data Interface"); ++ break; ++ ++ case STRING_CONTROL: ++ ret = set_usb_string(data, "QEMU USB Net Control Interface"); ++ break; ++ ++ case STRING_RNDIS_CONTROL: ++ ret = set_usb_string(data, "QEMU USB Net RNDIS Control Interface"); ++ break; ++ ++ case STRING_CDC: ++ ret = set_usb_string(data, "QEMU USB Net CDC"); ++ break; ++ ++ case STRING_SUBSET: ++ ret = set_usb_string(data, "QEMU USB Net Subset"); ++ break; ++ ++ case STRING_RNDIS: ++ ret = set_usb_string(data, "QEMU USB Net RNDIS"); ++ break; ++ ++ case STRING_SERIALNUMBER: ++ ret = set_usb_string(data, "1"); ++ break; ++ ++ default: ++ goto fail; ++ } ++ break; ++ ++ default: ++ goto fail; ++ } ++ break; ++ ++ case DeviceRequest | USB_REQ_GET_CONFIGURATION: ++ data[0] = s->rndis ? DEV_RNDIS_CONFIG_VALUE : DEV_CONFIG_VALUE; ++ ret = 1; ++ break; ++ ++ case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: ++ switch (value & 0xff) { ++ case DEV_CONFIG_VALUE: ++ s->rndis = 0; ++ break; ++ ++ case DEV_RNDIS_CONFIG_VALUE: ++ s->rndis = 1; ++ break; ++ ++ default: ++ goto fail; ++ } ++ ret = 0; ++ break; ++ ++ case DeviceRequest | USB_REQ_GET_INTERFACE: ++ case InterfaceRequest | USB_REQ_GET_INTERFACE: ++ data[0] = 0; ++ ret = 1; ++ break; ++ ++ case DeviceOutRequest | USB_REQ_SET_INTERFACE: ++ case InterfaceOutRequest | USB_REQ_SET_INTERFACE: ++ ret = 0; ++ break; ++ ++ default: ++ fail: ++ fprintf(stderr, "usbnet: failed control transaction: request 0x%x value 0x%x index 0x%x length 0x%x\n", ++ request, value, index, length); ++ ret = USB_RET_STALL; ++ break; ++ } ++ return ret; ++} ++ ++static int usb_net_handle_statusin(USBNetState *s, USBPacket *p) ++{ ++ int ret = 8; ++ if (p->len < 8) ++ return USB_RET_STALL; ++ ((__le32 *)p->data)[0] = cpu_to_le32(1); ++ ((__le32 *)p->data)[1] = cpu_to_le32(0); ++ if (!s->rndis_resp.tqh_first) ++ ret = USB_RET_NAK; ++#if DEBUG ++ fprintf(stderr, "usbnet: interrupt poll len %u return %d", p->len, ret); ++ { ++ int i; ++ fprintf(stderr, ":"); ++ for (i = 0; i < ret; i++) { ++ if (!(i & 15)) ++ fprintf(stderr, "\n%04X:", i); ++ fprintf(stderr, " %02X", p->data[i]); ++ } ++ fprintf(stderr, "\n\n"); ++ } ++#endif ++ return ret; ++} ++ ++static int usb_net_handle_datain(USBNetState *s, USBPacket *p) ++{ ++ int ret = USB_RET_NAK; ++ ++ if (s->in_ptr > s->in_len) { ++ s->in_ptr = s->in_len = 0; ++ ret = USB_RET_NAK; ++ return ret; ++ } ++ if (!s->in_len) { ++ ret = USB_RET_NAK; ++ return ret; ++ } ++ ret = s->in_len - s->in_ptr; ++ if (ret > p->len) ++ ret = p->len; ++ memcpy(p->data, &s->in_buf[s->in_ptr], ret); ++ s->in_ptr += ret; ++ if (s->in_ptr >= s->in_len && (s->rndis || (s->in_len & (64-1)) || !ret)) { ++ /* no short packet necessary */ ++ s->in_ptr = s->in_len = 0; ++ } ++#if TRAFFIC_DEBUG ++ fprintf(stderr, "usbnet: data in len %u return %d", p->len, ret); ++ { ++ int i; ++ fprintf(stderr, ":"); ++ for (i = 0; i < ret; i++) { ++ if (!(i & 15)) ++ fprintf(stderr, "\n%04X:", i); ++ fprintf(stderr, " %02X", p->data[i]); ++ } ++ fprintf(stderr, "\n\n"); ++ } ++#endif ++ return ret; ++} ++ ++static int usb_net_handle_dataout(USBNetState *s, USBPacket *p) ++{ ++ int ret = p->len; ++ int sz = sizeof(s->out_buf) - s->out_ptr; ++ struct rndis_packet_msg_type *msg = (struct rndis_packet_msg_type *)s->out_buf; ++ uint32_t len; ++ ++#if TRAFFIC_DEBUG ++ fprintf(stderr, "usbnet: data out len %u\n", p->len); ++ { ++ int i; ++ fprintf(stderr, ":"); ++ for (i = 0; i < p->len; i++) { ++ if (!(i & 15)) ++ fprintf(stderr, "\n%04X:", i); ++ fprintf(stderr, " %02X", p->data[i]); ++ } ++ fprintf(stderr, "\n\n"); ++ } ++#endif ++ if (sz > ret) ++ sz = ret; ++ memcpy(&s->out_buf[s->out_ptr], p->data, sz); ++ s->out_ptr += sz; ++ if (!s->rndis) { ++ if (ret < 64) { ++ qemu_send_packet(s->vc, s->out_buf, s->out_ptr); ++ s->out_ptr = 0; ++ } ++ return ret; ++ } ++ len = le32_to_cpu(msg->MessageLength); ++ if (s->out_ptr < 8 || s->out_ptr < len) ++ return ret; ++ if (le32_to_cpu(msg->MessageType) == REMOTE_NDIS_PACKET_MSG) { ++ uint32_t offs = 8 + le32_to_cpu(msg->DataOffset); ++ uint32_t size = le32_to_cpu(msg->DataLength); ++ if (offs + size <= len) ++ qemu_send_packet(s->vc, s->out_buf + offs, size); ++ } ++ s->out_ptr -= len; ++ memmove(s->out_buf, &s->out_buf[len], s->out_ptr); ++ return ret; ++} ++ ++static int usb_net_handle_data(USBDevice *dev, USBPacket *p) ++{ ++ USBNetState *s = (USBNetState *)dev; ++ int ret = 0; ++ ++ switch(p->pid) { ++ case USB_TOKEN_IN: ++ switch (p->devep) { ++ case 1: ++ ret = usb_net_handle_statusin(s, p); ++ break; ++ ++ case 2: ++ ret = usb_net_handle_datain(s, p); ++ break; ++ ++ default: ++ goto fail; ++ } ++ break; ++ ++ case USB_TOKEN_OUT: ++ switch (p->devep) { ++ case 2: ++ ret = usb_net_handle_dataout(s, p); ++ break; ++ ++ default: ++ goto fail; ++ } ++ break; ++ ++ default: ++ fail: ++ ret = USB_RET_STALL; ++ break; ++ } ++ if (ret == USB_RET_STALL) ++ fprintf(stderr, "usbnet: failed data transaction: pid 0x%x ep 0x%x len 0x%x\n", p->pid, p->devep, p->len); ++ return ret; ++} ++ ++static void usbnet_receive(void *opaque, const uint8_t *buf, int size) ++{ ++ USBNetState *s = opaque; ++ ++ if (s->rndis) { ++ struct rndis_packet_msg_type *msg = (struct rndis_packet_msg_type *)s->in_buf; ++ if (!s->rndis_state == RNDIS_DATA_INITIALIZED) ++ return; ++ if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf)) ++ return; ++ memset(msg, 0, sizeof(struct rndis_packet_msg_type)); ++ msg->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG); ++ msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type)); ++ msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8); ++ msg->DataLength = cpu_to_le32(size); ++ //msg->OOBDataOffset; ++ //msg->OOBDataLength; ++ //msg->NumOOBDataElements; ++ //msg->PerPacketInfoOffset; ++ //msg->PerPacketInfoLength; ++ //msg->VcHandle; ++ //msg->Reserved; ++ memcpy(msg + 1, buf, size); ++ s->in_len = size + sizeof(struct rndis_packet_msg_type); ++ } else { ++ if (size > sizeof(s->in_buf)) ++ return; ++ memcpy(s->in_buf, buf, size); ++ s->in_len = size; ++ } ++ s->in_ptr = 0; ++} ++ ++static int usbnet_can_receive(void *opaque) ++{ ++ USBNetState *s = opaque; ++ ++ if (s->rndis && !s->rndis_state == RNDIS_DATA_INITIALIZED) ++ return 1; ++ return !s->in_len; ++} ++ ++static void usb_net_handle_destroy(USBDevice *dev) ++{ ++ USBNetState *s = (USBNetState *)dev; ++ rndis_clear_responsequeue(s); ++ qemu_free(s); ++} ++ ++USBDevice *usb_net_init(NICInfo *nd) ++{ ++ USBNetState *s; ++ ++ s = qemu_mallocz(sizeof(USBNetState)); ++ if (!s) ++ return NULL; ++ s->dev.speed = USB_SPEED_FULL; ++ s->dev.handle_packet = usb_generic_handle_packet; ++ ++ s->dev.handle_reset = usb_net_handle_reset; ++ s->dev.handle_control = usb_net_handle_control; ++ s->dev.handle_data = usb_net_handle_data; ++ s->dev.handle_destroy = usb_net_handle_destroy; ++ ++ s->rndis = 1; ++ s->rndis_state = RNDIS_UNINITIALIZED; ++ s->medium = NDIS_MEDIUM_802_3; ++ s->speed = 1000000; /* 100MBps, in 100Bps units */ ++ s->media_state = NDIS_MEDIA_STATE_CONNECTED; ++ s->filter = 0; ++ s->vendorid = 0x1234; ++ memcpy(s->mac, nd->macaddr, 6); ++ TAILQ_INIT(&s->rndis_resp); ++ ++ pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Network Interface"); ++ s->vc = qemu_new_vlan_client(nd->vlan, usbnet_receive, usbnet_can_receive, s); ++ snprintf(s->vc->info_str, sizeof(s->vc->info_str), ++ "usbnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x", ++ s->mac[0], s->mac[1], s->mac[2], ++ s->mac[3], s->mac[4], s->mac[5]); ++ fprintf(stderr, "usbnet: initialized mac %02x:%02x:%02x:%02x:%02x:%02x\n", ++ s->mac[0], s->mac[1], s->mac[2], ++ s->mac[3], s->mac[4], s->mac[5]); ++ return (USBDevice *)s; ++} +diff -urN 4242/Makefile qemu-omap/Makefile +--- 4242/Makefile 2008-04-24 20:17:05.000000000 +0100 ++++ qemu-omap/Makefile 2008-04-23 09:57:55.000000000 +0100 +@@ -55,7 +55,8 @@ + OBJS+=tmp105.o + OBJS+=scsi-disk.o cdrom.o + OBJS+=scsi-generic.o +-OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o usb-serial.o ++OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-net.o ++OBJS+=usb-wacom.o usb-serial.o + OBJS+=sd.o ssi-sd.o + + ifdef CONFIG_BRLAPI +diff -urN 4242/softmmu_template.h qemu-omap/softmmu_template.h +--- 4242/softmmu_template.h 2008-04-24 18:11:49.000000000 +0100 ++++ qemu-omap/softmmu_template.h 2008-04-23 09:57:56.000000000 +0100 +@@ -51,12 +51,15 @@ int mmu_idx, void *retaddr); static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, @@ -13821,7 +2162,7 @@ index 0a4bc7e..d480f34 100644 #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, +@@ -95,7 +98,9 @@ /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; @@ -13832,7 +2173,7 @@ index 0a4bc7e..d480f34 100644 } 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, +@@ -147,7 +152,9 @@ /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; @@ -13843,7 +2184,7 @@ index 0a4bc7e..d480f34 100644 } 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, +@@ -186,11 +193,14 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, DATA_TYPE val, target_ulong tlb_addr, @@ -13860,7 +2201,7 @@ index 0a4bc7e..d480f34 100644 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, +@@ -228,7 +238,8 @@ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; retaddr = GETPC(); @@ -13870,7 +2211,7 @@ index 0a4bc7e..d480f34 100644 } 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, +@@ -278,7 +289,8 @@ /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; @@ -13880,91 +2221,161 @@ index 0a4bc7e..d480f34 100644 } 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 +diff -urN 4242/target-i386/cpu.h qemu-omap/target-i386/cpu.h +--- 4242/target-i386/cpu.h 2008-04-23 12:18:51.000000000 +0100 ++++ qemu-omap/target-i386/cpu.h 2008-04-23 09:57:56.000000000 +0100 +@@ -499,7 +499,7 @@ + SegmentCache idt; /* only base and limit are used */ + + target_ulong cr[9]; /* NOTE: cr1, cr5-7 are unused */ +- uint64_t a20_mask; ++ uint32_t a20_mask; + + /* FPU state */ + unsigned int fpstt; /* top of stack index */ +diff -urN 4242/target-i386/helper2.c qemu-omap/target-i386/helper2.c +--- 4242/target-i386/helper2.c 2008-04-23 12:18:51.000000000 +0100 ++++ qemu-omap/target-i386/helper2.c 2008-04-23 09:57:56.000000000 +0100 +@@ -377,7 +377,7 @@ + env->hflags |= HF_GIF_MASK; + + cpu_x86_update_cr0(env, 0x60000010); +- env->a20_mask = ~0x0; ++ env->a20_mask = 0xffffffff; + env->smbase = 0x30000; + + env->idt.limit = 0xffff; +@@ -695,7 +695,7 @@ + /* when a20 is changed, all the MMU mappings are invalid, so + we must flush everything */ + tlb_flush(env, 1); +- env->a20_mask = (~0x100000) | (a20_state << 20); ++ env->a20_mask = 0xffefffff | (a20_state << 20); + } + } - /* 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; +@@ -800,8 +800,7 @@ - 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; + #else + +-/* Bits 52-62 of a PTE are reserved. Bit 63 is the NX bit. */ +-#define PHYS_ADDR_MASK 0xffffffffff000L ++#define PHYS_ADDR_MASK 0xfffff000 + + /* return value: + -1 = cannot handle fault +@@ -813,10 +812,9 @@ + int is_write1, int mmu_idx, int is_softmmu) + { + uint64_t ptep, pte; +- target_ulong pde_addr, pte_addr; ++ uint32_t pdpe_addr, pde_addr, pte_addr; + int error_code, is_dirty, prot, page_size, ret, is_write, is_user; +- target_phys_addr_t paddr; +- uint32_t page_offset; ++ unsigned long paddr, page_offset; + target_ulong vaddr, virt_addr; + + is_user = mmu_idx == MMU_USER_IDX; +@@ -836,11 +834,12 @@ + + if (env->cr[4] & CR4_PAE_MASK) { + uint64_t pde, pdpe; +- target_ulong pdpe_addr; + ++ /* XXX: we only use 32 bit physical addresses */ + #ifdef TARGET_X86_64 + if (env->hflags & HF_LMA_MASK) { +- uint64_t pml4e_addr, pml4e; ++ uint32_t pml4e_addr; ++ uint64_t pml4e; + int32_t sext; + + /* test virtual address sign extension */ +@@ -1102,19 +1101,17 @@ + + target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) + { +- target_ulong pde_addr, pte_addr; +- uint64_t pte; +- target_phys_addr_t paddr; +- uint32_t page_offset; +- int page_size; ++ uint32_t pde_addr, pte_addr; ++ uint32_t pde, pte, paddr, page_offset, page_size; + + if (env->cr[4] & CR4_PAE_MASK) { +- target_ulong pdpe_addr; +- uint64_t pde, pdpe; ++ uint32_t pdpe_addr, pde_addr, pte_addr; ++ uint32_t pdpe; + ++ /* XXX: we only use 32 bit physical addresses */ + #ifdef TARGET_X86_64 + if (env->hflags & HF_LMA_MASK) { +- uint64_t pml4e_addr, pml4e; ++ uint32_t pml4e_addr, pml4e; + int32_t sext; + + /* test virtual address sign extension */ +@@ -1124,13 +1121,13 @@ + + pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) & + env->a20_mask; +- pml4e = ldq_phys(pml4e_addr); ++ pml4e = ldl_phys(pml4e_addr); + if (!(pml4e & PG_PRESENT_MASK)) + return -1; + + pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) & + env->a20_mask; +- pdpe = ldq_phys(pdpe_addr); ++ pdpe = ldl_phys(pdpe_addr); + if (!(pdpe & PG_PRESENT_MASK)) + return -1; + } else +@@ -1138,14 +1135,14 @@ + { + pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & + env->a20_mask; +- pdpe = ldq_phys(pdpe_addr); ++ pdpe = ldl_phys(pdpe_addr); + if (!(pdpe & PG_PRESENT_MASK)) + return -1; } - 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); + + pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) & + env->a20_mask; +- pde = ldq_phys(pde_addr); ++ pde = ldl_phys(pde_addr); + if (!(pde & PG_PRESENT_MASK)) { + return -1; + } +@@ -1158,11 +1155,9 @@ + pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) & + env->a20_mask; + page_size = 4096; +- pte = ldq_phys(pte_addr); ++ pte = ldl_phys(pte_addr); + } + } else { +- uint32_t pde; +- + if (!(env->cr[0] & CR0_PG_MASK)) { + pte = addr; + page_size = 4096; +diff -urN 4242/vl.c qemu-omap/vl.c +--- 4242/vl.c 2008-04-24 21:26:21.000000000 +0100 ++++ qemu-omap/vl.c 2008-04-23 09:57:57.000000000 +0100 +@@ -5284,6 +5284,11 @@ + dev = usb_keyboard_init(); + } else if (strstart(devname, "disk:", &p)) { + dev = usb_msd_init(p); ++ } else if (strstart(devname, "net:", &p)) { ++ unsigned int nr = strtoul(p, NULL, 0); ++ if (nr >= (unsigned int) nb_nics || strcmp(nd_table[nr].model, "usb")) ++ return -1; ++ dev = usb_net_init(&nd_table[nr]); + } else if (!strcmp(devname, "wacom-tablet")) { + dev = usb_wacom_init(); + } else if (strstart(devname, "serial:", &p)) { diff --git a/meta/packages/qemu/qemu-0.9.1+svn/series b/meta/packages/qemu/qemu-0.9.1+svn/series index 126da8828..fb110340c 100644 --- a/meta/packages/qemu/qemu-0.9.1+svn/series +++ b/meta/packages/qemu/qemu-0.9.1+svn/series @@ -1,5 +1,4 @@ -02_snapshot_use_tmpdir.patch -p0 -05_non-fatal_if_linux_hd_missing.patch -p1 +05_non-fatal_if_linux_hd_missing.patch 06_exit_segfault.patch -p0 10_signal_jobs.patch -p0 11_signal_sigaction.patch -p0 @@ -8,18 +7,19 @@ 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 +52_ne2000_return.patch 61_safe_64bit_int.patch -p0 63_sparc_build.patch -p0 -64_ppc_asm_constraints.patch -p1 +64_ppc_asm_constraints.patch 65_kfreebsd.patch -p0 66_tls_ld.patch -p0 91-oh-sdl-cursor.patch -p0 -qemu-0.9.0-nptl.patch -p1 -qemu-0.9.0-nptl-update.patch -p1 -qemu-amd64-32b-mapping-0.9.0.patch -p1 +qemu-0.9.0-nptl.patch +qemu-0.9.0-nptl-update.patch +qemu-amd64-32b-mapping-0.9.0.patch workaround_bad_futex_headers.patch -p1 -fix_segfault.patch -p1 -no-strip.patch -p1 +fix_segfault.patch +no-strip.patch +fix_brk.patch +fix_protection_bits.patch -p1 qemu-n800-support.patch -p1 diff --git a/meta/packages/qemu/qemu-0.9.1+svn/writev_fix.patch b/meta/packages/qemu/qemu-0.9.1+svn/writev_fix.patch deleted file mode 100644 index e0ed4af97..000000000 --- a/meta/packages/qemu/qemu-0.9.1+svn/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_0.9.1.bb b/meta/packages/qemu/qemu_0.9.1.bb index a51e437f7..5400afb05 100644 --- a/meta/packages/qemu/qemu_0.9.1.bb +++ b/meta/packages/qemu/qemu_0.9.1.bb @@ -7,7 +7,6 @@ FILESDIR = "${WORKDIR}" SRC_URI = "\ http://fabrice.bellard.free.fr/qemu/qemu-0.9.1.tar.gz \ - file://02_snapshot_use_tmpdir.patch;patch=1;pnum=0 \ file://04_do_not_print_rtc_freq_if_ok.patch;patch=1;pnum=1 \ file://05_non-fatal_if_linux_hd_missing.patch;patch=1;pnum=1 \ file://06_exit_segfault.patch;patch=1;pnum=0 \ diff --git a/meta/packages/qemu/qemu_svn.bb b/meta/packages/qemu/qemu_svn.bb index 802d47b71..0d15a0c3a 100644 --- a/meta/packages/qemu/qemu_svn.bb +++ b/meta/packages/qemu/qemu_svn.bb @@ -1,13 +1,12 @@ LICENSE = "GPL" DEPENDS = "zlib" PV = "0.9.1+svnr${SRCREV}" -PR = "r3" +PR = "r5" FILESPATH = "${FILE_DIRNAME}/qemu-0.9.1+svn/" SRC_URI = "\ svn://svn.savannah.nongnu.org/qemu;module=trunk \ - file://02_snapshot_use_tmpdir.patch;patch=1;pnum=0 \ 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 \ @@ -17,7 +16,6 @@ SRC_URI = "\ 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 \ @@ -26,7 +24,6 @@ SRC_URI = "\ 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 \ |