[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 15/36] aspeed/smc: extend tests for Command mode
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 15/36] aspeed/smc: extend tests for Command mode |
Date: |
Thu, 19 Jan 2017 14:09:34 +0000 |
From: Cédric Le Goater <address@hidden>
The Aspeed SMC controllers have a mode (Command mode) in which
accesses to the flash content are no different than doing MMIOs. The
controller generates all the necessary commands to load (or store)
data in memory.
So add a couple of tests doing direct reads and writes on the AHB bus.
Signed-off-by: Cédric Le Goater <address@hidden>
Reviewed-by: Andrew Jeffery <address@hidden>
Message-id: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
---
tests/m25p80-test.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/tests/m25p80-test.c b/tests/m25p80-test.c
index 8dd550d..244aa33 100644
--- a/tests/m25p80-test.c
+++ b/tests/m25p80-test.c
@@ -36,6 +36,9 @@
#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */
#define R_CTRL0 0x10
#define CTRL_CE_STOP_ACTIVE (1 << 2)
+#define CTRL_READMODE 0x0
+#define CTRL_FREADMODE 0x1
+#define CTRL_WRITEMODE 0x2
#define CTRL_USERMODE 0x3
#define ASPEED_FMC_BASE 0x1E620000
@@ -86,6 +89,22 @@ static void spi_conf_remove(uint32_t value)
writel(ASPEED_FMC_BASE + R_CONF, conf);
}
+static void spi_ce_ctrl(uint32_t value)
+{
+ uint32_t conf = readl(ASPEED_FMC_BASE + R_CE_CTRL);
+
+ conf |= value;
+ writel(ASPEED_FMC_BASE + R_CE_CTRL, conf);
+}
+
+static void spi_ctrl_setmode(uint8_t mode, uint8_t cmd)
+{
+ uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
+ ctrl &= ~(CTRL_USERMODE | 0xff << 16);
+ ctrl |= mode | (cmd << 16);
+ writel(ASPEED_FMC_BASE + R_CTRL0, ctrl);
+}
+
static void spi_ctrl_start_user(void)
{
uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0);
@@ -152,6 +171,18 @@ static void read_page(uint32_t addr, uint32_t *page)
spi_ctrl_stop_user();
}
+static void read_page_mem(uint32_t addr, uint32_t *page)
+{
+ int i;
+
+ /* move out USER mode to use direct reads from the AHB bus */
+ spi_ctrl_setmode(CTRL_READMODE, READ);
+
+ for (i = 0; i < PAGE_SIZE / 4; i++) {
+ page[i] = make_be32(readl(ASPEED_FLASH_BASE + addr + i * 4));
+ }
+}
+
static void test_erase_sector(void)
{
uint32_t some_page_addr = 0x600 * PAGE_SIZE;
@@ -248,6 +279,75 @@ static void test_write_page(void)
flash_reset();
}
+static void test_read_page_mem(void)
+{
+ uint32_t my_page_addr = 0x14000 * PAGE_SIZE; /* beyond 16MB */
+ uint32_t some_page_addr = 0x15000 * PAGE_SIZE;
+ uint32_t page[PAGE_SIZE / 4];
+ int i;
+
+ /* Enable 4BYTE mode for controller. This is should be strapped by
+ * HW for CE0 anyhow.
+ */
+ spi_ce_ctrl(1 << CRTL_EXTENDED0);
+
+ /* Enable 4BYTE mode for flash. */
+ spi_conf(CONF_ENABLE_W0);
+ spi_ctrl_start_user();
+ writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
+ spi_ctrl_stop_user();
+ spi_conf_remove(CONF_ENABLE_W0);
+
+ /* Check what was written */
+ read_page_mem(my_page_addr, page);
+ for (i = 0; i < PAGE_SIZE / 4; i++) {
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
+ }
+
+ /* Check some other page. It should be full of 0xff */
+ read_page_mem(some_page_addr, page);
+ for (i = 0; i < PAGE_SIZE / 4; i++) {
+ g_assert_cmphex(page[i], ==, 0xffffffff);
+ }
+
+ flash_reset();
+}
+
+static void test_write_page_mem(void)
+{
+ uint32_t my_page_addr = 0x15000 * PAGE_SIZE;
+ uint32_t page[PAGE_SIZE / 4];
+ int i;
+
+ /* Enable 4BYTE mode for controller. This is should be strapped by
+ * HW for CE0 anyhow.
+ */
+ spi_ce_ctrl(1 << CRTL_EXTENDED0);
+
+ /* Enable 4BYTE mode for flash. */
+ spi_conf(CONF_ENABLE_W0);
+ spi_ctrl_start_user();
+ writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR);
+ writeb(ASPEED_FLASH_BASE, WREN);
+ spi_ctrl_stop_user();
+
+ /* move out USER mode to use direct writes to the AHB bus */
+ spi_ctrl_setmode(CTRL_WRITEMODE, PP);
+
+ for (i = 0; i < PAGE_SIZE / 4; i++) {
+ writel(ASPEED_FLASH_BASE + my_page_addr + i * 4,
+ make_be32(my_page_addr + i * 4));
+ }
+
+ /* Check what was written */
+ read_page_mem(my_page_addr, page);
+ for (i = 0; i < PAGE_SIZE / 4; i++) {
+ g_assert_cmphex(page[i], ==, my_page_addr + i * 4);
+ }
+
+ flash_reset();
+}
+
static char tmp_path[] = "/tmp/qtest.m25p80.XXXXXX";
int main(int argc, char **argv)
@@ -273,6 +373,8 @@ int main(int argc, char **argv)
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);
ret = g_test_run();
--
2.7.4
- [Qemu-devel] [PULL 34/36] target/arm/psci.c: If EL2 implemented, start CPUs in EL2, (continued)
- [Qemu-devel] [PULL 34/36] target/arm/psci.c: If EL2 implemented, start CPUs in EL2, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 32/36] hw/arm/virt: Support using SMC for PSCI, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 08/36] aspeed/smc: remove call to aspeed_smc_update_cs() in reset function, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 29/36] hw/intc/arm_gicv3: Implement ICV_ registers EOIR and IAR, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 20/36] hw/intc/arm_gic: Add external IRQ lines for VIRQ and VFIQ, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 25/36] hw/intc/gicv3: Add data fields for virtualization support, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 19/36] hw/intc/arm_gicv3: Add external IRQ lines for VIRQ and VFIQ, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 26/36] hw/intc/arm_gicv3: Add accessors for ICH_ system registers, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 30/36] hw/intc/arm_gicv3: Implement gicv3_cpuif_virt_update(), Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 18/36] hw/arm/virt-acpi - reserve ECAM space as PNP0C02 device, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 15/36] aspeed/smc: extend tests for Command mode,
Peter Maydell <=
- [Qemu-devel] [PULL 12/36] aspeed/smc: adjust the size of the register region, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 03/36] block: m25p80: Introduce die erase command, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 36/36] hw/arm/virt: Add board property to enable EL2, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 35/36] target-arm: Enable EL2 feature bit on A53 and A57, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 07/36] aspeed/smc: remove call to reset in realize function, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 04/36] block: m25p80: Improve 1GiB Micron flash definition, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 05/36] target/arm: Handle VIRQ and VFIQ in arm_cpu_do_interrupt_aarch32(), Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 02/36] block: m25p80: Add Quad Page Program 4byte, Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 01/36] arm: Uniquely name imx25 I2C buses., Peter Maydell, 2017/01/19
- [Qemu-devel] [PULL 17/36] arm: virt: Fix segmentation fault when specifying an unsupported CPU, Peter Maydell, 2017/01/19