From patchwork Wed Nov 27 09:15:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886745 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F333BD609B0 for ; Wed, 27 Nov 2024 09:17:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9Q-00027g-DP; Wed, 27 Nov 2024 04:16:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9O-00026x-BS; Wed, 27 Nov 2024 04:15:58 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9M-0004K2-Sk; Wed, 27 Nov 2024 04:15:58 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:43 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:43 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , , =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH v3 01/10] test/qtest/aspeed_smc-test: Move testcases to test_palmetto_bmc function Date: Wed, 27 Nov 2024 17:15:34 +0800 Message-ID: <20241127091543.1243114-2-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org So far, the test cases are used for testing SMC model with AST2400 BMC. However, AST2400 is end off live and ASPEED is no longer support this SOC. To test SMC model for AST2500, AST2600 and AST1030, move the test cases from main to test_palmetto_bmc function. Signed-off-by: Jamin Lin Reviewed-by: Cédric Le Goater --- tests/qtest/aspeed_smc-test.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index 4673371d95..ec1fa6ec15 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -610,14 +610,12 @@ static void test_write_block_protect_bottom_bit(void) flash_reset(); } -int main(int argc, char **argv) +static int test_palmetto_bmc(void) { g_autofree char *tmp_path = NULL; int ret; int fd; - g_test_init(&argc, &argv, NULL); - fd = g_file_open_tmp("qtest.m25p80.XXXXXX", &tmp_path, NULL); g_assert(fd >= 0); ret = ftruncate(fd, FLASH_SIZE); @@ -644,8 +642,18 @@ int main(int argc, char **argv) flash_reset(); ret = g_test_run(); - qtest_quit(global_qtest); unlink(tmp_path); + + return ret; +} + +int main(int argc, char **argv) +{ + int ret; + + g_test_init(&argc, &argv, NULL); + ret = test_palmetto_bmc(); + return ret; } From patchwork Wed Nov 27 09:15:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886747 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2D4D9D609BA for ; Wed, 27 Nov 2024 09:18:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9a-00029m-Dq; Wed, 27 Nov 2024 04:16:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9S-00027u-Gq; Wed, 27 Nov 2024 04:16:02 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9P-0004K2-4y; Wed, 27 Nov 2024 04:16:02 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:44 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:44 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , , =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH v3 02/10] test/qtest/aspeed_smc-test: Introduce a new TestData to test different BMC SOCs Date: Wed, 27 Nov 2024 17:15:35 +0800 Message-ID: <20241127091543.1243114-3-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Currently, these test cases are only used for testing fmc_cs0 for AST2400. To test others BMC SOCs, introduces a new TestData structure. Users can set the spi base address, flash base address, jedesc id and so on for different BMC SOCs and flash model testing. Introduce new helper functions to make the test case more readable. Set spi base address 0x1E620000, flash_base address 0x20000000 and jedec id 0x20ba19 for fmc_cs0 with n25q256a flash for AST2400 SMC model testing. To pass the TestData into the test case, replace qtest_add_func with qtest_add_data_func. Signed-off-by: Jamin Lin Reviewed-by: Cédric Le Goater --- tests/qtest/aspeed_smc-test.c | 546 +++++++++++++++++++--------------- 1 file changed, 299 insertions(+), 247 deletions(-) diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index ec1fa6ec15..4c62009605 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -43,9 +43,6 @@ #define CTRL_USERMODE 0x3 #define SR_WEL BIT(1) -#define ASPEED_FMC_BASE 0x1E620000 -#define ASPEED_FLASH_BASE 0x20000000 - /* * Flash commands */ @@ -65,11 +62,16 @@ enum { ERASE_SECTOR = 0xd8, }; -#define FLASH_JEDEC 0x20ba19 /* n25q256a */ -#define FLASH_SIZE (32 * 1024 * 1024) - #define FLASH_PAGE_SIZE 256 +typedef struct TestData { + QTestState *s; + uint64_t spi_base; + uint64_t flash_base; + uint32_t jedec_id; + char *tmp_path; +} TestData; + /* * Use an explicit bswap for the values read/wrote to the flash region * as they are BE and the Aspeed CPU is LE. @@ -79,275 +81,315 @@ static inline uint32_t make_be32(uint32_t data) return bswap32(data); } -static void spi_conf(uint32_t value) +static inline void spi_writel(const TestData *data, uint64_t offset, + uint32_t value) +{ + qtest_writel(data->s, data->spi_base + offset, value); +} + +static inline uint32_t spi_readl(const TestData *data, uint64_t offset) +{ + return qtest_readl(data->s, data->spi_base + offset); +} + +static inline void flash_writeb(const TestData *data, uint64_t offset, + uint8_t value) +{ + qtest_writeb(data->s, data->flash_base + offset, value); +} + +static inline void flash_writel(const TestData *data, uint64_t offset, + uint32_t value) +{ + qtest_writel(data->s, data->flash_base + offset, value); +} + +static inline uint8_t flash_readb(const TestData *data, uint64_t offset) { - uint32_t conf = readl(ASPEED_FMC_BASE + R_CONF); + return qtest_readb(data->s, data->flash_base + offset); +} + +static inline uint32_t flash_readl(const TestData *data, uint64_t offset) +{ + return qtest_readl(data->s, data->flash_base + offset); +} + +static void spi_conf(const TestData *data, uint32_t value) +{ + uint32_t conf = spi_readl(data, R_CONF); conf |= value; - writel(ASPEED_FMC_BASE + R_CONF, conf); + spi_writel(data, R_CONF, conf); } -static void spi_conf_remove(uint32_t value) +static void spi_conf_remove(const TestData *data, uint32_t value) { - uint32_t conf = readl(ASPEED_FMC_BASE + R_CONF); + uint32_t conf = spi_readl(data, R_CONF); conf &= ~value; - writel(ASPEED_FMC_BASE + R_CONF, conf); + spi_writel(data, R_CONF, conf); } -static void spi_ce_ctrl(uint32_t value) +static void spi_ce_ctrl(const TestData *data, uint32_t value) { - uint32_t conf = readl(ASPEED_FMC_BASE + R_CE_CTRL); + uint32_t conf = spi_readl(data, R_CE_CTRL); conf |= value; - writel(ASPEED_FMC_BASE + R_CE_CTRL, conf); + spi_writel(data, R_CE_CTRL, conf); } -static void spi_ctrl_setmode(uint8_t mode, uint8_t cmd) +static void spi_ctrl_setmode(const TestData *data, uint8_t mode, uint8_t cmd) { - uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0); + uint32_t ctrl = spi_readl(data, R_CTRL0); ctrl &= ~(CTRL_USERMODE | 0xff << 16); ctrl |= mode | (cmd << 16); - writel(ASPEED_FMC_BASE + R_CTRL0, ctrl); + spi_writel(data, R_CTRL0, ctrl); } -static void spi_ctrl_start_user(void) +static void spi_ctrl_start_user(const TestData *data) { - uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0); + uint32_t ctrl = spi_readl(data, R_CTRL0); ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; - writel(ASPEED_FMC_BASE + R_CTRL0, ctrl); + spi_writel(data, R_CTRL0, ctrl); ctrl &= ~CTRL_CE_STOP_ACTIVE; - writel(ASPEED_FMC_BASE + R_CTRL0, ctrl); + spi_writel(data, R_CTRL0, ctrl); } -static void spi_ctrl_stop_user(void) +static void spi_ctrl_stop_user(const TestData *data) { - uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0); + uint32_t ctrl = spi_readl(data, R_CTRL0); ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; - writel(ASPEED_FMC_BASE + R_CTRL0, ctrl); + spi_writel(data, R_CTRL0, ctrl); } -static void flash_reset(void) +static void flash_reset(const TestData *data) { - spi_conf(CONF_ENABLE_W0); + spi_conf(data, CONF_ENABLE_W0); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, RESET_ENABLE); - writeb(ASPEED_FLASH_BASE, RESET_MEMORY); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, BULK_ERASE); - writeb(ASPEED_FLASH_BASE, WRDI); - spi_ctrl_stop_user(); + spi_ctrl_start_user(data); + flash_writeb(data, 0, RESET_ENABLE); + flash_writeb(data, 0, RESET_MEMORY); + flash_writeb(data, 0, WREN); + flash_writeb(data, 0, BULK_ERASE); + flash_writeb(data, 0, WRDI); + spi_ctrl_stop_user(data); - spi_conf_remove(CONF_ENABLE_W0); + spi_conf_remove(data, CONF_ENABLE_W0); } -static void test_read_jedec(void) +static void test_read_jedec(const void *data) { + const TestData *test_data = (const TestData *)data; uint32_t jedec = 0x0; - spi_conf(CONF_ENABLE_W0); + spi_conf(test_data, CONF_ENABLE_W0); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, JEDEC_READ); - jedec |= readb(ASPEED_FLASH_BASE) << 16; - jedec |= readb(ASPEED_FLASH_BASE) << 8; - jedec |= readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, JEDEC_READ); + jedec |= flash_readb(test_data, 0) << 16; + jedec |= flash_readb(test_data, 0) << 8; + jedec |= flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); - flash_reset(); + flash_reset(test_data); - g_assert_cmphex(jedec, ==, FLASH_JEDEC); + g_assert_cmphex(jedec, ==, test_data->jedec_id); } -static void read_page(uint32_t addr, uint32_t *page) +static void read_page(const TestData *data, uint32_t addr, uint32_t *page) { int i; - spi_ctrl_start_user(); + spi_ctrl_start_user(data); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, READ); - writel(ASPEED_FLASH_BASE, make_be32(addr)); + flash_writeb(data, 0, EN_4BYTE_ADDR); + flash_writeb(data, 0, READ); + flash_writel(data, 0, make_be32(addr)); /* Continuous read are supported */ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - page[i] = make_be32(readl(ASPEED_FLASH_BASE)); + page[i] = make_be32(flash_readl(data, 0)); } - spi_ctrl_stop_user(); + spi_ctrl_stop_user(data); } -static void read_page_mem(uint32_t addr, uint32_t *page) +static void read_page_mem(const TestData *data, 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); + spi_ctrl_setmode(data, CTRL_READMODE, READ); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - page[i] = make_be32(readl(ASPEED_FLASH_BASE + addr + i * 4)); + page[i] = make_be32(flash_readl(data, addr + i * 4)); } } -static void write_page_mem(uint32_t addr, uint32_t write_value) +static void write_page_mem(const TestData *data, uint32_t addr, + uint32_t write_value) { - spi_ctrl_setmode(CTRL_WRITEMODE, PP); + spi_ctrl_setmode(data, CTRL_WRITEMODE, PP); for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE + addr + i * 4, write_value); + flash_writel(data, addr + i * 4, write_value); } } -static void assert_page_mem(uint32_t addr, uint32_t expected_value) +static void assert_page_mem(const TestData *data, uint32_t addr, + uint32_t expected_value) { uint32_t page[FLASH_PAGE_SIZE / 4]; - read_page_mem(addr, page); + read_page_mem(data, addr, page); for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, expected_value); } } -static void test_erase_sector(void) +static void test_erase_sector(const void *data) { + const TestData *test_data = (const TestData *)data; uint32_t some_page_addr = 0x600 * FLASH_PAGE_SIZE; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; - spi_conf(CONF_ENABLE_W0); + spi_conf(test_data, CONF_ENABLE_W0); /* * Previous page should be full of 0xffs after backend is * initialized */ - read_page(some_page_addr - FLASH_PAGE_SIZE, page); + read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, 0xffffffff); } - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, PP); - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr)); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(some_page_addr)); /* Fill the page with its own addresses */ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr + i * 4)); + flash_writel(test_data, 0, make_be32(some_page_addr + i * 4)); } - spi_ctrl_stop_user(); + spi_ctrl_stop_user(test_data); /* Check the page is correctly written */ - read_page(some_page_addr, page); + read_page(test_data, some_page_addr, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, some_page_addr + i * 4); } - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, ERASE_SECTOR); - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr)); - spi_ctrl_stop_user(); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, ERASE_SECTOR); + flash_writel(test_data, 0, make_be32(some_page_addr)); + spi_ctrl_stop_user(test_data); /* Check the page is erased */ - read_page(some_page_addr, page); + read_page(test_data, some_page_addr, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, 0xffffffff); } - flash_reset(); + flash_reset(test_data); } -static void test_erase_all(void) +static void test_erase_all(const void *data) { + const TestData *test_data = (const TestData *)data; uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; - spi_conf(CONF_ENABLE_W0); + spi_conf(test_data, CONF_ENABLE_W0); /* * Previous page should be full of 0xffs after backend is * initialized */ - read_page(some_page_addr - FLASH_PAGE_SIZE, page); + read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, 0xffffffff); } - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, PP); - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr)); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(some_page_addr)); /* Fill the page with its own addresses */ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr + i * 4)); + flash_writel(test_data, 0, make_be32(some_page_addr + i * 4)); } - spi_ctrl_stop_user(); + spi_ctrl_stop_user(test_data); /* Check the page is correctly written */ - read_page(some_page_addr, page); + read_page(test_data, some_page_addr, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, some_page_addr + i * 4); } - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, BULK_ERASE); - spi_ctrl_stop_user(); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + spi_ctrl_stop_user(test_data); /* Check the page is erased */ - read_page(some_page_addr, page); + read_page(test_data, some_page_addr, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, 0xffffffff); } - flash_reset(); + flash_reset(test_data); } -static void test_write_page(void) +static void test_write_page(const void *data) { + const TestData *test_data = (const TestData *)data; uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */ uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; - spi_conf(CONF_ENABLE_W0); + spi_conf(test_data, CONF_ENABLE_W0); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, PP); - writel(ASPEED_FLASH_BASE, make_be32(my_page_addr)); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); /* Fill the page with its own addresses */ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE, make_be32(my_page_addr + i * 4)); + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); } - spi_ctrl_stop_user(); + spi_ctrl_stop_user(test_data); /* Check what was written */ - read_page(my_page_addr, page); + read_page(test_data, my_page_addr, page); for (i = 0; i < FLASH_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(some_page_addr, page); + read_page(test_data, some_page_addr, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, 0xffffffff); } - flash_reset(); + flash_reset(test_data); } -static void test_read_page_mem(void) +static void test_read_page_mem(const void *data) { + const TestData *test_data = (const TestData *)data; uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */ uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; uint32_t page[FLASH_PAGE_SIZE / 4]; @@ -357,40 +399,41 @@ static void test_read_page_mem(void) * Enable 4BYTE mode for controller. This is should be strapped by * HW for CE0 anyhow. */ - spi_ce_ctrl(1 << CRTL_EXTENDED0); + spi_ce_ctrl(test_data, 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); - writeb(ASPEED_FLASH_BASE, PP); - writel(ASPEED_FLASH_BASE, make_be32(my_page_addr)); + spi_conf(test_data, CONF_ENABLE_W0); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); /* Fill the page with its own addresses */ for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE, make_be32(my_page_addr + i * 4)); + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); } - spi_ctrl_stop_user(); - spi_conf_remove(CONF_ENABLE_W0); + spi_ctrl_stop_user(test_data); + spi_conf_remove(test_data, CONF_ENABLE_W0); /* Check what was written */ - read_page_mem(my_page_addr, page); + read_page_mem(test_data, my_page_addr, page); for (i = 0; i < FLASH_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); + read_page_mem(test_data, some_page_addr, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, 0xffffffff); } - flash_reset(); + flash_reset(test_data); } -static void test_write_page_mem(void) +static void test_write_page_mem(const void *data) { + const TestData *test_data = (const TestData *)data; uint32_t my_page_addr = 0x15000 * FLASH_PAGE_SIZE; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; @@ -399,150 +442,153 @@ static void test_write_page_mem(void) * Enable 4BYTE mode for controller. This is should be strapped by * HW for CE0 anyhow. */ - spi_ce_ctrl(1 << CRTL_EXTENDED0); + spi_ce_ctrl(test_data, 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(); + spi_conf(test_data, CONF_ENABLE_W0); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); /* move out USER mode to use direct writes to the AHB bus */ - spi_ctrl_setmode(CTRL_WRITEMODE, PP); + spi_ctrl_setmode(test_data, CTRL_WRITEMODE, PP); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE + my_page_addr + i * 4, + flash_writel(test_data, my_page_addr + i * 4, make_be32(my_page_addr + i * 4)); } /* Check what was written */ - read_page_mem(my_page_addr, page); + read_page_mem(test_data, my_page_addr, page); for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { g_assert_cmphex(page[i], ==, my_page_addr + i * 4); } - flash_reset(); + flash_reset(test_data); } -static void test_read_status_reg(void) +static void test_read_status_reg(const void *data) { + const TestData *test_data = (const TestData *)data; uint8_t r; - spi_conf(CONF_ENABLE_W0); + spi_conf(test_data, CONF_ENABLE_W0); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); g_assert_cmphex(r & SR_WEL, ==, 0); g_assert(!qtest_qom_get_bool - (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); + (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); g_assert_cmphex(r & SR_WEL, ==, SR_WEL); g_assert(qtest_qom_get_bool - (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); + (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WRDI); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WRDI); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); g_assert_cmphex(r & SR_WEL, ==, 0); g_assert(!qtest_qom_get_bool - (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); + (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); - flash_reset(); + flash_reset(test_data); } -static void test_status_reg_write_protection(void) +static void test_status_reg_write_protection(const void *data) { + const TestData *test_data = (const TestData *)data; uint8_t r; - spi_conf(CONF_ENABLE_W0); + spi_conf(test_data, CONF_ENABLE_W0); /* default case: WP# is high and SRWD is low -> status register writable */ - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); /* test ability to write SRWD */ - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, SRWD); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, SRWD); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); g_assert_cmphex(r & SRWD, ==, SRWD); /* WP# high and SRWD high -> status register writable */ - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); /* test ability to write SRWD */ - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, 0); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, 0); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); g_assert_cmphex(r & SRWD, ==, 0); /* WP# low and SRWD low -> status register writable */ - qtest_set_irq_in(global_qtest, + qtest_set_irq_in(test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 0); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); /* test ability to write SRWD */ - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, SRWD); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, SRWD); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); g_assert_cmphex(r & SRWD, ==, SRWD); /* WP# low and SRWD high -> status register NOT writable */ - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0 , WREN); /* test ability to write SRWD */ - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, 0); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, 0); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); /* write is not successful */ g_assert_cmphex(r & SRWD, ==, SRWD); - qtest_set_irq_in(global_qtest, + qtest_set_irq_in(test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 1); - flash_reset(); + flash_reset(test_data); } -static void test_write_block_protect(void) +static void test_write_block_protect(const void *data) { + const TestData *test_data = (const TestData *)data; uint32_t sector_size = 65536; uint32_t n_sectors = 512; - spi_ce_ctrl(1 << CRTL_EXTENDED0); - spi_conf(CONF_ENABLE_W0); + spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0); + spi_conf(test_data, CONF_ENABLE_W0); uint32_t bp_bits = 0b0; for (int i = 0; i < 16; i++) { bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, BULK_ERASE); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, bp_bits); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - spi_ctrl_stop_user(); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, bp_bits); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; uint32_t protection_start = n_sectors - num_protected_sectors; @@ -551,27 +597,28 @@ static void test_write_block_protect(void) for (int sector = 0; sector < n_sectors; sector++) { uint32_t addr = sector * sector_size; - assert_page_mem(addr, 0xffffffff); - write_page_mem(addr, make_be32(0xabcdef12)); + assert_page_mem(test_data, addr, 0xffffffff); + write_page_mem(test_data, addr, make_be32(0xabcdef12)); uint32_t expected_value = protection_start <= sector && sector < protection_end ? 0xffffffff : 0xabcdef12; - assert_page_mem(addr, expected_value); + assert_page_mem(test_data, addr, expected_value); } } - flash_reset(); + flash_reset(test_data); } -static void test_write_block_protect_bottom_bit(void) +static void test_write_block_protect_bottom_bit(const void *data) { + const TestData *test_data = (const TestData *)data; uint32_t sector_size = 65536; uint32_t n_sectors = 512; - spi_ce_ctrl(1 << CRTL_EXTENDED0); - spi_conf(CONF_ENABLE_W0); + spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0); + spi_conf(test_data, CONF_ENABLE_W0); /* top bottom bit is enabled */ uint32_t bp_bits = 0b00100 << 3; @@ -579,15 +626,15 @@ static void test_write_block_protect_bottom_bit(void) for (int i = 0; i < 16; i++) { bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, BULK_ERASE); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, bp_bits); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - spi_ctrl_stop_user(); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, bp_bits); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; uint32_t protection_start = 0; @@ -596,64 +643,69 @@ static void test_write_block_protect_bottom_bit(void) for (int sector = 0; sector < n_sectors; sector++) { uint32_t addr = sector * sector_size; - assert_page_mem(addr, 0xffffffff); - write_page_mem(addr, make_be32(0xabcdef12)); + assert_page_mem(test_data, addr, 0xffffffff); + write_page_mem(test_data, addr, make_be32(0xabcdef12)); uint32_t expected_value = protection_start <= sector && sector < protection_end ? 0xffffffff : 0xabcdef12; - assert_page_mem(addr, expected_value); + assert_page_mem(test_data, addr, expected_value); } } - flash_reset(); + flash_reset(test_data); } -static int test_palmetto_bmc(void) +static void test_palmetto_bmc(TestData *data) { - g_autofree char *tmp_path = NULL; int ret; int fd; - fd = g_file_open_tmp("qtest.m25p80.XXXXXX", &tmp_path, NULL); + fd = g_file_open_tmp("qtest.m25p80.n25q256a.XXXXXX", &data->tmp_path, NULL); g_assert(fd >= 0); - ret = ftruncate(fd, FLASH_SIZE); + ret = ftruncate(fd, 32 * 1024 * 1024); g_assert(ret == 0); close(fd); - global_qtest = qtest_initf("-m 256 -machine palmetto-bmc " - "-drive file=%s,format=raw,if=mtd", - tmp_path); - - 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); - qtest_add_func("/ast2400/smc/read_status_reg", test_read_status_reg); - qtest_add_func("/ast2400/smc/status_reg_write_protection", - test_status_reg_write_protection); - qtest_add_func("/ast2400/smc/write_block_protect", - test_write_block_protect); - qtest_add_func("/ast2400/smc/write_block_protect_bottom_bit", - test_write_block_protect_bottom_bit); - - flash_reset(); - ret = g_test_run(); - qtest_quit(global_qtest); - unlink(tmp_path); - - return ret; + data->s = qtest_initf("-m 256 -machine palmetto-bmc " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with n25q256a flash */ + data->flash_base = 0x20000000; + data->spi_base = 0x1E620000; + data->jedec_id = 0x20ba19; + + qtest_add_data_func("/ast2400/smc/read_jedec", data, test_read_jedec); + qtest_add_data_func("/ast2400/smc/erase_sector", data, test_erase_sector); + qtest_add_data_func("/ast2400/smc/erase_all", data, test_erase_all); + qtest_add_data_func("/ast2400/smc/write_page", data, test_write_page); + qtest_add_data_func("/ast2400/smc/read_page_mem", + data, test_read_page_mem); + qtest_add_data_func("/ast2400/smc/write_page_mem", + data, test_write_page_mem); + qtest_add_data_func("/ast2400/smc/read_status_reg", + data, test_read_status_reg); + qtest_add_data_func("/ast2400/smc/status_reg_write_protection", + data, test_status_reg_write_protection); + qtest_add_data_func("/ast2400/smc/write_block_protect", + data, test_write_block_protect); + qtest_add_data_func("/ast2400/smc/write_block_protect_bottom_bit", + data, test_write_block_protect_bottom_bit); } int main(int argc, char **argv) { + TestData palmetto_data; int ret; g_test_init(&argc, &argv, NULL); - ret = test_palmetto_bmc(); + test_palmetto_bmc(&palmetto_data); + ret = g_test_run(); + + qtest_quit(palmetto_data.s); + unlink(palmetto_data.tmp_path); return ret; } From patchwork Wed Nov 27 09:15:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886744 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 682CFD609B0 for ; Wed, 27 Nov 2024 09:17:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9k-0002FZ-9U; Wed, 27 Nov 2024 04:16:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9X-00028o-Rn; Wed, 27 Nov 2024 04:16:08 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9T-0004K2-CU; Wed, 27 Nov 2024 04:16:06 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:44 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:44 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , , =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH v3 03/10] test/qtest/aspeed_smc-test: Support to test all CE pins Date: Wed, 27 Nov 2024 17:15:36 +0800 Message-ID: <20241127091543.1243114-4-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Currently, these test cases only support to test CE0. To test all CE pins, introduces new ce and node members in TestData structure. The ce member is used for saving the ce index and node member is used for saving the node path, respectively. Signed-off-by: Jamin Lin Reviewed-by: Cédric Le Goater --- tests/qtest/aspeed_smc-test.c | 77 ++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index 4c62009605..b8ab20b43d 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -32,11 +32,11 @@ * ASPEED SPI Controller registers */ #define R_CONF 0x00 -#define CONF_ENABLE_W0 (1 << 16) +#define CONF_ENABLE_W0 16 #define R_CE_CTRL 0x04 #define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */ #define R_CTRL0 0x10 -#define CTRL_CE_STOP_ACTIVE (1 << 2) +#define CTRL_CE_STOP_ACTIVE BIT(2) #define CTRL_READMODE 0x0 #define CTRL_FREADMODE 0x1 #define CTRL_WRITEMODE 0x2 @@ -70,6 +70,8 @@ typedef struct TestData { uint64_t flash_base; uint32_t jedec_id; char *tmp_path; + uint8_t cs; + const char *node; } TestData; /* @@ -140,34 +142,37 @@ static void spi_ce_ctrl(const TestData *data, uint32_t value) static void spi_ctrl_setmode(const TestData *data, uint8_t mode, uint8_t cmd) { - uint32_t ctrl = spi_readl(data, R_CTRL0); + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); ctrl &= ~(CTRL_USERMODE | 0xff << 16); ctrl |= mode | (cmd << 16); - spi_writel(data, R_CTRL0, ctrl); + spi_writel(data, ctrl_reg, ctrl); } static void spi_ctrl_start_user(const TestData *data) { - uint32_t ctrl = spi_readl(data, R_CTRL0); + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; - spi_writel(data, R_CTRL0, ctrl); + spi_writel(data, ctrl_reg, ctrl); ctrl &= ~CTRL_CE_STOP_ACTIVE; - spi_writel(data, R_CTRL0, ctrl); + spi_writel(data, ctrl_reg, ctrl); } static void spi_ctrl_stop_user(const TestData *data) { - uint32_t ctrl = spi_readl(data, R_CTRL0); + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; - spi_writel(data, R_CTRL0, ctrl); + spi_writel(data, ctrl_reg, ctrl); } static void flash_reset(const TestData *data) { - spi_conf(data, CONF_ENABLE_W0); + spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs)); spi_ctrl_start_user(data); flash_writeb(data, 0, RESET_ENABLE); @@ -177,7 +182,7 @@ static void flash_reset(const TestData *data) flash_writeb(data, 0, WRDI); spi_ctrl_stop_user(data); - spi_conf_remove(data, CONF_ENABLE_W0); + spi_conf_remove(data, 1 << (CONF_ENABLE_W0 + data->cs)); } static void test_read_jedec(const void *data) @@ -185,7 +190,7 @@ static void test_read_jedec(const void *data) const TestData *test_data = (const TestData *)data; uint32_t jedec = 0x0; - spi_conf(test_data, CONF_ENABLE_W0); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); spi_ctrl_start_user(test_data); flash_writeb(test_data, 0, JEDEC_READ); @@ -255,7 +260,7 @@ static void test_erase_sector(const void *data) uint32_t page[FLASH_PAGE_SIZE / 4]; int i; - spi_conf(test_data, CONF_ENABLE_W0); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); /* * Previous page should be full of 0xffs after backend is @@ -307,7 +312,7 @@ static void test_erase_all(const void *data) uint32_t page[FLASH_PAGE_SIZE / 4]; int i; - spi_conf(test_data, CONF_ENABLE_W0); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); /* * Previous page should be full of 0xffs after backend is @@ -358,7 +363,7 @@ static void test_write_page(const void *data) uint32_t page[FLASH_PAGE_SIZE / 4]; int i; - spi_conf(test_data, CONF_ENABLE_W0); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); spi_ctrl_start_user(test_data); flash_writeb(test_data, 0, EN_4BYTE_ADDR); @@ -396,13 +401,12 @@ static void test_read_page_mem(const void *data) int i; /* - * Enable 4BYTE mode for controller. This is should be strapped by - * HW for CE0 anyhow. + * Enable 4BYTE mode for controller. */ - spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0); + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); /* Enable 4BYTE mode for flash. */ - spi_conf(test_data, CONF_ENABLE_W0); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); spi_ctrl_start_user(test_data); flash_writeb(test_data, 0, EN_4BYTE_ADDR); flash_writeb(test_data, 0, WREN); @@ -414,7 +418,7 @@ static void test_read_page_mem(const void *data) flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); } spi_ctrl_stop_user(test_data); - spi_conf_remove(test_data, CONF_ENABLE_W0); + spi_conf_remove(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); /* Check what was written */ read_page_mem(test_data, my_page_addr, page); @@ -439,13 +443,12 @@ static void test_write_page_mem(const void *data) int i; /* - * Enable 4BYTE mode for controller. This is should be strapped by - * HW for CE0 anyhow. + * Enable 4BYTE mode for controller. */ - spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0); + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); /* Enable 4BYTE mode for flash. */ - spi_conf(test_data, CONF_ENABLE_W0); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); spi_ctrl_start_user(test_data); flash_writeb(test_data, 0, EN_4BYTE_ADDR); flash_writeb(test_data, 0, WREN); @@ -473,7 +476,7 @@ static void test_read_status_reg(const void *data) const TestData *test_data = (const TestData *)data; uint8_t r; - spi_conf(test_data, CONF_ENABLE_W0); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); spi_ctrl_start_user(test_data); flash_writeb(test_data, 0, RDSR); @@ -482,7 +485,7 @@ static void test_read_status_reg(const void *data) g_assert_cmphex(r & SR_WEL, ==, 0); g_assert(!qtest_qom_get_bool - (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); + (test_data->s, test_data->node, "write-enable")); spi_ctrl_start_user(test_data); flash_writeb(test_data, 0, WREN); @@ -492,7 +495,7 @@ static void test_read_status_reg(const void *data) g_assert_cmphex(r & SR_WEL, ==, SR_WEL); g_assert(qtest_qom_get_bool - (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); + (test_data->s, test_data->node, "write-enable")); spi_ctrl_start_user(test_data); flash_writeb(test_data, 0, WRDI); @@ -502,7 +505,7 @@ static void test_read_status_reg(const void *data) g_assert_cmphex(r & SR_WEL, ==, 0); g_assert(!qtest_qom_get_bool - (test_data->s, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); + (test_data->s, test_data->node, "write-enable")); flash_reset(test_data); } @@ -512,7 +515,7 @@ static void test_status_reg_write_protection(const void *data) const TestData *test_data = (const TestData *)data; uint8_t r; - spi_conf(test_data, CONF_ENABLE_W0); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); /* default case: WP# is high and SRWD is low -> status register writable */ spi_ctrl_start_user(test_data); @@ -537,8 +540,7 @@ static void test_status_reg_write_protection(const void *data) g_assert_cmphex(r & SRWD, ==, 0); /* WP# low and SRWD low -> status register writable */ - qtest_set_irq_in(test_data->s, - "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 0); + qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 0); spi_ctrl_start_user(test_data); flash_writeb(test_data, 0, WREN); /* test ability to write SRWD */ @@ -561,8 +563,7 @@ static void test_status_reg_write_protection(const void *data) /* write is not successful */ g_assert_cmphex(r & SRWD, ==, SRWD); - qtest_set_irq_in(test_data->s, - "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 1); + qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 1); flash_reset(test_data); } @@ -572,8 +573,8 @@ static void test_write_block_protect(const void *data) uint32_t sector_size = 65536; uint32_t n_sectors = 512; - spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0); - spi_conf(test_data, CONF_ENABLE_W0); + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); uint32_t bp_bits = 0b0; @@ -617,8 +618,8 @@ static void test_write_block_protect_bottom_bit(const void *data) uint32_t sector_size = 65536; uint32_t n_sectors = 512; - spi_ce_ctrl(test_data, 1 << CRTL_EXTENDED0); - spi_conf(test_data, CONF_ENABLE_W0); + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); /* top bottom bit is enabled */ uint32_t bp_bits = 0b00100 << 3; @@ -676,6 +677,8 @@ static void test_palmetto_bmc(TestData *data) data->flash_base = 0x20000000; data->spi_base = 0x1E620000; data->jedec_id = 0x20ba19; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; qtest_add_data_func("/ast2400/smc/read_jedec", data, test_read_jedec); qtest_add_data_func("/ast2400/smc/erase_sector", data, test_erase_sector); From patchwork Wed Nov 27 09:15:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886740 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 31C7ED609BA for ; Wed, 27 Nov 2024 09:16:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9k-0002Gw-P4; Wed, 27 Nov 2024 04:16:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9d-0002AB-P1; Wed, 27 Nov 2024 04:16:13 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9Z-0004K2-KY; Wed, 27 Nov 2024 04:16:11 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:45 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:45 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , , =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH v3 04/10] test/qtest/aspeed_smc-test: Introducing a "page_addr" data field Date: Wed, 27 Nov 2024 17:15:37 +0800 Message-ID: <20241127091543.1243114-5-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Currently, these test cases used the hardcode offset 0x1400000 (0x14000 * 256) which was beyond the 16MB flash size for flash page read/write command testing. However, the default fmc flash model of ast1030-a1 EVB is "w25q80bl" whose size is 1MB. To test SoC flash models, introduces a new page_addr member in TestData structure, so users can set the offset for flash page read/write command testing. Signed-off-by: Jamin Lin Reviewed-by: Cédric Le Goater --- tests/qtest/aspeed_smc-test.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index b8ab20b43d..6db18451d2 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -72,6 +72,7 @@ typedef struct TestData { char *tmp_path; uint8_t cs; const char *node; + uint32_t page_addr; } TestData; /* @@ -256,7 +257,7 @@ static void assert_page_mem(const TestData *data, uint32_t addr, static void test_erase_sector(const void *data) { const TestData *test_data = (const TestData *)data; - uint32_t some_page_addr = 0x600 * FLASH_PAGE_SIZE; + uint32_t some_page_addr = test_data->page_addr; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; @@ -308,7 +309,7 @@ static void test_erase_sector(const void *data) static void test_erase_all(const void *data) { const TestData *test_data = (const TestData *)data; - uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; + uint32_t some_page_addr = test_data->page_addr; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; @@ -358,8 +359,8 @@ static void test_erase_all(const void *data) static void test_write_page(const void *data) { const TestData *test_data = (const TestData *)data; - uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */ - uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; @@ -395,8 +396,8 @@ static void test_write_page(const void *data) static void test_read_page_mem(const void *data) { const TestData *test_data = (const TestData *)data; - uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */ - uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; @@ -438,7 +439,7 @@ static void test_read_page_mem(const void *data) static void test_write_page_mem(const void *data) { const TestData *test_data = (const TestData *)data; - uint32_t my_page_addr = 0x15000 * FLASH_PAGE_SIZE; + uint32_t my_page_addr = test_data->page_addr; uint32_t page[FLASH_PAGE_SIZE / 4]; int i; @@ -679,6 +680,8 @@ static void test_palmetto_bmc(TestData *data) data->jedec_id = 0x20ba19; data->cs = 0; data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 16MB */ + data->page_addr = 0x14000 * FLASH_PAGE_SIZE; qtest_add_data_func("/ast2400/smc/read_jedec", data, test_read_jedec); qtest_add_data_func("/ast2400/smc/erase_sector", data, test_erase_sector); From patchwork Wed Nov 27 09:15:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886746 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A280DD609BA for ; Wed, 27 Nov 2024 09:18:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9p-0002M6-TU; Wed, 27 Nov 2024 04:16:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9h-0002BD-Qa; Wed, 27 Nov 2024 04:16:19 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9g-0004K2-5j; Wed, 27 Nov 2024 04:16:17 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:45 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:45 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , , =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH v3 05/10] test/qtest/aspeed_smc-test: Support to test AST2500 Date: Wed, 27 Nov 2024 17:15:38 +0800 Message-ID: <20241127091543.1243114-6-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add test_ast2500_evb function and reused testcases for AST2500 testing. The spi base address, flash base address and ce index of fmc_cs0 are 0x1E620000, 0x20000000 and 0, respectively. The default flash model of fmc_cs0 is "mx25l25635e" whose size is 32MB, so set jedec_id 0xc22019. Signed-off-by: Jamin Lin Reviewed-by: Cédric Le Goater --- tests/qtest/aspeed_smc-test.c | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index 6db18451d2..0171ecf4ed 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -701,17 +701,57 @@ static void test_palmetto_bmc(TestData *data) data, test_write_block_protect_bottom_bit); } +static void test_ast2500_evb(TestData *data) +{ + int ret; + int fd; + + fd = g_file_open_tmp("qtest.m25p80.mx25l25635e.XXXXXX", + &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 32 * 1024 * 1024); + g_assert(ret == 0); + close(fd); + + data->s = qtest_initf("-machine ast2500-evb " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with mx25l25635e flash */ + data->flash_base = 0x20000000; + data->spi_base = 0x1E620000; + data->jedec_id = 0xc22019; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 16MB */ + data->page_addr = 0x14000 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast2500/smc/read_jedec", data, test_read_jedec); + qtest_add_data_func("/ast2500/smc/erase_sector", data, test_erase_sector); + qtest_add_data_func("/ast2500/smc/erase_all", data, test_erase_all); + qtest_add_data_func("/ast2500/smc/write_page", data, test_write_page); + qtest_add_data_func("/ast2500/smc/read_page_mem", + data, test_read_page_mem); + qtest_add_data_func("/ast2500/smc/write_page_mem", + data, test_write_page_mem); + qtest_add_data_func("/ast2500/smc/read_status_reg", + data, test_read_status_reg); +} int main(int argc, char **argv) { TestData palmetto_data; + TestData ast2500_evb_data; int ret; g_test_init(&argc, &argv, NULL); test_palmetto_bmc(&palmetto_data); + test_ast2500_evb(&ast2500_evb_data); ret = g_test_run(); qtest_quit(palmetto_data.s); + qtest_quit(ast2500_evb_data.s); unlink(palmetto_data.tmp_path); + unlink(ast2500_evb_data.tmp_path); return ret; } From patchwork Wed Nov 27 09:15:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886742 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2BFB9D609BA for ; Wed, 27 Nov 2024 09:17:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9s-0002RL-8Z; Wed, 27 Nov 2024 04:16:28 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9l-0002J8-6W; Wed, 27 Nov 2024 04:16:21 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9i-0004K2-Mt; Wed, 27 Nov 2024 04:16:20 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:45 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:45 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , , =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH v3 06/10] test/qtest/aspeed_smc-test: Support to test AST2600 Date: Wed, 27 Nov 2024 17:15:39 +0800 Message-ID: <20241127091543.1243114-7-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add test_ast2600_evb function and reused testcases for AST2600 testing. The spi base address, flash base address and ce index of fmc_cs0 are 0x1E620000, 0x20000000 and 0, respectively. The default flash model of fmc_cs0 is "mx66u51235f" whose size is 64MB, so set jedec_id 0xc2253a. Signed-off-by: Jamin Lin Reviewed-by: Cédric Le Goater --- tests/qtest/aspeed_smc-test.c | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index 0171ecf4ed..30f997679c 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -737,21 +737,62 @@ static void test_ast2500_evb(TestData *data) qtest_add_data_func("/ast2500/smc/read_status_reg", data, test_read_status_reg); } + +static void test_ast2600_evb(TestData *data) +{ + int ret; + int fd; + + fd = g_file_open_tmp("qtest.m25p80.mx66u51235f.XXXXXX", + &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 64 * 1024 * 1024); + g_assert(ret == 0); + close(fd); + + data->s = qtest_initf("-machine ast2600-evb " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with mx66u51235f flash */ + data->flash_base = 0x20000000; + data->spi_base = 0x1E620000; + data->jedec_id = 0xc2253a; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 16MB */ + data->page_addr = 0x14000 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast2600/smc/read_jedec", data, test_read_jedec); + qtest_add_data_func("/ast2600/smc/erase_sector", data, test_erase_sector); + qtest_add_data_func("/ast2600/smc/erase_all", data, test_erase_all); + qtest_add_data_func("/ast2600/smc/write_page", data, test_write_page); + qtest_add_data_func("/ast2600/smc/read_page_mem", + data, test_read_page_mem); + qtest_add_data_func("/ast2600/smc/write_page_mem", + data, test_write_page_mem); + qtest_add_data_func("/ast2600/smc/read_status_reg", + data, test_read_status_reg); +} int main(int argc, char **argv) { TestData palmetto_data; TestData ast2500_evb_data; + TestData ast2600_evb_data; int ret; g_test_init(&argc, &argv, NULL); test_palmetto_bmc(&palmetto_data); test_ast2500_evb(&ast2500_evb_data); + test_ast2600_evb(&ast2600_evb_data); ret = g_test_run(); qtest_quit(palmetto_data.s); qtest_quit(ast2500_evb_data.s); + qtest_quit(ast2600_evb_data.s); unlink(palmetto_data.tmp_path); unlink(ast2500_evb_data.tmp_path); + unlink(ast2600_evb_data.tmp_path); return ret; } From patchwork Wed Nov 27 09:15:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886749 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3DFE4D609B0 for ; Wed, 27 Nov 2024 09:18:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9u-0002Ui-27; Wed, 27 Nov 2024 04:16:30 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9n-0002Lm-Qs; Wed, 27 Nov 2024 04:16:25 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9m-0004K2-3P; Wed, 27 Nov 2024 04:16:23 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:45 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:45 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , , =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH v3 07/10] test/qtest/aspeed_smc-test: Support to test AST1030 Date: Wed, 27 Nov 2024 17:15:40 +0800 Message-ID: <20241127091543.1243114-8-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add test_ast1030_evb function and reused testcases for AST1030 testing. The base address, flash base address and ce index of fmc_cs0 are 0x7E620000, 0x80000000 and 0, respectively. The default flash model of fmc_cs0 is "w25q80bl" whose size is 1MB, so set jedec_id 0xef4014. Signed-off-by: Jamin Lin Reviewed-by: Cédric Le Goater --- tests/qtest/aspeed_smc-test.c | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index 30f997679c..c5c38e23c5 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -774,11 +774,50 @@ static void test_ast2600_evb(TestData *data) qtest_add_data_func("/ast2600/smc/read_status_reg", data, test_read_status_reg); } + +static void test_ast1030_evb(TestData *data) +{ + int ret; + int fd; + + fd = g_file_open_tmp("qtest.m25p80.w25q80bl.XXXXXX", + &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 1 * 1024 * 1024); + g_assert(ret == 0); + close(fd); + + data->s = qtest_initf("-machine ast1030-evb " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with w25q80bl flash */ + data->flash_base = 0x80000000; + data->spi_base = 0x7E620000; + data->jedec_id = 0xef4014; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 512KB */ + data->page_addr = 0x800 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast1030/smc/read_jedec", data, test_read_jedec); + qtest_add_data_func("/ast1030/smc/erase_sector", data, test_erase_sector); + qtest_add_data_func("/ast1030/smc/erase_all", data, test_erase_all); + qtest_add_data_func("/ast1030/smc/write_page", data, test_write_page); + qtest_add_data_func("/ast1030/smc/read_page_mem", + data, test_read_page_mem); + qtest_add_data_func("/ast1030/smc/write_page_mem", + data, test_write_page_mem); + qtest_add_data_func("/ast1030/smc/read_status_reg", + data, test_read_status_reg); +} + int main(int argc, char **argv) { TestData palmetto_data; TestData ast2500_evb_data; TestData ast2600_evb_data; + TestData ast1030_evb_data; int ret; g_test_init(&argc, &argv, NULL); @@ -786,13 +825,16 @@ int main(int argc, char **argv) test_palmetto_bmc(&palmetto_data); test_ast2500_evb(&ast2500_evb_data); test_ast2600_evb(&ast2600_evb_data); + test_ast1030_evb(&ast1030_evb_data); ret = g_test_run(); qtest_quit(palmetto_data.s); qtest_quit(ast2500_evb_data.s); qtest_quit(ast2600_evb_data.s); + qtest_quit(ast1030_evb_data.s); unlink(palmetto_data.tmp_path); unlink(ast2500_evb_data.tmp_path); unlink(ast2600_evb_data.tmp_path); + unlink(ast1030_evb_data.tmp_path); return ret; } From patchwork Wed Nov 27 09:15:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886750 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 666A2D609BA for ; Wed, 27 Nov 2024 09:18:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9t-0002T2-3V; Wed, 27 Nov 2024 04:16:29 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9q-0002Nr-OI; Wed, 27 Nov 2024 04:16:26 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9p-0004K2-1h; Wed, 27 Nov 2024 04:16:26 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:46 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:46 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , , =?utf-8?q?C=C3=A9dric_Le_Goater?= Subject: [PATCH v3 08/10] test/qtest/aspeed_smc-test: Support write page command with QPI mode Date: Wed, 27 Nov 2024 17:15:41 +0800 Message-ID: <20241127091543.1243114-9-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a new testcase for write page command with QPI mode testing. Currently, only run this testcase for AST2500, AST2600 and AST1030. Signed-off-by: Jamin Lin Reviewed-by: Cédric Le Goater --- tests/qtest/aspeed_smc-test.c | 74 +++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index c5c38e23c5..59f3876cdc 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -36,6 +36,7 @@ #define R_CE_CTRL 0x04 #define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */ #define R_CTRL0 0x10 +#define CTRL_IO_QUAD_IO BIT(31) #define CTRL_CE_STOP_ACTIVE BIT(2) #define CTRL_READMODE 0x0 #define CTRL_FREADMODE 0x1 @@ -62,6 +63,7 @@ enum { ERASE_SECTOR = 0xd8, }; +#define CTRL_IO_MODE_MASK (BIT(31) | BIT(30) | BIT(29) | BIT(28)) #define FLASH_PAGE_SIZE 256 typedef struct TestData { @@ -171,6 +173,18 @@ static void spi_ctrl_stop_user(const TestData *data) spi_writel(data, ctrl_reg, ctrl); } +static void spi_ctrl_set_io_mode(const TestData *data, uint32_t value) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + uint32_t mode; + + mode = value & CTRL_IO_MODE_MASK; + ctrl &= ~CTRL_IO_MODE_MASK; + ctrl |= mode; + spi_writel(data, ctrl_reg, ctrl); +} + static void flash_reset(const TestData *data) { spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs)); @@ -659,6 +673,60 @@ static void test_write_block_protect_bottom_bit(const void *data) flash_reset(test_data); } +static void test_write_page_qpi(const void *data) +{ + const TestData *test_data = (const TestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; + uint32_t page[FLASH_PAGE_SIZE / 4]; + uint32_t page_pattern[] = { + 0xebd8c134, 0x5da196bc, 0xae15e729, 0x5085ccdf + }; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); + + /* Set QPI mode */ + spi_ctrl_set_io_mode(test_data, CTRL_IO_QUAD_IO); + + /* Fill the page pattern */ + for (i = 0; i < ARRAY_SIZE(page_pattern); i++) { + flash_writel(test_data, 0, make_be32(page_pattern[i])); + } + + /* Fill the page with its own addresses */ + for (; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); + } + + /* Restore io mode */ + spi_ctrl_set_io_mode(test_data, 0); + spi_ctrl_stop_user(test_data); + + /* Check what was written */ + read_page(test_data, my_page_addr, page); + for (i = 0; i < ARRAY_SIZE(page_pattern); i++) { + g_assert_cmphex(page[i], ==, page_pattern[i]); + } + for (; i < FLASH_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(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + static void test_palmetto_bmc(TestData *data) { int ret; @@ -736,6 +804,8 @@ static void test_ast2500_evb(TestData *data) data, test_write_page_mem); qtest_add_data_func("/ast2500/smc/read_status_reg", data, test_read_status_reg); + qtest_add_data_func("/ast2500/smc/write_page_qpi", + data, test_write_page_qpi); } static void test_ast2600_evb(TestData *data) @@ -773,6 +843,8 @@ static void test_ast2600_evb(TestData *data) data, test_write_page_mem); qtest_add_data_func("/ast2600/smc/read_status_reg", data, test_read_status_reg); + qtest_add_data_func("/ast2600/smc/write_page_qpi", + data, test_write_page_qpi); } static void test_ast1030_evb(TestData *data) @@ -810,6 +882,8 @@ static void test_ast1030_evb(TestData *data) data, test_write_page_mem); qtest_add_data_func("/ast1030/smc/read_status_reg", data, test_read_status_reg); + qtest_add_data_func("/ast1030/smc/write_page_qpi", + data, test_write_page_qpi); } int main(int argc, char **argv) From patchwork Wed Nov 27 09:15:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886743 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C4EDBD609B0 for ; Wed, 27 Nov 2024 09:17:46 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGE9y-0002dC-GE; Wed, 27 Nov 2024 04:16:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9w-0002XP-BI; Wed, 27 Nov 2024 04:16:32 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9r-0004K2-Tn; Wed, 27 Nov 2024 04:16:32 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:46 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:46 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , Subject: [PATCH v3 09/10] test/qtest: Introduce a new aspeed-smc-utils.c to place common testcases Date: Wed, 27 Nov 2024 17:15:42 +0800 Message-ID: <20241127091543.1243114-10-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The testcases for ASPEED SMC model were placed in aspeed_smc-test.c. However, this test file only supports for ARM32. To support all ASPEED SOCs such as AST2700 whose CPU architecture is aarch64, introduces a new aspeed-smc-utils source file and move all common APIs and testcases from aspeed_smc-test.c to aspeed-smc-utils.c. Finally, users are able to re-used these testcase for AST2700 and future ASPEED SOCs testing. Signed-off-by: Jamin Lin --- tests/qtest/aspeed-smc-utils.c | 686 ++++++++++++++++++++++++++++ tests/qtest/aspeed-smc-utils.h | 95 ++++ tests/qtest/aspeed_smc-test.c | 800 +++------------------------------ tests/qtest/meson.build | 1 + 4 files changed, 841 insertions(+), 741 deletions(-) create mode 100644 tests/qtest/aspeed-smc-utils.c create mode 100644 tests/qtest/aspeed-smc-utils.h diff --git a/tests/qtest/aspeed-smc-utils.c b/tests/qtest/aspeed-smc-utils.c new file mode 100644 index 0000000000..c27d09e767 --- /dev/null +++ b/tests/qtest/aspeed-smc-utils.c @@ -0,0 +1,686 @@ +/* + * QTest testcase for the M25P80 Flash (Using the Aspeed SPI + * Controller) + * + * Copyright (C) 2016 IBM Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu/bswap.h" +#include "libqtest-single.h" +#include "qemu/bitops.h" +#include "aspeed-smc-utils.h" + +/* + * Use an explicit bswap for the values read/wrote to the flash region + * as they are BE and the Aspeed CPU is LE. + */ +static inline uint32_t make_be32(uint32_t data) +{ + return bswap32(data); +} + +static inline void spi_writel(const AspeedSMCTestData *data, uint64_t offset, + uint32_t value) +{ + qtest_writel(data->s, data->spi_base + offset, value); +} + +static inline uint32_t spi_readl(const AspeedSMCTestData *data, uint64_t offset) +{ + return qtest_readl(data->s, data->spi_base + offset); +} + +static inline void flash_writeb(const AspeedSMCTestData *data, uint64_t offset, + uint8_t value) +{ + qtest_writeb(data->s, data->flash_base + offset, value); +} + +static inline void flash_writel(const AspeedSMCTestData *data, uint64_t offset, + uint32_t value) +{ + qtest_writel(data->s, data->flash_base + offset, value); +} + +static inline uint8_t flash_readb(const AspeedSMCTestData *data, + uint64_t offset) +{ + return qtest_readb(data->s, data->flash_base + offset); +} + +static inline uint32_t flash_readl(const AspeedSMCTestData *data, + uint64_t offset) +{ + return qtest_readl(data->s, data->flash_base + offset); +} + +static void spi_conf(const AspeedSMCTestData *data, uint32_t value) +{ + uint32_t conf = spi_readl(data, R_CONF); + + conf |= value; + spi_writel(data, R_CONF, conf); +} + +static void spi_conf_remove(const AspeedSMCTestData *data, uint32_t value) +{ + uint32_t conf = spi_readl(data, R_CONF); + + conf &= ~value; + spi_writel(data, R_CONF, conf); +} + +static void spi_ce_ctrl(const AspeedSMCTestData *data, uint32_t value) +{ + uint32_t conf = spi_readl(data, R_CE_CTRL); + + conf |= value; + spi_writel(data, R_CE_CTRL, conf); +} + +static void spi_ctrl_setmode(const AspeedSMCTestData *data, uint8_t mode, + uint8_t cmd) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + ctrl &= ~(CTRL_USERMODE | 0xff << 16); + ctrl |= mode | (cmd << 16); + spi_writel(data, ctrl_reg, ctrl); +} + +static void spi_ctrl_start_user(const AspeedSMCTestData *data) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + + ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; + spi_writel(data, ctrl_reg, ctrl); + + ctrl &= ~CTRL_CE_STOP_ACTIVE; + spi_writel(data, ctrl_reg, ctrl); +} + +static void spi_ctrl_stop_user(const AspeedSMCTestData *data) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + + ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; + spi_writel(data, ctrl_reg, ctrl); +} + +static void spi_ctrl_set_io_mode(const AspeedSMCTestData *data, uint32_t value) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + uint32_t mode; + + mode = value & CTRL_IO_MODE_MASK; + ctrl &= ~CTRL_IO_MODE_MASK; + ctrl |= mode; + spi_writel(data, ctrl_reg, ctrl); +} + +static void flash_reset(const AspeedSMCTestData *data) +{ + spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs)); + + spi_ctrl_start_user(data); + flash_writeb(data, 0, RESET_ENABLE); + flash_writeb(data, 0, RESET_MEMORY); + flash_writeb(data, 0, WREN); + flash_writeb(data, 0, BULK_ERASE); + flash_writeb(data, 0, WRDI); + spi_ctrl_stop_user(data); + + spi_conf_remove(data, 1 << (CONF_ENABLE_W0 + data->cs)); +} + +static void read_page(const AspeedSMCTestData *data, uint32_t addr, + uint32_t *page) +{ + int i; + + spi_ctrl_start_user(data); + + flash_writeb(data, 0, EN_4BYTE_ADDR); + flash_writeb(data, 0, READ); + flash_writel(data, 0, make_be32(addr)); + + /* Continuous read are supported */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + page[i] = make_be32(flash_readl(data, 0)); + } + spi_ctrl_stop_user(data); +} + +static void read_page_mem(const AspeedSMCTestData *data, uint32_t addr, + uint32_t *page) +{ + int i; + + /* move out USER mode to use direct reads from the AHB bus */ + spi_ctrl_setmode(data, CTRL_READMODE, READ); + + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + page[i] = make_be32(flash_readl(data, addr + i * 4)); + } +} + +static void write_page_mem(const AspeedSMCTestData *data, uint32_t addr, + uint32_t write_value) +{ + spi_ctrl_setmode(data, CTRL_WRITEMODE, PP); + + for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(data, addr + i * 4, write_value); + } +} + +static void assert_page_mem(const AspeedSMCTestData *data, uint32_t addr, + uint32_t expected_value) +{ + uint32_t page[FLASH_PAGE_SIZE / 4]; + read_page_mem(data, addr, page); + for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, expected_value); + } +} + +void aspeed_smc_test_read_jedec(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t jedec = 0x0; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, JEDEC_READ); + jedec |= flash_readb(test_data, 0) << 16; + jedec |= flash_readb(test_data, 0) << 8; + jedec |= flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + + flash_reset(test_data); + + g_assert_cmphex(jedec, ==, test_data->jedec_id); +} + +void aspeed_smc_test_erase_sector(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t some_page_addr = test_data->page_addr; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* + * Previous page should be full of 0xffs after backend is + * initialized + */ + read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(some_page_addr)); + + /* Fill the page with its own addresses */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(some_page_addr + i * 4)); + } + spi_ctrl_stop_user(test_data); + + /* Check the page is correctly written */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, some_page_addr + i * 4); + } + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, ERASE_SECTOR); + flash_writel(test_data, 0, make_be32(some_page_addr)); + spi_ctrl_stop_user(test_data); + + /* Check the page is erased */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_erase_all(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t some_page_addr = test_data->page_addr; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* + * Previous page should be full of 0xffs after backend is + * initialized + */ + read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(some_page_addr)); + + /* Fill the page with its own addresses */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(some_page_addr + i * 4)); + } + spi_ctrl_stop_user(test_data); + + /* Check the page is correctly written */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, some_page_addr + i * 4); + } + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + spi_ctrl_stop_user(test_data); + + /* Check the page is erased */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_write_page(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); + + /* Fill the page with its own addresses */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); + } + spi_ctrl_stop_user(test_data); + + /* Check what was written */ + read_page(test_data, my_page_addr, page); + for (i = 0; i < FLASH_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(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_read_page_mem(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + /* + * Enable 4BYTE mode for controller. + */ + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + + /* Enable 4BYTE mode for flash. */ + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); + + /* Fill the page with its own addresses */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); + } + spi_ctrl_stop_user(test_data); + spi_conf_remove(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* Check what was written */ + read_page_mem(test_data, my_page_addr, page); + for (i = 0; i < FLASH_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(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_write_page_mem(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + /* + * Enable 4BYTE mode for controller. + */ + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + + /* Enable 4BYTE mode for flash. */ + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); + + /* move out USER mode to use direct writes to the AHB bus */ + spi_ctrl_setmode(test_data, CTRL_WRITEMODE, PP); + + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, my_page_addr + i * 4, + make_be32(my_page_addr + i * 4)); + } + + /* Check what was written */ + read_page_mem(test_data, my_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, my_page_addr + i * 4); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_read_status_reg(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint8_t r; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + + g_assert_cmphex(r & SR_WEL, ==, 0); + g_assert(!qtest_qom_get_bool + (test_data->s, test_data->node, "write-enable")); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + + g_assert_cmphex(r & SR_WEL, ==, SR_WEL); + g_assert(qtest_qom_get_bool + (test_data->s, test_data->node, "write-enable")); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WRDI); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + + g_assert_cmphex(r & SR_WEL, ==, 0); + g_assert(!qtest_qom_get_bool + (test_data->s, test_data->node, "write-enable")); + + flash_reset(test_data); +} + +void aspeed_smc_test_status_reg_write_protection(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint8_t r; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* default case: WP# is high and SRWD is low -> status register writable */ + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + /* test ability to write SRWD */ + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, SRWD); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + g_assert_cmphex(r & SRWD, ==, SRWD); + + /* WP# high and SRWD high -> status register writable */ + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + /* test ability to write SRWD */ + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, 0); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + g_assert_cmphex(r & SRWD, ==, 0); + + /* WP# low and SRWD low -> status register writable */ + qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 0); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + /* test ability to write SRWD */ + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, SRWD); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + g_assert_cmphex(r & SRWD, ==, SRWD); + + /* WP# low and SRWD high -> status register NOT writable */ + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0 , WREN); + /* test ability to write SRWD */ + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, 0); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + /* write is not successful */ + g_assert_cmphex(r & SRWD, ==, SRWD); + + qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 1); + flash_reset(test_data); +} + +void aspeed_smc_test_write_block_protect(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t sector_size = 65536; + uint32_t n_sectors = 512; + + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + uint32_t bp_bits = 0b0; + + for (int i = 0; i < 16; i++) { + bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, bp_bits); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); + + uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; + uint32_t protection_start = n_sectors - num_protected_sectors; + uint32_t protection_end = n_sectors; + + for (int sector = 0; sector < n_sectors; sector++) { + uint32_t addr = sector * sector_size; + + assert_page_mem(test_data, addr, 0xffffffff); + write_page_mem(test_data, addr, make_be32(0xabcdef12)); + + uint32_t expected_value = protection_start <= sector + && sector < protection_end + ? 0xffffffff : 0xabcdef12; + + assert_page_mem(test_data, addr, expected_value); + } + } + + flash_reset(test_data); +} + +void aspeed_smc_test_write_block_protect_bottom_bit(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t sector_size = 65536; + uint32_t n_sectors = 512; + + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* top bottom bit is enabled */ + uint32_t bp_bits = 0b00100 << 3; + + for (int i = 0; i < 16; i++) { + bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, bp_bits); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); + + uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; + uint32_t protection_start = 0; + uint32_t protection_end = num_protected_sectors; + + for (int sector = 0; sector < n_sectors; sector++) { + uint32_t addr = sector * sector_size; + + assert_page_mem(test_data, addr, 0xffffffff); + write_page_mem(test_data, addr, make_be32(0xabcdef12)); + + uint32_t expected_value = protection_start <= sector + && sector < protection_end + ? 0xffffffff : 0xabcdef12; + + assert_page_mem(test_data, addr, expected_value); + } + } + + flash_reset(test_data); +} + +void aspeed_smc_test_write_page_qpi(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; + uint32_t page[FLASH_PAGE_SIZE / 4]; + uint32_t page_pattern[] = { + 0xebd8c134, 0x5da196bc, 0xae15e729, 0x5085ccdf + }; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); + + /* Set QPI mode */ + spi_ctrl_set_io_mode(test_data, CTRL_IO_QUAD_IO); + + /* Fill the page pattern */ + for (i = 0; i < ARRAY_SIZE(page_pattern); i++) { + flash_writel(test_data, 0, make_be32(page_pattern[i])); + } + + /* Fill the page with its own addresses */ + for (; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); + } + + /* Restore io mode */ + spi_ctrl_set_io_mode(test_data, 0); + spi_ctrl_stop_user(test_data); + + /* Check what was written */ + read_page(test_data, my_page_addr, page); + for (i = 0; i < ARRAY_SIZE(page_pattern); i++) { + g_assert_cmphex(page[i], ==, page_pattern[i]); + } + for (; i < FLASH_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(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + diff --git a/tests/qtest/aspeed-smc-utils.h b/tests/qtest/aspeed-smc-utils.h new file mode 100644 index 0000000000..b07870f3b8 --- /dev/null +++ b/tests/qtest/aspeed-smc-utils.h @@ -0,0 +1,95 @@ +/* + * QTest testcase for the M25P80 Flash (Using the Aspeed SPI + * Controller) + * + * Copyright (C) 2016 IBM Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef TESTS_ASPEED_SMC_UTILS_H +#define TESTS_ASPEED_SMC_UTILS_H + +#include "qemu/osdep.h" +#include "qemu/bswap.h" +#include "libqtest-single.h" +#include "qemu/bitops.h" + +/* + * ASPEED SPI Controller registers + */ +#define R_CONF 0x00 +#define CONF_ENABLE_W0 16 +#define R_CE_CTRL 0x04 +#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */ +#define R_CTRL0 0x10 +#define CTRL_IO_QUAD_IO BIT(31) +#define CTRL_CE_STOP_ACTIVE BIT(2) +#define CTRL_READMODE 0x0 +#define CTRL_FREADMODE 0x1 +#define CTRL_WRITEMODE 0x2 +#define CTRL_USERMODE 0x3 +#define SR_WEL BIT(1) + +/* + * Flash commands + */ +enum { + JEDEC_READ = 0x9f, + RDSR = 0x5, + WRDI = 0x4, + BULK_ERASE = 0xc7, + READ = 0x03, + PP = 0x02, + WRSR = 0x1, + WREN = 0x6, + SRWD = 0x80, + RESET_ENABLE = 0x66, + RESET_MEMORY = 0x99, + EN_4BYTE_ADDR = 0xB7, + ERASE_SECTOR = 0xd8, +}; + +#define CTRL_IO_MODE_MASK (BIT(31) | BIT(30) | BIT(29) | BIT(28)) +#define FLASH_PAGE_SIZE 256 + +typedef struct AspeedSMCTestData { + QTestState *s; + uint64_t spi_base; + uint64_t flash_base; + uint32_t jedec_id; + char *tmp_path; + uint8_t cs; + const char *node; + uint32_t page_addr; +} AspeedSMCTestData; + +void aspeed_smc_test_read_jedec(const void *data); +void aspeed_smc_test_erase_sector(const void *data); +void aspeed_smc_test_erase_all(const void *data); +void aspeed_smc_test_write_page(const void *data); +void aspeed_smc_test_read_page_mem(const void *data); +void aspeed_smc_test_write_page_mem(const void *data); +void aspeed_smc_test_read_status_reg(const void *data); +void aspeed_smc_test_status_reg_write_protection(const void *data); +void aspeed_smc_test_write_block_protect(const void *data); +void aspeed_smc_test_write_block_protect_bottom_bit(const void *data); +void aspeed_smc_test_write_page_qpi(const void *data); + +#endif /* TESTS_ASPEED_SMC_UTILS_H */ diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index 59f3876cdc..4e1389385d 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -27,707 +27,9 @@ #include "qemu/bswap.h" #include "libqtest-single.h" #include "qemu/bitops.h" +#include "aspeed-smc-utils.h" -/* - * ASPEED SPI Controller registers - */ -#define R_CONF 0x00 -#define CONF_ENABLE_W0 16 -#define R_CE_CTRL 0x04 -#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */ -#define R_CTRL0 0x10 -#define CTRL_IO_QUAD_IO BIT(31) -#define CTRL_CE_STOP_ACTIVE BIT(2) -#define CTRL_READMODE 0x0 -#define CTRL_FREADMODE 0x1 -#define CTRL_WRITEMODE 0x2 -#define CTRL_USERMODE 0x3 -#define SR_WEL BIT(1) - -/* - * Flash commands - */ -enum { - JEDEC_READ = 0x9f, - RDSR = 0x5, - WRDI = 0x4, - BULK_ERASE = 0xc7, - READ = 0x03, - PP = 0x02, - WRSR = 0x1, - WREN = 0x6, - SRWD = 0x80, - RESET_ENABLE = 0x66, - RESET_MEMORY = 0x99, - EN_4BYTE_ADDR = 0xB7, - ERASE_SECTOR = 0xd8, -}; - -#define CTRL_IO_MODE_MASK (BIT(31) | BIT(30) | BIT(29) | BIT(28)) -#define FLASH_PAGE_SIZE 256 - -typedef struct TestData { - QTestState *s; - uint64_t spi_base; - uint64_t flash_base; - uint32_t jedec_id; - char *tmp_path; - uint8_t cs; - const char *node; - uint32_t page_addr; -} TestData; - -/* - * Use an explicit bswap for the values read/wrote to the flash region - * as they are BE and the Aspeed CPU is LE. - */ -static inline uint32_t make_be32(uint32_t data) -{ - return bswap32(data); -} - -static inline void spi_writel(const TestData *data, uint64_t offset, - uint32_t value) -{ - qtest_writel(data->s, data->spi_base + offset, value); -} - -static inline uint32_t spi_readl(const TestData *data, uint64_t offset) -{ - return qtest_readl(data->s, data->spi_base + offset); -} - -static inline void flash_writeb(const TestData *data, uint64_t offset, - uint8_t value) -{ - qtest_writeb(data->s, data->flash_base + offset, value); -} - -static inline void flash_writel(const TestData *data, uint64_t offset, - uint32_t value) -{ - qtest_writel(data->s, data->flash_base + offset, value); -} - -static inline uint8_t flash_readb(const TestData *data, uint64_t offset) -{ - return qtest_readb(data->s, data->flash_base + offset); -} - -static inline uint32_t flash_readl(const TestData *data, uint64_t offset) -{ - return qtest_readl(data->s, data->flash_base + offset); -} - -static void spi_conf(const TestData *data, uint32_t value) -{ - uint32_t conf = spi_readl(data, R_CONF); - - conf |= value; - spi_writel(data, R_CONF, conf); -} - -static void spi_conf_remove(const TestData *data, uint32_t value) -{ - uint32_t conf = spi_readl(data, R_CONF); - - conf &= ~value; - spi_writel(data, R_CONF, conf); -} - -static void spi_ce_ctrl(const TestData *data, uint32_t value) -{ - uint32_t conf = spi_readl(data, R_CE_CTRL); - - conf |= value; - spi_writel(data, R_CE_CTRL, conf); -} - -static void spi_ctrl_setmode(const TestData *data, uint8_t mode, uint8_t cmd) -{ - uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; - uint32_t ctrl = spi_readl(data, ctrl_reg); - ctrl &= ~(CTRL_USERMODE | 0xff << 16); - ctrl |= mode | (cmd << 16); - spi_writel(data, ctrl_reg, ctrl); -} - -static void spi_ctrl_start_user(const TestData *data) -{ - uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; - uint32_t ctrl = spi_readl(data, ctrl_reg); - - ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; - spi_writel(data, ctrl_reg, ctrl); - - ctrl &= ~CTRL_CE_STOP_ACTIVE; - spi_writel(data, ctrl_reg, ctrl); -} - -static void spi_ctrl_stop_user(const TestData *data) -{ - uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; - uint32_t ctrl = spi_readl(data, ctrl_reg); - - ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; - spi_writel(data, ctrl_reg, ctrl); -} - -static void spi_ctrl_set_io_mode(const TestData *data, uint32_t value) -{ - uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; - uint32_t ctrl = spi_readl(data, ctrl_reg); - uint32_t mode; - - mode = value & CTRL_IO_MODE_MASK; - ctrl &= ~CTRL_IO_MODE_MASK; - ctrl |= mode; - spi_writel(data, ctrl_reg, ctrl); -} - -static void flash_reset(const TestData *data) -{ - spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs)); - - spi_ctrl_start_user(data); - flash_writeb(data, 0, RESET_ENABLE); - flash_writeb(data, 0, RESET_MEMORY); - flash_writeb(data, 0, WREN); - flash_writeb(data, 0, BULK_ERASE); - flash_writeb(data, 0, WRDI); - spi_ctrl_stop_user(data); - - spi_conf_remove(data, 1 << (CONF_ENABLE_W0 + data->cs)); -} - -static void test_read_jedec(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t jedec = 0x0; - - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, JEDEC_READ); - jedec |= flash_readb(test_data, 0) << 16; - jedec |= flash_readb(test_data, 0) << 8; - jedec |= flash_readb(test_data, 0); - spi_ctrl_stop_user(test_data); - - flash_reset(test_data); - - g_assert_cmphex(jedec, ==, test_data->jedec_id); -} - -static void read_page(const TestData *data, uint32_t addr, uint32_t *page) -{ - int i; - - spi_ctrl_start_user(data); - - flash_writeb(data, 0, EN_4BYTE_ADDR); - flash_writeb(data, 0, READ); - flash_writel(data, 0, make_be32(addr)); - - /* Continuous read are supported */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - page[i] = make_be32(flash_readl(data, 0)); - } - spi_ctrl_stop_user(data); -} - -static void read_page_mem(const TestData *data, uint32_t addr, uint32_t *page) -{ - int i; - - /* move out USER mode to use direct reads from the AHB bus */ - spi_ctrl_setmode(data, CTRL_READMODE, READ); - - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - page[i] = make_be32(flash_readl(data, addr + i * 4)); - } -} - -static void write_page_mem(const TestData *data, uint32_t addr, - uint32_t write_value) -{ - spi_ctrl_setmode(data, CTRL_WRITEMODE, PP); - - for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - flash_writel(data, addr + i * 4, write_value); - } -} - -static void assert_page_mem(const TestData *data, uint32_t addr, - uint32_t expected_value) -{ - uint32_t page[FLASH_PAGE_SIZE / 4]; - read_page_mem(data, addr, page); - for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, expected_value); - } -} - -static void test_erase_sector(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t some_page_addr = test_data->page_addr; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - /* - * Previous page should be full of 0xffs after backend is - * initialized - */ - read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, PP); - flash_writel(test_data, 0, make_be32(some_page_addr)); - - /* Fill the page with its own addresses */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - flash_writel(test_data, 0, make_be32(some_page_addr + i * 4)); - } - spi_ctrl_stop_user(test_data); - - /* Check the page is correctly written */ - read_page(test_data, some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, some_page_addr + i * 4); - } - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, ERASE_SECTOR); - flash_writel(test_data, 0, make_be32(some_page_addr)); - spi_ctrl_stop_user(test_data); - - /* Check the page is erased */ - read_page(test_data, some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(test_data); -} - -static void test_erase_all(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t some_page_addr = test_data->page_addr; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - /* - * Previous page should be full of 0xffs after backend is - * initialized - */ - read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, PP); - flash_writel(test_data, 0, make_be32(some_page_addr)); - - /* Fill the page with its own addresses */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - flash_writel(test_data, 0, make_be32(some_page_addr + i * 4)); - } - spi_ctrl_stop_user(test_data); - - /* Check the page is correctly written */ - read_page(test_data, some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, some_page_addr + i * 4); - } - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, BULK_ERASE); - spi_ctrl_stop_user(test_data); - - /* Check the page is erased */ - read_page(test_data, some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(test_data); -} - -static void test_write_page(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t my_page_addr = test_data->page_addr; - uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, PP); - flash_writel(test_data, 0, make_be32(my_page_addr)); - - /* Fill the page with its own addresses */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); - } - spi_ctrl_stop_user(test_data); - - /* Check what was written */ - read_page(test_data, my_page_addr, page); - for (i = 0; i < FLASH_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(test_data, some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(test_data); -} - -static void test_read_page_mem(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t my_page_addr = test_data->page_addr; - uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - /* - * Enable 4BYTE mode for controller. - */ - spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); - - /* Enable 4BYTE mode for flash. */ - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, PP); - flash_writel(test_data, 0, make_be32(my_page_addr)); - - /* Fill the page with its own addresses */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); - } - spi_ctrl_stop_user(test_data); - spi_conf_remove(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - /* Check what was written */ - read_page_mem(test_data, my_page_addr, page); - for (i = 0; i < FLASH_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(test_data, some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(test_data); -} - -static void test_write_page_mem(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t my_page_addr = test_data->page_addr; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - /* - * Enable 4BYTE mode for controller. - */ - spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); - - /* Enable 4BYTE mode for flash. */ - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, WREN); - spi_ctrl_stop_user(test_data); - - /* move out USER mode to use direct writes to the AHB bus */ - spi_ctrl_setmode(test_data, CTRL_WRITEMODE, PP); - - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - flash_writel(test_data, my_page_addr + i * 4, - make_be32(my_page_addr + i * 4)); - } - - /* Check what was written */ - read_page_mem(test_data, my_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, my_page_addr + i * 4); - } - - flash_reset(test_data); -} - -static void test_read_status_reg(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint8_t r; - - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, RDSR); - r = flash_readb(test_data, 0); - spi_ctrl_stop_user(test_data); - - g_assert_cmphex(r & SR_WEL, ==, 0); - g_assert(!qtest_qom_get_bool - (test_data->s, test_data->node, "write-enable")); - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, RDSR); - r = flash_readb(test_data, 0); - spi_ctrl_stop_user(test_data); - - g_assert_cmphex(r & SR_WEL, ==, SR_WEL); - g_assert(qtest_qom_get_bool - (test_data->s, test_data->node, "write-enable")); - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WRDI); - flash_writeb(test_data, 0, RDSR); - r = flash_readb(test_data, 0); - spi_ctrl_stop_user(test_data); - - g_assert_cmphex(r & SR_WEL, ==, 0); - g_assert(!qtest_qom_get_bool - (test_data->s, test_data->node, "write-enable")); - - flash_reset(test_data); -} - -static void test_status_reg_write_protection(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint8_t r; - - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - /* default case: WP# is high and SRWD is low -> status register writable */ - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WREN); - /* test ability to write SRWD */ - flash_writeb(test_data, 0, WRSR); - flash_writeb(test_data, 0, SRWD); - flash_writeb(test_data, 0, RDSR); - r = flash_readb(test_data, 0); - spi_ctrl_stop_user(test_data); - g_assert_cmphex(r & SRWD, ==, SRWD); - - /* WP# high and SRWD high -> status register writable */ - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WREN); - /* test ability to write SRWD */ - flash_writeb(test_data, 0, WRSR); - flash_writeb(test_data, 0, 0); - flash_writeb(test_data, 0, RDSR); - r = flash_readb(test_data, 0); - spi_ctrl_stop_user(test_data); - g_assert_cmphex(r & SRWD, ==, 0); - - /* WP# low and SRWD low -> status register writable */ - qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 0); - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WREN); - /* test ability to write SRWD */ - flash_writeb(test_data, 0, WRSR); - flash_writeb(test_data, 0, SRWD); - flash_writeb(test_data, 0, RDSR); - r = flash_readb(test_data, 0); - spi_ctrl_stop_user(test_data); - g_assert_cmphex(r & SRWD, ==, SRWD); - - /* WP# low and SRWD high -> status register NOT writable */ - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0 , WREN); - /* test ability to write SRWD */ - flash_writeb(test_data, 0, WRSR); - flash_writeb(test_data, 0, 0); - flash_writeb(test_data, 0, RDSR); - r = flash_readb(test_data, 0); - spi_ctrl_stop_user(test_data); - /* write is not successful */ - g_assert_cmphex(r & SRWD, ==, SRWD); - - qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 1); - flash_reset(test_data); -} - -static void test_write_block_protect(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t sector_size = 65536; - uint32_t n_sectors = 512; - - spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - uint32_t bp_bits = 0b0; - - for (int i = 0; i < 16; i++) { - bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2); - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, BULK_ERASE); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, WRSR); - flash_writeb(test_data, 0, bp_bits); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, WREN); - spi_ctrl_stop_user(test_data); - - uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; - uint32_t protection_start = n_sectors - num_protected_sectors; - uint32_t protection_end = n_sectors; - - for (int sector = 0; sector < n_sectors; sector++) { - uint32_t addr = sector * sector_size; - - assert_page_mem(test_data, addr, 0xffffffff); - write_page_mem(test_data, addr, make_be32(0xabcdef12)); - - uint32_t expected_value = protection_start <= sector - && sector < protection_end - ? 0xffffffff : 0xabcdef12; - - assert_page_mem(test_data, addr, expected_value); - } - } - - flash_reset(test_data); -} - -static void test_write_block_protect_bottom_bit(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t sector_size = 65536; - uint32_t n_sectors = 512; - - spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - /* top bottom bit is enabled */ - uint32_t bp_bits = 0b00100 << 3; - - for (int i = 0; i < 16; i++) { - bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2); - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, BULK_ERASE); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, WRSR); - flash_writeb(test_data, 0, bp_bits); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, WREN); - spi_ctrl_stop_user(test_data); - - uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; - uint32_t protection_start = 0; - uint32_t protection_end = num_protected_sectors; - - for (int sector = 0; sector < n_sectors; sector++) { - uint32_t addr = sector * sector_size; - - assert_page_mem(test_data, addr, 0xffffffff); - write_page_mem(test_data, addr, make_be32(0xabcdef12)); - - uint32_t expected_value = protection_start <= sector - && sector < protection_end - ? 0xffffffff : 0xabcdef12; - - assert_page_mem(test_data, addr, expected_value); - } - } - - flash_reset(test_data); -} - -static void test_write_page_qpi(const void *data) -{ - const TestData *test_data = (const TestData *)data; - uint32_t my_page_addr = test_data->page_addr; - uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; - uint32_t page[FLASH_PAGE_SIZE / 4]; - uint32_t page_pattern[] = { - 0xebd8c134, 0x5da196bc, 0xae15e729, 0x5085ccdf - }; - int i; - - spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); - - spi_ctrl_start_user(test_data); - flash_writeb(test_data, 0, EN_4BYTE_ADDR); - flash_writeb(test_data, 0, WREN); - flash_writeb(test_data, 0, PP); - flash_writel(test_data, 0, make_be32(my_page_addr)); - - /* Set QPI mode */ - spi_ctrl_set_io_mode(test_data, CTRL_IO_QUAD_IO); - - /* Fill the page pattern */ - for (i = 0; i < ARRAY_SIZE(page_pattern); i++) { - flash_writel(test_data, 0, make_be32(page_pattern[i])); - } - - /* Fill the page with its own addresses */ - for (; i < FLASH_PAGE_SIZE / 4; i++) { - flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); - } - - /* Restore io mode */ - spi_ctrl_set_io_mode(test_data, 0); - spi_ctrl_stop_user(test_data); - - /* Check what was written */ - read_page(test_data, my_page_addr, page); - for (i = 0; i < ARRAY_SIZE(page_pattern); i++) { - g_assert_cmphex(page[i], ==, page_pattern[i]); - } - for (; i < FLASH_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(test_data, some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(test_data); -} - -static void test_palmetto_bmc(TestData *data) +static void test_palmetto_bmc(AspeedSMCTestData *data) { int ret; int fd; @@ -751,25 +53,29 @@ static void test_palmetto_bmc(TestData *data) /* beyond 16MB */ data->page_addr = 0x14000 * FLASH_PAGE_SIZE; - qtest_add_data_func("/ast2400/smc/read_jedec", data, test_read_jedec); - qtest_add_data_func("/ast2400/smc/erase_sector", data, test_erase_sector); - qtest_add_data_func("/ast2400/smc/erase_all", data, test_erase_all); - qtest_add_data_func("/ast2400/smc/write_page", data, test_write_page); + qtest_add_data_func("/ast2400/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast2400/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast2400/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast2400/smc/write_page", + data, aspeed_smc_test_write_page); qtest_add_data_func("/ast2400/smc/read_page_mem", - data, test_read_page_mem); + data, aspeed_smc_test_read_page_mem); qtest_add_data_func("/ast2400/smc/write_page_mem", - data, test_write_page_mem); + data, aspeed_smc_test_write_page_mem); qtest_add_data_func("/ast2400/smc/read_status_reg", - data, test_read_status_reg); + data, aspeed_smc_test_read_status_reg); qtest_add_data_func("/ast2400/smc/status_reg_write_protection", - data, test_status_reg_write_protection); + data, aspeed_smc_test_status_reg_write_protection); qtest_add_data_func("/ast2400/smc/write_block_protect", - data, test_write_block_protect); + data, aspeed_smc_test_write_block_protect); qtest_add_data_func("/ast2400/smc/write_block_protect_bottom_bit", - data, test_write_block_protect_bottom_bit); + data, aspeed_smc_test_write_block_protect_bottom_bit); } -static void test_ast2500_evb(TestData *data) +static void test_ast2500_evb(AspeedSMCTestData *data) { int ret; int fd; @@ -794,21 +100,25 @@ static void test_ast2500_evb(TestData *data) /* beyond 16MB */ data->page_addr = 0x14000 * FLASH_PAGE_SIZE; - qtest_add_data_func("/ast2500/smc/read_jedec", data, test_read_jedec); - qtest_add_data_func("/ast2500/smc/erase_sector", data, test_erase_sector); - qtest_add_data_func("/ast2500/smc/erase_all", data, test_erase_all); - qtest_add_data_func("/ast2500/smc/write_page", data, test_write_page); + qtest_add_data_func("/ast2500/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast2500/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast2500/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast2500/smc/write_page", + data, aspeed_smc_test_write_page); qtest_add_data_func("/ast2500/smc/read_page_mem", - data, test_read_page_mem); + data, aspeed_smc_test_read_page_mem); qtest_add_data_func("/ast2500/smc/write_page_mem", - data, test_write_page_mem); + data, aspeed_smc_test_write_page_mem); qtest_add_data_func("/ast2500/smc/read_status_reg", - data, test_read_status_reg); + data, aspeed_smc_test_read_status_reg); qtest_add_data_func("/ast2500/smc/write_page_qpi", - data, test_write_page_qpi); + data, aspeed_smc_test_write_page_qpi); } -static void test_ast2600_evb(TestData *data) +static void test_ast2600_evb(AspeedSMCTestData *data) { int ret; int fd; @@ -833,21 +143,25 @@ static void test_ast2600_evb(TestData *data) /* beyond 16MB */ data->page_addr = 0x14000 * FLASH_PAGE_SIZE; - qtest_add_data_func("/ast2600/smc/read_jedec", data, test_read_jedec); - qtest_add_data_func("/ast2600/smc/erase_sector", data, test_erase_sector); - qtest_add_data_func("/ast2600/smc/erase_all", data, test_erase_all); - qtest_add_data_func("/ast2600/smc/write_page", data, test_write_page); + qtest_add_data_func("/ast2600/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast2600/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast2600/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast2600/smc/write_page", + data, aspeed_smc_test_write_page); qtest_add_data_func("/ast2600/smc/read_page_mem", - data, test_read_page_mem); + data, aspeed_smc_test_read_page_mem); qtest_add_data_func("/ast2600/smc/write_page_mem", - data, test_write_page_mem); + data, aspeed_smc_test_write_page_mem); qtest_add_data_func("/ast2600/smc/read_status_reg", - data, test_read_status_reg); + data, aspeed_smc_test_read_status_reg); qtest_add_data_func("/ast2600/smc/write_page_qpi", - data, test_write_page_qpi); + data, aspeed_smc_test_write_page_qpi); } -static void test_ast1030_evb(TestData *data) +static void test_ast1030_evb(AspeedSMCTestData *data) { int ret; int fd; @@ -872,26 +186,30 @@ static void test_ast1030_evb(TestData *data) /* beyond 512KB */ data->page_addr = 0x800 * FLASH_PAGE_SIZE; - qtest_add_data_func("/ast1030/smc/read_jedec", data, test_read_jedec); - qtest_add_data_func("/ast1030/smc/erase_sector", data, test_erase_sector); - qtest_add_data_func("/ast1030/smc/erase_all", data, test_erase_all); - qtest_add_data_func("/ast1030/smc/write_page", data, test_write_page); + qtest_add_data_func("/ast1030/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast1030/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast1030/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast1030/smc/write_page", + data, aspeed_smc_test_write_page); qtest_add_data_func("/ast1030/smc/read_page_mem", - data, test_read_page_mem); + data, aspeed_smc_test_read_page_mem); qtest_add_data_func("/ast1030/smc/write_page_mem", - data, test_write_page_mem); + data, aspeed_smc_test_write_page_mem); qtest_add_data_func("/ast1030/smc/read_status_reg", - data, test_read_status_reg); + data, aspeed_smc_test_read_status_reg); qtest_add_data_func("/ast1030/smc/write_page_qpi", - data, test_write_page_qpi); + data, aspeed_smc_test_write_page_qpi); } int main(int argc, char **argv) { - TestData palmetto_data; - TestData ast2500_evb_data; - TestData ast2600_evb_data; - TestData ast1030_evb_data; + AspeedSMCTestData palmetto_data; + AspeedSMCTestData ast2500_evb_data; + AspeedSMCTestData ast2600_evb_data; + AspeedSMCTestData ast1030_evb_data; int ret; g_test_init(&argc, &argv, NULL); diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index f2f35367ae..ea68ec1441 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -360,6 +360,7 @@ qtests = { 'virtio-net-failover': files('migration-helpers.c'), 'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'), 'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'), + 'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'), } if vnc.found() From patchwork Wed Nov 27 09:15:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jamin Lin X-Patchwork-Id: 13886748 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DD7DCD609B0 for ; Wed, 27 Nov 2024 09:18:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tGEA3-0002y1-2r; Wed, 27 Nov 2024 04:16:39 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGEA0-0002pY-9t; Wed, 27 Nov 2024 04:16:36 -0500 Received: from mail.aspeedtech.com ([211.20.114.72] helo=TWMBX01.aspeed.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tGE9y-0004aA-KK; Wed, 27 Nov 2024 04:16:36 -0500 Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.12; Wed, 27 Nov 2024 17:15:47 +0800 Received: from localhost.localdomain (192.168.10.10) by TWMBX01.aspeed.com (192.168.0.62) with Microsoft SMTP Server id 15.2.1258.12 via Frontend Transport; Wed, 27 Nov 2024 17:15:47 +0800 To: =?utf-8?q?C=C3=A9dric_Le_Goater?= , Peter Maydell , Steven Lee , Troy Lee , Andrew Jeffery , "Joel Stanley" , Fabiano Rosas , Laurent Vivier , Paolo Bonzini , "open list:ASPEED BMCs" , "open list:All patches CC here" CC: , , Subject: [PATCH v3 10/10] test/qtest/ast2700-smc-test: Support to test AST2700 Date: Wed, 27 Nov 2024 17:15:43 +0800 Message-ID: <20241127091543.1243114-11-jamin_lin@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> References: <20241127091543.1243114-1-jamin_lin@aspeedtech.com> MIME-Version: 1.0 Received-SPF: pass client-ip=211.20.114.72; envelope-from=jamin_lin@aspeedtech.com; helo=TWMBX01.aspeed.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_FAIL=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jamin Lin X-Patchwork-Original-From: Jamin Lin via From: Jamin Lin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add test_ast2700_evb function and reused testcases which are from aspeed_smc-test.c for AST2700 testing. The base address, flash base address and ce index of fmc_cs0 are 0x14000000, 0x100000000 and 0, respectively. The default flash model of fmc_cs0 is "w25q01jvq" whose size is 128MB, so set jedec_id 0xef4021. Signed-off-by: Jamin Lin --- tests/qtest/ast2700-smc-test.c | 71 ++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 4 +- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 tests/qtest/ast2700-smc-test.c diff --git a/tests/qtest/ast2700-smc-test.c b/tests/qtest/ast2700-smc-test.c new file mode 100644 index 0000000000..d1c4856307 --- /dev/null +++ b/tests/qtest/ast2700-smc-test.c @@ -0,0 +1,71 @@ +/* + * QTest testcase for the M25P80 Flash using the ASPEED SPI Controller since + * AST2700. + * + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2024 ASPEED Technology Inc. + */ + +#include "qemu/osdep.h" +#include "qemu/bswap.h" +#include "libqtest-single.h" +#include "qemu/bitops.h" +#include "aspeed-smc-utils.h" + +static void test_ast2700_evb(AspeedSMCTestData *data) +{ + int ret; + int fd; + + fd = g_file_open_tmp("qtest.m25p80.w25q01jvq.XXXXXX", + &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 128 * 1024 * 1024); + g_assert(ret == 0); + close(fd); + + data->s = qtest_initf("-machine ast2700-evb " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with w25q01jvq flash */ + data->flash_base = 0x100000000; + data->spi_base = 0x14000000; + data->jedec_id = 0xef4021; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 64MB */ + data->page_addr = 0x40000 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast2700/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast2700/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast2700/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast2700/smc/write_page", + data, aspeed_smc_test_write_page); + qtest_add_data_func("/ast2700/smc/read_page_mem", + data, aspeed_smc_test_read_page_mem); + qtest_add_data_func("/ast2700/smc/write_page_mem", + data, aspeed_smc_test_write_page_mem); + qtest_add_data_func("/ast2700/smc/read_status_reg", + data, aspeed_smc_test_read_status_reg); + qtest_add_data_func("/ast2700/smc/write_page_qpi", + data, aspeed_smc_test_write_page_qpi); +} + +int main(int argc, char **argv) +{ + AspeedSMCTestData ast2700_evb_data; + int ret; + + g_test_init(&argc, &argv, NULL); + + test_ast2700_evb(&ast2700_evb_data); + ret = g_test_run(); + + qtest_quit(ast2700_evb_data.s); + unlink(ast2700_evb_data.tmp_path); + return ret; +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index ea68ec1441..21e9320a95 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -214,7 +214,8 @@ qtests_aspeed = \ 'aspeed_smc-test', 'aspeed_gpio-test'] qtests_aspeed64 = \ - ['ast2700-gpio-test'] + ['ast2700-gpio-test', + 'ast2700-smc-test'] qtests_stm32l4x5 = \ ['stm32l4x5_exti-test', @@ -361,6 +362,7 @@ qtests = { 'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'), 'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'), 'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'), + 'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'), } if vnc.found()