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