]> Git Repo - qemu.git/blob - hw/omap2.c
Use temporary registers for the MIPS FPU emulation.
[qemu.git] / hw / omap2.c
1 /*
2  * TI OMAP processors emulation.
3  *
4  * Copyright (C) 2007-2008 Nokia Corporation
5  * Written by Andrzej Zaborowski <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 or
10  * (at your option) version 3 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22 #include "hw.h"
23 #include "arm-misc.h"
24 #include "omap.h"
25 #include "sysemu.h"
26 #include "qemu-timer.h"
27 #include "qemu-char.h"
28 #include "flash.h"
29
30 /* GP timers */
31 struct omap_gp_timer_s {
32     qemu_irq irq;
33     qemu_irq wkup;
34     qemu_irq in;
35     qemu_irq out;
36     omap_clk clk;
37     target_phys_addr_t base;
38     QEMUTimer *timer;
39     QEMUTimer *match;
40     struct omap_target_agent_s *ta;
41
42     int in_val;
43     int out_val;
44     int64_t time;
45     int64_t rate;
46     int64_t ticks_per_sec;
47
48     int16_t config;
49     int status;
50     int it_ena;
51     int wu_ena;
52     int enable;
53     int inout;
54     int capt2;
55     int pt;
56     enum {
57         gpt_trigger_none, gpt_trigger_overflow, gpt_trigger_both
58     } trigger;
59     enum {
60         gpt_capture_none, gpt_capture_rising,
61         gpt_capture_falling, gpt_capture_both
62     } capture;
63     int scpwm;
64     int ce;
65     int pre;
66     int ptv;
67     int ar;
68     int st;
69     int posted;
70     uint32_t val;
71     uint32_t load_val;
72     uint32_t capture_val[2];
73     uint32_t match_val;
74     int capt_num;
75
76     uint16_t writeh;    /* LSB */
77     uint16_t readh;     /* MSB */
78 };
79
80 #define GPT_TCAR_IT     (1 << 2)
81 #define GPT_OVF_IT      (1 << 1)
82 #define GPT_MAT_IT      (1 << 0)
83
84 static inline void omap_gp_timer_intr(struct omap_gp_timer_s *timer, int it)
85 {
86     if (timer->it_ena & it) {
87         if (!timer->status)
88             qemu_irq_raise(timer->irq);
89
90         timer->status |= it;
91         /* Or are the status bits set even when masked?
92          * i.e. is masking applied before or after the status register?  */
93     }
94
95     if (timer->wu_ena & it)
96         qemu_irq_pulse(timer->wkup);
97 }
98
99 static inline void omap_gp_timer_out(struct omap_gp_timer_s *timer, int level)
100 {
101     if (!timer->inout && timer->out_val != level) {
102         timer->out_val = level;
103         qemu_set_irq(timer->out, level);
104     }
105 }
106
107 static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer)
108 {
109     uint64_t distance;
110
111     if (timer->st && timer->rate) {
112         distance = qemu_get_clock(vm_clock) - timer->time;
113         distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
114
115         if (distance >= 0xffffffff - timer->val)
116             return 0xffffffff;
117         else
118             return timer->val + distance;
119     } else
120         return timer->val;
121 }
122
123 static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer)
124 {
125     if (timer->st) {
126         timer->val = omap_gp_timer_read(timer);
127         timer->time = qemu_get_clock(vm_clock);
128     }
129 }
130
131 static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
132 {
133     int64_t expires, matches;
134
135     if (timer->st && timer->rate) {
136         expires = muldiv64(0x100000000ll - timer->val,
137                         timer->ticks_per_sec, timer->rate);
138         qemu_mod_timer(timer->timer, timer->time + expires);
139
140         if (timer->ce && timer->match_val >= timer->val) {
141             matches = muldiv64(timer->match_val - timer->val,
142                             timer->ticks_per_sec, timer->rate);
143             qemu_mod_timer(timer->match, timer->time + matches);
144         } else
145             qemu_del_timer(timer->match);
146     } else {
147         qemu_del_timer(timer->timer);
148         qemu_del_timer(timer->match);
149         omap_gp_timer_out(timer, timer->scpwm);
150     }
151 }
152
153 static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer)
154 {
155     if (timer->pt)
156         /* TODO in overflow-and-match mode if the first event to
157          * occurs is the match, don't toggle.  */
158         omap_gp_timer_out(timer, !timer->out_val);
159     else
160         /* TODO inverted pulse on timer->out_val == 1?  */
161         qemu_irq_pulse(timer->out);
162 }
163
164 static void omap_gp_timer_tick(void *opaque)
165 {
166     struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
167
168     if (!timer->ar) {
169         timer->st = 0;
170         timer->val = 0;
171     } else {
172         timer->val = timer->load_val;
173         timer->time = qemu_get_clock(vm_clock);
174     }
175
176     if (timer->trigger == gpt_trigger_overflow ||
177                     timer->trigger == gpt_trigger_both)
178         omap_gp_timer_trigger(timer);
179
180     omap_gp_timer_intr(timer, GPT_OVF_IT);
181     omap_gp_timer_update(timer);
182 }
183
184 static void omap_gp_timer_match(void *opaque)
185 {
186     struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
187
188     if (timer->trigger == gpt_trigger_both)
189         omap_gp_timer_trigger(timer);
190
191     omap_gp_timer_intr(timer, GPT_MAT_IT);
192 }
193
194 static void omap_gp_timer_input(void *opaque, int line, int on)
195 {
196     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
197     int trigger;
198
199     switch (s->capture) {
200     default:
201     case gpt_capture_none:
202         trigger = 0;
203         break;
204     case gpt_capture_rising:
205         trigger = !s->in_val && on;
206         break;
207     case gpt_capture_falling:
208         trigger = s->in_val && !on;
209         break;
210     case gpt_capture_both:
211         trigger = (s->in_val == !on);
212         break;
213     }
214     s->in_val = on;
215
216     if (s->inout && trigger && s->capt_num < 2) {
217         s->capture_val[s->capt_num] = omap_gp_timer_read(s);
218
219         if (s->capt2 == s->capt_num ++)
220             omap_gp_timer_intr(s, GPT_TCAR_IT);
221     }
222 }
223
224 static void omap_gp_timer_clk_update(void *opaque, int line, int on)
225 {
226     struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
227
228     omap_gp_timer_sync(timer);
229     timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
230     omap_gp_timer_update(timer);
231 }
232
233 static void omap_gp_timer_clk_setup(struct omap_gp_timer_s *timer)
234 {
235     omap_clk_adduser(timer->clk,
236                     qemu_allocate_irqs(omap_gp_timer_clk_update, timer, 1)[0]);
237     timer->rate = omap_clk_getrate(timer->clk);
238 }
239
240 static void omap_gp_timer_reset(struct omap_gp_timer_s *s)
241 {
242     s->config = 0x000;
243     s->status = 0;
244     s->it_ena = 0;
245     s->wu_ena = 0;
246     s->inout = 0;
247     s->capt2 = 0;
248     s->capt_num = 0;
249     s->pt = 0;
250     s->trigger = gpt_trigger_none;
251     s->capture = gpt_capture_none;
252     s->scpwm = 0;
253     s->ce = 0;
254     s->pre = 0;
255     s->ptv = 0;
256     s->ar = 0;
257     s->st = 0;
258     s->posted = 1;
259     s->val = 0x00000000;
260     s->load_val = 0x00000000;
261     s->capture_val[0] = 0x00000000;
262     s->capture_val[1] = 0x00000000;
263     s->match_val = 0x00000000;
264     omap_gp_timer_update(s);
265 }
266
267 static uint32_t omap_gp_timer_readw(void *opaque, target_phys_addr_t addr)
268 {
269     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
270     int offset = addr - s->base;
271
272     switch (offset) {
273     case 0x00:  /* TIDR */
274         return 0x21;
275
276     case 0x10:  /* TIOCP_CFG */
277         return s->config;
278
279     case 0x14:  /* TISTAT */
280         /* ??? When's this bit reset? */
281         return 1;                                               /* RESETDONE */
282
283     case 0x18:  /* TISR */
284         return s->status;
285
286     case 0x1c:  /* TIER */
287         return s->it_ena;
288
289     case 0x20:  /* TWER */
290         return s->wu_ena;
291
292     case 0x24:  /* TCLR */
293         return (s->inout << 14) |
294                 (s->capt2 << 13) |
295                 (s->pt << 12) |
296                 (s->trigger << 10) |
297                 (s->capture << 8) |
298                 (s->scpwm << 7) |
299                 (s->ce << 6) |
300                 (s->pre << 5) |
301                 (s->ptv << 2) |
302                 (s->ar << 1) |
303                 (s->st << 0);
304
305     case 0x28:  /* TCRR */
306         return omap_gp_timer_read(s);
307
308     case 0x2c:  /* TLDR */
309         return s->load_val;
310
311     case 0x30:  /* TTGR */
312         return 0xffffffff;
313
314     case 0x34:  /* TWPS */
315         return 0x00000000;      /* No posted writes pending.  */
316
317     case 0x38:  /* TMAR */
318         return s->match_val;
319
320     case 0x3c:  /* TCAR1 */
321         return s->capture_val[0];
322
323     case 0x40:  /* TSICR */
324         return s->posted << 2;
325
326     case 0x44:  /* TCAR2 */
327         return s->capture_val[1];
328     }
329
330     OMAP_BAD_REG(addr);
331     return 0;
332 }
333
334 static uint32_t omap_gp_timer_readh(void *opaque, target_phys_addr_t addr)
335 {
336     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
337     uint32_t ret;
338
339     if (addr & 2)
340         return s->readh;
341     else {
342         ret = omap_gp_timer_readw(opaque, addr);
343         s->readh = ret >> 16;
344         return ret & 0xffff;
345     }
346 }
347
348 static CPUReadMemoryFunc *omap_gp_timer_readfn[] = {
349     omap_badwidth_read32,
350     omap_gp_timer_readh,
351     omap_gp_timer_readw,
352 };
353
354 static void omap_gp_timer_write(void *opaque, target_phys_addr_t addr,
355                 uint32_t value)
356 {
357     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
358     int offset = addr - s->base;
359
360     switch (offset) {
361     case 0x00:  /* TIDR */
362     case 0x14:  /* TISTAT */
363     case 0x34:  /* TWPS */
364     case 0x3c:  /* TCAR1 */
365     case 0x44:  /* TCAR2 */
366         OMAP_RO_REG(addr);
367         break;
368
369     case 0x10:  /* TIOCP_CFG */
370         s->config = value & 0x33d;
371         if (((value >> 3) & 3) == 3)                            /* IDLEMODE */
372             fprintf(stderr, "%s: illegal IDLEMODE value in TIOCP_CFG\n",
373                             __FUNCTION__);
374         if (value & 2)                                          /* SOFTRESET */
375             omap_gp_timer_reset(s);
376         break;
377
378     case 0x18:  /* TISR */
379         if (value & GPT_TCAR_IT)
380             s->capt_num = 0;
381         if (s->status && !(s->status &= ~value))
382             qemu_irq_lower(s->irq);
383         break;
384
385     case 0x1c:  /* TIER */
386         s->it_ena = value & 7;
387         break;
388
389     case 0x20:  /* TWER */
390         s->wu_ena = value & 7;
391         break;
392
393     case 0x24:  /* TCLR */
394         omap_gp_timer_sync(s);
395         s->inout = (value >> 14) & 1;
396         s->capt2 = (value >> 13) & 1;
397         s->pt = (value >> 12) & 1;
398         s->trigger = (value >> 10) & 3;
399         if (s->capture == gpt_capture_none &&
400                         ((value >> 8) & 3) != gpt_capture_none)
401             s->capt_num = 0;
402         s->capture = (value >> 8) & 3;
403         s->scpwm = (value >> 7) & 1;
404         s->ce = (value >> 6) & 1;
405         s->pre = (value >> 5) & 1;
406         s->ptv = (value >> 2) & 7;
407         s->ar = (value >> 1) & 1;
408         s->st = (value >> 0) & 1;
409         if (s->inout && s->trigger != gpt_trigger_none)
410             fprintf(stderr, "%s: GP timer pin must be an output "
411                             "for this trigger mode\n", __FUNCTION__);
412         if (!s->inout && s->capture != gpt_capture_none)
413             fprintf(stderr, "%s: GP timer pin must be an input "
414                             "for this capture mode\n", __FUNCTION__);
415         if (s->trigger == gpt_trigger_none)
416             omap_gp_timer_out(s, s->scpwm);
417         /* TODO: make sure this doesn't overflow 32-bits */
418         s->ticks_per_sec = ticks_per_sec << (s->pre ? s->ptv + 1 : 0);
419         omap_gp_timer_update(s);
420         break;
421
422     case 0x28:  /* TCRR */
423         s->time = qemu_get_clock(vm_clock);
424         s->val = value;
425         omap_gp_timer_update(s);
426         break;
427
428     case 0x2c:  /* TLDR */
429         s->load_val = value;
430         break;
431
432     case 0x30:  /* TTGR */
433         s->time = qemu_get_clock(vm_clock);
434         s->val = s->load_val;
435         omap_gp_timer_update(s);
436         break;
437
438     case 0x38:  /* TMAR */
439         omap_gp_timer_sync(s);
440         s->match_val = value;
441         omap_gp_timer_update(s);
442         break;
443
444     case 0x40:  /* TSICR */
445         s->posted = (value >> 2) & 1;
446         if (value & 2)  /* How much exactly are we supposed to reset? */
447             omap_gp_timer_reset(s);
448         break;
449
450     default:
451         OMAP_BAD_REG(addr);
452     }
453 }
454
455 static void omap_gp_timer_writeh(void *opaque, target_phys_addr_t addr,
456                 uint32_t value)
457 {
458     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
459
460     if (addr & 2)
461         return omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh);
462     else
463         s->writeh = (uint16_t) value;
464 }
465
466 static CPUWriteMemoryFunc *omap_gp_timer_writefn[] = {
467     omap_badwidth_write32,
468     omap_gp_timer_writeh,
469     omap_gp_timer_write,
470 };
471
472 struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
473                 qemu_irq irq, omap_clk fclk, omap_clk iclk)
474 {
475     int iomemtype;
476     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *)
477             qemu_mallocz(sizeof(struct omap_gp_timer_s));
478
479     s->ta = ta;
480     s->irq = irq;
481     s->clk = fclk;
482     s->timer = qemu_new_timer(vm_clock, omap_gp_timer_tick, s);
483     s->match = qemu_new_timer(vm_clock, omap_gp_timer_match, s);
484     s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0];
485     omap_gp_timer_reset(s);
486     omap_gp_timer_clk_setup(s);
487
488     iomemtype = l4_register_io_memory(0, omap_gp_timer_readfn,
489                     omap_gp_timer_writefn, s);
490     s->base = omap_l4_attach(ta, 0, iomemtype);
491
492     return s;
493 }
494
495 /* 32-kHz Sync Timer of the OMAP2 */
496 static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
497     return muldiv64(qemu_get_clock(vm_clock), 0x8000, ticks_per_sec);
498 }
499
500 static void omap_synctimer_reset(struct omap_synctimer_s *s)
501 {
502     s->val = omap_synctimer_read(s);
503 }
504
505 static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr)
506 {
507     struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
508     int offset = addr - s->base;
509
510     switch (offset) {
511     case 0x00:  /* 32KSYNCNT_REV */
512         return 0x21;
513
514     case 0x10:  /* CR */
515         return omap_synctimer_read(s) - s->val;
516     }
517
518     OMAP_BAD_REG(addr);
519     return 0;
520 }
521
522 static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr)
523 {
524     struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
525     uint32_t ret;
526
527     if (addr & 2)
528         return s->readh;
529     else {
530         ret = omap_synctimer_readw(opaque, addr);
531         s->readh = ret >> 16;
532         return ret & 0xffff;
533     }
534 }
535
536 static CPUReadMemoryFunc *omap_synctimer_readfn[] = {
537     omap_badwidth_read32,
538     omap_synctimer_readh,
539     omap_synctimer_readw,
540 };
541
542 static void omap_synctimer_write(void *opaque, target_phys_addr_t addr,
543                 uint32_t value)
544 {
545     OMAP_BAD_REG(addr);
546 }
547
548 static CPUWriteMemoryFunc *omap_synctimer_writefn[] = {
549     omap_badwidth_write32,
550     omap_synctimer_write,
551     omap_synctimer_write,
552 };
553
554 void omap_synctimer_init(struct omap_target_agent_s *ta,
555                 struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
556 {
557     struct omap_synctimer_s *s = &mpu->synctimer;
558
559     omap_synctimer_reset(s);
560     s->base = omap_l4_attach(ta, 0, l4_register_io_memory(0,
561                             omap_synctimer_readfn, omap_synctimer_writefn, s));
562 }
563
564 /* General-Purpose Interface of OMAP2 */
565 struct omap2_gpio_s {
566     target_phys_addr_t base;
567     qemu_irq irq[2];
568     qemu_irq wkup;
569     qemu_irq *in;
570     qemu_irq handler[32];
571
572     uint8_t config[2];
573     uint32_t inputs;
574     uint32_t outputs;
575     uint32_t dir;
576     uint32_t level[2];
577     uint32_t edge[2];
578     uint32_t mask[2];
579     uint32_t wumask;
580     uint32_t ints[2];
581     uint32_t debounce;
582     uint8_t delay;
583 };
584
585 static inline void omap_gpio_module_int_update(struct omap2_gpio_s *s,
586                 int line)
587 {
588     qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
589 }
590
591 static void omap_gpio_module_wake(struct omap2_gpio_s *s, int line)
592 {
593     if (!(s->config[0] & (1 << 2)))                     /* ENAWAKEUP */
594         return;
595     if (!(s->config[0] & (3 << 3)))                     /* Force Idle */
596         return;
597     if (!(s->wumask & (1 << line)))
598         return;
599
600     qemu_irq_raise(s->wkup);
601 }
602
603 static inline void omap_gpio_module_out_update(struct omap2_gpio_s *s,
604                 uint32_t diff)
605 {
606     int ln;
607
608     s->outputs ^= diff;
609     diff &= ~s->dir;
610     while ((ln = ffs(diff))) {
611         ln --;
612         qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
613         diff &= ~(1 << ln);
614     }
615 }
616
617 static void omap_gpio_module_level_update(struct omap2_gpio_s *s, int line)
618 {
619     s->ints[line] |= s->dir &
620             ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
621     omap_gpio_module_int_update(s, line);
622 }
623
624 static inline void omap_gpio_module_int(struct omap2_gpio_s *s, int line)
625 {
626     s->ints[0] |= 1 << line;
627     omap_gpio_module_int_update(s, 0);
628     s->ints[1] |= 1 << line;
629     omap_gpio_module_int_update(s, 1);
630     omap_gpio_module_wake(s, line);
631 }
632
633 static void omap_gpio_module_set(void *opaque, int line, int level)
634 {
635     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
636
637     if (level) {
638         if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
639             omap_gpio_module_int(s, line);
640         s->inputs |= 1 << line;
641     } else {
642         if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
643             omap_gpio_module_int(s, line);
644         s->inputs &= ~(1 << line);
645     }
646 }
647
648 static void omap_gpio_module_reset(struct omap2_gpio_s *s)
649 {
650     s->config[0] = 0;
651     s->config[1] = 2;
652     s->ints[0] = 0;
653     s->ints[1] = 0;
654     s->mask[0] = 0;
655     s->mask[1] = 0;
656     s->wumask = 0;
657     s->dir = ~0;
658     s->level[0] = 0;
659     s->level[1] = 0;
660     s->edge[0] = 0;
661     s->edge[1] = 0;
662     s->debounce = 0;
663     s->delay = 0;
664 }
665
666 static uint32_t omap_gpio_module_read(void *opaque, target_phys_addr_t addr)
667 {
668     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
669     int offset = addr - s->base;
670
671     switch (offset) {
672     case 0x00:  /* GPIO_REVISION */
673         return 0x18;
674
675     case 0x10:  /* GPIO_SYSCONFIG */
676         return s->config[0];
677
678     case 0x14:  /* GPIO_SYSSTATUS */
679         return 0x01;
680
681     case 0x18:  /* GPIO_IRQSTATUS1 */
682         return s->ints[0];
683
684     case 0x1c:  /* GPIO_IRQENABLE1 */
685     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
686     case 0x64:  /* GPIO_SETIRQENABLE1 */
687         return s->mask[0];
688
689     case 0x20:  /* GPIO_WAKEUPENABLE */
690     case 0x80:  /* GPIO_CLEARWKUENA */
691     case 0x84:  /* GPIO_SETWKUENA */
692         return s->wumask;
693
694     case 0x28:  /* GPIO_IRQSTATUS2 */
695         return s->ints[1];
696
697     case 0x2c:  /* GPIO_IRQENABLE2 */
698     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
699     case 0x74:  /* GPIO_SETIREQNEABLE2 */
700         return s->mask[1];
701
702     case 0x30:  /* GPIO_CTRL */
703         return s->config[1];
704
705     case 0x34:  /* GPIO_OE */
706         return s->dir;
707
708     case 0x38:  /* GPIO_DATAIN */
709         return s->inputs;
710
711     case 0x3c:  /* GPIO_DATAOUT */
712     case 0x90:  /* GPIO_CLEARDATAOUT */
713     case 0x94:  /* GPIO_SETDATAOUT */
714         return s->outputs;
715
716     case 0x40:  /* GPIO_LEVELDETECT0 */
717         return s->level[0];
718
719     case 0x44:  /* GPIO_LEVELDETECT1 */
720         return s->level[1];
721
722     case 0x48:  /* GPIO_RISINGDETECT */
723         return s->edge[0];
724
725     case 0x4c:  /* GPIO_FALLINGDETECT */
726         return s->edge[1];
727
728     case 0x50:  /* GPIO_DEBOUNCENABLE */
729         return s->debounce;
730
731     case 0x54:  /* GPIO_DEBOUNCINGTIME */
732         return s->delay;
733     }
734
735     OMAP_BAD_REG(addr);
736     return 0;
737 }
738
739 static void omap_gpio_module_write(void *opaque, target_phys_addr_t addr,
740                 uint32_t value)
741 {
742     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
743     int offset = addr - s->base;
744     uint32_t diff;
745     int ln;
746
747     switch (offset) {
748     case 0x00:  /* GPIO_REVISION */
749     case 0x14:  /* GPIO_SYSSTATUS */
750     case 0x38:  /* GPIO_DATAIN */
751         OMAP_RO_REG(addr);
752         break;
753
754     case 0x10:  /* GPIO_SYSCONFIG */
755         if (((value >> 3) & 3) == 3)
756             fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
757         if (value & 2)
758             omap_gpio_module_reset(s);
759         s->config[0] = value & 0x1d;
760         break;
761
762     case 0x18:  /* GPIO_IRQSTATUS1 */
763         if (s->ints[0] & value) {
764             s->ints[0] &= ~value;
765             omap_gpio_module_level_update(s, 0);
766         }
767         break;
768
769     case 0x1c:  /* GPIO_IRQENABLE1 */
770         s->mask[0] = value;
771         omap_gpio_module_int_update(s, 0);
772         break;
773
774     case 0x20:  /* GPIO_WAKEUPENABLE */
775         s->wumask = value;
776         break;
777
778     case 0x28:  /* GPIO_IRQSTATUS2 */
779         if (s->ints[1] & value) {
780             s->ints[1] &= ~value;
781             omap_gpio_module_level_update(s, 1);
782         }
783         break;
784
785     case 0x2c:  /* GPIO_IRQENABLE2 */
786         s->mask[1] = value;
787         omap_gpio_module_int_update(s, 1);
788         break;
789
790     case 0x30:  /* GPIO_CTRL */
791         s->config[1] = value & 7;
792         break;
793
794     case 0x34:  /* GPIO_OE */
795         diff = s->outputs & (s->dir ^ value);
796         s->dir = value;
797
798         value = s->outputs & ~s->dir;
799         while ((ln = ffs(diff))) {
800             diff &= ~(1 <<-- ln);
801             qemu_set_irq(s->handler[ln], (value >> ln) & 1);
802         }
803
804         omap_gpio_module_level_update(s, 0);
805         omap_gpio_module_level_update(s, 1);
806         break;
807
808     case 0x3c:  /* GPIO_DATAOUT */
809         omap_gpio_module_out_update(s, s->outputs ^ value);
810         break;
811
812     case 0x40:  /* GPIO_LEVELDETECT0 */
813         s->level[0] = value;
814         omap_gpio_module_level_update(s, 0);
815         omap_gpio_module_level_update(s, 1);
816         break;
817
818     case 0x44:  /* GPIO_LEVELDETECT1 */
819         s->level[1] = value;
820         omap_gpio_module_level_update(s, 0);
821         omap_gpio_module_level_update(s, 1);
822         break;
823
824     case 0x48:  /* GPIO_RISINGDETECT */
825         s->edge[0] = value;
826         break;
827
828     case 0x4c:  /* GPIO_FALLINGDETECT */
829         s->edge[1] = value;
830         break;
831
832     case 0x50:  /* GPIO_DEBOUNCENABLE */
833         s->debounce = value;
834         break;
835
836     case 0x54:  /* GPIO_DEBOUNCINGTIME */
837         s->delay = value;
838         break;
839
840     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
841         s->mask[0] &= ~value;
842         omap_gpio_module_int_update(s, 0);
843         break;
844
845     case 0x64:  /* GPIO_SETIRQENABLE1 */
846         s->mask[0] |= value;
847         omap_gpio_module_int_update(s, 0);
848         break;
849
850     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
851         s->mask[1] &= ~value;
852         omap_gpio_module_int_update(s, 1);
853         break;
854
855     case 0x74:  /* GPIO_SETIREQNEABLE2 */
856         s->mask[1] |= value;
857         omap_gpio_module_int_update(s, 1);
858         break;
859
860     case 0x80:  /* GPIO_CLEARWKUENA */
861         s->wumask &= ~value;
862         break;
863
864     case 0x84:  /* GPIO_SETWKUENA */
865         s->wumask |= value;
866         break;
867
868     case 0x90:  /* GPIO_CLEARDATAOUT */
869         omap_gpio_module_out_update(s, s->outputs & value);
870         break;
871
872     case 0x94:  /* GPIO_SETDATAOUT */
873         omap_gpio_module_out_update(s, ~s->outputs & value);
874         break;
875
876     default:
877         OMAP_BAD_REG(addr);
878         return;
879     }
880 }
881
882 static uint32_t omap_gpio_module_readp(void *opaque, target_phys_addr_t addr)
883 {
884     return omap_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
885 }
886
887 static void omap_gpio_module_writep(void *opaque, target_phys_addr_t addr,
888                 uint32_t value)
889 {
890     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
891     int offset = addr - s->base;
892     uint32_t cur = 0;
893     uint32_t mask = 0xffff;
894
895     switch (offset & ~3) {
896     case 0x00:  /* GPIO_REVISION */
897     case 0x14:  /* GPIO_SYSSTATUS */
898     case 0x38:  /* GPIO_DATAIN */
899         OMAP_RO_REG(addr);
900         break;
901
902     case 0x10:  /* GPIO_SYSCONFIG */
903     case 0x1c:  /* GPIO_IRQENABLE1 */
904     case 0x20:  /* GPIO_WAKEUPENABLE */
905     case 0x2c:  /* GPIO_IRQENABLE2 */
906     case 0x30:  /* GPIO_CTRL */
907     case 0x34:  /* GPIO_OE */
908     case 0x3c:  /* GPIO_DATAOUT */
909     case 0x40:  /* GPIO_LEVELDETECT0 */
910     case 0x44:  /* GPIO_LEVELDETECT1 */
911     case 0x48:  /* GPIO_RISINGDETECT */
912     case 0x4c:  /* GPIO_FALLINGDETECT */
913     case 0x50:  /* GPIO_DEBOUNCENABLE */
914     case 0x54:  /* GPIO_DEBOUNCINGTIME */
915         cur = omap_gpio_module_read(opaque, addr & ~3) &
916                 ~(mask << ((addr & 3) << 3));
917
918         /* Fall through.  */
919     case 0x18:  /* GPIO_IRQSTATUS1 */
920     case 0x28:  /* GPIO_IRQSTATUS2 */
921     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
922     case 0x64:  /* GPIO_SETIRQENABLE1 */
923     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
924     case 0x74:  /* GPIO_SETIREQNEABLE2 */
925     case 0x80:  /* GPIO_CLEARWKUENA */
926     case 0x84:  /* GPIO_SETWKUENA */
927     case 0x90:  /* GPIO_CLEARDATAOUT */
928     case 0x94:  /* GPIO_SETDATAOUT */
929         value <<= (addr & 3) << 3;
930         omap_gpio_module_write(opaque, addr, cur | value);
931         break;
932
933     default:
934         OMAP_BAD_REG(addr);
935         return;
936     }
937 }
938
939 static CPUReadMemoryFunc *omap_gpio_module_readfn[] = {
940     omap_gpio_module_readp,
941     omap_gpio_module_readp,
942     omap_gpio_module_read,
943 };
944
945 static CPUWriteMemoryFunc *omap_gpio_module_writefn[] = {
946     omap_gpio_module_writep,
947     omap_gpio_module_writep,
948     omap_gpio_module_write,
949 };
950
951 static void omap_gpio_module_init(struct omap2_gpio_s *s,
952                 struct omap_target_agent_s *ta, int region,
953                 qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
954                 omap_clk fclk, omap_clk iclk)
955 {
956     int iomemtype;
957
958     s->irq[0] = mpu;
959     s->irq[1] = dsp;
960     s->wkup = wkup;
961     s->in = qemu_allocate_irqs(omap_gpio_module_set, s, 32);
962
963     iomemtype = l4_register_io_memory(0, omap_gpio_module_readfn,
964                     omap_gpio_module_writefn, s);
965     s->base = omap_l4_attach(ta, region, iomemtype);
966 }
967
968 struct omap_gpif_s {
969     struct omap2_gpio_s module[5];
970     int modules;
971
972     target_phys_addr_t topbase;
973     int autoidle;
974     int gpo;
975 };
976
977 static void omap_gpif_reset(struct omap_gpif_s *s)
978 {
979     int i;
980
981     for (i = 0; i < s->modules; i ++)
982         omap_gpio_module_reset(s->module + i);
983
984     s->autoidle = 0;
985     s->gpo = 0;
986 }
987
988 static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
989 {
990     struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
991     int offset = addr - s->topbase;
992
993     switch (offset) {
994     case 0x00:  /* IPGENERICOCPSPL_REVISION */
995         return 0x18;
996
997     case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
998         return s->autoidle;
999
1000     case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
1001         return 0x01;
1002
1003     case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
1004         return 0x00;
1005
1006     case 0x40:  /* IPGENERICOCPSPL_GPO */
1007         return s->gpo;
1008
1009     case 0x50:  /* IPGENERICOCPSPL_GPI */
1010         return 0x00;
1011     }
1012
1013     OMAP_BAD_REG(addr);
1014     return 0;
1015 }
1016
1017 static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
1018                 uint32_t value)
1019 {
1020     struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
1021     int offset = addr - s->topbase;
1022
1023     switch (offset) {
1024     case 0x00:  /* IPGENERICOCPSPL_REVISION */
1025     case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
1026     case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
1027     case 0x50:  /* IPGENERICOCPSPL_GPI */
1028         OMAP_RO_REG(addr);
1029         break;
1030
1031     case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
1032         if (value & (1 << 1))                                   /* SOFTRESET */
1033             omap_gpif_reset(s);
1034         s->autoidle = value & 1;
1035         break;
1036
1037     case 0x40:  /* IPGENERICOCPSPL_GPO */
1038         s->gpo = value & 1;
1039         break;
1040
1041     default:
1042         OMAP_BAD_REG(addr);
1043         return;
1044     }
1045 }
1046
1047 static CPUReadMemoryFunc *omap_gpif_top_readfn[] = {
1048     omap_gpif_top_read,
1049     omap_gpif_top_read,
1050     omap_gpif_top_read,
1051 };
1052
1053 static CPUWriteMemoryFunc *omap_gpif_top_writefn[] = {
1054     omap_gpif_top_write,
1055     omap_gpif_top_write,
1056     omap_gpif_top_write,
1057 };
1058
1059 struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
1060                 qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
1061 {
1062     int iomemtype, i;
1063     struct omap_gpif_s *s = (struct omap_gpif_s *)
1064             qemu_mallocz(sizeof(struct omap_gpif_s));
1065     int region[4] = { 0, 2, 4, 5 };
1066
1067     s->modules = modules;
1068     for (i = 0; i < modules; i ++)
1069         omap_gpio_module_init(s->module + i, ta, region[i],
1070                         irq[i], 0, 0, fclk[i], iclk);
1071
1072     omap_gpif_reset(s);
1073
1074     iomemtype = l4_register_io_memory(0, omap_gpif_top_readfn,
1075                     omap_gpif_top_writefn, s);
1076     s->topbase = omap_l4_attach(ta, 1, iomemtype);
1077
1078     return s;
1079 }
1080
1081 qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
1082 {
1083     if (start >= s->modules * 32 || start < 0)
1084         cpu_abort(cpu_single_env, "%s: No GPIO line %i\n",
1085                         __FUNCTION__, start);
1086     return s->module[start >> 5].in + (start & 31);
1087 }
1088
1089 void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
1090 {
1091     if (line >= s->modules * 32 || line < 0)
1092         cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
1093     s->module[line >> 5].handler[line & 31] = handler;
1094 }
1095
1096 /* Multichannel SPI */
1097 struct omap_mcspi_s {
1098     target_phys_addr_t base;
1099     qemu_irq irq;
1100     int chnum;
1101
1102     uint32_t sysconfig;
1103     uint32_t systest;
1104     uint32_t irqst;
1105     uint32_t irqen;
1106     uint32_t wken;
1107     uint32_t control;
1108
1109     struct omap_mcspi_ch_s {
1110         qemu_irq txdrq;
1111         qemu_irq rxdrq;
1112         uint32_t (*txrx)(void *opaque, uint32_t, int);
1113         void *opaque;
1114
1115         uint32_t tx;
1116         uint32_t rx;
1117
1118         uint32_t config;
1119         uint32_t status;
1120         uint32_t control;
1121     } ch[4];
1122 };
1123
1124 static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s)
1125 {
1126     qemu_set_irq(s->irq, s->irqst & s->irqen);
1127 }
1128
1129 static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch)
1130 {
1131     qemu_set_irq(ch->txdrq,
1132                     (ch->control & 1) &&                /* EN */
1133                     (ch->config & (1 << 14)) &&         /* DMAW */
1134                     (ch->status & (1 << 1)) &&          /* TXS */
1135                     ((ch->config >> 12) & 3) != 1);     /* TRM */
1136     qemu_set_irq(ch->rxdrq,
1137                     (ch->control & 1) &&                /* EN */
1138                     (ch->config & (1 << 15)) &&         /* DMAW */
1139                     (ch->status & (1 << 0)) &&          /* RXS */
1140                     ((ch->config >> 12) & 3) != 2);     /* TRM */
1141 }
1142
1143 static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
1144 {
1145     struct omap_mcspi_ch_s *ch = s->ch + chnum;
1146
1147     if (!(ch->control & 1))                             /* EN */
1148         return;
1149     if ((ch->status & (1 << 0)) &&                      /* RXS */
1150                     ((ch->config >> 12) & 3) != 2 &&    /* TRM */
1151                     !(ch->config & (1 << 19)))          /* TURBO */
1152         goto intr_update;
1153     if ((ch->status & (1 << 1)) &&                      /* TXS */
1154                     ((ch->config >> 12) & 3) != 1)      /* TRM */
1155         goto intr_update;
1156
1157     if (!(s->control & 1) ||                            /* SINGLE */
1158                     (ch->config & (1 << 20))) {         /* FORCE */
1159         if (ch->txrx)
1160             ch->rx = ch->txrx(ch->opaque, ch->tx,       /* WL */
1161                             1 + (0x1f & (ch->config >> 7)));
1162     }
1163
1164     ch->tx = 0;
1165     ch->status |= 1 << 2;                               /* EOT */
1166     ch->status |= 1 << 1;                               /* TXS */
1167     if (((ch->config >> 12) & 3) != 2)                  /* TRM */
1168         ch->status |= 1 << 0;                           /* RXS */
1169
1170 intr_update:
1171     if ((ch->status & (1 << 0)) &&                      /* RXS */
1172                     ((ch->config >> 12) & 3) != 2 &&    /* TRM */
1173                     !(ch->config & (1 << 19)))          /* TURBO */
1174         s->irqst |= 1 << (2 + 4 * chnum);               /* RX_FULL */
1175     if ((ch->status & (1 << 1)) &&                      /* TXS */
1176                     ((ch->config >> 12) & 3) != 1)      /* TRM */
1177         s->irqst |= 1 << (0 + 4 * chnum);               /* TX_EMPTY */
1178     omap_mcspi_interrupt_update(s);
1179     omap_mcspi_dmarequest_update(ch);
1180 }
1181
1182 static void omap_mcspi_reset(struct omap_mcspi_s *s)
1183 {
1184     int ch;
1185
1186     s->sysconfig = 0;
1187     s->systest = 0;
1188     s->irqst = 0;
1189     s->irqen = 0;
1190     s->wken = 0;
1191     s->control = 4;
1192
1193     for (ch = 0; ch < 4; ch ++) {
1194         s->ch[ch].config = 0x060000;
1195         s->ch[ch].status = 2;                           /* TXS */
1196         s->ch[ch].control = 0;
1197
1198         omap_mcspi_dmarequest_update(s->ch + ch);
1199     }
1200
1201     omap_mcspi_interrupt_update(s);
1202 }
1203
1204 static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr)
1205 {
1206     struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1207     int offset = addr - s->base;
1208     int ch = 0;
1209     uint32_t ret;
1210
1211     switch (offset) {
1212     case 0x00:  /* MCSPI_REVISION */
1213         return 0x91;
1214
1215     case 0x10:  /* MCSPI_SYSCONFIG */
1216         return s->sysconfig;
1217
1218     case 0x14:  /* MCSPI_SYSSTATUS */
1219         return 1;                                       /* RESETDONE */
1220
1221     case 0x18:  /* MCSPI_IRQSTATUS */
1222         return s->irqst;
1223
1224     case 0x1c:  /* MCSPI_IRQENABLE */
1225         return s->irqen;
1226
1227     case 0x20:  /* MCSPI_WAKEUPENABLE */
1228         return s->wken;
1229
1230     case 0x24:  /* MCSPI_SYST */
1231         return s->systest;
1232
1233     case 0x28:  /* MCSPI_MODULCTRL */
1234         return s->control;
1235
1236     case 0x68: ch ++;
1237     case 0x54: ch ++;
1238     case 0x40: ch ++;
1239     case 0x2c:  /* MCSPI_CHCONF */
1240         return s->ch[ch].config;
1241
1242     case 0x6c: ch ++;
1243     case 0x58: ch ++;
1244     case 0x44: ch ++;
1245     case 0x30:  /* MCSPI_CHSTAT */
1246         return s->ch[ch].status;
1247
1248     case 0x70: ch ++;
1249     case 0x5c: ch ++;
1250     case 0x48: ch ++;
1251     case 0x34:  /* MCSPI_CHCTRL */
1252         return s->ch[ch].control;
1253
1254     case 0x74: ch ++;
1255     case 0x60: ch ++;
1256     case 0x4c: ch ++;
1257     case 0x38:  /* MCSPI_TX */
1258         return s->ch[ch].tx;
1259
1260     case 0x78: ch ++;
1261     case 0x64: ch ++;
1262     case 0x50: ch ++;
1263     case 0x3c:  /* MCSPI_RX */
1264         s->ch[ch].status &= ~(1 << 0);                  /* RXS */
1265         ret = s->ch[ch].rx;
1266         omap_mcspi_transfer_run(s, ch);
1267         return ret;
1268     }
1269
1270     OMAP_BAD_REG(addr);
1271     return 0;
1272 }
1273
1274 static void omap_mcspi_write(void *opaque, target_phys_addr_t addr,
1275                 uint32_t value)
1276 {
1277     struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1278     int offset = addr - s->base;
1279     int ch = 0;
1280
1281     switch (offset) {
1282     case 0x00:  /* MCSPI_REVISION */
1283     case 0x14:  /* MCSPI_SYSSTATUS */
1284     case 0x30:  /* MCSPI_CHSTAT0 */
1285     case 0x3c:  /* MCSPI_RX0 */
1286     case 0x44:  /* MCSPI_CHSTAT1 */
1287     case 0x50:  /* MCSPI_RX1 */
1288     case 0x58:  /* MCSPI_CHSTAT2 */
1289     case 0x64:  /* MCSPI_RX2 */
1290     case 0x6c:  /* MCSPI_CHSTAT3 */
1291     case 0x78:  /* MCSPI_RX3 */
1292         OMAP_RO_REG(addr);
1293         return;
1294
1295     case 0x10:  /* MCSPI_SYSCONFIG */
1296         if (value & (1 << 1))                           /* SOFTRESET */
1297             omap_mcspi_reset(s);
1298         s->sysconfig = value & 0x31d;
1299         break;
1300
1301     case 0x18:  /* MCSPI_IRQSTATUS */
1302         if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) {
1303             s->irqst &= ~value;
1304             omap_mcspi_interrupt_update(s);
1305         }
1306         break;
1307
1308     case 0x1c:  /* MCSPI_IRQENABLE */
1309         s->irqen = value & 0x1777f;
1310         omap_mcspi_interrupt_update(s);
1311         break;
1312
1313     case 0x20:  /* MCSPI_WAKEUPENABLE */
1314         s->wken = value & 1;
1315         break;
1316
1317     case 0x24:  /* MCSPI_SYST */
1318         if (s->control & (1 << 3))                      /* SYSTEM_TEST */
1319             if (value & (1 << 11)) {                    /* SSB */
1320                 s->irqst |= 0x1777f;
1321                 omap_mcspi_interrupt_update(s);
1322             }
1323         s->systest = value & 0xfff;
1324         break;
1325
1326     case 0x28:  /* MCSPI_MODULCTRL */
1327         if (value & (1 << 3))                           /* SYSTEM_TEST */
1328             if (s->systest & (1 << 11)) {               /* SSB */
1329                 s->irqst |= 0x1777f;
1330                 omap_mcspi_interrupt_update(s);
1331             }
1332         s->control = value & 0xf;
1333         break;
1334
1335     case 0x68: ch ++;
1336     case 0x54: ch ++;
1337     case 0x40: ch ++;
1338     case 0x2c:  /* MCSPI_CHCONF */
1339         if ((value ^ s->ch[ch].config) & (3 << 14))     /* DMAR | DMAW */
1340             omap_mcspi_dmarequest_update(s->ch + ch);
1341         if (((value >> 12) & 3) == 3)                   /* TRM */
1342             fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__);
1343         if (((value >> 7) & 0x1f) < 3)                  /* WL */
1344             fprintf(stderr, "%s: invalid WL value (%i)\n",
1345                             __FUNCTION__, (value >> 7) & 0x1f);
1346         s->ch[ch].config = value & 0x7fffff;
1347         break;
1348
1349     case 0x70: ch ++;
1350     case 0x5c: ch ++;
1351     case 0x48: ch ++;
1352     case 0x34:  /* MCSPI_CHCTRL */
1353         if (value & ~s->ch[ch].control & 1) {           /* EN */
1354             s->ch[ch].control |= 1;
1355             omap_mcspi_transfer_run(s, ch);
1356         } else
1357             s->ch[ch].control = value & 1;
1358         break;
1359
1360     case 0x74: ch ++;
1361     case 0x60: ch ++;
1362     case 0x4c: ch ++;
1363     case 0x38:  /* MCSPI_TX */
1364         s->ch[ch].tx = value;
1365         s->ch[ch].status &= ~(1 << 1);                  /* TXS */
1366         omap_mcspi_transfer_run(s, ch);
1367         break;
1368
1369     default:
1370         OMAP_BAD_REG(addr);
1371         return;
1372     }
1373 }
1374
1375 static CPUReadMemoryFunc *omap_mcspi_readfn[] = {
1376     omap_badwidth_read32,
1377     omap_badwidth_read32,
1378     omap_mcspi_read,
1379 };
1380
1381 static CPUWriteMemoryFunc *omap_mcspi_writefn[] = {
1382     omap_badwidth_write32,
1383     omap_badwidth_write32,
1384     omap_mcspi_write,
1385 };
1386
1387 struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
1388                 qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
1389 {
1390     int iomemtype;
1391     struct omap_mcspi_s *s = (struct omap_mcspi_s *)
1392             qemu_mallocz(sizeof(struct omap_mcspi_s));
1393     struct omap_mcspi_ch_s *ch = s->ch;
1394
1395     s->irq = irq;
1396     s->chnum = chnum;
1397     while (chnum --) {
1398         ch->txdrq = *drq ++;
1399         ch->rxdrq = *drq ++;
1400         ch ++;
1401     }
1402     omap_mcspi_reset(s);
1403
1404     iomemtype = l4_register_io_memory(0, omap_mcspi_readfn,
1405                     omap_mcspi_writefn, s);
1406     s->base = omap_l4_attach(ta, 0, iomemtype);
1407
1408     return s;
1409 }
1410
1411 void omap_mcspi_attach(struct omap_mcspi_s *s,
1412                 uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque,
1413                 int chipselect)
1414 {
1415     if (chipselect < 0 || chipselect >= s->chnum)
1416         cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n",
1417                         __FUNCTION__, chipselect);
1418
1419     s->ch[chipselect].txrx = txrx;
1420     s->ch[chipselect].opaque = opaque;
1421 }
1422
1423 /* STI/XTI (emulation interface) console - reverse engineered only */
1424 struct omap_sti_s {
1425     target_phys_addr_t base;
1426     target_phys_addr_t channel_base;
1427     qemu_irq irq;
1428     CharDriverState *chr;
1429
1430     uint32_t sysconfig;
1431     uint32_t systest;
1432     uint32_t irqst;
1433     uint32_t irqen;
1434     uint32_t clkcontrol;
1435     uint32_t serial_config;
1436 };
1437
1438 #define STI_TRACE_CONSOLE_CHANNEL       239
1439 #define STI_TRACE_CONTROL_CHANNEL       253
1440
1441 static inline void omap_sti_interrupt_update(struct omap_sti_s *s)
1442 {
1443     qemu_set_irq(s->irq, s->irqst & s->irqen);
1444 }
1445
1446 static void omap_sti_reset(struct omap_sti_s *s)
1447 {
1448     s->sysconfig = 0;
1449     s->irqst = 0;
1450     s->irqen = 0;
1451     s->clkcontrol = 0;
1452     s->serial_config = 0;
1453
1454     omap_sti_interrupt_update(s);
1455 }
1456
1457 static uint32_t omap_sti_read(void *opaque, target_phys_addr_t addr)
1458 {
1459     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
1460     int offset = addr - s->base;
1461
1462     switch (offset) {
1463     case 0x00:  /* STI_REVISION */
1464         return 0x10;
1465
1466     case 0x10:  /* STI_SYSCONFIG */
1467         return s->sysconfig;
1468
1469     case 0x14:  /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
1470         return 0x00;
1471
1472     case 0x18:  /* STI_IRQSTATUS */
1473         return s->irqst;
1474
1475     case 0x1c:  /* STI_IRQSETEN / STI_IRQCLREN */
1476         return s->irqen;
1477
1478     case 0x24:  /* STI_ER / STI_DR / XTI_TRACESELECT */
1479     case 0x28:  /* STI_RX_DR / XTI_RXDATA */
1480         /* TODO */
1481         return 0;
1482
1483     case 0x2c:  /* STI_CLK_CTRL / XTI_SCLKCRTL */
1484         return s->clkcontrol;
1485
1486     case 0x30:  /* STI_SERIAL_CFG / XTI_SCONFIG */
1487         return s->serial_config;
1488     }
1489
1490     OMAP_BAD_REG(addr);
1491     return 0;
1492 }
1493
1494 static void omap_sti_write(void *opaque, target_phys_addr_t addr,
1495                 uint32_t value)
1496 {
1497     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
1498     int offset = addr - s->base;
1499
1500     switch (offset) {
1501     case 0x00:  /* STI_REVISION */
1502     case 0x14:  /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
1503         OMAP_RO_REG(addr);
1504         return;
1505
1506     case 0x10:  /* STI_SYSCONFIG */
1507         if (value & (1 << 1))                           /* SOFTRESET */
1508             omap_sti_reset(s);
1509         s->sysconfig = value & 0xfe;
1510         break;
1511
1512     case 0x18:  /* STI_IRQSTATUS */
1513         s->irqst &= ~value;
1514         omap_sti_interrupt_update(s);
1515         break;
1516
1517     case 0x1c:  /* STI_IRQSETEN / STI_IRQCLREN */
1518         s->irqen = value & 0xffff;
1519         omap_sti_interrupt_update(s);
1520         break;
1521
1522     case 0x2c:  /* STI_CLK_CTRL / XTI_SCLKCRTL */
1523         s->clkcontrol = value & 0xff;
1524         break;
1525
1526     case 0x30:  /* STI_SERIAL_CFG / XTI_SCONFIG */
1527         s->serial_config = value & 0xff;
1528         break;
1529
1530     case 0x24:  /* STI_ER / STI_DR / XTI_TRACESELECT */
1531     case 0x28:  /* STI_RX_DR / XTI_RXDATA */
1532         /* TODO */
1533         return;
1534
1535     default:
1536         OMAP_BAD_REG(addr);
1537         return;
1538     }
1539 }
1540
1541 static CPUReadMemoryFunc *omap_sti_readfn[] = {
1542     omap_badwidth_read32,
1543     omap_badwidth_read32,
1544     omap_sti_read,
1545 };
1546
1547 static CPUWriteMemoryFunc *omap_sti_writefn[] = {
1548     omap_badwidth_write32,
1549     omap_badwidth_write32,
1550     omap_sti_write,
1551 };
1552
1553 static uint32_t omap_sti_fifo_read(void *opaque, target_phys_addr_t addr)
1554 {
1555     OMAP_BAD_REG(addr);
1556     return 0;
1557 }
1558
1559 static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr,
1560                 uint32_t value)
1561 {
1562     struct omap_sti_s *s = (struct omap_sti_s *) opaque;
1563     int offset = addr - s->channel_base;
1564     int ch = offset >> 6;
1565     uint8_t byte = value;
1566
1567     if (ch == STI_TRACE_CONTROL_CHANNEL) {
1568         /* Flush channel <i>value</i>.  */
1569         qemu_chr_write(s->chr, "\r", 1);
1570     } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
1571         if (value == 0xc0 || value == 0xc3) {
1572             /* Open channel <i>ch</i>.  */
1573         } else if (value == 0x00)
1574             qemu_chr_write(s->chr, "\n", 1);
1575         else
1576             qemu_chr_write(s->chr, &byte, 1);
1577     }
1578 }
1579
1580 static CPUReadMemoryFunc *omap_sti_fifo_readfn[] = {
1581     omap_sti_fifo_read,
1582     omap_badwidth_read8,
1583     omap_badwidth_read8,
1584 };
1585
1586 static CPUWriteMemoryFunc *omap_sti_fifo_writefn[] = {
1587     omap_sti_fifo_write,
1588     omap_badwidth_write8,
1589     omap_badwidth_write8,
1590 };
1591
1592 struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
1593                 target_phys_addr_t channel_base, qemu_irq irq, omap_clk clk,
1594                 CharDriverState *chr)
1595 {
1596     int iomemtype;
1597     struct omap_sti_s *s = (struct omap_sti_s *)
1598             qemu_mallocz(sizeof(struct omap_sti_s));
1599
1600     s->irq = irq;
1601     omap_sti_reset(s);
1602
1603     s->chr = chr ?: qemu_chr_open("null");
1604
1605     iomemtype = l4_register_io_memory(0, omap_sti_readfn,
1606                     omap_sti_writefn, s);
1607     s->base = omap_l4_attach(ta, 0, iomemtype);
1608
1609     iomemtype = cpu_register_io_memory(0, omap_sti_fifo_readfn,
1610                     omap_sti_fifo_writefn, s);
1611     s->channel_base = channel_base;
1612     cpu_register_physical_memory(s->channel_base, 0x10000, iomemtype);
1613
1614     return s;
1615 }
1616
1617 /* L4 Interconnect */
1618 struct omap_target_agent_s {
1619     struct omap_l4_s *bus;
1620     int regions;
1621     struct omap_l4_region_s *start;
1622     target_phys_addr_t base;
1623     uint32_t component;
1624     uint32_t control;
1625     uint32_t status;
1626 };
1627
1628 struct omap_l4_s {
1629     target_phys_addr_t base;
1630     int ta_num;
1631     struct omap_target_agent_s ta[0];
1632 };
1633
1634 #ifdef L4_MUX_HACK
1635 static int omap_l4_io_entries;
1636 static int omap_cpu_io_entry;
1637 static struct omap_l4_entry {
1638         CPUReadMemoryFunc **mem_read;
1639         CPUWriteMemoryFunc **mem_write;
1640         void *opaque;
1641 } *omap_l4_io_entry;
1642 static CPUReadMemoryFunc **omap_l4_io_readb_fn;
1643 static CPUReadMemoryFunc **omap_l4_io_readh_fn;
1644 static CPUReadMemoryFunc **omap_l4_io_readw_fn;
1645 static CPUWriteMemoryFunc **omap_l4_io_writeb_fn;
1646 static CPUWriteMemoryFunc **omap_l4_io_writeh_fn;
1647 static CPUWriteMemoryFunc **omap_l4_io_writew_fn;
1648 static void **omap_l4_io_opaque;
1649
1650 int l4_register_io_memory(int io_index, CPUReadMemoryFunc **mem_read,
1651                 CPUWriteMemoryFunc **mem_write, void *opaque)
1652 {
1653     omap_l4_io_entry[omap_l4_io_entries].mem_read = mem_read;
1654     omap_l4_io_entry[omap_l4_io_entries].mem_write = mem_write;
1655     omap_l4_io_entry[omap_l4_io_entries].opaque = opaque;
1656
1657     return omap_l4_io_entries ++;
1658 }
1659
1660 static uint32_t omap_l4_io_readb(void *opaque, target_phys_addr_t addr)
1661 {
1662     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
1663
1664     return omap_l4_io_readb_fn[i](omap_l4_io_opaque[i], addr);
1665 }
1666
1667 static uint32_t omap_l4_io_readh(void *opaque, target_phys_addr_t addr)
1668 {
1669     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
1670
1671     return omap_l4_io_readh_fn[i](omap_l4_io_opaque[i], addr);
1672 }
1673
1674 static uint32_t omap_l4_io_readw(void *opaque, target_phys_addr_t addr)
1675 {
1676     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
1677
1678     return omap_l4_io_readw_fn[i](omap_l4_io_opaque[i], addr);
1679 }
1680
1681 static void omap_l4_io_writeb(void *opaque, target_phys_addr_t addr,
1682                 uint32_t value)
1683 {
1684     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
1685
1686     return omap_l4_io_writeb_fn[i](omap_l4_io_opaque[i], addr, value);
1687 }
1688
1689 static void omap_l4_io_writeh(void *opaque, target_phys_addr_t addr,
1690                 uint32_t value)
1691 {
1692     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
1693
1694     return omap_l4_io_writeh_fn[i](omap_l4_io_opaque[i], addr, value);
1695 }
1696
1697 static void omap_l4_io_writew(void *opaque, target_phys_addr_t addr,
1698                 uint32_t value)
1699 {
1700     unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;
1701
1702     return omap_l4_io_writew_fn[i](omap_l4_io_opaque[i], addr, value);
1703 }
1704
1705 static CPUReadMemoryFunc *omap_l4_io_readfn[] = {
1706     omap_l4_io_readb,
1707     omap_l4_io_readh,
1708     omap_l4_io_readw,
1709 };
1710
1711 static CPUWriteMemoryFunc *omap_l4_io_writefn[] = {
1712     omap_l4_io_writeb,
1713     omap_l4_io_writeh,
1714     omap_l4_io_writew,
1715 };
1716 #endif
1717
1718 struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
1719 {
1720     struct omap_l4_s *bus = qemu_mallocz(
1721                     sizeof(*bus) + ta_num * sizeof(*bus->ta));
1722
1723     bus->ta_num = ta_num;
1724     bus->base = base;
1725
1726 #ifdef L4_MUX_HACK
1727     omap_l4_io_entries = 1;
1728     omap_l4_io_entry = qemu_mallocz(125 * sizeof(*omap_l4_io_entry));
1729
1730     omap_cpu_io_entry =
1731             cpu_register_io_memory(0, omap_l4_io_readfn,
1732                             omap_l4_io_writefn, bus);
1733 # define L4_PAGES       (0xb4000 / TARGET_PAGE_SIZE)
1734     omap_l4_io_readb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
1735     omap_l4_io_readh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
1736     omap_l4_io_readw_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
1737     omap_l4_io_writeb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
1738     omap_l4_io_writeh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
1739     omap_l4_io_writew_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
1740     omap_l4_io_opaque = qemu_mallocz(sizeof(void *) * L4_PAGES);
1741 #endif
1742
1743     return bus;
1744 }
1745
1746 static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr)
1747 {
1748     struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
1749     target_phys_addr_t reg = addr - s->base;
1750
1751     switch (reg) {
1752     case 0x00:  /* COMPONENT */
1753         return s->component;
1754
1755     case 0x20:  /* AGENT_CONTROL */
1756         return s->control;
1757
1758     case 0x28:  /* AGENT_STATUS */
1759         return s->status;
1760     }
1761
1762     OMAP_BAD_REG(addr);
1763     return 0;
1764 }
1765
1766 static void omap_l4ta_write(void *opaque, target_phys_addr_t addr,
1767                 uint32_t value)
1768 {
1769     struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
1770     target_phys_addr_t reg = addr - s->base;
1771
1772     switch (reg) {
1773     case 0x00:  /* COMPONENT */
1774     case 0x28:  /* AGENT_STATUS */
1775         OMAP_RO_REG(addr);
1776         break;
1777
1778     case 0x20:  /* AGENT_CONTROL */
1779         s->control = value & 0x01000700;
1780         if (value & 1)                                  /* OCP_RESET */
1781             s->status &= ~1;                            /* REQ_TIMEOUT */
1782         break;
1783
1784     default:
1785         OMAP_BAD_REG(addr);
1786     }
1787 }
1788
1789 static CPUReadMemoryFunc *omap_l4ta_readfn[] = {
1790     omap_badwidth_read16,
1791     omap_l4ta_read,
1792     omap_badwidth_read16,
1793 };
1794
1795 static CPUWriteMemoryFunc *omap_l4ta_writefn[] = {
1796     omap_badwidth_write32,
1797     omap_badwidth_write32,
1798     omap_l4ta_write,
1799 };
1800
1801 #define L4TA(n)         (n)
1802 #define L4TAO(n)        ((n) + 39)
1803
1804 static struct omap_l4_region_s {
1805     target_phys_addr_t offset;
1806     size_t size;
1807     int access;
1808 } omap_l4_region[125] = {
1809     [  1] = { 0x40800,  0x800, 32          }, /* Initiator agent */
1810     [  2] = { 0x41000, 0x1000, 32          }, /* Link agent */
1811     [  0] = { 0x40000,  0x800, 32          }, /* Address and protection */
1812     [  3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
1813     [  4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
1814     [  5] = { 0x04000, 0x1000, 32 | 16     }, /* 32K Timer */
1815     [  6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
1816     [  7] = { 0x08000,  0x800, 32          }, /* PRCM Region A */
1817     [  8] = { 0x08800,  0x800, 32          }, /* PRCM Region B */
1818     [  9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
1819     [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
1820     [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
1821     [ 12] = { 0x14000, 0x1000, 32          }, /* Test/emulation (TAP) */
1822     [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
1823     [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
1824     [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
1825     [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
1826     [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
1827     [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
1828     [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
1829     [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
1830     [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
1831     [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
1832     [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
1833     [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
1834     [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
1835     [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
1836     [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
1837     [ 28] = { 0x50000,  0x400, 32 | 16 | 8 }, /* Display top */
1838     [ 29] = { 0x50400,  0x400, 32 | 16 | 8 }, /* Display control */
1839     [ 30] = { 0x50800,  0x400, 32 | 16 | 8 }, /* Display RFBI */
1840     [ 31] = { 0x50c00,  0x400, 32 | 16 | 8 }, /* Display encoder */
1841     [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
1842     [ 33] = { 0x52000,  0x400, 32 | 16 | 8 }, /* Camera top */
1843     [ 34] = { 0x52400,  0x400, 32 | 16 | 8 }, /* Camera core */
1844     [ 35] = { 0x52800,  0x400, 32 | 16 | 8 }, /* Camera DMA */
1845     [ 36] = { 0x52c00,  0x400, 32 | 16 | 8 }, /* Camera MMU */
1846     [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
1847     [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
1848     [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
1849     [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
1850     [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
1851     [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
1852     [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
1853     [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
1854     [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
1855     [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
1856     [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
1857     [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
1858     [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
1859     [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
1860     [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
1861     [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
1862     [ 53] = { 0x66000,  0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
1863     [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
1864     [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
1865     [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
1866     [ 57] = { 0x6a000, 0x1000,      16 | 8 }, /* UART1 */
1867     [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
1868     [ 59] = { 0x6c000, 0x1000,      16 | 8 }, /* UART2 */
1869     [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
1870     [ 61] = { 0x6e000, 0x1000,      16 | 8 }, /* UART3 */
1871     [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
1872     [ 63] = { 0x70000, 0x1000,      16     }, /* I2C1 */
1873     [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
1874     [ 65] = { 0x72000, 0x1000,      16     }, /* I2C2 */
1875     [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
1876     [ 67] = { 0x74000, 0x1000,      16     }, /* McBSP1 */
1877     [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
1878     [ 69] = { 0x76000, 0x1000,      16     }, /* McBSP2 */
1879     [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
1880     [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
1881     [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
1882     [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
1883     [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
1884     [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
1885     [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
1886     [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
1887     [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
1888     [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
1889     [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
1890     [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
1891     [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
1892     [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
1893     [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
1894     [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
1895     [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
1896     [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
1897     [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
1898     [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
1899     [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
1900     [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
1901     [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
1902     [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
1903     [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
1904     [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
1905     [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
1906     [ 97] = { 0x90000, 0x1000,      16     }, /* EAC */
1907     [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
1908     [ 99] = { 0x92000, 0x1000,      16     }, /* FAC */
1909     [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
1910     [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
1911     [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
1912     [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
1913     [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
1914     [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
1915     [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
1916     [107] = { 0x9c000, 0x1000,      16 | 8 }, /* MMC SDIO */
1917     [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
1918     [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
1919     [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
1920     [111] = { 0xa0000, 0x1000, 32          }, /* RNG */
1921     [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
1922     [113] = { 0xa2000, 0x1000, 32          }, /* DES3DES */
1923     [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
1924     [115] = { 0xa4000, 0x1000, 32          }, /* SHA1MD5 */
1925     [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
1926     [117] = { 0xa6000, 0x1000, 32          }, /* AES */
1927     [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
1928     [119] = { 0xa8000, 0x2000, 32          }, /* PKA */
1929     [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
1930     [121] = { 0xb0000, 0x1000, 32          }, /* MG */
1931     [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
1932     [123] = { 0xb2000, 0x1000, 32          }, /* HDQ/1-Wire */
1933     [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
1934 };
1935
1936 static struct omap_l4_agent_info_s {
1937     int ta;
1938     int region;
1939     int regions;
1940     int ta_region;
1941 } omap_l4_agent_info[54] = {
1942     { 0,           0, 3, 2 }, /* L4IA initiatior agent */
1943     { L4TAO(1),    3, 2, 1 }, /* Control and pinout module */
1944     { L4TAO(2),    5, 2, 1 }, /* 32K timer */
1945     { L4TAO(3),    7, 3, 2 }, /* PRCM */
1946     { L4TA(1),    10, 2, 1 }, /* BCM */
1947     { L4TA(2),    12, 2, 1 }, /* Test JTAG */
1948     { L4TA(3),    14, 6, 3 }, /* Quad GPIO */
1949     { L4TA(4),    20, 4, 3 }, /* WD timer 1/2 */
1950     { L4TA(7),    24, 2, 1 }, /* GP timer 1 */
1951     { L4TA(9),    26, 2, 1 }, /* ATM11 ETB */
1952     { L4TA(10),   28, 5, 4 }, /* Display subsystem */
1953     { L4TA(11),   33, 5, 4 }, /* Camera subsystem */
1954     { L4TA(12),   38, 2, 1 }, /* sDMA */
1955     { L4TA(13),   40, 5, 4 }, /* SSI */
1956     { L4TAO(4),   45, 2, 1 }, /* USB */
1957     { L4TA(14),   47, 2, 1 }, /* Win Tracer1 */
1958     { L4TA(15),   49, 2, 1 }, /* Win Tracer2 */
1959     { L4TA(16),   51, 2, 1 }, /* Win Tracer3 */
1960     { L4TA(17),   53, 2, 1 }, /* Win Tracer4 */
1961     { L4TA(18),   55, 2, 1 }, /* XTI */
1962     { L4TA(19),   57, 2, 1 }, /* UART1 */
1963     { L4TA(20),   59, 2, 1 }, /* UART2 */
1964     { L4TA(21),   61, 2, 1 }, /* UART3 */
1965     { L4TAO(5),   63, 2, 1 }, /* I2C1 */
1966     { L4TAO(6),   65, 2, 1 }, /* I2C2 */
1967     { L4TAO(7),   67, 2, 1 }, /* McBSP1 */
1968     { L4TAO(8),   69, 2, 1 }, /* McBSP2 */
1969     { L4TA(5),    71, 2, 1 }, /* WD Timer 3 (DSP) */
1970     { L4TA(6),    73, 2, 1 }, /* WD Timer 4 (IVA) */
1971     { L4TA(8),    75, 2, 1 }, /* GP Timer 2 */
1972     { L4TA(22),   77, 2, 1 }, /* GP Timer 3 */
1973     { L4TA(23),   79, 2, 1 }, /* GP Timer 4 */
1974     { L4TA(24),   81, 2, 1 }, /* GP Timer 5 */
1975     { L4TA(25),   83, 2, 1 }, /* GP Timer 6 */
1976     { L4TA(26),   85, 2, 1 }, /* GP Timer 7 */
1977     { L4TA(27),   87, 2, 1 }, /* GP Timer 8 */
1978     { L4TA(28),   89, 2, 1 }, /* GP Timer 9 */
1979     { L4TA(29),   91, 2, 1 }, /* GP Timer 10 */
1980     { L4TA(30),   93, 2, 1 }, /* GP Timer 11 */
1981     { L4TA(31),   95, 2, 1 }, /* GP Timer 12 */
1982     { L4TA(32),   97, 2, 1 }, /* EAC */
1983     { L4TA(33),   99, 2, 1 }, /* FAC */
1984     { L4TA(34),  101, 2, 1 }, /* IPC */
1985     { L4TA(35),  103, 2, 1 }, /* SPI1 */
1986     { L4TA(36),  105, 2, 1 }, /* SPI2 */
1987     { L4TAO(9),  107, 2, 1 }, /* MMC SDIO */
1988     { L4TAO(10), 109, 2, 1 },
1989     { L4TAO(11), 111, 2, 1 }, /* RNG */
1990     { L4TAO(12), 113, 2, 1 }, /* DES3DES */
1991     { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
1992     { L4TA(37),  117, 2, 1 }, /* AES */
1993     { L4TA(38),  119, 2, 1 }, /* PKA */
1994     { -1,        121, 2, 1 },
1995     { L4TA(39),  123, 2, 1 }, /* HDQ/1-Wire */
1996 };
1997
1998 #define omap_l4ta(bus, cs)      omap_l4ta_get(bus, L4TA(cs))
1999 #define omap_l4tao(bus, cs)     omap_l4ta_get(bus, L4TAO(cs))
2000
2001 struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs)
2002 {
2003     int i, iomemtype;
2004     struct omap_target_agent_s *ta = 0;
2005     struct omap_l4_agent_info_s *info = 0;
2006
2007     for (i = 0; i < bus->ta_num; i ++)
2008         if (omap_l4_agent_info[i].ta == cs) {
2009             ta = &bus->ta[i];
2010             info = &omap_l4_agent_info[i];
2011             break;
2012         }
2013     if (!ta) {
2014         fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
2015         exit(-1);
2016     }
2017
2018     ta->bus = bus;
2019     ta->start = &omap_l4_region[info->region];
2020     ta->regions = info->regions;
2021
2022     ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2023     ta->status = 0x00000000;
2024     ta->control = 0x00000200;   /* XXX 01000200 for L4TAO */
2025
2026     iomemtype = l4_register_io_memory(0, omap_l4ta_readfn,
2027                     omap_l4ta_writefn, ta);
2028     ta->base = omap_l4_attach(ta, info->ta_region, iomemtype);
2029
2030     return ta;
2031 }
2032
2033 target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
2034                 int iotype)
2035 {
2036     target_phys_addr_t base;
2037     ssize_t size;
2038 #ifdef L4_MUX_HACK
2039     int i;
2040 #endif
2041
2042     if (region < 0 || region >= ta->regions) {
2043         fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);
2044         exit(-1);
2045     }
2046
2047     base = ta->bus->base + ta->start[region].offset;
2048     size = ta->start[region].size;
2049     if (iotype) {
2050 #ifndef L4_MUX_HACK
2051         cpu_register_physical_memory(base, size, iotype);
2052 #else
2053         cpu_register_physical_memory(base, size, omap_cpu_io_entry);
2054         i = (base - ta->bus->base) / TARGET_PAGE_SIZE;
2055         for (; size > 0; size -= TARGET_PAGE_SIZE, i ++) {
2056             omap_l4_io_readb_fn[i] = omap_l4_io_entry[iotype].mem_read[0];
2057             omap_l4_io_readh_fn[i] = omap_l4_io_entry[iotype].mem_read[1];
2058             omap_l4_io_readw_fn[i] = omap_l4_io_entry[iotype].mem_read[2];
2059             omap_l4_io_writeb_fn[i] = omap_l4_io_entry[iotype].mem_write[0];
2060             omap_l4_io_writeh_fn[i] = omap_l4_io_entry[iotype].mem_write[1];
2061             omap_l4_io_writew_fn[i] = omap_l4_io_entry[iotype].mem_write[2];
2062             omap_l4_io_opaque[i] = omap_l4_io_entry[iotype].opaque;
2063         }
2064 #endif
2065     }
2066
2067     return base;
2068 }
2069
2070 /* TEST-Chip-level TAP */
2071 static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr)
2072 {
2073     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
2074     target_phys_addr_t reg = addr - s->tap_base;
2075
2076     switch (reg) {
2077     case 0x204: /* IDCODE_reg */
2078         switch (s->mpu_model) {
2079         case omap2420:
2080         case omap2422:
2081         case omap2423:
2082             return 0x5b5d902f;  /* ES 2.2 */
2083         case omap2430:
2084             return 0x5b68a02f;  /* ES 2.2 */
2085         case omap3430:
2086             return 0x1b7ae02f;  /* ES 2 */
2087         default:
2088             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2089         }
2090
2091     case 0x208: /* PRODUCTION_ID_reg for OMAP2 */
2092     case 0x210: /* PRODUCTION_ID_reg for OMAP3 */
2093         switch (s->mpu_model) {
2094         case omap2420:
2095             return 0x000254f0;  /* POP ESHS2.1.1 in N91/93/95, ES2 in N800 */
2096         case omap2422:
2097             return 0x000400f0;
2098         case omap2423:
2099             return 0x000800f0;
2100         case omap2430:
2101             return 0x000000f0;
2102         case omap3430:
2103             return 0x000000f0;
2104         default:
2105             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2106         }
2107
2108     case 0x20c:
2109         switch (s->mpu_model) {
2110         case omap2420:
2111         case omap2422:
2112         case omap2423:
2113             return 0xcafeb5d9;  /* ES 2.2 */
2114         case omap2430:
2115             return 0xcafeb68a;  /* ES 2.2 */
2116         case omap3430:
2117             return 0xcafeb7ae;  /* ES 2 */
2118         default:
2119             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
2120         }
2121
2122     case 0x218: /* DIE_ID_reg */
2123         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2124     case 0x21c: /* DIE_ID_reg */
2125         return 0x54 << 24;
2126     case 0x220: /* DIE_ID_reg */
2127         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2128     case 0x224: /* DIE_ID_reg */
2129         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
2130     }
2131
2132     OMAP_BAD_REG(addr);
2133     return 0;
2134 }
2135
2136 static void omap_tap_write(void *opaque, target_phys_addr_t addr,
2137                 uint32_t value)
2138 {
2139     OMAP_BAD_REG(addr);
2140 }
2141
2142 static CPUReadMemoryFunc *omap_tap_readfn[] = {
2143     omap_badwidth_read32,
2144     omap_badwidth_read32,
2145     omap_tap_read,
2146 };
2147
2148 static CPUWriteMemoryFunc *omap_tap_writefn[] = {
2149     omap_badwidth_write32,
2150     omap_badwidth_write32,
2151     omap_tap_write,
2152 };
2153
2154 void omap_tap_init(struct omap_target_agent_s *ta,
2155                 struct omap_mpu_state_s *mpu)
2156 {
2157     mpu->tap_base = omap_l4_attach(ta, 0, l4_register_io_memory(0,
2158                             omap_tap_readfn, omap_tap_writefn, mpu));
2159 }
2160
2161 /* Power, Reset, and Clock Management */
2162 struct omap_prcm_s {
2163     target_phys_addr_t base;
2164     qemu_irq irq[3];
2165     struct omap_mpu_state_s *mpu;
2166
2167     uint32_t irqst[3];
2168     uint32_t irqen[3];
2169
2170     uint32_t sysconfig;
2171     uint32_t voltctrl;
2172     uint32_t scratch[20];
2173
2174     uint32_t clksrc[1];
2175     uint32_t clkout[1];
2176     uint32_t clkemul[1];
2177     uint32_t clkpol[1];
2178     uint32_t clksel[8];
2179     uint32_t clken[12];
2180     uint32_t clkctrl[4];
2181     uint32_t clkidle[7];
2182     uint32_t setuptime[2];
2183
2184     uint32_t wkup[3];
2185     uint32_t wken[3];
2186     uint32_t wkst[3];
2187     uint32_t rst[4];
2188     uint32_t rstctrl[1];
2189     uint32_t power[4];
2190     uint32_t rsttime_wkup;
2191
2192     uint32_t ev;
2193     uint32_t evtime[2];
2194 };
2195
2196 static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
2197 {
2198     qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
2199     /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
2200 }
2201
2202 static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr)
2203 {
2204     struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
2205     int offset = addr - s->base;
2206
2207     switch (offset) {
2208     case 0x000: /* PRCM_REVISION */
2209         return 0x10;
2210
2211     case 0x010: /* PRCM_SYSCONFIG */
2212         return s->sysconfig;
2213
2214     case 0x018: /* PRCM_IRQSTATUS_MPU */
2215         return s->irqst[0];
2216
2217     case 0x01c: /* PRCM_IRQENABLE_MPU */
2218         return s->irqen[0];
2219
2220     case 0x050: /* PRCM_VOLTCTRL */
2221         return s->voltctrl;
2222     case 0x054: /* PRCM_VOLTST */
2223         return s->voltctrl & 3;
2224
2225     case 0x060: /* PRCM_CLKSRC_CTRL */
2226         return s->clksrc[0];
2227     case 0x070: /* PRCM_CLKOUT_CTRL */
2228         return s->clkout[0];
2229     case 0x078: /* PRCM_CLKEMUL_CTRL */
2230         return s->clkemul[0];
2231     case 0x080: /* PRCM_CLKCFG_CTRL */
2232     case 0x084: /* PRCM_CLKCFG_STATUS */
2233         return 0;
2234
2235     case 0x090: /* PRCM_VOLTSETUP */
2236         return s->setuptime[0];
2237
2238     case 0x094: /* PRCM_CLKSSETUP */
2239         return s->setuptime[1];
2240
2241     case 0x098: /* PRCM_POLCTRL */
2242         return s->clkpol[0];
2243
2244     case 0x0b0: /* GENERAL_PURPOSE1 */
2245     case 0x0b4: /* GENERAL_PURPOSE2 */
2246     case 0x0b8: /* GENERAL_PURPOSE3 */
2247     case 0x0bc: /* GENERAL_PURPOSE4 */
2248     case 0x0c0: /* GENERAL_PURPOSE5 */
2249     case 0x0c4: /* GENERAL_PURPOSE6 */
2250     case 0x0c8: /* GENERAL_PURPOSE7 */
2251     case 0x0cc: /* GENERAL_PURPOSE8 */
2252     case 0x0d0: /* GENERAL_PURPOSE9 */
2253     case 0x0d4: /* GENERAL_PURPOSE10 */
2254     case 0x0d8: /* GENERAL_PURPOSE11 */
2255     case 0x0dc: /* GENERAL_PURPOSE12 */
2256     case 0x0e0: /* GENERAL_PURPOSE13 */
2257     case 0x0e4: /* GENERAL_PURPOSE14 */
2258     case 0x0e8: /* GENERAL_PURPOSE15 */
2259     case 0x0ec: /* GENERAL_PURPOSE16 */
2260     case 0x0f0: /* GENERAL_PURPOSE17 */
2261     case 0x0f4: /* GENERAL_PURPOSE18 */
2262     case 0x0f8: /* GENERAL_PURPOSE19 */
2263     case 0x0fc: /* GENERAL_PURPOSE20 */
2264         return s->scratch[(offset - 0xb0) >> 2];
2265
2266     case 0x140: /* CM_CLKSEL_MPU */
2267         return s->clksel[0];
2268     case 0x148: /* CM_CLKSTCTRL_MPU */
2269         return s->clkctrl[0];
2270
2271     case 0x158: /* RM_RSTST_MPU */
2272         return s->rst[0];
2273     case 0x1c8: /* PM_WKDEP_MPU */
2274         return s->wkup[0];
2275     case 0x1d4: /* PM_EVGENCTRL_MPU */
2276         return s->ev;
2277     case 0x1d8: /* PM_EVEGENONTIM_MPU */
2278         return s->evtime[0];
2279     case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
2280         return s->evtime[1];
2281     case 0x1e0: /* PM_PWSTCTRL_MPU */
2282         return s->power[0];
2283     case 0x1e4: /* PM_PWSTST_MPU */
2284         return 0;
2285
2286     case 0x200: /* CM_FCLKEN1_CORE */
2287         return s->clken[0];
2288     case 0x204: /* CM_FCLKEN2_CORE */
2289         return s->clken[1];
2290     case 0x210: /* CM_ICLKEN1_CORE */
2291         return s->clken[2];
2292     case 0x214: /* CM_ICLKEN2_CORE */
2293         return s->clken[3];
2294     case 0x21c: /* CM_ICLKEN4_CORE */
2295         return s->clken[4];
2296
2297     case 0x220: /* CM_IDLEST1_CORE */
2298         /* TODO: check the actual iclk status */
2299         return 0x7ffffff9;
2300     case 0x224: /* CM_IDLEST2_CORE */
2301         /* TODO: check the actual iclk status */
2302         return 0x00000007;
2303     case 0x22c: /* CM_IDLEST4_CORE */
2304         /* TODO: check the actual iclk status */
2305         return 0x0000001f;
2306
2307     case 0x230: /* CM_AUTOIDLE1_CORE */
2308         return s->clkidle[0];
2309     case 0x234: /* CM_AUTOIDLE2_CORE */
2310         return s->clkidle[1];
2311     case 0x238: /* CM_AUTOIDLE3_CORE */
2312         return s->clkidle[2];
2313     case 0x23c: /* CM_AUTOIDLE4_CORE */
2314         return s->clkidle[3];
2315
2316     case 0x240: /* CM_CLKSEL1_CORE */
2317         return s->clksel[1];
2318     case 0x244: /* CM_CLKSEL2_CORE */
2319         return s->clksel[2];
2320
2321     case 0x248: /* CM_CLKSTCTRL_CORE */
2322         return s->clkctrl[1];
2323
2324     case 0x2a0: /* PM_WKEN1_CORE */
2325         return s->wken[0];
2326     case 0x2a4: /* PM_WKEN2_CORE */
2327         return s->wken[1];
2328
2329     case 0x2b0: /* PM_WKST1_CORE */
2330         return s->wkst[0];
2331     case 0x2b4: /* PM_WKST2_CORE */
2332         return s->wkst[1];
2333     case 0x2c8: /* PM_WKDEP_CORE */
2334         return 0x1e;
2335
2336     case 0x2e0: /* PM_PWSTCTRL_CORE */
2337         return s->power[1];
2338     case 0x2e4: /* PM_PWSTST_CORE */
2339         return 0x000030 | (s->power[1] & 0xfc00);
2340
2341     case 0x300: /* CM_FCLKEN_GFX */
2342         return s->clken[5];
2343     case 0x310: /* CM_ICLKEN_GFX */
2344         return s->clken[6];
2345     case 0x320: /* CM_IDLEST_GFX */
2346         /* TODO: check the actual iclk status */
2347         return 0x00000001;
2348     case 0x340: /* CM_CLKSEL_GFX */
2349         return s->clksel[3];
2350     case 0x348: /* CM_CLKSTCTRL_GFX */
2351         return s->clkctrl[2];
2352     case 0x350: /* RM_RSTCTRL_GFX */
2353         return s->rstctrl[0];
2354     case 0x358: /* RM_RSTST_GFX */
2355         return s->rst[1];
2356     case 0x3c8: /* PM_WKDEP_GFX */
2357         return s->wkup[1];
2358
2359     case 0x3e0: /* PM_PWSTCTRL_GFX */
2360         return s->power[2];
2361     case 0x3e4: /* PM_PWSTST_GFX */
2362         return s->power[2] & 3;
2363
2364     case 0x400: /* CM_FCLKEN_WKUP */
2365         return s->clken[7];
2366     case 0x410: /* CM_ICLKEN_WKUP */
2367         return s->clken[8];
2368     case 0x420: /* CM_IDLEST_WKUP */
2369         /* TODO: check the actual iclk status */
2370         return 0x0000003f;
2371     case 0x430: /* CM_AUTOIDLE_WKUP */
2372         return s->clkidle[4];
2373     case 0x440: /* CM_CLKSEL_WKUP */
2374         return s->clksel[4];
2375     case 0x450: /* RM_RSTCTRL_WKUP */
2376         return 0;
2377     case 0x454: /* RM_RSTTIME_WKUP */
2378         return s->rsttime_wkup;
2379     case 0x458: /* RM_RSTST_WKUP */
2380         return s->rst[2];
2381     case 0x4a0: /* PM_WKEN_WKUP */
2382         return s->wken[2];
2383     case 0x4b0: /* PM_WKST_WKUP */
2384         return s->wkst[2];
2385
2386     case 0x500: /* CM_CLKEN_PLL */
2387         return s->clken[9];
2388     case 0x520: /* CM_IDLEST_CKGEN */
2389         /* Core uses 32-kHz clock */
2390         if (!(s->clksel[6] & 3))
2391             return 0x00000377;
2392         /* DPLL not in lock mode, core uses ref_clk */
2393         if ((s->clken[9] & 3) != 3)
2394             return 0x00000375;
2395         /* Core uses DPLL */
2396         return 0x00000376;
2397     case 0x530: /* CM_AUTOIDLE_PLL */
2398         return s->clkidle[5];
2399     case 0x540: /* CM_CLKSEL1_PLL */
2400         return s->clksel[5];
2401     case 0x544: /* CM_CLKSEL2_PLL */
2402         return s->clksel[6];
2403
2404     case 0x800: /* CM_FCLKEN_DSP */
2405         return s->clken[10];
2406     case 0x810: /* CM_ICLKEN_DSP */
2407         return s->clken[11];
2408     case 0x820: /* CM_IDLEST_DSP */
2409         /* TODO: check the actual iclk status */
2410         return 0x00000103;
2411     case 0x830: /* CM_AUTOIDLE_DSP */
2412         return s->clkidle[6];
2413     case 0x840: /* CM_CLKSEL_DSP */
2414         return s->clksel[7];
2415     case 0x848: /* CM_CLKSTCTRL_DSP */
2416         return s->clkctrl[3];
2417     case 0x850: /* RM_RSTCTRL_DSP */
2418         return 0;
2419     case 0x858: /* RM_RSTST_DSP */
2420         return s->rst[3];
2421     case 0x8c8: /* PM_WKDEP_DSP */
2422         return s->wkup[2];
2423     case 0x8e0: /* PM_PWSTCTRL_DSP */
2424         return s->power[3];
2425     case 0x8e4: /* PM_PWSTST_DSP */
2426         return 0x008030 | (s->power[3] & 0x3003);
2427
2428     case 0x8f0: /* PRCM_IRQSTATUS_DSP */
2429         return s->irqst[1];
2430     case 0x8f4: /* PRCM_IRQENABLE_DSP */
2431         return s->irqen[1];
2432
2433     case 0x8f8: /* PRCM_IRQSTATUS_IVA */
2434         return s->irqst[2];
2435     case 0x8fc: /* PRCM_IRQENABLE_IVA */
2436         return s->irqen[2];
2437     }
2438
2439     OMAP_BAD_REG(addr);
2440     return 0;
2441 }
2442
2443 static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
2444                 uint32_t value)
2445 {
2446     struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
2447     int offset = addr - s->base;
2448
2449     switch (offset) {
2450     case 0x000: /* PRCM_REVISION */
2451     case 0x054: /* PRCM_VOLTST */
2452     case 0x084: /* PRCM_CLKCFG_STATUS */
2453     case 0x1e4: /* PM_PWSTST_MPU */
2454     case 0x220: /* CM_IDLEST1_CORE */
2455     case 0x224: /* CM_IDLEST2_CORE */
2456     case 0x22c: /* CM_IDLEST4_CORE */
2457     case 0x2c8: /* PM_WKDEP_CORE */
2458     case 0x2e4: /* PM_PWSTST_CORE */
2459     case 0x320: /* CM_IDLEST_GFX */
2460     case 0x3e4: /* PM_PWSTST_GFX */
2461     case 0x420: /* CM_IDLEST_WKUP */
2462     case 0x520: /* CM_IDLEST_CKGEN */
2463     case 0x820: /* CM_IDLEST_DSP */
2464     case 0x8e4: /* PM_PWSTST_DSP */
2465         OMAP_RO_REG(addr);
2466         return;
2467
2468     case 0x010: /* PRCM_SYSCONFIG */
2469         s->sysconfig = value & 1;
2470         break;
2471
2472     case 0x018: /* PRCM_IRQSTATUS_MPU */
2473         s->irqst[0] &= ~value;
2474         omap_prcm_int_update(s, 0);
2475         break;
2476     case 0x01c: /* PRCM_IRQENABLE_MPU */
2477         s->irqen[0] = value & 0x3f;
2478         omap_prcm_int_update(s, 0);
2479         break;
2480
2481     case 0x050: /* PRCM_VOLTCTRL */
2482         s->voltctrl = value & 0xf1c3;
2483         break;
2484
2485     case 0x060: /* PRCM_CLKSRC_CTRL */
2486         s->clksrc[0] = value & 0xdb;
2487         /* TODO update clocks */
2488         break;
2489
2490     case 0x070: /* PRCM_CLKOUT_CTRL */
2491         s->clkout[0] = value & 0xbbbb;
2492         /* TODO update clocks */
2493         break;
2494
2495     case 0x078: /* PRCM_CLKEMUL_CTRL */
2496         s->clkemul[0] = value & 1;
2497         /* TODO update clocks */
2498         break;
2499
2500     case 0x080: /* PRCM_CLKCFG_CTRL */
2501         break;
2502
2503     case 0x090: /* PRCM_VOLTSETUP */
2504         s->setuptime[0] = value & 0xffff;
2505         break;
2506     case 0x094: /* PRCM_CLKSSETUP */
2507         s->setuptime[1] = value & 0xffff;
2508         break;
2509
2510     case 0x098: /* PRCM_POLCTRL */
2511         s->clkpol[0] = value & 0x701;
2512         break;
2513
2514     case 0x0b0: /* GENERAL_PURPOSE1 */
2515     case 0x0b4: /* GENERAL_PURPOSE2 */
2516     case 0x0b8: /* GENERAL_PURPOSE3 */
2517     case 0x0bc: /* GENERAL_PURPOSE4 */
2518     case 0x0c0: /* GENERAL_PURPOSE5 */
2519     case 0x0c4: /* GENERAL_PURPOSE6 */
2520     case 0x0c8: /* GENERAL_PURPOSE7 */
2521     case 0x0cc: /* GENERAL_PURPOSE8 */
2522     case 0x0d0: /* GENERAL_PURPOSE9 */
2523     case 0x0d4: /* GENERAL_PURPOSE10 */
2524     case 0x0d8: /* GENERAL_PURPOSE11 */
2525     case 0x0dc: /* GENERAL_PURPOSE12 */
2526     case 0x0e0: /* GENERAL_PURPOSE13 */
2527     case 0x0e4: /* GENERAL_PURPOSE14 */
2528     case 0x0e8: /* GENERAL_PURPOSE15 */
2529     case 0x0ec: /* GENERAL_PURPOSE16 */
2530     case 0x0f0: /* GENERAL_PURPOSE17 */
2531     case 0x0f4: /* GENERAL_PURPOSE18 */
2532     case 0x0f8: /* GENERAL_PURPOSE19 */
2533     case 0x0fc: /* GENERAL_PURPOSE20 */
2534         s->scratch[(offset - 0xb0) >> 2] = value;
2535         break;
2536
2537     case 0x140: /* CM_CLKSEL_MPU */
2538         s->clksel[0] = value & 0x1f;
2539         /* TODO update clocks */
2540         break;
2541     case 0x148: /* CM_CLKSTCTRL_MPU */
2542         s->clkctrl[0] = value & 0x1f;
2543         break;
2544
2545     case 0x158: /* RM_RSTST_MPU */
2546         s->rst[0] &= ~value;
2547         break;
2548     case 0x1c8: /* PM_WKDEP_MPU */
2549         s->wkup[0] = value & 0x15;
2550         break;
2551
2552     case 0x1d4: /* PM_EVGENCTRL_MPU */
2553         s->ev = value & 0x1f;
2554         break;
2555     case 0x1d8: /* PM_EVEGENONTIM_MPU */
2556         s->evtime[0] = value;
2557         break;
2558     case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
2559         s->evtime[1] = value;
2560         break;
2561
2562     case 0x1e0: /* PM_PWSTCTRL_MPU */
2563         s->power[0] = value & 0xc0f;
2564         break;
2565
2566     case 0x200: /* CM_FCLKEN1_CORE */
2567         s->clken[0] = value & 0xbfffffff;
2568         /* TODO update clocks */
2569         break;
2570     case 0x204: /* CM_FCLKEN2_CORE */
2571         s->clken[1] = value & 0x00000007;
2572         /* TODO update clocks */
2573         break;
2574     case 0x210: /* CM_ICLKEN1_CORE */
2575         s->clken[2] = value & 0xfffffff9;
2576         /* TODO update clocks */
2577         break;
2578     case 0x214: /* CM_ICLKEN2_CORE */
2579         s->clken[3] = value & 0x00000007;
2580         /* TODO update clocks */
2581         break;
2582     case 0x21c: /* CM_ICLKEN4_CORE */
2583         s->clken[4] = value & 0x0000001f;
2584         /* TODO update clocks */
2585         break;
2586
2587     case 0x230: /* CM_AUTOIDLE1_CORE */
2588         s->clkidle[0] = value & 0xfffffff9;
2589         /* TODO update clocks */
2590         break;
2591     case 0x234: /* CM_AUTOIDLE2_CORE */
2592         s->clkidle[1] = value & 0x00000007;
2593         /* TODO update clocks */
2594         break;
2595     case 0x238: /* CM_AUTOIDLE3_CORE */
2596         s->clkidle[2] = value & 0x00000007;
2597         /* TODO update clocks */
2598         break;
2599     case 0x23c: /* CM_AUTOIDLE4_CORE */
2600         s->clkidle[3] = value & 0x0000001f;
2601         /* TODO update clocks */
2602         break;
2603
2604     case 0x240: /* CM_CLKSEL1_CORE */
2605         s->clksel[1] = value & 0x0fffbf7f;
2606         /* TODO update clocks */
2607         break;
2608
2609     case 0x244: /* CM_CLKSEL2_CORE */
2610         s->clksel[2] = value & 0x00fffffc;
2611         /* TODO update clocks */
2612         break;
2613
2614     case 0x248: /* CM_CLKSTCTRL_CORE */
2615         s->clkctrl[1] = value & 0x7;
2616         break;
2617
2618     case 0x2a0: /* PM_WKEN1_CORE */
2619         s->wken[0] = value & 0x04667ff8;
2620         break;
2621     case 0x2a4: /* PM_WKEN2_CORE */
2622         s->wken[1] = value & 0x00000005;
2623         break;
2624
2625     case 0x2b0: /* PM_WKST1_CORE */
2626         s->wkst[0] &= ~value;
2627         break;
2628     case 0x2b4: /* PM_WKST2_CORE */
2629         s->wkst[1] &= ~value;
2630         break;
2631
2632     case 0x2e0: /* PM_PWSTCTRL_CORE */
2633         s->power[1] = (value & 0x00fc3f) | (1 << 2);
2634         break;
2635
2636     case 0x300: /* CM_FCLKEN_GFX */
2637         s->clken[5] = value & 6;
2638         /* TODO update clocks */
2639         break;
2640     case 0x310: /* CM_ICLKEN_GFX */
2641         s->clken[6] = value & 1;
2642         /* TODO update clocks */
2643         break;
2644     case 0x340: /* CM_CLKSEL_GFX */
2645         s->clksel[3] = value & 7;
2646         /* TODO update clocks */
2647         break;
2648     case 0x348: /* CM_CLKSTCTRL_GFX */
2649         s->clkctrl[2] = value & 1;
2650         break;
2651     case 0x350: /* RM_RSTCTRL_GFX */
2652         s->rstctrl[0] = value & 1;
2653         /* TODO: reset */
2654         break;
2655     case 0x358: /* RM_RSTST_GFX */
2656         s->rst[1] &= ~value;
2657         break;
2658     case 0x3c8: /* PM_WKDEP_GFX */
2659         s->wkup[1] = value & 0x13;
2660         break;
2661     case 0x3e0: /* PM_PWSTCTRL_GFX */
2662         s->power[2] = (value & 0x00c0f) | (3 << 2);
2663         break;
2664
2665     case 0x400: /* CM_FCLKEN_WKUP */
2666         s->clken[7] = value & 0xd;
2667         /* TODO update clocks */
2668         break;
2669     case 0x410: /* CM_ICLKEN_WKUP */
2670         s->clken[8] = value & 0x3f;
2671         /* TODO update clocks */
2672         break;
2673     case 0x430: /* CM_AUTOIDLE_WKUP */
2674         s->clkidle[4] = value & 0x0000003f;
2675         /* TODO update clocks */
2676         break;
2677     case 0x440: /* CM_CLKSEL_WKUP */
2678         s->clksel[4] = value & 3;
2679         /* TODO update clocks */
2680         break;
2681     case 0x450: /* RM_RSTCTRL_WKUP */
2682         /* TODO: reset */
2683         if (value & 2)
2684             qemu_system_reset_request();
2685         break;
2686     case 0x454: /* RM_RSTTIME_WKUP */
2687         s->rsttime_wkup = value & 0x1fff;
2688         break;
2689     case 0x458: /* RM_RSTST_WKUP */
2690         s->rst[2] &= ~value;
2691         break;
2692     case 0x4a0: /* PM_WKEN_WKUP */
2693         s->wken[2] = value & 0x00000005;
2694         break;
2695     case 0x4b0: /* PM_WKST_WKUP */
2696         s->wkst[2] &= ~value;
2697         break;
2698
2699     case 0x500: /* CM_CLKEN_PLL */
2700         s->clken[9] = value & 0xcf;
2701         /* TODO update clocks */
2702         break;
2703     case 0x530: /* CM_AUTOIDLE_PLL */
2704         s->clkidle[5] = value & 0x000000cf;
2705         /* TODO update clocks */
2706         break;
2707     case 0x540: /* CM_CLKSEL1_PLL */
2708         s->clksel[5] = value & 0x03bfff28;
2709         /* TODO update clocks */
2710         break;
2711     case 0x544: /* CM_CLKSEL2_PLL */
2712         s->clksel[6] = value & 3;
2713         /* TODO update clocks */
2714         break;
2715
2716     case 0x800: /* CM_FCLKEN_DSP */
2717         s->clken[10] = value & 0x501;
2718         /* TODO update clocks */
2719         break;
2720     case 0x810: /* CM_ICLKEN_DSP */
2721         s->clken[11] = value & 0x2;
2722         /* TODO update clocks */
2723         break;
2724     case 0x830: /* CM_AUTOIDLE_DSP */
2725         s->clkidle[6] = value & 0x2;
2726         /* TODO update clocks */
2727         break;
2728     case 0x840: /* CM_CLKSEL_DSP */
2729         s->clksel[7] = value & 0x3fff;
2730         /* TODO update clocks */
2731         break;
2732     case 0x848: /* CM_CLKSTCTRL_DSP */
2733         s->clkctrl[3] = value & 0x101;
2734         break;
2735     case 0x850: /* RM_RSTCTRL_DSP */
2736         /* TODO: reset */
2737         break;
2738     case 0x858: /* RM_RSTST_DSP */
2739         s->rst[3] &= ~value;
2740         break;
2741     case 0x8c8: /* PM_WKDEP_DSP */
2742         s->wkup[2] = value & 0x13;
2743         break;
2744     case 0x8e0: /* PM_PWSTCTRL_DSP */
2745         s->power[3] = (value & 0x03017) | (3 << 2);
2746         break;
2747
2748     case 0x8f0: /* PRCM_IRQSTATUS_DSP */
2749         s->irqst[1] &= ~value;
2750         omap_prcm_int_update(s, 1);
2751         break;
2752     case 0x8f4: /* PRCM_IRQENABLE_DSP */
2753         s->irqen[1] = value & 0x7;
2754         omap_prcm_int_update(s, 1);
2755         break;
2756
2757     case 0x8f8: /* PRCM_IRQSTATUS_IVA */
2758         s->irqst[2] &= ~value;
2759         omap_prcm_int_update(s, 2);
2760         break;
2761     case 0x8fc: /* PRCM_IRQENABLE_IVA */
2762         s->irqen[2] = value & 0x7;
2763         omap_prcm_int_update(s, 2);
2764         break;
2765
2766     default:
2767         OMAP_BAD_REG(addr);
2768         return;
2769     }
2770 }
2771
2772 static CPUReadMemoryFunc *omap_prcm_readfn[] = {
2773     omap_badwidth_read32,
2774     omap_badwidth_read32,
2775     omap_prcm_read,
2776 };
2777
2778 static CPUWriteMemoryFunc *omap_prcm_writefn[] = {
2779     omap_badwidth_write32,
2780     omap_badwidth_write32,
2781     omap_prcm_write,
2782 };
2783
2784 static void omap_prcm_reset(struct omap_prcm_s *s)
2785 {
2786     s->sysconfig = 0;
2787     s->irqst[0] = 0;
2788     s->irqst[1] = 0;
2789     s->irqst[2] = 0;
2790     s->irqen[0] = 0;
2791     s->irqen[1] = 0;
2792     s->irqen[2] = 0;
2793     s->voltctrl = 0x1040;
2794     s->ev = 0x14;
2795     s->evtime[0] = 0;
2796     s->evtime[1] = 0;
2797     s->clkctrl[0] = 0;
2798     s->clkctrl[1] = 0;
2799     s->clkctrl[2] = 0;
2800     s->clkctrl[3] = 0;
2801     s->clken[1] = 7;
2802     s->clken[3] = 7;
2803     s->clken[4] = 0;
2804     s->clken[5] = 0;
2805     s->clken[6] = 0;
2806     s->clken[7] = 0xc;
2807     s->clken[8] = 0x3e;
2808     s->clken[9] = 0x0d;
2809     s->clken[10] = 0;
2810     s->clken[11] = 0;
2811     s->clkidle[0] = 0;
2812     s->clkidle[2] = 7;
2813     s->clkidle[3] = 0;
2814     s->clkidle[4] = 0;
2815     s->clkidle[5] = 0x0c;
2816     s->clkidle[6] = 0;
2817     s->clksel[0] = 0x01;
2818     s->clksel[1] = 0x02100121;
2819     s->clksel[2] = 0x00000000;
2820     s->clksel[3] = 0x01;
2821     s->clksel[4] = 0;
2822     s->clksel[7] = 0x0121;
2823     s->wkup[0] = 0x15;
2824     s->wkup[1] = 0x13;
2825     s->wkup[2] = 0x13;
2826     s->wken[0] = 0x04667ff8;
2827     s->wken[1] = 0x00000005;
2828     s->wken[2] = 5;
2829     s->wkst[0] = 0;
2830     s->wkst[1] = 0;
2831     s->wkst[2] = 0;
2832     s->power[0] = 0x00c;
2833     s->power[1] = 4;
2834     s->power[2] = 0x0000c;
2835     s->power[3] = 0x14;
2836     s->rstctrl[0] = 1;
2837     s->rst[3] = 1;
2838 }
2839
2840 static void omap_prcm_coldreset(struct omap_prcm_s *s)
2841 {
2842     s->setuptime[0] = 0;
2843     s->setuptime[1] = 0;
2844     memset(&s->scratch, 0, sizeof(s->scratch));
2845     s->rst[0] = 0x01;
2846     s->rst[1] = 0x00;
2847     s->rst[2] = 0x01;
2848     s->clken[0] = 0;
2849     s->clken[2] = 0;
2850     s->clkidle[1] = 0;
2851     s->clksel[5] = 0;
2852     s->clksel[6] = 2;
2853     s->clksrc[0] = 0x43;
2854     s->clkout[0] = 0x0303;
2855     s->clkemul[0] = 0;
2856     s->clkpol[0] = 0x100;
2857     s->rsttime_wkup = 0x1002;
2858
2859     omap_prcm_reset(s);
2860 }
2861
2862 struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
2863                 qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
2864                 struct omap_mpu_state_s *mpu)
2865 {
2866     int iomemtype;
2867     struct omap_prcm_s *s = (struct omap_prcm_s *)
2868             qemu_mallocz(sizeof(struct omap_prcm_s));
2869
2870     s->irq[0] = mpu_int;
2871     s->irq[1] = dsp_int;
2872     s->irq[2] = iva_int;
2873     s->mpu = mpu;
2874     omap_prcm_coldreset(s);
2875
2876     iomemtype = l4_register_io_memory(0, omap_prcm_readfn,
2877                     omap_prcm_writefn, s);
2878     s->base = omap_l4_attach(ta, 0, iomemtype);
2879     omap_l4_attach(ta, 1, iomemtype);
2880
2881     return s;
2882 }
2883
2884 /* System and Pinout control */
2885 struct omap_sysctl_s {
2886     target_phys_addr_t base;
2887     struct omap_mpu_state_s *mpu;
2888
2889     uint32_t sysconfig;
2890     uint32_t devconfig;
2891     uint32_t psaconfig;
2892     uint32_t padconf[0x45];
2893     uint8_t obs;
2894     uint32_t msuspendmux[5];
2895 };
2896
2897 static uint32_t omap_sysctl_read(void *opaque, target_phys_addr_t addr)
2898 {
2899     struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
2900     int offset = addr - s->base;
2901
2902     switch (offset) {
2903     case 0x000: /* CONTROL_REVISION */
2904         return 0x20;
2905
2906     case 0x010: /* CONTROL_SYSCONFIG */
2907         return s->sysconfig;
2908
2909     case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
2910         return s->padconf[(offset - 0x30) >> 2];
2911
2912     case 0x270: /* CONTROL_DEBOBS */
2913         return s->obs;
2914
2915     case 0x274: /* CONTROL_DEVCONF */
2916         return s->devconfig;
2917
2918     case 0x28c: /* CONTROL_EMU_SUPPORT */
2919         return 0;
2920
2921     case 0x290: /* CONTROL_MSUSPENDMUX_0 */
2922         return s->msuspendmux[0];
2923     case 0x294: /* CONTROL_MSUSPENDMUX_1 */
2924         return s->msuspendmux[1];
2925     case 0x298: /* CONTROL_MSUSPENDMUX_2 */
2926         return s->msuspendmux[2];
2927     case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
2928         return s->msuspendmux[3];
2929     case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
2930         return s->msuspendmux[4];
2931     case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
2932         return 0;
2933
2934     case 0x2b8: /* CONTROL_PSA_CTRL */
2935         return s->psaconfig;
2936     case 0x2bc: /* CONTROL_PSA_CMD */
2937     case 0x2c0: /* CONTROL_PSA_VALUE */
2938         return 0;
2939
2940     case 0x2b0: /* CONTROL_SEC_CTRL */
2941         return 0x800000f1;
2942     case 0x2d0: /* CONTROL_SEC_EMU */
2943         return 0x80000015;
2944     case 0x2d4: /* CONTROL_SEC_TAP */
2945         return 0x8000007f;
2946     case 0x2b4: /* CONTROL_SEC_TEST */
2947     case 0x2f0: /* CONTROL_SEC_STATUS */
2948     case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
2949         /* Secure mode is not present on general-pusrpose device.  Outside
2950          * secure mode these values cannot be read or written.  */
2951         return 0;
2952
2953     case 0x2d8: /* CONTROL_OCM_RAM_PERM */
2954         return 0xff;
2955     case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
2956     case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
2957     case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
2958         /* No secure mode so no Extended Secure RAM present.  */
2959         return 0;
2960
2961     case 0x2f8: /* CONTROL_STATUS */
2962         /* Device Type => General-purpose */
2963         return 0x0300;
2964     case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
2965
2966     case 0x300: /* CONTROL_RPUB_KEY_H_0 */
2967     case 0x304: /* CONTROL_RPUB_KEY_H_1 */
2968     case 0x308: /* CONTROL_RPUB_KEY_H_2 */
2969     case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
2970         return 0xdecafbad;
2971
2972     case 0x310: /* CONTROL_RAND_KEY_0 */
2973     case 0x314: /* CONTROL_RAND_KEY_1 */
2974     case 0x318: /* CONTROL_RAND_KEY_2 */
2975     case 0x31c: /* CONTROL_RAND_KEY_3 */
2976     case 0x320: /* CONTROL_CUST_KEY_0 */
2977     case 0x324: /* CONTROL_CUST_KEY_1 */
2978     case 0x330: /* CONTROL_TEST_KEY_0 */
2979     case 0x334: /* CONTROL_TEST_KEY_1 */
2980     case 0x338: /* CONTROL_TEST_KEY_2 */
2981     case 0x33c: /* CONTROL_TEST_KEY_3 */
2982     case 0x340: /* CONTROL_TEST_KEY_4 */
2983     case 0x344: /* CONTROL_TEST_KEY_5 */
2984     case 0x348: /* CONTROL_TEST_KEY_6 */
2985     case 0x34c: /* CONTROL_TEST_KEY_7 */
2986     case 0x350: /* CONTROL_TEST_KEY_8 */
2987     case 0x354: /* CONTROL_TEST_KEY_9 */
2988         /* Can only be accessed in secure mode and when C_FieldAccEnable
2989          * bit is set in CONTROL_SEC_CTRL.
2990          * TODO: otherwise an interconnect access error is generated.  */
2991         return 0;
2992     }
2993
2994     OMAP_BAD_REG(addr);
2995     return 0;
2996 }
2997
2998 static void omap_sysctl_write(void *opaque, target_phys_addr_t addr,
2999                 uint32_t value)
3000 {
3001     struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
3002     int offset = addr - s->base;
3003
3004     switch (offset) {
3005     case 0x000: /* CONTROL_REVISION */
3006     case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
3007     case 0x2c0: /* CONTROL_PSA_VALUE */
3008     case 0x2f8: /* CONTROL_STATUS */
3009     case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
3010     case 0x300: /* CONTROL_RPUB_KEY_H_0 */
3011     case 0x304: /* CONTROL_RPUB_KEY_H_1 */
3012     case 0x308: /* CONTROL_RPUB_KEY_H_2 */
3013     case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
3014     case 0x310: /* CONTROL_RAND_KEY_0 */
3015     case 0x314: /* CONTROL_RAND_KEY_1 */
3016     case 0x318: /* CONTROL_RAND_KEY_2 */
3017     case 0x31c: /* CONTROL_RAND_KEY_3 */
3018     case 0x320: /* CONTROL_CUST_KEY_0 */
3019     case 0x324: /* CONTROL_CUST_KEY_1 */
3020     case 0x330: /* CONTROL_TEST_KEY_0 */
3021     case 0x334: /* CONTROL_TEST_KEY_1 */
3022     case 0x338: /* CONTROL_TEST_KEY_2 */
3023     case 0x33c: /* CONTROL_TEST_KEY_3 */
3024     case 0x340: /* CONTROL_TEST_KEY_4 */
3025     case 0x344: /* CONTROL_TEST_KEY_5 */
3026     case 0x348: /* CONTROL_TEST_KEY_6 */
3027     case 0x34c: /* CONTROL_TEST_KEY_7 */
3028     case 0x350: /* CONTROL_TEST_KEY_8 */
3029     case 0x354: /* CONTROL_TEST_KEY_9 */
3030         OMAP_RO_REG(addr);
3031         return;
3032
3033     case 0x010: /* CONTROL_SYSCONFIG */
3034         s->sysconfig = value & 0x1e;
3035         break;
3036
3037     case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
3038         /* XXX: should check constant bits */
3039         s->padconf[(offset - 0x30) >> 2] = value & 0x1f1f1f1f;
3040         break;
3041
3042     case 0x270: /* CONTROL_DEBOBS */
3043         s->obs = value & 0xff;
3044         break;
3045
3046     case 0x274: /* CONTROL_DEVCONF */
3047         s->devconfig = value & 0xffffc7ff;
3048         break;
3049
3050     case 0x28c: /* CONTROL_EMU_SUPPORT */
3051         break;
3052
3053     case 0x290: /* CONTROL_MSUSPENDMUX_0 */
3054         s->msuspendmux[0] = value & 0x3fffffff;
3055         break;
3056     case 0x294: /* CONTROL_MSUSPENDMUX_1 */
3057         s->msuspendmux[1] = value & 0x3fffffff;
3058         break;
3059     case 0x298: /* CONTROL_MSUSPENDMUX_2 */
3060         s->msuspendmux[2] = value & 0x3fffffff;
3061         break;
3062     case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
3063         s->msuspendmux[3] = value & 0x3fffffff;
3064         break;
3065     case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
3066         s->msuspendmux[4] = value & 0x3fffffff;
3067         break;
3068
3069     case 0x2b8: /* CONTROL_PSA_CTRL */
3070         s->psaconfig = value & 0x1c;
3071         s->psaconfig |= (value & 0x20) ? 2 : 1;
3072         break;
3073     case 0x2bc: /* CONTROL_PSA_CMD */
3074         break;
3075
3076     case 0x2b0: /* CONTROL_SEC_CTRL */
3077     case 0x2b4: /* CONTROL_SEC_TEST */
3078     case 0x2d0: /* CONTROL_SEC_EMU */
3079     case 0x2d4: /* CONTROL_SEC_TAP */
3080     case 0x2d8: /* CONTROL_OCM_RAM_PERM */
3081     case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
3082     case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
3083     case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
3084     case 0x2f0: /* CONTROL_SEC_STATUS */
3085     case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
3086         break;
3087
3088     default:
3089         OMAP_BAD_REG(addr);
3090         return;
3091     }
3092 }
3093
3094 static CPUReadMemoryFunc *omap_sysctl_readfn[] = {
3095     omap_badwidth_read32,       /* TODO */
3096     omap_badwidth_read32,       /* TODO */
3097     omap_sysctl_read,
3098 };
3099
3100 static CPUWriteMemoryFunc *omap_sysctl_writefn[] = {
3101     omap_badwidth_write32,      /* TODO */
3102     omap_badwidth_write32,      /* TODO */
3103     omap_sysctl_write,
3104 };
3105
3106 static void omap_sysctl_reset(struct omap_sysctl_s *s)
3107 {
3108     /* (power-on reset) */
3109     s->sysconfig = 0;
3110     s->obs = 0;
3111     s->devconfig = 0x0c000000;
3112     s->msuspendmux[0] = 0x00000000;
3113     s->msuspendmux[1] = 0x00000000;
3114     s->msuspendmux[2] = 0x00000000;
3115     s->msuspendmux[3] = 0x00000000;
3116     s->msuspendmux[4] = 0x00000000;
3117     s->psaconfig = 1;
3118
3119     s->padconf[0x00] = 0x000f0f0f;
3120     s->padconf[0x01] = 0x00000000;
3121     s->padconf[0x02] = 0x00000000;
3122     s->padconf[0x03] = 0x00000000;
3123     s->padconf[0x04] = 0x00000000;
3124     s->padconf[0x05] = 0x00000000;
3125     s->padconf[0x06] = 0x00000000;
3126     s->padconf[0x07] = 0x00000000;
3127     s->padconf[0x08] = 0x08080800;
3128     s->padconf[0x09] = 0x08080808;
3129     s->padconf[0x0a] = 0x08080808;
3130     s->padconf[0x0b] = 0x08080808;
3131     s->padconf[0x0c] = 0x08080808;
3132     s->padconf[0x0d] = 0x08080800;
3133     s->padconf[0x0e] = 0x08080808;
3134     s->padconf[0x0f] = 0x08080808;
3135     s->padconf[0x10] = 0x18181808;      /* | 0x07070700 if SBoot3 */
3136     s->padconf[0x11] = 0x18181818;      /* | 0x07070707 if SBoot3 */
3137     s->padconf[0x12] = 0x18181818;      /* | 0x07070707 if SBoot3 */
3138     s->padconf[0x13] = 0x18181818;      /* | 0x07070707 if SBoot3 */
3139     s->padconf[0x14] = 0x18181818;      /* | 0x00070707 if SBoot3 */
3140     s->padconf[0x15] = 0x18181818;
3141     s->padconf[0x16] = 0x18181818;      /* | 0x07000000 if SBoot3 */
3142     s->padconf[0x17] = 0x1f001f00;
3143     s->padconf[0x18] = 0x1f1f1f1f;
3144     s->padconf[0x19] = 0x00000000;
3145     s->padconf[0x1a] = 0x1f180000;
3146     s->padconf[0x1b] = 0x00001f1f;
3147     s->padconf[0x1c] = 0x1f001f00;
3148     s->padconf[0x1d] = 0x00000000;
3149     s->padconf[0x1e] = 0x00000000;
3150     s->padconf[0x1f] = 0x08000000;
3151     s->padconf[0x20] = 0x08080808;
3152     s->padconf[0x21] = 0x08080808;
3153     s->padconf[0x22] = 0x0f080808;
3154     s->padconf[0x23] = 0x0f0f0f0f;
3155     s->padconf[0x24] = 0x000f0f0f;
3156     s->padconf[0x25] = 0x1f1f1f0f;
3157     s->padconf[0x26] = 0x080f0f1f;
3158     s->padconf[0x27] = 0x070f1808;
3159     s->padconf[0x28] = 0x0f070707;
3160     s->padconf[0x29] = 0x000f0f1f;
3161     s->padconf[0x2a] = 0x0f0f0f1f;
3162     s->padconf[0x2b] = 0x08000000;
3163     s->padconf[0x2c] = 0x0000001f;
3164     s->padconf[0x2d] = 0x0f0f1f00;
3165     s->padconf[0x2e] = 0x1f1f0f0f;
3166     s->padconf[0x2f] = 0x0f1f1f1f;
3167     s->padconf[0x30] = 0x0f0f0f0f;
3168     s->padconf[0x31] = 0x0f1f0f1f;
3169     s->padconf[0x32] = 0x0f0f0f0f;
3170     s->padconf[0x33] = 0x0f1f0f1f;
3171     s->padconf[0x34] = 0x1f1f0f0f;
3172     s->padconf[0x35] = 0x0f0f1f1f;
3173     s->padconf[0x36] = 0x0f0f1f0f;
3174     s->padconf[0x37] = 0x0f0f0f0f;
3175     s->padconf[0x38] = 0x1f18180f;
3176     s->padconf[0x39] = 0x1f1f1f1f;
3177     s->padconf[0x3a] = 0x00001f1f;
3178     s->padconf[0x3b] = 0x00000000;
3179     s->padconf[0x3c] = 0x00000000;
3180     s->padconf[0x3d] = 0x0f0f0f0f;
3181     s->padconf[0x3e] = 0x18000f0f;
3182     s->padconf[0x3f] = 0x00070000;
3183     s->padconf[0x40] = 0x00000707;
3184     s->padconf[0x41] = 0x0f1f0700;
3185     s->padconf[0x42] = 0x1f1f070f;
3186     s->padconf[0x43] = 0x0008081f;
3187     s->padconf[0x44] = 0x00000800;
3188 }
3189
3190 struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
3191                 omap_clk iclk, struct omap_mpu_state_s *mpu)
3192 {
3193     int iomemtype;
3194     struct omap_sysctl_s *s = (struct omap_sysctl_s *)
3195             qemu_mallocz(sizeof(struct omap_sysctl_s));
3196
3197     s->mpu = mpu;
3198     omap_sysctl_reset(s);
3199
3200     iomemtype = l4_register_io_memory(0, omap_sysctl_readfn,
3201                     omap_sysctl_writefn, s);
3202     s->base = omap_l4_attach(ta, 0, iomemtype);
3203     omap_l4_attach(ta, 0, iomemtype);
3204
3205     return s;
3206 }
3207
3208 /* SDRAM Controller Subsystem */
3209 struct omap_sdrc_s {
3210     target_phys_addr_t base;
3211
3212     uint8_t config;
3213 };
3214
3215 static void omap_sdrc_reset(struct omap_sdrc_s *s)
3216 {
3217     s->config = 0x10;
3218 }
3219
3220 static uint32_t omap_sdrc_read(void *opaque, target_phys_addr_t addr)
3221 {
3222     struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
3223     int offset = addr - s->base;
3224
3225     switch (offset) {
3226     case 0x00:  /* SDRC_REVISION */
3227         return 0x20;
3228
3229     case 0x10:  /* SDRC_SYSCONFIG */
3230         return s->config;
3231
3232     case 0x14:  /* SDRC_SYSSTATUS */
3233         return 1;                                               /* RESETDONE */
3234
3235     case 0x40:  /* SDRC_CS_CFG */
3236     case 0x44:  /* SDRC_SHARING */
3237     case 0x48:  /* SDRC_ERR_ADDR */
3238     case 0x4c:  /* SDRC_ERR_TYPE */
3239     case 0x60:  /* SDRC_DLLA_SCTRL */
3240     case 0x64:  /* SDRC_DLLA_STATUS */
3241     case 0x68:  /* SDRC_DLLB_CTRL */
3242     case 0x6c:  /* SDRC_DLLB_STATUS */
3243     case 0x70:  /* SDRC_POWER */
3244     case 0x80:  /* SDRC_MCFG_0 */
3245     case 0x84:  /* SDRC_MR_0 */
3246     case 0x88:  /* SDRC_EMR1_0 */
3247     case 0x8c:  /* SDRC_EMR2_0 */
3248     case 0x90:  /* SDRC_EMR3_0 */
3249     case 0x94:  /* SDRC_DCDL1_CTRL */
3250     case 0x98:  /* SDRC_DCDL2_CTRL */
3251     case 0x9c:  /* SDRC_ACTIM_CTRLA_0 */
3252     case 0xa0:  /* SDRC_ACTIM_CTRLB_0 */
3253     case 0xa4:  /* SDRC_RFR_CTRL_0 */
3254     case 0xa8:  /* SDRC_MANUAL_0 */
3255     case 0xb0:  /* SDRC_MCFG_1 */
3256     case 0xb4:  /* SDRC_MR_1 */
3257     case 0xb8:  /* SDRC_EMR1_1 */
3258     case 0xbc:  /* SDRC_EMR2_1 */
3259     case 0xc0:  /* SDRC_EMR3_1 */
3260     case 0xc4:  /* SDRC_ACTIM_CTRLA_1 */
3261     case 0xc8:  /* SDRC_ACTIM_CTRLB_1 */
3262     case 0xd4:  /* SDRC_RFR_CTRL_1 */
3263     case 0xd8:  /* SDRC_MANUAL_1 */
3264         return 0x00;
3265     }
3266
3267     OMAP_BAD_REG(addr);
3268     return 0;
3269 }
3270
3271 static void omap_sdrc_write(void *opaque, target_phys_addr_t addr,
3272                 uint32_t value)
3273 {
3274     struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
3275     int offset = addr - s->base;
3276
3277     switch (offset) {
3278     case 0x00:  /* SDRC_REVISION */
3279     case 0x14:  /* SDRC_SYSSTATUS */
3280     case 0x48:  /* SDRC_ERR_ADDR */
3281     case 0x64:  /* SDRC_DLLA_STATUS */
3282     case 0x6c:  /* SDRC_DLLB_STATUS */
3283         OMAP_RO_REG(addr);
3284         return;
3285
3286     case 0x10:  /* SDRC_SYSCONFIG */
3287         if ((value >> 3) != 0x2)
3288             fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
3289                             __FUNCTION__, value >> 3);
3290         if (value & 2)
3291             omap_sdrc_reset(s);
3292         s->config = value & 0x18;
3293         break;
3294
3295     case 0x40:  /* SDRC_CS_CFG */
3296     case 0x44:  /* SDRC_SHARING */
3297     case 0x4c:  /* SDRC_ERR_TYPE */
3298     case 0x60:  /* SDRC_DLLA_SCTRL */
3299     case 0x68:  /* SDRC_DLLB_CTRL */
3300     case 0x70:  /* SDRC_POWER */
3301     case 0x80:  /* SDRC_MCFG_0 */
3302     case 0x84:  /* SDRC_MR_0 */
3303     case 0x88:  /* SDRC_EMR1_0 */
3304     case 0x8c:  /* SDRC_EMR2_0 */
3305     case 0x90:  /* SDRC_EMR3_0 */
3306     case 0x94:  /* SDRC_DCDL1_CTRL */
3307     case 0x98:  /* SDRC_DCDL2_CTRL */
3308     case 0x9c:  /* SDRC_ACTIM_CTRLA_0 */
3309     case 0xa0:  /* SDRC_ACTIM_CTRLB_0 */
3310     case 0xa4:  /* SDRC_RFR_CTRL_0 */
3311     case 0xa8:  /* SDRC_MANUAL_0 */
3312     case 0xb0:  /* SDRC_MCFG_1 */
3313     case 0xb4:  /* SDRC_MR_1 */
3314     case 0xb8:  /* SDRC_EMR1_1 */
3315     case 0xbc:  /* SDRC_EMR2_1 */
3316     case 0xc0:  /* SDRC_EMR3_1 */
3317     case 0xc4:  /* SDRC_ACTIM_CTRLA_1 */
3318     case 0xc8:  /* SDRC_ACTIM_CTRLB_1 */
3319     case 0xd4:  /* SDRC_RFR_CTRL_1 */
3320     case 0xd8:  /* SDRC_MANUAL_1 */
3321         break;
3322
3323     default:
3324         OMAP_BAD_REG(addr);
3325         return;
3326     }
3327 }
3328
3329 static CPUReadMemoryFunc *omap_sdrc_readfn[] = {
3330     omap_badwidth_read32,
3331     omap_badwidth_read32,
3332     omap_sdrc_read,
3333 };
3334
3335 static CPUWriteMemoryFunc *omap_sdrc_writefn[] = {
3336     omap_badwidth_write32,
3337     omap_badwidth_write32,
3338     omap_sdrc_write,
3339 };
3340
3341 struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base)
3342 {
3343     int iomemtype;
3344     struct omap_sdrc_s *s = (struct omap_sdrc_s *)
3345             qemu_mallocz(sizeof(struct omap_sdrc_s));
3346
3347     s->base = base;
3348     omap_sdrc_reset(s);
3349
3350     iomemtype = cpu_register_io_memory(0, omap_sdrc_readfn,
3351                     omap_sdrc_writefn, s);
3352     cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3353
3354     return s;
3355 }
3356
3357 /* General-Purpose Memory Controller */
3358 struct omap_gpmc_s {
3359     target_phys_addr_t base;
3360     qemu_irq irq;
3361
3362     uint8_t sysconfig;
3363     uint16_t irqst;
3364     uint16_t irqen;
3365     uint16_t timeout;
3366     uint16_t config;
3367     uint32_t prefconfig[2];
3368     int prefcontrol;
3369     int preffifo;
3370     int prefcount;
3371     struct omap_gpmc_cs_file_s {
3372         uint32_t config[7];
3373         target_phys_addr_t base;
3374         size_t size;
3375         int iomemtype;
3376         void (*base_update)(void *opaque, target_phys_addr_t new);
3377         void (*unmap)(void *opaque);
3378         void *opaque;
3379     } cs_file[8];
3380     int ecc_cs;
3381     int ecc_ptr;
3382     uint32_t ecc_cfg;
3383     struct ecc_state_s ecc[9];
3384 };
3385
3386 static void omap_gpmc_int_update(struct omap_gpmc_s *s)
3387 {
3388     qemu_set_irq(s->irq, s->irqen & s->irqst);
3389 }
3390
3391 static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
3392 {
3393     /* TODO: check for overlapping regions and report access errors */
3394     if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
3395                     (base < 0 || base >= 0x40) ||
3396                     (base & 0x0f & ~mask)) {
3397         fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
3398                         __FUNCTION__);
3399         return;
3400     }
3401
3402     if (!f->opaque)
3403         return;
3404
3405     f->base = base << 24;
3406     f->size = (0x0fffffff & ~(mask << 24)) + 1;
3407     /* TODO: rather than setting the size of the mapping (which should be
3408      * constant), the mask should cause wrapping of the address space, so
3409      * that the same memory becomes accessible at every <i>size</i> bytes
3410      * starting from <i>base</i>.  */
3411     if (f->iomemtype)
3412         cpu_register_physical_memory(f->base, f->size, f->iomemtype);
3413
3414     if (f->base_update)
3415         f->base_update(f->opaque, f->base);
3416 }
3417
3418 static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
3419 {
3420     if (f->size) {
3421         if (f->unmap)
3422             f->unmap(f->opaque);
3423         if (f->iomemtype)
3424             cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED);
3425         f->base = 0;
3426         f->size = 0;
3427     }
3428 }
3429
3430 static void omap_gpmc_reset(struct omap_gpmc_s *s)
3431 {
3432     int i;
3433
3434     s->sysconfig = 0;
3435     s->irqst = 0;
3436     s->irqen = 0;
3437     omap_gpmc_int_update(s);
3438     s->timeout = 0;
3439     s->config = 0xa00;
3440     s->prefconfig[0] = 0x00004000;
3441     s->prefconfig[1] = 0x00000000;
3442     s->prefcontrol = 0;
3443     s->preffifo = 0;
3444     s->prefcount = 0;
3445     for (i = 0; i < 8; i ++) {
3446         if (s->cs_file[i].config[6] & (1 << 6))                 /* CSVALID */
3447             omap_gpmc_cs_unmap(s->cs_file + i);
3448         s->cs_file[i].config[0] = i ? 1 << 12 : 0;
3449         s->cs_file[i].config[1] = 0x101001;
3450         s->cs_file[i].config[2] = 0x020201;
3451         s->cs_file[i].config[3] = 0x10031003;
3452         s->cs_file[i].config[4] = 0x10f1111;
3453         s->cs_file[i].config[5] = 0;
3454         s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
3455         if (s->cs_file[i].config[6] & (1 << 6))                 /* CSVALID */
3456             omap_gpmc_cs_map(&s->cs_file[i],
3457                             s->cs_file[i].config[6] & 0x1f,     /* MASKADDR */
3458                         (s->cs_file[i].config[6] >> 8 & 0xf));  /* BASEADDR */
3459     }
3460     omap_gpmc_cs_map(s->cs_file, 0, 0xf);
3461     s->ecc_cs = 0;
3462     s->ecc_ptr = 0;
3463     s->ecc_cfg = 0x3fcff000;
3464     for (i = 0; i < 9; i ++)
3465         ecc_reset(&s->ecc[i]);
3466 }
3467
3468 static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
3469 {
3470     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
3471     int offset = addr - s->base;
3472     int cs;
3473     struct omap_gpmc_cs_file_s *f;
3474
3475     switch (offset) {
3476     case 0x000: /* GPMC_REVISION */
3477         return 0x20;
3478
3479     case 0x010: /* GPMC_SYSCONFIG */
3480         return s->sysconfig;
3481
3482     case 0x014: /* GPMC_SYSSTATUS */
3483         return 1;                                               /* RESETDONE */
3484
3485     case 0x018: /* GPMC_IRQSTATUS */
3486         return s->irqst;
3487
3488     case 0x01c: /* GPMC_IRQENABLE */
3489         return s->irqen;
3490
3491     case 0x040: /* GPMC_TIMEOUT_CONTROL */
3492         return s->timeout;
3493
3494     case 0x044: /* GPMC_ERR_ADDRESS */
3495     case 0x048: /* GPMC_ERR_TYPE */
3496         return 0;
3497
3498     case 0x050: /* GPMC_CONFIG */
3499         return s->config;
3500
3501     case 0x054: /* GPMC_STATUS */
3502         return 0x001;
3503
3504     case 0x060 ... 0x1d4:
3505         cs = (offset - 0x060) / 0x30;
3506         offset -= cs * 0x30;
3507         f = s->cs_file + cs;
3508         switch (offset - cs * 0x30) {
3509             case 0x60:  /* GPMC_CONFIG1 */
3510                 return f->config[0];
3511             case 0x64:  /* GPMC_CONFIG2 */
3512                 return f->config[1];
3513             case 0x68:  /* GPMC_CONFIG3 */
3514                 return f->config[2];
3515             case 0x6c:  /* GPMC_CONFIG4 */
3516                 return f->config[3];
3517             case 0x70:  /* GPMC_CONFIG5 */
3518                 return f->config[4];
3519             case 0x74:  /* GPMC_CONFIG6 */
3520                 return f->config[5];
3521             case 0x78:  /* GPMC_CONFIG7 */
3522                 return f->config[6];
3523             case 0x84:  /* GPMC_NAND_DATA */
3524                 return 0;
3525         }
3526         break;
3527
3528     case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */
3529         return s->prefconfig[0];
3530     case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */
3531         return s->prefconfig[1];
3532     case 0x1ec: /* GPMC_PREFETCH_CONTROL */
3533         return s->prefcontrol;
3534     case 0x1f0: /* GPMC_PREFETCH_STATUS */
3535         return (s->preffifo << 24) |
3536                 ((s->preffifo >
3537                   ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
3538                 s->prefcount;
3539
3540     case 0x1f4: /* GPMC_ECC_CONFIG */
3541         return s->ecc_cs;
3542     case 0x1f8: /* GPMC_ECC_CONTROL */
3543         return s->ecc_ptr;
3544     case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */
3545         return s->ecc_cfg;
3546     case 0x200 ... 0x220:       /* GPMC_ECC_RESULT */
3547         cs = (offset & 0x1f) >> 2;
3548         /* TODO: check correctness */
3549         return
3550                 ((s->ecc[cs].cp    &  0x07) <<  0) |
3551                 ((s->ecc[cs].cp    &  0x38) << 13) |
3552                 ((s->ecc[cs].lp[0] & 0x1ff) <<  3) |
3553                 ((s->ecc[cs].lp[1] & 0x1ff) << 19);
3554
3555     case 0x230: /* GPMC_TESTMODE_CTRL */
3556         return 0;
3557     case 0x234: /* GPMC_PSA_LSB */
3558     case 0x238: /* GPMC_PSA_MSB */
3559         return 0x00000000;
3560     }
3561
3562     OMAP_BAD_REG(addr);
3563     return 0;
3564 }
3565
3566 static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
3567                 uint32_t value)
3568 {
3569     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
3570     int offset = addr - s->base;
3571     int cs;
3572     struct omap_gpmc_cs_file_s *f;
3573
3574     switch (offset) {
3575     case 0x000: /* GPMC_REVISION */
3576     case 0x014: /* GPMC_SYSSTATUS */
3577     case 0x054: /* GPMC_STATUS */
3578     case 0x1f0: /* GPMC_PREFETCH_STATUS */
3579     case 0x200 ... 0x220:       /* GPMC_ECC_RESULT */
3580     case 0x234: /* GPMC_PSA_LSB */
3581     case 0x238: /* GPMC_PSA_MSB */
3582         OMAP_RO_REG(addr);
3583         break;
3584
3585     case 0x010: /* GPMC_SYSCONFIG */
3586         if ((value >> 3) == 0x3)
3587             fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
3588                             __FUNCTION__, value >> 3);
3589         if (value & 2)
3590             omap_gpmc_reset(s);
3591         s->sysconfig = value & 0x19;
3592         break;
3593
3594     case 0x018: /* GPMC_IRQSTATUS */
3595         s->irqen = ~value;
3596         omap_gpmc_int_update(s);
3597         break;
3598
3599     case 0x01c: /* GPMC_IRQENABLE */
3600         s->irqen = value & 0xf03;
3601         omap_gpmc_int_update(s);
3602         break;
3603
3604     case 0x040: /* GPMC_TIMEOUT_CONTROL */
3605         s->timeout = value & 0x1ff1;
3606         break;
3607
3608     case 0x044: /* GPMC_ERR_ADDRESS */
3609     case 0x048: /* GPMC_ERR_TYPE */
3610         break;
3611
3612     case 0x050: /* GPMC_CONFIG */
3613         s->config = value & 0xf13;
3614         break;
3615
3616     case 0x060 ... 0x1d4:
3617         cs = (offset - 0x060) / 0x30;
3618         offset -= cs * 0x30;
3619         f = s->cs_file + cs;
3620         switch (offset) {
3621             case 0x60:  /* GPMC_CONFIG1 */
3622                 f->config[0] = value & 0xffef3e13;
3623                 break;
3624             case 0x64:  /* GPMC_CONFIG2 */
3625                 f->config[1] = value & 0x001f1f8f;
3626                 break;
3627             case 0x68:  /* GPMC_CONFIG3 */
3628                 f->config[2] = value & 0x001f1f8f;
3629                 break;
3630             case 0x6c:  /* GPMC_CONFIG4 */
3631                 f->config[3] = value & 0x1f8f1f8f;
3632                 break;
3633             case 0x70:  /* GPMC_CONFIG5 */
3634                 f->config[4] = value & 0x0f1f1f1f;
3635                 break;
3636             case 0x74:  /* GPMC_CONFIG6 */
3637                 f->config[5] = value & 0x00000fcf;
3638                 break;
3639             case 0x78:  /* GPMC_CONFIG7 */
3640                 if ((f->config[6] ^ value) & 0xf7f) {
3641                     if (f->config[6] & (1 << 6))                /* CSVALID */
3642                         omap_gpmc_cs_unmap(f);
3643                     if (value & (1 << 6))                       /* CSVALID */
3644                         omap_gpmc_cs_map(f, value & 0x1f,       /* MASKADDR */
3645                                         (value >> 8 & 0xf));    /* BASEADDR */
3646                 }
3647                 f->config[6] = value & 0x00000f7f;
3648                 break;
3649             case 0x7c:  /* GPMC_NAND_COMMAND */
3650             case 0x80:  /* GPMC_NAND_ADDRESS */
3651             case 0x84:  /* GPMC_NAND_DATA */
3652                 break;
3653
3654             default:
3655                 goto bad_reg;
3656         }
3657         break;
3658
3659     case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */
3660         s->prefconfig[0] = value & 0x7f8f7fbf;
3661         /* TODO: update interrupts, fifos, dmas */
3662         break;
3663
3664     case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */
3665         s->prefconfig[1] = value & 0x3fff;
3666         break;
3667
3668     case 0x1ec: /* GPMC_PREFETCH_CONTROL */
3669         s->prefcontrol = value & 1;
3670         if (s->prefcontrol) {
3671             if (s->prefconfig[0] & 1)
3672                 s->preffifo = 0x40;
3673             else
3674                 s->preffifo = 0x00;
3675         }
3676         /* TODO: start */
3677         break;
3678
3679     case 0x1f4: /* GPMC_ECC_CONFIG */
3680         s->ecc_cs = 0x8f;
3681         break;
3682     case 0x1f8: /* GPMC_ECC_CONTROL */
3683         if (value & (1 << 8))
3684             for (cs = 0; cs < 9; cs ++)
3685                 ecc_reset(&s->ecc[cs]);
3686         s->ecc_ptr = value & 0xf;
3687         if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
3688             s->ecc_ptr = 0;
3689             s->ecc_cs &= ~1;
3690         }
3691         break;
3692     case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */
3693         s->ecc_cfg = value & 0x3fcff1ff;
3694         break;
3695     case 0x230: /* GPMC_TESTMODE_CTRL */
3696         if (value & 7)
3697             fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
3698         break;
3699
3700     default:
3701     bad_reg:
3702         OMAP_BAD_REG(addr);
3703         return;
3704     }
3705 }
3706
3707 static CPUReadMemoryFunc *omap_gpmc_readfn[] = {
3708     omap_badwidth_read32,       /* TODO */
3709     omap_badwidth_read32,       /* TODO */
3710     omap_gpmc_read,
3711 };
3712
3713 static CPUWriteMemoryFunc *omap_gpmc_writefn[] = {
3714     omap_badwidth_write32,      /* TODO */
3715     omap_badwidth_write32,      /* TODO */
3716     omap_gpmc_write,
3717 };
3718
3719 struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
3720 {
3721     int iomemtype;
3722     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
3723             qemu_mallocz(sizeof(struct omap_gpmc_s));
3724
3725     s->base = base;
3726     omap_gpmc_reset(s);
3727
3728     iomemtype = cpu_register_io_memory(0, omap_gpmc_readfn,
3729                     omap_gpmc_writefn, s);
3730     cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3731
3732     return s;
3733 }
3734
3735 void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
3736                 void (*base_upd)(void *opaque, target_phys_addr_t new),
3737                 void (*unmap)(void *opaque), void *opaque)
3738 {
3739     struct omap_gpmc_cs_file_s *f;
3740
3741     if (cs < 0 || cs >= 8) {
3742         fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
3743         exit(-1);
3744     }
3745     f = &s->cs_file[cs];
3746
3747     f->iomemtype = iomemtype;
3748     f->base_update = base_upd;
3749     f->unmap = unmap;
3750     f->opaque = opaque;
3751
3752     if (f->config[6] & (1 << 6))                                /* CSVALID */
3753         omap_gpmc_cs_map(f, f->config[6] & 0x1f,                /* MASKADDR */
3754                         (f->config[6] >> 8 & 0xf));             /* BASEADDR */
3755 }
3756
3757 /* General chip reset */
3758 static void omap2_mpu_reset(void *opaque)
3759 {
3760     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3761
3762     omap_inth_reset(mpu->ih[0]);
3763     omap_dma_reset(mpu->dma);
3764     omap_prcm_reset(mpu->prcm);
3765     omap_sysctl_reset(mpu->sysc);
3766     omap_gp_timer_reset(mpu->gptimer[0]);
3767     omap_gp_timer_reset(mpu->gptimer[1]);
3768     omap_gp_timer_reset(mpu->gptimer[2]);
3769     omap_gp_timer_reset(mpu->gptimer[3]);
3770     omap_gp_timer_reset(mpu->gptimer[4]);
3771     omap_gp_timer_reset(mpu->gptimer[5]);
3772     omap_gp_timer_reset(mpu->gptimer[6]);
3773     omap_gp_timer_reset(mpu->gptimer[7]);
3774     omap_gp_timer_reset(mpu->gptimer[8]);
3775     omap_gp_timer_reset(mpu->gptimer[9]);
3776     omap_gp_timer_reset(mpu->gptimer[10]);
3777     omap_gp_timer_reset(mpu->gptimer[11]);
3778     omap_synctimer_reset(&mpu->synctimer);
3779     omap_sdrc_reset(mpu->sdrc);
3780     omap_gpmc_reset(mpu->gpmc);
3781     omap_dss_reset(mpu->dss);
3782     omap_uart_reset(mpu->uart[0]);
3783     omap_uart_reset(mpu->uart[1]);
3784     omap_uart_reset(mpu->uart[2]);
3785     omap_mmc_reset(mpu->mmc);
3786     omap_gpif_reset(mpu->gpif);
3787     omap_mcspi_reset(mpu->mcspi[0]);
3788     omap_mcspi_reset(mpu->mcspi[1]);
3789     omap_i2c_reset(mpu->i2c[0]);
3790     omap_i2c_reset(mpu->i2c[1]);
3791     cpu_reset(mpu->env);
3792 }
3793
3794 static int omap2_validate_addr(struct omap_mpu_state_s *s,
3795                 target_phys_addr_t addr)
3796 {
3797     return 1;
3798 }
3799
3800 static const struct dma_irq_map omap2_dma_irq_map[] = {
3801     { 0, OMAP_INT_24XX_SDMA_IRQ0 },
3802     { 0, OMAP_INT_24XX_SDMA_IRQ1 },
3803     { 0, OMAP_INT_24XX_SDMA_IRQ2 },
3804     { 0, OMAP_INT_24XX_SDMA_IRQ3 },
3805 };
3806
3807 struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
3808                 DisplayState *ds, const char *core)
3809 {
3810     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
3811             qemu_mallocz(sizeof(struct omap_mpu_state_s));
3812     ram_addr_t sram_base, q2_base;
3813     qemu_irq *cpu_irq;
3814     qemu_irq dma_irqs[4];
3815     omap_clk gpio_clks[4];
3816     int sdindex;
3817     int i;
3818
3819     /* Core */
3820     s->mpu_model = omap2420;
3821     s->env = cpu_init(core ?: "arm1136-r2");
3822     if (!s->env) {
3823         fprintf(stderr, "Unable to find CPU definition\n");
3824         exit(1);
3825     }
3826     s->sdram_size = sdram_size;
3827     s->sram_size = OMAP242X_SRAM_SIZE;
3828
3829     s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3830
3831     /* Clocks */
3832     omap_clk_init(s);
3833
3834     /* Memory-mapped stuff */
3835     cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
3836                     (q2_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
3837     cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
3838                     (sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
3839
3840     s->l4 = omap_l4_init(OMAP2_L4_BASE, 54);
3841
3842     /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
3843     cpu_irq = arm_pic_init_cpu(s->env);
3844     s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0],
3845                     cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
3846                     omap_findclk(s, "mpu_intc_fclk"),
3847                     omap_findclk(s, "mpu_intc_iclk"));
3848
3849     s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
3850                     s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s);
3851
3852     s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
3853                     omap_findclk(s, "omapctrl_iclk"), s);
3854
3855     for (i = 0; i < 4; i ++)
3856         dma_irqs[i] =
3857                 s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr];
3858     s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
3859                     omap_findclk(s, "sdma_iclk"),
3860                     omap_findclk(s, "sdma_fclk"));
3861     s->port->addr_valid = omap2_validate_addr;
3862
3863     s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
3864                     s->irq[0][OMAP_INT_24XX_UART1_IRQ],
3865                     omap_findclk(s, "uart1_fclk"),
3866                     omap_findclk(s, "uart1_iclk"),
3867                     s->drq[OMAP24XX_DMA_UART1_TX],
3868                     s->drq[OMAP24XX_DMA_UART1_RX], serial_hds[0]);
3869     s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20),
3870                     s->irq[0][OMAP_INT_24XX_UART2_IRQ],
3871                     omap_findclk(s, "uart2_fclk"),
3872                     omap_findclk(s, "uart2_iclk"),
3873                     s->drq[OMAP24XX_DMA_UART2_TX],
3874                     s->drq[OMAP24XX_DMA_UART2_RX],
3875                     serial_hds[0] ? serial_hds[1] : 0);
3876     s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21),
3877                     s->irq[0][OMAP_INT_24XX_UART3_IRQ],
3878                     omap_findclk(s, "uart3_fclk"),
3879                     omap_findclk(s, "uart3_iclk"),
3880                     s->drq[OMAP24XX_DMA_UART3_TX],
3881                     s->drq[OMAP24XX_DMA_UART3_RX],
3882                     serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
3883
3884     s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
3885                     s->irq[0][OMAP_INT_24XX_GPTIMER1],
3886                     omap_findclk(s, "wu_gpt1_clk"),
3887                     omap_findclk(s, "wu_l4_iclk"));
3888     s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
3889                     s->irq[0][OMAP_INT_24XX_GPTIMER2],
3890                     omap_findclk(s, "core_gpt2_clk"),
3891                     omap_findclk(s, "core_l4_iclk"));
3892     s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
3893                     s->irq[0][OMAP_INT_24XX_GPTIMER3],
3894                     omap_findclk(s, "core_gpt3_clk"),
3895                     omap_findclk(s, "core_l4_iclk"));
3896     s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
3897                     s->irq[0][OMAP_INT_24XX_GPTIMER4],
3898                     omap_findclk(s, "core_gpt4_clk"),
3899                     omap_findclk(s, "core_l4_iclk"));
3900     s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
3901                     s->irq[0][OMAP_INT_24XX_GPTIMER5],
3902                     omap_findclk(s, "core_gpt5_clk"),
3903                     omap_findclk(s, "core_l4_iclk"));
3904     s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
3905                     s->irq[0][OMAP_INT_24XX_GPTIMER6],
3906                     omap_findclk(s, "core_gpt6_clk"),
3907                     omap_findclk(s, "core_l4_iclk"));
3908     s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
3909                     s->irq[0][OMAP_INT_24XX_GPTIMER7],
3910                     omap_findclk(s, "core_gpt7_clk"),
3911                     omap_findclk(s, "core_l4_iclk"));
3912     s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
3913                     s->irq[0][OMAP_INT_24XX_GPTIMER8],
3914                     omap_findclk(s, "core_gpt8_clk"),
3915                     omap_findclk(s, "core_l4_iclk"));
3916     s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
3917                     s->irq[0][OMAP_INT_24XX_GPTIMER9],
3918                     omap_findclk(s, "core_gpt9_clk"),
3919                     omap_findclk(s, "core_l4_iclk"));
3920     s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
3921                     s->irq[0][OMAP_INT_24XX_GPTIMER10],
3922                     omap_findclk(s, "core_gpt10_clk"),
3923                     omap_findclk(s, "core_l4_iclk"));
3924     s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
3925                     s->irq[0][OMAP_INT_24XX_GPTIMER11],
3926                     omap_findclk(s, "core_gpt11_clk"),
3927                     omap_findclk(s, "core_l4_iclk"));
3928     s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
3929                     s->irq[0][OMAP_INT_24XX_GPTIMER12],
3930                     omap_findclk(s, "core_gpt12_clk"),
3931                     omap_findclk(s, "core_l4_iclk"));
3932
3933     omap_tap_init(omap_l4ta(s->l4, 2), s);
3934
3935     omap_synctimer_init(omap_l4tao(s->l4, 2), s,
3936                     omap_findclk(s, "clk32-kHz"),
3937                     omap_findclk(s, "core_l4_iclk"));
3938
3939     s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
3940                     s->irq[0][OMAP_INT_24XX_I2C1_IRQ],
3941                     &s->drq[OMAP24XX_DMA_I2C1_TX],
3942                     omap_findclk(s, "i2c1.fclk"),
3943                     omap_findclk(s, "i2c1.iclk"));
3944     s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
3945                     s->irq[0][OMAP_INT_24XX_I2C2_IRQ],
3946                     &s->drq[OMAP24XX_DMA_I2C2_TX],
3947                     omap_findclk(s, "i2c2.fclk"),
3948                     omap_findclk(s, "i2c2.iclk"));
3949
3950     gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
3951     gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
3952     gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
3953     gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
3954     s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
3955                     &s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
3956                     gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
3957
3958     s->sdrc = omap_sdrc_init(0x68009000);
3959     s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
3960
3961     sdindex = drive_get_index(IF_SD, 0, 0);
3962     if (sdindex == -1) {
3963         fprintf(stderr, "qemu: missing SecureDigital device\n");
3964         exit(1);
3965     }
3966     s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), drives_table[sdindex].bdrv,
3967                     s->irq[0][OMAP_INT_24XX_MMC_IRQ],
3968                     &s->drq[OMAP24XX_DMA_MMC1_TX],
3969                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
3970
3971     s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
3972                     s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ], 
3973                     &s->drq[OMAP24XX_DMA_SPI1_TX0],
3974                     omap_findclk(s, "spi1_fclk"),
3975                     omap_findclk(s, "spi1_iclk"));
3976     s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
3977                     s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ], 
3978                     &s->drq[OMAP24XX_DMA_SPI2_TX0],
3979                     omap_findclk(s, "spi2_fclk"),
3980                     omap_findclk(s, "spi2_iclk"));
3981
3982     s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800, ds,
3983                     /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
3984                     s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
3985                     omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
3986                     omap_findclk(s, "dss_54m_clk"),
3987                     omap_findclk(s, "dss_l3_iclk"),
3988                     omap_findclk(s, "dss_l4_iclk"));
3989
3990     omap_sti_init(omap_l4ta(s->l4, 18), 0x54000000,
3991                     s->irq[0][OMAP_INT_24XX_STI], omap_findclk(s, "emul_ck"),
3992                     serial_hds[0] && serial_hds[1] && serial_hds[2] ?
3993                     serial_hds[3] : 0);
3994
3995     /* All register mappings (includin those not currenlty implemented):
3996      * SystemControlMod 48000000 - 48000fff
3997      * SystemControlL4  48001000 - 48001fff
3998      * 32kHz Timer Mod  48004000 - 48004fff
3999      * 32kHz Timer L4   48005000 - 48005fff
4000      * PRCM ModA        48008000 - 480087ff
4001      * PRCM ModB        48008800 - 48008fff
4002      * PRCM L4          48009000 - 48009fff
4003      * TEST-BCM Mod     48012000 - 48012fff
4004      * TEST-BCM L4      48013000 - 48013fff
4005      * TEST-TAP Mod     48014000 - 48014fff
4006      * TEST-TAP L4      48015000 - 48015fff
4007      * GPIO1 Mod        48018000 - 48018fff
4008      * GPIO Top         48019000 - 48019fff
4009      * GPIO2 Mod        4801a000 - 4801afff
4010      * GPIO L4          4801b000 - 4801bfff
4011      * GPIO3 Mod        4801c000 - 4801cfff
4012      * GPIO4 Mod        4801e000 - 4801efff
4013      * WDTIMER1 Mod     48020000 - 48010fff
4014      * WDTIMER Top      48021000 - 48011fff
4015      * WDTIMER2 Mod     48022000 - 48012fff
4016      * WDTIMER L4       48023000 - 48013fff
4017      * WDTIMER3 Mod     48024000 - 48014fff
4018      * WDTIMER3 L4      48025000 - 48015fff
4019      * WDTIMER4 Mod     48026000 - 48016fff
4020      * WDTIMER4 L4      48027000 - 48017fff
4021      * GPTIMER1 Mod     48028000 - 48018fff
4022      * GPTIMER1 L4      48029000 - 48019fff
4023      * GPTIMER2 Mod     4802a000 - 4801afff
4024      * GPTIMER2 L4      4802b000 - 4801bfff
4025      * L4-Config AP     48040000 - 480407ff
4026      * L4-Config IP     48040800 - 48040fff
4027      * L4-Config LA     48041000 - 48041fff
4028      * ARM11ETB Mod     48048000 - 48049fff
4029      * ARM11ETB L4      4804a000 - 4804afff
4030      * DISPLAY Top      48050000 - 480503ff
4031      * DISPLAY DISPC    48050400 - 480507ff
4032      * DISPLAY RFBI     48050800 - 48050bff
4033      * DISPLAY VENC     48050c00 - 48050fff
4034      * DISPLAY L4       48051000 - 48051fff
4035      * CAMERA Top       48052000 - 480523ff
4036      * CAMERA core      48052400 - 480527ff
4037      * CAMERA DMA       48052800 - 48052bff
4038      * CAMERA MMU       48052c00 - 48052fff
4039      * CAMERA L4        48053000 - 48053fff
4040      * SDMA Mod         48056000 - 48056fff
4041      * SDMA L4          48057000 - 48057fff
4042      * SSI Top          48058000 - 48058fff
4043      * SSI GDD          48059000 - 48059fff
4044      * SSI Port1        4805a000 - 4805afff
4045      * SSI Port2        4805b000 - 4805bfff
4046      * SSI L4           4805c000 - 4805cfff
4047      * USB Mod          4805e000 - 480fefff
4048      * USB L4           4805f000 - 480fffff
4049      * WIN_TRACER1 Mod  48060000 - 48060fff
4050      * WIN_TRACER1 L4   48061000 - 48061fff
4051      * WIN_TRACER2 Mod  48062000 - 48062fff
4052      * WIN_TRACER2 L4   48063000 - 48063fff
4053      * WIN_TRACER3 Mod  48064000 - 48064fff
4054      * WIN_TRACER3 L4   48065000 - 48065fff
4055      * WIN_TRACER4 Top  48066000 - 480660ff
4056      * WIN_TRACER4 ETT  48066100 - 480661ff
4057      * WIN_TRACER4 WT   48066200 - 480662ff
4058      * WIN_TRACER4 L4   48067000 - 48067fff
4059      * XTI Mod          48068000 - 48068fff
4060      * XTI L4           48069000 - 48069fff
4061      * UART1 Mod        4806a000 - 4806afff
4062      * UART1 L4         4806b000 - 4806bfff
4063      * UART2 Mod        4806c000 - 4806cfff
4064      * UART2 L4         4806d000 - 4806dfff
4065      * UART3 Mod        4806e000 - 4806efff
4066      * UART3 L4         4806f000 - 4806ffff
4067      * I2C1 Mod         48070000 - 48070fff
4068      * I2C1 L4          48071000 - 48071fff
4069      * I2C2 Mod         48072000 - 48072fff
4070      * I2C2 L4          48073000 - 48073fff
4071      * McBSP1 Mod       48074000 - 48074fff
4072      * McBSP1 L4        48075000 - 48075fff
4073      * McBSP2 Mod       48076000 - 48076fff
4074      * McBSP2 L4        48077000 - 48077fff
4075      * GPTIMER3 Mod     48078000 - 48078fff
4076      * GPTIMER3 L4      48079000 - 48079fff
4077      * GPTIMER4 Mod     4807a000 - 4807afff
4078      * GPTIMER4 L4      4807b000 - 4807bfff
4079      * GPTIMER5 Mod     4807c000 - 4807cfff
4080      * GPTIMER5 L4      4807d000 - 4807dfff
4081      * GPTIMER6 Mod     4807e000 - 4807efff
4082      * GPTIMER6 L4      4807f000 - 4807ffff
4083      * GPTIMER7 Mod     48080000 - 48080fff
4084      * GPTIMER7 L4      48081000 - 48081fff
4085      * GPTIMER8 Mod     48082000 - 48082fff
4086      * GPTIMER8 L4      48083000 - 48083fff
4087      * GPTIMER9 Mod     48084000 - 48084fff
4088      * GPTIMER9 L4      48085000 - 48085fff
4089      * GPTIMER10 Mod    48086000 - 48086fff
4090      * GPTIMER10 L4     48087000 - 48087fff
4091      * GPTIMER11 Mod    48088000 - 48088fff
4092      * GPTIMER11 L4     48089000 - 48089fff
4093      * GPTIMER12 Mod    4808a000 - 4808afff
4094      * GPTIMER12 L4     4808b000 - 4808bfff
4095      * EAC Mod          48090000 - 48090fff
4096      * EAC L4           48091000 - 48091fff
4097      * FAC Mod          48092000 - 48092fff
4098      * FAC L4           48093000 - 48093fff
4099      * MAILBOX Mod      48094000 - 48094fff
4100      * MAILBOX L4       48095000 - 48095fff
4101      * SPI1 Mod         48098000 - 48098fff
4102      * SPI1 L4          48099000 - 48099fff
4103      * SPI2 Mod         4809a000 - 4809afff
4104      * SPI2 L4          4809b000 - 4809bfff
4105      * MMC/SDIO Mod     4809c000 - 4809cfff
4106      * MMC/SDIO L4      4809d000 - 4809dfff
4107      * MS_PRO Mod       4809e000 - 4809efff
4108      * MS_PRO L4        4809f000 - 4809ffff
4109      * RNG Mod          480a0000 - 480a0fff
4110      * RNG L4           480a1000 - 480a1fff
4111      * DES3DES Mod      480a2000 - 480a2fff
4112      * DES3DES L4       480a3000 - 480a3fff
4113      * SHA1MD5 Mod      480a4000 - 480a4fff
4114      * SHA1MD5 L4       480a5000 - 480a5fff
4115      * AES Mod          480a6000 - 480a6fff
4116      * AES L4           480a7000 - 480a7fff
4117      * PKA Mod          480a8000 - 480a9fff
4118      * PKA L4           480aa000 - 480aafff
4119      * MG Mod           480b0000 - 480b0fff
4120      * MG L4            480b1000 - 480b1fff
4121      * HDQ/1-wire Mod   480b2000 - 480b2fff
4122      * HDQ/1-wire L4    480b3000 - 480b3fff
4123      * MPU interrupt    480fe000 - 480fefff
4124      * STI channel base 54000000 - 5400ffff
4125      * IVA RAM          5c000000 - 5c01ffff
4126      * IVA ROM          5c020000 - 5c027fff
4127      * IMG_BUF_A        5c040000 - 5c040fff
4128      * IMG_BUF_B        5c042000 - 5c042fff
4129      * VLCDS            5c048000 - 5c0487ff
4130      * IMX_COEF         5c049000 - 5c04afff
4131      * IMX_CMD          5c051000 - 5c051fff
4132      * VLCDQ            5c053000 - 5c0533ff
4133      * VLCDH            5c054000 - 5c054fff
4134      * SEQ_CMD          5c055000 - 5c055fff
4135      * IMX_REG          5c056000 - 5c0560ff
4136      * VLCD_REG         5c056100 - 5c0561ff
4137      * SEQ_REG          5c056200 - 5c0562ff
4138      * IMG_BUF_REG      5c056300 - 5c0563ff
4139      * SEQIRQ_REG       5c056400 - 5c0564ff
4140      * OCP_REG          5c060000 - 5c060fff
4141      * SYSC_REG         5c070000 - 5c070fff
4142      * MMU_REG          5d000000 - 5d000fff
4143      * sDMA R           68000400 - 680005ff
4144      * sDMA W           68000600 - 680007ff
4145      * Display Control  68000800 - 680009ff
4146      * DSP subsystem    68000a00 - 68000bff
4147      * MPU subsystem    68000c00 - 68000dff
4148      * IVA subsystem    68001000 - 680011ff
4149      * USB              68001200 - 680013ff
4150      * Camera           68001400 - 680015ff
4151      * VLYNQ (firewall) 68001800 - 68001bff
4152      * VLYNQ            68001e00 - 68001fff
4153      * SSI              68002000 - 680021ff
4154      * L4               68002400 - 680025ff
4155      * DSP (firewall)   68002800 - 68002bff
4156      * DSP subsystem    68002e00 - 68002fff
4157      * IVA (firewall)   68003000 - 680033ff
4158      * IVA              68003600 - 680037ff
4159      * GFX              68003a00 - 68003bff
4160      * CMDWR emulation  68003c00 - 68003dff
4161      * SMS              68004000 - 680041ff
4162      * OCM              68004200 - 680043ff
4163      * GPMC             68004400 - 680045ff
4164      * RAM (firewall)   68005000 - 680053ff
4165      * RAM (err login)  68005400 - 680057ff
4166      * ROM (firewall)   68005800 - 68005bff
4167      * ROM (err login)  68005c00 - 68005fff
4168      * GPMC (firewall)  68006000 - 680063ff
4169      * GPMC (err login) 68006400 - 680067ff
4170      * SMS (err login)  68006c00 - 68006fff
4171      * SMS registers    68008000 - 68008fff
4172      * SDRC registers   68009000 - 68009fff
4173      * GPMC registers   6800a000   6800afff
4174      */
4175
4176     qemu_register_reset(omap2_mpu_reset, s);
4177
4178     return s;
4179 }
This page took 0.244926 seconds and 4 git commands to generate.