Commit 87fd22e0 authored by Sven Schnelle's avatar Sven Schnelle Committed by Alexander Gordeev

s390/ipl: add eckd support

This adds support to IPL from ECKD DASDs to linux.
It introduces a few sysfs files in /sys/firmware/reipl/eckd:

bootprog: the boot program selector
clear:    whether to issue a diag308 LOAD_NORMAL or LOAD_CLEAR
device:   the device to ipl from
br_chr:   Cylinder/Head/Record number to read the bootrecord from.
          Might be '0' or 'auto' if it should be read from the
	  volume label.
scpdata:  data to be passed to the ipl'd program.

The new ipl type is called 'eckd'.
Signed-off-by: default avatarSven Schnelle <svens@linux.ibm.com>
Reviewed-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 5de2322d
...@@ -108,6 +108,11 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size, ...@@ -108,6 +108,11 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
scp_data_len = ipb->nvme.scp_data_len; scp_data_len = ipb->nvme.scp_data_len;
scp_data = ipb->nvme.scp_data; scp_data = ipb->nvme.scp_data;
break; break;
case IPL_PBT_ECKD:
scp_data_len = ipb->eckd.scp_data_len;
scp_data = ipb->eckd.scp_data;
break;
default: default:
goto out; goto out;
} }
...@@ -153,6 +158,7 @@ static void append_ipl_block_parm(void) ...@@ -153,6 +158,7 @@ static void append_ipl_block_parm(void)
break; break;
case IPL_PBT_FCP: case IPL_PBT_FCP:
case IPL_PBT_NVME: case IPL_PBT_NVME:
case IPL_PBT_ECKD:
rc = ipl_block_get_ascii_scpdata( rc = ipl_block_get_ascii_scpdata(
parm, COMMAND_LINE_SIZE - len - 1, &ipl_block); parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
break; break;
......
...@@ -22,6 +22,7 @@ struct ipl_parameter_block { ...@@ -22,6 +22,7 @@ struct ipl_parameter_block {
struct ipl_pb0_common common; struct ipl_pb0_common common;
struct ipl_pb0_fcp fcp; struct ipl_pb0_fcp fcp;
struct ipl_pb0_ccw ccw; struct ipl_pb0_ccw ccw;
struct ipl_pb0_eckd eckd;
struct ipl_pb0_nvme nvme; struct ipl_pb0_nvme nvme;
char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)]; char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)];
}; };
...@@ -41,6 +42,10 @@ struct ipl_parameter_block { ...@@ -41,6 +42,10 @@ struct ipl_parameter_block {
sizeof(struct ipl_pb0_ccw)) sizeof(struct ipl_pb0_ccw))
#define IPL_BP0_CCW_LEN (sizeof(struct ipl_pb0_ccw)) #define IPL_BP0_CCW_LEN (sizeof(struct ipl_pb0_ccw))
#define IPL_BP_ECKD_LEN (sizeof(struct ipl_pl_hdr) + \
sizeof(struct ipl_pb0_eckd))
#define IPL_BP0_ECKD_LEN (sizeof(struct ipl_pb0_eckd))
#define IPL_MAX_SUPPORTED_VERSION (0) #define IPL_MAX_SUPPORTED_VERSION (0)
#define IPL_RB_CERT_UNKNOWN ((unsigned short)-1) #define IPL_RB_CERT_UNKNOWN ((unsigned short)-1)
...@@ -68,6 +73,7 @@ enum ipl_type { ...@@ -68,6 +73,7 @@ enum ipl_type {
IPL_TYPE_NSS = 16, IPL_TYPE_NSS = 16,
IPL_TYPE_NVME = 32, IPL_TYPE_NVME = 32,
IPL_TYPE_NVME_DUMP = 64, IPL_TYPE_NVME_DUMP = 64,
IPL_TYPE_ECKD = 128,
}; };
struct ipl_info struct ipl_info
...@@ -77,6 +83,9 @@ struct ipl_info ...@@ -77,6 +83,9 @@ struct ipl_info
struct { struct {
struct ccw_dev_id dev_id; struct ccw_dev_id dev_id;
} ccw; } ccw;
struct {
struct ccw_dev_id dev_id;
} eckd;
struct { struct {
struct ccw_dev_id dev_id; struct ccw_dev_id dev_id;
u64 wwpn; u64 wwpn;
......
...@@ -87,6 +87,7 @@ struct sclp_info { ...@@ -87,6 +87,7 @@ struct sclp_info {
unsigned char has_gisaf : 1; unsigned char has_gisaf : 1;
unsigned char has_diag318 : 1; unsigned char has_diag318 : 1;
unsigned char has_sipl : 1; unsigned char has_sipl : 1;
unsigned char has_sipl_eckd : 1;
unsigned char has_dirq : 1; unsigned char has_dirq : 1;
unsigned char has_iplcc : 1; unsigned char has_iplcc : 1;
unsigned char has_zpci_lsi : 1; unsigned char has_zpci_lsi : 1;
......
...@@ -27,6 +27,7 @@ enum ipl_pbt { ...@@ -27,6 +27,7 @@ enum ipl_pbt {
IPL_PBT_FCP = 0, IPL_PBT_FCP = 0,
IPL_PBT_SCP_DATA = 1, IPL_PBT_SCP_DATA = 1,
IPL_PBT_CCW = 2, IPL_PBT_CCW = 2,
IPL_PBT_ECKD = 3,
IPL_PBT_NVME = 4, IPL_PBT_NVME = 4,
}; };
...@@ -111,6 +112,33 @@ struct ipl_pb0_ccw { ...@@ -111,6 +112,33 @@ struct ipl_pb0_ccw {
__u8 reserved5[8]; __u8 reserved5[8];
} __packed; } __packed;
/* IPL Parameter Block 0 for ECKD */
struct ipl_pb0_eckd {
__u32 len;
__u8 pbt;
__u8 reserved1[3];
__u32 reserved2[78];
__u8 opt;
__u8 reserved4[4];
__u8 reserved5:5;
__u8 ssid:3;
__u16 devno;
__u32 reserved6[5];
__u32 bootprog;
__u8 reserved7[12];
struct {
__u16 cyl;
__u8 head;
__u8 record;
__u32 reserved;
} br_chr __packed;
__u32 scp_data_len;
__u8 reserved8[260];
__u8 scp_data[];
} __packed;
#define IPL_PB0_ECKD_OPT_IPL 0x10
#define IPL_PB0_CCW_VM_FLAG_NSS 0x80 #define IPL_PB0_CCW_VM_FLAG_NSS 0x80
#define IPL_PB0_CCW_VM_FLAG_VP 0x40 #define IPL_PB0_CCW_VM_FLAG_VP 0x40
......
This diff is collapsed.
...@@ -57,8 +57,10 @@ static void __init sclp_early_facilities_detect(void) ...@@ -57,8 +57,10 @@ static void __init sclp_early_facilities_detect(void)
sclp.has_diag318 = !!(sccb->byte_134 & 0x80); sclp.has_diag318 = !!(sccb->byte_134 & 0x80);
sclp.has_iplcc = !!(sccb->byte_134 & 0x02); sclp.has_iplcc = !!(sccb->byte_134 & 0x02);
} }
if (sccb->cpuoff > 137) if (sccb->cpuoff > 137) {
sclp.has_sipl = !!(sccb->cbl & 0x4000); sclp.has_sipl = !!(sccb->cbl & 0x4000);
sclp.has_sipl_eckd = !!(sccb->cbl & 0x2000);
}
sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
sclp.rzm <<= 20; sclp.rzm <<= 20;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment