2 * drivers/s390/char/sclp_info.c
4 * Copyright IBM Corp. 2007
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
8 #include <linux/init.h>
9 #include <linux/errno.h>
10 #include <linux/string.h>
14 struct sclp_readinfo_sccb
{
15 struct sccb_header header
; /* 0-7 */
18 u8 _reserved0
[24 - 11]; /* 11-23 */
19 u8 loadparm
[8]; /* 24-31 */
20 u8 _reserved1
[48 - 32]; /* 32-47 */
21 u64 facilities
; /* 48-55 */
22 u8 _reserved2
[91 - 56]; /* 56-90 */
24 u8 _reserved3
[100 - 92]; /* 92-99 */
25 u32 rnsize2
; /* 100-103 */
26 u64 rnmax2
; /* 104-111 */
27 u8 _reserved4
[4096 - 112]; /* 112-4095 */
28 } __attribute__((packed
, aligned(4096)));
30 static struct sclp_readinfo_sccb __initdata early_readinfo_sccb
;
31 static int __initdata early_readinfo_sccb_valid
;
35 void __init
sclp_readinfo_early(void)
39 struct sclp_readinfo_sccb
*sccb
;
40 sclp_cmdw_t commands
[] = {SCLP_CMDW_READ_SCP_INFO_FORCED
,
41 SCLP_CMDW_READ_SCP_INFO
};
43 /* Enable service signal subclass mask. */
45 sccb
= &early_readinfo_sccb
;
46 for (i
= 0; i
< ARRAY_SIZE(commands
); i
++) {
48 memset(sccb
, 0, sizeof(*sccb
));
49 sccb
->header
.length
= sizeof(*sccb
);
50 sccb
->header
.control_mask
[2] = 0x80;
51 ret
= sclp_service_call(commands
[i
], sccb
);
52 } while (ret
== -EBUSY
);
56 __load_psw_mask(PSW_BASE_BITS
| PSW_MASK_EXT
|
57 PSW_MASK_WAIT
| PSW_DEFAULT_KEY
);
60 * Contents of the sccb might have changed
61 * therefore a barrier is needed.
64 if (sccb
->header
.response_code
== 0x10) {
65 early_readinfo_sccb_valid
= 1;
68 if (sccb
->header
.response_code
!= 0x1f0)
71 /* Disable service signal subclass mask again. */
72 __ctl_clear_bit(0, 9);
75 void __init
sclp_facilities_detect(void)
77 if (!early_readinfo_sccb_valid
)
79 sclp_facilities
= early_readinfo_sccb
.facilities
;
82 unsigned long long __init
sclp_memory_detect(void)
84 unsigned long long memsize
;
85 struct sclp_readinfo_sccb
*sccb
;
87 if (!early_readinfo_sccb_valid
)
89 sccb
= &early_readinfo_sccb
;
91 memsize
= sccb
->rnsize
<< 20;
93 memsize
= sccb
->rnsize2
<< 20;
95 memsize
*= sccb
->rnmax
;
97 memsize
*= sccb
->rnmax2
;
102 * This function will be called after sclp_memory_detect(), which gets called
103 * early from early.c code. Therefore the sccb should have valid contents.
105 void __init
sclp_get_ipl_info(struct sclp_ipl_info
*info
)
107 struct sclp_readinfo_sccb
*sccb
;
109 if (!early_readinfo_sccb_valid
)
111 sccb
= &early_readinfo_sccb
;
113 if (sccb
->flags
& 0x2)
115 memcpy(&info
->loadparm
, &sccb
->loadparm
, LOADPARM_LEN
);