/*
 * QEMU S390 bootmap interpreter
 *
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
 * your option) any later version. See the COPYING file in the top-level
 * directory.
 */

#include "libc.h"
#include "s390-ccw.h"
#include "bootmap.h"
#include "virtio.h"
#include "bswap.h"

#ifdef DEBUG
/* #define DEBUG_FALLBACK */
#endif

#ifdef DEBUG_FALLBACK
#define dputs(txt) \
    do { sclp_print("zipl: " txt); } while (0)
#else
#define dputs(fmt, ...) \
    do { } while (0)
#endif

/* Scratch space */
static uint8_t sec[MAX_SECTOR_SIZE*4] __attribute__((__aligned__(PAGE_SIZE)));

const uint8_t el_torito_magic[] = "EL TORITO SPECIFICATION"
                                  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

/*
 * Match two CCWs located after PSW and eight filler bytes.
 * From libmagic and arch/s390/kernel/head.S.
 */
const uint8_t linux_s390_magic[] = "\x02\x00\x00\x18\x60\x00\x00\x50\x02\x00"
                                   "\x00\x68\x60\x00\x00\x50\x40\x40\x40\x40"
                                   "\x40\x40\x40\x40";

static inline bool is_iso_vd_valid(IsoVolDesc *vd)
{
    const uint8_t vol_desc_magic[] = "CD001";

    return !memcmp(&vd->ident[0], vol_desc_magic, 5) &&
           vd->version == 0x1 &&
           vd->type <= VOL_DESC_TYPE_PARTITION;
}

/***********************************************************************
 * IPL an ECKD DASD (CDL or LDL/CMS format)
 */

static unsigned char _bprs[8*1024]; /* guessed "max" ECKD sector size */
static const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr);
static uint8_t _s2[MAX_SECTOR_SIZE * 3] __attribute__((__aligned__(PAGE_SIZE)));
static void *s2_prev_blk = _s2;
static void *s2_cur_blk = _s2 + MAX_SECTOR_SIZE;
static void *s2_next_blk = _s2 + MAX_SECTOR_SIZE * 2;

static inline void verify_boot_info(BootInfo *bip)
{
    IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL sig in BootInfo");
    IPL_assert(bip->version == BOOT_INFO_VERSION, "Wrong zIPL version");
    IPL_assert(bip->bp_type == BOOT_INFO_BP_TYPE_IPL, "DASD is not for IPL");
    IPL_assert(bip->dev_type == BOOT_INFO_DEV_TYPE_ECKD, "DASD is not ECKD");
    IPL_assert(bip->flags == BOOT_INFO_FLAGS_ARCH, "Not for this arch");
    IPL_assert(block_size_ok(bip->bp.ipl.bm_ptr.eckd.bptr.size),
               "Bad block size in zIPL section of the 1st record.");
}

static block_number_t eckd_block_num(EckdCHS *chs)
{
    const uint64_t sectors = virtio_get_sectors();
    const uint64_t heads = virtio_get_heads();
    const uint64_t cylinder = chs->cylinder
                            + ((chs->head & 0xfff0) << 12);
    const uint64_t head = chs->head & 0x000f;
    const block_number_t block = sectors * heads * cylinder
                               + sectors * head
                               + chs->sector
                               - 1; /* block nr starts with zero */
    return block;
}

static bool eckd_valid_address(BootMapPointer *p)
{
    const uint64_t head = p->eckd.chs.head & 0x000f;

    if (head >= virtio_get_heads()
        ||  p->eckd.chs.sector > virtio_get_sectors()
        ||  p->eckd.chs.sector <= 0) {
        return false;
    }

    if (!virtio_guessed_disk_nature() &&
        eckd_block_num(&p->eckd.chs) >= virtio_get_blocks()) {
        return false;
    }

    return true;
}

static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address)
{
    block_number_t block_nr;
    int j, rc;
    BootMapPointer *bprs = (void *)_bprs;
    bool more_data;

    memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs));
    read_block(blk, bprs, "BPRS read failed");

    do {
        more_data = false;
        for (j = 0;; j++) {
            block_nr = eckd_block_num(&bprs[j].xeckd.bptr.chs);
            if (is_null_block_number(block_nr)) { /* end of chunk */
                break;
            }

            /* we need the updated blockno for the next indirect entry
             * in the chain, but don't want to advance address
             */
            if (j == (max_bprs_entries - 1)) {
                break;
            }

            IPL_assert(block_size_ok(bprs[j].xeckd.bptr.size),
                       "bad chunk block size");
            IPL_assert(eckd_valid_address(&bprs[j]), "bad chunk ECKD addr");

            if ((bprs[j].xeckd.bptr.count == 0) && unused_space(&(bprs[j+1]),
                sizeof(EckdBlockPtr))) {
                /* This is a "continue" pointer.
                 * This ptr should be the last one in the current
                 * script section.
                 * I.e. the next ptr must point to the unused memory area
                 */
                memset(_bprs, FREE_SPACE_FILLER, sizeof(_bprs));
                read_block(block_nr, bprs, "BPRS continuation read failed");
                more_data = true;
                break;
            }

            /* Load (count+1) blocks of code at (block_nr)
             * to memory (address).
             */
            rc = virtio_read_many(block_nr, (void *)(*address),
                                  bprs[j].xeckd.bptr.count+1);
            IPL_assert(rc == 0, "code chunk read failed");

            *address += (bprs[j].xeckd.bptr.count+1) * virtio_get_block_size();
        }
    } while (more_data);
    return block_nr;
}

static bool find_zipl_boot_menu_banner(int *offset)
{
    int i;

    /* Menu banner starts with "zIPL" */
    for (i = 0; i < virtio_get_block_size() - 4; i++) {
        if (magic_match(s2_cur_blk + i, ZIPL_MAGIC_EBCDIC)) {
            *offset = i;
            return true;
        }
    }

    return false;
}

static int eckd_get_boot_menu_index(block_number_t s1b_block_nr)
{
    block_number_t cur_block_nr;
    block_number_t prev_block_nr = 0;
    block_number_t next_block_nr = 0;
    EckdStage1b *s1b = (void *)sec;
    int banner_offset;
    int i;

    /* Get Stage1b data */
    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(s1b_block_nr, s1b, "Cannot read stage1b boot loader");

    memset(_s2, FREE_SPACE_FILLER, sizeof(_s2));

    /* Get Stage2 data */
    for (i = 0; i < STAGE2_BLK_CNT_MAX; i++) {
        cur_block_nr = eckd_block_num(&s1b->seek[i].chs);

        if (!cur_block_nr) {
            break;
        }

        read_block(cur_block_nr, s2_cur_blk, "Cannot read stage2 boot loader");

        if (find_zipl_boot_menu_banner(&banner_offset)) {
            /*
             * Load the adjacent blocks to account for the
             * possibility of menu data spanning multiple blocks.
             */
            if (prev_block_nr) {
                read_block(prev_block_nr, s2_prev_blk,
                           "Cannot read stage2 boot loader");
            }

            if (i + 1 < STAGE2_BLK_CNT_MAX) {
                next_block_nr = eckd_block_num(&s1b->seek[i + 1].chs);
            }

            if (next_block_nr) {
                read_block(next_block_nr, s2_next_blk,
                           "Cannot read stage2 boot loader");
            }

            return menu_get_zipl_boot_index(s2_cur_blk + banner_offset);
        }

        prev_block_nr = cur_block_nr;
    }

    sclp_print("No zipl boot menu data found. Booting default entry.");
    return 0;
}

static void run_eckd_boot_script(block_number_t bmt_block_nr,
                                 block_number_t s1b_block_nr)
{
    int i;
    unsigned int loadparm = get_loadparm_index();
    block_number_t block_nr;
    uint64_t address;
    BootMapTable *bmt = (void *)sec;
    BootMapScript *bms = (void *)sec;

    if (menu_is_enabled_zipl()) {
        loadparm = eckd_get_boot_menu_index(s1b_block_nr);
    }

    debug_print_int("loadparm", loadparm);
    IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than"
               " maximum number of boot entries allowed");

    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(bmt_block_nr, sec, "Cannot read Boot Map Table");

    block_nr = eckd_block_num(&bmt->entry[loadparm].xeckd.bptr.chs);
    IPL_assert(block_nr != -1, "Cannot find Boot Map Table Entry");

    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(block_nr, sec, "Cannot read Boot Map Script");

    for (i = 0; bms->entry[i].type == BOOT_SCRIPT_LOAD; i++) {
        address = bms->entry[i].address.load_address;
        block_nr = eckd_block_num(&bms->entry[i].blkptr.xeckd.bptr.chs);

        do {
            block_nr = load_eckd_segments(block_nr, &address);
        } while (block_nr != -1);
    }

    IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC,
               "Unknown script entry type");
    jump_to_IPL_code(bms->entry[i].address.load_address); /* no return */
}

static void ipl_eckd_cdl(void)
{
    XEckdMbr *mbr;
    EckdCdlIpl2 *ipl2 = (void *)sec;
    IplVolumeLabel *vlbl = (void *)sec;
    block_number_t bmt_block_nr, s1b_block_nr;

    /* we have just read the block #0 and recognized it as "IPL1" */
    sclp_print("CDL\n");

    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(1, ipl2, "Cannot read IPL2 record at block 1");

    mbr = &ipl2->mbr;
    IPL_assert(magic_match(mbr, ZIPL_MAGIC), "No zIPL section in IPL2 record.");
    IPL_assert(block_size_ok(mbr->blockptr.xeckd.bptr.size),
               "Bad block size in zIPL section of IPL2 record.");
    IPL_assert(mbr->dev_type == DEV_TYPE_ECKD,
               "Non-ECKD device type in zIPL section of IPL2 record.");

    /* save pointer to Boot Map Table */
    bmt_block_nr = eckd_block_num(&mbr->blockptr.xeckd.bptr.chs);

    /* save pointer to Stage1b Data */
    s1b_block_nr = eckd_block_num(&ipl2->stage1.seek[0].chs);

    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(2, vlbl, "Cannot read Volume Label at block 2");
    IPL_assert(magic_match(vlbl->key, VOL1_MAGIC),
               "Invalid magic of volume label block");
    IPL_assert(magic_match(vlbl->f.key, VOL1_MAGIC),
               "Invalid magic of volser block");
    print_volser(vlbl->f.volser);

    run_eckd_boot_script(bmt_block_nr, s1b_block_nr);
    /* no return */
}

static void print_eckd_ldl_msg(ECKD_IPL_mode_t mode)
{
    LDL_VTOC *vlbl = (void *)sec; /* already read, 3rd block */
    char msg[4] = { '?', '.', '\n', '\0' };

    sclp_print((mode == ECKD_CMS) ? "CMS" : "LDL");
    sclp_print(" version ");
    switch (vlbl->LDL_version) {
    case LDL1_VERSION:
        msg[0] = '1';
        break;
    case LDL2_VERSION:
        msg[0] = '2';
        break;
    default:
        msg[0] = vlbl->LDL_version;
        msg[0] &= 0x0f; /* convert EBCDIC   */
        msg[0] |= 0x30; /* to ASCII (digit) */
        msg[1] = '?';
        break;
    }
    sclp_print(msg);
    print_volser(vlbl->volser);
}

static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
{
    block_number_t bmt_block_nr, s1b_block_nr;
    EckdLdlIpl1 *ipl1 = (void *)sec;

    if (mode != ECKD_LDL_UNLABELED) {
        print_eckd_ldl_msg(mode);
    }

    /* DO NOT read BootMap pointer (only one, xECKD) at block #2 */

    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(0, sec, "Cannot read block 0 to grab boot info.");
    if (mode == ECKD_LDL_UNLABELED) {
        if (!magic_match(ipl1->bip.magic, ZIPL_MAGIC)) {
            return; /* not applicable layout */
        }
        sclp_print("unlabeled LDL.\n");
    }
    verify_boot_info(&ipl1->bip);

    /* save pointer to Boot Map Table */
    bmt_block_nr = eckd_block_num(&ipl1->bip.bp.ipl.bm_ptr.eckd.bptr.chs);

    /* save pointer to Stage1b Data */
    s1b_block_nr = eckd_block_num(&ipl1->stage1.seek[0].chs);

    run_eckd_boot_script(bmt_block_nr, s1b_block_nr);
    /* no return */
}

static void print_eckd_msg(void)
{
    char msg[] = "Using ECKD scheme (block size *****), ";
    char *p = &msg[34], *q = &msg[30];
    int n = virtio_get_block_size();

    /* Fill in the block size and show up the message */
    if (n > 0 && n <= 99999) {
        while (n) {
            *p-- = '0' + (n % 10);
            n /= 10;
        }
        while (p >= q) {
            *p-- = ' ';
        }
    }
    sclp_print(msg);
}

static void ipl_eckd(void)
{
    XEckdMbr *mbr = (void *)sec;
    LDL_VTOC *vlbl = (void *)sec;

    print_eckd_msg();

    /* Grab the MBR again */
    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(0, mbr, "Cannot read block 0 on DASD");

    if (magic_match(mbr->magic, IPL1_MAGIC)) {
        ipl_eckd_cdl(); /* no return */
    }

    /* LDL/CMS? */
    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(2, vlbl, "Cannot read block 2");

    if (magic_match(vlbl->magic, CMS1_MAGIC)) {
        ipl_eckd_ldl(ECKD_CMS); /* no return */
    }
    if (magic_match(vlbl->magic, LNX1_MAGIC)) {
        ipl_eckd_ldl(ECKD_LDL); /* no return */
    }

    ipl_eckd_ldl(ECKD_LDL_UNLABELED); /* it still may return */
    /*
     * Ok, it is not a LDL by any means.
     * It still might be a CDL with zero record keys for IPL1 and IPL2
     */
    ipl_eckd_cdl();
}

/***********************************************************************
 * IPL a SCSI disk
 */

static void zipl_load_segment(ComponentEntry *entry)
{
    const int max_entries = (MAX_SECTOR_SIZE / sizeof(ScsiBlockPtr));
    ScsiBlockPtr *bprs = (void *)sec;
    const int bprs_size = sizeof(sec);
    block_number_t blockno;
    uint64_t address;
    int i;
    char err_msg[] = "zIPL failed to read BPRS at 0xZZZZZZZZZZZZZZZZ";
    char *blk_no = &err_msg[30]; /* where to print blockno in (those ZZs) */

    blockno = entry->data.blockno;
    address = entry->load_address;

    debug_print_int("loading segment at block", blockno);
    debug_print_int("addr", address);

    do {
        memset(bprs, FREE_SPACE_FILLER, bprs_size);
        fill_hex_val(blk_no, &blockno, sizeof(blockno));
        read_block(blockno, bprs, err_msg);

        for (i = 0;; i++) {
            uint64_t *cur_desc = (void *)&bprs[i];

            blockno = bprs[i].blockno;
            if (!blockno) {
                break;
            }

            /* we need the updated blockno for the next indirect entry in the
               chain, but don't want to advance address */
            if (i == (max_entries - 1)) {
                break;
            }

            if (bprs[i].blockct == 0 && unused_space(&bprs[i + 1],
                sizeof(ScsiBlockPtr))) {
                /* This is a "continue" pointer.
                 * This ptr is the last one in the current script section.
                 * I.e. the next ptr must point to the unused memory area.
                 * The blockno is not zero, so the upper loop must continue
                 * reading next section of BPRS.
                 */
                break;
            }
            address = virtio_load_direct(cur_desc[0], cur_desc[1], 0,
                                         (void *)address);
            IPL_assert(address != -1, "zIPL load segment failed");
        }
    } while (blockno);
}

/* Run a zipl program */
static void zipl_run(ScsiBlockPtr *pte)
{
    ComponentHeader *header;
    ComponentEntry *entry;
    uint8_t tmp_sec[MAX_SECTOR_SIZE];

    read_block(pte->blockno, tmp_sec, "Cannot read header");
    header = (ComponentHeader *)tmp_sec;

    IPL_assert(magic_match(tmp_sec, ZIPL_MAGIC), "No zIPL magic in header");
    IPL_assert(header->type == ZIPL_COMP_HEADER_IPL, "Bad header type");

    dputs("start loading images\n");

    /* Load image(s) into RAM */
    entry = (ComponentEntry *)(&header[1]);
    while (entry->component_type == ZIPL_COMP_ENTRY_LOAD) {
        zipl_load_segment(entry);

        entry++;

        IPL_assert((uint8_t *)(&entry[1]) <= (tmp_sec + MAX_SECTOR_SIZE),
                   "Wrong entry value");
    }

    IPL_assert(entry->component_type == ZIPL_COMP_ENTRY_EXEC, "No EXEC entry");

    /* should not return */
    jump_to_IPL_code(entry->load_address);
}

static void ipl_scsi(void)
{
    ScsiMbr *mbr = (void *)sec;
    int program_table_entries = 0;
    BootMapTable *prog_table = (void *)sec;
    unsigned int loadparm = get_loadparm_index();
    bool valid_entries[MAX_BOOT_ENTRIES] = {false};
    size_t i;

    /* Grab the MBR */
    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
    read_block(0, mbr, "Cannot read block 0");

    if (!magic_match(mbr->magic, ZIPL_MAGIC)) {
        return;
    }

    sclp_print("Using SCSI scheme.\n");
    debug_print_int("MBR Version", mbr->version_id);
    IPL_check(mbr->version_id == 1,
              "Unknown MBR layout version, assuming version 1");
    debug_print_int("program table", mbr->pt.blockno);
    IPL_assert(mbr->pt.blockno, "No Program Table");

    /* Parse the program table */
    read_block(mbr->pt.blockno, sec, "Error reading Program Table");
    IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT");

    for (i = 0; i < MAX_BOOT_ENTRIES; i++) {
        if (prog_table->entry[i].scsi.blockno) {
            valid_entries[i] = true;
            program_table_entries++;
        }
    }

    debug_print_int("program table entries", program_table_entries);
    IPL_assert(program_table_entries != 0, "Empty Program Table");

    if (menu_is_enabled_enum()) {
        loadparm = menu_get_enum_boot_index(valid_entries);
    }

    debug_print_int("loadparm", loadparm);
    IPL_assert(loadparm < MAX_BOOT_ENTRIES, "loadparm value greater than"
               " maximum number of boot entries allowed");

    zipl_run(&prog_table->entry[loadparm].scsi); /* no return */
}

/***********************************************************************
 * IPL El Torito ISO9660 image or DVD
 */

static bool is_iso_bc_entry_compatible(IsoBcSection *s)
{
    uint8_t *magic_sec = (uint8_t *)(sec + ISO_SECTOR_SIZE);

    if (s->unused || !s->sector_count) {
        return false;
    }
    read_iso_sector(bswap32(s->load_rba), magic_sec,
                    "Failed to read image sector 0");

    /* Checking bytes 8 - 32 for S390 Linux magic */
    return !memcmp(magic_sec + 8, linux_s390_magic, 24);
}

/* Location of the current sector of the directory */
static uint32_t sec_loc[ISO9660_MAX_DIR_DEPTH];
/* Offset in the current sector of the directory */
static uint32_t sec_offset[ISO9660_MAX_DIR_DEPTH];
/* Remained directory space in bytes */
static uint32_t dir_rem[ISO9660_MAX_DIR_DEPTH];

static inline uint32_t iso_get_file_size(uint32_t load_rba)
{
    IsoVolDesc *vd = (IsoVolDesc *)sec;
    IsoDirHdr *cur_record = &vd->vd.primary.rootdir;
    uint8_t *temp = sec + ISO_SECTOR_SIZE;
    int level = 0;

    read_iso_sector(ISO_PRIMARY_VD_SECTOR, sec,
                    "Failed to read ISO primary descriptor");
    sec_loc[0] = iso_733_to_u32(cur_record->ext_loc);
    dir_rem[0] = 0;
    sec_offset[0] = 0;

    while (level >= 0) {
        IPL_assert(sec_offset[level] <= ISO_SECTOR_SIZE,
                   "Directory tree structure violation");

        cur_record = (IsoDirHdr *)(temp + sec_offset[level]);

        if (sec_offset[level] == 0) {
            read_iso_sector(sec_loc[level], temp,
                            "Failed to read ISO directory");
            if (dir_rem[level] == 0) {
                /* Skip self and parent records */
                dir_rem[level] = iso_733_to_u32(cur_record->data_len) -
                                 cur_record->dr_len;
                sec_offset[level] += cur_record->dr_len;

                cur_record = (IsoDirHdr *)(temp + sec_offset[level]);
                dir_rem[level] -= cur_record->dr_len;
                sec_offset[level] += cur_record->dr_len;
                continue;
            }
        }

        if (!cur_record->dr_len || sec_offset[level] == ISO_SECTOR_SIZE) {
            /* Zero-padding and/or the end of current sector */
            dir_rem[level] -= ISO_SECTOR_SIZE - sec_offset[level];
            sec_offset[level] = 0;
            sec_loc[level]++;
        } else {
            /* The directory record is valid */
            if (load_rba == iso_733_to_u32(cur_record->ext_loc)) {
                return iso_733_to_u32(cur_record->data_len);
            }

            dir_rem[level] -= cur_record->dr_len;
            sec_offset[level] += cur_record->dr_len;

            if (cur_record->file_flags & 0x2) {
                /* Subdirectory */
                if (level == ISO9660_MAX_DIR_DEPTH - 1) {
                    sclp_print("ISO-9660 directory depth limit exceeded\n");
                } else {
                    level++;
                    sec_loc[level] = iso_733_to_u32(cur_record->ext_loc);
                    sec_offset[level] = 0;
                    dir_rem[level] = 0;
                    continue;
                }
            }
        }

        if (dir_rem[level] == 0) {
            /* Nothing remaining */
            level--;
            read_iso_sector(sec_loc[level], temp,
                            "Failed to read ISO directory");
        }
    }

    return 0;
}

static void load_iso_bc_entry(IsoBcSection *load)
{
    IsoBcSection s = *load;
    /*
     * According to spec, extent for each file
     * is padded and ISO_SECTOR_SIZE bytes aligned
     */
    uint32_t blks_to_load = bswap16(s.sector_count) >> ET_SECTOR_SHIFT;
    uint32_t real_size = iso_get_file_size(bswap32(s.load_rba));

    if (real_size) {
        /* Round up blocks to load */
        blks_to_load = (real_size + ISO_SECTOR_SIZE - 1) / ISO_SECTOR_SIZE;
        sclp_print("ISO boot image size verified\n");
    } else {
        sclp_print("ISO boot image size could not be verified\n");
    }

    read_iso_boot_image(bswap32(s.load_rba),
                        (void *)((uint64_t)bswap16(s.load_segment)),
                        blks_to_load);

    jump_to_low_kernel();
}

static uint32_t find_iso_bc(void)
{
    IsoVolDesc *vd = (IsoVolDesc *)sec;
    uint32_t block_num = ISO_PRIMARY_VD_SECTOR;

    if (virtio_read_many(block_num++, sec, 1)) {
        /* If primary vd cannot be read, there is no boot catalog */
        return 0;
    }

    while (is_iso_vd_valid(vd) && vd->type != VOL_DESC_TERMINATOR) {
        if (vd->type == VOL_DESC_TYPE_BOOT) {
            IsoVdElTorito *et = &vd->vd.boot;

            if (!memcmp(&et->el_torito[0], el_torito_magic, 32)) {
                return bswap32(et->bc_offset);
            }
        }
        read_iso_sector(block_num++, sec,
                        "Failed to read ISO volume descriptor");
    }

    return 0;
}

static IsoBcSection *find_iso_bc_entry(void)
{
    IsoBcEntry *e = (IsoBcEntry *)sec;
    uint32_t offset = find_iso_bc();
    int i;
    unsigned int loadparm = get_loadparm_index();

    if (!offset) {
        return NULL;
    }

    read_iso_sector(offset, sec, "Failed to read El Torito boot catalog");

    if (!is_iso_bc_valid(e)) {
        /* The validation entry is mandatory */
        panic("No valid boot catalog found!\n");
        return NULL;
    }

    /*
     * Each entry has 32 bytes size, so one sector cannot contain > 64 entries.
     * We consider only boot catalogs with no more than 64 entries.
     */
    for (i = 1; i < ISO_BC_ENTRY_PER_SECTOR; i++) {
        if (e[i].id == ISO_BC_BOOTABLE_SECTION) {
            if (is_iso_bc_entry_compatible(&e[i].body.sect)) {
                if (loadparm <= 1) {
                    /* found, default, or unspecified */
                    return &e[i].body.sect;
                }
                loadparm--;
            }
        }
    }

    panic("No suitable boot entry found on ISO-9660 media!\n");

    return NULL;
}

static void ipl_iso_el_torito(void)
{
    IsoBcSection *s = find_iso_bc_entry();

    if (s) {
        load_iso_bc_entry(s);
        /* no return */
    }
}

/***********************************************************************
 * Bus specific IPL sequences
 */

static void zipl_load_vblk(void)
{
    if (virtio_guessed_disk_nature()) {
        virtio_assume_iso9660();
    }
    ipl_iso_el_torito();

    if (virtio_guessed_disk_nature()) {
        sclp_print("Using guessed DASD geometry.\n");
        virtio_assume_eckd();
    }
    ipl_eckd();
}

static void zipl_load_vscsi(void)
{
    if (virtio_get_block_size() == VIRTIO_ISO_BLOCK_SIZE) {
        /* Is it an ISO image in non-CD drive? */
        ipl_iso_el_torito();
    }

    sclp_print("Using guessed DASD geometry.\n");
    virtio_assume_eckd();
    ipl_eckd();
}

/***********************************************************************
 * IPL starts here
 */

void zipl_load(void)
{
    VDev *vdev = virtio_get_device();

    if (vdev->is_cdrom) {
        ipl_iso_el_torito();
        panic("\n! Cannot IPL this ISO image !\n");
    }

    if (virtio_get_device_type() == VIRTIO_ID_NET) {
        jump_to_IPL_code(vdev->netboot_start_addr);
    }

    ipl_scsi();

    switch (virtio_get_device_type()) {
    case VIRTIO_ID_BLOCK:
        zipl_load_vblk();
        break;
    case VIRTIO_ID_SCSI:
        zipl_load_vscsi();
        break;
    default:
        panic("\n! Unknown IPL device type !\n");
    }

    panic("\n* this can never happen *\n");
}
