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