1  /* SPDX-License-Identifier: GPL-2.0 */
2  /*
3   * s390 (re)ipl support
4   *
5   * Copyright IBM Corp. 2007
6   */
7  
8  #ifndef _ASM_S390_IPL_H
9  #define _ASM_S390_IPL_H
10  
11  #include <asm/lowcore.h>
12  #include <asm/types.h>
13  #include <asm/cio.h>
14  #include <asm/setup.h>
15  #include <asm/page.h>
16  #include <uapi/asm/ipl.h>
17  
18  struct ipl_parameter_block {
19  	struct ipl_pl_hdr hdr;
20  	union {
21  		struct ipl_pb_hdr pb0_hdr;
22  		struct ipl_pb0_common common;
23  		struct ipl_pb0_fcp fcp;
24  		struct ipl_pb0_ccw ccw;
25  		struct ipl_pb0_eckd eckd;
26  		struct ipl_pb0_nvme nvme;
27  		char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)];
28  	};
29  } __packed __aligned(PAGE_SIZE);
30  
31  #define NSS_NAME_SIZE 8
32  
33  #define IPL_BP_FCP_LEN (sizeof(struct ipl_pl_hdr) + \
34  			      sizeof(struct ipl_pb0_fcp))
35  #define IPL_BP0_FCP_LEN (sizeof(struct ipl_pb0_fcp))
36  
37  #define IPL_BP_NVME_LEN (sizeof(struct ipl_pl_hdr) + \
38  			      sizeof(struct ipl_pb0_nvme))
39  #define IPL_BP0_NVME_LEN (sizeof(struct ipl_pb0_nvme))
40  
41  #define IPL_BP_CCW_LEN (sizeof(struct ipl_pl_hdr) + \
42  			      sizeof(struct ipl_pb0_ccw))
43  #define IPL_BP0_CCW_LEN (sizeof(struct ipl_pb0_ccw))
44  
45  #define IPL_BP_ECKD_LEN (sizeof(struct ipl_pl_hdr) + \
46  			      sizeof(struct ipl_pb0_eckd))
47  #define IPL_BP0_ECKD_LEN (sizeof(struct ipl_pb0_eckd))
48  
49  #define IPL_MAX_SUPPORTED_VERSION (0)
50  
51  #define IPL_RB_CERT_UNKNOWN ((unsigned short)-1)
52  
53  #define DIAG308_VMPARM_SIZE (64)
54  #define DIAG308_SCPDATA_OFFSET offsetof(struct ipl_parameter_block, \
55  					fcp.scp_data)
56  #define DIAG308_SCPDATA_SIZE (PAGE_SIZE - DIAG308_SCPDATA_OFFSET)
57  
58  struct save_area;
59  struct save_area * __init save_area_alloc(bool is_boot_cpu);
60  struct save_area * __init save_area_boot_cpu(void);
61  void __init save_area_add_regs(struct save_area *, void *regs);
62  void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
63  
64  extern void s390_reset_system(void);
65  extern size_t ipl_block_get_ascii_vmparm(char *dest, size_t size,
66  					 const struct ipl_parameter_block *ipb);
67  
68  enum ipl_type {
69  	IPL_TYPE_UNKNOWN	= 1,
70  	IPL_TYPE_CCW		= 2,
71  	IPL_TYPE_FCP		= 4,
72  	IPL_TYPE_FCP_DUMP	= 8,
73  	IPL_TYPE_NSS		= 16,
74  	IPL_TYPE_NVME		= 32,
75  	IPL_TYPE_NVME_DUMP	= 64,
76  	IPL_TYPE_ECKD		= 128,
77  	IPL_TYPE_ECKD_DUMP	= 256,
78  };
79  
80  struct ipl_info
81  {
82  	enum ipl_type type;
83  	union {
84  		struct {
85  			struct ccw_dev_id dev_id;
86  		} ccw;
87  		struct {
88  			struct ccw_dev_id dev_id;
89  		} eckd;
90  		struct {
91  			struct ccw_dev_id dev_id;
92  			u64 wwpn;
93  			u64 lun;
94  		} fcp;
95  		struct {
96  			u32 fid;
97  			u32 nsid;
98  		} nvme;
99  		struct {
100  			char name[NSS_NAME_SIZE + 1];
101  		} nss;
102  	} data;
103  };
104  
105  extern struct ipl_info ipl_info;
106  extern void setup_ipl(void);
107  extern void set_os_info_reipl_block(void);
108  
is_ipl_type_dump(void)109  static inline bool is_ipl_type_dump(void)
110  {
111  	return (ipl_info.type == IPL_TYPE_FCP_DUMP) ||
112  		(ipl_info.type == IPL_TYPE_ECKD_DUMP) ||
113  		(ipl_info.type == IPL_TYPE_NVME_DUMP);
114  }
115  
116  struct ipl_report {
117  	struct ipl_parameter_block *ipib;
118  	struct list_head components;
119  	struct list_head certificates;
120  	size_t size;
121  };
122  
123  struct ipl_report_component {
124  	struct list_head list;
125  	struct ipl_rb_component_entry entry;
126  };
127  
128  struct ipl_report_certificate {
129  	struct list_head list;
130  	struct ipl_rb_certificate_entry entry;
131  	void *key;
132  };
133  
134  struct kexec_buf;
135  struct ipl_report *ipl_report_init(struct ipl_parameter_block *ipib);
136  void *ipl_report_finish(struct ipl_report *report);
137  int ipl_report_free(struct ipl_report *report);
138  int ipl_report_add_component(struct ipl_report *report, struct kexec_buf *kbuf,
139  			     unsigned char flags, unsigned short cert);
140  int ipl_report_add_certificate(struct ipl_report *report, void *key,
141  			       unsigned long addr, unsigned long len);
142  
143  /*
144   * DIAG 308 support
145   */
146  enum diag308_subcode  {
147  	DIAG308_CLEAR_RESET = 0,
148  	DIAG308_LOAD_NORMAL_RESET = 1,
149  	DIAG308_REL_HSA = 2,
150  	DIAG308_LOAD_CLEAR = 3,
151  	DIAG308_LOAD_NORMAL_DUMP = 4,
152  	DIAG308_SET = 5,
153  	DIAG308_STORE = 6,
154  	DIAG308_LOAD_NORMAL = 7,
155  };
156  
157  enum diag308_subcode_flags {
158  	DIAG308_FLAG_EI = 1UL << 16,
159  };
160  
161  enum diag308_rc {
162  	DIAG308_RC_OK		= 0x0001,
163  	DIAG308_RC_NOCONFIG	= 0x0102,
164  };
165  
166  extern int diag308(unsigned long subcode, void *addr);
167  extern void store_status(void (*fn)(void *), void *data);
168  extern void lgr_info_log(void);
169  
170  #endif /* _ASM_S390_IPL_H */
171