mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20191015' into staging
target-arm queue: * Add Aspeed AST2600 SoC support (but no new board model yet) * aspeed/wdt: Check correct register for clock source * bcm2835: code cleanups, better logging, trace events * implement v2.0 of the Arm semihosting specification * provide new 'transaction-based' ptimer API and use it for the Arm devices that use ptimers * ARM: KVM: support more than 256 CPUs # gpg: Signature made Tue 15 Oct 2019 18:09:42 BST # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20191015: (67 commits) hw/misc/bcm2835_mbox: Add trace events hw/arm/bcm2835: Add various unimplemented peripherals hw/arm/bcm2835: Rename some definitions hw/arm/bcm2835_peripherals: Name various address spaces hw/arm/bcm2835_peripherals: Improve logging hw/arm/raspi: Use the IEC binary prefix definitions aspeed/soc: Add ASPEED Video stub aspeed: add support for the Aspeed MII controller of the AST2600 aspeed: Parameterise number of MACs m25p80: Add support for w25q512jv aspeed/soc: Add AST2600 support aspeed: Introduce an object class per SoC aspeed/i2c: Add AST2600 support aspeed/i2c: Introduce an object class per SoC hw/gpio: Add in AST2600 specific implementation aspeed/smc: Add AST2600 support aspeed/smc: Introduce segment operations hw: wdt_aspeed: Add AST2600 support watchdog/aspeed: Introduce an object class per SoC aspeed/sdmc: Add AST2600 support ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -41,7 +41,7 @@ obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
|
||||
obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
|
||||
obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
|
||||
obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o
|
||||
obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
|
||||
obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o aspeed_ast2600.o
|
||||
obj-$(CONFIG_MPS2) += mps2.o
|
||||
obj-$(CONFIG_MPS2) += mps2-tz.o
|
||||
obj-$(CONFIG_MSF2) += msf2-soc.o
|
||||
|
||||
+16
-3
@@ -170,6 +170,7 @@ static void aspeed_board_init(MachineState *machine,
|
||||
AspeedSoCClass *sc;
|
||||
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
|
||||
ram_addr_t max_ram_size;
|
||||
int i;
|
||||
|
||||
bmc = g_new0(AspeedBoardState, 1);
|
||||
|
||||
@@ -214,7 +215,7 @@ static void aspeed_board_init(MachineState *machine,
|
||||
memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
|
||||
memory_region_add_subregion(&bmc->ram_container, 0, &bmc->ram);
|
||||
memory_region_add_subregion(get_system_memory(),
|
||||
sc->info->memmap[ASPEED_SDRAM],
|
||||
sc->memmap[ASPEED_SDRAM],
|
||||
&bmc->ram_container);
|
||||
|
||||
max_ram_size = object_property_get_uint(OBJECT(&bmc->soc), "max-ram-size",
|
||||
@@ -245,13 +246,26 @@ static void aspeed_board_init(MachineState *machine,
|
||||
}
|
||||
|
||||
aspeed_board_binfo.ram_size = ram_size;
|
||||
aspeed_board_binfo.loader_start = sc->info->memmap[ASPEED_SDRAM];
|
||||
aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM];
|
||||
aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
|
||||
|
||||
if (cfg->i2c_init) {
|
||||
cfg->i2c_init(bmc);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
|
||||
SDHCIState *sdhci = &bmc->soc.sdhci.slots[i];
|
||||
DriveInfo *dinfo = drive_get_next(IF_SD);
|
||||
BlockBackend *blk;
|
||||
DeviceState *card;
|
||||
|
||||
blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
|
||||
card = qdev_create(qdev_get_child_bus(DEVICE(sdhci), "sd-bus"),
|
||||
TYPE_SD_CARD);
|
||||
qdev_prop_set_drive(card, "drive", blk, &error_fatal);
|
||||
object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
|
||||
}
|
||||
|
||||
arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
|
||||
}
|
||||
|
||||
@@ -373,7 +387,6 @@ static void aspeed_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->desc = board->desc;
|
||||
mc->init = aspeed_machine_init;
|
||||
mc->max_cpus = ASPEED_CPUS_NUM;
|
||||
mc->no_sdcard = 1;
|
||||
mc->no_floppy = 1;
|
||||
mc->no_cdrom = 1;
|
||||
mc->no_parallel = 1;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+121
-78
@@ -34,8 +34,10 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
|
||||
[ASPEED_SDMC] = 0x1E6E0000,
|
||||
[ASPEED_SCU] = 0x1E6E2000,
|
||||
[ASPEED_XDMA] = 0x1E6E7000,
|
||||
[ASPEED_VIDEO] = 0x1E700000,
|
||||
[ASPEED_ADC] = 0x1E6E9000,
|
||||
[ASPEED_SRAM] = 0x1E720000,
|
||||
[ASPEED_SDHCI] = 0x1E740000,
|
||||
[ASPEED_GPIO] = 0x1E780000,
|
||||
[ASPEED_RTC] = 0x1E781000,
|
||||
[ASPEED_TIMER1] = 0x1E782000,
|
||||
@@ -62,7 +64,9 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
|
||||
[ASPEED_SCU] = 0x1E6E2000,
|
||||
[ASPEED_XDMA] = 0x1E6E7000,
|
||||
[ASPEED_ADC] = 0x1E6E9000,
|
||||
[ASPEED_VIDEO] = 0x1E700000,
|
||||
[ASPEED_SRAM] = 0x1E720000,
|
||||
[ASPEED_SDHCI] = 0x1E740000,
|
||||
[ASPEED_GPIO] = 0x1E780000,
|
||||
[ASPEED_RTC] = 0x1E781000,
|
||||
[ASPEED_TIMER1] = 0x1E782000,
|
||||
@@ -108,39 +112,16 @@ static const int aspeed_soc_ast2400_irqmap[] = {
|
||||
[ASPEED_ETH1] = 2,
|
||||
[ASPEED_ETH2] = 3,
|
||||
[ASPEED_XDMA] = 6,
|
||||
[ASPEED_SDHCI] = 26,
|
||||
};
|
||||
|
||||
#define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
|
||||
|
||||
static const AspeedSoCInfo aspeed_socs[] = {
|
||||
{
|
||||
.name = "ast2400-a1",
|
||||
.cpu_type = ARM_CPU_TYPE_NAME("arm926"),
|
||||
.silicon_rev = AST2400_A1_SILICON_REV,
|
||||
.sram_size = 0x8000,
|
||||
.spis_num = 1,
|
||||
.wdts_num = 2,
|
||||
.irqmap = aspeed_soc_ast2400_irqmap,
|
||||
.memmap = aspeed_soc_ast2400_memmap,
|
||||
.num_cpus = 1,
|
||||
}, {
|
||||
.name = "ast2500-a1",
|
||||
.cpu_type = ARM_CPU_TYPE_NAME("arm1176"),
|
||||
.silicon_rev = AST2500_A1_SILICON_REV,
|
||||
.sram_size = 0x9000,
|
||||
.spis_num = 2,
|
||||
.wdts_num = 3,
|
||||
.irqmap = aspeed_soc_ast2500_irqmap,
|
||||
.memmap = aspeed_soc_ast2500_memmap,
|
||||
.num_cpus = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
|
||||
{
|
||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||
|
||||
return qdev_get_gpio_in(DEVICE(&s->vic), sc->info->irqmap[ctrl]);
|
||||
return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[ctrl]);
|
||||
}
|
||||
|
||||
static void aspeed_soc_init(Object *obj)
|
||||
@@ -151,13 +132,13 @@ static void aspeed_soc_init(Object *obj)
|
||||
char socname[8];
|
||||
char typename[64];
|
||||
|
||||
if (sscanf(sc->info->name, "%7s", socname) != 1) {
|
||||
if (sscanf(sc->name, "%7s", socname) != 1) {
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
for (i = 0; i < sc->info->num_cpus; i++) {
|
||||
for (i = 0; i < sc->num_cpus; i++) {
|
||||
object_initialize_child(obj, "cpu[*]", OBJECT(&s->cpu[i]),
|
||||
sizeof(s->cpu[i]), sc->info->cpu_type,
|
||||
sizeof(s->cpu[i]), sc->cpu_type,
|
||||
&error_abort, NULL);
|
||||
}
|
||||
|
||||
@@ -165,7 +146,7 @@ static void aspeed_soc_init(Object *obj)
|
||||
sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu),
|
||||
typename);
|
||||
qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
|
||||
sc->info->silicon_rev);
|
||||
sc->silicon_rev);
|
||||
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
|
||||
"hw-strap1", &error_abort);
|
||||
object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
|
||||
@@ -179,13 +160,15 @@ static void aspeed_soc_init(Object *obj)
|
||||
sysbus_init_child_obj(obj, "rtc", OBJECT(&s->rtc), sizeof(s->rtc),
|
||||
TYPE_ASPEED_RTC);
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
|
||||
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
|
||||
sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
|
||||
sizeof(s->timerctrl), typename);
|
||||
object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
|
||||
OBJECT(&s->scu), &error_abort);
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
|
||||
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
|
||||
TYPE_ASPEED_I2C);
|
||||
typename);
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
|
||||
sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc),
|
||||
@@ -195,31 +178,29 @@ static void aspeed_soc_init(Object *obj)
|
||||
object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
|
||||
&error_abort);
|
||||
|
||||
for (i = 0; i < sc->info->spis_num; i++) {
|
||||
for (i = 0; i < sc->spis_num; i++) {
|
||||
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
|
||||
sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]),
|
||||
sizeof(s->spi[i]), typename);
|
||||
}
|
||||
|
||||
snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
|
||||
sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc),
|
||||
TYPE_ASPEED_SDMC);
|
||||
qdev_prop_set_uint32(DEVICE(&s->sdmc), "silicon-rev",
|
||||
sc->info->silicon_rev);
|
||||
typename);
|
||||
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
|
||||
"ram-size", &error_abort);
|
||||
object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc),
|
||||
"max-ram-size", &error_abort);
|
||||
|
||||
for (i = 0; i < sc->info->wdts_num; i++) {
|
||||
for (i = 0; i < sc->wdts_num; i++) {
|
||||
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
|
||||
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
|
||||
sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
|
||||
qdev_prop_set_uint32(DEVICE(&s->wdt[i]), "silicon-rev",
|
||||
sc->info->silicon_rev);
|
||||
sizeof(s->wdt[i]), typename);
|
||||
object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
|
||||
OBJECT(&s->scu), &error_abort);
|
||||
}
|
||||
|
||||
for (i = 0; i < ASPEED_MACS_NUM; i++) {
|
||||
for (i = 0; i < sc->macs_num; i++) {
|
||||
sysbus_init_child_obj(obj, "ftgmac100[*]", OBJECT(&s->ftgmac100[i]),
|
||||
sizeof(s->ftgmac100[i]), TYPE_FTGMAC100);
|
||||
}
|
||||
@@ -230,6 +211,15 @@ static void aspeed_soc_init(Object *obj)
|
||||
snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
|
||||
sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
|
||||
typename);
|
||||
|
||||
sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
|
||||
TYPE_ASPEED_SDHCI);
|
||||
|
||||
/* Init sd card slot class here so that they're under the correct parent */
|
||||
for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
|
||||
sysbus_init_child_obj(obj, "sdhci[*]", OBJECT(&s->sdhci.slots[i]),
|
||||
sizeof(s->sdhci.slots[i]), TYPE_SYSBUS_SDHCI);
|
||||
}
|
||||
}
|
||||
|
||||
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
@@ -240,13 +230,17 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
Error *err = NULL, *local_err = NULL;
|
||||
|
||||
/* IO space */
|
||||
create_unimplemented_device("aspeed_soc.io", sc->info->memmap[ASPEED_IOMEM],
|
||||
create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_IOMEM],
|
||||
ASPEED_SOC_IOMEM_SIZE);
|
||||
|
||||
if (s->num_cpus > sc->info->num_cpus) {
|
||||
/* Video engine stub */
|
||||
create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_VIDEO],
|
||||
0x1000);
|
||||
|
||||
if (s->num_cpus > sc->num_cpus) {
|
||||
warn_report("%s: invalid number of CPUs %d, using default %d",
|
||||
sc->info->name, s->num_cpus, sc->info->num_cpus);
|
||||
s->num_cpus = sc->info->num_cpus;
|
||||
sc->name, s->num_cpus, sc->num_cpus);
|
||||
s->num_cpus = sc->num_cpus;
|
||||
}
|
||||
|
||||
/* CPU */
|
||||
@@ -260,13 +254,13 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
/* SRAM */
|
||||
memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram",
|
||||
sc->info->sram_size, &err);
|
||||
sc->sram_size, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
memory_region_add_subregion(get_system_memory(),
|
||||
sc->info->memmap[ASPEED_SRAM], &s->sram);
|
||||
sc->memmap[ASPEED_SRAM], &s->sram);
|
||||
|
||||
/* SCU */
|
||||
object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
|
||||
@@ -274,7 +268,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->info->memmap[ASPEED_SCU]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_SCU]);
|
||||
|
||||
/* VIC */
|
||||
object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
|
||||
@@ -282,7 +276,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->info->memmap[ASPEED_VIC]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_VIC]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
|
||||
qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
|
||||
@@ -294,7 +288,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->info->memmap[ASPEED_RTC]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_RTC]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_RTC));
|
||||
|
||||
@@ -305,7 +299,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0,
|
||||
sc->info->memmap[ASPEED_TIMER1]);
|
||||
sc->memmap[ASPEED_TIMER1]);
|
||||
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
|
||||
qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_TIMER1 + i);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
|
||||
@@ -314,7 +308,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
/* UART - attach an 8250 to the IO space as our UART5 */
|
||||
if (serial_hd(0)) {
|
||||
qemu_irq uart5 = aspeed_soc_get_irq(s, ASPEED_UART5);
|
||||
serial_mm_init(get_system_memory(), sc->info->memmap[ASPEED_UART5], 2,
|
||||
serial_mm_init(get_system_memory(), sc->memmap[ASPEED_UART5], 2,
|
||||
uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
@@ -324,12 +318,12 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->info->memmap[ASPEED_I2C]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_I2C]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_I2C));
|
||||
|
||||
/* FMC, The number of CS is set at the board level */
|
||||
object_property_set_int(OBJECT(&s->fmc), sc->info->memmap[ASPEED_SDRAM],
|
||||
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
|
||||
"sdram-base", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
@@ -340,14 +334,14 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->info->memmap[ASPEED_FMC]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_FMC]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
|
||||
s->fmc.ctrl->flash_window_base);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_FMC));
|
||||
|
||||
/* SPI */
|
||||
for (i = 0; i < sc->info->spis_num; i++) {
|
||||
for (i = 0; i < sc->spis_num; i++) {
|
||||
object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err);
|
||||
object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
|
||||
&local_err);
|
||||
@@ -357,7 +351,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
|
||||
sc->info->memmap[ASPEED_SPI1 + i]);
|
||||
sc->memmap[ASPEED_SPI1 + i]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
|
||||
s->spi[i].ctrl->flash_window_base);
|
||||
}
|
||||
@@ -368,21 +362,23 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->info->memmap[ASPEED_SDMC]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_SDMC]);
|
||||
|
||||
/* Watch dog */
|
||||
for (i = 0; i < sc->info->wdts_num; i++) {
|
||||
for (i = 0; i < sc->wdts_num; i++) {
|
||||
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
|
||||
|
||||
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
|
||||
sc->info->memmap[ASPEED_WDT] + i * 0x20);
|
||||
sc->memmap[ASPEED_WDT] + i * awc->offset);
|
||||
}
|
||||
|
||||
/* Net */
|
||||
for (i = 0; i < nb_nics; i++) {
|
||||
for (i = 0; i < nb_nics && i < sc->macs_num; i++) {
|
||||
qdev_set_nic_properties(DEVICE(&s->ftgmac100[i]), &nd_table[i]);
|
||||
object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed",
|
||||
&err);
|
||||
@@ -394,7 +390,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
|
||||
sc->info->memmap[ASPEED_ETH1 + i]);
|
||||
sc->memmap[ASPEED_ETH1 + i]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
|
||||
}
|
||||
@@ -406,7 +402,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0,
|
||||
sc->info->memmap[ASPEED_XDMA]);
|
||||
sc->memmap[ASPEED_XDMA]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_XDMA));
|
||||
|
||||
@@ -416,9 +412,20 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->info->memmap[ASPEED_GPIO]);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_GPIO]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_GPIO));
|
||||
|
||||
/* SDHCI */
|
||||
object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0,
|
||||
sc->memmap[ASPEED_SDHCI]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
|
||||
aspeed_soc_get_irq(s, ASPEED_SDHCI));
|
||||
}
|
||||
static Property aspeed_soc_properties[] = {
|
||||
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
|
||||
@@ -428,9 +435,7 @@ static Property aspeed_soc_properties[] = {
|
||||
static void aspeed_soc_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
|
||||
|
||||
sc->info = (AspeedSoCInfo *) data;
|
||||
dc->realize = aspeed_soc_realize;
|
||||
/* Reason: Uses serial_hds and nd_table in realize() directly */
|
||||
dc->user_creatable = false;
|
||||
@@ -440,26 +445,64 @@ static void aspeed_soc_class_init(ObjectClass *oc, void *data)
|
||||
static const TypeInfo aspeed_soc_type_info = {
|
||||
.name = TYPE_ASPEED_SOC,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_init = aspeed_soc_init,
|
||||
.instance_size = sizeof(AspeedSoCState),
|
||||
.class_size = sizeof(AspeedSoCClass),
|
||||
.class_init = aspeed_soc_class_init,
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void aspeed_soc_register_types(void)
|
||||
static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
int i;
|
||||
AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
|
||||
|
||||
type_register_static(&aspeed_soc_type_info);
|
||||
for (i = 0; i < ARRAY_SIZE(aspeed_socs); ++i) {
|
||||
TypeInfo ti = {
|
||||
.name = aspeed_socs[i].name,
|
||||
.parent = TYPE_ASPEED_SOC,
|
||||
.class_init = aspeed_soc_class_init,
|
||||
.class_data = (void *) &aspeed_socs[i],
|
||||
};
|
||||
type_register(&ti);
|
||||
}
|
||||
sc->name = "ast2400-a1";
|
||||
sc->cpu_type = ARM_CPU_TYPE_NAME("arm926");
|
||||
sc->silicon_rev = AST2400_A1_SILICON_REV;
|
||||
sc->sram_size = 0x8000;
|
||||
sc->spis_num = 1;
|
||||
sc->wdts_num = 2;
|
||||
sc->macs_num = 2;
|
||||
sc->irqmap = aspeed_soc_ast2400_irqmap;
|
||||
sc->memmap = aspeed_soc_ast2400_memmap;
|
||||
sc->num_cpus = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_soc_ast2400_type_info = {
|
||||
.name = "ast2400-a1",
|
||||
.parent = TYPE_ASPEED_SOC,
|
||||
.instance_init = aspeed_soc_init,
|
||||
.instance_size = sizeof(AspeedSoCState),
|
||||
.class_init = aspeed_soc_ast2400_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
|
||||
|
||||
sc->name = "ast2500-a1";
|
||||
sc->cpu_type = ARM_CPU_TYPE_NAME("arm1176");
|
||||
sc->silicon_rev = AST2500_A1_SILICON_REV;
|
||||
sc->sram_size = 0x9000;
|
||||
sc->spis_num = 2;
|
||||
sc->wdts_num = 3;
|
||||
sc->macs_num = 2;
|
||||
sc->irqmap = aspeed_soc_ast2500_irqmap;
|
||||
sc->memmap = aspeed_soc_ast2500_memmap;
|
||||
sc->num_cpus = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_soc_ast2500_type_info = {
|
||||
.name = "ast2500-a1",
|
||||
.parent = TYPE_ASPEED_SOC,
|
||||
.instance_init = aspeed_soc_init,
|
||||
.instance_size = sizeof(AspeedSoCState),
|
||||
.class_init = aspeed_soc_ast2500_class_init,
|
||||
};
|
||||
static void aspeed_soc_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_soc_type_info);
|
||||
type_register_static(&aspeed_soc_ast2400_type_info);
|
||||
type_register_static(&aspeed_soc_ast2500_type_info);
|
||||
};
|
||||
|
||||
type_init(aspeed_soc_register_types)
|
||||
|
||||
@@ -22,6 +22,20 @@
|
||||
/* Capabilities for SD controller: no DMA, high-speed, default clocks etc. */
|
||||
#define BCM2835_SDHC_CAPAREG 0x52134b4
|
||||
|
||||
static void create_unimp(BCM2835PeripheralState *ps,
|
||||
UnimplementedDeviceState *uds,
|
||||
const char *name, hwaddr ofs, hwaddr size)
|
||||
{
|
||||
sysbus_init_child_obj(OBJECT(ps), name, uds,
|
||||
sizeof(UnimplementedDeviceState),
|
||||
TYPE_UNIMPLEMENTED_DEVICE);
|
||||
qdev_prop_set_string(DEVICE(uds), "name", name);
|
||||
qdev_prop_set_uint64(DEVICE(uds), "size", size);
|
||||
object_property_set_bool(OBJECT(uds), true, "realized", &error_fatal);
|
||||
memory_region_add_subregion_overlap(&ps->peri_mr, ofs,
|
||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(uds), 0), -1000);
|
||||
}
|
||||
|
||||
static void bcm2835_peripherals_init(Object *obj)
|
||||
{
|
||||
BCM2835PeripheralState *s = BCM2835_PERIPHERALS(obj);
|
||||
@@ -165,7 +179,8 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart0), 0));
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart0), 0,
|
||||
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
|
||||
INTERRUPT_UART));
|
||||
INTERRUPT_UART0));
|
||||
|
||||
/* AUX / UART1 */
|
||||
qdev_prop_set_chr(DEVICE(&s->aux), "chardev", serial_hd(1));
|
||||
|
||||
@@ -175,7 +190,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
memory_region_add_subregion(&s->peri_mr, UART1_OFFSET,
|
||||
memory_region_add_subregion(&s->peri_mr, AUX_OFFSET,
|
||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->aux), 0));
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->aux), 0,
|
||||
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
|
||||
@@ -268,7 +283,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
memory_region_add_subregion(&s->peri_mr, EMMC_OFFSET,
|
||||
memory_region_add_subregion(&s->peri_mr, EMMC1_OFFSET,
|
||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sdhci), 0));
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
|
||||
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
|
||||
@@ -322,6 +337,23 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
|
||||
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
|
||||
create_unimp(s, &s->systmr, "bcm2835-systimer", ST_OFFSET, 0x20);
|
||||
create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000);
|
||||
create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000);
|
||||
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
|
||||
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
|
||||
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
|
||||
create_unimp(s, &s->bscsl, "bcm2835-spis", BSC_SL_OFFSET, 0x100);
|
||||
create_unimp(s, &s->i2c[0], "bcm2835-i2c0", BSC0_OFFSET, 0x20);
|
||||
create_unimp(s, &s->i2c[1], "bcm2835-i2c1", BSC1_OFFSET, 0x20);
|
||||
create_unimp(s, &s->i2c[2], "bcm2835-i2c2", BSC2_OFFSET, 0x20);
|
||||
create_unimp(s, &s->otp, "bcm2835-otp", OTP_OFFSET, 0x80);
|
||||
create_unimp(s, &s->dbus, "bcm2835-dbus", DBUS_OFFSET, 0x8000);
|
||||
create_unimp(s, &s->ave0, "bcm2835-ave0", AVE0_OFFSET, 0x8000);
|
||||
create_unimp(s, &s->dwc2, "dwc-usb2", USB_OTG_OFFSET, 0x1000);
|
||||
create_unimp(s, &s->sdramc, "bcm2835-sdramc", SDRAMC_OFFSET, 0x100);
|
||||
}
|
||||
|
||||
static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
/* set periphbase/CBAR value for CPU-local registers */
|
||||
object_property_set_int(OBJECT(&s->cpus[n]),
|
||||
BCM2836_PERI_BASE + MCORE_OFFSET,
|
||||
BCM2836_PERI_BASE + MSYNC_OFFSET,
|
||||
"reset-cbar", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
|
||||
+10
-6
@@ -843,13 +843,10 @@ static void mv88w8618_timer_tick(void *opaque)
|
||||
static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s,
|
||||
uint32_t freq)
|
||||
{
|
||||
QEMUBH *bh;
|
||||
|
||||
sysbus_init_irq(dev, &s->irq);
|
||||
s->freq = freq;
|
||||
|
||||
bh = qemu_bh_new(mv88w8618_timer_tick, s);
|
||||
s->ptimer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
|
||||
s->ptimer = ptimer_init(mv88w8618_timer_tick, s, PTIMER_POLICY_DEFAULT);
|
||||
}
|
||||
|
||||
static uint64_t mv88w8618_pit_read(void *opaque, hwaddr offset,
|
||||
@@ -879,16 +876,19 @@ static void mv88w8618_pit_write(void *opaque, hwaddr offset,
|
||||
case MP_PIT_TIMER1_LENGTH ... MP_PIT_TIMER4_LENGTH:
|
||||
t = &s->timer[offset >> 2];
|
||||
t->limit = value;
|
||||
ptimer_transaction_begin(t->ptimer);
|
||||
if (t->limit > 0) {
|
||||
ptimer_set_limit(t->ptimer, t->limit, 1);
|
||||
} else {
|
||||
ptimer_stop(t->ptimer);
|
||||
}
|
||||
ptimer_transaction_commit(t->ptimer);
|
||||
break;
|
||||
|
||||
case MP_PIT_CONTROL:
|
||||
for (i = 0; i < 4; i++) {
|
||||
t = &s->timer[i];
|
||||
ptimer_transaction_begin(t->ptimer);
|
||||
if (value & 0xf && t->limit > 0) {
|
||||
ptimer_set_limit(t->ptimer, t->limit, 0);
|
||||
ptimer_set_freq(t->ptimer, t->freq);
|
||||
@@ -896,6 +896,7 @@ static void mv88w8618_pit_write(void *opaque, hwaddr offset,
|
||||
} else {
|
||||
ptimer_stop(t->ptimer);
|
||||
}
|
||||
ptimer_transaction_commit(t->ptimer);
|
||||
value >>= 4;
|
||||
}
|
||||
break;
|
||||
@@ -914,8 +915,11 @@ static void mv88w8618_pit_reset(DeviceState *d)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ptimer_stop(s->timer[i].ptimer);
|
||||
s->timer[i].limit = 0;
|
||||
mv88w8618_timer_state *t = &s->timer[i];
|
||||
ptimer_transaction_begin(t->ptimer);
|
||||
ptimer_stop(t->ptimer);
|
||||
ptimer_transaction_commit(t->ptimer);
|
||||
t->limit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -230,7 +230,7 @@ static void raspi2_machine_init(MachineClass *mc)
|
||||
mc->max_cpus = BCM283X_NCPUS;
|
||||
mc->min_cpus = BCM283X_NCPUS;
|
||||
mc->default_cpus = BCM283X_NCPUS;
|
||||
mc->default_ram_size = 1024 * 1024 * 1024;
|
||||
mc->default_ram_size = 1 * GiB;
|
||||
mc->ignore_memory_transaction_failures = true;
|
||||
};
|
||||
DEFINE_MACHINE("raspi2", raspi2_machine_init)
|
||||
@@ -252,7 +252,7 @@ static void raspi3_machine_init(MachineClass *mc)
|
||||
mc->max_cpus = BCM283X_NCPUS;
|
||||
mc->min_cpus = BCM283X_NCPUS;
|
||||
mc->default_cpus = BCM283X_NCPUS;
|
||||
mc->default_ram_size = 1024 * 1024 * 1024;
|
||||
mc->default_ram_size = 1 * GiB;
|
||||
}
|
||||
DEFINE_MACHINE("raspi3", raspi3_machine_init)
|
||||
#endif
|
||||
|
||||
@@ -327,6 +327,7 @@ static const FlashPartInfo known_devices[] = {
|
||||
{ INFO("w25q80", 0xef5014, 0, 64 << 10, 16, ER_4K) },
|
||||
{ INFO("w25q80bl", 0xef4014, 0, 64 << 10, 16, ER_4K) },
|
||||
{ INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K) },
|
||||
{ INFO("w25q512jv", 0xef4020, 0, 64 << 10, 1024, ER_4K) },
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -162,8 +162,9 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
switch (offset) {
|
||||
case AUX_ENABLES:
|
||||
if (value != 1) {
|
||||
qemu_log_mask(LOG_UNIMP, "%s: unsupported attempt to enable SPI "
|
||||
"or disable UART\n", __func__);
|
||||
qemu_log_mask(LOG_UNIMP, "%s: unsupported attempt to enable SPI"
|
||||
" or disable UART: 0x%"PRIx64"\n",
|
||||
__func__, value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+138
-16
@@ -31,6 +31,16 @@ struct ptimer_state
|
||||
uint8_t policy_mask;
|
||||
QEMUBH *bh;
|
||||
QEMUTimer *timer;
|
||||
ptimer_cb callback;
|
||||
void *callback_opaque;
|
||||
/*
|
||||
* These track whether we're in a transaction block, and if we
|
||||
* need to do a timer reload when the block finishes. They don't
|
||||
* need to be migrated because migration can never happen in the
|
||||
* middle of a transaction block.
|
||||
*/
|
||||
bool in_transaction;
|
||||
bool need_reload;
|
||||
};
|
||||
|
||||
/* Use a bottom-half routine to avoid reentrancy issues. */
|
||||
@@ -39,13 +49,16 @@ static void ptimer_trigger(ptimer_state *s)
|
||||
if (s->bh) {
|
||||
replay_bh_schedule_event(s->bh);
|
||||
}
|
||||
if (s->callback) {
|
||||
s->callback(s->callback_opaque);
|
||||
}
|
||||
}
|
||||
|
||||
static void ptimer_reload(ptimer_state *s, int delta_adjust)
|
||||
{
|
||||
uint32_t period_frac = s->period_frac;
|
||||
uint64_t period = s->period;
|
||||
uint64_t delta = s->delta;
|
||||
uint32_t period_frac;
|
||||
uint64_t period;
|
||||
uint64_t delta;
|
||||
bool suppress_trigger = false;
|
||||
|
||||
/*
|
||||
@@ -58,11 +71,20 @@ static void ptimer_reload(ptimer_state *s, int delta_adjust)
|
||||
(s->policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT)) {
|
||||
suppress_trigger = true;
|
||||
}
|
||||
if (delta == 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)
|
||||
if (s->delta == 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)
|
||||
&& !suppress_trigger) {
|
||||
ptimer_trigger(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that ptimer_trigger() might call the device callback function,
|
||||
* which can then modify timer state, so we must not cache any fields
|
||||
* from ptimer_state until after we have called it.
|
||||
*/
|
||||
delta = s->delta;
|
||||
period = s->period;
|
||||
period_frac = s->period_frac;
|
||||
|
||||
if (delta == 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_RELOAD)) {
|
||||
delta = s->delta = s->limit;
|
||||
}
|
||||
@@ -136,6 +158,15 @@ static void ptimer_tick(void *opaque)
|
||||
ptimer_state *s = (ptimer_state *)opaque;
|
||||
bool trigger = true;
|
||||
|
||||
/*
|
||||
* We perform all the tick actions within a begin/commit block
|
||||
* because the callback function that ptimer_trigger() calls
|
||||
* might make calls into the ptimer APIs that provoke another
|
||||
* trigger, and we want that to cause the callback function
|
||||
* to be called iteratively, not recursively.
|
||||
*/
|
||||
ptimer_transaction_begin(s);
|
||||
|
||||
if (s->enabled == 2) {
|
||||
s->delta = 0;
|
||||
s->enabled = 0;
|
||||
@@ -164,6 +195,8 @@ static void ptimer_tick(void *opaque)
|
||||
if (trigger) {
|
||||
ptimer_trigger(s);
|
||||
}
|
||||
|
||||
ptimer_transaction_commit(s);
|
||||
}
|
||||
|
||||
uint64_t ptimer_get_count(ptimer_state *s)
|
||||
@@ -263,10 +296,15 @@ uint64_t ptimer_get_count(ptimer_state *s)
|
||||
|
||||
void ptimer_set_count(ptimer_state *s, uint64_t count)
|
||||
{
|
||||
assert(s->in_transaction || !s->callback);
|
||||
s->delta = count;
|
||||
if (s->enabled) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
if (!s->callback) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
} else {
|
||||
s->need_reload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,6 +312,8 @@ void ptimer_run(ptimer_state *s, int oneshot)
|
||||
{
|
||||
bool was_disabled = !s->enabled;
|
||||
|
||||
assert(s->in_transaction || !s->callback);
|
||||
|
||||
if (was_disabled && s->period == 0) {
|
||||
if (!qtest_enabled()) {
|
||||
fprintf(stderr, "Timer with period zero, disabling\n");
|
||||
@@ -282,8 +322,12 @@ void ptimer_run(ptimer_state *s, int oneshot)
|
||||
}
|
||||
s->enabled = oneshot ? 2 : 1;
|
||||
if (was_disabled) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
if (!s->callback) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
} else {
|
||||
s->need_reload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,35 +335,50 @@ void ptimer_run(ptimer_state *s, int oneshot)
|
||||
is immediately restarted. */
|
||||
void ptimer_stop(ptimer_state *s)
|
||||
{
|
||||
assert(s->in_transaction || !s->callback);
|
||||
|
||||
if (!s->enabled)
|
||||
return;
|
||||
|
||||
s->delta = ptimer_get_count(s);
|
||||
timer_del(s->timer);
|
||||
s->enabled = 0;
|
||||
if (s->callback) {
|
||||
s->need_reload = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set counter increment interval in nanoseconds. */
|
||||
void ptimer_set_period(ptimer_state *s, int64_t period)
|
||||
{
|
||||
assert(s->in_transaction || !s->callback);
|
||||
s->delta = ptimer_get_count(s);
|
||||
s->period = period;
|
||||
s->period_frac = 0;
|
||||
if (s->enabled) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
if (!s->callback) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
} else {
|
||||
s->need_reload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set counter frequency in Hz. */
|
||||
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
|
||||
{
|
||||
assert(s->in_transaction || !s->callback);
|
||||
s->delta = ptimer_get_count(s);
|
||||
s->period = 1000000000ll / freq;
|
||||
s->period_frac = (1000000000ll << 32) / freq;
|
||||
if (s->enabled) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
if (!s->callback) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
} else {
|
||||
s->need_reload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,12 +386,17 @@ void ptimer_set_freq(ptimer_state *s, uint32_t freq)
|
||||
count = limit. */
|
||||
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
|
||||
{
|
||||
assert(s->in_transaction || !s->callback);
|
||||
s->limit = limit;
|
||||
if (reload)
|
||||
s->delta = limit;
|
||||
if (s->enabled && reload) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
if (!s->callback) {
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
} else {
|
||||
s->need_reload = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,6 +405,32 @@ uint64_t ptimer_get_limit(ptimer_state *s)
|
||||
return s->limit;
|
||||
}
|
||||
|
||||
void ptimer_transaction_begin(ptimer_state *s)
|
||||
{
|
||||
assert(!s->in_transaction || !s->callback);
|
||||
s->in_transaction = true;
|
||||
s->need_reload = false;
|
||||
}
|
||||
|
||||
void ptimer_transaction_commit(ptimer_state *s)
|
||||
{
|
||||
assert(s->in_transaction);
|
||||
/*
|
||||
* We must loop here because ptimer_reload() can call the callback
|
||||
* function, which might then update ptimer state in a way that
|
||||
* means we need to do another reload and possibly another callback.
|
||||
* A disabled timer never needs reloading (and if we don't check
|
||||
* this then we loop forever if ptimer_reload() disables the timer).
|
||||
*/
|
||||
while (s->need_reload && s->enabled) {
|
||||
s->need_reload = false;
|
||||
s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ptimer_reload(s, 0);
|
||||
}
|
||||
/* Now we've finished reload we can leave the transaction block. */
|
||||
s->in_transaction = false;
|
||||
}
|
||||
|
||||
const VMStateDescription vmstate_ptimer = {
|
||||
.name = "ptimer",
|
||||
.version_id = 1,
|
||||
@@ -358,7 +448,7 @@ const VMStateDescription vmstate_ptimer = {
|
||||
}
|
||||
};
|
||||
|
||||
ptimer_state *ptimer_init(QEMUBH *bh, uint8_t policy_mask)
|
||||
ptimer_state *ptimer_init_with_bh(QEMUBH *bh, uint8_t policy_mask)
|
||||
{
|
||||
ptimer_state *s;
|
||||
|
||||
@@ -377,9 +467,41 @@ ptimer_state *ptimer_init(QEMUBH *bh, uint8_t policy_mask)
|
||||
return s;
|
||||
}
|
||||
|
||||
ptimer_state *ptimer_init(ptimer_cb callback, void *callback_opaque,
|
||||
uint8_t policy_mask)
|
||||
{
|
||||
ptimer_state *s;
|
||||
|
||||
/*
|
||||
* The callback function is mandatory; so we use it to distinguish
|
||||
* old-style QEMUBH ptimers from new transaction API ptimers.
|
||||
* (ptimer_init_with_bh() allows a NULL bh pointer and at least
|
||||
* one device (digic-timer) passes NULL, so it's not the case
|
||||
* that either s->bh != NULL or s->callback != NULL.)
|
||||
*/
|
||||
assert(callback);
|
||||
|
||||
s = g_new0(ptimer_state, 1);
|
||||
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s);
|
||||
s->policy_mask = policy_mask;
|
||||
s->callback = callback;
|
||||
s->callback_opaque = callback_opaque;
|
||||
|
||||
/*
|
||||
* These two policies are incompatible -- trigger-on-decrement implies
|
||||
* a timer trigger when the count becomes 0, but no-immediate-trigger
|
||||
* implies a trigger when the count stops being 0.
|
||||
*/
|
||||
assert(!((policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
|
||||
(policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)));
|
||||
return s;
|
||||
}
|
||||
|
||||
void ptimer_free(ptimer_state *s)
|
||||
{
|
||||
qemu_bh_delete(s->bh);
|
||||
if (s->bh) {
|
||||
qemu_bh_delete(s->bh);
|
||||
}
|
||||
timer_free(s->timer);
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ static void bcm2835_fb_realize(DeviceState *dev, Error **errp)
|
||||
s->initial_config.base = s->vcram_base + BCM2835_FB_OFFSET;
|
||||
|
||||
s->dma_mr = MEMORY_REGION(obj);
|
||||
address_space_init(&s->dma_as, s->dma_mr, NULL);
|
||||
address_space_init(&s->dma_as, s->dma_mr, TYPE_BCM2835_FB "-memory");
|
||||
|
||||
bcm2835_fb_reset(dev);
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ static uint64_t bcm2835_dma_read(BCM2835DMAState *s, hwaddr offset,
|
||||
res = ch->debug;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
@@ -228,7 +228,7 @@ static void bcm2835_dma_write(BCM2835DMAState *s, hwaddr offset,
|
||||
ch->debug = value;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
@@ -247,7 +247,7 @@ static uint64_t bcm2835_dma0_read(void *opaque, hwaddr offset, unsigned size)
|
||||
case BCM2708_DMA_ENABLE:
|
||||
return s->enable;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
|
||||
__func__, offset);
|
||||
return 0;
|
||||
}
|
||||
@@ -274,7 +274,7 @@ static void bcm2835_dma0_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
s->enable = (value & 0xffff);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
|
||||
__func__, offset);
|
||||
}
|
||||
}
|
||||
@@ -383,7 +383,7 @@ static void bcm2835_dma_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
s->dma_mr = MEMORY_REGION(obj);
|
||||
address_space_init(&s->dma_as, s->dma_mr, NULL);
|
||||
address_space_init(&s->dma_as, s->dma_mr, TYPE_BCM2835_DMA "-memory");
|
||||
|
||||
bcm2835_dma_reset(dev);
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
st->nr = i;
|
||||
st->bh = qemu_bh_new(timer_hit, st);
|
||||
st->ptimer = ptimer_init(st->bh, PTIMER_POLICY_DEFAULT);
|
||||
st->ptimer = ptimer_init_with_bh(st->bh, PTIMER_POLICY_DEFAULT);
|
||||
ptimer_set_freq(st->ptimer, s->freqhz);
|
||||
}
|
||||
return;
|
||||
|
||||
+137
-5
@@ -169,6 +169,48 @@
|
||||
#define GPIO_3_6V_MEM_SIZE 0x1F0
|
||||
#define GPIO_3_6V_REG_ARRAY_SIZE (GPIO_3_6V_MEM_SIZE >> 2)
|
||||
|
||||
/* AST2600 only - 1.8V gpios */
|
||||
/*
|
||||
* The AST2600 has same 3.6V gpios as the AST2400 (memory offsets 0x0-0x198)
|
||||
* and addtional 1.8V gpios (memory offsets 0x800-0x9D4).
|
||||
*/
|
||||
#define GPIO_1_8V_REG_OFFSET 0x800
|
||||
#define GPIO_1_8V_ABCD_DATA_VALUE ((0x800 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_DIRECTION ((0x804 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_INT_ENABLE ((0x808 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_INT_SENS_0 ((0x80C - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_INT_SENS_1 ((0x810 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_INT_SENS_2 ((0x814 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_INT_STATUS ((0x818 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_RESET_TOLERANT ((0x81C - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_DATA_VALUE ((0x820 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_DIRECTION ((0x824 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_INT_ENABLE ((0x828 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_INT_SENS_0 ((0x82C - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_INT_SENS_1 ((0x830 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_INT_SENS_2 ((0x834 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_INT_STATUS ((0x838 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_RESET_TOLERANT ((0x83C - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_DEBOUNCE_1 ((0x840 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_DEBOUNCE_2 ((0x844 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_DEBOUNCE_1 ((0x848 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_DEBOUNCE_2 ((0x84C - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_DEBOUNCE_TIME_1 ((0x850 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_DEBOUNCE_TIME_2 ((0x854 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_DEBOUNCE_TIME_3 ((0x858 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_COMMAND_SRC_0 ((0x860 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_COMMAND_SRC_1 ((0x864 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_COMMAND_SRC_0 ((0x868 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_COMMAND_SRC_1 ((0x86C - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_DATA_READ ((0x8C0 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_DATA_READ ((0x8C4 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_ABCD_INPUT_MASK ((0x9D0 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_E_INPUT_MASK ((0x9D4 - GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_1_8V_MEM_SIZE 0x9D8
|
||||
#define GPIO_1_8V_REG_ARRAY_SIZE ((GPIO_1_8V_MEM_SIZE - \
|
||||
GPIO_1_8V_REG_OFFSET) >> 2)
|
||||
#define GPIO_MAX_MEM_SIZE MAX(GPIO_3_6V_MEM_SIZE, GPIO_1_8V_MEM_SIZE)
|
||||
|
||||
static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio)
|
||||
{
|
||||
uint32_t falling_edge = 0, rising_edge = 0;
|
||||
@@ -465,6 +507,39 @@ static const AspeedGPIOReg aspeed_3_6v_gpios[GPIO_3_6V_REG_ARRAY_SIZE] = {
|
||||
[GPIO_AC_INPUT_MASK] = { 7, gpio_reg_input_mask },
|
||||
};
|
||||
|
||||
static const AspeedGPIOReg aspeed_1_8v_gpios[GPIO_1_8V_REG_ARRAY_SIZE] = {
|
||||
/* 1.8V Set ABCD */
|
||||
[GPIO_1_8V_ABCD_DATA_VALUE] = {0, gpio_reg_data_value},
|
||||
[GPIO_1_8V_ABCD_DIRECTION] = {0, gpio_reg_direction},
|
||||
[GPIO_1_8V_ABCD_INT_ENABLE] = {0, gpio_reg_int_enable},
|
||||
[GPIO_1_8V_ABCD_INT_SENS_0] = {0, gpio_reg_int_sens_0},
|
||||
[GPIO_1_8V_ABCD_INT_SENS_1] = {0, gpio_reg_int_sens_1},
|
||||
[GPIO_1_8V_ABCD_INT_SENS_2] = {0, gpio_reg_int_sens_2},
|
||||
[GPIO_1_8V_ABCD_INT_STATUS] = {0, gpio_reg_int_status},
|
||||
[GPIO_1_8V_ABCD_RESET_TOLERANT] = {0, gpio_reg_reset_tolerant},
|
||||
[GPIO_1_8V_ABCD_DEBOUNCE_1] = {0, gpio_reg_debounce_1},
|
||||
[GPIO_1_8V_ABCD_DEBOUNCE_2] = {0, gpio_reg_debounce_2},
|
||||
[GPIO_1_8V_ABCD_COMMAND_SRC_0] = {0, gpio_reg_cmd_source_0},
|
||||
[GPIO_1_8V_ABCD_COMMAND_SRC_1] = {0, gpio_reg_cmd_source_1},
|
||||
[GPIO_1_8V_ABCD_DATA_READ] = {0, gpio_reg_data_read},
|
||||
[GPIO_1_8V_ABCD_INPUT_MASK] = {0, gpio_reg_input_mask},
|
||||
/* 1.8V Set E */
|
||||
[GPIO_1_8V_E_DATA_VALUE] = {1, gpio_reg_data_value},
|
||||
[GPIO_1_8V_E_DIRECTION] = {1, gpio_reg_direction},
|
||||
[GPIO_1_8V_E_INT_ENABLE] = {1, gpio_reg_int_enable},
|
||||
[GPIO_1_8V_E_INT_SENS_0] = {1, gpio_reg_int_sens_0},
|
||||
[GPIO_1_8V_E_INT_SENS_1] = {1, gpio_reg_int_sens_1},
|
||||
[GPIO_1_8V_E_INT_SENS_2] = {1, gpio_reg_int_sens_2},
|
||||
[GPIO_1_8V_E_INT_STATUS] = {1, gpio_reg_int_status},
|
||||
[GPIO_1_8V_E_RESET_TOLERANT] = {1, gpio_reg_reset_tolerant},
|
||||
[GPIO_1_8V_E_DEBOUNCE_1] = {1, gpio_reg_debounce_1},
|
||||
[GPIO_1_8V_E_DEBOUNCE_2] = {1, gpio_reg_debounce_2},
|
||||
[GPIO_1_8V_E_COMMAND_SRC_0] = {1, gpio_reg_cmd_source_0},
|
||||
[GPIO_1_8V_E_COMMAND_SRC_1] = {1, gpio_reg_cmd_source_1},
|
||||
[GPIO_1_8V_E_DATA_READ] = {1, gpio_reg_data_read},
|
||||
[GPIO_1_8V_E_INPUT_MASK] = {1, gpio_reg_input_mask},
|
||||
};
|
||||
|
||||
static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
|
||||
{
|
||||
AspeedGPIOState *s = ASPEED_GPIO(opaque);
|
||||
@@ -663,8 +738,11 @@ static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name,
|
||||
int set_idx, group_idx = 0;
|
||||
|
||||
if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
|
||||
error_setg(errp, "%s: error reading %s", __func__, name);
|
||||
return;
|
||||
/* 1.8V gpio */
|
||||
if (sscanf(name, "gpio%3s%1d", group, &pin) != 2) {
|
||||
error_setg(errp, "%s: error reading %s", __func__, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
set_idx = get_set_idx(s, group, &group_idx);
|
||||
if (set_idx == -1) {
|
||||
@@ -692,8 +770,11 @@ static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
|
||||
return;
|
||||
}
|
||||
if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
|
||||
error_setg(errp, "%s: error reading %s", __func__, name);
|
||||
return;
|
||||
/* 1.8V gpio */
|
||||
if (sscanf(name, "gpio%3s%1d", group, &pin) != 2) {
|
||||
error_setg(errp, "%s: error reading %s", __func__, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
set_idx = get_set_idx(s, group, &group_idx);
|
||||
if (set_idx == -1) {
|
||||
@@ -726,6 +807,21 @@ static const GPIOSetProperties ast2500_set_props[] = {
|
||||
[7] = {0x000000ff, 0x000000ff, {"AC"} },
|
||||
};
|
||||
|
||||
static GPIOSetProperties ast2600_3_6v_set_props[] = {
|
||||
[0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
|
||||
[1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
|
||||
[2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
|
||||
[3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
|
||||
[4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
|
||||
[5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
|
||||
[6] = {0xffff0000, 0x0fff0000, {"Y", "Z", "", ""} },
|
||||
};
|
||||
|
||||
static GPIOSetProperties ast2600_1_8v_set_props[] = {
|
||||
[0] = {0xffffffff, 0xffffffff, {"18A", "18B", "18C", "18D"} },
|
||||
[1] = {0x0000000f, 0x0000000f, {"18E"} },
|
||||
};
|
||||
|
||||
static const MemoryRegionOps aspeed_gpio_ops = {
|
||||
.read = aspeed_gpio_read,
|
||||
.write = aspeed_gpio_write,
|
||||
@@ -758,7 +854,7 @@ static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s,
|
||||
TYPE_ASPEED_GPIO, GPIO_3_6V_MEM_SIZE);
|
||||
TYPE_ASPEED_GPIO, GPIO_MAX_MEM_SIZE);
|
||||
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
@@ -851,6 +947,26 @@ static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
|
||||
agc->reg_table = aspeed_3_6v_gpios;
|
||||
}
|
||||
|
||||
static void aspeed_gpio_ast2600_3_6v_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
|
||||
|
||||
agc->props = ast2600_3_6v_set_props;
|
||||
agc->nr_gpio_pins = 208;
|
||||
agc->nr_gpio_sets = 7;
|
||||
agc->reg_table = aspeed_3_6v_gpios;
|
||||
}
|
||||
|
||||
static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
|
||||
|
||||
agc->props = ast2600_1_8v_set_props;
|
||||
agc->nr_gpio_pins = 36;
|
||||
agc->nr_gpio_sets = 2;
|
||||
agc->reg_table = aspeed_1_8v_gpios;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_gpio_info = {
|
||||
.name = TYPE_ASPEED_GPIO,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
@@ -874,11 +990,27 @@ static const TypeInfo aspeed_gpio_ast2500_info = {
|
||||
.instance_init = aspeed_gpio_init,
|
||||
};
|
||||
|
||||
static const TypeInfo aspeed_gpio_ast2600_3_6v_info = {
|
||||
.name = TYPE_ASPEED_GPIO "-ast2600",
|
||||
.parent = TYPE_ASPEED_GPIO,
|
||||
.class_init = aspeed_gpio_ast2600_3_6v_class_init,
|
||||
.instance_init = aspeed_gpio_init,
|
||||
};
|
||||
|
||||
static const TypeInfo aspeed_gpio_ast2600_1_8v_info = {
|
||||
.name = TYPE_ASPEED_GPIO "-ast2600-1_8v",
|
||||
.parent = TYPE_ASPEED_GPIO,
|
||||
.class_init = aspeed_gpio_ast2600_1_8v_class_init,
|
||||
.instance_init = aspeed_gpio_init,
|
||||
};
|
||||
|
||||
static void aspeed_gpio_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_gpio_info);
|
||||
type_register_static(&aspeed_gpio_ast2400_info);
|
||||
type_register_static(&aspeed_gpio_ast2500_info);
|
||||
type_register_static(&aspeed_gpio_ast2600_3_6v_info);
|
||||
type_register_static(&aspeed_gpio_ast2600_1_8v_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_gpio_register_types);
|
||||
|
||||
+96
-10
@@ -145,10 +145,12 @@ static inline bool aspeed_i2c_bus_is_enabled(AspeedI2CBus *bus)
|
||||
|
||||
static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
|
||||
{
|
||||
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
|
||||
|
||||
bus->intr_status &= bus->intr_ctrl;
|
||||
if (bus->intr_status) {
|
||||
bus->controller->intr_status |= 1 << bus->id;
|
||||
qemu_irq_raise(bus->controller->irq);
|
||||
qemu_irq_raise(aic->bus_get_irq(bus));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +275,7 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
AspeedI2CBus *bus = opaque;
|
||||
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
|
||||
bool handle_rx;
|
||||
|
||||
switch (offset) {
|
||||
@@ -299,7 +302,7 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
|
||||
bus->intr_status &= ~(value & 0x7FFF);
|
||||
if (!bus->intr_status) {
|
||||
bus->controller->intr_status &= ~(1 << bus->id);
|
||||
qemu_irq_lower(bus->controller->irq);
|
||||
qemu_irq_lower(aic->bus_get_irq(bus));
|
||||
}
|
||||
if (handle_rx && (bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST))) {
|
||||
aspeed_i2c_handle_rx_cmd(bus);
|
||||
@@ -408,10 +411,11 @@ static void aspeed_i2c_reset(DeviceState *dev)
|
||||
{
|
||||
int i;
|
||||
AspeedI2CState *s = ASPEED_I2C(dev);
|
||||
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
|
||||
|
||||
s->intr_status = 0;
|
||||
|
||||
for (i = 0; i < ASPEED_I2C_NR_BUSSES; i++) {
|
||||
for (i = 0; i < aic->num_busses; i++) {
|
||||
s->busses[i].intr_ctrl = 0;
|
||||
s->busses[i].intr_status = 0;
|
||||
s->busses[i].cmd = 0;
|
||||
@@ -421,7 +425,7 @@ static void aspeed_i2c_reset(DeviceState *dev)
|
||||
}
|
||||
|
||||
/*
|
||||
* Address Definitions
|
||||
* Address Definitions (AST2400 and AST2500)
|
||||
*
|
||||
* 0x000 ... 0x03F: Global Register
|
||||
* 0x040 ... 0x07F: Device 1
|
||||
@@ -446,22 +450,26 @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
|
||||
int i;
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
AspeedI2CState *s = ASPEED_I2C(dev);
|
||||
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
|
||||
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_i2c_ctrl_ops, s,
|
||||
"aspeed.i2c", 0x1000);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
|
||||
for (i = 0; i < ASPEED_I2C_NR_BUSSES; i++) {
|
||||
char name[16];
|
||||
int offset = i < 7 ? 1 : 5;
|
||||
for (i = 0; i < aic->num_busses; i++) {
|
||||
char name[32];
|
||||
int offset = i < aic->gap ? 1 : 5;
|
||||
|
||||
sysbus_init_irq(sbd, &s->busses[i].irq);
|
||||
snprintf(name, sizeof(name), "aspeed.i2c.%d", i);
|
||||
s->busses[i].controller = s;
|
||||
s->busses[i].id = i;
|
||||
s->busses[i].bus = i2c_init_bus(dev, name);
|
||||
memory_region_init_io(&s->busses[i].mr, OBJECT(dev),
|
||||
&aspeed_i2c_bus_ops, &s->busses[i], name, 0x40);
|
||||
memory_region_add_subregion(&s->iomem, 0x40 * (i + offset),
|
||||
&aspeed_i2c_bus_ops, &s->busses[i], name,
|
||||
aic->reg_size);
|
||||
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
|
||||
&s->busses[i].mr);
|
||||
}
|
||||
}
|
||||
@@ -481,11 +489,88 @@ static const TypeInfo aspeed_i2c_info = {
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(AspeedI2CState),
|
||||
.class_init = aspeed_i2c_class_init,
|
||||
.class_size = sizeof(AspeedI2CClass),
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
|
||||
{
|
||||
return bus->controller->irq;
|
||||
}
|
||||
|
||||
static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2400 I2C Controller";
|
||||
|
||||
aic->num_busses = 14;
|
||||
aic->reg_size = 0x40;
|
||||
aic->gap = 7;
|
||||
aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2400_i2c_info = {
|
||||
.name = TYPE_ASPEED_2400_I2C,
|
||||
.parent = TYPE_ASPEED_I2C,
|
||||
.class_init = aspeed_2400_i2c_class_init,
|
||||
};
|
||||
|
||||
static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus)
|
||||
{
|
||||
return bus->controller->irq;
|
||||
}
|
||||
|
||||
static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2500 I2C Controller";
|
||||
|
||||
aic->num_busses = 14;
|
||||
aic->reg_size = 0x40;
|
||||
aic->gap = 7;
|
||||
aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2500_i2c_info = {
|
||||
.name = TYPE_ASPEED_2500_I2C,
|
||||
.parent = TYPE_ASPEED_I2C,
|
||||
.class_init = aspeed_2500_i2c_class_init,
|
||||
};
|
||||
|
||||
static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
|
||||
{
|
||||
return bus->irq;
|
||||
}
|
||||
|
||||
static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass);
|
||||
|
||||
dc->desc = "ASPEED 2600 I2C Controller";
|
||||
|
||||
aic->num_busses = 16;
|
||||
aic->reg_size = 0x80;
|
||||
aic->gap = -1; /* no gap */
|
||||
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_2600_i2c_info = {
|
||||
.name = TYPE_ASPEED_2600_I2C,
|
||||
.parent = TYPE_ASPEED_I2C,
|
||||
.class_init = aspeed_2600_i2c_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_i2c_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_i2c_info);
|
||||
type_register_static(&aspeed_2400_i2c_info);
|
||||
type_register_static(&aspeed_2500_i2c_info);
|
||||
type_register_static(&aspeed_2600_i2c_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_i2c_register_types)
|
||||
@@ -494,9 +579,10 @@ type_init(aspeed_i2c_register_types)
|
||||
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr)
|
||||
{
|
||||
AspeedI2CState *s = ASPEED_I2C(dev);
|
||||
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
|
||||
I2CBus *bus = NULL;
|
||||
|
||||
if (busnr >= 0 && busnr < ASPEED_I2C_NR_BUSSES) {
|
||||
if (busnr >= 0 && busnr < aic->num_busses) {
|
||||
bus = s->busses[busnr].bus;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ void kvm_arm_gic_set_irq(uint32_t num_irq, int irq, int level)
|
||||
* has separate fields in the irq number for type,
|
||||
* CPU number and interrupt number.
|
||||
*/
|
||||
int kvm_irq, irqtype, cpu;
|
||||
int irqtype, cpu;
|
||||
|
||||
if (irq < (num_irq - GIC_INTERNAL)) {
|
||||
/* External interrupt. The kernel numbers these like the GIC
|
||||
@@ -72,10 +72,7 @@ void kvm_arm_gic_set_irq(uint32_t num_irq, int irq, int level)
|
||||
cpu = irq / GIC_INTERNAL;
|
||||
irq %= GIC_INTERNAL;
|
||||
}
|
||||
kvm_irq = (irqtype << KVM_ARM_IRQ_TYPE_SHIFT)
|
||||
| (cpu << KVM_ARM_IRQ_VCPU_SHIFT) | irq;
|
||||
|
||||
kvm_set_irq(kvm_state, kvm_irq, !!level);
|
||||
kvm_arm_set_irq(cpu, irqtype, irq, !!level);
|
||||
}
|
||||
|
||||
static void kvm_arm_gicv2_set_irq(void *opaque, int irq, int level)
|
||||
|
||||
@@ -264,7 +264,7 @@ static uint64_t bcm2836_control_read(void *opaque, hwaddr offset, unsigned size)
|
||||
} else if (offset >= REG_MBOX0_RDCLR && offset < REG_LIMIT) {
|
||||
return s->mailboxes[(offset - REG_MBOX0_RDCLR) >> 2];
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
|
||||
qemu_log_mask(LOG_UNIMP, "%s: Unsupported offset 0x%"HWADDR_PRIx"\n",
|
||||
__func__, offset);
|
||||
return 0;
|
||||
}
|
||||
@@ -293,8 +293,9 @@ static void bcm2836_control_write(void *opaque, hwaddr offset,
|
||||
} else if (offset >= REG_MBOX0_RDCLR && offset < REG_LIMIT) {
|
||||
s->mailboxes[(offset - REG_MBOX0_RDCLR) >> 2] &= ~val;
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
|
||||
__func__, offset);
|
||||
qemu_log_mask(LOG_UNIMP, "%s: Unsupported offset 0x%"HWADDR_PRIx
|
||||
" value 0x%"PRIx64"\n",
|
||||
__func__, offset, val);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -141,7 +141,7 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
|
||||
|
||||
s = g_new0(m5206_timer_state, 1);
|
||||
bh = qemu_bh_new(m5206_timer_trigger, s);
|
||||
s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
|
||||
s->timer = ptimer_init_with_bh(bh, PTIMER_POLICY_DEFAULT);
|
||||
s->irq = irq;
|
||||
m5206_timer_reset(s);
|
||||
return s;
|
||||
|
||||
+1
-1
@@ -192,7 +192,7 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
|
||||
for (i = 0; i < 2; i++) {
|
||||
s = g_new0(m5208_timer_state, 1);
|
||||
bh = qemu_bh_new(m5208_timer_trigger, s);
|
||||
s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
|
||||
s->timer = ptimer_init_with_bh(bh, PTIMER_POLICY_DEFAULT);
|
||||
memory_region_init_io(&s->iomem, NULL, &m5208_timer_ops, s,
|
||||
"m5208-timer", 0x00004000);
|
||||
memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user