1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * SBI verification 4 * 5 * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com> 6 */ 7 #include <libcflat.h> 8 #include <alloc_page.h> 9 #include <cpumask.h> 10 #include <limits.h> 11 #include <memregions.h> 12 #include <on-cpus.h> 13 #include <rand.h> 14 #include <setjmp.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <vmalloc.h> 18 19 #include <asm/barrier.h> 20 #include <asm/csr.h> 21 #include <asm/delay.h> 22 #include <asm/io.h> 23 #include <asm/mmu.h> 24 #include <asm/page.h> 25 #include <asm/processor.h> 26 #include <asm/sbi.h> 27 #include <asm/setup.h> 28 #include <asm/smp.h> 29 #include <asm/timer.h> 30 31 #include "sbi-tests.h" 32 33 #define HIGH_ADDR_BOUNDARY ((phys_addr_t)1 << 32) 34 35 void check_sse(void); 36 void check_fwft(void); 37 38 static long __labs(long a) 39 { 40 return __builtin_labs(a); 41 } 42 43 static void help(void) 44 { 45 puts("Test SBI\n"); 46 puts("An environ must be provided where expected values are given.\n"); 47 } 48 49 static struct sbiret sbi_base(int fid, unsigned long arg0) 50 { 51 return sbi_ecall(SBI_EXT_BASE, fid, arg0, 0, 0, 0, 0, 0); 52 } 53 54 static struct sbiret sbi_dbcn_write(unsigned long num_bytes, unsigned long base_addr_lo, 55 unsigned long base_addr_hi) 56 { 57 return sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE, 58 num_bytes, base_addr_lo, base_addr_hi, 0, 0, 0); 59 } 60 61 static struct sbiret sbi_dbcn_write_byte(uint8_t byte) 62 { 63 return sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE_BYTE, byte, 0, 0, 0, 0, 0); 64 } 65 66 static struct sbiret sbi_hart_suspend_raw(unsigned long suspend_type, unsigned long resume_addr, unsigned long opaque) 67 { 68 return sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_SUSPEND, suspend_type, resume_addr, opaque, 0, 0, 0); 69 } 70 71 static struct sbiret sbi_system_suspend_raw(unsigned long sleep_type, unsigned long resume_addr, unsigned long opaque) 72 { 73 return sbi_ecall(SBI_EXT_SUSP, 0, sleep_type, resume_addr, opaque, 0, 0, 0); 74 } 75 76 void sbi_bad_fid(int ext) 77 { 78 struct sbiret ret = sbi_ecall(ext, 0xbad, 0, 0, 0, 0, 0, 0); 79 sbiret_report_error(&ret, SBI_ERR_NOT_SUPPORTED, "Bad FID"); 80 } 81 82 static void start_cpu(void *data) 83 { 84 /* nothing to do */ 85 } 86 87 static void stop_cpu(void *data) 88 { 89 struct sbiret ret = sbi_hart_stop(); 90 assert_msg(0, "cpu%d (hartid = %lx) failed to stop with sbiret.error %ld", 91 smp_processor_id(), current_thread_info()->hartid, ret.error); 92 } 93 94 static int rand_online_cpu(prng_state *ps) 95 { 96 int cpu, me = smp_processor_id(); 97 98 for (;;) { 99 cpu = prng32(ps) % nr_cpus; 100 cpu = cpumask_next(cpu - 1, &cpu_present_mask); 101 if (cpu != nr_cpus && cpu != me && cpu_present(cpu)) 102 break; 103 } 104 105 return cpu; 106 } 107 108 static void split_phys_addr(phys_addr_t paddr, unsigned long *hi, unsigned long *lo) 109 { 110 *lo = (unsigned long)paddr; 111 *hi = 0; 112 if (__riscv_xlen == 32) 113 *hi = (unsigned long)(paddr >> 32); 114 } 115 116 static bool check_addr(phys_addr_t start, phys_addr_t size) 117 { 118 struct mem_region *r = memregions_find(start); 119 return r && r->end - start >= size && r->flags == MR_F_UNUSED; 120 } 121 122 static phys_addr_t get_highest_addr(void) 123 { 124 phys_addr_t highest_end = 0; 125 struct mem_region *r; 126 127 for (r = mem_regions; r->end; ++r) { 128 if (r->end > highest_end) 129 highest_end = r->end; 130 } 131 132 return highest_end - 1; 133 } 134 135 static bool get_invalid_addr(phys_addr_t *paddr, bool allow_default) 136 { 137 if (env_enabled("INVALID_ADDR_AUTO")) { 138 *paddr = get_highest_addr() + 1; 139 return true; 140 } else if (allow_default && !getenv("INVALID_ADDR")) { 141 *paddr = -1ul; 142 return true; 143 } else if (env_or_skip("INVALID_ADDR")) { 144 *paddr = strtoull(getenv("INVALID_ADDR"), NULL, 0); 145 return true; 146 } 147 148 return false; 149 } 150 151 static void timer_setup(void (*handler)(struct pt_regs *)) 152 { 153 install_irq_handler(IRQ_S_TIMER, handler); 154 timer_irq_enable(); 155 } 156 157 static void timer_teardown(void) 158 { 159 timer_irq_disable(); 160 timer_stop(); 161 install_irq_handler(IRQ_S_TIMER, NULL); 162 } 163 164 static void check_base(void) 165 { 166 struct sbiret ret; 167 long expected; 168 169 report_prefix_push("base"); 170 171 sbi_bad_fid(SBI_EXT_BASE); 172 173 ret = sbi_base(SBI_EXT_BASE_GET_SPEC_VERSION, 0); 174 175 report_prefix_push("spec_version"); 176 if (env_or_skip("SBI_SPEC_VERSION")) { 177 expected = (long)strtoul(getenv("SBI_SPEC_VERSION"), NULL, 0); 178 assert_msg(!(expected & BIT(31)), "SBI spec version bit 31 must be zero"); 179 assert_msg(__riscv_xlen == 32 || !(expected >> 32), "SBI spec version bits greater than 31 must be zero"); 180 sbiret_check(&ret, 0, expected); 181 } 182 report_prefix_pop(); 183 184 ret.value &= 0x7ffffffful; 185 186 if (ret.error || ret.value < 2) { 187 report_skip("SBI spec version 0.2 or higher required"); 188 return; 189 } 190 191 report_prefix_push("impl_id"); 192 if (env_or_skip("SBI_IMPL_ID")) { 193 expected = (long)strtoul(getenv("SBI_IMPL_ID"), NULL, 0); 194 ret = sbi_base(SBI_EXT_BASE_GET_IMP_ID, 0); 195 sbiret_check(&ret, 0, expected); 196 } 197 report_prefix_pop(); 198 199 report_prefix_push("impl_version"); 200 if (env_or_skip("SBI_IMPL_VERSION")) { 201 expected = (long)strtoul(getenv("SBI_IMPL_VERSION"), NULL, 0); 202 ret = sbi_base(SBI_EXT_BASE_GET_IMP_VERSION, 0); 203 sbiret_check(&ret, 0, expected); 204 } 205 report_prefix_pop(); 206 207 report_prefix_push("probe_ext"); 208 expected = getenv("SBI_PROBE_EXT") ? (long)strtoul(getenv("SBI_PROBE_EXT"), NULL, 0) : 1; 209 ret = sbi_base(SBI_EXT_BASE_PROBE_EXT, SBI_EXT_BASE); 210 sbiret_check(&ret, 0, expected); 211 report_prefix_push("unavailable"); 212 ret = sbi_base(SBI_EXT_BASE_PROBE_EXT, 0xb000000); 213 sbiret_check(&ret, 0, 0); 214 report_prefix_popn(2); 215 216 report_prefix_push("mvendorid"); 217 if (env_or_skip("MVENDORID")) { 218 expected = (long)strtoul(getenv("MVENDORID"), NULL, 0); 219 assert(__riscv_xlen == 32 || !(expected >> 32)); 220 ret = sbi_base(SBI_EXT_BASE_GET_MVENDORID, 0); 221 sbiret_check(&ret, 0, expected); 222 } 223 report_prefix_pop(); 224 225 report_prefix_push("marchid"); 226 if (env_or_skip("MARCHID")) { 227 expected = (long)strtoul(getenv("MARCHID"), NULL, 0); 228 ret = sbi_base(SBI_EXT_BASE_GET_MARCHID, 0); 229 sbiret_check(&ret, 0, expected); 230 } 231 report_prefix_pop(); 232 233 report_prefix_push("mimpid"); 234 if (env_or_skip("MIMPID")) { 235 expected = (long)strtoul(getenv("MIMPID"), NULL, 0); 236 ret = sbi_base(SBI_EXT_BASE_GET_MIMPID, 0); 237 sbiret_check(&ret, 0, expected); 238 } 239 report_prefix_popn(2); 240 } 241 242 struct timer_info { 243 bool timer_works; 244 bool mask_timer_irq; 245 bool timer_irq_set; 246 bool timer_irq_cleared; 247 unsigned long timer_irq_count; 248 }; 249 250 static struct timer_info timer_info; 251 252 static bool timer_irq_pending(void) 253 { 254 return csr_read(CSR_SIP) & IP_TIP; 255 } 256 257 static void timer_irq_handler(struct pt_regs *regs) 258 { 259 timer_info.timer_works = true; 260 261 if (timer_info.timer_irq_count < ULONG_MAX) 262 ++timer_info.timer_irq_count; 263 264 if (timer_irq_pending()) 265 timer_info.timer_irq_set = true; 266 267 if (timer_info.mask_timer_irq) 268 timer_irq_disable(); 269 else 270 sbi_set_timer(ULONG_MAX); 271 272 if (!timer_irq_pending()) 273 timer_info.timer_irq_cleared = true; 274 } 275 276 static void timer_check_set_timer(bool mask_timer_irq) 277 { 278 struct sbiret ret; 279 unsigned long begin, end, duration; 280 const char *mask_test_str = mask_timer_irq ? " for mask irq test" : ""; 281 unsigned long d = getenv("SBI_TIMER_DELAY") ? strtol(getenv("SBI_TIMER_DELAY"), NULL, 0) : 200000; 282 unsigned long margin = getenv("SBI_TIMER_MARGIN") ? strtol(getenv("SBI_TIMER_MARGIN"), NULL, 0) : 200000; 283 284 d = usec_to_cycles(d); 285 margin = usec_to_cycles(margin); 286 287 timer_info = (struct timer_info){ .mask_timer_irq = mask_timer_irq }; 288 begin = timer_get_cycles(); 289 ret = sbi_set_timer(begin + d); 290 291 report(!ret.error, "set timer%s", mask_test_str); 292 if (ret.error) 293 report_info("set timer%s failed with %ld\n", mask_test_str, ret.error); 294 295 while ((end = timer_get_cycles()) <= (begin + d + margin) && !timer_info.timer_works) 296 cpu_relax(); 297 298 report(timer_info.timer_works, "timer interrupt received%s", mask_test_str); 299 report(timer_info.timer_irq_set, "pending timer interrupt bit set in irq handler%s", mask_test_str); 300 301 if (!mask_timer_irq) { 302 report(timer_info.timer_irq_set && timer_info.timer_irq_cleared, 303 "pending timer interrupt bit cleared by setting timer to -1"); 304 } 305 306 if (timer_info.timer_works) { 307 duration = end - begin; 308 report(duration >= d && duration <= (d + margin), "timer delay honored%s", mask_test_str); 309 } 310 311 report(timer_info.timer_irq_count == 1, "timer interrupt received exactly once%s", mask_test_str); 312 } 313 314 static void check_time(void) 315 { 316 bool pending; 317 318 report_prefix_push("time"); 319 320 if (!sbi_probe(SBI_EXT_TIME)) { 321 report_skip("time extension not available"); 322 report_prefix_pop(); 323 return; 324 } 325 326 sbi_bad_fid(SBI_EXT_TIME); 327 328 report_prefix_push("set_timer"); 329 330 install_irq_handler(IRQ_S_TIMER, timer_irq_handler); 331 local_irq_enable(); 332 timer_irq_enable(); 333 334 timer_check_set_timer(false); 335 336 if (csr_read(CSR_SIE) & IE_TIE) 337 timer_check_set_timer(true); 338 else 339 report_skip("timer irq enable bit is not writable, skipping mask irq test"); 340 341 timer_irq_disable(); 342 sbi_set_timer(0); 343 pending = timer_irq_pending(); 344 report(pending, "timer immediately pending by setting timer to 0"); 345 sbi_set_timer(ULONG_MAX); 346 if (pending) 347 report(!timer_irq_pending(), "pending timer cleared while masked"); 348 else 349 report_skip("timer is not pending, skipping timer cleared while masked test"); 350 351 local_irq_disable(); 352 install_irq_handler(IRQ_S_TIMER, NULL); 353 354 report_prefix_popn(2); 355 } 356 357 static bool ipi_received[NR_CPUS]; 358 static bool ipi_timeout[NR_CPUS]; 359 static cpumask_t ipi_done; 360 361 static void ipi_timeout_handler(struct pt_regs *regs) 362 { 363 timer_stop(); 364 ipi_timeout[smp_processor_id()] = true; 365 } 366 367 static void ipi_irq_handler(struct pt_regs *regs) 368 { 369 ipi_ack(); 370 ipi_received[smp_processor_id()] = true; 371 } 372 373 static void ipi_hart_wait(void *data) 374 { 375 unsigned long timeout = (unsigned long)data; 376 int me = smp_processor_id(); 377 378 install_irq_handler(IRQ_S_SOFT, ipi_irq_handler); 379 install_irq_handler(IRQ_S_TIMER, ipi_timeout_handler); 380 local_ipi_enable(); 381 timer_irq_enable(); 382 local_irq_enable(); 383 384 timer_start(timeout); 385 while (!READ_ONCE(ipi_received[me]) && !READ_ONCE(ipi_timeout[me])) 386 cpu_relax(); 387 local_irq_disable(); 388 timer_stop(); 389 local_ipi_disable(); 390 timer_irq_disable(); 391 install_irq_handler(IRQ_S_SOFT, NULL); 392 install_irq_handler(IRQ_S_TIMER, NULL); 393 394 cpumask_set_cpu(me, &ipi_done); 395 } 396 397 static void ipi_hart_check(cpumask_t *mask) 398 { 399 int cpu; 400 401 for_each_cpu(cpu, mask) { 402 if (ipi_timeout[cpu]) { 403 const char *rec = ipi_received[cpu] ? "but was still received" 404 : "and has still not been received"; 405 report_fail("ipi timed out on cpu%d %s", cpu, rec); 406 } 407 408 ipi_timeout[cpu] = false; 409 ipi_received[cpu] = false; 410 } 411 } 412 413 static void check_ipi(void) 414 { 415 unsigned long d = getenv("SBI_IPI_TIMEOUT") ? strtol(getenv("SBI_IPI_TIMEOUT"), NULL, 0) : 200000; 416 int nr_cpus_present = cpumask_weight(&cpu_present_mask); 417 int me = smp_processor_id(); 418 unsigned long max_hartid = 0; 419 unsigned long hartid1, hartid2; 420 cpumask_t ipi_receivers; 421 static prng_state ps; 422 struct sbiret ret; 423 int cpu, cpu2; 424 425 ps = prng_init(0xDEADBEEF); 426 427 report_prefix_push("ipi"); 428 429 if (!sbi_probe(SBI_EXT_IPI)) { 430 report_skip("ipi extension not available"); 431 report_prefix_pop(); 432 return; 433 } 434 435 sbi_bad_fid(SBI_EXT_IPI); 436 437 if (nr_cpus_present < 2) { 438 report_skip("At least 2 cpus required"); 439 report_prefix_pop(); 440 return; 441 } 442 443 report_prefix_push("random hart"); 444 cpumask_clear(&ipi_done); 445 cpumask_clear(&ipi_receivers); 446 cpu = rand_online_cpu(&ps); 447 cpumask_set_cpu(cpu, &ipi_receivers); 448 on_cpu_async(cpu, ipi_hart_wait, (void *)d); 449 ret = sbi_send_ipi_cpu(cpu); 450 report(ret.error == SBI_SUCCESS, "ipi returned success"); 451 while (!cpumask_equal(&ipi_done, &ipi_receivers)) 452 cpu_relax(); 453 ipi_hart_check(&ipi_receivers); 454 report_prefix_pop(); 455 456 report_prefix_push("two in hart_mask"); 457 458 if (nr_cpus_present < 3) { 459 report_skip("3 cpus required"); 460 goto end_two; 461 } 462 463 cpu = rand_online_cpu(&ps); 464 hartid1 = cpus[cpu].hartid; 465 hartid2 = 0; 466 for_each_present_cpu(cpu2) { 467 if (cpu2 == cpu || cpu2 == me) 468 continue; 469 hartid2 = cpus[cpu2].hartid; 470 if (__labs(hartid2 - hartid1) < BITS_PER_LONG) 471 break; 472 } 473 if (cpu2 == nr_cpus) { 474 report_skip("hartids are too sparse"); 475 goto end_two; 476 } 477 478 cpumask_clear(&ipi_done); 479 cpumask_clear(&ipi_receivers); 480 cpumask_set_cpu(cpu, &ipi_receivers); 481 cpumask_set_cpu(cpu2, &ipi_receivers); 482 on_cpu_async(cpu, ipi_hart_wait, (void *)d); 483 on_cpu_async(cpu2, ipi_hart_wait, (void *)d); 484 ret = sbi_send_ipi((1UL << __labs(hartid2 - hartid1)) | 1UL, hartid1 < hartid2 ? hartid1 : hartid2); 485 report(ret.error == SBI_SUCCESS, "ipi returned success"); 486 while (!cpumask_equal(&ipi_done, &ipi_receivers)) 487 cpu_relax(); 488 ipi_hart_check(&ipi_receivers); 489 end_two: 490 report_prefix_pop(); 491 492 report_prefix_push("broadcast"); 493 cpumask_clear(&ipi_done); 494 cpumask_copy(&ipi_receivers, &cpu_present_mask); 495 cpumask_clear_cpu(me, &ipi_receivers); 496 on_cpumask_async(&ipi_receivers, ipi_hart_wait, (void *)d); 497 ret = sbi_send_ipi_broadcast(); 498 report(ret.error == SBI_SUCCESS, "ipi returned success"); 499 while (!cpumask_equal(&ipi_done, &ipi_receivers)) 500 cpu_relax(); 501 ipi_hart_check(&ipi_receivers); 502 report_prefix_pop(); 503 504 report_prefix_push("invalid parameters"); 505 506 for_each_present_cpu(cpu) { 507 if (cpus[cpu].hartid > max_hartid) 508 max_hartid = cpus[cpu].hartid; 509 } 510 511 /* Test no targets */ 512 ret = sbi_send_ipi(0, 0); 513 sbiret_report_error(&ret, SBI_SUCCESS, "no targets, hart_mask_base is 0"); 514 ret = sbi_send_ipi(0, 1); 515 sbiret_report_error(&ret, SBI_SUCCESS, "no targets, hart_mask_base is 1"); 516 517 /* Try the next higher hartid than the max */ 518 bool kfail = __sbi_get_imp_id() == SBI_IMPL_OPENSBI && 519 __sbi_get_imp_version() < sbi_impl_opensbi_mk_version(1, 7); 520 ret = sbi_send_ipi(2, max_hartid); 521 sbiret_kfail_error(kfail, &ret, SBI_ERR_INVALID_PARAM, "hart_mask"); 522 ret = sbi_send_ipi(1, max_hartid + 1); 523 sbiret_kfail_error(kfail, &ret, SBI_ERR_INVALID_PARAM, "hart_mask_base"); 524 525 report_prefix_pop(); 526 527 report_prefix_pop(); 528 } 529 530 unsigned char sbi_hsm_stop_hart[NR_CPUS]; 531 unsigned char sbi_hsm_hart_start_checks[NR_CPUS]; 532 unsigned char sbi_hsm_non_retentive_hart_suspend_checks[NR_CPUS]; 533 534 static const char * const hart_state_str[] = { 535 [SBI_EXT_HSM_STARTED] = "started", 536 [SBI_EXT_HSM_STOPPED] = "stopped", 537 [SBI_EXT_HSM_SUSPENDED] = "suspended", 538 }; 539 struct hart_state_transition_info { 540 enum sbi_ext_hsm_sid initial_state; 541 enum sbi_ext_hsm_sid intermediate_state; 542 enum sbi_ext_hsm_sid final_state; 543 }; 544 static cpumask_t sbi_hsm_started_hart_checks; 545 static bool sbi_hsm_invalid_hartid_check; 546 static bool sbi_hsm_timer_fired; 547 extern void sbi_hsm_check_hart_start(void); 548 extern void sbi_hsm_check_non_retentive_suspend(void); 549 550 static void hsm_timer_irq_handler(struct pt_regs *regs) 551 { 552 timer_stop(); 553 sbi_hsm_timer_fired = true; 554 } 555 556 static void hart_check_already_started(void *data) 557 { 558 struct sbiret ret; 559 unsigned long hartid = current_thread_info()->hartid; 560 int me = smp_processor_id(); 561 562 ret = sbi_hart_start(hartid, virt_to_phys(&start_cpu), 0); 563 564 if (ret.error == SBI_ERR_ALREADY_AVAILABLE) 565 cpumask_set_cpu(me, &sbi_hsm_started_hart_checks); 566 } 567 568 static void hart_start_invalid_hartid(void *data) 569 { 570 struct sbiret ret; 571 572 ret = sbi_hart_start(-1UL, virt_to_phys(&start_cpu), 0); 573 574 if (ret.error == SBI_ERR_INVALID_PARAM) 575 sbi_hsm_invalid_hartid_check = true; 576 } 577 578 static cpumask_t hsm_suspend_not_supported; 579 580 static void ipi_nop(struct pt_regs *regs) 581 { 582 ipi_ack(); 583 } 584 585 static void hart_suspend_and_wait_ipi(unsigned long suspend_type, unsigned long resume_addr, 586 unsigned long opaque, bool returns, const char *typestr) 587 { 588 unsigned long hartid = current_thread_info()->hartid; 589 struct sbiret ret; 590 591 install_irq_handler(IRQ_S_SOFT, ipi_nop); 592 local_ipi_enable(); 593 local_irq_enable(); 594 595 ret = sbi_hart_suspend_raw(suspend_type, resume_addr, opaque); 596 if (ret.error == SBI_ERR_NOT_SUPPORTED) 597 cpumask_set_cpu(smp_processor_id(), &hsm_suspend_not_supported); 598 else if (ret.error) 599 report_fail("failed to %s cpu%d (hartid = %lx) (error=%ld)", 600 typestr, smp_processor_id(), hartid, ret.error); 601 else if (!returns) 602 report_fail("failed to %s cpu%d (hartid = %lx) (call should not return)", 603 typestr, smp_processor_id(), hartid); 604 605 local_irq_disable(); 606 local_ipi_disable(); 607 install_irq_handler(IRQ_S_SOFT, NULL); 608 } 609 610 static void hart_retentive_suspend(void *data) 611 { 612 hart_suspend_and_wait_ipi(SBI_EXT_HSM_HART_SUSPEND_RETENTIVE, 0, 0, true, "retentive suspend"); 613 } 614 615 static void hart_non_retentive_suspend(void *data) 616 { 617 unsigned long params[] = { 618 [SBI_HSM_MAGIC_IDX] = SBI_HSM_MAGIC, 619 [SBI_HSM_HARTID_IDX] = current_thread_info()->hartid, 620 }; 621 622 hart_suspend_and_wait_ipi(SBI_EXT_HSM_HART_SUSPEND_NON_RETENTIVE, 623 virt_to_phys(&sbi_hsm_check_non_retentive_suspend), virt_to_phys(params), 624 false, "non-retentive suspend"); 625 } 626 627 /* This test function is only being run on RV64 to verify that upper bits of suspend_type are ignored */ 628 static void hart_retentive_suspend_with_msb_set(void *data) 629 { 630 unsigned long suspend_type = SBI_EXT_HSM_HART_SUSPEND_RETENTIVE | (_AC(1, UL) << (__riscv_xlen - 1)); 631 632 hart_suspend_and_wait_ipi(suspend_type, 0, 0, true, "retentive suspend with MSB set"); 633 } 634 635 /* This test function is only being run on RV64 to verify that upper bits of suspend_type are ignored */ 636 static void hart_non_retentive_suspend_with_msb_set(void *data) 637 { 638 unsigned long suspend_type = SBI_EXT_HSM_HART_SUSPEND_NON_RETENTIVE | (_AC(1, UL) << (__riscv_xlen - 1)); 639 unsigned long params[] = { 640 [SBI_HSM_MAGIC_IDX] = SBI_HSM_MAGIC, 641 [SBI_HSM_HARTID_IDX] = current_thread_info()->hartid, 642 }; 643 644 hart_suspend_and_wait_ipi(suspend_type, 645 virt_to_phys(&sbi_hsm_check_non_retentive_suspend), virt_to_phys(params), 646 false, "non-retentive suspend with MSB set"); 647 } 648 649 static bool hart_wait_on_status(unsigned long hartid, enum sbi_ext_hsm_sid status, unsigned long duration) 650 { 651 struct sbiret ret; 652 653 sbi_hsm_timer_fired = false; 654 timer_start(duration); 655 656 ret = sbi_hart_get_status(hartid); 657 658 while (!ret.error && ret.value == status && !sbi_hsm_timer_fired) { 659 cpu_relax(); 660 ret = sbi_hart_get_status(hartid); 661 } 662 663 timer_stop(); 664 665 if (sbi_hsm_timer_fired) 666 report_info("timer fired while waiting on status %u for hartid %lx", status, hartid); 667 else if (ret.error) 668 report_fail("got %ld while waiting on status %u for hartid %lx", ret.error, status, hartid); 669 670 return !sbi_hsm_timer_fired && !ret.error; 671 } 672 673 static int hart_wait_state_transition(cpumask_t *mask, unsigned long duration, 674 struct hart_state_transition_info *states) 675 { 676 struct sbiret ret; 677 unsigned long hartid; 678 int cpu, count = 0; 679 680 for_each_cpu(cpu, mask) { 681 hartid = cpus[cpu].hartid; 682 if (!hart_wait_on_status(hartid, states->initial_state, duration)) 683 continue; 684 if (!hart_wait_on_status(hartid, states->intermediate_state, duration)) 685 continue; 686 687 ret = sbi_hart_get_status(hartid); 688 if (ret.error) 689 report_info("hartid %lx get status failed (error=%ld)", hartid, ret.error); 690 else if (ret.value != states->final_state) 691 report_info("hartid %lx status is not '%s' (ret.value=%ld)", hartid, 692 hart_state_str[states->final_state], ret.value); 693 else 694 count++; 695 } 696 697 return count; 698 } 699 700 static void hart_wait_until_idle(cpumask_t *mask, unsigned long duration) 701 { 702 sbi_hsm_timer_fired = false; 703 timer_start(duration); 704 705 while (!cpumask_subset(mask, &cpu_idle_mask) && !sbi_hsm_timer_fired) 706 cpu_relax(); 707 708 timer_stop(); 709 710 if (sbi_hsm_timer_fired) 711 report_info("hsm timer fired before all cpus became idle"); 712 } 713 714 static void check_hsm(void) 715 { 716 struct sbiret ret; 717 unsigned long hartid; 718 cpumask_t secondary_cpus_mask, mask, resume_mask; 719 struct hart_state_transition_info transition_states; 720 bool ipi_unavailable = false; 721 int cpu, me = smp_processor_id(); 722 int max_cpus = getenv("SBI_MAX_CPUS") ? strtol(getenv("SBI_MAX_CPUS"), NULL, 0) : nr_cpus; 723 unsigned long hsm_timer_duration = getenv("SBI_HSM_TIMER_DURATION") 724 ? strtol(getenv("SBI_HSM_TIMER_DURATION"), NULL, 0) : 200000; 725 unsigned long sbi_hsm_hart_start_params[NR_CPUS * SBI_HSM_NUM_OF_PARAMS]; 726 int count, check, expected_count, resume_count; 727 728 max_cpus = MIN(MIN(max_cpus, nr_cpus), cpumask_weight(&cpu_present_mask)); 729 730 report_prefix_push("hsm"); 731 732 if (!sbi_probe(SBI_EXT_HSM)) { 733 report_skip("hsm extension not available"); 734 report_prefix_pop(); 735 return; 736 } 737 738 sbi_bad_fid(SBI_EXT_HSM); 739 740 report_prefix_push("hart_get_status"); 741 742 hartid = current_thread_info()->hartid; 743 ret = sbi_hart_get_status(hartid); 744 745 if (ret.error) { 746 report_fail("failed to get status of current hart (error=%ld)", ret.error); 747 report_prefix_popn(2); 748 return; 749 } else if (ret.value != SBI_EXT_HSM_STARTED) { 750 report_fail("current hart is not started (ret.value=%ld)", ret.value); 751 report_prefix_popn(2); 752 return; 753 } 754 755 report_pass("status of current hart is started"); 756 757 report_prefix_pop(); 758 759 if (max_cpus < 2) { 760 report_skip("no other cpus to run the remaining hsm tests on"); 761 report_prefix_pop(); 762 return; 763 } 764 765 report_prefix_push("hart_stop"); 766 767 cpumask_copy(&secondary_cpus_mask, &cpu_present_mask); 768 cpumask_clear_cpu(me, &secondary_cpus_mask); 769 timer_setup(hsm_timer_irq_handler); 770 local_irq_enable(); 771 772 /* Assume that previous tests have not cleaned up and stopped the secondary harts */ 773 on_cpumask_async(&secondary_cpus_mask, stop_cpu, NULL); 774 775 transition_states = (struct hart_state_transition_info) { 776 .initial_state = SBI_EXT_HSM_STARTED, 777 .intermediate_state = SBI_EXT_HSM_STOP_PENDING, 778 .final_state = SBI_EXT_HSM_STOPPED, 779 }; 780 count = hart_wait_state_transition(&secondary_cpus_mask, hsm_timer_duration, &transition_states); 781 782 report(count == max_cpus - 1, "all secondary harts stopped"); 783 784 report_prefix_pop(); 785 786 report_prefix_push("hart_start"); 787 788 for_each_cpu(cpu, &secondary_cpus_mask) { 789 hartid = cpus[cpu].hartid; 790 sbi_hsm_hart_start_params[cpu * SBI_HSM_NUM_OF_PARAMS + SBI_HSM_MAGIC_IDX] = SBI_HSM_MAGIC; 791 sbi_hsm_hart_start_params[cpu * SBI_HSM_NUM_OF_PARAMS + SBI_HSM_HARTID_IDX] = hartid; 792 793 ret = sbi_hart_start(hartid, virt_to_phys(&sbi_hsm_check_hart_start), 794 virt_to_phys(&sbi_hsm_hart_start_params[cpu * SBI_HSM_NUM_OF_PARAMS])); 795 if (ret.error) { 796 report_fail("failed to start test on cpu%d (hartid = %lx) (error=%ld)", cpu, hartid, ret.error); 797 continue; 798 } 799 } 800 801 transition_states = (struct hart_state_transition_info) { 802 .initial_state = SBI_EXT_HSM_STOPPED, 803 .intermediate_state = SBI_EXT_HSM_START_PENDING, 804 .final_state = SBI_EXT_HSM_STARTED, 805 }; 806 count = hart_wait_state_transition(&secondary_cpus_mask, hsm_timer_duration, &transition_states); 807 check = 0; 808 809 for_each_cpu(cpu, &secondary_cpus_mask) { 810 sbi_hsm_timer_fired = false; 811 timer_start(hsm_timer_duration); 812 813 while (!(READ_ONCE(sbi_hsm_hart_start_checks[cpu]) & SBI_HSM_TEST_DONE) && !sbi_hsm_timer_fired) 814 cpu_relax(); 815 816 timer_stop(); 817 818 if (sbi_hsm_timer_fired) { 819 report_info("hsm timer fired before cpu%d (hartid = %lx) is done with start checks", cpu, hartid); 820 continue; 821 } 822 823 if (!(sbi_hsm_hart_start_checks[cpu] & SBI_HSM_TEST_SATP)) 824 report_info("satp is not zero for test on cpu%d (hartid = %lx)", cpu, hartid); 825 else if (!(sbi_hsm_hart_start_checks[cpu] & SBI_HSM_TEST_SIE)) 826 report_info("sstatus.SIE is not zero for test on cpu%d (hartid = %lx)", cpu, hartid); 827 else if (!(sbi_hsm_hart_start_checks[cpu] & SBI_HSM_TEST_MAGIC_A1)) 828 report_info("a1 does not start with magic for test on cpu%d (hartid = %lx)", cpu, hartid); 829 else if (!(sbi_hsm_hart_start_checks[cpu] & SBI_HSM_TEST_HARTID_A0)) 830 report_info("a0 is not hartid for test on cpu %d (hartid = %lx)", cpu, hartid); 831 else 832 check++; 833 } 834 835 report(count == max_cpus - 1, "all secondary harts started"); 836 report(check == max_cpus - 1, "all secondary harts have expected register values after hart start"); 837 838 report_prefix_pop(); 839 840 report_prefix_push("hart_stop"); 841 842 memset(sbi_hsm_stop_hart, 1, sizeof(sbi_hsm_stop_hart)); 843 844 transition_states = (struct hart_state_transition_info) { 845 .initial_state = SBI_EXT_HSM_STARTED, 846 .intermediate_state = SBI_EXT_HSM_STOP_PENDING, 847 .final_state = SBI_EXT_HSM_STOPPED, 848 }; 849 count = hart_wait_state_transition(&secondary_cpus_mask, hsm_timer_duration, &transition_states); 850 851 report(count == max_cpus - 1, "all secondary harts stopped"); 852 853 /* Reset the stop flags so that we can reuse them after suspension tests */ 854 memset(sbi_hsm_stop_hart, 0, sizeof(sbi_hsm_stop_hart)); 855 856 report_prefix_pop(); 857 858 report_prefix_push("hart_start"); 859 860 /* Select just one secondary cpu to run the invalid hartid test */ 861 on_cpu(cpumask_next(-1, &secondary_cpus_mask), hart_start_invalid_hartid, NULL); 862 863 report(sbi_hsm_invalid_hartid_check, "secondary hart refuse to start with invalid hartid"); 864 865 on_cpumask_async(&secondary_cpus_mask, hart_check_already_started, NULL); 866 867 transition_states = (struct hart_state_transition_info) { 868 .initial_state = SBI_EXT_HSM_STOPPED, 869 .intermediate_state = SBI_EXT_HSM_START_PENDING, 870 .final_state = SBI_EXT_HSM_STARTED, 871 }; 872 count = hart_wait_state_transition(&secondary_cpus_mask, hsm_timer_duration, &transition_states); 873 874 report(count == max_cpus - 1, "all secondary harts started"); 875 876 hart_wait_until_idle(&secondary_cpus_mask, hsm_timer_duration); 877 878 report(cpumask_weight(&sbi_hsm_started_hart_checks) == max_cpus - 1, 879 "all secondary harts are already started"); 880 881 report_prefix_pop(); 882 883 report_prefix_push("hart_suspend"); 884 885 if (!sbi_probe(SBI_EXT_IPI)) { 886 report_skip("skipping suspension tests since ipi extension is unavailable"); 887 report_prefix_pop(); 888 ipi_unavailable = true; 889 goto sbi_hsm_hart_stop_tests; 890 } 891 892 cpumask_clear(&hsm_suspend_not_supported); 893 on_cpumask_async(&secondary_cpus_mask, hart_retentive_suspend, NULL); 894 895 transition_states = (struct hart_state_transition_info) { 896 .initial_state = SBI_EXT_HSM_STARTED, 897 .intermediate_state = SBI_EXT_HSM_SUSPEND_PENDING, 898 .final_state = SBI_EXT_HSM_SUSPENDED, 899 }; 900 count = hart_wait_state_transition(&secondary_cpus_mask, hsm_timer_duration, &transition_states); 901 902 expected_count = max_cpus - 1 - cpumask_weight(&hsm_suspend_not_supported); 903 904 if (expected_count != 0) { 905 if (expected_count != max_cpus - 1) 906 report_info("not all harts support retentive suspend"); 907 report(count == expected_count, "supporting secondary harts retentive suspended"); 908 } else { 909 report_skip("retentive suspend not supported by any harts"); 910 goto nonret_suspend_tests; 911 } 912 913 cpumask_andnot(&resume_mask, &secondary_cpus_mask, &hsm_suspend_not_supported); 914 resume_count = cpumask_weight(&resume_mask); 915 916 /* Ignore the return value since we check the status of each hart anyway */ 917 sbi_send_ipi_cpumask(&resume_mask); 918 919 transition_states = (struct hart_state_transition_info) { 920 .initial_state = SBI_EXT_HSM_SUSPENDED, 921 .intermediate_state = SBI_EXT_HSM_RESUME_PENDING, 922 .final_state = SBI_EXT_HSM_STARTED, 923 }; 924 count = hart_wait_state_transition(&resume_mask, hsm_timer_duration, &transition_states); 925 926 report(count == resume_count, "supporting secondary harts retentive resumed"); 927 928 nonret_suspend_tests: 929 hart_wait_until_idle(&secondary_cpus_mask, hsm_timer_duration); 930 931 cpumask_clear(&hsm_suspend_not_supported); 932 on_cpumask_async(&secondary_cpus_mask, hart_non_retentive_suspend, NULL); 933 934 transition_states = (struct hart_state_transition_info) { 935 .initial_state = SBI_EXT_HSM_STARTED, 936 .intermediate_state = SBI_EXT_HSM_SUSPEND_PENDING, 937 .final_state = SBI_EXT_HSM_SUSPENDED, 938 }; 939 count = hart_wait_state_transition(&secondary_cpus_mask, hsm_timer_duration, &transition_states); 940 941 expected_count = max_cpus - 1 - cpumask_weight(&hsm_suspend_not_supported); 942 943 if (expected_count != 0) { 944 if (expected_count != max_cpus - 1) 945 report_info("not all harts support non-retentive suspend"); 946 report(count == expected_count, "supporting secondary harts non-retentive suspended"); 947 } else { 948 report_skip("non-retentive suspend not supported by any harts"); 949 goto hsm_suspend_tests_done; 950 } 951 952 cpumask_andnot(&resume_mask, &secondary_cpus_mask, &hsm_suspend_not_supported); 953 resume_count = cpumask_weight(&resume_mask); 954 955 /* Ignore the return value since we check the status of each hart anyway */ 956 sbi_send_ipi_cpumask(&resume_mask); 957 958 transition_states = (struct hart_state_transition_info) { 959 .initial_state = SBI_EXT_HSM_SUSPENDED, 960 .intermediate_state = SBI_EXT_HSM_RESUME_PENDING, 961 .final_state = SBI_EXT_HSM_STARTED, 962 }; 963 count = hart_wait_state_transition(&resume_mask, hsm_timer_duration, &transition_states); 964 check = 0; 965 966 for_each_cpu(cpu, &resume_mask) { 967 sbi_hsm_timer_fired = false; 968 timer_start(hsm_timer_duration); 969 970 while (!(READ_ONCE(sbi_hsm_non_retentive_hart_suspend_checks[cpu]) & SBI_HSM_TEST_DONE) && !sbi_hsm_timer_fired) 971 cpu_relax(); 972 973 timer_stop(); 974 975 if (sbi_hsm_timer_fired) { 976 report_info("hsm timer fired before hart %ld is done with non-retentive resume checks", hartid); 977 continue; 978 } 979 980 if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_SATP)) 981 report_info("satp is not zero for test on cpu%d (hartid = %lx)", cpu, hartid); 982 else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_SIE)) 983 report_info("sstatus.SIE is not zero for test on cpu%d (hartid = %lx)", cpu, hartid); 984 else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_MAGIC_A1)) 985 report_info("a1 does not start with magic for test on cpu%d (hartid = %lx)", cpu, hartid); 986 else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_HARTID_A0)) 987 report_info("a0 is not hartid for test on cpu%d (hartid = %lx)", cpu, hartid); 988 else 989 check++; 990 } 991 992 report(count == resume_count, "supporting secondary harts non-retentive resumed"); 993 report(check == resume_count, "supporting secondary harts have expected register values after non-retentive resume"); 994 995 hsm_suspend_tests_done: 996 report_prefix_pop(); 997 998 sbi_hsm_hart_stop_tests: 999 report_prefix_push("hart_stop"); 1000 1001 if (ipi_unavailable || expected_count == 0) 1002 on_cpumask_async(&secondary_cpus_mask, stop_cpu, NULL); 1003 else 1004 memset(sbi_hsm_stop_hart, 1, sizeof(sbi_hsm_stop_hart)); 1005 1006 transition_states = (struct hart_state_transition_info) { 1007 .initial_state = SBI_EXT_HSM_STARTED, 1008 .intermediate_state = SBI_EXT_HSM_STOP_PENDING, 1009 .final_state = SBI_EXT_HSM_STOPPED, 1010 }; 1011 count = hart_wait_state_transition(&secondary_cpus_mask, hsm_timer_duration, &transition_states); 1012 1013 report(count == max_cpus - 1, "all secondary harts stopped"); 1014 1015 report_prefix_pop(); 1016 1017 if (__riscv_xlen == 32 || ipi_unavailable) { 1018 local_irq_disable(); 1019 timer_teardown(); 1020 report_prefix_pop(); 1021 return; 1022 } 1023 1024 report_prefix_push("hart_suspend"); 1025 1026 /* Select just one secondary cpu to run suspension tests with MSB of suspend type being set */ 1027 cpu = cpumask_next(-1, &secondary_cpus_mask); 1028 hartid = cpus[cpu].hartid; 1029 cpumask_clear(&mask); 1030 cpumask_set_cpu(cpu, &mask); 1031 1032 /* Boot up the secondary cpu and let it proceed to the idle loop */ 1033 on_cpu(cpu, start_cpu, NULL); 1034 1035 cpumask_clear(&hsm_suspend_not_supported); 1036 on_cpu_async(cpu, hart_retentive_suspend_with_msb_set, NULL); 1037 1038 transition_states = (struct hart_state_transition_info) { 1039 .initial_state = SBI_EXT_HSM_STARTED, 1040 .intermediate_state = SBI_EXT_HSM_SUSPEND_PENDING, 1041 .final_state = SBI_EXT_HSM_SUSPENDED, 1042 }; 1043 count = hart_wait_state_transition(&mask, hsm_timer_duration, &transition_states); 1044 1045 expected_count = 1 - cpumask_weight(&hsm_suspend_not_supported); 1046 1047 if (expected_count) { 1048 report(count == expected_count, "retentive suspend with MSB set"); 1049 } else { 1050 report_skip("retentive suspend not supported by cpu%d", cpu); 1051 goto nonret_suspend_with_msb; 1052 } 1053 1054 /* Ignore the return value since we manually validate the status of the hart anyway */ 1055 sbi_send_ipi_cpu(cpu); 1056 1057 transition_states = (struct hart_state_transition_info) { 1058 .initial_state = SBI_EXT_HSM_SUSPENDED, 1059 .intermediate_state = SBI_EXT_HSM_RESUME_PENDING, 1060 .final_state = SBI_EXT_HSM_STARTED, 1061 }; 1062 count = hart_wait_state_transition(&mask, hsm_timer_duration, &transition_states); 1063 1064 report(count, "secondary hart retentive resumed with MSB set"); 1065 1066 nonret_suspend_with_msb: 1067 /* Reset these flags so that we can reuse them for the non-retentive suspension test */ 1068 sbi_hsm_stop_hart[cpu] = 0; 1069 sbi_hsm_non_retentive_hart_suspend_checks[cpu] = 0; 1070 1071 cpumask_clear(&hsm_suspend_not_supported); 1072 on_cpu_async(cpu, hart_non_retentive_suspend_with_msb_set, NULL); 1073 1074 transition_states = (struct hart_state_transition_info) { 1075 .initial_state = SBI_EXT_HSM_STARTED, 1076 .intermediate_state = SBI_EXT_HSM_SUSPEND_PENDING, 1077 .final_state = SBI_EXT_HSM_SUSPENDED, 1078 }; 1079 count = hart_wait_state_transition(&mask, hsm_timer_duration, &transition_states); 1080 1081 expected_count = 1 - cpumask_weight(&hsm_suspend_not_supported); 1082 1083 if (expected_count) { 1084 report(count == expected_count, "non-retentive suspend with MSB set"); 1085 } else { 1086 report_skip("non-retentive suspend not supported by cpu%d", cpu); 1087 goto hsm_hart_stop_test; 1088 } 1089 1090 /* Ignore the return value since we manually validate the status of the hart anyway */ 1091 sbi_send_ipi_cpu(cpu); 1092 1093 transition_states = (struct hart_state_transition_info) { 1094 .initial_state = SBI_EXT_HSM_SUSPENDED, 1095 .intermediate_state = SBI_EXT_HSM_RESUME_PENDING, 1096 .final_state = SBI_EXT_HSM_STARTED, 1097 }; 1098 count = hart_wait_state_transition(&mask, hsm_timer_duration, &transition_states); 1099 check = 0; 1100 1101 if (count) { 1102 sbi_hsm_timer_fired = false; 1103 timer_start(hsm_timer_duration); 1104 1105 while (!(READ_ONCE(sbi_hsm_non_retentive_hart_suspend_checks[cpu]) & SBI_HSM_TEST_DONE) && !sbi_hsm_timer_fired) 1106 cpu_relax(); 1107 1108 timer_stop(); 1109 1110 if (sbi_hsm_timer_fired) { 1111 report_info("hsm timer fired before cpu%d (hartid = %lx) is done with non-retentive resume checks", cpu, hartid); 1112 } else { 1113 if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_SATP)) 1114 report_info("satp is not zero for test on cpu%d (hartid = %lx)", cpu, hartid); 1115 else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_SIE)) 1116 report_info("sstatus.SIE is not zero for test on cpu%d (hartid = %lx)", cpu, hartid); 1117 else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_MAGIC_A1)) 1118 report_info("a1 does not start with magic for test on cpu%d (hartid = %lx)", cpu, hartid); 1119 else if (!(sbi_hsm_non_retentive_hart_suspend_checks[cpu] & SBI_HSM_TEST_HARTID_A0)) 1120 report_info("a0 is not hartid for test on cpu%d (hartid = %lx)", cpu, hartid); 1121 else 1122 check = 1; 1123 } 1124 } 1125 1126 report(count, "secondary hart non-retentive resumed with MSB set"); 1127 report(check, "secondary hart has expected register values after non-retentive resume with MSB set"); 1128 1129 hsm_hart_stop_test: 1130 report_prefix_pop(); 1131 1132 report_prefix_push("hart_stop"); 1133 1134 if (expected_count == 0) 1135 on_cpu_async(cpu, stop_cpu, NULL); 1136 else 1137 sbi_hsm_stop_hart[cpu] = 1; 1138 1139 transition_states = (struct hart_state_transition_info) { 1140 .initial_state = SBI_EXT_HSM_STARTED, 1141 .intermediate_state = SBI_EXT_HSM_STOP_PENDING, 1142 .final_state = SBI_EXT_HSM_STOPPED, 1143 }; 1144 count = hart_wait_state_transition(&mask, hsm_timer_duration, &transition_states); 1145 1146 report(count, "secondary hart stopped after suspension tests with MSB set"); 1147 1148 local_irq_disable(); 1149 timer_teardown(); 1150 report_prefix_popn(2); 1151 } 1152 1153 #define DBCN_WRITE_TEST_STRING "DBCN_WRITE_TEST_STRING\n" 1154 #define DBCN_WRITE_BYTE_TEST_BYTE ((u8)'a') 1155 1156 static void dbcn_write_test(const char *s, unsigned long num_bytes, bool xfail) 1157 { 1158 unsigned long base_addr_lo, base_addr_hi; 1159 phys_addr_t paddr = virt_to_phys((void *)s); 1160 int num_calls = 0; 1161 struct sbiret ret; 1162 1163 split_phys_addr(paddr, &base_addr_hi, &base_addr_lo); 1164 1165 do { 1166 ret = sbi_dbcn_write(num_bytes, base_addr_lo, base_addr_hi); 1167 num_bytes -= ret.value; 1168 paddr += ret.value; 1169 split_phys_addr(paddr, &base_addr_hi, &base_addr_lo); 1170 num_calls++; 1171 } while (num_bytes != 0 && ret.error == SBI_SUCCESS); 1172 1173 report_xfail(xfail, ret.error == SBI_SUCCESS, "write success (error=%ld)", ret.error); 1174 report_info("%d sbi calls made", num_calls); 1175 } 1176 1177 static void dbcn_high_write_test(const char *s, unsigned long num_bytes, 1178 phys_addr_t page_addr, size_t page_offset, 1179 bool highmem_supported) 1180 { 1181 int nr_pages = page_offset ? 2 : 1; 1182 void *vaddr; 1183 1184 if (page_addr != PAGE_ALIGN(page_addr) || page_addr + PAGE_SIZE < HIGH_ADDR_BOUNDARY || 1185 !check_addr(page_addr, nr_pages * PAGE_SIZE)) { 1186 report_skip("Memory above 4G required"); 1187 return; 1188 } 1189 1190 vaddr = alloc_vpages(nr_pages); 1191 1192 for (int i = 0; i < nr_pages; ++i) 1193 install_page(current_pgtable(), page_addr + i * PAGE_SIZE, vaddr + i * PAGE_SIZE); 1194 memcpy(vaddr + page_offset, DBCN_WRITE_TEST_STRING, num_bytes); 1195 dbcn_write_test(vaddr + page_offset, num_bytes, !highmem_supported); 1196 } 1197 1198 /* 1199 * Only the write functionality is tested here. There's no easy way to 1200 * non-interactively test SBI_EXT_DBCN_CONSOLE_READ. 1201 */ 1202 static void check_dbcn(void) 1203 { 1204 unsigned long num_bytes = strlen(DBCN_WRITE_TEST_STRING); 1205 unsigned long base_addr_lo, base_addr_hi; 1206 bool highmem_supported = true; 1207 phys_addr_t paddr; 1208 struct sbiret ret; 1209 char *buf; 1210 1211 report_prefix_push("dbcn"); 1212 1213 if (!sbi_probe(SBI_EXT_DBCN)) { 1214 report_skip("DBCN extension unavailable"); 1215 report_prefix_pop(); 1216 return; 1217 } 1218 1219 sbi_bad_fid(SBI_EXT_DBCN); 1220 1221 report_prefix_push("write"); 1222 1223 dbcn_write_test(DBCN_WRITE_TEST_STRING, num_bytes, false); 1224 1225 assert(num_bytes < PAGE_SIZE); 1226 1227 report_prefix_push("page boundary"); 1228 buf = alloc_pages(1); 1229 memcpy(&buf[PAGE_SIZE - num_bytes / 2], DBCN_WRITE_TEST_STRING, num_bytes); 1230 dbcn_write_test(&buf[PAGE_SIZE - num_bytes / 2], num_bytes, false); 1231 report_prefix_pop(); 1232 1233 if (env_enabled("SBI_HIGHMEM_NOT_SUPPORTED")) 1234 highmem_supported = false; 1235 1236 report_prefix_push("high boundary"); 1237 if (!env_enabled("SBI_DBCN_SKIP_HIGH_BOUNDARY")) 1238 dbcn_high_write_test(DBCN_WRITE_TEST_STRING, num_bytes, 1239 HIGH_ADDR_BOUNDARY - PAGE_SIZE, PAGE_SIZE - num_bytes / 2, 1240 highmem_supported); 1241 else 1242 report_skip("user disabled"); 1243 report_prefix_pop(); 1244 1245 report_prefix_push("high page"); 1246 if (!env_enabled("SBI_DBCN_SKIP_HIGH_PAGE")) { 1247 paddr = getenv("HIGH_PAGE") ? strtoull(getenv("HIGH_PAGE"), NULL, 0) : HIGH_ADDR_BOUNDARY; 1248 dbcn_high_write_test(DBCN_WRITE_TEST_STRING, num_bytes, paddr, 0, highmem_supported); 1249 } else { 1250 report_skip("user disabled"); 1251 } 1252 report_prefix_pop(); 1253 1254 /* Bytes are read from memory and written to the console */ 1255 report_prefix_push("invalid parameter"); 1256 if (get_invalid_addr(&paddr, false)) { 1257 split_phys_addr(paddr, &base_addr_hi, &base_addr_lo); 1258 ret = sbi_dbcn_write(1, base_addr_lo, base_addr_hi); 1259 report(ret.error == SBI_ERR_INVALID_PARAM, "address (error=%ld)", ret.error); 1260 } 1261 report_prefix_popn(2); 1262 report_prefix_push("write_byte"); 1263 1264 puts("DBCN_WRITE_BYTE TEST BYTE: "); 1265 ret = sbi_dbcn_write_byte(DBCN_WRITE_BYTE_TEST_BYTE); 1266 puts("\n"); 1267 report(ret.error == SBI_SUCCESS, "write success (error=%ld)", ret.error); 1268 report(ret.value == 0, "expected ret.value (%ld)", ret.value); 1269 1270 puts("DBCN_WRITE_BYTE TEST WORD: "); /* still expect 'a' in the output */ 1271 ret = sbi_ecall(SBI_EXT_DBCN, SBI_EXT_DBCN_CONSOLE_WRITE_BYTE, 0x64636261, 0, 0, 0, 0, 0); 1272 puts("\n"); 1273 report(ret.error == SBI_SUCCESS, "write success (error=%ld)", ret.error); 1274 report(ret.value == 0, "expected ret.value (%ld)", ret.value); 1275 1276 report_prefix_popn(2); 1277 } 1278 1279 void sbi_susp_resume(unsigned long hartid, unsigned long opaque); 1280 jmp_buf sbi_susp_jmp; 1281 1282 #define SBI_SUSP_TIMER_DURATION_US 500000 1283 static void susp_timer(struct pt_regs *regs) 1284 { 1285 timer_start(SBI_SUSP_TIMER_DURATION_US); 1286 } 1287 1288 struct susp_params { 1289 unsigned long sleep_type; 1290 unsigned long resume_addr; 1291 unsigned long opaque; 1292 bool returns; 1293 struct sbiret ret; 1294 }; 1295 1296 static bool susp_basic_prep(unsigned long ctx[], struct susp_params *params) 1297 { 1298 int cpu, me = smp_processor_id(); 1299 unsigned long *csrs; 1300 struct sbiret ret; 1301 cpumask_t mask; 1302 1303 csrs = (unsigned long *)ctx[SBI_SUSP_CSRS_IDX]; 1304 csrs[SBI_CSR_SSTATUS_IDX] = csr_read(CSR_SSTATUS); 1305 csrs[SBI_CSR_SIE_IDX] = csr_read(CSR_SIE); 1306 csrs[SBI_CSR_STVEC_IDX] = csr_read(CSR_STVEC); 1307 csrs[SBI_CSR_SSCRATCH_IDX] = csr_read(CSR_SSCRATCH); 1308 csrs[SBI_CSR_SATP_IDX] = csr_read(CSR_SATP); 1309 1310 memset(params, 0, sizeof(*params)); 1311 params->sleep_type = 0; /* suspend-to-ram */ 1312 params->resume_addr = virt_to_phys(sbi_susp_resume); 1313 params->opaque = virt_to_phys(ctx); 1314 params->returns = false; 1315 1316 cpumask_copy(&mask, &cpu_present_mask); 1317 cpumask_clear_cpu(me, &mask); 1318 on_cpumask_async(&mask, stop_cpu, NULL); 1319 1320 /* Wait up to 1s for all harts to stop */ 1321 for (int i = 0; i < 100; i++) { 1322 int count = 1; 1323 1324 udelay(10000); 1325 1326 for_each_present_cpu(cpu) { 1327 if (cpu == me) 1328 continue; 1329 ret = sbi_hart_get_status(cpus[cpu].hartid); 1330 if (!ret.error && ret.value == SBI_EXT_HSM_STOPPED) 1331 ++count; 1332 } 1333 if (count == cpumask_weight(&cpu_present_mask)) 1334 break; 1335 } 1336 1337 for_each_present_cpu(cpu) { 1338 ret = sbi_hart_get_status(cpus[cpu].hartid); 1339 if (cpu == me) { 1340 assert_msg(!ret.error && ret.value == SBI_EXT_HSM_STARTED, 1341 "cpu%d is not started", cpu); 1342 } else { 1343 assert_msg(!ret.error && ret.value == SBI_EXT_HSM_STOPPED, 1344 "cpu%d is not stopped", cpu); 1345 } 1346 } 1347 1348 return true; 1349 } 1350 1351 static void susp_basic_check(unsigned long ctx[], struct susp_params *params) 1352 { 1353 if (ctx[SBI_SUSP_RESULTS_IDX] == SBI_SUSP_TEST_MASK) { 1354 report_pass("suspend and resume"); 1355 } else { 1356 if (!(ctx[SBI_SUSP_RESULTS_IDX] & SBI_SUSP_TEST_SATP)) 1357 report_fail("SATP set to zero on resume"); 1358 if (!(ctx[SBI_SUSP_RESULTS_IDX] & SBI_SUSP_TEST_SIE)) 1359 report_fail("sstatus.SIE clear on resume"); 1360 if (!(ctx[SBI_SUSP_RESULTS_IDX] & SBI_SUSP_TEST_HARTID)) 1361 report_fail("a0 is hartid on resume"); 1362 } 1363 } 1364 1365 static bool susp_type_prep(unsigned long ctx[], struct susp_params *params) 1366 { 1367 bool r; 1368 1369 r = susp_basic_prep(ctx, params); 1370 assert(r); 1371 params->sleep_type = 1; 1372 params->returns = true; 1373 params->ret.error = SBI_ERR_INVALID_PARAM; 1374 1375 return true; 1376 } 1377 1378 #if __riscv_xlen != 32 1379 static bool susp_type_prep2(unsigned long ctx[], struct susp_params *params) 1380 { 1381 bool r; 1382 1383 r = susp_basic_prep(ctx, params); 1384 assert(r); 1385 params->sleep_type = BIT(32); 1386 1387 return true; 1388 } 1389 #endif 1390 1391 static bool susp_badaddr_prep(unsigned long ctx[], struct susp_params *params) 1392 { 1393 phys_addr_t badaddr; 1394 bool r; 1395 1396 if (!get_invalid_addr(&badaddr, false)) 1397 return false; 1398 1399 r = susp_basic_prep(ctx, params); 1400 assert(r); 1401 params->resume_addr = badaddr; 1402 params->returns = true; 1403 params->ret.error = SBI_ERR_INVALID_ADDRESS; 1404 1405 return true; 1406 } 1407 1408 static bool susp_one_prep(unsigned long ctx[], struct susp_params *params) 1409 { 1410 int started = 0, cpu, me = smp_processor_id(); 1411 struct sbiret ret; 1412 bool r; 1413 1414 if (cpumask_weight(&cpu_present_mask) < 2) { 1415 report_skip("At least 2 cpus required"); 1416 return false; 1417 } 1418 1419 r = susp_basic_prep(ctx, params); 1420 assert(r); 1421 params->returns = true; 1422 params->ret.error = SBI_ERR_DENIED; 1423 1424 for_each_present_cpu(cpu) { 1425 if (cpu == me) 1426 continue; 1427 break; 1428 } 1429 1430 on_cpu(cpu, start_cpu, NULL); 1431 1432 for_each_present_cpu(cpu) { 1433 ret = sbi_hart_get_status(cpus[cpu].hartid); 1434 assert_msg(!ret.error, "HSM get status failed for cpu%d", cpu); 1435 if (ret.value == SBI_EXT_HSM_STARTED) 1436 started++; 1437 } 1438 1439 assert(started == 2); 1440 1441 return true; 1442 } 1443 1444 static void check_susp(void) 1445 { 1446 unsigned long csrs[SBI_CSR_NR_IDX]; 1447 unsigned long ctx[SBI_SUSP_NR_IDX] = { 1448 [SBI_SUSP_MAGIC_IDX] = SBI_SUSP_MAGIC, 1449 [SBI_SUSP_CSRS_IDX] = (unsigned long)csrs, 1450 [SBI_SUSP_HARTID_IDX] = current_thread_info()->hartid, 1451 }; 1452 enum { 1453 #define SUSP_FIRST_TESTNUM 1 1454 SUSP_BASIC = SUSP_FIRST_TESTNUM, 1455 SUSP_TYPE, 1456 SUSP_TYPE2, 1457 SUSP_BAD_ADDR, 1458 SUSP_ONE_ONLINE, 1459 NR_SUSP_TESTS, 1460 }; 1461 struct susp_test { 1462 const char *name; 1463 bool (*prep)(unsigned long ctx[], struct susp_params *params); 1464 void (*check)(unsigned long ctx[], struct susp_params *params); 1465 } susp_tests[] = { 1466 [SUSP_BASIC] = { "basic", susp_basic_prep, susp_basic_check, }, 1467 [SUSP_TYPE] = { "sleep_type", susp_type_prep, }, 1468 #if __riscv_xlen != 32 1469 [SUSP_TYPE2] = { "sleep_type upper bits", susp_type_prep2, susp_basic_check }, 1470 #endif 1471 [SUSP_BAD_ADDR] = { "bad addr", susp_badaddr_prep, }, 1472 [SUSP_ONE_ONLINE] = { "one cpu online", susp_one_prep, }, 1473 }; 1474 struct susp_params params; 1475 struct sbiret ret; 1476 int testnum, i; 1477 1478 report_prefix_push("susp"); 1479 1480 if (!sbi_probe(SBI_EXT_SUSP)) { 1481 report_skip("SUSP extension not available"); 1482 report_prefix_pop(); 1483 return; 1484 } 1485 1486 sbi_bad_fid(SBI_EXT_SUSP); 1487 1488 timer_setup(susp_timer); 1489 local_irq_enable(); 1490 timer_start(SBI_SUSP_TIMER_DURATION_US); 1491 1492 ret = sbi_ecall(SBI_EXT_SUSP, 1, 0, 0, 0, 0, 0, 0); 1493 report(ret.error == SBI_ERR_NOT_SUPPORTED, "funcid != 0 not supported"); 1494 1495 for (i = SUSP_FIRST_TESTNUM; i < NR_SUSP_TESTS; i++) { 1496 if (!susp_tests[i].name) 1497 continue; 1498 1499 report_prefix_push(susp_tests[i].name); 1500 1501 ctx[SBI_SUSP_TESTNUM_IDX] = i; 1502 ctx[SBI_SUSP_RESULTS_IDX] = 0; 1503 1504 local_irq_disable(); 1505 1506 assert(susp_tests[i].prep); 1507 if (!susp_tests[i].prep(ctx, ¶ms)) { 1508 report_prefix_pop(); 1509 continue; 1510 } 1511 1512 if ((testnum = setjmp(sbi_susp_jmp)) == 0) { 1513 ret = sbi_system_suspend_raw(params.sleep_type, params.resume_addr, params.opaque); 1514 1515 local_irq_enable(); 1516 1517 if (!params.returns && ret.error == SBI_ERR_NOT_SUPPORTED) { 1518 report_fail("probing claims support, but it's not?"); 1519 report_prefix_pop(); 1520 goto out; 1521 } else if (!params.returns) { 1522 report_fail("unexpected return with error: %ld, value: %ld", ret.error, ret.value); 1523 } else { 1524 if (!report(ret.error == params.ret.error, "got expected sbi.error (%ld)", params.ret.error)) 1525 report_info("expected sbi.error %ld, received %ld", params.ret.error, ret.error); 1526 } 1527 1528 report_prefix_pop(); 1529 continue; 1530 } 1531 assert(testnum == i); 1532 1533 local_irq_enable(); 1534 1535 if (susp_tests[i].check) 1536 susp_tests[i].check(ctx, ¶ms); 1537 1538 report_prefix_pop(); 1539 } 1540 1541 out: 1542 local_irq_disable(); 1543 timer_teardown(); 1544 1545 report_prefix_pop(); 1546 } 1547 1548 int main(int argc, char **argv) 1549 { 1550 if (argc > 1 && !strcmp(argv[1], "-h")) { 1551 help(); 1552 exit(0); 1553 } 1554 1555 report_prefix_push("sbi"); 1556 check_base(); 1557 check_time(); 1558 check_ipi(); 1559 check_hsm(); 1560 check_dbcn(); 1561 check_susp(); 1562 check_sse(); 1563 check_fwft(); 1564 1565 return report_summary(); 1566 } 1567