mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-28 05:50:37 +00:00
s390x/ipl: always load the bios for ccw machine
We will need bios support in order to be able to support selecting a different boot device via diagnose 308 in the ccw machine, so let's make the bios mandatory for the ccw machine. Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com> Signed-off-by: Fan Zhang <zhangfan@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
parent
cd2d554127
commit
f0180f913e
107
hw/s390x/ipl.c
107
hw/s390x/ipl.c
@ -50,6 +50,8 @@ typedef struct S390IPLState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
uint64_t start_addr;
|
||||
uint64_t bios_start_addr;
|
||||
bool enforce_bios;
|
||||
|
||||
/*< public >*/
|
||||
char *kernel;
|
||||
@ -65,11 +67,14 @@ static int s390_ipl_init(SysBusDevice *dev)
|
||||
uint64_t pentry = KERN_IMAGE_START;
|
||||
int kernel_size;
|
||||
|
||||
if (!ipl->kernel) {
|
||||
int bios_size;
|
||||
char *bios_filename;
|
||||
int bios_size;
|
||||
char *bios_filename;
|
||||
|
||||
/* Load zipl bootloader */
|
||||
/*
|
||||
* Always load the bios if it was enforced,
|
||||
* even if an external kernel has been defined.
|
||||
*/
|
||||
if (!ipl->kernel || ipl->enforce_bios) {
|
||||
if (bios_name == NULL) {
|
||||
bios_name = ipl->firmware;
|
||||
}
|
||||
@ -79,12 +84,12 @@ static int s390_ipl_init(SysBusDevice *dev)
|
||||
hw_error("could not find stage1 bootloader\n");
|
||||
}
|
||||
|
||||
bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL,
|
||||
NULL, 1, ELF_MACHINE, 0);
|
||||
bios_size = load_elf(bios_filename, NULL, NULL, &ipl->bios_start_addr,
|
||||
NULL, NULL, 1, ELF_MACHINE, 0);
|
||||
if (bios_size < 0) {
|
||||
bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
|
||||
4096);
|
||||
ipl->start_addr = ZIPL_IMAGE_START;
|
||||
ipl->bios_start_addr = ZIPL_IMAGE_START;
|
||||
if (bios_size > 4096) {
|
||||
hw_error("stage1 bootloader is > 4k\n");
|
||||
}
|
||||
@ -94,52 +99,59 @@ static int s390_ipl_init(SysBusDevice *dev)
|
||||
if (bios_size == -1) {
|
||||
hw_error("could not load bootloader '%s'\n", bios_name);
|
||||
}
|
||||
return 0;
|
||||
|
||||
/* default boot target is the bios */
|
||||
ipl->start_addr = ipl->bios_start_addr;
|
||||
}
|
||||
|
||||
kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,
|
||||
NULL, 1, ELF_MACHINE, 0);
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
|
||||
}
|
||||
if (kernel_size < 0) {
|
||||
fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
|
||||
* kernel parameters here as well. Note: For old kernels (up to 3.2)
|
||||
* we can not rely on the ELF entry point - it was 0x800 (the SALIPL
|
||||
* loader) and it won't work. For this case we force it to 0x10000, too.
|
||||
*/
|
||||
if (pentry == KERN_IMAGE_START || pentry == 0x800) {
|
||||
ipl->start_addr = KERN_IMAGE_START;
|
||||
/* Overwrite parameters in the kernel image, which are "rom" */
|
||||
strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
|
||||
} else {
|
||||
ipl->start_addr = pentry;
|
||||
}
|
||||
|
||||
if (ipl->initrd) {
|
||||
ram_addr_t initrd_offset;
|
||||
int initrd_size;
|
||||
|
||||
initrd_offset = INITRD_START;
|
||||
while (kernel_size + 0x100000 > initrd_offset) {
|
||||
initrd_offset += 0x100000;
|
||||
if (ipl->kernel) {
|
||||
kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,
|
||||
NULL, 1, ELF_MACHINE, 0);
|
||||
if (kernel_size < 0) {
|
||||
kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
|
||||
}
|
||||
initrd_size = load_image_targphys(ipl->initrd, initrd_offset,
|
||||
ram_size - initrd_offset);
|
||||
if (initrd_size == -1) {
|
||||
fprintf(stderr, "qemu: could not load initrd '%s'\n", ipl->initrd);
|
||||
exit(1);
|
||||
if (kernel_size < 0) {
|
||||
fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the
|
||||
* kernel parameters here as well. Note: For old kernels (up to 3.2)
|
||||
* we can not rely on the ELF entry point - it was 0x800 (the SALIPL
|
||||
* loader) and it won't work. For this case we force it to 0x10000, too.
|
||||
*/
|
||||
if (pentry == KERN_IMAGE_START || pentry == 0x800) {
|
||||
ipl->start_addr = KERN_IMAGE_START;
|
||||
/* Overwrite parameters in the kernel image, which are "rom" */
|
||||
strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
|
||||
} else {
|
||||
ipl->start_addr = pentry;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
if (ipl->initrd) {
|
||||
ram_addr_t initrd_offset;
|
||||
int initrd_size;
|
||||
|
||||
initrd_offset = INITRD_START;
|
||||
while (kernel_size + 0x100000 > initrd_offset) {
|
||||
initrd_offset += 0x100000;
|
||||
}
|
||||
initrd_size = load_image_targphys(ipl->initrd, initrd_offset,
|
||||
ram_size - initrd_offset);
|
||||
if (initrd_size == -1) {
|
||||
fprintf(stderr, "qemu: could not load initrd '%s'\n",
|
||||
ipl->initrd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -148,6 +160,7 @@ static Property s390_ipl_properties[] = {
|
||||
DEFINE_PROP_STRING("initrd", S390IPLState, initrd),
|
||||
DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
|
||||
DEFINE_PROP_STRING("firmware", S390IPLState, firmware),
|
||||
DEFINE_PROP_BOOL("enforce_bios", S390IPLState, enforce_bios, false),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@ -126,7 +126,7 @@ static void ccw_init(MachineState *machine)
|
||||
css_bus = virtual_css_bus_init();
|
||||
s390_sclp_init();
|
||||
s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
|
||||
machine->initrd_filename, "s390-ccw.img");
|
||||
machine->initrd_filename, "s390-ccw.img", true);
|
||||
s390_flic_init();
|
||||
|
||||
dev = qdev_create(NULL, TYPE_S390_PCI_HOST_BRIDGE);
|
||||
|
@ -128,7 +128,8 @@ static void s390_virtio_register_hcalls(void)
|
||||
void s390_init_ipl_dev(const char *kernel_filename,
|
||||
const char *kernel_cmdline,
|
||||
const char *initrd_filename,
|
||||
const char *firmware)
|
||||
const char *firmware,
|
||||
bool enforce_bios)
|
||||
{
|
||||
DeviceState *dev;
|
||||
|
||||
@ -141,6 +142,7 @@ void s390_init_ipl_dev(const char *kernel_filename,
|
||||
}
|
||||
qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
|
||||
qdev_prop_set_string(dev, "firmware", firmware);
|
||||
qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
|
||||
qdev_init_nofail(dev);
|
||||
}
|
||||
|
||||
@ -221,7 +223,7 @@ static void s390_init(MachineState *machine)
|
||||
s390_bus = s390_virtio_bus_init(&my_ram_size);
|
||||
s390_sclp_init();
|
||||
s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
|
||||
machine->initrd_filename, ZIPL_FILENAME);
|
||||
machine->initrd_filename, ZIPL_FILENAME, false);
|
||||
s390_flic_init();
|
||||
|
||||
/* register hypercalls */
|
||||
|
@ -26,7 +26,8 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys);
|
||||
void s390_init_ipl_dev(const char *kernel_filename,
|
||||
const char *kernel_cmdline,
|
||||
const char *initrd_filename,
|
||||
const char *firmware);
|
||||
const char *firmware,
|
||||
bool enforce_bios);
|
||||
void s390_create_virtio_net(BusState *bus, const char *name);
|
||||
void s390_nmi(NMIState *n, int cpu_index, Error **errp);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user