xref: /openbmc/qemu/tests/qtest/aspeed_fsi-test.c (revision 412a91f6)
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