*/
#include "qemu/osdep.h"
-#include "exec/address-spaces.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "hw/qdev-core.h"
-#include "cpu.h"
#include "hw/sysbus.h"
#include "hw/char/serial.h"
#include "hw/misc/unimp.h"
#include "hw/loader.h"
#include "sysemu/sysemu.h"
#include "hw/arm/allwinner-h3.h"
+#include "target/arm/cpu-qom.h"
+#include "target/arm/gtimer.h"
/* Memory map */
const hwaddr allwinner_h3_memmap[] = {
[AW_H3_DEV_OHCI3] = 0x01c1d400,
[AW_H3_DEV_CCU] = 0x01c20000,
[AW_H3_DEV_PIT] = 0x01c20c00,
+ [AW_H3_DEV_WDT] = 0x01c20ca0,
[AW_H3_DEV_UART0] = 0x01c28000,
[AW_H3_DEV_UART1] = 0x01c28400,
[AW_H3_DEV_UART2] = 0x01c28800,
[AW_H3_DEV_UART3] = 0x01c28c00,
+ [AW_H3_DEV_TWI0] = 0x01c2ac00,
+ [AW_H3_DEV_TWI1] = 0x01c2b000,
+ [AW_H3_DEV_TWI2] = 0x01c2b400,
[AW_H3_DEV_EMAC] = 0x01c30000,
[AW_H3_DEV_DRAMCOM] = 0x01c62000,
[AW_H3_DEV_DRAMCTL] = 0x01c63000,
[AW_H3_DEV_GIC_VCPU] = 0x01c86000,
[AW_H3_DEV_RTC] = 0x01f00000,
[AW_H3_DEV_CPUCFG] = 0x01f01c00,
+ [AW_H3_DEV_R_TWI] = 0x01f02400,
[AW_H3_DEV_SDRAM] = 0x40000000
};
{ "uart1", 0x01c28400, 1 * KiB },
{ "uart2", 0x01c28800, 1 * KiB },
{ "uart3", 0x01c28c00, 1 * KiB },
- { "twi0", 0x01c2ac00, 1 * KiB },
- { "twi1", 0x01c2b000, 1 * KiB },
- { "twi2", 0x01c2b400, 1 * KiB },
{ "scr", 0x01c2c400, 1 * KiB },
{ "gpu", 0x01c40000, 64 * KiB },
{ "hstmr", 0x01c60000, 4 * KiB },
{ "r_prcm", 0x01f01400, 1 * KiB },
{ "r_twd", 0x01f01800, 1 * KiB },
{ "r_cir-rx", 0x01f02000, 1 * KiB },
- { "r_twi", 0x01f02400, 1 * KiB },
{ "r_uart", 0x01f02800, 1 * KiB },
{ "r_pio", 0x01f02c00, 1 * KiB },
{ "r_pwm", 0x01f03800, 1 * KiB },
AW_H3_GIC_SPI_UART1 = 1,
AW_H3_GIC_SPI_UART2 = 2,
AW_H3_GIC_SPI_UART3 = 3,
+ AW_H3_GIC_SPI_TWI0 = 6,
+ AW_H3_GIC_SPI_TWI1 = 7,
+ AW_H3_GIC_SPI_TWI2 = 8,
AW_H3_GIC_SPI_TIMER0 = 18,
AW_H3_GIC_SPI_TIMER1 = 19,
+ AW_H3_GIC_SPI_R_TWI = 44,
AW_H3_GIC_SPI_MMC0 = 60,
AW_H3_GIC_SPI_EHCI0 = 72,
AW_H3_GIC_SPI_OHCI0 = 73,
const int64_t rom_size = 32 * KiB;
g_autofree uint8_t *buffer = g_new0(uint8_t, rom_size);
- if (blk_pread(blk, 8 * KiB, buffer, rom_size) < 0) {
+ if (blk_pread(blk, 8 * KiB, rom_size, buffer, 0) < 0) {
error_setg(&error_fatal, "%s: failed to read BlockBackend data",
__func__);
return;
"ram-size");
object_initialize_child(obj, "rtc", &s->rtc, TYPE_AW_RTC_SUN6I);
+
+ object_initialize_child(obj, "twi0", &s->i2c0, TYPE_AW_I2C_SUN6I);
+ object_initialize_child(obj, "twi1", &s->i2c1, TYPE_AW_I2C_SUN6I);
+ object_initialize_child(obj, "twi2", &s->i2c2, TYPE_AW_I2C_SUN6I);
+ object_initialize_child(obj, "r_twi", &s->r_twi, TYPE_AW_I2C_SUN6I);
+
+ object_initialize_child(obj, "wdt", &s->wdt, TYPE_AW_WDT_SUN6I);
}
static void allwinner_h3_realize(DeviceState *dev, Error **errp)
/* CPUs */
for (i = 0; i < AW_H3_NUM_CPUS; i++) {
- /* Provide Power State Coordination Interface */
- qdev_prop_set_int32(DEVICE(&s->cpus[i]), "psci-conduit",
- QEMU_PSCI_CONDUIT_HVC);
-
- /* Disable secondary CPUs */
+ /*
+ * Disable secondary CPUs. Guest EL3 firmware will start
+ * them via CPU reset control registers.
+ */
qdev_prop_set_bit(DEVICE(&s->cpus[i]), "start-powered-off",
i > 0);
sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, s->memmap[AW_H3_DEV_RTC]);
+ /* I2C */
+ sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, s->memmap[AW_H3_DEV_TWI0]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0,
+ qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_TWI0));
+
+ sysbus_realize(SYS_BUS_DEVICE(&s->i2c1), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c1), 0, s->memmap[AW_H3_DEV_TWI1]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c1), 0,
+ qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_TWI1));
+
+ sysbus_realize(SYS_BUS_DEVICE(&s->i2c2), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c2), 0, s->memmap[AW_H3_DEV_TWI2]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c2), 0,
+ qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_TWI2));
+
+ sysbus_realize(SYS_BUS_DEVICE(&s->r_twi), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->r_twi), 0, s->memmap[AW_H3_DEV_R_TWI]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->r_twi), 0,
+ qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_R_TWI));
+
+ /* WDT */
+ sysbus_realize(SYS_BUS_DEVICE(&s->wdt), &error_fatal);
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->wdt), 0,
+ s->memmap[AW_H3_DEV_WDT], 1);
+
/* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(unimplemented); i++) {
create_unimplemented_device(unimplemented[i].device_name,