Lines Matching +full:rom +full:-
24 * Gunzip functionality in this file is derived from u-boot:
28 * (C) Copyright 2000-2005
47 #include "qemu/error-report.h"
49 #include "qapi/qapi-commands-machine.h"
50 #include "qapi/type-helpers.h"
71 /* return the size or -1 if error */
78 return -1; in get_image_size()
84 /* return the size or -1 if error */
92 return -1; in load_image_size()
95 while ((actsize = read(fd, addr + l, size - l)) > 0) { in load_image_size()
101 return actsize < 0 ? -1 : l; in load_image_size()
104 /* read()-like version */
125 /* return the size or -1 if error */
133 return -1; in load_image_targphys_as()
136 if (rom_add_file_fixed_as(filename, addr, -1, as) < 0) { in load_image_targphys_as()
137 return -1; in load_image_targphys_as()
148 /* Can only load an image into RAM or ROM */ in load_image_mr()
149 return -1; in load_image_mr()
155 return -1; in load_image_mr()
158 if (rom_add_file_mr(filename, mr, -1) < 0) { in load_image_mr()
159 return -1; in load_image_mr()
174 rom_add_blob_fixed(name, source, (nulp - source) + 1, dest); in pstrcpy_targphys()
177 ptr = rom_ptr(dest + buf_size - 1, sizeof(*ptr)); in pstrcpy_targphys()
198 bswap32s(&e->a_info); in bswap_ahdr()
199 bswap32s(&e->a_text); in bswap_ahdr()
200 bswap32s(&e->a_data); in bswap_ahdr()
201 bswap32s(&e->a_bss); in bswap_ahdr()
202 bswap32s(&e->a_syms); in bswap_ahdr()
203 bswap32s(&e->a_entry); in bswap_ahdr()
204 bswap32s(&e->a_trsize); in bswap_ahdr()
205 bswap32s(&e->a_drsize); in bswap_ahdr()
213 #define _N_HDROFF(x) (1024 - sizeof (struct exec))
218 #define _N_SEGMENT_ROUND(x, target_page_size) (((x) + target_page_size - 1) & ~(target_page_size - …
237 return -1; in load_aout()
279 return -1; in load_aout()
390 size_t br = read(fd, hdr + off, hdr_size - off); in load_elf_hdr()
395 case -1: in load_elf_hdr()
467 return -1; in load_elf_ram_sym()
520 bswap32s(&hdr->ih_magic); in bswap_uboot_header()
521 bswap32s(&hdr->ih_hcrc); in bswap_uboot_header()
522 bswap32s(&hdr->ih_time); in bswap_uboot_header()
523 bswap32s(&hdr->ih_size); in bswap_uboot_header()
524 bswap32s(&hdr->ih_load); in bswap_uboot_header()
525 bswap32s(&hdr->ih_ep); in bswap_uboot_header()
526 bswap32s(&hdr->ih_dcrc); in bswap_uboot_header()
538 size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); in zalloc()
573 return -1; in gunzip()
601 r = inflateInit2(&s, -MAX_WBITS); in gunzip()
604 return (-1); in gunzip()
607 s.avail_in = srclen - i; in gunzip()
614 return -1; in gunzip()
616 dstbytes = s.next_out - (unsigned char *) dst; in gunzip()
623 return -1; in gunzip()
626 /* Load a U-Boot image. */
639 int ret = -1; in load_uboot_image()
644 return -1; in load_uboot_image()
653 if (hdr->ih_magic != IH_MAGIC) in load_uboot_image()
656 if (hdr->ih_type != image_type) { in load_uboot_image()
658 hdr->ih_type == IH_TYPE_KERNEL_NOLOAD)) { in load_uboot_image()
659 fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type, in load_uboot_image()
666 switch (hdr->ih_type) { in load_uboot_image()
674 hdr->ih_load = *loadaddr + sizeof(*hdr); in load_uboot_image()
675 hdr->ih_ep += hdr->ih_load; in load_uboot_image()
678 address = hdr->ih_load; in load_uboot_image()
683 *loadaddr = hdr->ih_load; in load_uboot_image()
686 switch (hdr->ih_comp) { in load_uboot_image()
694 "Unable to load u-boot images with compression type %d\n", in load_uboot_image()
695 hdr->ih_comp); in load_uboot_image()
700 *ep = hdr->ih_ep; in load_uboot_image()
705 if (hdr->ih_os == IH_OS_LINUX) { in load_uboot_image()
707 } else if (hdr->ih_os == IH_OS_VXWORKS) { in load_uboot_image()
710 * on Arm (64-bit only), PowerPC and RISC-V architectures. in load_uboot_image()
712 switch (hdr->ih_arch) { in load_uboot_image()
732 fprintf(stderr, "Unsupported u-boot image type %d\n", hdr->ih_type); in load_uboot_image()
736 data = g_malloc(hdr->ih_size); in load_uboot_image()
738 if (read(fd, data, hdr->ih_size) != hdr->ih_size) { in load_uboot_image()
752 bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size); in load_uboot_image()
758 hdr->ih_size = bytes; in load_uboot_image()
761 rom_add_blob_fixed_as(filename, data, hdr->ih_size, address, as); in load_uboot_image()
763 ret = hdr->ih_size; in load_uboot_image()
802 /* Load a gzip-compressed kernel to a dynamically allocated buffer. */
810 int ret = -1; in load_image_gzipped_buffer()
817 /* Is it a gzip-compressed file? */ in load_image_gzipped_buffer()
849 /* The PE/COFF MS-DOS stub magic number */
860 * self-decompressing executables when loaded via EFI. The compressed payload
861 * can also be extracted from the image and decompressed by a non-EFI loader.
865 …el.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/firmware/efi/libstub/zboot-header.S
904 if (memcmp(&header->msdos_magic, EFI_PE_MSDOS_MAGIC, 2) != 0 || in unpack_efi_zboot_image()
905 memcmp(&header->zimg, "zimg", 4) != 0 || in unpack_efi_zboot_image()
906 memcmp(&header->linux_magic, EFI_PE_LINUX_MAGIC, 4) != 0) { in unpack_efi_zboot_image()
910 if (strcmp(header->compression_type, "gzip") != 0) { in unpack_efi_zboot_image()
913 (int)sizeof(header->compression_type) - 1, in unpack_efi_zboot_image()
914 header->compression_type); in unpack_efi_zboot_image()
915 return -1; in unpack_efi_zboot_image()
918 ploff = ldl_le_p(&header->payload_offset); in unpack_efi_zboot_image()
919 plsize = ldl_le_p(&header->payload_size); in unpack_efi_zboot_image()
923 return -1; in unpack_efi_zboot_image()
931 return -1; in unpack_efi_zboot_image()
941 * Functions for reboot-persistent memory regions.
942 * - used for vga bios and option roms.
943 * - also linux kernel (-kernel / -initrd).
946 typedef struct Rom Rom; typedef
948 struct Rom { struct
970 QTAILQ_ENTRY(Rom) next; argument
974 static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
977 * rom->data can be heap-allocated or memory-mapped (e.g. when added with
980 static void rom_free_data(Rom *rom) in rom_free_data() argument
982 if (rom->mapped_file) { in rom_free_data()
983 g_mapped_file_unref(rom->mapped_file); in rom_free_data()
984 rom->mapped_file = NULL; in rom_free_data()
986 g_free(rom->data); in rom_free_data()
989 rom->data = NULL; in rom_free_data()
992 static void rom_free(Rom *rom) in rom_free() argument
994 rom_free_data(rom); in rom_free()
995 g_free(rom->path); in rom_free()
996 g_free(rom->name); in rom_free()
997 g_free(rom->fw_dir); in rom_free()
998 g_free(rom->fw_file); in rom_free()
999 g_free(rom); in rom_free()
1002 static inline bool rom_order_compare(Rom *rom, Rom *item) in rom_order_compare() argument
1004 return ((uintptr_t)(void *)rom->as > (uintptr_t)(void *)item->as) || in rom_order_compare()
1005 (rom->as == item->as && rom->addr >= item->addr); in rom_order_compare()
1008 static void rom_insert(Rom *rom) in rom_insert() argument
1010 Rom *item; in rom_insert()
1013 hw_error ("ROM images must be loaded at startup\n"); in rom_insert()
1017 if (!rom->as) { in rom_insert()
1018 rom->as = &address_space_memory; in rom_insert()
1021 rom->committed = false; in rom_insert()
1025 if (rom_order_compare(rom, item)) { in rom_insert()
1028 QTAILQ_INSERT_BEFORE(item, rom, next); in rom_insert()
1031 QTAILQ_INSERT_TAIL(&roms, rom, next); in rom_insert()
1037 fw_cfg_modify_file(fw_cfg, id + strlen("/rom@"), host, length); in fw_cfg_resized()
1041 static void *rom_set_mr(Rom *rom, Object *owner, const char *name, bool ro) in rom_set_mr() argument
1045 rom->mr = g_malloc(sizeof(*rom->mr)); in rom_set_mr()
1046 memory_region_init_resizeable_ram(rom->mr, owner, name, in rom_set_mr()
1047 rom->datasize, rom->romsize, in rom_set_mr()
1050 memory_region_set_readonly(rom->mr, ro); in rom_set_mr()
1051 vmstate_register_ram_global(rom->mr); in rom_set_mr()
1053 data = memory_region_get_ram_ptr(rom->mr); in rom_set_mr()
1054 memcpy(data, rom->data, rom->datasize); in rom_set_mr()
1065 Rom *rom; in rom_add_file() local
1072 "not valid when loading a rom\n"); in rom_add_file()
1074 return -1; in rom_add_file()
1077 rom = g_malloc0(sizeof(*rom)); in rom_add_file()
1078 rom->name = g_strdup(file); in rom_add_file()
1079 rom->path = qemu_find_file(QEMU_FILE_TYPE_BIOS, rom->name); in rom_add_file()
1080 rom->as = as; in rom_add_file()
1081 if (rom->path == NULL) { in rom_add_file()
1082 rom->path = g_strdup(file); in rom_add_file()
1085 if (!g_file_get_contents(rom->path, (gchar **) &rom->data, in rom_add_file()
1087 fprintf(stderr, "rom: file %-20s: error %s\n", in rom_add_file()
1088 rom->name, gerr->message); in rom_add_file()
1093 rom->fw_dir = g_strdup(fw_dir); in rom_add_file()
1094 rom->fw_file = g_strdup(file); in rom_add_file()
1096 rom->addr = addr; in rom_add_file()
1097 rom->romsize = size; in rom_add_file()
1098 rom->datasize = rom->romsize; in rom_add_file()
1099 rom_insert(rom); in rom_add_file()
1100 if (rom->fw_file && fw_cfg) { in rom_add_file()
1105 basename = strrchr(rom->fw_file, '/'); in rom_add_file()
1109 basename = rom->fw_file; in rom_add_file()
1111 snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", rom->fw_dir, in rom_add_file()
1113 snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); in rom_add_file()
1115 if ((!has_option_rom || mc->option_rom_has_mr) && mc->rom_file_has_mr) { in rom_add_file()
1116 data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, true); in rom_add_file()
1118 data = rom->data; in rom_add_file()
1121 fw_cfg_add_file(fw_cfg, fw_file_name, data, rom->romsize); in rom_add_file()
1124 rom->mr = mr; in rom_add_file()
1125 snprintf(devpath, sizeof(devpath), "/rom@%s", file); in rom_add_file()
1127 snprintf(devpath, sizeof(devpath), "/rom@" HWADDR_FMT_plx, addr); in rom_add_file()
1135 rom_free(rom); in rom_add_file()
1136 return -1; in rom_add_file()
1145 Rom *rom; in rom_add_blob() local
1148 rom = g_malloc0(sizeof(*rom)); in rom_add_blob()
1149 rom->name = g_strdup(name); in rom_add_blob()
1150 rom->as = as; in rom_add_blob()
1151 rom->addr = addr; in rom_add_blob()
1152 rom->romsize = max_len ? max_len : len; in rom_add_blob()
1153 rom->datasize = len; in rom_add_blob()
1154 g_assert(rom->romsize >= rom->datasize); in rom_add_blob()
1155 rom->data = g_malloc0(rom->datasize); in rom_add_blob()
1156 memcpy(rom->data, blob, len); in rom_add_blob()
1157 rom_insert(rom); in rom_add_blob()
1163 snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); in rom_add_blob()
1168 if (mc->rom_file_has_mr) { in rom_add_blob()
1169 data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, read_only); in rom_add_blob()
1170 mr = rom->mr; in rom_add_blob()
1172 data = rom->data; in rom_add_blob()
1177 data, rom->datasize, read_only); in rom_add_blob()
1183 * all the rom. We just allocate the first part and the rest is just zeros. This
1191 Rom *rom; in rom_add_elf_program() local
1193 rom = g_malloc0(sizeof(*rom)); in rom_add_elf_program()
1194 rom->name = g_strdup(name); in rom_add_elf_program()
1195 rom->addr = addr; in rom_add_elf_program()
1196 rom->datasize = datasize; in rom_add_elf_program()
1197 rom->romsize = romsize; in rom_add_elf_program()
1198 rom->data = data; in rom_add_elf_program()
1199 rom->as = as; in rom_add_elf_program()
1203 rom->mapped_file = mapped_file; in rom_add_elf_program()
1206 rom_insert(rom); in rom_add_elf_program()
1212 return rom_add_file(file, "vgaroms", 0, -1, true, NULL, NULL); in rom_add_vga()
1222 Rom *rom; in rom_reset() local
1224 QTAILQ_FOREACH(rom, &roms, next) { in rom_reset()
1225 if (rom->fw_file) { in rom_reset()
1229 * We don't need to fill in the RAM with ROM data because we'll fill in rom_reset()
1234 if (rom->data && rom->isrom) { in rom_reset()
1237 * overwrite a potentially modified 'rom'. in rom_reset()
1239 rom_free_data(rom); in rom_reset()
1244 if (rom->data == NULL) { in rom_reset()
1247 if (rom->mr) { in rom_reset()
1248 void *host = memory_region_get_ram_ptr(rom->mr); in rom_reset()
1249 memcpy(host, rom->data, rom->datasize); in rom_reset()
1250 memset(host + rom->datasize, 0, rom->romsize - rom->datasize); in rom_reset()
1252 address_space_write_rom(rom->as, rom->addr, MEMTXATTRS_UNSPECIFIED, in rom_reset()
1253 rom->data, rom->datasize); in rom_reset()
1254 address_space_set(rom->as, rom->addr + rom->datasize, 0, in rom_reset()
1255 rom->romsize - rom->datasize, in rom_reset()
1258 if (rom->isrom) { in rom_reset()
1259 /* rom needs to be written only once */ in rom_reset()
1260 rom_free_data(rom); in rom_reset()
1263 * The rom loader is really on the same level as firmware in the guest in rom_reset()
1264 * shadowing a ROM into RAM. Such a shadowing mechanism needs to ensure in rom_reset()
1268 cpu_flush_icache_range(rom->addr, rom->datasize); in rom_reset()
1270 trace_loader_write_rom(rom->name, rom->addr, rom->datasize, rom->isrom); in rom_reset()
1274 /* Return true if two consecutive ROMs in the ROM list overlap */
1275 static bool roms_overlap(Rom *last_rom, Rom *this_rom) in roms_overlap()
1280 return last_rom->as == this_rom->as && in roms_overlap()
1281 last_rom->addr + last_rom->romsize > this_rom->addr; in roms_overlap()
1284 static const char *rom_as_name(Rom *rom) in rom_as_name() argument
1286 const char *name = rom->as ? rom->as->name : NULL; in rom_as_name()
1292 error_report("Some ROM regions are overlapping"); in rom_print_overlap_error_header()
1294 "These ROM regions might have been loaded by " in rom_print_overlap_error_header()
1302 static void rom_print_one_overlap_error(Rom *last_rom, Rom *rom) in rom_print_one_overlap_error() argument
1306 rom_as_name(rom)); in rom_print_one_overlap_error()
1308 " %s (addresses 0x" HWADDR_FMT_plx " - 0x" HWADDR_FMT_plx ")\n", in rom_print_one_overlap_error()
1309 last_rom->name, last_rom->addr, last_rom->addr + last_rom->romsize); in rom_print_one_overlap_error()
1311 " %s (addresses 0x" HWADDR_FMT_plx " - 0x" HWADDR_FMT_plx ")\n", in rom_print_one_overlap_error()
1312 rom->name, rom->addr, rom->addr + rom->romsize); in rom_print_one_overlap_error()
1318 Rom *rom, *last_rom = NULL; in rom_check_and_register_reset() local
1321 QTAILQ_FOREACH(rom, &roms, next) { in rom_check_and_register_reset()
1322 if (rom->fw_file) { in rom_check_and_register_reset()
1325 if (!rom->mr) { in rom_check_and_register_reset()
1326 if (roms_overlap(last_rom, rom)) { in rom_check_and_register_reset()
1331 rom_print_one_overlap_error(last_rom, rom); in rom_check_and_register_reset()
1334 last_rom = rom; in rom_check_and_register_reset()
1336 section = memory_region_find(rom->mr ? rom->mr : get_system_memory(), in rom_check_and_register_reset()
1337 rom->addr, 1); in rom_check_and_register_reset()
1338 rom->isrom = int128_nz(section.size) && memory_region_is_rom(section.mr); in rom_check_and_register_reset()
1342 return -1; in rom_check_and_register_reset()
1371 Rom *rom; in rom_transaction_begin() local
1374 QTAILQ_FOREACH(rom, &roms, next) { in rom_transaction_begin()
1375 rom->committed = true; in rom_transaction_begin()
1381 Rom *rom; in rom_transaction_end() local
1382 Rom *tmp; in rom_transaction_end()
1384 QTAILQ_FOREACH_SAFE(rom, &roms, next, tmp) { in rom_transaction_end()
1385 if (rom->committed) { in rom_transaction_end()
1389 rom->committed = true; in rom_transaction_end()
1391 QTAILQ_REMOVE(&roms, rom, next); in rom_transaction_end()
1392 rom_free(rom); in rom_transaction_end()
1397 static Rom *find_rom(hwaddr addr, size_t size) in find_rom()
1399 Rom *rom; in find_rom() local
1401 QTAILQ_FOREACH(rom, &roms, next) { in find_rom()
1402 if (rom->fw_file) { in find_rom()
1405 if (rom->mr) { in find_rom()
1408 if (rom->addr > addr) { in find_rom()
1411 if (rom->addr + rom->romsize < addr + size) { in find_rom()
1414 return rom; in find_rom()
1426 * Sort into address order. We break ties between rom-startpoints
1427 * and rom-endpoints in favour of the startpoint, by sorting the 0->1
1428 * transition before the 1->0 transition. Either way round would
1437 if (ra->base == rb->base) { in sort_secs()
1438 return ra->se - rb->se; in sort_secs()
1440 return ra->base > rb->base ? 1 : -1; in sort_secs()
1446 cand->base = base; in add_romsec_to_list()
1447 cand->se = se; in add_romsec_to_list()
1453 Rom *rom; in rom_find_largest_gap_between() local
1460 QTAILQ_FOREACH(rom, &roms, next) { in rom_find_largest_gap_between()
1462 if (rom->mr || rom->fw_file) { in rom_find_largest_gap_between()
1466 if (rom->addr + rom->romsize <= base) { in rom_find_largest_gap_between()
1470 if (rom->addr >= base + size) { in rom_find_largest_gap_between()
1474 /* Save the start and end of each relevant ROM */ in rom_find_largest_gap_between()
1475 secs = add_romsec_to_list(secs, rom->addr, 1); in rom_find_largest_gap_between()
1477 if (rom->addr + rom->romsize < base + size) { in rom_find_largest_gap_between()
1478 secs = add_romsec_to_list(secs, rom->addr + rom->romsize, -1); in rom_find_largest_gap_between()
1488 cand = (RomSec *) it->data; in rom_find_largest_gap_between()
1489 if (count == 0 && count + cand->se == 1) { in rom_find_largest_gap_between()
1490 size_t gap = cand->base - gapstart; in rom_find_largest_gap_between()
1495 } else if (count == 1 && count + cand->se == 0) { in rom_find_largest_gap_between()
1496 gapstart = cand->base; in rom_find_largest_gap_between()
1498 count += cand->se; in rom_find_largest_gap_between()
1507 * a ROM between addr and addr + size is copied. Note that this can involve
1515 Rom *rom; in rom_copy() local
1517 QTAILQ_FOREACH(rom, &roms, next) { in rom_copy()
1518 if (rom->fw_file) { in rom_copy()
1521 if (rom->mr) { in rom_copy()
1524 if (rom->addr + rom->romsize < addr) { in rom_copy()
1527 if (rom->addr > end || rom->addr < addr) { in rom_copy()
1531 d = dest + (rom->addr - addr); in rom_copy()
1532 s = rom->data; in rom_copy()
1533 l = rom->datasize; in rom_copy()
1536 l = dest - d; in rom_copy()
1543 if (rom->romsize > rom->datasize) { in rom_copy()
1545 * allocate all the ROM because the trailing data are only zeros. in rom_copy()
1549 l = rom->romsize - rom->datasize; in rom_copy()
1552 /* Rom size doesn't fit in the destination area. Adjust to avoid in rom_copy()
1555 l = dest - d; in rom_copy()
1564 return (d + l) - dest; in rom_copy()
1569 Rom *rom; in rom_ptr() local
1571 rom = find_rom(addr, size); in rom_ptr()
1572 if (!rom || !rom->data) in rom_ptr()
1574 return rom->data + (addr - rom->addr); in rom_ptr()
1578 size_t size; /* Amount of data we want from ROM, in bytes */
1581 void *rom; /* Output: rom data pointer, if found */ member
1590 if (mr != cbdata->mr) { in find_rom_cb()
1594 alias_addr = int128_get64(start) + cbdata->xlat - offset_in_region; in find_rom_cb()
1595 cbdata->rom = rom_ptr(alias_addr, cbdata->size); in find_rom_cb()
1596 if (!cbdata->rom) { in find_rom_cb()
1606 * Find any ROM data for the given guest address range. If there in rom_ptr_for_as()
1607 * is a ROM blob then return a pointer to the host memory in rom_ptr_for_as()
1610 * We look not only for ROM blobs that were loaded directly to in rom_ptr_for_as()
1611 * addr, but also for ROM blobs that were loaded to aliases of in rom_ptr_for_as()
1615 * 'struct Rom' returned by rom_ptr(). The Rom::as is the in rom_ptr_for_as()
1616 * AddressSpace which the rom blob should be written to, whereas in rom_ptr_for_as()
1619 * in multiple AddressSpaces. (A common example is a ROM blob in rom_ptr_for_as()
1621 * CPU's cpu->as pointer.) This does mean we might potentially in rom_ptr_for_as()
1622 * return a false-positive match if a ROM blob was loaded into an in rom_ptr_for_as()
1628 void *rom; in rom_ptr_for_as() local
1633 rom = rom_ptr(addr, size); in rom_ptr_for_as()
1634 if (rom) { in rom_ptr_for_as()
1635 return rom; in rom_ptr_for_as()
1649 return cbdata.rom; in rom_ptr_for_as()
1654 Rom *rom; in qmp_x_query_roms() local
1657 QTAILQ_FOREACH(rom, &roms, next) { in qmp_x_query_roms()
1658 if (rom->mr) { in qmp_x_query_roms()
1661 memory_region_name(rom->mr), in qmp_x_query_roms()
1662 rom->romsize, in qmp_x_query_roms()
1663 rom->name); in qmp_x_query_roms()
1664 } else if (!rom->fw_file) { in qmp_x_query_roms()
1667 rom->addr, rom->romsize, in qmp_x_query_roms()
1668 rom->isrom ? "rom" : "ram", in qmp_x_query_roms()
1669 rom->name); in qmp_x_query_roms()
1673 rom->fw_dir, in qmp_x_query_roms()
1674 rom->fw_file, in qmp_x_query_roms()
1675 rom->romsize, in qmp_x_query_roms()
1676 rom->name); in qmp_x_query_roms()
1693 /* Each record contains a 16-bit address which is combined with the upper 16
1694 * bits of the implicit "next address" to form a 32-bit address.
1710 /* return 0 or -1 if error */
1714 /* +-------+---------------+-------+---------------------+--------+ in parse_record()
1717 * +-------+---------------+-------+---------------------+--------+ in parse_record()
1719 * |1 byte | 2 bytes |1 byte | 0-255 bytes | 1 byte | in parse_record()
1733 line->byte_count |= value; in parse_record()
1735 line->address <<= 4; in parse_record()
1736 line->address += g_ascii_xdigit_value(c); in parse_record()
1738 line->record_type |= value; in parse_record()
1739 } else if (8 <= idx && idx < 8 + 2 * line->byte_count) { in parse_record()
1740 line->data[(idx - 8) >> 1] |= value; in parse_record()
1741 } else if (8 + 2 * line->byte_count <= idx && in parse_record()
1742 idx < 10 + 2 * line->byte_count) { in parse_record()
1743 line->checksum |= value; in parse_record()
1766 /* return size or -1 if error */
1769 HexLine *line = &(parser->line); in handle_record_type()
1770 switch (line->record_type) { in handle_record_type()
1772 parser->current_address = in handle_record_type()
1773 (parser->next_address_to_write & NEXT_ADDR_MASK) | line->address; in handle_record_type()
1775 if (parser->current_address != parser->next_address_to_write) { in handle_record_type()
1776 if (parser->current_rom_index != 0) { in handle_record_type()
1777 rom_add_blob_fixed_as(parser->filename, parser->bin_buf, in handle_record_type()
1778 parser->current_rom_index, in handle_record_type()
1779 parser->rom_start_address, parser->as); in handle_record_type()
1781 parser->rom_start_address = parser->current_address; in handle_record_type()
1782 parser->current_rom_index = 0; in handle_record_type()
1786 memcpy(parser->bin_buf + parser->current_rom_index, line->data, in handle_record_type()
1787 line->byte_count); in handle_record_type()
1788 parser->current_rom_index += line->byte_count; in handle_record_type()
1789 parser->total_size += line->byte_count; in handle_record_type()
1791 parser->next_address_to_write = in handle_record_type()
1792 parser->current_address + line->byte_count; in handle_record_type()
1796 if (parser->current_rom_index != 0) { in handle_record_type()
1797 rom_add_blob_fixed_as(parser->filename, parser->bin_buf, in handle_record_type()
1798 parser->current_rom_index, in handle_record_type()
1799 parser->rom_start_address, parser->as); in handle_record_type()
1801 parser->complete = true; in handle_record_type()
1802 return parser->total_size; in handle_record_type()
1805 if (line->byte_count != 2 && line->address != 0) { in handle_record_type()
1806 return -1; in handle_record_type()
1809 if (parser->current_rom_index != 0) { in handle_record_type()
1810 rom_add_blob_fixed_as(parser->filename, parser->bin_buf, in handle_record_type()
1811 parser->current_rom_index, in handle_record_type()
1812 parser->rom_start_address, parser->as); in handle_record_type()
1816 * in case of non-contiguous block of memory */ in handle_record_type()
1817 parser->next_address_to_write = (line->data[0] << 12) | in handle_record_type()
1818 (line->data[1] << 4); in handle_record_type()
1819 if (line->record_type == EXT_LINEAR_ADDR_RECORD) { in handle_record_type()
1820 parser->next_address_to_write <<= 12; in handle_record_type()
1823 parser->rom_start_address = parser->next_address_to_write; in handle_record_type()
1824 parser->current_rom_index = 0; in handle_record_type()
1828 if (line->byte_count != 4 && line->address != 0) { in handle_record_type()
1829 return -1; in handle_record_type()
1832 /* x86 16-bit CS:IP segmented addressing */ in handle_record_type()
1833 *(parser->start_addr) = (((line->data[0] << 8) | line->data[1]) << 4) + in handle_record_type()
1834 ((line->data[2] << 8) | line->data[3]); in handle_record_type()
1838 if (line->byte_count != 4 && line->address != 0) { in handle_record_type()
1839 return -1; in handle_record_type()
1842 *(parser->start_addr) = ldl_be_p(line->data); in handle_record_type()
1846 return -1; in handle_record_type()
1849 return parser->total_size; in handle_record_type()
1852 /* return size or -1 if error */
1856 bool in_process = false; /* avoid re-enter and in parse_hex_blob()
1883 parser.total_size = -1; in parse_hex_blob()
1887 if (handle_record_type(&parser) == -1) { in parse_hex_blob()
1888 parser.total_size = -1; in parse_hex_blob()
1904 parser.total_size = -1; in parse_hex_blob()
1913 rom_transaction_end(parser.total_size != -1); in parse_hex_blob()
1917 /* return size or -1 if error */
1926 return -1; in load_targphys_hex_as()