Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge tag 'pull-aspeed-20230901' of https://github.com/legoater/qemu
…into staging

aspeed queue:

* Fixes for the Aspeed I2C model
* New SDK image for avocado tests
* blockdev support for flash device definition
* SD refactoring preparing ground for eMMC support

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmTxsaQACgkQUaNDx8/7
# 7KGXmg//XJNisscl/VWSBaGmH5MbQUAg/QCRalXx1V/lJ8rhE/JqwnWKuoPFd4EN
# iDlh3ufpzxPhHFc9boechuM5ytlrJxpLJoCIJ4sw/4qnO3Dy3Q6BCy1t8Ma62D1u
# oE7cAMHsriJ1uTJNHUTFo72VapTaH2XwFN9lFDuQW45d+WWAXtVJsqvRgFETNmw6
# YYnTTpH2gLTZZFEgOixhWpGLh4Ibc/l8U1VzL0ctQmC11xng0bqk3PAqU9NGzcM5
# MJmEGAxg43CnFu9NJI1nMqC/coi/8PFtrM7HprSwE3H8Jkwncs4ePVT+kZQC+VNQ
# 7EaVkksfEGHlN8XP5+eQDrQ5yT6ve+fbHTLQhwULfeyt0GlQ8h1yewvHCDWo/zw3
# XI1ZyOcNZ2yiaenSUrTPzu0LiqZEJQnzRjPCpgTi1fU08ryEMEaPtr176YDLCguQ
# cpRj4QSZHCrGl/Eo9NlkFP/2rQDKTvCcedKPkYLQtsurSiH/36Oj9YvZycNtZ574
# ortKAtru4YV/rglNX4L8JDhdI+nqvy1liifpJsiS/2KBZDpVFaP8PzGIV40HNy3G
# 8/LVTnaggZaScF3ftHhkg84uQumELS9l2dhsNCL9HqdlrNXLQrVAIR6iuQlpOKBa
# 5S/6h7ZXGOb1qNVQjYp4HCrB7X1KIJYksZ3GdUREf8ot5Ds1FhE=
# =ymmX
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 01 Sep 2023 05:40:52 EDT
# gpg:                using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@redhat.com>" [unknown]
# gpg:                 aka "Cédric Le Goater <clg@kaod.org>" [unknown]
# 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

* tag 'pull-aspeed-20230901' of https://github.com/legoater/qemu: (26 commits)
  hw/sd: Introduce a "sd-card" SPI variant model
  hw/sd: Add sd_cmd_SET_BLOCK_COUNT() handler
  hw/sd: Add sd_cmd_SEND_TUNING_BLOCK() handler
  hw/sd: Add sd_cmd_SEND_RELATIVE_ADDR() handler
  hw/sd: Add sd_cmd_ALL_SEND_CID() handler
  hw/sd: Add sd_cmd_SEND_OP_CMD() handler
  hw/sd: Add sd_cmd_GO_IDLE_STATE() handler
  hw/sd: Add sd_cmd_unimplemented() handler
  hw/sd: Add sd_cmd_illegal() handler
  hw/sd: Introduce sd_cmd_handler type
  hw/sd: Move proto_name to SDProto structure
  hw/sd: When card is in wrong state, log which spec version is used
  hw/sd: When card is in wrong state, log which state it is
  hw/sd/sdcard: Return ILLEGAL for CMD19/CMD23 prior SD spec v3.01
  aspeed: Get the BlockBackend of FMC0 from the flash device
  m25p80: Introduce an helper to retrieve the BlockBackend of a device
  aspeed: Create flash devices only when defaults are enabled
  hw/ssi: Check for duplicate CS indexes
  aspeed/smc: Wire CS lines at reset
  hw/ssi: Introduce a ssi_get_cs() helper
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
Stefan Hajnoczi committed Sep 6, 2023
2 parents 2d8fbcb + c3287c0 commit e00ad52
Show file tree
Hide file tree
Showing 19 changed files with 367 additions and 201 deletions.
35 changes: 29 additions & 6 deletions docs/system/arm/aspeed.rst
Expand Up @@ -104,7 +104,7 @@ To boot a kernel directly from a Linux build tree:
-dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
-initrd rootfs.cpio
The image should be attached as an MTD drive. Run :
To boot the machine from the flash image, use an MTD drive :

.. code-block:: bash
Expand All @@ -117,23 +117,46 @@ Options specific to Aspeed machines are :
device by using the FMC controller to load the instructions, and
not simply from RAM. This takes a little longer.

* ``fmc-model`` to change the FMC Flash model. FW needs support for
the chip model to boot.
* ``fmc-model`` to change the default FMC Flash model. FW needs
support for the chip model to boot.

* ``spi-model`` to change the SPI Flash model.
* ``spi-model`` to change the default 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 :
To use other flash models, for instance a different FMC chip and a
bigger (64M) SPI for the ``ast2500-evb`` machine, run :

.. code-block:: bash
-M ast2500-evb,fmc-model=mx25l25635e,spi-model=mx66u51235f
When more flexibility is needed to define the flash devices, to use
different flash models or define all flash devices (up to 8), the
``-nodefaults`` QEMU option can be used to avoid creating the default
flash devices.

Flash devices should then be created from the command line and attached
to a block device :

.. code-block:: bash
$ qemu-system-arm -M ast2600-evb \
-blockdev node-name=fmc0,driver=file,filename=/path/to/fmc0.img \
-device mx66u51235f,bus=ssi.0,cs=0x0,drive=fmc0 \
-blockdev node-name=fmc1,driver=file,filename=/path/to/fmc1.img \
-device mx66u51235f,bus=ssi.0,cs=0x1,drive=fmc1 \
-blockdev node-name=spi1,driver=file,filename=/path/to/spi1.img \
-device mx66u51235f,cs=0x0,bus=ssi.1,drive=spi1 \
-nographic -nodefaults
In that case, the machine boots fetching instructions from the FMC0
device. It is slower to start but closer to what HW does. Using the
machine option ``execute-in-place`` has a similar effect.

To change the boot console and use device ``UART3`` (``/dev/ttyS2``
under Linux), use :

Expand Down
40 changes: 19 additions & 21 deletions hw/arm/aspeed.c
Expand Up @@ -15,6 +15,7 @@
#include "hw/arm/aspeed.h"
#include "hw/arm/aspeed_soc.h"
#include "hw/arm/aspeed_eeprom.h"
#include "hw/block/flash.h"
#include "hw/i2c/i2c_mux_pca954x.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/misc/pca9552.h"
Expand Down Expand Up @@ -47,6 +48,13 @@ struct AspeedMachineState {
char *spi_model;
};

/* On 32-bit hosts, lower RAM to 1G because of the 2047 MB limit */
#if HOST_LONG_BITS == 32
#define ASPEED_RAM_SIZE(sz) MIN((sz), 1 * GiB)
#else
#define ASPEED_RAM_SIZE(sz) (sz)
#endif

/* Palmetto hardware value: 0x120CE416 */
#define PALMETTO_BMC_HW_STRAP1 ( \
SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) | \
Expand Down Expand Up @@ -300,17 +308,14 @@ void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,

for (i = 0; i < count; ++i) {
DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
qemu_irq cs_line;
DeviceState *dev;

dev = qdev_new(flashtype);
if (dinfo) {
qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
}
qdev_prop_set_uint8(dev, "cs", i);
qdev_realize_and_unref(dev, BUS(s->spi), &error_fatal);

cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
qdev_connect_gpio_out_named(DEVICE(s), "cs", i, cs_line);
}
}

Expand Down Expand Up @@ -392,12 +397,14 @@ static void aspeed_machine_init(MachineState *machine)
connect_serial_hds_to_uarts(bmc);
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);

aspeed_board_init_flashes(&bmc->soc.fmc,
if (defaults_enabled()) {
aspeed_board_init_flashes(&bmc->soc.fmc,
bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
amc->num_cs, 0);
aspeed_board_init_flashes(&bmc->soc.spi[0],
aspeed_board_init_flashes(&bmc->soc.spi[0],
bmc->spi_model ? bmc->spi_model : amc->spi_model,
1, amc->num_cs);
}

if (machine->kernel_filename && sc->num_cpus > 1) {
/* With no u-boot we must set up a boot stub for the secondary CPU */
Expand Down Expand Up @@ -430,11 +437,12 @@ static void aspeed_machine_init(MachineState *machine)
}

if (!bmc->mmio_exec) {
DriveInfo *mtd0 = drive_get(IF_MTD, 0, 0);
DeviceState *dev = ssi_get_cs(bmc->soc.fmc.spi, 0);
BlockBackend *fmc0 = dev ? m25p80_get_blk(dev) : NULL;

if (mtd0) {
if (fmc0) {
uint64_t rom_size = memory_region_size(&bmc->soc.spi_boot);
aspeed_install_boot_rom(bmc, blk_by_legacy_dinfo(mtd0), rom_size);
aspeed_install_boot_rom(bmc, fmc0, rom_size);
}
}

Expand Down Expand Up @@ -1423,12 +1431,7 @@ static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data)
aspeed_soc_num_cpus(amc->soc_name);
};

/* On 32-bit hosts, lower RAM to 1G because of the 2047 MB limit */
#if HOST_LONG_BITS == 32
#define FUJI_BMC_RAM_SIZE (1 * GiB)
#else
#define FUJI_BMC_RAM_SIZE (2 * GiB)
#endif
#define FUJI_BMC_RAM_SIZE ASPEED_RAM_SIZE(2 * GiB)

static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data)
{
Expand All @@ -1450,12 +1453,7 @@ static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data)
aspeed_soc_num_cpus(amc->soc_name);
};

/* On 32-bit hosts, lower RAM to 1G because of the 2047 MB limit */
#if HOST_LONG_BITS == 32
#define BLETCHLEY_BMC_RAM_SIZE (1 * GiB)
#else
#define BLETCHLEY_BMC_RAM_SIZE (2 * GiB)
#endif
#define BLETCHLEY_BMC_RAM_SIZE ASPEED_RAM_SIZE(2 * GiB)

static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
{
Expand Down
7 changes: 4 additions & 3 deletions hw/arm/stellaris.c
Expand Up @@ -1235,14 +1235,15 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)

dinfo = drive_get(IF_SD, 0, 0);
blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
carddev = qdev_new(TYPE_SD_CARD);
carddev = qdev_new(TYPE_SD_CARD_SPI);
qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
qdev_prop_set_bit(carddev, "spi", true);
qdev_realize_and_unref(carddev,
qdev_get_child_bus(sddev, "sd-bus"),
&error_fatal);

ssddev = ssi_create_peripheral(bus, "ssd0323");
ssddev = qdev_new("ssd0323");
qdev_prop_set_uint8(ssddev, "cs", 1);
qdev_realize_and_unref(ssddev, bus, &error_fatal);

gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
Expand Down
1 change: 1 addition & 0 deletions hw/arm/xilinx_zynq.c
Expand Up @@ -164,6 +164,7 @@ static inline int zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
blk_by_legacy_dinfo(dinfo),
&error_fatal);
}
qdev_prop_set_uint8(flash_dev, "cs", j);
qdev_realize_and_unref(flash_dev, BUS(spi), &error_fatal);

cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
Expand Down
1 change: 1 addition & 0 deletions hw/arm/xlnx-versal-virt.c
Expand Up @@ -740,6 +740,7 @@ static void versal_virt_init(MachineState *machine)
qdev_prop_set_drive_err(flash_dev, "drive",
blk_by_legacy_dinfo(dinfo), &error_fatal);
}
qdev_prop_set_uint8(flash_dev, "cs", i);
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);

cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
Expand Down
2 changes: 2 additions & 0 deletions hw/arm/xlnx-zcu102.c
Expand Up @@ -201,6 +201,7 @@ static void xlnx_zcu102_init(MachineState *machine)
qdev_prop_set_drive_err(flash_dev, "drive",
blk_by_legacy_dinfo(dinfo), &error_fatal);
}
qdev_prop_set_uint8(flash_dev, "cs", i);
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);

cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
Expand All @@ -224,6 +225,7 @@ static void xlnx_zcu102_init(MachineState *machine)
qdev_prop_set_drive_err(flash_dev, "drive",
blk_by_legacy_dinfo(dinfo), &error_fatal);
}
qdev_prop_set_uint8(flash_dev, "cs", i);
qdev_realize_and_unref(flash_dev, spi_bus, &error_fatal);

cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
Expand Down
6 changes: 6 additions & 0 deletions hw/block/m25p80.c
Expand Up @@ -25,6 +25,7 @@
#include "qemu/units.h"
#include "sysemu/block-backend.h"
#include "hw/block/block.h"
#include "hw/block/flash.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/ssi/ssi.h"
Expand Down Expand Up @@ -1830,3 +1831,8 @@ static void m25p80_register_types(void)
}

type_init(m25p80_register_types)

BlockBackend *m25p80_get_blk(DeviceState *dev)
{
return M25P80(dev)->blk;
}
40 changes: 13 additions & 27 deletions hw/i2c/aspeed_i2c.c
Expand Up @@ -226,7 +226,7 @@ static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
return 0;
}

static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
static int aspeed_i2c_bus_send(AspeedI2CBus *bus)
{
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
int ret = -1;
Expand All @@ -236,10 +236,10 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
uint32_t reg_byte_buf = aspeed_i2c_bus_byte_buf_offset(bus);
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
int pool_tx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl,
TX_COUNT);
TX_COUNT) + 1;

if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
for (i = pool_start; i < pool_tx_count; i++) {
for (i = 0; i < pool_tx_count; i++) {
uint8_t *pool_base = aic->bus_pool_base(bus);

trace_aspeed_i2c_bus_send("BUF", i + 1, pool_tx_count,
Expand Down Expand Up @@ -273,7 +273,7 @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
}
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, TX_DMA_EN, 0);
} else {
trace_aspeed_i2c_bus_send("BYTE", pool_start, 1,
trace_aspeed_i2c_bus_send("BYTE", 0, 1,
bus->regs[reg_byte_buf]);
ret = i2c_send(bus->bus, bus->regs[reg_byte_buf]);
}
Expand All @@ -293,10 +293,14 @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
uint32_t reg_dma_addr = aspeed_i2c_bus_dma_addr_offset(bus);
int pool_rx_count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl,
RX_COUNT);
RX_SIZE) + 1;

if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_BUFF_EN)) {
uint8_t *pool_base = aic->bus_pool_base(bus);
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl,
BUF_ORGANIZATION)) {
pool_base += 16;
}

for (i = 0; i < pool_rx_count; i++) {
pool_base[i] = i2c_recv(bus->bus);
Expand Down Expand Up @@ -418,7 +422,7 @@ static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_BUFF_EN)) {
count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT);
count = SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT) + 1;
} else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, RX_DMA_EN)) {
count = bus->regs[reg_dma_len];
} else { /* BYTE mode */
Expand Down Expand Up @@ -446,10 +450,8 @@ static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
*/
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
{
uint8_t pool_start = 0;
uint32_t reg_intr_sts = aspeed_i2c_bus_intr_sts_offset(bus);
uint32_t reg_cmd = aspeed_i2c_bus_cmd_offset(bus);
uint32_t reg_pool_ctrl = aspeed_i2c_bus_pool_ctrl_offset(bus);
uint32_t reg_dma_len = aspeed_i2c_bus_dma_len_offset(bus);

if (!aspeed_i2c_check_sram(bus)) {
Expand Down Expand Up @@ -483,27 +485,11 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)

SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_START_CMD, 0);

/*
* The START command is also a TX command, as the slave
* address is sent on the bus. Drop the TX flag if nothing
* else needs to be sent in this sequence.
*/
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_pool_ctrl, TX_COUNT)
== 1) {
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
} else {
/*
* Increase the start index in the TX pool buffer to
* skip the address byte.
*/
pool_start++;
}
} else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) {
if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) {
if (bus->regs[reg_dma_len] == 0) {
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
}
} else {
} else if (!SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_BUFF_EN)) {
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_cmd, M_TX_CMD, 0);
}

Expand All @@ -520,7 +506,7 @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)

if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, M_TX_CMD)) {
aspeed_i2c_set_state(bus, I2CD_MTXD);
if (aspeed_i2c_bus_send(bus, pool_start)) {
if (aspeed_i2c_bus_send(bus)) {
SHARED_ARRAY_FIELD_DP32(bus->regs, reg_intr_sts, TX_NAK, 1);
i2c_end_transfer(bus->bus);
} else {
Expand Down
1 change: 1 addition & 0 deletions hw/microblaze/petalogix_ml605_mmu.c
Expand Up @@ -192,6 +192,7 @@ petalogix_ml605_init(MachineState *machine)
blk_by_legacy_dinfo(dinfo),
&error_fatal);
}
qdev_prop_set_uint8(dev, "cs", i);
qdev_realize_and_unref(dev, BUS(spi), &error_fatal);

cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);
Expand Down
3 changes: 1 addition & 2 deletions hw/riscv/sifive_u.c
Expand Up @@ -674,9 +674,8 @@ static void sifive_u_machine_init(MachineState *machine)

dinfo = drive_get(IF_SD, 0, 0);
blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
card_dev = qdev_new(TYPE_SD_CARD);
card_dev = qdev_new(TYPE_SD_CARD_SPI);
qdev_prop_set_drive_err(card_dev, "drive", blk, &error_fatal);
qdev_prop_set_bit(card_dev, "spi", true);
qdev_realize_and_unref(card_dev,
qdev_get_child_bus(sd_dev, "sd-bus"),
&error_fatal);
Expand Down

0 comments on commit e00ad52

Please sign in to comment.