Commit 293f78bc1b33e4da0fce3d59a7cc8426db8eb04c
1 parent
5af45186
Remove most uses of phys_ram_base (initial patch by Ian Jackson)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4442 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
135 additions
and
41 deletions
hw/sun4m.c
| ... | ... | @@ -182,7 +182,7 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, |
| 182 | 182 | header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR); |
| 183 | 183 | header->kernel_size = cpu_to_be64((uint64_t)kernel_size); |
| 184 | 184 | if (cmdline) { |
| 185 | - strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); | |
| 185 | + pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, cmdline); | |
| 186 | 186 | header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); |
| 187 | 187 | header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); |
| 188 | 188 | } |
| ... | ... | @@ -315,7 +315,8 @@ static void secondary_cpu_reset(void *opaque) |
| 315 | 315 | } |
| 316 | 316 | |
| 317 | 317 | static unsigned long sun4m_load_kernel(const char *kernel_filename, |
| 318 | - const char *initrd_filename) | |
| 318 | + const char *initrd_filename, | |
| 319 | + ram_addr_t RAM_size) | |
| 319 | 320 | { |
| 320 | 321 | int linux_boot; |
| 321 | 322 | unsigned int i; |
| ... | ... | @@ -328,11 +329,12 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename, |
| 328 | 329 | kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL, |
| 329 | 330 | NULL); |
| 330 | 331 | if (kernel_size < 0) |
| 331 | - kernel_size = load_aout(kernel_filename, | |
| 332 | - phys_ram_base + KERNEL_LOAD_ADDR); | |
| 332 | + kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, | |
| 333 | + RAM_size - KERNEL_LOAD_ADDR); | |
| 333 | 334 | if (kernel_size < 0) |
| 334 | - kernel_size = load_image(kernel_filename, | |
| 335 | - phys_ram_base + KERNEL_LOAD_ADDR); | |
| 335 | + kernel_size = load_image_targphys(kernel_filename, | |
| 336 | + KERNEL_LOAD_ADDR, | |
| 337 | + RAM_size - KERNEL_LOAD_ADDR); | |
| 336 | 338 | if (kernel_size < 0) { |
| 337 | 339 | fprintf(stderr, "qemu: could not load kernel '%s'\n", |
| 338 | 340 | kernel_filename); |
| ... | ... | @@ -342,8 +344,9 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename, |
| 342 | 344 | /* load initrd */ |
| 343 | 345 | initrd_size = 0; |
| 344 | 346 | if (initrd_filename) { |
| 345 | - initrd_size = load_image(initrd_filename, | |
| 346 | - phys_ram_base + INITRD_LOAD_ADDR); | |
| 347 | + initrd_size = load_image_targphys(initrd_filename, | |
| 348 | + INITRD_LOAD_ADDR, | |
| 349 | + RAM_size - INITRD_LOAD_ADDR); | |
| 347 | 350 | if (initrd_size < 0) { |
| 348 | 351 | fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", |
| 349 | 352 | initrd_filename); |
| ... | ... | @@ -352,12 +355,9 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename, |
| 352 | 355 | } |
| 353 | 356 | if (initrd_size > 0) { |
| 354 | 357 | for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) { |
| 355 | - if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i) | |
| 356 | - == 0x48647253) { // HdrS | |
| 357 | - stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, | |
| 358 | - INITRD_LOAD_ADDR); | |
| 359 | - stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, | |
| 360 | - initrd_size); | |
| 358 | + if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS | |
| 359 | + stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR); | |
| 360 | + stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size); | |
| 361 | 361 | break; |
| 362 | 362 | } |
| 363 | 363 | } |
| ... | ... | @@ -435,7 +435,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, |
| 435 | 435 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); |
| 436 | 436 | ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); |
| 437 | 437 | if (ret < 0 || ret > PROM_SIZE_MAX) |
| 438 | - ret = load_image(buf, phys_ram_base + prom_offset); | |
| 438 | + ret = load_image_targphys(buf, prom_offset, PROM_SIZE_MAX); | |
| 439 | 439 | if (ret < 0 || ret > PROM_SIZE_MAX) { |
| 440 | 440 | fprintf(stderr, "qemu: could not load prom '%s'\n", |
| 441 | 441 | buf); |
| ... | ... | @@ -452,10 +452,12 @@ static void sun4m_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, |
| 452 | 452 | hwdef->clock_irq); |
| 453 | 453 | |
| 454 | 454 | if (hwdef->idreg_base != (target_phys_addr_t)-1) { |
| 455 | - stl_raw(phys_ram_base + prom_offset, 0xfe810103); | |
| 455 | + static const uint8_t idreg_data[] = { 0xfe, 0x81, 0x01, 0x03 }; | |
| 456 | 456 | |
| 457 | - cpu_register_physical_memory(hwdef->idreg_base, sizeof(uint32_t), | |
| 457 | + cpu_register_physical_memory(hwdef->idreg_base, sizeof(idreg_data), | |
| 458 | 458 | prom_offset | IO_MEM_ROM); |
| 459 | + cpu_physical_memory_write_rom(hwdef->idreg_base, idreg_data, | |
| 460 | + sizeof(idreg_data)); | |
| 459 | 461 | } |
| 460 | 462 | |
| 461 | 463 | iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version, |
| ... | ... | @@ -534,7 +536,8 @@ static void sun4m_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, |
| 534 | 536 | if (hwdef->cs_base != (target_phys_addr_t)-1) |
| 535 | 537 | cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl); |
| 536 | 538 | |
| 537 | - kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename); | |
| 539 | + kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename, | |
| 540 | + RAM_size); | |
| 538 | 541 | |
| 539 | 542 | nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, |
| 540 | 543 | boot_device, RAM_size, kernel_size, graphic_width, |
| ... | ... | @@ -602,7 +605,7 @@ static void sun4c_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, |
| 602 | 605 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); |
| 603 | 606 | ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); |
| 604 | 607 | if (ret < 0 || ret > PROM_SIZE_MAX) |
| 605 | - ret = load_image(buf, phys_ram_base + prom_offset); | |
| 608 | + ret = load_image_targphys(buf, prom_offset, PROM_SIZE_MAX); | |
| 606 | 609 | if (ret < 0 || ret > PROM_SIZE_MAX) { |
| 607 | 610 | fprintf(stderr, "qemu: could not load prom '%s'\n", |
| 608 | 611 | buf); |
| ... | ... | @@ -683,7 +686,8 @@ static void sun4c_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, |
| 683 | 686 | esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i); |
| 684 | 687 | } |
| 685 | 688 | |
| 686 | - kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename); | |
| 689 | + kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename, | |
| 690 | + RAM_size); | |
| 687 | 691 | |
| 688 | 692 | nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, |
| 689 | 693 | boot_device, RAM_size, kernel_size, graphic_width, |
| ... | ... | @@ -1417,7 +1421,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, |
| 1417 | 1421 | snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); |
| 1418 | 1422 | ret = load_elf(buf, hwdef->slavio_base - PROM_VADDR, NULL, NULL, NULL); |
| 1419 | 1423 | if (ret < 0 || ret > PROM_SIZE_MAX) |
| 1420 | - ret = load_image(buf, phys_ram_base + prom_offset); | |
| 1424 | + ret = load_image_targphys(buf, prom_offset, PROM_SIZE_MAX); | |
| 1421 | 1425 | if (ret < 0 || ret > PROM_SIZE_MAX) { |
| 1422 | 1426 | fprintf(stderr, "qemu: could not load prom '%s'\n", |
| 1423 | 1427 | buf); |
| ... | ... | @@ -1486,7 +1490,8 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, |
| 1486 | 1490 | esp_scsi_attach(main_esp, drives_table[drive_index].bdrv, i); |
| 1487 | 1491 | } |
| 1488 | 1492 | |
| 1489 | - kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename); | |
| 1493 | + kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename, | |
| 1494 | + RAM_size); | |
| 1490 | 1495 | |
| 1491 | 1496 | nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, |
| 1492 | 1497 | boot_device, RAM_size, kernel_size, graphic_width, | ... | ... |
hw/sun4u.c
| ... | ... | @@ -105,7 +105,7 @@ static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, |
| 105 | 105 | header->kernel_image = cpu_to_be64((uint64_t)kernel_image); |
| 106 | 106 | header->kernel_size = cpu_to_be64((uint64_t)kernel_size); |
| 107 | 107 | if (cmdline) { |
| 108 | - strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); | |
| 108 | + pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, cmdline); | |
| 109 | 109 | header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); |
| 110 | 110 | header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); |
| 111 | 111 | } |
| ... | ... | @@ -289,11 +289,12 @@ static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size, |
| 289 | 289 | /* XXX: put correct offset */ |
| 290 | 290 | kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL); |
| 291 | 291 | if (kernel_size < 0) |
| 292 | - kernel_size = load_aout(kernel_filename, | |
| 293 | - phys_ram_base + KERNEL_LOAD_ADDR); | |
| 292 | + kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, | |
| 293 | + ram_size - KERNEL_LOAD_ADDR); | |
| 294 | 294 | if (kernel_size < 0) |
| 295 | - kernel_size = load_image(kernel_filename, | |
| 296 | - phys_ram_base + KERNEL_LOAD_ADDR); | |
| 295 | + kernel_size = load_image_targphys(kernel_filename, | |
| 296 | + KERNEL_LOAD_ADDR, | |
| 297 | + ram_size - KERNEL_LOAD_ADDR); | |
| 297 | 298 | if (kernel_size < 0) { |
| 298 | 299 | fprintf(stderr, "qemu: could not load kernel '%s'\n", |
| 299 | 300 | kernel_filename); |
| ... | ... | @@ -302,8 +303,9 @@ static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size, |
| 302 | 303 | |
| 303 | 304 | /* load initrd */ |
| 304 | 305 | if (initrd_filename) { |
| 305 | - initrd_size = load_image(initrd_filename, | |
| 306 | - phys_ram_base + INITRD_LOAD_ADDR); | |
| 306 | + initrd_size = load_image_targphys(initrd_filename, | |
| 307 | + INITRD_LOAD_ADDR, | |
| 308 | + ram_size - INITRD_LOAD_ADDR); | |
| 307 | 309 | if (initrd_size < 0) { |
| 308 | 310 | fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", |
| 309 | 311 | initrd_filename); |
| ... | ... | @@ -312,12 +314,9 @@ static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size, |
| 312 | 314 | } |
| 313 | 315 | if (initrd_size > 0) { |
| 314 | 316 | for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) { |
| 315 | - if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i) | |
| 316 | - == 0x48647253) { // HdrS | |
| 317 | - stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, | |
| 318 | - INITRD_LOAD_ADDR); | |
| 319 | - stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, | |
| 320 | - initrd_size); | |
| 317 | + if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS | |
| 318 | + stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR); | |
| 319 | + stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size); | |
| 321 | 320 | break; |
| 322 | 321 | } |
| 323 | 322 | } | ... | ... |
loader.c
| ... | ... | @@ -39,6 +39,7 @@ int get_image_size(const char *filename) |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | /* return the size or -1 if error */ |
| 42 | +/* deprecated, because caller does not specify buffer size! */ | |
| 42 | 43 | int load_image(const char *filename, uint8_t *addr) |
| 43 | 44 | { |
| 44 | 45 | int fd, size; |
| ... | ... | @@ -55,6 +56,84 @@ int load_image(const char *filename, uint8_t *addr) |
| 55 | 56 | return size; |
| 56 | 57 | } |
| 57 | 58 | |
| 59 | +/* return the amount read, just like fread. 0 may mean error or eof */ | |
| 60 | +int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f) | |
| 61 | +{ | |
| 62 | + uint8_t buf[4096]; | |
| 63 | + target_phys_addr_t dst_begin = dst_addr; | |
| 64 | + size_t want, did; | |
| 65 | + | |
| 66 | + while (nbytes) { | |
| 67 | + want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes; | |
| 68 | + did = fread(buf, 1, want, f); | |
| 69 | + if (did != want) break; | |
| 70 | + | |
| 71 | + cpu_physical_memory_write_rom(dst_addr, buf, did); | |
| 72 | + dst_addr += did; | |
| 73 | + nbytes -= did; | |
| 74 | + } | |
| 75 | + return dst_addr - dst_begin; | |
| 76 | +} | |
| 77 | + | |
| 78 | +/* returns 0 on error, 1 if ok */ | |
| 79 | +int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f) | |
| 80 | +{ | |
| 81 | + return fread_targphys(dst_addr, nbytes, f) == nbytes; | |
| 82 | +} | |
| 83 | + | |
| 84 | +/* read()-like version */ | |
| 85 | +int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes) | |
| 86 | +{ | |
| 87 | + uint8_t buf[4096]; | |
| 88 | + target_phys_addr_t dst_begin = dst_addr; | |
| 89 | + size_t want, did; | |
| 90 | + | |
| 91 | + while (nbytes) { | |
| 92 | + want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes; | |
| 93 | + did = read(fd, buf, want); | |
| 94 | + if (did != want) break; | |
| 95 | + | |
| 96 | + cpu_physical_memory_write_rom(dst_addr, buf, did); | |
| 97 | + dst_addr += did; | |
| 98 | + nbytes -= did; | |
| 99 | + } | |
| 100 | + return dst_addr - dst_begin; | |
| 101 | +} | |
| 102 | + | |
| 103 | +/* return the size or -1 if error */ | |
| 104 | +int load_image_targphys(const char *filename, | |
| 105 | + target_phys_addr_t addr, int max_sz) | |
| 106 | +{ | |
| 107 | + FILE *f; | |
| 108 | + size_t got; | |
| 109 | + | |
| 110 | + f = fopen(filename, "rb"); | |
| 111 | + if (!f) return -1; | |
| 112 | + | |
| 113 | + got = fread_targphys(addr, max_sz, f); | |
| 114 | + if (ferror(f)) { fclose(f); return -1; } | |
| 115 | + fclose(f); | |
| 116 | + | |
| 117 | + return got; | |
| 118 | +} | |
| 119 | + | |
| 120 | +void pstrcpy_targphys(target_phys_addr_t dest, int buf_size, | |
| 121 | + const char *source) | |
| 122 | +{ | |
| 123 | + static const uint8_t nul_byte = 0; | |
| 124 | + const char *nulp; | |
| 125 | + | |
| 126 | + if (buf_size <= 0) return; | |
| 127 | + nulp = memchr(source, 0, buf_size); | |
| 128 | + if (nulp) { | |
| 129 | + cpu_physical_memory_write_rom(dest, (uint8_t *)source, | |
| 130 | + (nulp - source) + 1); | |
| 131 | + } else { | |
| 132 | + cpu_physical_memory_write_rom(dest, (uint8_t *)source, buf_size - 1); | |
| 133 | + cpu_physical_memory_write_rom(dest, &nul_byte, 1); | |
| 134 | + } | |
| 135 | +} | |
| 136 | + | |
| 58 | 137 | /* A.OUT loader */ |
| 59 | 138 | |
| 60 | 139 | struct exec |
| ... | ... | @@ -105,7 +184,7 @@ static void bswap_ahdr(struct exec *e) |
| 105 | 184 | : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x)))) |
| 106 | 185 | |
| 107 | 186 | |
| 108 | -int load_aout(const char *filename, uint8_t *addr) | |
| 187 | +int load_aout(const char *filename, target_phys_addr_t addr, int max_sz) | |
| 109 | 188 | { |
| 110 | 189 | int fd, size, ret; |
| 111 | 190 | struct exec e; |
| ... | ... | @@ -126,17 +205,21 @@ int load_aout(const char *filename, uint8_t *addr) |
| 126 | 205 | case ZMAGIC: |
| 127 | 206 | case QMAGIC: |
| 128 | 207 | case OMAGIC: |
| 208 | + if (e.a_text + e.a_data > max_sz) | |
| 209 | + goto fail; | |
| 129 | 210 | lseek(fd, N_TXTOFF(e), SEEK_SET); |
| 130 | - size = read(fd, addr, e.a_text + e.a_data); | |
| 211 | + size = read_targphys(fd, addr, e.a_text + e.a_data); | |
| 131 | 212 | if (size < 0) |
| 132 | 213 | goto fail; |
| 133 | 214 | break; |
| 134 | 215 | case NMAGIC: |
| 216 | + if (N_DATADDR(e) + e.a_data > max_sz) | |
| 217 | + goto fail; | |
| 135 | 218 | lseek(fd, N_TXTOFF(e), SEEK_SET); |
| 136 | - size = read(fd, addr, e.a_text); | |
| 219 | + size = read_targphys(fd, addr, e.a_text); | |
| 137 | 220 | if (size < 0) |
| 138 | 221 | goto fail; |
| 139 | - ret = read(fd, addr + N_DATADDR(e), e.a_data); | |
| 222 | + ret = read_targphys(fd, addr + N_DATADDR(e), e.a_data); | |
| 140 | 223 | if (ret < 0) |
| 141 | 224 | goto fail; |
| 142 | 225 | size += ret; | ... | ... |
sysemu.h
| ... | ... | @@ -151,11 +151,18 @@ extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; |
| 151 | 151 | #ifdef NEED_CPU_H |
| 152 | 152 | /* loader.c */ |
| 153 | 153 | int get_image_size(const char *filename); |
| 154 | -int load_image(const char *filename, uint8_t *addr); | |
| 154 | +int load_image(const char *filename, uint8_t *addr); /* deprecated */ | |
| 155 | +int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz); | |
| 155 | 156 | int load_elf(const char *filename, int64_t virt_to_phys_addend, |
| 156 | 157 | uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr); |
| 157 | -int load_aout(const char *filename, uint8_t *addr); | |
| 158 | +int load_aout(const char *filename, target_phys_addr_t addr, int max_sz); | |
| 158 | 159 | int load_uboot(const char *filename, target_ulong *ep, int *is_linux); |
| 160 | + | |
| 161 | +int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f); | |
| 162 | +int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f); | |
| 163 | +int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes); | |
| 164 | +void pstrcpy_targphys(target_phys_addr_t dest, int buf_size, | |
| 165 | + const char *source); | |
| 159 | 166 | #endif |
| 160 | 167 | |
| 161 | 168 | #ifdef HAS_AUDIO | ... | ... |