]> git.proxmox.com Git - mirror_qemu.git/blame - hw/arm/strongarm.c
migration: Move the VMStateDescription typedef to typedefs.h
[mirror_qemu.git] / hw / arm / strongarm.c
CommitLineData
5bc95aa2
DES
1/*
2 * StrongARM SA-1100/SA-1110 emulation
3 *
4 * Copyright (C) 2011 Dmitry Eremin-Solenikov
5 *
6 * Largely based on StrongARM emulation:
7 * Copyright (c) 2006 Openedhand Ltd.
8 * Written by Andrzej Zaborowski <balrog@zabor.org>
9 *
10 * UART code based on QEMU 16550A UART emulation
11 * Copyright (c) 2003-2004 Fabrice Bellard
12 * Copyright (c) 2008 Citrix Systems, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, see <http://www.gnu.org/licenses/>.
6b620ca3
PB
25 *
26 * Contributions after 2012-01-13 are licensed under the terms of the
27 * GNU GPL, version 2 or (at your option) any later version.
5bc95aa2 28 */
c8623c02 29
12b16722 30#include "qemu/osdep.h"
a8d25326 31#include "qemu-common.h"
4771d756 32#include "cpu.h"
c8623c02 33#include "hw/boards.h"
64552b6b 34#include "hw/irq.h"
83c9f4ca 35#include "hw/sysbus.h"
47b43a1f 36#include "strongarm.h"
1de7afc9 37#include "qemu/error-report.h"
12ec8bd5 38#include "hw/arm/boot.h"
4d43a603 39#include "chardev/char-fe.h"
7566c6ef 40#include "chardev/char-serial.h"
9c17d615 41#include "sysemu/sysemu.h"
8fd06719 42#include "hw/ssi/ssi.h"
f348b6d1 43#include "qemu/cutils.h"
03dd024f 44#include "qemu/log.h"
5bc95aa2
DES
45
46//#define DEBUG
47
48/*
49 TODO
50 - Implement cp15, c14 ?
51 - Implement cp15, c15 !!! (idle used in L)
52 - Implement idle mode handling/DIM
53 - Implement sleep mode/Wake sources
54 - Implement reset control
55 - Implement memory control regs
56 - PCMCIA handling
57 - Maybe support MBGNT/MBREQ
58 - DMA channels
59 - GPCLK
60 - IrDA
61 - MCP
62 - Enhance UART with modem signals
63 */
64
65#ifdef DEBUG
66# define DPRINTF(format, ...) printf(format , ## __VA_ARGS__)
67#else
68# define DPRINTF(format, ...) do { } while (0)
69#endif
70
71static struct {
a8170e5e 72 hwaddr io_base;
5bc95aa2
DES
73 int irq;
74} sa_serial[] = {
75 { 0x80010000, SA_PIC_UART1 },
76 { 0x80030000, SA_PIC_UART2 },
77 { 0x80050000, SA_PIC_UART3 },
78 { 0, 0 }
79};
80
81/* Interrupt Controller */
74e075f6
AF
82
83#define TYPE_STRONGARM_PIC "strongarm_pic"
84#define STRONGARM_PIC(obj) \
85 OBJECT_CHECK(StrongARMPICState, (obj), TYPE_STRONGARM_PIC)
86
87typedef struct StrongARMPICState {
88 SysBusDevice parent_obj;
89
eb2fefbc 90 MemoryRegion iomem;
5bc95aa2
DES
91 qemu_irq irq;
92 qemu_irq fiq;
93
94 uint32_t pending;
95 uint32_t enabled;
96 uint32_t is_fiq;
97 uint32_t int_idle;
98} StrongARMPICState;
99
100#define ICIP 0x00
101#define ICMR 0x04
102#define ICLR 0x08
103#define ICFP 0x10
104#define ICPR 0x20
105#define ICCR 0x0c
106
107#define SA_PIC_SRCS 32
108
109
110static void strongarm_pic_update(void *opaque)
111{
112 StrongARMPICState *s = opaque;
113
114 /* FIXME: reflect DIM */
115 qemu_set_irq(s->fiq, s->pending & s->enabled & s->is_fiq);
116 qemu_set_irq(s->irq, s->pending & s->enabled & ~s->is_fiq);
117}
118
119static void strongarm_pic_set_irq(void *opaque, int irq, int level)
120{
121 StrongARMPICState *s = opaque;
122
123 if (level) {
124 s->pending |= 1 << irq;
125 } else {
126 s->pending &= ~(1 << irq);
127 }
128
129 strongarm_pic_update(s);
130}
131
a8170e5e 132static uint64_t strongarm_pic_mem_read(void *opaque, hwaddr offset,
eb2fefbc 133 unsigned size)
5bc95aa2
DES
134{
135 StrongARMPICState *s = opaque;
136
137 switch (offset) {
138 case ICIP:
139 return s->pending & ~s->is_fiq & s->enabled;
140 case ICMR:
141 return s->enabled;
142 case ICLR:
143 return s->is_fiq;
144 case ICCR:
145 return s->int_idle == 0;
146 case ICFP:
147 return s->pending & s->is_fiq & s->enabled;
148 case ICPR:
149 return s->pending;
150 default:
151 printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
152 __func__, offset);
153 return 0;
154 }
155}
156
a8170e5e 157static void strongarm_pic_mem_write(void *opaque, hwaddr offset,
eb2fefbc 158 uint64_t value, unsigned size)
5bc95aa2
DES
159{
160 StrongARMPICState *s = opaque;
161
162 switch (offset) {
163 case ICMR:
164 s->enabled = value;
165 break;
166 case ICLR:
167 s->is_fiq = value;
168 break;
169 case ICCR:
170 s->int_idle = (value & 1) ? 0 : ~0;
171 break;
172 default:
173 printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
174 __func__, offset);
175 break;
176 }
177 strongarm_pic_update(s);
178}
179
eb2fefbc
AK
180static const MemoryRegionOps strongarm_pic_ops = {
181 .read = strongarm_pic_mem_read,
182 .write = strongarm_pic_mem_write,
183 .endianness = DEVICE_NATIVE_ENDIAN,
5bc95aa2
DES
184};
185
5a67508c 186static void strongarm_pic_initfn(Object *obj)
5bc95aa2 187{
5a67508c
XZ
188 DeviceState *dev = DEVICE(obj);
189 StrongARMPICState *s = STRONGARM_PIC(obj);
190 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
5bc95aa2 191
74e075f6 192 qdev_init_gpio_in(dev, strongarm_pic_set_irq, SA_PIC_SRCS);
5a67508c 193 memory_region_init_io(&s->iomem, obj, &strongarm_pic_ops, s,
64bde0f3 194 "pic", 0x1000);
74e075f6
AF
195 sysbus_init_mmio(sbd, &s->iomem);
196 sysbus_init_irq(sbd, &s->irq);
197 sysbus_init_irq(sbd, &s->fiq);
5bc95aa2
DES
198}
199
200static int strongarm_pic_post_load(void *opaque, int version_id)
201{
202 strongarm_pic_update(opaque);
203 return 0;
204}
205
206static VMStateDescription vmstate_strongarm_pic_regs = {
207 .name = "strongarm_pic",
208 .version_id = 0,
209 .minimum_version_id = 0,
5bc95aa2
DES
210 .post_load = strongarm_pic_post_load,
211 .fields = (VMStateField[]) {
212 VMSTATE_UINT32(pending, StrongARMPICState),
213 VMSTATE_UINT32(enabled, StrongARMPICState),
214 VMSTATE_UINT32(is_fiq, StrongARMPICState),
215 VMSTATE_UINT32(int_idle, StrongARMPICState),
216 VMSTATE_END_OF_LIST(),
217 },
218};
219
999e12bb
AL
220static void strongarm_pic_class_init(ObjectClass *klass, void *data)
221{
39bffca2 222 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 223
39bffca2
AL
224 dc->desc = "StrongARM PIC";
225 dc->vmsd = &vmstate_strongarm_pic_regs;
999e12bb
AL
226}
227
8c43a6f0 228static const TypeInfo strongarm_pic_info = {
74e075f6 229 .name = TYPE_STRONGARM_PIC,
39bffca2
AL
230 .parent = TYPE_SYS_BUS_DEVICE,
231 .instance_size = sizeof(StrongARMPICState),
5a67508c 232 .instance_init = strongarm_pic_initfn,
39bffca2 233 .class_init = strongarm_pic_class_init,
5bc95aa2
DES
234};
235
236/* Real-Time Clock */
237#define RTAR 0x00 /* RTC Alarm register */
238#define RCNR 0x04 /* RTC Counter register */
239#define RTTR 0x08 /* RTC Timer Trim register */
240#define RTSR 0x10 /* RTC Status register */
241
242#define RTSR_AL (1 << 0) /* RTC Alarm detected */
243#define RTSR_HZ (1 << 1) /* RTC 1Hz detected */
244#define RTSR_ALE (1 << 2) /* RTC Alarm enable */
245#define RTSR_HZE (1 << 3) /* RTC 1Hz enable */
246
247/* 16 LSB of RTTR are clockdiv for internal trim logic,
248 * trim delete isn't emulated, so
249 * f = 32 768 / (RTTR_trim + 1) */
250
4e002105
AF
251#define TYPE_STRONGARM_RTC "strongarm-rtc"
252#define STRONGARM_RTC(obj) \
253 OBJECT_CHECK(StrongARMRTCState, (obj), TYPE_STRONGARM_RTC)
254
255typedef struct StrongARMRTCState {
256 SysBusDevice parent_obj;
257
eb2fefbc 258 MemoryRegion iomem;
5bc95aa2
DES
259 uint32_t rttr;
260 uint32_t rtsr;
261 uint32_t rtar;
262 uint32_t last_rcnr;
263 int64_t last_hz;
264 QEMUTimer *rtc_alarm;
265 QEMUTimer *rtc_hz;
266 qemu_irq rtc_irq;
267 qemu_irq rtc_hz_irq;
268} StrongARMRTCState;
269
270static inline void strongarm_rtc_int_update(StrongARMRTCState *s)
271{
272 qemu_set_irq(s->rtc_irq, s->rtsr & RTSR_AL);
273 qemu_set_irq(s->rtc_hz_irq, s->rtsr & RTSR_HZ);
274}
275
276static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
277{
884f17c2 278 int64_t rt = qemu_clock_get_ms(rtc_clock);
5bc95aa2
DES
279 s->last_rcnr += ((rt - s->last_hz) << 15) /
280 (1000 * ((s->rttr & 0xffff) + 1));
281 s->last_hz = rt;
282}
283
284static inline void strongarm_rtc_timer_update(StrongARMRTCState *s)
285{
286 if ((s->rtsr & RTSR_HZE) && !(s->rtsr & RTSR_HZ)) {
bc72ad67 287 timer_mod(s->rtc_hz, s->last_hz + 1000);
5bc95aa2 288 } else {
bc72ad67 289 timer_del(s->rtc_hz);
5bc95aa2
DES
290 }
291
292 if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) {
bc72ad67 293 timer_mod(s->rtc_alarm, s->last_hz +
5bc95aa2
DES
294 (((s->rtar - s->last_rcnr) * 1000 *
295 ((s->rttr & 0xffff) + 1)) >> 15));
296 } else {
bc72ad67 297 timer_del(s->rtc_alarm);
5bc95aa2
DES
298 }
299}
300
301static inline void strongarm_rtc_alarm_tick(void *opaque)
302{
303 StrongARMRTCState *s = opaque;
304 s->rtsr |= RTSR_AL;
305 strongarm_rtc_timer_update(s);
306 strongarm_rtc_int_update(s);
307}
308
309static inline void strongarm_rtc_hz_tick(void *opaque)
310{
311 StrongARMRTCState *s = opaque;
312 s->rtsr |= RTSR_HZ;
313 strongarm_rtc_timer_update(s);
314 strongarm_rtc_int_update(s);
315}
316
a8170e5e 317static uint64_t strongarm_rtc_read(void *opaque, hwaddr addr,
eb2fefbc 318 unsigned size)
5bc95aa2
DES
319{
320 StrongARMRTCState *s = opaque;
321
322 switch (addr) {
323 case RTTR:
324 return s->rttr;
325 case RTSR:
326 return s->rtsr;
327 case RTAR:
328 return s->rtar;
329 case RCNR:
330 return s->last_rcnr +
884f17c2 331 ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
5bc95aa2
DES
332 (1000 * ((s->rttr & 0xffff) + 1));
333 default:
334 printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
335 return 0;
336 }
337}
338
a8170e5e 339static void strongarm_rtc_write(void *opaque, hwaddr addr,
eb2fefbc 340 uint64_t value, unsigned size)
5bc95aa2
DES
341{
342 StrongARMRTCState *s = opaque;
343 uint32_t old_rtsr;
344
345 switch (addr) {
346 case RTTR:
347 strongarm_rtc_hzupdate(s);
348 s->rttr = value;
349 strongarm_rtc_timer_update(s);
350 break;
351
352 case RTSR:
353 old_rtsr = s->rtsr;
354 s->rtsr = (value & (RTSR_ALE | RTSR_HZE)) |
355 (s->rtsr & ~(value & (RTSR_AL | RTSR_HZ)));
356
357 if (s->rtsr != old_rtsr) {
358 strongarm_rtc_timer_update(s);
359 }
360
361 strongarm_rtc_int_update(s);
362 break;
363
364 case RTAR:
365 s->rtar = value;
366 strongarm_rtc_timer_update(s);
367 break;
368
369 case RCNR:
370 strongarm_rtc_hzupdate(s);
371 s->last_rcnr = value;
372 strongarm_rtc_timer_update(s);
373 break;
374
375 default:
376 printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
377 }
378}
379
eb2fefbc
AK
380static const MemoryRegionOps strongarm_rtc_ops = {
381 .read = strongarm_rtc_read,
382 .write = strongarm_rtc_write,
383 .endianness = DEVICE_NATIVE_ENDIAN,
5bc95aa2
DES
384};
385
5a67508c 386static void strongarm_rtc_init(Object *obj)
5bc95aa2 387{
5a67508c
XZ
388 StrongARMRTCState *s = STRONGARM_RTC(obj);
389 SysBusDevice *dev = SYS_BUS_DEVICE(obj);
5bc95aa2 390 struct tm tm;
5bc95aa2
DES
391
392 s->rttr = 0x0;
393 s->rtsr = 0;
394
395 qemu_get_timedate(&tm, 0);
396
397 s->last_rcnr = (uint32_t) mktimegm(&tm);
884f17c2 398 s->last_hz = qemu_clock_get_ms(rtc_clock);
5bc95aa2 399
884f17c2
AB
400 s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
401 s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
5bc95aa2
DES
402
403 sysbus_init_irq(dev, &s->rtc_irq);
404 sysbus_init_irq(dev, &s->rtc_hz_irq);
405
5a67508c 406 memory_region_init_io(&s->iomem, obj, &strongarm_rtc_ops, s,
64bde0f3 407 "rtc", 0x10000);
750ecd44 408 sysbus_init_mmio(dev, &s->iomem);
5bc95aa2
DES
409}
410
44b1ff31 411static int strongarm_rtc_pre_save(void *opaque)
5bc95aa2
DES
412{
413 StrongARMRTCState *s = opaque;
414
415 strongarm_rtc_hzupdate(s);
44b1ff31
DDAG
416
417 return 0;
5bc95aa2
DES
418}
419
420static int strongarm_rtc_post_load(void *opaque, int version_id)
421{
422 StrongARMRTCState *s = opaque;
423
424 strongarm_rtc_timer_update(s);
425 strongarm_rtc_int_update(s);
426
427 return 0;
428}
429
430static const VMStateDescription vmstate_strongarm_rtc_regs = {
431 .name = "strongarm-rtc",
432 .version_id = 0,
433 .minimum_version_id = 0,
5bc95aa2
DES
434 .pre_save = strongarm_rtc_pre_save,
435 .post_load = strongarm_rtc_post_load,
436 .fields = (VMStateField[]) {
437 VMSTATE_UINT32(rttr, StrongARMRTCState),
438 VMSTATE_UINT32(rtsr, StrongARMRTCState),
439 VMSTATE_UINT32(rtar, StrongARMRTCState),
440 VMSTATE_UINT32(last_rcnr, StrongARMRTCState),
441 VMSTATE_INT64(last_hz, StrongARMRTCState),
442 VMSTATE_END_OF_LIST(),
443 },
444};
445
999e12bb
AL
446static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data)
447{
39bffca2 448 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 449
39bffca2
AL
450 dc->desc = "StrongARM RTC Controller";
451 dc->vmsd = &vmstate_strongarm_rtc_regs;
999e12bb
AL
452}
453
8c43a6f0 454static const TypeInfo strongarm_rtc_sysbus_info = {
4e002105 455 .name = TYPE_STRONGARM_RTC,
39bffca2
AL
456 .parent = TYPE_SYS_BUS_DEVICE,
457 .instance_size = sizeof(StrongARMRTCState),
5a67508c 458 .instance_init = strongarm_rtc_init,
39bffca2 459 .class_init = strongarm_rtc_sysbus_class_init,
5bc95aa2
DES
460};
461
462/* GPIO */
463#define GPLR 0x00
464#define GPDR 0x04
465#define GPSR 0x08
466#define GPCR 0x0c
467#define GRER 0x10
468#define GFER 0x14
469#define GEDR 0x18
470#define GAFR 0x1c
471
f55beb84
AF
472#define TYPE_STRONGARM_GPIO "strongarm-gpio"
473#define STRONGARM_GPIO(obj) \
474 OBJECT_CHECK(StrongARMGPIOInfo, (obj), TYPE_STRONGARM_GPIO)
475
5bc95aa2
DES
476typedef struct StrongARMGPIOInfo StrongARMGPIOInfo;
477struct StrongARMGPIOInfo {
478 SysBusDevice busdev;
eb2fefbc 479 MemoryRegion iomem;
5bc95aa2
DES
480 qemu_irq handler[28];
481 qemu_irq irqs[11];
482 qemu_irq irqX;
483
484 uint32_t ilevel;
485 uint32_t olevel;
486 uint32_t dir;
487 uint32_t rising;
488 uint32_t falling;
489 uint32_t status;
5bc95aa2
DES
490 uint32_t gafr;
491
492 uint32_t prev_level;
493};
494
495
496static void strongarm_gpio_irq_update(StrongARMGPIOInfo *s)
497{
498 int i;
499 for (i = 0; i < 11; i++) {
500 qemu_set_irq(s->irqs[i], s->status & (1 << i));
501 }
502
503 qemu_set_irq(s->irqX, (s->status & ~0x7ff));
504}
505
506static void strongarm_gpio_set(void *opaque, int line, int level)
507{
508 StrongARMGPIOInfo *s = opaque;
509 uint32_t mask;
510
511 mask = 1 << line;
512
513 if (level) {
514 s->status |= s->rising & mask &
515 ~s->ilevel & ~s->dir;
516 s->ilevel |= mask;
517 } else {
518 s->status |= s->falling & mask &
519 s->ilevel & ~s->dir;
520 s->ilevel &= ~mask;
521 }
522
523 if (s->status & mask) {
524 strongarm_gpio_irq_update(s);
525 }
526}
527
528static void strongarm_gpio_handler_update(StrongARMGPIOInfo *s)
529{
530 uint32_t level, diff;
531 int bit;
532
533 level = s->olevel & s->dir;
534
535 for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
786a4ea8 536 bit = ctz32(diff);
5bc95aa2
DES
537 qemu_set_irq(s->handler[bit], (level >> bit) & 1);
538 }
539
540 s->prev_level = level;
541}
542
a8170e5e 543static uint64_t strongarm_gpio_read(void *opaque, hwaddr offset,
eb2fefbc 544 unsigned size)
5bc95aa2
DES
545{
546 StrongARMGPIOInfo *s = opaque;
547
548 switch (offset) {
549 case GPDR: /* GPIO Pin-Direction registers */
550 return s->dir;
551
552 case GPSR: /* GPIO Pin-Output Set registers */
92335a0d
PM
553 qemu_log_mask(LOG_GUEST_ERROR,
554 "strongarm GPIO: read from write only register GPSR\n");
555 return 0;
5bc95aa2
DES
556
557 case GPCR: /* GPIO Pin-Output Clear registers */
92335a0d
PM
558 qemu_log_mask(LOG_GUEST_ERROR,
559 "strongarm GPIO: read from write only register GPCR\n");
560 return 0;
5bc95aa2
DES
561
562 case GRER: /* GPIO Rising-Edge Detect Enable registers */
563 return s->rising;
564
565 case GFER: /* GPIO Falling-Edge Detect Enable registers */
566 return s->falling;
567
568 case GAFR: /* GPIO Alternate Function registers */
569 return s->gafr;
570
571 case GPLR: /* GPIO Pin-Level registers */
572 return (s->olevel & s->dir) |
573 (s->ilevel & ~s->dir);
574
575 case GEDR: /* GPIO Edge Detect Status registers */
576 return s->status;
577
578 default:
579 printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
580 }
581
582 return 0;
583}
584
a8170e5e 585static void strongarm_gpio_write(void *opaque, hwaddr offset,
eb2fefbc 586 uint64_t value, unsigned size)
5bc95aa2
DES
587{
588 StrongARMGPIOInfo *s = opaque;
589
590 switch (offset) {
591 case GPDR: /* GPIO Pin-Direction registers */
9a93b2fa 592 s->dir = value & 0x0fffffff;
5bc95aa2
DES
593 strongarm_gpio_handler_update(s);
594 break;
595
596 case GPSR: /* GPIO Pin-Output Set registers */
9a93b2fa 597 s->olevel |= value & 0x0fffffff;
5bc95aa2 598 strongarm_gpio_handler_update(s);
5bc95aa2
DES
599 break;
600
601 case GPCR: /* GPIO Pin-Output Clear registers */
602 s->olevel &= ~value;
603 strongarm_gpio_handler_update(s);
604 break;
605
606 case GRER: /* GPIO Rising-Edge Detect Enable registers */
607 s->rising = value;
608 break;
609
610 case GFER: /* GPIO Falling-Edge Detect Enable registers */
611 s->falling = value;
612 break;
613
614 case GAFR: /* GPIO Alternate Function registers */
615 s->gafr = value;
616 break;
617
618 case GEDR: /* GPIO Edge Detect Status registers */
619 s->status &= ~value;
620 strongarm_gpio_irq_update(s);
621 break;
622
623 default:
624 printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
625 }
626}
627
eb2fefbc
AK
628static const MemoryRegionOps strongarm_gpio_ops = {
629 .read = strongarm_gpio_read,
630 .write = strongarm_gpio_write,
631 .endianness = DEVICE_NATIVE_ENDIAN,
5bc95aa2
DES
632};
633
a8170e5e 634static DeviceState *strongarm_gpio_init(hwaddr base,
5bc95aa2
DES
635 DeviceState *pic)
636{
637 DeviceState *dev;
638 int i;
639
f55beb84 640 dev = qdev_create(NULL, TYPE_STRONGARM_GPIO);
5bc95aa2
DES
641 qdev_init_nofail(dev);
642
1356b98d 643 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
5bc95aa2 644 for (i = 0; i < 12; i++)
1356b98d 645 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
5bc95aa2
DES
646 qdev_get_gpio_in(pic, SA_PIC_GPIO0_EDGE + i));
647
648 return dev;
649}
650
5a67508c 651static void strongarm_gpio_initfn(Object *obj)
5bc95aa2 652{
5a67508c
XZ
653 DeviceState *dev = DEVICE(obj);
654 StrongARMGPIOInfo *s = STRONGARM_GPIO(obj);
655 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
5bc95aa2
DES
656 int i;
657
f55beb84
AF
658 qdev_init_gpio_in(dev, strongarm_gpio_set, 28);
659 qdev_init_gpio_out(dev, s->handler, 28);
5bc95aa2 660
5a67508c 661 memory_region_init_io(&s->iomem, obj, &strongarm_gpio_ops, s,
64bde0f3 662 "gpio", 0x1000);
5bc95aa2 663
f55beb84 664 sysbus_init_mmio(sbd, &s->iomem);
5bc95aa2 665 for (i = 0; i < 11; i++) {
f55beb84 666 sysbus_init_irq(sbd, &s->irqs[i]);
5bc95aa2 667 }
f55beb84 668 sysbus_init_irq(sbd, &s->irqX);
5bc95aa2
DES
669}
670
671static const VMStateDescription vmstate_strongarm_gpio_regs = {
672 .name = "strongarm-gpio",
673 .version_id = 0,
674 .minimum_version_id = 0,
5bc95aa2
DES
675 .fields = (VMStateField[]) {
676 VMSTATE_UINT32(ilevel, StrongARMGPIOInfo),
677 VMSTATE_UINT32(olevel, StrongARMGPIOInfo),
678 VMSTATE_UINT32(dir, StrongARMGPIOInfo),
679 VMSTATE_UINT32(rising, StrongARMGPIOInfo),
680 VMSTATE_UINT32(falling, StrongARMGPIOInfo),
681 VMSTATE_UINT32(status, StrongARMGPIOInfo),
682 VMSTATE_UINT32(gafr, StrongARMGPIOInfo),
ed657d71 683 VMSTATE_UINT32(prev_level, StrongARMGPIOInfo),
5bc95aa2
DES
684 VMSTATE_END_OF_LIST(),
685 },
686};
687
999e12bb
AL
688static void strongarm_gpio_class_init(ObjectClass *klass, void *data)
689{
39bffca2 690 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 691
39bffca2 692 dc->desc = "StrongARM GPIO controller";
ed657d71 693 dc->vmsd = &vmstate_strongarm_gpio_regs;
999e12bb
AL
694}
695
8c43a6f0 696static const TypeInfo strongarm_gpio_info = {
f55beb84 697 .name = TYPE_STRONGARM_GPIO,
39bffca2
AL
698 .parent = TYPE_SYS_BUS_DEVICE,
699 .instance_size = sizeof(StrongARMGPIOInfo),
5a67508c 700 .instance_init = strongarm_gpio_initfn,
39bffca2 701 .class_init = strongarm_gpio_class_init,
5bc95aa2
DES
702};
703
704/* Peripheral Pin Controller */
705#define PPDR 0x00
706#define PPSR 0x04
707#define PPAR 0x08
708#define PSDR 0x0c
709#define PPFR 0x10
710
c71e6732
AF
711#define TYPE_STRONGARM_PPC "strongarm-ppc"
712#define STRONGARM_PPC(obj) \
713 OBJECT_CHECK(StrongARMPPCInfo, (obj), TYPE_STRONGARM_PPC)
714
5bc95aa2
DES
715typedef struct StrongARMPPCInfo StrongARMPPCInfo;
716struct StrongARMPPCInfo {
c71e6732
AF
717 SysBusDevice parent_obj;
718
eb2fefbc 719 MemoryRegion iomem;
5bc95aa2
DES
720 qemu_irq handler[28];
721
722 uint32_t ilevel;
723 uint32_t olevel;
724 uint32_t dir;
725 uint32_t ppar;
726 uint32_t psdr;
727 uint32_t ppfr;
728
729 uint32_t prev_level;
730};
731
732static void strongarm_ppc_set(void *opaque, int line, int level)
733{
734 StrongARMPPCInfo *s = opaque;
735
736 if (level) {
737 s->ilevel |= 1 << line;
738 } else {
739 s->ilevel &= ~(1 << line);
740 }
741}
742
743static void strongarm_ppc_handler_update(StrongARMPPCInfo *s)
744{
745 uint32_t level, diff;
746 int bit;
747
748 level = s->olevel & s->dir;
749
750 for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
786a4ea8 751 bit = ctz32(diff);
5bc95aa2
DES
752 qemu_set_irq(s->handler[bit], (level >> bit) & 1);
753 }
754
755 s->prev_level = level;
756}
757
a8170e5e 758static uint64_t strongarm_ppc_read(void *opaque, hwaddr offset,
eb2fefbc 759 unsigned size)
5bc95aa2
DES
760{
761 StrongARMPPCInfo *s = opaque;
762
763 switch (offset) {
764 case PPDR: /* PPC Pin Direction registers */
765 return s->dir | ~0x3fffff;
766
767 case PPSR: /* PPC Pin State registers */
768 return (s->olevel & s->dir) |
769 (s->ilevel & ~s->dir) |
770 ~0x3fffff;
771
772 case PPAR:
773 return s->ppar | ~0x41000;
774
775 case PSDR:
776 return s->psdr;
777
778 case PPFR:
779 return s->ppfr | ~0x7f001;
780
781 default:
782 printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
783 }
784
785 return 0;
786}
787
a8170e5e 788static void strongarm_ppc_write(void *opaque, hwaddr offset,
eb2fefbc 789 uint64_t value, unsigned size)
5bc95aa2
DES
790{
791 StrongARMPPCInfo *s = opaque;
792
793 switch (offset) {
794 case PPDR: /* PPC Pin Direction registers */
795 s->dir = value & 0x3fffff;
796 strongarm_ppc_handler_update(s);
797 break;
798
799 case PPSR: /* PPC Pin State registers */
800 s->olevel = value & s->dir & 0x3fffff;
801 strongarm_ppc_handler_update(s);
802 break;
803
804 case PPAR:
805 s->ppar = value & 0x41000;
806 break;
807
808 case PSDR:
809 s->psdr = value & 0x3fffff;
810 break;
811
812 case PPFR:
813 s->ppfr = value & 0x7f001;
814 break;
815
816 default:
817 printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
818 }
819}
820
eb2fefbc
AK
821static const MemoryRegionOps strongarm_ppc_ops = {
822 .read = strongarm_ppc_read,
823 .write = strongarm_ppc_write,
824 .endianness = DEVICE_NATIVE_ENDIAN,
5bc95aa2
DES
825};
826
5a67508c 827static void strongarm_ppc_init(Object *obj)
5bc95aa2 828{
5a67508c
XZ
829 DeviceState *dev = DEVICE(obj);
830 StrongARMPPCInfo *s = STRONGARM_PPC(obj);
831 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
5bc95aa2 832
c71e6732
AF
833 qdev_init_gpio_in(dev, strongarm_ppc_set, 22);
834 qdev_init_gpio_out(dev, s->handler, 22);
5bc95aa2 835
5a67508c 836 memory_region_init_io(&s->iomem, obj, &strongarm_ppc_ops, s,
64bde0f3 837 "ppc", 0x1000);
5bc95aa2 838
c71e6732 839 sysbus_init_mmio(sbd, &s->iomem);
5bc95aa2
DES
840}
841
842static const VMStateDescription vmstate_strongarm_ppc_regs = {
843 .name = "strongarm-ppc",
844 .version_id = 0,
845 .minimum_version_id = 0,
5bc95aa2
DES
846 .fields = (VMStateField[]) {
847 VMSTATE_UINT32(ilevel, StrongARMPPCInfo),
848 VMSTATE_UINT32(olevel, StrongARMPPCInfo),
849 VMSTATE_UINT32(dir, StrongARMPPCInfo),
850 VMSTATE_UINT32(ppar, StrongARMPPCInfo),
851 VMSTATE_UINT32(psdr, StrongARMPPCInfo),
852 VMSTATE_UINT32(ppfr, StrongARMPPCInfo),
ed657d71 853 VMSTATE_UINT32(prev_level, StrongARMPPCInfo),
5bc95aa2
DES
854 VMSTATE_END_OF_LIST(),
855 },
856};
857
999e12bb
AL
858static void strongarm_ppc_class_init(ObjectClass *klass, void *data)
859{
39bffca2 860 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 861
39bffca2 862 dc->desc = "StrongARM PPC controller";
ed657d71 863 dc->vmsd = &vmstate_strongarm_ppc_regs;
999e12bb
AL
864}
865
8c43a6f0 866static const TypeInfo strongarm_ppc_info = {
c71e6732 867 .name = TYPE_STRONGARM_PPC,
39bffca2
AL
868 .parent = TYPE_SYS_BUS_DEVICE,
869 .instance_size = sizeof(StrongARMPPCInfo),
5a67508c 870 .instance_init = strongarm_ppc_init,
39bffca2 871 .class_init = strongarm_ppc_class_init,
5bc95aa2
DES
872};
873
874/* UART Ports */
875#define UTCR0 0x00
876#define UTCR1 0x04
877#define UTCR2 0x08
878#define UTCR3 0x0c
879#define UTDR 0x14
880#define UTSR0 0x1c
881#define UTSR1 0x20
882
883#define UTCR0_PE (1 << 0) /* Parity enable */
884#define UTCR0_OES (1 << 1) /* Even parity */
885#define UTCR0_SBS (1 << 2) /* 2 stop bits */
886#define UTCR0_DSS (1 << 3) /* 8-bit data */
887
888#define UTCR3_RXE (1 << 0) /* Rx enable */
889#define UTCR3_TXE (1 << 1) /* Tx enable */
890#define UTCR3_BRK (1 << 2) /* Force Break */
891#define UTCR3_RIE (1 << 3) /* Rx int enable */
892#define UTCR3_TIE (1 << 4) /* Tx int enable */
893#define UTCR3_LBM (1 << 5) /* Loopback */
894
895#define UTSR0_TFS (1 << 0) /* Tx FIFO nearly empty */
896#define UTSR0_RFS (1 << 1) /* Rx FIFO nearly full */
897#define UTSR0_RID (1 << 2) /* Receiver Idle */
898#define UTSR0_RBB (1 << 3) /* Receiver begin break */
899#define UTSR0_REB (1 << 4) /* Receiver end break */
900#define UTSR0_EIF (1 << 5) /* Error in FIFO */
901
902#define UTSR1_RNE (1 << 1) /* Receive FIFO not empty */
903#define UTSR1_TNF (1 << 2) /* Transmit FIFO not full */
904#define UTSR1_PRE (1 << 3) /* Parity error */
905#define UTSR1_FRE (1 << 4) /* Frame error */
906#define UTSR1_ROR (1 << 5) /* Receive Over Run */
907
908#define RX_FIFO_PRE (1 << 8)
909#define RX_FIFO_FRE (1 << 9)
910#define RX_FIFO_ROR (1 << 10)
911
fff3af97
AF
912#define TYPE_STRONGARM_UART "strongarm-uart"
913#define STRONGARM_UART(obj) \
914 OBJECT_CHECK(StrongARMUARTState, (obj), TYPE_STRONGARM_UART)
915
916typedef struct StrongARMUARTState {
917 SysBusDevice parent_obj;
918
eb2fefbc 919 MemoryRegion iomem;
becdfa00 920 CharBackend chr;
5bc95aa2
DES
921 qemu_irq irq;
922
923 uint8_t utcr0;
924 uint16_t brd;
925 uint8_t utcr3;
926 uint8_t utsr0;
927 uint8_t utsr1;
928
929 uint8_t tx_fifo[8];
930 uint8_t tx_start;
931 uint8_t tx_len;
932 uint16_t rx_fifo[12]; /* value + error flags in high bits */
933 uint8_t rx_start;
934 uint8_t rx_len;
935
936 uint64_t char_transmit_time; /* time to transmit a char in ticks*/
937 bool wait_break_end;
938 QEMUTimer *rx_timeout_timer;
939 QEMUTimer *tx_timer;
940} StrongARMUARTState;
941
942static void strongarm_uart_update_status(StrongARMUARTState *s)
943{
944 uint16_t utsr1 = 0;
945
946 if (s->tx_len != 8) {
947 utsr1 |= UTSR1_TNF;
948 }
949
950 if (s->rx_len != 0) {
951 uint16_t ent = s->rx_fifo[s->rx_start];
952
953 utsr1 |= UTSR1_RNE;
954 if (ent & RX_FIFO_PRE) {
955 s->utsr1 |= UTSR1_PRE;
956 }
957 if (ent & RX_FIFO_FRE) {
958 s->utsr1 |= UTSR1_FRE;
959 }
960 if (ent & RX_FIFO_ROR) {
961 s->utsr1 |= UTSR1_ROR;
962 }
963 }
964
965 s->utsr1 = utsr1;
966}
967
968static void strongarm_uart_update_int_status(StrongARMUARTState *s)
969{
970 uint16_t utsr0 = s->utsr0 &
971 (UTSR0_REB | UTSR0_RBB | UTSR0_RID);
972 int i;
973
974 if ((s->utcr3 & UTCR3_TXE) &&
975 (s->utcr3 & UTCR3_TIE) &&
976 s->tx_len <= 4) {
977 utsr0 |= UTSR0_TFS;
978 }
979
980 if ((s->utcr3 & UTCR3_RXE) &&
981 (s->utcr3 & UTCR3_RIE) &&
982 s->rx_len > 4) {
983 utsr0 |= UTSR0_RFS;
984 }
985
986 for (i = 0; i < s->rx_len && i < 4; i++)
987 if (s->rx_fifo[(s->rx_start + i) % 12] & ~0xff) {
988 utsr0 |= UTSR0_EIF;
989 break;
990 }
991
992 s->utsr0 = utsr0;
993 qemu_set_irq(s->irq, utsr0);
994}
995
996static void strongarm_uart_update_parameters(StrongARMUARTState *s)
997{
998 int speed, parity, data_bits, stop_bits, frame_size;
999 QEMUSerialSetParams ssp;
1000
1001 /* Start bit. */
1002 frame_size = 1;
1003 if (s->utcr0 & UTCR0_PE) {
1004 /* Parity bit. */
1005 frame_size++;
1006 if (s->utcr0 & UTCR0_OES) {
1007 parity = 'E';
1008 } else {
1009 parity = 'O';
1010 }
1011 } else {
1012 parity = 'N';
1013 }
1014 if (s->utcr0 & UTCR0_SBS) {
1015 stop_bits = 2;
1016 } else {
1017 stop_bits = 1;
1018 }
1019
1020 data_bits = (s->utcr0 & UTCR0_DSS) ? 8 : 7;
1021 frame_size += data_bits + stop_bits;
1022 speed = 3686400 / 16 / (s->brd + 1);
1023 ssp.speed = speed;
1024 ssp.parity = parity;
1025 ssp.data_bits = data_bits;
1026 ssp.stop_bits = stop_bits;
73bcb24d 1027 s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
fa394ed6 1028 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
5bc95aa2
DES
1029
1030 DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label,
1031 speed, parity, data_bits, stop_bits);
1032}
1033
1034static void strongarm_uart_rx_to(void *opaque)
1035{
1036 StrongARMUARTState *s = opaque;
1037
1038 if (s->rx_len) {
1039 s->utsr0 |= UTSR0_RID;
1040 strongarm_uart_update_int_status(s);
1041 }
1042}
1043
1044static void strongarm_uart_rx_push(StrongARMUARTState *s, uint16_t c)
1045{
1046 if ((s->utcr3 & UTCR3_RXE) == 0) {
1047 /* rx disabled */
1048 return;
1049 }
1050
1051 if (s->wait_break_end) {
1052 s->utsr0 |= UTSR0_REB;
1053 s->wait_break_end = false;
1054 }
1055
1056 if (s->rx_len < 12) {
1057 s->rx_fifo[(s->rx_start + s->rx_len) % 12] = c;
1058 s->rx_len++;
1059 } else
1060 s->rx_fifo[(s->rx_start + 11) % 12] |= RX_FIFO_ROR;
1061}
1062
1063static int strongarm_uart_can_receive(void *opaque)
1064{
1065 StrongARMUARTState *s = opaque;
1066
1067 if (s->rx_len == 12) {
1068 return 0;
1069 }
1070 /* It's best not to get more than 2/3 of RX FIFO, so advertise that much */
1071 if (s->rx_len < 8) {
1072 return 8 - s->rx_len;
1073 }
1074 return 1;
1075}
1076
1077static void strongarm_uart_receive(void *opaque, const uint8_t *buf, int size)
1078{
1079 StrongARMUARTState *s = opaque;
1080 int i;
1081
1082 for (i = 0; i < size; i++) {
1083 strongarm_uart_rx_push(s, buf[i]);
1084 }
1085
1086 /* call the timeout receive callback in 3 char transmit time */
bc72ad67
AB
1087 timer_mod(s->rx_timeout_timer,
1088 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
5bc95aa2
DES
1089
1090 strongarm_uart_update_status(s);
1091 strongarm_uart_update_int_status(s);
1092}
1093
1094static void strongarm_uart_event(void *opaque, int event)
1095{
1096 StrongARMUARTState *s = opaque;
1097 if (event == CHR_EVENT_BREAK) {
1098 s->utsr0 |= UTSR0_RBB;
1099 strongarm_uart_rx_push(s, RX_FIFO_FRE);
1100 s->wait_break_end = true;
1101 strongarm_uart_update_status(s);
1102 strongarm_uart_update_int_status(s);
1103 }
1104}
1105
1106static void strongarm_uart_tx(void *opaque)
1107{
1108 StrongARMUARTState *s = opaque;
bc72ad67 1109 uint64_t new_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
5bc95aa2
DES
1110
1111 if (s->utcr3 & UTCR3_LBM) /* loopback */ {
1112 strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
30650701 1113 } else if (qemu_chr_fe_backend_connected(&s->chr)) {
6ab3fc32
DB
1114 /* XXX this blocks entire thread. Rewrite to use
1115 * qemu_chr_fe_write and background I/O callbacks */
5345fdb4 1116 qemu_chr_fe_write_all(&s->chr, &s->tx_fifo[s->tx_start], 1);
5bc95aa2
DES
1117 }
1118
1119 s->tx_start = (s->tx_start + 1) % 8;
1120 s->tx_len--;
1121 if (s->tx_len) {
bc72ad67 1122 timer_mod(s->tx_timer, new_xmit_ts + s->char_transmit_time);
5bc95aa2
DES
1123 }
1124 strongarm_uart_update_status(s);
1125 strongarm_uart_update_int_status(s);
1126}
1127
a8170e5e 1128static uint64_t strongarm_uart_read(void *opaque, hwaddr addr,
eb2fefbc 1129 unsigned size)
5bc95aa2
DES
1130{
1131 StrongARMUARTState *s = opaque;
1132 uint16_t ret;
1133
1134 switch (addr) {
1135 case UTCR0:
1136 return s->utcr0;
1137
1138 case UTCR1:
1139 return s->brd >> 8;
1140
1141 case UTCR2:
1142 return s->brd & 0xff;
1143
1144 case UTCR3:
1145 return s->utcr3;
1146
1147 case UTDR:
1148 if (s->rx_len != 0) {
1149 ret = s->rx_fifo[s->rx_start];
1150 s->rx_start = (s->rx_start + 1) % 12;
1151 s->rx_len--;
1152 strongarm_uart_update_status(s);
1153 strongarm_uart_update_int_status(s);
1154 return ret;
1155 }
1156 return 0;
1157
1158 case UTSR0:
1159 return s->utsr0;
1160
1161 case UTSR1:
1162 return s->utsr1;
1163
1164 default:
1165 printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
1166 return 0;
1167 }
1168}
1169
a8170e5e 1170static void strongarm_uart_write(void *opaque, hwaddr addr,
eb2fefbc 1171 uint64_t value, unsigned size)
5bc95aa2
DES
1172{
1173 StrongARMUARTState *s = opaque;
1174
1175 switch (addr) {
1176 case UTCR0:
1177 s->utcr0 = value & 0x7f;
1178 strongarm_uart_update_parameters(s);
1179 break;
1180
1181 case UTCR1:
1182 s->brd = (s->brd & 0xff) | ((value & 0xf) << 8);
1183 strongarm_uart_update_parameters(s);
1184 break;
1185
1186 case UTCR2:
1187 s->brd = (s->brd & 0xf00) | (value & 0xff);
1188 strongarm_uart_update_parameters(s);
1189 break;
1190
1191 case UTCR3:
1192 s->utcr3 = value & 0x3f;
1193 if ((s->utcr3 & UTCR3_RXE) == 0) {
1194 s->rx_len = 0;
1195 }
1196 if ((s->utcr3 & UTCR3_TXE) == 0) {
1197 s->tx_len = 0;
1198 }
1199 strongarm_uart_update_status(s);
1200 strongarm_uart_update_int_status(s);
1201 break;
1202
1203 case UTDR:
1204 if ((s->utcr3 & UTCR3_TXE) && s->tx_len != 8) {
1205 s->tx_fifo[(s->tx_start + s->tx_len) % 8] = value;
1206 s->tx_len++;
1207 strongarm_uart_update_status(s);
1208 strongarm_uart_update_int_status(s);
1209 if (s->tx_len == 1) {
1210 strongarm_uart_tx(s);
1211 }
1212 }
1213 break;
1214
1215 case UTSR0:
1216 s->utsr0 = s->utsr0 & ~(value &
1217 (UTSR0_REB | UTSR0_RBB | UTSR0_RID));
1218 strongarm_uart_update_int_status(s);
1219 break;
1220
1221 default:
1222 printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
1223 }
1224}
1225
eb2fefbc
AK
1226static const MemoryRegionOps strongarm_uart_ops = {
1227 .read = strongarm_uart_read,
1228 .write = strongarm_uart_write,
1229 .endianness = DEVICE_NATIVE_ENDIAN,
5bc95aa2
DES
1230};
1231
5a67508c 1232static void strongarm_uart_init(Object *obj)
5bc95aa2 1233{
5a67508c
XZ
1234 StrongARMUARTState *s = STRONGARM_UART(obj);
1235 SysBusDevice *dev = SYS_BUS_DEVICE(obj);
5bc95aa2 1236
5a67508c 1237 memory_region_init_io(&s->iomem, obj, &strongarm_uart_ops, s,
64bde0f3 1238 "uart", 0x10000);
750ecd44 1239 sysbus_init_mmio(dev, &s->iomem);
5bc95aa2
DES
1240 sysbus_init_irq(dev, &s->irq);
1241
bc72ad67
AB
1242 s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
1243 s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
8934515a
XZ
1244}
1245
1246static void strongarm_uart_realize(DeviceState *dev, Error **errp)
1247{
1248 StrongARMUARTState *s = STRONGARM_UART(dev);
5bc95aa2 1249
fa394ed6
MAL
1250 qemu_chr_fe_set_handlers(&s->chr,
1251 strongarm_uart_can_receive,
1252 strongarm_uart_receive,
1253 strongarm_uart_event,
81517ba3 1254 NULL, s, NULL, true);
5bc95aa2
DES
1255}
1256
1257static void strongarm_uart_reset(DeviceState *dev)
1258{
fff3af97 1259 StrongARMUARTState *s = STRONGARM_UART(dev);
5bc95aa2
DES
1260
1261 s->utcr0 = UTCR0_DSS; /* 8 data, no parity */
1262 s->brd = 23; /* 9600 */
1263 /* enable send & recv - this actually violates spec */
1264 s->utcr3 = UTCR3_TXE | UTCR3_RXE;
1265
1266 s->rx_len = s->tx_len = 0;
1267
1268 strongarm_uart_update_parameters(s);
1269 strongarm_uart_update_status(s);
1270 strongarm_uart_update_int_status(s);
1271}
1272
1273static int strongarm_uart_post_load(void *opaque, int version_id)
1274{
1275 StrongARMUARTState *s = opaque;
1276
1277 strongarm_uart_update_parameters(s);
1278 strongarm_uart_update_status(s);
1279 strongarm_uart_update_int_status(s);
1280
1281 /* tx and restart timer */
1282 if (s->tx_len) {
1283 strongarm_uart_tx(s);
1284 }
1285
1286 /* restart rx timeout timer */
1287 if (s->rx_len) {
bc72ad67
AB
1288 timer_mod(s->rx_timeout_timer,
1289 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
5bc95aa2
DES
1290 }
1291
1292 return 0;
1293}
1294
1295static const VMStateDescription vmstate_strongarm_uart_regs = {
1296 .name = "strongarm-uart",
1297 .version_id = 0,
1298 .minimum_version_id = 0,
5bc95aa2
DES
1299 .post_load = strongarm_uart_post_load,
1300 .fields = (VMStateField[]) {
1301 VMSTATE_UINT8(utcr0, StrongARMUARTState),
1302 VMSTATE_UINT16(brd, StrongARMUARTState),
1303 VMSTATE_UINT8(utcr3, StrongARMUARTState),
1304 VMSTATE_UINT8(utsr0, StrongARMUARTState),
1305 VMSTATE_UINT8_ARRAY(tx_fifo, StrongARMUARTState, 8),
1306 VMSTATE_UINT8(tx_start, StrongARMUARTState),
1307 VMSTATE_UINT8(tx_len, StrongARMUARTState),
1308 VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMUARTState, 12),
1309 VMSTATE_UINT8(rx_start, StrongARMUARTState),
1310 VMSTATE_UINT8(rx_len, StrongARMUARTState),
1311 VMSTATE_BOOL(wait_break_end, StrongARMUARTState),
1312 VMSTATE_END_OF_LIST(),
1313 },
1314};
1315
999e12bb
AL
1316static Property strongarm_uart_properties[] = {
1317 DEFINE_PROP_CHR("chardev", StrongARMUARTState, chr),
1318 DEFINE_PROP_END_OF_LIST(),
1319};
1320
1321static void strongarm_uart_class_init(ObjectClass *klass, void *data)
1322{
39bffca2 1323 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 1324
39bffca2
AL
1325 dc->desc = "StrongARM UART controller";
1326 dc->reset = strongarm_uart_reset;
1327 dc->vmsd = &vmstate_strongarm_uart_regs;
1328 dc->props = strongarm_uart_properties;
8934515a 1329 dc->realize = strongarm_uart_realize;
999e12bb
AL
1330}
1331
8c43a6f0 1332static const TypeInfo strongarm_uart_info = {
fff3af97 1333 .name = TYPE_STRONGARM_UART,
39bffca2
AL
1334 .parent = TYPE_SYS_BUS_DEVICE,
1335 .instance_size = sizeof(StrongARMUARTState),
5a67508c 1336 .instance_init = strongarm_uart_init,
39bffca2 1337 .class_init = strongarm_uart_class_init,
5bc95aa2
DES
1338};
1339
1340/* Synchronous Serial Ports */
0ca81872
AF
1341
1342#define TYPE_STRONGARM_SSP "strongarm-ssp"
1343#define STRONGARM_SSP(obj) \
1344 OBJECT_CHECK(StrongARMSSPState, (obj), TYPE_STRONGARM_SSP)
1345
1346typedef struct StrongARMSSPState {
1347 SysBusDevice parent_obj;
1348
eb2fefbc 1349 MemoryRegion iomem;
5bc95aa2
DES
1350 qemu_irq irq;
1351 SSIBus *bus;
1352
1353 uint16_t sscr[2];
1354 uint16_t sssr;
1355
1356 uint16_t rx_fifo[8];
1357 uint8_t rx_level;
1358 uint8_t rx_start;
1359} StrongARMSSPState;
1360
1361#define SSCR0 0x60 /* SSP Control register 0 */
1362#define SSCR1 0x64 /* SSP Control register 1 */
1363#define SSDR 0x6c /* SSP Data register */
1364#define SSSR 0x74 /* SSP Status register */
1365
1366/* Bitfields for above registers */
1367#define SSCR0_SPI(x) (((x) & 0x30) == 0x00)
1368#define SSCR0_SSP(x) (((x) & 0x30) == 0x10)
1369#define SSCR0_UWIRE(x) (((x) & 0x30) == 0x20)
1370#define SSCR0_PSP(x) (((x) & 0x30) == 0x30)
1371#define SSCR0_SSE (1 << 7)
1372#define SSCR0_DSS(x) (((x) & 0xf) + 1)
1373#define SSCR1_RIE (1 << 0)
1374#define SSCR1_TIE (1 << 1)
1375#define SSCR1_LBM (1 << 2)
1376#define SSSR_TNF (1 << 2)
1377#define SSSR_RNE (1 << 3)
1378#define SSSR_TFS (1 << 5)
1379#define SSSR_RFS (1 << 6)
1380#define SSSR_ROR (1 << 7)
1381#define SSSR_RW 0x0080
1382
1383static void strongarm_ssp_int_update(StrongARMSSPState *s)
1384{
1385 int level = 0;
1386
1387 level |= (s->sssr & SSSR_ROR);
1388 level |= (s->sssr & SSSR_RFS) && (s->sscr[1] & SSCR1_RIE);
1389 level |= (s->sssr & SSSR_TFS) && (s->sscr[1] & SSCR1_TIE);
1390 qemu_set_irq(s->irq, level);
1391}
1392
1393static void strongarm_ssp_fifo_update(StrongARMSSPState *s)
1394{
1395 s->sssr &= ~SSSR_TFS;
1396 s->sssr &= ~SSSR_TNF;
1397 if (s->sscr[0] & SSCR0_SSE) {
1398 if (s->rx_level >= 4) {
1399 s->sssr |= SSSR_RFS;
1400 } else {
1401 s->sssr &= ~SSSR_RFS;
1402 }
1403 if (s->rx_level) {
1404 s->sssr |= SSSR_RNE;
1405 } else {
1406 s->sssr &= ~SSSR_RNE;
1407 }
1408 /* TX FIFO is never filled, so it is always in underrun
1409 condition if SSP is enabled */
1410 s->sssr |= SSSR_TFS;
1411 s->sssr |= SSSR_TNF;
1412 }
1413
1414 strongarm_ssp_int_update(s);
1415}
1416
a8170e5e 1417static uint64_t strongarm_ssp_read(void *opaque, hwaddr addr,
eb2fefbc 1418 unsigned size)
5bc95aa2
DES
1419{
1420 StrongARMSSPState *s = opaque;
1421 uint32_t retval;
1422
1423 switch (addr) {
1424 case SSCR0:
1425 return s->sscr[0];
1426 case SSCR1:
1427 return s->sscr[1];
1428 case SSSR:
1429 return s->sssr;
1430 case SSDR:
1431 if (~s->sscr[0] & SSCR0_SSE) {
1432 return 0xffffffff;
1433 }
1434 if (s->rx_level < 1) {
1435 printf("%s: SSP Rx Underrun\n", __func__);
1436 return 0xffffffff;
1437 }
1438 s->rx_level--;
1439 retval = s->rx_fifo[s->rx_start++];
1440 s->rx_start &= 0x7;
1441 strongarm_ssp_fifo_update(s);
1442 return retval;
1443 default:
1444 printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
1445 break;
1446 }
1447 return 0;
1448}
1449
a8170e5e 1450static void strongarm_ssp_write(void *opaque, hwaddr addr,
eb2fefbc 1451 uint64_t value, unsigned size)
5bc95aa2
DES
1452{
1453 StrongARMSSPState *s = opaque;
1454
1455 switch (addr) {
1456 case SSCR0:
1457 s->sscr[0] = value & 0xffbf;
1458 if ((s->sscr[0] & SSCR0_SSE) && SSCR0_DSS(value) < 4) {
1459 printf("%s: Wrong data size: %i bits\n", __func__,
eb2fefbc 1460 (int)SSCR0_DSS(value));
5bc95aa2
DES
1461 }
1462 if (!(value & SSCR0_SSE)) {
1463 s->sssr = 0;
1464 s->rx_level = 0;
1465 }
1466 strongarm_ssp_fifo_update(s);
1467 break;
1468
1469 case SSCR1:
1470 s->sscr[1] = value & 0x2f;
1471 if (value & SSCR1_LBM) {
1472 printf("%s: Attempt to use SSP LBM mode\n", __func__);
1473 }
1474 strongarm_ssp_fifo_update(s);
1475 break;
1476
1477 case SSSR:
1478 s->sssr &= ~(value & SSSR_RW);
1479 strongarm_ssp_int_update(s);
1480 break;
1481
1482 case SSDR:
1483 if (SSCR0_UWIRE(s->sscr[0])) {
1484 value &= 0xff;
1485 } else
1486 /* Note how 32bits overflow does no harm here */
1487 value &= (1 << SSCR0_DSS(s->sscr[0])) - 1;
1488
1489 /* Data goes from here to the Tx FIFO and is shifted out from
1490 * there directly to the slave, no need to buffer it.
1491 */
1492 if (s->sscr[0] & SSCR0_SSE) {
1493 uint32_t readval;
1494 if (s->sscr[1] & SSCR1_LBM) {
1495 readval = value;
1496 } else {
1497 readval = ssi_transfer(s->bus, value);
1498 }
1499
1500 if (s->rx_level < 0x08) {
1501 s->rx_fifo[(s->rx_start + s->rx_level++) & 0x7] = readval;
1502 } else {
1503 s->sssr |= SSSR_ROR;
1504 }
1505 }
1506 strongarm_ssp_fifo_update(s);
1507 break;
1508
1509 default:
1510 printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
1511 break;
1512 }
1513}
1514
eb2fefbc
AK
1515static const MemoryRegionOps strongarm_ssp_ops = {
1516 .read = strongarm_ssp_read,
1517 .write = strongarm_ssp_write,
1518 .endianness = DEVICE_NATIVE_ENDIAN,
5bc95aa2
DES
1519};
1520
1521static int strongarm_ssp_post_load(void *opaque, int version_id)
1522{
1523 StrongARMSSPState *s = opaque;
1524
1525 strongarm_ssp_fifo_update(s);
1526
1527 return 0;
1528}
1529
8934515a 1530static void strongarm_ssp_init(Object *obj)
5bc95aa2 1531{
8934515a 1532 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
0ca81872
AF
1533 DeviceState *dev = DEVICE(sbd);
1534 StrongARMSSPState *s = STRONGARM_SSP(dev);
5bc95aa2 1535
0ca81872 1536 sysbus_init_irq(sbd, &s->irq);
5bc95aa2 1537
8934515a 1538 memory_region_init_io(&s->iomem, obj, &strongarm_ssp_ops, s,
64bde0f3 1539 "ssp", 0x1000);
0ca81872 1540 sysbus_init_mmio(sbd, &s->iomem);
5bc95aa2 1541
0ca81872 1542 s->bus = ssi_create_bus(dev, "ssi");
5bc95aa2
DES
1543}
1544
1545static void strongarm_ssp_reset(DeviceState *dev)
1546{
0ca81872
AF
1547 StrongARMSSPState *s = STRONGARM_SSP(dev);
1548
5bc95aa2
DES
1549 s->sssr = 0x03; /* 3 bit data, SPI, disabled */
1550 s->rx_start = 0;
1551 s->rx_level = 0;
1552}
1553
1554static const VMStateDescription vmstate_strongarm_ssp_regs = {
1555 .name = "strongarm-ssp",
1556 .version_id = 0,
1557 .minimum_version_id = 0,
5bc95aa2
DES
1558 .post_load = strongarm_ssp_post_load,
1559 .fields = (VMStateField[]) {
1560 VMSTATE_UINT16_ARRAY(sscr, StrongARMSSPState, 2),
1561 VMSTATE_UINT16(sssr, StrongARMSSPState),
1562 VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMSSPState, 8),
1563 VMSTATE_UINT8(rx_start, StrongARMSSPState),
1564 VMSTATE_UINT8(rx_level, StrongARMSSPState),
1565 VMSTATE_END_OF_LIST(),
1566 },
1567};
1568
999e12bb
AL
1569static void strongarm_ssp_class_init(ObjectClass *klass, void *data)
1570{
39bffca2 1571 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 1572
39bffca2
AL
1573 dc->desc = "StrongARM SSP controller";
1574 dc->reset = strongarm_ssp_reset;
1575 dc->vmsd = &vmstate_strongarm_ssp_regs;
999e12bb
AL
1576}
1577
8c43a6f0 1578static const TypeInfo strongarm_ssp_info = {
0ca81872 1579 .name = TYPE_STRONGARM_SSP,
39bffca2
AL
1580 .parent = TYPE_SYS_BUS_DEVICE,
1581 .instance_size = sizeof(StrongARMSSPState),
8934515a 1582 .instance_init = strongarm_ssp_init,
39bffca2 1583 .class_init = strongarm_ssp_class_init,
5bc95aa2
DES
1584};
1585
1586/* Main CPU functions */
eb2fefbc 1587StrongARMState *sa1110_init(MemoryRegion *sysmem,
ba1ba5cc 1588 unsigned int sdram_size, const char *cpu_type)
5bc95aa2
DES
1589{
1590 StrongARMState *s;
5bc95aa2
DES
1591 int i;
1592
b45c03f5 1593 s = g_new0(StrongARMState, 1);
5bc95aa2 1594
ba1ba5cc 1595 if (strncmp(cpu_type, "sa1110", 6)) {
6daf194d 1596 error_report("Machine requires a SA1110 processor.");
5bc95aa2
DES
1597 exit(1);
1598 }
1599
ba1ba5cc 1600 s->cpu = ARM_CPU(cpu_create(cpu_type));
5bc95aa2 1601
c8623c02
DM
1602 memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram",
1603 sdram_size);
eb2fefbc 1604 memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
5bc95aa2 1605
5bc95aa2 1606 s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
4f071cf9
PM
1607 qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
1608 qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ),
1609 NULL);
5bc95aa2
DES
1610
1611 sysbus_create_varargs("pxa25x-timer", 0x90000000,
1612 qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
1613 qdev_get_gpio_in(s->pic, SA_PIC_OSTC1),
1614 qdev_get_gpio_in(s->pic, SA_PIC_OSTC2),
1615 qdev_get_gpio_in(s->pic, SA_PIC_OSTC3),
1616 NULL);
1617
4e002105 1618 sysbus_create_simple(TYPE_STRONGARM_RTC, 0x90010000,
5bc95aa2
DES
1619 qdev_get_gpio_in(s->pic, SA_PIC_RTC_ALARM));
1620
1621 s->gpio = strongarm_gpio_init(0x90040000, s->pic);
1622
c71e6732 1623 s->ppc = sysbus_create_varargs(TYPE_STRONGARM_PPC, 0x90060000, NULL);
5bc95aa2
DES
1624
1625 for (i = 0; sa_serial[i].io_base; i++) {
fff3af97 1626 DeviceState *dev = qdev_create(NULL, TYPE_STRONGARM_UART);
9bca0edb 1627 qdev_prop_set_chr(dev, "chardev", serial_hd(i));
5bc95aa2 1628 qdev_init_nofail(dev);
1356b98d 1629 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0,
5bc95aa2 1630 sa_serial[i].io_base);
1356b98d 1631 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
5bc95aa2
DES
1632 qdev_get_gpio_in(s->pic, sa_serial[i].irq));
1633 }
1634
0ca81872 1635 s->ssp = sysbus_create_varargs(TYPE_STRONGARM_SSP, 0x80070000,
5bc95aa2
DES
1636 qdev_get_gpio_in(s->pic, SA_PIC_SSP), NULL);
1637 s->ssp_bus = (SSIBus *)qdev_get_child_bus(s->ssp, "ssi");
1638
1639 return s;
1640}
1641
83f7d43a 1642static void strongarm_register_types(void)
5bc95aa2 1643{
39bffca2
AL
1644 type_register_static(&strongarm_pic_info);
1645 type_register_static(&strongarm_rtc_sysbus_info);
1646 type_register_static(&strongarm_gpio_info);
1647 type_register_static(&strongarm_ppc_info);
1648 type_register_static(&strongarm_uart_info);
1649 type_register_static(&strongarm_ssp_info);
5bc95aa2 1650}
83f7d43a
AF
1651
1652type_init(strongarm_register_types)