Commit 532cd4b0 authored by Cornelia Huck's avatar Cornelia Huck
Browse files

Merge tag 'tags/s390x-2018-05-02' into staging



s390-ccw firmware updates:
- Improvements to the boot menu (can now handle non-sequential entries)
- s390-netboot now resets the machine before jumping into the OS kernel
- s390-netboot now supports indirect loading via .INS files
- some other minor fixes and clean-ups

# gpg: Signature made Wed 02 May 2018 04:15:21 PM CEST
# gpg:                using RSA key 2ED9D774FE702DB5
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [undefined]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [undefined]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]

* tag 'tags/s390x-2018-05-02':
  pc-bios/s390: Update firmware images
  s390-ccw: force diag 308 subcode to unsigned long
  pc-bios/s390-ccw/net: Add support for .INS config files
  pc-bios/s390-ccw/net: Use diag308 to reset machine before jumping to the OS
  pc-bios/s390-ccw/net: Split up net_load() into init, load and release parts
  pc-bios/s390-ccw: fix non-sequential boot entries (enum)
  pc-bios/s390-ccw: fix non-sequential boot entries (eckd)
  pc-bios/s390-ccw: fix loadparm initialization and int conversion
  pc-bios/s390-ccw: rename MAX_TABLE_ENTRIES to MAX_BOOT_ENTRIES
  pc-bios/s390-ccw: size_t should be unsigned

Signed-off-by: default avatarCornelia Huck <cohuck@redhat.com>
parents 052888f0 312185cf
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -373,6 +373,10 @@ int s390_ipl_set_loadparm(uint8_t *loadparm)
            loadparm[i] = ascii2ebcdic[(uint8_t) lp[i]];
        }

        if (i < 8) {
            memset(loadparm + i, 0x40, 8 - i); /* fill with EBCDIC spaces */
        }

        g_free(lp);
        return 0;
    }
+3.95 KiB (33.8 KiB)

File changed.

No diff preview for this file type.

+3 −1
Original line number Diff line number Diff line
@@ -9,7 +9,9 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)

.PHONY : all clean build-all

OBJECTS = start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-blkdev.o libc.o menu.o
OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o

QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
QEMU_CFLAGS += -march=z900 -fPIE -fno-strict-aliasing
+10 −69
Original line number Diff line number Diff line
@@ -29,14 +29,6 @@
/* Scratch space */
static uint8_t sec[MAX_SECTOR_SIZE*4] __attribute__((__aligned__(PAGE_SIZE)));

typedef struct ResetInfo {
    uint32_t ipl_mask;
    uint32_t ipl_addr;
    uint32_t ipl_continue;
} ResetInfo;

static ResetInfo save;

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

@@ -57,53 +49,6 @@ static inline bool is_iso_vd_valid(IsoVolDesc *vd)
           vd->type <= VOL_DESC_TYPE_PARTITION;
}

static void jump_to_IPL_2(void)
{
    ResetInfo *current = 0;

    void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue;
    *current = save;
    ipl(); /* should not return */
}

static void jump_to_IPL_code(uint64_t address)
{
    /* store the subsystem information _after_ the bootmap was loaded */
    write_subsystem_identification();

    /* prevent unknown IPL types in the guest */
    if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
        iplb.pbt = S390_IPL_TYPE_CCW;
        set_iplb(&iplb);
    }

    /*
     * The IPL PSW is at address 0. We also must not overwrite the
     * content of non-BIOS memory after we loaded the guest, so we
     * save the original content and restore it in jump_to_IPL_2.
     */
    ResetInfo *current = 0;

    save = *current;
    current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2;
    current->ipl_continue = address & 0x7fffffff;

    debug_print_int("set IPL addr to", current->ipl_continue);

    /* Ensure the guest output starts fresh */
    sclp_print("\n");

    /*
     * HACK ALERT.
     * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2
     * can then use r15 as its stack pointer.
     */
    asm volatile("lghi 1,1\n\t"
                 "diag 1,1,0x308\n\t"
                 : : : "1", "memory");
    panic("\n! IPL returns !\n");
}

/***********************************************************************
 * IPL an ECKD DASD (CDL or LDL/CMS format)
 */
@@ -297,7 +242,7 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr,
    }

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

    memset(sec, FREE_SPACE_FILLER, sizeof(sec));
@@ -565,6 +510,8 @@ static void ipl_scsi(void)
    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));
@@ -585,22 +532,22 @@ static void ipl_scsi(void)
    read_block(mbr->pt.blockno, sec, "Error reading Program Table");
    IPL_assert(magic_match(sec, ZIPL_MAGIC), "No zIPL magic in PT");

    while (program_table_entries <= MAX_TABLE_ENTRIES) {
        if (!prog_table->entry[program_table_entries].scsi.blockno) {
            break;
        }
    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(program_table_entries);
        loadparm = menu_get_enum_boot_index(valid_entries);
    }

    debug_print_int("loadparm", loadparm);
    IPL_assert(loadparm <= MAX_TABLE_ENTRIES, "loadparm value greater than"
    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 */
@@ -727,13 +674,7 @@ static void load_iso_bc_entry(IsoBcSection *load)
                        (void *)((uint64_t)bswap16(s.load_segment)),
                        blks_to_load);

    /* Trying to get PSW at zero address */
    if (*((uint64_t *)0) & IPL_PSW_MASK) {
        jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
    }

    /* Try default linux start address */
    jump_to_IPL_code(KERN_IMAGE_START);
    jump_to_low_kernel();
}

static uint32_t find_iso_bc(void)
+0 −6
Original line number Diff line number Diff line
@@ -57,8 +57,6 @@ typedef union BootMapPointer {
    ExtEckdBlockPtr xeckd;
} __attribute__ ((packed)) BootMapPointer;

#define MAX_TABLE_ENTRIES  30

/* aka Program Table */
typedef struct BootMapTable {
    uint8_t magic[4];
@@ -355,10 +353,6 @@ static inline uint32_t iso_733_to_u32(uint64_t x)
#define ISO_SECTOR_SIZE 2048
/* El Torito specifies boot image size in 512 byte blocks */
#define ET_SECTOR_SHIFT 2
#define KERN_IMAGE_START 0x010000UL
#define PSW_MASK_64 0x0000000100000000ULL
#define PSW_MASK_32 0x0000000080000000ULL
#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)

#define ISO_PRIMARY_VD_SECTOR 16

Loading