1*26f2bbd6SEugene (jno) Dvurechenski /* 2*26f2bbd6SEugene (jno) Dvurechenski * QEMU S390 bootmap interpreter -- declarations 3*26f2bbd6SEugene (jno) Dvurechenski * 4*26f2bbd6SEugene (jno) Dvurechenski * Copyright 2014 IBM Corp. 5*26f2bbd6SEugene (jno) Dvurechenski * Author(s): Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com> 6*26f2bbd6SEugene (jno) Dvurechenski * 7*26f2bbd6SEugene (jno) Dvurechenski * This work is licensed under the terms of the GNU GPL, version 2 or (at 8*26f2bbd6SEugene (jno) Dvurechenski * your option) any later version. See the COPYING file in the top-level 9*26f2bbd6SEugene (jno) Dvurechenski * directory. 10*26f2bbd6SEugene (jno) Dvurechenski */ 11*26f2bbd6SEugene (jno) Dvurechenski #ifndef _PC_BIOS_S390_CCW_BOOTMAP_H 12*26f2bbd6SEugene (jno) Dvurechenski #define _PC_BIOS_S390_CCW_BOOTMAP_H 13*26f2bbd6SEugene (jno) Dvurechenski 14*26f2bbd6SEugene (jno) Dvurechenski #include "s390-ccw.h" 15*26f2bbd6SEugene (jno) Dvurechenski 16*26f2bbd6SEugene (jno) Dvurechenski #define FREE_SPACE_FILLER '\xAA' 17*26f2bbd6SEugene (jno) Dvurechenski 18*26f2bbd6SEugene (jno) Dvurechenski typedef struct ScsiBlockPtr { 19*26f2bbd6SEugene (jno) Dvurechenski uint64_t blockno; 20*26f2bbd6SEugene (jno) Dvurechenski uint16_t size; 21*26f2bbd6SEugene (jno) Dvurechenski uint16_t blockct; 22*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved[4]; 23*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) ScsiBlockPtr; 24*26f2bbd6SEugene (jno) Dvurechenski 25*26f2bbd6SEugene (jno) Dvurechenski typedef struct FbaBlockPtr { 26*26f2bbd6SEugene (jno) Dvurechenski uint32_t blockno; 27*26f2bbd6SEugene (jno) Dvurechenski uint16_t size; 28*26f2bbd6SEugene (jno) Dvurechenski uint16_t blockct; 29*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) FbaBlockPtr; 30*26f2bbd6SEugene (jno) Dvurechenski 31*26f2bbd6SEugene (jno) Dvurechenski typedef struct EckdBlockPtr { 32*26f2bbd6SEugene (jno) Dvurechenski uint16_t cylinder; /* cylinder/head/sector is an address of the block */ 33*26f2bbd6SEugene (jno) Dvurechenski uint16_t head; 34*26f2bbd6SEugene (jno) Dvurechenski uint8_t sector; 35*26f2bbd6SEugene (jno) Dvurechenski uint16_t size; 36*26f2bbd6SEugene (jno) Dvurechenski uint8_t count; /* (size_in_blocks-1); 37*26f2bbd6SEugene (jno) Dvurechenski * it's 0 for TablePtr, ScriptPtr, and SectionPtr */ 38*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) EckdBlockPtr; 39*26f2bbd6SEugene (jno) Dvurechenski 40*26f2bbd6SEugene (jno) Dvurechenski typedef struct ExtEckdBlockPtr { 41*26f2bbd6SEugene (jno) Dvurechenski EckdBlockPtr bptr; 42*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved[8]; 43*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) ExtEckdBlockPtr; 44*26f2bbd6SEugene (jno) Dvurechenski 45*26f2bbd6SEugene (jno) Dvurechenski typedef union BootMapPointer { 46*26f2bbd6SEugene (jno) Dvurechenski ScsiBlockPtr scsi; 47*26f2bbd6SEugene (jno) Dvurechenski FbaBlockPtr fba; 48*26f2bbd6SEugene (jno) Dvurechenski EckdBlockPtr eckd; 49*26f2bbd6SEugene (jno) Dvurechenski ExtEckdBlockPtr xeckd; 50*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootMapPointer; 51*26f2bbd6SEugene (jno) Dvurechenski 52*26f2bbd6SEugene (jno) Dvurechenski typedef struct ComponentEntry { 53*26f2bbd6SEugene (jno) Dvurechenski ScsiBlockPtr data; 54*26f2bbd6SEugene (jno) Dvurechenski uint8_t pad[7]; 55*26f2bbd6SEugene (jno) Dvurechenski uint8_t component_type; 56*26f2bbd6SEugene (jno) Dvurechenski uint64_t load_address; 57*26f2bbd6SEugene (jno) Dvurechenski } __attribute((packed)) ComponentEntry; 58*26f2bbd6SEugene (jno) Dvurechenski 59*26f2bbd6SEugene (jno) Dvurechenski typedef struct ComponentHeader { 60*26f2bbd6SEugene (jno) Dvurechenski uint8_t magic[4]; /* == "zIPL" */ 61*26f2bbd6SEugene (jno) Dvurechenski uint8_t type; /* == ZIPL_COMP_HEADER_* */ 62*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved[27]; 63*26f2bbd6SEugene (jno) Dvurechenski } __attribute((packed)) ComponentHeader; 64*26f2bbd6SEugene (jno) Dvurechenski 65*26f2bbd6SEugene (jno) Dvurechenski typedef struct ScsiMbr { 66*26f2bbd6SEugene (jno) Dvurechenski uint8_t magic[4]; 67*26f2bbd6SEugene (jno) Dvurechenski uint32_t version_id; 68*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved[8]; 69*26f2bbd6SEugene (jno) Dvurechenski ScsiBlockPtr blockptr; 70*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) ScsiMbr; 71*26f2bbd6SEugene (jno) Dvurechenski 72*26f2bbd6SEugene (jno) Dvurechenski #define ZIPL_MAGIC "zIPL" 73*26f2bbd6SEugene (jno) Dvurechenski #define IPL1_MAGIC "\xc9\xd7\xd3\xf1" /* == "IPL1" in EBCDIC */ 74*26f2bbd6SEugene (jno) Dvurechenski #define IPL2_MAGIC "\xc9\xd7\xd3\xf2" /* == "IPL2" in EBCDIC */ 75*26f2bbd6SEugene (jno) Dvurechenski #define VOL1_MAGIC "\xe5\xd6\xd3\xf1" /* == "VOL1" in EBCDIC */ 76*26f2bbd6SEugene (jno) Dvurechenski #define LNX1_MAGIC "\xd3\xd5\xe7\xf1" /* == "LNX1" in EBCDIC */ 77*26f2bbd6SEugene (jno) Dvurechenski #define CMS1_MAGIC "\xc3\xd4\xe2\xf1" /* == "CMS1" in EBCDIC */ 78*26f2bbd6SEugene (jno) Dvurechenski 79*26f2bbd6SEugene (jno) Dvurechenski #define LDL1_VERSION '\x40' /* == ' ' in EBCDIC */ 80*26f2bbd6SEugene (jno) Dvurechenski #define LDL2_VERSION '\xf2' /* == '2' in EBCDIC */ 81*26f2bbd6SEugene (jno) Dvurechenski 82*26f2bbd6SEugene (jno) Dvurechenski #define ZIPL_COMP_HEADER_IPL 0x00 83*26f2bbd6SEugene (jno) Dvurechenski #define ZIPL_COMP_HEADER_DUMP 0x01 84*26f2bbd6SEugene (jno) Dvurechenski 85*26f2bbd6SEugene (jno) Dvurechenski #define ZIPL_COMP_ENTRY_LOAD 0x02 86*26f2bbd6SEugene (jno) Dvurechenski #define ZIPL_COMP_ENTRY_EXEC 0x01 87*26f2bbd6SEugene (jno) Dvurechenski 88*26f2bbd6SEugene (jno) Dvurechenski typedef struct XEckdMbr { 89*26f2bbd6SEugene (jno) Dvurechenski uint8_t magic[4]; /* == "xIPL" */ 90*26f2bbd6SEugene (jno) Dvurechenski uint8_t version; 91*26f2bbd6SEugene (jno) Dvurechenski uint8_t bp_type; 92*26f2bbd6SEugene (jno) Dvurechenski uint8_t dev_type; /* == DEV_TYPE_* */ 93*26f2bbd6SEugene (jno) Dvurechenski #define DEV_TYPE_ECKD 0x00 94*26f2bbd6SEugene (jno) Dvurechenski #define DEV_TYPE_FBA 0x01 95*26f2bbd6SEugene (jno) Dvurechenski uint8_t flags; 96*26f2bbd6SEugene (jno) Dvurechenski BootMapPointer blockptr; 97*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved[8]; 98*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) XEckdMbr; /* see also BootInfo */ 99*26f2bbd6SEugene (jno) Dvurechenski 100*26f2bbd6SEugene (jno) Dvurechenski typedef struct BootMapScriptEntry { 101*26f2bbd6SEugene (jno) Dvurechenski BootMapPointer blkptr; 102*26f2bbd6SEugene (jno) Dvurechenski uint8_t pad[7]; 103*26f2bbd6SEugene (jno) Dvurechenski uint8_t type; /* == BOOT_SCRIPT_* */ 104*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_SCRIPT_EXEC 0x01 105*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_SCRIPT_LOAD 0x02 106*26f2bbd6SEugene (jno) Dvurechenski union { 107*26f2bbd6SEugene (jno) Dvurechenski uint64_t load_address; 108*26f2bbd6SEugene (jno) Dvurechenski uint64_t load_psw; 109*26f2bbd6SEugene (jno) Dvurechenski } address; 110*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootMapScriptEntry; 111*26f2bbd6SEugene (jno) Dvurechenski 112*26f2bbd6SEugene (jno) Dvurechenski typedef struct BootMapScriptHeader { 113*26f2bbd6SEugene (jno) Dvurechenski uint32_t magic; 114*26f2bbd6SEugene (jno) Dvurechenski uint8_t type; 115*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_SCRIPT_HDR_IPL 0x00 116*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved[27]; 117*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootMapScriptHeader; 118*26f2bbd6SEugene (jno) Dvurechenski 119*26f2bbd6SEugene (jno) Dvurechenski typedef struct BootMapScript { 120*26f2bbd6SEugene (jno) Dvurechenski BootMapScriptHeader header; 121*26f2bbd6SEugene (jno) Dvurechenski BootMapScriptEntry entry[0]; 122*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootMapScript; 123*26f2bbd6SEugene (jno) Dvurechenski 124*26f2bbd6SEugene (jno) Dvurechenski /* 125*26f2bbd6SEugene (jno) Dvurechenski * These aren't real VTOCs, but referred to this way in some docs. 126*26f2bbd6SEugene (jno) Dvurechenski * They are "volume labels" actually. 127*26f2bbd6SEugene (jno) Dvurechenski * 128*26f2bbd6SEugene (jno) Dvurechenski * Some structures looks similar to described above, but left 129*26f2bbd6SEugene (jno) Dvurechenski * separate as there is no indication that they are the same. 130*26f2bbd6SEugene (jno) Dvurechenski * So, the value definitions are left separate too. 131*26f2bbd6SEugene (jno) Dvurechenski */ 132*26f2bbd6SEugene (jno) Dvurechenski typedef struct LDL_VTOC { /* @ rec.3 cyl.0 trk.0 for ECKD */ 133*26f2bbd6SEugene (jno) Dvurechenski char magic[4]; /* "LNX1", EBCDIC */ 134*26f2bbd6SEugene (jno) Dvurechenski char volser[6]; /* volser, EBCDIC */ 135*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved[69]; /* reserved, 0x40 */ 136*26f2bbd6SEugene (jno) Dvurechenski uint8_t LDL_version; /* 0x40 or 0xF2 */ 137*26f2bbd6SEugene (jno) Dvurechenski uint64_t formatted_blocks; /* if LDL_version >= 0xF2 */ 138*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) LDL_VTOC; 139*26f2bbd6SEugene (jno) Dvurechenski 140*26f2bbd6SEugene (jno) Dvurechenski typedef struct format_date { 141*26f2bbd6SEugene (jno) Dvurechenski uint8_t YY; 142*26f2bbd6SEugene (jno) Dvurechenski uint8_t MM; 143*26f2bbd6SEugene (jno) Dvurechenski uint8_t DD; 144*26f2bbd6SEugene (jno) Dvurechenski uint8_t hh; 145*26f2bbd6SEugene (jno) Dvurechenski uint8_t mm; 146*26f2bbd6SEugene (jno) Dvurechenski uint8_t ss; 147*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) format_date_t; 148*26f2bbd6SEugene (jno) Dvurechenski 149*26f2bbd6SEugene (jno) Dvurechenski typedef struct CMS_VTOC { /* @ rec.3 cyl.0 trk.0 for ECKD */ 150*26f2bbd6SEugene (jno) Dvurechenski /* @ blk.1 (zero based) for FBA */ 151*26f2bbd6SEugene (jno) Dvurechenski char magic[4]; /* 'CMS1', EBCDIC */ 152*26f2bbd6SEugene (jno) Dvurechenski char volser[6]; /* volser, EBCDIC */ 153*26f2bbd6SEugene (jno) Dvurechenski uint16_t version; /* = 0 */ 154*26f2bbd6SEugene (jno) Dvurechenski uint32_t block_size; /* = 512, 1024, 2048, or 4096 */ 155*26f2bbd6SEugene (jno) Dvurechenski uint32_t disk_origin; /* = 4 or 5 */ 156*26f2bbd6SEugene (jno) Dvurechenski uint32_t blocks; /* Number of usable cyls/blocks */ 157*26f2bbd6SEugene (jno) Dvurechenski uint32_t formatted; /* Max number of fmtd cyls/blks */ 158*26f2bbd6SEugene (jno) Dvurechenski uint32_t CMS_blocks; /* disk size in CMS blocks */ 159*26f2bbd6SEugene (jno) Dvurechenski uint32_t CMS_used; /* Number of CMS blocks in use */ 160*26f2bbd6SEugene (jno) Dvurechenski uint32_t FST_size; /* = 64, bytes */ 161*26f2bbd6SEugene (jno) Dvurechenski uint32_t FST_per_CMS_blk; /* */ 162*26f2bbd6SEugene (jno) Dvurechenski format_date_t format_date; /* YYMMDDhhmmss as 6 bytes */ 163*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved1[2]; /* = 0 */ 164*26f2bbd6SEugene (jno) Dvurechenski uint32_t offset; /* disk offset when reserved */ 165*26f2bbd6SEugene (jno) Dvurechenski uint32_t next_hole; /* block nr */ 166*26f2bbd6SEugene (jno) Dvurechenski uint32_t HBLK_hole_offset; /* >> HBLK data of next hole */ 167*26f2bbd6SEugene (jno) Dvurechenski uint32_t alloc_map_usr_off; /* >> user part of Alloc map */ 168*26f2bbd6SEugene (jno) Dvurechenski uint8_t reserved2[4]; /* = 0 */ 169*26f2bbd6SEugene (jno) Dvurechenski char shared_seg_name[8]; /* */ 170*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) CMS_VTOC; 171*26f2bbd6SEugene (jno) Dvurechenski 172*26f2bbd6SEugene (jno) Dvurechenski /* from zipl/include/boot.h */ 173*26f2bbd6SEugene (jno) Dvurechenski typedef struct BootInfoBpIpl { 174*26f2bbd6SEugene (jno) Dvurechenski union { 175*26f2bbd6SEugene (jno) Dvurechenski ExtEckdBlockPtr eckd; 176*26f2bbd6SEugene (jno) Dvurechenski ScsiBlockPtr linr; 177*26f2bbd6SEugene (jno) Dvurechenski } bm_ptr; 178*26f2bbd6SEugene (jno) Dvurechenski uint8_t unused[16]; 179*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootInfoBpIpl; 180*26f2bbd6SEugene (jno) Dvurechenski 181*26f2bbd6SEugene (jno) Dvurechenski typedef struct EckdDumpParam { 182*26f2bbd6SEugene (jno) Dvurechenski uint32_t start_blk; 183*26f2bbd6SEugene (jno) Dvurechenski uint32_t end_blk; 184*26f2bbd6SEugene (jno) Dvurechenski uint16_t blocksize; 185*26f2bbd6SEugene (jno) Dvurechenski uint8_t num_heads; 186*26f2bbd6SEugene (jno) Dvurechenski uint8_t bpt; 187*26f2bbd6SEugene (jno) Dvurechenski char reserved[4]; 188*26f2bbd6SEugene (jno) Dvurechenski } __attribute((packed, may_alias)) EckdDumpParam; 189*26f2bbd6SEugene (jno) Dvurechenski 190*26f2bbd6SEugene (jno) Dvurechenski typedef struct FbaDumpParam { 191*26f2bbd6SEugene (jno) Dvurechenski uint64_t start_blk; 192*26f2bbd6SEugene (jno) Dvurechenski uint64_t blockct; 193*26f2bbd6SEugene (jno) Dvurechenski } __attribute((packed)) FbaDumpParam; 194*26f2bbd6SEugene (jno) Dvurechenski 195*26f2bbd6SEugene (jno) Dvurechenski typedef struct BootInfoBpDump { 196*26f2bbd6SEugene (jno) Dvurechenski union { 197*26f2bbd6SEugene (jno) Dvurechenski EckdDumpParam eckd; 198*26f2bbd6SEugene (jno) Dvurechenski FbaDumpParam fba; 199*26f2bbd6SEugene (jno) Dvurechenski } param; 200*26f2bbd6SEugene (jno) Dvurechenski uint8_t unused[16]; 201*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootInfoBpDump; 202*26f2bbd6SEugene (jno) Dvurechenski 203*26f2bbd6SEugene (jno) Dvurechenski typedef struct BootInfo { /* @ 0x70, record #0 */ 204*26f2bbd6SEugene (jno) Dvurechenski unsigned char magic[4]; /* = 'zIPL', ASCII */ 205*26f2bbd6SEugene (jno) Dvurechenski uint8_t version; /* = 1 */ 206*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_VERSION 1 207*26f2bbd6SEugene (jno) Dvurechenski uint8_t bp_type; /* = 0 */ 208*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_BP_TYPE_IPL 0x00 209*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_BP_TYPE_DUMP 0x01 210*26f2bbd6SEugene (jno) Dvurechenski uint8_t dev_type; /* = 0 */ 211*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_DEV_TYPE_ECKD 0x00 212*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_DEV_TYPE_FBA 0x01 213*26f2bbd6SEugene (jno) Dvurechenski uint8_t flags; /* = 1 */ 214*26f2bbd6SEugene (jno) Dvurechenski #ifdef __s390x__ 215*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_FLAGS_ARCH 0x01 216*26f2bbd6SEugene (jno) Dvurechenski #else 217*26f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_FLAGS_ARCH 0x00 218*26f2bbd6SEugene (jno) Dvurechenski #endif 219*26f2bbd6SEugene (jno) Dvurechenski union { 220*26f2bbd6SEugene (jno) Dvurechenski BootInfoBpDump dump; 221*26f2bbd6SEugene (jno) Dvurechenski BootInfoBpIpl ipl; 222*26f2bbd6SEugene (jno) Dvurechenski } bp; 223*26f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootInfo; /* see also XEckdMbr */ 224*26f2bbd6SEugene (jno) Dvurechenski 225*26f2bbd6SEugene (jno) Dvurechenski typedef struct Ipl1 { 226*26f2bbd6SEugene (jno) Dvurechenski unsigned char key[4]; /* == "IPL1" */ 227*26f2bbd6SEugene (jno) Dvurechenski unsigned char data[24]; 228*26f2bbd6SEugene (jno) Dvurechenski } __attribute__((packed)) Ipl1; 229*26f2bbd6SEugene (jno) Dvurechenski 230*26f2bbd6SEugene (jno) Dvurechenski typedef struct Ipl2 { 231*26f2bbd6SEugene (jno) Dvurechenski unsigned char key[4]; /* == "IPL2" */ 232*26f2bbd6SEugene (jno) Dvurechenski union { 233*26f2bbd6SEugene (jno) Dvurechenski unsigned char data[144]; 234*26f2bbd6SEugene (jno) Dvurechenski struct { 235*26f2bbd6SEugene (jno) Dvurechenski unsigned char reserved1[92-4]; 236*26f2bbd6SEugene (jno) Dvurechenski XEckdMbr mbr; 237*26f2bbd6SEugene (jno) Dvurechenski unsigned char reserved2[144-(92-4)-sizeof(XEckdMbr)]; 238*26f2bbd6SEugene (jno) Dvurechenski } x; 239*26f2bbd6SEugene (jno) Dvurechenski } u; 240*26f2bbd6SEugene (jno) Dvurechenski } __attribute__((packed)) Ipl2; 241*26f2bbd6SEugene (jno) Dvurechenski 242*26f2bbd6SEugene (jno) Dvurechenski typedef struct IplVolumeLabel { 243*26f2bbd6SEugene (jno) Dvurechenski unsigned char key[4]; /* == "VOL1" */ 244*26f2bbd6SEugene (jno) Dvurechenski union { 245*26f2bbd6SEugene (jno) Dvurechenski unsigned char data[80]; 246*26f2bbd6SEugene (jno) Dvurechenski struct { 247*26f2bbd6SEugene (jno) Dvurechenski unsigned char key[4]; /* == "VOL1" */ 248*26f2bbd6SEugene (jno) Dvurechenski unsigned char volser[6]; 249*26f2bbd6SEugene (jno) Dvurechenski unsigned char reserved[6]; 250*26f2bbd6SEugene (jno) Dvurechenski } f; 251*26f2bbd6SEugene (jno) Dvurechenski }; 252*26f2bbd6SEugene (jno) Dvurechenski } __attribute__((packed)) IplVolumeLabel; 253*26f2bbd6SEugene (jno) Dvurechenski 254*26f2bbd6SEugene (jno) Dvurechenski #endif /* _PC_BIOS_S390_CCW_BOOTMAP_H */ 255