~ubuntu-branches/ubuntu/wily/qemu-kvm-spice/wily

« back to all changes in this revision

Viewing changes to hw/loader.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-10-19 10:44:56 UTC
  • Revision ID: james.westby@ubuntu.com-20111019104456-xgvskumk3sxi97f4
Tags: upstream-0.15.0+noroms
ImportĀ upstreamĀ versionĀ 0.15.0+noroms

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU Executable loader
 
3
 *
 
4
 * Copyright (c) 2006 Fabrice Bellard
 
5
 *
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
7
 * of this software and associated documentation files (the "Software"), to deal
 
8
 * in the Software without restriction, including without limitation the rights
 
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
10
 * copies of the Software, and to permit persons to whom the Software is
 
11
 * furnished to do so, subject to the following conditions:
 
12
 *
 
13
 * The above copyright notice and this permission notice shall be included in
 
14
 * all copies or substantial portions of the Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
22
 * THE SOFTWARE.
 
23
 *
 
24
 * Gunzip functionality in this file is derived from u-boot:
 
25
 *
 
26
 * (C) Copyright 2008 Semihalf
 
27
 *
 
28
 * (C) Copyright 2000-2005
 
29
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
30
 *
 
31
 * This program is free software; you can redistribute it and/or
 
32
 * modify it under the terms of the GNU General Public License as
 
33
 * published by the Free Software Foundation; either version 2 of
 
34
 * the License, or (at your option) any later version.
 
35
 *
 
36
 * This program is distributed in the hope that it will be useful,
 
37
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
38
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
39
 * GNU General Public License for more details.
 
40
 *
 
41
 * You should have received a copy of the GNU General Public License along
 
42
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 
43
 */
 
44
 
 
45
#include "hw.h"
 
46
#include "disas.h"
 
47
#include "monitor.h"
 
48
#include "sysemu.h"
 
49
#include "uboot_image.h"
 
50
#include "loader.h"
 
51
#include "fw_cfg.h"
 
52
 
 
53
#include <zlib.h>
 
54
 
 
55
static int roms_loaded;
 
56
 
 
57
/* return the size or -1 if error */
 
58
int get_image_size(const char *filename)
 
59
{
 
60
    int fd, size;
 
61
    fd = open(filename, O_RDONLY | O_BINARY);
 
62
    if (fd < 0)
 
63
        return -1;
 
64
    size = lseek(fd, 0, SEEK_END);
 
65
    close(fd);
 
66
    return size;
 
67
}
 
68
 
 
69
/* return the size or -1 if error */
 
70
/* deprecated, because caller does not specify buffer size! */
 
71
int load_image(const char *filename, uint8_t *addr)
 
72
{
 
73
    int fd, size;
 
74
    fd = open(filename, O_RDONLY | O_BINARY);
 
75
    if (fd < 0)
 
76
        return -1;
 
77
    size = lseek(fd, 0, SEEK_END);
 
78
    lseek(fd, 0, SEEK_SET);
 
79
    if (read(fd, addr, size) != size) {
 
80
        close(fd);
 
81
        return -1;
 
82
    }
 
83
    close(fd);
 
84
    return size;
 
85
}
 
86
 
 
87
/* read()-like version */
 
88
int read_targphys(const char *name,
 
89
                  int fd, target_phys_addr_t dst_addr, size_t nbytes)
 
90
{
 
91
    uint8_t *buf;
 
92
    size_t did;
 
93
 
 
94
    buf = qemu_malloc(nbytes);
 
95
    did = read(fd, buf, nbytes);
 
96
    if (did > 0)
 
97
        rom_add_blob_fixed("read", buf, did, dst_addr);
 
98
    qemu_free(buf);
 
99
    return did;
 
100
}
 
101
 
 
102
/* return the size or -1 if error */
 
103
int load_image_targphys(const char *filename,
 
104
                        target_phys_addr_t addr, int max_sz)
 
105
{
 
106
    int size;
 
107
 
 
108
    size = get_image_size(filename);
 
109
    if (size > 0)
 
110
        rom_add_file_fixed(filename, addr, -1);
 
111
    return size;
 
112
}
 
113
 
 
114
void pstrcpy_targphys(const char *name, target_phys_addr_t dest, int buf_size,
 
115
                      const char *source)
 
116
{
 
117
    const char *nulp;
 
118
    char *ptr;
 
119
 
 
120
    if (buf_size <= 0) return;
 
121
    nulp = memchr(source, 0, buf_size);
 
122
    if (nulp) {
 
123
        rom_add_blob_fixed(name, source, (nulp - source) + 1, dest);
 
124
    } else {
 
125
        rom_add_blob_fixed(name, source, buf_size, dest);
 
126
        ptr = rom_ptr(dest + buf_size - 1);
 
127
        *ptr = 0;
 
128
    }
 
129
}
 
130
 
 
131
/* A.OUT loader */
 
132
 
 
133
struct exec
 
134
{
 
135
  uint32_t a_info;   /* Use macros N_MAGIC, etc for access */
 
136
  uint32_t a_text;   /* length of text, in bytes */
 
137
  uint32_t a_data;   /* length of data, in bytes */
 
138
  uint32_t a_bss;    /* length of uninitialized data area, in bytes */
 
139
  uint32_t a_syms;   /* length of symbol table data in file, in bytes */
 
140
  uint32_t a_entry;  /* start address */
 
141
  uint32_t a_trsize; /* length of relocation info for text, in bytes */
 
142
  uint32_t a_drsize; /* length of relocation info for data, in bytes */
 
143
};
 
144
 
 
145
static void bswap_ahdr(struct exec *e)
 
146
{
 
147
    bswap32s(&e->a_info);
 
148
    bswap32s(&e->a_text);
 
149
    bswap32s(&e->a_data);
 
150
    bswap32s(&e->a_bss);
 
151
    bswap32s(&e->a_syms);
 
152
    bswap32s(&e->a_entry);
 
153
    bswap32s(&e->a_trsize);
 
154
    bswap32s(&e->a_drsize);
 
155
}
 
156
 
 
157
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
 
158
#define OMAGIC 0407
 
159
#define NMAGIC 0410
 
160
#define ZMAGIC 0413
 
161
#define QMAGIC 0314
 
162
#define _N_HDROFF(x) (1024 - sizeof (struct exec))
 
163
#define N_TXTOFF(x)                                                     \
 
164
    (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) :     \
 
165
     (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
 
166
#define N_TXTADDR(x, target_page_size) (N_MAGIC(x) == QMAGIC ? target_page_size : 0)
 
167
#define _N_SEGMENT_ROUND(x, target_page_size) (((x) + target_page_size - 1) & ~(target_page_size - 1))
 
168
 
 
169
#define _N_TXTENDADDR(x, target_page_size) (N_TXTADDR(x, target_page_size)+(x).a_text)
 
170
 
 
171
#define N_DATADDR(x, target_page_size) \
 
172
    (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x, target_page_size)) \
 
173
     : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x, target_page_size), target_page_size)))
 
174
 
 
175
 
 
176
int load_aout(const char *filename, target_phys_addr_t addr, int max_sz,
 
177
              int bswap_needed, target_phys_addr_t target_page_size)
 
178
{
 
179
    int fd, size, ret;
 
180
    struct exec e;
 
181
    uint32_t magic;
 
182
 
 
183
    fd = open(filename, O_RDONLY | O_BINARY);
 
184
    if (fd < 0)
 
185
        return -1;
 
186
 
 
187
    size = read(fd, &e, sizeof(e));
 
188
    if (size < 0)
 
189
        goto fail;
 
190
 
 
191
    if (bswap_needed) {
 
192
        bswap_ahdr(&e);
 
193
    }
 
194
 
 
195
    magic = N_MAGIC(e);
 
196
    switch (magic) {
 
197
    case ZMAGIC:
 
198
    case QMAGIC:
 
199
    case OMAGIC:
 
200
        if (e.a_text + e.a_data > max_sz)
 
201
            goto fail;
 
202
        lseek(fd, N_TXTOFF(e), SEEK_SET);
 
203
        size = read_targphys(filename, fd, addr, e.a_text + e.a_data);
 
204
        if (size < 0)
 
205
            goto fail;
 
206
        break;
 
207
    case NMAGIC:
 
208
        if (N_DATADDR(e, target_page_size) + e.a_data > max_sz)
 
209
            goto fail;
 
210
        lseek(fd, N_TXTOFF(e), SEEK_SET);
 
211
        size = read_targphys(filename, fd, addr, e.a_text);
 
212
        if (size < 0)
 
213
            goto fail;
 
214
        ret = read_targphys(filename, fd, addr + N_DATADDR(e, target_page_size),
 
215
                            e.a_data);
 
216
        if (ret < 0)
 
217
            goto fail;
 
218
        size += ret;
 
219
        break;
 
220
    default:
 
221
        goto fail;
 
222
    }
 
223
    close(fd);
 
224
    return size;
 
225
 fail:
 
226
    close(fd);
 
227
    return -1;
 
228
}
 
229
 
 
230
/* ELF loader */
 
231
 
 
232
static void *load_at(int fd, int offset, int size)
 
233
{
 
234
    void *ptr;
 
235
    if (lseek(fd, offset, SEEK_SET) < 0)
 
236
        return NULL;
 
237
    ptr = qemu_malloc(size);
 
238
    if (read(fd, ptr, size) != size) {
 
239
        qemu_free(ptr);
 
240
        return NULL;
 
241
    }
 
242
    return ptr;
 
243
}
 
244
 
 
245
#ifdef ELF_CLASS
 
246
#undef ELF_CLASS
 
247
#endif
 
248
 
 
249
#define ELF_CLASS   ELFCLASS32
 
250
#include "elf.h"
 
251
 
 
252
#define SZ              32
 
253
#define elf_word        uint32_t
 
254
#define elf_sword        int32_t
 
255
#define bswapSZs        bswap32s
 
256
#include "elf_ops.h"
 
257
 
 
258
#undef elfhdr
 
259
#undef elf_phdr
 
260
#undef elf_shdr
 
261
#undef elf_sym
 
262
#undef elf_note
 
263
#undef elf_word
 
264
#undef elf_sword
 
265
#undef bswapSZs
 
266
#undef SZ
 
267
#define elfhdr          elf64_hdr
 
268
#define elf_phdr        elf64_phdr
 
269
#define elf_note        elf64_note
 
270
#define elf_shdr        elf64_shdr
 
271
#define elf_sym         elf64_sym
 
272
#define elf_word        uint64_t
 
273
#define elf_sword        int64_t
 
274
#define bswapSZs        bswap64s
 
275
#define SZ              64
 
276
#include "elf_ops.h"
 
277
 
 
278
/* return < 0 if error, otherwise the number of bytes loaded in memory */
 
279
int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
 
280
             void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
 
281
             uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb)
 
282
{
 
283
    int fd, data_order, target_data_order, must_swab, ret;
 
284
    uint8_t e_ident[EI_NIDENT];
 
285
 
 
286
    fd = open(filename, O_RDONLY | O_BINARY);
 
287
    if (fd < 0) {
 
288
        perror(filename);
 
289
        return -1;
 
290
    }
 
291
    if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
 
292
        goto fail;
 
293
    if (e_ident[0] != ELFMAG0 ||
 
294
        e_ident[1] != ELFMAG1 ||
 
295
        e_ident[2] != ELFMAG2 ||
 
296
        e_ident[3] != ELFMAG3)
 
297
        goto fail;
 
298
#ifdef HOST_WORDS_BIGENDIAN
 
299
    data_order = ELFDATA2MSB;
 
300
#else
 
301
    data_order = ELFDATA2LSB;
 
302
#endif
 
303
    must_swab = data_order != e_ident[EI_DATA];
 
304
    if (big_endian) {
 
305
        target_data_order = ELFDATA2MSB;
 
306
    } else {
 
307
        target_data_order = ELFDATA2LSB;
 
308
    }
 
309
 
 
310
    if (target_data_order != e_ident[EI_DATA]) {
 
311
        goto fail;
 
312
    }
 
313
 
 
314
    lseek(fd, 0, SEEK_SET);
 
315
    if (e_ident[EI_CLASS] == ELFCLASS64) {
 
316
        ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab,
 
317
                         pentry, lowaddr, highaddr, elf_machine, clear_lsb);
 
318
    } else {
 
319
        ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab,
 
320
                         pentry, lowaddr, highaddr, elf_machine, clear_lsb);
 
321
    }
 
322
 
 
323
    close(fd);
 
324
    return ret;
 
325
 
 
326
 fail:
 
327
    close(fd);
 
328
    return -1;
 
329
}
 
330
 
 
331
static void bswap_uboot_header(uboot_image_header_t *hdr)
 
332
{
 
333
#ifndef HOST_WORDS_BIGENDIAN
 
334
    bswap32s(&hdr->ih_magic);
 
335
    bswap32s(&hdr->ih_hcrc);
 
336
    bswap32s(&hdr->ih_time);
 
337
    bswap32s(&hdr->ih_size);
 
338
    bswap32s(&hdr->ih_load);
 
339
    bswap32s(&hdr->ih_ep);
 
340
    bswap32s(&hdr->ih_dcrc);
 
341
#endif
 
342
}
 
343
 
 
344
 
 
345
#define ZALLOC_ALIGNMENT        16
 
346
 
 
347
static void *zalloc(void *x, unsigned items, unsigned size)
 
348
{
 
349
    void *p;
 
350
 
 
351
    size *= items;
 
352
    size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
 
353
 
 
354
    p = qemu_malloc(size);
 
355
 
 
356
    return (p);
 
357
}
 
358
 
 
359
static void zfree(void *x, void *addr)
 
360
{
 
361
    qemu_free(addr);
 
362
}
 
363
 
 
364
 
 
365
#define HEAD_CRC        2
 
366
#define EXTRA_FIELD     4
 
367
#define ORIG_NAME       8
 
368
#define COMMENT         0x10
 
369
#define RESERVED        0xe0
 
370
 
 
371
#define DEFLATED        8
 
372
 
 
373
/* This is the maximum in uboot, so if a uImage overflows this, it would
 
374
 * overflow on real hardware too. */
 
375
#define UBOOT_MAX_GUNZIP_BYTES 0x800000
 
376
 
 
377
static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
 
378
                      size_t srclen)
 
379
{
 
380
    z_stream s;
 
381
    ssize_t dstbytes;
 
382
    int r, i, flags;
 
383
 
 
384
    /* skip header */
 
385
    i = 10;
 
386
    flags = src[3];
 
387
    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
 
388
        puts ("Error: Bad gzipped data\n");
 
389
        return -1;
 
390
    }
 
391
    if ((flags & EXTRA_FIELD) != 0)
 
392
        i = 12 + src[10] + (src[11] << 8);
 
393
    if ((flags & ORIG_NAME) != 0)
 
394
        while (src[i++] != 0)
 
395
            ;
 
396
    if ((flags & COMMENT) != 0)
 
397
        while (src[i++] != 0)
 
398
            ;
 
399
    if ((flags & HEAD_CRC) != 0)
 
400
        i += 2;
 
401
    if (i >= srclen) {
 
402
        puts ("Error: gunzip out of data in header\n");
 
403
        return -1;
 
404
    }
 
405
 
 
406
    s.zalloc = zalloc;
 
407
    s.zfree = zfree;
 
408
 
 
409
    r = inflateInit2(&s, -MAX_WBITS);
 
410
    if (r != Z_OK) {
 
411
        printf ("Error: inflateInit2() returned %d\n", r);
 
412
        return (-1);
 
413
    }
 
414
    s.next_in = src + i;
 
415
    s.avail_in = srclen - i;
 
416
    s.next_out = dst;
 
417
    s.avail_out = dstlen;
 
418
    r = inflate(&s, Z_FINISH);
 
419
    if (r != Z_OK && r != Z_STREAM_END) {
 
420
        printf ("Error: inflate() returned %d\n", r);
 
421
        return -1;
 
422
    }
 
423
    dstbytes = s.next_out - (unsigned char *) dst;
 
424
    inflateEnd(&s);
 
425
 
 
426
    return dstbytes;
 
427
}
 
428
 
 
429
/* Load a U-Boot image.  */
 
430
int load_uimage(const char *filename, target_phys_addr_t *ep,
 
431
                target_phys_addr_t *loadaddr, int *is_linux)
 
432
{
 
433
    int fd;
 
434
    int size;
 
435
    uboot_image_header_t h;
 
436
    uboot_image_header_t *hdr = &h;
 
437
    uint8_t *data = NULL;
 
438
    int ret = -1;
 
439
 
 
440
    fd = open(filename, O_RDONLY | O_BINARY);
 
441
    if (fd < 0)
 
442
        return -1;
 
443
 
 
444
    size = read(fd, hdr, sizeof(uboot_image_header_t));
 
445
    if (size < 0)
 
446
        goto out;
 
447
 
 
448
    bswap_uboot_header(hdr);
 
449
 
 
450
    if (hdr->ih_magic != IH_MAGIC)
 
451
        goto out;
 
452
 
 
453
    /* TODO: Implement other image types.  */
 
454
    if (hdr->ih_type != IH_TYPE_KERNEL) {
 
455
        fprintf(stderr, "Can only load u-boot image type \"kernel\"\n");
 
456
        goto out;
 
457
    }
 
458
 
 
459
    switch (hdr->ih_comp) {
 
460
    case IH_COMP_NONE:
 
461
    case IH_COMP_GZIP:
 
462
        break;
 
463
    default:
 
464
        fprintf(stderr,
 
465
                "Unable to load u-boot images with compression type %d\n",
 
466
                hdr->ih_comp);
 
467
        goto out;
 
468
    }
 
469
 
 
470
    /* TODO: Check CPU type.  */
 
471
    if (is_linux) {
 
472
        if (hdr->ih_os == IH_OS_LINUX)
 
473
            *is_linux = 1;
 
474
        else
 
475
            *is_linux = 0;
 
476
    }
 
477
 
 
478
    *ep = hdr->ih_ep;
 
479
    data = qemu_malloc(hdr->ih_size);
 
480
 
 
481
    if (read(fd, data, hdr->ih_size) != hdr->ih_size) {
 
482
        fprintf(stderr, "Error reading file\n");
 
483
        goto out;
 
484
    }
 
485
 
 
486
    if (hdr->ih_comp == IH_COMP_GZIP) {
 
487
        uint8_t *compressed_data;
 
488
        size_t max_bytes;
 
489
        ssize_t bytes;
 
490
 
 
491
        compressed_data = data;
 
492
        max_bytes = UBOOT_MAX_GUNZIP_BYTES;
 
493
        data = qemu_malloc(max_bytes);
 
494
 
 
495
        bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size);
 
496
        qemu_free(compressed_data);
 
497
        if (bytes < 0) {
 
498
            fprintf(stderr, "Unable to decompress gzipped image!\n");
 
499
            goto out;
 
500
        }
 
501
        hdr->ih_size = bytes;
 
502
    }
 
503
 
 
504
    rom_add_blob_fixed(filename, data, hdr->ih_size, hdr->ih_load);
 
505
 
 
506
    if (loadaddr)
 
507
        *loadaddr = hdr->ih_load;
 
508
 
 
509
    ret = hdr->ih_size;
 
510
 
 
511
out:
 
512
    if (data)
 
513
        qemu_free(data);
 
514
    close(fd);
 
515
    return ret;
 
516
}
 
517
 
 
518
/*
 
519
 * Functions for reboot-persistent memory regions.
 
520
 *  - used for vga bios and option roms.
 
521
 *  - also linux kernel (-kernel / -initrd).
 
522
 */
 
523
 
 
524
typedef struct Rom Rom;
 
525
 
 
526
struct Rom {
 
527
    char *name;
 
528
    char *path;
 
529
    size_t romsize;
 
530
    uint8_t *data;
 
531
    int isrom;
 
532
    char *fw_dir;
 
533
    char *fw_file;
 
534
 
 
535
    target_phys_addr_t addr;
 
536
    QTAILQ_ENTRY(Rom) next;
 
537
};
 
538
 
 
539
static FWCfgState *fw_cfg;
 
540
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
 
541
 
 
542
static void rom_insert(Rom *rom)
 
543
{
 
544
    Rom *item;
 
545
 
 
546
    if (roms_loaded) {
 
547
        hw_error ("ROM images must be loaded at startup\n");
 
548
    }
 
549
 
 
550
    /* list is ordered by load address */
 
551
    QTAILQ_FOREACH(item, &roms, next) {
 
552
        if (rom->addr >= item->addr)
 
553
            continue;
 
554
        QTAILQ_INSERT_BEFORE(item, rom, next);
 
555
        return;
 
556
    }
 
557
    QTAILQ_INSERT_TAIL(&roms, rom, next);
 
558
}
 
559
 
 
560
int rom_add_file(const char *file, const char *fw_dir,
 
561
                 target_phys_addr_t addr, int32_t bootindex)
 
562
{
 
563
    Rom *rom;
 
564
    int rc, fd = -1;
 
565
    char devpath[100];
 
566
 
 
567
    rom = qemu_mallocz(sizeof(*rom));
 
568
    rom->name = qemu_strdup(file);
 
569
    rom->path = qemu_find_file(QEMU_FILE_TYPE_BIOS, rom->name);
 
570
    if (rom->path == NULL) {
 
571
        rom->path = qemu_strdup(file);
 
572
    }
 
573
 
 
574
    fd = open(rom->path, O_RDONLY | O_BINARY);
 
575
    if (fd == -1) {
 
576
        fprintf(stderr, "Could not open option rom '%s': %s\n",
 
577
                rom->path, strerror(errno));
 
578
        goto err;
 
579
    }
 
580
 
 
581
    if (fw_dir) {
 
582
        rom->fw_dir  = qemu_strdup(fw_dir);
 
583
        rom->fw_file = qemu_strdup(file);
 
584
    }
 
585
    rom->addr    = addr;
 
586
    rom->romsize = lseek(fd, 0, SEEK_END);
 
587
    rom->data    = qemu_mallocz(rom->romsize);
 
588
    lseek(fd, 0, SEEK_SET);
 
589
    rc = read(fd, rom->data, rom->romsize);
 
590
    if (rc != rom->romsize) {
 
591
        fprintf(stderr, "rom: file %-20s: read error: rc=%d (expected %zd)\n",
 
592
                rom->name, rc, rom->romsize);
 
593
        goto err;
 
594
    }
 
595
    close(fd);
 
596
    rom_insert(rom);
 
597
    if (rom->fw_file && fw_cfg) {
 
598
        const char *basename;
 
599
        char fw_file_name[56];
 
600
 
 
601
        basename = strrchr(rom->fw_file, '/');
 
602
        if (basename) {
 
603
            basename++;
 
604
        } else {
 
605
            basename = rom->fw_file;
 
606
        }
 
607
        snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", rom->fw_dir,
 
608
                 basename);
 
609
        fw_cfg_add_file(fw_cfg, fw_file_name, rom->data, rom->romsize);
 
610
        snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
 
611
    } else {
 
612
        snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr);
 
613
    }
 
614
 
 
615
    add_boot_device_path(bootindex, NULL, devpath);
 
616
    return 0;
 
617
 
 
618
err:
 
619
    if (fd != -1)
 
620
        close(fd);
 
621
    qemu_free(rom->data);
 
622
    qemu_free(rom->path);
 
623
    qemu_free(rom->name);
 
624
    qemu_free(rom);
 
625
    return -1;
 
626
}
 
627
 
 
628
int rom_add_blob(const char *name, const void *blob, size_t len,
 
629
                 target_phys_addr_t addr)
 
630
{
 
631
    Rom *rom;
 
632
 
 
633
    rom = qemu_mallocz(sizeof(*rom));
 
634
    rom->name    = qemu_strdup(name);
 
635
    rom->addr    = addr;
 
636
    rom->romsize = len;
 
637
    rom->data    = qemu_mallocz(rom->romsize);
 
638
    memcpy(rom->data, blob, len);
 
639
    rom_insert(rom);
 
640
    return 0;
 
641
}
 
642
 
 
643
int rom_add_vga(const char *file)
 
644
{
 
645
    return rom_add_file(file, "vgaroms", 0, -1);
 
646
}
 
647
 
 
648
int rom_add_option(const char *file, int32_t bootindex)
 
649
{
 
650
    return rom_add_file(file, "genroms", 0, bootindex);
 
651
}
 
652
 
 
653
static void rom_reset(void *unused)
 
654
{
 
655
    Rom *rom;
 
656
 
 
657
    QTAILQ_FOREACH(rom, &roms, next) {
 
658
        if (rom->fw_file) {
 
659
            continue;
 
660
        }
 
661
        if (rom->data == NULL) {
 
662
            continue;
 
663
        }
 
664
        cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
 
665
        if (rom->isrom) {
 
666
            /* rom needs to be written only once */
 
667
            qemu_free(rom->data);
 
668
            rom->data = NULL;
 
669
        }
 
670
    }
 
671
}
 
672
 
 
673
int rom_load_all(void)
 
674
{
 
675
    target_phys_addr_t addr = 0;
 
676
    int memtype;
 
677
    Rom *rom;
 
678
 
 
679
    QTAILQ_FOREACH(rom, &roms, next) {
 
680
        if (rom->fw_file) {
 
681
            continue;
 
682
        }
 
683
        if (addr > rom->addr) {
 
684
            fprintf(stderr, "rom: requested regions overlap "
 
685
                    "(rom %s. free=0x" TARGET_FMT_plx
 
686
                    ", addr=0x" TARGET_FMT_plx ")\n",
 
687
                    rom->name, addr, rom->addr);
 
688
            return -1;
 
689
        }
 
690
        addr  = rom->addr;
 
691
        addr += rom->romsize;
 
692
        memtype = cpu_get_physical_page_desc(rom->addr) & (3 << IO_MEM_SHIFT);
 
693
        if (memtype == IO_MEM_ROM)
 
694
            rom->isrom = 1;
 
695
    }
 
696
    qemu_register_reset(rom_reset, NULL);
 
697
    roms_loaded = 1;
 
698
    return 0;
 
699
}
 
700
 
 
701
void rom_set_fw(void *f)
 
702
{
 
703
    fw_cfg = f;
 
704
}
 
705
 
 
706
static Rom *find_rom(target_phys_addr_t addr)
 
707
{
 
708
    Rom *rom;
 
709
 
 
710
    QTAILQ_FOREACH(rom, &roms, next) {
 
711
        if (rom->fw_file) {
 
712
            continue;
 
713
        }
 
714
        if (rom->addr > addr) {
 
715
            continue;
 
716
        }
 
717
        if (rom->addr + rom->romsize < addr) {
 
718
            continue;
 
719
        }
 
720
        return rom;
 
721
    }
 
722
    return NULL;
 
723
}
 
724
 
 
725
/*
 
726
 * Copies memory from registered ROMs to dest. Any memory that is contained in
 
727
 * a ROM between addr and addr + size is copied. Note that this can involve
 
728
 * multiple ROMs, which need not start at addr and need not end at addr + size.
 
729
 */
 
730
int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
 
731
{
 
732
    target_phys_addr_t end = addr + size;
 
733
    uint8_t *s, *d = dest;
 
734
    size_t l = 0;
 
735
    Rom *rom;
 
736
 
 
737
    QTAILQ_FOREACH(rom, &roms, next) {
 
738
        if (rom->fw_file) {
 
739
            continue;
 
740
        }
 
741
        if (rom->addr + rom->romsize < addr) {
 
742
            continue;
 
743
        }
 
744
        if (rom->addr > end) {
 
745
            break;
 
746
        }
 
747
        if (!rom->data) {
 
748
            continue;
 
749
        }
 
750
 
 
751
        d = dest + (rom->addr - addr);
 
752
        s = rom->data;
 
753
        l = rom->romsize;
 
754
 
 
755
        if ((d + l) > (dest + size)) {
 
756
            l = dest - d;
 
757
        }
 
758
 
 
759
        memcpy(d, s, l);
 
760
    }
 
761
 
 
762
    return (d + l) - dest;
 
763
}
 
764
 
 
765
void *rom_ptr(target_phys_addr_t addr)
 
766
{
 
767
    Rom *rom;
 
768
 
 
769
    rom = find_rom(addr);
 
770
    if (!rom || !rom->data)
 
771
        return NULL;
 
772
    return rom->data + (addr - rom->addr);
 
773
}
 
774
 
 
775
void do_info_roms(Monitor *mon)
 
776
{
 
777
    Rom *rom;
 
778
 
 
779
    QTAILQ_FOREACH(rom, &roms, next) {
 
780
        if (!rom->fw_file) {
 
781
            monitor_printf(mon, "addr=" TARGET_FMT_plx
 
782
                           " size=0x%06zx mem=%s name=\"%s\" \n",
 
783
                           rom->addr, rom->romsize,
 
784
                           rom->isrom ? "rom" : "ram",
 
785
                           rom->name);
 
786
        } else {
 
787
            monitor_printf(mon, "fw=%s/%s"
 
788
                           " size=0x%06zx name=\"%s\" \n",
 
789
                           rom->fw_dir,
 
790
                           rom->fw_file,
 
791
                           rom->romsize,
 
792
                           rom->name);
 
793
        }
 
794
    }
 
795
}