1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Channel Subsystem tests
4 *
5 * Copyright (c) 2020 IBM Corp
6 *
7 * Authors:
8 * Pierre Morel <pmorel@linux.ibm.com>
9 */
10
11 #include <libcflat.h>
12 #include <interrupt.h>
13 #include <hardware.h>
14
15 #include <asm/arch_def.h>
16 #include <asm/page.h>
17
18 #include <malloc_io.h>
19 #include <css.h>
20
21 #define DEFAULT_CU_TYPE 0x3832 /* virtio-ccw */
22 static unsigned long cu_type = DEFAULT_CU_TYPE;
23
24 static int test_device_sid;
25 static struct senseid *senseid;
26 struct ccw1 *ccw;
27
28 char alignment_test_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
29
test_enumerate(void)30 static void test_enumerate(void)
31 {
32 test_device_sid = css_enumerate();
33 if (test_device_sid & SCHID_ONE) {
34 report_pass("Schid of first I/O device: 0x%08x", test_device_sid);
35 return;
36 }
37 report_fail("No I/O device found");
38 }
39
test_enable(void)40 static void test_enable(void)
41 {
42 int cc;
43
44 if (!test_device_sid) {
45 report_skip("No device");
46 return;
47 }
48
49 cc = css_enable(test_device_sid, IO_SCH_ISC);
50
51 report(cc == 0, "Enable subchannel %08x", test_device_sid);
52 }
53
54 /*
55 * test_sense
56 * Pre-requisites:
57 * - We need the test device as the first recognized
58 * device by the enumeration.
59 */
test_sense(void)60 static void test_sense(void)
61 {
62 int ret;
63 int len;
64
65 if (!test_device_sid) {
66 report_skip("No device");
67 return;
68 }
69
70 ret = css_enable(test_device_sid, IO_SCH_ISC);
71 if (ret) {
72 report_fail("Could not enable the subchannel: %08x",
73 test_device_sid);
74 return;
75 }
76
77 lowcore.io_int_param = 0;
78
79 senseid = alloc_io_mem(sizeof(*senseid), 0);
80 if (!senseid) {
81 report_fail("Allocation of senseid");
82 return;
83 }
84
85 ccw = ccw_alloc(CCW_CMD_SENSE_ID, senseid, sizeof(*senseid), CCW_F_SLI);
86 if (!ccw) {
87 report_fail("Allocation of CCW");
88 goto error_ccw;
89 }
90
91 ret = start_ccw1_chain(test_device_sid, ccw);
92 if (ret) {
93 report_fail("Starting CCW chain");
94 goto error;
95 }
96
97 if (wait_and_check_io_completion(test_device_sid) < 0)
98 goto error;
99
100 /* Test transfer completion */
101 report_prefix_push("ssch transfer completion");
102
103 ret = css_residual_count(test_device_sid);
104
105 if (ret < 0) {
106 report_info("no valid residual count");
107 } else if (ret != 0) {
108 len = sizeof(*senseid) - ret;
109 if (ret && len < CSS_SENSEID_COMMON_LEN) {
110 report_fail("transferred a too short length: %d", ret);
111 goto error;
112 } else if (ret && len)
113 report_info("transferred a shorter length: %d", len);
114 }
115
116 if (senseid->reserved != 0xff) {
117 report_fail("transferred garbage: 0x%02x", senseid->reserved);
118 goto error;
119 }
120
121 report_prefix_pop();
122
123 report_info("reserved 0x%02x cu_type 0x%04x cu_model 0x%02x dev_type 0x%04x dev_model 0x%02x",
124 senseid->reserved, senseid->cu_type, senseid->cu_model,
125 senseid->dev_type, senseid->dev_model);
126
127 report(senseid->cu_type == cu_type, "cu_type expected 0x%04x got 0x%04x",
128 (uint16_t)cu_type, senseid->cu_type);
129
130 error:
131 free_io_mem(ccw, sizeof(*ccw));
132 error_ccw:
133 free_io_mem(senseid, sizeof(*senseid));
134 }
135
sense_id(void)136 static void sense_id(void)
137 {
138 assert(!start_ccw1_chain(test_device_sid, ccw));
139
140 assert(wait_and_check_io_completion(test_device_sid) >= 0);
141 }
142
css_init(void)143 static void css_init(void)
144 {
145 assert(register_io_int_func(css_irq_io) == 0);
146 lowcore.io_int_param = 0;
147
148 report(get_chsc_scsc(), "Store Channel Characteristics");
149 }
150
test_schm(void)151 static void test_schm(void)
152 {
153 if (css_test_general_feature(CSSC_EXTENDED_MEASUREMENT_BLOCK))
154 report_info("Extended measurement block available");
155
156 /* bits 59-63 of MB address must be 0 if MBU is defined */
157 report_prefix_push("Unaligned operand");
158 expect_pgm_int();
159 schm((void *)0x01, SCHM_MBU);
160 check_pgm_int_code(PGM_INT_CODE_OPERAND);
161 report_prefix_pop();
162
163 /* bits 36-61 of register 1 (flags) must be 0 */
164 report_prefix_push("Bad flags");
165 expect_pgm_int();
166 schm(NULL, 0xfffffffc);
167 check_pgm_int_code(PGM_INT_CODE_OPERAND);
168 report_prefix_pop();
169
170 /* SCHM is a privilege operation */
171 report_prefix_push("Privilege");
172 enter_pstate();
173 expect_pgm_int();
174 schm(NULL, SCHM_MBU);
175 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
176 report_prefix_pop();
177
178 /* Normal operation */
179 report_prefix_push("Normal operation");
180 schm(NULL, SCHM_MBU);
181 report_pass("SCHM call without address");
182 report_prefix_pop();
183 }
184
185 #define SCHM_UPDATE_CNT 10
start_measuring(uint64_t mbo,uint16_t mbi,bool fmt1)186 static bool start_measuring(uint64_t mbo, uint16_t mbi, bool fmt1)
187 {
188 int i;
189
190 senseid = alloc_io_mem(sizeof(*senseid), 0);
191 assert(senseid);
192
193 ccw = ccw_alloc(CCW_CMD_SENSE_ID, senseid, sizeof(*senseid), CCW_F_SLI);
194 assert(ccw);
195
196 if (!css_enable_mb(test_device_sid, mbo, mbi, PMCW_MBUE, fmt1)) {
197 report_abort("Enabling measurement block failed");
198 return false;
199 }
200
201 for (i = 0; i < SCHM_UPDATE_CNT; i++)
202 sense_id();
203
204 free_io_mem(ccw, sizeof(*ccw));
205 free_io_mem(senseid, sizeof(*senseid));
206
207 return true;
208 }
209
210 /*
211 * test_schm_fmt0:
212 * With measurement block format 0 a memory space is shared
213 * by all subchannels, each subchannel can provide an index
214 * for the measurement block facility to store the measurements.
215 */
test_schm_fmt0(void)216 static void test_schm_fmt0(void)
217 {
218 struct measurement_block_format0 *mb0;
219 int shared_mb_size = 2 * sizeof(struct measurement_block_format0);
220
221 if (!test_device_sid) {
222 report_skip("No device");
223 return;
224 }
225
226 /* Allocate zeroed Measurement block */
227 mb0 = alloc_io_mem(shared_mb_size, 0);
228 if (!mb0) {
229 report_abort("measurement_block_format0 allocation failed");
230 return;
231 }
232
233 schm(NULL, 0); /* Stop any previous measurement */
234 schm(mb0, SCHM_MBU);
235
236 /* Expect success */
237 report_prefix_push("Valid MB address and index 0");
238 report(start_measuring(0, 0, false) &&
239 mb0->ssch_rsch_count == SCHM_UPDATE_CNT,
240 "SSCH measured %d", mb0->ssch_rsch_count);
241 report_prefix_pop();
242
243 /* Clear the measurement block for the next test */
244 memset(mb0, 0, shared_mb_size);
245
246 /* Expect success */
247 report_prefix_push("Valid MB address and index 1");
248 if (start_measuring(0, 1, false))
249 report(mb0[1].ssch_rsch_count == SCHM_UPDATE_CNT,
250 "SSCH measured %d", mb0[1].ssch_rsch_count);
251 report_prefix_pop();
252
253 /* Stop the measurement */
254 css_disable_mb(test_device_sid);
255 schm(NULL, 0);
256
257 free_io_mem(mb0, shared_mb_size);
258 }
259
msch_with_wrong_fmt1_mbo(unsigned int schid,uint64_t mb)260 static void msch_with_wrong_fmt1_mbo(unsigned int schid, uint64_t mb)
261 {
262 struct pmcw *pmcw = &schib.pmcw;
263 int cc;
264
265 /* Read the SCHIB for this subchannel */
266 cc = stsch(schid, &schib);
267 if (cc) {
268 report_fail("stsch: sch %08x failed with cc=%d", schid, cc);
269 return;
270 }
271
272 /* Update the SCHIB to enable the measurement block */
273 pmcw->flags |= PMCW_MBUE;
274 pmcw->flags2 |= PMCW_MBF1;
275 schib.mbo = mb;
276
277 /* Tell the CSS we want to modify the subchannel */
278 expect_pgm_int();
279 cc = msch(schid, &schib);
280 check_pgm_int_code(PGM_INT_CODE_OPERAND);
281 }
282
283 /*
284 * test_schm_fmt1:
285 * With measurement block format 1 the measurement block is
286 * dedicated to a subchannel.
287 */
test_schm_fmt1(void)288 static void test_schm_fmt1(void)
289 {
290 struct measurement_block_format1 *mb1;
291
292 if (!test_device_sid) {
293 report_skip("No device");
294 return;
295 }
296
297 if (!css_test_general_feature(CSSC_EXTENDED_MEASUREMENT_BLOCK)) {
298 report_skip("Extended measurement block not available");
299 return;
300 }
301
302 /* Allocate zeroed Measurement block */
303 mb1 = alloc_io_mem(sizeof(struct measurement_block_format1), 0);
304 if (!mb1) {
305 report_abort("measurement_block_format1 allocation failed");
306 return;
307 }
308
309 schm(NULL, 0); /* Stop any previous measurement */
310 schm(0, SCHM_MBU);
311
312 /* Expect error for non aligned MB */
313 report_prefix_push("Unaligned MB origin");
314 msch_with_wrong_fmt1_mbo(test_device_sid, (uint64_t)mb1 + 1);
315 report_prefix_pop();
316
317 /* Clear the measurement block for the next test */
318 memset(mb1, 0, sizeof(*mb1));
319
320 /* Expect success */
321 report_prefix_push("Valid MB origin");
322 if (start_measuring((u64)mb1, 0, true))
323 report(mb1->ssch_rsch_count == SCHM_UPDATE_CNT,
324 "SSCH measured %d", mb1->ssch_rsch_count);
325 report_prefix_pop();
326
327 /* Stop the measurement */
328 css_disable_mb(test_device_sid);
329 schm(NULL, 0);
330
331 free_io_mem(mb1, sizeof(struct measurement_block_format1));
332 }
333
test_msch(void)334 static void test_msch(void)
335 {
336 int invalid_pmcw_flags[] = {0, 1, 6, 7};
337 struct schib test_schib;
338 uint16_t old_pmcw_flags;
339 const int align_to = 4;
340 int invalid_flag;
341 int cc;
342
343 if (!test_device_sid) {
344 report_skip("No device");
345 return;
346 }
347
348 cc = stsch(test_device_sid, &schib);
349 if (cc) {
350 report_fail("stsch: sch %08x failed with cc=%d", test_device_sid, cc);
351 return;
352 }
353
354 report_prefix_push("Unaligned");
355 for (int i = 1; i < align_to; i *= 2) {
356 report_prefix_pushf("%d", i);
357
358 expect_pgm_int();
359 msch(test_device_sid, (struct schib *)(alignment_test_page + i));
360 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
361
362 report_prefix_pop();
363 }
364 report_prefix_pop();
365
366 report_prefix_push("Invalid SCHIB");
367 old_pmcw_flags = schib.pmcw.flags;
368 for (int i = 0; i < ARRAY_SIZE(invalid_pmcw_flags); i++) {
369 invalid_flag = invalid_pmcw_flags[i];
370
371 report_prefix_pushf("PMCW flag bit %d set", invalid_flag);
372
373 schib.pmcw.flags = old_pmcw_flags | BIT(15 - invalid_flag);
374 expect_pgm_int();
375 msch(test_device_sid, &schib);
376 check_pgm_int_code(PGM_INT_CODE_OPERAND);
377
378 cc = stsch(test_device_sid, &test_schib);
379 report(!cc, "STSCH succeeded");
380 report(!(test_schib.pmcw.flags & BIT(15 - invalid_flag)), "Clear on STSCH");
381
382 report_prefix_pop();
383 }
384 report_prefix_pop();
385
386 schib.pmcw.flags = old_pmcw_flags;
387 }
388
check_stcrw_no_crw_available(void)389 static void check_stcrw_no_crw_available(void)
390 {
391 uint32_t crw = 0xfeedc0fe;
392 int cc;
393
394 report_prefix_push("No CRW available");
395 cc = stcrw(&crw);
396 report(cc == 1, "cc == 1");
397 report(!crw, "stored zeroes in crw");
398 report_prefix_pop();
399 }
400
check_stcrw_crw_available(void)401 static int check_stcrw_crw_available(void)
402 {
403 const uint32_t magic = 0xfeedc0fe;
404 uint32_t crw = magic;
405 int cc;
406
407 report_prefix_push("CRW available");
408 cc = stcrw(&crw);
409 report(!cc, "cc is zero");
410 report(crw != magic, "stored crw");
411 report_prefix_pop();
412
413 return crw;
414 }
415
crw_get_rsc(uint32_t crw)416 static uint32_t crw_get_rsc(uint32_t crw)
417 {
418 const int rsc_begin = 4;
419 const int rsc_end = 8;
420
421 return (crw & GENMASK(31 - rsc_begin, 31 - rsc_end)) >> 24;
422 }
423
424 #define CRW_RSC_CHP 4
test_stcrw(void)425 static void test_stcrw(void)
426 {
427 const int align_to = 4;
428 int res;
429 uint32_t crw;
430
431 if (!test_device_sid) {
432 report_skip("No device");
433 return;
434 }
435
436 report_prefix_push("Unaligned");
437 for (int i = 1; i < align_to; i *= 2) {
438 report_prefix_pushf("%d", i);
439
440 expect_pgm_int();
441 stcrw((uint32_t *)(alignment_test_page + i));
442 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
443
444 report_prefix_pop();
445 }
446 report_prefix_pop();
447
448 report_prefix_push("No CRW available initally");
449 check_stcrw_no_crw_available();
450 report_prefix_pop();
451
452 res = css_generate_crw(test_device_sid);
453 if (res) {
454 report_skip("Couldn't generate CRW");
455 report_prefix_pop();
456 return;
457 }
458
459 crw = check_stcrw_crw_available();
460
461 report_prefix_push("CRW available");
462 report(crw_get_rsc(crw) == CRW_RSC_CHP, "CRW has Channel Path RSC");
463 report_prefix_pop();
464
465 report_prefix_push("No more CRWs pending");
466 check_stcrw_no_crw_available();
467 report_prefix_pop();
468 }
469
test_ssch(void)470 static void test_ssch(void)
471 {
472 const int align_to = 4;
473 struct orb orb;
474
475 if (!test_device_sid) {
476 report_skip("No device");
477 return;
478 }
479
480 report_prefix_push("Unaligned");
481 for (int i = 1; i < align_to; i *= 2) {
482 report_prefix_pushf("%d", i);
483
484 expect_pgm_int();
485 ssch(test_device_sid, (struct orb *)(alignment_test_page + i));
486 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
487
488 report_prefix_pop();
489 }
490 report_prefix_pop();
491
492 report_prefix_push("Invalid ORB");
493
494 memset(&orb, 0xff, sizeof(orb));
495 expect_pgm_int();
496 ssch(test_device_sid, &orb);
497 check_pgm_int_code(PGM_INT_CODE_OPERAND);
498
499 report_prefix_pop();
500 }
501
test_stsch(void)502 static void test_stsch(void)
503 {
504 const int align_to = 4;
505 struct schib schib;
506 int cc;
507
508 if (!test_device_sid) {
509 report_skip("No device");
510 return;
511 }
512
513 report_prefix_push("Unaligned");
514 for (int i = 1; i < align_to; i *= 2) {
515 report_prefix_pushf("%d", i);
516
517 expect_pgm_int();
518 stsch(test_device_sid, (struct schib *)(alignment_test_page + i));
519 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
520
521 report_prefix_pop();
522 }
523 report_prefix_pop();
524
525 report_prefix_push("Invalid subchannel number");
526 cc = stsch(0x0001ffff, &schib);
527 report(cc == 3, "Channel not operational");
528 report_prefix_pop();
529
530 /*
531 * No matter if multiple-subchannel-set facility is installed, bit 47
532 * always needs to be 1.
533 */
534 report_prefix_push("Bit 47 in SID is zero");
535 expect_pgm_int();
536 stsch(0x0000ffff, &schib);
537 check_pgm_int_code(PGM_INT_CODE_OPERAND);
538 report_prefix_pop();
539 }
540
541 /*
542 * According to architecture MSCH does ignore bit 5 of the second word
543 * but STSCH will store bit 5 as zero.
544 */
test_pmcw_bit5(void)545 static void test_pmcw_bit5(void)
546 {
547 int cc;
548 uint16_t old_pmcw_flags;
549
550 cc = stsch(test_device_sid, &schib);
551 if (cc) {
552 report_fail("stsch: sch %08x failed with cc=%d", test_device_sid, cc);
553 return;
554 }
555 old_pmcw_flags = schib.pmcw.flags;
556
557 report_prefix_push("Bit 5 set");
558
559 schib.pmcw.flags = old_pmcw_flags | BIT(15 - 5);
560 cc = msch(test_device_sid, &schib);
561 report(!cc, "MSCH cc == 0");
562
563 cc = stsch(test_device_sid, &schib);
564 report(!cc, "STSCH cc == 0");
565 report(!(schib.pmcw.flags & BIT(15 - 5)), "STSCH PMCW Bit 5 is clear");
566
567 report_prefix_pop();
568
569 report_prefix_push("Bit 5 clear");
570
571 schib.pmcw.flags = old_pmcw_flags & ~BIT(15 - 5);
572 cc = msch(test_device_sid, &schib);
573 report(!cc, "MSCH cc == 0");
574
575 cc = stsch(test_device_sid, &schib);
576 report(!cc, "STSCH cc == 0");
577 report(!(schib.pmcw.flags & BIT(15 - 5)), "STSCH PMCW Bit 5 is clear");
578
579 report_prefix_pop();
580 }
581
test_tsch(void)582 static void test_tsch(void)
583 {
584 const int align_to = 4;
585 struct irb irb;
586 int cc;
587
588 if (!test_device_sid) {
589 report_skip("No device");
590 return;
591 }
592
593 report_prefix_push("Unaligned");
594 for (int i = 1; i < align_to; i *= 2) {
595 report_prefix_pushf("%d", i);
596
597 expect_pgm_int();
598 tsch(test_device_sid, (struct irb *)(alignment_test_page + i));
599 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
600
601 report_prefix_pop();
602 }
603 report_prefix_pop();
604
605 report_prefix_push("Invalid subchannel number");
606 cc = tsch(0x0001ffff, &irb);
607 report(cc == 3, "Channel not operational");
608 report_prefix_pop();
609
610 report_prefix_push("Bit 47 in SID is zero");
611 expect_pgm_int();
612 tsch(0x0000ffff, &irb);
613 check_pgm_int_code(PGM_INT_CODE_OPERAND);
614 report_prefix_pop();
615 }
616
617 static struct {
618 const char *name;
619 void (*func)(void);
620 } tests[] = {
621 /* The css_init test is needed to initialize the CSS Characteristics */
622 { "initialize CSS (chsc)", css_init },
623 { "enumerate (stsch)", test_enumerate },
624 { "enable (msch)", test_enable },
625 { "sense (ssch/tsch)", test_sense },
626 { "measurement block (schm)", test_schm },
627 { "measurement block format0", test_schm_fmt0 },
628 { "measurement block format1", test_schm_fmt1 },
629 { "msch", test_msch },
630 { "stcrw", test_stcrw },
631 { "ssch", test_ssch },
632 { "stsch", test_stsch },
633 { "pmcw bit 5 ignored", test_pmcw_bit5 },
634 { "tsch", test_tsch },
635 { NULL, NULL }
636 };
637
main(int argc,char * argv[])638 int main(int argc, char *argv[])
639 {
640 int i;
641
642 report_prefix_push("Channel Subsystem");
643
644 /* There's no guarantee where our devices are without qemu */
645 if (!host_is_qemu()) {
646 report_skip("Not running under QEMU");
647 goto done;
648 }
649
650 enable_io_isc(0x80 >> IO_SCH_ISC);
651 for (i = 0; tests[i].name; i++) {
652 report_prefix_push(tests[i].name);
653 tests[i].func();
654 report_prefix_pop();
655 }
656
657 done:
658 report_prefix_pop();
659 return report_summary();
660 }
661