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; i++) {
 258        address = bms->entry[i].address.load_address;
 259        block_nr = eckd_block_num(&bms->entry[i].blkptr.xeckd.bptr.chs);
 260
 261        do {
 262            block_nr = load_eckd_segments(block_nr, &address);
 263        } while (block_nr != -1);
 264    }
 265
 266    IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC,
 267               "Unknown script entry type");
 268    jump_to_IPL_code(bms->entry[i].address.load_address); /* no return */
 269}
 270
 271static void ipl_eckd_cdl(void)
 272{
 273    XEckdMbr *mbr;
 274    EckdCdlIpl2 *ipl2 = (void *)sec;
 275    IplVolumeLabel *vlbl = (void *)sec;
 276    block_number_t bmt_block_nr, s1b_block_nr;
 277
 278    /* we have just read the block #0 and recognized it as "IPL1" */
 279    sclp_print("CDL\n");
 280
 281    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 282    read_block(1, ipl2, "Cannot read IPL2 record at block 1");
 283
 284    mbr = &ipl2->mbr;
 285    IPL_assert(magic_match(mbr, ZIPL_MAGIC), "No zIPL section in IPL2 record.");
 286    IPL_assert(block_size_ok(mbr->blockptr.xeckd.bptr.size),
 287               "Bad block size in zIPL section of IPL2 record.");
 288    IPL_assert(mbr->dev_type == DEV_TYPE_ECKD,
 289               "Non-ECKD device type in zIPL section of IPL2 record.");
 290
 291    /* save pointer to Boot Map Table */
 292    bmt_block_nr = eckd_block_num(&mbr->blockptr.xeckd.bptr.chs);
 293
 294    /* save pointer to Stage1b Data */
 295    s1b_block_nr = eckd_block_num(&ipl2->stage1.seek[0].chs);
 296
 297    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 298    read_block(2, vlbl, "Cannot read Volume Label at block 2");
 299    IPL_assert(magic_match(vlbl->key, VOL1_MAGIC),
 300               "Invalid magic of volume label block");
 301    IPL_assert(magic_match(vlbl->f.key, VOL1_MAGIC),
 302               "Invalid magic of volser block");
 303    print_volser(vlbl->f.volser);
 304
 305    run_eckd_boot_script(bmt_block_nr, s1b_block_nr);
 306    /* no return */
 307}
 308
 309static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode)
 310{
 311    LDL_VTOC *vlbl = (void *)sec; /* already read, 3rd block */
 312    char msg[4] = { '?', '.', '\n', '\0' };
 313
 314    sclp_print((mode == ECKD_CMS) ? "CMS" : "LDL");
 315    sclp_print(" version ");
 316    switch (vlbl->LDL_version) {
 317    case LDL1_VERSION:
 318        msg[0] = '1';
 319        break;
 320    case LDL2_VERSION:
 321        msg[0] = '2';
 322        break;
 323    default:
 324        msg[0] = vlbl->LDL_version;
 325        msg[0] &= 0x0f; /* convert EBCDIC   */
 326        msg[0] |= 0x30; /* to ASCII (digit) */
 327        msg[1] = '?';
 328        break;
 329    }
 330    sclp_print(msg);
 331    print_volser(vlbl->volser);
 332}
 333
 334static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
 335{
 336    block_number_t bmt_block_nr, s1b_block_nr;
 337    EckdLdlIpl1 *ipl1 = (void *)sec;
 338
 339    if (mode != ECKD_LDL_UNLABELED) {
 340        print_eckd_ldl_msg(mode);
 341    }
 342
 343    /* DO NOT read BootMap pointer (only one, xECKD) at block #2 */
 344
 345    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 346    read_block(0, sec, "Cannot read block 0 to grab boot info.");
 347    if (mode == ECKD_LDL_UNLABELED) {
 348        if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) {
 349            return; /* not applicable layout */
 350        }
 351        sclp_print("unlabeled LDL.\n");
 352    }
 353    verify_boot_info(&ipl1->bip);
 354
 355    /* save pointer to Boot Map Table */
 356    bmt_block_nr = eckd_block_num(&ipl1->bip.bp.ipl.bm_ptr.eckd.bptr.chs);
 357
 358    /* save pointer to Stage1b Data */
 359    s1b_block_nr = eckd_block_num(&ipl1->stage1.seek[0].chs);
 360
 361    run_eckd_boot_script(bmt_block_nr, s1b_block_nr);
 362    /* no return */
 363}
 364
 365static void print_eckd_msg(void)
 366{
 367    char msg[] = "Using ECKD scheme (block size *****), ";
 368    char *p = &msg[34], *q = &msg[30];
 369    int n = virtio_get_block_size();
 370
 371    /* Fill in the block size and show up the message */
 372    if (n > 0 && n <= 99999) {
 373        while (n) {
 374            *p-- = '0' + (n % 10);
 375            n /= 10;
 376        }
 377        while (p >= q) {
 378            *p-- = ' ';
 379        }
 380    }
 381    sclp_print(msg);
 382}
 383
 384static void ipl_eckd(void)
 385{
 386    XEckdMbr *mbr = (void *)sec;
 387    LDL_VTOC *vlbl = (void *)sec;
 388
 389    print_eckd_msg();
 390
 391    /* Grab the MBR again */
 392    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 393    read_block(0, mbr, "Cannot read block 0 on DASD");
 394
 395    if (magic_match(mbr->magic, IPL1_MAGIC)) {
 396        ipl_eckd_cdl(); /* no return */
 397    }
 398
 399    /* LDL/CMS? */
 400    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 401    read_block(2, vlbl, "Cannot read block 2");
 402
 403    if (magic_match(vlbl->magic, CMS1_MAGIC)) {
 404        ipl_eckd_ldl(ECKD_CMS); /* no return */
 405    }
 406    if (magic_match(vlbl->magic, LNX1_MAGIC)) {
 407        ipl_eckd_ldl(ECKD_LDL); /* no return */
 408    }
 409
 410    ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */
 411    /*
 412     * Ok, it is not a LDL by any means.
 413     * It still might be a CDL with zero record keys for IPL1 and IPL2
 414     */
 415    ipl_eckd_cdl();
 416}
 417
 418/***********************************************************************
 419 * IPL a SCSI disk
 420 */
 421
 422static void zipl_load_segment(ComponentEntry *entry)
 423{
 424    const int max_entries = (MAX_SECTOR_SIZE / sizeof(ScsiBlockPtr));
 425    ScsiBlockPtr *bprs = (void *)sec;
 426    const int bprs_size = sizeof(sec);
 427    block_number_t blockno;
 428    uint64_t address;
 429    int i;
 430    char err_msg[] = "zIPL failed to read BPRS at 0xZZZZZZZZZZZZZZZZ";
 431    char *blk_no = &err_msg[30]; /* where to print blockno in (those ZZs) */
 432
 433    blockno = entry->data.blockno;
 434    address = entry->load_address;
 435
 436    debug_print_int("loading segment at block", blockno);
 437    debug_print_int("addr", address);
 438
 439    do {
 440        memset(bprs, FREE_SPACE_FILLER, bprs_size);
 441        fill_hex_val(blk_no, &blockno, sizeof(blockno));
 442        read_block(blockno, bprs, err_msg);
 443
 444        for (i = 0;; i++) {
 445            uint64_t *cur_desc = (void *)&bprs[i];
 446
 447            blockno = bprs[i].blockno;
 448            if (!blockno) {
 449                break;
 450            }
 451
 452            /* we need the updated blockno for the next indirect entry in the
 453               chain, but don't want to advance address */
 454            if (i == (max_entries - 1)) {
 455                break;
 456            }
 457
 458            if (bprs[i].blockct == 0 && unused_space(&bprs[i + 1],
 459                sizeof(ScsiBlockPtr))) {
 460                /* This is a "continue" pointer.
 461                 * This ptr is the last one in the current script section.
 462                 * I.e. the next ptr must point to the unused memory area.
 463                 * The blockno is not zero, so the upper loop must continue
 464                 * reading next section of BPRS.
 465                 */
 466                break;
 467            }
 468            address = virtio_load_direct(cur_desc[0], cur_desc[1], 0,
 469                                         (void *)address);
 470            IPL_assert(address != -1, "zIPL load segment failed");
 471        }
 472    } while (blockno);
 473}
 474
 475/* Run a zipl program */
 476static void zipl_run(ScsiBlockPtr *pte)
 477{
 478    ComponentHeader *header;
 479    ComponentEntry *entry;
 480    uint8_t tmp_sec[MAX_SECTOR_SIZE];
 481
 482    read_block(pte->blockno, tmp_sec, "Cannot read header");
 483    header = (ComponentHeader *)tmp_sec;
 484
 485    IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic in header");
 486    IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type");
 487
 488    dputs("start loading images\n");
 489
 490    /* Load image(s) into RAM */
 491    entry = (ComponentEntry *)(&header[1]);
 492    while (entry->component_type == ZIPL_COMP_ENTRY_LOAD) {
 493        zipl_load_segment(entry);
 494
 495        entry++;
 496
 497        IPL_assert((uint8_t *)(&entry[1]) <= (tmp_sec + MAX_SECTOR_SIZE),
 498                   "Wrong entry value");
 499    }
 500
 501    IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry");
 502
 503    /* should not return */
 504    jump_to_IPL_code(entry->load_address);
 505}
 506
 507static void ipl_scsi(void)
 508{
 509    ScsiMbr *mbr = (void *)sec;
 510    int program_table_entries = 0;
 511    BootMapTable *prog_table = (void *)sec;
 512    unsigned int loadparm = get_loadparm_index();
 513    bool valid_entries[MAX_BOOT_ENTRIES] = {false};
 514    size_t i;
 515
 516    /* Grab the MBR */
 517    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
 518    read_block(0, mbr, "Cannot read block 0");
 519
 520    if (!magic_match(mbr->magic, ZIPL_MAGIC)) {
 521        return;
 522    }
 523
 524    sclp_print("Using SCSI scheme.\n");
 525    debug_print_int("MBR Version", mbr->version_id);
 526    IPL_check(mbr->version_id == 1,
 527              "Unknown MBR layout version, assuming version 1");
 528    debug_print_int("program table", mbr->pt.blockno);
 529    IPL_assert(mbr->pt.blockno, "No Program Table");
 530
 531    /* Parse the program table */
 532    read_block(mbr->pt.blockno, sec, "Error reading Program Table");
 533    IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT");
 534
 535    for (i = 0; i < MAX_BOOT_ENTRIES; i++) {
 536        if (prog_table->entry[i].scsi.blockno) {
 537            valid_entries[i] = true;
 538            program_table_entries++;
 539        }
 540    }
 541
 542    debug_print_int("program table entries", program_table_entries);
 543    IPL_assert(program_table_entries != 0, "Empty Program Table");
 544
 545    if (menu_is_enabled_enum()) {
 546        loadparm = menu_get_enum_boot_index(valid_entries);
 547    }
 548
 549    debug_print_int("loadparm", loadparm);
 550    IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than"
 551               " maximum number of boot entries allowed");
 552
 553    zipl_run(&prog_table->entry[loadparm].scsi); /* no return */
 554}
 555
 556/***********************************************************************
 557 * IPL El Torito ISO9660 image or DVD
 558 */
 559
 560static bool is_iso_bc_entry_compatible(IsoBcSection *s)
 561{
 562    uint8_t *magic_sec = (uint8_t *)(sec + ISO_SECTOR_SIZE);
 563
 564    if (s->unused || !s->sector_count) {
 565        return false;
 566    }
 567    read_iso_sector(bswap32(s->load_rba), magic_sec,
 568                    "Failed to read image sector 0");
 569
 570    /* Checking bytes 8 - 32 for S390 Linux magic */
 571    return !memcmp(magic_sec + 8, linux_s390_magic, 24);
 572}
 573
 574/* Location of the current sector of the directory */
 575static uint32_t sec_loc[ISO9660_MAX_DIR_DEPTH];
 576/* Offset in the current sector of the directory */
 577static uint32_t sec_offset[ISO9660_MAX_DIR_DEPTH];
 578/* Remained directory space in bytes */
 579static uint32_t dir_rem[ISO9660_MAX_DIR_DEPTH];
 580
 581static inline uint32_t iso_get_file_size(uint32_t load_rba)
 582{
 583    IsoVolDesc *vd = (IsoVolDesc *)sec;
 584    IsoDirHdr *cur_record = &vd->vd.primary.rootdir;
 585    uint8_t *temp = sec + ISO_SECTOR_SIZE;
 586    int level = 0;
 587
 588    read_iso_sector(ISO_PRIMARY_VD_SECTOR, sec,
 589                    "Failed to read ISO primary descriptor");
 590    sec_loc[0] = iso_733_to_u32(cur_record->ext_loc);
 591    dir_rem[0] = 0;
 592    sec_offset[0] = 0;
 593
 594    while (level >= 0) {
 595        IPL_assert(sec_offset[level] <= ISO_SECTOR_SIZE,
 596                   "Directory tree structure violation");
 597
 598        cur_record = (IsoDirHdr *)(temp + sec_offset[level]);
 599
 600        if (sec_offset[level] == 0) {
 601            read_iso_sector(sec_loc[level], temp,
 602                            "Failed to read ISO directory");
 603            if (dir_rem[level] == 0) {
 604                /* Skip self and parent records */
 605                dir_rem[level] = iso_733_to_u32(cur_record->data_len) -
 606                                 cur_record->dr_len;
 607                sec_offset[level] += cur_record->dr_len;
 608
 609                cur_record = (IsoDirHdr *)(temp + sec_offset[level]);
 610                dir_rem[level] -= cur_record->dr_len;
 611                sec_offset[level] += cur_record->dr_len;
 612                continue;
 613            }
 614        }
 615
 616        if (!cur_record->dr_len || sec_offset[level] == ISO_SECTOR_SIZE) {
 617            /* Zero-padding and/or the end of current sector */
 618            dir_rem[level] -= ISO_SECTOR_SIZE - sec_offset[level];
 619            sec_offset[level] = 0;
 620            sec_loc[level]++;
 621        } else {
 622            /* The directory record is valid */
 623            if (load_rba == iso_733_to_u32(cur_record->ext_loc)) {
 624                return iso_733_to_u32(cur_record->data_len);
 625            }
 626
 627            dir_rem[level] -= cur_record->dr_len;
 628            sec_offset[level] += cur_record->dr_len;
 629
 630            if (cur_record->file_flags & 0x2) {
 631                /* Subdirectory */
 632                if (level == ISO9660_MAX_DIR_DEPTH - 1) {
 633                    sclp_print("ISO-9660 directory depth limit exceeded\n");
 634                } else {
 635                    level++;
 636                    sec_loc[level] = iso_733_to_u32(cur_record->ext_loc);
 637                    sec_offset[level] = 0;
 638                    dir_rem[level] = 0;
 639                    continue;
 640                }
 641            }
 642        }
 643
 644        if (dir_rem[level] == 0) {
 645            /* Nothing remaining */
 646            level--;
 647            read_iso_sector(sec_loc[level], temp,
 648                            "Failed to read ISO directory");
 649        }
 650    }
 651
 652    return 0;
 653}
 654
 655static void load_iso_bc_entry(IsoBcSection *load)
 656{
 657    IsoBcSection s = *load;
 658    /*
 659     * According to spec, extent for each file
 660     * is padded and ISO_SECTOR_SIZE bytes aligned
 661     */
 662    uint32_t blks_to_load = bswap16(s.sector_count) >> ET_SECTOR_SHIFT;
 663    uint32_t real_size = iso_get_file_size(bswap32(s.load_rba));
 664
 665    if (real_size) {
 666        /* Round up blocks to load */
 667        blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE;
 668        sclp_print("ISO boot image size verified\n");
 669    } else {
 670        sclp_print("ISO boot image size could not be verified\n");
 671    }
 672
 673    read_iso_boot_image(bswap32(s.load_rba),
 674                        (void *)((uint64_t)bswap16(s.load_segment)),
 675                        blks_to_load);
 676
 677    jump_to_low_kernel();
 678}
 679
 680static uint32_t find_iso_bc(void)
 681{
 682    IsoVolDesc *vd = (IsoVolDesc *)sec;
 683    uint32_t block_num = ISO_PRIMARY_VD_SECTOR;
 684
 685    if (virtio_read_many(block_num++, sec, 1)) {
 686        /* If primary vd cannot be read, there is no boot catalog */
 687        return 0;
 688    }
 689
 690    while (is_iso_vd_valid(vd) && vd->type != VOL_DESC_TERMINATOR) {
 691        if (vd->type == VOL_DESC_TYPE_BOOT) {
 692            IsoVdElTorito *et = &vd->vd.boot;
 693
 694            if (!memcmp(&et->el_torito[0], el_torito_magic, 32)) {
 695                return bswap32(et->bc_offset);
 696            }
 697        }
 698        read_iso_sector(block_num++, sec,
 699                        "Failed to read ISO volume descriptor");
 700    }
 701
 702    return 0;
 703}
 704
 705static IsoBcSection *find_iso_bc_entry(void)
 706{
 707    IsoBcEntry *e = (IsoBcEntry *)sec;
 708    uint32_t offset = find_iso_bc();
 709    int i;
 710    unsigned int loadparm = get_loadparm_index();
 711
 712    if (!offset) {
 713        return NULL;
 714    }
 715
 716    read_iso_sector(offset, sec, "Failed to read El Torito boot catalog");
 717
 718    if (!is_iso_bc_valid(e)) {
 719        /* The validation entry is mandatory */
 720        panic("No valid boot catalog found!\n");
 721        return NULL;
 722    }
 723
 724    /*
 725     * Each entry has 32 bytes size, so one sector cannot contain > 64 entries.
 726     * We consider only boot catalogs with no more than 64 entries.
 727     */
 728    for (i = 1; i < ISO_BC_ENTRY_PER_SECTOR; i++) {
 729        if (e[i].id == ISO_BC_BOOTABLE_SECTION) {
 730            if (is_iso_bc_entry_compatible(&e[i].body.sect)) {
 731                if (loadparm <= 1) {
 732                    /* found, default, or unspecified */
 733                    return &e[i].body.sect;
 734                }
 735                loadparm--;
 736            }
 737        }
 738    }
 739
 740    panic("No suitable boot entry found on ISO-9660 media!\n");
 741
 742    return NULL;
 743}
 744
 745static void ipl_iso_el_torito(void)
 746{
 747    IsoBcSection *s = find_iso_bc_entry();
 748
 749    if (s) {
 750        load_iso_bc_entry(s);
 751        /* no return */
 752    }
 753}
 754
 755/***********************************************************************
 756 * Bus specific IPL sequences
 757 */
 758
 759static void zipl_load_vblk(void)
 760{
 761    if (virtio_guessed_disk_nature()) {
 762        virtio_assume_iso9660();
 763    }
 764    ipl_iso_el_torito();
 765
 766    if (virtio_guessed_disk_nature()) {
 767        sclp_print("Using guessed DASD geometry.\n");
 768        virtio_assume_eckd();
 769    }
 770    ipl_eckd();
 771}
 772
 773static void zipl_load_vscsi(void)
 774{
 775    if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) {
 776        /* Is it an ISO image in non-CD drive? */
 777        ipl_iso_el_torito();
 778    }
 779
 780    sclp_print("Using guessed DASD geometry.\n");
 781    virtio_assume_eckd();
 782    ipl_eckd();
 783}
 784
 785/***********************************************************************
 786 * IPL starts here
 787 */
 788
 789void zipl_load(void)
 790{
 791    VDev *vdev = virtio_get_device();
 792
 793    if (vdev->is_cdrom) {
 794        ipl_iso_el_torito();
 795        panic("\n! Cannot IPL this ISO image !\n");
 796    }
 797
 798    if (virtio_get_device_type() == VIRTIO_ID_NET) {
 799        jump_to_IPL_code(vdev->netboot_start_addr);
 800    }
 801
 802    ipl_scsi();
 803
 804    switch (virtio_get_device_type()) {
 805    case VIRTIO_ID_BLOCK:
 806        zipl_load_vblk();
 807        break;
 808    case VIRTIO_ID_SCSI:
 809        zipl_load_vscsi();
 810        break;
 811    default:
 812        panic("\n! Unknown IPL device type !\n");
 813    }
 814
 815    panic("\n* this can never happen *\n");
 816}
 817