Statistics
| Branch: | Revision:

root / tests / i440fx-test.c @ f53ec699

History | View | Annotate | Download (8.3 kB)

1
/*
2
 * qtest I440FX test case
3
 *
4
 * Copyright IBM, Corp. 2012-2013
5
 *
6
 * Authors:
7
 *  Anthony Liguori   <aliguori@us.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 "libqos/pci.h"
14
#include "libqos/pci-pc.h"
15
#include "libqtest.h"
16

    
17
#include "hw/pci/pci_regs.h"
18

    
19
#include <glib.h>
20
#include <string.h>
21

    
22
#define BROKEN 1
23

    
24
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
25

    
26
typedef struct TestData
27
{
28
    int num_cpus;
29
    QPCIBus *bus;
30
} TestData;
31

    
32
static void test_i440fx_defaults(gconstpointer opaque)
33
{
34
    const TestData *s = opaque;
35
    QPCIDevice *dev;
36
    uint32_t value;
37

    
38
    dev = qpci_device_find(s->bus, QPCI_DEVFN(0, 0));
39
    g_assert(dev != NULL);
40

    
41
    /* 3.2.2 */
42
    g_assert_cmpint(qpci_config_readw(dev, PCI_VENDOR_ID), ==, 0x8086);
43
    /* 3.2.3 */
44
    g_assert_cmpint(qpci_config_readw(dev, PCI_DEVICE_ID), ==, 0x1237);
45
#ifndef BROKEN
46
    /* 3.2.4 */
47
    g_assert_cmpint(qpci_config_readw(dev, PCI_COMMAND), ==, 0x0006);
48
    /* 3.2.5 */
49
    g_assert_cmpint(qpci_config_readw(dev, PCI_STATUS), ==, 0x0280);
50
#endif
51
    /* 3.2.7 */
52
    g_assert_cmpint(qpci_config_readb(dev, PCI_CLASS_PROG), ==, 0x00);
53
    g_assert_cmpint(qpci_config_readw(dev, PCI_CLASS_DEVICE), ==, 0x0600);
54
    /* 3.2.8 */
55
    g_assert_cmpint(qpci_config_readb(dev, PCI_LATENCY_TIMER), ==, 0x00);
56
    /* 3.2.9 */
57
    g_assert_cmpint(qpci_config_readb(dev, PCI_HEADER_TYPE), ==, 0x00);
58
    /* 3.2.10 */
59
    g_assert_cmpint(qpci_config_readb(dev, PCI_BIST), ==, 0x00);
60

    
61
    /* 3.2.11 */
62
    value = qpci_config_readw(dev, 0x50); /* PMCCFG */
63
    if (s->num_cpus == 1) { /* WPE */
64
        g_assert(!(value & (1 << 15)));
65
    } else {
66
        g_assert((value & (1 << 15)));
67
    }
68

    
69
    g_assert(!(value & (1 << 6))); /* EPTE */
70

    
71
    /* 3.2.12 */
72
    g_assert_cmpint(qpci_config_readb(dev, 0x52), ==, 0x00); /* DETURBO */
73
    /* 3.2.13 */
74
#ifndef BROKEN
75
    g_assert_cmpint(qpci_config_readb(dev, 0x53), ==, 0x80); /* DBC */
76
#endif
77
    /* 3.2.14 */
78
    g_assert_cmpint(qpci_config_readb(dev, 0x54), ==, 0x00); /* AXC */
79
    /* 3.2.15 */
80
    g_assert_cmpint(qpci_config_readw(dev, 0x55), ==, 0x0000); /* DRT */
81
#ifndef BROKEN
82
    /* 3.2.16 */
83
    g_assert_cmpint(qpci_config_readb(dev, 0x57), ==, 0x01); /* DRAMC */
84
    /* 3.2.17 */
85
    g_assert_cmpint(qpci_config_readb(dev, 0x58), ==, 0x10); /* DRAMT */
86
#endif
87
    /* 3.2.18 */
88
    g_assert_cmpint(qpci_config_readb(dev, 0x59), ==, 0x00); /* PAM0 */
89
    g_assert_cmpint(qpci_config_readb(dev, 0x5A), ==, 0x00); /* PAM1 */
90
    g_assert_cmpint(qpci_config_readb(dev, 0x5B), ==, 0x00); /* PAM2 */
91
    g_assert_cmpint(qpci_config_readb(dev, 0x5C), ==, 0x00); /* PAM3 */
92
    g_assert_cmpint(qpci_config_readb(dev, 0x5D), ==, 0x00); /* PAM4 */
93
    g_assert_cmpint(qpci_config_readb(dev, 0x5E), ==, 0x00); /* PAM5 */
94
    g_assert_cmpint(qpci_config_readb(dev, 0x5F), ==, 0x00); /* PAM6 */
95
#ifndef BROKEN
96
    /* 3.2.19 */
97
    g_assert_cmpint(qpci_config_readb(dev, 0x60), ==, 0x01); /* DRB0 */
98
    g_assert_cmpint(qpci_config_readb(dev, 0x61), ==, 0x01); /* DRB1 */
99
    g_assert_cmpint(qpci_config_readb(dev, 0x62), ==, 0x01); /* DRB2 */
100
    g_assert_cmpint(qpci_config_readb(dev, 0x63), ==, 0x01); /* DRB3 */
101
    g_assert_cmpint(qpci_config_readb(dev, 0x64), ==, 0x01); /* DRB4 */
102
    g_assert_cmpint(qpci_config_readb(dev, 0x65), ==, 0x01); /* DRB5 */
103
    g_assert_cmpint(qpci_config_readb(dev, 0x66), ==, 0x01); /* DRB6 */
104
    g_assert_cmpint(qpci_config_readb(dev, 0x67), ==, 0x01); /* DRB7 */
105
#endif
106
    /* 3.2.20 */
107
    g_assert_cmpint(qpci_config_readb(dev, 0x68), ==, 0x00); /* FDHC */
108
    /* 3.2.21 */
109
    g_assert_cmpint(qpci_config_readb(dev, 0x70), ==, 0x00); /* MTT */
110
#ifndef BROKEN
111
    /* 3.2.22 */
112
    g_assert_cmpint(qpci_config_readb(dev, 0x71), ==, 0x10); /* CLT */
113
#endif
114
    /* 3.2.23 */
115
    g_assert_cmpint(qpci_config_readb(dev, 0x72), ==, 0x02); /* SMRAM */
116
    /* 3.2.24 */
117
    g_assert_cmpint(qpci_config_readb(dev, 0x90), ==, 0x00); /* ERRCMD */
118
    /* 3.2.25 */
119
    g_assert_cmpint(qpci_config_readb(dev, 0x91), ==, 0x00); /* ERRSTS */
120
    /* 3.2.26 */
121
    g_assert_cmpint(qpci_config_readb(dev, 0x93), ==, 0x00); /* TRC */
122
}
123

    
124
#define PAM_RE 1
125
#define PAM_WE 2
126

    
127
static void pam_set(QPCIDevice *dev, int index, int flags)
128
{
129
    int regno = 0x59 + (index / 2);
130
    uint8_t reg;
131

    
132
    reg = qpci_config_readb(dev, regno);
133
    if (index & 1) {
134
        reg = (reg & 0x0F) | (flags << 4);
135
    } else {
136
        reg = (reg & 0xF0) | flags;
137
    }
138
    qpci_config_writeb(dev, regno, reg);
139
}
140

    
141
static gboolean verify_area(uint32_t start, uint32_t end, uint8_t value)
142
{
143
    uint32_t size = end - start + 1;
144
    gboolean ret = TRUE;
145
    uint8_t *data;
146
    int i;
147

    
148
    data = g_malloc0(size);
149
    memread(start, data, size);
150

    
151
    g_test_message("verify_area: data[0] = 0x%x", data[0]);
152

    
153
    for (i = 0; i < size; i++) {
154
        if (data[i] != value) {
155
            ret = FALSE;
156
            break;
157
        }
158
    }
159

    
160
    g_free(data);
161

    
162
    return ret;
163
}
164

    
165
static void write_area(uint32_t start, uint32_t end, uint8_t value)
166
{
167
    uint32_t size = end - start + 1;
168
    uint8_t *data;
169

    
170
    data = g_malloc0(size);
171
    memset(data, value, size);
172
    memwrite(start, data, size);
173

    
174
    g_free(data);
175
}
176

    
177
static void test_i440fx_pam(gconstpointer opaque)
178
{
179
    const TestData *s = opaque;
180
    QPCIDevice *dev;
181
    int i;
182
    static struct {
183
        uint32_t start;
184
        uint32_t end;
185
    } pam_area[] = {
186
        { 0, 0 },             /* Reserved */
187
        { 0xF0000, 0xFFFFF }, /* BIOS Area */
188
        { 0xC0000, 0xC3FFF }, /* Option ROM */
189
        { 0xC4000, 0xC7FFF }, /* Option ROM */
190
        { 0xC8000, 0xCBFFF }, /* Option ROM */
191
        { 0xCC000, 0xCFFFF }, /* Option ROM */
192
        { 0xD0000, 0xD3FFF }, /* Option ROM */
193
        { 0xD4000, 0xD7FFF }, /* Option ROM */
194
        { 0xD8000, 0xDBFFF }, /* Option ROM */
195
        { 0xDC000, 0xDFFFF }, /* Option ROM */
196
        { 0xE0000, 0xE3FFF }, /* BIOS Extension */
197
        { 0xE4000, 0xE7FFF }, /* BIOS Extension */
198
        { 0xE8000, 0xEBFFF }, /* BIOS Extension */
199
        { 0xEC000, 0xEFFFF }, /* BIOS Extension */
200
    };
201

    
202
    dev = qpci_device_find(s->bus, QPCI_DEVFN(0, 0));
203
    g_assert(dev != NULL);
204

    
205
    for (i = 0; i < ARRAY_SIZE(pam_area); i++) {
206
        if (pam_area[i].start == pam_area[i].end) {
207
            continue;
208
        }
209

    
210
        g_test_message("Checking area 0x%05x..0x%05x",
211
                       pam_area[i].start, pam_area[i].end);
212
        /* Switch to RE for the area */
213
        pam_set(dev, i, PAM_RE);
214
        /* Verify the RAM is all zeros */
215
        g_assert(verify_area(pam_area[i].start, pam_area[i].end, 0));
216

    
217
        /* Switch to WE for the area */
218
        pam_set(dev, i, PAM_RE | PAM_WE);
219
        /* Write out a non-zero mask to the full area */
220
        write_area(pam_area[i].start, pam_area[i].end, 0x42);
221

    
222
#ifndef BROKEN
223
        /* QEMU only supports a limited form of PAM */
224

    
225
        /* Switch to !RE for the area */
226
        pam_set(dev, i, PAM_WE);
227
        /* Verify the area is not our mask */
228
        g_assert(!verify_area(pam_area[i].start, pam_area[i].end, 0x42));
229
#endif
230

    
231
        /* Verify the area is our new mask */
232
        g_assert(verify_area(pam_area[i].start, pam_area[i].end, 0x42));
233

    
234
        /* Write out a new mask */
235
        write_area(pam_area[i].start, pam_area[i].end, 0x82);
236

    
237
#ifndef BROKEN
238
        /* QEMU only supports a limited form of PAM */
239

    
240
        /* Verify the area is not our mask */
241
        g_assert(!verify_area(pam_area[i].start, pam_area[i].end, 0x82));
242

    
243
        /* Switch to RE for the area */
244
        pam_set(dev, i, PAM_RE | PAM_WE);
245
#endif
246
        /* Verify the area is our new mask */
247
        g_assert(verify_area(pam_area[i].start, pam_area[i].end, 0x82));
248

    
249
        /* Reset area */
250
        pam_set(dev, i, 0);
251

    
252
        /* Verify the area is not our new mask */
253
        g_assert(!verify_area(pam_area[i].start, pam_area[i].end, 0x82));
254
    }
255
}
256

    
257
int main(int argc, char **argv)
258
{
259
    QTestState *s;
260
    TestData data;
261
    char *cmdline;
262
    int ret;
263

    
264
    g_test_init(&argc, &argv, NULL);
265

    
266
    data.num_cpus = 1;
267

    
268
    cmdline = g_strdup_printf("-display none -smp %d", data.num_cpus);
269
    s = qtest_start(cmdline);
270
    g_free(cmdline);
271

    
272
    data.bus = qpci_init_pc();
273

    
274
    g_test_add_data_func("/i440fx/defaults", &data, test_i440fx_defaults);
275
    g_test_add_data_func("/i440fx/pam", &data, test_i440fx_pam);
276
    
277

    
278
    ret = g_test_run();
279

    
280
    if (s) {
281
        qtest_quit(s);
282
    }
283

    
284
    return ret;
285
}