| .. | .. |
|---|
| 15 | 15 | #include "sclp_sdias.h" |
|---|
| 16 | 16 | #include "sclp.h" |
|---|
| 17 | 17 | |
|---|
| 18 | | -#define SCLP_CMDW_READ_SCP_INFO 0x00020001 |
|---|
| 19 | | -#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 |
|---|
| 20 | | - |
|---|
| 21 | | -struct read_info_sccb { |
|---|
| 22 | | - struct sccb_header header; /* 0-7 */ |
|---|
| 23 | | - u16 rnmax; /* 8-9 */ |
|---|
| 24 | | - u8 rnsize; /* 10 */ |
|---|
| 25 | | - u8 _pad_11[16 - 11]; /* 11-15 */ |
|---|
| 26 | | - u16 ncpurl; /* 16-17 */ |
|---|
| 27 | | - u16 cpuoff; /* 18-19 */ |
|---|
| 28 | | - u8 _pad_20[24 - 20]; /* 20-23 */ |
|---|
| 29 | | - u8 loadparm[8]; /* 24-31 */ |
|---|
| 30 | | - u8 _pad_32[42 - 32]; /* 32-41 */ |
|---|
| 31 | | - u8 fac42; /* 42 */ |
|---|
| 32 | | - u8 fac43; /* 43 */ |
|---|
| 33 | | - u8 _pad_44[48 - 44]; /* 44-47 */ |
|---|
| 34 | | - u64 facilities; /* 48-55 */ |
|---|
| 35 | | - u8 _pad_56[66 - 56]; /* 56-65 */ |
|---|
| 36 | | - u8 fac66; /* 66 */ |
|---|
| 37 | | - u8 _pad_67[76 - 67]; /* 67-83 */ |
|---|
| 38 | | - u32 ibc; /* 76-79 */ |
|---|
| 39 | | - u8 _pad80[84 - 80]; /* 80-83 */ |
|---|
| 40 | | - u8 fac84; /* 84 */ |
|---|
| 41 | | - u8 fac85; /* 85 */ |
|---|
| 42 | | - u8 _pad_86[91 - 86]; /* 86-90 */ |
|---|
| 43 | | - u8 fac91; /* 91 */ |
|---|
| 44 | | - u8 _pad_92[98 - 92]; /* 92-97 */ |
|---|
| 45 | | - u8 fac98; /* 98 */ |
|---|
| 46 | | - u8 hamaxpow; /* 99 */ |
|---|
| 47 | | - u32 rnsize2; /* 100-103 */ |
|---|
| 48 | | - u64 rnmax2; /* 104-111 */ |
|---|
| 49 | | - u8 _pad_112[116 - 112]; /* 112-115 */ |
|---|
| 50 | | - u8 fac116; /* 116 */ |
|---|
| 51 | | - u8 fac117; /* 117 */ |
|---|
| 52 | | - u8 fac118; /* 118 */ |
|---|
| 53 | | - u8 fac119; /* 119 */ |
|---|
| 54 | | - u16 hcpua; /* 120-121 */ |
|---|
| 55 | | - u8 _pad_122[124 - 122]; /* 122-123 */ |
|---|
| 56 | | - u32 hmfai; /* 124-127 */ |
|---|
| 57 | | - u8 _pad_128[4096 - 128]; /* 128-4095 */ |
|---|
| 58 | | -} __packed __aligned(PAGE_SIZE); |
|---|
| 59 | | - |
|---|
| 60 | 18 | static struct sclp_ipl_info sclp_ipl_info; |
|---|
| 61 | 19 | |
|---|
| 62 | 20 | struct sclp_info sclp; |
|---|
| 63 | 21 | EXPORT_SYMBOL(sclp); |
|---|
| 64 | | - |
|---|
| 65 | | -static int __init sclp_early_read_info(struct read_info_sccb *sccb) |
|---|
| 66 | | -{ |
|---|
| 67 | | - int i; |
|---|
| 68 | | - sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, |
|---|
| 69 | | - SCLP_CMDW_READ_SCP_INFO}; |
|---|
| 70 | | - |
|---|
| 71 | | - for (i = 0; i < ARRAY_SIZE(commands); i++) { |
|---|
| 72 | | - memset(sccb, 0, sizeof(*sccb)); |
|---|
| 73 | | - sccb->header.length = sizeof(*sccb); |
|---|
| 74 | | - sccb->header.function_code = 0x80; |
|---|
| 75 | | - sccb->header.control_mask[2] = 0x80; |
|---|
| 76 | | - if (sclp_early_cmd(commands[i], sccb)) |
|---|
| 77 | | - break; |
|---|
| 78 | | - if (sccb->header.response_code == 0x10) |
|---|
| 79 | | - return 0; |
|---|
| 80 | | - if (sccb->header.response_code != 0x1f0) |
|---|
| 81 | | - break; |
|---|
| 82 | | - } |
|---|
| 83 | | - return -EIO; |
|---|
| 84 | | -} |
|---|
| 85 | 22 | |
|---|
| 86 | 23 | static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb) |
|---|
| 87 | 24 | { |
|---|
| 88 | 25 | struct sclp_core_entry *cpue; |
|---|
| 89 | 26 | u16 boot_cpu_address, cpu; |
|---|
| 90 | 27 | |
|---|
| 91 | | - if (sclp_early_read_info(sccb)) |
|---|
| 28 | + if (sclp_early_get_info(sccb)) |
|---|
| 92 | 29 | return; |
|---|
| 93 | 30 | |
|---|
| 94 | 31 | sclp.facilities = sccb->facilities; |
|---|
| .. | .. |
|---|
| 107 | 44 | S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; |
|---|
| 108 | 45 | if (sccb->fac91 & 0x40) |
|---|
| 109 | 46 | S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST; |
|---|
| 47 | + if (sccb->cpuoff > 134) |
|---|
| 48 | + sclp.has_diag318 = !!(sccb->byte_134 & 0x80); |
|---|
| 49 | + if (sccb->cpuoff > 137) |
|---|
| 50 | + sclp.has_sipl = !!(sccb->cbl & 0x4000); |
|---|
| 110 | 51 | sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; |
|---|
| 111 | 52 | sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; |
|---|
| 112 | 53 | sclp.rzm <<= 20; |
|---|
| .. | .. |
|---|
| 147 | 88 | sclp_ipl_info.has_dump = 1; |
|---|
| 148 | 89 | memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN); |
|---|
| 149 | 90 | |
|---|
| 91 | + if (sccb->hsa_size) |
|---|
| 92 | + sclp.hsa_size = (sccb->hsa_size - 1) * PAGE_SIZE; |
|---|
| 150 | 93 | sclp.mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0; |
|---|
| 151 | 94 | sclp.mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0; |
|---|
| 152 | 95 | sclp.mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0; |
|---|
| 153 | 96 | |
|---|
| 154 | 97 | sclp.hmfai = sccb->hmfai; |
|---|
| 98 | + sclp.has_dirq = !!(sccb->cpudirq & 0x80); |
|---|
| 155 | 99 | } |
|---|
| 156 | 100 | |
|---|
| 157 | 101 | /* |
|---|
| .. | .. |
|---|
| 189 | 133 | return 0; |
|---|
| 190 | 134 | } |
|---|
| 191 | 135 | |
|---|
| 192 | | -static long __init sclp_early_hsa_size_init(struct sdias_sccb *sccb) |
|---|
| 193 | | -{ |
|---|
| 194 | | - memset(sccb, 0, sizeof(*sccb)); |
|---|
| 195 | | - sccb->hdr.length = sizeof(*sccb); |
|---|
| 196 | | - sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf); |
|---|
| 197 | | - sccb->evbuf.hdr.type = EVTYP_SDIAS; |
|---|
| 198 | | - sccb->evbuf.event_qual = SDIAS_EQ_SIZE; |
|---|
| 199 | | - sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP; |
|---|
| 200 | | - sccb->evbuf.event_id = 4712; |
|---|
| 201 | | - sccb->evbuf.dbs = 1; |
|---|
| 202 | | - if (sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_DATA, sccb)) |
|---|
| 203 | | - return -EIO; |
|---|
| 204 | | - if (sccb->hdr.response_code != 0x20) |
|---|
| 205 | | - return -EIO; |
|---|
| 206 | | - if (sccb->evbuf.blk_cnt == 0) |
|---|
| 207 | | - return 0; |
|---|
| 208 | | - return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE; |
|---|
| 209 | | -} |
|---|
| 210 | | - |
|---|
| 211 | | -static long __init sclp_early_hsa_copy_wait(struct sdias_sccb *sccb) |
|---|
| 212 | | -{ |
|---|
| 213 | | - memset(sccb, 0, PAGE_SIZE); |
|---|
| 214 | | - sccb->hdr.length = PAGE_SIZE; |
|---|
| 215 | | - if (sclp_early_cmd(SCLP_CMDW_READ_EVENT_DATA, sccb)) |
|---|
| 216 | | - return -EIO; |
|---|
| 217 | | - if ((sccb->hdr.response_code != 0x20) && (sccb->hdr.response_code != 0x220)) |
|---|
| 218 | | - return -EIO; |
|---|
| 219 | | - if (sccb->evbuf.blk_cnt == 0) |
|---|
| 220 | | - return 0; |
|---|
| 221 | | - return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE; |
|---|
| 222 | | -} |
|---|
| 223 | | - |
|---|
| 224 | | -static void __init sclp_early_hsa_size_detect(void *sccb) |
|---|
| 225 | | -{ |
|---|
| 226 | | - unsigned long flags; |
|---|
| 227 | | - long size = -EIO; |
|---|
| 228 | | - |
|---|
| 229 | | - raw_local_irq_save(flags); |
|---|
| 230 | | - if (sclp_early_set_event_mask(sccb, EVTYP_SDIAS_MASK, EVTYP_SDIAS_MASK)) |
|---|
| 231 | | - goto out; |
|---|
| 232 | | - size = sclp_early_hsa_size_init(sccb); |
|---|
| 233 | | - /* First check for synchronous response (LPAR) */ |
|---|
| 234 | | - if (size) |
|---|
| 235 | | - goto out_mask; |
|---|
| 236 | | - if (!(S390_lowcore.ext_params & 1)) |
|---|
| 237 | | - sclp_early_wait_irq(); |
|---|
| 238 | | - size = sclp_early_hsa_copy_wait(sccb); |
|---|
| 239 | | -out_mask: |
|---|
| 240 | | - sclp_early_set_event_mask(sccb, 0, 0); |
|---|
| 241 | | -out: |
|---|
| 242 | | - raw_local_irq_restore(flags); |
|---|
| 243 | | - if (size > 0) |
|---|
| 244 | | - sclp.hsa_size = size; |
|---|
| 245 | | -} |
|---|
| 246 | | - |
|---|
| 247 | 136 | static void __init sclp_early_console_detect(struct init_sccb *sccb) |
|---|
| 248 | 137 | { |
|---|
| 249 | 138 | if (sccb->header.response_code != 0x20) |
|---|
| .. | .. |
|---|
| 258 | 147 | |
|---|
| 259 | 148 | void __init sclp_early_detect(void) |
|---|
| 260 | 149 | { |
|---|
| 261 | | - void *sccb = &sclp_early_sccb; |
|---|
| 150 | + void *sccb = sclp_early_sccb; |
|---|
| 262 | 151 | |
|---|
| 263 | 152 | sclp_early_facilities_detect(sccb); |
|---|
| 264 | 153 | sclp_early_init_core_info(sccb); |
|---|
| 265 | | - sclp_early_hsa_size_detect(sccb); |
|---|
| 266 | 154 | |
|---|
| 267 | 155 | /* |
|---|
| 268 | 156 | * Turn off SCLP event notifications. Also save remote masks in the |
|---|