forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/drivers/s390/char/sclp_early_core.c
....@@ -9,16 +9,20 @@
99 #include <asm/lowcore.h>
1010 #include <asm/ebcdic.h>
1111 #include <asm/irq.h>
12
+#include <asm/sections.h>
13
+#include <asm/mem_detect.h>
1214 #include "sclp.h"
1315 #include "sclp_rw.h"
1416
15
-char sclp_early_sccb[PAGE_SIZE] __aligned(PAGE_SIZE) __section(.data);
16
-int sclp_init_state __section(.data) = sclp_init_state_uninitialized;
17
+static struct read_info_sccb __bootdata(sclp_info_sccb);
18
+static int __bootdata(sclp_info_sccb_valid);
19
+char *sclp_early_sccb = (char *) EARLY_SCCB_OFFSET;
20
+int sclp_init_state = sclp_init_state_uninitialized;
1721 /*
1822 * Used to keep track of the size of the event masks. Qemu until version 2.11
1923 * only supports 4 and needs a workaround.
2024 */
21
-bool sclp_mask_compat_mode __section(.data);
25
+bool sclp_mask_compat_mode;
2226
2327 void sclp_early_wait_irq(void)
2428 {
....@@ -87,8 +91,8 @@
8791 struct mto *mto;
8892 struct go *go;
8993
90
- sccb = (struct write_sccb *) &sclp_early_sccb;
91
- end = (unsigned char *) sccb + sizeof(sclp_early_sccb) - 1;
94
+ sccb = (struct write_sccb *) sclp_early_sccb;
95
+ end = (unsigned char *) sccb + EARLY_SCCB_SIZE - 1;
9296 memset(sccb, 0, sizeof(*sccb));
9397 ptr = (unsigned char *) &sccb->msg.mdb.mto;
9498 offset = 0;
....@@ -135,9 +139,9 @@
135139 {
136140 struct vt220_sccb *sccb;
137141
138
- sccb = (struct vt220_sccb *) &sclp_early_sccb;
139
- if (sizeof(*sccb) + len >= sizeof(sclp_early_sccb))
140
- len = sizeof(sclp_early_sccb) - sizeof(*sccb);
142
+ sccb = (struct vt220_sccb *) sclp_early_sccb;
143
+ if (sizeof(*sccb) + len >= EARLY_SCCB_SIZE)
144
+ len = EARLY_SCCB_SIZE - sizeof(*sccb);
141145 memset(sccb, 0, sizeof(*sccb));
142146 memcpy(&sccb->msg.data, str, len);
143147 sccb->header.length = sizeof(*sccb) + len;
....@@ -195,7 +199,7 @@
195199 BUILD_BUG_ON(sizeof(struct init_sccb) > PAGE_SIZE);
196200
197201 *have_linemode = *have_vt220 = 0;
198
- sccb = (struct init_sccb *) &sclp_early_sccb;
202
+ sccb = (struct init_sccb *) sclp_early_sccb;
199203 receive_mask = disable ? 0 : EVTYP_OPCMD_MASK;
200204 send_mask = disable ? 0 : EVTYP_VT220MSG_MASK | EVTYP_MSG_MASK;
201205 rc = sclp_early_set_event_mask(sccb, receive_mask, send_mask);
....@@ -210,11 +214,11 @@
210214 * Output one or more lines of text on the SCLP console (VT220 and /
211215 * or line-mode).
212216 */
213
-void __sclp_early_printk(const char *str, unsigned int len, unsigned int force)
217
+void __sclp_early_printk(const char *str, unsigned int len)
214218 {
215219 int have_linemode, have_vt220;
216220
217
- if (!force && sclp_init_state != sclp_init_state_uninitialized)
221
+ if (sclp_init_state != sclp_init_state_uninitialized)
218222 return;
219223 if (sclp_early_setup(0, &have_linemode, &have_vt220) != 0)
220224 return;
....@@ -227,10 +231,117 @@
227231
228232 void sclp_early_printk(const char *str)
229233 {
230
- __sclp_early_printk(str, strlen(str), 0);
234
+ __sclp_early_printk(str, strlen(str));
231235 }
232236
233
-void sclp_early_printk_force(const char *str)
237
+int __init sclp_early_read_info(void)
234238 {
235
- __sclp_early_printk(str, strlen(str), 1);
239
+ int i;
240
+ struct read_info_sccb *sccb = &sclp_info_sccb;
241
+ sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
242
+ SCLP_CMDW_READ_SCP_INFO};
243
+
244
+ for (i = 0; i < ARRAY_SIZE(commands); i++) {
245
+ memset(sccb, 0, sizeof(*sccb));
246
+ sccb->header.length = sizeof(*sccb);
247
+ sccb->header.function_code = 0x80;
248
+ sccb->header.control_mask[2] = 0x80;
249
+ if (sclp_early_cmd(commands[i], sccb))
250
+ break;
251
+ if (sccb->header.response_code == 0x10) {
252
+ sclp_info_sccb_valid = 1;
253
+ return 0;
254
+ }
255
+ if (sccb->header.response_code != 0x1f0)
256
+ break;
257
+ }
258
+ return -EIO;
259
+}
260
+
261
+int __init sclp_early_get_info(struct read_info_sccb *info)
262
+{
263
+ if (!sclp_info_sccb_valid)
264
+ return -EIO;
265
+
266
+ *info = sclp_info_sccb;
267
+ return 0;
268
+}
269
+
270
+int __init sclp_early_get_memsize(unsigned long *mem)
271
+{
272
+ unsigned long rnmax;
273
+ unsigned long rnsize;
274
+ struct read_info_sccb *sccb = &sclp_info_sccb;
275
+
276
+ if (!sclp_info_sccb_valid)
277
+ return -EIO;
278
+
279
+ rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
280
+ rnsize = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
281
+ rnsize <<= 20;
282
+ *mem = rnsize * rnmax;
283
+ return 0;
284
+}
285
+
286
+int __init sclp_early_get_hsa_size(unsigned long *hsa_size)
287
+{
288
+ if (!sclp_info_sccb_valid)
289
+ return -EIO;
290
+
291
+ *hsa_size = 0;
292
+ if (sclp_info_sccb.hsa_size)
293
+ *hsa_size = (sclp_info_sccb.hsa_size - 1) * PAGE_SIZE;
294
+ return 0;
295
+}
296
+
297
+#define SCLP_STORAGE_INFO_FACILITY 0x0000400000000000UL
298
+
299
+void __weak __init add_mem_detect_block(u64 start, u64 end) {}
300
+int __init sclp_early_read_storage_info(void)
301
+{
302
+ struct read_storage_sccb *sccb = (struct read_storage_sccb *)sclp_early_sccb;
303
+ int rc, id, max_id = 0;
304
+ unsigned long rn, rzm;
305
+ sclp_cmdw_t command;
306
+ u16 sn;
307
+
308
+ if (!sclp_info_sccb_valid)
309
+ return -EIO;
310
+
311
+ if (!(sclp_info_sccb.facilities & SCLP_STORAGE_INFO_FACILITY))
312
+ return -EOPNOTSUPP;
313
+
314
+ rzm = sclp_info_sccb.rnsize ?: sclp_info_sccb.rnsize2;
315
+ rzm <<= 20;
316
+
317
+ for (id = 0; id <= max_id; id++) {
318
+ memset(sclp_early_sccb, 0, EARLY_SCCB_SIZE);
319
+ sccb->header.length = EARLY_SCCB_SIZE;
320
+ command = SCLP_CMDW_READ_STORAGE_INFO | (id << 8);
321
+ rc = sclp_early_cmd(command, sccb);
322
+ if (rc)
323
+ goto fail;
324
+
325
+ max_id = sccb->max_id;
326
+ switch (sccb->header.response_code) {
327
+ case 0x0010:
328
+ for (sn = 0; sn < sccb->assigned; sn++) {
329
+ if (!sccb->entries[sn])
330
+ continue;
331
+ rn = sccb->entries[sn] >> 16;
332
+ add_mem_detect_block((rn - 1) * rzm, rn * rzm);
333
+ }
334
+ break;
335
+ case 0x0310:
336
+ case 0x0410:
337
+ break;
338
+ default:
339
+ goto fail;
340
+ }
341
+ }
342
+
343
+ return 0;
344
+fail:
345
+ mem_detect.count = 0;
346
+ return -EIO;
236347 }