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