qemu/pc-bios/s390-ccw/bootmap.c
<<
>>
Prefs
   1/*
   2 * QEMU S390 bootmap interpreter
   3 *
   4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
   5 *
   6 * This work is licensed under the terms of the GNU GPL, version 2 or (at
   7 * your option) any later version. See the COPYING file in the top-level
   8 * directory.
   9 */
  10
  11#include "libc.h"
  12#include "s390-ccw.h"
  13#include "bootmap.h"
  14#include "virtio.h"
  15#include "bswap.h"
  16
  17#ifdef DEBUG
  18/* #define DEBUG_FALLBACK */
  19#endif
  20
  21#ifdef DEBUG_FALLBACK
  22#define dputs(txt) \
  23    do { sclp_print("zipl: " txt); } while (0)
  24#else
  25#define dputs(fmt, ...) \
  26    do { } while (0)
  27#endif
  28
  29/* Scratch space */
  30static uint8_t sec[MAX_SECTOR_SIZE*4] __attribute__((__aligned__(PAGE_SIZE)));
  31
  32typedef struct ResetInfo {
  33    uint32_t ipl_mask;
  34    uint32_t ipl_addr;
  35    uint32_t ipl_continue;
  36} ResetInfo;
  37
  38static ResetInfo save;
  39
  40static void jump_to_IPL_2(void)
  41{
  42    ResetInfo *current = 0;
  43
  44    void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue;
  45    *current = save;
  46    ipl(); /* should not return */
  47}
  48
  49static void jump_to_IPL_code(uint64_t address)
  50{
  51    /* store the subsystem information _after_ the bootmap was loaded */
  52    write_subsystem_identification();
  53
  54    /* prevent unknown IPL types in the guest */
  55    if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
  56        iplb.pbt = S390_IPL_TYPE_CCW;
  57        set_iplb(&iplb);
  58    }
  59
  60    /*
  61     * The IPL PSW is at address 0. We also must not overwrite the
  62     * content of non-BIOS memory after we loaded the guest, so we
  63     * save the original content and restore it in jump_to_IPL_2.
  64     */
  65    ResetInfo *current = 0;
  66
  67    save = *current;
  68    current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2;
  69    current->ipl_continue = address & 0x7fffffff;
  70
  71    debug_print_int("set IPL addr to", current->ipl_continue);
  72
  73    /* Ensure the guest output starts fresh */
  74    sclp_print("\n");
  75
  76    /*
  77     * HACK ALERT.
  78     * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2
  79     * can then use r15 as its stack pointer.
  80     */
  81    asm volatile("lghi 1,1\n\t"
  82                 "diag 1,1,0x308\n\t"
  83                 : : : "1", "memory");
  84    panic("\n! IPL returns !\n");
  85}
  86
  87/***********************************************************************
  88 * IPL an ECKD DASD (CDL or LDL/CMS format)
  89 */
  90
  91static unsigned char _bprs[8*1024]; /* guessed "max" ECKD sector size */
  92static const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr);
  93
  94static inline void verify_boot_info(BootInfo *bip)
  95{
  96    IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL sig in BootInfo");
  97    IPL_assert(bip->version == BOOT_INFO_VERSION, "Wrong zIPL version");
  98    IPL_assert(bip->bp_type == BOOT_INFO_BP_TYPE_IPL, "DASD is not for IPL");
  99    IPL_assert(bip->dev_type == BOOT_INFO_DEV_TYPE_ECKD, "DASD is not ECKD");
 100    IPL_assert(bip->flags == BOOT_INFO_FLAGS_ARCH, "Not for this arch");
 101    IPL_assert(block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size),
 102               "Bad block size in zIPL section of the 1st record.");
 103}
 104
 105static block_number_t eckd_block_num(BootMapPointer *p)
 106{
 107    const uint64_t sectors = virtio_get_sectors();
 108    const uint64_t heads = virtio_get_heads();
 109    const uint64_t cylinder = p->eckd.cylinder
 110                            + ((p->eckd.head & 0xfff0) << 12);
 111    const uint64_t head = p->eckd.head & 0x000f;
 112    const block_number_t block = sectors * heads * cylinder
 113                               + sectors * head
 114                               + p->eckd.sector
 115                               - 1; /* block nr starts with zero */
 116    return block;
 117}
 118
 119static bool eckd_valid_address(BootMapPointer *p)
 120{
 121    const uint64_t head = p->eckd.head & 0x000f;
 122
 123    if (head >= virtio_get_heads()
 124        ||  p->eckd.sector > virtio_get_sectors()
 125        ||  p->eckd.sector <= 0) {
 126        return false;
 127    }
 128
 129    if (!virtio_guessed_disk_nature() &&
 130        eckd_block_num(p) >= virtio_get_blocks()) {
 131        return false;
 132    }
 133
 134    return true;
 135}
 136
 137static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address)
 138{
 139    block_number_t block_nr;
 140    int j, rc;
 141    BootMapPointer *bprs = (void *)_bprs;
 142    bool more_data;
 143
 144    memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs));
 145    read_block(blk, bprs, "BPRS read failed");
 146
 147    do {
 148        more_data = false;
 149        for (j = 0;; j++) {
 150            block_nr = eckd_block_num((void *)&(bprs[j].xeckd));
 151            if (is_null_block_number(block_nr)) { /* end of chunk */
 152                break;
 153            }
 154
 155            /* we need the updated blockno for the next indirect entry
 156             * in the chain, but don't want to advance address
 157             */
 158            if (j == (max_bprs_entries - 1)) {
 159                break;
 160            }
 161
 162            IPL_assert(block_size_ok(bprs[j].xeckd.bptr.size),
 163                       "bad chunk block size");
 164            IPL_assert(eckd_valid_address(&bprs[j]), "bad chunk ECKD addr");
 165
 166            if ((bprs[j].xeckd.bptr.count == 0) && unused_space(&(bprs[j+1]),
 167                sizeof(EckdBlockPtr))) {
 168                /* This is a "continue" pointer.
 169                 * This ptr should be the last one in the current
 170                 * script section.
 171                 * I.e. the next ptr must point to the unused memory area
 172                 */
 173                memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs));
 174                read_block(block_nr, bprs, "BPRS continuation read failed");
 175                more_data = true;
 176                break;
 177            }
 178
 179            /* Load (count+1) blocks of code at (block_nr)
 180             * to memory (address).
 181             */
 182            rc = virtio_read_many(block_nr, (void *)(*address),
 183                                  bprs[j].xeckd.bptr.count+1);
 184            IPL_assert(rc == 0, "code chunk read failed");
 185
 186            *address += (bprs[j].xeckd.bptr.count+1) * virtio_get_block_size();
 187        }
 188    } while (more_data);
 189    return block_nr;
 190}
 191
 192static void run_eckd_boot_script(block_number_t mbr_block_nr)
 193{
 194    int i;
 195    unsigned int loadparm = get_loadparm_index();
 196    block_number_t block_nr;
 197    uint64_t address;
 198    ScsiMbr *bte = (void *)sec; /* Eckd bootmap table entry */
 199    BootMapScript *bms = (void *)sec;
 200
 201    debug_print_int("loadparm", loadparm);
 202    IPL_assert(loadparm < 31, "loadparm value greater than"
 203               " maximum number of boot entries allowed");
 204
 205    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 206    read_block(mbr_block_nr, sec, "Cannot read MBR");
 207
 208    block_nr = eckd_block_num((void *)&(bte->blockptr[loadparm]));
 209    IPL_assert(block_nr != -1, "No Boot Map");
 210
 211    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 212    read_block(block_nr, sec, "Cannot read Boot Map Script");
 213
 214    for (i = 0; bms->entry[i].type == BOOT_SCRIPT_LOAD; i++) {
 215        address = bms->entry[i].address.load_address;
 216        block_nr = eckd_block_num(&(bms->entry[i].blkptr));
 217
 218        do {
 219            block_nr = load_eckd_segments(block_nr, &address);
 220        } while (block_nr != -1);
 221    }
 222
 223    IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC,
 224               "Unknown script entry type");
 225    jump_to_IPL_code(bms->entry[i].address.load_address); /* no return */
 226}
 227
 228static void ipl_eckd_cdl(void)
 229{
 230    XEckdMbr *mbr;
 231    Ipl2 *ipl2 = (void *)sec;
 232    IplVolumeLabel *vlbl = (void *)sec;
 233    block_number_t block_nr;
 234
 235    /* we have just read the block #0 and recognized it as "IPL1" */
 236    sclp_print("CDL\n");
 237
 238    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 239    read_block(1, ipl2, "Cannot read IPL2 record at block 1");
 240
 241    mbr = &ipl2->u.x.mbr;
 242    IPL_assert(magic_match(mbr, ZIPL_MAGIC), "No zIPL section in IPL2 record.");
 243    IPL_assert(block_size_ok(mbr->blockptr.xeckd.bptr.size),
 244               "Bad block size in zIPL section of IPL2 record.");
 245    IPL_assert(mbr->dev_type == DEV_TYPE_ECKD,
 246               "Non-ECKD device type in zIPL section of IPL2 record.");
 247
 248    /* save pointer to Boot Script */
 249    block_nr = eckd_block_num((void *)&(mbr->blockptr));
 250
 251    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 252    read_block(2, vlbl, "Cannot read Volume Label at block 2");
 253    IPL_assert(magic_match(vlbl->key, VOL1_MAGIC),
 254               "Invalid magic of volume label block");
 255    IPL_assert(magic_match(vlbl->f.key, VOL1_MAGIC),
 256               "Invalid magic of volser block");
 257    print_volser(vlbl->f.volser);
 258
 259    run_eckd_boot_script(block_nr);
 260    /* no return */
 261}
 262
 263static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode)
 264{
 265    LDL_VTOC *vlbl = (void *)sec; /* already read, 3rd block */
 266    char msg[4] = { '?', '.', '\n', '\0' };
 267
 268    sclp_print((mode == ECKD_CMS) ? "CMS" : "LDL");
 269    sclp_print(" version ");
 270    switch (vlbl->LDL_version) {
 271    case LDL1_VERSION:
 272        msg[0] = '1';
 273        break;
 274    case LDL2_VERSION:
 275        msg[0] = '2';
 276        break;
 277    default:
 278        msg[0] = vlbl->LDL_version;
 279        msg[0] &= 0x0f; /* convert EBCDIC   */
 280        msg[0] |= 0x30; /* to ASCII (digit) */
 281        msg[1] = '?';
 282        break;
 283    }
 284    sclp_print(msg);
 285    print_volser(vlbl->volser);
 286}
 287
 288static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
 289{
 290    block_number_t block_nr;
 291    BootInfo *bip = (void *)(sec + 0x70); /* BootInfo is MBR for LDL */
 292
 293    if (mode != ECKD_LDL_UNLABELED) {
 294        print_eckd_ldl_msg(mode);
 295    }
 296
 297    /* DO NOT read BootMap pointer (only one, xECKD) at block #2 */
 298
 299    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 300    read_block(0, sec, "Cannot read block 0 to grab boot info.");
 301    if (mode == ECKD_LDL_UNLABELED) {
 302        if (!magic_match(bip->magic, ZIPL_MAGIC)) {
 303            return; /* not applicable layout */
 304        }
 305        sclp_print("unlabeled LDL.\n");
 306    }
 307    verify_boot_info(bip);
 308
 309    block_nr = eckd_block_num((void *)&(bip->bp.ipl.bm_ptr.eckd.bptr));
 310    run_eckd_boot_script(block_nr);
 311    /* no return */
 312}
 313
 314static void print_eckd_msg(void)
 315{
 316    char msg[] = "Using ECKD scheme (block size *****), ";
 317    char *p = &msg[34], *q = &msg[30];
 318    int n = virtio_get_block_size();
 319
 320    /* Fill in the block size and show up the message */
 321    if (n > 0 && n <= 99999) {
 322        while (n) {
 323            *p-- = '0' + (n % 10);
 324            n /= 10;
 325        }
 326        while (p >= q) {
 327            *p-- = ' ';
 328        }
 329    }
 330    sclp_print(msg);
 331}
 332
 333static void ipl_eckd(void)
 334{
 335    ScsiMbr *mbr = (void *)sec;
 336    LDL_VTOC *vlbl = (void *)sec;
 337
 338    print_eckd_msg();
 339
 340    /* Grab the MBR again */
 341    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 342    read_block(0, mbr, "Cannot read block 0 on DASD");
 343
 344    if (magic_match(mbr->magic, IPL1_MAGIC)) {
 345        ipl_eckd_cdl(); /* no return */
 346    }
 347
 348    /* LDL/CMS? */
 349    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 350    read_block(2, vlbl, "Cannot read block 2");
 351
 352    if (magic_match(vlbl->magic, CMS1_MAGIC)) {
 353        ipl_eckd_ldl(ECKD_CMS); /* no return */
 354    }
 355    if (magic_match(vlbl->magic, LNX1_MAGIC)) {
 356        ipl_eckd_ldl(ECKD_LDL); /* no return */
 357    }
 358
 359    ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */
 360    /*
 361     * Ok, it is not a LDL by any means.
 362     * It still might be a CDL with zero record keys for IPL1 and IPL2
 363     */
 364    ipl_eckd_cdl();
 365}
 366
 367/***********************************************************************
 368 * IPL a SCSI disk
 369 */
 370
 371static void zipl_load_segment(ComponentEntry *entry)
 372{
 373    const int max_entries = (MAX_SECTOR_SIZE / sizeof(ScsiBlockPtr));
 374    ScsiBlockPtr *bprs = (void *)sec;
 375    const int bprs_size = sizeof(sec);
 376    block_number_t blockno;
 377    uint64_t address;
 378    int i;
 379    char err_msg[] = "zIPL failed to read BPRS at 0xZZZZZZZZZZZZZZZZ";
 380    char *blk_no = &err_msg[30]; /* where to print blockno in (those ZZs) */
 381
 382    blockno = entry->data.blockno;
 383    address = entry->load_address;
 384
 385    debug_print_int("loading segment at block", blockno);
 386    debug_print_int("addr", address);
 387
 388    do {
 389        memset(bprs, FREE_SPACE_FILLER, bprs_size);
 390        fill_hex_val(blk_no, &blockno, sizeof(blockno));
 391        read_block(blockno, bprs, err_msg);
 392
 393        for (i = 0;; i++) {
 394            uint64_t *cur_desc = (void *)&bprs[i];
 395
 396            blockno = bprs[i].blockno;
 397            if (!blockno) {
 398                break;
 399            }
 400
 401            /* we need the updated blockno for the next indirect entry in the
 402               chain, but don't want to advance address */
 403            if (i == (max_entries - 1)) {
 404                break;
 405            }
 406
 407            if (bprs[i].blockct == 0 && unused_space(&bprs[i + 1],
 408                sizeof(ScsiBlockPtr))) {
 409                /* This is a "continue" pointer.
 410                 * This ptr is the last one in the current script section.
 411                 * I.e. the next ptr must point to the unused memory area.
 412                 * The blockno is not zero, so the upper loop must continue
 413                 * reading next section of BPRS.
 414                 */
 415                break;
 416            }
 417            address = virtio_load_direct(cur_desc[0], cur_desc[1], 0,
 418                                         (void *)address);
 419            IPL_assert(address != -1, "zIPL load segment failed");
 420        }
 421    } while (blockno);
 422}
 423
 424/* Run a zipl program */
 425static void zipl_run(ScsiBlockPtr *pte)
 426{
 427    ComponentHeader *header;
 428    ComponentEntry *entry;
 429    uint8_t tmp_sec[MAX_SECTOR_SIZE];
 430
 431    read_block(pte->blockno, tmp_sec, "Cannot read header");
 432    header = (ComponentHeader *)tmp_sec;
 433
 434    IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic in header");
 435    IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type");
 436
 437    dputs("start loading images\n");
 438
 439    /* Load image(s) into RAM */
 440    entry = (ComponentEntry *)(&header[1]);
 441    while (entry->component_type == ZIPL_COMP_ENTRY_LOAD) {
 442        zipl_load_segment(entry);
 443
 444        entry++;
 445
 446        IPL_assert((uint8_t *)(&entry[1]) <= (tmp_sec + MAX_SECTOR_SIZE),
 447                   "Wrong entry value");
 448    }
 449
 450    IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry");
 451
 452    /* should not return */
 453    jump_to_IPL_code(entry->load_address);
 454}
 455
 456static void ipl_scsi(void)
 457{
 458    ScsiMbr *mbr = (void *)sec;
 459    uint8_t *ns, *ns_end;
 460    int program_table_entries = 0;
 461    const int pte_len = sizeof(ScsiBlockPtr);
 462    ScsiBlockPtr *prog_table_entry = NULL;
 463    unsigned int loadparm = get_loadparm_index();
 464
 465    /* Grab the MBR */
 466    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 467    read_block(0, mbr, "Cannot read block 0");
 468
 469    if (!magic_match(mbr->magic, ZIPL_MAGIC)) {
 470        return;
 471    }
 472
 473    sclp_print("Using SCSI scheme.\n");
 474    debug_print_int("MBR Version", mbr->version_id);
 475    IPL_check(mbr->version_id == 1,
 476              "Unknown MBR layout version, assuming version 1");
 477    debug_print_int("program table", mbr->blockptr[0].blockno);
 478    IPL_assert(mbr->blockptr[0].blockno, "No Program Table");
 479
 480    /* Parse the program table */
 481    read_block(mbr->blockptr[0].blockno, sec,
 482               "Error reading Program Table");
 483
 484    IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT");
 485
 486    debug_print_int("loadparm index", loadparm);
 487    ns_end = sec + virtio_get_block_size();
 488    for (ns = (sec + pte_len); (ns + pte_len) < ns_end; ns += pte_len) {
 489        prog_table_entry = (ScsiBlockPtr *)ns;
 490        if (!prog_table_entry->blockno) {
 491            break;
 492        }
 493
 494        program_table_entries++;
 495        if (program_table_entries == loadparm + 1) {
 496            break; /* selected entry found */
 497        }
 498    }
 499
 500    debug_print_int("program table entries", program_table_entries);
 501
 502    IPL_assert(program_table_entries != 0, "Empty Program Table");
 503
 504    zipl_run(prog_table_entry); /* no return */
 505}
 506
 507/***********************************************************************
 508 * IPL El Torito ISO9660 image or DVD
 509 */
 510
 511static bool is_iso_bc_entry_compatible(IsoBcSection *s)
 512{
 513    uint8_t *magic_sec = (uint8_t *)(sec + ISO_SECTOR_SIZE);
 514
 515    if (s->unused || !s->sector_count) {
 516        return false;
 517    }
 518    read_iso_sector(bswap32(s->load_rba), magic_sec,
 519                    "Failed to read image sector 0");
 520
 521    /* Checking bytes 8 - 32 for S390 Linux magic */
 522    return !_memcmp(magic_sec + 8, linux_s390_magic, 24);
 523}
 524
 525/* Location of the current sector of the directory */
 526static uint32_t sec_loc[ISO9660_MAX_DIR_DEPTH];
 527/* Offset in the current sector of the directory */
 528static uint32_t sec_offset[ISO9660_MAX_DIR_DEPTH];
 529/* Remained directory space in bytes */
 530static uint32_t dir_rem[ISO9660_MAX_DIR_DEPTH];
 531
 532static inline uint32_t iso_get_file_size(uint32_t load_rba)
 533{
 534    IsoVolDesc *vd = (IsoVolDesc *)sec;
 535    IsoDirHdr *cur_record = &vd->vd.primary.rootdir;
 536    uint8_t *temp = sec + ISO_SECTOR_SIZE;
 537    int level = 0;
 538
 539    read_iso_sector(ISO_PRIMARY_VD_SECTOR, sec,
 540                    "Failed to read ISO primary descriptor");
 541    sec_loc[0] = iso_733_to_u32(cur_record->ext_loc);
 542    dir_rem[0] = 0;
 543    sec_offset[0] = 0;
 544
 545    while (level >= 0) {
 546        IPL_assert(sec_offset[level] <= ISO_SECTOR_SIZE,
 547                   "Directory tree structure violation");
 548
 549        cur_record = (IsoDirHdr *)(temp + sec_offset[level]);
 550
 551        if (sec_offset[level] == 0) {
 552            read_iso_sector(sec_loc[level], temp,
 553                            "Failed to read ISO directory");
 554            if (dir_rem[level] == 0) {
 555                /* Skip self and parent records */
 556                dir_rem[level] = iso_733_to_u32(cur_record->data_len) -
 557                                 cur_record->dr_len;
 558                sec_offset[level] += cur_record->dr_len;
 559
 560                cur_record = (IsoDirHdr *)(temp + sec_offset[level]);
 561                dir_rem[level] -= cur_record->dr_len;
 562                sec_offset[level] += cur_record->dr_len;
 563                continue;
 564            }
 565        }
 566
 567        if (!cur_record->dr_len || sec_offset[level] == ISO_SECTOR_SIZE) {
 568            /* Zero-padding and/or the end of current sector */
 569            dir_rem[level] -= ISO_SECTOR_SIZE - sec_offset[level];
 570            sec_offset[level] = 0;
 571            sec_loc[level]++;
 572        } else {
 573            /* The directory record is valid */
 574            if (load_rba == iso_733_to_u32(cur_record->ext_loc)) {
 575                return iso_733_to_u32(cur_record->data_len);
 576            }
 577
 578            dir_rem[level] -= cur_record->dr_len;
 579            sec_offset[level] += cur_record->dr_len;
 580
 581            if (cur_record->file_flags & 0x2) {
 582                /* Subdirectory */
 583                if (level == ISO9660_MAX_DIR_DEPTH - 1) {
 584                    sclp_print("ISO-9660 directory depth limit exceeded\n");
 585                } else {
 586                    level++;
 587                    sec_loc[level] = iso_733_to_u32(cur_record->ext_loc);
 588                    sec_offset[level] = 0;
 589                    dir_rem[level] = 0;
 590                    continue;
 591                }
 592            }
 593        }
 594
 595        if (dir_rem[level] == 0) {
 596            /* Nothing remaining */
 597            level--;
 598            read_iso_sector(sec_loc[level], temp,
 599                            "Failed to read ISO directory");
 600        }
 601    }
 602
 603    return 0;
 604}
 605
 606static void load_iso_bc_entry(IsoBcSection *load)
 607{
 608    IsoBcSection s = *load;
 609    /*
 610     * According to spec, extent for each file
 611     * is padded and ISO_SECTOR_SIZE bytes aligned
 612     */
 613    uint32_t blks_to_load = bswap16(s.sector_count) >> ET_SECTOR_SHIFT;
 614    uint32_t real_size = iso_get_file_size(bswap32(s.load_rba));
 615
 616    if (real_size) {
 617        /* Round up blocks to load */
 618        blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE;
 619        sclp_print("ISO boot image size verified\n");
 620    } else {
 621        sclp_print("ISO boot image size could not be verified\n");
 622    }
 623
 624    read_iso_boot_image(bswap32(s.load_rba),
 625                        (void *)((uint64_t)bswap16(s.load_segment)),
 626                        blks_to_load);
 627
 628    /* Trying to get PSW at zero address */
 629    if (*((uint64_t *)0) & IPL_PSW_MASK) {
 630        jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
 631    }
 632
 633    /* Try default linux start address */
 634    jump_to_IPL_code(KERN_IMAGE_START);
 635}
 636
 637static uint32_t find_iso_bc(void)
 638{
 639    IsoVolDesc *vd = (IsoVolDesc *)sec;
 640    uint32_t block_num = ISO_PRIMARY_VD_SECTOR;
 641
 642    if (virtio_read_many(block_num++, sec, 1)) {
 643        /* If primary vd cannot be read, there is no boot catalog */
 644        return 0;
 645    }
 646
 647    while (is_iso_vd_valid(vd) && vd->type != VOL_DESC_TERMINATOR) {
 648        if (vd->type == VOL_DESC_TYPE_BOOT) {
 649            IsoVdElTorito *et = &vd->vd.boot;
 650
 651            if (!_memcmp(&et->el_torito[0], el_torito_magic, 32)) {
 652                return bswap32(et->bc_offset);
 653            }
 654        }
 655        read_iso_sector(block_num++, sec,
 656                        "Failed to read ISO volume descriptor");
 657    }
 658
 659    return 0;
 660}
 661
 662static IsoBcSection *find_iso_bc_entry(void)
 663{
 664    IsoBcEntry *e = (IsoBcEntry *)sec;
 665    uint32_t offset = find_iso_bc();
 666    int i;
 667    unsigned int loadparm = get_loadparm_index();
 668
 669    if (!offset) {
 670        return NULL;
 671    }
 672
 673    read_iso_sector(offset, sec, "Failed to read El Torito boot catalog");
 674
 675    if (!is_iso_bc_valid(e)) {
 676        /* The validation entry is mandatory */
 677        panic("No valid boot catalog found!\n");
 678        return NULL;
 679    }
 680
 681    /*
 682     * Each entry has 32 bytes size, so one sector cannot contain > 64 entries.
 683     * We consider only boot catalogs with no more than 64 entries.
 684     */
 685    for (i = 1; i < ISO_BC_ENTRY_PER_SECTOR; i++) {
 686        if (e[i].id == ISO_BC_BOOTABLE_SECTION) {
 687            if (is_iso_bc_entry_compatible(&e[i].body.sect)) {
 688                if (loadparm <= 1) {
 689                    /* found, default, or unspecified */
 690                    return &e[i].body.sect;
 691                }
 692                loadparm--;
 693            }
 694        }
 695    }
 696
 697    panic("No suitable boot entry found on ISO-9660 media!\n");
 698
 699    return NULL;
 700}
 701
 702static void ipl_iso_el_torito(void)
 703{
 704    IsoBcSection *s = find_iso_bc_entry();
 705
 706    if (s) {
 707        load_iso_bc_entry(s);
 708        /* no return */
 709    }
 710}
 711
 712/***********************************************************************
 713 * Bus specific IPL sequences
 714 */
 715
 716static void zipl_load_vblk(void)
 717{
 718    if (virtio_guessed_disk_nature()) {
 719        virtio_assume_iso9660();
 720    }
 721    ipl_iso_el_torito();
 722
 723    if (virtio_guessed_disk_nature()) {
 724        sclp_print("Using guessed DASD geometry.\n");
 725        virtio_assume_eckd();
 726    }
 727    ipl_eckd();
 728}
 729
 730static void zipl_load_vscsi(void)
 731{
 732    if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) {
 733        /* Is it an ISO image in non-CD drive? */
 734        ipl_iso_el_torito();
 735    }
 736
 737    sclp_print("Using guessed DASD geometry.\n");
 738    virtio_assume_eckd();
 739    ipl_eckd();
 740}
 741
 742/***********************************************************************
 743 * IPL starts here
 744 */
 745
 746void zipl_load(void)
 747{
 748    VDev *vdev = virtio_get_device();
 749
 750    if (vdev->is_cdrom) {
 751        ipl_iso_el_torito();
 752        panic("\n! Cannot IPL this ISO image !\n");
 753    }
 754
 755    if (virtio_get_device_type() == VIRTIO_ID_NET) {
 756        jump_to_IPL_code(vdev->netboot_start_addr);
 757    }
 758
 759    ipl_scsi();
 760
 761    switch (virtio_get_device_type()) {
 762    case VIRTIO_ID_BLOCK:
 763        zipl_load_vblk();
 764        break;
 765    case VIRTIO_ID_SCSI:
 766        zipl_load_vscsi();
 767        break;
 768    default:
 769        panic("\n! Unknown IPL device type !\n");
 770    }
 771
 772    panic("\n* this can never happen *\n");
 773}
 774