aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/system/arm/aspeed.rst11
-rw-r--r--hw/arm/aspeed.c58
-rw-r--r--hw/arm/aspeed_ast2600.c2
-rw-r--r--hw/arm/aspeed_eeprom.c45
-rw-r--r--hw/arm/aspeed_eeprom.h5
-rw-r--r--hw/arm/fby35.c29
-rw-r--r--hw/misc/aspeed_hace.c2
-rw-r--r--target/arm/cpu.c32
-rw-r--r--target/arm/cpu.h2
9 files changed, 160 insertions, 26 deletions
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index d4e293e7f9..80538422a1 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -122,6 +122,11 @@ Options specific to Aspeed machines are :
* ``spi-model`` to change the SPI Flash model.
+ * ``bmc-console`` to change the default console device. Most of the
+ machines use the ``UART5`` device for a boot console, which is
+ mapped on ``/dev/ttyS4`` under Linux, but it is not always the
+ case.
+
For instance, to start the ``ast2500-evb`` machine with a different
FMC chip and a bigger (64M) SPI chip, use :
@@ -129,6 +134,12 @@ FMC chip and a bigger (64M) SPI chip, use :
-M ast2500-evb,fmc-model=mx25l25635e,spi-model=mx66u51235f
+To change the boot console and use device ``UART3`` (``/dev/ttyS2``
+under Linux), use :
+
+.. code-block:: bash
+
+ -M ast2500-evb,bmc-console=uart3
Aspeed minibmc family boards (``ast1030-evb``)
==================================================================
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 0b29028fe1..6880998484 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -40,7 +40,9 @@ struct AspeedMachineState {
/* Public */
AspeedSoCState soc;
+ MemoryRegion boot_rom;
bool mmio_exec;
+ uint32_t uart_chosen;
char *fmc_model;
char *spi_model;
};
@@ -275,15 +277,15 @@ static void write_boot_rom(BlockBackend *blk, hwaddr addr, size_t rom_size,
* Create a ROM and copy the flash contents at the expected address
* (0x0). Boots faster than execute-in-place.
*/
-static void aspeed_install_boot_rom(AspeedSoCState *soc, BlockBackend *blk,
+static void aspeed_install_boot_rom(AspeedMachineState *bmc, BlockBackend *blk,
uint64_t rom_size)
{
- MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
+ AspeedSoCState *soc = &bmc->soc;
- memory_region_init_rom(boot_rom, NULL, "aspeed.boot_rom", rom_size,
+ memory_region_init_rom(&bmc->boot_rom, NULL, "aspeed.boot_rom", rom_size,
&error_abort);
memory_region_add_subregion_overlap(&soc->spi_boot_container, 0,
- boot_rom, 1);
+ &bmc->boot_rom, 1);
write_boot_rom(blk, ASPEED_SOC_SPI_BOOT_ADDR, rom_size, &error_abort);
}
@@ -332,10 +334,11 @@ static void connect_serial_hds_to_uarts(AspeedMachineState *bmc)
AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
AspeedSoCState *s = &bmc->soc;
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ int uart_chosen = bmc->uart_chosen ? bmc->uart_chosen : amc->uart_default;
- aspeed_soc_uart_set_chr(s, amc->uart_default, serial_hd(0));
+ aspeed_soc_uart_set_chr(s, uart_chosen, serial_hd(0));
for (int i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
- if (uart == amc->uart_default) {
+ if (uart == uart_chosen) {
continue;
}
aspeed_soc_uart_set_chr(s, uart, serial_hd(i));
@@ -431,8 +434,7 @@ static void aspeed_machine_init(MachineState *machine)
if (mtd0) {
uint64_t rom_size = memory_region_size(&bmc->soc.spi_boot);
- aspeed_install_boot_rom(&bmc->soc, blk_by_legacy_dinfo(mtd0),
- rom_size);
+ aspeed_install_boot_rom(bmc, blk_by_legacy_dinfo(mtd0), rom_size);
}
}
@@ -788,8 +790,10 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
0x48);
i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), TYPE_TMP105,
0x4a);
- at24c_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 8), 0x50, 64 * KiB);
- at24c_eeprom_init(aspeed_i2c_get_bus(&soc->i2c, 8), 0x51, 64 * KiB);
+ at24c_eeprom_init_rom(aspeed_i2c_get_bus(&soc->i2c, 8), 0x50,
+ 64 * KiB, rainier_bb_fruid, rainier_bb_fruid_len);
+ at24c_eeprom_init_rom(aspeed_i2c_get_bus(&soc->i2c, 8), 0x51,
+ 64 * KiB, rainier_bmc_fruid, rainier_bmc_fruid_len);
create_pca9552(soc, 8, 0x60);
create_pca9552(soc, 8, 0x61);
/* Bus 8: ucd90320@11 */
@@ -1076,6 +1080,35 @@ static void aspeed_set_spi_model(Object *obj, const char *value, Error **errp)
bmc->spi_model = g_strdup(value);
}
+static char *aspeed_get_bmc_console(Object *obj, Error **errp)
+{
+ AspeedMachineState *bmc = ASPEED_MACHINE(obj);
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
+ int uart_chosen = bmc->uart_chosen ? bmc->uart_chosen : amc->uart_default;
+
+ return g_strdup_printf("uart%d", uart_chosen - ASPEED_DEV_UART1 + 1);
+}
+
+static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
+{
+ AspeedMachineState *bmc = ASPEED_MACHINE(obj);
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
+ AspeedSoCClass *sc = ASPEED_SOC_CLASS(object_class_by_name(amc->soc_name));
+ int val;
+
+ if (sscanf(value, "uart%u", &val) != 1) {
+ error_setg(errp, "Bad value for \"uart\" property");
+ return;
+ }
+
+ /* The number of UART depends on the SoC */
+ if (val < 1 || val > sc->uarts_num) {
+ error_setg(errp, "\"uart\" should be in range [1 - %d]", sc->uarts_num);
+ return;
+ }
+ bmc->uart_chosen = ASPEED_DEV_UART1 + val - 1;
+}
+
static void aspeed_machine_class_props_init(ObjectClass *oc)
{
object_class_property_add_bool(oc, "execute-in-place",
@@ -1084,6 +1117,11 @@ static void aspeed_machine_class_props_init(ObjectClass *oc)
object_class_property_set_description(oc, "execute-in-place",
"boot directly from CE0 flash device");
+ object_class_property_add_str(oc, "bmc-console", aspeed_get_bmc_console,
+ aspeed_set_bmc_console);
+ object_class_property_set_description(oc, "bmc-console",
+ "Change the default UART to \"uartX\"");
+
object_class_property_add_str(oc, "fmc-model", aspeed_get_fmc_model,
aspeed_set_fmc_model);
object_class_property_set_description(oc, "fmc-model",
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 1bf1246148..a8b3a8065a 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -316,6 +316,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
&error_abort);
object_property_set_bool(OBJECT(&s->cpu[i]), "neon", false,
&error_abort);
+ object_property_set_bool(OBJECT(&s->cpu[i]), "vfp-d32", false,
+ &error_abort);
object_property_set_link(OBJECT(&s->cpu[i]), "memory",
OBJECT(s->memory), &error_abort);
diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c
index dc33a88a54..ace5266cec 100644
--- a/hw/arm/aspeed_eeprom.c
+++ b/hw/arm/aspeed_eeprom.c
@@ -119,9 +119,52 @@ const uint8_t yosemitev2_bmc_fruid[] = {
0x6e, 0x66, 0x69, 0x67, 0x20, 0x41, 0xc1, 0x45,
};
+const uint8_t rainier_bb_fruid[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84,
+ 0x28, 0x00, 0x52, 0x54, 0x04, 0x56, 0x48, 0x44, 0x52, 0x56, 0x44, 0x02,
+ 0x01, 0x00, 0x50, 0x54, 0x0e, 0x56, 0x54, 0x4f, 0x43, 0x00, 0x00, 0x37,
+ 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x46, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x52, 0x54,
+ 0x04, 0x56, 0x54, 0x4f, 0x43, 0x50, 0x54, 0x38, 0x56, 0x49, 0x4e, 0x49,
+ 0x00, 0x00, 0x81, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x53,
+ 0x59, 0x53, 0x00, 0x00, 0xbb, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x56, 0x43, 0x45, 0x4e, 0x00, 0x00, 0xe2, 0x00, 0x27, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x56, 0x53, 0x42, 0x50, 0x00, 0x00, 0x09, 0x01, 0x19, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x46, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00,
+ 0x52, 0x54, 0x04, 0x56, 0x49, 0x4e, 0x49, 0x44, 0x52, 0x04, 0x44, 0x45,
+ 0x53, 0x43, 0x48, 0x57, 0x02, 0x30, 0x31, 0x43, 0x43, 0x04, 0x33, 0x34,
+ 0x35, 0x36, 0x46, 0x4e, 0x04, 0x46, 0x52, 0x34, 0x39, 0x53, 0x4e, 0x04,
+ 0x53, 0x52, 0x31, 0x32, 0x50, 0x4e, 0x04, 0x50, 0x52, 0x39, 0x39, 0x50,
+ 0x46, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x52, 0x54,
+ 0x04, 0x56, 0x53, 0x59, 0x53, 0x53, 0x45, 0x07, 0x49, 0x42, 0x4d, 0x53,
+ 0x59, 0x53, 0x31, 0x54, 0x4d, 0x08, 0x32, 0x32, 0x32, 0x32, 0x2d, 0x32,
+ 0x32, 0x32, 0x50, 0x46, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
+ 0x00, 0x52, 0x54, 0x04, 0x56, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x07, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x46, 0x43, 0x08, 0x31, 0x31, 0x31,
+ 0x31, 0x2d, 0x31, 0x31, 0x31, 0x50, 0x46, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x15, 0x00, 0x52, 0x54, 0x04, 0x56, 0x53, 0x42, 0x50, 0x49,
+ 0x4d, 0x04, 0x50, 0x00, 0x10, 0x01, 0x50, 0x46, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+};
+
+/* Rainier BMC FRU */
+const uint8_t rainier_bmc_fruid[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84,
+ 0x28, 0x00, 0x52, 0x54, 0x04, 0x56, 0x48, 0x44, 0x52, 0x56, 0x44, 0x02,
+ 0x01, 0x00, 0x50, 0x54, 0x0e, 0x56, 0x54, 0x4f, 0x43, 0x00, 0x00, 0x37,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x46, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x52, 0x54,
+ 0x04, 0x56, 0x54, 0x4f, 0x43, 0x50, 0x54, 0x0e, 0x56, 0x49, 0x4e, 0x49,
+ 0x00, 0x00, 0x57, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x46,
+ 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x52, 0x54, 0x04, 0x56, 0x49, 0x4e,
+ 0x49, 0x44, 0x52, 0x04, 0x44, 0x45, 0x53, 0x43, 0x48, 0x57, 0x02, 0x30,
+ 0x31, 0x50, 0x46, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
const size_t tiogapass_bmc_fruid_len = sizeof(tiogapass_bmc_fruid);
const size_t fby35_nic_fruid_len = sizeof(fby35_nic_fruid);
const size_t fby35_bb_fruid_len = sizeof(fby35_bb_fruid);
const size_t fby35_bmc_fruid_len = sizeof(fby35_bmc_fruid);
-
const size_t yosemitev2_bmc_fruid_len = sizeof(yosemitev2_bmc_fruid);
+const size_t rainier_bb_fruid_len = sizeof(rainier_bb_fruid);
+const size_t rainier_bmc_fruid_len = sizeof(rainier_bmc_fruid);
diff --git a/hw/arm/aspeed_eeprom.h b/hw/arm/aspeed_eeprom.h
index 86db6f0479..bbf9e54365 100644
--- a/hw/arm/aspeed_eeprom.h
+++ b/hw/arm/aspeed_eeprom.h
@@ -22,4 +22,9 @@ extern const size_t fby35_bmc_fruid_len;
extern const uint8_t yosemitev2_bmc_fruid[];
extern const size_t yosemitev2_bmc_fruid_len;
+extern const uint8_t rainier_bb_fruid[];
+extern const size_t rainier_bb_fruid_len;
+extern const uint8_t rainier_bmc_fruid[];
+extern const size_t rainier_bmc_fruid_len;
+
#endif
diff --git a/hw/arm/fby35.c b/hw/arm/fby35.c
index f4600c290b..f2ff6c1abf 100644
--- a/hw/arm/fby35.c
+++ b/hw/arm/fby35.c
@@ -70,8 +70,6 @@ static void fby35_bmc_write_boot_rom(DriveInfo *dinfo, MemoryRegion *mr,
static void fby35_bmc_init(Fby35State *s)
{
- DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
-
object_initialize_child(OBJECT(s), "bmc", &s->bmc, "ast2600-a3");
memory_region_init(&s->bmc_memory, OBJECT(&s->bmc), "bmc-memory",
@@ -95,18 +93,21 @@ static void fby35_bmc_init(Fby35State *s)
aspeed_board_init_flashes(&s->bmc.fmc, "n25q00", 2, 0);
/* Install first FMC flash content as a boot rom. */
- if (drive0) {
- AspeedSMCFlash *fl = &s->bmc.fmc.flashes[0];
- MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
- uint64_t size = memory_region_size(&fl->mmio);
-
- if (!s->mmio_exec) {
- memory_region_init_rom(boot_rom, NULL, "aspeed.boot_rom",
- size, &error_abort);
- memory_region_add_subregion(&s->bmc_memory, FBY35_BMC_FIRMWARE_ADDR,
- boot_rom);
- fby35_bmc_write_boot_rom(drive0, boot_rom, FBY35_BMC_FIRMWARE_ADDR,
- size, &error_abort);
+ if (!s->mmio_exec) {
+ DriveInfo *mtd0 = drive_get(IF_MTD, 0, 0);
+
+ if (mtd0) {
+ AspeedSoCState *bmc = &s->bmc;
+ uint64_t rom_size = memory_region_size(&bmc->spi_boot);
+
+ memory_region_init_rom(&s->bmc_boot_rom, NULL, "aspeed.boot_rom",
+ rom_size, &error_abort);
+ memory_region_add_subregion_overlap(&bmc->spi_boot_container, 0,
+ &s->bmc_boot_rom, 1);
+
+ fby35_bmc_write_boot_rom(mtd0, &s->bmc_boot_rom,
+ FBY35_BMC_FIRMWARE_ADDR,
+ rom_size, &error_abort);
}
}
}
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 12a761f1f5..b07506ec04 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -189,7 +189,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
bool acc_mode)
{
struct iovec iov[ASPEED_HACE_MAX_SG];
- g_autofree uint8_t *digest_buf;
+ g_autofree uint8_t *digest_buf = NULL;
size_t digest_len = 0;
int niov = 0;
int i;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 4d5bb57f07..353fc48567 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1277,6 +1277,9 @@ static Property arm_cpu_cfgend_property =
static Property arm_cpu_has_vfp_property =
DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
+static Property arm_cpu_has_vfp_d32_property =
+ DEFINE_PROP_BOOL("vfp-d32", ARMCPU, has_vfp_d32, true);
+
static Property arm_cpu_has_neon_property =
DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
@@ -1408,6 +1411,22 @@ void arm_cpu_post_init(Object *obj)
}
}
+ if (cpu->has_vfp && cpu_isar_feature(aa32_simd_r32, cpu)) {
+ cpu->has_vfp_d32 = true;
+ if (!kvm_enabled()) {
+ /*
+ * The permitted values of the SIMDReg bits [3:0] on
+ * Armv8-A are either 0b0000 and 0b0010. On such CPUs,
+ * make sure that has_vfp_d32 can not be set to false.
+ */
+ if (!(arm_feature(&cpu->env, ARM_FEATURE_V8) &&
+ !arm_feature(&cpu->env, ARM_FEATURE_M))) {
+ qdev_property_add_static(DEVICE(obj),
+ &arm_cpu_has_vfp_d32_property);
+ }
+ }
+ }
+
if (arm_feature(&cpu->env, ARM_FEATURE_NEON)) {
cpu->has_neon = true;
if (!kvm_enabled()) {
@@ -1674,6 +1693,19 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
+ if (cpu->has_vfp_d32 != cpu->has_neon) {
+ error_setg(errp, "ARM CPUs must have both VFP-D32 and Neon or neither");
+ return;
+ }
+
+ if (!cpu->has_vfp_d32) {
+ uint32_t u;
+
+ u = cpu->isar.mvfr0;
+ u = FIELD_DP32(u, MVFR0, SIMDREG, 1); /* 16 registers */
+ cpu->isar.mvfr0 = u;
+ }
+
if (!cpu->has_vfp) {
uint64_t t;
uint32_t u;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 36c608f0e6..af0119addf 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -924,6 +924,8 @@ struct ArchCPU {
bool has_pmu;
/* CPU has VFP */
bool has_vfp;
+ /* CPU has 32 VFP registers */
+ bool has_vfp_d32;
/* CPU has Neon */
bool has_neon;
/* CPU has M-profile DSP extension */