]> Git Repo - qemu.git/blob - hw/omap2.c
Add basic OMAP2 chip support.
[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 = cpu_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, cpu_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 = cpu_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 = cpu_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);
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);
1161     }
1162
1163     ch->tx = 0;
1164     ch->status |= 1 << 2;                               /* EOT */
1165     ch->status |= 1 << 1;                               /* TXS */
1166     if (((ch->config >> 12) & 3) != 2)                  /* TRM */
1167         ch->status |= 1 << 0;                           /* RXS */
1168
1169 intr_update:
1170     if ((ch->status & (1 << 0)) &&                      /* RXS */
1171                     ((ch->config >> 12) & 3) != 2 &&    /* TRM */
1172                     !(ch->config & (1 << 19)))          /* TURBO */
1173         s->irqst |= 1 << (2 + 4 * chnum);               /* RX_FULL */
1174     if ((ch->status & (1 << 1)) &&                      /* TXS */
1175                     ((ch->config >> 12) & 3) != 1)      /* TRM */
1176         s->irqst |= 1 << (0 + 4 * chnum);               /* TX_EMPTY */
1177     omap_mcspi_interrupt_update(s);
1178     omap_mcspi_dmarequest_update(ch);
1179 }
1180
1181 static void omap_mcspi_reset(struct omap_mcspi_s *s)
1182 {
1183     int ch;
1184
1185     s->sysconfig = 0;
1186     s->systest = 0;
1187     s->irqst = 0;
1188     s->irqen = 0;
1189     s->wken = 0;
1190     s->control = 4;
1191
1192     for (ch = 0; ch < 4; ch ++) {
1193         s->ch[ch].config = 0x060000;
1194         s->ch[ch].status = 2;                           /* TXS */
1195         s->ch[ch].control = 0;
1196
1197         omap_mcspi_dmarequest_update(s->ch + ch);
1198     }
1199
1200     omap_mcspi_interrupt_update(s);
1201 }
1202
1203 static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr)
1204 {
1205     struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1206     int offset = addr - s->base;
1207     int ch = 0;
1208     uint32_t ret;
1209
1210     switch (offset) {
1211     case 0x00:  /* MCSPI_REVISION */
1212         return 0x91;
1213
1214     case 0x10:  /* MCSPI_SYSCONFIG */
1215         return s->sysconfig;
1216
1217     case 0x14:  /* MCSPI_SYSSTATUS */
1218         return 1;                                       /* RESETDONE */
1219
1220     case 0x18:  /* MCSPI_IRQSTATUS */
1221         return s->irqst;
1222
1223     case 0x1c:  /* MCSPI_IRQENABLE */
1224         return s->irqen;
1225
1226     case 0x20:  /* MCSPI_WAKEUPENABLE */
1227         return s->wken;
1228
1229     case 0x24:  /* MCSPI_SYST */
1230         return s->systest;
1231
1232     case 0x28:  /* MCSPI_MODULCTRL */
1233         return s->control;
1234
1235     case 0x68: ch ++;
1236     case 0x54: ch ++;
1237     case 0x40: ch ++;
1238     case 0x2c:  /* MCSPI_CHCONF */
1239         return s->ch[ch].config;
1240
1241     case 0x6c: ch ++;
1242     case 0x58: ch ++;
1243     case 0x44: ch ++;
1244     case 0x30:  /* MCSPI_CHSTAT */
1245         return s->ch[ch].status;
1246
1247     case 0x70: ch ++;
1248     case 0x5c: ch ++;
1249     case 0x48: ch ++;
1250     case 0x34:  /* MCSPI_CHCTRL */
1251         return s->ch[ch].control;
1252
1253     case 0x74: ch ++;
1254     case 0x60: ch ++;
1255     case 0x4c: ch ++;
1256     case 0x38:  /* MCSPI_TX */
1257         return s->ch[ch].tx;
1258
1259     case 0x78: ch ++;
1260     case 0x64: ch ++;
1261     case 0x50: ch ++;
1262     case 0x3c:  /* MCSPI_RX */
1263         s->ch[ch].status &= ~(1 << 0);                  /* RXS */
1264         ret = s->ch[ch].rx;
1265         omap_mcspi_transfer_run(s, ch);
1266         return ret;
1267     }
1268
1269     OMAP_BAD_REG(addr);
1270     return 0;
1271 }
1272
1273 static void omap_mcspi_write(void *opaque, target_phys_addr_t addr,
1274                 uint32_t value)
1275 {
1276     struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1277     int offset = addr - s->base;
1278     int ch = 0;
1279
1280     switch (offset) {
1281     case 0x00:  /* MCSPI_REVISION */
1282     case 0x14:  /* MCSPI_SYSSTATUS */
1283     case 0x30:  /* MCSPI_CHSTAT0 */
1284     case 0x3c:  /* MCSPI_RX0 */
1285     case 0x44:  /* MCSPI_CHSTAT1 */
1286     case 0x50:  /* MCSPI_RX1 */
1287     case 0x58:  /* MCSPI_CHSTAT2 */
1288     case 0x64:  /* MCSPI_RX2 */
1289     case 0x6c:  /* MCSPI_CHSTAT3 */
1290     case 0x78:  /* MCSPI_RX3 */
1291         OMAP_RO_REG(addr);
1292         return;
1293
1294     case 0x10:  /* MCSPI_SYSCONFIG */
1295         if (value & (1 << 1))                           /* SOFTRESET */
1296             omap_mcspi_reset(s);
1297         s->sysconfig = value & 0x31d;
1298         break;
1299
1300     case 0x18:  /* MCSPI_IRQSTATUS */
1301         if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) {
1302             s->irqst &= ~value;
1303             omap_mcspi_interrupt_update(s);
1304         }
1305         break;
1306
1307     case 0x1c:  /* MCSPI_IRQENABLE */
1308         s->irqen = value & 0x1777f;
1309         omap_mcspi_interrupt_update(s);
1310         break;
1311
1312     case 0x20:  /* MCSPI_WAKEUPENABLE */
1313         s->wken = value & 1;
1314         break;
1315
1316     case 0x24:  /* MCSPI_SYST */
1317         if (s->control & (1 << 3))                      /* SYSTEM_TEST */
1318             if (value & (1 << 11)) {                    /* SSB */
1319                 s->irqst |= 0x1777f;
1320                 omap_mcspi_interrupt_update(s);
1321             }
1322         s->systest = value & 0xfff;
1323         break;
1324
1325     case 0x28:  /* MCSPI_MODULCTRL */
1326         if (value & (1 << 3))                           /* SYSTEM_TEST */
1327             if (s->systest & (1 << 11)) {               /* SSB */
1328                 s->irqst |= 0x1777f;
1329                 omap_mcspi_interrupt_update(s);
1330             }
1331         s->control = value & 0xf;
1332         break;
1333
1334     case 0x68: ch ++;
1335     case 0x54: ch ++;
1336     case 0x40: ch ++;
1337     case 0x2c:  /* MCSPI_CHCONF */
1338         if ((value ^ s->ch[ch].config) & (3 << 14))     /* DMAR | DMAW */
1339             omap_mcspi_dmarequest_update(s->ch + ch);
1340         if (((value >> 12) & 3) == 3)                   /* TRM */
1341             fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__);
1342         if (((value >> 7) & 0x1f) < 3)                  /* WL */
1343             fprintf(stderr, "%s: invalid WL value (%i)\n",
1344                             __FUNCTION__, (value >> 7) & 0x1f);
1345         s->ch[ch].config = value & 0x7fffff;
1346         break;
1347
1348     case 0x70: ch ++;
1349     case 0x5c: ch ++;
1350     case 0x48: ch ++;
1351     case 0x34:  /* MCSPI_CHCTRL */
1352         if (value & ~s->ch[ch].control & 1) {           /* EN */
1353             s->ch[ch].control |= 1;
1354             omap_mcspi_transfer_run(s, ch);
1355         } else
1356             s->ch[ch].control = value & 1;
1357         break;
1358
1359     case 0x74: ch ++;
1360     case 0x60: ch ++;
1361     case 0x4c: ch ++;
1362     case 0x38:  /* MCSPI_TX */
1363         s->ch[ch].tx = value;
1364         s->ch[ch].status &= ~(1 << 1);                  /* TXS */
1365         omap_mcspi_transfer_run(s, ch);
1366         break;
1367
1368     default:
1369         OMAP_BAD_REG(addr);
1370         return;
1371     }
1372 }
1373
1374 static CPUReadMemoryFunc *omap_mcspi_readfn[] = {
1375     omap_badwidth_read32,
1376     omap_badwidth_read32,
1377     omap_mcspi_read,
1378 };
1379
1380 static CPUWriteMemoryFunc *omap_mcspi_writefn[] = {
1381     omap_badwidth_write32,
1382     omap_badwidth_write32,
1383     omap_mcspi_write,
1384 };
1385
1386 struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
1387                 qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
1388 {
1389     int iomemtype;
1390     struct omap_mcspi_s *s = (struct omap_mcspi_s *)
1391             qemu_mallocz(sizeof(struct omap_mcspi_s));
1392     struct omap_mcspi_ch_s *ch = s->ch;
1393
1394     s->irq = irq;
1395     s->chnum = chnum;
1396     while (chnum --) {
1397         ch->txdrq = *drq ++;
1398         ch->rxdrq = *drq ++;
1399         ch ++;
1400     }
1401     omap_mcspi_reset(s);
1402
1403     iomemtype = cpu_register_io_memory(0, omap_mcspi_readfn,
1404                     omap_mcspi_writefn, s);
1405     s->base = omap_l4_attach(ta, 0, iomemtype);
1406
1407     return s;
1408 }
1409
1410 void omap_mcspi_attach(struct omap_mcspi_s *s,
1411                 uint32_t (*txrx)(void *opaque, uint32_t), void *opaque,
1412                 int chipselect)
1413 {
1414     if (chipselect < 0 || chipselect >= s->chnum)
1415         cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n",
1416                         __FUNCTION__, chipselect);
1417
1418     s->ch[chipselect].txrx = txrx;
1419     s->ch[chipselect].opaque = opaque;
1420 }
1421
1422 /* L4 Interconnect */
1423 struct omap_target_agent_s {
1424     struct omap_l4_s *bus;
1425     int regions;
1426     struct omap_l4_region_s *start;
1427     target_phys_addr_t base;
1428     uint32_t component;
1429     uint32_t control;
1430     uint32_t status;
1431 };
1432
1433 struct omap_l4_s {
1434     target_phys_addr_t base;
1435     int ta_num;
1436     struct omap_target_agent_s ta[0];
1437 };
1438
1439 struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
1440 {
1441     struct omap_l4_s *bus = qemu_mallocz(
1442                     sizeof(*bus) + ta_num * sizeof(*bus->ta));
1443
1444     bus->ta_num = ta_num;
1445     bus->base = base;
1446
1447     return bus;
1448 }
1449
1450 static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr)
1451 {
1452     struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
1453     target_phys_addr_t reg = addr - s->base;
1454
1455     switch (reg) {
1456     case 0x00:  /* COMPONENT */
1457         return s->component;
1458
1459     case 0x20:  /* AGENT_CONTROL */
1460         return s->control;
1461
1462     case 0x28:  /* AGENT_STATUS */
1463         return s->status;
1464     }
1465
1466     OMAP_BAD_REG(addr);
1467     return 0;
1468 }
1469
1470 static void omap_l4ta_write(void *opaque, target_phys_addr_t addr,
1471                 uint32_t value)
1472 {
1473     struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
1474     target_phys_addr_t reg = addr - s->base;
1475
1476     switch (reg) {
1477     case 0x00:  /* COMPONENT */
1478     case 0x28:  /* AGENT_STATUS */
1479         OMAP_RO_REG(addr);
1480         break;
1481
1482     case 0x20:  /* AGENT_CONTROL */
1483         s->control = value & 0x01000700;
1484         if (value & 1)                                  /* OCP_RESET */
1485             s->status &= ~1;                            /* REQ_TIMEOUT */
1486         break;
1487
1488     default:
1489         OMAP_BAD_REG(addr);
1490     }
1491 }
1492
1493 static CPUReadMemoryFunc *omap_l4ta_readfn[] = {
1494     omap_badwidth_read16,
1495     omap_l4ta_read,
1496     omap_badwidth_read16,
1497 };
1498
1499 static CPUWriteMemoryFunc *omap_l4ta_writefn[] = {
1500     omap_badwidth_write32,
1501     omap_badwidth_write32,
1502     omap_l4ta_write,
1503 };
1504
1505 #define L4TA(n)         (n)
1506 #define L4TAO(n)        ((n) + 39)
1507
1508 static struct omap_l4_region_s {
1509     target_phys_addr_t offset;
1510     size_t size;
1511     int access;
1512 } omap_l4_region[125] = {
1513     [  1] = { 0x40800,  0x800, 32          }, /* Initiator agent */
1514     [  2] = { 0x41000, 0x1000, 32          }, /* Link agent */
1515     [  0] = { 0x40000,  0x800, 32          }, /* Address and protection */
1516     [  3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
1517     [  4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
1518     [  5] = { 0x04000, 0x1000, 32 | 16     }, /* 32K Timer */
1519     [  6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
1520     [  7] = { 0x08000,  0x800, 32          }, /* PRCM Region A */
1521     [  8] = { 0x08800,  0x800, 32          }, /* PRCM Region B */
1522     [  9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
1523     [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
1524     [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
1525     [ 12] = { 0x14000, 0x1000, 32          }, /* Test/emulation (TAP) */
1526     [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
1527     [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
1528     [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
1529     [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
1530     [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
1531     [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
1532     [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
1533     [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
1534     [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
1535     [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
1536     [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
1537     [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
1538     [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
1539     [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
1540     [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
1541     [ 28] = { 0x50000,  0x400, 32 | 16 | 8 }, /* Display top */
1542     [ 29] = { 0x50400,  0x400, 32 | 16 | 8 }, /* Display control */
1543     [ 30] = { 0x50800,  0x400, 32 | 16 | 8 }, /* Display RFBI */
1544     [ 31] = { 0x50c00,  0x400, 32 | 16 | 8 }, /* Display encoder */
1545     [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
1546     [ 33] = { 0x52000,  0x400, 32 | 16 | 8 }, /* Camera top */
1547     [ 34] = { 0x52400,  0x400, 32 | 16 | 8 }, /* Camera core */
1548     [ 35] = { 0x52800,  0x400, 32 | 16 | 8 }, /* Camera DMA */
1549     [ 36] = { 0x52c00,  0x400, 32 | 16 | 8 }, /* Camera MMU */
1550     [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
1551     [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
1552     [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
1553     [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
1554     [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
1555     [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
1556     [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
1557     [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
1558     [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
1559     [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
1560     [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
1561     [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
1562     [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
1563     [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
1564     [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
1565     [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
1566     [ 53] = { 0x66000,  0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
1567     [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
1568     [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
1569     [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
1570     [ 57] = { 0x6a000, 0x1000,      16 | 8 }, /* UART1 */
1571     [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
1572     [ 59] = { 0x6c000, 0x1000,      16 | 8 }, /* UART2 */
1573     [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
1574     [ 61] = { 0x6e000, 0x1000,      16 | 8 }, /* UART3 */
1575     [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
1576     [ 63] = { 0x70000, 0x1000,      16     }, /* I2C1 */
1577     [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
1578     [ 65] = { 0x72000, 0x1000,      16     }, /* I2C2 */
1579     [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
1580     [ 67] = { 0x74000, 0x1000,      16     }, /* McBSP1 */
1581     [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
1582     [ 69] = { 0x76000, 0x1000,      16     }, /* McBSP2 */
1583     [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
1584     [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
1585     [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
1586     [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
1587     [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
1588     [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
1589     [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
1590     [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
1591     [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
1592     [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
1593     [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
1594     [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
1595     [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
1596     [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
1597     [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
1598     [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
1599     [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
1600     [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
1601     [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
1602     [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
1603     [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
1604     [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
1605     [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
1606     [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
1607     [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
1608     [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
1609     [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
1610     [ 97] = { 0x90000, 0x1000,      16     }, /* EAC */
1611     [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
1612     [ 99] = { 0x92000, 0x1000,      16     }, /* FAC */
1613     [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
1614     [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
1615     [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
1616     [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
1617     [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
1618     [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
1619     [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
1620     [107] = { 0x9c000, 0x1000,      16 | 8 }, /* MMC SDIO */
1621     [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
1622     [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
1623     [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
1624     [111] = { 0xa0000, 0x1000, 32          }, /* RNG */
1625     [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
1626     [113] = { 0xa2000, 0x1000, 32          }, /* DES3DES */
1627     [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
1628     [115] = { 0xa4000, 0x1000, 32          }, /* SHA1MD5 */
1629     [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
1630     [117] = { 0xa6000, 0x1000, 32          }, /* AES */
1631     [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
1632     [119] = { 0xa8000, 0x2000, 32          }, /* PKA */
1633     [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
1634     [121] = { 0xb0000, 0x1000, 32          }, /* MG */
1635     [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
1636     [123] = { 0xb2000, 0x1000, 32          }, /* HDQ/1-Wire */
1637     [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
1638 };
1639
1640 static struct omap_l4_agent_info_s {
1641     int ta;
1642     int region;
1643     int regions;
1644     int ta_region;
1645 } omap_l4_agent_info[54] = {
1646     { 0,           0, 3, 2 }, /* L4IA initiatior agent */
1647     { L4TAO(1),    3, 2, 1 }, /* Control and pinout module */
1648     { L4TAO(2),    5, 2, 1 }, /* 32K timer */
1649     { L4TAO(3),    7, 3, 2 }, /* PRCM */
1650     { L4TA(1),    10, 2, 1 }, /* BCM */
1651     { L4TA(2),    12, 2, 1 }, /* Test JTAG */
1652     { L4TA(3),    14, 6, 3 }, /* Quad GPIO */
1653     { L4TA(4),    20, 4, 3 }, /* WD timer 1/2 */
1654     { L4TA(7),    24, 2, 1 }, /* GP timer 1 */
1655     { L4TA(9),    26, 2, 1 }, /* ATM11 ETB */
1656     { L4TA(10),   28, 5, 4 }, /* Display subsystem */
1657     { L4TA(11),   33, 5, 4 }, /* Camera subsystem */
1658     { L4TA(12),   38, 2, 1 }, /* sDMA */
1659     { L4TA(13),   40, 5, 4 }, /* SSI */
1660     { L4TAO(4),   45, 2, 1 }, /* USB */
1661     { L4TA(14),   47, 2, 1 }, /* Win Tracer1 */
1662     { L4TA(15),   49, 2, 1 }, /* Win Tracer2 */
1663     { L4TA(16),   51, 2, 1 }, /* Win Tracer3 */
1664     { L4TA(17),   53, 2, 1 }, /* Win Tracer4 */
1665     { L4TA(18),   55, 2, 1 }, /* XTI */
1666     { L4TA(19),   57, 2, 1 }, /* UART1 */
1667     { L4TA(20),   59, 2, 1 }, /* UART2 */
1668     { L4TA(21),   61, 2, 1 }, /* UART3 */
1669     { L4TAO(5),   63, 2, 1 }, /* I2C1 */
1670     { L4TAO(6),   65, 2, 1 }, /* I2C2 */
1671     { L4TAO(7),   67, 2, 1 }, /* McBSP1 */
1672     { L4TAO(8),   69, 2, 1 }, /* McBSP2 */
1673     { L4TA(5),    71, 2, 1 }, /* WD Timer 3 (DSP) */
1674     { L4TA(6),    73, 2, 1 }, /* WD Timer 4 (IVA) */
1675     { L4TA(8),    75, 2, 1 }, /* GP Timer 2 */
1676     { L4TA(22),   77, 2, 1 }, /* GP Timer 3 */
1677     { L4TA(23),   79, 2, 1 }, /* GP Timer 4 */
1678     { L4TA(24),   81, 2, 1 }, /* GP Timer 5 */
1679     { L4TA(25),   83, 2, 1 }, /* GP Timer 6 */
1680     { L4TA(26),   85, 2, 1 }, /* GP Timer 7 */
1681     { L4TA(27),   87, 2, 1 }, /* GP Timer 8 */
1682     { L4TA(28),   89, 2, 1 }, /* GP Timer 9 */
1683     { L4TA(29),   91, 2, 1 }, /* GP Timer 10 */
1684     { L4TA(30),   93, 2, 1 }, /* GP Timer 11 */
1685     { L4TA(31),   95, 2, 1 }, /* GP Timer 12 */
1686     { L4TA(32),   97, 2, 1 }, /* EAC */
1687     { L4TA(33),   99, 2, 1 }, /* FAC */
1688     { L4TA(34),  101, 2, 1 }, /* IPC */
1689     { L4TA(35),  103, 2, 1 }, /* SPI1 */
1690     { L4TA(36),  105, 2, 1 }, /* SPI2 */
1691     { L4TAO(9),  107, 2, 1 }, /* MMC SDIO */
1692     { L4TAO(10), 109, 2, 1 },
1693     { L4TAO(11), 111, 2, 1 }, /* RNG */
1694     { L4TAO(12), 113, 2, 1 }, /* DES3DES */
1695     { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
1696     { L4TA(37),  117, 2, 1 }, /* AES */
1697     { L4TA(38),  119, 2, 1 }, /* PKA */
1698     { -1,        121, 2, 1 },
1699     { L4TA(39),  123, 2, 1 }, /* HDQ/1-Wire */
1700 };
1701
1702 #define omap_l4ta(bus, cs)      omap_l4ta_get(bus, L4TA(cs))
1703 #define omap_l4tao(bus, cs)     omap_l4ta_get(bus, L4TAO(cs))
1704
1705 struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs)
1706 {
1707     int i, iomemtype;
1708     struct omap_target_agent_s *ta = 0;
1709     struct omap_l4_agent_info_s *info = 0;
1710
1711     for (i = 0; i < bus->ta_num; i ++)
1712         if (omap_l4_agent_info[i].ta == cs) {
1713             ta = &bus->ta[i];
1714             info = &omap_l4_agent_info[i];
1715             break;
1716         }
1717     if (!ta) {
1718         fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
1719         exit(-1);
1720     }
1721
1722     ta->bus = bus;
1723     ta->start = &omap_l4_region[info->region];
1724     ta->regions = info->regions;
1725     ta->base = bus->base + ta->start[info->ta_region].offset;
1726
1727     ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1728     ta->status = 0x00000000;
1729     ta->control = 0x00000200;   /* XXX 01000200 for L4TAO */
1730
1731     iomemtype = cpu_register_io_memory(0, omap_l4ta_readfn,
1732                     omap_l4ta_writefn, ta);
1733     cpu_register_physical_memory(ta->base, 0x200, iomemtype);
1734
1735     return ta;
1736 }
1737
1738 target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
1739                 int iotype)
1740 {
1741     target_phys_addr_t base;
1742     size_t size;
1743
1744     if (region < 0 || region >= ta->regions) {
1745         fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);
1746         exit(-1);
1747     }
1748
1749     base = ta->bus->base + ta->start[region].offset;
1750     size = ta->start[region].size;
1751     if (iotype)
1752         cpu_register_physical_memory(base, size, iotype);
1753
1754     return base;
1755 }
1756
1757 /* TEST-Chip-level TAP */
1758 static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr)
1759 {
1760     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1761     target_phys_addr_t reg = addr - s->tap_base;
1762
1763     switch (reg) {
1764     case 0x204: /* IDCODE_reg */
1765         switch (s->mpu_model) {
1766         case omap2420:
1767         case omap2422:
1768         case omap2423:
1769             return 0x5b5d902f;  /* ES 2.2 */
1770         case omap2430:
1771             return 0x5b68a02f;  /* ES 2.2 */
1772         case omap3430:
1773             return 0x1b7ae02f;  /* ES 2 */
1774         default:
1775             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
1776         }
1777
1778     case 0x208: /* PRODUCTION_ID_reg for OMAP2 */
1779     case 0x210: /* PRODUCTION_ID_reg for OMAP3 */
1780         switch (s->mpu_model) {
1781         case omap2420:
1782             return 0x000254f0;  /* POP ESHS2.1.1 in N91/93/95, ES2 in N800 */
1783         case omap2422:
1784             return 0x000400f0;
1785         case omap2423:
1786             return 0x000800f0;
1787         case omap2430:
1788             return 0x000000f0;
1789         case omap3430:
1790             return 0x000000f0;
1791         default:
1792             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
1793         }
1794
1795     case 0x20c:
1796         switch (s->mpu_model) {
1797         case omap2420:
1798         case omap2422:
1799         case omap2423:
1800             return 0xcafeb5d9;  /* ES 2.2 */
1801         case omap2430:
1802             return 0xcafeb68a;  /* ES 2.2 */
1803         case omap3430:
1804             return 0xcafeb7ae;  /* ES 2 */
1805         default:
1806             cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
1807         }
1808
1809     case 0x218: /* DIE_ID_reg */
1810         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1811     case 0x21c: /* DIE_ID_reg */
1812         return 0x54 << 24;
1813     case 0x220: /* DIE_ID_reg */
1814         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1815     case 0x224: /* DIE_ID_reg */
1816         return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
1817     }
1818
1819     OMAP_BAD_REG(addr);
1820     return 0;
1821 }
1822
1823 static void omap_tap_write(void *opaque, target_phys_addr_t addr,
1824                 uint32_t value)
1825 {
1826     OMAP_BAD_REG(addr);
1827 }
1828
1829 static CPUReadMemoryFunc *omap_tap_readfn[] = {
1830     omap_badwidth_read32,
1831     omap_badwidth_read32,
1832     omap_tap_read,
1833 };
1834
1835 static CPUWriteMemoryFunc *omap_tap_writefn[] = {
1836     omap_badwidth_write32,
1837     omap_badwidth_write32,
1838     omap_tap_write,
1839 };
1840
1841 void omap_tap_init(struct omap_target_agent_s *ta,
1842                 struct omap_mpu_state_s *mpu)
1843 {
1844     mpu->tap_base = omap_l4_attach(ta, 0, cpu_register_io_memory(0,
1845                             omap_tap_readfn, omap_tap_writefn, mpu));
1846 }
1847
1848 /* Power, Reset, and Clock Management */
1849 struct omap_prcm_s {
1850     target_phys_addr_t base;
1851     qemu_irq irq[3];
1852     struct omap_mpu_state_s *mpu;
1853
1854     uint32_t irqst[3];
1855     uint32_t irqen[3];
1856
1857     uint32_t sysconfig;
1858     uint32_t voltctrl;
1859     uint32_t scratch[20];
1860
1861     uint32_t clksrc[1];
1862     uint32_t clkout[1];
1863     uint32_t clkemul[1];
1864     uint32_t clkpol[1];
1865     uint32_t clksel[8];
1866     uint32_t clken[12];
1867     uint32_t clkctrl[4];
1868     uint32_t clkidle[7];
1869     uint32_t setuptime[2];
1870
1871     uint32_t wkup[3];
1872     uint32_t wken[3];
1873     uint32_t wkst[3];
1874     uint32_t rst[4];
1875     uint32_t rstctrl[1];
1876     uint32_t power[4];
1877     uint32_t rsttime_wkup;
1878
1879     uint32_t ev;
1880     uint32_t evtime[2];
1881 };
1882
1883 static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
1884 {
1885     qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
1886     /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
1887 }
1888
1889 static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr)
1890 {
1891     struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
1892     int offset = addr - s->base;
1893
1894     switch (offset) {
1895     case 0x000: /* PRCM_REVISION */
1896         return 0x10;
1897
1898     case 0x010: /* PRCM_SYSCONFIG */
1899         return s->sysconfig;
1900
1901     case 0x018: /* PRCM_IRQSTATUS_MPU */
1902         return s->irqst[0];
1903
1904     case 0x01c: /* PRCM_IRQENABLE_MPU */
1905         return s->irqen[0];
1906
1907     case 0x050: /* PRCM_VOLTCTRL */
1908         return s->voltctrl;
1909     case 0x054: /* PRCM_VOLTST */
1910         return s->voltctrl & 3;
1911
1912     case 0x060: /* PRCM_CLKSRC_CTRL */
1913         return s->clksrc[0];
1914     case 0x070: /* PRCM_CLKOUT_CTRL */
1915         return s->clkout[0];
1916     case 0x078: /* PRCM_CLKEMUL_CTRL */
1917         return s->clkemul[0];
1918     case 0x080: /* PRCM_CLKCFG_CTRL */
1919     case 0x084: /* PRCM_CLKCFG_STATUS */
1920         return 0;
1921
1922     case 0x090: /* PRCM_VOLTSETUP */
1923         return s->setuptime[0];
1924
1925     case 0x094: /* PRCM_CLKSSETUP */
1926         return s->setuptime[1];
1927
1928     case 0x098: /* PRCM_POLCTRL */
1929         return s->clkpol[0];
1930
1931     case 0x0b0: /* GENERAL_PURPOSE1 */
1932     case 0x0b4: /* GENERAL_PURPOSE2 */
1933     case 0x0b8: /* GENERAL_PURPOSE3 */
1934     case 0x0bc: /* GENERAL_PURPOSE4 */
1935     case 0x0c0: /* GENERAL_PURPOSE5 */
1936     case 0x0c4: /* GENERAL_PURPOSE6 */
1937     case 0x0c8: /* GENERAL_PURPOSE7 */
1938     case 0x0cc: /* GENERAL_PURPOSE8 */
1939     case 0x0d0: /* GENERAL_PURPOSE9 */
1940     case 0x0d4: /* GENERAL_PURPOSE10 */
1941     case 0x0d8: /* GENERAL_PURPOSE11 */
1942     case 0x0dc: /* GENERAL_PURPOSE12 */
1943     case 0x0e0: /* GENERAL_PURPOSE13 */
1944     case 0x0e4: /* GENERAL_PURPOSE14 */
1945     case 0x0e8: /* GENERAL_PURPOSE15 */
1946     case 0x0ec: /* GENERAL_PURPOSE16 */
1947     case 0x0f0: /* GENERAL_PURPOSE17 */
1948     case 0x0f4: /* GENERAL_PURPOSE18 */
1949     case 0x0f8: /* GENERAL_PURPOSE19 */
1950     case 0x0fc: /* GENERAL_PURPOSE20 */
1951         return s->scratch[(offset - 0xb0) >> 2];
1952
1953     case 0x140: /* CM_CLKSEL_MPU */
1954         return s->clksel[0];
1955     case 0x148: /* CM_CLKSTCTRL_MPU */
1956         return s->clkctrl[0];
1957
1958     case 0x158: /* RM_RSTST_MPU */
1959         return s->rst[0];
1960     case 0x1c8: /* PM_WKDEP_MPU */
1961         return s->wkup[0];
1962     case 0x1d4: /* PM_EVGENCTRL_MPU */
1963         return s->ev;
1964     case 0x1d8: /* PM_EVEGENONTIM_MPU */
1965         return s->evtime[0];
1966     case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
1967         return s->evtime[1];
1968     case 0x1e0: /* PM_PWSTCTRL_MPU */
1969         return s->power[0];
1970     case 0x1e4: /* PM_PWSTST_MPU */
1971         return 0;
1972
1973     case 0x200: /* CM_FCLKEN1_CORE */
1974         return s->clken[0];
1975     case 0x204: /* CM_FCLKEN2_CORE */
1976         return s->clken[1];
1977     case 0x210: /* CM_ICLKEN1_CORE */
1978         return s->clken[2];
1979     case 0x214: /* CM_ICLKEN2_CORE */
1980         return s->clken[3];
1981     case 0x21c: /* CM_ICLKEN4_CORE */
1982         return s->clken[4];
1983
1984     case 0x220: /* CM_IDLEST1_CORE */
1985         /* TODO: check the actual iclk status */
1986         return 0x7ffffff9;
1987     case 0x224: /* CM_IDLEST2_CORE */
1988         /* TODO: check the actual iclk status */
1989         return 0x00000007;
1990     case 0x22c: /* CM_IDLEST4_CORE */
1991         /* TODO: check the actual iclk status */
1992         return 0x0000001f;
1993
1994     case 0x230: /* CM_AUTOIDLE1_CORE */
1995         return s->clkidle[0];
1996     case 0x234: /* CM_AUTOIDLE2_CORE */
1997         return s->clkidle[1];
1998     case 0x238: /* CM_AUTOIDLE3_CORE */
1999         return s->clkidle[2];
2000     case 0x23c: /* CM_AUTOIDLE4_CORE */
2001         return s->clkidle[3];
2002
2003     case 0x240: /* CM_CLKSEL1_CORE */
2004         return s->clksel[1];
2005     case 0x244: /* CM_CLKSEL2_CORE */
2006         return s->clksel[2];
2007
2008     case 0x248: /* CM_CLKSTCTRL_CORE */
2009         return s->clkctrl[1];
2010
2011     case 0x2a0: /* PM_WKEN1_CORE */
2012         return s->wken[0];
2013     case 0x2a4: /* PM_WKEN2_CORE */
2014         return s->wken[1];
2015
2016     case 0x2b0: /* PM_WKST1_CORE */
2017         return s->wkst[0];
2018     case 0x2b4: /* PM_WKST2_CORE */
2019         return s->wkst[1];
2020     case 0x2c8: /* PM_WKDEP_CORE */
2021         return 0x1e;
2022
2023     case 0x2e0: /* PM_PWSTCTRL_CORE */
2024         return s->power[1];
2025     case 0x2e4: /* PM_PWSTST_CORE */
2026         return 0x000030 | (s->power[1] & 0xfc00);
2027
2028     case 0x300: /* CM_FCLKEN_GFX */
2029         return s->clken[5];
2030     case 0x310: /* CM_ICLKEN_GFX */
2031         return s->clken[6];
2032     case 0x320: /* CM_IDLEST_GFX */
2033         /* TODO: check the actual iclk status */
2034         return 0x00000001;
2035     case 0x340: /* CM_CLKSEL_GFX */
2036         return s->clksel[3];
2037     case 0x348: /* CM_CLKSTCTRL_GFX */
2038         return s->clkctrl[2];
2039     case 0x350: /* RM_RSTCTRL_GFX */
2040         return s->rstctrl[0];
2041     case 0x358: /* RM_RSTST_GFX */
2042         return s->rst[1];
2043     case 0x3c8: /* PM_WKDEP_GFX */
2044         return s->wkup[1];
2045
2046     case 0x3e0: /* PM_PWSTCTRL_GFX */
2047         return s->power[2];
2048     case 0x3e4: /* PM_PWSTST_GFX */
2049         return s->power[2] & 3;
2050
2051     case 0x400: /* CM_FCLKEN_WKUP */
2052         return s->clken[7];
2053     case 0x410: /* CM_ICLKEN_WKUP */
2054         return s->clken[8];
2055     case 0x420: /* CM_IDLEST_WKUP */
2056         /* TODO: check the actual iclk status */
2057         return 0x0000003f;
2058     case 0x430: /* CM_AUTOIDLE_WKUP */
2059         return s->clkidle[4];
2060     case 0x440: /* CM_CLKSEL_WKUP */
2061         return s->clksel[4];
2062     case 0x450: /* RM_RSTCTRL_WKUP */
2063         return 0;
2064     case 0x454: /* RM_RSTTIME_WKUP */
2065         return s->rsttime_wkup;
2066     case 0x458: /* RM_RSTST_WKUP */
2067         return s->rst[2];
2068     case 0x4a0: /* PM_WKEN_WKUP */
2069         return s->wken[2];
2070     case 0x4b0: /* PM_WKST_WKUP */
2071         return s->wkst[2];
2072
2073     case 0x500: /* CM_CLKEN_PLL */
2074         return s->clken[9];
2075     case 0x520: /* CM_IDLEST_CKGEN */
2076         /* Core uses 32-kHz clock */
2077         if (!(s->clksel[6] & 3))
2078             return 0x00000377;
2079         /* DPLL not in lock mode, core uses ref_clk */
2080         if ((s->clken[9] & 3) != 3)
2081             return 0x00000375;
2082         /* Core uses DPLL */
2083         return 0x00000376;
2084     case 0x530: /* CM_AUTOIDLE_PLL */
2085         return s->clkidle[5];
2086     case 0x540: /* CM_CLKSEL1_PLL */
2087         return s->clksel[5];
2088     case 0x544: /* CM_CLKSEL2_PLL */
2089         return s->clksel[6];
2090
2091     case 0x800: /* CM_FCLKEN_DSP */
2092         return s->clken[10];
2093     case 0x810: /* CM_ICLKEN_DSP */
2094         return s->clken[11];
2095     case 0x820: /* CM_IDLEST_DSP */
2096         /* TODO: check the actual iclk status */
2097         return 0x00000103;
2098     case 0x830: /* CM_AUTOIDLE_DSP */
2099         return s->clkidle[6];
2100     case 0x840: /* CM_CLKSEL_DSP */
2101         return s->clksel[7];
2102     case 0x848: /* CM_CLKSTCTRL_DSP */
2103         return s->clkctrl[3];
2104     case 0x850: /* RM_RSTCTRL_DSP */
2105         return 0;
2106     case 0x858: /* RM_RSTST_DSP */
2107         return s->rst[3];
2108     case 0x8c8: /* PM_WKDEP_DSP */
2109         return s->wkup[2];
2110     case 0x8e0: /* PM_PWSTCTRL_DSP */
2111         return s->power[3];
2112     case 0x8e4: /* PM_PWSTST_DSP */
2113         return 0x008030 | (s->power[3] & 0x3003);
2114
2115     case 0x8f0: /* PRCM_IRQSTATUS_DSP */
2116         return s->irqst[1];
2117     case 0x8f4: /* PRCM_IRQENABLE_DSP */
2118         return s->irqen[1];
2119
2120     case 0x8f8: /* PRCM_IRQSTATUS_IVA */
2121         return s->irqst[2];
2122     case 0x8fc: /* PRCM_IRQENABLE_IVA */
2123         return s->irqen[2];
2124     }
2125
2126     OMAP_BAD_REG(addr);
2127     return 0;
2128 }
2129
2130 static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
2131                 uint32_t value)
2132 {
2133     struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
2134     int offset = addr - s->base;
2135
2136     switch (offset) {
2137     case 0x000: /* PRCM_REVISION */
2138     case 0x054: /* PRCM_VOLTST */
2139     case 0x084: /* PRCM_CLKCFG_STATUS */
2140     case 0x1e4: /* PM_PWSTST_MPU */
2141     case 0x220: /* CM_IDLEST1_CORE */
2142     case 0x224: /* CM_IDLEST2_CORE */
2143     case 0x22c: /* CM_IDLEST4_CORE */
2144     case 0x2c8: /* PM_WKDEP_CORE */
2145     case 0x2e4: /* PM_PWSTST_CORE */
2146     case 0x320: /* CM_IDLEST_GFX */
2147     case 0x3e4: /* PM_PWSTST_GFX */
2148     case 0x420: /* CM_IDLEST_WKUP */
2149     case 0x520: /* CM_IDLEST_CKGEN */
2150     case 0x820: /* CM_IDLEST_DSP */
2151     case 0x8e4: /* PM_PWSTST_DSP */
2152         OMAP_RO_REG(addr);
2153         return;
2154
2155     case 0x010: /* PRCM_SYSCONFIG */
2156         s->sysconfig = value & 1;
2157         break;
2158
2159     case 0x018: /* PRCM_IRQSTATUS_MPU */
2160         s->irqst[0] &= ~value;
2161         omap_prcm_int_update(s, 0);
2162         break;
2163     case 0x01c: /* PRCM_IRQENABLE_MPU */
2164         s->irqen[0] = value & 0x3f;
2165         omap_prcm_int_update(s, 0);
2166         break;
2167
2168     case 0x050: /* PRCM_VOLTCTRL */
2169         s->voltctrl = value & 0xf1c3;
2170         break;
2171
2172     case 0x060: /* PRCM_CLKSRC_CTRL */
2173         s->clksrc[0] = value & 0xdb;
2174         /* TODO update clocks */
2175         break;
2176
2177     case 0x070: /* PRCM_CLKOUT_CTRL */
2178         s->clkout[0] = value & 0xbbbb;
2179         /* TODO update clocks */
2180         break;
2181
2182     case 0x078: /* PRCM_CLKEMUL_CTRL */
2183         s->clkemul[0] = value & 1;
2184         /* TODO update clocks */
2185         break;
2186
2187     case 0x080: /* PRCM_CLKCFG_CTRL */
2188         break;
2189
2190     case 0x090: /* PRCM_VOLTSETUP */
2191         s->setuptime[0] = value & 0xffff;
2192         break;
2193     case 0x094: /* PRCM_CLKSSETUP */
2194         s->setuptime[1] = value & 0xffff;
2195         break;
2196
2197     case 0x098: /* PRCM_POLCTRL */
2198         s->clkpol[0] = value & 0x701;
2199         break;
2200
2201     case 0x0b0: /* GENERAL_PURPOSE1 */
2202     case 0x0b4: /* GENERAL_PURPOSE2 */
2203     case 0x0b8: /* GENERAL_PURPOSE3 */
2204     case 0x0bc: /* GENERAL_PURPOSE4 */
2205     case 0x0c0: /* GENERAL_PURPOSE5 */
2206     case 0x0c4: /* GENERAL_PURPOSE6 */
2207     case 0x0c8: /* GENERAL_PURPOSE7 */
2208     case 0x0cc: /* GENERAL_PURPOSE8 */
2209     case 0x0d0: /* GENERAL_PURPOSE9 */
2210     case 0x0d4: /* GENERAL_PURPOSE10 */
2211     case 0x0d8: /* GENERAL_PURPOSE11 */
2212     case 0x0dc: /* GENERAL_PURPOSE12 */
2213     case 0x0e0: /* GENERAL_PURPOSE13 */
2214     case 0x0e4: /* GENERAL_PURPOSE14 */
2215     case 0x0e8: /* GENERAL_PURPOSE15 */
2216     case 0x0ec: /* GENERAL_PURPOSE16 */
2217     case 0x0f0: /* GENERAL_PURPOSE17 */
2218     case 0x0f4: /* GENERAL_PURPOSE18 */
2219     case 0x0f8: /* GENERAL_PURPOSE19 */
2220     case 0x0fc: /* GENERAL_PURPOSE20 */
2221         s->scratch[(offset - 0xb0) >> 2] = value;
2222         break;
2223
2224     case 0x140: /* CM_CLKSEL_MPU */
2225         s->clksel[0] = value & 0x1f;
2226         /* TODO update clocks */
2227         break;
2228     case 0x148: /* CM_CLKSTCTRL_MPU */
2229         s->clkctrl[0] = value & 0x1f;
2230         break;
2231
2232     case 0x158: /* RM_RSTST_MPU */
2233         s->rst[0] &= ~value;
2234         break;
2235     case 0x1c8: /* PM_WKDEP_MPU */
2236         s->wkup[0] = value & 0x15;
2237         break;
2238
2239     case 0x1d4: /* PM_EVGENCTRL_MPU */
2240         s->ev = value & 0x1f;
2241         break;
2242     case 0x1d8: /* PM_EVEGENONTIM_MPU */
2243         s->evtime[0] = value;
2244         break;
2245     case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
2246         s->evtime[1] = value;
2247         break;
2248
2249     case 0x1e0: /* PM_PWSTCTRL_MPU */
2250         s->power[0] = value & 0xc0f;
2251         break;
2252
2253     case 0x200: /* CM_FCLKEN1_CORE */
2254         s->clken[0] = value & 0xbfffffff;
2255         /* TODO update clocks */
2256         break;
2257     case 0x204: /* CM_FCLKEN2_CORE */
2258         s->clken[1] = value & 0x00000007;
2259         /* TODO update clocks */
2260         break;
2261     case 0x210: /* CM_ICLKEN1_CORE */
2262         s->clken[2] = value & 0xfffffff9;
2263         /* TODO update clocks */
2264         break;
2265     case 0x214: /* CM_ICLKEN2_CORE */
2266         s->clken[3] = value & 0x00000007;
2267         /* TODO update clocks */
2268         break;
2269     case 0x21c: /* CM_ICLKEN4_CORE */
2270         s->clken[4] = value & 0x0000001f;
2271         /* TODO update clocks */
2272         break;
2273
2274     case 0x230: /* CM_AUTOIDLE1_CORE */
2275         s->clkidle[0] = value & 0xfffffff9;
2276         /* TODO update clocks */
2277         break;
2278     case 0x234: /* CM_AUTOIDLE2_CORE */
2279         s->clkidle[1] = value & 0x00000007;
2280         /* TODO update clocks */
2281         break;
2282     case 0x238: /* CM_AUTOIDLE3_CORE */
2283         s->clkidle[2] = value & 0x00000007;
2284         /* TODO update clocks */
2285         break;
2286     case 0x23c: /* CM_AUTOIDLE4_CORE */
2287         s->clkidle[3] = value & 0x0000001f;
2288         /* TODO update clocks */
2289         break;
2290
2291     case 0x240: /* CM_CLKSEL1_CORE */
2292         s->clksel[1] = value & 0x0fffbf7f;
2293         /* TODO update clocks */
2294         break;
2295
2296     case 0x244: /* CM_CLKSEL2_CORE */
2297         s->clksel[2] = value & 0x00fffffc;
2298         /* TODO update clocks */
2299         break;
2300
2301     case 0x248: /* CM_CLKSTCTRL_CORE */
2302         s->clkctrl[1] = value & 0x7;
2303         break;
2304
2305     case 0x2a0: /* PM_WKEN1_CORE */
2306         s->wken[0] = value & 0x04667ff8;
2307         break;
2308     case 0x2a4: /* PM_WKEN2_CORE */
2309         s->wken[1] = value & 0x00000005;
2310         break;
2311
2312     case 0x2b0: /* PM_WKST1_CORE */
2313         s->wkst[0] &= ~value;
2314         break;
2315     case 0x2b4: /* PM_WKST2_CORE */
2316         s->wkst[1] &= ~value;
2317         break;
2318
2319     case 0x2e0: /* PM_PWSTCTRL_CORE */
2320         s->power[1] = (value & 0x00fc3f) | (1 << 2);
2321         break;
2322
2323     case 0x300: /* CM_FCLKEN_GFX */
2324         s->clken[5] = value & 6;
2325         /* TODO update clocks */
2326         break;
2327     case 0x310: /* CM_ICLKEN_GFX */
2328         s->clken[6] = value & 1;
2329         /* TODO update clocks */
2330         break;
2331     case 0x340: /* CM_CLKSEL_GFX */
2332         s->clksel[3] = value & 7;
2333         /* TODO update clocks */
2334         break;
2335     case 0x348: /* CM_CLKSTCTRL_GFX */
2336         s->clkctrl[2] = value & 1;
2337         break;
2338     case 0x350: /* RM_RSTCTRL_GFX */
2339         s->rstctrl[0] = value & 1;
2340         /* TODO: reset */
2341         break;
2342     case 0x358: /* RM_RSTST_GFX */
2343         s->rst[1] &= ~value;
2344         break;
2345     case 0x3c8: /* PM_WKDEP_GFX */
2346         s->wkup[1] = value & 0x13;
2347         break;
2348     case 0x3e0: /* PM_PWSTCTRL_GFX */
2349         s->power[2] = (value & 0x00c0f) | (3 << 2);
2350         break;
2351
2352     case 0x400: /* CM_FCLKEN_WKUP */
2353         s->clken[7] = value & 0xd;
2354         /* TODO update clocks */
2355         break;
2356     case 0x410: /* CM_ICLKEN_WKUP */
2357         s->clken[8] = value & 0x3f;
2358         /* TODO update clocks */
2359         break;
2360     case 0x430: /* CM_AUTOIDLE_WKUP */
2361         s->clkidle[4] = value & 0x0000003f;
2362         /* TODO update clocks */
2363         break;
2364     case 0x440: /* CM_CLKSEL_WKUP */
2365         s->clksel[4] = value & 3;
2366         /* TODO update clocks */
2367         break;
2368     case 0x450: /* RM_RSTCTRL_WKUP */
2369         /* TODO: reset */
2370         if (value & 2)
2371             qemu_system_reset_request();
2372         break;
2373     case 0x454: /* RM_RSTTIME_WKUP */
2374         s->rsttime_wkup = value & 0x1fff;
2375         break;
2376     case 0x458: /* RM_RSTST_WKUP */
2377         s->rst[2] &= ~value;
2378         break;
2379     case 0x4a0: /* PM_WKEN_WKUP */
2380         s->wken[2] = value & 0x00000005;
2381         break;
2382     case 0x4b0: /* PM_WKST_WKUP */
2383         s->wkst[2] &= ~value;
2384         break;
2385
2386     case 0x500: /* CM_CLKEN_PLL */
2387         s->clken[9] = value & 0xcf;
2388         /* TODO update clocks */
2389         break;
2390     case 0x530: /* CM_AUTOIDLE_PLL */
2391         s->clkidle[5] = value & 0x000000cf;
2392         /* TODO update clocks */
2393         break;
2394     case 0x540: /* CM_CLKSEL1_PLL */
2395         s->clksel[5] = value & 0x03bfff28;
2396         /* TODO update clocks */
2397         break;
2398     case 0x544: /* CM_CLKSEL2_PLL */
2399         s->clksel[6] = value & 3;
2400         /* TODO update clocks */
2401         break;
2402
2403     case 0x800: /* CM_FCLKEN_DSP */
2404         s->clken[10] = value & 0x501;
2405         /* TODO update clocks */
2406         break;
2407     case 0x810: /* CM_ICLKEN_DSP */
2408         s->clken[11] = value & 0x2;
2409         /* TODO update clocks */
2410         break;
2411     case 0x830: /* CM_AUTOIDLE_DSP */
2412         s->clkidle[6] = value & 0x2;
2413         /* TODO update clocks */
2414         break;
2415     case 0x840: /* CM_CLKSEL_DSP */
2416         s->clksel[7] = value & 0x3fff;
2417         /* TODO update clocks */
2418         break;
2419     case 0x848: /* CM_CLKSTCTRL_DSP */
2420         s->clkctrl[3] = value & 0x101;
2421         break;
2422     case 0x850: /* RM_RSTCTRL_DSP */
2423         /* TODO: reset */
2424         break;
2425     case 0x858: /* RM_RSTST_DSP */
2426         s->rst[3] &= ~value;
2427         break;
2428     case 0x8c8: /* PM_WKDEP_DSP */
2429         s->wkup[2] = value & 0x13;
2430         break;
2431     case 0x8e0: /* PM_PWSTCTRL_DSP */
2432         s->power[3] = (value & 0x03017) | (3 << 2);
2433         break;
2434
2435     case 0x8f0: /* PRCM_IRQSTATUS_DSP */
2436         s->irqst[1] &= ~value;
2437         omap_prcm_int_update(s, 1);
2438         break;
2439     case 0x8f4: /* PRCM_IRQENABLE_DSP */
2440         s->irqen[1] = value & 0x7;
2441         omap_prcm_int_update(s, 1);
2442         break;
2443
2444     case 0x8f8: /* PRCM_IRQSTATUS_IVA */
2445         s->irqst[2] &= ~value;
2446         omap_prcm_int_update(s, 2);
2447         break;
2448     case 0x8fc: /* PRCM_IRQENABLE_IVA */
2449         s->irqen[2] = value & 0x7;
2450         omap_prcm_int_update(s, 2);
2451         break;
2452
2453     default:
2454         OMAP_BAD_REG(addr);
2455         return;
2456     }
2457 }
2458
2459 static CPUReadMemoryFunc *omap_prcm_readfn[] = {
2460     omap_badwidth_read32,
2461     omap_badwidth_read32,
2462     omap_prcm_read,
2463 };
2464
2465 static CPUWriteMemoryFunc *omap_prcm_writefn[] = {
2466     omap_badwidth_write32,
2467     omap_badwidth_write32,
2468     omap_prcm_write,
2469 };
2470
2471 static void omap_prcm_reset(struct omap_prcm_s *s)
2472 {
2473     s->sysconfig = 0;
2474     s->irqst[0] = 0;
2475     s->irqst[1] = 0;
2476     s->irqst[2] = 0;
2477     s->irqen[0] = 0;
2478     s->irqen[1] = 0;
2479     s->irqen[2] = 0;
2480     s->voltctrl = 0x1040;
2481     s->ev = 0x14;
2482     s->evtime[0] = 0;
2483     s->evtime[1] = 0;
2484     s->clkctrl[0] = 0;
2485     s->clkctrl[1] = 0;
2486     s->clkctrl[2] = 0;
2487     s->clkctrl[3] = 0;
2488     s->clken[1] = 7;
2489     s->clken[3] = 7;
2490     s->clken[4] = 0;
2491     s->clken[5] = 0;
2492     s->clken[6] = 0;
2493     s->clken[7] = 0xc;
2494     s->clken[8] = 0x3e;
2495     s->clken[9] = 0x0d;
2496     s->clken[10] = 0;
2497     s->clken[11] = 0;
2498     s->clkidle[0] = 0;
2499     s->clkidle[2] = 7;
2500     s->clkidle[3] = 0;
2501     s->clkidle[4] = 0;
2502     s->clkidle[5] = 0x0c;
2503     s->clkidle[6] = 0;
2504     s->clksel[0] = 0x01;
2505     s->clksel[1] = 0x02100121;
2506     s->clksel[2] = 0x00000000;
2507     s->clksel[3] = 0x01;
2508     s->clksel[4] = 0;
2509     s->clksel[7] = 0x0121;
2510     s->wkup[0] = 0x15;
2511     s->wkup[1] = 0x13;
2512     s->wkup[2] = 0x13;
2513     s->wken[0] = 0x04667ff8;
2514     s->wken[1] = 0x00000005;
2515     s->wken[2] = 5;
2516     s->wkst[0] = 0;
2517     s->wkst[1] = 0;
2518     s->wkst[2] = 0;
2519     s->power[0] = 0x00c;
2520     s->power[1] = 4;
2521     s->power[2] = 0x0000c;
2522     s->power[3] = 0x14;
2523     s->rstctrl[0] = 1;
2524     s->rst[3] = 1;
2525 }
2526
2527 static void omap_prcm_coldreset(struct omap_prcm_s *s)
2528 {
2529     s->setuptime[0] = 0;
2530     s->setuptime[1] = 0;
2531     memset(&s->scratch, 0, sizeof(s->scratch));
2532     s->rst[0] = 0x01;
2533     s->rst[1] = 0x00;
2534     s->rst[2] = 0x01;
2535     s->clken[0] = 0;
2536     s->clken[2] = 0;
2537     s->clkidle[1] = 0;
2538     s->clksel[5] = 0;
2539     s->clksel[6] = 2;
2540     s->clksrc[0] = 0x43;
2541     s->clkout[0] = 0x0303;
2542     s->clkemul[0] = 0;
2543     s->clkpol[0] = 0x100;
2544     s->rsttime_wkup = 0x1002;
2545
2546     omap_prcm_reset(s);
2547 }
2548
2549 struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
2550                 qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
2551                 struct omap_mpu_state_s *mpu)
2552 {
2553     int iomemtype;
2554     struct omap_prcm_s *s = (struct omap_prcm_s *)
2555             qemu_mallocz(sizeof(struct omap_prcm_s));
2556
2557     s->irq[0] = mpu_int;
2558     s->irq[1] = dsp_int;
2559     s->irq[2] = iva_int;
2560     s->mpu = mpu;
2561     omap_prcm_coldreset(s);
2562
2563     iomemtype = cpu_register_io_memory(0, omap_prcm_readfn,
2564                     omap_prcm_writefn, s);
2565     s->base = omap_l4_attach(ta, 0, iomemtype);
2566     omap_l4_attach(ta, 1, iomemtype);
2567
2568     return s;
2569 }
2570
2571 /* System and Pinout control */
2572 struct omap_sysctl_s {
2573     target_phys_addr_t base;
2574     struct omap_mpu_state_s *mpu;
2575
2576     uint32_t sysconfig;
2577     uint32_t devconfig;
2578     uint32_t psaconfig;
2579     uint32_t padconf[0x45];
2580     uint8_t obs;
2581     uint32_t msuspendmux[5];
2582 };
2583
2584 static uint32_t omap_sysctl_read(void *opaque, target_phys_addr_t addr)
2585 {
2586     struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
2587     int offset = addr - s->base;
2588
2589     switch (offset) {
2590     case 0x000: /* CONTROL_REVISION */
2591         return 0x20;
2592
2593     case 0x010: /* CONTROL_SYSCONFIG */
2594         return s->sysconfig;
2595
2596     case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
2597         return s->padconf[(offset - 0x30) >> 2];
2598
2599     case 0x270: /* CONTROL_DEBOBS */
2600         return s->obs;
2601
2602     case 0x274: /* CONTROL_DEVCONF */
2603         return s->devconfig;
2604
2605     case 0x28c: /* CONTROL_EMU_SUPPORT */
2606         return 0;
2607
2608     case 0x290: /* CONTROL_MSUSPENDMUX_0 */
2609         return s->msuspendmux[0];
2610     case 0x294: /* CONTROL_MSUSPENDMUX_1 */
2611         return s->msuspendmux[1];
2612     case 0x298: /* CONTROL_MSUSPENDMUX_2 */
2613         return s->msuspendmux[2];
2614     case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
2615         return s->msuspendmux[3];
2616     case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
2617         return s->msuspendmux[4];
2618     case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
2619         return 0;
2620
2621     case 0x2b8: /* CONTROL_PSA_CTRL */
2622         return s->psaconfig;
2623     case 0x2bc: /* CONTROL_PSA_CMD */
2624     case 0x2c0: /* CONTROL_PSA_VALUE */
2625         return 0;
2626
2627     case 0x2b0: /* CONTROL_SEC_CTRL */
2628         return 0x800000f1;
2629     case 0x2d0: /* CONTROL_SEC_EMU */
2630         return 0x80000015;
2631     case 0x2d4: /* CONTROL_SEC_TAP */
2632         return 0x8000007f;
2633     case 0x2b4: /* CONTROL_SEC_TEST */
2634     case 0x2f0: /* CONTROL_SEC_STATUS */
2635     case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
2636         /* Secure mode is not present on general-pusrpose device.  Outside
2637          * secure mode these values cannot be read or written.  */
2638         return 0;
2639
2640     case 0x2d8: /* CONTROL_OCM_RAM_PERM */
2641         return 0xff;
2642     case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
2643     case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
2644     case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
2645         /* No secure mode so no Extended Secure RAM present.  */
2646         return 0;
2647
2648     case 0x2f8: /* CONTROL_STATUS */
2649         /* Device Type => General-purpose */
2650         return 0x0300;
2651     case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
2652
2653     case 0x300: /* CONTROL_RPUB_KEY_H_0 */
2654     case 0x304: /* CONTROL_RPUB_KEY_H_1 */
2655     case 0x308: /* CONTROL_RPUB_KEY_H_2 */
2656     case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
2657         return 0xdecafbad;
2658
2659     case 0x310: /* CONTROL_RAND_KEY_0 */
2660     case 0x314: /* CONTROL_RAND_KEY_1 */
2661     case 0x318: /* CONTROL_RAND_KEY_2 */
2662     case 0x31c: /* CONTROL_RAND_KEY_3 */
2663     case 0x320: /* CONTROL_CUST_KEY_0 */
2664     case 0x324: /* CONTROL_CUST_KEY_1 */
2665     case 0x330: /* CONTROL_TEST_KEY_0 */
2666     case 0x334: /* CONTROL_TEST_KEY_1 */
2667     case 0x338: /* CONTROL_TEST_KEY_2 */
2668     case 0x33c: /* CONTROL_TEST_KEY_3 */
2669     case 0x340: /* CONTROL_TEST_KEY_4 */
2670     case 0x344: /* CONTROL_TEST_KEY_5 */
2671     case 0x348: /* CONTROL_TEST_KEY_6 */
2672     case 0x34c: /* CONTROL_TEST_KEY_7 */
2673     case 0x350: /* CONTROL_TEST_KEY_8 */
2674     case 0x354: /* CONTROL_TEST_KEY_9 */
2675         /* Can only be accessed in secure mode and when C_FieldAccEnable
2676          * bit is set in CONTROL_SEC_CTRL.
2677          * TODO: otherwise an interconnect access error is generated.  */
2678         return 0;
2679     }
2680
2681     OMAP_BAD_REG(addr);
2682     return 0;
2683 }
2684
2685 static void omap_sysctl_write(void *opaque, target_phys_addr_t addr,
2686                 uint32_t value)
2687 {
2688     struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
2689     int offset = addr - s->base;
2690
2691     switch (offset) {
2692     case 0x000: /* CONTROL_REVISION */
2693     case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
2694     case 0x2c0: /* CONTROL_PSA_VALUE */
2695     case 0x2f8: /* CONTROL_STATUS */
2696     case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
2697     case 0x300: /* CONTROL_RPUB_KEY_H_0 */
2698     case 0x304: /* CONTROL_RPUB_KEY_H_1 */
2699     case 0x308: /* CONTROL_RPUB_KEY_H_2 */
2700     case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
2701     case 0x310: /* CONTROL_RAND_KEY_0 */
2702     case 0x314: /* CONTROL_RAND_KEY_1 */
2703     case 0x318: /* CONTROL_RAND_KEY_2 */
2704     case 0x31c: /* CONTROL_RAND_KEY_3 */
2705     case 0x320: /* CONTROL_CUST_KEY_0 */
2706     case 0x324: /* CONTROL_CUST_KEY_1 */
2707     case 0x330: /* CONTROL_TEST_KEY_0 */
2708     case 0x334: /* CONTROL_TEST_KEY_1 */
2709     case 0x338: /* CONTROL_TEST_KEY_2 */
2710     case 0x33c: /* CONTROL_TEST_KEY_3 */
2711     case 0x340: /* CONTROL_TEST_KEY_4 */
2712     case 0x344: /* CONTROL_TEST_KEY_5 */
2713     case 0x348: /* CONTROL_TEST_KEY_6 */
2714     case 0x34c: /* CONTROL_TEST_KEY_7 */
2715     case 0x350: /* CONTROL_TEST_KEY_8 */
2716     case 0x354: /* CONTROL_TEST_KEY_9 */
2717         OMAP_RO_REG(addr);
2718         return;
2719
2720     case 0x010: /* CONTROL_SYSCONFIG */
2721         s->sysconfig = value & 0x1e;
2722         break;
2723
2724     case 0x030 ... 0x140:       /* CONTROL_PADCONF - only used in the POP */
2725         /* XXX: should check constant bits */
2726         s->padconf[(offset - 0x30) >> 2] = value & 0x1f1f1f1f;
2727         break;
2728
2729     case 0x270: /* CONTROL_DEBOBS */
2730         s->obs = value & 0xff;
2731         break;
2732
2733     case 0x274: /* CONTROL_DEVCONF */
2734         s->devconfig = value & 0xffffc7ff;
2735         break;
2736
2737     case 0x28c: /* CONTROL_EMU_SUPPORT */
2738         break;
2739
2740     case 0x290: /* CONTROL_MSUSPENDMUX_0 */
2741         s->msuspendmux[0] = value & 0x3fffffff;
2742         break;
2743     case 0x294: /* CONTROL_MSUSPENDMUX_1 */
2744         s->msuspendmux[1] = value & 0x3fffffff;
2745         break;
2746     case 0x298: /* CONTROL_MSUSPENDMUX_2 */
2747         s->msuspendmux[2] = value & 0x3fffffff;
2748         break;
2749     case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
2750         s->msuspendmux[3] = value & 0x3fffffff;
2751         break;
2752     case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
2753         s->msuspendmux[4] = value & 0x3fffffff;
2754         break;
2755
2756     case 0x2b8: /* CONTROL_PSA_CTRL */
2757         s->psaconfig = value & 0x1c;
2758         s->psaconfig |= (value & 0x20) ? 2 : 1;
2759         break;
2760     case 0x2bc: /* CONTROL_PSA_CMD */
2761         break;
2762
2763     case 0x2b0: /* CONTROL_SEC_CTRL */
2764     case 0x2b4: /* CONTROL_SEC_TEST */
2765     case 0x2d0: /* CONTROL_SEC_EMU */
2766     case 0x2d4: /* CONTROL_SEC_TAP */
2767     case 0x2d8: /* CONTROL_OCM_RAM_PERM */
2768     case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
2769     case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
2770     case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
2771     case 0x2f0: /* CONTROL_SEC_STATUS */
2772     case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
2773         break;
2774
2775     default:
2776         OMAP_BAD_REG(addr);
2777         return;
2778     }
2779 }
2780
2781 static CPUReadMemoryFunc *omap_sysctl_readfn[] = {
2782     omap_badwidth_read32,       /* TODO */
2783     omap_badwidth_read32,       /* TODO */
2784     omap_sysctl_read,
2785 };
2786
2787 static CPUWriteMemoryFunc *omap_sysctl_writefn[] = {
2788     omap_badwidth_write32,      /* TODO */
2789     omap_badwidth_write32,      /* TODO */
2790     omap_sysctl_write,
2791 };
2792
2793 static void omap_sysctl_reset(struct omap_sysctl_s *s)
2794 {
2795     /* (power-on reset) */
2796     s->sysconfig = 0;
2797     s->obs = 0;
2798     s->devconfig = 0x0c000000;
2799     s->msuspendmux[0] = 0x00000000;
2800     s->msuspendmux[1] = 0x00000000;
2801     s->msuspendmux[2] = 0x00000000;
2802     s->msuspendmux[3] = 0x00000000;
2803     s->msuspendmux[4] = 0x00000000;
2804     s->psaconfig = 1;
2805
2806     s->padconf[0x00] = 0x000f0f0f;
2807     s->padconf[0x01] = 0x00000000;
2808     s->padconf[0x02] = 0x00000000;
2809     s->padconf[0x03] = 0x00000000;
2810     s->padconf[0x04] = 0x00000000;
2811     s->padconf[0x05] = 0x00000000;
2812     s->padconf[0x06] = 0x00000000;
2813     s->padconf[0x07] = 0x00000000;
2814     s->padconf[0x08] = 0x08080800;
2815     s->padconf[0x09] = 0x08080808;
2816     s->padconf[0x0a] = 0x08080808;
2817     s->padconf[0x0b] = 0x08080808;
2818     s->padconf[0x0c] = 0x08080808;
2819     s->padconf[0x0d] = 0x08080800;
2820     s->padconf[0x0e] = 0x08080808;
2821     s->padconf[0x0f] = 0x08080808;
2822     s->padconf[0x10] = 0x18181808;      /* | 0x07070700 if SBoot3 */
2823     s->padconf[0x11] = 0x18181818;      /* | 0x07070707 if SBoot3 */
2824     s->padconf[0x12] = 0x18181818;      /* | 0x07070707 if SBoot3 */
2825     s->padconf[0x13] = 0x18181818;      /* | 0x07070707 if SBoot3 */
2826     s->padconf[0x14] = 0x18181818;      /* | 0x00070707 if SBoot3 */
2827     s->padconf[0x15] = 0x18181818;
2828     s->padconf[0x16] = 0x18181818;      /* | 0x07000000 if SBoot3 */
2829     s->padconf[0x17] = 0x1f001f00;
2830     s->padconf[0x18] = 0x1f1f1f1f;
2831     s->padconf[0x19] = 0x00000000;
2832     s->padconf[0x1a] = 0x1f180000;
2833     s->padconf[0x1b] = 0x00001f1f;
2834     s->padconf[0x1c] = 0x1f001f00;
2835     s->padconf[0x1d] = 0x00000000;
2836     s->padconf[0x1e] = 0x00000000;
2837     s->padconf[0x1f] = 0x08000000;
2838     s->padconf[0x20] = 0x08080808;
2839     s->padconf[0x21] = 0x08080808;
2840     s->padconf[0x22] = 0x0f080808;
2841     s->padconf[0x23] = 0x0f0f0f0f;
2842     s->padconf[0x24] = 0x000f0f0f;
2843     s->padconf[0x25] = 0x1f1f1f0f;
2844     s->padconf[0x26] = 0x080f0f1f;
2845     s->padconf[0x27] = 0x070f1808;
2846     s->padconf[0x28] = 0x0f070707;
2847     s->padconf[0x29] = 0x000f0f1f;
2848     s->padconf[0x2a] = 0x0f0f0f1f;
2849     s->padconf[0x2b] = 0x08000000;
2850     s->padconf[0x2c] = 0x0000001f;
2851     s->padconf[0x2d] = 0x0f0f1f00;
2852     s->padconf[0x2e] = 0x1f1f0f0f;
2853     s->padconf[0x2f] = 0x0f1f1f1f;
2854     s->padconf[0x30] = 0x0f0f0f0f;
2855     s->padconf[0x31] = 0x0f1f0f1f;
2856     s->padconf[0x32] = 0x0f0f0f0f;
2857     s->padconf[0x33] = 0x0f1f0f1f;
2858     s->padconf[0x34] = 0x1f1f0f0f;
2859     s->padconf[0x35] = 0x0f0f1f1f;
2860     s->padconf[0x36] = 0x0f0f1f0f;
2861     s->padconf[0x37] = 0x0f0f0f0f;
2862     s->padconf[0x38] = 0x1f18180f;
2863     s->padconf[0x39] = 0x1f1f1f1f;
2864     s->padconf[0x3a] = 0x00001f1f;
2865     s->padconf[0x3b] = 0x00000000;
2866     s->padconf[0x3c] = 0x00000000;
2867     s->padconf[0x3d] = 0x0f0f0f0f;
2868     s->padconf[0x3e] = 0x18000f0f;
2869     s->padconf[0x3f] = 0x00070000;
2870     s->padconf[0x40] = 0x00000707;
2871     s->padconf[0x41] = 0x0f1f0700;
2872     s->padconf[0x42] = 0x1f1f070f;
2873     s->padconf[0x43] = 0x0008081f;
2874     s->padconf[0x44] = 0x00000800;
2875 }
2876
2877 struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
2878                 omap_clk iclk, struct omap_mpu_state_s *mpu)
2879 {
2880     int iomemtype;
2881     struct omap_sysctl_s *s = (struct omap_sysctl_s *)
2882             qemu_mallocz(sizeof(struct omap_sysctl_s));
2883
2884     s->mpu = mpu;
2885     omap_sysctl_reset(s);
2886
2887     iomemtype = cpu_register_io_memory(0, omap_sysctl_readfn,
2888                     omap_sysctl_writefn, s);
2889     s->base = omap_l4_attach(ta, 0, iomemtype);
2890     omap_l4_attach(ta, 0, iomemtype);
2891
2892     return s;
2893 }
2894
2895 /* SDRAM Controller Subsystem */
2896 struct omap_sdrc_s {
2897     target_phys_addr_t base;
2898
2899     uint8_t config;
2900 };
2901
2902 static void omap_sdrc_reset(struct omap_sdrc_s *s)
2903 {
2904     s->config = 0x10;
2905 }
2906
2907 static uint32_t omap_sdrc_read(void *opaque, target_phys_addr_t addr)
2908 {
2909     struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
2910     int offset = addr - s->base;
2911
2912     switch (offset) {
2913     case 0x00:  /* SDRC_REVISION */
2914         return 0x20;
2915
2916     case 0x10:  /* SDRC_SYSCONFIG */
2917         return s->config;
2918
2919     case 0x14:  /* SDRC_SYSSTATUS */
2920         return 1;                                               /* RESETDONE */
2921
2922     case 0x40:  /* SDRC_CS_CFG */
2923     case 0x44:  /* SDRC_SHARING */
2924     case 0x48:  /* SDRC_ERR_ADDR */
2925     case 0x4c:  /* SDRC_ERR_TYPE */
2926     case 0x60:  /* SDRC_DLLA_SCTRL */
2927     case 0x64:  /* SDRC_DLLA_STATUS */
2928     case 0x68:  /* SDRC_DLLB_CTRL */
2929     case 0x6c:  /* SDRC_DLLB_STATUS */
2930     case 0x70:  /* SDRC_POWER */
2931     case 0x80:  /* SDRC_MCFG_0 */
2932     case 0x84:  /* SDRC_MR_0 */
2933     case 0x88:  /* SDRC_EMR1_0 */
2934     case 0x8c:  /* SDRC_EMR2_0 */
2935     case 0x90:  /* SDRC_EMR3_0 */
2936     case 0x94:  /* SDRC_DCDL1_CTRL */
2937     case 0x98:  /* SDRC_DCDL2_CTRL */
2938     case 0x9c:  /* SDRC_ACTIM_CTRLA_0 */
2939     case 0xa0:  /* SDRC_ACTIM_CTRLB_0 */
2940     case 0xa4:  /* SDRC_RFR_CTRL_0 */
2941     case 0xa8:  /* SDRC_MANUAL_0 */
2942     case 0xb0:  /* SDRC_MCFG_1 */
2943     case 0xb4:  /* SDRC_MR_1 */
2944     case 0xb8:  /* SDRC_EMR1_1 */
2945     case 0xbc:  /* SDRC_EMR2_1 */
2946     case 0xc0:  /* SDRC_EMR3_1 */
2947     case 0xc4:  /* SDRC_ACTIM_CTRLA_1 */
2948     case 0xc8:  /* SDRC_ACTIM_CTRLB_1 */
2949     case 0xd4:  /* SDRC_RFR_CTRL_1 */
2950     case 0xd8:  /* SDRC_MANUAL_1 */
2951         return 0x00;
2952     }
2953
2954     OMAP_BAD_REG(addr);
2955     return 0;
2956 }
2957
2958 static void omap_sdrc_write(void *opaque, target_phys_addr_t addr,
2959                 uint32_t value)
2960 {
2961     struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
2962     int offset = addr - s->base;
2963
2964     switch (offset) {
2965     case 0x00:  /* SDRC_REVISION */
2966     case 0x14:  /* SDRC_SYSSTATUS */
2967     case 0x48:  /* SDRC_ERR_ADDR */
2968     case 0x64:  /* SDRC_DLLA_STATUS */
2969     case 0x6c:  /* SDRC_DLLB_STATUS */
2970         OMAP_RO_REG(addr);
2971         return;
2972
2973     case 0x10:  /* SDRC_SYSCONFIG */
2974         if ((value >> 3) != 0x2)
2975             fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
2976                             __FUNCTION__, value >> 3);
2977         if (value & 2)
2978             omap_sdrc_reset(s);
2979         s->config = value & 0x18;
2980         break;
2981
2982     case 0x40:  /* SDRC_CS_CFG */
2983     case 0x44:  /* SDRC_SHARING */
2984     case 0x4c:  /* SDRC_ERR_TYPE */
2985     case 0x60:  /* SDRC_DLLA_SCTRL */
2986     case 0x68:  /* SDRC_DLLB_CTRL */
2987     case 0x70:  /* SDRC_POWER */
2988     case 0x80:  /* SDRC_MCFG_0 */
2989     case 0x84:  /* SDRC_MR_0 */
2990     case 0x88:  /* SDRC_EMR1_0 */
2991     case 0x8c:  /* SDRC_EMR2_0 */
2992     case 0x90:  /* SDRC_EMR3_0 */
2993     case 0x94:  /* SDRC_DCDL1_CTRL */
2994     case 0x98:  /* SDRC_DCDL2_CTRL */
2995     case 0x9c:  /* SDRC_ACTIM_CTRLA_0 */
2996     case 0xa0:  /* SDRC_ACTIM_CTRLB_0 */
2997     case 0xa4:  /* SDRC_RFR_CTRL_0 */
2998     case 0xa8:  /* SDRC_MANUAL_0 */
2999     case 0xb0:  /* SDRC_MCFG_1 */
3000     case 0xb4:  /* SDRC_MR_1 */
3001     case 0xb8:  /* SDRC_EMR1_1 */
3002     case 0xbc:  /* SDRC_EMR2_1 */
3003     case 0xc0:  /* SDRC_EMR3_1 */
3004     case 0xc4:  /* SDRC_ACTIM_CTRLA_1 */
3005     case 0xc8:  /* SDRC_ACTIM_CTRLB_1 */
3006     case 0xd4:  /* SDRC_RFR_CTRL_1 */
3007     case 0xd8:  /* SDRC_MANUAL_1 */
3008         break;
3009
3010     default:
3011         OMAP_BAD_REG(addr);
3012         return;
3013     }
3014 }
3015
3016 static CPUReadMemoryFunc *omap_sdrc_readfn[] = {
3017     omap_badwidth_read32,
3018     omap_badwidth_read32,
3019     omap_sdrc_read,
3020 };
3021
3022 static CPUWriteMemoryFunc *omap_sdrc_writefn[] = {
3023     omap_badwidth_write32,
3024     omap_badwidth_write32,
3025     omap_sdrc_write,
3026 };
3027
3028 struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base)
3029 {
3030     int iomemtype;
3031     struct omap_sdrc_s *s = (struct omap_sdrc_s *)
3032             qemu_mallocz(sizeof(struct omap_sdrc_s));
3033
3034     s->base = base;
3035     omap_sdrc_reset(s);
3036
3037     iomemtype = cpu_register_io_memory(0, omap_sdrc_readfn,
3038                     omap_sdrc_writefn, s);
3039     cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3040
3041     return s;
3042 }
3043
3044 /* General-Purpose Memory Controller */
3045 struct omap_gpmc_s {
3046     target_phys_addr_t base;
3047     qemu_irq irq;
3048
3049     uint8_t sysconfig;
3050     uint16_t irqst;
3051     uint16_t irqen;
3052     uint16_t timeout;
3053     uint16_t config;
3054     uint32_t prefconfig[2];
3055     int prefcontrol;
3056     int preffifo;
3057     int prefcount;
3058     struct omap_gpmc_cs_file_s {
3059         uint32_t config[7];
3060         target_phys_addr_t base;
3061         size_t size;
3062         int iomemtype;
3063         void (*base_update)(void *opaque, target_phys_addr_t new);
3064         void (*unmap)(void *opaque);
3065         void *opaque;
3066     } cs_file[8];
3067     int ecc_cs;
3068     int ecc_ptr;
3069     uint32_t ecc_cfg;
3070     struct ecc_state_s ecc[9];
3071 };
3072
3073 static void omap_gpmc_int_update(struct omap_gpmc_s *s)
3074 {
3075     qemu_set_irq(s->irq, s->irqen & s->irqst);
3076 }
3077
3078 static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
3079 {
3080     /* TODO: check for overlapping regions and report access errors */
3081     if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
3082                     (base < 0 || base >= 0x40) ||
3083                     (base & 0x0f & ~mask)) {
3084         fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
3085                         __FUNCTION__);
3086         return;
3087     }
3088
3089     if (!f->opaque)
3090         return;
3091
3092     f->base = base << 24;
3093     f->size = (0x0fffffff & ~(mask << 24)) + 1;
3094     /* TODO: rather than setting the size of the mapping (which should be
3095      * constant), the mask should cause wrapping of the address space, so
3096      * that the same memory becomes accessible at every <i>size</i> bytes
3097      * starting from <i>base</i>.  */
3098     if (f->iomemtype)
3099         cpu_register_physical_memory(f->base, f->size, f->iomemtype);
3100
3101     if (f->base_update)
3102         f->base_update(f->opaque, f->base);
3103 }
3104
3105 static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
3106 {
3107     if (f->size) {
3108         if (f->unmap)
3109             f->unmap(f->opaque);
3110         if (f->iomemtype)
3111             cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED);
3112         f->base = 0;
3113         f->size = 0;
3114     }
3115 }
3116
3117 static void omap_gpmc_reset(struct omap_gpmc_s *s)
3118 {
3119     int i;
3120
3121     s->sysconfig = 0;
3122     s->irqst = 0;
3123     s->irqen = 0;
3124     omap_gpmc_int_update(s);
3125     s->timeout = 0;
3126     s->config = 0xa00;
3127     s->prefconfig[0] = 0x00004000;
3128     s->prefconfig[1] = 0x00000000;
3129     s->prefcontrol = 0;
3130     s->preffifo = 0;
3131     s->prefcount = 0;
3132     for (i = 0; i < 8; i ++) {
3133         if (s->cs_file[i].config[6] & (1 << 6))                 /* CSVALID */
3134             omap_gpmc_cs_unmap(s->cs_file + i);
3135         s->cs_file[i].config[0] = i ? 1 << 12 : 0;
3136         s->cs_file[i].config[1] = 0x101001;
3137         s->cs_file[i].config[2] = 0x020201;
3138         s->cs_file[i].config[3] = 0x10031003;
3139         s->cs_file[i].config[4] = 0x10f1111;
3140         s->cs_file[i].config[5] = 0;
3141         s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
3142         if (s->cs_file[i].config[6] & (1 << 6))                 /* CSVALID */
3143             omap_gpmc_cs_map(&s->cs_file[i],
3144                             s->cs_file[i].config[6] & 0x1f,     /* MASKADDR */
3145                         (s->cs_file[i].config[6] >> 8 & 0xf));  /* BASEADDR */
3146     }
3147     omap_gpmc_cs_map(s->cs_file, 0, 0xf);
3148     s->ecc_cs = 0;
3149     s->ecc_ptr = 0;
3150     s->ecc_cfg = 0x3fcff000;
3151     for (i = 0; i < 9; i ++)
3152         ecc_reset(&s->ecc[i]);
3153 }
3154
3155 static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
3156 {
3157     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
3158     int offset = addr - s->base;
3159     int cs;
3160     struct omap_gpmc_cs_file_s *f;
3161
3162     switch (offset) {
3163     case 0x000: /* GPMC_REVISION */
3164         return 0x20;
3165
3166     case 0x010: /* GPMC_SYSCONFIG */
3167         return s->sysconfig;
3168
3169     case 0x014: /* GPMC_SYSSTATUS */
3170         return 1;                                               /* RESETDONE */
3171
3172     case 0x018: /* GPMC_IRQSTATUS */
3173         return s->irqst;
3174
3175     case 0x01c: /* GPMC_IRQENABLE */
3176         return s->irqen;
3177
3178     case 0x040: /* GPMC_TIMEOUT_CONTROL */
3179         return s->timeout;
3180
3181     case 0x044: /* GPMC_ERR_ADDRESS */
3182     case 0x048: /* GPMC_ERR_TYPE */
3183         return 0;
3184
3185     case 0x050: /* GPMC_CONFIG */
3186         return s->config;
3187
3188     case 0x054: /* GPMC_STATUS */
3189         return 0x001;
3190
3191     case 0x060 ... 0x1d4:
3192         cs = (offset - 0x060) / 0x30;
3193         offset -= cs * 0x30;
3194         f = s->cs_file + cs;
3195         switch (offset - cs * 0x30) {
3196             case 0x60:  /* GPMC_CONFIG1 */
3197                 return f->config[0];
3198             case 0x64:  /* GPMC_CONFIG2 */
3199                 return f->config[1];
3200             case 0x68:  /* GPMC_CONFIG3 */
3201                 return f->config[2];
3202             case 0x6c:  /* GPMC_CONFIG4 */
3203                 return f->config[3];
3204             case 0x70:  /* GPMC_CONFIG5 */
3205                 return f->config[4];
3206             case 0x74:  /* GPMC_CONFIG6 */
3207                 return f->config[5];
3208             case 0x78:  /* GPMC_CONFIG7 */
3209                 return f->config[6];
3210             case 0x84:  /* GPMC_NAND_DATA */
3211                 return 0;
3212         }
3213         break;
3214
3215     case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */
3216         return s->prefconfig[0];
3217     case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */
3218         return s->prefconfig[1];
3219     case 0x1ec: /* GPMC_PREFETCH_CONTROL */
3220         return s->prefcontrol;
3221     case 0x1f0: /* GPMC_PREFETCH_STATUS */
3222         return (s->preffifo << 24) |
3223                 ((s->preffifo >
3224                   ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
3225                 s->prefcount;
3226
3227     case 0x1f4: /* GPMC_ECC_CONFIG */
3228         return s->ecc_cs;
3229     case 0x1f8: /* GPMC_ECC_CONTROL */
3230         return s->ecc_ptr;
3231     case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */
3232         return s->ecc_cfg;
3233     case 0x200 ... 0x220:       /* GPMC_ECC_RESULT */
3234         cs = (offset & 0x1f) >> 2;
3235         /* TODO: check correctness */
3236         return
3237                 ((s->ecc[cs].cp    &  0x07) <<  0) |
3238                 ((s->ecc[cs].cp    &  0x38) << 13) |
3239                 ((s->ecc[cs].lp[0] & 0x1ff) <<  3) |
3240                 ((s->ecc[cs].lp[1] & 0x1ff) << 19);
3241
3242     case 0x230: /* GPMC_TESTMODE_CTRL */
3243         return 0;
3244     case 0x234: /* GPMC_PSA_LSB */
3245     case 0x238: /* GPMC_PSA_MSB */
3246         return 0x00000000;
3247     }
3248
3249     OMAP_BAD_REG(addr);
3250     return 0;
3251 }
3252
3253 static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
3254                 uint32_t value)
3255 {
3256     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
3257     int offset = addr - s->base;
3258     int cs;
3259     struct omap_gpmc_cs_file_s *f;
3260
3261     switch (offset) {
3262     case 0x000: /* GPMC_REVISION */
3263     case 0x014: /* GPMC_SYSSTATUS */
3264     case 0x054: /* GPMC_STATUS */
3265     case 0x1f0: /* GPMC_PREFETCH_STATUS */
3266     case 0x200 ... 0x220:       /* GPMC_ECC_RESULT */
3267     case 0x234: /* GPMC_PSA_LSB */
3268     case 0x238: /* GPMC_PSA_MSB */
3269         OMAP_RO_REG(addr);
3270         break;
3271
3272     case 0x010: /* GPMC_SYSCONFIG */
3273         if ((value >> 3) == 0x3)
3274             fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
3275                             __FUNCTION__, value >> 3);
3276         if (value & 2)
3277             omap_gpmc_reset(s);
3278         s->sysconfig = value & 0x19;
3279         break;
3280
3281     case 0x018: /* GPMC_IRQSTATUS */
3282         s->irqen = ~value;
3283         omap_gpmc_int_update(s);
3284         break;
3285
3286     case 0x01c: /* GPMC_IRQENABLE */
3287         s->irqen = value & 0xf03;
3288         omap_gpmc_int_update(s);
3289         break;
3290
3291     case 0x040: /* GPMC_TIMEOUT_CONTROL */
3292         s->timeout = value & 0x1ff1;
3293         break;
3294
3295     case 0x044: /* GPMC_ERR_ADDRESS */
3296     case 0x048: /* GPMC_ERR_TYPE */
3297         break;
3298
3299     case 0x050: /* GPMC_CONFIG */
3300         s->config = value & 0xf13;
3301         break;
3302
3303     case 0x060 ... 0x1d4:
3304         cs = (offset - 0x060) / 0x30;
3305         offset -= cs * 0x30;
3306         f = s->cs_file + cs;
3307         switch (offset) {
3308             case 0x60:  /* GPMC_CONFIG1 */
3309                 f->config[0] = value & 0xffef3e13;
3310                 break;
3311             case 0x64:  /* GPMC_CONFIG2 */
3312                 f->config[1] = value & 0x001f1f8f;
3313                 break;
3314             case 0x68:  /* GPMC_CONFIG3 */
3315                 f->config[2] = value & 0x001f1f8f;
3316                 break;
3317             case 0x6c:  /* GPMC_CONFIG4 */
3318                 f->config[3] = value & 0x1f8f1f8f;
3319                 break;
3320             case 0x70:  /* GPMC_CONFIG5 */
3321                 f->config[4] = value & 0x0f1f1f1f;
3322                 break;
3323             case 0x74:  /* GPMC_CONFIG6 */
3324                 f->config[5] = value & 0x00000fcf;
3325                 break;
3326             case 0x78:  /* GPMC_CONFIG7 */
3327                 if ((f->config[6] ^ value) & 0xf7f) {
3328                     if (f->config[6] & (1 << 6))                /* CSVALID */
3329                         omap_gpmc_cs_unmap(f);
3330                     if (value & (1 << 6))                       /* CSVALID */
3331                         omap_gpmc_cs_map(f, value & 0x1f,       /* MASKADDR */
3332                                         (value >> 8 & 0xf));    /* BASEADDR */
3333                 }
3334                 f->config[6] = value & 0x00000f7f;
3335                 break;
3336             case 0x7c:  /* GPMC_NAND_COMMAND */
3337             case 0x80:  /* GPMC_NAND_ADDRESS */
3338             case 0x84:  /* GPMC_NAND_DATA */
3339                 break;
3340
3341             default:
3342                 goto bad_reg;
3343         }
3344         break;
3345
3346     case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */
3347         s->prefconfig[0] = value & 0x7f8f7fbf;
3348         /* TODO: update interrupts, fifos, dmas */
3349         break;
3350
3351     case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */
3352         s->prefconfig[1] = value & 0x3fff;
3353         break;
3354
3355     case 0x1ec: /* GPMC_PREFETCH_CONTROL */
3356         s->prefcontrol = value & 1;
3357         if (s->prefcontrol) {
3358             if (s->prefconfig[0] & 1)
3359                 s->preffifo = 0x40;
3360             else
3361                 s->preffifo = 0x00;
3362         }
3363         /* TODO: start */
3364         break;
3365
3366     case 0x1f4: /* GPMC_ECC_CONFIG */
3367         s->ecc_cs = 0x8f;
3368         break;
3369     case 0x1f8: /* GPMC_ECC_CONTROL */
3370         if (value & (1 << 8))
3371             for (cs = 0; cs < 9; cs ++)
3372                 ecc_reset(&s->ecc[cs]);
3373         s->ecc_ptr = value & 0xf;
3374         if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
3375             s->ecc_ptr = 0;
3376             s->ecc_cs &= ~1;
3377         }
3378         break;
3379     case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */
3380         s->ecc_cfg = value & 0x3fcff1ff;
3381         break;
3382     case 0x230: /* GPMC_TESTMODE_CTRL */
3383         if (value & 7)
3384             fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
3385         break;
3386
3387     default:
3388     bad_reg:
3389         OMAP_BAD_REG(addr);
3390         return;
3391     }
3392 }
3393
3394 static CPUReadMemoryFunc *omap_gpmc_readfn[] = {
3395     omap_badwidth_read32,       /* TODO */
3396     omap_badwidth_read32,       /* TODO */
3397     omap_gpmc_read,
3398 };
3399
3400 static CPUWriteMemoryFunc *omap_gpmc_writefn[] = {
3401     omap_badwidth_write32,      /* TODO */
3402     omap_badwidth_write32,      /* TODO */
3403     omap_gpmc_write,
3404 };
3405
3406 struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
3407 {
3408     int iomemtype;
3409     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
3410             qemu_mallocz(sizeof(struct omap_gpmc_s));
3411
3412     s->base = base;
3413     omap_gpmc_reset(s);
3414
3415     iomemtype = cpu_register_io_memory(0, omap_gpmc_readfn,
3416                     omap_gpmc_writefn, s);
3417     cpu_register_physical_memory(s->base, 0x1000, iomemtype);
3418
3419     return s;
3420 }
3421
3422 void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
3423                 void (*base_upd)(void *opaque, target_phys_addr_t new),
3424                 void (*unmap)(void *opaque), void *opaque)
3425 {
3426     struct omap_gpmc_cs_file_s *f;
3427
3428     if (cs < 0 || cs >= 8) {
3429         fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
3430         exit(-1);
3431     }
3432     f = &s->cs_file[cs];
3433
3434     f->iomemtype = iomemtype;
3435     f->base_update = base_upd;
3436     f->unmap = unmap;
3437     f->opaque = opaque;
3438
3439     if (f->config[6] & (1 << 6))                                /* CSVALID */
3440         omap_gpmc_cs_map(f, f->config[6] & 0x1f,                /* MASKADDR */
3441                         (f->config[6] >> 8 & 0xf));             /* BASEADDR */
3442 }
3443
3444 /* General chip reset */
3445 static void omap2_mpu_reset(void *opaque)
3446 {
3447     struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
3448
3449     omap_inth_reset(mpu->ih[0]);
3450     omap_dma_reset(mpu->dma);
3451     omap_prcm_reset(mpu->prcm);
3452     omap_sysctl_reset(mpu->sysc);
3453     omap_gp_timer_reset(mpu->gptimer[0]);
3454     omap_gp_timer_reset(mpu->gptimer[1]);
3455     omap_gp_timer_reset(mpu->gptimer[2]);
3456     omap_gp_timer_reset(mpu->gptimer[3]);
3457     omap_gp_timer_reset(mpu->gptimer[4]);
3458     omap_gp_timer_reset(mpu->gptimer[5]);
3459     omap_gp_timer_reset(mpu->gptimer[6]);
3460     omap_gp_timer_reset(mpu->gptimer[7]);
3461     omap_gp_timer_reset(mpu->gptimer[8]);
3462     omap_gp_timer_reset(mpu->gptimer[9]);
3463     omap_gp_timer_reset(mpu->gptimer[10]);
3464     omap_gp_timer_reset(mpu->gptimer[11]);
3465     omap_synctimer_reset(&mpu->synctimer);
3466     omap_sdrc_reset(mpu->sdrc);
3467     omap_gpmc_reset(mpu->gpmc);
3468     omap_dss_reset(mpu->dss);
3469     omap_uart_reset(mpu->uart[0]);
3470     omap_uart_reset(mpu->uart[1]);
3471     omap_uart_reset(mpu->uart[2]);
3472     omap_mmc_reset(mpu->mmc);
3473     omap_gpif_reset(mpu->gpif);
3474     omap_mcspi_reset(mpu->mcspi[0]);
3475     omap_mcspi_reset(mpu->mcspi[1]);
3476     omap_i2c_reset(mpu->i2c[0]);
3477     omap_i2c_reset(mpu->i2c[1]);
3478     cpu_reset(mpu->env);
3479 }
3480
3481 static int omap2_validate_addr(struct omap_mpu_state_s *s,
3482                 target_phys_addr_t addr)
3483 {
3484     return 1;
3485 }
3486
3487 static const struct dma_irq_map omap2_dma_irq_map[] = {
3488     { 0, OMAP_INT_24XX_SDMA_IRQ0 },
3489     { 0, OMAP_INT_24XX_SDMA_IRQ1 },
3490     { 0, OMAP_INT_24XX_SDMA_IRQ2 },
3491     { 0, OMAP_INT_24XX_SDMA_IRQ3 },
3492 };
3493
3494 struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
3495                 DisplayState *ds, const char *core)
3496 {
3497     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
3498             qemu_mallocz(sizeof(struct omap_mpu_state_s));
3499     ram_addr_t sram_base, q3_base;
3500     qemu_irq *cpu_irq;
3501     qemu_irq dma_irqs[4];
3502     omap_clk gpio_clks[4];
3503     int sdindex;
3504     int i;
3505
3506     /* Core */
3507     s->mpu_model = omap2420;
3508     s->env = cpu_init(core ?: "arm1136-r2");
3509     if (!s->env) {
3510         fprintf(stderr, "Unable to find CPU definition\n");
3511         exit(1);
3512     }
3513     s->sdram_size = sdram_size;
3514     s->sram_size = OMAP242X_SRAM_SIZE;
3515
3516     s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
3517
3518     /* Clocks */
3519     omap_clk_init(s);
3520
3521     /* Memory-mapped stuff */
3522     cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
3523                     (q3_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
3524     cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
3525                     (sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
3526
3527     s->l4 = omap_l4_init(OMAP2_L4_BASE, 54);
3528
3529     /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
3530     cpu_irq = arm_pic_init_cpu(s->env);
3531     s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0],
3532                     cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
3533                     omap_findclk(s, "mpu_intc_fclk"),
3534                     omap_findclk(s, "mpu_intc_iclk"));
3535
3536     s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
3537                     s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s);
3538
3539     s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
3540                     omap_findclk(s, "omapctrl_iclk"), s);
3541
3542     for (i = 0; i < 4; i ++)
3543         dma_irqs[i] =
3544                 s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr];
3545     s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
3546                     omap_findclk(s, "sdma_iclk"),
3547                     omap_findclk(s, "sdma_fclk"));
3548     s->port->addr_valid = omap2_validate_addr;
3549
3550     s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
3551                     s->irq[0][OMAP_INT_24XX_UART1_IRQ],
3552                     omap_findclk(s, "uart1_fclk"),
3553                     omap_findclk(s, "uart1_iclk"),
3554                     s->drq[OMAP24XX_DMA_UART1_TX],
3555                     s->drq[OMAP24XX_DMA_UART1_RX], serial_hds[0]);
3556     s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20),
3557                     s->irq[0][OMAP_INT_24XX_UART2_IRQ],
3558                     omap_findclk(s, "uart2_fclk"),
3559                     omap_findclk(s, "uart2_iclk"),
3560                     s->drq[OMAP24XX_DMA_UART2_TX],
3561                     s->drq[OMAP24XX_DMA_UART2_RX],
3562                     serial_hds[0] ? serial_hds[1] : 0);
3563     s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21),
3564                     s->irq[0][OMAP_INT_24XX_UART3_IRQ],
3565                     omap_findclk(s, "uart3_fclk"),
3566                     omap_findclk(s, "uart3_iclk"),
3567                     s->drq[OMAP24XX_DMA_UART3_TX],
3568                     s->drq[OMAP24XX_DMA_UART3_RX],
3569                     serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
3570
3571     s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
3572                     s->irq[0][OMAP_INT_24XX_GPTIMER1],
3573                     omap_findclk(s, "wu_gpt1_clk"),
3574                     omap_findclk(s, "wu_l4_iclk"));
3575     s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
3576                     s->irq[0][OMAP_INT_24XX_GPTIMER2],
3577                     omap_findclk(s, "core_gpt2_clk"),
3578                     omap_findclk(s, "core_l4_iclk"));
3579     s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
3580                     s->irq[0][OMAP_INT_24XX_GPTIMER3],
3581                     omap_findclk(s, "core_gpt3_clk"),
3582                     omap_findclk(s, "core_l4_iclk"));
3583     s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
3584                     s->irq[0][OMAP_INT_24XX_GPTIMER4],
3585                     omap_findclk(s, "core_gpt4_clk"),
3586                     omap_findclk(s, "core_l4_iclk"));
3587     s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
3588                     s->irq[0][OMAP_INT_24XX_GPTIMER5],
3589                     omap_findclk(s, "core_gpt5_clk"),
3590                     omap_findclk(s, "core_l4_iclk"));
3591     s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
3592                     s->irq[0][OMAP_INT_24XX_GPTIMER6],
3593                     omap_findclk(s, "core_gpt6_clk"),
3594                     omap_findclk(s, "core_l4_iclk"));
3595     s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
3596                     s->irq[0][OMAP_INT_24XX_GPTIMER7],
3597                     omap_findclk(s, "core_gpt7_clk"),
3598                     omap_findclk(s, "core_l4_iclk"));
3599     s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
3600                     s->irq[0][OMAP_INT_24XX_GPTIMER8],
3601                     omap_findclk(s, "core_gpt8_clk"),
3602                     omap_findclk(s, "core_l4_iclk"));
3603     s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
3604                     s->irq[0][OMAP_INT_24XX_GPTIMER9],
3605                     omap_findclk(s, "core_gpt9_clk"),
3606                     omap_findclk(s, "core_l4_iclk"));
3607     s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
3608                     s->irq[0][OMAP_INT_24XX_GPTIMER10],
3609                     omap_findclk(s, "core_gpt10_clk"),
3610                     omap_findclk(s, "core_l4_iclk"));
3611     s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
3612                     s->irq[0][OMAP_INT_24XX_GPTIMER11],
3613                     omap_findclk(s, "core_gpt11_clk"),
3614                     omap_findclk(s, "core_l4_iclk"));
3615     s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
3616                     s->irq[0][OMAP_INT_24XX_GPTIMER12],
3617                     omap_findclk(s, "core_gpt12_clk"),
3618                     omap_findclk(s, "core_l4_iclk"));
3619
3620     omap_tap_init(omap_l4ta(s->l4, 2), s);
3621
3622     omap_synctimer_init(omap_l4tao(s->l4, 2), s,
3623                     omap_findclk(s, "clk32-kHz"),
3624                     omap_findclk(s, "core_l4_iclk"));
3625
3626     s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
3627                     s->irq[0][OMAP_INT_24XX_I2C1_IRQ],
3628                     &s->drq[OMAP24XX_DMA_I2C1_TX],
3629                     omap_findclk(s, "i2c1.fclk"),
3630                     omap_findclk(s, "i2c1.iclk"));
3631     s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
3632                     s->irq[0][OMAP_INT_24XX_I2C2_IRQ],
3633                     &s->drq[OMAP24XX_DMA_I2C2_TX],
3634                     omap_findclk(s, "i2c2.fclk"),
3635                     omap_findclk(s, "i2c2.iclk"));
3636
3637     gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
3638     gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
3639     gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
3640     gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
3641     s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
3642                     &s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
3643                     gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
3644
3645     s->sdrc = omap_sdrc_init(0x68009000);
3646     s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
3647
3648     sdindex = drive_get_index(IF_SD, 0, 0);
3649     if (sdindex == -1) {
3650         fprintf(stderr, "qemu: missing SecureDigital device\n");
3651         exit(1);
3652     }
3653     s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), drives_table[sdindex].bdrv,
3654                     s->irq[0][OMAP_INT_24XX_MMC_IRQ],
3655                     &s->drq[OMAP24XX_DMA_MMC1_TX],
3656                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
3657
3658     s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
3659                     s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ], 
3660                     &s->drq[OMAP24XX_DMA_SPI1_TX0],
3661                     omap_findclk(s, "spi1_fclk"),
3662                     omap_findclk(s, "spi1_iclk"));
3663     s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
3664                     s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ], 
3665                     &s->drq[OMAP24XX_DMA_SPI2_TX0],
3666                     omap_findclk(s, "spi2_fclk"),
3667                     omap_findclk(s, "spi2_iclk"));
3668
3669     s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800, ds,
3670                     /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
3671                     s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
3672                     omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
3673                     omap_findclk(s, "dss_54m_clk"),
3674                     omap_findclk(s, "dss_l3_iclk"),
3675                     omap_findclk(s, "dss_l4_iclk"));
3676
3677     /* All register mappings (includin those not currenlty implemented):
3678      * SystemControlMod 48000000 - 48000fff
3679      * SystemControlL4  48001000 - 48001fff
3680      * 32kHz Timer Mod  48004000 - 48004fff
3681      * 32kHz Timer L4   48005000 - 48005fff
3682      * PRCM ModA        48008000 - 480087ff
3683      * PRCM ModB        48008800 - 48008fff
3684      * PRCM L4          48009000 - 48009fff
3685      * TEST-BCM Mod     48012000 - 48012fff
3686      * TEST-BCM L4      48013000 - 48013fff
3687      * TEST-TAP Mod     48014000 - 48014fff
3688      * TEST-TAP L4      48015000 - 48015fff
3689      * GPIO1 Mod        48018000 - 48018fff
3690      * GPIO Top         48019000 - 48019fff
3691      * GPIO2 Mod        4801a000 - 4801afff
3692      * GPIO L4          4801b000 - 4801bfff
3693      * GPIO3 Mod        4801c000 - 4801cfff
3694      * GPIO4 Mod        4801e000 - 4801efff
3695      * WDTIMER1 Mod     48020000 - 48010fff
3696      * WDTIMER Top      48021000 - 48011fff
3697      * WDTIMER2 Mod     48022000 - 48012fff
3698      * WDTIMER L4       48023000 - 48013fff
3699      * WDTIMER3 Mod     48024000 - 48014fff
3700      * WDTIMER3 L4      48025000 - 48015fff
3701      * WDTIMER4 Mod     48026000 - 48016fff
3702      * WDTIMER4 L4      48027000 - 48017fff
3703      * GPTIMER1 Mod     48028000 - 48018fff
3704      * GPTIMER1 L4      48029000 - 48019fff
3705      * GPTIMER2 Mod     4802a000 - 4801afff
3706      * GPTIMER2 L4      4802b000 - 4801bfff
3707      * L4-Config AP     48040000 - 480407ff
3708      * L4-Config IP     48040800 - 48040fff
3709      * L4-Config LA     48041000 - 48041fff
3710      * ARM11ETB Mod     48048000 - 48049fff
3711      * ARM11ETB L4      4804a000 - 4804afff
3712      * DISPLAY Top      48050000 - 480503ff
3713      * DISPLAY DISPC    48050400 - 480507ff
3714      * DISPLAY RFBI     48050800 - 48050bff
3715      * DISPLAY VENC     48050c00 - 48050fff
3716      * DISPLAY L4       48051000 - 48051fff
3717      * CAMERA Top       48052000 - 480523ff
3718      * CAMERA core      48052400 - 480527ff
3719      * CAMERA DMA       48052800 - 48052bff
3720      * CAMERA MMU       48052c00 - 48052fff
3721      * CAMERA L4        48053000 - 48053fff
3722      * SDMA Mod         48056000 - 48056fff
3723      * SDMA L4          48057000 - 48057fff
3724      * SSI Top          48058000 - 48058fff
3725      * SSI GDD          48059000 - 48059fff
3726      * SSI Port1        4805a000 - 4805afff
3727      * SSI Port2        4805b000 - 4805bfff
3728      * SSI L4           4805c000 - 4805cfff
3729      * USB Mod          4805e000 - 480fefff
3730      * USB L4           4805f000 - 480fffff
3731      * WIN_TRACER1 Mod  48060000 - 48060fff
3732      * WIN_TRACER1 L4   48061000 - 48061fff
3733      * WIN_TRACER2 Mod  48062000 - 48062fff
3734      * WIN_TRACER2 L4   48063000 - 48063fff
3735      * WIN_TRACER3 Mod  48064000 - 48064fff
3736      * WIN_TRACER3 L4   48065000 - 48065fff
3737      * WIN_TRACER4 Top  48066000 - 480660ff
3738      * WIN_TRACER4 ETT  48066100 - 480661ff
3739      * WIN_TRACER4 WT   48066200 - 480662ff
3740      * WIN_TRACER4 L4   48067000 - 48067fff
3741      * XTI Mod          48068000 - 48068fff
3742      * XTI L4           48069000 - 48069fff
3743      * UART1 Mod        4806a000 - 4806afff
3744      * UART1 L4         4806b000 - 4806bfff
3745      * UART2 Mod        4806c000 - 4806cfff
3746      * UART2 L4         4806d000 - 4806dfff
3747      * UART3 Mod        4806e000 - 4806efff
3748      * UART3 L4         4806f000 - 4806ffff
3749      * I2C1 Mod         48070000 - 48070fff
3750      * I2C1 L4          48071000 - 48071fff
3751      * I2C2 Mod         48072000 - 48072fff
3752      * I2C2 L4          48073000 - 48073fff
3753      * McBSP1 Mod       48074000 - 48074fff
3754      * McBSP1 L4        48075000 - 48075fff
3755      * McBSP2 Mod       48076000 - 48076fff
3756      * McBSP2 L4        48077000 - 48077fff
3757      * GPTIMER3 Mod     48078000 - 48078fff
3758      * GPTIMER3 L4      48079000 - 48079fff
3759      * GPTIMER4 Mod     4807a000 - 4807afff
3760      * GPTIMER4 L4      4807b000 - 4807bfff
3761      * GPTIMER5 Mod     4807c000 - 4807cfff
3762      * GPTIMER5 L4      4807d000 - 4807dfff
3763      * GPTIMER6 Mod     4807e000 - 4807efff
3764      * GPTIMER6 L4      4807f000 - 4807ffff
3765      * GPTIMER7 Mod     48080000 - 48080fff
3766      * GPTIMER7 L4      48081000 - 48081fff
3767      * GPTIMER8 Mod     48082000 - 48082fff
3768      * GPTIMER8 L4      48083000 - 48083fff
3769      * GPTIMER9 Mod     48084000 - 48084fff
3770      * GPTIMER9 L4      48085000 - 48085fff
3771      * GPTIMER10 Mod    48086000 - 48086fff
3772      * GPTIMER10 L4     48087000 - 48087fff
3773      * GPTIMER11 Mod    48088000 - 48088fff
3774      * GPTIMER11 L4     48089000 - 48089fff
3775      * GPTIMER12 Mod    4808a000 - 4808afff
3776      * GPTIMER12 L4     4808b000 - 4808bfff
3777      * EAC Mod          48090000 - 48090fff
3778      * EAC L4           48091000 - 48091fff
3779      * FAC Mod          48092000 - 48092fff
3780      * FAC L4           48093000 - 48093fff
3781      * MAILBOX Mod      48094000 - 48094fff
3782      * MAILBOX L4       48095000 - 48095fff
3783      * SPI1 Mod         48098000 - 48098fff
3784      * SPI1 L4          48099000 - 48099fff
3785      * SPI2 Mod         4809a000 - 4809afff
3786      * SPI2 L4          4809b000 - 4809bfff
3787      * MMC/SDIO Mod     4809c000 - 4809cfff
3788      * MMC/SDIO L4      4809d000 - 4809dfff
3789      * MS_PRO Mod       4809e000 - 4809efff
3790      * MS_PRO L4        4809f000 - 4809ffff
3791      * RNG Mod          480a0000 - 480a0fff
3792      * RNG L4           480a1000 - 480a1fff
3793      * DES3DES Mod      480a2000 - 480a2fff
3794      * DES3DES L4       480a3000 - 480a3fff
3795      * SHA1MD5 Mod      480a4000 - 480a4fff
3796      * SHA1MD5 L4       480a5000 - 480a5fff
3797      * AES Mod          480a6000 - 480a6fff
3798      * AES L4           480a7000 - 480a7fff
3799      * PKA Mod          480a8000 - 480a9fff
3800      * PKA L4           480aa000 - 480aafff
3801      * MG Mod           480b0000 - 480b0fff
3802      * MG L4            480b1000 - 480b1fff
3803      * HDQ/1-wire Mod   480b2000 - 480b2fff
3804      * HDQ/1-wire L4    480b3000 - 480b3fff
3805      * MPU interrupt    480fe000 - 480fefff
3806      * IVA RAM          5c000000 - 5c01ffff
3807      * IVA ROM          5c020000 - 5c027fff
3808      * IMG_BUF_A        5c040000 - 5c040fff
3809      * IMG_BUF_B        5c042000 - 5c042fff
3810      * VLCDS            5c048000 - 5c0487ff
3811      * IMX_COEF         5c049000 - 5c04afff
3812      * IMX_CMD          5c051000 - 5c051fff
3813      * VLCDQ            5c053000 - 5c0533ff
3814      * VLCDH            5c054000 - 5c054fff
3815      * SEQ_CMD          5c055000 - 5c055fff
3816      * IMX_REG          5c056000 - 5c0560ff
3817      * VLCD_REG         5c056100 - 5c0561ff
3818      * SEQ_REG          5c056200 - 5c0562ff
3819      * IMG_BUF_REG      5c056300 - 5c0563ff
3820      * SEQIRQ_REG       5c056400 - 5c0564ff
3821      * OCP_REG          5c060000 - 5c060fff
3822      * SYSC_REG         5c070000 - 5c070fff
3823      * MMU_REG          5d000000 - 5d000fff
3824      * sDMA R           68000400 - 680005ff
3825      * sDMA W           68000600 - 680007ff
3826      * Display Control  68000800 - 680009ff
3827      * DSP subsystem    68000a00 - 68000bff
3828      * MPU subsystem    68000c00 - 68000dff
3829      * IVA subsystem    68001000 - 680011ff
3830      * USB              68001200 - 680013ff
3831      * Camera           68001400 - 680015ff
3832      * VLYNQ (firewall) 68001800 - 68001bff
3833      * VLYNQ            68001e00 - 68001fff
3834      * SSI              68002000 - 680021ff
3835      * L4               68002400 - 680025ff
3836      * DSP (firewall)   68002800 - 68002bff
3837      * DSP subsystem    68002e00 - 68002fff
3838      * IVA (firewall)   68003000 - 680033ff
3839      * IVA              68003600 - 680037ff
3840      * GFX              68003a00 - 68003bff
3841      * CMDWR emulation  68003c00 - 68003dff
3842      * SMS              68004000 - 680041ff
3843      * OCM              68004200 - 680043ff
3844      * GPMC             68004400 - 680045ff
3845      * RAM (firewall)   68005000 - 680053ff
3846      * RAM (err login)  68005400 - 680057ff
3847      * ROM (firewall)   68005800 - 68005bff
3848      * ROM (err login)  68005c00 - 68005fff
3849      * GPMC (firewall)  68006000 - 680063ff
3850      * GPMC (err login) 68006400 - 680067ff
3851      * SMS (err login)  68006c00 - 68006fff
3852      * SMS registers    68008000 - 68008fff
3853      * SDRC registers   68009000 - 68009fff
3854      * GPMC registers   6800a000   6800afff
3855      */
3856
3857     qemu_register_reset(omap2_mpu_reset, s);
3858
3859     return s;
3860 }
This page took 0.240194 seconds and 4 git commands to generate.