aboutsummaryrefslogtreecommitdiff
path: root/tests/qtest/aspeed_fsi-test.c
blob: f5ab269972e47cdf52dc1ac5d6d792a4658a8658 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
 * QTest testcases for IBM's Flexible Service Interface (FSI)
 *
 * Copyright (c) 2023 IBM Corporation
 *
 * Authors:
 *   Ninad Palsule <ninad@linux.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include <glib/gstdio.h>

#include "qemu/module.h"
#include "libqtest-single.h"

/* Registers from ast2600 specifications */
#define ASPEED_FSI_ENGINER_TRIGGER   0x04
#define ASPEED_FSI_OPB0_BUS_SELECT   0x10
#define ASPEED_FSI_OPB1_BUS_SELECT   0x28
#define ASPEED_FSI_OPB0_RW_DIRECTION 0x14
#define ASPEED_FSI_OPB1_RW_DIRECTION 0x2c
#define ASPEED_FSI_OPB0_XFER_SIZE    0x18
#define ASPEED_FSI_OPB1_XFER_SIZE    0x30
#define ASPEED_FSI_OPB0_BUS_ADDR     0x1c
#define ASPEED_FSI_OPB1_BUS_ADDR     0x34
#define ASPEED_FSI_INTRRUPT_CLEAR    0x40
#define ASPEED_FSI_INTRRUPT_STATUS   0x48
#define ASPEED_FSI_OPB0_BUS_STATUS   0x80
#define ASPEED_FSI_OPB1_BUS_STATUS   0x8c
#define ASPEED_FSI_OPB0_READ_DATA    0x84
#define ASPEED_FSI_OPB1_READ_DATA    0x90

/*
 * FSI Base addresses from the ast2600 specifications.
 */
#define AST2600_OPB_FSI0_BASE_ADDR 0x1e79b000
#define AST2600_OPB_FSI1_BASE_ADDR 0x1e79b100

static uint32_t aspeed_fsi_base_addr;

static uint32_t aspeed_fsi_readl(QTestState *s, uint32_t reg)
{
    return qtest_readl(s, aspeed_fsi_base_addr + reg);
}

static void aspeed_fsi_writel(QTestState *s, uint32_t reg, uint32_t val)
{
    qtest_writel(s, aspeed_fsi_base_addr + reg, val);
}

/* Setup base address and select register */
static void test_fsi_setup(QTestState *s, uint32_t base_addr)
{
    uint32_t curval;

    aspeed_fsi_base_addr = base_addr;

    /* Set the base select register */
    if (base_addr == AST2600_OPB_FSI0_BASE_ADDR) {
        /* Unselect FSI1 */
        aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_SELECT, 0x0);
        curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_SELECT);
        g_assert_cmphex(curval, ==, 0x0);

        /* Select FSI0 */
        aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_SELECT, 0x1);
        curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_SELECT);
        g_assert_cmphex(curval, ==, 0x1);
    } else if (base_addr == AST2600_OPB_FSI1_BASE_ADDR) {
        /* Unselect FSI0 */
        aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_SELECT, 0x0);
        curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_SELECT);
        g_assert_cmphex(curval, ==, 0x0);

        /* Select FSI1 */
        aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_SELECT, 0x1);
        curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_SELECT);
        g_assert_cmphex(curval, ==, 0x1);
    } else {
        g_assert_not_reached();
    }
}

static void test_fsi_reg_change(QTestState *s, uint32_t reg, uint32_t newval)
{
    uint32_t base;
    uint32_t curval;

    base = aspeed_fsi_readl(s, reg);
    aspeed_fsi_writel(s, reg, newval);
    curval = aspeed_fsi_readl(s, reg);
    g_assert_cmpuint(curval, ==, newval);
    aspeed_fsi_writel(s, reg, base);
    curval = aspeed_fsi_readl(s, reg);
    g_assert_cmpuint(curval, ==, base);
}

static void test_fsi0_master_regs(const void *data)
{
    QTestState *s = (QTestState *)data;

    test_fsi_setup(s, AST2600_OPB_FSI0_BASE_ADDR);

    test_fsi_reg_change(s, ASPEED_FSI_OPB0_RW_DIRECTION, 0xF3F4F514);
    test_fsi_reg_change(s, ASPEED_FSI_OPB0_XFER_SIZE, 0xF3F4F518);
    test_fsi_reg_change(s, ASPEED_FSI_OPB0_BUS_ADDR, 0xF3F4F51c);
    test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_CLEAR, 0xF3F4F540);
    test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_STATUS, 0xF3F4F548);
    test_fsi_reg_change(s, ASPEED_FSI_OPB0_BUS_STATUS, 0xF3F4F580);
    test_fsi_reg_change(s, ASPEED_FSI_OPB0_READ_DATA, 0xF3F4F584);
}

static void test_fsi1_master_regs(const void *data)
{
    QTestState *s = (QTestState *)data;

    test_fsi_setup(s, AST2600_OPB_FSI1_BASE_ADDR);

    test_fsi_reg_change(s, ASPEED_FSI_OPB1_RW_DIRECTION, 0xF3F4F514);
    test_fsi_reg_change(s, ASPEED_FSI_OPB1_XFER_SIZE, 0xF3F4F518);
    test_fsi_reg_change(s, ASPEED_FSI_OPB1_BUS_ADDR, 0xF3F4F51c);
    test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_CLEAR, 0xF3F4F540);
    test_fsi_reg_change(s, ASPEED_FSI_INTRRUPT_STATUS, 0xF3F4F548);
    test_fsi_reg_change(s, ASPEED_FSI_OPB1_BUS_STATUS, 0xF3F4F580);
    test_fsi_reg_change(s, ASPEED_FSI_OPB1_READ_DATA, 0xF3F4F584);
}

static void test_fsi0_getcfam_addr0(const void *data)
{
    QTestState *s = (QTestState *)data;
    uint32_t curval;

    test_fsi_setup(s, AST2600_OPB_FSI0_BASE_ADDR);

    /* Master access direction read */
    aspeed_fsi_writel(s, ASPEED_FSI_OPB0_RW_DIRECTION, 0x1);
    /* word */
    aspeed_fsi_writel(s, ASPEED_FSI_OPB0_XFER_SIZE, 0x3);
    /* Address */
    aspeed_fsi_writel(s, ASPEED_FSI_OPB0_BUS_ADDR, 0xa0000000);
    aspeed_fsi_writel(s, ASPEED_FSI_INTRRUPT_CLEAR, 0x1);
    aspeed_fsi_writel(s, ASPEED_FSI_ENGINER_TRIGGER, 0x1);

    curval = aspeed_fsi_readl(s, ASPEED_FSI_INTRRUPT_STATUS);
    g_assert_cmphex(curval, ==, 0x10000);
    curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_BUS_STATUS);
    g_assert_cmphex(curval, ==, 0x0);
    curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB0_READ_DATA);
    g_assert_cmphex(curval, ==, 0x152d02c0);
}

static void test_fsi1_getcfam_addr0(const void *data)
{
    QTestState *s = (QTestState *)data;
    uint32_t curval;

    test_fsi_setup(s, AST2600_OPB_FSI1_BASE_ADDR);

    /* Master access direction read */
    aspeed_fsi_writel(s, ASPEED_FSI_OPB1_RW_DIRECTION, 0x1);

    aspeed_fsi_writel(s, ASPEED_FSI_OPB1_XFER_SIZE, 0x3);
    aspeed_fsi_writel(s, ASPEED_FSI_OPB1_BUS_ADDR, 0xa0000000);
    aspeed_fsi_writel(s, ASPEED_FSI_INTRRUPT_CLEAR, 0x1);
    aspeed_fsi_writel(s, ASPEED_FSI_ENGINER_TRIGGER, 0x1);

    curval = aspeed_fsi_readl(s, ASPEED_FSI_INTRRUPT_STATUS);
    g_assert_cmphex(curval, ==, 0x20000);
    curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_BUS_STATUS);
    g_assert_cmphex(curval, ==, 0x0);
    curval = aspeed_fsi_readl(s, ASPEED_FSI_OPB1_READ_DATA);
    g_assert_cmphex(curval, ==, 0x152d02c0);
}

int main(int argc, char **argv)
{
    int ret = -1;
    QTestState *s;

    g_test_init(&argc, &argv, NULL);

    s = qtest_init("-machine ast2600-evb ");

    /* Tests for OPB/FSI0 */
    qtest_add_data_func("/aspeed-fsi-test/test_fsi0_master_regs", s,
                        test_fsi0_master_regs);

    qtest_add_data_func("/aspeed-fsi-test/test_fsi0_getcfam_addr0", s,
                        test_fsi0_getcfam_addr0);

    /* Tests for OPB/FSI1 */
    qtest_add_data_func("/aspeed-fsi-test/test_fsi1_master_regs", s,
                        test_fsi1_master_regs);

    qtest_add_data_func("/aspeed-fsi-test/test_fsi1_getcfam_addr0", s,
                        test_fsi1_getcfam_addr0);

    ret = g_test_run();
    qtest_quit(s);

    return ret;
}