summaryrefslogtreecommitdiff
path: root/pc-bios
diff options
context:
space:
mode:
authorCollin Walling <walling@linux.ibm.com>2018-04-16 12:56:09 -0400
committerThomas Huth <thuth@redhat.com>2018-05-02 11:27:14 +0200
commit7385e947fc65a44dd05abb86c874beb915c1989c (patch)
treee889f3ccd6cbeae75668dd0efde7da8c2683c77e /pc-bios
parent074afe60d4c8167dcfaee7aca1065c6360449eaa (diff)
downloadqemu-7385e947fc65a44dd05abb86c874beb915c1989c.tar.gz
pc-bios/s390-ccw: fix non-sequential boot entries (eckd)
zIPL boot menu entries can be non-sequential. Let's account for this issue for the s390 zIPL boot menu. Since this boot menu is actually an imitation and is not completely capable of everything the real zIPL menu can do, let's also print a different banner to the user. Signed-off-by: Collin Walling <walling@linux.ibm.com> Reported-by: Vasily Gorbik <gor@linux.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Janosch Frank <frankja@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'pc-bios')
-rw-r--r--pc-bios/s390-ccw/menu.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c
index 96eec81e84..aaf5d61ae6 100644
--- a/pc-bios/s390-ccw/menu.c
+++ b/pc-bios/s390-ccw/menu.c
@@ -158,7 +158,7 @@ static void boot_menu_prompt(bool retry)
}
}
-static int get_boot_index(int entries)
+static int get_boot_index(bool *valid_entries)
{
int boot_index;
bool retry = false;
@@ -168,7 +168,8 @@ static int get_boot_index(int entries)
boot_menu_prompt(retry);
boot_index = get_index();
retry = true;
- } while (boot_index < 0 || boot_index >= entries);
+ } while (boot_index < 0 || boot_index >= MAX_BOOT_ENTRIES ||
+ !valid_entries[boot_index]);
sclp_print("\nBooting entry #");
sclp_print(uitoa(boot_index, tmp, sizeof(tmp)));
@@ -176,7 +177,8 @@ static int get_boot_index(int entries)
return boot_index;
}
-static void zipl_println(const char *data, size_t len)
+/* Returns the entry number that was printed */
+static int zipl_print_entry(const char *data, size_t len)
{
char buf[len + 2];
@@ -185,12 +187,15 @@ static void zipl_println(const char *data, size_t len)
buf[len + 1] = '\0';
sclp_print(buf);
+
+ return buf[0] == ' ' ? atoui(buf + 1) : atoui(buf);
}
int menu_get_zipl_boot_index(const char *menu_data)
{
size_t len;
- int entries;
+ int entry;
+ bool valid_entries[MAX_BOOT_ENTRIES] = {false};
uint16_t zipl_flag = *(uint16_t *)(menu_data - ZIPL_FLAG_OFFSET);
uint16_t zipl_timeout = *(uint16_t *)(menu_data - ZIPL_TIMEOUT_OFFSET);
@@ -202,19 +207,25 @@ int menu_get_zipl_boot_index(const char *menu_data)
timeout = zipl_timeout * 1000;
}
- /* Print and count all menu items, including the banner */
- for (entries = 0; *menu_data; entries++) {
+ /* Print banner */
+ sclp_print("s390-ccw zIPL Boot Menu\n\n");
+ menu_data += strlen(menu_data) + 1;
+
+ /* Print entries */
+ while (*menu_data) {
len = strlen(menu_data);
- zipl_println(menu_data, len);
+ entry = zipl_print_entry(menu_data, len);
menu_data += len + 1;
- if (entries < 2) {
+ valid_entries[entry] = true;
+
+ if (entry == 0) {
sclp_print("\n");
}
}
sclp_print("\n");
- return get_boot_index(entries - 1); /* subtract 1 to exclude banner */
+ return get_boot_index(valid_entries);
}