From patchwork Thu Jun 26 14:30:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Freimann X-Patchwork-Id: 364566 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3BB4D1400F0 for ; Fri, 27 Jun 2014 00:35:06 +1000 (EST) Received: from localhost ([::1]:45008 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0AlU-0004yl-DN for incoming@patchwork.ozlabs.org; Thu, 26 Jun 2014 10:35:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50225) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0AhD-0006bB-9z for qemu-devel@nongnu.org; Thu, 26 Jun 2014 10:30:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X0Ah2-0001lx-4y for qemu-devel@nongnu.org; Thu, 26 Jun 2014 10:30:39 -0400 Received: from e06smtp14.uk.ibm.com ([195.75.94.110]:42939) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0Ah1-0001la-S8 for qemu-devel@nongnu.org; Thu, 26 Jun 2014 10:30:28 -0400 Received: from /spool/local by e06smtp14.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 26 Jun 2014 15:30:25 +0100 Received: from d06dlp03.portsmouth.uk.ibm.com (9.149.20.15) by e06smtp14.uk.ibm.com (192.168.101.144) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 26 Jun 2014 15:30:24 +0100 Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id D82A61B0805F for ; Thu, 26 Jun 2014 15:30:56 +0100 (BST) Received: from d06av07.portsmouth.uk.ibm.com (d06av07.portsmouth.uk.ibm.com [9.149.37.248]) by b06cxnps4075.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s5QEUOkD34013292 for ; Thu, 26 Jun 2014 14:30:24 GMT Received: from d06av07.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s5QEUNOs005698 for ; Thu, 26 Jun 2014 10:30:24 -0400 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s5QEUNTf005689; Thu, 26 Jun 2014 10:30:23 -0400 Received: by tuxmaker.boeblingen.de.ibm.com (Postfix, from userid 1122) id 87F931224439; Thu, 26 Jun 2014 16:30:23 +0200 (CEST) From: Jens Freimann To: Christian Borntraeger , Alexander Graf , Cornelia Huck Date: Thu, 26 Jun 2014 16:30:08 +0200 Message-Id: <1403793009-54176-10-git-send-email-jfrei@linux.vnet.ibm.com> X-Mailer: git-send-email 1.8.5.5 In-Reply-To: <1403793009-54176-1-git-send-email-jfrei@linux.vnet.ibm.com> References: <1403793009-54176-1-git-send-email-jfrei@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14062614-1948-0000-0000-0000005609C7 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.75.94.110 Cc: "Eugene \(jno\) Dvurechenski" , Jens Freimann , qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 09/10] pc-bios/s390-ccw: IPL from LDL/CMS-formatted ECKD DASD X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: "Eugene (jno) Dvurechenski" Add code that allows us to start from two further ECKD DASD disk layouts: LDL (Linux disk layout) and CMS (cms-formatted disk). Signed-off-by: Eugene (jno) Dvurechenski Signed-off-by: Jens Freimann --- pc-bios/s390-ccw/bootmap.c | 92 ++++++++++++++++++++++++++++++++++++++++++---- pc-bios/s390-ccw/bootmap.h | 7 ++++ 2 files changed, 92 insertions(+), 7 deletions(-) diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c index 6f73ffc..30088f2 100644 --- a/pc-bios/s390-ccw/bootmap.c +++ b/pc-bios/s390-ccw/bootmap.c @@ -80,6 +80,17 @@ static void jump_to_IPL_code(uint64_t address) static unsigned char _bprs[8*1024]; /* guessed "max" ECKD sector size */ const int max_bprs_entries = sizeof(_bprs) / sizeof(ExtEckdBlockPtr); +static inline void verify_boot_info(BootInfo *bip) +{ + IPL_assert(magic_match(bip->magic, ZIPL_MAGIC), "No zIPL magic"); + 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 bool eckd_valid_address(BootMapPointer *p) { const uint64_t cylinder = p->eckd.cylinder @@ -198,19 +209,15 @@ static void run_eckd_boot_script(block_number_t mbr_block_nr) jump_to_IPL_code(bms->entry[i].address.load_address); /* no return */ } -static void ipl_eckd(void) +static void ipl_eckd_cdl(void) { XEckdMbr *mbr; Ipl2 *ipl2 = (void *)sec; IplVolumeLabel *vlbl = (void *)sec; block_number_t block_nr; - sclp_print("Using ECKD scheme.\n"); - if (virtio_guessed_disk_nature()) { - sclp_print("Using guessed DASD geometry.\n"); - virtio_assume_eckd(); - } /* 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"); @@ -238,6 +245,57 @@ static void ipl_eckd(void) /* no return */ } +static void ipl_eckd_ldl(ECKD_IPL_mode_t mode) +{ + LDL_VTOC *vlbl = (void *)sec; /* already read, 3rd block */ + char msg[4] = { '?', '.', '\n', '\0' }; + block_number_t block_nr; + BootInfo *bip; + + 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); + + /* 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"); + bip = (void *)(sec + 0x70); /* "boot info" is "eckd mbr" for LDL */ + verify_boot_info(bip); + + block_nr = eckd_block_num((void *)&(bip->bp.ipl.bm_ptr.eckd.bptr)); + run_eckd_boot_script(block_nr); + /* no return */ +} + +static void ipl_eckd(ECKD_IPL_mode_t mode) +{ + switch (mode) { + case ECKD_CDL: + ipl_eckd_cdl(); /* no return */ + case ECKD_CMS: + case ECKD_LDL: + ipl_eckd_ldl(mode); /* no return */ + default: + virtio_panic("\n! Unknown ECKD IPL mode !\n"); + } +} + /*********************************************************************** * IPL a SCSI disk */ @@ -374,6 +432,7 @@ static void ipl_scsi(void) void zipl_load(void) { ScsiMbr *mbr = (void *)sec; + LDL_VTOC *vlbl = (void *)sec; /* Grab the MBR */ memset(sec, FREE_SPACE_FILLER, sizeof(sec)); @@ -384,8 +443,27 @@ void zipl_load(void) if (magic_match(mbr->magic, ZIPL_MAGIC)) { ipl_scsi(); /* no return */ } + + /* We have failed to follow the SCSI scheme, so */ + sclp_print("Using ECKD scheme.\n"); + if (virtio_guessed_disk_nature()) { + sclp_print("Using guessed DASD geometry.\n"); + virtio_assume_eckd(); + } + if (magic_match(mbr->magic, IPL1_MAGIC)) { - ipl_eckd(); /* CDL ECKD; no return */ + ipl_eckd(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(ECKD_CMS); /* no return */ + } + if (magic_match(vlbl->magic, LNX1_MAGIC)) { + ipl_eckd(ECKD_LDL); /* no return */ } virtio_panic("\n* invalid MBR magic *\n"); diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h index 1846632..30ef22f 100644 --- a/pc-bios/s390-ccw/bootmap.h +++ b/pc-bios/s390-ccw/bootmap.h @@ -255,6 +255,13 @@ typedef struct IplVolumeLabel { }; } __attribute__((packed)) IplVolumeLabel; +typedef enum { + ECKD_NO_IPL, + ECKD_CDL, + ECKD_CMS, + ECKD_LDL, +} ECKD_IPL_mode_t; + /* utility code below */ static inline void IPL_assert(bool term, const char *message)