1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Perform Set Clock tests 4 * 5 * Copyright IBM Corp. 2022 6 * 7 * Authors: 8 * Nico Boehr <nrb@linux.ibm.com> 9 */ 10 #include <libcflat.h> 11 #include <uv.h> 12 #include <asm/interrupt.h> 13 #include <asm/time.h> 14 15 static void test_priv(void) 16 { 17 uint64_t time_to_set_privileged = 0xfacef00dcafe0000, 18 time_to_set_nonprivileged = 0xcafe0000, 19 time_verify; 20 int cc; 21 22 report_prefix_push("privileged"); 23 cc = sck(&time_to_set_privileged); 24 report(!cc, "set clock cc=%d", cc); 25 26 cc = stck(&time_verify); 27 report(!cc, "store clock cc=%d", cc); 28 report(time_verify > time_to_set_privileged, 29 "privileged set affected the clock"); 30 report_prefix_pop(); 31 32 report_prefix_push("unprivileged"); 33 expect_pgm_int(); 34 enter_pstate(); 35 sck(&time_to_set_nonprivileged); 36 leave_pstate(); 37 check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION); 38 39 cc = stck(&time_verify); 40 report(!cc, "store clock cc=%d", cc); 41 report(time_verify > time_to_set_privileged, 42 "unprivileged set did not affect the clock"); 43 report_prefix_pop(); 44 } 45 46 static void test_align(void) 47 { 48 const int align_to = 8; 49 char unalign[sizeof(uint64_t) + align_to] __attribute__((aligned(8))); 50 51 report_prefix_push("Unaligned operand"); 52 for (int i = 1; i < align_to; i *= 2) { 53 report_prefix_pushf("%d", i); 54 expect_pgm_int(); 55 sck((uint64_t *)(unalign + i)); 56 check_pgm_int_code(PGM_INT_CODE_SPECIFICATION); 57 report_prefix_pop(); 58 } 59 report_prefix_pop(); 60 } 61 62 static void test_set(void) 63 { 64 uint64_t start = 0, end = 0, time = 0xcafef00dbeef; 65 const uint64_t ticks_per_ms = 1000 << 12, ms_to_wait = 5; 66 int cc; 67 68 report_prefix_push("set"); 69 70 cc = sck(&time); 71 report(!cc, "set clock cc=%d", cc); 72 73 cc = stck(&start); 74 report(!cc, "store start clock cc=%d", cc); 75 report(start >= time, "start >= set value"); 76 77 mdelay(ms_to_wait); 78 79 cc = stck(&end); 80 report(!cc, "store end clock cc=%d", cc); 81 report(end > time, "end > set value"); 82 83 report(end - start > (ticks_per_ms * ms_to_wait), "Advances"); 84 85 report_prefix_pop(); 86 } 87 88 int main(void) 89 { 90 report_prefix_push("sck"); 91 92 if (uv_os_is_guest()) { 93 report_skip("Test unsupported under PV"); 94 goto out; 95 } 96 97 test_align(); 98 test_set(); 99 test_priv(); 100 101 out: 102 report_prefix_pop(); 103 return report_summary(); 104 } 105