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"
72 /* return the size or -1 if error */
79 return -1; in get_image_size()
85 /* return the size or -1 if error */
93 return -1; in load_image_size()
96 while ((actsize = read(fd, addr + l, size - l)) > 0) { in load_image_size()
102 return actsize < 0 ? -1 : l; in load_image_size()
105 /* read()-like version */
126 /* return the size or -1 if error */
134 return -1; in load_image_targphys_as()
137 if (rom_add_file_fixed_as(filename, addr, -1, as) < 0) { in load_image_targphys_as()
138 return -1; in load_image_targphys_as()
149 /* Can only load an image into RAM or ROM */ in load_image_mr()
150 return -1; in load_image_mr()
156 return -1; in load_image_mr()
159 if (rom_add_file_mr(filename, mr, -1) < 0) { in load_image_mr()
160 return -1; in load_image_mr()
175 rom_add_blob_fixed(name, source, (nulp - source) + 1, dest); in pstrcpy_targphys()
178 ptr = rom_ptr(dest + buf_size - 1, sizeof(*ptr)); in pstrcpy_targphys()
199 bswap32s(&e->a_info); in bswap_ahdr()
200 bswap32s(&e->a_text); in bswap_ahdr()
201 bswap32s(&e->a_data); in bswap_ahdr()
202 bswap32s(&e->a_bss); in bswap_ahdr()
203 bswap32s(&e->a_syms); in bswap_ahdr()
204 bswap32s(&e->a_entry); in bswap_ahdr()
205 bswap32s(&e->a_trsize); in bswap_ahdr()
206 bswap32s(&e->a_drsize); in bswap_ahdr()
214 #define _N_HDROFF(x) (1024 - sizeof (struct exec))
219 #define _N_SEGMENT_ROUND(x, target_page_size) (((x) + target_page_size - 1) & ~(target_page_size - …
238 return -1; in load_aout()
280 return -1; in load_aout()
391 size_t br = read(fd, hdr + off, hdr_size - off); in load_elf_hdr()
396 case -1: in load_elf_hdr()
455 return -1; in load_elf_ram_sym()
499 bswap32s(&hdr->ih_magic); in bswap_uboot_header()
500 bswap32s(&hdr->ih_hcrc); in bswap_uboot_header()
501 bswap32s(&hdr->ih_time); in bswap_uboot_header()
502 bswap32s(&hdr->ih_size); in bswap_uboot_header()
503 bswap32s(&hdr->ih_load); in bswap_uboot_header()
504 bswap32s(&hdr->ih_ep); in bswap_uboot_header()
505 bswap32s(&hdr->ih_dcrc); in bswap_uboot_header()
517 size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); in zalloc()
552 return -1; in gunzip()
580 r = inflateInit2(&s, -MAX_WBITS); in gunzip()
583 return (-1); in gunzip()
586 s.avail_in = srclen - i; in gunzip()
593 return -1; in gunzip()
595 dstbytes = s.next_out - (unsigned char *) dst; in gunzip()
602 return -1; in gunzip()
605 /* Load a U-Boot image. */
618 int ret = -1; in load_uboot_image()
623 return -1; in load_uboot_image()
632 if (hdr->ih_magic != IH_MAGIC) in load_uboot_image()
635 if (hdr->ih_type != image_type) { in load_uboot_image()
637 hdr->ih_type == IH_TYPE_KERNEL_NOLOAD)) { in load_uboot_image()
638 fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type, in load_uboot_image()
645 switch (hdr->ih_type) { in load_uboot_image()
653 hdr->ih_load = *loadaddr + sizeof(*hdr); in load_uboot_image()
654 hdr->ih_ep += hdr->ih_load; in load_uboot_image()
657 address = hdr->ih_load; in load_uboot_image()
662 *loadaddr = hdr->ih_load; in load_uboot_image()
665 switch (hdr->ih_comp) { in load_uboot_image()
673 "Unable to load u-boot images with compression type %d\n", in load_uboot_image()
674 hdr->ih_comp); in load_uboot_image()
679 *ep = hdr->ih_ep; in load_uboot_image()
684 if (hdr->ih_os == IH_OS_LINUX) { in load_uboot_image()
686 } else if (hdr->ih_os == IH_OS_VXWORKS) { in load_uboot_image()
689 * on Arm (64-bit only), PowerPC and RISC-V architectures. in load_uboot_image()
691 switch (hdr->ih_arch) { in load_uboot_image()
711 fprintf(stderr, "Unsupported u-boot image type %d\n", hdr->ih_type); in load_uboot_image()
715 data = g_malloc(hdr->ih_size); in load_uboot_image()
717 if (read(fd, data, hdr->ih_size) != hdr->ih_size) { in load_uboot_image()
731 bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size); in load_uboot_image()
737 hdr->ih_size = bytes; in load_uboot_image()
740 rom_add_blob_fixed_as(filename, data, hdr->ih_size, address, as); in load_uboot_image()
742 ret = hdr->ih_size; in load_uboot_image()
781 /* Load a gzip-compressed kernel to a dynamically allocated buffer. */
789 int ret = -1; in load_image_gzipped_buffer()
796 /* Is it a gzip-compressed file? */ in load_image_gzipped_buffer()
828 /* The PE/COFF MS-DOS stub magic number */
839 * self-decompressing executables when loaded via EFI. The compressed payload
840 * can also be extracted from the image and decompressed by a non-EFI loader.
844 …el.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/firmware/efi/libstub/zboot-header.S
883 if (memcmp(&header->msdos_magic, EFI_PE_MSDOS_MAGIC, 2) != 0 || in unpack_efi_zboot_image()
884 memcmp(&header->zimg, "zimg", 4) != 0 || in unpack_efi_zboot_image()
885 memcmp(&header->linux_magic, EFI_PE_LINUX_MAGIC, 4) != 0) { in unpack_efi_zboot_image()
889 if (strcmp(header->compression_type, "gzip") != 0) { in unpack_efi_zboot_image()
892 (int)sizeof(header->compression_type) - 1, in unpack_efi_zboot_image()
893 header->compression_type); in unpack_efi_zboot_image()
894 return -1; in unpack_efi_zboot_image()
897 ploff = ldl_le_p(&header->payload_offset); in unpack_efi_zboot_image()
898 plsize = ldl_le_p(&header->payload_size); in unpack_efi_zboot_image()
902 return -1; in unpack_efi_zboot_image()
910 return -1; in unpack_efi_zboot_image()
920 * Functions for reboot-persistent memory regions.
921 * - used for vga bios and option roms.
922 * - also linux kernel (-kernel / -initrd).
925 typedef struct Rom Rom; typedef
927 struct Rom { struct
949 QTAILQ_ENTRY(Rom) next; argument
953 static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
956 * rom->data can be heap-allocated or memory-mapped (e.g. when added with
959 static void rom_free_data(Rom *rom) in rom_free_data() argument
961 if (rom->mapped_file) { in rom_free_data()
962 g_mapped_file_unref(rom->mapped_file); in rom_free_data()
963 rom->mapped_file = NULL; in rom_free_data()
965 g_free(rom->data); in rom_free_data()
968 rom->data = NULL; in rom_free_data()
971 static void rom_free(Rom *rom) in rom_free() argument
973 rom_free_data(rom); in rom_free()
974 g_free(rom->path); in rom_free()
975 g_free(rom->name); in rom_free()
976 g_free(rom->fw_dir); in rom_free()
977 g_free(rom->fw_file); in rom_free()
978 g_free(rom); in rom_free()
981 static inline bool rom_order_compare(Rom *rom, Rom *item) in rom_order_compare() argument
983 return ((uintptr_t)(void *)rom->as > (uintptr_t)(void *)item->as) || in rom_order_compare()
984 (rom->as == item->as && rom->addr >= item->addr); in rom_order_compare()
987 static void rom_insert(Rom *rom) in rom_insert() argument
989 Rom *item; in rom_insert()
992 hw_error ("ROM images must be loaded at startup\n"); in rom_insert()
996 if (!rom->as) { in rom_insert()
997 rom->as = &address_space_memory; in rom_insert()
1000 rom->committed = false; in rom_insert()
1004 if (rom_order_compare(rom, item)) { in rom_insert()
1007 QTAILQ_INSERT_BEFORE(item, rom, next); in rom_insert()
1010 QTAILQ_INSERT_TAIL(&roms, rom, next); in rom_insert()
1016 fw_cfg_modify_file(fw_cfg, id + strlen("/rom@"), host, length); in fw_cfg_resized()
1020 static void *rom_set_mr(Rom *rom, Object *owner, const char *name, bool ro) in rom_set_mr() argument
1024 rom->mr = g_malloc(sizeof(*rom->mr)); in rom_set_mr()
1025 memory_region_init_resizeable_ram(rom->mr, owner, name, in rom_set_mr()
1026 rom->datasize, rom->romsize, in rom_set_mr()
1029 memory_region_set_readonly(rom->mr, ro); in rom_set_mr()
1030 vmstate_register_ram_global(rom->mr); in rom_set_mr()
1032 data = memory_region_get_ram_ptr(rom->mr); in rom_set_mr()
1034 memcpy(data, rom->data, rom->datasize); in rom_set_mr()
1046 Rom *rom; in rom_add_file() local
1053 "not valid when loading a rom\n"); in rom_add_file()
1055 return -1; in rom_add_file()
1058 rom = g_malloc0(sizeof(*rom)); in rom_add_file()
1059 rom->name = g_strdup(file); in rom_add_file()
1060 rom->path = qemu_find_file(QEMU_FILE_TYPE_BIOS, rom->name); in rom_add_file()
1061 rom->as = as; in rom_add_file()
1062 if (rom->path == NULL) { in rom_add_file()
1063 rom->path = g_strdup(file); in rom_add_file()
1066 if (!g_file_get_contents(rom->path, (gchar **) &rom->data, in rom_add_file()
1068 fprintf(stderr, "rom: file %-20s: error %s\n", in rom_add_file()
1069 rom->name, gerr->message); in rom_add_file()
1074 rom->fw_dir = g_strdup(fw_dir); in rom_add_file()
1075 rom->fw_file = g_strdup(file); in rom_add_file()
1077 rom->addr = addr; in rom_add_file()
1078 rom->romsize = size; in rom_add_file()
1079 rom->datasize = rom->romsize; in rom_add_file()
1080 rom_insert(rom); in rom_add_file()
1081 if (rom->fw_file && fw_cfg) { in rom_add_file()
1086 basename = strrchr(rom->fw_file, '/'); in rom_add_file()
1090 basename = rom->fw_file; in rom_add_file()
1092 snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", rom->fw_dir, in rom_add_file()
1094 snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); in rom_add_file()
1096 if ((!has_option_rom || mc->option_rom_has_mr) && mc->rom_file_has_mr) { in rom_add_file()
1097 data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, true); in rom_add_file()
1099 data = rom->data; in rom_add_file()
1102 fw_cfg_add_file(fw_cfg, fw_file_name, data, rom->romsize); in rom_add_file()
1105 rom->mr = mr; in rom_add_file()
1106 snprintf(devpath, sizeof(devpath), "/rom@%s", file); in rom_add_file()
1108 snprintf(devpath, sizeof(devpath), "/rom@" HWADDR_FMT_plx, addr); in rom_add_file()
1116 rom_free(rom); in rom_add_file()
1117 return -1; in rom_add_file()
1126 Rom *rom; in rom_add_blob() local
1129 rom = g_malloc0(sizeof(*rom)); in rom_add_blob()
1130 rom->name = g_strdup(name); in rom_add_blob()
1131 rom->as = as; in rom_add_blob()
1132 rom->addr = addr; in rom_add_blob()
1133 rom->romsize = max_len ? max_len : len; in rom_add_blob()
1134 rom->datasize = len; in rom_add_blob()
1135 g_assert(rom->romsize >= rom->datasize); in rom_add_blob()
1136 rom->data = g_malloc0(rom->datasize); in rom_add_blob()
1137 memcpy(rom->data, blob, len); in rom_add_blob()
1138 rom_insert(rom); in rom_add_blob()
1144 snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name); in rom_add_blob()
1149 if (mc->rom_file_has_mr) { in rom_add_blob()
1150 data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, read_only); in rom_add_blob()
1151 mr = rom->mr; in rom_add_blob()
1153 data = rom->data; in rom_add_blob()
1158 data, rom->datasize, read_only); in rom_add_blob()
1164 * all the rom. We just allocate the first part and the rest is just zeros. This
1172 Rom *rom; in rom_add_elf_program() local
1174 rom = g_malloc0(sizeof(*rom)); in rom_add_elf_program()
1175 rom->name = g_strdup(name); in rom_add_elf_program()
1176 rom->addr = addr; in rom_add_elf_program()
1177 rom->datasize = datasize; in rom_add_elf_program()
1178 rom->romsize = romsize; in rom_add_elf_program()
1179 rom->data = data; in rom_add_elf_program()
1180 rom->as = as; in rom_add_elf_program()
1184 rom->mapped_file = mapped_file; in rom_add_elf_program()
1187 rom_insert(rom); in rom_add_elf_program()
1193 return rom_add_file(file, "vgaroms", 0, -1, true, NULL, NULL); in rom_add_vga()
1203 Rom *rom; in rom_reset() local
1205 QTAILQ_FOREACH(rom, &roms, next) { in rom_reset()
1206 if (rom->fw_file) { in rom_reset()
1210 * We don't need to fill in the RAM with ROM data because we'll fill in rom_reset()
1215 if (rom->data && rom->isrom) { in rom_reset()
1218 * overwrite a potentially modified 'rom'. in rom_reset()
1220 rom_free_data(rom); in rom_reset()
1225 if (rom->data == NULL) { in rom_reset()
1228 if (rom->mr) { in rom_reset()
1229 void *host = memory_region_get_ram_ptr(rom->mr); in rom_reset()
1230 memcpy(host, rom->data, rom->datasize); in rom_reset()
1231 memset(host + rom->datasize, 0, rom->romsize - rom->datasize); in rom_reset()
1233 address_space_write_rom(rom->as, rom->addr, MEMTXATTRS_UNSPECIFIED, in rom_reset()
1234 rom->data, rom->datasize); in rom_reset()
1235 address_space_set(rom->as, rom->addr + rom->datasize, 0, in rom_reset()
1236 rom->romsize - rom->datasize, in rom_reset()
1239 if (rom->isrom) { in rom_reset()
1240 /* rom needs to be written only once */ in rom_reset()
1241 rom_free_data(rom); in rom_reset()
1244 * The rom loader is really on the same level as firmware in the guest in rom_reset()
1245 * shadowing a ROM into RAM. Such a shadowing mechanism needs to ensure in rom_reset()
1249 cpu_flush_icache_range(rom->addr, rom->datasize); in rom_reset()
1251 trace_loader_write_rom(rom->name, rom->addr, rom->datasize, rom->isrom); in rom_reset()
1255 /* Return true if two consecutive ROMs in the ROM list overlap */
1256 static bool roms_overlap(Rom *last_rom, Rom *this_rom) in roms_overlap()
1261 return last_rom->as == this_rom->as && in roms_overlap()
1262 last_rom->addr + last_rom->romsize > this_rom->addr; in roms_overlap()
1265 static const char *rom_as_name(Rom *rom) in rom_as_name() argument
1267 const char *name = rom->as ? rom->as->name : NULL; in rom_as_name()
1273 error_report("Some ROM regions are overlapping"); in rom_print_overlap_error_header()
1275 "These ROM regions might have been loaded by " in rom_print_overlap_error_header()
1283 static void rom_print_one_overlap_error(Rom *last_rom, Rom *rom) in rom_print_one_overlap_error() argument
1287 rom_as_name(rom)); in rom_print_one_overlap_error()
1289 " %s (addresses 0x" HWADDR_FMT_plx " - 0x" HWADDR_FMT_plx ")\n", in rom_print_one_overlap_error()
1290 last_rom->name, last_rom->addr, last_rom->addr + last_rom->romsize); in rom_print_one_overlap_error()
1292 " %s (addresses 0x" HWADDR_FMT_plx " - 0x" HWADDR_FMT_plx ")\n", in rom_print_one_overlap_error()
1293 rom->name, rom->addr, rom->addr + rom->romsize); in rom_print_one_overlap_error()
1299 Rom *rom, *last_rom = NULL; in rom_check_and_register_reset() local
1302 QTAILQ_FOREACH(rom, &roms, next) { in rom_check_and_register_reset()
1303 if (rom->fw_file) { in rom_check_and_register_reset()
1306 if (!rom->mr) { in rom_check_and_register_reset()
1307 if (roms_overlap(last_rom, rom)) { in rom_check_and_register_reset()
1312 rom_print_one_overlap_error(last_rom, rom); in rom_check_and_register_reset()
1315 last_rom = rom; in rom_check_and_register_reset()
1317 section = memory_region_find(rom->mr ? rom->mr : get_system_memory(), in rom_check_and_register_reset()
1318 rom->addr, 1); in rom_check_and_register_reset()
1319 rom->isrom = int128_nz(section.size) && memory_region_is_rom(section.mr); in rom_check_and_register_reset()
1323 return -1; in rom_check_and_register_reset()
1352 Rom *rom; in rom_transaction_begin() local
1355 QTAILQ_FOREACH(rom, &roms, next) { in rom_transaction_begin()
1356 rom->committed = true; in rom_transaction_begin()
1362 Rom *rom; in rom_transaction_end() local
1363 Rom *tmp; in rom_transaction_end()
1365 QTAILQ_FOREACH_SAFE(rom, &roms, next, tmp) { in rom_transaction_end()
1366 if (rom->committed) { in rom_transaction_end()
1370 rom->committed = true; in rom_transaction_end()
1372 QTAILQ_REMOVE(&roms, rom, next); in rom_transaction_end()
1373 rom_free(rom); in rom_transaction_end()
1378 static Rom *find_rom(hwaddr addr, size_t size) in find_rom()
1380 Rom *rom; in find_rom() local
1382 QTAILQ_FOREACH(rom, &roms, next) { in find_rom()
1383 if (rom->fw_file) { in find_rom()
1386 if (rom->mr) { in find_rom()
1389 if (rom->addr > addr) { in find_rom()
1392 if (rom->addr + rom->romsize < addr + size) { in find_rom()
1395 return rom; in find_rom()
1407 * Sort into address order. We break ties between rom-startpoints
1408 * and rom-endpoints in favour of the startpoint, by sorting the 0->1
1409 * transition before the 1->0 transition. Either way round would
1418 if (ra->base == rb->base) { in sort_secs()
1419 return ra->se - rb->se; in sort_secs()
1421 return ra->base > rb->base ? 1 : -1; in sort_secs()
1427 cand->base = base; in add_romsec_to_list()
1428 cand->se = se; in add_romsec_to_list()
1434 Rom *rom; in rom_find_largest_gap_between() local
1441 QTAILQ_FOREACH(rom, &roms, next) { in rom_find_largest_gap_between()
1443 if (rom->mr || rom->fw_file) { in rom_find_largest_gap_between()
1447 if (rom->addr + rom->romsize <= base) { in rom_find_largest_gap_between()
1451 if (rom->addr >= base + size) { in rom_find_largest_gap_between()
1455 /* Save the start and end of each relevant ROM */ in rom_find_largest_gap_between()
1456 secs = add_romsec_to_list(secs, rom->addr, 1); in rom_find_largest_gap_between()
1458 if (rom->addr + rom->romsize < base + size) { in rom_find_largest_gap_between()
1459 secs = add_romsec_to_list(secs, rom->addr + rom->romsize, -1); in rom_find_largest_gap_between()
1469 cand = (RomSec *) it->data; in rom_find_largest_gap_between()
1470 if (count == 0 && count + cand->se == 1) { in rom_find_largest_gap_between()
1471 size_t gap = cand->base - gapstart; in rom_find_largest_gap_between()
1476 } else if (count == 1 && count + cand->se == 0) { in rom_find_largest_gap_between()
1477 gapstart = cand->base; in rom_find_largest_gap_between()
1479 count += cand->se; in rom_find_largest_gap_between()
1488 * a ROM between addr and addr + size is copied. Note that this can involve
1496 Rom *rom; in rom_copy() local
1498 QTAILQ_FOREACH(rom, &roms, next) { in rom_copy()
1499 if (rom->fw_file) { in rom_copy()
1502 if (rom->mr) { in rom_copy()
1505 if (rom->addr + rom->romsize < addr) { in rom_copy()
1508 if (rom->addr > end || rom->addr < addr) { in rom_copy()
1512 d = dest + (rom->addr - addr); in rom_copy()
1513 s = rom->data; in rom_copy()
1514 l = rom->datasize; in rom_copy()
1517 l = dest - d; in rom_copy()
1524 if (rom->romsize > rom->datasize) { in rom_copy()
1526 * allocate all the ROM because the trailing data are only zeros. in rom_copy()
1530 l = rom->romsize - rom->datasize; in rom_copy()
1533 /* Rom size doesn't fit in the destination area. Adjust to avoid in rom_copy()
1536 l = dest - d; in rom_copy()
1545 return (d + l) - dest; in rom_copy()
1550 Rom *rom; in rom_ptr() local
1552 rom = find_rom(addr, size); in rom_ptr()
1553 if (!rom || !rom->data) in rom_ptr()
1555 return rom->data + (addr - rom->addr); in rom_ptr()
1559 size_t size; /* Amount of data we want from ROM, in bytes */
1562 void *rom; /* Output: rom data pointer, if found */ member
1571 if (mr != cbdata->mr) { in find_rom_cb()
1575 alias_addr = int128_get64(start) + cbdata->xlat - offset_in_region; in find_rom_cb()
1576 cbdata->rom = rom_ptr(alias_addr, cbdata->size); in find_rom_cb()
1577 if (!cbdata->rom) { in find_rom_cb()
1587 * Find any ROM data for the given guest address range. If there in rom_ptr_for_as()
1588 * is a ROM blob then return a pointer to the host memory in rom_ptr_for_as()
1591 * We look not only for ROM blobs that were loaded directly to in rom_ptr_for_as()
1592 * addr, but also for ROM blobs that were loaded to aliases of in rom_ptr_for_as()
1596 * 'struct Rom' returned by rom_ptr(). The Rom::as is the in rom_ptr_for_as()
1597 * AddressSpace which the rom blob should be written to, whereas in rom_ptr_for_as()
1600 * in multiple AddressSpaces. (A common example is a ROM blob in rom_ptr_for_as()
1602 * CPU's cpu->as pointer.) This does mean we might potentially in rom_ptr_for_as()
1603 * return a false-positive match if a ROM blob was loaded into an in rom_ptr_for_as()
1609 void *rom; in rom_ptr_for_as() local
1614 rom = rom_ptr(addr, size); in rom_ptr_for_as()
1615 if (rom) { in rom_ptr_for_as()
1616 return rom; in rom_ptr_for_as()
1630 return cbdata.rom; in rom_ptr_for_as()
1635 Rom *rom; in qmp_x_query_roms() local
1638 QTAILQ_FOREACH(rom, &roms, next) { in qmp_x_query_roms()
1639 if (rom->mr) { in qmp_x_query_roms()
1642 memory_region_name(rom->mr), in qmp_x_query_roms()
1643 rom->romsize, in qmp_x_query_roms()
1644 rom->name); in qmp_x_query_roms()
1645 } else if (!rom->fw_file) { in qmp_x_query_roms()
1648 rom->addr, rom->romsize, in qmp_x_query_roms()
1649 rom->isrom ? "rom" : "ram", in qmp_x_query_roms()
1650 rom->name); in qmp_x_query_roms()
1654 rom->fw_dir, in qmp_x_query_roms()
1655 rom->fw_file, in qmp_x_query_roms()
1656 rom->romsize, in qmp_x_query_roms()
1657 rom->name); in qmp_x_query_roms()
1674 /* Each record contains a 16-bit address which is combined with the upper 16
1675 * bits of the implicit "next address" to form a 32-bit address.
1691 /* return 0 or -1 if error */
1695 /* +-------+---------------+-------+---------------------+--------+ in parse_record()
1698 * +-------+---------------+-------+---------------------+--------+ in parse_record()
1700 * |1 byte | 2 bytes |1 byte | 0-255 bytes | 1 byte | in parse_record()
1714 line->byte_count |= value; in parse_record()
1716 line->address <<= 4; in parse_record()
1717 line->address += g_ascii_xdigit_value(c); in parse_record()
1719 line->record_type |= value; in parse_record()
1720 } else if (8 <= idx && idx < 8 + 2 * line->byte_count) { in parse_record()
1721 line->data[(idx - 8) >> 1] |= value; in parse_record()
1722 } else if (8 + 2 * line->byte_count <= idx && in parse_record()
1723 idx < 10 + 2 * line->byte_count) { in parse_record()
1724 line->checksum |= value; in parse_record()
1747 /* return size or -1 if error */
1750 HexLine *line = &(parser->line); in handle_record_type()
1751 switch (line->record_type) { in handle_record_type()
1753 parser->current_address = in handle_record_type()
1754 (parser->next_address_to_write & NEXT_ADDR_MASK) | line->address; in handle_record_type()
1756 if (parser->current_address != parser->next_address_to_write) { in handle_record_type()
1757 if (parser->current_rom_index != 0) { in handle_record_type()
1758 rom_add_blob_fixed_as(parser->filename, parser->bin_buf, in handle_record_type()
1759 parser->current_rom_index, in handle_record_type()
1760 parser->rom_start_address, parser->as); in handle_record_type()
1762 parser->rom_start_address = parser->current_address; in handle_record_type()
1763 parser->current_rom_index = 0; in handle_record_type()
1767 memcpy(parser->bin_buf + parser->current_rom_index, line->data, in handle_record_type()
1768 line->byte_count); in handle_record_type()
1769 parser->current_rom_index += line->byte_count; in handle_record_type()
1770 parser->total_size += line->byte_count; in handle_record_type()
1772 parser->next_address_to_write = in handle_record_type()
1773 parser->current_address + line->byte_count; in handle_record_type()
1777 if (parser->current_rom_index != 0) { in handle_record_type()
1778 rom_add_blob_fixed_as(parser->filename, parser->bin_buf, in handle_record_type()
1779 parser->current_rom_index, in handle_record_type()
1780 parser->rom_start_address, parser->as); in handle_record_type()
1782 parser->complete = true; in handle_record_type()
1783 return parser->total_size; in handle_record_type()
1786 if (line->byte_count != 2 && line->address != 0) { in handle_record_type()
1787 return -1; in handle_record_type()
1790 if (parser->current_rom_index != 0) { in handle_record_type()
1791 rom_add_blob_fixed_as(parser->filename, parser->bin_buf, in handle_record_type()
1792 parser->current_rom_index, in handle_record_type()
1793 parser->rom_start_address, parser->as); in handle_record_type()
1797 * in case of non-contiguous block of memory */ in handle_record_type()
1798 parser->next_address_to_write = (line->data[0] << 12) | in handle_record_type()
1799 (line->data[1] << 4); in handle_record_type()
1800 if (line->record_type == EXT_LINEAR_ADDR_RECORD) { in handle_record_type()
1801 parser->next_address_to_write <<= 12; in handle_record_type()
1804 parser->rom_start_address = parser->next_address_to_write; in handle_record_type()
1805 parser->current_rom_index = 0; in handle_record_type()
1809 if (line->byte_count != 4 && line->address != 0) { in handle_record_type()
1810 return -1; in handle_record_type()
1813 /* x86 16-bit CS:IP segmented addressing */ in handle_record_type()
1814 *(parser->start_addr) = (((line->data[0] << 8) | line->data[1]) << 4) + in handle_record_type()
1815 ((line->data[2] << 8) | line->data[3]); in handle_record_type()
1819 if (line->byte_count != 4 && line->address != 0) { in handle_record_type()
1820 return -1; in handle_record_type()
1823 *(parser->start_addr) = ldl_be_p(line->data); in handle_record_type()
1827 return -1; in handle_record_type()
1830 return parser->total_size; in handle_record_type()
1833 /* return size or -1 if error */
1837 bool in_process = false; /* avoid re-enter and in parse_hex_blob()
1864 parser.total_size = -1; in parse_hex_blob()
1868 if (handle_record_type(&parser) == -1) { in parse_hex_blob()
1869 parser.total_size = -1; in parse_hex_blob()
1885 parser.total_size = -1; in parse_hex_blob()
1894 rom_transaction_end(parser.total_size != -1); in parse_hex_blob()
1898 /* return size or -1 if error */
1907 return -1; in load_targphys_hex_as()