Revision 40905a6a hw/stellaris.c
b/hw/stellaris.c | ||
---|---|---|
10 | 10 |
#include "sysbus.h" |
11 | 11 |
#include "ssi.h" |
12 | 12 |
#include "arm-misc.h" |
13 |
#include "primecell.h" |
|
14 | 13 |
#include "devices.h" |
15 | 14 |
#include "qemu-timer.h" |
16 | 15 |
#include "i2c.h" |
... | ... | |
45 | 44 |
/* General purpose timer module. */ |
46 | 45 |
|
47 | 46 |
typedef struct gptm_state { |
47 |
SysBusDevice busdev; |
|
48 | 48 |
uint32_t config; |
49 | 49 |
uint32_t mode[2]; |
50 | 50 |
uint32_t control; |
... | ... | |
112 | 112 |
s->state |= 1; |
113 | 113 |
if ((s->control & 0x20)) { |
114 | 114 |
/* Output trigger. */ |
115 |
qemu_irq_raise(s->trigger); |
|
116 |
qemu_irq_lower(s->trigger); |
|
115 |
qemu_irq_pulse(s->trigger); |
|
117 | 116 |
} |
118 | 117 |
if (s->mode[0] & 1) { |
119 | 118 |
/* One-shot. */ |
... | ... | |
340 | 339 |
return 0; |
341 | 340 |
} |
342 | 341 |
|
343 |
static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger)
|
|
342 |
static void stellaris_gptm_init(SysBusDevice *dev)
|
|
344 | 343 |
{ |
345 | 344 |
int iomemtype; |
346 |
gptm_state *s; |
|
345 |
gptm_state *s = FROM_SYSBUS(gptm_state, dev);
|
|
347 | 346 |
|
348 |
s = (gptm_state *)qemu_mallocz(sizeof(gptm_state)); |
|
349 |
s->irq = irq; |
|
350 |
s->trigger = trigger; |
|
351 |
s->opaque[0] = s->opaque[1] = s; |
|
347 |
sysbus_init_irq(dev, &s->irq); |
|
348 |
qdev_init_gpio_out(&dev->qdev, &s->trigger, 1); |
|
352 | 349 |
|
353 | 350 |
iomemtype = cpu_register_io_memory(0, gptm_readfn, |
354 | 351 |
gptm_writefn, s); |
355 |
cpu_register_physical_memory(base, 0x00001000, iomemtype); |
|
352 |
sysbus_init_mmio(dev, 0x1000, iomemtype); |
|
353 |
|
|
354 |
s->opaque[0] = s->opaque[1] = s; |
|
356 | 355 |
s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]); |
357 | 356 |
s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]); |
358 | 357 |
register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s); |
... | ... | |
906 | 905 |
|
907 | 906 |
typedef struct |
908 | 907 |
{ |
908 |
SysBusDevice busdev; |
|
909 | 909 |
uint32_t actss; |
910 | 910 |
uint32_t ris; |
911 | 911 |
uint32_t im; |
... | ... | |
1178 | 1178 |
return 0; |
1179 | 1179 |
} |
1180 | 1180 |
|
1181 |
static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq *irq)
|
|
1181 |
static void stellaris_adc_init(SysBusDevice *dev)
|
|
1182 | 1182 |
{ |
1183 |
stellaris_adc_state *s; |
|
1183 |
stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
|
|
1184 | 1184 |
int iomemtype; |
1185 |
qemu_irq *qi; |
|
1186 | 1185 |
int n; |
1187 | 1186 |
|
1188 |
s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state)); |
|
1189 | 1187 |
for (n = 0; n < 4; n++) { |
1190 |
s->irq[n] = irq[n];
|
|
1188 |
sysbus_init_irq(dev, &s->irq[n]);
|
|
1191 | 1189 |
} |
1192 | 1190 |
|
1193 | 1191 |
iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn, |
1194 | 1192 |
stellaris_adc_writefn, s); |
1195 |
cpu_register_physical_memory(base, 0x00001000, iomemtype);
|
|
1193 |
sysbus_init_mmio(dev, 0x1000, iomemtype);
|
|
1196 | 1194 |
stellaris_adc_reset(s); |
1197 |
qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1);
|
|
1195 |
qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
|
|
1198 | 1196 |
register_savevm("stellaris_adc", -1, 1, |
1199 | 1197 |
stellaris_adc_save, stellaris_adc_load, s); |
1200 |
return qi[0]; |
|
1201 | 1198 |
} |
1202 | 1199 |
|
1203 | 1200 |
/* Some boards have both an OLED controller and SD card connected to |
... | ... | |
1294 | 1291 |
static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; |
1295 | 1292 |
|
1296 | 1293 |
qemu_irq *pic; |
1297 |
qemu_irq *gpio_in[7]; |
|
1298 |
qemu_irq *gpio_out[7]; |
|
1294 |
DeviceState *gpio_dev[7]; |
|
1295 |
qemu_irq gpio_in[7][8]; |
|
1296 |
qemu_irq gpio_out[7][8]; |
|
1299 | 1297 |
qemu_irq adc; |
1300 | 1298 |
int sram_size; |
1301 | 1299 |
int flash_size; |
1302 | 1300 |
i2c_bus *i2c; |
1301 |
DeviceState *dev; |
|
1303 | 1302 |
int i; |
1303 |
int j; |
|
1304 | 1304 |
|
1305 | 1305 |
flash_size = ((board->dc0 & 0xffff) + 1) << 1; |
1306 | 1306 |
sram_size = (board->dc0 >> 18) + 1; |
1307 | 1307 |
pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); |
1308 | 1308 |
|
1309 | 1309 |
if (board->dc1 & (1 << 16)) { |
1310 |
adc = stellaris_adc_init(0x40038000, pic + 14); |
|
1310 |
dev = sysbus_create_varargs("stellaris-adc", 0x40038000, |
|
1311 |
pic[14], pic[15], pic[16], pic[17], NULL); |
|
1312 |
adc = qdev_get_gpio_in(dev, 0); |
|
1311 | 1313 |
} else { |
1312 | 1314 |
adc = NULL; |
1313 | 1315 |
} |
1314 | 1316 |
for (i = 0; i < 4; i++) { |
1315 | 1317 |
if (board->dc2 & (0x10000 << i)) { |
1316 |
stellaris_gptm_init(0x40030000 + i * 0x1000, |
|
1317 |
pic[timer_irq[i]], adc); |
|
1318 |
dev = sysbus_create_simple("stellaris-gptm", |
|
1319 |
0x40030000 + i * 0x1000, |
|
1320 |
pic[timer_irq[i]]); |
|
1321 |
/* TODO: This is incorrect, but we get away with it because |
|
1322 |
the ADC output is only ever pulsed. */ |
|
1323 |
qdev_connect_gpio_out(dev, 0, adc); |
|
1318 | 1324 |
} |
1319 | 1325 |
} |
1320 | 1326 |
|
... | ... | |
1322 | 1328 |
|
1323 | 1329 |
for (i = 0; i < 7; i++) { |
1324 | 1330 |
if (board->dc4 & (1 << i)) { |
1325 |
gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]], |
|
1326 |
&gpio_out[i]); |
|
1331 |
gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i], |
|
1332 |
pic[gpio_irq[i]]); |
|
1333 |
for (j = 0; j < 8; j++) { |
|
1334 |
gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j); |
|
1335 |
gpio_out[i][j] = NULL; |
|
1336 |
} |
|
1327 | 1337 |
} |
1328 | 1338 |
} |
1329 | 1339 |
|
1330 | 1340 |
if (board->dc2 & (1 << 12)) { |
1331 |
DeviceState *dev; |
|
1332 | 1341 |
dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]); |
1333 | 1342 |
i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); |
1334 | 1343 |
if (board->peripherals & BP_OLED_I2C) { |
... | ... | |
1343 | 1352 |
} |
1344 | 1353 |
} |
1345 | 1354 |
if (board->dc2 & (1 << 4)) { |
1346 |
DeviceState *dev; |
|
1347 | 1355 |
dev = sysbus_create_simple("pl022", 0x40008000, pic[7]); |
1348 | 1356 |
if (board->peripherals & BP_OLED_SSI) { |
1349 | 1357 |
DeviceState *mux; |
... | ... | |
1387 | 1395 |
|
1388 | 1396 |
stellaris_gamepad_init(5, gpad_irq, gpad_keycode); |
1389 | 1397 |
} |
1398 |
for (i = 0; i < 7; i++) { |
|
1399 |
if (board->dc4 & (1 << i)) { |
|
1400 |
for (j = 0; j < 8; j++) { |
|
1401 |
if (gpio_out[i][j]) { |
|
1402 |
qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]); |
|
1403 |
} |
|
1404 |
} |
|
1405 |
} |
|
1406 |
} |
|
1390 | 1407 |
} |
1391 | 1408 |
|
1392 | 1409 |
/* FIXME: Figure out how to generate these from stellaris_boards. */ |
... | ... | |
1435 | 1452 |
{ |
1436 | 1453 |
sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state), |
1437 | 1454 |
stellaris_i2c_init); |
1455 |
sysbus_register_dev("stellaris-gptm", sizeof(gptm_state), |
|
1456 |
stellaris_gptm_init); |
|
1457 |
sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state), |
|
1458 |
stellaris_adc_init); |
|
1438 | 1459 |
ssi_register_slave("evb6965-ssi", sizeof(stellaris_ssi_bus_state), |
1439 | 1460 |
&stellaris_ssi_bus_info); |
1440 | 1461 |
} |
Also available in: Unified diff