1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2c6557e7fSMartin Schwidefsky /*
3c6557e7fSMartin Schwidefsky * s390 (re)ipl support
4c6557e7fSMartin Schwidefsky *
5c6557e7fSMartin Schwidefsky * Copyright IBM Corp. 2007
6c6557e7fSMartin Schwidefsky */
7c6557e7fSMartin Schwidefsky
8c6557e7fSMartin Schwidefsky #ifndef _ASM_S390_IPL_H
9c6557e7fSMartin Schwidefsky #define _ASM_S390_IPL_H
10c6557e7fSMartin Schwidefsky
1158952942SMichael Holzheu #include <asm/lowcore.h>
12c6557e7fSMartin Schwidefsky #include <asm/types.h>
13c6557e7fSMartin Schwidefsky #include <asm/cio.h>
14c6557e7fSMartin Schwidefsky #include <asm/setup.h>
156040b3f4SAlexander Egorenkov #include <asm/page.h>
165f1207fbSMartin Schwidefsky #include <uapi/asm/ipl.h>
175f1207fbSMartin Schwidefsky
185f1207fbSMartin Schwidefsky struct ipl_parameter_block {
195f1207fbSMartin Schwidefsky struct ipl_pl_hdr hdr;
205f1207fbSMartin Schwidefsky union {
215f1207fbSMartin Schwidefsky struct ipl_pb_hdr pb0_hdr;
225f1207fbSMartin Schwidefsky struct ipl_pb0_common common;
235f1207fbSMartin Schwidefsky struct ipl_pb0_fcp fcp;
245f1207fbSMartin Schwidefsky struct ipl_pb0_ccw ccw;
2587fd22e0SSven Schnelle struct ipl_pb0_eckd eckd;
263737e8eeSJason J. Herne struct ipl_pb0_nvme nvme;
275f1207fbSMartin Schwidefsky char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)];
285f1207fbSMartin Schwidefsky };
295f1207fbSMartin Schwidefsky } __packed __aligned(PAGE_SIZE);
30c6557e7fSMartin Schwidefsky
31978fa72eSHeiko Carstens #define NSS_NAME_SIZE 8
32978fa72eSHeiko Carstens
335f1207fbSMartin Schwidefsky #define IPL_BP_FCP_LEN (sizeof(struct ipl_pl_hdr) + \
345f1207fbSMartin Schwidefsky sizeof(struct ipl_pb0_fcp))
355f1207fbSMartin Schwidefsky #define IPL_BP0_FCP_LEN (sizeof(struct ipl_pb0_fcp))
363737e8eeSJason J. Herne
373737e8eeSJason J. Herne #define IPL_BP_NVME_LEN (sizeof(struct ipl_pl_hdr) + \
383737e8eeSJason J. Herne sizeof(struct ipl_pb0_nvme))
393737e8eeSJason J. Herne #define IPL_BP0_NVME_LEN (sizeof(struct ipl_pb0_nvme))
403737e8eeSJason J. Herne
415f1207fbSMartin Schwidefsky #define IPL_BP_CCW_LEN (sizeof(struct ipl_pl_hdr) + \
425f1207fbSMartin Schwidefsky sizeof(struct ipl_pb0_ccw))
435f1207fbSMartin Schwidefsky #define IPL_BP0_CCW_LEN (sizeof(struct ipl_pb0_ccw))
44c6557e7fSMartin Schwidefsky
4587fd22e0SSven Schnelle #define IPL_BP_ECKD_LEN (sizeof(struct ipl_pl_hdr) + \
4687fd22e0SSven Schnelle sizeof(struct ipl_pb0_eckd))
4787fd22e0SSven Schnelle #define IPL_BP0_ECKD_LEN (sizeof(struct ipl_pb0_eckd))
4887fd22e0SSven Schnelle
49c6557e7fSMartin Schwidefsky #define IPL_MAX_SUPPORTED_VERSION (0)
50c6557e7fSMartin Schwidefsky
5199feaa71SPhilipp Rudo #define IPL_RB_CERT_UNKNOWN ((unsigned short)-1)
5299feaa71SPhilipp Rudo
535f1207fbSMartin Schwidefsky #define DIAG308_VMPARM_SIZE (64)
545f1207fbSMartin Schwidefsky #define DIAG308_SCPDATA_OFFSET offsetof(struct ipl_parameter_block, \
555f1207fbSMartin Schwidefsky fcp.scp_data)
565f1207fbSMartin Schwidefsky #define DIAG308_SCPDATA_SIZE (PAGE_SIZE - DIAG308_SCPDATA_OFFSET)
57c6557e7fSMartin Schwidefsky
581a2c5840SMartin Schwidefsky struct save_area;
591a2c5840SMartin Schwidefsky struct save_area * __init save_area_alloc(bool is_boot_cpu);
601a2c5840SMartin Schwidefsky struct save_area * __init save_area_boot_cpu(void);
611a2c5840SMartin Schwidefsky void __init save_area_add_regs(struct save_area *, void *regs);
621a2c5840SMartin Schwidefsky void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
6358952942SMichael Holzheu
64d485235bSVasily Gorbik extern void s390_reset_system(void);
6549698745SVasily Gorbik extern size_t ipl_block_get_ascii_vmparm(char *dest, size_t size,
6649698745SVasily Gorbik const struct ipl_parameter_block *ipb);
67c6557e7fSMartin Schwidefsky
68c6557e7fSMartin Schwidefsky enum ipl_type {
69c6557e7fSMartin Schwidefsky IPL_TYPE_UNKNOWN = 1,
70c6557e7fSMartin Schwidefsky IPL_TYPE_CCW = 2,
71c6557e7fSMartin Schwidefsky IPL_TYPE_FCP = 4,
72c6557e7fSMartin Schwidefsky IPL_TYPE_FCP_DUMP = 8,
73c6557e7fSMartin Schwidefsky IPL_TYPE_NSS = 16,
743737e8eeSJason J. Herne IPL_TYPE_NVME = 32,
75d70e38cbSJason J. Herne IPL_TYPE_NVME_DUMP = 64,
7687fd22e0SSven Schnelle IPL_TYPE_ECKD = 128,
77*e2d2a296SSven Schnelle IPL_TYPE_ECKD_DUMP = 256,
78c6557e7fSMartin Schwidefsky };
79c6557e7fSMartin Schwidefsky
80c6557e7fSMartin Schwidefsky struct ipl_info
81c6557e7fSMartin Schwidefsky {
82c6557e7fSMartin Schwidefsky enum ipl_type type;
83c6557e7fSMartin Schwidefsky union {
84c6557e7fSMartin Schwidefsky struct {
85c6557e7fSMartin Schwidefsky struct ccw_dev_id dev_id;
86c6557e7fSMartin Schwidefsky } ccw;
87c6557e7fSMartin Schwidefsky struct {
88c6557e7fSMartin Schwidefsky struct ccw_dev_id dev_id;
8987fd22e0SSven Schnelle } eckd;
9087fd22e0SSven Schnelle struct {
9187fd22e0SSven Schnelle struct ccw_dev_id dev_id;
92c6557e7fSMartin Schwidefsky u64 wwpn;
93c6557e7fSMartin Schwidefsky u64 lun;
94c6557e7fSMartin Schwidefsky } fcp;
95c6557e7fSMartin Schwidefsky struct {
963737e8eeSJason J. Herne u32 fid;
973737e8eeSJason J. Herne u32 nsid;
983737e8eeSJason J. Herne } nvme;
993737e8eeSJason J. Herne struct {
100c6557e7fSMartin Schwidefsky char name[NSS_NAME_SIZE + 1];
101c6557e7fSMartin Schwidefsky } nss;
102c6557e7fSMartin Schwidefsky } data;
103c6557e7fSMartin Schwidefsky };
104c6557e7fSMartin Schwidefsky
105c6557e7fSMartin Schwidefsky extern struct ipl_info ipl_info;
106c6557e7fSMartin Schwidefsky extern void setup_ipl(void);
1073b967847SVasily Gorbik extern void set_os_info_reipl_block(void);
108c6557e7fSMartin Schwidefsky
is_ipl_type_dump(void)109bd37b368SAlexander Egorenkov static inline bool is_ipl_type_dump(void)
110bd37b368SAlexander Egorenkov {
111bd37b368SAlexander Egorenkov return (ipl_info.type == IPL_TYPE_FCP_DUMP) ||
112*e2d2a296SSven Schnelle (ipl_info.type == IPL_TYPE_ECKD_DUMP) ||
113bd37b368SAlexander Egorenkov (ipl_info.type == IPL_TYPE_NVME_DUMP);
114bd37b368SAlexander Egorenkov }
115bd37b368SAlexander Egorenkov
116937347acSMartin Schwidefsky struct ipl_report {
117937347acSMartin Schwidefsky struct ipl_parameter_block *ipib;
118937347acSMartin Schwidefsky struct list_head components;
119937347acSMartin Schwidefsky struct list_head certificates;
120937347acSMartin Schwidefsky size_t size;
121937347acSMartin Schwidefsky };
122937347acSMartin Schwidefsky
123937347acSMartin Schwidefsky struct ipl_report_component {
124937347acSMartin Schwidefsky struct list_head list;
125937347acSMartin Schwidefsky struct ipl_rb_component_entry entry;
126937347acSMartin Schwidefsky };
127937347acSMartin Schwidefsky
128937347acSMartin Schwidefsky struct ipl_report_certificate {
129937347acSMartin Schwidefsky struct list_head list;
130937347acSMartin Schwidefsky struct ipl_rb_certificate_entry entry;
131937347acSMartin Schwidefsky void *key;
132937347acSMartin Schwidefsky };
133937347acSMartin Schwidefsky
134937347acSMartin Schwidefsky struct kexec_buf;
135937347acSMartin Schwidefsky struct ipl_report *ipl_report_init(struct ipl_parameter_block *ipib);
136937347acSMartin Schwidefsky void *ipl_report_finish(struct ipl_report *report);
137937347acSMartin Schwidefsky int ipl_report_free(struct ipl_report *report);
138937347acSMartin Schwidefsky int ipl_report_add_component(struct ipl_report *report, struct kexec_buf *kbuf,
139937347acSMartin Schwidefsky unsigned char flags, unsigned short cert);
140937347acSMartin Schwidefsky int ipl_report_add_certificate(struct ipl_report *report, void *key,
141937347acSMartin Schwidefsky unsigned long addr, unsigned long len);
142937347acSMartin Schwidefsky
143c6557e7fSMartin Schwidefsky /*
144c6557e7fSMartin Schwidefsky * DIAG 308 support
145c6557e7fSMartin Schwidefsky */
146c6557e7fSMartin Schwidefsky enum diag308_subcode {
1472ba24343SAlexander Egorenkov DIAG308_CLEAR_RESET = 0,
1482ba24343SAlexander Egorenkov DIAG308_LOAD_NORMAL_RESET = 1,
149c6557e7fSMartin Schwidefsky DIAG308_REL_HSA = 2,
1500599eeadSHeiko Carstens DIAG308_LOAD_CLEAR = 3,
1510599eeadSHeiko Carstens DIAG308_LOAD_NORMAL_DUMP = 4,
152c6557e7fSMartin Schwidefsky DIAG308_SET = 5,
153c6557e7fSMartin Schwidefsky DIAG308_STORE = 6,
1541a2ae03bSGerald Schaefer DIAG308_LOAD_NORMAL = 7,
155c6557e7fSMartin Schwidefsky };
156c6557e7fSMartin Schwidefsky
1572ba24343SAlexander Egorenkov enum diag308_subcode_flags {
1582ba24343SAlexander Egorenkov DIAG308_FLAG_EI = 1UL << 16,
1592ba24343SAlexander Egorenkov };
1602ba24343SAlexander Egorenkov
161c6557e7fSMartin Schwidefsky enum diag308_rc {
162c6557e7fSMartin Schwidefsky DIAG308_RC_OK = 0x0001,
163c6557e7fSMartin Schwidefsky DIAG308_RC_NOCONFIG = 0x0102,
164c6557e7fSMartin Schwidefsky };
165c6557e7fSMartin Schwidefsky
166c6557e7fSMartin Schwidefsky extern int diag308(unsigned long subcode, void *addr);
1671a36a39eSMartin Schwidefsky extern void store_status(void (*fn)(void *), void *data);
1683ab121abSMichael Holzheu extern void lgr_info_log(void);
169c6557e7fSMartin Schwidefsky
170c6557e7fSMartin Schwidefsky #endif /* _ASM_S390_IPL_H */
171