X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=hw%2Fs390x%2Fipl.c;h=51b272e190a9e723e0b60b0d111acee8e50de8d4;hb=5d45a332920d6dd5536ba5f886713f5a213f90bb;hp=0d6734900426c94e3e10306a5195d1e8d85014fa;hpb=49b67e9440892179c016a7afd33725a50d995ba6;p=mirror_qemu.git diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 0d67349004..51b272e190 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -33,7 +33,6 @@ #define KERN_PARM_AREA 0x010480UL #define INITRD_START 0x800000UL #define INITRD_PARM_START 0x010408UL -#define INITRD_PARM_SIZE 0x010410UL #define PARMFILE_START 0x001000UL #define ZIPL_IMAGE_START 0x009000UL #define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64) @@ -132,7 +131,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) goto error; } - bios_size = load_elf(bios_filename, bios_translate_addr, &fwbase, + bios_size = load_elf(bios_filename, NULL, + bios_translate_addr, &fwbase, &ipl->bios_start_addr, NULL, NULL, 1, EM_S390, 0, 0); if (bios_size > 0) { @@ -156,7 +156,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) } if (ipl->kernel) { - kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, + kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, + &pentry, NULL, NULL, 1, EM_S390, 0, 0); if (kernel_size < 0) { kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); @@ -165,12 +166,12 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) goto error; } /* if this is Linux use KERN_IMAGE_START */ - magic = rom_ptr(LINUX_MAGIC_ADDR); + magic = rom_ptr(LINUX_MAGIC_ADDR, 6); if (magic && !memcmp(magic, "S390EP", 6)) { pentry = KERN_IMAGE_START; } else { /* if not Linux load the address of the (short) IPL PSW */ - ipl_psw = rom_ptr(4); + ipl_psw = rom_ptr(4, 4); if (ipl_psw) { pentry = be32_to_cpu(*ipl_psw) & 0x7fffffffUL; } else { @@ -186,9 +187,12 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) * loader) and it won't work. For this case we force it to 0x10000, too. */ if (pentry == KERN_IMAGE_START || pentry == 0x800) { + char *parm_area = rom_ptr(KERN_PARM_AREA, strlen(ipl->cmdline) + 1); ipl->start_addr = KERN_IMAGE_START; /* Overwrite parameters in the kernel image, which are "rom" */ - strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); + if (parm_area) { + strcpy(parm_area, ipl->cmdline); + } } else { ipl->start_addr = pentry; } @@ -196,6 +200,7 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) if (ipl->initrd) { ram_addr_t initrd_offset; int initrd_size; + uint64_t *romptr; initrd_offset = INITRD_START; while (kernel_size + 0x100000 > initrd_offset) { @@ -212,8 +217,11 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) * we have to overwrite values in the kernel image, * which are "rom" */ - stq_p(rom_ptr(INITRD_PARM_START), initrd_offset); - stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size); + romptr = rom_ptr(INITRD_PARM_START, 16); + if (romptr) { + stq_p(romptr, initrd_offset); + stq_p(romptr + 1, initrd_size); + } } } /* @@ -244,8 +252,6 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl) { QemuOptsList *plist = qemu_find_opts("boot-opts"); QemuOpts *opts = QTAILQ_FIRST(&plist->head); - uint8_t *flags = &ipl->qipl.qipl_flags; - uint32_t *timeout = &ipl->qipl.boot_menu_timeout; const char *tmp; unsigned long splash_time = 0; @@ -261,7 +267,7 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl) case S390_IPL_TYPE_CCW: /* In the absence of -boot menu, use zipl parameters */ if (!qemu_opt_get(opts, "menu")) { - *flags |= QIPL_FLAG_BM_OPTS_ZIPL; + ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_ZIPL; return; } break; @@ -278,23 +284,23 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl) return; } - *flags |= QIPL_FLAG_BM_OPTS_CMD; + ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_CMD; tmp = qemu_opt_get(opts, "splash-time"); if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) { error_report("splash-time is invalid, forcing it to 0"); - *timeout = 0; + ipl->qipl.boot_menu_timeout = 0; return; } if (splash_time > 0xffffffff) { error_report("splash-time is too large, forcing it to max value"); - *timeout = 0xffffffff; + ipl->qipl.boot_menu_timeout = 0xffffffff; return; } - *timeout = cpu_to_be32(splash_time); + ipl->qipl.boot_menu_timeout = cpu_to_be32(splash_time); } static CcwDevice *s390_get_ccw_device(DeviceState *dev_st) @@ -430,7 +436,8 @@ static int load_netboot_image(Error **errp) goto unref_mr; } - img_size = load_elf_ram(netboot_filename, NULL, NULL, &ipl->start_addr, + img_size = load_elf_ram(netboot_filename, NULL, NULL, NULL, + &ipl->start_addr, NULL, NULL, 1, EM_S390, 0, 0, NULL, false); if (img_size < 0) { @@ -535,7 +542,13 @@ void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type) ipl->iplb_valid = s390_gen_initial_iplb(ipl); } } - qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + if (reset_type == S390_RESET_MODIFIED_CLEAR || + reset_type == S390_RESET_LOAD_NORMAL) { + /* ignore -no-reboot, send no event */ + qemu_system_reset_request(SHUTDOWN_CAUSE_SUBSYSTEM_RESET); + } else { + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + } /* as this is triggered by a CPU, make sure to exit the loop */ if (tcg_enabled()) { cpu_loop_exit(cs);