root / hw / arm / digic.c @ 142593c9
History | View | Annotate | Download (3.2 kB)
1 |
/*
|
---|---|
2 |
* QEMU model of the Canon DIGIC SoC.
|
3 |
*
|
4 |
* Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
|
5 |
*
|
6 |
* This model is based on reverse engineering efforts
|
7 |
* made by CHDK (http://chdk.wikia.com) and
|
8 |
* Magic Lantern (http://www.magiclantern.fm) projects
|
9 |
* contributors.
|
10 |
*
|
11 |
* This program is free software; you can redistribute it and/or modify
|
12 |
* it under the terms of the GNU General Public License as published by
|
13 |
* the Free Software Foundation; either version 2 of the License, or
|
14 |
* (at your option) any later version.
|
15 |
*
|
16 |
* This program is distributed in the hope that it will be useful,
|
17 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 |
* GNU General Public License for more details.
|
20 |
*
|
21 |
*/
|
22 |
|
23 |
#include "hw/arm/digic.h" |
24 |
|
25 |
#define DIGIC4_TIMER_BASE(n) (0xc0210000 + (n) * 0x100) |
26 |
|
27 |
#define DIGIC_UART_BASE 0xc0800000 |
28 |
|
29 |
static void digic_init(Object *obj) |
30 |
{ |
31 |
DigicState *s = DIGIC(obj); |
32 |
DeviceState *dev; |
33 |
int i;
|
34 |
|
35 |
object_initialize(&s->cpu, sizeof(s->cpu), "arm946-" TYPE_ARM_CPU); |
36 |
object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL); |
37 |
|
38 |
for (i = 0; i < DIGIC4_NB_TIMERS; i++) { |
39 |
#define DIGIC_TIMER_NAME_MLEN 11 |
40 |
char name[DIGIC_TIMER_NAME_MLEN];
|
41 |
|
42 |
object_initialize(&s->timer[i], sizeof(s->timer[i]), TYPE_DIGIC_TIMER);
|
43 |
dev = DEVICE(&s->timer[i]); |
44 |
qdev_set_parent_bus(dev, sysbus_get_default()); |
45 |
snprintf(name, DIGIC_TIMER_NAME_MLEN, "timer[%d]", i);
|
46 |
object_property_add_child(obj, name, OBJECT(&s->timer[i]), NULL);
|
47 |
} |
48 |
|
49 |
object_initialize(&s->uart, sizeof(s->uart), TYPE_DIGIC_UART);
|
50 |
dev = DEVICE(&s->uart); |
51 |
qdev_set_parent_bus(dev, sysbus_get_default()); |
52 |
object_property_add_child(obj, "uart", OBJECT(&s->uart), NULL); |
53 |
} |
54 |
|
55 |
static void digic_realize(DeviceState *dev, Error **errp) |
56 |
{ |
57 |
DigicState *s = DIGIC(dev); |
58 |
Error *err = NULL;
|
59 |
SysBusDevice *sbd; |
60 |
int i;
|
61 |
|
62 |
object_property_set_bool(OBJECT(&s->cpu), true, "reset-hivecs", &err); |
63 |
if (err != NULL) { |
64 |
error_propagate(errp, err); |
65 |
return;
|
66 |
} |
67 |
|
68 |
object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err); |
69 |
if (err != NULL) { |
70 |
error_propagate(errp, err); |
71 |
return;
|
72 |
} |
73 |
|
74 |
for (i = 0; i < DIGIC4_NB_TIMERS; i++) { |
75 |
object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err); |
76 |
if (err != NULL) { |
77 |
error_propagate(errp, err); |
78 |
return;
|
79 |
} |
80 |
|
81 |
sbd = SYS_BUS_DEVICE(&s->timer[i]); |
82 |
sysbus_mmio_map(sbd, 0, DIGIC4_TIMER_BASE(i));
|
83 |
} |
84 |
|
85 |
object_property_set_bool(OBJECT(&s->uart), true, "realized", &err); |
86 |
if (err != NULL) { |
87 |
error_propagate(errp, err); |
88 |
return;
|
89 |
} |
90 |
|
91 |
sbd = SYS_BUS_DEVICE(&s->uart); |
92 |
sysbus_mmio_map(sbd, 0, DIGIC_UART_BASE);
|
93 |
} |
94 |
|
95 |
static void digic_class_init(ObjectClass *oc, void *data) |
96 |
{ |
97 |
DeviceClass *dc = DEVICE_CLASS(oc); |
98 |
|
99 |
dc->realize = digic_realize; |
100 |
} |
101 |
|
102 |
static const TypeInfo digic_type_info = { |
103 |
.name = TYPE_DIGIC, |
104 |
.parent = TYPE_DEVICE, |
105 |
.instance_size = sizeof(DigicState),
|
106 |
.instance_init = digic_init, |
107 |
.class_init = digic_class_init, |
108 |
}; |
109 |
|
110 |
static void digic_register_types(void) |
111 |
{ |
112 |
type_register_static(&digic_type_info); |
113 |
} |
114 |
|
115 |
type_init(digic_register_types) |