aboutsummaryrefslogtreecommitdiff
path: root/hw/arm
diff options
context:
space:
mode:
authorHavard Skinnemoen <hskinnemoen@google.com>2020-09-10 22:20:57 -0700
committerPeter Maydell <peter.maydell@linaro.org>2020-09-14 14:24:59 +0100
commitb821242c7b3b174bbf7c01a19c93c4e52fedab5d (patch)
tree836833c9a3f007182c6896056517375fa2222ca0 /hw/arm
parent1351f892467bd8d9655b43b8fbf10a8d08890612 (diff)
hw/ssi: NPCM7xx Flash Interface Unit device model
This implements a device model for the NPCM7xx SPI flash controller. Direct reads and writes, and user-mode transactions have been tested in various modes. Protection features are not implemented yet. All the FIU instances are available in the SoC's address space, regardless of whether or not they're connected to actual flash chips. Reviewed-by: Tyrone Ting <kfting@nuvoton.com> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Alexander Bulekov <alxndr@bu.edu> Signed-off-by: Havard Skinnemoen <hskinnemoen@google.com> Message-id: 20200911052101.2602693-11-hskinnemoen@google.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/arm')
-rw-r--r--hw/arm/Kconfig1
-rw-r--r--hw/arm/npcm7xx.c58
2 files changed, 59 insertions, 0 deletions
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index cd74642034..f303c6bead 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -361,6 +361,7 @@ config NPCM7XX
select ARM_GIC
select PL310 # cache controller
select SERIAL
+ select SSI
select UNIMP
config FSL_IMX25
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 6bb1693833..7884b2b03d 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -99,6 +99,39 @@ static const hwaddr npcm7xx_uart_addr[] = {
0xf0004000,
};
+/* Direct memory-mapped access to SPI0 CS0-1. */
+static const hwaddr npcm7xx_fiu0_flash_addr[] = {
+ 0x80000000, /* CS0 */
+ 0x88000000, /* CS1 */
+};
+
+/* Direct memory-mapped access to SPI3 CS0-3. */
+static const hwaddr npcm7xx_fiu3_flash_addr[] = {
+ 0xa0000000, /* CS0 */
+ 0xa8000000, /* CS1 */
+ 0xb0000000, /* CS2 */
+ 0xb8000000, /* CS3 */
+};
+
+static const struct {
+ const char *name;
+ hwaddr regs_addr;
+ int cs_count;
+ const hwaddr *flash_addr;
+} npcm7xx_fiu[] = {
+ {
+ .name = "fiu0",
+ .regs_addr = 0xfb000000,
+ .cs_count = ARRAY_SIZE(npcm7xx_fiu0_flash_addr),
+ .flash_addr = npcm7xx_fiu0_flash_addr,
+ }, {
+ .name = "fiu3",
+ .regs_addr = 0xc0000000,
+ .cs_count = ARRAY_SIZE(npcm7xx_fiu3_flash_addr),
+ .flash_addr = npcm7xx_fiu3_flash_addr,
+ },
+};
+
static void npcm7xx_write_secondary_boot(ARMCPU *cpu,
const struct arm_boot_info *info)
{
@@ -192,6 +225,12 @@ static void npcm7xx_init(Object *obj)
for (i = 0; i < ARRAY_SIZE(s->tim); i++) {
object_initialize_child(obj, "tim[*]", &s->tim[i], TYPE_NPCM7XX_TIMER);
}
+
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
+ for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
+ object_initialize_child(obj, npcm7xx_fiu[i].name, &s->fiu[i],
+ TYPE_NPCM7XX_FIU);
+ }
}
static void npcm7xx_realize(DeviceState *dev, Error **errp)
@@ -291,6 +330,25 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
serial_hd(i), DEVICE_LITTLE_ENDIAN);
}
+ /*
+ * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
+ * specified, but this is a programming error.
+ */
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_fiu) != ARRAY_SIZE(s->fiu));
+ for (i = 0; i < ARRAY_SIZE(s->fiu); i++) {
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->fiu[i]);
+ int j;
+
+ object_property_set_int(OBJECT(sbd), "cs-count",
+ npcm7xx_fiu[i].cs_count, &error_abort);
+ sysbus_realize(sbd, &error_abort);
+
+ sysbus_mmio_map(sbd, 0, npcm7xx_fiu[i].regs_addr);
+ for (j = 0; j < npcm7xx_fiu[i].cs_count; j++) {
+ sysbus_mmio_map(sbd, j + 1, npcm7xx_fiu[i].flash_addr[j]);
+ }
+ }
+
/* RAM2 (SRAM) */
memory_region_init_ram(&s->sram, OBJECT(dev), "ram2",
NPCM7XX_RAM2_SZ, &error_abort);