diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-05-04 17:05:53 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-05-04 17:05:53 +0100 |
commit | 87c6cef605a077b20a245d54167127ccf7996e23 (patch) | |
tree | 62553013584befc8e93edc79bdd9752450f50c04 /hw/ssi | |
parent | 3e13d8e34b53d8f9a3421a816ccfbdc5fa874e98 (diff) | |
parent | 9cccb912cfa865f0bae6b156fa94e2f216dd8835 (diff) |
Merge remote-tracking branch 'remotes/legoater/tags/pull-aspeed-20210503' into staging
Aspeed patches :
* Fixes for the DMA space
* New model for ASPEED's Hash and Crypto Engine (Joel and Klaus)
* Acceptance tests (Joel)
* A fix for the XDMA model
* Some extra features for the SMC controller.
* Two new boards : rainier-bmc and quanta-q7l1-bmc (Patrick)
# gpg: Signature made Mon 03 May 2021 06:23:36 BST
# 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-20210503:
aspeed: Add support for the quanta-q7l1-bmc board
hw/block: m25p80: Add support for mt25ql02g and mt25qu02g
aspeed: Add support for the rainier-bmc board
aspeed: Deprecate the swift-bmc machine
tests/qtest: Rename m25p80 test in aspeed_smc test
aspeed/smc: Add extra controls to request DMA
aspeed/smc: Add a 'features' attribute to the object class
hw/misc/aspeed_xdma: Add AST2600 support
tests/acceptance: Test ast2600 machine
tests/acceptance: Test ast2400 and ast2500 machines
tests/qtest: Add test for Aspeed HACE
aspeed: Integrate HACE
hw: Model ASPEED's Hash and Crypto Engine
hw/arm/aspeed: Do not sysbus-map mmio flash region directly, use alias
aspeed/i2c: Rename DMA address space
aspeed/i2c: Fix DMA address mask
aspeed/smc: Remove unused "sdram-base" property
aspeed/smc: Use the RAM memory region for DMAs
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ssi')
-rw-r--r-- | hw/ssi/aspeed_smc.c | 119 |
1 files changed, 92 insertions, 27 deletions
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index 16addee4dc..189b35637c 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -127,6 +127,8 @@ /* DMA Control/Status Register */ #define R_DMA_CTRL (0x80 / 4) +#define DMA_CTRL_REQUEST (1 << 31) +#define DMA_CTRL_GRANT (1 << 30) #define DMA_CTRL_DELAY_MASK 0xf #define DMA_CTRL_DELAY_SHIFT 8 #define DMA_CTRL_FREQ_MASK 0xf @@ -178,10 +180,8 @@ * 0: 4 bytes * 0x7FFFFF: 32M bytes */ -#define DMA_DRAM_ADDR(s, val) ((s)->sdram_base | \ - ((val) & (s)->ctrl->dma_dram_mask)) -#define DMA_FLASH_ADDR(s, val) ((s)->ctrl->flash_window_base | \ - ((val) & (s)->ctrl->dma_flash_mask)) +#define DMA_DRAM_ADDR(s, val) ((val) & (s)->ctrl->dma_dram_mask) +#define DMA_FLASH_ADDR(s, val) ((val) & (s)->ctrl->dma_flash_mask) #define DMA_LENGTH(val) ((val) & 0x01FFFFFC) /* Flash opcodes. */ @@ -230,6 +230,7 @@ static uint32_t aspeed_smc_segment_to_reg(const AspeedSMCState *s, const AspeedSegments *seg); static void aspeed_smc_reg_to_segment(const AspeedSMCState *s, uint32_t reg, AspeedSegments *seg); +static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint32_t value); /* * AST2600 definitions @@ -259,6 +260,15 @@ static uint32_t aspeed_2600_smc_segment_to_reg(const AspeedSMCState *s, const AspeedSegments *seg); static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s, uint32_t reg, AspeedSegments *seg); +static void aspeed_2600_smc_dma_ctrl(AspeedSMCState *s, uint32_t value); + +#define ASPEED_SMC_FEATURE_DMA 0x1 +#define ASPEED_SMC_FEATURE_DMA_GRANT 0x2 + +static inline bool aspeed_smc_has_dma(const AspeedSMCState *s) +{ + return !!(s->ctrl->features & ASPEED_SMC_FEATURE_DMA); +} static const AspeedSMCController controllers[] = { { @@ -273,10 +283,11 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_legacy, .flash_window_base = ASPEED_SOC_SMC_FLASH_BASE, .flash_window_size = 0x6000000, - .has_dma = false, + .features = 0x0, .nregs = ASPEED_SMC_R_SMC_MAX, .segment_to_reg = aspeed_smc_segment_to_reg, .reg_to_segment = aspeed_smc_reg_to_segment, + .dma_ctrl = aspeed_smc_dma_ctrl, }, { .name = "aspeed.fmc-ast2400", .r_conf = R_CONF, @@ -289,12 +300,13 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_fmc, .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE, .flash_window_size = 0x10000000, - .has_dma = true, + .features = ASPEED_SMC_FEATURE_DMA, .dma_flash_mask = 0x0FFFFFFC, .dma_dram_mask = 0x1FFFFFFC, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_smc_segment_to_reg, .reg_to_segment = aspeed_smc_reg_to_segment, + .dma_ctrl = aspeed_smc_dma_ctrl, }, { .name = "aspeed.spi1-ast2400", .r_conf = R_SPI_CONF, @@ -307,10 +319,11 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_spi, .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE, .flash_window_size = 0x10000000, - .has_dma = false, + .features = 0x0, .nregs = ASPEED_SMC_R_SPI_MAX, .segment_to_reg = aspeed_smc_segment_to_reg, .reg_to_segment = aspeed_smc_reg_to_segment, + .dma_ctrl = aspeed_smc_dma_ctrl, }, { .name = "aspeed.fmc-ast2500", .r_conf = R_CONF, @@ -323,12 +336,13 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_ast2500_fmc, .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE, .flash_window_size = 0x10000000, - .has_dma = true, + .features = ASPEED_SMC_FEATURE_DMA, .dma_flash_mask = 0x0FFFFFFC, .dma_dram_mask = 0x3FFFFFFC, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_smc_segment_to_reg, .reg_to_segment = aspeed_smc_reg_to_segment, + .dma_ctrl = aspeed_smc_dma_ctrl, }, { .name = "aspeed.spi1-ast2500", .r_conf = R_CONF, @@ -341,10 +355,11 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_ast2500_spi1, .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE, .flash_window_size = 0x8000000, - .has_dma = false, + .features = 0x0, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_smc_segment_to_reg, .reg_to_segment = aspeed_smc_reg_to_segment, + .dma_ctrl = aspeed_smc_dma_ctrl, }, { .name = "aspeed.spi2-ast2500", .r_conf = R_CONF, @@ -357,10 +372,11 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_ast2500_spi2, .flash_window_base = ASPEED_SOC_SPI2_FLASH_BASE, .flash_window_size = 0x8000000, - .has_dma = false, + .features = 0x0, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_smc_segment_to_reg, .reg_to_segment = aspeed_smc_reg_to_segment, + .dma_ctrl = aspeed_smc_dma_ctrl, }, { .name = "aspeed.fmc-ast2600", .r_conf = R_CONF, @@ -373,12 +389,13 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_ast2600_fmc, .flash_window_base = ASPEED26_SOC_FMC_FLASH_BASE, .flash_window_size = 0x10000000, - .has_dma = true, + .features = ASPEED_SMC_FEATURE_DMA, .dma_flash_mask = 0x0FFFFFFC, .dma_dram_mask = 0x3FFFFFFC, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_2600_smc_segment_to_reg, .reg_to_segment = aspeed_2600_smc_reg_to_segment, + .dma_ctrl = aspeed_2600_smc_dma_ctrl, }, { .name = "aspeed.spi1-ast2600", .r_conf = R_CONF, @@ -391,12 +408,14 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_ast2600_spi1, .flash_window_base = ASPEED26_SOC_SPI_FLASH_BASE, .flash_window_size = 0x10000000, - .has_dma = true, + .features = ASPEED_SMC_FEATURE_DMA | + ASPEED_SMC_FEATURE_DMA_GRANT, .dma_flash_mask = 0x0FFFFFFC, .dma_dram_mask = 0x3FFFFFFC, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_2600_smc_segment_to_reg, .reg_to_segment = aspeed_2600_smc_reg_to_segment, + .dma_ctrl = aspeed_2600_smc_dma_ctrl, }, { .name = "aspeed.spi2-ast2600", .r_conf = R_CONF, @@ -409,12 +428,14 @@ static const AspeedSMCController controllers[] = { .segments = aspeed_segments_ast2600_spi2, .flash_window_base = ASPEED26_SOC_SPI2_FLASH_BASE, .flash_window_size = 0x10000000, - .has_dma = true, + .features = ASPEED_SMC_FEATURE_DMA | + ASPEED_SMC_FEATURE_DMA_GRANT, .dma_flash_mask = 0x0FFFFFFC, .dma_dram_mask = 0x3FFFFFFC, .nregs = ASPEED_SMC_R_MAX, .segment_to_reg = aspeed_2600_smc_segment_to_reg, .reg_to_segment = aspeed_2600_smc_reg_to_segment, + .dma_ctrl = aspeed_2600_smc_dma_ctrl, }, }; @@ -999,11 +1020,11 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size) addr == R_CE_CMD_CTRL || addr == R_INTR_CTRL || addr == R_DUMMY_DATA || - (s->ctrl->has_dma && addr == R_DMA_CTRL) || - (s->ctrl->has_dma && addr == R_DMA_FLASH_ADDR) || - (s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) || - (s->ctrl->has_dma && addr == R_DMA_LEN) || - (s->ctrl->has_dma && addr == R_DMA_CHECKSUM) || + (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) || + (aspeed_smc_has_dma(s) && addr == R_DMA_FLASH_ADDR) || + (aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR) || + (aspeed_smc_has_dma(s) && addr == R_DMA_LEN) || + (aspeed_smc_has_dma(s) && addr == R_DMA_CHECKSUM) || (addr >= R_SEG_ADDR0 && addr < R_SEG_ADDR0 + s->ctrl->max_peripherals) || (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->ctrl->max_peripherals)) { @@ -1236,7 +1257,7 @@ static void aspeed_smc_dma_done(AspeedSMCState *s) } } -static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint64_t dma_ctrl) +static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl) { if (!(dma_ctrl & DMA_CTRL_ENABLE)) { s->regs[R_DMA_CTRL] = dma_ctrl; @@ -1261,6 +1282,46 @@ static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint64_t dma_ctrl) aspeed_smc_dma_done(s); } +static inline bool aspeed_smc_dma_granted(AspeedSMCState *s) +{ + if (!(s->ctrl->features & ASPEED_SMC_FEATURE_DMA_GRANT)) { + return true; + } + + if (!(s->regs[R_DMA_CTRL] & DMA_CTRL_GRANT)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA not granted\n", __func__); + return false; + } + + return true; +} + +static void aspeed_2600_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl) +{ + /* Preserve DMA bits */ + dma_ctrl |= s->regs[R_DMA_CTRL] & (DMA_CTRL_REQUEST | DMA_CTRL_GRANT); + + if (dma_ctrl == 0xAEED0000) { + /* automatically grant request */ + s->regs[R_DMA_CTRL] |= (DMA_CTRL_REQUEST | DMA_CTRL_GRANT); + return; + } + + /* clear request */ + if (dma_ctrl == 0xDEEA0000) { + s->regs[R_DMA_CTRL] &= ~(DMA_CTRL_REQUEST | DMA_CTRL_GRANT); + return; + } + + if (!aspeed_smc_dma_granted(s)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA not granted\n", __func__); + return; + } + + aspeed_smc_dma_ctrl(s, dma_ctrl); + s->regs[R_DMA_CTRL] &= ~(DMA_CTRL_REQUEST | DMA_CTRL_GRANT); +} + static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data, unsigned int size) { @@ -1292,13 +1353,16 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data, s->regs[addr] = value & 0xff; } else if (addr == R_INTR_CTRL) { s->regs[addr] = value; - } else if (s->ctrl->has_dma && addr == R_DMA_CTRL) { - aspeed_smc_dma_ctrl(s, value); - } else if (s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) { + } else if (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) { + s->ctrl->dma_ctrl(s, value); + } else if (aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR && + aspeed_smc_dma_granted(s)) { s->regs[addr] = DMA_DRAM_ADDR(s, value); - } else if (s->ctrl->has_dma && addr == R_DMA_FLASH_ADDR) { + } else if (aspeed_smc_has_dma(s) && addr == R_DMA_FLASH_ADDR && + aspeed_smc_dma_granted(s)) { s->regs[addr] = DMA_FLASH_ADDR(s, value); - } else if (s->ctrl->has_dma && addr == R_DMA_LEN) { + } else if (aspeed_smc_has_dma(s) && addr == R_DMA_LEN && + aspeed_smc_dma_granted(s)) { s->regs[addr] = DMA_LENGTH(value); } else { qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n", @@ -1386,7 +1450,9 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp) memory_region_init_io(&s->mmio_flash, OBJECT(s), &aspeed_smc_flash_default_ops, s, name, s->ctrl->flash_window_size); - sysbus_init_mmio(sbd, &s->mmio_flash); + memory_region_init_alias(&s->mmio_flash_alias, OBJECT(s), name, + &s->mmio_flash, 0, s->ctrl->flash_window_size); + sysbus_init_mmio(sbd, &s->mmio_flash_alias); s->flashes = g_new0(AspeedSMCFlash, s->ctrl->max_peripherals); @@ -1412,7 +1478,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp) } /* DMA support */ - if (s->ctrl->has_dma) { + if (aspeed_smc_has_dma(s)) { aspeed_smc_dma_setup(s, errp); } } @@ -1432,7 +1498,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_UINT64("sdram-base", AspeedSMCState, sdram_base, 0), DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr, TYPE_MEMORY_REGION, MemoryRegion *), DEFINE_PROP_END_OF_LIST(), |