~ubuntu-branches/ubuntu/precise/seabios/precise-updates

« back to all changes in this revision

Viewing changes to .pc/debian-changes-0.6.0-0ubuntu2/src/paravirt.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2010-10-22 11:04:31 UTC
  • Revision ID: james.westby@ubuntu.com-20101022110431-fnfj73ra6xkq623n
Tags: 0.6.0-0ubuntu2
Add all patches which were included in qemu-0.13.0-rc2 (per
commit on Jul 13, 2010).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Paravirtualization support.
 
2
//
 
3
// Copyright (C) 2009 Red Hat Inc.
 
4
//
 
5
// Authors:
 
6
//  Gleb Natapov <gnatapov@redhat.com>
 
7
//
 
8
// This file may be distributed under the terms of the GNU LGPLv3 license.
 
9
 
 
10
#include "config.h" // CONFIG_COREBOOT
 
11
#include "util.h" // ntoh[ls]
 
12
#include "ioport.h" // outw
 
13
#include "paravirt.h" // qemu_cfg_port_probe
 
14
#include "smbios.h" // struct smbios_structure_header
 
15
 
 
16
int qemu_cfg_present;
 
17
 
 
18
static void
 
19
qemu_cfg_select(u16 f)
 
20
{
 
21
    outw(f, PORT_QEMU_CFG_CTL);
 
22
}
 
23
 
 
24
static void
 
25
qemu_cfg_read(u8 *buf, int len)
 
26
{
 
27
    while (len--)
 
28
        *(buf++) = inb(PORT_QEMU_CFG_DATA);
 
29
}
 
30
 
 
31
static void
 
32
qemu_cfg_skip(int len)
 
33
{
 
34
    while (len--)
 
35
        inb(PORT_QEMU_CFG_DATA);
 
36
}
 
37
 
 
38
static void
 
39
qemu_cfg_read_entry(void *buf, int e, int len)
 
40
{
 
41
    qemu_cfg_select(e);
 
42
    qemu_cfg_read(buf, len);
 
43
}
 
44
 
 
45
void qemu_cfg_port_probe(void)
 
46
{
 
47
    char *sig = "QEMU";
 
48
    int i;
 
49
 
 
50
    if (CONFIG_COREBOOT)
 
51
        return;
 
52
 
 
53
    qemu_cfg_present = 1;
 
54
 
 
55
    qemu_cfg_select(QEMU_CFG_SIGNATURE);
 
56
 
 
57
    for (i = 0; i < 4; i++)
 
58
        if (inb(PORT_QEMU_CFG_DATA) != sig[i]) {
 
59
            qemu_cfg_present = 0;
 
60
            break;
 
61
        }
 
62
    dprintf(4, "qemu_cfg_present=%d\n", qemu_cfg_present);
 
63
}
 
64
 
 
65
void qemu_cfg_get_uuid(u8 *uuid)
 
66
{
 
67
    if (!qemu_cfg_present)
 
68
        return;
 
69
 
 
70
    qemu_cfg_read_entry(uuid, QEMU_CFG_UUID, 16);
 
71
}
 
72
 
 
73
int qemu_cfg_show_boot_menu(void)
 
74
{
 
75
    u16 v;
 
76
    if (!qemu_cfg_present)
 
77
        return 1;
 
78
 
 
79
    qemu_cfg_read_entry(&v, QEMU_CFG_BOOT_MENU, sizeof(v));
 
80
 
 
81
    return v;
 
82
}
 
83
 
 
84
int qemu_cfg_irq0_override(void)
 
85
{
 
86
    u8 v;
 
87
 
 
88
    if (!qemu_cfg_present)
 
89
        return 0;
 
90
 
 
91
    qemu_cfg_read_entry(&v, QEMU_CFG_IRQ0_OVERRIDE, sizeof(v));
 
92
 
 
93
    return v;
 
94
}
 
95
 
 
96
u16 qemu_cfg_acpi_additional_tables(void)
 
97
{
 
98
    u16 cnt;
 
99
 
 
100
    if (!qemu_cfg_present)
 
101
        return 0;
 
102
 
 
103
    qemu_cfg_read_entry(&cnt, QEMU_CFG_ACPI_TABLES, sizeof(cnt));
 
104
 
 
105
    return cnt;
 
106
}
 
107
 
 
108
u16 qemu_cfg_next_acpi_table_len(void)
 
109
{
 
110
    u16 len;
 
111
 
 
112
    qemu_cfg_read((u8*)&len, sizeof(len));
 
113
 
 
114
    return len;
 
115
}
 
116
 
 
117
void* qemu_cfg_next_acpi_table_load(void *addr, u16 len)
 
118
{
 
119
    qemu_cfg_read(addr, len);
 
120
    return addr;
 
121
}
 
122
 
 
123
u16 qemu_cfg_smbios_entries(void)
 
124
{
 
125
    u16 cnt;
 
126
 
 
127
    if (!qemu_cfg_present)
 
128
        return 0;
 
129
 
 
130
    qemu_cfg_read_entry(&cnt, QEMU_CFG_SMBIOS_ENTRIES, sizeof(cnt));
 
131
 
 
132
    return cnt;
 
133
}
 
134
 
 
135
u32 qemu_cfg_e820_entries(void)
 
136
{
 
137
    u32 cnt;
 
138
 
 
139
    if (!qemu_cfg_present)
 
140
        return 0;
 
141
 
 
142
    qemu_cfg_read_entry(&cnt, QEMU_CFG_E820_TABLE, sizeof(cnt));
 
143
    return cnt;
 
144
}
 
145
 
 
146
void* qemu_cfg_e820_load_next(void *addr)
 
147
{
 
148
    qemu_cfg_read(addr, sizeof(struct e820_reservation));
 
149
    return addr;
 
150
}
 
151
 
 
152
struct smbios_header {
 
153
    u16 length;
 
154
    u8 type;
 
155
} PACKED;
 
156
 
 
157
struct smbios_field {
 
158
    struct smbios_header header;
 
159
    u8 type;
 
160
    u16 offset;
 
161
    u8 data[];
 
162
} PACKED;
 
163
 
 
164
struct smbios_table {
 
165
    struct smbios_header header;
 
166
    u8 data[];
 
167
} PACKED;
 
168
 
 
169
#define SMBIOS_FIELD_ENTRY 0
 
170
#define SMBIOS_TABLE_ENTRY 1
 
171
 
 
172
size_t qemu_cfg_smbios_load_field(int type, size_t offset, void *addr)
 
173
{
 
174
    int i;
 
175
 
 
176
    for (i = qemu_cfg_smbios_entries(); i > 0; i--) {
 
177
        struct smbios_field field;
 
178
 
 
179
        qemu_cfg_read((u8 *)&field, sizeof(struct smbios_header));
 
180
        field.header.length -= sizeof(struct smbios_header);
 
181
 
 
182
        if (field.header.type != SMBIOS_FIELD_ENTRY) {
 
183
            qemu_cfg_skip(field.header.length);
 
184
            continue;
 
185
        }
 
186
 
 
187
        qemu_cfg_read((u8 *)&field.type,
 
188
                      sizeof(field) - sizeof(struct smbios_header));
 
189
        field.header.length -= sizeof(field) - sizeof(struct smbios_header);
 
190
 
 
191
        if (field.type != type || field.offset != offset) {
 
192
            qemu_cfg_skip(field.header.length);
 
193
            continue;
 
194
        }
 
195
 
 
196
        qemu_cfg_read(addr, field.header.length);
 
197
        return (size_t)field.header.length;
 
198
    }
 
199
    return 0;
 
200
}
 
201
 
 
202
int qemu_cfg_smbios_load_external(int type, char **p, unsigned *nr_structs,
 
203
                                  unsigned *max_struct_size, char *end)
 
204
{
 
205
    static u64 used_bitmap[4] = { 0 };
 
206
    char *start = *p;
 
207
    int i;
 
208
 
 
209
    /* Check if we've already reported these tables */
 
210
    if (used_bitmap[(type >> 6) & 0x3] & (1ULL << (type & 0x3f)))
 
211
        return 1;
 
212
 
 
213
    /* Don't introduce spurious end markers */
 
214
    if (type == 127)
 
215
        return 0;
 
216
 
 
217
    for (i = qemu_cfg_smbios_entries(); i > 0; i--) {
 
218
        struct smbios_table table;
 
219
        struct smbios_structure_header *header = (void *)*p;
 
220
        int string;
 
221
 
 
222
        qemu_cfg_read((u8 *)&table, sizeof(struct smbios_header));
 
223
        table.header.length -= sizeof(struct smbios_header);
 
224
 
 
225
        if (table.header.type != SMBIOS_TABLE_ENTRY) {
 
226
            qemu_cfg_skip(table.header.length);
 
227
            continue;
 
228
        }
 
229
 
 
230
        if (end - *p < sizeof(struct smbios_structure_header)) {
 
231
            warn_noalloc();
 
232
            break;
 
233
        }
 
234
 
 
235
        qemu_cfg_read((u8 *)*p, sizeof(struct smbios_structure_header));
 
236
        table.header.length -= sizeof(struct smbios_structure_header);
 
237
 
 
238
        if (header->type != type) {
 
239
            qemu_cfg_skip(table.header.length);
 
240
            continue;
 
241
        }
 
242
 
 
243
        *p += sizeof(struct smbios_structure_header);
 
244
 
 
245
        /* Entries end with a double NULL char, if there's a string at
 
246
         * the end (length is greater than formatted length), the string
 
247
         * terminator provides the first NULL. */
 
248
        string = header->length < table.header.length +
 
249
                 sizeof(struct smbios_structure_header);
 
250
 
 
251
        /* Read the rest and terminate the entry */
 
252
        if (end - *p < table.header.length) {
 
253
            warn_noalloc();
 
254
            *p -= sizeof(struct smbios_structure_header);
 
255
            continue;
 
256
        }
 
257
        qemu_cfg_read((u8 *)*p, table.header.length);
 
258
        *p += table.header.length;
 
259
        *((u8*)*p) = 0;
 
260
        (*p)++;
 
261
        if (!string) {
 
262
            *((u8*)*p) = 0;
 
263
            (*p)++;
 
264
        }
 
265
 
 
266
        (*nr_structs)++;
 
267
        if (*p - (char *)header > *max_struct_size)
 
268
            *max_struct_size = *p - (char *)header;
 
269
    }
 
270
 
 
271
    if (start != *p) {
 
272
        /* Mark that we've reported on this type */
 
273
        used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
 
274
        return 1;
 
275
    }
 
276
 
 
277
    return 0;
 
278
}
 
279
 
 
280
int qemu_cfg_get_numa_nodes(void)
 
281
{
 
282
    u64 cnt;
 
283
 
 
284
    qemu_cfg_read_entry(&cnt, QEMU_CFG_NUMA, sizeof(cnt));
 
285
 
 
286
    return (int)cnt;
 
287
}
 
288
 
 
289
void qemu_cfg_get_numa_data(u64 *data, int n)
 
290
{
 
291
    int i;
 
292
 
 
293
    for (i = 0; i < n; i++)
 
294
        qemu_cfg_read((u8*)(data + i), sizeof(u64));
 
295
}
 
296
 
 
297
u16 qemu_cfg_get_max_cpus(void)
 
298
{
 
299
    u16 cnt;
 
300
 
 
301
    if (!qemu_cfg_present)
 
302
        return 0;
 
303
 
 
304
    qemu_cfg_read_entry(&cnt, QEMU_CFG_MAX_CPUS, sizeof(cnt));
 
305
 
 
306
    return cnt;
 
307
}
 
308
 
 
309
static QemuCfgFile LastFile;
 
310
 
 
311
static u32
 
312
__cfg_next_prefix_file(const char *prefix, int prefixlen, u32 prevselect)
 
313
{
 
314
    if (!qemu_cfg_present)
 
315
        return 0;
 
316
 
 
317
    u32 count;
 
318
    qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
 
319
    count = ntohl(count);
 
320
    u32 e;
 
321
    for (e = 0; e < count; e++) {
 
322
        qemu_cfg_read((void*)&LastFile, sizeof(LastFile));
 
323
        u32 select = ntohs(LastFile.select);
 
324
        if (select <= prevselect)
 
325
            continue;
 
326
        if (memcmp(prefix, LastFile.name, prefixlen) == 0)
 
327
            return select;
 
328
    }
 
329
    return 0;
 
330
}
 
331
 
 
332
u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect)
 
333
{
 
334
    return __cfg_next_prefix_file(prefix, strlen(prefix), prevselect);
 
335
}
 
336
 
 
337
u32 qemu_cfg_find_file(const char *name)
 
338
{
 
339
    return __cfg_next_prefix_file(name, strlen(name) + 1, 0);
 
340
}
 
341
 
 
342
int qemu_cfg_size_file(u32 select)
 
343
{
 
344
    if (select != ntohs(LastFile.select))
 
345
        return -1;
 
346
    return ntohl(LastFile.size);
 
347
}
 
348
 
 
349
int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen)
 
350
{
 
351
    if (!qemu_cfg_present)
 
352
        return -1;
 
353
    if (!select || select != ntohs(LastFile.select))
 
354
        return -1;
 
355
    int len = qemu_cfg_size_file(select);
 
356
    if (len < 0 || len > maxlen)
 
357
        return -1;
 
358
    qemu_cfg_read_entry(dst, select, len);
 
359
    return len;
 
360
}