diff options
Diffstat (limited to 'pc-bios/s390-ccw/bootmap.c')
-rw-r--r-- | pc-bios/s390-ccw/bootmap.c | 129 |
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"); } |