xref: /openbmc/qemu/pc-bios/s390-ccw/bootmap.h (revision a94b485e17dab77d96a8b958305e485c3b9a7a91)
126f2bbd6SEugene (jno) Dvurechenski /*
226f2bbd6SEugene (jno) Dvurechenski  * QEMU S390 bootmap interpreter -- declarations
326f2bbd6SEugene (jno) Dvurechenski  *
426f2bbd6SEugene (jno) Dvurechenski  * Copyright 2014 IBM Corp.
526f2bbd6SEugene (jno) Dvurechenski  * Author(s): Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com>
626f2bbd6SEugene (jno) Dvurechenski  *
726f2bbd6SEugene (jno) Dvurechenski  * This work is licensed under the terms of the GNU GPL, version 2 or (at
826f2bbd6SEugene (jno) Dvurechenski  * your option) any later version. See the COPYING file in the top-level
926f2bbd6SEugene (jno) Dvurechenski  * directory.
1026f2bbd6SEugene (jno) Dvurechenski  */
1126f2bbd6SEugene (jno) Dvurechenski #ifndef _PC_BIOS_S390_CCW_BOOTMAP_H
1226f2bbd6SEugene (jno) Dvurechenski #define _PC_BIOS_S390_CCW_BOOTMAP_H
1326f2bbd6SEugene (jno) Dvurechenski 
1426f2bbd6SEugene (jno) Dvurechenski #include "s390-ccw.h"
15*a94b485eSEugene (jno) Dvurechenski #include "virtio.h"
16*a94b485eSEugene (jno) Dvurechenski 
17*a94b485eSEugene (jno) Dvurechenski typedef uint64_t block_number_t;
18*a94b485eSEugene (jno) Dvurechenski #define NULL_BLOCK_NR 0xffffffffffffffff
1926f2bbd6SEugene (jno) Dvurechenski 
2026f2bbd6SEugene (jno) Dvurechenski #define FREE_SPACE_FILLER '\xAA'
2126f2bbd6SEugene (jno) Dvurechenski 
2226f2bbd6SEugene (jno) Dvurechenski typedef struct ScsiBlockPtr {
2326f2bbd6SEugene (jno) Dvurechenski     uint64_t blockno;
2426f2bbd6SEugene (jno) Dvurechenski     uint16_t size;
2526f2bbd6SEugene (jno) Dvurechenski     uint16_t blockct;
2626f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved[4];
2726f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) ScsiBlockPtr;
2826f2bbd6SEugene (jno) Dvurechenski 
2926f2bbd6SEugene (jno) Dvurechenski typedef struct FbaBlockPtr {
3026f2bbd6SEugene (jno) Dvurechenski     uint32_t blockno;
3126f2bbd6SEugene (jno) Dvurechenski     uint16_t size;
3226f2bbd6SEugene (jno) Dvurechenski     uint16_t blockct;
3326f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) FbaBlockPtr;
3426f2bbd6SEugene (jno) Dvurechenski 
3526f2bbd6SEugene (jno) Dvurechenski typedef struct EckdBlockPtr {
3626f2bbd6SEugene (jno) Dvurechenski     uint16_t cylinder; /* cylinder/head/sector is an address of the block */
3726f2bbd6SEugene (jno) Dvurechenski     uint16_t head;
3826f2bbd6SEugene (jno) Dvurechenski     uint8_t sector;
3926f2bbd6SEugene (jno) Dvurechenski     uint16_t size;
4026f2bbd6SEugene (jno) Dvurechenski     uint8_t count; /* (size_in_blocks-1);
4126f2bbd6SEugene (jno) Dvurechenski                     * it's 0 for TablePtr, ScriptPtr, and SectionPtr */
4226f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) EckdBlockPtr;
4326f2bbd6SEugene (jno) Dvurechenski 
4426f2bbd6SEugene (jno) Dvurechenski typedef struct ExtEckdBlockPtr {
4526f2bbd6SEugene (jno) Dvurechenski     EckdBlockPtr bptr;
4626f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved[8];
4726f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) ExtEckdBlockPtr;
4826f2bbd6SEugene (jno) Dvurechenski 
4926f2bbd6SEugene (jno) Dvurechenski typedef union BootMapPointer {
5026f2bbd6SEugene (jno) Dvurechenski     ScsiBlockPtr scsi;
5126f2bbd6SEugene (jno) Dvurechenski     FbaBlockPtr fba;
5226f2bbd6SEugene (jno) Dvurechenski     EckdBlockPtr eckd;
5326f2bbd6SEugene (jno) Dvurechenski     ExtEckdBlockPtr xeckd;
5426f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootMapPointer;
5526f2bbd6SEugene (jno) Dvurechenski 
5626f2bbd6SEugene (jno) Dvurechenski typedef struct ComponentEntry {
5726f2bbd6SEugene (jno) Dvurechenski     ScsiBlockPtr data;
5826f2bbd6SEugene (jno) Dvurechenski     uint8_t pad[7];
5926f2bbd6SEugene (jno) Dvurechenski     uint8_t component_type;
6026f2bbd6SEugene (jno) Dvurechenski     uint64_t load_address;
6126f2bbd6SEugene (jno) Dvurechenski } __attribute((packed)) ComponentEntry;
6226f2bbd6SEugene (jno) Dvurechenski 
6326f2bbd6SEugene (jno) Dvurechenski typedef struct ComponentHeader {
6426f2bbd6SEugene (jno) Dvurechenski     uint8_t magic[4];   /* == "zIPL"                    */
6526f2bbd6SEugene (jno) Dvurechenski     uint8_t type;       /* == ZIPL_COMP_HEADER_*        */
6626f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved[27];
6726f2bbd6SEugene (jno) Dvurechenski } __attribute((packed)) ComponentHeader;
6826f2bbd6SEugene (jno) Dvurechenski 
6926f2bbd6SEugene (jno) Dvurechenski typedef struct ScsiMbr {
7026f2bbd6SEugene (jno) Dvurechenski     uint8_t magic[4];
7126f2bbd6SEugene (jno) Dvurechenski     uint32_t version_id;
7226f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved[8];
7326f2bbd6SEugene (jno) Dvurechenski     ScsiBlockPtr blockptr;
7426f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) ScsiMbr;
7526f2bbd6SEugene (jno) Dvurechenski 
7626f2bbd6SEugene (jno) Dvurechenski #define ZIPL_MAGIC              "zIPL"
7726f2bbd6SEugene (jno) Dvurechenski #define IPL1_MAGIC "\xc9\xd7\xd3\xf1" /* == "IPL1" in EBCDIC */
7826f2bbd6SEugene (jno) Dvurechenski #define IPL2_MAGIC "\xc9\xd7\xd3\xf2" /* == "IPL2" in EBCDIC */
7926f2bbd6SEugene (jno) Dvurechenski #define VOL1_MAGIC "\xe5\xd6\xd3\xf1" /* == "VOL1" in EBCDIC */
8026f2bbd6SEugene (jno) Dvurechenski #define LNX1_MAGIC "\xd3\xd5\xe7\xf1" /* == "LNX1" in EBCDIC */
8126f2bbd6SEugene (jno) Dvurechenski #define CMS1_MAGIC "\xc3\xd4\xe2\xf1" /* == "CMS1" in EBCDIC */
8226f2bbd6SEugene (jno) Dvurechenski 
8326f2bbd6SEugene (jno) Dvurechenski #define LDL1_VERSION '\x40' /* == ' ' in EBCDIC */
8426f2bbd6SEugene (jno) Dvurechenski #define LDL2_VERSION '\xf2' /* == '2' in EBCDIC */
8526f2bbd6SEugene (jno) Dvurechenski 
8626f2bbd6SEugene (jno) Dvurechenski #define ZIPL_COMP_HEADER_IPL    0x00
8726f2bbd6SEugene (jno) Dvurechenski #define ZIPL_COMP_HEADER_DUMP   0x01
8826f2bbd6SEugene (jno) Dvurechenski 
8926f2bbd6SEugene (jno) Dvurechenski #define ZIPL_COMP_ENTRY_LOAD    0x02
9026f2bbd6SEugene (jno) Dvurechenski #define ZIPL_COMP_ENTRY_EXEC    0x01
9126f2bbd6SEugene (jno) Dvurechenski 
9226f2bbd6SEugene (jno) Dvurechenski typedef struct XEckdMbr {
9326f2bbd6SEugene (jno) Dvurechenski     uint8_t magic[4];   /* == "xIPL"        */
9426f2bbd6SEugene (jno) Dvurechenski     uint8_t version;
9526f2bbd6SEugene (jno) Dvurechenski     uint8_t bp_type;
9626f2bbd6SEugene (jno) Dvurechenski     uint8_t dev_type;   /* == DEV_TYPE_*    */
9726f2bbd6SEugene (jno) Dvurechenski #define DEV_TYPE_ECKD 0x00
9826f2bbd6SEugene (jno) Dvurechenski #define DEV_TYPE_FBA  0x01
9926f2bbd6SEugene (jno) Dvurechenski     uint8_t flags;
10026f2bbd6SEugene (jno) Dvurechenski     BootMapPointer blockptr;
10126f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved[8];
10226f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) XEckdMbr; /* see also BootInfo */
10326f2bbd6SEugene (jno) Dvurechenski 
10426f2bbd6SEugene (jno) Dvurechenski typedef struct BootMapScriptEntry {
10526f2bbd6SEugene (jno) Dvurechenski     BootMapPointer blkptr;
10626f2bbd6SEugene (jno) Dvurechenski     uint8_t pad[7];
10726f2bbd6SEugene (jno) Dvurechenski     uint8_t type;   /* == BOOT_SCRIPT_* */
10826f2bbd6SEugene (jno) Dvurechenski #define BOOT_SCRIPT_EXEC 0x01
10926f2bbd6SEugene (jno) Dvurechenski #define BOOT_SCRIPT_LOAD 0x02
11026f2bbd6SEugene (jno) Dvurechenski     union {
11126f2bbd6SEugene (jno) Dvurechenski         uint64_t load_address;
11226f2bbd6SEugene (jno) Dvurechenski         uint64_t load_psw;
11326f2bbd6SEugene (jno) Dvurechenski     } address;
11426f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootMapScriptEntry;
11526f2bbd6SEugene (jno) Dvurechenski 
11626f2bbd6SEugene (jno) Dvurechenski typedef struct BootMapScriptHeader {
11726f2bbd6SEugene (jno) Dvurechenski     uint32_t magic;
11826f2bbd6SEugene (jno) Dvurechenski     uint8_t type;
11926f2bbd6SEugene (jno) Dvurechenski #define BOOT_SCRIPT_HDR_IPL 0x00
12026f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved[27];
12126f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootMapScriptHeader;
12226f2bbd6SEugene (jno) Dvurechenski 
12326f2bbd6SEugene (jno) Dvurechenski typedef struct BootMapScript {
12426f2bbd6SEugene (jno) Dvurechenski     BootMapScriptHeader header;
12526f2bbd6SEugene (jno) Dvurechenski     BootMapScriptEntry  entry[0];
12626f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootMapScript;
12726f2bbd6SEugene (jno) Dvurechenski 
12826f2bbd6SEugene (jno) Dvurechenski /*
12926f2bbd6SEugene (jno) Dvurechenski  * These aren't real VTOCs, but referred to this way in some docs.
13026f2bbd6SEugene (jno) Dvurechenski  * They are "volume labels" actually.
13126f2bbd6SEugene (jno) Dvurechenski  *
13226f2bbd6SEugene (jno) Dvurechenski  * Some structures looks similar to described above, but left
13326f2bbd6SEugene (jno) Dvurechenski  * separate as there is no indication that they are the same.
13426f2bbd6SEugene (jno) Dvurechenski  * So, the value definitions are left separate too.
13526f2bbd6SEugene (jno) Dvurechenski  */
13626f2bbd6SEugene (jno) Dvurechenski typedef struct LDL_VTOC {       /* @ rec.3 cyl.0 trk.0 for ECKD */
13726f2bbd6SEugene (jno) Dvurechenski     char magic[4];              /* "LNX1", EBCDIC               */
13826f2bbd6SEugene (jno) Dvurechenski     char volser[6];             /* volser, EBCDIC               */
13926f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved[69];       /* reserved, 0x40               */
14026f2bbd6SEugene (jno) Dvurechenski     uint8_t LDL_version;        /* 0x40 or 0xF2                 */
14126f2bbd6SEugene (jno) Dvurechenski     uint64_t formatted_blocks;  /* if LDL_version >= 0xF2       */
14226f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) LDL_VTOC;
14326f2bbd6SEugene (jno) Dvurechenski 
14426f2bbd6SEugene (jno) Dvurechenski typedef struct format_date {
14526f2bbd6SEugene (jno) Dvurechenski     uint8_t YY;
14626f2bbd6SEugene (jno) Dvurechenski     uint8_t MM;
14726f2bbd6SEugene (jno) Dvurechenski     uint8_t DD;
14826f2bbd6SEugene (jno) Dvurechenski     uint8_t hh;
14926f2bbd6SEugene (jno) Dvurechenski     uint8_t mm;
15026f2bbd6SEugene (jno) Dvurechenski     uint8_t ss;
15126f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) format_date_t;
15226f2bbd6SEugene (jno) Dvurechenski 
15326f2bbd6SEugene (jno) Dvurechenski typedef struct CMS_VTOC {       /* @ rec.3 cyl.0 trk.0 for ECKD */
15426f2bbd6SEugene (jno) Dvurechenski                                 /* @ blk.1 (zero based) for FBA */
15526f2bbd6SEugene (jno) Dvurechenski     char magic[4];              /* 'CMS1', EBCDIC               */
15626f2bbd6SEugene (jno) Dvurechenski     char volser[6];             /* volser, EBCDIC               */
15726f2bbd6SEugene (jno) Dvurechenski     uint16_t version;           /* = 0                          */
15826f2bbd6SEugene (jno) Dvurechenski     uint32_t block_size;        /* = 512, 1024, 2048, or 4096   */
15926f2bbd6SEugene (jno) Dvurechenski     uint32_t disk_origin;       /* = 4 or 5                     */
16026f2bbd6SEugene (jno) Dvurechenski     uint32_t blocks;            /* Number of usable cyls/blocks */
16126f2bbd6SEugene (jno) Dvurechenski     uint32_t formatted;         /* Max number of fmtd cyls/blks */
16226f2bbd6SEugene (jno) Dvurechenski     uint32_t CMS_blocks;        /* disk size in CMS blocks      */
16326f2bbd6SEugene (jno) Dvurechenski     uint32_t CMS_used;          /* Number of CMS blocks in use  */
16426f2bbd6SEugene (jno) Dvurechenski     uint32_t FST_size;          /* = 64, bytes                  */
16526f2bbd6SEugene (jno) Dvurechenski     uint32_t FST_per_CMS_blk;   /*                              */
16626f2bbd6SEugene (jno) Dvurechenski     format_date_t format_date;  /* YYMMDDhhmmss as 6 bytes      */
16726f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved1[2];       /* = 0                          */
16826f2bbd6SEugene (jno) Dvurechenski     uint32_t offset;            /* disk offset when reserved    */
16926f2bbd6SEugene (jno) Dvurechenski     uint32_t next_hole;         /* block nr                     */
17026f2bbd6SEugene (jno) Dvurechenski     uint32_t HBLK_hole_offset;  /* >> HBLK data of next hole    */
17126f2bbd6SEugene (jno) Dvurechenski     uint32_t alloc_map_usr_off; /* >> user part of Alloc map    */
17226f2bbd6SEugene (jno) Dvurechenski     uint8_t reserved2[4];       /* = 0                          */
17326f2bbd6SEugene (jno) Dvurechenski     char shared_seg_name[8];    /*                              */
17426f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) CMS_VTOC;
17526f2bbd6SEugene (jno) Dvurechenski 
17626f2bbd6SEugene (jno) Dvurechenski /* from zipl/include/boot.h */
17726f2bbd6SEugene (jno) Dvurechenski typedef struct BootInfoBpIpl {
17826f2bbd6SEugene (jno) Dvurechenski     union {
17926f2bbd6SEugene (jno) Dvurechenski         ExtEckdBlockPtr eckd;
18026f2bbd6SEugene (jno) Dvurechenski         ScsiBlockPtr linr;
18126f2bbd6SEugene (jno) Dvurechenski     } bm_ptr;
18226f2bbd6SEugene (jno) Dvurechenski     uint8_t unused[16];
18326f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootInfoBpIpl;
18426f2bbd6SEugene (jno) Dvurechenski 
18526f2bbd6SEugene (jno) Dvurechenski typedef struct EckdDumpParam {
18626f2bbd6SEugene (jno) Dvurechenski     uint32_t        start_blk;
18726f2bbd6SEugene (jno) Dvurechenski     uint32_t        end_blk;
18826f2bbd6SEugene (jno) Dvurechenski     uint16_t        blocksize;
18926f2bbd6SEugene (jno) Dvurechenski     uint8_t         num_heads;
19026f2bbd6SEugene (jno) Dvurechenski     uint8_t         bpt;
19126f2bbd6SEugene (jno) Dvurechenski     char            reserved[4];
19226f2bbd6SEugene (jno) Dvurechenski } __attribute((packed, may_alias)) EckdDumpParam;
19326f2bbd6SEugene (jno) Dvurechenski 
19426f2bbd6SEugene (jno) Dvurechenski typedef struct FbaDumpParam {
19526f2bbd6SEugene (jno) Dvurechenski     uint64_t        start_blk;
19626f2bbd6SEugene (jno) Dvurechenski     uint64_t        blockct;
19726f2bbd6SEugene (jno) Dvurechenski } __attribute((packed)) FbaDumpParam;
19826f2bbd6SEugene (jno) Dvurechenski 
19926f2bbd6SEugene (jno) Dvurechenski typedef struct BootInfoBpDump {
20026f2bbd6SEugene (jno) Dvurechenski     union {
20126f2bbd6SEugene (jno) Dvurechenski         EckdDumpParam eckd;
20226f2bbd6SEugene (jno) Dvurechenski         FbaDumpParam fba;
20326f2bbd6SEugene (jno) Dvurechenski     } param;
20426f2bbd6SEugene (jno) Dvurechenski     uint8_t         unused[16];
20526f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootInfoBpDump;
20626f2bbd6SEugene (jno) Dvurechenski 
20726f2bbd6SEugene (jno) Dvurechenski typedef struct BootInfo {          /* @ 0x70, record #0    */
20826f2bbd6SEugene (jno) Dvurechenski     unsigned char magic[4]; /* = 'zIPL', ASCII      */
20926f2bbd6SEugene (jno) Dvurechenski     uint8_t version;        /* = 1                  */
21026f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_VERSION               1
21126f2bbd6SEugene (jno) Dvurechenski     uint8_t bp_type;        /* = 0                  */
21226f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_BP_TYPE_IPL           0x00
21326f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_BP_TYPE_DUMP          0x01
21426f2bbd6SEugene (jno) Dvurechenski     uint8_t dev_type;       /* = 0                  */
21526f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_DEV_TYPE_ECKD         0x00
21626f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_DEV_TYPE_FBA          0x01
21726f2bbd6SEugene (jno) Dvurechenski     uint8_t flags;          /* = 1                  */
21826f2bbd6SEugene (jno) Dvurechenski #ifdef __s390x__
21926f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_FLAGS_ARCH            0x01
22026f2bbd6SEugene (jno) Dvurechenski #else
22126f2bbd6SEugene (jno) Dvurechenski #define BOOT_INFO_FLAGS_ARCH            0x00
22226f2bbd6SEugene (jno) Dvurechenski #endif
22326f2bbd6SEugene (jno) Dvurechenski     union {
22426f2bbd6SEugene (jno) Dvurechenski         BootInfoBpDump dump;
22526f2bbd6SEugene (jno) Dvurechenski         BootInfoBpIpl ipl;
22626f2bbd6SEugene (jno) Dvurechenski     } bp;
22726f2bbd6SEugene (jno) Dvurechenski } __attribute__ ((packed)) BootInfo; /* see also XEckdMbr   */
22826f2bbd6SEugene (jno) Dvurechenski 
22926f2bbd6SEugene (jno) Dvurechenski typedef struct Ipl1 {
23026f2bbd6SEugene (jno) Dvurechenski     unsigned char key[4]; /* == "IPL1" */
23126f2bbd6SEugene (jno) Dvurechenski     unsigned char data[24];
23226f2bbd6SEugene (jno) Dvurechenski } __attribute__((packed)) Ipl1;
23326f2bbd6SEugene (jno) Dvurechenski 
23426f2bbd6SEugene (jno) Dvurechenski typedef struct Ipl2 {
23526f2bbd6SEugene (jno) Dvurechenski     unsigned char key[4]; /* == "IPL2" */
23626f2bbd6SEugene (jno) Dvurechenski     union {
23726f2bbd6SEugene (jno) Dvurechenski         unsigned char data[144];
23826f2bbd6SEugene (jno) Dvurechenski         struct {
23926f2bbd6SEugene (jno) Dvurechenski             unsigned char reserved1[92-4];
24026f2bbd6SEugene (jno) Dvurechenski             XEckdMbr mbr;
24126f2bbd6SEugene (jno) Dvurechenski             unsigned char reserved2[144-(92-4)-sizeof(XEckdMbr)];
24226f2bbd6SEugene (jno) Dvurechenski         } x;
24326f2bbd6SEugene (jno) Dvurechenski     } u;
24426f2bbd6SEugene (jno) Dvurechenski } __attribute__((packed)) Ipl2;
24526f2bbd6SEugene (jno) Dvurechenski 
24626f2bbd6SEugene (jno) Dvurechenski typedef struct IplVolumeLabel {
24726f2bbd6SEugene (jno) Dvurechenski     unsigned char key[4]; /* == "VOL1" */
24826f2bbd6SEugene (jno) Dvurechenski     union {
24926f2bbd6SEugene (jno) Dvurechenski         unsigned char data[80];
25026f2bbd6SEugene (jno) Dvurechenski         struct {
25126f2bbd6SEugene (jno) Dvurechenski             unsigned char key[4]; /* == "VOL1" */
25226f2bbd6SEugene (jno) Dvurechenski             unsigned char volser[6];
25326f2bbd6SEugene (jno) Dvurechenski             unsigned char reserved[6];
25426f2bbd6SEugene (jno) Dvurechenski         } f;
25526f2bbd6SEugene (jno) Dvurechenski     };
25626f2bbd6SEugene (jno) Dvurechenski } __attribute__((packed)) IplVolumeLabel;
25726f2bbd6SEugene (jno) Dvurechenski 
258*a94b485eSEugene (jno) Dvurechenski /* utility code below */
259*a94b485eSEugene (jno) Dvurechenski 
260*a94b485eSEugene (jno) Dvurechenski static inline void IPL_assert(bool term, const char *message)
261*a94b485eSEugene (jno) Dvurechenski {
262*a94b485eSEugene (jno) Dvurechenski     if (!term) {
263*a94b485eSEugene (jno) Dvurechenski         sclp_print("\n! ");
264*a94b485eSEugene (jno) Dvurechenski         sclp_print(message);
265*a94b485eSEugene (jno) Dvurechenski         virtio_panic(" !\n"); /* no return */
266*a94b485eSEugene (jno) Dvurechenski     }
267*a94b485eSEugene (jno) Dvurechenski }
268*a94b485eSEugene (jno) Dvurechenski 
269*a94b485eSEugene (jno) Dvurechenski static const unsigned char ebc2asc[256] =
270*a94b485eSEugene (jno) Dvurechenski       /* 0123456789abcdef0123456789abcdef */
271*a94b485eSEugene (jno) Dvurechenski         "................................" /* 1F */
272*a94b485eSEugene (jno) Dvurechenski         "................................" /* 3F */
273*a94b485eSEugene (jno) Dvurechenski         " ...........<(+|&.........!$*);." /* 5F first.chr.here.is.real.space */
274*a94b485eSEugene (jno) Dvurechenski         "-/.........,%_>?.........`:#@'=\""/* 7F */
275*a94b485eSEugene (jno) Dvurechenski         ".abcdefghi.......jklmnopqr......" /* 9F */
276*a94b485eSEugene (jno) Dvurechenski         "..stuvwxyz......................" /* BF */
277*a94b485eSEugene (jno) Dvurechenski         ".ABCDEFGHI.......JKLMNOPQR......" /* DF */
278*a94b485eSEugene (jno) Dvurechenski         "..STUVWXYZ......0123456789......";/* FF */
279*a94b485eSEugene (jno) Dvurechenski 
280*a94b485eSEugene (jno) Dvurechenski static inline void ebcdic_to_ascii(const char *src,
281*a94b485eSEugene (jno) Dvurechenski                                    char *dst,
282*a94b485eSEugene (jno) Dvurechenski                                    unsigned int size)
283*a94b485eSEugene (jno) Dvurechenski {
284*a94b485eSEugene (jno) Dvurechenski     unsigned int i;
285*a94b485eSEugene (jno) Dvurechenski     for (i = 0; i < size; i++) {
286*a94b485eSEugene (jno) Dvurechenski         unsigned c = src[i];
287*a94b485eSEugene (jno) Dvurechenski         dst[i] = ebc2asc[c];
288*a94b485eSEugene (jno) Dvurechenski     }
289*a94b485eSEugene (jno) Dvurechenski }
290*a94b485eSEugene (jno) Dvurechenski 
291*a94b485eSEugene (jno) Dvurechenski static inline void print_volser(const void *volser)
292*a94b485eSEugene (jno) Dvurechenski {
293*a94b485eSEugene (jno) Dvurechenski     char ascii[8];
294*a94b485eSEugene (jno) Dvurechenski 
295*a94b485eSEugene (jno) Dvurechenski     ebcdic_to_ascii((char *)volser, ascii, 6);
296*a94b485eSEugene (jno) Dvurechenski     ascii[6] = '\0';
297*a94b485eSEugene (jno) Dvurechenski     sclp_print("VOLSER=[");
298*a94b485eSEugene (jno) Dvurechenski     sclp_print(ascii);
299*a94b485eSEugene (jno) Dvurechenski     sclp_print("]\n");
300*a94b485eSEugene (jno) Dvurechenski }
301*a94b485eSEugene (jno) Dvurechenski 
302*a94b485eSEugene (jno) Dvurechenski static inline bool unused_space(const void *p, size_t size)
303*a94b485eSEugene (jno) Dvurechenski {
304*a94b485eSEugene (jno) Dvurechenski     size_t i;
305*a94b485eSEugene (jno) Dvurechenski     const unsigned char *m = p;
306*a94b485eSEugene (jno) Dvurechenski 
307*a94b485eSEugene (jno) Dvurechenski     for (i = 0; i < size; i++) {
308*a94b485eSEugene (jno) Dvurechenski         if (m[i] != FREE_SPACE_FILLER) {
309*a94b485eSEugene (jno) Dvurechenski             return false;
310*a94b485eSEugene (jno) Dvurechenski         }
311*a94b485eSEugene (jno) Dvurechenski     }
312*a94b485eSEugene (jno) Dvurechenski     return true;
313*a94b485eSEugene (jno) Dvurechenski }
314*a94b485eSEugene (jno) Dvurechenski 
315*a94b485eSEugene (jno) Dvurechenski static inline bool is_null_block_number(block_number_t x)
316*a94b485eSEugene (jno) Dvurechenski {
317*a94b485eSEugene (jno) Dvurechenski     return x == NULL_BLOCK_NR;
318*a94b485eSEugene (jno) Dvurechenski }
319*a94b485eSEugene (jno) Dvurechenski 
320*a94b485eSEugene (jno) Dvurechenski static inline void read_block(block_number_t blockno,
321*a94b485eSEugene (jno) Dvurechenski                               void *buffer,
322*a94b485eSEugene (jno) Dvurechenski                               const char *errmsg)
323*a94b485eSEugene (jno) Dvurechenski {
324*a94b485eSEugene (jno) Dvurechenski     IPL_assert(virtio_read(blockno, buffer) == 0, errmsg);
325*a94b485eSEugene (jno) Dvurechenski }
326*a94b485eSEugene (jno) Dvurechenski 
327*a94b485eSEugene (jno) Dvurechenski static inline bool block_size_ok(uint32_t block_size)
328*a94b485eSEugene (jno) Dvurechenski {
329*a94b485eSEugene (jno) Dvurechenski     return block_size == virtio_get_block_size();
330*a94b485eSEugene (jno) Dvurechenski }
331*a94b485eSEugene (jno) Dvurechenski 
332*a94b485eSEugene (jno) Dvurechenski static inline bool magic_match(const void *data, const void *magic)
333*a94b485eSEugene (jno) Dvurechenski {
334*a94b485eSEugene (jno) Dvurechenski     return *((uint32_t *)data) == *((uint32_t *)magic);
335*a94b485eSEugene (jno) Dvurechenski }
336*a94b485eSEugene (jno) Dvurechenski 
33726f2bbd6SEugene (jno) Dvurechenski #endif /* _PC_BIOS_S390_CCW_BOOTMAP_H */
338