diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index d7c457e0ed..e38eedd83a 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -23,7 +23,7 @@ static SubChannelId blk_schid = { .one = 1 };
static char loadparm_str[LOADPARM_LEN + 1];
QemuIplParameters qipl;
IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
-static bool have_iplb;
+bool have_iplb;
static uint16_t cutype;
LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
@@ -55,6 +55,12 @@ void write_iplb_location(void)
}
}
+static void copy_qipl(void)
+{
+ QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
+ memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
+}
+
unsigned int get_loadparm_index(void)
{
return atoi(loadparm_str);
@@ -152,6 +158,7 @@ static void menu_setup(void)
/* If loadparm was set to any other value, then do not enable menu */
if (memcmp(loadparm_str, LOADPARM_EMPTY, LOADPARM_LEN) != 0) {
+ menu_set_parms(qipl.qipl_flags && ~BOOT_MENU_FLAG_MASK, 0);
return;
}
@@ -183,7 +190,10 @@ static void css_setup(void)
static void boot_setup(void)
{
char lpmsg[] = "LOADPARM=[________]\n";
- have_iplb = store_iplb(&iplb);
+
+ if (!have_iplb) {
+ have_iplb = store_iplb(&iplb);
+ }
if (memcmp(iplb.loadparm, "@@@@@@@@", LOADPARM_LEN) != 0) {
ebcdic_to_ascii((char *) iplb.loadparm, loadparm_str, LOADPARM_LEN);
@@ -191,6 +201,10 @@ static void boot_setup(void)
sclp_get_loadparm_ascii(loadparm_str);
}
+ if (have_iplb) {
+ menu_setup();
+ }
+
memcpy(lpmsg + 10, loadparm_str, 8);
puts(lpmsg);
@@ -208,6 +222,7 @@ static bool find_boot_device(void)
switch (iplb.pbt) {
case S390_IPL_TYPE_CCW:
+ vdev->scsi_device_selected = false;
debug_print_int("device no. ", iplb.ccw.devno);
blk_schid.ssid = iplb.ccw.ssid & 0x3;
debug_print_int("ssid ", blk_schid.ssid);
@@ -231,15 +246,8 @@ static bool find_boot_device(void)
static int virtio_setup(void)
{
VDev *vdev = virtio_get_device();
- QemuIplParameters *early_qipl = (QemuIplParameters *)QIPL_ADDRESS;
int ret;
- memcpy(&qipl, early_qipl, sizeof(QemuIplParameters));
-
- if (have_iplb) {
- menu_setup();
- }
-
switch (vdev->senseid.cu_model) {
case VIRTIO_ID_NET:
puts("Network boot device detected");
@@ -281,41 +289,19 @@ static void ipl_boot_device(void)
}
}
-/*
- * No boot device has been specified, so we have to scan through the
- * channels to find one.
- */
-static void probe_boot_device(void)
-{
- int ssid, sch_no, ret;
-
- for (ssid = 0; ssid < 0x3; ssid++) {
- blk_schid.ssid = ssid;
- for (sch_no = 0; sch_no < 0x10000; sch_no++) {
- ret = is_dev_possibly_bootable(-1, sch_no);
- if (ret < 0) {
- break;
- }
- if (ret == true) {
- ipl_boot_device(); /* Only returns if unsuccessful */
- return;
- }
- }
- }
-
- puts("Could not find a suitable boot device (none specified)");
-}
-
void main(void)
{
+ copy_qipl();
sclp_setup();
css_setup();
- boot_setup();
- if (have_iplb && find_boot_device()) {
- ipl_boot_device();
- } else {
- probe_boot_device();
- }
+ do {
+ boot_setup();
+ if (have_iplb && find_boot_device()) {
+ ipl_boot_device();
+ }
+ have_iplb = load_next_iplb();
+ } while (have_iplb);
+
+ panic("No suitable device for IPL. Halting...");
- panic("Failed to IPL. Halting...");
}