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