Statistics
| Branch: | Revision:

root / tests / hd-geo-test.c @ 5e954943

History | View | Annotate | Download (10.5 kB)

1 0e8a8c8f Markus Armbruster
/*
2 0e8a8c8f Markus Armbruster
 * Hard disk geometry test cases.
3 0e8a8c8f Markus Armbruster
 *
4 0e8a8c8f Markus Armbruster
 * Copyright (c) 2012 Red Hat Inc.
5 0e8a8c8f Markus Armbruster
 *
6 0e8a8c8f Markus Armbruster
 * Authors:
7 0e8a8c8f Markus Armbruster
 *  Markus Armbruster <armbru@redhat.com>,
8 0e8a8c8f Markus Armbruster
 *
9 0e8a8c8f Markus Armbruster
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 0e8a8c8f Markus Armbruster
 * See the COPYING file in the top-level directory.
11 0e8a8c8f Markus Armbruster
 */
12 0e8a8c8f Markus Armbruster
13 0e8a8c8f Markus Armbruster
/*
14 0e8a8c8f Markus Armbruster
 * Covers only IDE and tests only CMOS contents.  Better than nothing.
15 0e8a8c8f Markus Armbruster
 * Improvements welcome.
16 0e8a8c8f Markus Armbruster
 */
17 0e8a8c8f Markus Armbruster
18 0e8a8c8f Markus Armbruster
#include <glib.h>
19 0e8a8c8f Markus Armbruster
#include <stdlib.h>
20 0e8a8c8f Markus Armbruster
#include <string.h>
21 0e8a8c8f Markus Armbruster
#include <unistd.h>
22 0e8a8c8f Markus Armbruster
#include "qemu-common.h"
23 0e8a8c8f Markus Armbruster
#include "libqtest.h"
24 0e8a8c8f Markus Armbruster
25 0e8a8c8f Markus Armbruster
static const char test_image[] = "/tmp/qtest.XXXXXX";
26 0e8a8c8f Markus Armbruster
27 0e8a8c8f Markus Armbruster
static char *create_test_img(int secs)
28 0e8a8c8f Markus Armbruster
{
29 0e8a8c8f Markus Armbruster
    char *template = strdup("/tmp/qtest.XXXXXX");
30 0e8a8c8f Markus Armbruster
    int fd, ret;
31 0e8a8c8f Markus Armbruster
32 0e8a8c8f Markus Armbruster
    fd = mkstemp(template);
33 0e8a8c8f Markus Armbruster
    g_assert(fd >= 0);
34 0e8a8c8f Markus Armbruster
    ret = ftruncate(fd, (off_t)secs * 512);
35 0e8a8c8f Markus Armbruster
    g_assert(ret == 0);
36 0e8a8c8f Markus Armbruster
    close(fd);
37 0e8a8c8f Markus Armbruster
    return template;
38 0e8a8c8f Markus Armbruster
}
39 0e8a8c8f Markus Armbruster
40 0e8a8c8f Markus Armbruster
typedef struct {
41 0e8a8c8f Markus Armbruster
    int cyls, heads, secs, trans;
42 0e8a8c8f Markus Armbruster
} CHST;
43 0e8a8c8f Markus Armbruster
44 0e8a8c8f Markus Armbruster
typedef enum {
45 0e8a8c8f Markus Armbruster
    mbr_blank, mbr_lba, mbr_chs,
46 0e8a8c8f Markus Armbruster
    mbr_last
47 0e8a8c8f Markus Armbruster
} MBRcontents;
48 0e8a8c8f Markus Armbruster
49 0e8a8c8f Markus Armbruster
typedef enum {
50 0e8a8c8f Markus Armbruster
    /* order is relevant */
51 0e8a8c8f Markus Armbruster
    backend_small, backend_large, backend_empty,
52 0e8a8c8f Markus Armbruster
    backend_last
53 0e8a8c8f Markus Armbruster
} Backend;
54 0e8a8c8f Markus Armbruster
55 0e8a8c8f Markus Armbruster
static const int img_secs[backend_last] = {
56 0e8a8c8f Markus Armbruster
    [backend_small] = 61440,
57 0e8a8c8f Markus Armbruster
    [backend_large] = 8388608,
58 0e8a8c8f Markus Armbruster
    [backend_empty] = -1,
59 0e8a8c8f Markus Armbruster
};
60 0e8a8c8f Markus Armbruster
61 0e8a8c8f Markus Armbruster
static const CHST hd_chst[backend_last][mbr_last] = {
62 0e8a8c8f Markus Armbruster
    [backend_small] = {
63 0e8a8c8f Markus Armbruster
        [mbr_blank] = { 60, 16, 63, 0 },
64 0e8a8c8f Markus Armbruster
        [mbr_lba]   = { 60, 16, 63, 2 },
65 0e8a8c8f Markus Armbruster
        [mbr_chs]   = { 60, 16, 63, 0 }
66 0e8a8c8f Markus Armbruster
    },
67 0e8a8c8f Markus Armbruster
    [backend_large] = {
68 0e8a8c8f Markus Armbruster
        [mbr_blank] = { 8322, 16, 63, 1 },
69 0e8a8c8f Markus Armbruster
        [mbr_lba]   = { 8322, 16, 63, 1 },
70 0e8a8c8f Markus Armbruster
        [mbr_chs]   = { 8322, 16, 63, 0 }
71 0e8a8c8f Markus Armbruster
    },
72 0e8a8c8f Markus Armbruster
};
73 0e8a8c8f Markus Armbruster
74 0e8a8c8f Markus Armbruster
static const char *img_file_name[backend_last];
75 0e8a8c8f Markus Armbruster
76 0e8a8c8f Markus Armbruster
static const CHST *cur_ide[4];
77 0e8a8c8f Markus Armbruster
78 0e8a8c8f Markus Armbruster
static bool is_hd(const CHST *expected_chst)
79 0e8a8c8f Markus Armbruster
{
80 0e8a8c8f Markus Armbruster
    return expected_chst && expected_chst->cyls;
81 0e8a8c8f Markus Armbruster
}
82 0e8a8c8f Markus Armbruster
83 0e8a8c8f Markus Armbruster
static void test_cmos_byte(int reg, int expected)
84 0e8a8c8f Markus Armbruster
{
85 0e8a8c8f Markus Armbruster
    enum { cmos_base = 0x70 };
86 0e8a8c8f Markus Armbruster
    int actual;
87 0e8a8c8f Markus Armbruster
88 0e8a8c8f Markus Armbruster
    outb(cmos_base + 0, reg);
89 0e8a8c8f Markus Armbruster
    actual = inb(cmos_base + 1);
90 0e8a8c8f Markus Armbruster
    g_assert(actual == expected);
91 0e8a8c8f Markus Armbruster
}
92 0e8a8c8f Markus Armbruster
93 0e8a8c8f Markus Armbruster
static void test_cmos_bytes(int reg0, int n, uint8_t expected[])
94 0e8a8c8f Markus Armbruster
{
95 0e8a8c8f Markus Armbruster
    int i;
96 0e8a8c8f Markus Armbruster
97 0e8a8c8f Markus Armbruster
    for (i = 0; i < 9; i++) {
98 0e8a8c8f Markus Armbruster
        test_cmos_byte(reg0 + i, expected[i]);
99 0e8a8c8f Markus Armbruster
    }
100 0e8a8c8f Markus Armbruster
}
101 0e8a8c8f Markus Armbruster
102 0e8a8c8f Markus Armbruster
static void test_cmos_disk_data(void)
103 0e8a8c8f Markus Armbruster
{
104 0e8a8c8f Markus Armbruster
    test_cmos_byte(0x12,
105 0e8a8c8f Markus Armbruster
                   (is_hd(cur_ide[0]) ? 0xf0 : 0) |
106 0e8a8c8f Markus Armbruster
                   (is_hd(cur_ide[1]) ? 0x0f : 0));
107 0e8a8c8f Markus Armbruster
}
108 0e8a8c8f Markus Armbruster
109 0e8a8c8f Markus Armbruster
static void test_cmos_drive_cyl(int reg0, const CHST *expected_chst)
110 0e8a8c8f Markus Armbruster
{
111 0e8a8c8f Markus Armbruster
    if (is_hd(expected_chst)) {
112 0e8a8c8f Markus Armbruster
        int c = expected_chst->cyls;
113 0e8a8c8f Markus Armbruster
        int h = expected_chst->heads;
114 0e8a8c8f Markus Armbruster
        int s = expected_chst->secs;
115 0e8a8c8f Markus Armbruster
        uint8_t expected_bytes[9] = {
116 0e8a8c8f Markus Armbruster
            c & 0xff, c >> 8, h, 0xff, 0xff, 0xc0 | ((h > 8) << 3),
117 0e8a8c8f Markus Armbruster
            c & 0xff, c >> 8, s
118 0e8a8c8f Markus Armbruster
        };
119 0e8a8c8f Markus Armbruster
        test_cmos_bytes(reg0, 9, expected_bytes);
120 0e8a8c8f Markus Armbruster
    } else {
121 0e8a8c8f Markus Armbruster
        int i;
122 0e8a8c8f Markus Armbruster
123 0e8a8c8f Markus Armbruster
        for (i = 0; i < 9; i++) {
124 0e8a8c8f Markus Armbruster
            test_cmos_byte(reg0 + i, 0);
125 0e8a8c8f Markus Armbruster
        }
126 0e8a8c8f Markus Armbruster
    }
127 0e8a8c8f Markus Armbruster
}
128 0e8a8c8f Markus Armbruster
129 0e8a8c8f Markus Armbruster
static void test_cmos_drive1(void)
130 0e8a8c8f Markus Armbruster
{
131 0e8a8c8f Markus Armbruster
    test_cmos_byte(0x19, is_hd(cur_ide[0]) ? 47 : 0);
132 0e8a8c8f Markus Armbruster
    test_cmos_drive_cyl(0x1b, cur_ide[0]);
133 0e8a8c8f Markus Armbruster
}
134 0e8a8c8f Markus Armbruster
135 0e8a8c8f Markus Armbruster
static void test_cmos_drive2(void)
136 0e8a8c8f Markus Armbruster
{
137 0e8a8c8f Markus Armbruster
    test_cmos_byte(0x1a, is_hd(cur_ide[1]) ? 47 : 0);
138 0e8a8c8f Markus Armbruster
    test_cmos_drive_cyl(0x24, cur_ide[1]);
139 0e8a8c8f Markus Armbruster
}
140 0e8a8c8f Markus Armbruster
141 0e8a8c8f Markus Armbruster
static void test_cmos_disktransflag(void)
142 0e8a8c8f Markus Armbruster
{
143 0e8a8c8f Markus Armbruster
    int val, i;
144 0e8a8c8f Markus Armbruster
145 0e8a8c8f Markus Armbruster
    val = 0;
146 0e8a8c8f Markus Armbruster
    for (i = 0; i < ARRAY_SIZE(cur_ide); i++) {
147 0e8a8c8f Markus Armbruster
        if (is_hd(cur_ide[i])) {
148 0e8a8c8f Markus Armbruster
            val |= cur_ide[i]->trans << (2 * i);
149 0e8a8c8f Markus Armbruster
        }
150 0e8a8c8f Markus Armbruster
    }
151 0e8a8c8f Markus Armbruster
    test_cmos_byte(0x39, val);
152 0e8a8c8f Markus Armbruster
}
153 0e8a8c8f Markus Armbruster
154 0e8a8c8f Markus Armbruster
static void test_cmos(void)
155 0e8a8c8f Markus Armbruster
{
156 0e8a8c8f Markus Armbruster
    test_cmos_disk_data();
157 0e8a8c8f Markus Armbruster
    test_cmos_drive1();
158 0e8a8c8f Markus Armbruster
    test_cmos_drive2();
159 0e8a8c8f Markus Armbruster
    test_cmos_disktransflag();
160 0e8a8c8f Markus Armbruster
}
161 0e8a8c8f Markus Armbruster
162 0e8a8c8f Markus Armbruster
static int append_arg(int argc, char *argv[], int argv_sz, char *arg)
163 0e8a8c8f Markus Armbruster
{
164 0e8a8c8f Markus Armbruster
    g_assert(argc + 1 < argv_sz);
165 0e8a8c8f Markus Armbruster
    argv[argc++] = arg;
166 0e8a8c8f Markus Armbruster
    argv[argc] = NULL;
167 0e8a8c8f Markus Armbruster
    return argc;
168 0e8a8c8f Markus Armbruster
}
169 0e8a8c8f Markus Armbruster
170 0e8a8c8f Markus Armbruster
static int setup_common(char *argv[], int argv_sz)
171 0e8a8c8f Markus Armbruster
{
172 0e8a8c8f Markus Armbruster
    memset(cur_ide, 0, sizeof(cur_ide));
173 0e8a8c8f Markus Armbruster
    return append_arg(0, argv, argv_sz,
174 2ad645d2 Andreas Fรคrber
                      g_strdup("-nodefaults"));
175 0e8a8c8f Markus Armbruster
}
176 0e8a8c8f Markus Armbruster
177 0e8a8c8f Markus Armbruster
static void setup_mbr(int img_idx, MBRcontents mbr)
178 0e8a8c8f Markus Armbruster
{
179 0e8a8c8f Markus Armbruster
    static const uint8_t part_lba[16] = {
180 0e8a8c8f Markus Armbruster
        /* chs 0,1,1 (lba 63) to chs 0,127,63 (8001 sectors) */
181 0e8a8c8f Markus Armbruster
        0x80, 1, 1, 0, 6, 127, 63, 0, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
182 0e8a8c8f Markus Armbruster
    };
183 0e8a8c8f Markus Armbruster
    static const uint8_t part_chs[16] = {
184 0e8a8c8f Markus Armbruster
        /* chs 0,1,1 (lba 63) to chs 7,15,63 (8001 sectors) */
185 0e8a8c8f Markus Armbruster
        0x80, 1, 1, 0, 6,  15, 63, 7, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
186 0e8a8c8f Markus Armbruster
    };
187 0e8a8c8f Markus Armbruster
    uint8_t buf[512];
188 0e8a8c8f Markus Armbruster
    int fd, ret;
189 0e8a8c8f Markus Armbruster
190 0e8a8c8f Markus Armbruster
    memset(buf, 0, sizeof(buf));
191 0e8a8c8f Markus Armbruster
192 0e8a8c8f Markus Armbruster
    if (mbr != mbr_blank) {
193 0e8a8c8f Markus Armbruster
        buf[0x1fe] = 0x55;
194 0e8a8c8f Markus Armbruster
        buf[0x1ff] = 0xAA;
195 0e8a8c8f Markus Armbruster
        memcpy(buf + 0x1BE, mbr == mbr_lba ? part_lba : part_chs, 16);
196 0e8a8c8f Markus Armbruster
    }
197 0e8a8c8f Markus Armbruster
198 0e8a8c8f Markus Armbruster
    fd = open(img_file_name[img_idx], O_WRONLY);
199 0e8a8c8f Markus Armbruster
    g_assert(fd >= 0);
200 0e8a8c8f Markus Armbruster
    ret = write(fd, buf, sizeof(buf));
201 0e8a8c8f Markus Armbruster
    g_assert(ret == sizeof(buf));
202 0e8a8c8f Markus Armbruster
    close(fd);
203 0e8a8c8f Markus Armbruster
}
204 0e8a8c8f Markus Armbruster
205 0e8a8c8f Markus Armbruster
static int setup_ide(int argc, char *argv[], int argv_sz,
206 0e8a8c8f Markus Armbruster
                     int ide_idx, const char *dev, int img_idx,
207 0e8a8c8f Markus Armbruster
                     MBRcontents mbr, const char *opts)
208 0e8a8c8f Markus Armbruster
{
209 0e8a8c8f Markus Armbruster
    char *s1, *s2, *s3;
210 0e8a8c8f Markus Armbruster
211 0e8a8c8f Markus Armbruster
    s1 = g_strdup_printf("-drive id=drive%d,if=%s",
212 0e8a8c8f Markus Armbruster
                         ide_idx, dev ? "none" : "ide");
213 0e8a8c8f Markus Armbruster
    s2 = dev ? g_strdup("") : g_strdup_printf(",index=%d", ide_idx);
214 0e8a8c8f Markus Armbruster
215 0e8a8c8f Markus Armbruster
    if (img_secs[img_idx] >= 0) {
216 0e8a8c8f Markus Armbruster
        setup_mbr(img_idx, mbr);
217 0e8a8c8f Markus Armbruster
        s3 = g_strdup_printf(",file=%s", img_file_name[img_idx]);
218 0e8a8c8f Markus Armbruster
    } else {
219 0e8a8c8f Markus Armbruster
        s3 = g_strdup(",media=cdrom");
220 0e8a8c8f Markus Armbruster
    }
221 0e8a8c8f Markus Armbruster
    argc = append_arg(argc, argv, argv_sz,
222 0e8a8c8f Markus Armbruster
                      g_strdup_printf("%s%s%s%s", s1, s2, s3, opts));
223 0e8a8c8f Markus Armbruster
    g_free(s1);
224 0e8a8c8f Markus Armbruster
    g_free(s2);
225 0e8a8c8f Markus Armbruster
    g_free(s3);
226 0e8a8c8f Markus Armbruster
227 0e8a8c8f Markus Armbruster
    if (dev) {
228 0e8a8c8f Markus Armbruster
        argc = append_arg(argc, argv, argv_sz,
229 0e8a8c8f Markus Armbruster
                          g_strdup_printf("-device %s,drive=drive%d,"
230 0e8a8c8f Markus Armbruster
                                          "bus=ide.%d,unit=%d",
231 0e8a8c8f Markus Armbruster
                                          dev, ide_idx,
232 0e8a8c8f Markus Armbruster
                                          ide_idx / 2, ide_idx % 2));
233 0e8a8c8f Markus Armbruster
    }
234 0e8a8c8f Markus Armbruster
    return argc;
235 0e8a8c8f Markus Armbruster
}
236 0e8a8c8f Markus Armbruster
237 0e8a8c8f Markus Armbruster
/*
238 0e8a8c8f Markus Armbruster
 * Test case: no IDE devices
239 0e8a8c8f Markus Armbruster
 */
240 0e8a8c8f Markus Armbruster
static void test_ide_none(void)
241 0e8a8c8f Markus Armbruster
{
242 0e8a8c8f Markus Armbruster
    char *argv[256];
243 0e8a8c8f Markus Armbruster
244 0e8a8c8f Markus Armbruster
    setup_common(argv, ARRAY_SIZE(argv));
245 0e8a8c8f Markus Armbruster
    qtest_start(g_strjoinv(" ", argv));
246 0e8a8c8f Markus Armbruster
    test_cmos();
247 1d9358e6 Markus Armbruster
    qtest_end();
248 0e8a8c8f Markus Armbruster
}
249 0e8a8c8f Markus Armbruster
250 0e8a8c8f Markus Armbruster
static void test_ide_mbr(bool use_device, MBRcontents mbr)
251 0e8a8c8f Markus Armbruster
{
252 0e8a8c8f Markus Armbruster
    char *argv[256];
253 0e8a8c8f Markus Armbruster
    int argc;
254 0e8a8c8f Markus Armbruster
    Backend i;
255 0e8a8c8f Markus Armbruster
    const char *dev;
256 0e8a8c8f Markus Armbruster
257 0e8a8c8f Markus Armbruster
    argc = setup_common(argv, ARRAY_SIZE(argv));
258 0e8a8c8f Markus Armbruster
    for (i = 0; i < backend_last; i++) {
259 0e8a8c8f Markus Armbruster
        cur_ide[i] = &hd_chst[i][mbr];
260 0e8a8c8f Markus Armbruster
        dev = use_device ? (is_hd(cur_ide[i]) ? "ide-hd" : "ide-cd") : NULL;
261 0e8a8c8f Markus Armbruster
        argc = setup_ide(argc, argv, ARRAY_SIZE(argv), i, dev, i, mbr, "");
262 0e8a8c8f Markus Armbruster
    }
263 0e8a8c8f Markus Armbruster
    qtest_start(g_strjoinv(" ", argv));
264 0e8a8c8f Markus Armbruster
    test_cmos();
265 1d9358e6 Markus Armbruster
    qtest_end();
266 0e8a8c8f Markus Armbruster
}
267 0e8a8c8f Markus Armbruster
268 0e8a8c8f Markus Armbruster
/*
269 0e8a8c8f Markus Armbruster
 * Test case: IDE devices (if=ide) with blank MBRs
270 0e8a8c8f Markus Armbruster
 */
271 0e8a8c8f Markus Armbruster
static void test_ide_drive_mbr_blank(void)
272 0e8a8c8f Markus Armbruster
{
273 0e8a8c8f Markus Armbruster
    test_ide_mbr(false, mbr_blank);
274 0e8a8c8f Markus Armbruster
}
275 0e8a8c8f Markus Armbruster
276 0e8a8c8f Markus Armbruster
/*
277 0e8a8c8f Markus Armbruster
 * Test case: IDE devices (if=ide) with MBRs indicating LBA is in use
278 0e8a8c8f Markus Armbruster
 */
279 0e8a8c8f Markus Armbruster
static void test_ide_drive_mbr_lba(void)
280 0e8a8c8f Markus Armbruster
{
281 0e8a8c8f Markus Armbruster
    test_ide_mbr(false, mbr_lba);
282 0e8a8c8f Markus Armbruster
}
283 0e8a8c8f Markus Armbruster
284 0e8a8c8f Markus Armbruster
/*
285 0e8a8c8f Markus Armbruster
 * Test case: IDE devices (if=ide) with MBRs indicating CHS is in use
286 0e8a8c8f Markus Armbruster
 */
287 0e8a8c8f Markus Armbruster
static void test_ide_drive_mbr_chs(void)
288 0e8a8c8f Markus Armbruster
{
289 0e8a8c8f Markus Armbruster
    test_ide_mbr(false, mbr_chs);
290 0e8a8c8f Markus Armbruster
}
291 0e8a8c8f Markus Armbruster
292 0e8a8c8f Markus Armbruster
/*
293 0e8a8c8f Markus Armbruster
 * Test case: IDE devices (if=none) with blank MBRs
294 0e8a8c8f Markus Armbruster
 */
295 0e8a8c8f Markus Armbruster
static void test_ide_device_mbr_blank(void)
296 0e8a8c8f Markus Armbruster
{
297 0e8a8c8f Markus Armbruster
    test_ide_mbr(true, mbr_blank);
298 0e8a8c8f Markus Armbruster
}
299 0e8a8c8f Markus Armbruster
300 0e8a8c8f Markus Armbruster
/*
301 0e8a8c8f Markus Armbruster
 * Test case: IDE devices (if=none) with MBRs indicating LBA is in use
302 0e8a8c8f Markus Armbruster
 */
303 0e8a8c8f Markus Armbruster
static void test_ide_device_mbr_lba(void)
304 0e8a8c8f Markus Armbruster
{
305 0e8a8c8f Markus Armbruster
    test_ide_mbr(true, mbr_lba);
306 0e8a8c8f Markus Armbruster
}
307 0e8a8c8f Markus Armbruster
308 0e8a8c8f Markus Armbruster
/*
309 0e8a8c8f Markus Armbruster
 * Test case: IDE devices (if=none) with MBRs indicating CHS is in use
310 0e8a8c8f Markus Armbruster
 */
311 0e8a8c8f Markus Armbruster
static void test_ide_device_mbr_chs(void)
312 0e8a8c8f Markus Armbruster
{
313 0e8a8c8f Markus Armbruster
    test_ide_mbr(true, mbr_chs);
314 0e8a8c8f Markus Armbruster
}
315 0e8a8c8f Markus Armbruster
316 0e8a8c8f Markus Armbruster
static void test_ide_drive_user(const char *dev, bool trans)
317 0e8a8c8f Markus Armbruster
{
318 0e8a8c8f Markus Armbruster
    char *argv[256], *opts;
319 0e8a8c8f Markus Armbruster
    int argc;
320 0e8a8c8f Markus Armbruster
    int secs = img_secs[backend_small];
321 0e8a8c8f Markus Armbruster
    const CHST expected_chst = { secs / (4 * 32) , 4, 32, trans };
322 0e8a8c8f Markus Armbruster
323 0e8a8c8f Markus Armbruster
    argc = setup_common(argv, ARRAY_SIZE(argv));
324 856dcba2 Markus Armbruster
    opts = g_strdup_printf("%s,%s%scyls=%d,heads=%d,secs=%d",
325 856dcba2 Markus Armbruster
                           dev ?: "",
326 856dcba2 Markus Armbruster
                           trans && dev ? "bios-chs-" : "",
327 856dcba2 Markus Armbruster
                           trans ? "trans=lba," : "",
328 0e8a8c8f Markus Armbruster
                           expected_chst.cyls, expected_chst.heads,
329 856dcba2 Markus Armbruster
                           expected_chst.secs);
330 0e8a8c8f Markus Armbruster
    cur_ide[0] = &expected_chst;
331 0e8a8c8f Markus Armbruster
    argc = setup_ide(argc, argv, ARRAY_SIZE(argv),
332 856dcba2 Markus Armbruster
                     0, dev ? opts : NULL, backend_small, mbr_chs,
333 856dcba2 Markus Armbruster
                     dev ? "" : opts);
334 0e8a8c8f Markus Armbruster
    g_free(opts);
335 0e8a8c8f Markus Armbruster
    qtest_start(g_strjoinv(" ", argv));
336 0e8a8c8f Markus Armbruster
    test_cmos();
337 1d9358e6 Markus Armbruster
    qtest_end();
338 0e8a8c8f Markus Armbruster
}
339 0e8a8c8f Markus Armbruster
340 0e8a8c8f Markus Armbruster
/*
341 0e8a8c8f Markus Armbruster
 * Test case: IDE device (if=ide) with explicit CHS
342 0e8a8c8f Markus Armbruster
 */
343 0e8a8c8f Markus Armbruster
static void test_ide_drive_user_chs(void)
344 0e8a8c8f Markus Armbruster
{
345 0e8a8c8f Markus Armbruster
    test_ide_drive_user(NULL, false);
346 0e8a8c8f Markus Armbruster
}
347 0e8a8c8f Markus Armbruster
348 0e8a8c8f Markus Armbruster
/*
349 0e8a8c8f Markus Armbruster
 * Test case: IDE device (if=ide) with explicit CHS and translation
350 0e8a8c8f Markus Armbruster
 */
351 0e8a8c8f Markus Armbruster
static void test_ide_drive_user_chst(void)
352 0e8a8c8f Markus Armbruster
{
353 0e8a8c8f Markus Armbruster
    test_ide_drive_user(NULL, true);
354 0e8a8c8f Markus Armbruster
}
355 0e8a8c8f Markus Armbruster
356 0e8a8c8f Markus Armbruster
/*
357 0e8a8c8f Markus Armbruster
 * Test case: IDE device (if=none) with explicit CHS
358 0e8a8c8f Markus Armbruster
 */
359 0e8a8c8f Markus Armbruster
static void test_ide_device_user_chs(void)
360 0e8a8c8f Markus Armbruster
{
361 0e8a8c8f Markus Armbruster
    test_ide_drive_user("ide-hd", false);
362 0e8a8c8f Markus Armbruster
}
363 0e8a8c8f Markus Armbruster
364 0e8a8c8f Markus Armbruster
/*
365 0e8a8c8f Markus Armbruster
 * Test case: IDE device (if=none) with explicit CHS and translation
366 0e8a8c8f Markus Armbruster
 */
367 0e8a8c8f Markus Armbruster
static void test_ide_device_user_chst(void)
368 0e8a8c8f Markus Armbruster
{
369 0e8a8c8f Markus Armbruster
    test_ide_drive_user("ide-hd", true);
370 0e8a8c8f Markus Armbruster
}
371 0e8a8c8f Markus Armbruster
372 4e4e6e31 Markus Armbruster
/*
373 4e4e6e31 Markus Armbruster
 * Test case: IDE devices (if=ide), but use index=0 for CD-ROM
374 4e4e6e31 Markus Armbruster
 */
375 4e4e6e31 Markus Armbruster
static void test_ide_drive_cd_0(void)
376 4e4e6e31 Markus Armbruster
{
377 4e4e6e31 Markus Armbruster
    char *argv[256];
378 4e4e6e31 Markus Armbruster
    int argc, ide_idx;
379 4e4e6e31 Markus Armbruster
    Backend i;
380 4e4e6e31 Markus Armbruster
381 4e4e6e31 Markus Armbruster
    argc = setup_common(argv, ARRAY_SIZE(argv));
382 4e4e6e31 Markus Armbruster
    for (i = 0; i <= backend_empty; i++) {
383 4e4e6e31 Markus Armbruster
        ide_idx = backend_empty - i;
384 4e4e6e31 Markus Armbruster
        cur_ide[ide_idx] = &hd_chst[i][mbr_blank];
385 4e4e6e31 Markus Armbruster
        argc = setup_ide(argc, argv, ARRAY_SIZE(argv),
386 4e4e6e31 Markus Armbruster
                         ide_idx, NULL, i, mbr_blank, "");
387 4e4e6e31 Markus Armbruster
    }
388 4e4e6e31 Markus Armbruster
    qtest_start(g_strjoinv(" ", argv));
389 4e4e6e31 Markus Armbruster
    test_cmos();
390 1d9358e6 Markus Armbruster
    qtest_end();
391 4e4e6e31 Markus Armbruster
}
392 4e4e6e31 Markus Armbruster
393 0e8a8c8f Markus Armbruster
int main(int argc, char **argv)
394 0e8a8c8f Markus Armbruster
{
395 0e8a8c8f Markus Armbruster
    Backend i;
396 0e8a8c8f Markus Armbruster
    int ret;
397 0e8a8c8f Markus Armbruster
398 0e8a8c8f Markus Armbruster
    g_test_init(&argc, &argv, NULL);
399 0e8a8c8f Markus Armbruster
400 0e8a8c8f Markus Armbruster
    for (i = 0; i < backend_last; i++) {
401 0e8a8c8f Markus Armbruster
        if (img_secs[i] >= 0) {
402 0e8a8c8f Markus Armbruster
            img_file_name[i] = create_test_img(img_secs[i]);
403 0e8a8c8f Markus Armbruster
        } else {
404 0e8a8c8f Markus Armbruster
            img_file_name[i] = NULL;
405 0e8a8c8f Markus Armbruster
        }
406 0e8a8c8f Markus Armbruster
    }
407 0e8a8c8f Markus Armbruster
408 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/none", test_ide_none);
409 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/drive/mbr/blank", test_ide_drive_mbr_blank);
410 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/drive/mbr/lba", test_ide_drive_mbr_lba);
411 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/drive/mbr/chs", test_ide_drive_mbr_chs);
412 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/drive/user/chs", test_ide_drive_user_chs);
413 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/drive/user/chst", test_ide_drive_user_chst);
414 4e4e6e31 Markus Armbruster
    qtest_add_func("hd-geo/ide/drive/cd_0", test_ide_drive_cd_0);
415 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/device/mbr/blank", test_ide_device_mbr_blank);
416 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/device/mbr/lba", test_ide_device_mbr_lba);
417 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/device/mbr/chs", test_ide_device_mbr_chs);
418 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/device/user/chs", test_ide_device_user_chs);
419 0e8a8c8f Markus Armbruster
    qtest_add_func("hd-geo/ide/device/user/chst", test_ide_device_user_chst);
420 0e8a8c8f Markus Armbruster
421 0e8a8c8f Markus Armbruster
    ret = g_test_run();
422 0e8a8c8f Markus Armbruster
423 0e8a8c8f Markus Armbruster
    for (i = 0; i < backend_last; i++) {
424 0e8a8c8f Markus Armbruster
        unlink(img_file_name[i]);
425 0e8a8c8f Markus Armbruster
    }
426 0e8a8c8f Markus Armbruster
427 0e8a8c8f Markus Armbruster
    return ret;
428 0e8a8c8f Markus Armbruster
}