master
h 258 lines 7.22 KB
Raw
1 /*
2 * S/390 boot structures
3 *
4 * Copyright 2024 IBM Corp.
5 * Author(s): Jared Rossi <jrossi@linux.ibm.com>
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or (at
8 * your option) any later version. See the COPYING file in the top-level
9 * directory.
10 */
11
12 #ifndef S390X_QIPL_H
13 #define S390X_QIPL_H
14
15 #include "diag308.h"
16
17 /* Boot Menu flags */
18 #define QIPL_FLAG_BM_OPTS_CMD 0x80
19 #define QIPL_FLAG_BM_OPTS_ZIPL 0x40
20
21 #define QIPL_ADDRESS 0xcc
22 #define LOADPARM_LEN 8
23 #define NO_LOADPARM "\0\0\0\0\0\0\0\0"
24
25 #define MAX_BOOT_ENTRIES 32
26
27 enum S390IplType {
28 S390_IPL_TYPE_FCP = 0x00,
29 S390_IPL_TYPE_CCW = 0x02,
30 S390_IPL_TYPE_PCI = 0x04,
31 S390_IPL_TYPE_PV = 0x05,
32 S390_IPL_TYPE_QEMU_SCSI = 0xff
33 };
34 typedef enum S390IplType S390IplType;
35
36 #define QEMU_DEFAULT_IPL S390_IPL_TYPE_CCW
37
38 #define S390_IPLB_HEADER_LEN 8
39 #define S390_IPLB_MIN_PV_LEN 148
40 #define S390_IPLB_MIN_CCW_LEN 200
41 #define S390_IPLB_MIN_FCP_LEN 384
42 #define S390_IPLB_MIN_PCI_LEN 376
43 #define S390_IPLB_MIN_QEMU_SCSI_LEN 200
44 #define S390_IPLB_MAX_LEN 4096
45
46 #define MAX_BOOT_DEVS 8 /* Max number of devices that may have a bootindex */
47
48 #define MAX_CERTIFICATES 64
49 #define CERT_BUF_SIZE ((MAX_BOOT_DEVS - 1) * 4096)
50 /* largest supported block size - same as VIRTIO_DASD_DEFAULT_BLOCK_SIZE */
51 #define VIRTIO_MAX_BLOCK_SIZE 4096
52 #define MAX_COMP_ENTRIES ((VIRTIO_MAX_BLOCK_SIZE - 32) / 32)
53
54 /*
55 * The QEMU IPL Parameters will be stored at absolute address
56 * 204 (0xcc) which means it is 32-bit word aligned but not
57 * double-word aligned. Placement of 64-bit data fields in this
58 * area must account for their alignment needs.
59 * The total size of the struct must never exceed 28 bytes.
60 */
61 struct QemuIplParameters {
62 uint8_t qipl_flags;
63 uint8_t index;
64 uint8_t reserved1[2];
65 uint64_t reserved2;
66 uint32_t boot_menu_timeout;
67 uint8_t reserved3[2];
68 uint16_t chain_len;
69 uint64_t ipl_data;
70 } QEMU_PACKED;
71 typedef struct QemuIplParameters QemuIplParameters;
72
73 struct IPLBlockPVComp {
74 uint64_t tweak_pref;
75 uint64_t addr;
76 uint64_t size;
77 } QEMU_PACKED;
78 typedef struct IPLBlockPVComp IPLBlockPVComp;
79
80 struct IPLBlockPV {
81 uint8_t reserved18[87]; /* 0x18 */
82 uint8_t version; /* 0x6f */
83 uint32_t reserved70; /* 0x70 */
84 uint32_t num_comp; /* 0x74 */
85 uint64_t pv_header_addr; /* 0x78 */
86 uint64_t pv_header_len; /* 0x80 */
87 struct IPLBlockPVComp components[0];
88 } QEMU_PACKED;
89 typedef struct IPLBlockPV IPLBlockPV;
90
91 struct IplBlockCcw {
92 uint8_t reserved0[85];
93 uint8_t ssid;
94 uint16_t devno;
95 uint8_t vm_flags;
96 uint8_t reserved3[3];
97 uint32_t vm_parm_len;
98 uint8_t nss_name[8];
99 uint8_t vm_parm[64];
100 uint8_t reserved4[8];
101 } QEMU_PACKED;
102 typedef struct IplBlockCcw IplBlockCcw;
103
104 struct IplBlockFcp {
105 uint8_t reserved1[305 - 1];
106 uint8_t opt;
107 uint8_t reserved2[3];
108 uint16_t reserved3;
109 uint16_t devno;
110 uint8_t reserved4[4];
111 uint64_t wwpn;
112 uint64_t lun;
113 uint32_t bootprog;
114 uint8_t reserved5[12];
115 uint64_t br_lba;
116 uint32_t scp_data_len;
117 uint8_t reserved6[260];
118 uint8_t scp_data[0];
119 } QEMU_PACKED;
120 typedef struct IplBlockFcp IplBlockFcp;
121
122 struct IplBlockQemuScsi {
123 uint32_t lun;
124 uint16_t target;
125 uint16_t channel;
126 uint8_t reserved0[77];
127 uint8_t ssid;
128 uint16_t devno;
129 } QEMU_PACKED;
130 typedef struct IplBlockQemuScsi IplBlockQemuScsi;
131
132 struct IplBlockPci {
133 uint32_t reserved0[76];
134 uint8_t opt;
135 uint8_t reserved1[3];
136 uint32_t fid;
137 } QEMU_PACKED;
138 typedef struct IplBlockPci IplBlockPci;
139
140 union IplParameterBlock {
141 struct {
142 uint32_t len;
143 uint8_t hdr_flags;
144 uint8_t reserved0[2];
145 uint8_t version;
146 uint32_t blk0_len;
147 uint8_t pbt;
148 uint8_t flags;
149 uint16_t reserved01;
150 uint8_t loadparm[LOADPARM_LEN];
151 union {
152 IplBlockCcw ccw;
153 IplBlockFcp fcp;
154 IPLBlockPV pv;
155 IplBlockQemuScsi scsi;
156 IplBlockPci pci;
157 };
158 } QEMU_PACKED;
159 struct {
160 uint8_t reserved1[110];
161 uint16_t devno;
162 uint8_t reserved2[88];
163 uint8_t reserved_ext[4096 - 200];
164 } QEMU_PACKED;
165 } QEMU_PACKED;
166 typedef union IplParameterBlock IplParameterBlock;
167
168 struct IplInfoReportBlockHeader {
169 uint32_t len;
170 uint8_t flags;
171 uint8_t reserved1[11];
172 };
173 typedef struct IplInfoReportBlockHeader IplInfoReportBlockHeader;
174
175 /* IPL Info Error Indicators */
176 #define S390_IIEI_NO_SIGNED_COMP 0x8000 /* bit 0 */
177 #define S390_IIEI_NO_SCLAB 0x4000 /* bit 1 */
178 #define S390_IIEI_NO_GLOBAL_SCLAB 0x2000 /* bit 2 */
179 #define S390_IIEI_MORE_GLOBAL_SCLAB 0x1000 /* bit 3 */
180 #define S390_IIEI_FOUND_UNSIGNED_COMP 0x800 /* bit 4 */
181 #define S390_IIEI_MORE_SIGNED_COMP 0x400 /* bit 5 */
182
183 struct IplInfoBlockHeader {
184 uint32_t len;
185 uint8_t type;
186 uint8_t reserved1[3];
187 uint16_t iiei;
188 uint8_t reserved2[6];
189 };
190 typedef struct IplInfoBlockHeader IplInfoBlockHeader;
191
192 enum IplInfoBlockType {
193 IPL_INFO_BLOCK_TYPE_CERTIFICATES = 1,
194 IPL_INFO_BLOCK_TYPE_COMPONENTS = 2,
195 };
196
197 struct IplSignatureCertificateEntry {
198 uint64_t addr;
199 uint64_t len;
200 };
201 typedef struct IplSignatureCertificateEntry IplSignatureCertificateEntry;
202
203 struct IplSignatureCertificateList {
204 IplInfoBlockHeader ipl_info_header;
205 IplSignatureCertificateEntry cert_entries[MAX_CERTIFICATES];
206 };
207 typedef struct IplSignatureCertificateList IplSignatureCertificateList;
208
209 #define S390_IPL_DEV_COMP_FLAG_SC 0x80
210 #define S390_IPL_DEV_COMP_FLAG_CSV 0x40
211
212 /* IPL Device Component Error Indicators */
213 #define S390_CEI_INVALID_SCLAB 0x80000000 /* bit 0 */
214 #define S390_CEI_INVALID_SCLAB_LEN 0x40000000 /* bit 1 */
215 #define S390_CEI_INVALID_SCLAB_FORMAT 0x20000000 /* bit 2 */
216 #define S390_CEI_UNMATCHED_SCLAB_LOAD_ADDR 0x10000000 /* bit 3 */
217 #define S390_CEI_UNMATCHED_SCLAB_LOAD_PSW 0x8000000 /* bit 4 */
218 #define S390_CEI_INVALID_LOAD_PSW 0x4000000 /* bit 5 */
219 #define S390_CEI_NUC_NOT_IN_GLOBAL_SCLAB 0x2000000 /* bit 6 */
220 #define S390_CEI_SCLAB_OLA_NOT_ONE 0x1000000 /* bit 7 */
221 #define S390_CEI_SC_NOT_IN_GLOBAL_SCLAB 0x800000 /* bit 8 */
222 #define S390_CEI_SCLAB_LOAD_ADDR_NOT_ZERO 0x400000 /* bit 9 */
223 #define S390_CEI_SCLAB_LOAD_PSW_NOT_ZERO 0x200000 /* bit 10 */
224 #define S390_CEI_INVALID_UNSIGNED_ADDR 0x100000 /* bit 11 */
225
226 struct IplDeviceComponentEntry {
227 uint64_t addr;
228 uint64_t len;
229 uint8_t flags;
230 uint8_t reserved1[5];
231 uint16_t cert_index;
232 uint32_t cei;
233 uint8_t reserved2[4];
234 };
235 typedef struct IplDeviceComponentEntry IplDeviceComponentEntry;
236
237 struct IplDeviceComponentList {
238 IplInfoBlockHeader ipl_info_header;
239 IplDeviceComponentEntry device_entries[MAX_COMP_ENTRIES];
240 };
241 typedef struct IplDeviceComponentList IplDeviceComponentList;
242
243 #define COMP_LIST_MAX sizeof(IplDeviceComponentList)
244 #define CERT_LIST_MAX sizeof(IplSignatureCertificateList)
245
246 struct IplInfoReportBlock {
247 IplInfoReportBlockHeader hdr;
248 uint8_t info_blks[COMP_LIST_MAX + CERT_LIST_MAX];
249 };
250 typedef struct IplInfoReportBlock IplInfoReportBlock;
251
252 struct IplBlocks {
253 IplParameterBlock iplb;
254 IplInfoReportBlock iirb;
255 };
256 typedef struct IplBlocks IplBlocks;
257
258 #endif