Statistics
| Branch: | Revision:

root / hw / loader.c @ e2553eb4

History | View | Annotate | Download (19.1 kB)

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);
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
        return -1;
312

    
313
    lseek(fd, 0, SEEK_SET);
314
    if (e_ident[EI_CLASS] == ELFCLASS64) {
315
        ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab,
316
                         pentry, lowaddr, highaddr, elf_machine, clear_lsb);
317
    } else {
318
        ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab,
319
                         pentry, lowaddr, highaddr, elf_machine, clear_lsb);
320
    }
321

    
322
    close(fd);
323
    return ret;
324

    
325
 fail:
326
    close(fd);
327
    return -1;
328
}
329

    
330
static void bswap_uboot_header(uboot_image_header_t *hdr)
331
{
332
#ifndef HOST_WORDS_BIGENDIAN
333
    bswap32s(&hdr->ih_magic);
334
    bswap32s(&hdr->ih_hcrc);
335
    bswap32s(&hdr->ih_time);
336
    bswap32s(&hdr->ih_size);
337
    bswap32s(&hdr->ih_load);
338
    bswap32s(&hdr->ih_ep);
339
    bswap32s(&hdr->ih_dcrc);
340
#endif
341
}
342

    
343

    
344
#define ZALLOC_ALIGNMENT        16
345

    
346
static void *zalloc(void *x, unsigned items, unsigned size)
347
{
348
    void *p;
349

    
350
    size *= items;
351
    size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
352

    
353
    p = qemu_malloc(size);
354

    
355
    return (p);
356
}
357

    
358
static void zfree(void *x, void *addr)
359
{
360
    qemu_free(addr);
361
}
362

    
363

    
364
#define HEAD_CRC        2
365
#define EXTRA_FIELD        4
366
#define ORIG_NAME        8
367
#define COMMENT                0x10
368
#define RESERVED        0xe0
369

    
370
#define DEFLATED        8
371

    
372
/* This is the maximum in uboot, so if a uImage overflows this, it would
373
 * overflow on real hardware too. */
374
#define UBOOT_MAX_GUNZIP_BYTES 0x800000
375

    
376
static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
377
                      size_t srclen)
378
{
379
    z_stream s;
380
    ssize_t dstbytes;
381
    int r, i, flags;
382

    
383
    /* skip header */
384
    i = 10;
385
    flags = src[3];
386
    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
387
        puts ("Error: Bad gzipped data\n");
388
        return -1;
389
    }
390
    if ((flags & EXTRA_FIELD) != 0)
391
        i = 12 + src[10] + (src[11] << 8);
392
    if ((flags & ORIG_NAME) != 0)
393
        while (src[i++] != 0)
394
            ;
395
    if ((flags & COMMENT) != 0)
396
        while (src[i++] != 0)
397
            ;
398
    if ((flags & HEAD_CRC) != 0)
399
        i += 2;
400
    if (i >= srclen) {
401
        puts ("Error: gunzip out of data in header\n");
402
        return -1;
403
    }
404

    
405
    s.zalloc = zalloc;
406
    s.zfree = zfree;
407

    
408
    r = inflateInit2(&s, -MAX_WBITS);
409
    if (r != Z_OK) {
410
        printf ("Error: inflateInit2() returned %d\n", r);
411
        return (-1);
412
    }
413
    s.next_in = src + i;
414
    s.avail_in = srclen - i;
415
    s.next_out = dst;
416
    s.avail_out = dstlen;
417
    r = inflate(&s, Z_FINISH);
418
    if (r != Z_OK && r != Z_STREAM_END) {
419
        printf ("Error: inflate() returned %d\n", r);
420
        return -1;
421
    }
422
    dstbytes = s.next_out - (unsigned char *) dst;
423
    inflateEnd(&s);
424

    
425
    return dstbytes;
426
}
427

    
428
/* Load a U-Boot image.  */
429
int load_uimage(const char *filename, target_phys_addr_t *ep,
430
                target_phys_addr_t *loadaddr, int *is_linux)
431
{
432
    int fd;
433
    int size;
434
    uboot_image_header_t h;
435
    uboot_image_header_t *hdr = &h;
436
    uint8_t *data = NULL;
437
    int ret = -1;
438

    
439
    fd = open(filename, O_RDONLY | O_BINARY);
440
    if (fd < 0)
441
        return -1;
442

    
443
    size = read(fd, hdr, sizeof(uboot_image_header_t));
444
    if (size < 0)
445
        goto out;
446

    
447
    bswap_uboot_header(hdr);
448

    
449
    if (hdr->ih_magic != IH_MAGIC)
450
        goto out;
451

    
452
    /* TODO: Implement other image types.  */
453
    if (hdr->ih_type != IH_TYPE_KERNEL) {
454
        fprintf(stderr, "Can only load u-boot image type \"kernel\"\n");
455
        goto out;
456
    }
457

    
458
    switch (hdr->ih_comp) {
459
    case IH_COMP_NONE:
460
    case IH_COMP_GZIP:
461
        break;
462
    default:
463
        fprintf(stderr,
464
                "Unable to load u-boot images with compression type %d\n",
465
                hdr->ih_comp);
466
        goto out;
467
    }
468

    
469
    /* TODO: Check CPU type.  */
470
    if (is_linux) {
471
        if (hdr->ih_os == IH_OS_LINUX)
472
            *is_linux = 1;
473
        else
474
            *is_linux = 0;
475
    }
476

    
477
    *ep = hdr->ih_ep;
478
    data = qemu_malloc(hdr->ih_size);
479

    
480
    if (read(fd, data, hdr->ih_size) != hdr->ih_size) {
481
        fprintf(stderr, "Error reading file\n");
482
        goto out;
483
    }
484

    
485
    if (hdr->ih_comp == IH_COMP_GZIP) {
486
        uint8_t *compressed_data;
487
        size_t max_bytes;
488
        ssize_t bytes;
489

    
490
        compressed_data = data;
491
        max_bytes = UBOOT_MAX_GUNZIP_BYTES;
492
        data = qemu_malloc(max_bytes);
493

    
494
        bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size);
495
        qemu_free(compressed_data);
496
        if (bytes < 0) {
497
            fprintf(stderr, "Unable to decompress gzipped image!\n");
498
            goto out;
499
        }
500
        hdr->ih_size = bytes;
501
    }
502

    
503
    rom_add_blob_fixed(filename, data, hdr->ih_size, hdr->ih_load);
504

    
505
    if (loadaddr)
506
        *loadaddr = hdr->ih_load;
507

    
508
    ret = hdr->ih_size;
509

    
510
out:
511
    if (data)
512
        qemu_free(data);
513
    close(fd);
514
    return ret;
515
}
516

    
517
/*
518
 * Functions for reboot-persistent memory regions.
519
 *  - used for vga bios and option roms.
520
 *  - also linux kernel (-kernel / -initrd).
521
 */
522

    
523
typedef struct Rom Rom;
524

    
525
struct Rom {
526
    char *name;
527
    char *path;
528
    size_t romsize;
529
    uint8_t *data;
530
    int isrom;
531
    char *fw_dir;
532
    char *fw_file;
533

    
534
    target_phys_addr_t addr;
535
    QTAILQ_ENTRY(Rom) next;
536
};
537

    
538
static FWCfgState *fw_cfg;
539
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
540

    
541
static void rom_insert(Rom *rom)
542
{
543
    Rom *item;
544

    
545
    if (roms_loaded) {
546
        hw_error ("ROM images must be loaded at startup\n");
547
    }
548

    
549
    /* list is ordered by load address */
550
    QTAILQ_FOREACH(item, &roms, next) {
551
        if (rom->addr >= item->addr)
552
            continue;
553
        QTAILQ_INSERT_BEFORE(item, rom, next);
554
        return;
555
    }
556
    QTAILQ_INSERT_TAIL(&roms, rom, next);
557
}
558

    
559
int rom_add_file(const char *file, const char *fw_dir,
560
                 target_phys_addr_t addr)
561
{
562
    Rom *rom;
563
    int rc, fd = -1;
564

    
565
    rom = qemu_mallocz(sizeof(*rom));
566
    rom->name = qemu_strdup(file);
567
    rom->path = qemu_find_file(QEMU_FILE_TYPE_BIOS, rom->name);
568
    if (rom->path == NULL) {
569
        rom->path = qemu_strdup(file);
570
    }
571

    
572
    fd = open(rom->path, O_RDONLY | O_BINARY);
573
    if (fd == -1) {
574
        fprintf(stderr, "Could not open option rom '%s': %s\n",
575
                rom->path, strerror(errno));
576
        goto err;
577
    }
578

    
579
    if (fw_dir) {
580
        rom->fw_dir  = qemu_strdup(fw_dir);
581
        rom->fw_file = qemu_strdup(file);
582
    }
583
    rom->addr    = addr;
584
    rom->romsize = lseek(fd, 0, SEEK_END);
585
    rom->data    = qemu_mallocz(rom->romsize);
586
    lseek(fd, 0, SEEK_SET);
587
    rc = read(fd, rom->data, rom->romsize);
588
    if (rc != rom->romsize) {
589
        fprintf(stderr, "rom: file %-20s: read error: rc=%d (expected %zd)\n",
590
                rom->name, rc, rom->romsize);
591
        goto err;
592
    }
593
    close(fd);
594
    rom_insert(rom);
595
    if (rom->fw_file && fw_cfg)
596
        fw_cfg_add_file(fw_cfg, rom->fw_dir, rom->fw_file, rom->data, rom->romsize);
597
    return 0;
598

    
599
err:
600
    if (fd != -1)
601
        close(fd);
602
    qemu_free(rom->data);
603
    qemu_free(rom->path);
604
    qemu_free(rom->name);
605
    qemu_free(rom);
606
    return -1;
607
}
608

    
609
int rom_add_blob(const char *name, const void *blob, size_t len,
610
                 target_phys_addr_t addr)
611
{
612
    Rom *rom;
613

    
614
    rom = qemu_mallocz(sizeof(*rom));
615
    rom->name    = qemu_strdup(name);
616
    rom->addr    = addr;
617
    rom->romsize = len;
618
    rom->data    = qemu_mallocz(rom->romsize);
619
    memcpy(rom->data, blob, len);
620
    rom_insert(rom);
621
    return 0;
622
}
623

    
624
int rom_add_vga(const char *file)
625
{
626
    return rom_add_file(file, "vgaroms", 0);
627
}
628

    
629
int rom_add_option(const char *file)
630
{
631
    return rom_add_file(file, "genroms", 0);
632
}
633

    
634
static void rom_reset(void *unused)
635
{
636
    Rom *rom;
637

    
638
    QTAILQ_FOREACH(rom, &roms, next) {
639
        if (rom->fw_file) {
640
            continue;
641
        }
642
        if (rom->data == NULL) {
643
            continue;
644
        }
645
        cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
646
        if (rom->isrom) {
647
            /* rom needs to be written only once */
648
            qemu_free(rom->data);
649
            rom->data = NULL;
650
        }
651
    }
652
}
653

    
654
int rom_load_all(void)
655
{
656
    target_phys_addr_t addr = 0;
657
    int memtype;
658
    Rom *rom;
659

    
660
    QTAILQ_FOREACH(rom, &roms, next) {
661
        if (rom->fw_file) {
662
            continue;
663
        }
664
        if (addr > rom->addr) {
665
            fprintf(stderr, "rom: requested regions overlap "
666
                    "(rom %s. free=0x" TARGET_FMT_plx
667
                    ", addr=0x" TARGET_FMT_plx ")\n",
668
                    rom->name, addr, rom->addr);
669
            return -1;
670
        }
671
        addr  = rom->addr;
672
        addr += rom->romsize;
673
        memtype = cpu_get_physical_page_desc(rom->addr) & (3 << IO_MEM_SHIFT);
674
        if (memtype == IO_MEM_ROM)
675
            rom->isrom = 1;
676
    }
677
    qemu_register_reset(rom_reset, NULL);
678
    roms_loaded = 1;
679
    return 0;
680
}
681

    
682
void rom_set_fw(void *f)
683
{
684
    fw_cfg = f;
685
}
686

    
687
static Rom *find_rom(target_phys_addr_t addr)
688
{
689
    Rom *rom;
690

    
691
    QTAILQ_FOREACH(rom, &roms, next) {
692
        if (rom->fw_file) {
693
            continue;
694
        }
695
        if (rom->addr > addr) {
696
            continue;
697
        }
698
        if (rom->addr + rom->romsize < addr) {
699
            continue;
700
        }
701
        return rom;
702
    }
703
    return NULL;
704
}
705

    
706
/*
707
 * Copies memory from registered ROMs to dest. Any memory that is contained in
708
 * a ROM between addr and addr + size is copied. Note that this can involve
709
 * multiple ROMs, which need not start at addr and need not end at addr + size.
710
 */
711
int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size)
712
{
713
    target_phys_addr_t end = addr + size;
714
    uint8_t *s, *d = dest;
715
    size_t l = 0;
716
    Rom *rom;
717

    
718
    QTAILQ_FOREACH(rom, &roms, next) {
719
        if (rom->fw_file) {
720
            continue;
721
        }
722
        if (rom->addr + rom->romsize < addr) {
723
            continue;
724
        }
725
        if (rom->addr > end) {
726
            break;
727
        }
728
        if (!rom->data) {
729
            continue;
730
        }
731

    
732
        d = dest + (rom->addr - addr);
733
        s = rom->data;
734
        l = rom->romsize;
735

    
736
        if ((d + l) > (dest + size)) {
737
            l = dest - d;
738
        }
739

    
740
        memcpy(d, s, l);
741
    }
742

    
743
    return (d + l) - dest;
744
}
745

    
746
void *rom_ptr(target_phys_addr_t addr)
747
{
748
    Rom *rom;
749

    
750
    rom = find_rom(addr);
751
    if (!rom || !rom->data)
752
        return NULL;
753
    return rom->data + (addr - rom->addr);
754
}
755

    
756
void do_info_roms(Monitor *mon)
757
{
758
    Rom *rom;
759

    
760
    QTAILQ_FOREACH(rom, &roms, next) {
761
        if (!rom->fw_file) {
762
            monitor_printf(mon, "addr=" TARGET_FMT_plx
763
                           " size=0x%06zx mem=%s name=\"%s\" \n",
764
                           rom->addr, rom->romsize,
765
                           rom->isrom ? "rom" : "ram",
766
                           rom->name);
767
        } else {
768
            monitor_printf(mon, "fw=%s/%s"
769
                           " size=0x%06zx name=\"%s\" \n",
770
                           rom->fw_dir,
771
                           rom->fw_file,
772
                           rom->romsize,
773
                           rom->name);
774
        }
775
    }
776
}