aboutsummaryrefslogtreecommitdiff
path: root/hw/arm
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm')
-rw-r--r--hw/arm/aspeed.c74
-rw-r--r--hw/arm/aspeed_ast10x0.c48
-rw-r--r--hw/arm/aspeed_ast2600.c32
-rw-r--r--hw/arm/aspeed_soc.c46
4 files changed, 177 insertions, 23 deletions
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index a74c13ab0f..98dc185acd 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -21,6 +21,7 @@
#include "hw/misc/led.h"
#include "hw/qdev-properties.h"
#include "sysemu/block-backend.h"
+#include "sysemu/reset.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
@@ -526,8 +527,15 @@ static void ast2500_evb_i2c_init(AspeedMachineState *bmc)
static void ast2600_evb_i2c_init(AspeedMachineState *bmc)
{
- /* Start with some devices on our I2C busses */
- ast2500_evb_i2c_init(bmc);
+ AspeedSoCState *soc = &bmc->soc;
+ uint8_t *eeprom_buf = g_malloc0(8 * 1024);
+
+ smbus_eeprom_init_one(aspeed_i2c_get_bus(&soc->i2c, 7), 0x50,
+ eeprom_buf);
+
+ /* LM75 is compatible with TMP105 driver */
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8),
+ TYPE_TMP105, 0x4d);
}
static void romulus_bmc_i2c_init(AspeedMachineState *bmc)
@@ -951,6 +959,35 @@ static void bletchley_bmc_i2c_init(AspeedMachineState *bmc)
i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67);
}
+static void fby35_i2c_init(AspeedMachineState *bmc)
+{
+ AspeedSoCState *soc = &bmc->soc;
+ I2CBus *i2c[16];
+
+ for (int i = 0; i < 16; i++) {
+ i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i);
+ }
+
+ i2c_slave_create_simple(i2c[2], TYPE_LM75, 0x4f);
+ i2c_slave_create_simple(i2c[8], TYPE_TMP421, 0x1f);
+ /* Hotswap controller is actually supposed to be mp5920 or ltc4282. */
+ i2c_slave_create_simple(i2c[11], "adm1272", 0x44);
+ i2c_slave_create_simple(i2c[12], TYPE_LM75, 0x4e);
+ i2c_slave_create_simple(i2c[12], TYPE_LM75, 0x4f);
+
+ aspeed_eeprom_init(i2c[4], 0x51, 128 * KiB);
+ aspeed_eeprom_init(i2c[6], 0x51, 128 * KiB);
+ aspeed_eeprom_init(i2c[8], 0x50, 32 * KiB);
+ aspeed_eeprom_init(i2c[11], 0x51, 128 * KiB);
+ aspeed_eeprom_init(i2c[11], 0x54, 128 * KiB);
+
+ /*
+ * TODO: There is a multi-master i2c connection to an AST1030 MiniBMC on
+ * buses 0, 1, 2, 3, and 9. Source address 0x10, target address 0x20 on
+ * each.
+ */
+}
+
static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
{
return ASPEED_MACHINE(obj)->mmio_exec;
@@ -1293,6 +1330,35 @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
aspeed_soc_num_cpus(amc->soc_name);
}
+static void fby35_reset(MachineState *state)
+{
+ AspeedMachineState *bmc = ASPEED_MACHINE(state);
+ AspeedGPIOState *gpio = &bmc->soc.gpio;
+
+ qemu_devices_reset();
+
+ /* Board ID */
+ object_property_set_bool(OBJECT(gpio), "gpioV4", true, &error_fatal);
+ object_property_set_bool(OBJECT(gpio), "gpioV5", true, &error_fatal);
+ object_property_set_bool(OBJECT(gpio), "gpioV6", true, &error_fatal);
+ object_property_set_bool(OBJECT(gpio), "gpioV7", false, &error_fatal);
+}
+
+static void aspeed_machine_fby35_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+ mc->desc = "Facebook fby35 BMC (Cortex-A7)";
+ mc->reset = fby35_reset;
+ amc->fmc_model = "mx66l1g45g";
+ amc->num_cs = 2;
+ amc->macs_mask = ASPEED_MAC3_ON;
+ amc->i2c_init = fby35_i2c_init;
+ /* FIXME: Replace this macro with something more general */
+ mc->default_ram_size = FUJI_BMC_RAM_SIZE;
+}
+
#define AST1030_INTERNAL_FLASH_SIZE (1024 * 1024)
/* Main SYSCLK frequency in Hz (200MHz) */
#define SYSCLK_FRQ 200000000ULL
@@ -1412,6 +1478,10 @@ static const TypeInfo aspeed_machine_types[] = {
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_bletchley_class_init,
}, {
+ .name = MACHINE_TYPE_NAME("fby35-bmc"),
+ .parent = MACHINE_TYPE_NAME("ast2600-evb"),
+ .class_init = aspeed_machine_fby35_class_init,
+ }, {
.name = MACHINE_TYPE_NAME("ast1030-evb"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
index 4271549282..d534541684 100644
--- a/hw/arm/aspeed_ast10x0.c
+++ b/hw/arm/aspeed_ast10x0.c
@@ -15,7 +15,6 @@
#include "sysemu/sysemu.h"
#include "hw/qdev-clock.h"
#include "hw/misc/unimp.h"
-#include "hw/char/serial.h"
#include "hw/arm/aspeed_soc.h"
#define ASPEED_SOC_IOMEM_SIZE 0x00200000
@@ -33,14 +32,38 @@ static const hwaddr aspeed_soc_ast1030_memmap[] = {
[ASPEED_DEV_SBC] = 0x7E6F2000,
[ASPEED_DEV_GPIO] = 0x7E780000,
[ASPEED_DEV_TIMER1] = 0x7E782000,
+ [ASPEED_DEV_UART1] = 0x7E783000,
+ [ASPEED_DEV_UART2] = 0x7E78D000,
+ [ASPEED_DEV_UART3] = 0x7E78E000,
+ [ASPEED_DEV_UART4] = 0x7E78F000,
[ASPEED_DEV_UART5] = 0x7E784000,
+ [ASPEED_DEV_UART6] = 0x7E790000,
+ [ASPEED_DEV_UART7] = 0x7E790100,
+ [ASPEED_DEV_UART8] = 0x7E790200,
+ [ASPEED_DEV_UART9] = 0x7E790300,
+ [ASPEED_DEV_UART10] = 0x7E790400,
+ [ASPEED_DEV_UART11] = 0x7E790500,
+ [ASPEED_DEV_UART12] = 0x7E790600,
+ [ASPEED_DEV_UART13] = 0x7E790700,
[ASPEED_DEV_WDT] = 0x7E785000,
[ASPEED_DEV_LPC] = 0x7E789000,
[ASPEED_DEV_I2C] = 0x7E7B0000,
};
static const int aspeed_soc_ast1030_irqmap[] = {
+ [ASPEED_DEV_UART1] = 47,
+ [ASPEED_DEV_UART2] = 48,
+ [ASPEED_DEV_UART3] = 49,
+ [ASPEED_DEV_UART4] = 50,
[ASPEED_DEV_UART5] = 8,
+ [ASPEED_DEV_UART6] = 57,
+ [ASPEED_DEV_UART7] = 58,
+ [ASPEED_DEV_UART8] = 59,
+ [ASPEED_DEV_UART9] = 60,
+ [ASPEED_DEV_UART10] = 61,
+ [ASPEED_DEV_UART11] = 62,
+ [ASPEED_DEV_UART12] = 63,
+ [ASPEED_DEV_UART13] = 64,
[ASPEED_DEV_GPIO] = 11,
[ASPEED_DEV_TIMER1] = 16,
[ASPEED_DEV_TIMER2] = 17,
@@ -61,11 +84,11 @@ static const int aspeed_soc_ast1030_irqmap[] = {
[ASPEED_DEV_KCS] = 138, /* 138 -> 142 */
};
-static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
+static qemu_irq aspeed_soc_ast1030_get_irq(AspeedSoCState *s, int dev)
{
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
- return qdev_get_gpio_in(DEVICE(&s->armv7m), sc->irqmap[ctrl]);
+ return qdev_get_gpio_in(DEVICE(&s->armv7m), sc->irqmap[dev]);
}
static void aspeed_soc_ast1030_init(Object *obj)
@@ -113,6 +136,9 @@ static void aspeed_soc_ast1030_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename);
}
+
+ snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
+ object_initialize_child(obj, "gpio", &s->gpio, typename);
}
static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
@@ -191,10 +217,8 @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
qdev_get_gpio_in(DEVICE(&s->armv7m),
sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4));
- /* UART5 - attach an 8250 to the IO space as our UART */
- serial_mm_init(get_system_memory(), sc->memmap[ASPEED_DEV_UART5], 2,
- aspeed_soc_get_irq(s, ASPEED_DEV_UART5),
- 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN);
+ /* UART */
+ aspeed_soc_uart_init(s);
/* Timer */
object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu),
@@ -260,6 +284,14 @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
}
+
+ /* GPIO */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
+ aspeed_soc_get_irq(s, ASPEED_DEV_GPIO));
}
static void aspeed_soc_ast1030_class_init(ObjectClass *klass, void *data)
@@ -277,9 +309,11 @@ static void aspeed_soc_ast1030_class_init(ObjectClass *klass, void *data)
sc->ehcis_num = 0;
sc->wdts_num = 4;
sc->macs_num = 1;
+ sc->uarts_num = 13;
sc->irqmap = aspeed_soc_ast1030_irqmap;
sc->memmap = aspeed_soc_ast1030_memmap;
sc->num_cpus = 1;
+ sc->get_irq = aspeed_soc_ast1030_get_irq;
}
static const TypeInfo aspeed_soc_ast1030_type_info = {
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index eedda7badc..b0a4199b69 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -11,7 +11,6 @@
#include "qapi/error.h"
#include "hw/misc/unimp.h"
#include "hw/arm/aspeed_soc.h"
-#include "hw/char/serial.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "hw/i2c/aspeed_i2c.h"
@@ -61,7 +60,18 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
[ASPEED_DEV_IBT] = 0x1E789140,
[ASPEED_DEV_I2C] = 0x1E78A000,
[ASPEED_DEV_UART1] = 0x1E783000,
+ [ASPEED_DEV_UART2] = 0x1E78D000,
+ [ASPEED_DEV_UART3] = 0x1E78E000,
+ [ASPEED_DEV_UART4] = 0x1E78F000,
[ASPEED_DEV_UART5] = 0x1E784000,
+ [ASPEED_DEV_UART6] = 0x1E790000,
+ [ASPEED_DEV_UART7] = 0x1E790100,
+ [ASPEED_DEV_UART8] = 0x1E790200,
+ [ASPEED_DEV_UART9] = 0x1E790300,
+ [ASPEED_DEV_UART10] = 0x1E790400,
+ [ASPEED_DEV_UART11] = 0x1E790500,
+ [ASPEED_DEV_UART12] = 0x1E790600,
+ [ASPEED_DEV_UART13] = 0x1E790700,
[ASPEED_DEV_VUART] = 0x1E787000,
[ASPEED_DEV_I3C] = 0x1E7A0000,
[ASPEED_DEV_SDRAM] = 0x80000000,
@@ -78,6 +88,14 @@ static const int aspeed_soc_ast2600_irqmap[] = {
[ASPEED_DEV_UART3] = 49,
[ASPEED_DEV_UART4] = 50,
[ASPEED_DEV_UART5] = 8,
+ [ASPEED_DEV_UART6] = 57,
+ [ASPEED_DEV_UART7] = 58,
+ [ASPEED_DEV_UART8] = 59,
+ [ASPEED_DEV_UART9] = 60,
+ [ASPEED_DEV_UART10] = 61,
+ [ASPEED_DEV_UART11] = 62,
+ [ASPEED_DEV_UART12] = 63,
+ [ASPEED_DEV_UART13] = 64,
[ASPEED_DEV_VUART] = 8,
[ASPEED_DEV_FMC] = 39,
[ASPEED_DEV_SDMC] = 0,
@@ -114,11 +132,11 @@ static const int aspeed_soc_ast2600_irqmap[] = {
[ASPEED_DEV_I3C] = 102, /* 102 -> 107 */
};
-static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
+static qemu_irq aspeed_soc_ast2600_get_irq(AspeedSoCState *s, int dev)
{
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
- return qdev_get_gpio_in(DEVICE(&s->a7mpcore), sc->irqmap[ctrl]);
+ return qdev_get_gpio_in(DEVICE(&s->a7mpcore), sc->irqmap[dev]);
}
static void aspeed_soc_ast2600_init(Object *obj)
@@ -353,10 +371,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
- /* UART - attach an 8250 to the IO space as our UART */
- serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
- aspeed_soc_get_irq(s, s->uart_default), 38400,
- serial_hd(0), DEVICE_LITTLE_ENDIAN);
+ /* UART */
+ aspeed_soc_uart_init(s);
/* I2C */
object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
@@ -569,9 +585,11 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
sc->ehcis_num = 2;
sc->wdts_num = 4;
sc->macs_num = 4;
+ sc->uarts_num = 13;
sc->irqmap = aspeed_soc_ast2600_irqmap;
sc->memmap = aspeed_soc_ast2600_memmap;
sc->num_cpus = 2;
+ sc->get_irq = aspeed_soc_ast2600_get_irq;
}
static const TypeInfo aspeed_soc_ast2600_type_info = {
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 58714cb2a0..30574d4276 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -48,6 +48,9 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
[ASPEED_DEV_ETH1] = 0x1E660000,
[ASPEED_DEV_ETH2] = 0x1E680000,
[ASPEED_DEV_UART1] = 0x1E783000,
+ [ASPEED_DEV_UART2] = 0x1E78D000,
+ [ASPEED_DEV_UART3] = 0x1E78E000,
+ [ASPEED_DEV_UART4] = 0x1E78F000,
[ASPEED_DEV_UART5] = 0x1E784000,
[ASPEED_DEV_VUART] = 0x1E787000,
[ASPEED_DEV_SDRAM] = 0x40000000,
@@ -80,6 +83,9 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
[ASPEED_DEV_ETH1] = 0x1E660000,
[ASPEED_DEV_ETH2] = 0x1E680000,
[ASPEED_DEV_UART1] = 0x1E783000,
+ [ASPEED_DEV_UART2] = 0x1E78D000,
+ [ASPEED_DEV_UART3] = 0x1E78E000,
+ [ASPEED_DEV_UART4] = 0x1E78F000,
[ASPEED_DEV_UART5] = 0x1E784000,
[ASPEED_DEV_VUART] = 0x1E787000,
[ASPEED_DEV_SDRAM] = 0x80000000,
@@ -121,11 +127,11 @@ static const int aspeed_soc_ast2400_irqmap[] = {
#define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
-static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
+static qemu_irq aspeed_soc_ast2400_get_irq(AspeedSoCState *s, int dev)
{
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
- return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[ctrl]);
+ return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[dev]);
}
static void aspeed_soc_init(Object *obj)
@@ -297,10 +303,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
- /* UART - attach an 8250 to the IO space as our UART */
- serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
- aspeed_soc_get_irq(s, s->uart_default), 38400,
- serial_hd(0), DEVICE_LITTLE_ENDIAN);
+ /* UART */
+ aspeed_soc_uart_init(s);
/* I2C */
object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
@@ -484,9 +488,11 @@ static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data)
sc->ehcis_num = 1;
sc->wdts_num = 2;
sc->macs_num = 2;
+ sc->uarts_num = 5;
sc->irqmap = aspeed_soc_ast2400_irqmap;
sc->memmap = aspeed_soc_ast2400_memmap;
sc->num_cpus = 1;
+ sc->get_irq = aspeed_soc_ast2400_get_irq;
}
static const TypeInfo aspeed_soc_ast2400_type_info = {
@@ -509,9 +515,11 @@ static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data)
sc->ehcis_num = 2;
sc->wdts_num = 3;
sc->macs_num = 2;
+ sc->uarts_num = 5;
sc->irqmap = aspeed_soc_ast2500_irqmap;
sc->memmap = aspeed_soc_ast2500_memmap;
sc->num_cpus = 1;
+ sc->get_irq = aspeed_soc_ast2400_get_irq;
}
static const TypeInfo aspeed_soc_ast2500_type_info = {
@@ -528,4 +536,28 @@ static void aspeed_soc_register_types(void)
type_register_static(&aspeed_soc_ast2500_type_info);
};
-type_init(aspeed_soc_register_types)
+type_init(aspeed_soc_register_types);
+
+qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev)
+{
+ return ASPEED_SOC_GET_CLASS(s)->get_irq(s, dev);
+}
+
+void aspeed_soc_uart_init(AspeedSoCState *s)
+{
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ int i, uart;
+
+ /* Attach an 8250 to the IO space as our UART */
+ serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
+ aspeed_soc_get_irq(s, s->uart_default), 38400,
+ serial_hd(0), DEVICE_LITTLE_ENDIAN);
+ for (i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
+ if (uart == s->uart_default) {
+ uart++;
+ }
+ serial_mm_init(get_system_memory(), sc->memmap[uart], 2,
+ aspeed_soc_get_irq(s, uart), 38400,
+ serial_hd(i), DEVICE_LITTLE_ENDIAN);
+ }
+}