qemu/hw/core/loader.c
<<
>>
Prefs
   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/hw.h"
  46#include "disas/disas.h"
  47#include "monitor/monitor.h"
  48#include "sysemu/sysemu.h"
  49#include "uboot_image.h"
  50#include "hw/loader.h"
  51#include "hw/nvram/fw_cfg.h"
  52#include "exec/memory.h"
  53#include "exec/address-spaces.h"
  54
  55#include <zlib.h>
  56
  57static int roms_loaded;
  58
  59/* return the size or -1 if error */
  60int get_image_size(const char *filename)
  61{
  62    int fd, size;
  63    fd = open(filename, O_RDONLY | O_BINARY);
  64    if (fd < 0)
  65        return -1;
  66    size = lseek(fd, 0, SEEK_END);
  67    close(fd);
  68    return size;
  69}
  70
  71/* return the size or -1 if error */
  72/* deprecated, because caller does not specify buffer size! */
  73int load_image(const char *filename, uint8_t *addr)
  74{
  75    int fd, size;
  76    fd = open(filename, O_RDONLY | O_BINARY);
  77    if (fd < 0)
  78        return -1;
  79    size = lseek(fd, 0, SEEK_END);
  80    lseek(fd, 0, SEEK_SET);
  81    if (read(fd, addr, size) != size) {
  82        close(fd);
  83        return -1;
  84    }
  85    close(fd);
  86    return size;
  87}
  88
  89/* read()-like version */
  90ssize_t read_targphys(const char *name,
  91                      int fd, hwaddr dst_addr, size_t nbytes)
  92{
  93    uint8_t *buf;
  94    ssize_t did;
  95
  96    buf = g_malloc(nbytes);
  97    did = read(fd, buf, nbytes);
  98    if (did > 0)
  99        rom_add_blob_fixed("read", buf, did, dst_addr);
 100    g_free(buf);
 101    return did;
 102}
 103
 104/* return the size or -1 if error */
 105int load_image_targphys(const char *filename,
 106                        hwaddr addr, uint64_t max_sz)
 107{
 108    int size;
 109
 110    size = get_image_size(filename);
 111    if (size > max_sz) {
 112        return -1;
 113    }
 114    if (size > 0) {
 115        rom_add_file_fixed(filename, addr, -1);
 116    }
 117    return size;
 118}
 119
 120void pstrcpy_targphys(const char *name, hwaddr dest, int buf_size,
 121                      const char *source)
 122{
 123    const char *nulp;
 124    char *ptr;
 125
 126    if (buf_size <= 0) return;
 127    nulp = memchr(source, 0, buf_size);
 128    if (nulp) {
 129        rom_add_blob_fixed(name, source, (nulp - source) + 1, dest);
 130    } else {
 131        rom_add_blob_fixed(name, source, buf_size, dest);
 132        ptr = rom_ptr(dest + buf_size - 1);
 133        *ptr = 0;
 134    }
 135}
 136
 137/* A.OUT loader */
 138
 139struct exec
 140{
 141  uint32_t a_info;   /* Use macros N_MAGIC, etc for access */
 142  uint32_t a_text;   /* length of text, in bytes */
 143  uint32_t a_data;   /* length of data, in bytes */
 144  uint32_t a_bss;    /* length of uninitialized data area, in bytes */
 145  uint32_t a_syms;   /* length of symbol table data in file, in bytes */
 146  uint32_t a_entry;  /* start address */
 147  uint32_t a_trsize; /* length of relocation info for text, in bytes */
 148  uint32_t a_drsize; /* length of relocation info for data, in bytes */
 149};
 150
 151static void bswap_ahdr(struct exec *e)
 152{
 153    bswap32s(&e->a_info);
 154    bswap32s(&e->a_text);
 155    bswap32s(&e->a_data);
 156    bswap32s(&e->a_bss);
 157    bswap32s(&e->a_syms);
 158    bswap32s(&e->a_entry);
 159    bswap32s(&e->a_trsize);
 160    bswap32s(&e->a_drsize);
 161}
 162
 163#define N_MAGIC(exec) ((exec).a_info & 0xffff)
 164#define OMAGIC 0407
 165#define NMAGIC 0410
 166#define ZMAGIC 0413
 167#define QMAGIC 0314
 168#define _N_HDROFF(x) (1024 - sizeof (struct exec))
 169#define N_TXTOFF(x)                                                     \
 170    (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) :     \
 171     (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
 172#define N_TXTADDR(x, target_page_size) (N_MAGIC(x) == QMAGIC ? target_page_size : 0)
 173#define _N_SEGMENT_ROUND(x, target_page_size) (((x) + target_page_size - 1) & ~(target_page_size - 1))
 174
 175#define _N_TXTENDADDR(x, target_page_size) (N_TXTADDR(x, target_page_size)+(x).a_text)
 176
 177#define N_DATADDR(x, target_page_size) \
 178    (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x, target_page_size)) \
 179     : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x, target_page_size), target_page_size)))
 180
 181
 182int load_aout(const char *filename, hwaddr addr, int max_sz,
 183              int bswap_needed, hwaddr target_page_size)
 184{
 185    int fd;
 186    ssize_t size, ret;
 187    struct exec e;
 188    uint32_t magic;
 189
 190    fd = open(filename, O_RDONLY | O_BINARY);
 191    if (fd < 0)
 192        return -1;
 193
 194    size = read(fd, &e, sizeof(e));
 195    if (size < 0)
 196        goto fail;
 197
 198    if (bswap_needed) {
 199        bswap_ahdr(&e);
 200    }
 201
 202    magic = N_MAGIC(e);
 203    switch (magic) {
 204    case ZMAGIC:
 205    case QMAGIC:
 206    case OMAGIC:
 207        if (e.a_text + e.a_data > max_sz)
 208            goto fail;
 209        lseek(fd, N_TXTOFF(e), SEEK_SET);
 210        size = read_targphys(filename, fd, addr, e.a_text + e.a_data);
 211        if (size < 0)
 212            goto fail;
 213        break;
 214    case NMAGIC:
 215        if (N_DATADDR(e, target_page_size) + e.a_data > max_sz)
 216            goto fail;
 217        lseek(fd, N_TXTOFF(e), SEEK_SET);
 218        size = read_targphys(filename, fd, addr, e.a_text);
 219        if (size < 0)
 220            goto fail;
 221        ret = read_targphys(filename, fd, addr + N_DATADDR(e, target_page_size),
 222                            e.a_data);
 223        if (ret < 0)
 224            goto fail;
 225        size += ret;
 226        break;
 227    default:
 228        goto fail;
 229    }
 230    close(fd);
 231    return size;
 232 fail:
 233    close(fd);
 234    return -1;
 235}
 236
 237/* ELF loader */
 238
 239static void *load_at(int fd, int offset, int size)
 240{
 241    void *ptr;
 242    if (lseek(fd, offset, SEEK_SET) < 0)
 243        return NULL;
 244    ptr = g_malloc(size);
 245    if (read(fd, ptr, size) != size) {
 246        g_free(ptr);
 247        return NULL;
 248    }
 249    return ptr;
 250}
 251
 252#ifdef ELF_CLASS
 253#undef ELF_CLASS
 254#endif
 255
 256#define ELF_CLASS   ELFCLASS32
 257#include "elf.h"
 258
 259#define SZ              32
 260#define elf_word        uint32_t
 261#define elf_sword        int32_t
 262#define bswapSZs        bswap32s
 263#include "hw/elf_ops.h"
 264
 265#undef elfhdr
 266#undef elf_phdr
 267#undef elf_shdr
 268#undef elf_sym
 269#undef elf_note
 270#undef elf_word
 271#undef elf_sword
 272#undef bswapSZs
 273#undef SZ
 274#define elfhdr          elf64_hdr
 275#define elf_phdr        elf64_phdr
 276#define elf_note        elf64_note
 277#define elf_shdr        elf64_shdr
 278#define elf_sym         elf64_sym
 279#define elf_word        uint64_t
 280#define elf_sword        int64_t
 281#define bswapSZs        bswap64s
 282#define SZ              64
 283#include "hw/elf_ops.h"
 284
 285/* return < 0 if error, otherwise the number of bytes loaded in memory */
 286int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
 287             void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
 288             uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb)
 289{
 290    int fd, data_order, target_data_order, must_swab, ret;
 291    uint8_t e_ident[EI_NIDENT];
 292
 293    fd = open(filename, O_RDONLY | O_BINARY);
 294    if (fd < 0) {
 295        perror(filename);
 296        return -1;
 297    }
 298    if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))
 299        goto fail;
 300    if (e_ident[0] != ELFMAG0 ||
 301        e_ident[1] != ELFMAG1 ||
 302        e_ident[2] != ELFMAG2 ||
 303        e_ident[3] != ELFMAG3)
 304        goto fail;
 305#ifdef HOST_WORDS_BIGENDIAN
 306    data_order = ELFDATA2MSB;
 307#else
 308    data_order = ELFDATA2LSB;
 309#endif
 310    must_swab = data_order != e_ident[EI_DATA];
 311    if (big_endian) {
 312        target_data_order = ELFDATA2MSB;
 313    } else {
 314        target_data_order = ELFDATA2LSB;
 315    }
 316
 317    if (target_data_order != e_ident[EI_DATA]) {
 318        goto fail;
 319    }
 320
 321    lseek(fd, 0, SEEK_SET);
 322    if (e_ident[EI_CLASS] == ELFCLASS64) {
 323        ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab,
 324                         pentry, lowaddr, highaddr, elf_machine, clear_lsb);
 325    } else {
 326        ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab,
 327                         pentry, lowaddr, highaddr, elf_machine, clear_lsb);
 328    }
 329
 330    close(fd);
 331    return ret;
 332
 333 fail:
 334    close(fd);
 335    return -1;
 336}
 337
 338static void bswap_uboot_header(uboot_image_header_t *hdr)
 339{
 340#ifndef HOST_WORDS_BIGENDIAN
 341    bswap32s(&hdr->ih_magic);
 342    bswap32s(&hdr->ih_hcrc);
 343    bswap32s(&hdr->ih_time);
 344    bswap32s(&hdr->ih_size);
 345    bswap32s(&hdr->ih_load);
 346    bswap32s(&hdr->ih_ep);
 347    bswap32s(&hdr->ih_dcrc);
 348#endif
 349}
 350
 351
 352#define ZALLOC_ALIGNMENT        16
 353
 354static void *zalloc(void *x, unsigned items, unsigned size)
 355{
 356    void *p;
 357
 358    size *= items;
 359    size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
 360
 361    p = g_malloc(size);
 362
 363    return (p);
 364}
 365
 366static void zfree(void *x, void *addr)
 367{
 368    g_free(addr);
 369}
 370
 371
 372#define HEAD_CRC        2
 373#define EXTRA_FIELD     4
 374#define ORIG_NAME       8
 375#define COMMENT         0x10
 376#define RESERVED        0xe0
 377
 378#define DEFLATED        8
 379
 380/* This is the usual maximum in uboot, so if a uImage overflows this, it would
 381 * overflow on real hardware too. */
 382#define UBOOT_MAX_GUNZIP_BYTES (64 << 20)
 383
 384static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
 385                      size_t srclen)
 386{
 387    z_stream s;
 388    ssize_t dstbytes;
 389    int r, i, flags;
 390
 391    /* skip header */
 392    i = 10;
 393    flags = src[3];
 394    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
 395        puts ("Error: Bad gzipped data\n");
 396        return -1;
 397    }
 398    if ((flags & EXTRA_FIELD) != 0)
 399        i = 12 + src[10] + (src[11] << 8);
 400    if ((flags & ORIG_NAME) != 0)
 401        while (src[i++] != 0)
 402            ;
 403    if ((flags & COMMENT) != 0)
 404        while (src[i++] != 0)
 405            ;
 406    if ((flags & HEAD_CRC) != 0)
 407        i += 2;
 408    if (i >= srclen) {
 409        puts ("Error: gunzip out of data in header\n");
 410        return -1;
 411    }
 412
 413    s.zalloc = zalloc;
 414    s.zfree = zfree;
 415
 416    r = inflateInit2(&s, -MAX_WBITS);
 417    if (r != Z_OK) {
 418        printf ("Error: inflateInit2() returned %d\n", r);
 419        return (-1);
 420    }
 421    s.next_in = src + i;
 422    s.avail_in = srclen - i;
 423    s.next_out = dst;
 424    s.avail_out = dstlen;
 425    r = inflate(&s, Z_FINISH);
 426    if (r != Z_OK && r != Z_STREAM_END) {
 427        printf ("Error: inflate() returned %d\n", r);
 428        return -1;
 429    }
 430    dstbytes = s.next_out - (unsigned char *) dst;
 431    inflateEnd(&s);
 432
 433    return dstbytes;
 434}
 435
 436/* Load a U-Boot image.  */
 437static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
 438                            int *is_linux, uint8_t image_type)
 439{
 440    int fd;
 441    int size;
 442    hwaddr address;
 443    uboot_image_header_t h;
 444    uboot_image_header_t *hdr = &h;
 445    uint8_t *data = NULL;
 446    int ret = -1;
 447    int do_uncompress = 0;
 448
 449    fd = open(filename, O_RDONLY | O_BINARY);
 450    if (fd < 0)
 451        return -1;
 452
 453    size = read(fd, hdr, sizeof(uboot_image_header_t));
 454    if (size < 0)
 455        goto out;
 456
 457    bswap_uboot_header(hdr);
 458
 459    if (hdr->ih_magic != IH_MAGIC)
 460        goto out;
 461
 462    if (hdr->ih_type != image_type) {
 463        fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
 464                image_type);
 465        goto out;
 466    }
 467
 468    /* TODO: Implement other image types.  */
 469    switch (hdr->ih_type) {
 470    case IH_TYPE_KERNEL:
 471        address = hdr->ih_load;
 472        if (loadaddr) {
 473            *loadaddr = hdr->ih_load;
 474        }
 475
 476        switch (hdr->ih_comp) {
 477        case IH_COMP_NONE:
 478            break;
 479        case IH_COMP_GZIP:
 480            do_uncompress = 1;
 481            break;
 482        default:
 483            fprintf(stderr,
 484                    "Unable to load u-boot images with compression type %d\n",
 485                    hdr->ih_comp);
 486            goto out;
 487        }
 488
 489        if (ep) {
 490            *ep = hdr->ih_ep;
 491        }
 492
 493        /* TODO: Check CPU type.  */
 494        if (is_linux) {
 495            if (hdr->ih_os == IH_OS_LINUX) {
 496                *is_linux = 1;
 497            } else {
 498                *is_linux = 0;
 499            }
 500        }
 501
 502        break;
 503    case IH_TYPE_RAMDISK:
 504        address = *loadaddr;
 505        break;
 506    default:
 507        fprintf(stderr, "Unsupported u-boot image type %d\n", hdr->ih_type);
 508        goto out;
 509    }
 510
 511    data = g_malloc(hdr->ih_size);
 512
 513    if (read(fd, data, hdr->ih_size) != hdr->ih_size) {
 514        fprintf(stderr, "Error reading file\n");
 515        goto out;
 516    }
 517
 518    if (do_uncompress) {
 519        uint8_t *compressed_data;
 520        size_t max_bytes;
 521        ssize_t bytes;
 522
 523        compressed_data = data;
 524        max_bytes = UBOOT_MAX_GUNZIP_BYTES;
 525        data = g_malloc(max_bytes);
 526
 527        bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size);
 528        g_free(compressed_data);
 529        if (bytes < 0) {
 530            fprintf(stderr, "Unable to decompress gzipped image!\n");
 531            goto out;
 532        }
 533        hdr->ih_size = bytes;
 534    }
 535
 536    rom_add_blob_fixed(filename, data, hdr->ih_size, address);
 537
 538    ret = hdr->ih_size;
 539
 540out:
 541    if (data)
 542        g_free(data);
 543    close(fd);
 544    return ret;
 545}
 546
 547int load_uimage(const char *filename, hwaddr *ep, hwaddr *loadaddr,
 548                int *is_linux)
 549{
 550    return load_uboot_image(filename, ep, loadaddr, is_linux, IH_TYPE_KERNEL);
 551}
 552
 553/* Load a ramdisk.  */
 554int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz)
 555{
 556    return load_uboot_image(filename, NULL, &addr, NULL, IH_TYPE_RAMDISK);
 557}
 558
 559/*
 560 * Functions for reboot-persistent memory regions.
 561 *  - used for vga bios and option roms.
 562 *  - also linux kernel (-kernel / -initrd).
 563 */
 564
 565typedef struct Rom Rom;
 566
 567struct Rom {
 568    char *name;
 569    char *path;
 570
 571    /* datasize is the amount of memory allocated in "data". If datasize is less
 572     * than romsize, it means that the area from datasize to romsize is filled
 573     * with zeros.
 574     */
 575    size_t romsize;
 576    size_t datasize;
 577
 578    uint8_t *data;
 579    int isrom;
 580    char *fw_dir;
 581    char *fw_file;
 582
 583    hwaddr addr;
 584    QTAILQ_ENTRY(Rom) next;
 585};
 586
 587static FWCfgState *fw_cfg;
 588static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
 589
 590static void rom_insert(Rom *rom)
 591{
 592    Rom *item;
 593
 594    if (roms_loaded) {
 595        hw_error ("ROM images must be loaded at startup\n");
 596    }
 597
 598    /* list is ordered by load address */
 599    QTAILQ_FOREACH(item, &roms, next) {
 600        if (rom->addr >= item->addr)
 601            continue;
 602        QTAILQ_INSERT_BEFORE(item, rom, next);
 603        return;
 604    }
 605    QTAILQ_INSERT_TAIL(&roms, rom, next);
 606}
 607
 608int rom_add_file(const char *file, const char *fw_dir,
 609                 hwaddr addr, int32_t bootindex)
 610{
 611    Rom *rom;
 612    int rc, fd = -1;
 613    char devpath[100];
 614
 615    rom = g_malloc0(sizeof(*rom));
 616    rom->name = g_strdup(file);
 617    rom->path = qemu_find_file(QEMU_FILE_TYPE_BIOS, rom->name);
 618    if (rom->path == NULL) {
 619        rom->path = g_strdup(file);
 620    }
 621
 622    fd = open(rom->path, O_RDONLY | O_BINARY);
 623    if (fd == -1) {
 624        fprintf(stderr, "Could not open option rom '%s': %s\n",
 625                rom->path, strerror(errno));
 626        goto err;
 627    }
 628
 629    if (fw_dir) {
 630        rom->fw_dir  = g_strdup(fw_dir);
 631        rom->fw_file = g_strdup(file);
 632    }
 633    rom->addr     = addr;
 634    rom->romsize  = lseek(fd, 0, SEEK_END);
 635    rom->datasize = rom->romsize;
 636    rom->data     = g_malloc0(rom->datasize);
 637    lseek(fd, 0, SEEK_SET);
 638    rc = read(fd, rom->data, rom->datasize);
 639    if (rc != rom->datasize) {
 640        fprintf(stderr, "rom: file %-20s: read error: rc=%d (expected %zd)\n",
 641                rom->name, rc, rom->datasize);
 642        goto err;
 643    }
 644    close(fd);
 645    rom_insert(rom);
 646    if (rom->fw_file && fw_cfg) {
 647        const char *basename;
 648        char fw_file_name[56];
 649
 650        basename = strrchr(rom->fw_file, '/');
 651        if (basename) {
 652            basename++;
 653        } else {
 654            basename = rom->fw_file;
 655        }
 656        snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", rom->fw_dir,
 657                 basename);
 658        fw_cfg_add_file(fw_cfg, fw_file_name, rom->data, rom->romsize);
 659        snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
 660    } else {
 661        snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr);
 662    }
 663
 664    add_boot_device_path(bootindex, NULL, devpath);
 665    return 0;
 666
 667err:
 668    if (fd != -1)
 669        close(fd);
 670    g_free(rom->data);
 671    g_free(rom->path);
 672    g_free(rom->name);
 673    g_free(rom);
 674    return -1;
 675}
 676
 677int rom_add_blob(const char *name, const void *blob, size_t len,
 678                 hwaddr addr)
 679{
 680    Rom *rom;
 681
 682    rom           = g_malloc0(sizeof(*rom));
 683    rom->name     = g_strdup(name);
 684    rom->addr     = addr;
 685    rom->romsize  = len;
 686    rom->datasize = len;
 687    rom->data     = g_malloc0(rom->datasize);
 688    memcpy(rom->data, blob, len);
 689    rom_insert(rom);
 690    return 0;
 691}
 692
 693/* This function is specific for elf program because we don't need to allocate
 694 * all the rom. We just allocate the first part and the rest is just zeros. This
 695 * is why romsize and datasize are different. Also, this function seize the
 696 * memory ownership of "data", so we don't have to allocate and copy the buffer.
 697 */
 698int rom_add_elf_program(const char *name, void *data, size_t datasize,
 699                        size_t romsize, hwaddr addr)
 700{
 701    Rom *rom;
 702
 703    rom           = g_malloc0(sizeof(*rom));
 704    rom->name     = g_strdup(name);
 705    rom->addr     = addr;
 706    rom->datasize = datasize;
 707    rom->romsize  = romsize;
 708    rom->data     = data;
 709    rom_insert(rom);
 710    return 0;
 711}
 712
 713int rom_add_vga(const char *file)
 714{
 715    return rom_add_file(file, "vgaroms", 0, -1);
 716}
 717
 718int rom_add_option(const char *file, int32_t bootindex)
 719{
 720    return rom_add_file(file, "genroms", 0, bootindex);
 721}
 722
 723static void rom_reset(void *unused)
 724{
 725    Rom *rom;
 726
 727    QTAILQ_FOREACH(rom, &roms, next) {
 728        if (rom->fw_file) {
 729            continue;
 730        }
 731        if (rom->data == NULL) {
 732            continue;
 733        }
 734        cpu_physical_memory_write_rom(rom->addr, rom->data, rom->datasize);
 735        if (rom->isrom) {
 736            /* rom needs to be written only once */
 737            g_free(rom->data);
 738            rom->data = NULL;
 739        }
 740    }
 741}
 742
 743int rom_load_all(void)
 744{
 745    hwaddr addr = 0;
 746    MemoryRegionSection section;
 747    Rom *rom;
 748
 749    QTAILQ_FOREACH(rom, &roms, next) {
 750        if (rom->fw_file) {
 751            continue;
 752        }
 753        if (addr > rom->addr) {
 754            fprintf(stderr, "rom: requested regions overlap "
 755                    "(rom %s. free=0x" TARGET_FMT_plx
 756                    ", addr=0x" TARGET_FMT_plx ")\n",
 757                    rom->name, addr, rom->addr);
 758            return -1;
 759        }
 760        addr  = rom->addr;
 761        addr += rom->romsize;
 762        section = memory_region_find(get_system_memory(), rom->addr, 1);
 763        rom->isrom = int128_nz(section.size) && memory_region_is_rom(section.mr);
 764        memory_region_unref(section.mr);
 765    }
 766    qemu_register_reset(rom_reset, NULL);
 767    roms_loaded = 1;
 768    return 0;
 769}
 770
 771void rom_set_fw(FWCfgState *f)
 772{
 773    fw_cfg = f;
 774}
 775
 776static Rom *find_rom(hwaddr addr)
 777{
 778    Rom *rom;
 779
 780    QTAILQ_FOREACH(rom, &roms, next) {
 781        if (rom->fw_file) {
 782            continue;
 783        }
 784        if (rom->addr > addr) {
 785            continue;
 786        }
 787        if (rom->addr + rom->romsize < addr) {
 788            continue;
 789        }
 790        return rom;
 791    }
 792    return NULL;
 793}
 794
 795/*
 796 * Copies memory from registered ROMs to dest. Any memory that is contained in
 797 * a ROM between addr and addr + size is copied. Note that this can involve
 798 * multiple ROMs, which need not start at addr and need not end at addr + size.
 799 */
 800int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
 801{
 802    hwaddr end = addr + size;
 803    uint8_t *s, *d = dest;
 804    size_t l = 0;
 805    Rom *rom;
 806
 807    QTAILQ_FOREACH(rom, &roms, next) {
 808        if (rom->fw_file) {
 809            continue;
 810        }
 811        if (rom->addr + rom->romsize < addr) {
 812            continue;
 813        }
 814        if (rom->addr > end) {
 815            break;
 816        }
 817
 818        d = dest + (rom->addr - addr);
 819        s = rom->data;
 820        l = rom->datasize;
 821
 822        if ((d + l) > (dest + size)) {
 823            l = dest - d;
 824        }
 825
 826        if (l > 0) {
 827            memcpy(d, s, l);
 828        }
 829
 830        if (rom->romsize > rom->datasize) {
 831            /* If datasize is less than romsize, it means that we didn't
 832             * allocate all the ROM because the trailing data are only zeros.
 833             */
 834
 835            d += l;
 836            l = rom->romsize - rom->datasize;
 837
 838            if ((d + l) > (dest + size)) {
 839                /* Rom size doesn't fit in the destination area. Adjust to avoid
 840                 * overflow.
 841                 */
 842                l = dest - d;
 843            }
 844
 845            if (l > 0) {
 846                memset(d, 0x0, l);
 847            }
 848        }
 849    }
 850
 851    return (d + l) - dest;
 852}
 853
 854void *rom_ptr(hwaddr addr)
 855{
 856    Rom *rom;
 857
 858    rom = find_rom(addr);
 859    if (!rom || !rom->data)
 860        return NULL;
 861    return rom->data + (addr - rom->addr);
 862}
 863
 864void do_info_roms(Monitor *mon, const QDict *qdict)
 865{
 866    Rom *rom;
 867
 868    QTAILQ_FOREACH(rom, &roms, next) {
 869        if (!rom->fw_file) {
 870            monitor_printf(mon, "addr=" TARGET_FMT_plx
 871                           " size=0x%06zx mem=%s name=\"%s\"\n",
 872                           rom->addr, rom->romsize,
 873                           rom->isrom ? "rom" : "ram",
 874                           rom->name);
 875        } else {
 876            monitor_printf(mon, "fw=%s/%s"
 877                           " size=0x%06zx name=\"%s\"\n",
 878                           rom->fw_dir,
 879                           rom->fw_file,
 880                           rom->romsize,
 881                           rom->name);
 882        }
 883    }
 884}
 885