]> Git Repo - qemu.git/blob - hw/arm/ast2400.c
build: Use $(CCAS) for compiling .S files
[qemu.git] / hw / arm / ast2400.c
1 /*
2  * AST2400 SoC
3  *
4  * Andrew Jeffery <[email protected]>
5  * Jeremy Kerr <[email protected]>
6  *
7  * Copyright 2016 IBM Corp.
8  *
9  * This code is licensed under the GPL version 2 or later.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "qemu-common.h"
16 #include "cpu.h"
17 #include "exec/address-spaces.h"
18 #include "hw/arm/ast2400.h"
19 #include "hw/char/serial.h"
20 #include "qemu/log.h"
21 #include "hw/i2c/aspeed_i2c.h"
22
23 #define AST2400_UART_5_BASE      0x00184000
24 #define AST2400_IOMEM_SIZE       0x00200000
25 #define AST2400_IOMEM_BASE       0x1E600000
26 #define AST2400_SMC_BASE         AST2400_IOMEM_BASE /* Legacy SMC */
27 #define AST2400_FMC_BASE         0X1E620000
28 #define AST2400_SPI_BASE         0X1E630000
29 #define AST2400_VIC_BASE         0x1E6C0000
30 #define AST2400_SCU_BASE         0x1E6E2000
31 #define AST2400_TIMER_BASE       0x1E782000
32 #define AST2400_I2C_BASE         0x1E78A000
33
34 #define AST2400_FMC_FLASH_BASE   0x20000000
35 #define AST2400_SPI_FLASH_BASE   0x30000000
36
37 #define AST2400_A0_SILICON_REV   0x02000303
38
39 static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
40 static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
41
42 /*
43  * IO handlers: simply catch any reads/writes to IO addresses that aren't
44  * handled by a device mapping.
45  */
46
47 static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned size)
48 {
49     qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
50                   __func__, offset, size);
51     return 0;
52 }
53
54 static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t value,
55                 unsigned size)
56 {
57     qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
58                   __func__, offset, value, size);
59 }
60
61 static const MemoryRegionOps ast2400_io_ops = {
62     .read = ast2400_io_read,
63     .write = ast2400_io_write,
64     .endianness = DEVICE_LITTLE_ENDIAN,
65 };
66
67 static void ast2400_init(Object *obj)
68 {
69     AST2400State *s = AST2400(obj);
70
71     s->cpu = cpu_arm_init("arm926");
72
73     object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
74     object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
75     qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
76
77     object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
78     object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
79     qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
80
81     object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
82     object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
83     qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
84
85     object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
86     object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
87     qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
88     qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
89                          AST2400_A0_SILICON_REV);
90     object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
91                               "hw-strap1", &error_abort);
92     object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
93                               "hw-strap2", &error_abort);
94
95     object_initialize(&s->smc, sizeof(s->smc), "aspeed.smc.fmc");
96     object_property_add_child(obj, "smc", OBJECT(&s->smc), NULL);
97     qdev_set_parent_bus(DEVICE(&s->smc), sysbus_get_default());
98
99     object_initialize(&s->spi, sizeof(s->spi), "aspeed.smc.spi");
100     object_property_add_child(obj, "spi", OBJECT(&s->spi), NULL);
101     qdev_set_parent_bus(DEVICE(&s->spi), sysbus_get_default());
102 }
103
104 static void ast2400_realize(DeviceState *dev, Error **errp)
105 {
106     int i;
107     AST2400State *s = AST2400(dev);
108     Error *err = NULL, *local_err = NULL;
109
110     /* IO space */
111     memory_region_init_io(&s->iomem, NULL, &ast2400_io_ops, NULL,
112             "ast2400.io", AST2400_IOMEM_SIZE);
113     memory_region_add_subregion_overlap(get_system_memory(), AST2400_IOMEM_BASE,
114             &s->iomem, -1);
115
116     /* VIC */
117     object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
118     if (err) {
119         error_propagate(errp, err);
120         return;
121     }
122     sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, AST2400_VIC_BASE);
123     sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
124                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
125     sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
126                        qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
127
128     /* Timer */
129     object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
130     if (err) {
131         error_propagate(errp, err);
132         return;
133     }
134     sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, AST2400_TIMER_BASE);
135     for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
136         qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
137         sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
138     }
139
140     /* SCU */
141     object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
142     if (err) {
143         error_propagate(errp, err);
144         return;
145     }
146     sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, AST2400_SCU_BASE);
147
148     /* UART - attach an 8250 to the IO space as our UART5 */
149     if (serial_hds[0]) {
150         qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
151         serial_mm_init(&s->iomem, AST2400_UART_5_BASE, 2,
152                        uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
153     }
154
155     /* I2C */
156     object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
157     if (err) {
158         error_propagate(errp, err);
159         return;
160     }
161     sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, AST2400_I2C_BASE);
162     sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
163                        qdev_get_gpio_in(DEVICE(&s->vic), 12));
164
165     /* SMC */
166     object_property_set_int(OBJECT(&s->smc), 1, "num-cs", &err);
167     object_property_set_bool(OBJECT(&s->smc), true, "realized", &local_err);
168     error_propagate(&err, local_err);
169     if (err) {
170         error_propagate(errp, err);
171         return;
172     }
173     sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 0, AST2400_FMC_BASE);
174     sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 1, AST2400_FMC_FLASH_BASE);
175     sysbus_connect_irq(SYS_BUS_DEVICE(&s->smc), 0,
176                        qdev_get_gpio_in(DEVICE(&s->vic), 19));
177
178     /* SPI */
179     object_property_set_int(OBJECT(&s->spi), 1, "num-cs", &err);
180     object_property_set_bool(OBJECT(&s->spi), true, "realized", &local_err);
181     error_propagate(&err, local_err);
182     if (err) {
183         error_propagate(errp, err);
184         return;
185     }
186     sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, AST2400_SPI_BASE);
187     sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1, AST2400_SPI_FLASH_BASE);
188 }
189
190 static void ast2400_class_init(ObjectClass *oc, void *data)
191 {
192     DeviceClass *dc = DEVICE_CLASS(oc);
193
194     dc->realize = ast2400_realize;
195
196     /*
197      * Reason: creates an ARM CPU, thus use after free(), see
198      * arm_cpu_class_init()
199      */
200     dc->cannot_destroy_with_object_finalize_yet = true;
201 }
202
203 static const TypeInfo ast2400_type_info = {
204     .name = TYPE_AST2400,
205     .parent = TYPE_SYS_BUS_DEVICE,
206     .instance_size = sizeof(AST2400State),
207     .instance_init = ast2400_init,
208     .class_init = ast2400_class_init,
209 };
210
211 static void ast2400_register_types(void)
212 {
213     type_register_static(&ast2400_type_info);
214 }
215
216 type_init(ast2400_register_types)
This page took 0.035629 seconds and 4 git commands to generate.