aboutsummaryrefslogtreecommitdiff
path: root/pc-bios/s390-ccw/bootmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'pc-bios/s390-ccw/bootmap.c')
-rw-r--r--pc-bios/s390-ccw/bootmap.c129
1 files changed, 87 insertions, 42 deletions
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 4925302..611102e 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -72,7 +72,7 @@ static void jump_to_IPL_code(uint64_t address)
asm volatile("lghi 1,1\n\t"
"diag 1,1,0x308\n\t"
: : : "1", "memory");
- virtio_panic("\n! IPL returns !\n");
+ panic("\n! IPL returns !\n");
}
/***********************************************************************
@@ -84,7 +84,7 @@ static const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr);
static inline void verify_boot_info(BootInfo *bip)
{
- IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL magic");
+ IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL sig in BootInfo");
IPL_assert(bip->version == BOOT_INFO_VERSION, "Wrong zIPL version");
IPL_assert(bip->bp_type == BOOT_INFO_BP_TYPE_IPL, "DASD is not for IPL");
IPL_assert(bip->dev_type == BOOT_INFO_DEV_TYPE_ECKD, "DASD is not ECKD");
@@ -315,6 +315,40 @@ static void print_eckd_msg(void)
sclp_print(msg);
}
+static void ipl_eckd(void)
+{
+ ScsiMbr *mbr = (void *)sec;
+ LDL_VTOC *vlbl = (void *)sec;
+
+ print_eckd_msg();
+
+ /* Grab the MBR again */
+ memset(sec, FREE_SPACE_FILLER, sizeof(sec));
+ read_block(0, mbr, "Cannot read block 0 on DASD");
+
+ if (magic_match(mbr->magic, IPL1_MAGIC)) {
+ ipl_eckd_cdl(); /* no return */
+ }
+
+ /* LDL/CMS? */
+ memset(sec, FREE_SPACE_FILLER, sizeof(sec));
+ read_block(2, vlbl, "Cannot read block 2");
+
+ if (magic_match(vlbl->magic, CMS1_MAGIC)) {
+ ipl_eckd_ldl(ECKD_CMS); /* no return */
+ }
+ if (magic_match(vlbl->magic, LNX1_MAGIC)) {
+ ipl_eckd_ldl(ECKD_LDL); /* no return */
+ }
+
+ ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */
+ /*
+ * Ok, it is not a LDL by any means.
+ * It still might be a CDL with zero record keys for IPL1 and IPL2
+ */
+ ipl_eckd_cdl();
+}
+
/***********************************************************************
* IPL a SCSI disk
*/
@@ -382,7 +416,7 @@ static void zipl_run(ScsiBlockPtr *pte)
read_block(pte->blockno, tmp_sec, "Cannot read header");
header = (ComponentHeader *)tmp_sec;
- IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic");
+ IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic in header");
IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type");
dputs("start loading images\n");
@@ -412,16 +446,26 @@ static void ipl_scsi(void)
const int pte_len = sizeof(ScsiBlockPtr);
ScsiBlockPtr *prog_table_entry;
- /* The 0-th block (MBR) was already read into sec[] */
+ /* Grab the MBR */
+ memset(sec, FREE_SPACE_FILLER, sizeof(sec));
+ read_block(0, mbr, "Cannot read block 0");
+
+ if (!magic_match(mbr->magic, ZIPL_MAGIC)) {
+ return;
+ }
sclp_print("Using SCSI scheme.\n");
+ debug_print_int("MBR Version", mbr->version_id);
+ IPL_check(mbr->version_id == 1,
+ "Unknown MBR layout version, assuming version 1");
debug_print_int("program table", mbr->blockptr.blockno);
+ IPL_assert(mbr->blockptr.blockno, "No Program Table");
/* Parse the program table */
read_block(mbr->blockptr.blockno, sec,
"Error reading Program Table");
- IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic");
+ IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT");
ns_end = sec + virtio_get_block_size();
for (ns = (sec + pte_len); (ns + pte_len) < ns_end; ns += pte_len) {
@@ -613,7 +657,7 @@ static IsoBcSection *find_iso_bc_entry(void)
if (!is_iso_bc_valid(e)) {
/* The validation entry is mandatory */
- virtio_panic("No valid boot catalog found!\n");
+ panic("No valid boot catalog found!\n");
return NULL;
}
@@ -629,7 +673,7 @@ static IsoBcSection *find_iso_bc_entry(void)
}
}
- virtio_panic("No suitable boot entry found on ISO-9660 media!\n");
+ panic("No suitable boot entry found on ISO-9660 media!\n");
return NULL;
}
@@ -645,57 +689,58 @@ static void ipl_iso_el_torito(void)
}
/***********************************************************************
- * IPL starts here
+ * Bus specific IPL sequences
*/
-void zipl_load(void)
+static void zipl_load_vblk(void)
{
- ScsiMbr *mbr = (void *)sec;
- LDL_VTOC *vlbl = (void *)sec;
-
- /* Grab the MBR */
- memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(0, mbr, "Cannot read block 0");
-
- dputs("checking magic\n");
-
- if (magic_match(mbr->magic, ZIPL_MAGIC)) {
- ipl_scsi(); /* no return */
- }
-
- /* Check if we can boot as ISO media */
if (virtio_guessed_disk_nature()) {
virtio_assume_iso9660();
}
ipl_iso_el_torito();
- /* We have failed to follow the SCSI scheme, so */
if (virtio_guessed_disk_nature()) {
sclp_print("Using guessed DASD geometry.\n");
virtio_assume_eckd();
}
- print_eckd_msg();
- if (magic_match(mbr->magic, IPL1_MAGIC)) {
- ipl_eckd_cdl(); /* no return */
+ ipl_eckd();
+}
+
+static void zipl_load_vscsi(void)
+{
+ if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) {
+ /* Is it an ISO image in non-CD drive? */
+ ipl_iso_el_torito();
}
- /* LDL/CMS? */
- memset(sec, FREE_SPACE_FILLER, sizeof(sec));
- read_block(2, vlbl, "Cannot read block 2");
+ sclp_print("Using guessed DASD geometry.\n");
+ virtio_assume_eckd();
+ ipl_eckd();
+}
- if (magic_match(vlbl->magic, CMS1_MAGIC)) {
- ipl_eckd_ldl(ECKD_CMS); /* no return */
- }
- if (magic_match(vlbl->magic, LNX1_MAGIC)) {
- ipl_eckd_ldl(ECKD_LDL); /* no return */
+/***********************************************************************
+ * IPL starts here
+ */
+
+void zipl_load(void)
+{
+ if (virtio_get_device()->is_cdrom) {
+ ipl_iso_el_torito();
+ panic("\n! Cannot IPL this ISO image !\n");
}
- ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */
- /*
- * Ok, it is not a LDL by any means.
- * It still might be a CDL with zero record keys for IPL1 and IPL2
- */
- ipl_eckd_cdl();
+ ipl_scsi();
+
+ switch (virtio_get_device_type()) {
+ case VIRTIO_ID_BLOCK:
+ zipl_load_vblk();
+ break;
+ case VIRTIO_ID_SCSI:
+ zipl_load_vscsi();
+ break;
+ default:
+ panic("\n! Unknown IPL device type !\n");
+ }
- virtio_panic("\n* this can never happen *\n");
+ panic("\n* this can never happen *\n");
}