Statistics
| Branch: | Revision:

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)