qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/24] aspeed: fixes and extensions
@ 2021-04-07 17:16 Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 01/24] aspeed/smc: Use the RAM memory region for DMAs Cédric Le Goater
                   ` (23 more replies)
  0 siblings, 24 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

Hello,

This is a 6.1 series of changes I have been collecting for the Aspeed
machines.

We were passing the memory address space region to the I2C and SMC
controller for DMAs. Passing the RAM memory region simplifies the
models. Thanks to Philippe.

Then, we have a model for the HACE (Hash And Crypto Engine) device of
the Aspeed SoC from Joel plus extensions from Klaus. These should be
ready but I lack a firmware image to check. An extra review would be
nice to have.

Follow acceptance tests for all SoCs (AST2400, AST2500 and AST2600), a
fix (kexec) for the XDMA model on the AST2600, an extra feature for
the SMC model which is required by a SPI driver Aspeed is working on,
a new machine, the AST2600 rainier-bmc, and the iBT device model that
I have been keeping for while (2016). It is ready for review now that
the LPC model (Andrew) is merged.

Finally, a new model from Joel for the DPS310 sensor device which can
be found on the witherspoon and rainier boards.

Thanks,

C.

Cédric Le Goater (12):
  aspeed/smc: Use the RAM memory region for DMAs
  aspeed/smc: Remove unused "sdram-base" property
  aspeed/i2c: Fix DMA address mask
  aspeed/i2c: Rename DMA address space
  hw/misc/aspeed_xdma: Add AST2600 support
  aspeed/smc: Add a 'features' attribute to the object class
  aspeed/smc: Add extra controls to request DMA
  tests/qtest: Rename m25p80 test in aspeed_smc test
  aspeed: Remove swift-bmc machine
  aspeed: Add support for the rainier-bmc board
  hw/misc: Add an iBT device model
  hw/block: m25p80: Add support for mt25qu02g

Joel Stanley (9):
  hw: Model ASPEED's Hash and Crypto Engine
  aspeed: Integrate HACE
  tests/qtest: Add test for Aspeed HACE
  tests/acceptance: Test ast2400 and ast2500 machines
  tests/acceptance: Test ast2600 machine
  aspeed: Emulate the AST2600A3
  hw/misc: Add Infineon DPS310 sensor model
  arm/aspeed: Add DPS310 to rainier
  arm/aspeed: Add DPS310 to witherspoon

Klaus Heinrich Kiwi (2):
  aspeed: Add Scater-Gather support for HACE Hash
  tests: Aspeed HACE Scatter-Gather tests

Philippe Mathieu-Daudé (1):
  hw/arm/aspeed: Do not sysbus-map mmio flash region directly, use alias

 docs/system/arm/aspeed.rst                    |   2 +-
 include/hw/arm/aspeed_soc.h                   |   5 +
 include/hw/misc/aspeed_hace.h                 |  43 ++
 include/hw/misc/aspeed_ibt.h                  |  47 ++
 include/hw/misc/aspeed_scu.h                  |   2 +
 include/hw/misc/aspeed_xdma.h                 |  17 +-
 include/hw/ssi/aspeed_smc.h                   |   7 +-
 hw/arm/aspeed.c                               | 144 +++--
 hw/arm/aspeed_ast2600.c                       |  36 +-
 hw/arm/aspeed_soc.c                           |  35 +-
 hw/block/m25p80.c                             |   1 +
 hw/i2c/aspeed_i2c.c                           |   5 +-
 hw/misc/aspeed_hace.c                         | 480 ++++++++++++++
 hw/misc/aspeed_ibt.c                          | 596 ++++++++++++++++++
 hw/misc/aspeed_scu.c                          |  32 +-
 hw/misc/aspeed_xdma.c                         | 124 +++-
 hw/misc/dps310.c                              | 339 ++++++++++
 hw/ssi/aspeed_smc.c                           | 119 +++-
 tests/qtest/aspeed_hace-test.c                | 469 ++++++++++++++
 .../{m25p80-test.c => aspeed_smc-test.c}      |  12 +-
 MAINTAINERS                                   |   1 +
 hw/arm/Kconfig                                |   1 +
 hw/misc/Kconfig                               |   4 +
 hw/misc/meson.build                           |   3 +
 hw/misc/trace-events                          |   7 +
 tests/acceptance/boot_linux_console.py        |  68 ++
 tests/qtest/meson.build                       |   5 +-
 27 files changed, 2458 insertions(+), 146 deletions(-)
 create mode 100644 include/hw/misc/aspeed_hace.h
 create mode 100644 include/hw/misc/aspeed_ibt.h
 create mode 100644 hw/misc/aspeed_hace.c
 create mode 100644 hw/misc/aspeed_ibt.c
 create mode 100644 hw/misc/dps310.c
 create mode 100644 tests/qtest/aspeed_hace-test.c
 rename tests/qtest/{m25p80-test.c => aspeed_smc-test.c} (96%)

-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 01/24] aspeed/smc: Use the RAM memory region for DMAs
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:32   ` Philippe Mathieu-Daudé
  2021-04-07 17:16 ` [PATCH 02/24] aspeed/smc: Remove unused "sdram-base" property Cédric Le Goater
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Philippe Mathieu-Daudé,
	qemu-devel, qemu-arm, Cédric Le Goater, Joel Stanley

Instead of passing the memory address space region, simply use the RAM
memory region instead. This simplifies RAM accesses.

Fixes: c4e1f0b48322 ("aspeed/smc: Add support for DMAs")
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/arm/aspeed.c     | 2 +-
 hw/ssi/aspeed_smc.c | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index a17b75f4940a..1cf5a15c8098 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -327,7 +327,7 @@ static void aspeed_machine_init(MachineState *machine)
     object_property_set_int(OBJECT(&bmc->soc), "num-cs", amc->num_cs,
                             &error_abort);
     object_property_set_link(OBJECT(&bmc->soc), "dram",
-                             OBJECT(&bmc->ram_container), &error_abort);
+                             OBJECT(machine->ram), &error_abort);
     if (machine->kernel_filename) {
         /*
          * When booting with a -kernel command line there is no u-boot
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 16addee4dc8d..6f72fb028e59 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -178,8 +178,7 @@
  *   0: 4 bytes
  *   0x7FFFFF: 32M bytes
  */
-#define DMA_DRAM_ADDR(s, val)   ((s)->sdram_base | \
-                                 ((val) & (s)->ctrl->dma_dram_mask))
+#define DMA_DRAM_ADDR(s, val)   ((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_LENGTH(val)         ((val) & 0x01FFFFFC)
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 02/24] aspeed/smc: Remove unused "sdram-base" property
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 01/24] aspeed/smc: Use the RAM memory region for DMAs Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:32   ` Philippe Mathieu-Daudé
  2021-04-07 17:16 ` [PATCH 03/24] aspeed/i2c: Fix DMA address mask Cédric Le Goater
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Philippe Mathieu-Daudé,
	qemu-devel, qemu-arm, Cédric Le Goater, Joel Stanley

Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ssi/aspeed_smc.h | 3 ---
 hw/arm/aspeed_ast2600.c     | 4 ----
 hw/arm/aspeed_soc.c         | 4 ----
 hw/ssi/aspeed_smc.c         | 1 -
 4 files changed, 12 deletions(-)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 16c03fe64f3b..ccd71d9b534e 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -103,9 +103,6 @@ struct AspeedSMCState {
     uint8_t r_timings;
     uint8_t conf_enable_w0;
 
-    /* for DMA support */
-    uint64_t sdram_base;
-
     AddressSpace flash_as;
     MemoryRegion *dram_mr;
     AddressSpace dram_as;
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bc87e754a3cc..2a1255b6a042 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -344,10 +344,6 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
     /* FMC, The number of CS is set at the board level */
     object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr),
                              &error_abort);
-    if (!object_property_set_int(OBJECT(&s->fmc), "sdram-base",
-                                 sc->memmap[ASPEED_DEV_SDRAM], errp)) {
-        return;
-    }
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
         return;
     }
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 057d053c8478..817f3ba63dfd 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -301,10 +301,6 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
     /* FMC, The number of CS is set at the board level */
     object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr),
                              &error_abort);
-    if (!object_property_set_int(OBJECT(&s->fmc), "sdram-base",
-                                 sc->memmap[ASPEED_DEV_SDRAM], errp)) {
-        return;
-    }
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
         return;
     }
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 6f72fb028e59..884e08aca4e2 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -1431,7 +1431,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(),
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 03/24] aspeed/i2c: Fix DMA address mask
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 01/24] aspeed/smc: Use the RAM memory region for DMAs Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 02/24] aspeed/smc: Remove unused "sdram-base" property Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 21:22   ` Philippe Mathieu-Daudé
  2021-04-07 17:16 ` [PATCH 04/24] aspeed/i2c: Rename DMA address space Cédric Le Goater
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Philippe Mathieu-Daudé,
	qemu-devel, qemu-arm, Cédric Le Goater, Joel Stanley

The RAM memory region is now used for DMAs accesses instead of the
memory address space region. Mask off the top bits of the DMA address
to reflect this change.

Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/i2c/aspeed_i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index 518a3f5c6f9d..e7133528899f 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -601,7 +601,7 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
             break;
         }
 
-        bus->dma_addr = value & 0xfffffffc;
+        bus->dma_addr = value & 0x3ffffffc;
         break;
 
     case I2CD_DMA_LEN:
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 04/24] aspeed/i2c: Rename DMA address space
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (2 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 03/24] aspeed/i2c: Fix DMA address mask Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:33   ` Philippe Mathieu-Daudé
  2021-04-07 17:16 ` [PATCH 05/24] hw/arm/aspeed: Do not sysbus-map mmio flash region directly, use alias Cédric Le Goater
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

It improves 'info mtree' output.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/i2c/aspeed_i2c.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index e7133528899f..8d276d9ed391 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -816,7 +816,8 @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
             return;
         }
 
-        address_space_init(&s->dram_as, s->dram_mr, "dma-dram");
+        address_space_init(&s->dram_as, s->dram_mr,
+                           TYPE_ASPEED_I2C "-dma-dram");
     }
 }
 
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 05/24] hw/arm/aspeed: Do not sysbus-map mmio flash region directly, use alias
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (3 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 04/24] aspeed/i2c: Rename DMA address space Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 06/24] hw: Model ASPEED's Hash and Crypto Engine Cédric Le Goater
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Philippe Mathieu-Daudé,
	qemu-devel, qemu-arm, Joel Stanley, Cédric Le Goater

From: Philippe Mathieu-Daudé <f4bug@amsat.org>

The flash mmio region is exposed as an AddressSpace.
AddressSpaces must not be sysbus-mapped, therefore map
the region using an alias.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
[ clg : Fix DMA_FLASH_ADDR() ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20210312182851.1922972-3-f4bug@amsat.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ssi/aspeed_smc.h | 1 +
 hw/ssi/aspeed_smc.c         | 7 ++++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index ccd71d9b534e..6ea2871cd899 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -84,6 +84,7 @@ struct AspeedSMCState {
 
     MemoryRegion mmio;
     MemoryRegion mmio_flash;
+    MemoryRegion mmio_flash_alias;
 
     qemu_irq irq;
     int irqline;
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 884e08aca4e2..50ea907aef74 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -179,8 +179,7 @@
  *   0x7FFFFF: 32M bytes
  */
 #define DMA_DRAM_ADDR(s, val)   ((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_FLASH_ADDR(s, val)  ((val) & (s)->ctrl->dma_flash_mask)
 #define DMA_LENGTH(val)         ((val) & 0x01FFFFFC)
 
 /* Flash opcodes. */
@@ -1385,7 +1384,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);
 
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 06/24] hw: Model ASPEED's Hash and Crypto Engine
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (4 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 05/24] hw/arm/aspeed: Do not sysbus-map mmio flash region directly, use alias Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 19:31   ` Klaus Heinrich Kiwi
  2021-04-07 17:16 ` [PATCH 07/24] aspeed: Integrate HACE Cédric Le Goater
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Philippe Mathieu-Daudé,
	qemu-devel, qemu-arm, Cédric Le Goater, Joel Stanley

From: Joel Stanley <joel@jms.id.au>

The HACE (Hash and Crypto Engine) is a device that offloads MD5, SHA1,
SHA2, RSA and other cryptographic algorithms.

This initial model implements a subset of the device's functionality;
currently only direct access (non-scatter gather) hashing.

Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
[ clg : minor checkpatch fixes ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20210324070955.125941-2-joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/misc/aspeed_hace.h |  43 ++++
 hw/misc/aspeed_hace.c         | 359 ++++++++++++++++++++++++++++++++++
 hw/misc/meson.build           |   1 +
 3 files changed, 403 insertions(+)
 create mode 100644 include/hw/misc/aspeed_hace.h
 create mode 100644 hw/misc/aspeed_hace.c

diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
new file mode 100644
index 000000000000..94d5ada95fa2
--- /dev/null
+++ b/include/hw/misc/aspeed_hace.h
@@ -0,0 +1,43 @@
+/*
+ * ASPEED Hash and Crypto Engine
+ *
+ * Copyright (C) 2021 IBM Corp.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_HACE_H
+#define ASPEED_HACE_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ASPEED_HACE "aspeed.hace"
+#define TYPE_ASPEED_AST2400_HACE TYPE_ASPEED_HACE "-ast2400"
+#define TYPE_ASPEED_AST2500_HACE TYPE_ASPEED_HACE "-ast2500"
+#define TYPE_ASPEED_AST2600_HACE TYPE_ASPEED_HACE "-ast2600"
+OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass, ASPEED_HACE)
+
+#define ASPEED_HACE_NR_REGS (0x64 >> 2)
+
+struct AspeedHACEState {
+    SysBusDevice parent;
+
+    MemoryRegion iomem;
+    qemu_irq irq;
+
+    uint32_t regs[ASPEED_HACE_NR_REGS];
+
+    MemoryRegion *dram_mr;
+    AddressSpace dram_as;
+};
+
+
+struct AspeedHACEClass {
+    SysBusDeviceClass parent_class;
+
+    uint32_t src_mask;
+    uint32_t dest_mask;
+    uint32_t hash_mask;
+};
+
+#endif /* _ASPEED_HACE_H_ */
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
new file mode 100644
index 000000000000..6e5b447a4835
--- /dev/null
+++ b/hw/misc/aspeed_hace.c
@@ -0,0 +1,359 @@
+/*
+ * ASPEED Hash and Crypto Engine
+ *
+ * Copyright (C) 2021 IBM Corp.
+ *
+ * Joel Stanley <joel@jms.id.au>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_hace.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+#include "crypto/hash.h"
+#include "hw/qdev-properties.h"
+#include "hw/irq.h"
+
+#define R_CRYPT_CMD     (0x10 / 4)
+
+#define R_STATUS        (0x1c / 4)
+#define HASH_IRQ        BIT(9)
+#define CRYPT_IRQ       BIT(12)
+#define TAG_IRQ         BIT(15)
+
+#define R_HASH_SRC      (0x20 / 4)
+#define R_HASH_DEST     (0x24 / 4)
+#define R_HASH_SRC_LEN  (0x2c / 4)
+
+#define R_HASH_CMD      (0x30 / 4)
+/* Hash algorithm selection */
+#define  HASH_ALGO_MASK                 (BIT(4) | BIT(5) | BIT(6))
+#define  HASH_ALGO_MD5                  0
+#define  HASH_ALGO_SHA1                 BIT(5)
+#define  HASH_ALGO_SHA224               BIT(6)
+#define  HASH_ALGO_SHA256               (BIT(4) | BIT(6))
+#define  HASH_ALGO_SHA512_SERIES        (BIT(5) | BIT(6))
+/* SHA512 algorithm selection */
+#define  SHA512_HASH_ALGO_MASK          (BIT(10) | BIT(11) | BIT(12))
+#define  HASH_ALGO_SHA512_SHA512        0
+#define  HASH_ALGO_SHA512_SHA384        BIT(10)
+#define  HASH_ALGO_SHA512_SHA256        BIT(11)
+#define  HASH_ALGO_SHA512_SHA224        (BIT(10) | BIT(11))
+/* HMAC modes */
+#define  HASH_HMAC_MASK                 (BIT(7) | BIT(8))
+#define  HASH_DIGEST                    0
+#define  HASH_DIGEST_HMAC               BIT(7)
+#define  HASH_DIGEST_ACCUM              BIT(8)
+#define  HASH_HMAC_KEY                  (BIT(7) | BIT(8))
+/* Cascaded operation modes */
+#define  HASH_ONLY                      0
+#define  HASH_ONLY2                     BIT(0)
+#define  HASH_CRYPT_THEN_HASH           BIT(1)
+#define  HASH_HASH_THEN_CRYPT           (BIT(0) | BIT(1))
+/* Other cmd bits */
+#define  HASH_IRQ_EN                    BIT(9)
+#define  HASH_SG_EN                     BIT(18)
+
+static const struct {
+    uint32_t mask;
+    QCryptoHashAlgorithm algo;
+} hash_algo_map[] = {
+    { HASH_ALGO_MD5, QCRYPTO_HASH_ALG_MD5 },
+    { HASH_ALGO_SHA1, QCRYPTO_HASH_ALG_SHA1 },
+    { HASH_ALGO_SHA224, QCRYPTO_HASH_ALG_SHA224 },
+    { HASH_ALGO_SHA256, QCRYPTO_HASH_ALG_SHA256 },
+    { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA512, QCRYPTO_HASH_ALG_SHA512 },
+    { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA384, QCRYPTO_HASH_ALG_SHA384 },
+    { HASH_ALGO_SHA512_SERIES | HASH_ALGO_SHA512_SHA256, QCRYPTO_HASH_ALG_SHA256 },
+};
+
+static int hash_algo_lookup(uint32_t mask)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(hash_algo_map); i++) {
+        if (mask == hash_algo_map[i].mask) {
+            return hash_algo_map[i].algo;
+        }
+    }
+
+    return -1;
+}
+
+static int do_hash_operation(AspeedHACEState *s, int algo)
+{
+    hwaddr src, len, dest;
+    uint8_t *digest_buf = NULL;
+    size_t digest_len = 0;
+    char *src_buf;
+    int rc;
+
+    src = s->regs[R_HASH_SRC];
+    len = s->regs[R_HASH_SRC_LEN];
+    dest = s->regs[R_HASH_DEST];
+
+    src_buf = address_space_map(&s->dram_as, src, &len, false,
+                                MEMTXATTRS_UNSPECIFIED);
+    if (!src_buf) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map dram\n", __func__);
+        return -EACCES;
+    }
+
+    rc = qcrypto_hash_bytes(algo, src_buf, len, &digest_buf, &digest_len,
+                            &error_fatal);
+    if (rc < 0) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
+        return rc;
+    }
+
+    rc = address_space_write(&s->dram_as, dest, MEMTXATTRS_UNSPECIFIED,
+                             digest_buf, digest_len);
+    if (rc) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: address space write failed\n", __func__);
+    }
+    g_free(digest_buf);
+
+    address_space_unmap(&s->dram_as, src_buf, len, false, len);
+
+    /*
+     * Set status bits to indicate completion. Testing shows hardware sets
+     * these irrespective of HASH_IRQ_EN.
+     */
+    s->regs[R_STATUS] |= HASH_IRQ;
+
+    return 0;
+}
+
+
+static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size)
+{
+    AspeedHACEState *s = ASPEED_HACE(opaque);
+
+    addr >>= 2;
+
+    if (addr >= ASPEED_HACE_NR_REGS) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+                      __func__, addr << 2);
+        return 0;
+    }
+
+    return s->regs[addr];
+}
+
+static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
+                              unsigned int size)
+{
+    AspeedHACEState *s = ASPEED_HACE(opaque);
+    AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s);
+
+    addr >>= 2;
+
+    if (addr >= ASPEED_HACE_NR_REGS) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+                      __func__, addr << 2);
+        return;
+    }
+
+    switch (addr) {
+    case R_STATUS:
+        if (data & HASH_IRQ) {
+            data &= ~HASH_IRQ;
+
+            if (s->regs[addr] & HASH_IRQ) {
+                qemu_irq_lower(s->irq);
+            }
+        }
+        break;
+    case R_HASH_SRC:
+        data &= ahc->src_mask;
+        break;
+    case R_HASH_DEST:
+        data &= ahc->dest_mask;
+        break;
+    case R_HASH_SRC_LEN:
+        data &= 0x0FFFFFFF;
+        break;
+    case R_HASH_CMD: {
+        int algo = -1;
+        if ((data & HASH_HMAC_MASK)) {
+            qemu_log_mask(LOG_UNIMP,
+                          "%s: HMAC engine command mode %"PRIx64" not implemented",
+                          __func__, (data & HASH_HMAC_MASK) >> 8);
+        }
+        if (data & HASH_SG_EN) {
+            qemu_log_mask(LOG_UNIMP,
+                          "%s: Hash scatter gather mode not implemented",
+                          __func__);
+        }
+        if (data & BIT(1)) {
+            qemu_log_mask(LOG_UNIMP,
+                          "%s: Cascaded mode not implemented",
+                          __func__);
+        }
+        algo = hash_algo_lookup(data & ahc->hash_mask);
+        if (algo < 0) {
+                qemu_log_mask(LOG_GUEST_ERROR,
+                        "%s: Invalid hash algorithm selection 0x%"PRIx64"\n",
+                        __func__, data & ahc->hash_mask);
+                break;
+        }
+        do_hash_operation(s, algo);
+
+        if (data & HASH_IRQ_EN) {
+            qemu_irq_raise(s->irq);
+        }
+        break;
+    }
+    case R_CRYPT_CMD:
+        qemu_log_mask(LOG_UNIMP, "%s: Crypt commands not implemented\n",
+                       __func__);
+        break;
+    default:
+        break;
+    }
+
+    s->regs[addr] = data;
+}
+
+static const MemoryRegionOps aspeed_hace_ops = {
+    .read = aspeed_hace_read,
+    .write = aspeed_hace_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+static void aspeed_hace_reset(DeviceState *dev)
+{
+    struct AspeedHACEState *s = ASPEED_HACE(dev);
+
+    memset(s->regs, 0, sizeof(s->regs));
+}
+
+static void aspeed_hace_realize(DeviceState *dev, Error **errp)
+{
+    AspeedHACEState *s = ASPEED_HACE(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+    sysbus_init_irq(sbd, &s->irq);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_hace_ops, s,
+            TYPE_ASPEED_HACE, 0x1000);
+
+    if (!s->dram_mr) {
+        error_setg(errp, TYPE_ASPEED_HACE ": 'dram' link not set");
+        return;
+    }
+
+    address_space_init(&s->dram_as, s->dram_mr, "dram");
+
+    sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static Property aspeed_hace_properties[] = {
+    DEFINE_PROP_LINK("dram", AspeedHACEState, dram_mr,
+                     TYPE_MEMORY_REGION, MemoryRegion *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+
+static const VMStateDescription vmstate_aspeed_hace = {
+    .name = TYPE_ASPEED_HACE,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, AspeedHACEState, ASPEED_HACE_NR_REGS),
+        VMSTATE_END_OF_LIST(),
+    }
+};
+
+static void aspeed_hace_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = aspeed_hace_realize;
+    dc->reset = aspeed_hace_reset;
+    device_class_set_props(dc, aspeed_hace_properties);
+    dc->vmsd = &vmstate_aspeed_hace;
+}
+
+static const TypeInfo aspeed_hace_info = {
+    .name = TYPE_ASPEED_HACE,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(AspeedHACEState),
+    .class_init = aspeed_hace_class_init,
+    .class_size = sizeof(AspeedHACEClass)
+};
+
+static void aspeed_ast2400_hace_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass);
+
+    dc->desc = "AST2400 Hash and Crypto Engine";
+
+    ahc->src_mask = 0x0FFFFFFF;
+    ahc->dest_mask = 0x0FFFFFF8;
+    ahc->hash_mask = HASH_ALGO_MASK;
+}
+
+static const TypeInfo aspeed_ast2400_hace_info = {
+    .name = TYPE_ASPEED_AST2400_HACE,
+    .parent = TYPE_ASPEED_HACE,
+    .class_init = aspeed_ast2400_hace_class_init,
+};
+
+static void aspeed_ast2500_hace_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass);
+
+    dc->desc = "AST2500 Hash and Crypto Engine";
+
+    ahc->src_mask = 0x3fffffff;
+    ahc->dest_mask = 0x3ffffff8;
+    ahc->hash_mask = HASH_ALGO_MASK;
+}
+
+static const TypeInfo aspeed_ast2500_hace_info = {
+    .name = TYPE_ASPEED_AST2500_HACE,
+    .parent = TYPE_ASPEED_HACE,
+    .class_init = aspeed_ast2500_hace_class_init,
+};
+
+static void aspeed_ast2600_hace_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass);
+
+    dc->desc = "AST2600 Hash and Crypto Engine";
+
+    ahc->src_mask = 0x7FFFFFFF;
+    ahc->dest_mask = 0x7FFFFFF8;
+    ahc->hash_mask = HASH_ALGO_MASK | SHA512_HASH_ALGO_MASK;
+}
+
+static const TypeInfo aspeed_ast2600_hace_info = {
+    .name = TYPE_ASPEED_AST2600_HACE,
+    .parent = TYPE_ASPEED_HACE,
+    .class_init = aspeed_ast2600_hace_class_init,
+};
+
+static void aspeed_hace_register_types(void)
+{
+    type_register_static(&aspeed_ast2400_hace_info);
+    type_register_static(&aspeed_ast2500_hace_info);
+    type_register_static(&aspeed_ast2600_hace_info);
+    type_register_static(&aspeed_hace_info);
+}
+
+type_init(aspeed_hace_register_types);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 21034dc60a81..1e7b8b064bd1 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -109,6 +109,7 @@ softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
 softmmu_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
 softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
+  'aspeed_hace.c',
   'aspeed_lpc.c',
   'aspeed_scu.c',
   'aspeed_sdmc.c',
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 07/24] aspeed: Integrate HACE
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (5 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 06/24] hw: Model ASPEED's Hash and Crypto Engine Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 19:22   ` Klaus Heinrich Kiwi
  2021-04-07 17:16 ` [PATCH 08/24] tests/qtest: Add test for Aspeed HACE Cédric Le Goater
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Philippe Mathieu-Daudé,
	qemu-devel, qemu-arm, Cédric Le Goater, Joel Stanley

From: Joel Stanley <joel@jms.id.au>

Add the hash and crypto engine model to the Aspeed socs.

Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20210324070955.125941-3-joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 docs/system/arm/aspeed.rst  |  2 +-
 include/hw/arm/aspeed_soc.h |  3 +++
 hw/arm/aspeed_ast2600.c     | 15 +++++++++++++++
 hw/arm/aspeed_soc.c         | 16 ++++++++++++++++
 4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index d1fb8f25b39c..f9466e6d8245 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -49,6 +49,7 @@ Supported devices
  * Ethernet controllers
  * Front LEDs (PCA9552 on I2C bus)
  * LPC Peripheral Controller (a subset of subdevices are supported)
+ * Hash/Crypto Engine (HACE) - Hash support only, no scatter-gather
 
 
 Missing devices
@@ -59,7 +60,6 @@ Missing devices
  * PWM and Fan Controller
  * Slave GPIO Controller
  * Super I/O Controller
- * Hash/Crypto Engine
  * PCI-Express 1 Controller
  * Graphic Display Controller
  * PECI Controller
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 9359d6da336d..d9161d26d645 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -21,6 +21,7 @@
 #include "hw/rtc/aspeed_rtc.h"
 #include "hw/i2c/aspeed_i2c.h"
 #include "hw/ssi/aspeed_smc.h"
+#include "hw/misc/aspeed_hace.h"
 #include "hw/watchdog/wdt_aspeed.h"
 #include "hw/net/ftgmac100.h"
 #include "target/arm/cpu.h"
@@ -50,6 +51,7 @@ struct AspeedSoCState {
     AspeedTimerCtrlState timerctrl;
     AspeedI2CState i2c;
     AspeedSCUState scu;
+    AspeedHACEState hace;
     AspeedXDMAState xdma;
     AspeedSMCState fmc;
     AspeedSMCState spi[ASPEED_SPIS_NUM];
@@ -133,6 +135,7 @@ enum {
     ASPEED_DEV_XDMA,
     ASPEED_DEV_EMMC,
     ASPEED_DEV_KCS,
+    ASPEED_DEV_HACE,
 };
 
 #endif /* ASPEED_SOC_H */
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 2a1255b6a042..e0fbb020c770 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -42,6 +42,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
     [ASPEED_DEV_ETH2]      = 0x1E680000,
     [ASPEED_DEV_ETH4]      = 0x1E690000,
     [ASPEED_DEV_VIC]       = 0x1E6C0000,
+    [ASPEED_DEV_HACE]      = 0x1E6D0000,
     [ASPEED_DEV_SDMC]      = 0x1E6E0000,
     [ASPEED_DEV_SCU]       = 0x1E6E2000,
     [ASPEED_DEV_XDMA]      = 0x1E6E7000,
@@ -102,6 +103,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
     [ASPEED_DEV_I2C]       = 110,   /* 110 -> 125 */
     [ASPEED_DEV_ETH1]      = 2,
     [ASPEED_DEV_ETH2]      = 3,
+    [ASPEED_DEV_HACE]      = 4,
     [ASPEED_DEV_ETH3]      = 32,
     [ASPEED_DEV_ETH4]      = 33,
     [ASPEED_DEV_KCS]       = 138,   /* 138 -> 142 */
@@ -213,6 +215,9 @@ static void aspeed_soc_ast2600_init(Object *obj)
                             TYPE_SYSBUS_SDHCI);
 
     object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
+
+    snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
+    object_initialize_child(obj, "hace", &s->hace, typename);
 }
 
 /*
@@ -494,6 +499,16 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4,
                        qdev_get_gpio_in(DEVICE(&s->a7mpcore),
                                 sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4));
+
+    /* HACE */
+    object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr),
+                             &error_abort);
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
+                       aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 817f3ba63dfd..8ed29113f79f 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -34,6 +34,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
     [ASPEED_DEV_VIC]    = 0x1E6C0000,
     [ASPEED_DEV_SDMC]   = 0x1E6E0000,
     [ASPEED_DEV_SCU]    = 0x1E6E2000,
+    [ASPEED_DEV_HACE]   = 0x1E6E3000,
     [ASPEED_DEV_XDMA]   = 0x1E6E7000,
     [ASPEED_DEV_VIDEO]  = 0x1E700000,
     [ASPEED_DEV_ADC]    = 0x1E6E9000,
@@ -65,6 +66,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
     [ASPEED_DEV_VIC]    = 0x1E6C0000,
     [ASPEED_DEV_SDMC]   = 0x1E6E0000,
     [ASPEED_DEV_SCU]    = 0x1E6E2000,
+    [ASPEED_DEV_HACE]   = 0x1E6E3000,
     [ASPEED_DEV_XDMA]   = 0x1E6E7000,
     [ASPEED_DEV_ADC]    = 0x1E6E9000,
     [ASPEED_DEV_VIDEO]  = 0x1E700000,
@@ -117,6 +119,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
     [ASPEED_DEV_ETH2]   = 3,
     [ASPEED_DEV_XDMA]   = 6,
     [ASPEED_DEV_SDHCI]  = 26,
+    [ASPEED_DEV_HACE]   = 4,
 };
 
 #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
@@ -212,6 +215,9 @@ static void aspeed_soc_init(Object *obj)
     }
 
     object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
+
+    snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
+    object_initialize_child(obj, "hace", &s->hace, typename);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -421,6 +427,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
 
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4,
                        qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_4));
+
+    /* HACE */
+    object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr),
+                             &error_abort);
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
+                       aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
 }
 static Property aspeed_soc_properties[] = {
     DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 08/24] tests/qtest: Add test for Aspeed HACE
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (6 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 07/24] aspeed: Integrate HACE Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 19:33   ` Klaus Heinrich Kiwi
  2021-04-07 17:16 ` [PATCH 09/24] aspeed: Add Scater-Gather support for HACE Hash Cédric Le Goater
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Thomas Huth, Andrew Jeffery, qemu-devel, qemu-arm,
	Cédric Le Goater, Joel Stanley

From: Joel Stanley <joel@jms.id.au>

This adds a test for the Aspeed Hash and Crypto (HACE) engine. It tests
the currently implemented behavior of the hash functionality.

The tests are similar, but are cut/pasted instead of broken out into a
common function so the assert machinery produces useful output when a
test fails.

Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Acked-by: Thomas Huth <thuth@redhat.com>
[ clg: - qtest_quit() fix ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20210324070955.125941-4-joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 tests/qtest/aspeed_hace-test.c | 321 +++++++++++++++++++++++++++++++++
 MAINTAINERS                    |   1 +
 tests/qtest/meson.build        |   3 +
 3 files changed, 325 insertions(+)
 create mode 100644 tests/qtest/aspeed_hace-test.c

diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
new file mode 100644
index 000000000000..675774e96eb9
--- /dev/null
+++ b/tests/qtest/aspeed_hace-test.c
@@ -0,0 +1,321 @@
+/*
+ * QTest testcase for the ASPEED Hash and Crypto Engine
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 IBM Corp.
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqos/libqtest.h"
+#include "qemu-common.h"
+#include "qemu/bitops.h"
+
+#define HACE_CMD                 0x10
+#define  HACE_SHA_BE_EN          BIT(3)
+#define  HACE_MD5_LE_EN          BIT(2)
+#define  HACE_ALGO_MD5           0
+#define  HACE_ALGO_SHA1          BIT(5)
+#define  HACE_ALGO_SHA224        BIT(6)
+#define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
+#define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
+#define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
+#define  HACE_SG_EN              BIT(18)
+
+#define HACE_STS                 0x1c
+#define  HACE_RSA_ISR            BIT(13)
+#define  HACE_CRYPTO_ISR         BIT(12)
+#define  HACE_HASH_ISR           BIT(9)
+#define  HACE_RSA_BUSY           BIT(2)
+#define  HACE_CRYPTO_BUSY        BIT(1)
+#define  HACE_HASH_BUSY          BIT(0)
+#define HACE_HASH_SRC            0x20
+#define HACE_HASH_DIGEST         0x24
+#define HACE_HASH_KEY_BUFF       0x28
+#define HACE_HASH_DATA_LEN       0x2c
+#define HACE_HASH_CMD            0x30
+
+/*
+ * Test vector is the ascii "abc"
+ *
+ * Expected results were generated using command line utitiles:
+ *
+ *  echo -n -e 'abc' | dd of=/tmp/test
+ *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
+ *
+ */
+static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
+
+static const uint8_t test_result_sha512[] = {
+    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
+    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
+    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
+    0xa5, 0x4c, 0xa4, 0x9f};
+
+static const uint8_t test_result_sha256[] = {
+    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
+    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
+
+static const uint8_t test_result_md5[] = {
+    0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
+    0x28, 0xe1, 0x7f, 0x72};
+
+
+static void write_regs(QTestState *s, uint32_t base, uint32_t src,
+                       uint32_t length, uint32_t out, uint32_t method)
+{
+        qtest_writel(s, base + HACE_HASH_SRC, src);
+        qtest_writel(s, base + HACE_HASH_DIGEST, out);
+        qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
+        qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
+}
+
+static void test_md5(const char *machine, const uint32_t base,
+                     const uint32_t src_addr)
+
+{
+    QTestState *s = qtest_init(machine);
+
+    uint32_t digest_addr = src_addr + 0x01000000;
+    uint8_t digest[16] = {0};
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_MD5);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_md5, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+static void test_sha256(const char *machine, const uint32_t base,
+                        const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t digest_addr = src_addr + 0x1000000;
+    uint8_t digest[32] = {0};
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA256);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sha256, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+static void test_sha512(const char *machine, const uint32_t base,
+                        const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t digest_addr = src_addr + 0x1000000;
+    uint8_t digest[64] = {0};
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA512);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sha512, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+struct masks {
+    uint32_t src;
+    uint32_t dest;
+    uint32_t len;
+};
+
+static const struct masks ast2600_masks = {
+    .src  = 0x7fffffff,
+    .dest = 0x7ffffff8,
+    .len  = 0x0fffffff,
+};
+
+static const struct masks ast2500_masks = {
+    .src  = 0x3fffffff,
+    .dest = 0x3ffffff8,
+    .len  = 0x0fffffff,
+};
+
+static const struct masks ast2400_masks = {
+    .src  = 0x0fffffff,
+    .dest = 0x0ffffff8,
+    .len  = 0x0fffffff,
+};
+
+static void test_addresses(const char *machine, const uint32_t base,
+                           const struct masks *expected)
+{
+    QTestState *s = qtest_init(machine);
+
+    /*
+     * Check command mode is zero, meaning engine is in direct access mode,
+     * as this affects the masking behavior of the HASH_SRC register.
+     */
+    g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
+
+
+    /* Check that the address masking is correct */
+    qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
+
+    qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, expected->dest);
+
+    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, expected->len);
+
+    /* Reset to zero */
+    qtest_writel(s, base + HACE_HASH_SRC, 0);
+    qtest_writel(s, base + HACE_HASH_DIGEST, 0);
+    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
+
+    /* Check that all bits are now zero */
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
+
+    qtest_quit(s);
+}
+
+/* ast2600 */
+static void test_md5_ast2600(void)
+{
+    test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
+static void test_sha256_ast2600(void)
+{
+    test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
+static void test_sha512_ast2600(void)
+{
+    test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
+static void test_addresses_ast2600(void)
+{
+    test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
+}
+
+/* ast2500 */
+static void test_md5_ast2500(void)
+{
+    test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+}
+
+static void test_sha256_ast2500(void)
+{
+    test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+}
+
+static void test_sha512_ast2500(void)
+{
+    test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+}
+
+static void test_addresses_ast2500(void)
+{
+    test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
+}
+
+/* ast2400 */
+static void test_md5_ast2400(void)
+{
+    test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+}
+
+static void test_sha256_ast2400(void)
+{
+    test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+}
+
+static void test_sha512_ast2400(void)
+{
+    test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+}
+
+static void test_addresses_ast2400(void)
+{
+    test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("ast2600/hace/addresses", test_addresses_ast2600);
+    qtest_add_func("ast2600/hace/sha512", test_sha512_ast2600);
+    qtest_add_func("ast2600/hace/sha256", test_sha256_ast2600);
+    qtest_add_func("ast2600/hace/md5", test_md5_ast2600);
+
+    qtest_add_func("ast2500/hace/addresses", test_addresses_ast2500);
+    qtest_add_func("ast2500/hace/sha512", test_sha512_ast2500);
+    qtest_add_func("ast2500/hace/sha256", test_sha256_ast2500);
+    qtest_add_func("ast2500/hace/md5", test_md5_ast2500);
+
+    qtest_add_func("ast2400/hace/addresses", test_addresses_ast2400);
+    qtest_add_func("ast2400/hace/sha512", test_sha512_ast2400);
+    qtest_add_func("ast2400/hace/sha256", test_sha256_ast2400);
+    qtest_add_func("ast2400/hace/md5", test_md5_ast2400);
+
+    return g_test_run();
+}
diff --git a/MAINTAINERS b/MAINTAINERS
index 58f342108e9e..63c050ddc84a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1026,6 +1026,7 @@ F: include/hw/misc/pca9552*.h
 F: hw/net/ftgmac100.c
 F: include/hw/net/ftgmac100.h
 F: docs/system/arm/aspeed.rst
+F: tests/qtest/*aspeed*
 
 NRF51
 M: Joel Stanley <joel@jms.id.au>
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 902cfef7cb2f..84b3219c15c6 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -163,12 +163,15 @@ qtests_npcm7xx = \
    'npcm7xx_timer-test',
    'npcm7xx_watchdog_timer-test'] + \
    (slirp.found() ? ['npcm7xx_emc-test'] : [])
+qtests_aspeed = \
+  ['aspeed_hace-test']
 qtests_arm = \
   (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
   (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
   (config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
   (config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
   (config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) +         \
+  (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \
   (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
   ['arm-cpu-features',
    'microbit-test',
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 09/24] aspeed: Add Scater-Gather support for HACE Hash
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (7 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 08/24] tests/qtest: Add test for Aspeed HACE Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-08 12:39   ` Joel Stanley
  2021-04-07 17:16 ` [PATCH 10/24] tests: Aspeed HACE Scatter-Gather tests Cédric Le Goater
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, qemu-devel, Klaus Heinrich Kiwi, qemu-arm,
	Cédric Le Goater, Joel Stanley

From: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>

Complement the Aspeed HACE support with Scatter-Gather hash support for
sha256 and sha512. Scatter-Gather is only supported on AST2600-series.

Signed-off-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
[ clg: - fixes for checkpatch errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20210326193745.13558-2-klaus@linux.vnet.ibm.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 docs/system/arm/aspeed.rst |   2 +-
 hw/misc/aspeed_hace.c      | 133 +++++++++++++++++++++++++++++++++++--
 2 files changed, 128 insertions(+), 7 deletions(-)

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index f9466e6d8245..8680fd9409db 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -49,7 +49,7 @@ Supported devices
  * Ethernet controllers
  * Front LEDs (PCA9552 on I2C bus)
  * LPC Peripheral Controller (a subset of subdevices are supported)
- * Hash/Crypto Engine (HACE) - Hash support only, no scatter-gather
+ * Hash/Crypto Engine (HACE) - Hash support only
 
 
 Missing devices
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 6e5b447a4835..8b3eebfaec63 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -57,6 +57,14 @@
 /* Other cmd bits */
 #define  HASH_IRQ_EN                    BIT(9)
 #define  HASH_SG_EN                     BIT(18)
+/* Scatter-gather data list */
+#define SG_LIST_LEN_SIZE                4
+#define SG_LIST_LEN_MASK                0x0FFFFFFF
+#define SG_LIST_LEN_LAST                BIT(31)
+#define SG_LIST_ADDR_SIZE               4
+#define SG_LIST_ADDR_MASK               0x7FFFFFFF
+#define SG_LIST_ENTRY_SIZE              (SG_LIST_LEN_SIZE + SG_LIST_ADDR_SIZE)
+#define ASPEED_HACE_MAX_SG              256        /* max number of entries */
 
 static const struct {
     uint32_t mask;
@@ -129,6 +137,121 @@ static int do_hash_operation(AspeedHACEState *s, int algo)
     return 0;
 }
 
+static int do_hash_sg_operation(AspeedHACEState *s, int algo)
+{
+    hwaddr src, dest, req_size;
+    uint32_t entry_len, entry_addr;
+    uint8_t *digest_buf = NULL;
+    unsigned int i = 0;
+    MemTxResult result;
+    struct iovec iov[ASPEED_HACE_MAX_SG];
+    size_t digest_len = 0, size = 0;
+    int rc;
+
+    req_size = s->regs[R_HASH_SRC_LEN];
+    dest = s->regs[R_HASH_DEST];
+
+    while (i < ASPEED_HACE_MAX_SG) {
+        src = s->regs[R_HASH_SRC] + (i * SG_LIST_ENTRY_SIZE);
+        entry_len = address_space_ldl_le(&s->dram_as, src,
+                                         MEMTXATTRS_UNSPECIFIED, &result);
+        if (result != MEMTX_OK) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "%s: failed to load SG Array length entry %"PRIu32
+                          " from 0x%"HWADDR_PRIx"\n", __func__, i, src);
+            rc = -EACCES;
+            goto cleanup;
+        }
+        entry_addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE,
+                                          MEMTXATTRS_UNSPECIFIED, &result);
+        if (result != MEMTX_OK) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "%s: failed to load SG Array address entry %"PRIu32
+                          " from 0x%"HWADDR_PRIx"\n",
+                          __func__, i, src + SG_LIST_LEN_SIZE);
+            rc = -EACCES;
+            goto cleanup;
+        }
+
+        iov[i].iov_len = (hwaddr) (entry_len & SG_LIST_LEN_MASK);
+        iov[i].iov_base = address_space_map(&s->dram_as,
+                                            entry_addr & SG_LIST_ADDR_MASK,
+                                            &iov[i].iov_len, false,
+                                            MEMTXATTRS_UNSPECIFIED);
+        if (!iov[i].iov_base) {
+            qemu_log_mask(LOG_GUEST_ERROR,
+                          "%s: failed to map dram for SG array entry %"PRIu32
+                          " for region 0x%"PRIx32", len %"PRIu32"\n",
+                          __func__, i, entry_addr & SG_LIST_ADDR_MASK,
+                          entry_len & SG_LIST_LEN_MASK);
+            rc = -EACCES;
+            goto cleanup;
+        }
+        if (iov[i].iov_len != (entry_len & SG_LIST_LEN_MASK))
+            qemu_log_mask(LOG_GUEST_ERROR,
+                         "%s:  Warning: dram map for SG region entry %"PRIu32
+                         " requested size %"PRIu32" != mapped size %"PRIu64"\n",
+                         __func__, i, entry_len & SG_LIST_LEN_MASK,
+                         iov[i].iov_len);
+
+        size += iov[i].iov_len;
+        i++;
+
+        if (entry_len & SG_LIST_LEN_LAST) {
+            break;
+        }
+    }
+
+    if (!(entry_len & SG_LIST_LEN_LAST)) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Error: Exhausted maximum of %"PRIu32
+                      " SG array entries\n",
+                      __func__, ASPEED_HACE_MAX_SG);
+        rc = -ENOTSUP;
+        goto cleanup;
+    }
+
+    if (size != req_size)
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Warning: requested SG total size %"PRIu64
+                      " != actual size %"PRIu64"\n",
+                      __func__, req_size, size);
+
+    rc = qcrypto_hash_bytesv(algo, iov, i, &digest_buf, &digest_len,
+                            &error_fatal);
+    if (rc < 0) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n",
+                      __func__);
+        goto cleanup;
+    }
+
+    rc = address_space_write(&s->dram_as, dest, MEMTXATTRS_UNSPECIFIED,
+                             digest_buf, digest_len);
+    if (rc)
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: address space write failed\n", __func__);
+    g_free(digest_buf);
+
+cleanup:
+
+    for (; i > 0; i--) {
+        address_space_unmap(&s->dram_as, iov[i - 1].iov_base,
+                            iov[i - 1].iov_len, false,
+                            iov[i - 1].iov_len);
+    }
+
+    /*
+     * Set status bits to indicate completion. Testing shows hardware sets
+     * these irrespective of HASH_IRQ_EN.
+     */
+    if (!rc) {
+        s->regs[R_STATUS] |= HASH_IRQ;
+    }
+
+    return rc;
+}
+
+
 
 static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size)
 {
@@ -187,11 +310,6 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
                           "%s: HMAC engine command mode %"PRIx64" not implemented",
                           __func__, (data & HASH_HMAC_MASK) >> 8);
         }
-        if (data & HASH_SG_EN) {
-            qemu_log_mask(LOG_UNIMP,
-                          "%s: Hash scatter gather mode not implemented",
-                          __func__);
-        }
         if (data & BIT(1)) {
             qemu_log_mask(LOG_UNIMP,
                           "%s: Cascaded mode not implemented",
@@ -204,7 +322,10 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
                         __func__, data & ahc->hash_mask);
                 break;
         }
-        do_hash_operation(s, algo);
+        if (data & HASH_SG_EN)
+            do_hash_sg_operation(s, algo);
+        else
+            do_hash_operation(s, algo);
 
         if (data & HASH_IRQ_EN) {
             qemu_irq_raise(s->irq);
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 10/24] tests: Aspeed HACE Scatter-Gather tests
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (8 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 09/24] aspeed: Add Scater-Gather support for HACE Hash Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 11/24] tests/acceptance: Test ast2400 and ast2500 machines Cédric Le Goater
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, qemu-devel, Klaus Heinrich Kiwi, qemu-arm,
	Cédric Le Goater, Joel Stanley

From: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>

Expand current Aspeed HACE testsuite to also include Scatter-Gather of
sha256 and sha512 operations.

Signed-off-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
[ clg: - dropped whitespace changes
       - endian fixes
       - qtest_quit() fix ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20210326193745.13558-3-klaus@linux.vnet.ibm.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 tests/qtest/aspeed_hace-test.c | 148 +++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)

diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
index 675774e96eb9..be9f08aa28d4 100644
--- a/tests/qtest/aspeed_hace-test.c
+++ b/tests/qtest/aspeed_hace-test.c
@@ -34,6 +34,12 @@
 #define HACE_HASH_KEY_BUFF       0x28
 #define HACE_HASH_DATA_LEN       0x2c
 #define HACE_HASH_CMD            0x30
+/* Scatter-Gather Hash */
+#define SG_LIST_LEN_LAST         BIT(31)
+struct AspeedSgList {
+        uint32_t len;
+        uint32_t addr;
+} __attribute__ ((__packed__));
 
 /*
  * Test vector is the ascii "abc"
@@ -63,6 +69,33 @@ static const uint8_t test_result_md5[] = {
     0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
     0x28, 0xe1, 0x7f, 0x72};
 
+/*
+ * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
+ * into blocks of 3 characters as shown
+ *
+ * Expected results were generated using command line utitiles:
+ *
+ *  echo -n -e 'abcdefghi' | dd of=/tmp/test
+ *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
+ *
+ */
+static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63};
+static const uint8_t test_vector_sg2[] = {0x64, 0x65, 0x66};
+static const uint8_t test_vector_sg3[] = {0x67, 0x68, 0x69};
+
+static const uint8_t test_result_sg_sha512[] = {
+    0xf2, 0x2d, 0x51, 0xd2, 0x52, 0x92, 0xca, 0x1d, 0x0f, 0x68, 0xf6, 0x9a,
+    0xed, 0xc7, 0x89, 0x70, 0x19, 0x30, 0x8c, 0xc9, 0xdb, 0x46, 0xef, 0xb7,
+    0x5a, 0x03, 0xdd, 0x49, 0x4f, 0xc7, 0xf1, 0x26, 0xc0, 0x10, 0xe8, 0xad,
+    0xe6, 0xa0, 0x0a, 0x0c, 0x1a, 0x5f, 0x1b, 0x75, 0xd8, 0x1e, 0x0e, 0xd5,
+    0xa9, 0x3c, 0xe9, 0x8d, 0xc9, 0xb8, 0x33, 0xdb, 0x78, 0x39, 0x24, 0x7b,
+    0x1d, 0x9c, 0x24, 0xfe};
+
+static const uint8_t test_result_sg_sha256[] = {
+    0x19, 0xcc, 0x02, 0xf2, 0x6d, 0xf4, 0x3c, 0xc5, 0x71, 0xbc, 0x9e, 0xd7,
+    0xb0, 0xc4, 0xd2, 0x92, 0x24, 0xa3, 0xec, 0x22, 0x95, 0x29, 0x22, 0x17,
+    0x25, 0xef, 0x76, 0xd0, 0x21, 0xc8, 0x32, 0x6f};
+
 
 static void write_regs(QTestState *s, uint32_t base, uint32_t src,
                        uint32_t length, uint32_t out, uint32_t method)
@@ -173,6 +206,108 @@ static void test_sha512(const char *machine, const uint32_t base,
     qtest_quit(s);
 }
 
+static void test_sha256_sg(const char *machine, const uint32_t base,
+                        const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t src_addr_1 = src_addr + 0x1000000;
+    const uint32_t src_addr_2 = src_addr + 0x2000000;
+    const uint32_t src_addr_3 = src_addr + 0x3000000;
+    const uint32_t digest_addr = src_addr + 0x4000000;
+    uint8_t digest[32] = {0};
+    struct AspeedSgList array[] = {
+        {  cpu_to_le32(sizeof(test_vector_sg1)),
+           cpu_to_le32(src_addr_1) },
+        {  cpu_to_le32(sizeof(test_vector_sg2)),
+           cpu_to_le32(src_addr_2) },
+        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
+           cpu_to_le32(src_addr_3) },
+    };
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
+    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
+    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
+    qtest_memwrite(s, src_addr, array, sizeof(array));
+
+    write_regs(s, base, src_addr,
+               (sizeof(test_vector_sg1)
+                + sizeof(test_vector_sg2)
+                + sizeof(test_vector_sg3)),
+               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sg_sha256, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+static void test_sha512_sg(const char *machine, const uint32_t base,
+                        const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t src_addr_1 = src_addr + 0x1000000;
+    const uint32_t src_addr_2 = src_addr + 0x2000000;
+    const uint32_t src_addr_3 = src_addr + 0x3000000;
+    const uint32_t digest_addr = src_addr + 0x4000000;
+    uint8_t digest[64] = {0};
+    struct AspeedSgList array[] = {
+        {  cpu_to_le32(sizeof(test_vector_sg1)),
+           cpu_to_le32(src_addr_1) },
+        {  cpu_to_le32(sizeof(test_vector_sg2)),
+           cpu_to_le32(src_addr_2) },
+        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
+           cpu_to_le32(src_addr_3) },
+    };
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
+    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
+    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
+    qtest_memwrite(s, src_addr, array, sizeof(array));
+
+    write_regs(s, base, src_addr,
+               (sizeof(test_vector_sg1)
+                + sizeof(test_vector_sg2)
+                + sizeof(test_vector_sg3)),
+               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sg_sha512, sizeof(digest));
+
+    qtest_quit(s);
+}
+
 struct masks {
     uint32_t src;
     uint32_t dest;
@@ -246,11 +381,21 @@ static void test_sha256_ast2600(void)
     test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
+static void test_sha256_sg_ast2600(void)
+{
+    test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
 static void test_sha512_ast2600(void)
 {
     test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
+static void test_sha512_sg_ast2600(void)
+{
+    test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
 static void test_addresses_ast2600(void)
 {
     test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
@@ -307,6 +452,9 @@ int main(int argc, char **argv)
     qtest_add_func("ast2600/hace/sha256", test_sha256_ast2600);
     qtest_add_func("ast2600/hace/md5", test_md5_ast2600);
 
+    qtest_add_func("ast2600/hace/sha512_sg", test_sha512_sg_ast2600);
+    qtest_add_func("ast2600/hace/sha256_sg", test_sha256_sg_ast2600);
+
     qtest_add_func("ast2500/hace/addresses", test_addresses_ast2500);
     qtest_add_func("ast2500/hace/sha512", test_sha512_ast2500);
     qtest_add_func("ast2500/hace/sha256", test_sha256_ast2500);
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 11/24] tests/acceptance: Test ast2400 and ast2500 machines
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (9 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 10/24] tests: Aspeed HACE Scatter-Gather tests Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 18:40   ` Willian Rampazzo
  2021-04-07 17:16 ` [PATCH 12/24] tests/acceptance: Test ast2600 machine Cédric Le Goater
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, qemu-devel, Wainer dos Santos Moschetta,
	qemu-arm, Joel Stanley, Cleber Rosa, Cédric Le Goater

From: Joel Stanley <joel@jms.id.au>

Test MTD images from the OpenBMC project on AST2400 and AST2500 SoCs
from ASPEED, by booting Palmetto and Romulus BMC machines.

The images are fetched from OpenBMC's release directory on github.

Cc: Cleber Rosa <crosa@redhat.com>
Cc: Wainer dos Santos Moschetta <wainersm@redhat.com>
Co-developed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Tested-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Cleber Rosa <crosa@redhat.com>
Tested-by: Cleber Rosa <crosa@redhat.com>
[ clg : - removed comment
        - removed ending self.vm.shutdown() ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20210304123951.163411-2-joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
index 1ca32ecf253b..37bca7358583 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -1010,6 +1010,49 @@ def test_arm_vexpressa9(self):
         self.vm.add_args('-dtb', self.workdir + '/day16/vexpress-v2p-ca9.dtb')
         self.do_test_advcal_2018('16', tar_hash, 'winter.zImage')
 
+    def test_arm_ast2400_palmetto_openbmc_v2_9_0(self):
+        """
+        :avocado: tags=arch:arm
+        :avocado: tags=machine:palmetto-bmc
+        """
+
+        image_url = ('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
+                     'obmc-phosphor-image-palmetto.static.mtd')
+        image_hash = ('3e13bbbc28e424865dc42f35ad672b10f2e82cdb11846bb28fa625b48beafd0d')
+        image_path = self.fetch_asset(image_url, asset_hash=image_hash,
+                                      algorithm='sha256')
+
+        self.do_test_arm_aspeed(image_path)
+
+    def test_arm_ast2500_romulus_openbmc_v2_9_0(self):
+        """
+        :avocado: tags=arch:arm
+        :avocado: tags=machine:romulus-bmc
+        """
+
+        image_url = ('https://github.com/openbmc/openbmc/releases/download/2.9.0/'
+                     'obmc-phosphor-image-romulus.static.mtd')
+        image_hash = ('820341076803f1955bc31e647a512c79f9add4f5233d0697678bab4604c7bb25')
+        image_path = self.fetch_asset(image_url, asset_hash=image_hash,
+                                      algorithm='sha256')
+
+        self.do_test_arm_aspeed(image_path)
+
+    def do_test_arm_aspeed(self, image):
+        self.vm.set_console()
+        self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
+                         '-net', 'nic')
+        self.vm.launch()
+
+        self.wait_for_console_pattern("U-Boot 2016.07")
+        self.wait_for_console_pattern("## Loading kernel from FIT Image at 20080000")
+        self.wait_for_console_pattern("Starting kernel ...")
+        self.wait_for_console_pattern("Booting Linux on physical CPU 0x0")
+        self.wait_for_console_pattern(
+                "aspeed-smc 1e620000.spi: read control register: 203b0641")
+        self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ")
+        self.wait_for_console_pattern("systemd[1]: Set hostname to")
+
     def test_m68k_mcf5208evb(self):
         """
         :avocado: tags=arch:m68k
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 12/24] tests/acceptance: Test ast2600 machine
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (10 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 11/24] tests/acceptance: Test ast2400 and ast2500 machines Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 18:36   ` Willian Rampazzo
  2021-04-07 17:16 ` [PATCH 13/24] hw/misc/aspeed_xdma: Add AST2600 support Cédric Le Goater
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, qemu-devel, Wainer dos Santos Moschetta,
	qemu-arm, Joel Stanley, Cleber Rosa, Cédric Le Goater

From: Joel Stanley <joel@jms.id.au>

This tests a Debian multi-soc arm32 Linux kernel on the AST2600 based
Tacoma BMC machine.

There is no root file system so the test terminates when boot reaches
the stage where it attempts and fails to mount something.

Cc: Cleber Rosa <crosa@redhat.com>
Cc: Wainer dos Santos Moschetta <wainersm@redhat.com>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Tested-by: Cédric Le Goater <clg@kaod.org>
[ clg : - removed comment
        - removed ending self.vm.shutdown() ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20210304123951.163411-3-joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 tests/acceptance/boot_linux_console.py | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
index 37bca7358583..276a53f14647 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -1053,6 +1053,31 @@ def do_test_arm_aspeed(self, image):
         self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ")
         self.wait_for_console_pattern("systemd[1]: Set hostname to")
 
+    def test_arm_ast2600_debian(self):
+        """
+        :avocado: tags=arch:arm
+        :avocado: tags=machine:tacoma-bmc
+        """
+        deb_url = ('http://snapshot.debian.org/archive/debian/'
+                   '20210302T203551Z/'
+                   'pool/main/l/linux/'
+                   'linux-image-5.10.0-3-armmp_5.10.13-1_armhf.deb')
+        deb_hash = 'db40d32fe39255d05482bea48d72467b67d6225bb2a2a4d6f618cb8976f1e09e'
+        deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash,
+                                    algorithm='sha256')
+        kernel_path = self.extract_from_deb(deb_path, '/boot/vmlinuz-5.10.0-3-armmp')
+        dtb_path = self.extract_from_deb(deb_path,
+                '/usr/lib/linux-image-5.10.0-3-armmp/aspeed-bmc-opp-tacoma.dtb')
+
+        self.vm.set_console()
+        self.vm.add_args('-kernel', kernel_path,
+                         '-dtb', dtb_path,
+                         '-net', 'nic')
+        self.vm.launch()
+        self.wait_for_console_pattern("Booting Linux on physical CPU 0xf00")
+        self.wait_for_console_pattern("SMP: Total of 2 processors activated")
+        self.wait_for_console_pattern("No filesystem could mount root")
+
     def test_m68k_mcf5208evb(self):
         """
         :avocado: tags=arch:m68k
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 13/24] hw/misc/aspeed_xdma: Add AST2600 support
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (11 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 12/24] tests/acceptance: Test ast2600 machine Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 20:29   ` Eddie James
  2021-04-07 17:16 ` [PATCH 14/24] aspeed/smc: Add a 'features' attribute to the object class Cédric Le Goater
                   ` (10 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Eddie James, qemu-devel, qemu-arm,
	Cédric Le Goater, Joel Stanley

When we introduced support for the AST2600 SoC, the XDMA controller
was forgotten. It went unnoticed because it's not used under emulation.
But the register layout being different, the reset procedure is bogus
and this breaks kexec.

Add a AspeedXDMAClass to take into account the register differences.

Cc: Eddie James <eajames@linux.ibm.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/misc/aspeed_xdma.h |  17 ++++-
 hw/arm/aspeed_ast2600.c       |   3 +-
 hw/arm/aspeed_soc.c           |   3 +-
 hw/misc/aspeed_xdma.c         | 124 +++++++++++++++++++++++++++-------
 4 files changed, 121 insertions(+), 26 deletions(-)

diff --git a/include/hw/misc/aspeed_xdma.h b/include/hw/misc/aspeed_xdma.h
index a2dea96984f3..b1478fd1c681 100644
--- a/include/hw/misc/aspeed_xdma.h
+++ b/include/hw/misc/aspeed_xdma.h
@@ -13,7 +13,10 @@
 #include "qom/object.h"
 
 #define TYPE_ASPEED_XDMA "aspeed.xdma"
-OBJECT_DECLARE_SIMPLE_TYPE(AspeedXDMAState, ASPEED_XDMA)
+#define TYPE_ASPEED_2400_XDMA TYPE_ASPEED_XDMA "-ast2400"
+#define TYPE_ASPEED_2500_XDMA TYPE_ASPEED_XDMA "-ast2500"
+#define TYPE_ASPEED_2600_XDMA TYPE_ASPEED_XDMA "-ast2600"
+OBJECT_DECLARE_TYPE(AspeedXDMAState, AspeedXDMAClass, ASPEED_XDMA)
 
 #define ASPEED_XDMA_NUM_REGS (ASPEED_XDMA_REG_SIZE / sizeof(uint32_t))
 #define ASPEED_XDMA_REG_SIZE 0x7C
@@ -28,4 +31,16 @@ struct AspeedXDMAState {
     uint32_t regs[ASPEED_XDMA_NUM_REGS];
 };
 
+struct AspeedXDMAClass {
+    SysBusDeviceClass parent_class;
+
+    uint8_t cmdq_endp;
+    uint8_t cmdq_wrp;
+    uint8_t cmdq_rdp;
+    uint8_t intr_ctrl;
+    uint32_t intr_ctrl_mask;
+    uint8_t intr_status;
+    uint32_t intr_complete;
+};
+
 #endif /* ASPEED_XDMA_H */
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index e0fbb020c770..c60824bfeecb 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -187,7 +187,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
         object_initialize_child(obj, "mii[*]", &s->mii[i], TYPE_ASPEED_MII);
     }
 
-    object_initialize_child(obj, "xdma", &s->xdma, TYPE_ASPEED_XDMA);
+    snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname);
+    object_initialize_child(obj, "xdma", &s->xdma, typename);
 
     snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
     object_initialize_child(obj, "gpio", &s->gpio, typename);
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 8ed29113f79f..4a95d27d9d63 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -199,7 +199,8 @@ static void aspeed_soc_init(Object *obj)
                                 TYPE_FTGMAC100);
     }
 
-    object_initialize_child(obj, "xdma", &s->xdma, TYPE_ASPEED_XDMA);
+    snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname);
+    object_initialize_child(obj, "xdma", &s->xdma, typename);
 
     snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
     object_initialize_child(obj, "gpio", &s->gpio, typename);
diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c
index 533d237e3ce2..1c21577c98c9 100644
--- a/hw/misc/aspeed_xdma.c
+++ b/hw/misc/aspeed_xdma.c
@@ -30,6 +30,19 @@
 #define  XDMA_IRQ_ENG_STAT_US_COMP BIT(4)
 #define  XDMA_IRQ_ENG_STAT_DS_COMP BIT(5)
 #define  XDMA_IRQ_ENG_STAT_RESET   0xF8000000
+
+#define XDMA_AST2600_BMC_CMDQ_ADDR   0x14
+#define XDMA_AST2600_BMC_CMDQ_ENDP   0x18
+#define XDMA_AST2600_BMC_CMDQ_WRP    0x1c
+#define XDMA_AST2600_BMC_CMDQ_RDP    0x20
+#define XDMA_AST2600_IRQ_CTRL        0x38
+#define  XDMA_AST2600_IRQ_CTRL_US_COMP    BIT(16)
+#define  XDMA_AST2600_IRQ_CTRL_DS_COMP    BIT(17)
+#define  XDMA_AST2600_IRQ_CTRL_W_MASK     0x017003FF
+#define XDMA_AST2600_IRQ_STATUS      0x3c
+#define  XDMA_AST2600_IRQ_STATUS_US_COMP  BIT(16)
+#define  XDMA_AST2600_IRQ_STATUS_DS_COMP  BIT(17)
+
 #define XDMA_MEM_SIZE              0x1000
 
 #define TO_REG(addr) ((addr) / sizeof(uint32_t))
@@ -52,56 +65,48 @@ static void aspeed_xdma_write(void *opaque, hwaddr addr, uint64_t val,
     unsigned int idx;
     uint32_t val32 = (uint32_t)val;
     AspeedXDMAState *xdma = opaque;
+    AspeedXDMAClass *axc = ASPEED_XDMA_GET_CLASS(xdma);
 
     if (addr >= ASPEED_XDMA_REG_SIZE) {
         return;
     }
 
-    switch (addr) {
-    case XDMA_BMC_CMDQ_ENDP:
+    if (addr == axc->cmdq_endp) {
         xdma->regs[TO_REG(addr)] = val32 & XDMA_BMC_CMDQ_W_MASK;
-        break;
-    case XDMA_BMC_CMDQ_WRP:
+    } else if (addr == axc->cmdq_wrp) {
         idx = TO_REG(addr);
         xdma->regs[idx] = val32 & XDMA_BMC_CMDQ_W_MASK;
-        xdma->regs[TO_REG(XDMA_BMC_CMDQ_RDP)] = xdma->regs[idx];
+        xdma->regs[TO_REG(axc->cmdq_rdp)] = xdma->regs[idx];
 
         trace_aspeed_xdma_write(addr, val);
 
         if (xdma->bmc_cmdq_readp_set) {
             xdma->bmc_cmdq_readp_set = 0;
         } else {
-            xdma->regs[TO_REG(XDMA_IRQ_ENG_STAT)] |=
-                XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP;
+            xdma->regs[TO_REG(axc->intr_status)] |= axc->intr_complete;
 
-            if (xdma->regs[TO_REG(XDMA_IRQ_ENG_CTRL)] &
-                (XDMA_IRQ_ENG_CTRL_US_COMP | XDMA_IRQ_ENG_CTRL_DS_COMP))
+            if (xdma->regs[TO_REG(axc->intr_ctrl)] & axc->intr_complete) {
                 qemu_irq_raise(xdma->irq);
+            }
         }
-        break;
-    case XDMA_BMC_CMDQ_RDP:
+    } else if (addr == axc->cmdq_rdp) {
         trace_aspeed_xdma_write(addr, val);
 
         if (val32 == XDMA_BMC_CMDQ_RDP_MAGIC) {
             xdma->bmc_cmdq_readp_set = 1;
         }
-        break;
-    case XDMA_IRQ_ENG_CTRL:
-        xdma->regs[TO_REG(addr)] = val32 & XDMA_IRQ_ENG_CTRL_W_MASK;
-        break;
-    case XDMA_IRQ_ENG_STAT:
+    } else if (addr == axc->intr_ctrl) {
+        xdma->regs[TO_REG(addr)] = val32 & axc->intr_ctrl_mask;
+    } else if (addr == axc->intr_status) {
         trace_aspeed_xdma_write(addr, val);
 
         idx = TO_REG(addr);
-        if (val32 & (XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP)) {
-            xdma->regs[idx] &=
-                ~(XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP);
+        if (val32 & axc->intr_complete) {
+            xdma->regs[idx] &= ~axc->intr_complete;
             qemu_irq_lower(xdma->irq);
         }
-        break;
-    default:
+    } else {
         xdma->regs[TO_REG(addr)] = val32;
-        break;
     }
 }
 
@@ -127,10 +132,11 @@ static void aspeed_xdma_realize(DeviceState *dev, Error **errp)
 static void aspeed_xdma_reset(DeviceState *dev)
 {
     AspeedXDMAState *xdma = ASPEED_XDMA(dev);
+    AspeedXDMAClass *axc = ASPEED_XDMA_GET_CLASS(xdma);
 
     xdma->bmc_cmdq_readp_set = 0;
     memset(xdma->regs, 0, ASPEED_XDMA_REG_SIZE);
-    xdma->regs[TO_REG(XDMA_IRQ_ENG_STAT)] = XDMA_IRQ_ENG_STAT_RESET;
+    xdma->regs[TO_REG(axc->intr_status)] = XDMA_IRQ_ENG_STAT_RESET;
 
     qemu_irq_lower(xdma->irq);
 }
@@ -144,6 +150,73 @@ static const VMStateDescription aspeed_xdma_vmstate = {
     },
 };
 
+static void aspeed_2600_xdma_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass);
+
+    dc->desc = "ASPEED 2600 XDMA Controller";
+
+    axc->cmdq_endp = XDMA_AST2600_BMC_CMDQ_ENDP;
+    axc->cmdq_wrp = XDMA_AST2600_BMC_CMDQ_WRP;
+    axc->cmdq_rdp = XDMA_AST2600_BMC_CMDQ_RDP;
+    axc->intr_ctrl = XDMA_AST2600_IRQ_CTRL;
+    axc->intr_ctrl_mask = XDMA_AST2600_IRQ_CTRL_W_MASK;
+    axc->intr_status = XDMA_AST2600_IRQ_STATUS;
+    axc->intr_complete = XDMA_AST2600_IRQ_STATUS_US_COMP |
+        XDMA_AST2600_IRQ_STATUS_DS_COMP;
+}
+
+static const TypeInfo aspeed_2600_xdma_info = {
+    .name = TYPE_ASPEED_2600_XDMA,
+    .parent = TYPE_ASPEED_XDMA,
+    .class_init = aspeed_2600_xdma_class_init,
+};
+
+static void aspeed_2500_xdma_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass);
+
+    dc->desc = "ASPEED 2500 XDMA Controller";
+
+    axc->cmdq_endp = XDMA_BMC_CMDQ_ENDP;
+    axc->cmdq_wrp = XDMA_BMC_CMDQ_WRP;
+    axc->cmdq_rdp = XDMA_BMC_CMDQ_RDP;
+    axc->intr_ctrl = XDMA_IRQ_ENG_CTRL;
+    axc->intr_ctrl_mask = XDMA_IRQ_ENG_CTRL_W_MASK;
+    axc->intr_status = XDMA_IRQ_ENG_STAT;
+    axc->intr_complete = XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP;
+};
+
+static const TypeInfo aspeed_2500_xdma_info = {
+    .name = TYPE_ASPEED_2500_XDMA,
+    .parent = TYPE_ASPEED_XDMA,
+    .class_init = aspeed_2500_xdma_class_init,
+};
+
+static void aspeed_2400_xdma_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass);
+
+    dc->desc = "ASPEED 2400 XDMA Controller";
+
+    axc->cmdq_endp = XDMA_BMC_CMDQ_ENDP;
+    axc->cmdq_wrp = XDMA_BMC_CMDQ_WRP;
+    axc->cmdq_rdp = XDMA_BMC_CMDQ_RDP;
+    axc->intr_ctrl = XDMA_IRQ_ENG_CTRL;
+    axc->intr_ctrl_mask = XDMA_IRQ_ENG_CTRL_W_MASK;
+    axc->intr_status = XDMA_IRQ_ENG_STAT;
+    axc->intr_complete = XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP;
+};
+
+static const TypeInfo aspeed_2400_xdma_info = {
+    .name = TYPE_ASPEED_2400_XDMA,
+    .parent = TYPE_ASPEED_XDMA,
+    .class_init = aspeed_2400_xdma_class_init,
+};
+
 static void aspeed_xdma_class_init(ObjectClass *classp, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(classp);
@@ -158,10 +231,15 @@ static const TypeInfo aspeed_xdma_info = {
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(AspeedXDMAState),
     .class_init    = aspeed_xdma_class_init,
+    .class_size    = sizeof(AspeedXDMAClass),
+    .abstract      = true,
 };
 
 static void aspeed_xdma_register_type(void)
 {
     type_register_static(&aspeed_xdma_info);
+    type_register_static(&aspeed_2400_xdma_info);
+    type_register_static(&aspeed_2500_xdma_info);
+    type_register_static(&aspeed_2600_xdma_info);
 }
 type_init(aspeed_xdma_register_type);
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 14/24] aspeed/smc: Add a 'features' attribute to the object class
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (12 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 13/24] hw/misc/aspeed_xdma: Add AST2600 support Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-09  6:55   ` Joel Stanley
  2021-04-07 17:16 ` [PATCH 15/24] aspeed/smc: Add extra controls to request DMA Cédric Le Goater
                   ` (9 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

It will simplify extensions of the SMC model.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ssi/aspeed_smc.h |  2 +-
 hw/ssi/aspeed_smc.c         | 44 +++++++++++++++++++++----------------
 2 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 6ea2871cd899..07879fd1c4a7 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -47,7 +47,7 @@ typedef struct AspeedSMCController {
     const AspeedSegments *segments;
     hwaddr flash_window_base;
     uint32_t flash_window_size;
-    bool has_dma;
+    uint32_t features;
     hwaddr dma_flash_mask;
     hwaddr dma_dram_mask;
     uint32_t nregs;
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 50ea907aef74..4521bbd4864e 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -257,6 +257,12 @@ 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);
+#define ASPEED_SMC_FEATURE_DMA       0x1
+
+static inline bool aspeed_smc_has_dma(const AspeedSMCState *s)
+{
+    return !!(s->ctrl->features & ASPEED_SMC_FEATURE_DMA);
+}
 
 static const AspeedSMCController controllers[] = {
     {
@@ -271,7 +277,7 @@ 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,
@@ -287,7 +293,7 @@ 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,
@@ -305,7 +311,7 @@ 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,
@@ -321,7 +327,7 @@ 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,
@@ -339,7 +345,7 @@ 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,
@@ -355,7 +361,7 @@ 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,
@@ -371,7 +377,7 @@ 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,
@@ -389,7 +395,7 @@ 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,
         .dma_flash_mask    = 0x0FFFFFFC,
         .dma_dram_mask     = 0x3FFFFFFC,
         .nregs             = ASPEED_SMC_R_MAX,
@@ -407,7 +413,7 @@ 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,
         .dma_flash_mask    = 0x0FFFFFFC,
         .dma_dram_mask     = 0x3FFFFFFC,
         .nregs             = ASPEED_SMC_R_MAX,
@@ -997,11 +1003,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)) {
@@ -1290,13 +1296,13 @@ 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) {
+    } else if (aspeed_smc_has_dma(s) && 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_DRAM_ADDR) {
         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) {
         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) {
         s->regs[addr] = DMA_LENGTH(value);
     } else {
         qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
@@ -1412,7 +1418,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);
     }
 }
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 15/24] aspeed/smc: Add extra controls to request DMA
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (13 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 14/24] aspeed/smc: Add a 'features' attribute to the object class Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-09  6:54   ` Joel Stanley
  2021-04-07 17:16 ` [PATCH 16/24] tests/qtest: Rename m25p80 test in aspeed_smc test Cédric Le Goater
                   ` (8 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Chin-Ting Kuo, qemu-devel, qemu-arm,
	Cédric Le Goater, Joel Stanley

The AST2600 SPI controllers have a set of bits to request/grant DMA
access. Add a new SMC feature for these controllers and use it to
check access to the DMA registers.

Cc: Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/ssi/aspeed_smc.h |  1 +
 hw/ssi/aspeed_smc.c         | 74 +++++++++++++++++++++++++++++++++----
 2 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 07879fd1c4a7..cdaf165300b6 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -55,6 +55,7 @@ typedef struct AspeedSMCController {
                                const AspeedSegments *seg);
     void (*reg_to_segment)(const struct AspeedSMCState *s, uint32_t reg,
                            AspeedSegments *seg);
+    void (*dma_ctrl)(struct AspeedSMCState *s, uint32_t value);
 } AspeedSMCController;
 
 typedef struct AspeedSMCFlash {
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 4521bbd4864e..189b35637c77 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
@@ -228,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
@@ -257,7 +260,10 @@ 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)
 {
@@ -281,6 +287,7 @@ static const AspeedSMCController controllers[] = {
         .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,
@@ -299,6 +306,7 @@ static const AspeedSMCController controllers[] = {
         .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,
@@ -315,6 +323,7 @@ static const AspeedSMCController controllers[] = {
         .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,
@@ -333,6 +342,7 @@ static const AspeedSMCController controllers[] = {
         .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,
@@ -349,6 +359,7 @@ static const AspeedSMCController controllers[] = {
         .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,
@@ -365,6 +376,7 @@ static const AspeedSMCController controllers[] = {
         .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,
@@ -383,6 +395,7 @@ static const AspeedSMCController controllers[] = {
         .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,
@@ -395,12 +408,14 @@ static const AspeedSMCController controllers[] = {
         .segments          = aspeed_segments_ast2600_spi1,
         .flash_window_base = ASPEED26_SOC_SPI_FLASH_BASE,
         .flash_window_size = 0x10000000,
-        .features          = ASPEED_SMC_FEATURE_DMA,
+        .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,
@@ -413,12 +428,14 @@ static const AspeedSMCController controllers[] = {
         .segments          = aspeed_segments_ast2600_spi2,
         .flash_window_base = ASPEED26_SOC_SPI2_FLASH_BASE,
         .flash_window_size = 0x10000000,
-        .features          = ASPEED_SMC_FEATURE_DMA,
+        .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,
     },
 };
 
@@ -1240,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;
@@ -1265,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)
 {
@@ -1297,12 +1354,15 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
     } else if (addr == R_INTR_CTRL) {
         s->regs[addr] = value;
     } else if (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) {
-        aspeed_smc_dma_ctrl(s, value);
-    } else if (aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR) {
+        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 (aspeed_smc_has_dma(s) && 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 (aspeed_smc_has_dma(s) && 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",
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 16/24] tests/qtest: Rename m25p80 test in aspeed_smc test
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (14 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 15/24] aspeed/smc: Add extra controls to request DMA Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-09  6:55   ` Joel Stanley
  2021-04-07 17:16 ` [PATCH 17/24] aspeed: Remove swift-bmc machine Cédric Le Goater
                   ` (7 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

The m25p80 test depends on the Aspeed SMC controller to test our
SPI-NOR flash support. Reflect this dependency by changing the name.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 tests/qtest/{m25p80-test.c => aspeed_smc-test.c} | 12 ++++++------
 tests/qtest/meson.build                          |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)
 rename tests/qtest/{m25p80-test.c => aspeed_smc-test.c} (96%)

diff --git a/tests/qtest/m25p80-test.c b/tests/qtest/aspeed_smc-test.c
similarity index 96%
rename from tests/qtest/m25p80-test.c
rename to tests/qtest/aspeed_smc-test.c
index f860cef5f08f..87b40a0ef186 100644
--- a/tests/qtest/m25p80-test.c
+++ b/tests/qtest/aspeed_smc-test.c
@@ -367,12 +367,12 @@ int main(int argc, char **argv)
                                "-drive file=%s,format=raw,if=mtd",
                                tmp_path);
 
-    qtest_add_func("/m25p80/read_jedec", test_read_jedec);
-    qtest_add_func("/m25p80/erase_sector", test_erase_sector);
-    qtest_add_func("/m25p80/erase_all",  test_erase_all);
-    qtest_add_func("/m25p80/write_page", test_write_page);
-    qtest_add_func("/m25p80/read_page_mem", test_read_page_mem);
-    qtest_add_func("/m25p80/write_page_mem", test_write_page_mem);
+    qtest_add_func("/ast2400/smc/read_jedec", test_read_jedec);
+    qtest_add_func("/ast2400/smc/erase_sector", test_erase_sector);
+    qtest_add_func("/ast2400/smc/erase_all",  test_erase_all);
+    qtest_add_func("/ast2400/smc/write_page", test_write_page);
+    qtest_add_func("/ast2400/smc/read_page_mem", test_read_page_mem);
+    qtest_add_func("/ast2400/smc/write_page_mem", test_write_page_mem);
 
     ret = g_test_run();
 
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 84b3219c15c6..269a30b217d7 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -164,7 +164,8 @@ qtests_npcm7xx = \
    'npcm7xx_watchdog_timer-test'] + \
    (slirp.found() ? ['npcm7xx_emc-test'] : [])
 qtests_aspeed = \
-  ['aspeed_hace-test']
+  ['aspeed_hace-test',
+   'aspeed_smc-test']
 qtests_arm = \
   (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
   (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
@@ -175,7 +176,6 @@ qtests_arm = \
   (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
   ['arm-cpu-features',
    'microbit-test',
-   'm25p80-test',
    'test-arm-mptimer',
    'boot-serial-test',
    'hexloader-test']
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 17/24] aspeed: Remove swift-bmc machine
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (15 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 16/24] tests/qtest: Rename m25p80 test in aspeed_smc test Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 18:13   ` Adriana Kobylak
  2021-04-07 18:29   ` Peter Maydell
  2021-04-07 17:16 ` [PATCH 18/24] aspeed: Add support for the rainier-bmc board Cédric Le Goater
                   ` (6 subsequent siblings)
  23 siblings, 2 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Adriana Kobylak, qemu-devel, qemu-arm,
	Cédric Le Goater, Joel Stanley

The SWIFT machine never came out of the lab and we already have enough
AST2500 based OpenPower machines. Remove it.

Cc: Adriana Kobylak <anoo@us.ibm.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/arm/aspeed.c | 61 -------------------------------------------------
 1 file changed, 61 deletions(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 1cf5a15c8098..97dcca74feb4 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -110,17 +110,6 @@ struct AspeedMachineState {
         SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) |                       \
         SCU_AST2500_HW_STRAP_RESERVED1)
 
-/* Swift hardware value: 0xF11AD206 */
-#define SWIFT_BMC_HW_STRAP1 (                                           \
-        AST2500_HW_STRAP1_DEFAULTS |                                    \
-        SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE |                     \
-        SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE |                        \
-        SCU_AST2500_HW_STRAP_UART_DEBUG |                               \
-        SCU_AST2500_HW_STRAP_DDR4_ENABLE |                              \
-        SCU_H_PLL_BYPASS_EN |                                           \
-        SCU_AST2500_HW_STRAP_ACPI_ENABLE |                              \
-        SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
-
 #define G220A_BMC_HW_STRAP1 (                                      \
         SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE |                     \
         SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE |                        \
@@ -465,35 +454,6 @@ static void romulus_bmc_i2c_init(AspeedMachineState *bmc)
     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 11), "ds1338", 0x32);
 }
 
-static void swift_bmc_i2c_init(AspeedMachineState *bmc)
-{
-    AspeedSoCState *soc = &bmc->soc;
-
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 3), "pca9552", 0x60);
-
-    /* The swift board expects a TMP275 but a TMP105 is compatible */
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "tmp105", 0x48);
-    /* The swift board expects a pca9551 but a pca9552 is compatible */
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "pca9552", 0x60);
-
-    /* The swift board expects an Epson RX8900 RTC but a ds1338 is compatible */
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "ds1338", 0x32);
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "pca9552", 0x60);
-
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "tmp423", 0x4c);
-    /* The swift board expects a pca9539 but a pca9552 is compatible */
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "pca9552", 0x74);
-
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10), "tmp423", 0x4c);
-    /* The swift board expects a pca9539 but a pca9552 is compatible */
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10), "pca9552",
-                     0x74);
-
-    /* The swift board expects a TMP275 but a TMP105 is compatible */
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 12), "tmp105", 0x48);
-    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 12), "tmp105", 0x4a);
-}
-
 static void sonorapass_bmc_i2c_init(AspeedMachineState *bmc)
 {
     AspeedSoCState *soc = &bmc->soc;
@@ -796,23 +756,6 @@ static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data)
         aspeed_soc_num_cpus(amc->soc_name);
 };
 
-static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
-{
-    MachineClass *mc = MACHINE_CLASS(oc);
-    AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
-
-    mc->desc       = "OpenPOWER Swift BMC (ARM1176)";
-    amc->soc_name  = "ast2500-a1";
-    amc->hw_strap1 = SWIFT_BMC_HW_STRAP1;
-    amc->fmc_model = "mx66l1g45g";
-    amc->spi_model = "mx66l1g45g";
-    amc->num_cs    = 2;
-    amc->i2c_init  = swift_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 void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -903,10 +846,6 @@ static const TypeInfo aspeed_machine_types[] = {
         .name          = MACHINE_TYPE_NAME("romulus-bmc"),
         .parent        = TYPE_ASPEED_MACHINE,
         .class_init    = aspeed_machine_romulus_class_init,
-    }, {
-        .name          = MACHINE_TYPE_NAME("swift-bmc"),
-        .parent        = TYPE_ASPEED_MACHINE,
-        .class_init    = aspeed_machine_swift_class_init,
     }, {
         .name          = MACHINE_TYPE_NAME("sonorapass-bmc"),
         .parent        = TYPE_ASPEED_MACHINE,
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 18/24] aspeed: Add support for the rainier-bmc board
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (16 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 17/24] aspeed: Remove swift-bmc machine Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-09  6:57   ` Joel Stanley
  2021-04-07 17:16 ` [PATCH 19/24] hw/misc: Add an iBT device model Cédric Le Goater
                   ` (5 subsequent siblings)
  23 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

The Rainer BMC board is a board for the middle range POWER10 IBM systems.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/arm/aspeed.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 97dcca74feb4..19588e17fec8 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -135,6 +135,10 @@ struct AspeedMachineState {
 #define TACOMA_BMC_HW_STRAP1  0x00000000
 #define TACOMA_BMC_HW_STRAP2  0x00000040
 
+/* Rainier hardware value: (QEMU prototype) */
+#define RAINIER_BMC_HW_STRAP1 0x00000000
+#define RAINIER_BMC_HW_STRAP2 0x00000000
+
 /*
  * The max ram region is for firmwares that scan the address space
  * with load/store to guess how much RAM the SoC has.
@@ -589,6 +593,58 @@ static void g220a_bmc_i2c_init(AspeedMachineState *bmc)
                           eeprom_buf);
 }
 
+static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
+{
+    AspeedSoCState *soc = &bmc->soc;
+
+    /* The rainier expects a TMP275 but a TMP105 is compatible */
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), TYPE_TMP105,
+                     0x48);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), TYPE_TMP105,
+                     0x49);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), TYPE_TMP105,
+                     0x4a);
+
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), TYPE_TMP105,
+                     0x48);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), TYPE_TMP105,
+                     0x49);
+
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), TYPE_TMP105,
+                     0x48);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), TYPE_TMP105,
+                     0x4a);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), TYPE_TMP105,
+                     0x4b);
+
+    /* Bus 7: TODO dps310@76 */
+    /* Bus 7: TODO max31785@52 */
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "pca9552", 0x61);
+    /* Bus 7: TODO si7021-a20@20 */
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), TYPE_TMP105,
+                     0x48);
+
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), TYPE_TMP105,
+                     0x48);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), TYPE_TMP105,
+                     0x4a);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8), "pca9552", 0x61);
+    /* Bus 8: ucd90320@11 */
+    /* Bus 8: ucd90320@b */
+    /* Bus 8: ucd90320@c */
+
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "tmp423", 0x4c);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9), "tmp423", 0x4d);
+
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10), "tmp423", 0x4c);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10), "tmp423", 0x4d);
+
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 11), TYPE_TMP105,
+                     0x48);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 11), TYPE_TMP105,
+                     0x49);
+}
+
 static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
 {
     return ASPEED_MACHINE(obj)->mmio_exec;
@@ -829,6 +885,25 @@ static void aspeed_machine_g220a_class_init(ObjectClass *oc, void *data)
         aspeed_soc_num_cpus(amc->soc_name);
 };
 
+static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+    mc->desc       = "IBM Rainier BMC (Cortex A7)";
+    amc->soc_name  = "ast2600-a1";
+    amc->hw_strap1 = RAINIER_BMC_HW_STRAP1;
+    amc->hw_strap2 = RAINIER_BMC_HW_STRAP2;
+    amc->fmc_model = "mx66l1g45g";
+    amc->spi_model = "mx66l1g45g";
+    amc->num_cs    = 2;
+    amc->macs_mask  = ASPEED_MAC2_ON | ASPEED_MAC3_ON;
+    amc->i2c_init  = rainier_bmc_i2c_init;
+    mc->default_ram_size = 1 * GiB;
+    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"),
@@ -866,6 +941,10 @@ static const TypeInfo aspeed_machine_types[] = {
         .name          = MACHINE_TYPE_NAME("g220a-bmc"),
         .parent        = TYPE_ASPEED_MACHINE,
         .class_init    = aspeed_machine_g220a_class_init,
+    }, {
+        .name          = MACHINE_TYPE_NAME("rainier-bmc"),
+        .parent        = TYPE_ASPEED_MACHINE,
+        .class_init    = aspeed_machine_rainier_class_init,
     }, {
         .name          = TYPE_ASPEED_MACHINE,
         .parent        = TYPE_MACHINE,
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 19/24] hw/misc: Add an iBT device model
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (17 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 18/24] aspeed: Add support for the rainier-bmc board Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 20/24] aspeed: Emulate the AST2600A3 Cédric Le Goater
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Corey Minyard, Andrew Jeffery, qemu-devel, Hao Wu, qemu-arm,
	Cédric Le Goater, Joel Stanley

Implement an IPMI BT interface model using a chardev backend to
communicate with an external PowerNV machine. It uses the OpenIPMI
simulator protocol for virtual machines described in :

    https://github.com/cminyard/openipmi/blob/master/lanserv/README.vm

and implemented by the 'ipmi-bmc-extern' model on the host side.

To use, start the Aspeed BMC machine with :

    -chardev socket,id=ipmi0,host=localhost,port=9002,ipv4,server,nowait \
    -global driver=aspeed.ibt,property=chardev,value=ipmi0

and the PowerNV machine with :

    -chardev socket,id=ipmi0,host=localhost,port=9002,reconnect=10 \
    -device ipmi-bmc-extern,id=bmc0,chardev=ipmi0 \
    -device isa-ipmi-bt,bmc=bmc0,irq=10 -nodefaults

Cc: Hao Wu <wuhaotsh@google.com>
Cc: Corey Minyard <cminyard@mvista.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Message-Id: <20210329121912.271900-1-clg@kaod.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/arm/aspeed_soc.h  |   2 +
 include/hw/misc/aspeed_ibt.h |  47 +++
 hw/arm/aspeed_ast2600.c      |  12 +
 hw/arm/aspeed_soc.c          |  12 +
 hw/misc/aspeed_ibt.c         | 596 +++++++++++++++++++++++++++++++++++
 hw/misc/meson.build          |   1 +
 hw/misc/trace-events         |   7 +
 7 files changed, 677 insertions(+)
 create mode 100644 include/hw/misc/aspeed_ibt.h
 create mode 100644 hw/misc/aspeed_ibt.c

diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index d9161d26d645..f0c36b8f7d35 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -30,6 +30,7 @@
 #include "hw/usb/hcd-ehci.h"
 #include "qom/object.h"
 #include "hw/misc/aspeed_lpc.h"
+#include "hw/misc/aspeed_ibt.h"
 
 #define ASPEED_SPIS_NUM  2
 #define ASPEED_EHCIS_NUM 2
@@ -65,6 +66,7 @@ struct AspeedSoCState {
     AspeedSDHCIState sdhci;
     AspeedSDHCIState emmc;
     AspeedLPCState lpc;
+    AspeedIBTState ibt;
 };
 
 #define TYPE_ASPEED_SOC "aspeed-soc"
diff --git a/include/hw/misc/aspeed_ibt.h b/include/hw/misc/aspeed_ibt.h
new file mode 100644
index 000000000000..a02a57df9ff8
--- /dev/null
+++ b/include/hw/misc/aspeed_ibt.h
@@ -0,0 +1,47 @@
+/*
+ * ASPEED iBT Device
+ *
+ * Copyright 2016 IBM Corp.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef ASPEED_IBT_H
+#define ASPEED_IBT_H
+
+#include "hw/sysbus.h"
+#include "chardev/char-fe.h"
+
+#define TYPE_ASPEED_IBT "aspeed.ibt"
+#define ASPEED_IBT(obj) OBJECT_CHECK(AspeedIBTState, (obj), TYPE_ASPEED_IBT)
+
+#define ASPEED_IBT_NR_REGS (0x1C >> 2)
+
+#define ASPEED_IBT_BUFFER_SIZE 64
+
+typedef struct AspeedIBTState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    CharBackend chr;
+    bool connected;
+
+    uint8_t recv_msg[ASPEED_IBT_BUFFER_SIZE];
+    uint8_t recv_msg_len;
+    int recv_msg_index;
+    int recv_msg_too_many;
+    bool recv_waiting;
+    int in_escape;
+
+    uint8_t send_msg[ASPEED_IBT_BUFFER_SIZE];
+    uint8_t send_msg_len;
+
+    MemoryRegion iomem;
+    qemu_irq irq;
+
+    uint32_t regs[ASPEED_IBT_NR_REGS];
+
+} AspeedIBTState;
+
+#endif /* ASPEED_IBT_H */
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index c60824bfeecb..bb650d31f5ad 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -219,6 +219,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
 
     snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
     object_initialize_child(obj, "hace", &s->hace, typename);
+
+    object_initialize_child(obj, "ibt", &s->ibt, TYPE_ASPEED_IBT);
 }
 
 /*
@@ -510,6 +512,16 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
                        aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
+
+    /* iBT */
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->ibt), errp)) {
+        return;
+    }
+    memory_region_add_subregion(&s->lpc.iomem,
+                   sc->memmap[ASPEED_DEV_IBT] - sc->memmap[ASPEED_DEV_LPC],
+                   &s->ibt.iomem);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->ibt), 0,
+                       aspeed_soc_get_irq(s, ASPEED_DEV_IBT));
 }
 
 static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 4a95d27d9d63..5ab4cefc7e8b 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -219,6 +219,8 @@ static void aspeed_soc_init(Object *obj)
 
     snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
     object_initialize_child(obj, "hace", &s->hace, typename);
+
+    object_initialize_child(obj, "ibt", &s->ibt, TYPE_ASPEED_IBT);
 }
 
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
@@ -438,6 +440,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
                        aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
+
+    /* iBT */
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->ibt), errp)) {
+        return;
+    }
+    memory_region_add_subregion(&s->lpc.iomem,
+                   sc->memmap[ASPEED_DEV_IBT] - sc->memmap[ASPEED_DEV_LPC],
+                   &s->ibt.iomem);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_ibt,
+                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_ibt));
 }
 static Property aspeed_soc_properties[] = {
     DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
diff --git a/hw/misc/aspeed_ibt.c b/hw/misc/aspeed_ibt.c
new file mode 100644
index 000000000000..69a2096ccb00
--- /dev/null
+++ b/hw/misc/aspeed_ibt.c
@@ -0,0 +1,596 @@
+/*
+ * ASPEED iBT Device
+ *
+ * Copyright (c) 2016-2021 Cédric Le Goater, IBM Corporation.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "sysemu/qtest.h"
+#include "sysemu/sysemu.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "migration/vmstate.h"
+#include "hw/misc/aspeed_ibt.h"
+#include "trace.h"
+
+#define BT_IO_REGION_SIZE 0x1C
+
+#define TO_REG(o) (o >> 2)
+
+#define BT_CR0                0x0   /* iBT config */
+#define   BT_CR0_IO_BASE         16
+#define   BT_CR0_IRQ             12
+#define   BT_CR0_EN_CLR_SLV_RDP  0x8
+#define   BT_CR0_EN_CLR_SLV_WRP  0x4
+#define   BT_CR0_ENABLE_IBT      0x1
+#define BT_CR1                0x4  /* interrupt enable */
+#define   BT_CR1_IRQ_H2B         0x01
+#define   BT_CR1_IRQ_HBUSY       0x40
+#define BT_CR2                0x8  /* interrupt status */
+#define   BT_CR2_IRQ_H2B         0x01
+#define   BT_CR2_IRQ_HBUSY       0x40
+#define BT_CR3                0xc /* unused */
+#define BT_CTRL                  0x10
+#define   BT_CTRL_B_BUSY         0x80
+#define   BT_CTRL_H_BUSY         0x40
+#define   BT_CTRL_OEM0           0x20
+#define   BT_CTRL_SMS_ATN        0x10
+#define   BT_CTRL_B2H_ATN        0x08
+#define   BT_CTRL_H2B_ATN        0x04
+#define   BT_CTRL_CLR_RD_PTR     0x02
+#define   BT_CTRL_CLR_WR_PTR     0x01
+#define BT_BMC2HOST            0x14
+#define BT_INTMASK             0x18
+#define   BT_INTMASK_B2H_IRQEN   0x01
+#define   BT_INTMASK_B2H_IRQ     0x02
+#define   BT_INTMASK_BMC_HWRST   0x80
+
+/*
+ * VM IPMI defines
+ */
+#define VM_MSG_CHAR        0xA0 /* Marks end of message */
+#define VM_CMD_CHAR        0xA1 /* Marks end of a command */
+#define VM_ESCAPE_CHAR     0xAA /* Set bit 4 from the next byte to 0 */
+
+#define VM_PROTOCOL_VERSION        1
+#define VM_CMD_VERSION             0xff /* A version number byte follows */
+#define VM_CMD_NOATTN              0x00
+#define VM_CMD_ATTN                0x01
+#define VM_CMD_ATTN_IRQ            0x02
+#define VM_CMD_POWEROFF            0x03
+#define VM_CMD_RESET               0x04
+#define VM_CMD_ENABLE_IRQ          0x05 /* Enable/disable the messaging irq */
+#define VM_CMD_DISABLE_IRQ         0x06
+#define VM_CMD_SEND_NMI            0x07
+#define VM_CMD_CAPABILITIES        0x08
+#define   VM_CAPABILITIES_POWER    0x01
+#define   VM_CAPABILITIES_RESET    0x02
+#define   VM_CAPABILITIES_IRQ      0x04
+#define   VM_CAPABILITIES_NMI      0x08
+#define   VM_CAPABILITIES_ATTN     0x10
+#define   VM_CAPABILITIES_GRACEFUL_SHUTDOWN 0x20
+#define VM_CMD_GRACEFUL_SHUTDOWN   0x09
+
+/*
+ * These routines are inspired by the 'ipmi-bmc-extern' model and by
+ * the lanserv simulator of OpenIPMI. See :
+ *    https://github.com/cminyard/openipmi/blob/master/lanserv/serial_ipmi.c
+ */
+static unsigned char ipmb_checksum(const unsigned char *data, int size,
+                                   unsigned char start)
+{
+        unsigned char csum = start;
+
+        for (; size > 0; size--, data++) {
+                csum += *data;
+        }
+        return csum;
+}
+
+static void vm_add_char(unsigned char ch, unsigned char *c, unsigned int *pos)
+{
+    switch (ch) {
+    case VM_MSG_CHAR:
+    case VM_CMD_CHAR:
+    case VM_ESCAPE_CHAR:
+        c[(*pos)++] = VM_ESCAPE_CHAR;
+        c[(*pos)++] = ch | 0x10;
+        break;
+
+    default:
+        c[(*pos)++] = ch;
+    }
+}
+
+static void aspeed_ibt_dump_msg(const char *func, unsigned char *msg,
+                                unsigned int len)
+{
+    if (trace_event_get_state_backends(TRACE_ASPEED_IBT_CHR_DUMP_MSG)) {
+        int size = len * 3 + 1;
+        char tmp[size];
+        int i, n = 0;
+
+        for (i = 0; i < len; i++) {
+            n += snprintf(tmp + n, size - n, "%02x:", msg[i]);
+        }
+        tmp[size - 1] = 0;
+
+        trace_aspeed_ibt_chr_dump_msg(func, tmp, len);
+    }
+}
+
+static void aspeed_ibt_chr_write(AspeedIBTState *ibt, const uint8_t *buf,
+                                 int len)
+{
+    int i;
+
+    if (!qemu_chr_fe_get_driver(&ibt->chr)) {
+        return;
+    }
+
+    aspeed_ibt_dump_msg(__func__, ibt->recv_msg, ibt->recv_msg_len);
+
+    for (i = 0; i < len; i++) {
+        qemu_chr_fe_write(&ibt->chr, &buf[i], 1);
+    }
+}
+
+static void vm_send(AspeedIBTState *ibt)
+{
+    unsigned int i;
+    unsigned int len = 0;
+    unsigned char c[(ibt->send_msg_len + 7) * 2];
+    uint8_t netfn;
+
+    /*
+     * The VM IPMI message format does not follow the IPMI BT
+     * interface format. The sequence and the netfn bytes need to be
+     * swapped.
+     */
+    netfn = ibt->send_msg[1];
+    ibt->send_msg[1] = ibt->send_msg[2];
+    ibt->send_msg[2] = netfn;
+
+    /* No length byte in the VM IPMI message format. trim it */
+    for (i = 1; i < ibt->send_msg_len; i++) {
+        vm_add_char(ibt->send_msg[i], c, &len);
+    }
+
+    vm_add_char(-ipmb_checksum(&ibt->send_msg[1], ibt->send_msg_len - 1, 0),
+                c, &len);
+    c[len++] = VM_MSG_CHAR;
+
+    aspeed_ibt_chr_write(ibt, c, len);
+}
+
+static void aspeed_ibt_update_irq(AspeedIBTState *ibt)
+{
+    bool raise = false;
+
+    /* H2B rising */
+    if ((ibt->regs[TO_REG(BT_CTRL)] & BT_CTRL_H2B_ATN) &&
+        ((ibt->regs[TO_REG(BT_CR1)] & BT_CR1_IRQ_H2B) == BT_CR1_IRQ_H2B)) {
+        ibt->regs[TO_REG(BT_CR2)] |= BT_CR2_IRQ_H2B;
+
+        /*
+         * Also flag the fact that we are waiting for the guest/driver
+         * to read a received message
+         */
+        ibt->recv_waiting = true;
+        raise = true;
+    }
+
+    /* H_BUSY falling (not supported) */
+    if ((ibt->regs[TO_REG(BT_CTRL)] & BT_CTRL_H_BUSY) &&
+        ((ibt->regs[TO_REG(BT_CR1)] & BT_CR1_IRQ_HBUSY) == BT_CR1_IRQ_HBUSY)) {
+        ibt->regs[TO_REG(BT_CR2)] |= BT_CR2_IRQ_HBUSY;
+
+        raise = true;
+    }
+
+    if (raise) {
+        qemu_irq_raise(ibt->irq);
+    }
+}
+
+static void vm_handle_msg(AspeedIBTState *ibt, unsigned char *msg,
+                          unsigned int len)
+{
+    uint8_t seq;
+
+    aspeed_ibt_dump_msg(__func__, ibt->recv_msg, ibt->recv_msg_len);
+
+    if (len < 4) {
+        qemu_log_mask(LOG_GUEST_ERROR, " %s: Message too short\n", __func__);
+        return;
+    }
+
+    if (ipmb_checksum(ibt->recv_msg, ibt->recv_msg_len, 0) != 0) {
+        qemu_log_mask(LOG_GUEST_ERROR, " %s: Message checksum failure\n",
+                      __func__);
+        return;
+    }
+
+    /* Trim the checksum byte */
+    ibt->recv_msg_len--;
+
+    /*
+     * The VM IPMI message format does not follow the IPMI BT
+     * interface format. The sequence and the netfn bytes need to be
+     * swapped.
+     */
+    seq = ibt->recv_msg[0];
+    ibt->recv_msg[0] = ibt->recv_msg[1];
+    ibt->recv_msg[1] = seq;
+
+    aspeed_ibt_update_irq(ibt);
+}
+
+/* TODO: handle commands */
+static void vm_handle_cmd(AspeedIBTState *ibt, unsigned char *msg,
+                          unsigned int len)
+{
+    aspeed_ibt_dump_msg(__func__, ibt->recv_msg, ibt->recv_msg_len);
+
+    if (len < 1) {
+        qemu_log_mask(LOG_GUEST_ERROR, " %s: Command too short\n", __func__);
+        return;
+    }
+
+    switch (msg[0]) {
+    case VM_CMD_VERSION:
+        break;
+
+    case VM_CMD_CAPABILITIES:
+        if (len < 2) {
+            return;
+        }
+        break;
+
+    case VM_CMD_RESET:
+        break;
+    }
+}
+
+static void vm_handle_char(AspeedIBTState *ibt, unsigned char ch)
+{
+    unsigned int len = ibt->recv_msg_len;
+
+    switch (ch) {
+    case VM_MSG_CHAR:
+    case VM_CMD_CHAR:
+        if (ibt->in_escape) {
+            qemu_log_mask(LOG_GUEST_ERROR, " %s: Message ended in escape\n",
+                          __func__);
+        } else if (ibt->recv_msg_too_many) {
+            qemu_log_mask(LOG_GUEST_ERROR, " %s: Message too long\n", __func__);
+        } else if (ibt->recv_msg_len == 0) {
+            /* Nothing to do */
+        } else if (ch == VM_MSG_CHAR) {
+            /* Last byte of message. Signal BMC as the host would do */
+            ibt->regs[TO_REG(BT_CTRL)] |= BT_CTRL_H2B_ATN;
+
+            vm_handle_msg(ibt, ibt->recv_msg, ibt->recv_msg_len);
+
+            /* Message is only handled when read by BMC (!B_BUSY) */
+        } else if (ch == VM_CMD_CHAR) {
+            vm_handle_cmd(ibt, ibt->recv_msg, ibt->recv_msg_len);
+
+            /* Command is now handled. reset receive state */
+            ibt->in_escape = 0;
+            ibt->recv_msg_len = 0;
+            ibt->recv_msg_too_many = 0;
+        }
+        break;
+
+    case VM_ESCAPE_CHAR:
+        if (!ibt->recv_msg_too_many) {
+            ibt->in_escape = 1;
+        }
+        break;
+
+    default:
+        if (ibt->in_escape) {
+            ibt->in_escape = 0;
+            ch &= ~0x10;
+        }
+
+        if (!ibt->recv_msg_too_many) {
+            if (len >= sizeof(ibt->recv_msg)) {
+                ibt->recv_msg_too_many = 1;
+                break;
+            }
+
+            ibt->recv_msg[len] = ch;
+            ibt->recv_msg_len++;
+        }
+        break;
+    }
+}
+
+static void vm_connected(AspeedIBTState *ibt)
+{
+    unsigned int len = 0;
+    unsigned char c[5];
+
+    vm_add_char(VM_CMD_VERSION, c, &len);
+    vm_add_char(VM_PROTOCOL_VERSION, c, &len);
+    c[len++] = VM_CMD_CHAR;
+
+    aspeed_ibt_chr_write(ibt, c, len);
+}
+
+static void aspeed_ibt_chr_event(void *opaque, QEMUChrEvent event)
+{
+    AspeedIBTState *ibt = ASPEED_IBT(opaque);
+
+    switch (event) {
+    case CHR_EVENT_OPENED:
+        vm_connected(ibt);
+        ibt->connected = true;
+        break;
+
+    case CHR_EVENT_CLOSED:
+        if (!ibt->connected) {
+            return;
+        }
+        ibt->connected = false;
+        break;
+    case CHR_EVENT_BREAK:
+    case CHR_EVENT_MUX_IN:
+    case CHR_EVENT_MUX_OUT:
+        /* Ignore */
+        break;
+   }
+    trace_aspeed_ibt_chr_event(ibt->connected);
+}
+
+static int aspeed_ibt_chr_can_receive(void *opaque)
+{
+    AspeedIBTState *ibt = ASPEED_IBT(opaque);
+
+    return !ibt->recv_waiting && !(ibt->regs[TO_REG(BT_CTRL)] & BT_CTRL_B_BUSY);
+}
+
+static void aspeed_ibt_chr_receive(void *opaque, const uint8_t *buf,
+                                   int size)
+{
+    AspeedIBTState *ibt = ASPEED_IBT(opaque);
+    int i;
+
+    if (!ibt->connected) {
+        qemu_log_mask(LOG_GUEST_ERROR, " %s: not connected !?\n", __func__);
+        return;
+    }
+
+    for (i = 0; i < size; i++) {
+        vm_handle_char(ibt, buf[i]);
+    }
+}
+
+static void aspeed_ibt_write(void *opaque, hwaddr offset, uint64_t data,
+                             unsigned size)
+{
+    AspeedIBTState *ibt = ASPEED_IBT(opaque);
+
+    trace_aspeed_ibt_write(offset, data);
+
+    switch (offset) {
+    case BT_CTRL:
+        /* CLR_WR_PTR: cleared before a message is written */
+        if (data & BT_CTRL_CLR_WR_PTR) {
+            memset(ibt->send_msg, 0, sizeof(ibt->send_msg));
+            ibt->send_msg_len = 0;
+            trace_aspeed_ibt_event("CLR_WR_PTR");
+        }
+
+        /* CLR_RD_PTR: cleared before a message is read */
+        else if (data & BT_CTRL_CLR_RD_PTR) {
+            ibt->recv_msg_index = -1;
+            trace_aspeed_ibt_event("CLR_RD_PTR");
+        }
+
+        /*
+         * H2B_ATN: raised by host to end message, cleared by BMC
+         * before reading message
+         */
+        else if (data & BT_CTRL_H2B_ATN) {
+            ibt->regs[TO_REG(BT_CTRL)] &= ~BT_CTRL_H2B_ATN;
+            trace_aspeed_ibt_event("H2B_ATN");
+        }
+
+        /* B_BUSY: raised and cleared by BMC when message is read */
+        else if (data & BT_CTRL_B_BUSY) {
+            ibt->regs[TO_REG(BT_CTRL)] ^= BT_CTRL_B_BUSY;
+            trace_aspeed_ibt_event("B_BUSY");
+        }
+
+        /*
+         * B2H_ATN: raised by BMC and cleared by host
+         *
+         * Also simulate the host busy bit which is set while the host
+         * is reading the message from the BMC
+         */
+        else if (data & BT_CTRL_B2H_ATN) {
+            trace_aspeed_ibt_event("B2H_ATN");
+            ibt->regs[TO_REG(BT_CTRL)] |= (BT_CTRL_B2H_ATN | BT_CTRL_H_BUSY);
+
+            vm_send(ibt);
+
+            ibt->regs[TO_REG(BT_CTRL)] &= ~(BT_CTRL_B2H_ATN | BT_CTRL_H_BUSY);
+
+            /* signal H_BUSY falling but that's a bit useless */
+            aspeed_ibt_update_irq(ibt);
+        }
+
+        /* Anything else is unexpected */
+        else {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected CTRL setting\n",
+                          __func__);
+        }
+
+        /* Message was read by BMC. we can reset the receive state */
+        if (!(ibt->regs[TO_REG(BT_CTRL)] & BT_CTRL_B_BUSY)) {
+            trace_aspeed_ibt_event("B_BUSY cleared");
+            ibt->recv_waiting = false;
+            ibt->in_escape = 0;
+            ibt->recv_msg_len = 0;
+            ibt->recv_msg_too_many = 0;
+        }
+        break;
+
+    case BT_BMC2HOST:
+        if (ibt->send_msg_len < sizeof(ibt->send_msg)) {
+            trace_aspeed_ibt_event("BMC2HOST");
+            ibt->send_msg[ibt->send_msg_len++] = data & 0xff;
+        }
+        break;
+
+    case BT_CR0: /* TODO: iBT config */
+    case BT_CR1: /* interrupt enable */
+    case BT_CR3: /* unused */
+    case BT_INTMASK:
+        ibt->regs[TO_REG(offset)] = (uint32_t) data;
+        break;
+    case BT_CR2: /* interrupt status. writing 1 clears. */
+        ibt->regs[TO_REG(offset)] ^= (uint32_t) data;
+        qemu_irq_lower(ibt->irq);
+        break;
+
+    default:
+        qemu_log_mask(LOG_UNIMP, "%s: not implemented 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+        break;
+    }
+}
+
+static uint64_t aspeed_ibt_read(void *opaque, hwaddr offset, unsigned size)
+{
+    AspeedIBTState *ibt = ASPEED_IBT(opaque);
+    uint64_t val = 0;
+
+    switch (offset) {
+    case BT_BMC2HOST:
+        trace_aspeed_ibt_event("BMC2HOST");
+        /*
+         * The IPMI BT interface requires the first byte to be the
+         * length of the message
+         */
+        if (ibt->recv_msg_index == -1) {
+            val = ibt->recv_msg_len;
+            ibt->recv_msg_index++;
+        } else if (ibt->recv_msg_index < ibt->recv_msg_len) {
+            val = ibt->recv_msg[ibt->recv_msg_index++];
+        }
+        break;
+
+    case BT_CR0:
+    case BT_CR1:
+    case BT_CR2:
+    case BT_CR3:
+    case BT_CTRL:
+    case BT_INTMASK:
+        return ibt->regs[TO_REG(offset)];
+    default:
+        qemu_log_mask(LOG_UNIMP, "%s: not implemented 0x%" HWADDR_PRIx "\n",
+                      __func__, offset);
+        return 0;
+    }
+
+    trace_aspeed_ibt_read(offset, val);
+    return val;
+}
+
+static const MemoryRegionOps aspeed_ibt_ops = {
+    .read = aspeed_ibt_read,
+    .write = aspeed_ibt_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+static void aspeed_ibt_reset(DeviceState *dev)
+{
+    AspeedIBTState *ibt = ASPEED_IBT(dev);
+
+    memset(ibt->regs, 0, sizeof(ibt->regs));
+
+    memset(ibt->recv_msg, 0, sizeof(ibt->recv_msg));
+    ibt->recv_msg_len = 0;
+    ibt->recv_msg_index = -1;
+    ibt->recv_msg_too_many = 0;
+    ibt->recv_waiting = false;
+    ibt->in_escape = 0;
+
+    memset(ibt->send_msg, 0, sizeof(ibt->send_msg));
+    ibt->send_msg_len = 0;
+}
+
+static void aspeed_ibt_realize(DeviceState *dev, Error **errp)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    AspeedIBTState *ibt = ASPEED_IBT(dev);
+
+    if (!qemu_chr_fe_get_driver(&ibt->chr) && !qtest_enabled()) {
+        warn_report("Aspeed iBT has no chardev backend");
+    } else {
+        qemu_chr_fe_set_handlers(&ibt->chr, aspeed_ibt_chr_can_receive,
+                                 aspeed_ibt_chr_receive, aspeed_ibt_chr_event,
+                                 NULL, ibt, NULL, true);
+    }
+
+    sysbus_init_irq(sbd, &ibt->irq);
+    memory_region_init_io(&ibt->iomem, OBJECT(ibt), &aspeed_ibt_ops, ibt,
+                          TYPE_ASPEED_IBT, BT_IO_REGION_SIZE);
+
+    sysbus_init_mmio(sbd, &ibt->iomem);
+}
+
+static Property aspeed_ibt_props[] = {
+    DEFINE_PROP_CHR("chardev", AspeedIBTState, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_aspeed_ibt = {
+    .name = "aspeed.bt",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, AspeedIBTState, ASPEED_IBT_NR_REGS),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void aspeed_ibt_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->realize = aspeed_ibt_realize;
+    dc->reset = aspeed_ibt_reset;
+    dc->desc = "ASPEED iBT Device";
+    dc->vmsd = &vmstate_aspeed_ibt;
+    device_class_set_props(dc, aspeed_ibt_props);
+}
+
+static const TypeInfo aspeed_ibt_info = {
+    .name = TYPE_ASPEED_IBT,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(AspeedIBTState),
+    .class_init = aspeed_ibt_class_init,
+};
+
+static void aspeed_ibt_register_types(void)
+{
+    type_register_static(&aspeed_ibt_info);
+}
+
+type_init(aspeed_ibt_register_types);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 1e7b8b064bd1..ed8196dc4380 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -110,6 +110,7 @@ softmmu_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
 softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
   'aspeed_hace.c',
+  'aspeed_ibt.c',
   'aspeed_lpc.c',
   'aspeed_scu.c',
   'aspeed_sdmc.c',
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index d0a89eb05964..e8fcacdfd9e9 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -19,6 +19,13 @@ allwinner_h3_dramphy_write(uint64_t offset, uint64_t data, unsigned size) "write
 allwinner_sid_read(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32
 allwinner_sid_write(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" PRIx64 " data 0x%" PRIx64 " size %" PRIu32
 
+# aspeed_ibt.c
+aspeed_ibt_chr_dump_msg(const char *func, const char *buf, uint32_t len) "%s: %s #%d bytes"
+aspeed_ibt_chr_event(bool connected) "connected:%d"
+aspeed_ibt_read(uint64_t offset, uint64_t value) "offset:0x%" PRIx64 " value:0x%" PRIx64
+aspeed_ibt_write(uint64_t offset, uint64_t value) "offset:0x%" PRIx64 " value:0x%" PRIx64
+aspeed_ibt_event(const char* event) "%s"
+
 # avr_power.c
 avr_power_read(uint8_t value) "power_reduc read value:%u"
 avr_power_write(uint8_t value) "power_reduc write value:%u"
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 20/24] aspeed: Emulate the AST2600A3
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (18 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 19/24] hw/misc: Add an iBT device model Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g Cédric Le Goater
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

From: Joel Stanley <joel@jms.id.au>

This is the latest revision of the ASPEED 2600 SoC.

Reset values are taken from v8 of the datasheet.

Signed-off-by: Joel Stanley <joel@jms.id.au>
Message-Id: <20210304124316.164742-1-joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/misc/aspeed_scu.h |  2 ++
 hw/arm/aspeed_ast2600.c      |  2 +-
 hw/misc/aspeed_scu.c         | 32 +++++++++++++++++++++++++-------
 3 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
index d49bfb02fbdb..c14aff2bcbb5 100644
--- a/include/hw/misc/aspeed_scu.h
+++ b/include/hw/misc/aspeed_scu.h
@@ -43,6 +43,8 @@ struct AspeedSCUState {
 #define AST2500_A1_SILICON_REV   0x04010303U
 #define AST2600_A0_SILICON_REV   0x05000303U
 #define AST2600_A1_SILICON_REV   0x05010303U
+#define AST2600_A2_SILICON_REV   0x05020303U
+#define AST2600_A3_SILICON_REV   0x05030303U
 
 #define ASPEED_IS_AST2500(si_rev)     ((((si_rev) >> 24) & 0xff) == 0x04)
 
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index bb650d31f5ad..c30d0f320c2a 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -533,7 +533,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
 
     sc->name         = "ast2600-a1";
     sc->cpu_type     = ARM_CPU_TYPE_NAME("cortex-a7");
-    sc->silicon_rev  = AST2600_A1_SILICON_REV;
+    sc->silicon_rev  = AST2600_A3_SILICON_REV;
     sc->sram_size    = 0x16400;
     sc->spis_num     = 2;
     sc->ehcis_num    = 2;
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 40a38ebd8549..3515d6ff6bbf 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -104,11 +104,19 @@
 #define AST2600_SDRAM_HANDSHAKE   TO_REG(0x100)
 #define AST2600_HPLL_PARAM        TO_REG(0x200)
 #define AST2600_HPLL_EXT          TO_REG(0x204)
+#define AST2600_APLL_PARAM        TO_REG(0x210)
+#define AST2600_APLL_EXT          TO_REG(0x214)
+#define AST2600_MPLL_PARAM        TO_REG(0x220)
 #define AST2600_MPLL_EXT          TO_REG(0x224)
+#define AST2600_EPLL_PARAM        TO_REG(0x240)
 #define AST2600_EPLL_EXT          TO_REG(0x244)
+#define AST2600_DPLL_PARAM        TO_REG(0x260)
+#define AST2600_DPLL_EXT          TO_REG(0x264)
 #define AST2600_CLK_SEL           TO_REG(0x300)
 #define AST2600_CLK_SEL2          TO_REG(0x304)
-#define AST2600_CLK_SEL3          TO_REG(0x310)
+#define AST2600_CLK_SEL3          TO_REG(0x308)
+#define AST2600_CLK_SEL4          TO_REG(0x310)
+#define AST2600_CLK_SEL5          TO_REG(0x314)
 #define AST2600_HW_STRAP1         TO_REG(0x500)
 #define AST2600_HW_STRAP1_CLR     TO_REG(0x504)
 #define AST2600_HW_STRAP1_PROT    TO_REG(0x508)
@@ -433,6 +441,8 @@ static uint32_t aspeed_silicon_revs[] = {
     AST2500_A1_SILICON_REV,
     AST2600_A0_SILICON_REV,
     AST2600_A1_SILICON_REV,
+    AST2600_A2_SILICON_REV,
+    AST2600_A3_SILICON_REV,
 };
 
 bool is_supported_silicon_rev(uint32_t silicon_rev)
@@ -651,16 +661,24 @@ static const MemoryRegionOps aspeed_ast2600_scu_ops = {
     .valid.unaligned = false,
 };
 
-static const uint32_t ast2600_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = {
+static const uint32_t ast2600_a3_resets[ASPEED_AST2600_SCU_NR_REGS] = {
     [AST2600_SYS_RST_CTRL]      = 0xF7C3FED8,
-    [AST2600_SYS_RST_CTRL2]     = 0xFFFFFFFC,
+    [AST2600_SYS_RST_CTRL2]     = 0x0DFFFFFC,
     [AST2600_CLK_STOP_CTRL]     = 0xFFFF7F8A,
     [AST2600_CLK_STOP_CTRL2]    = 0xFFF0FFF0,
     [AST2600_SDRAM_HANDSHAKE]   = 0x00000000,
-    [AST2600_HPLL_PARAM]        = 0x1000405F,
+    [AST2600_HPLL_PARAM]        = 0x1000408F,
+    [AST2600_APLL_PARAM]        = 0x1000405F,
+    [AST2600_MPLL_PARAM]        = 0x1008405F,
+    [AST2600_EPLL_PARAM]        = 0x1004077F,
+    [AST2600_DPLL_PARAM]        = 0x1078405F,
+    [AST2600_CLK_SEL]           = 0xF3940000,
+    [AST2600_CLK_SEL2]          = 0x00700000,
+    [AST2600_CLK_SEL3]          = 0x00000000,
+    [AST2600_CLK_SEL4]          = 0xF3F40000,
+    [AST2600_CLK_SEL5]          = 0x30000000,
     [AST2600_CHIP_ID0]          = 0x1234ABCD,
     [AST2600_CHIP_ID1]          = 0x88884444,
-
 };
 
 static void aspeed_ast2600_scu_reset(DeviceState *dev)
@@ -675,7 +693,7 @@ static void aspeed_ast2600_scu_reset(DeviceState *dev)
      * of actual revision. QEMU and Linux only support A1 onwards so this is
      * sufficient.
      */
-    s->regs[AST2600_SILICON_REV] = AST2600_A1_SILICON_REV;
+    s->regs[AST2600_SILICON_REV] = AST2600_A3_SILICON_REV;
     s->regs[AST2600_SILICON_REV2] = s->silicon_rev;
     s->regs[AST2600_HW_STRAP1] = s->hw_strap1;
     s->regs[AST2600_HW_STRAP2] = s->hw_strap2;
@@ -689,7 +707,7 @@ static void aspeed_2600_scu_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "ASPEED 2600 System Control Unit";
     dc->reset = aspeed_ast2600_scu_reset;
-    asc->resets = ast2600_a1_resets;
+    asc->resets = ast2600_a3_resets;
     asc->calc_hpll = aspeed_2500_scu_calc_hpll; /* No change since AST2500 */
     asc->apb_divider = 4;
     asc->nr_regs = ASPEED_AST2600_SCU_NR_REGS;
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (19 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 20/24] aspeed: Emulate the AST2600A3 Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:36   ` Alistair Francis
  2021-04-08  8:00   ` Francisco Iglesias
  2021-04-07 17:16 ` [PATCH 22/24] hw/misc: Add Infineon DPS310 sensor model Cédric Le Goater
                   ` (2 subsequent siblings)
  23 siblings, 2 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, qemu-devel, Francisco Iglesias, qemu-arm,
	Alistair Francis, Cédric Le Goater, Joel Stanley

The Micron mt25qu02g is a 3V 2Gb serial NOR flash memory supporting
dual I/O and quad I/O, 4KB, 32KB, 64KB sector erase. It also supports
4B opcodes.

Cc: Alistair Francis <alistair.francis@wdc.com>
Cc: Francisco Iglesias <francisco.iglesias@xilinx.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/block/m25p80.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 183d3f44c259..2afb939ae28e 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -259,6 +259,7 @@ static const FlashPartInfo known_devices[] = {
     { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
     { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
     { INFO_STACKED("mt25qu01g", 0x20bb21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
+    { INFO_STACKED("mt25qu02g", 0x20ba22, 0x1040, 64 << 10, 4096, ER_4K, 2) },
 
     /* Spansion -- single (large) sector size only, at least
      * for the chips listed here (without boot sectors).
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 22/24] hw/misc: Add Infineon DPS310 sensor model
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (20 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 23/24] arm/aspeed: Add DPS310 to rainier Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 24/24] arm/aspeed: Add DPS310 to witherspoon Cédric Le Goater
  23 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

From: Joel Stanley <joel@jms.id.au>

This contains some hardcoded register values that were obtained from the
hardware after reading the temperature.

It does enough to test the Linux kernel driver.

Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/misc/dps310.c    | 339 ++++++++++++++++++++++++++++++++++++++++++++
 hw/arm/Kconfig      |   1 +
 hw/misc/Kconfig     |   4 +
 hw/misc/meson.build |   1 +
 4 files changed, 345 insertions(+)
 create mode 100644 hw/misc/dps310.c

diff --git a/hw/misc/dps310.c b/hw/misc/dps310.c
new file mode 100644
index 000000000000..153357b88236
--- /dev/null
+++ b/hw/misc/dps310.c
@@ -0,0 +1,339 @@
+/*
+ * Infineon DPS310 temperature and himidity sensor
+ *
+ * Copyright 2017 IBM Corporation
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/i2c/i2c.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "migration/vmstate.h"
+
+typedef struct DPS310State {
+    /*< private >*/
+    I2CSlave i2c;
+
+    /*< public >*/
+
+    uint8_t regs[0x30];
+
+    int16_t pressure, temperature;
+
+    uint8_t len;
+    uint8_t buf[2];
+    uint8_t pointer;
+
+} DPS310State;
+
+typedef struct DPS310Class {
+    I2CSlaveClass parent_class;
+} DPS310Class;
+
+#define TYPE_DPS310 "dps310"
+#define DPS310(obj) OBJECT_CHECK(DPS310State, (obj), TYPE_DPS310)
+
+#define DPS310_CLASS(klass) \
+     OBJECT_CLASS_CHECK(DPS310Class, (klass), TYPE_DPS310)
+#define DPS310_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(DPS310Class, (obj), TYPE_DPS310)
+
+#define DPS310_PRS_B2           0x00
+#define DPS310_PRS_B1           0x01
+#define DPS310_PRS_B0           0x02
+#define DPS310_TMP_B2           0x03
+#define DPS310_TMP_B1           0x04
+#define DPS310_TMP_B0           0x05
+#define DPS310_PRS_CFG          0x06
+#define DPS310_TMP_CFG          0x07
+#define  DPS310_TMP_RATE_BITS   GENMASK(6, 4)
+#define DPS310_MEAS_CFG         0x08
+#define  DPS310_MEAS_CTRL_BITS  GENMASK(2, 0)
+#define   DPS310_PRESSURE_EN    BIT(0)
+#define   DPS310_TEMP_EN        BIT(1)
+#define   DPS310_BACKGROUND     BIT(2)
+#define  DPS310_PRS_RDY         BIT(4)
+#define  DPS310_TMP_RDY         BIT(5)
+#define  DPS310_SENSOR_RDY      BIT(6)
+#define  DPS310_COEF_RDY        BIT(7)
+#define DPS310_RESET            0x0c
+#define  DPS310_RESET_MAGIC     (BIT(0) | BIT(3))
+#define DPS310_COEF_BASE        0x10
+
+static void dps310_reset(DeviceState *dev)
+{
+    DPS310State *s = DPS310(dev);
+
+    memset(s->regs, 0, sizeof(s->regs));
+    s->pointer = 0;
+
+    s->regs[0x00] = 0xf3;
+    s->regs[0x01] = 0x4a;
+    s->regs[0x02] = 0xcc;
+    s->regs[0x03] = 0x06;
+    s->regs[0x04] = 0x7b;
+    s->regs[0x05] = 0xf3;
+    s->regs[0x06] = 0x07;
+    s->regs[0x07] = 0x87;
+    s->regs[0x08] = 0xc0;
+    s->regs[0x09] = 0x0c;
+    s->regs[0x0a] = 0x00;
+    s->regs[0x0b] = 0x00;
+    s->regs[0x0c] = 0x00;
+    s->regs[0x0d] = 0x10;
+    s->regs[0x0e] = 0x00;
+    s->regs[0x0f] = 0x00;
+    s->regs[0x10] = 0x0e;
+    s->regs[0x11] = 0x0e;
+    s->regs[0x12] = 0xdb;
+    s->regs[0x13] = 0x13;
+    s->regs[0x14] = 0xca;
+    s->regs[0x15] = 0xff;
+    s->regs[0x16] = 0x35;
+    s->regs[0x17] = 0x10;
+    s->regs[0x18] = 0xf3;
+    s->regs[0x19] = 0x34;
+    s->regs[0x1a] = 0x05;
+    s->regs[0x1b] = 0xc3;
+    s->regs[0x1c] = 0xd6;
+    s->regs[0x1d] = 0x84;
+    s->regs[0x1e] = 0x00;
+    s->regs[0x1f] = 0xa4;
+    s->regs[0x20] = 0xf9;
+    s->regs[0x21] = 0xa9;
+    s->regs[0x22] = 0x00;
+    s->regs[0x23] = 0x00;
+    s->regs[0x24] = 0x20;
+    s->regs[0x25] = 0x49;
+    s->regs[0x26] = 0x4a;
+    s->regs[0x27] = 0x41;
+    s->regs[0x28] = 0x86;
+    s->regs[0x29] = 0x00;
+    s->regs[0x2a] = 0x00;
+    s->regs[0x2b] = 0x00;
+    s->regs[0x2c] = 0x00;
+    s->regs[0x2d] = 0x00;
+    s->regs[0x2e] = 0x00;
+    s->regs[0x2f] = 0x00;
+
+    /* TODO: assert these after some timeout ? */
+    s->regs[DPS310_MEAS_CFG] = DPS310_COEF_RDY | DPS310_SENSOR_RDY
+        | DPS310_TMP_RDY | DPS310_PRS_RDY;
+
+}
+
+
+static void dps310_get_pressure(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    DPS310State *s = DPS310(obj);
+    int64_t value;
+
+    /* TODO */
+    value = s->pressure;
+
+    visit_type_int(v, name, &value, errp);
+}
+
+static void dps310_get_temperature(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    DPS310State *s = DPS310(obj);
+    int64_t value;
+
+    /* TODO */
+    value = s->temperature;
+
+
+    visit_type_int(v, name, &value, errp);
+}
+
+static void dps310_set_temperature(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    DPS310State *s = DPS310(obj);
+    Error *local_err = NULL;
+    int64_t temp;
+
+    visit_type_int(v, name, &temp, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    /* TODO */
+    if (temp >= 200 || temp < -100) {
+        error_setg(errp, "value %" PRId64 ".%03" PRIu64 " °C is out of range",
+                   temp / 1000, temp % 1000);
+        return;
+    }
+
+    s->temperature = temp;
+}
+
+static void dps310_set_pressure(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    DPS310State *s = DPS310(obj);
+    Error *local_err = NULL;
+    int64_t pres;
+
+    visit_type_int(v, name, &pres, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    /* TODO */
+    if (pres >= 200 || pres < -100) {
+        error_setg(errp, "value %" PRId64 ".%03" PRIu64 " is out of range",
+                   pres / 1000, pres % 1000);
+        return;
+    }
+
+    s->pressure = pres;
+}
+
+static void dps310_read(DPS310State *s)
+{
+    s->len = 0;
+
+    switch (s->pointer) {
+    case DPS310_PRS_B2:
+    case DPS310_PRS_B1:
+    case DPS310_PRS_B0:
+    case DPS310_TMP_B2:
+    case DPS310_TMP_B1:
+    case DPS310_TMP_B0:
+    case DPS310_PRS_CFG:
+    case DPS310_TMP_CFG:
+    case DPS310_MEAS_CFG:
+    case DPS310_COEF_BASE:
+    default:
+        s->buf[s->len++] = s->regs[s->pointer];
+        break;
+    }
+}
+
+static void dps310_write(DPS310State *s)
+{
+    switch (s->pointer) {
+    case DPS310_RESET:
+        if (s->buf[0] == DPS310_RESET_MAGIC) {
+            dps310_reset(DEVICE(s));
+        }
+        break;
+    case DPS310_PRS_CFG:
+    case DPS310_TMP_CFG:
+    case DPS310_MEAS_CFG:
+    case DPS310_COEF_BASE:
+    default:
+        s->regs[s->pointer] = s->buf[0];
+        break;
+    }
+}
+
+static uint8_t dps310_rx(I2CSlave *i2c)
+{
+    DPS310State *s = DPS310(i2c);
+
+    if (s->len < 2) {
+        return s->buf[s->len++];
+    } else {
+        return 0xff;
+    }
+}
+
+static int dps310_tx(I2CSlave *i2c, uint8_t data)
+{
+    DPS310State *s = DPS310(i2c);
+
+    if (s->len == 0) {
+        /*
+         * first byte is the register pointer for a read or write
+         * operation
+         */
+        s->pointer = data;
+        s->len++;
+    } else if (s->len == 1) {
+        /*
+         * second byte is the data to write. The device only supports
+         * one byte writes
+         */
+        s->buf[0] = data;
+        dps310_write(s);
+    }
+
+    return 0;
+}
+
+static int dps310_event(I2CSlave *i2c, enum i2c_event event)
+{
+    DPS310State *s = DPS310(i2c);
+
+    if (event == I2C_START_RECV) {
+        dps310_read(s);
+    }
+
+    s->len = 0;
+    return 0;
+}
+
+static const VMStateDescription vmstate_dps310 = {
+    .name = "DPS310",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(len, DPS310State),
+        VMSTATE_UINT8_ARRAY(buf, DPS310State, 2),
+        VMSTATE_UINT8_ARRAY(regs, DPS310State, 0x30),
+        VMSTATE_UINT8(pointer, DPS310State),
+        VMSTATE_INT16(temperature, DPS310State),
+        VMSTATE_INT16(pressure, DPS310State),
+        VMSTATE_I2C_SLAVE(i2c, DPS310State),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+
+static void dps310_initfn(Object *obj)
+{
+    object_property_add(obj, "temperature", "int",
+                        dps310_get_temperature,
+                        dps310_set_temperature, NULL, NULL);
+    object_property_add(obj, "pressure", "int",
+                        dps310_get_pressure,
+                        dps310_set_pressure, NULL, NULL);
+}
+
+static void dps310_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->event = dps310_event;
+    k->recv = dps310_rx;
+    k->send = dps310_tx;
+    dc->reset = dps310_reset;
+    dc->vmsd = &vmstate_dps310;
+}
+
+static const TypeInfo dps310_info = {
+    .name          = TYPE_DPS310,
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(DPS310State),
+    .instance_init = dps310_initfn,
+    .class_init    = dps310_class_init,
+};
+
+static void dps310_register_types(void)
+{
+    type_register_static(&dps310_info);
+}
+
+type_init(dps310_register_types)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 8c37cf00da74..66532e0e3e82 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -408,6 +408,7 @@ config ASPEED_SOC
     select DS1338
     select FTGMAC100
     select I2C
+    select DPS310
     select PCA9552
     select SERIAL
     select SMBUS_EEPROM
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index c71ed2582046..016e34790e4f 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -49,6 +49,10 @@ config EDU
     default y if TEST_DEVICES
     depends on PCI && MSI_NONBROKEN
 
+config DPS310
+    bool
+    depends on I2C
+
 config PCA9552
     bool
     depends on I2C
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index ed8196dc4380..30cb61ec0e31 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -1,4 +1,5 @@
 softmmu_ss.add(when: 'CONFIG_APPLESMC', if_true: files('applesmc.c'))
+softmmu_ss.add(when: 'CONFIG_DPS310', if_true: files('dps310.c'))
 softmmu_ss.add(when: 'CONFIG_EDU', if_true: files('edu.c'))
 softmmu_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: files('vmcoreinfo.c'))
 softmmu_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: files('debugexit.c'))
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 23/24] arm/aspeed: Add DPS310 to rainier
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (21 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 22/24] hw/misc: Add Infineon DPS310 sensor model Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  2021-04-07 17:16 ` [PATCH 24/24] arm/aspeed: Add DPS310 to witherspoon Cédric Le Goater
  23 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

From: Joel Stanley <joel@jms.id.au>

Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/arm/aspeed.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 19588e17fec8..96782269b220 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -617,9 +617,9 @@ static void rainier_bmc_i2c_init(AspeedMachineState *bmc)
     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 6), TYPE_TMP105,
                      0x4b);
 
-    /* Bus 7: TODO dps310@76 */
     /* Bus 7: TODO max31785@52 */
     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "pca9552", 0x61);
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), "dps310", 0x76);
     /* Bus 7: TODO si7021-a20@20 */
     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7), TYPE_TMP105,
                      0x48);
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 24/24] arm/aspeed: Add DPS310 to witherspoon
  2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
                   ` (22 preceding siblings ...)
  2021-04-07 17:16 ` [PATCH 23/24] arm/aspeed: Add DPS310 to rainier Cédric Le Goater
@ 2021-04-07 17:16 ` Cédric Le Goater
  23 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-07 17:16 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, Cédric Le Goater, qemu-arm, Joel Stanley,
	qemu-devel

From: Joel Stanley <joel@jms.id.au>

Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/arm/aspeed.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 96782269b220..c1e1434a3770 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -521,7 +521,6 @@ static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
 
     /* Bus 3: TODO bmp280@77 */
     /* Bus 3: TODO max31785@52 */
-    /* Bus 3: TODO dps310@76 */
     dev = DEVICE(i2c_slave_new(TYPE_PCA9552, 0x60));
     qdev_prop_set_string(dev, "description", "pca1");
     i2c_slave_realize_and_unref(I2C_SLAVE(dev),
@@ -536,6 +535,7 @@ static void witherspoon_bmc_i2c_init(AspeedMachineState *bmc)
         qdev_connect_gpio_out(dev, pca1_leds[i].gpio_id,
                               qdev_get_gpio_in(DEVICE(led), 0));
     }
+    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 3), "dps310", 0x76);
     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 4), "tmp423", 0x4c);
     i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 5), "tmp423", 0x4c);
 
-- 
2.26.3



^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 01/24] aspeed/smc: Use the RAM memory region for DMAs
  2021-04-07 17:16 ` [PATCH 01/24] aspeed/smc: Use the RAM memory region for DMAs Cédric Le Goater
@ 2021-04-07 17:32   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 50+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-04-07 17:32 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, qemu-devel, Joel Stanley

On 4/7/21 7:16 PM, Cédric Le Goater wrote:
> Instead of passing the memory address space region, simply use the RAM
> memory region instead. This simplifies RAM accesses.
> 
> Fixes: c4e1f0b48322 ("aspeed/smc: Add support for DMAs")
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/arm/aspeed.c     | 2 +-
>  hw/ssi/aspeed_smc.c | 3 +--
>  2 files changed, 2 insertions(+), 3 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 02/24] aspeed/smc: Remove unused "sdram-base" property
  2021-04-07 17:16 ` [PATCH 02/24] aspeed/smc: Remove unused "sdram-base" property Cédric Le Goater
@ 2021-04-07 17:32   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 50+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-04-07 17:32 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, qemu-devel, Joel Stanley

On 4/7/21 7:16 PM, Cédric Le Goater wrote:
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  include/hw/ssi/aspeed_smc.h | 3 ---
>  hw/arm/aspeed_ast2600.c     | 4 ----
>  hw/arm/aspeed_soc.c         | 4 ----
>  hw/ssi/aspeed_smc.c         | 1 -
>  4 files changed, 12 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 04/24] aspeed/i2c: Rename DMA address space
  2021-04-07 17:16 ` [PATCH 04/24] aspeed/i2c: Rename DMA address space Cédric Le Goater
@ 2021-04-07 17:33   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 50+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-04-07 17:33 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, Joel Stanley, qemu-devel

On 4/7/21 7:16 PM, Cédric Le Goater wrote:
> It improves 'info mtree' output.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/i2c/aspeed_i2c.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g
  2021-04-07 17:16 ` [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g Cédric Le Goater
@ 2021-04-07 17:36   ` Alistair Francis
  2021-04-08  8:00   ` Francisco Iglesias
  1 sibling, 0 replies; 50+ messages in thread
From: Alistair Francis @ 2021-04-07 17:36 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Peter Maydell, Andrew Jeffery, qemu-devel@nongnu.org Developers,
	Francisco Iglesias, qemu-arm, Alistair Francis, Joel Stanley

On Wed, Apr 7, 2021 at 1:35 PM Cédric Le Goater <clg@kaod.org> wrote:
>
> The Micron mt25qu02g is a 3V 2Gb serial NOR flash memory supporting
> dual I/O and quad I/O, 4KB, 32KB, 64KB sector erase. It also supports
> 4B opcodes.
>
> Cc: Alistair Francis <alistair.francis@wdc.com>
> Cc: Francisco Iglesias <francisco.iglesias@xilinx.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  hw/block/m25p80.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 183d3f44c259..2afb939ae28e 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -259,6 +259,7 @@ static const FlashPartInfo known_devices[] = {
>      { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
>      { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
>      { INFO_STACKED("mt25qu01g", 0x20bb21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
> +    { INFO_STACKED("mt25qu02g", 0x20ba22, 0x1040, 64 << 10, 4096, ER_4K, 2) },
>
>      /* Spansion -- single (large) sector size only, at least
>       * for the chips listed here (without boot sectors).
> --
> 2.26.3
>
>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 17/24] aspeed: Remove swift-bmc machine
  2021-04-07 17:16 ` [PATCH 17/24] aspeed: Remove swift-bmc machine Cédric Le Goater
@ 2021-04-07 18:13   ` Adriana Kobylak
  2021-04-07 18:29   ` Peter Maydell
  1 sibling, 0 replies; 50+ messages in thread
From: Adriana Kobylak @ 2021-04-07 18:13 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Peter Maydell, Andrew Jeffery, Adriana Kobylak, qemu-devel,
	qemu-arm, Joel Stanley

[-- Attachment #1: Type: text/plain, Size: 5277 bytes --]



"Cédric Le Goater" <clg@kaod.org> wrote on 04/07/2021 12:16:30 PM:

> From: "Cédric Le Goater" <clg@kaod.org>
> To: "Peter Maydell" <peter.maydell@linaro.org>
> Cc: "Andrew Jeffery" <andrew@aj.id.au>, "Joel Stanley"
> <joel@jms.id.au>, qemu-arm@nongnu.org, qemu-devel@nongnu.org,
> "Cédric Le Goater" <clg@kaod.org>, Adriana Kobylak/Austin/IBM@IBM
> Date: 04/07/2021 12:16 PM
> Subject: [PATCH 17/24] aspeed: Remove swift-bmc machine
>
> The SWIFT machine never came out of the lab and we already have enough
> AST2500 based OpenPower machines. Remove it.
>
> Cc: Adriana Kobylak <anoo@us.ibm.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Adriana Kobylak <anoo@us.ibm.com>

> ---
>  hw/arm/aspeed.c | 61 -------------------------------------------------
>  1 file changed, 61 deletions(-)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 1cf5a15c8098..97dcca74feb4 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -110,17 +110,6 @@ struct AspeedMachineState {
>          SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) |
\
>          SCU_AST2500_HW_STRAP_RESERVED1)
>
> -/* Swift hardware value: 0xF11AD206 */
> -#define SWIFT_BMC_HW_STRAP1
(                                           \
> -        AST2500_HW_STRAP1_DEFAULTS |
\
> -        SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE |
\
> -        SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE |
\
> -        SCU_AST2500_HW_STRAP_UART_DEBUG |
\
> -        SCU_AST2500_HW_STRAP_DDR4_ENABLE |
\
> -        SCU_H_PLL_BYPASS_EN |
\
> -        SCU_AST2500_HW_STRAP_ACPI_ENABLE |
\
> -        SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
> -
>  #define G220A_BMC_HW_STRAP1 (                                      \
>          SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE |
\
>          SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE |
\
> @@ -465,35 +454,6 @@ static void romulus_bmc_i2c_init(AspeedMachineState
*bmc)
>      i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 11),
> "ds1338", 0x32);
>  }
>
> -static void swift_bmc_i2c_init(AspeedMachineState *bmc)
> -{
> -    AspeedSoCState *soc = &bmc->soc;
> -
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 3),
> "pca9552", 0x60);
> -
> -    /* The swift board expects a TMP275 but a TMP105 is compatible */
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7),
> "tmp105", 0x48);
> -    /* The swift board expects a pca9551 but a pca9552 is compatible */
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 7),
> "pca9552", 0x60);
> -
> -    /* The swift board expects an Epson RX8900 RTC but a ds1338 is
> compatible */
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8),
> "ds1338", 0x32);
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 8),
> "pca9552", 0x60);
> -
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9),
> "tmp423", 0x4c);
> -    /* The swift board expects a pca9539 but a pca9552 is compatible */
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 9),
> "pca9552", 0x74);
> -
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10),
> "tmp423", 0x4c);
> -    /* The swift board expects a pca9539 but a pca9552 is compatible */
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 10),
"pca9552",
> -                     0x74);
> -
> -    /* The swift board expects a TMP275 but a TMP105 is compatible */
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 12),
> "tmp105", 0x48);
> -    i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 12),
> "tmp105", 0x4a);
> -}
> -
>  static void sonorapass_bmc_i2c_init(AspeedMachineState *bmc)
>  {
>      AspeedSoCState *soc = &bmc->soc;
> @@ -796,23 +756,6 @@ static void
> aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data)
>          aspeed_soc_num_cpus(amc->soc_name);
>  };
>
> -static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
> -{
> -    MachineClass *mc = MACHINE_CLASS(oc);
> -    AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
> -
> -    mc->desc       = "OpenPOWER Swift BMC (ARM1176)";
> -    amc->soc_name  = "ast2500-a1";
> -    amc->hw_strap1 = SWIFT_BMC_HW_STRAP1;
> -    amc->fmc_model = "mx66l1g45g";
> -    amc->spi_model = "mx66l1g45g";
> -    amc->num_cs    = 2;
> -    amc->i2c_init  = swift_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 void aspeed_machine_witherspoon_class_init(ObjectClass *oc,
> void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
> @@ -903,10 +846,6 @@ static const TypeInfo aspeed_machine_types[] = {
>          .name          = MACHINE_TYPE_NAME("romulus-bmc"),
>          .parent        = TYPE_ASPEED_MACHINE,
>          .class_init    = aspeed_machine_romulus_class_init,
> -    }, {
> -        .name          = MACHINE_TYPE_NAME("swift-bmc"),
> -        .parent        = TYPE_ASPEED_MACHINE,
> -        .class_init    = aspeed_machine_swift_class_init,
>      }, {
>          .name          = MACHINE_TYPE_NAME("sonorapass-bmc"),
>          .parent        = TYPE_ASPEED_MACHINE,
> --
> 2.26.3
>

[-- Attachment #2: Type: text/html, Size: 9022 bytes --]

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 17/24] aspeed: Remove swift-bmc machine
  2021-04-07 17:16 ` [PATCH 17/24] aspeed: Remove swift-bmc machine Cédric Le Goater
  2021-04-07 18:13   ` Adriana Kobylak
@ 2021-04-07 18:29   ` Peter Maydell
  2021-04-08  7:40     ` Cédric Le Goater
  1 sibling, 1 reply; 50+ messages in thread
From: Peter Maydell @ 2021-04-07 18:29 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Andrew Jeffery, qemu-arm, Joel Stanley, Adriana Kobylak, QEMU Developers

On Wed, 7 Apr 2021 at 18:17, Cédric Le Goater <clg@kaod.org> wrote:
>
> The SWIFT machine never came out of the lab and we already have enough
> AST2500 based OpenPower machines. Remove it.
>
> Cc: Adriana Kobylak <anoo@us.ibm.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

We've had QEMU releases with this machine in them, right?
If so, then we need to go through the usual deprecate-and-delete
cycle, we can't just drop it immediately.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 12/24] tests/acceptance: Test ast2600 machine
  2021-04-07 17:16 ` [PATCH 12/24] tests/acceptance: Test ast2600 machine Cédric Le Goater
@ 2021-04-07 18:36   ` Willian Rampazzo
  0 siblings, 0 replies; 50+ messages in thread
From: Willian Rampazzo @ 2021-04-07 18:36 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Peter Maydell, Andrew Jeffery, qemu-devel,
	Wainer dos Santos Moschetta, qemu-arm, Joel Stanley, Cleber Rosa

On Wed, Apr 7, 2021 at 2:45 PM Cédric Le Goater <clg@kaod.org> wrote:
>
> From: Joel Stanley <joel@jms.id.au>
>
> This tests a Debian multi-soc arm32 Linux kernel on the AST2600 based
> Tacoma BMC machine.
>
> There is no root file system so the test terminates when boot reaches
> the stage where it attempts and fails to mount something.
>
> Cc: Cleber Rosa <crosa@redhat.com>
> Cc: Wainer dos Santos Moschetta <wainersm@redhat.com>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> Tested-by: Cédric Le Goater <clg@kaod.org>
> [ clg : - removed comment
>         - removed ending self.vm.shutdown() ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> Message-Id: <20210304123951.163411-3-joel@jms.id.au>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  tests/acceptance/boot_linux_console.py | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>

Reviewed-by: Willian Rampazzo <willianr@redhat.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 11/24] tests/acceptance: Test ast2400 and ast2500 machines
  2021-04-07 17:16 ` [PATCH 11/24] tests/acceptance: Test ast2400 and ast2500 machines Cédric Le Goater
@ 2021-04-07 18:40   ` Willian Rampazzo
  0 siblings, 0 replies; 50+ messages in thread
From: Willian Rampazzo @ 2021-04-07 18:40 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Peter Maydell, Andrew Jeffery, qemu-devel,
	Wainer dos Santos Moschetta, qemu-arm, Joel Stanley, Cleber Rosa

On Wed, Apr 7, 2021 at 2:33 PM Cédric Le Goater <clg@kaod.org> wrote:
>
> From: Joel Stanley <joel@jms.id.au>
>
> Test MTD images from the OpenBMC project on AST2400 and AST2500 SoCs
> from ASPEED, by booting Palmetto and Romulus BMC machines.
>
> The images are fetched from OpenBMC's release directory on github.
>
> Cc: Cleber Rosa <crosa@redhat.com>
> Cc: Wainer dos Santos Moschetta <wainersm@redhat.com>
> Co-developed-by: Cédric Le Goater <clg@kaod.org>
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> Tested-by: Cédric Le Goater <clg@kaod.org>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> Reviewed-by: Cleber Rosa <crosa@redhat.com>
> Tested-by: Cleber Rosa <crosa@redhat.com>
> [ clg : - removed comment
>         - removed ending self.vm.shutdown() ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> Message-Id: <20210304123951.163411-2-joel@jms.id.au>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
>

Reviewed-by: Willian Rampazzo <willianr@redhat.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 07/24] aspeed: Integrate HACE
  2021-04-07 17:16 ` [PATCH 07/24] aspeed: Integrate HACE Cédric Le Goater
@ 2021-04-07 19:22   ` Klaus Heinrich Kiwi
  0 siblings, 0 replies; 50+ messages in thread
From: Klaus Heinrich Kiwi @ 2021-04-07 19:22 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, Joel Stanley,
	Philippe Mathieu-Daudé,
	qemu-devel



On 4/7/2021 2:16 PM, Cédric Le Goater wrote:
> From: Joel Stanley <joel@jms.id.au>
> 
> Add the hash and crypto engine model to the Aspeed socs.
> 
> Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Message-Id: <20210324070955.125941-3-joel@jms.id.au>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>

> ---
>   docs/system/arm/aspeed.rst  |  2 +-
>   include/hw/arm/aspeed_soc.h |  3 +++
>   hw/arm/aspeed_ast2600.c     | 15 +++++++++++++++
>   hw/arm/aspeed_soc.c         | 16 ++++++++++++++++
>   4 files changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
> index d1fb8f25b39c..f9466e6d8245 100644
> --- a/docs/system/arm/aspeed.rst
> +++ b/docs/system/arm/aspeed.rst
> @@ -49,6 +49,7 @@ Supported devices
>    * Ethernet controllers
>    * Front LEDs (PCA9552 on I2C bus)
>    * LPC Peripheral Controller (a subset of subdevices are supported)
> + * Hash/Crypto Engine (HACE) - Hash support only, no scatter-gather
>   
>   
>   Missing devices
> @@ -59,7 +60,6 @@ Missing devices
>    * PWM and Fan Controller
>    * Slave GPIO Controller
>    * Super I/O Controller
> - * Hash/Crypto Engine
>    * PCI-Express 1 Controller
>    * Graphic Display Controller
>    * PECI Controller
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index 9359d6da336d..d9161d26d645 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -21,6 +21,7 @@
>   #include "hw/rtc/aspeed_rtc.h"
>   #include "hw/i2c/aspeed_i2c.h"
>   #include "hw/ssi/aspeed_smc.h"
> +#include "hw/misc/aspeed_hace.h"
>   #include "hw/watchdog/wdt_aspeed.h"
>   #include "hw/net/ftgmac100.h"
>   #include "target/arm/cpu.h"
> @@ -50,6 +51,7 @@ struct AspeedSoCState {
>       AspeedTimerCtrlState timerctrl;
>       AspeedI2CState i2c;
>       AspeedSCUState scu;
> +    AspeedHACEState hace;
>       AspeedXDMAState xdma;
>       AspeedSMCState fmc;
>       AspeedSMCState spi[ASPEED_SPIS_NUM];
> @@ -133,6 +135,7 @@ enum {
>       ASPEED_DEV_XDMA,
>       ASPEED_DEV_EMMC,
>       ASPEED_DEV_KCS,
> +    ASPEED_DEV_HACE,
>   };
>   
>   #endif /* ASPEED_SOC_H */
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index 2a1255b6a042..e0fbb020c770 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -42,6 +42,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
>       [ASPEED_DEV_ETH2]      = 0x1E680000,
>       [ASPEED_DEV_ETH4]      = 0x1E690000,
>       [ASPEED_DEV_VIC]       = 0x1E6C0000,
> +    [ASPEED_DEV_HACE]      = 0x1E6D0000,
>       [ASPEED_DEV_SDMC]      = 0x1E6E0000,
>       [ASPEED_DEV_SCU]       = 0x1E6E2000,
>       [ASPEED_DEV_XDMA]      = 0x1E6E7000,
> @@ -102,6 +103,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
>       [ASPEED_DEV_I2C]       = 110,   /* 110 -> 125 */
>       [ASPEED_DEV_ETH1]      = 2,
>       [ASPEED_DEV_ETH2]      = 3,
> +    [ASPEED_DEV_HACE]      = 4,
>       [ASPEED_DEV_ETH3]      = 32,
>       [ASPEED_DEV_ETH4]      = 33,
>       [ASPEED_DEV_KCS]       = 138,   /* 138 -> 142 */
> @@ -213,6 +215,9 @@ static void aspeed_soc_ast2600_init(Object *obj)
>                               TYPE_SYSBUS_SDHCI);
>   
>       object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
> +
> +    snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
> +    object_initialize_child(obj, "hace", &s->hace, typename);
>   }
>   
>   /*
> @@ -494,6 +499,16 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
>       sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4,
>                          qdev_get_gpio_in(DEVICE(&s->a7mpcore),
>                                   sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4));
> +
> +    /* HACE */
> +    object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr),
> +                             &error_abort);
> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
> +                       aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
>   }
>   
>   static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 817f3ba63dfd..8ed29113f79f 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -34,6 +34,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
>       [ASPEED_DEV_VIC]    = 0x1E6C0000,
>       [ASPEED_DEV_SDMC]   = 0x1E6E0000,
>       [ASPEED_DEV_SCU]    = 0x1E6E2000,
> +    [ASPEED_DEV_HACE]   = 0x1E6E3000,
>       [ASPEED_DEV_XDMA]   = 0x1E6E7000,
>       [ASPEED_DEV_VIDEO]  = 0x1E700000,
>       [ASPEED_DEV_ADC]    = 0x1E6E9000,
> @@ -65,6 +66,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
>       [ASPEED_DEV_VIC]    = 0x1E6C0000,
>       [ASPEED_DEV_SDMC]   = 0x1E6E0000,
>       [ASPEED_DEV_SCU]    = 0x1E6E2000,
> +    [ASPEED_DEV_HACE]   = 0x1E6E3000,
>       [ASPEED_DEV_XDMA]   = 0x1E6E7000,
>       [ASPEED_DEV_ADC]    = 0x1E6E9000,
>       [ASPEED_DEV_VIDEO]  = 0x1E700000,
> @@ -117,6 +119,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
>       [ASPEED_DEV_ETH2]   = 3,
>       [ASPEED_DEV_XDMA]   = 6,
>       [ASPEED_DEV_SDHCI]  = 26,
> +    [ASPEED_DEV_HACE]   = 4,
>   };
>   
>   #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
> @@ -212,6 +215,9 @@ static void aspeed_soc_init(Object *obj)
>       }
>   
>       object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
> +
> +    snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
> +    object_initialize_child(obj, "hace", &s->hace, typename);
>   }
>   
>   static void aspeed_soc_realize(DeviceState *dev, Error **errp)
> @@ -421,6 +427,16 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
>   
>       sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4,
>                          qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_4));
> +
> +    /* HACE */
> +    object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr),
> +                             &error_abort);
> +    if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
> +        return;
> +    }
> +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
> +    sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
> +                       aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
>   }
>   static Property aspeed_soc_properties[] = {
>       DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
> 

-- 
Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 06/24] hw: Model ASPEED's Hash and Crypto Engine
  2021-04-07 17:16 ` [PATCH 06/24] hw: Model ASPEED's Hash and Crypto Engine Cédric Le Goater
@ 2021-04-07 19:31   ` Klaus Heinrich Kiwi
  0 siblings, 0 replies; 50+ messages in thread
From: Klaus Heinrich Kiwi @ 2021-04-07 19:31 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, Joel Stanley,
	Philippe Mathieu-Daudé,
	qemu-devel



On 4/7/2021 2:16 PM, Cédric Le Goater wrote:
> From: Joel Stanley <joel@jms.id.au>
> 
> The HACE (Hash and Crypto Engine) is a device that offloads MD5, SHA1,
> SHA2, RSA and other cryptographic algorithms.
> 
> This initial model implements a subset of the device's functionality;
> currently only direct access (non-scatter gather) hashing.

> +
> +static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
> +                              unsigned int size)
> +{
> +    AspeedHACEState *s = ASPEED_HACE(opaque);
> +    AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s);
> +
> +    addr >>= 2;
> +
> +    if (addr >= ASPEED_HACE_NR_REGS) {
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
> +                      __func__, addr << 2);
> +        return;
> +    }
> +
> +    switch (addr) {
> +    case R_STATUS:
> +        if (data & HASH_IRQ) {
> +            data &= ~HASH_IRQ;
> +
> +            if (s->regs[addr] & HASH_IRQ) {
> +                qemu_irq_lower(s->irq);
> +            }
> +        }
> +        break;
> +    case R_HASH_SRC:
> +        data &= ahc->src_mask;
> +        break;
> +    case R_HASH_DEST:
> +        data &= ahc->dest_mask;
> +        break;
> +    case R_HASH_SRC_LEN:
> +        data &= 0x0FFFFFFF;
> +        break;
> +    case R_HASH_CMD: {
> +        int algo = -1;
> +        if ((data & HASH_HMAC_MASK)) {
> +            qemu_log_mask(LOG_UNIMP,
> +                          "%s: HMAC engine command mode %"PRIx64" not implemented",
> +                          __func__, (data & HASH_HMAC_MASK) >> 8);
> +        }
> +        if (data & HASH_SG_EN) {
> +            qemu_log_mask(LOG_UNIMP,
> +                          "%s: Hash scatter gather mode not implemented",
> +                          __func__);
> +        }
> +        if (data & BIT(1)) {
> +            qemu_log_mask(LOG_UNIMP,
> +                          "%s: Cascaded mode not implemented",
> +                          __func__);
> +       if the guest is requesting a command that is not implemented, wouldn't it be safer to bail out
and return instead of just logging and continue?


  -Klaus

-- 
Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 08/24] tests/qtest: Add test for Aspeed HACE
  2021-04-07 17:16 ` [PATCH 08/24] tests/qtest: Add test for Aspeed HACE Cédric Le Goater
@ 2021-04-07 19:33   ` Klaus Heinrich Kiwi
  0 siblings, 0 replies; 50+ messages in thread
From: Klaus Heinrich Kiwi @ 2021-04-07 19:33 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell
  Cc: Andrew Jeffery, Thomas Huth, qemu-arm, qemu-devel, Joel Stanley



On 4/7/2021 2:16 PM, Cédric Le Goater wrote:
> From: Joel Stanley <joel@jms.id.au>
> 
> This adds a test for the Aspeed Hash and Crypto (HACE) engine. It tests
> the currently implemented behavior of the hash functionality.
> 
> The tests are similar, but are cut/pasted instead of broken out into a
> common function so the assert machinery produces useful output when a
> test fails.
> 
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> Reviewed-by: Cédric Le Goater <clg@kaod.org>
> Acked-by: Thomas Huth <thuth@redhat.com>
> [ clg: - qtest_quit() fix ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> Message-Id: <20210324070955.125941-4-joel@jms.id.au>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>

> ---
>   tests/qtest/aspeed_hace-test.c | 321 +++++++++++++++++++++++++++++++++
>   MAINTAINERS                    |   1 +
>   tests/qtest/meson.build        |   3 +
>   3 files changed, 325 insertions(+)
>   create mode 100644 tests/qtest/aspeed_hace-test.c
> 
> diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
> new file mode 100644
> index 000000000000..675774e96eb9
> --- /dev/null
> +++ b/tests/qtest/aspeed_hace-test.c
> @@ -0,0 +1,321 @@
> +/*
> + * QTest testcase for the ASPEED Hash and Crypto Engine
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + * Copyright 2021 IBM Corp.
> + */
> +
> +#include "qemu/osdep.h"
> +
> +#include "libqos/libqtest.h"
> +#include "qemu-common.h"
> +#include "qemu/bitops.h"
> +
> +#define HACE_CMD                 0x10
> +#define  HACE_SHA_BE_EN          BIT(3)
> +#define  HACE_MD5_LE_EN          BIT(2)
> +#define  HACE_ALGO_MD5           0
> +#define  HACE_ALGO_SHA1          BIT(5)
> +#define  HACE_ALGO_SHA224        BIT(6)
> +#define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
> +#define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
> +#define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
> +#define  HACE_SG_EN              BIT(18)
> +
> +#define HACE_STS                 0x1c
> +#define  HACE_RSA_ISR            BIT(13)
> +#define  HACE_CRYPTO_ISR         BIT(12)
> +#define  HACE_HASH_ISR           BIT(9)
> +#define  HACE_RSA_BUSY           BIT(2)
> +#define  HACE_CRYPTO_BUSY        BIT(1)
> +#define  HACE_HASH_BUSY          BIT(0)
> +#define HACE_HASH_SRC            0x20
> +#define HACE_HASH_DIGEST         0x24
> +#define HACE_HASH_KEY_BUFF       0x28
> +#define HACE_HASH_DATA_LEN       0x2c
> +#define HACE_HASH_CMD            0x30
> +
> +/*
> + * Test vector is the ascii "abc"
> + *
> + * Expected results were generated using command line utitiles:
> + *
> + *  echo -n -e 'abc' | dd of=/tmp/test
> + *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
> + *
> + */
> +static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
> +
> +static const uint8_t test_result_sha512[] = {
> +    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> +    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> +    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
> +    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> +    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> +    0xa5, 0x4c, 0xa4, 0x9f};
> +
> +static const uint8_t test_result_sha256[] = {
> +    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> +    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> +    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> +
> +static const uint8_t test_result_md5[] = {
> +    0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
> +    0x28, 0xe1, 0x7f, 0x72};
> +
> +
> +static void write_regs(QTestState *s, uint32_t base, uint32_t src,
> +                       uint32_t length, uint32_t out, uint32_t method)
> +{
> +        qtest_writel(s, base + HACE_HASH_SRC, src);
> +        qtest_writel(s, base + HACE_HASH_DIGEST, out);
> +        qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
> +        qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
> +}
> +
> +static void test_md5(const char *machine, const uint32_t base,
> +                     const uint32_t src_addr)
> +
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    uint32_t digest_addr = src_addr + 0x01000000;
> +    uint8_t digest[16] = {0};
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_MD5);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_md5, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +static void test_sha256(const char *machine, const uint32_t base,
> +                        const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t digest_addr = src_addr + 0x1000000;
> +    uint8_t digest[32] = {0};
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA256);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_sha256, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +static void test_sha512(const char *machine, const uint32_t base,
> +                        const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t digest_addr = src_addr + 0x1000000;
> +    uint8_t digest[64] = {0};
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA512);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_sha512, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +struct masks {
> +    uint32_t src;
> +    uint32_t dest;
> +    uint32_t len;
> +};
> +
> +static const struct masks ast2600_masks = {
> +    .src  = 0x7fffffff,
> +    .dest = 0x7ffffff8,
> +    .len  = 0x0fffffff,
> +};
> +
> +static const struct masks ast2500_masks = {
> +    .src  = 0x3fffffff,
> +    .dest = 0x3ffffff8,
> +    .len  = 0x0fffffff,
> +};
> +
> +static const struct masks ast2400_masks = {
> +    .src  = 0x0fffffff,
> +    .dest = 0x0ffffff8,
> +    .len  = 0x0fffffff,
> +};
> +
> +static void test_addresses(const char *machine, const uint32_t base,
> +                           const struct masks *expected)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    /*
> +     * Check command mode is zero, meaning engine is in direct access mode,
> +     * as this affects the masking behavior of the HASH_SRC register.
> +     */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
> +
> +
> +    /* Check that the address masking is correct */
> +    qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
> +
> +    qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, expected->dest);
> +
> +    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, expected->len);
> +
> +    /* Reset to zero */
> +    qtest_writel(s, base + HACE_HASH_SRC, 0);
> +    qtest_writel(s, base + HACE_HASH_DIGEST, 0);
> +    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
> +
> +    /* Check that all bits are now zero */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
> +
> +    qtest_quit(s);
> +}
> +
> +/* ast2600 */
> +static void test_md5_ast2600(void)
> +{
> +    test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +}
> +
> +static void test_sha256_ast2600(void)
> +{
> +    test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +}
> +
> +static void test_sha512_ast2600(void)
> +{
> +    test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +}
> +
> +static void test_addresses_ast2600(void)
> +{
> +    test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
> +}
> +
> +/* ast2500 */
> +static void test_md5_ast2500(void)
> +{
> +    test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> +}
> +
> +static void test_sha256_ast2500(void)
> +{
> +    test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> +}
> +
> +static void test_sha512_ast2500(void)
> +{
> +    test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> +}
> +
> +static void test_addresses_ast2500(void)
> +{
> +    test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
> +}
> +
> +/* ast2400 */
> +static void test_md5_ast2400(void)
> +{
> +    test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> +}
> +
> +static void test_sha256_ast2400(void)
> +{
> +    test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> +}
> +
> +static void test_sha512_ast2400(void)
> +{
> +    test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> +}
> +
> +static void test_addresses_ast2400(void)
> +{
> +    test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    g_test_init(&argc, &argv, NULL);
> +
> +    qtest_add_func("ast2600/hace/addresses", test_addresses_ast2600);
> +    qtest_add_func("ast2600/hace/sha512", test_sha512_ast2600);
> +    qtest_add_func("ast2600/hace/sha256", test_sha256_ast2600);
> +    qtest_add_func("ast2600/hace/md5", test_md5_ast2600);
> +
> +    qtest_add_func("ast2500/hace/addresses", test_addresses_ast2500);
> +    qtest_add_func("ast2500/hace/sha512", test_sha512_ast2500);
> +    qtest_add_func("ast2500/hace/sha256", test_sha256_ast2500);
> +    qtest_add_func("ast2500/hace/md5", test_md5_ast2500);
> +
> +    qtest_add_func("ast2400/hace/addresses", test_addresses_ast2400);
> +    qtest_add_func("ast2400/hace/sha512", test_sha512_ast2400);
> +    qtest_add_func("ast2400/hace/sha256", test_sha256_ast2400);
> +    qtest_add_func("ast2400/hace/md5", test_md5_ast2400);
> +
> +    return g_test_run();
> +}
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 58f342108e9e..63c050ddc84a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1026,6 +1026,7 @@ F: include/hw/misc/pca9552*.h
>   F: hw/net/ftgmac100.c
>   F: include/hw/net/ftgmac100.h
>   F: docs/system/arm/aspeed.rst
> +F: tests/qtest/*aspeed*
>   
>   NRF51
>   M: Joel Stanley <joel@jms.id.au>
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 902cfef7cb2f..84b3219c15c6 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -163,12 +163,15 @@ qtests_npcm7xx = \
>      'npcm7xx_timer-test',
>      'npcm7xx_watchdog_timer-test'] + \
>      (slirp.found() ? ['npcm7xx_emc-test'] : [])
> +qtests_aspeed = \
> +  ['aspeed_hace-test']
>   qtests_arm = \
>     (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
>     (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
>     (config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
>     (config_all_devices.has_key('CONFIG_CMSDK_APB_WATCHDOG') ? ['cmsdk-apb-watchdog-test'] : []) + \
>     (config_all_devices.has_key('CONFIG_PFLASH_CFI02') ? ['pflash-cfi02-test'] : []) +         \
> +  (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \
>     (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
>     ['arm-cpu-features',
>      'microbit-test',
> 

-- 
Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 13/24] hw/misc/aspeed_xdma: Add AST2600 support
  2021-04-07 17:16 ` [PATCH 13/24] hw/misc/aspeed_xdma: Add AST2600 support Cédric Le Goater
@ 2021-04-07 20:29   ` Eddie James
  0 siblings, 0 replies; 50+ messages in thread
From: Eddie James @ 2021-04-07 20:29 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, Joel Stanley, qemu-devel

On Wed, 2021-04-07 at 19:16 +0200, Cédric Le Goater wrote:
> When we introduced support for the AST2600 SoC, the XDMA controller
> was forgotten. It went unnoticed because it's not used under
> emulation.
> But the register layout being different, the reset procedure is bogus
> and this breaks kexec.
> 
> Add a AspeedXDMAClass to take into account the register differences.

Thanks Cedric!

Reviewed-by: Eddie James <eajames@linux.ibm.com>

> 
> Cc: Eddie James <eajames@linux.ibm.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  include/hw/misc/aspeed_xdma.h |  17 ++++-
>  hw/arm/aspeed_ast2600.c       |   3 +-
>  hw/arm/aspeed_soc.c           |   3 +-
>  hw/misc/aspeed_xdma.c         | 124 +++++++++++++++++++++++++++-----
> --
>  4 files changed, 121 insertions(+), 26 deletions(-)
> 
> diff --git a/include/hw/misc/aspeed_xdma.h
> b/include/hw/misc/aspeed_xdma.h
> index a2dea96984f3..b1478fd1c681 100644
> --- a/include/hw/misc/aspeed_xdma.h
> +++ b/include/hw/misc/aspeed_xdma.h
> @@ -13,7 +13,10 @@
>  #include "qom/object.h"
>  
>  #define TYPE_ASPEED_XDMA "aspeed.xdma"
> -OBJECT_DECLARE_SIMPLE_TYPE(AspeedXDMAState, ASPEED_XDMA)
> +#define TYPE_ASPEED_2400_XDMA TYPE_ASPEED_XDMA "-ast2400"
> +#define TYPE_ASPEED_2500_XDMA TYPE_ASPEED_XDMA "-ast2500"
> +#define TYPE_ASPEED_2600_XDMA TYPE_ASPEED_XDMA "-ast2600"
> +OBJECT_DECLARE_TYPE(AspeedXDMAState, AspeedXDMAClass, ASPEED_XDMA)
>  
>  #define ASPEED_XDMA_NUM_REGS (ASPEED_XDMA_REG_SIZE /
> sizeof(uint32_t))
>  #define ASPEED_XDMA_REG_SIZE 0x7C
> @@ -28,4 +31,16 @@ struct AspeedXDMAState {
>      uint32_t regs[ASPEED_XDMA_NUM_REGS];
>  };
>  
> +struct AspeedXDMAClass {
> +    SysBusDeviceClass parent_class;
> +
> +    uint8_t cmdq_endp;
> +    uint8_t cmdq_wrp;
> +    uint8_t cmdq_rdp;
> +    uint8_t intr_ctrl;
> +    uint32_t intr_ctrl_mask;
> +    uint8_t intr_status;
> +    uint32_t intr_complete;
> +};
> +
>  #endif /* ASPEED_XDMA_H */
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index e0fbb020c770..c60824bfeecb 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -187,7 +187,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
>          object_initialize_child(obj, "mii[*]", &s->mii[i],
> TYPE_ASPEED_MII);
>      }
>  
> -    object_initialize_child(obj, "xdma", &s->xdma,
> TYPE_ASPEED_XDMA);
> +    snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s",
> socname);
> +    object_initialize_child(obj, "xdma", &s->xdma, typename);
>  
>      snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
>      object_initialize_child(obj, "gpio", &s->gpio, typename);
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 8ed29113f79f..4a95d27d9d63 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -199,7 +199,8 @@ static void aspeed_soc_init(Object *obj)
>                                  TYPE_FTGMAC100);
>      }
>  
> -    object_initialize_child(obj, "xdma", &s->xdma,
> TYPE_ASPEED_XDMA);
> +    snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s",
> socname);
> +    object_initialize_child(obj, "xdma", &s->xdma, typename);
>  
>      snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
>      object_initialize_child(obj, "gpio", &s->gpio, typename);
> diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c
> index 533d237e3ce2..1c21577c98c9 100644
> --- a/hw/misc/aspeed_xdma.c
> +++ b/hw/misc/aspeed_xdma.c
> @@ -30,6 +30,19 @@
>  #define  XDMA_IRQ_ENG_STAT_US_COMP BIT(4)
>  #define  XDMA_IRQ_ENG_STAT_DS_COMP BIT(5)
>  #define  XDMA_IRQ_ENG_STAT_RESET   0xF8000000
> +
> +#define XDMA_AST2600_BMC_CMDQ_ADDR   0x14
> +#define XDMA_AST2600_BMC_CMDQ_ENDP   0x18
> +#define XDMA_AST2600_BMC_CMDQ_WRP    0x1c
> +#define XDMA_AST2600_BMC_CMDQ_RDP    0x20
> +#define XDMA_AST2600_IRQ_CTRL        0x38
> +#define  XDMA_AST2600_IRQ_CTRL_US_COMP    BIT(16)
> +#define  XDMA_AST2600_IRQ_CTRL_DS_COMP    BIT(17)
> +#define  XDMA_AST2600_IRQ_CTRL_W_MASK     0x017003FF
> +#define XDMA_AST2600_IRQ_STATUS      0x3c
> +#define  XDMA_AST2600_IRQ_STATUS_US_COMP  BIT(16)
> +#define  XDMA_AST2600_IRQ_STATUS_DS_COMP  BIT(17)
> +
>  #define XDMA_MEM_SIZE              0x1000
>  
>  #define TO_REG(addr) ((addr) / sizeof(uint32_t))
> @@ -52,56 +65,48 @@ static void aspeed_xdma_write(void *opaque,
> hwaddr addr, uint64_t val,
>      unsigned int idx;
>      uint32_t val32 = (uint32_t)val;
>      AspeedXDMAState *xdma = opaque;
> +    AspeedXDMAClass *axc = ASPEED_XDMA_GET_CLASS(xdma);
>  
>      if (addr >= ASPEED_XDMA_REG_SIZE) {
>          return;
>      }
>  
> -    switch (addr) {
> -    case XDMA_BMC_CMDQ_ENDP:
> +    if (addr == axc->cmdq_endp) {
>          xdma->regs[TO_REG(addr)] = val32 & XDMA_BMC_CMDQ_W_MASK;
> -        break;
> -    case XDMA_BMC_CMDQ_WRP:
> +    } else if (addr == axc->cmdq_wrp) {
>          idx = TO_REG(addr);
>          xdma->regs[idx] = val32 & XDMA_BMC_CMDQ_W_MASK;
> -        xdma->regs[TO_REG(XDMA_BMC_CMDQ_RDP)] = xdma->regs[idx];
> +        xdma->regs[TO_REG(axc->cmdq_rdp)] = xdma->regs[idx];
>  
>          trace_aspeed_xdma_write(addr, val);
>  
>          if (xdma->bmc_cmdq_readp_set) {
>              xdma->bmc_cmdq_readp_set = 0;
>          } else {
> -            xdma->regs[TO_REG(XDMA_IRQ_ENG_STAT)] |=
> -                XDMA_IRQ_ENG_STAT_US_COMP |
> XDMA_IRQ_ENG_STAT_DS_COMP;
> +            xdma->regs[TO_REG(axc->intr_status)] |= axc-
> >intr_complete;
>  
> -            if (xdma->regs[TO_REG(XDMA_IRQ_ENG_CTRL)] &
> -                (XDMA_IRQ_ENG_CTRL_US_COMP |
> XDMA_IRQ_ENG_CTRL_DS_COMP))
> +            if (xdma->regs[TO_REG(axc->intr_ctrl)] & axc-
> >intr_complete) {
>                  qemu_irq_raise(xdma->irq);
> +            }
>          }
> -        break;
> -    case XDMA_BMC_CMDQ_RDP:
> +    } else if (addr == axc->cmdq_rdp) {
>          trace_aspeed_xdma_write(addr, val);
>  
>          if (val32 == XDMA_BMC_CMDQ_RDP_MAGIC) {
>              xdma->bmc_cmdq_readp_set = 1;
>          }
> -        break;
> -    case XDMA_IRQ_ENG_CTRL:
> -        xdma->regs[TO_REG(addr)] = val32 & XDMA_IRQ_ENG_CTRL_W_MASK;
> -        break;
> -    case XDMA_IRQ_ENG_STAT:
> +    } else if (addr == axc->intr_ctrl) {
> +        xdma->regs[TO_REG(addr)] = val32 & axc->intr_ctrl_mask;
> +    } else if (addr == axc->intr_status) {
>          trace_aspeed_xdma_write(addr, val);
>  
>          idx = TO_REG(addr);
> -        if (val32 & (XDMA_IRQ_ENG_STAT_US_COMP |
> XDMA_IRQ_ENG_STAT_DS_COMP)) {
> -            xdma->regs[idx] &=
> -                ~(XDMA_IRQ_ENG_STAT_US_COMP |
> XDMA_IRQ_ENG_STAT_DS_COMP);
> +        if (val32 & axc->intr_complete) {
> +            xdma->regs[idx] &= ~axc->intr_complete;
>              qemu_irq_lower(xdma->irq);
>          }
> -        break;
> -    default:
> +    } else {
>          xdma->regs[TO_REG(addr)] = val32;
> -        break;
>      }
>  }
>  
> @@ -127,10 +132,11 @@ static void aspeed_xdma_realize(DeviceState
> *dev, Error **errp)
>  static void aspeed_xdma_reset(DeviceState *dev)
>  {
>      AspeedXDMAState *xdma = ASPEED_XDMA(dev);
> +    AspeedXDMAClass *axc = ASPEED_XDMA_GET_CLASS(xdma);
>  
>      xdma->bmc_cmdq_readp_set = 0;
>      memset(xdma->regs, 0, ASPEED_XDMA_REG_SIZE);
> -    xdma->regs[TO_REG(XDMA_IRQ_ENG_STAT)] = XDMA_IRQ_ENG_STAT_RESET;
> +    xdma->regs[TO_REG(axc->intr_status)] = XDMA_IRQ_ENG_STAT_RESET;
>  
>      qemu_irq_lower(xdma->irq);
>  }
> @@ -144,6 +150,73 @@ static const VMStateDescription
> aspeed_xdma_vmstate = {
>      },
>  };
>  
> +static void aspeed_2600_xdma_class_init(ObjectClass *klass, void
> *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass);
> +
> +    dc->desc = "ASPEED 2600 XDMA Controller";
> +
> +    axc->cmdq_endp = XDMA_AST2600_BMC_CMDQ_ENDP;
> +    axc->cmdq_wrp = XDMA_AST2600_BMC_CMDQ_WRP;
> +    axc->cmdq_rdp = XDMA_AST2600_BMC_CMDQ_RDP;
> +    axc->intr_ctrl = XDMA_AST2600_IRQ_CTRL;
> +    axc->intr_ctrl_mask = XDMA_AST2600_IRQ_CTRL_W_MASK;
> +    axc->intr_status = XDMA_AST2600_IRQ_STATUS;
> +    axc->intr_complete = XDMA_AST2600_IRQ_STATUS_US_COMP |
> +        XDMA_AST2600_IRQ_STATUS_DS_COMP;
> +}
> +
> +static const TypeInfo aspeed_2600_xdma_info = {
> +    .name = TYPE_ASPEED_2600_XDMA,
> +    .parent = TYPE_ASPEED_XDMA,
> +    .class_init = aspeed_2600_xdma_class_init,
> +};
> +
> +static void aspeed_2500_xdma_class_init(ObjectClass *klass, void
> *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass);
> +
> +    dc->desc = "ASPEED 2500 XDMA Controller";
> +
> +    axc->cmdq_endp = XDMA_BMC_CMDQ_ENDP;
> +    axc->cmdq_wrp = XDMA_BMC_CMDQ_WRP;
> +    axc->cmdq_rdp = XDMA_BMC_CMDQ_RDP;
> +    axc->intr_ctrl = XDMA_IRQ_ENG_CTRL;
> +    axc->intr_ctrl_mask = XDMA_IRQ_ENG_CTRL_W_MASK;
> +    axc->intr_status = XDMA_IRQ_ENG_STAT;
> +    axc->intr_complete = XDMA_IRQ_ENG_STAT_US_COMP |
> XDMA_IRQ_ENG_STAT_DS_COMP;
> +};
> +
> +static const TypeInfo aspeed_2500_xdma_info = {
> +    .name = TYPE_ASPEED_2500_XDMA,
> +    .parent = TYPE_ASPEED_XDMA,
> +    .class_init = aspeed_2500_xdma_class_init,
> +};
> +
> +static void aspeed_2400_xdma_class_init(ObjectClass *klass, void
> *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass);
> +
> +    dc->desc = "ASPEED 2400 XDMA Controller";
> +
> +    axc->cmdq_endp = XDMA_BMC_CMDQ_ENDP;
> +    axc->cmdq_wrp = XDMA_BMC_CMDQ_WRP;
> +    axc->cmdq_rdp = XDMA_BMC_CMDQ_RDP;
> +    axc->intr_ctrl = XDMA_IRQ_ENG_CTRL;
> +    axc->intr_ctrl_mask = XDMA_IRQ_ENG_CTRL_W_MASK;
> +    axc->intr_status = XDMA_IRQ_ENG_STAT;
> +    axc->intr_complete = XDMA_IRQ_ENG_STAT_US_COMP |
> XDMA_IRQ_ENG_STAT_DS_COMP;
> +};
> +
> +static const TypeInfo aspeed_2400_xdma_info = {
> +    .name = TYPE_ASPEED_2400_XDMA,
> +    .parent = TYPE_ASPEED_XDMA,
> +    .class_init = aspeed_2400_xdma_class_init,
> +};
> +
>  static void aspeed_xdma_class_init(ObjectClass *classp, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(classp);
> @@ -158,10 +231,15 @@ static const TypeInfo aspeed_xdma_info = {
>      .parent        = TYPE_SYS_BUS_DEVICE,
>      .instance_size = sizeof(AspeedXDMAState),
>      .class_init    = aspeed_xdma_class_init,
> +    .class_size    = sizeof(AspeedXDMAClass),
> +    .abstract      = true,
>  };
>  
>  static void aspeed_xdma_register_type(void)
>  {
>      type_register_static(&aspeed_xdma_info);
> +    type_register_static(&aspeed_2400_xdma_info);
> +    type_register_static(&aspeed_2500_xdma_info);
> +    type_register_static(&aspeed_2600_xdma_info);
>  }
>  type_init(aspeed_xdma_register_type);



^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 03/24] aspeed/i2c: Fix DMA address mask
  2021-04-07 17:16 ` [PATCH 03/24] aspeed/i2c: Fix DMA address mask Cédric Le Goater
@ 2021-04-07 21:22   ` Philippe Mathieu-Daudé
  2021-04-08  8:58     ` Cédric Le Goater
  0 siblings, 1 reply; 50+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-04-07 21:22 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, qemu-devel, Joel Stanley

Hi Cédric,

On 4/7/21 7:16 PM, Cédric Le Goater wrote:
> The RAM memory region is now used for DMAs accesses instead of the
> memory address space region. Mask off the top bits of the DMA address
> to reflect this change.
> 
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/i2c/aspeed_i2c.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
> index 518a3f5c6f9d..e7133528899f 100644
> --- a/hw/i2c/aspeed_i2c.c
> +++ b/hw/i2c/aspeed_i2c.c
> @@ -601,7 +601,7 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
>              break;
>          }
>  
> -        bus->dma_addr = value & 0xfffffffc;
> +        bus->dma_addr = value & 0x3ffffffc;

This field is migrated (aspeed_i2c_bus_vmstate).

Does the first patch "aspeed/smc: Use the RAM memory region for DMAs"
break the migration?


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 17/24] aspeed: Remove swift-bmc machine
  2021-04-07 18:29   ` Peter Maydell
@ 2021-04-08  7:40     ` Cédric Le Goater
  2021-04-08  9:05       ` Peter Maydell
  0 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-08  7:40 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, Joel Stanley, Adriana Kobylak, QEMU Developers

On 4/7/21 8:29 PM, Peter Maydell wrote:
> On Wed, 7 Apr 2021 at 18:17, Cédric Le Goater <clg@kaod.org> wrote:
>>
>> The SWIFT machine never came out of the lab and we already have enough
>> AST2500 based OpenPower machines. Remove it.
>>
>> Cc: Adriana Kobylak <anoo@us.ibm.com>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> 
> We've had QEMU releases with this machine in them, right?
> If so, then we need to go through the usual deprecate-and-delete
> cycle, we can't just drop it immediately.

You are right. Instead, I will add : 

    mc->deprecation_reason = "redundant system. Please use a similar "
        "OpenPOWER BMC, Witherspoon or Romulus.";

And we will drop the swift machine in QEMU 6.3

Thanks,

C.


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g
  2021-04-07 17:16 ` [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g Cédric Le Goater
  2021-04-07 17:36   ` Alistair Francis
@ 2021-04-08  8:00   ` Francisco Iglesias
  2021-04-08  8:40     ` Cédric Le Goater
  1 sibling, 1 reply; 50+ messages in thread
From: Francisco Iglesias @ 2021-04-08  8:00 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Peter Maydell, Andrew Jeffery, qemu-devel, qemu-arm,
	Alistair Francis, Joel Stanley

Hello Cedric!

On Wed, Apr 07, 2021 at 07:16:34PM +0200, Cédric Le Goater wrote:
> The Micron mt25qu02g is a 3V 2Gb serial NOR flash memory supporting
> dual I/O and quad I/O, 4KB, 32KB, 64KB sector erase. It also supports
> 4B opcodes.
> 
> Cc: Alistair Francis <alistair.francis@wdc.com>
> Cc: Francisco Iglesias <francisco.iglesias@xilinx.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  hw/block/m25p80.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 183d3f44c259..2afb939ae28e 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -259,6 +259,7 @@ static const FlashPartInfo known_devices[] = {
>      { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
>      { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
>      { INFO_STACKED("mt25qu01g", 0x20bb21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
> +    { INFO_STACKED("mt25qu02g", 0x20ba22, 0x1040, 64 << 10, 4096, ER_4K, 2) },

Is it possible it should be as below instead?

{ INFO_STACKED("mt25qu02g", 0x20bb22, 0x1040, 64 << 10, 4096, ER_4K | ER_32K, 2) },

's/0x20ba22/0x20bb22/' (or 's/mt25qu02g/mt25ql02g/') since 'u' looks to stand
for 1.7-2.0 V and 'bb' for 1.8 V (see page 2 and 32 in [1]).

s/ER_4K/ER_4K | ER_32K/ since ERASE_32K is supported (see page 36). 

If you find above changes ok and go with them please add:

Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>

Best regards,
Francisco Iglesias

[1] Micron Serial NOR Flash Memory 1.8V, Multiple I/O, 64KB Sector Erase MT25QU02GCBB
    https://4donline.ihs.com/images/VipMasterIC/IC/MICT/MICT-S-A0008500026/MICT-S-A0008511423-1.pdf?hkey=52A5661711E402568146F3353EA87419

>  
>      /* Spansion -- single (large) sector size only, at least
>       * for the chips listed here (without boot sectors).
> -- 
> 2.26.3
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g
  2021-04-08  8:00   ` Francisco Iglesias
@ 2021-04-08  8:40     ` Cédric Le Goater
  2021-04-08  9:21       ` Francisco Iglesias
  0 siblings, 1 reply; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-08  8:40 UTC (permalink / raw)
  To: Francisco Iglesias
  Cc: Peter Maydell, Andrew Jeffery, qemu-devel, qemu-arm,
	Alistair Francis, Joel Stanley

On 4/8/21 10:00 AM, Francisco Iglesias wrote:
> Hello Cedric!
> 
> On Wed, Apr 07, 2021 at 07:16:34PM +0200, Cédric Le Goater wrote:
>> The Micron mt25qu02g is a 3V 2Gb serial NOR flash memory supporting
>> dual I/O and quad I/O, 4KB, 32KB, 64KB sector erase. It also supports
>> 4B opcodes.
>>
>> Cc: Alistair Francis <alistair.francis@wdc.com>
>> Cc: Francisco Iglesias <francisco.iglesias@xilinx.com>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  hw/block/m25p80.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
>> index 183d3f44c259..2afb939ae28e 100644
>> --- a/hw/block/m25p80.c
>> +++ b/hw/block/m25p80.c
>> @@ -259,6 +259,7 @@ static const FlashPartInfo known_devices[] = {
>>      { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
>>      { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
>>      { INFO_STACKED("mt25qu01g", 0x20bb21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
>> +    { INFO_STACKED("mt25qu02g", 0x20ba22, 0x1040, 64 << 10, 4096, ER_4K, 2) },
> 
> Is it possible it should be as below instead?
> 
> { INFO_STACKED("mt25qu02g", 0x20bb22, 0x1040, 64 << 10, 4096, ER_4K | ER_32K, 2) },
> 
> 's/0x20ba22/0x20bb22/' (or 's/mt25qu02g/mt25ql02g/') since 'u' looks to stand
> for 1.7-2.0 V and 'bb' for 1.8 V (see page 2 and 32 in [1]).

Here is what I am seeing : 

 mt25ql02g 0x20ba22 3V
 mt25qu02g 0x20bb22 1.8V

Do we agree ? 

> s/ER_4K/ER_4K | ER_32K/ since ERASE_32K is supported (see page 36). 

yes. I should have added that ! 
 
> If you find above changes ok and go with them please add:
> 
> Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>

Sure,

Thanks,

C.


> Best regards,
> Francisco Iglesias
> 
> [1] Micron Serial NOR Flash Memory 1.8V, Multiple I/O, 64KB Sector Erase MT25QU02GCBB
>     https://4donline.ihs.com/images/VipMasterIC/IC/MICT/MICT-S-A0008500026/MICT-S-A0008511423-1.pdf?hkey=52A5661711E402568146F3353EA87419
> 
>>  
>>      /* Spansion -- single (large) sector size only, at least
>>       * for the chips listed here (without boot sectors).
>> -- 
>> 2.26.3
>>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 03/24] aspeed/i2c: Fix DMA address mask
  2021-04-07 21:22   ` Philippe Mathieu-Daudé
@ 2021-04-08  8:58     ` Cédric Le Goater
  0 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-08  8:58 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, Peter Maydell
  Cc: Andrew Jeffery, qemu-arm, qemu-devel, Joel Stanley

On 4/7/21 11:22 PM, Philippe Mathieu-Daudé wrote:
> Hi Cédric,
> 
> On 4/7/21 7:16 PM, Cédric Le Goater wrote:
>> The RAM memory region is now used for DMAs accesses instead of the
>> memory address space region. Mask off the top bits of the DMA address
>> to reflect this change.
>>
>> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  hw/i2c/aspeed_i2c.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
>> index 518a3f5c6f9d..e7133528899f 100644
>> --- a/hw/i2c/aspeed_i2c.c
>> +++ b/hw/i2c/aspeed_i2c.c
>> @@ -601,7 +601,7 @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
>>              break;
>>          }
>>  
>> -        bus->dma_addr = value & 0xfffffffc;
>> +        bus->dma_addr = value & 0x3ffffffc;
> 
> This field is migrated (aspeed_i2c_bus_vmstate).

yes.
> Does the first patch "aspeed/smc: Use the RAM memory region for DMAs"
> break the migration?

You are right it does. Maintaining migration compatibility is overkill 
for this machine, but I should mention the first patch is breaking it.

Thanks,

C.
 



^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 17/24] aspeed: Remove swift-bmc machine
  2021-04-08  7:40     ` Cédric Le Goater
@ 2021-04-08  9:05       ` Peter Maydell
  0 siblings, 0 replies; 50+ messages in thread
From: Peter Maydell @ 2021-04-08  9:05 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Andrew Jeffery, qemu-arm, Joel Stanley, Adriana Kobylak, QEMU Developers

On Thu, 8 Apr 2021 at 08:40, Cédric Le Goater <clg@kaod.org> wrote:
>
> On 4/7/21 8:29 PM, Peter Maydell wrote:
> > On Wed, 7 Apr 2021 at 18:17, Cédric Le Goater <clg@kaod.org> wrote:
> >>
> >> The SWIFT machine never came out of the lab and we already have enough
> >> AST2500 based OpenPower machines. Remove it.
> >>
> >> Cc: Adriana Kobylak <anoo@us.ibm.com>
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> >
> > We've had QEMU releases with this machine in them, right?
> > If so, then we need to go through the usual deprecate-and-delete
> > cycle, we can't just drop it immediately.
>
> You are right. Instead, I will add :
>
>     mc->deprecation_reason = "redundant system. Please use a similar "
>         "OpenPOWER BMC, Witherspoon or Romulus.";

Don't forget to document the deprecation in docs/system/deprecated.rst.

> And we will drop the swift machine in QEMU 6.3

We only have x.0, x.1, x.2 releases, so it would be 7.0.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g
  2021-04-08  8:40     ` Cédric Le Goater
@ 2021-04-08  9:21       ` Francisco Iglesias
  0 siblings, 0 replies; 50+ messages in thread
From: Francisco Iglesias @ 2021-04-08  9:21 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Peter Maydell, Andrew Jeffery, qemu-devel, Francisco Iglesias,
	qemu-arm, Alistair Francis, Joel Stanley

Hi Cedric,

On [2021 Apr 08] Thu 10:40:18, Cédric Le Goater wrote:
> On 4/8/21 10:00 AM, Francisco Iglesias wrote:
> > Hello Cedric!
> > 
> > On Wed, Apr 07, 2021 at 07:16:34PM +0200, Cédric Le Goater wrote:
> >> The Micron mt25qu02g is a 3V 2Gb serial NOR flash memory supporting
> >> dual I/O and quad I/O, 4KB, 32KB, 64KB sector erase. It also supports
> >> 4B opcodes.
> >>
> >> Cc: Alistair Francis <alistair.francis@wdc.com>
> >> Cc: Francisco Iglesias <francisco.iglesias@xilinx.com>
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> >> ---
> >>  hw/block/m25p80.c | 1 +
> >>  1 file changed, 1 insertion(+)
> >>
> >> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> >> index 183d3f44c259..2afb939ae28e 100644
> >> --- a/hw/block/m25p80.c
> >> +++ b/hw/block/m25p80.c
> >> @@ -259,6 +259,7 @@ static const FlashPartInfo known_devices[] = {
> >>      { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
> >>      { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
> >>      { INFO_STACKED("mt25qu01g", 0x20bb21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
> >> +    { INFO_STACKED("mt25qu02g", 0x20ba22, 0x1040, 64 << 10, 4096, ER_4K, 2) },
> > 
> > Is it possible it should be as below instead?
> > 
> > { INFO_STACKED("mt25qu02g", 0x20bb22, 0x1040, 64 << 10, 4096, ER_4K | ER_32K, 2) },
> > 
> > 's/0x20ba22/0x20bb22/' (or 's/mt25qu02g/mt25ql02g/') since 'u' looks to stand
> > for 1.7-2.0 V and 'bb' for 1.8 V (see page 2 and 32 in [1]).
> 
> Here is what I am seeing : 
> 
>  mt25ql02g 0x20ba22 3V
>  mt25qu02g 0x20bb22 1.8V
> 
> Do we agree ? 

Yes :)

Best regards,
Francisco

> 
> > s/ER_4K/ER_4K | ER_32K/ since ERASE_32K is supported (see page 36). 
> 
> yes. I should have added that ! 
>  
> > If you find above changes ok and go with them please add:
> > 
> > Reviewed-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
> 
> Sure,
> 
> Thanks,
> 
> C.
> 
> 
> > Best regards,
> > Francisco Iglesias
> > 
> > [1] Micron Serial NOR Flash Memory 1.8V, Multiple I/O, 64KB Sector Erase MT25QU02GCBB
> >     https://4donline.ihs.com/images/VipMasterIC/IC/MICT/MICT-S-A0008500026/MICT-S-A0008511423-1.pdf?hkey=52A5661711E402568146F3353EA87419
> > 
> >>  
> >>      /* Spansion -- single (large) sector size only, at least
> >>       * for the chips listed here (without boot sectors).
> >> -- 
> >> 2.26.3
> >>
> 
> 


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 09/24] aspeed: Add Scater-Gather support for HACE Hash
  2021-04-07 17:16 ` [PATCH 09/24] aspeed: Add Scater-Gather support for HACE Hash Cédric Le Goater
@ 2021-04-08 12:39   ` Joel Stanley
  0 siblings, 0 replies; 50+ messages in thread
From: Joel Stanley @ 2021-04-08 12:39 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Andrew Jeffery, Peter Maydell, qemu-arm, QEMU Developers,
	Klaus Heinrich Kiwi

Hi Klaus,

On Wed, 7 Apr 2021 at 17:16, Cédric Le Goater <clg@kaod.org> wrote:
>
> From: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
>
> Complement the Aspeed HACE support with Scatter-Gather hash support for
> sha256 and sha512. Scatter-Gather is only supported on AST2600-series.

Sorry it's taken some time for me to get to this patch. It looks good.

While spending some time reviewing, I ended up using your ideas to
rework the do_hash_operation to support both sg and direct modes. It
results in a smaller patch and shares codepaths for both modes. I'll
send it out soon for review.

Cheers,

Joel


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 15/24] aspeed/smc: Add extra controls to request DMA
  2021-04-07 17:16 ` [PATCH 15/24] aspeed/smc: Add extra controls to request DMA Cédric Le Goater
@ 2021-04-09  6:54   ` Joel Stanley
  2021-04-10  7:08     ` Cédric Le Goater
  0 siblings, 1 reply; 50+ messages in thread
From: Joel Stanley @ 2021-04-09  6:54 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Andrew Jeffery, Peter Maydell, Chin-Ting Kuo, qemu-arm, QEMU Developers

On Wed, 7 Apr 2021 at 17:17, Cédric Le Goater <clg@kaod.org> wrote:
>
> The AST2600 SPI controllers have a set of bits to request/grant DMA
> access. Add a new SMC feature for these controllers and use it to
> check access to the DMA registers.

Ah this is why you added the features mask. Makes sense.

Reviewed-by: Joel Stanley <joel@jms.id.au>

>
> Cc: Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  include/hw/ssi/aspeed_smc.h |  1 +
>  hw/ssi/aspeed_smc.c         | 74 +++++++++++++++++++++++++++++++++----
>  2 files changed, 68 insertions(+), 7 deletions(-)
>
> diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
> index 07879fd1c4a7..cdaf165300b6 100644
> --- a/include/hw/ssi/aspeed_smc.h
> +++ b/include/hw/ssi/aspeed_smc.h
> @@ -55,6 +55,7 @@ typedef struct AspeedSMCController {
>                                 const AspeedSegments *seg);
>      void (*reg_to_segment)(const struct AspeedSMCState *s, uint32_t reg,
>                             AspeedSegments *seg);
> +    void (*dma_ctrl)(struct AspeedSMCState *s, uint32_t value);
>  } AspeedSMCController;
>
>  typedef struct AspeedSMCFlash {
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index 4521bbd4864e..189b35637c77 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
> @@ -228,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
> @@ -257,7 +260,10 @@ 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)
>  {
> @@ -281,6 +287,7 @@ static const AspeedSMCController controllers[] = {
>          .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,
> @@ -299,6 +306,7 @@ static const AspeedSMCController controllers[] = {
>          .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,
> @@ -315,6 +323,7 @@ static const AspeedSMCController controllers[] = {
>          .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,
> @@ -333,6 +342,7 @@ static const AspeedSMCController controllers[] = {
>          .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,
> @@ -349,6 +359,7 @@ static const AspeedSMCController controllers[] = {
>          .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,
> @@ -365,6 +376,7 @@ static const AspeedSMCController controllers[] = {
>          .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,
> @@ -383,6 +395,7 @@ static const AspeedSMCController controllers[] = {
>          .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,
> @@ -395,12 +408,14 @@ static const AspeedSMCController controllers[] = {
>          .segments          = aspeed_segments_ast2600_spi1,
>          .flash_window_base = ASPEED26_SOC_SPI_FLASH_BASE,
>          .flash_window_size = 0x10000000,
> -        .features          = ASPEED_SMC_FEATURE_DMA,
> +        .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,
> @@ -413,12 +428,14 @@ static const AspeedSMCController controllers[] = {
>          .segments          = aspeed_segments_ast2600_spi2,
>          .flash_window_base = ASPEED26_SOC_SPI2_FLASH_BASE,
>          .flash_window_size = 0x10000000,
> -        .features          = ASPEED_SMC_FEATURE_DMA,
> +        .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,
>      },
>  };
>
> @@ -1240,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;
> @@ -1265,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)
>  {
> @@ -1297,12 +1354,15 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
>      } else if (addr == R_INTR_CTRL) {
>          s->regs[addr] = value;
>      } else if (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) {
> -        aspeed_smc_dma_ctrl(s, value);
> -    } else if (aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR) {
> +        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 (aspeed_smc_has_dma(s) && 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 (aspeed_smc_has_dma(s) && 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",
> --
> 2.26.3
>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 14/24] aspeed/smc: Add a 'features' attribute to the object class
  2021-04-07 17:16 ` [PATCH 14/24] aspeed/smc: Add a 'features' attribute to the object class Cédric Le Goater
@ 2021-04-09  6:55   ` Joel Stanley
  0 siblings, 0 replies; 50+ messages in thread
From: Joel Stanley @ 2021-04-09  6:55 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Andrew Jeffery, Peter Maydell, qemu-arm, QEMU Developers

On Wed, 7 Apr 2021 at 17:17, Cédric Le Goater <clg@kaod.org> wrote:
>
> It will simplify extensions of the SMC model.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Joel Stanley <joel@jms.id.au>

> ---
>  include/hw/ssi/aspeed_smc.h |  2 +-
>  hw/ssi/aspeed_smc.c         | 44 +++++++++++++++++++++----------------
>  2 files changed, 26 insertions(+), 20 deletions(-)
>
> diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
> index 6ea2871cd899..07879fd1c4a7 100644
> --- a/include/hw/ssi/aspeed_smc.h
> +++ b/include/hw/ssi/aspeed_smc.h
> @@ -47,7 +47,7 @@ typedef struct AspeedSMCController {
>      const AspeedSegments *segments;
>      hwaddr flash_window_base;
>      uint32_t flash_window_size;
> -    bool has_dma;
> +    uint32_t features;
>      hwaddr dma_flash_mask;
>      hwaddr dma_dram_mask;
>      uint32_t nregs;
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
> index 50ea907aef74..4521bbd4864e 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -257,6 +257,12 @@ 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);
> +#define ASPEED_SMC_FEATURE_DMA       0x1
> +
> +static inline bool aspeed_smc_has_dma(const AspeedSMCState *s)
> +{
> +    return !!(s->ctrl->features & ASPEED_SMC_FEATURE_DMA);
> +}
>
>  static const AspeedSMCController controllers[] = {
>      {
> @@ -271,7 +277,7 @@ 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,
> @@ -287,7 +293,7 @@ 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,
> @@ -305,7 +311,7 @@ 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,
> @@ -321,7 +327,7 @@ 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,
> @@ -339,7 +345,7 @@ 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,
> @@ -355,7 +361,7 @@ 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,
> @@ -371,7 +377,7 @@ 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,
> @@ -389,7 +395,7 @@ 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,
>          .dma_flash_mask    = 0x0FFFFFFC,
>          .dma_dram_mask     = 0x3FFFFFFC,
>          .nregs             = ASPEED_SMC_R_MAX,
> @@ -407,7 +413,7 @@ 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,
>          .dma_flash_mask    = 0x0FFFFFFC,
>          .dma_dram_mask     = 0x3FFFFFFC,
>          .nregs             = ASPEED_SMC_R_MAX,
> @@ -997,11 +1003,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)) {
> @@ -1290,13 +1296,13 @@ 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) {
> +    } else if (aspeed_smc_has_dma(s) && 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_DRAM_ADDR) {
>          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) {
>          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) {
>          s->regs[addr] = DMA_LENGTH(value);
>      } else {
>          qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
> @@ -1412,7 +1418,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);
>      }
>  }
> --
> 2.26.3
>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 16/24] tests/qtest: Rename m25p80 test in aspeed_smc test
  2021-04-07 17:16 ` [PATCH 16/24] tests/qtest: Rename m25p80 test in aspeed_smc test Cédric Le Goater
@ 2021-04-09  6:55   ` Joel Stanley
  0 siblings, 0 replies; 50+ messages in thread
From: Joel Stanley @ 2021-04-09  6:55 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Andrew Jeffery, Peter Maydell, qemu-arm, QEMU Developers

On Wed, 7 Apr 2021 at 17:17, Cédric Le Goater <clg@kaod.org> wrote:
>
> The m25p80 test depends on the Aspeed SMC controller to test our
> SPI-NOR flash support. Reflect this dependency by changing the name.
>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

\o/ more tests

Reviewed-by: Joel Stanley <joel@jms.id.au>

> ---
>  tests/qtest/{m25p80-test.c => aspeed_smc-test.c} | 12 ++++++------
>  tests/qtest/meson.build                          |  4 ++--
>  2 files changed, 8 insertions(+), 8 deletions(-)
>  rename tests/qtest/{m25p80-test.c => aspeed_smc-test.c} (96%)
>
> diff --git a/tests/qtest/m25p80-test.c b/tests/qtest/aspeed_smc-test.c
> similarity index 96%
> rename from tests/qtest/m25p80-test.c
> rename to tests/qtest/aspeed_smc-test.c
> index f860cef5f08f..87b40a0ef186 100644
> --- a/tests/qtest/m25p80-test.c
> +++ b/tests/qtest/aspeed_smc-test.c
> @@ -367,12 +367,12 @@ int main(int argc, char **argv)
>                                 "-drive file=%s,format=raw,if=mtd",
>                                 tmp_path);
>
> -    qtest_add_func("/m25p80/read_jedec", test_read_jedec);
> -    qtest_add_func("/m25p80/erase_sector", test_erase_sector);
> -    qtest_add_func("/m25p80/erase_all",  test_erase_all);
> -    qtest_add_func("/m25p80/write_page", test_write_page);
> -    qtest_add_func("/m25p80/read_page_mem", test_read_page_mem);
> -    qtest_add_func("/m25p80/write_page_mem", test_write_page_mem);
> +    qtest_add_func("/ast2400/smc/read_jedec", test_read_jedec);
> +    qtest_add_func("/ast2400/smc/erase_sector", test_erase_sector);
> +    qtest_add_func("/ast2400/smc/erase_all",  test_erase_all);
> +    qtest_add_func("/ast2400/smc/write_page", test_write_page);
> +    qtest_add_func("/ast2400/smc/read_page_mem", test_read_page_mem);
> +    qtest_add_func("/ast2400/smc/write_page_mem", test_write_page_mem);
>
>      ret = g_test_run();
>
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 84b3219c15c6..269a30b217d7 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -164,7 +164,8 @@ qtests_npcm7xx = \
>     'npcm7xx_watchdog_timer-test'] + \
>     (slirp.found() ? ['npcm7xx_emc-test'] : [])
>  qtests_aspeed = \
> -  ['aspeed_hace-test']
> +  ['aspeed_hace-test',
> +   'aspeed_smc-test']
>  qtests_arm = \
>    (config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
>    (config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
> @@ -175,7 +176,6 @@ qtests_arm = \
>    (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
>    ['arm-cpu-features',
>     'microbit-test',
> -   'm25p80-test',
>     'test-arm-mptimer',
>     'boot-serial-test',
>     'hexloader-test']
> --
> 2.26.3
>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 18/24] aspeed: Add support for the rainier-bmc board
  2021-04-07 17:16 ` [PATCH 18/24] aspeed: Add support for the rainier-bmc board Cédric Le Goater
@ 2021-04-09  6:57   ` Joel Stanley
  0 siblings, 0 replies; 50+ messages in thread
From: Joel Stanley @ 2021-04-09  6:57 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Andrew Jeffery, Peter Maydell, qemu-arm, QEMU Developers

On Wed, 7 Apr 2021 at 17:17, Cédric Le Goater <clg@kaod.org> wrote:
>
> The Rainer BMC board is a board for the middle range POWER10 IBM systems.

Rainier

>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: Joel Stanley <joel@jms.id.au>

> ---
>  hw/arm/aspeed.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 79 insertions(+)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 97dcca74feb4..19588e17fec8 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -135,6 +135,10 @@ struct AspeedMachineState {
>  #define TACOMA_BMC_HW_STRAP1  0x00000000
>  #define TACOMA_BMC_HW_STRAP2  0x00000040
>
> +/* Rainier hardware value: (QEMU prototype) */

Can we drop the prototype comment?

> +#define RAINIER_BMC_HW_STRAP1 0x00000000
> +#define RAINIER_BMC_HW_STRAP2 0x00000000


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 15/24] aspeed/smc: Add extra controls to request DMA
  2021-04-09  6:54   ` Joel Stanley
@ 2021-04-10  7:08     ` Cédric Le Goater
  0 siblings, 0 replies; 50+ messages in thread
From: Cédric Le Goater @ 2021-04-10  7:08 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Andrew Jeffery, Peter Maydell, Chin-Ting Kuo, qemu-arm, QEMU Developers

On 4/9/21 8:54 AM, Joel Stanley wrote:
> On Wed, 7 Apr 2021 at 17:17, Cédric Le Goater <clg@kaod.org> wrote:
>>
>> The AST2600 SPI controllers have a set of bits to request/grant DMA
>> access. Add a new SMC feature for these controllers and use it to
>> check access to the DMA registers.
> 
> Ah this is why you added the features mask. Makes sense.

Yes. It's a bit redundant with the dma_ctrl() handler but it looks cleaner. 

> 
> Reviewed-by: Joel Stanley <joel@jms.id.au>


Thanks,

C.


>>
>> Cc: Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>  include/hw/ssi/aspeed_smc.h |  1 +
>>  hw/ssi/aspeed_smc.c         | 74 +++++++++++++++++++++++++++++++++----
>>  2 files changed, 68 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
>> index 07879fd1c4a7..cdaf165300b6 100644
>> --- a/include/hw/ssi/aspeed_smc.h
>> +++ b/include/hw/ssi/aspeed_smc.h
>> @@ -55,6 +55,7 @@ typedef struct AspeedSMCController {
>>                                 const AspeedSegments *seg);
>>      void (*reg_to_segment)(const struct AspeedSMCState *s, uint32_t reg,
>>                             AspeedSegments *seg);
>> +    void (*dma_ctrl)(struct AspeedSMCState *s, uint32_t value);
>>  } AspeedSMCController;
>>
>>  typedef struct AspeedSMCFlash {
>> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
>> index 4521bbd4864e..189b35637c77 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
>> @@ -228,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
>> @@ -257,7 +260,10 @@ 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)
>>  {
>> @@ -281,6 +287,7 @@ static const AspeedSMCController controllers[] = {
>>          .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,
>> @@ -299,6 +306,7 @@ static const AspeedSMCController controllers[] = {
>>          .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,
>> @@ -315,6 +323,7 @@ static const AspeedSMCController controllers[] = {
>>          .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,
>> @@ -333,6 +342,7 @@ static const AspeedSMCController controllers[] = {
>>          .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,
>> @@ -349,6 +359,7 @@ static const AspeedSMCController controllers[] = {
>>          .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,
>> @@ -365,6 +376,7 @@ static const AspeedSMCController controllers[] = {
>>          .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,
>> @@ -383,6 +395,7 @@ static const AspeedSMCController controllers[] = {
>>          .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,
>> @@ -395,12 +408,14 @@ static const AspeedSMCController controllers[] = {
>>          .segments          = aspeed_segments_ast2600_spi1,
>>          .flash_window_base = ASPEED26_SOC_SPI_FLASH_BASE,
>>          .flash_window_size = 0x10000000,
>> -        .features          = ASPEED_SMC_FEATURE_DMA,
>> +        .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,
>> @@ -413,12 +428,14 @@ static const AspeedSMCController controllers[] = {
>>          .segments          = aspeed_segments_ast2600_spi2,
>>          .flash_window_base = ASPEED26_SOC_SPI2_FLASH_BASE,
>>          .flash_window_size = 0x10000000,
>> -        .features          = ASPEED_SMC_FEATURE_DMA,
>> +        .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,
>>      },
>>  };
>>
>> @@ -1240,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;
>> @@ -1265,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)
>>  {
>> @@ -1297,12 +1354,15 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
>>      } else if (addr == R_INTR_CTRL) {
>>          s->regs[addr] = value;
>>      } else if (aspeed_smc_has_dma(s) && addr == R_DMA_CTRL) {
>> -        aspeed_smc_dma_ctrl(s, value);
>> -    } else if (aspeed_smc_has_dma(s) && addr == R_DMA_DRAM_ADDR) {
>> +        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 (aspeed_smc_has_dma(s) && 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 (aspeed_smc_has_dma(s) && 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",
>> --
>> 2.26.3
>>



^ permalink raw reply	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2021-04-10  7:09 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-07 17:16 [PATCH 00/24] aspeed: fixes and extensions Cédric Le Goater
2021-04-07 17:16 ` [PATCH 01/24] aspeed/smc: Use the RAM memory region for DMAs Cédric Le Goater
2021-04-07 17:32   ` Philippe Mathieu-Daudé
2021-04-07 17:16 ` [PATCH 02/24] aspeed/smc: Remove unused "sdram-base" property Cédric Le Goater
2021-04-07 17:32   ` Philippe Mathieu-Daudé
2021-04-07 17:16 ` [PATCH 03/24] aspeed/i2c: Fix DMA address mask Cédric Le Goater
2021-04-07 21:22   ` Philippe Mathieu-Daudé
2021-04-08  8:58     ` Cédric Le Goater
2021-04-07 17:16 ` [PATCH 04/24] aspeed/i2c: Rename DMA address space Cédric Le Goater
2021-04-07 17:33   ` Philippe Mathieu-Daudé
2021-04-07 17:16 ` [PATCH 05/24] hw/arm/aspeed: Do not sysbus-map mmio flash region directly, use alias Cédric Le Goater
2021-04-07 17:16 ` [PATCH 06/24] hw: Model ASPEED's Hash and Crypto Engine Cédric Le Goater
2021-04-07 19:31   ` Klaus Heinrich Kiwi
2021-04-07 17:16 ` [PATCH 07/24] aspeed: Integrate HACE Cédric Le Goater
2021-04-07 19:22   ` Klaus Heinrich Kiwi
2021-04-07 17:16 ` [PATCH 08/24] tests/qtest: Add test for Aspeed HACE Cédric Le Goater
2021-04-07 19:33   ` Klaus Heinrich Kiwi
2021-04-07 17:16 ` [PATCH 09/24] aspeed: Add Scater-Gather support for HACE Hash Cédric Le Goater
2021-04-08 12:39   ` Joel Stanley
2021-04-07 17:16 ` [PATCH 10/24] tests: Aspeed HACE Scatter-Gather tests Cédric Le Goater
2021-04-07 17:16 ` [PATCH 11/24] tests/acceptance: Test ast2400 and ast2500 machines Cédric Le Goater
2021-04-07 18:40   ` Willian Rampazzo
2021-04-07 17:16 ` [PATCH 12/24] tests/acceptance: Test ast2600 machine Cédric Le Goater
2021-04-07 18:36   ` Willian Rampazzo
2021-04-07 17:16 ` [PATCH 13/24] hw/misc/aspeed_xdma: Add AST2600 support Cédric Le Goater
2021-04-07 20:29   ` Eddie James
2021-04-07 17:16 ` [PATCH 14/24] aspeed/smc: Add a 'features' attribute to the object class Cédric Le Goater
2021-04-09  6:55   ` Joel Stanley
2021-04-07 17:16 ` [PATCH 15/24] aspeed/smc: Add extra controls to request DMA Cédric Le Goater
2021-04-09  6:54   ` Joel Stanley
2021-04-10  7:08     ` Cédric Le Goater
2021-04-07 17:16 ` [PATCH 16/24] tests/qtest: Rename m25p80 test in aspeed_smc test Cédric Le Goater
2021-04-09  6:55   ` Joel Stanley
2021-04-07 17:16 ` [PATCH 17/24] aspeed: Remove swift-bmc machine Cédric Le Goater
2021-04-07 18:13   ` Adriana Kobylak
2021-04-07 18:29   ` Peter Maydell
2021-04-08  7:40     ` Cédric Le Goater
2021-04-08  9:05       ` Peter Maydell
2021-04-07 17:16 ` [PATCH 18/24] aspeed: Add support for the rainier-bmc board Cédric Le Goater
2021-04-09  6:57   ` Joel Stanley
2021-04-07 17:16 ` [PATCH 19/24] hw/misc: Add an iBT device model Cédric Le Goater
2021-04-07 17:16 ` [PATCH 20/24] aspeed: Emulate the AST2600A3 Cédric Le Goater
2021-04-07 17:16 ` [PATCH 21/24] hw/block: m25p80: Add support for mt25qu02g Cédric Le Goater
2021-04-07 17:36   ` Alistair Francis
2021-04-08  8:00   ` Francisco Iglesias
2021-04-08  8:40     ` Cédric Le Goater
2021-04-08  9:21       ` Francisco Iglesias
2021-04-07 17:16 ` [PATCH 22/24] hw/misc: Add Infineon DPS310 sensor model Cédric Le Goater
2021-04-07 17:16 ` [PATCH 23/24] arm/aspeed: Add DPS310 to rainier Cédric Le Goater
2021-04-07 17:16 ` [PATCH 24/24] arm/aspeed: Add DPS310 to witherspoon Cédric Le Goater

This is a public inbox, see mirroring instructions
on how to clone and mirror all data and code used for this inbox