1 /* 2 * QTest testcases for IBM's Flexible Service Interface (FSI) 3 * 4 * Copyright (c) 2023 IBM Corporation 5 * 6 * Authors: 7 * Ninad Palsule <ninad@linux.ibm.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13 #include "qemu/osdep.h" 14 #include <glib/gstdio.h> 15 16 #include "qemu/module.h" 17 #include "libqtest-single.h" 18 19 /* Registers from ast2600 specifications */ 20 #define ASPEED_FSI_ENGINER_TRIGGER 0x04 21 #define ASPEED_FSI_OPB0_BUS_SELECT 0x10 22 #define ASPEED_FSI_OPB1_BUS_SELECT 0x28 23 #define ASPEED_FSI_OPB0_RW_DIRECTION 0x14 24 #define ASPEED_FSI_OPB1_RW_DIRECTION 0x2c 25 #define ASPEED_FSI_OPB0_XFER_SIZE 0x18 26 #define ASPEED_FSI_OPB1_XFER_SIZE 0x30 27 #define ASPEED_FSI_OPB0_BUS_ADDR 0x1c 28 #define ASPEED_FSI_OPB1_BUS_ADDR 0x34 29 #define ASPEED_FSI_INTRRUPT_CLEAR 0x40 30 #define ASPEED_FSI_INTRRUPT_STATUS 0x48 31 #define ASPEED_FSI_OPB0_BUS_STATUS 0x80 32 #define ASPEED_FSI_OPB1_BUS_STATUS 0x8c 33 #define ASPEED_FSI_OPB0_READ_DATA 0x84 34 #define ASPEED_FSI_OPB1_READ_DATA 0x90 35 36 /* 37 * FSI Base addresses from the ast2600 specifications. 38 */ 39 #define AST2600_OPB_FSI0_BASE_ADDR 0x1e79b000 40 #define AST2600_OPB_FSI1_BASE_ADDR 0x1e79b100 41 42 static uint32_t aspeed_fsi_base_addr; 43 44 static uint32_t aspeed_fsi_readl(QTestState *s, uint32_t reg) 45 { 46 return qtest_readl(s, aspeed_fsi_base_addr + reg); 47 } 48 49 static void aspeed_fsi_writel(QTestState *s, uint32_t reg, uint32_t val) 50 { 51 qtest_writel(s, aspeed_fsi_base_addr + reg, val); 52 } 53 54 /* Setup base address and select register */ 55 static void test_fsi_setup(QTestState *s, uint32_t base_addr) 56 { 57 uint32_t curval; 58 59 aspeed_fsi_base_addr = base_addr; 60 61 /* Set the base select register */ 62 if (base_addr == AST2600_OPB_FSI0_BASE_ADDR) { 63 /* Unselect FSI1 */ 64 aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_SELECT, 0x0); 65 curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_SELECT); 66 g_assert_cmpuint(curval, ==, 0x0); 67 68 /* Select FSI0 */ 69 aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_SELECT, 0x1); 70 curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_SELECT); 71 g_assert_cmpuint(curval, ==, 0x1); 72 } else if (base_addr == AST2600_OPB_FSI1_BASE_ADDR) { 73 /* Unselect FSI0 */ 74 aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_SELECT, 0x0); 75 curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_SELECT); 76 g_assert_cmpuint(curval, ==, 0x0); 77 78 /* Select FSI1 */ 79 aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_SELECT, 0x1); 80 curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_SELECT); 81 g_assert_cmpuint(curval, ==, 0x1); 82 } else { 83 g_assert_not_reached(); 84 } 85 } 86 87 static void test_fsi_reg_change(QTestState *s, uint32_t reg, uint32_t newval) 88 { 89 uint32_t base; 90 uint32_t curval; 91 92 base = aspeed_fsi_readl(s, reg); 93 aspeed_fsi_writel(s, reg, newval); 94 curval = aspeed_fsi_readl(s, reg); 95 g_assert_cmpuint(curval, ==, newval); 96 aspeed_fsi_writel(s, reg, base); 97 curval = aspeed_fsi_readl(s, reg); 98 g_assert_cmpuint(curval, ==, base); 99 } 100 101 static void test_fsi0_master_regs(const void *data) 102 { 103 QTestState *s = (QTestState *)data; 104 105 test_fsi_setup(s, AST2600_OPB_FSI0_BASE_ADDR); 106 107 test_fsi_reg_change(s, ASPEED_FSI_OPB0_RW_DIRECTION, 0xF3F4F514); 108 test_fsi_reg_change(s, ASPEED_FSI_OPB0_XFER_SIZE, 0xF3F4F518); 109 test_fsi_reg_change(s, ASPEED_FSI_OPB0_BUS_ADDR, 0xF3F4F51c); 110 test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_CLEAR, 0xF3F4F540); 111 test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_STATUS, 0xF3F4F548); 112 test_fsi_reg_change(s, ASPEED_FSI_OPB0_BUS_STATUS, 0xF3F4F580); 113 test_fsi_reg_change(s, ASPEED_FSI_OPB0_READ_DATA, 0xF3F4F584); 114 } 115 116 static void test_fsi1_master_regs(const void *data) 117 { 118 QTestState *s = (QTestState *)data; 119 120 test_fsi_setup(s, AST2600_OPB_FSI1_BASE_ADDR); 121 122 test_fsi_reg_change(s, ASPEED_FSI_OPB1_RW_DIRECTION, 0xF3F4F514); 123 test_fsi_reg_change(s, ASPEED_FSI_OPB1_XFER_SIZE, 0xF3F4F518); 124 test_fsi_reg_change(s, ASPEED_FSI_OPB1_BUS_ADDR, 0xF3F4F51c); 125 test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_CLEAR, 0xF3F4F540); 126 test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_STATUS, 0xF3F4F548); 127 test_fsi_reg_change(s, ASPEED_FSI_OPB1_BUS_STATUS, 0xF3F4F580); 128 test_fsi_reg_change(s, ASPEED_FSI_OPB1_READ_DATA, 0xF3F4F584); 129 } 130 131 static void test_fsi0_getcfam_addr0(const void *data) 132 { 133 QTestState *s = (QTestState *)data; 134 uint32_t curval; 135 136 test_fsi_setup(s, AST2600_OPB_FSI0_BASE_ADDR); 137 138 /* Master access direction read */ 139 aspeed_fsi_writel(s, ASPEED_FSI_OPB0_RW_DIRECTION, 0x1); 140 /* word */ 141 aspeed_fsi_writel(s, ASPEED_FSI_OPB0_XFER_SIZE, 0x3); 142 /* Address */ 143 aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_ADDR, 0xa0000000); 144 aspeed_fsi_writel(s, ASPEED_FSI_INTRRUPT_CLEAR, 0x1); 145 aspeed_fsi_writel(s, ASPEED_FSI_ENGINER_TRIGGER, 0x1); 146 147 curval = aspeed_fsi_readl(s, ASPEED_FSI_INTRRUPT_STATUS); 148 g_assert_cmpuint(curval, ==, 0x10000); 149 curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_STATUS); 150 g_assert_cmpuint(curval, ==, 0x0); 151 curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_READ_DATA); 152 g_assert_cmpuint(curval, ==, 0x152d02c0); 153 } 154 155 static void test_fsi1_getcfam_addr0(const void *data) 156 { 157 QTestState *s = (QTestState *)data; 158 uint32_t curval; 159 160 test_fsi_setup(s, AST2600_OPB_FSI1_BASE_ADDR); 161 162 /* Master access direction read */ 163 aspeed_fsi_writel(s, ASPEED_FSI_OPB1_RW_DIRECTION, 0x1); 164 165 aspeed_fsi_writel(s, ASPEED_FSI_OPB1_XFER_SIZE, 0x3); 166 aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_ADDR, 0xa0000000); 167 aspeed_fsi_writel(s, ASPEED_FSI_INTRRUPT_CLEAR, 0x1); 168 aspeed_fsi_writel(s, ASPEED_FSI_ENGINER_TRIGGER, 0x1); 169 170 curval = aspeed_fsi_readl(s, ASPEED_FSI_INTRRUPT_STATUS); 171 g_assert_cmpuint(curval, ==, 0x20000); 172 curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_STATUS); 173 g_assert_cmpuint(curval, ==, 0x0); 174 curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_READ_DATA); 175 g_assert_cmpuint(curval, ==, 0x152d02c0); 176 } 177 178 int main(int argc, char **argv) 179 { 180 int ret = -1; 181 QTestState *s; 182 183 g_test_init(&argc, &argv, NULL); 184 185 s = qtest_init("-machine ast2600-evb "); 186 187 /* Tests for OPB/FSI0 */ 188 qtest_add_data_func("/aspeed-fsi-test/test_fsi0_master_regs", s, 189 test_fsi0_master_regs); 190 191 qtest_add_data_func("/aspeed-fsi-test/test_fsi0_getcfam_addr0", s, 192 test_fsi0_getcfam_addr0); 193 194 /* Tests for OPB/FSI1 */ 195 qtest_add_data_func("/aspeed-fsi-test/test_fsi1_master_regs", s, 196 test_fsi1_master_regs); 197 198 qtest_add_data_func("/aspeed-fsi-test/test_fsi1_getcfam_addr0", s, 199 test_fsi1_getcfam_addr0); 200 201 ret = g_test_run(); 202 qtest_quit(s); 203 204 return ret; 205 } 206