aspeed queue:

* Fix for a potential memory leak
 * Aspeed SMC cleanups on the definition of the number of flash devices
 * New bletchley-bmc machine, AST2600 based
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmInEY0ACgkQUaNDx8/7
 7KFgrhAAtSypnyVyjM9H2YkyhUrzDAgY4xIRPo8p2G3JcbipwnR3d7p4nZLZ9IIx
 8jeDrLRE/qFlhgMA/Vki1+aEix/bleoAMQq1aNMwPyJd2/72XayX5wgsh/gXNS0j
 URQYGE58n2ObEtQKvENr/HXGzTFORXeVyklgWs0DMXCokV2R6fy7uK3dbff8gmWa
 OVPAhUGsug4mzXh7Cw0nNuok1IkTyUq6f37UhM05UMYvdW7euIsnX77r/dFuPaYc
 wDbmaX2FmWzu08oVOpXasCWojqmMiNvhn53OLcOr1/XDON8Dj9WQlVKaVHpIjbJF
 yWlxSS4xqd6kQj2nKvGheGXLei55CtamdVVHFXXpmPtmKxKNbUUy6zFYcF+j6UJV
 fiNE7tFtZNxMNT58MZ3Qm1OjCzskCGtLR8HT///xDqqne+ikav4FE8f0M9BFOb+M
 ViONfJybig1n6dHRRN9Bfb3Ob6+LdipkzsW2mSq3kARpsex+uKbXFEgifdzLasHv
 wZsYu7oNZksJ31EAAY/ClfkiNc+jkk9baJru+FZRum4YO97d2pQAtfEruHs39UHs
 H9aa6qTXR3UJwzIrnHvVCobrLSMtT4I3CbVWDznM5tdCrSN1v/E6XgoWW/fJ8qHl
 YHkPsGHuO/mlUPSI06d/26dUNrsxibks3V0kMIC3BazLmklVQLI=
 =5VHm
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/legoater/tags/pull-aspeed-20220308' into staging

aspeed queue:

* Fix for a potential memory leak
* Aspeed SMC cleanups on the definition of the number of flash devices
* New bletchley-bmc machine, AST2600 based

# gpg: Signature made Tue 08 Mar 2022 08:19:25 GMT
# gpg:                using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: A0F6 6548 F048 95EB FE6B  0B60 51A3 43C7 CFFB ECA1

* remotes/legoater/tags/pull-aspeed-20220308:
  hw: aspeed_gpio: Cleanup stray semicolon after switch
  hw/arm/aspeed: add Bletchley machine type
  hw/arm/aspeed: allow missing spi_model
  hw/block: m25p80: Add support for w25q01jvq
  aspeed/smc: Fix error log
  aspeed/smc: Let the SSI core layer define the bus name
  aspeed/smc: Rename 'max_peripherals' to 'cs_num_max'
  aspeed/smc: Remove 'num_cs' field
  aspeed: Rework aspeed_board_init_flashes() interface
  aspeed/smc: Use max number of CE instead of 'num_cs'
  aspeed: Fix a potential memory leak bug in write_boot_rom()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2022-03-09 18:06:40 +00:00
commit 8098417d11
7 changed files with 114 additions and 49 deletions

View file

@ -167,6 +167,11 @@ struct AspeedMachineState {
#define FUJI_BMC_HW_STRAP1 0x00000000
#define FUJI_BMC_HW_STRAP2 0x00000000
/* Bletchley hardware value */
/* TODO: Leave same as EVB for now. */
#define BLETCHLEY_BMC_HW_STRAP1 AST2600_EVB_HW_STRAP1
#define BLETCHLEY_BMC_HW_STRAP2 AST2600_EVB_HW_STRAP2
/*
* The max ram region is for firmwares that scan the address space
* with load/store to guess how much RAM the SoC has.
@ -246,7 +251,7 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
Error **errp)
{
BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
uint8_t *storage;
g_autofree void *storage = NULL;
int64_t size;
/* The block backend size should have already been 'validated' by
@ -262,23 +267,25 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
rom_size = size;
}
storage = g_new0(uint8_t, rom_size);
storage = g_malloc0(rom_size);
if (blk_pread(blk, 0, storage, rom_size) < 0) {
error_setg(errp, "failed to read the initial flash content");
return;
}
rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
g_free(storage);
}
static void aspeed_board_init_flashes(AspeedSMCState *s,
const char *flashtype,
int unit0)
static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
unsigned int count, int unit0)
{
int i ;
int i;
for (i = 0; i < s->num_cs; ++i) {
if (!flashtype) {
return;
}
for (i = 0; i < count; ++i) {
DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
qemu_irq cs_line;
DeviceState *dev;
@ -345,8 +352,6 @@ static void aspeed_machine_init(MachineState *machine)
&error_abort);
object_property_set_int(OBJECT(&bmc->soc), "hw-strap2", amc->hw_strap2,
&error_abort);
object_property_set_int(OBJECT(&bmc->soc), "num-cs", amc->num_cs,
&error_abort);
object_property_set_link(OBJECT(&bmc->soc), "dram",
OBJECT(machine->ram), &error_abort);
if (machine->kernel_filename) {
@ -374,10 +379,10 @@ static void aspeed_machine_init(MachineState *machine)
aspeed_board_init_flashes(&bmc->soc.fmc,
bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
0);
amc->num_cs, 0);
aspeed_board_init_flashes(&bmc->soc.spi[0],
bmc->spi_model ? bmc->spi_model : amc->spi_model,
bmc->soc.fmc.num_cs);
1, amc->num_cs);
/* Install first FMC flash content as a boot rom. */
if (drive0) {
@ -897,6 +902,54 @@ static void fuji_bmc_i2c_init(AspeedMachineState *bmc)
}
}
#define TYPE_TMP421 "tmp421"
static void bletchley_bmc_i2c_init(AspeedMachineState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
I2CBus *i2c[13] = {};
for (int i = 0; i < 13; i++) {
if ((i == 8) || (i == 11)) {
continue;
}
i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i);
}
/* Bus 0 - 5 all have the same config. */
for (int i = 0; i < 6; i++) {
/* Missing model: ti,ina230 @ 0x45 */
/* Missing model: mps,mp5023 @ 0x40 */
i2c_slave_create_simple(i2c[i], TYPE_TMP421, 0x4f);
/* Missing model: nxp,pca9539 @ 0x76, but PCA9552 works enough */
i2c_slave_create_simple(i2c[i], TYPE_PCA9552, 0x76);
i2c_slave_create_simple(i2c[i], TYPE_PCA9552, 0x67);
/* Missing model: fsc,fusb302 @ 0x22 */
}
/* Bus 6 */
at24c_eeprom_init(i2c[6], 0x56, 65536);
/* Missing model: nxp,pcf85263 @ 0x51 , but ds1338 works enough */
i2c_slave_create_simple(i2c[6], "ds1338", 0x51);
/* Bus 7 */
at24c_eeprom_init(i2c[7], 0x54, 65536);
/* Bus 9 */
i2c_slave_create_simple(i2c[9], TYPE_TMP421, 0x4f);
/* Bus 10 */
i2c_slave_create_simple(i2c[10], TYPE_TMP421, 0x4f);
/* Missing model: ti,hdc1080 @ 0x40 */
i2c_slave_create_simple(i2c[10], TYPE_PCA9552, 0x67);
/* Bus 12 */
/* Missing model: adi,adm1278 @ 0x11 */
i2c_slave_create_simple(i2c[12], TYPE_TMP421, 0x4c);
i2c_slave_create_simple(i2c[12], TYPE_TMP421, 0x4d);
i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67);
}
static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
{
return ASPEED_MACHINE(obj)->mmio_exec;
@ -1220,6 +1273,25 @@ static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data)
aspeed_soc_num_cpus(amc->soc_name);
};
static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
mc->desc = "Facebook Bletchley BMC (Cortex-A7)";
amc->soc_name = "ast2600-a3";
amc->hw_strap1 = BLETCHLEY_BMC_HW_STRAP1;
amc->hw_strap2 = BLETCHLEY_BMC_HW_STRAP2;
amc->fmc_model = "w25q01jvq";
amc->spi_model = NULL;
amc->num_cs = 2;
amc->macs_mask = ASPEED_MAC2_ON;
amc->i2c_init = bletchley_bmc_i2c_init;
mc->default_ram_size = 512 * MiB;
mc->default_cpus = mc->min_cpus = mc->max_cpus =
aspeed_soc_num_cpus(amc->soc_name);
}
static const TypeInfo aspeed_machine_types[] = {
{
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
@ -1273,6 +1345,10 @@ static const TypeInfo aspeed_machine_types[] = {
.name = MACHINE_TYPE_NAME("fuji-bmc"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_fuji_class_init,
}, {
.name = MACHINE_TYPE_NAME("bletchley-bmc"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_bletchley_class_init,
}, {
.name = TYPE_ASPEED_MACHINE,
.parent = TYPE_MACHINE,

View file

@ -163,7 +163,6 @@ static void aspeed_soc_ast2600_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
object_initialize_child(obj, "fmc", &s->fmc, typename);
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
for (i = 0; i < sc->spis_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
@ -383,7 +382,6 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
for (i = 0; i < sc->spis_num; i++) {
object_property_set_link(OBJECT(&s->spi[i]), "dram",
OBJECT(s->dram_mr), &error_abort);
object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
return;
}

View file

@ -170,7 +170,6 @@ static void aspeed_soc_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
object_initialize_child(obj, "fmc", &s->fmc, typename);
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
for (i = 0; i < sc->spis_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
@ -327,7 +326,6 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
/* SPI */
for (i = 0; i < sc->spis_num; i++) {
object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
return;
}

View file

@ -340,6 +340,7 @@ static const FlashPartInfo known_devices[] = {
{ 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) },
{ INFO("w25q01jvq", 0xef4021, 0, 64 << 10, 2048, ER_4K) },
};
typedef enum {

View file

@ -571,7 +571,7 @@ static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
HWADDR_PRIx"\n", __func__, offset);
return 0;
};
}
}
static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,

View file

@ -224,7 +224,7 @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
AspeedSegments seg;
int i;
for (i = 0; i < asc->max_peripherals; i++) {
for (i = 0; i < asc->cs_num_max; i++) {
if (i == cs) {
continue;
}
@ -290,7 +290,7 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
*/
if ((asc->segments == aspeed_2500_spi1_segments ||
asc->segments == aspeed_2500_spi2_segments) &&
cs == asc->max_peripherals &&
cs == asc->cs_num_max &&
seg.addr + seg.size != asc->segments[cs].addr +
asc->segments[cs].size) {
aspeed_smc_error("Tried to change CS%d end address to 0x%"
@ -327,7 +327,7 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
unsigned size)
{
aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u" PRIx64, addr, size);
aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u", addr, size);
return 0;
}
@ -693,13 +693,13 @@ static void aspeed_smc_reset(DeviceState *d)
}
/* Unselect all peripherals */
for (i = 0; i < s->num_cs; ++i) {
for (i = 0; i < asc->cs_num_max; ++i) {
s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
qemu_set_irq(s->cs_lines[i], true);
}
/* setup the default segment register values and regions for all */
for (i = 0; i < asc->max_peripherals; ++i) {
for (i = 0; i < asc->cs_num_max; ++i) {
aspeed_smc_flash_set_segment_region(s, i,
asc->segment_to_reg(s, &asc->segments[i]));
}
@ -729,8 +729,8 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
(aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
(aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
(addr >= R_SEG_ADDR0 &&
addr < R_SEG_ADDR0 + asc->max_peripherals) ||
(addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->max_peripherals)) {
addr < R_SEG_ADDR0 + asc->cs_num_max) ||
(addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max)) {
trace_aspeed_smc_read(addr << 2, size, s->regs[addr]);
@ -1042,11 +1042,11 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
addr < s->r_timings + asc->nregs_timings) ||
addr == s->r_ce_ctrl) {
s->regs[addr] = value;
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max) {
int cs = addr - s->r_ctrl0;
aspeed_smc_flash_update_ctrl(&s->flashes[cs], value);
} else if (addr >= R_SEG_ADDR0 &&
addr < R_SEG_ADDR0 + asc->max_peripherals) {
addr < R_SEG_ADDR0 + asc->cs_num_max) {
int cs = addr - R_SEG_ADDR0;
if (value != s->regs[R_SEG_ADDR0 + cs]) {
@ -1090,7 +1090,7 @@ static void aspeed_smc_instance_init(Object *obj)
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
int i;
for (i = 0; i < asc->max_peripherals; i++) {
for (i = 0; i < asc->cs_num_max; i++) {
object_initialize_child(obj, "flash[*]", &s->flashes[i],
TYPE_ASPEED_SMC_FLASH);
}
@ -1127,21 +1127,15 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
s->r_timings = asc->r_timings;
s->conf_enable_w0 = asc->conf_enable_w0;
/* Enforce some real HW limits */
if (s->num_cs > asc->max_peripherals) {
aspeed_smc_error("num_cs cannot exceed: %d", asc->max_peripherals);
s->num_cs = asc->max_peripherals;
}
/* DMA irq. Keep it first for the initialization in the SoC */
sysbus_init_irq(sbd, &s->irq);
s->spi = ssi_create_bus(dev, "spi");
s->spi = ssi_create_bus(dev, NULL);
/* Setup cs_lines for peripherals */
s->cs_lines = g_new0(qemu_irq, s->num_cs);
s->cs_lines = g_new0(qemu_irq, asc->cs_num_max);
for (i = 0; i < s->num_cs; ++i) {
for (i = 0; i < asc->cs_num_max; ++i) {
sysbus_init_irq(sbd, &s->cs_lines[i]);
}
@ -1174,7 +1168,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
* module behind to handle the memory accesses. This depends on
* the board configuration.
*/
for (i = 0; i < asc->max_peripherals; ++i) {
for (i = 0; i < asc->cs_num_max; ++i) {
AspeedSMCFlash *fl = &s->flashes[i];
if (!object_property_set_link(OBJECT(fl), "controller", OBJECT(s),
@ -1211,7 +1205,6 @@ static const VMStateDescription vmstate_aspeed_smc = {
};
static Property aspeed_smc_properties[] = {
DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
TYPE_MEMORY_REGION, MemoryRegion *),
@ -1321,7 +1314,7 @@ static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 1;
asc->cs_num_max = 1;
asc->segments = aspeed_2400_smc_segments;
asc->flash_window_base = 0x10000000;
asc->flash_window_size = 0x6000000;
@ -1366,7 +1359,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 5;
asc->cs_num_max = 5;
asc->segments = aspeed_2400_fmc_segments;
asc->segment_addr_mask = 0xffff0000;
asc->resets = aspeed_2400_fmc_resets;
@ -1408,7 +1401,7 @@ static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_SPI_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = SPI_CONF_ENABLE_W0;
asc->max_peripherals = 1;
asc->cs_num_max = 1;
asc->segments = aspeed_2400_spi1_segments;
asc->flash_window_base = 0x30000000;
asc->flash_window_size = 0x10000000;
@ -1449,7 +1442,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 3;
asc->cs_num_max = 3;
asc->segments = aspeed_2500_fmc_segments;
asc->segment_addr_mask = 0xffff0000;
asc->resets = aspeed_2500_fmc_resets;
@ -1487,7 +1480,7 @@ static void aspeed_2500_spi1_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 2;
asc->cs_num_max = 2;
asc->segments = aspeed_2500_spi1_segments;
asc->segment_addr_mask = 0xffff0000;
asc->flash_window_base = 0x30000000;
@ -1522,7 +1515,7 @@ static void aspeed_2500_spi2_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 2;
asc->cs_num_max = 2;
asc->segments = aspeed_2500_spi2_segments;
asc->segment_addr_mask = 0xffff0000;
asc->flash_window_base = 0x38000000;
@ -1604,7 +1597,7 @@ static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 3;
asc->cs_num_max = 3;
asc->segments = aspeed_2600_fmc_segments;
asc->segment_addr_mask = 0x0ff00ff0;
asc->resets = aspeed_2600_fmc_resets;
@ -1643,7 +1636,7 @@ static void aspeed_2600_spi1_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 2;
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 2;
asc->cs_num_max = 2;
asc->segments = aspeed_2600_spi1_segments;
asc->segment_addr_mask = 0x0ff00ff0;
asc->flash_window_base = 0x30000000;
@ -1682,7 +1675,7 @@ static void aspeed_2600_spi2_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 3;
asc->conf_enable_w0 = CONF_ENABLE_W0;
asc->max_peripherals = 3;
asc->cs_num_max = 3;
asc->segments = aspeed_2600_spi2_segments;
asc->segment_addr_mask = 0x0ff00ff0;
asc->flash_window_base = 0x50000000;

View file

@ -57,7 +57,6 @@ struct AspeedSMCState {
qemu_irq irq;
uint32_t num_cs;
qemu_irq *cs_lines;
bool inject_failure;
@ -96,7 +95,7 @@ struct AspeedSMCClass {
uint8_t r_timings;
uint8_t nregs_timings;
uint8_t conf_enable_w0;
uint8_t max_peripherals;
uint8_t cs_num_max;
const uint32_t *resets;
const AspeedSegments *segments;
uint32_t segment_addr_mask;