1fa624cc2SJanosch Frank /* SPDX-License-Identifier: GPL-2.0-only */
2331c31feSJanosch Frank /*
3331c31feSJanosch Frank * Store System Information tests
4331c31feSJanosch Frank *
5331c31feSJanosch Frank * Copyright (c) 2019 IBM Corp
6331c31feSJanosch Frank *
7331c31feSJanosch Frank * Authors:
8331c31feSJanosch Frank * Janosch Frank <frankja@linux.ibm.com>
9331c31feSJanosch Frank */
10331c31feSJanosch Frank
11331c31feSJanosch Frank #include <libcflat.h>
12*b108d8eeSNico Boehr #include <bitops.h>
13331c31feSJanosch Frank #include <asm/page.h>
14331c31feSJanosch Frank #include <asm/asm-offsets.h>
15331c31feSJanosch Frank #include <asm/interrupt.h>
16743713f7SJanosch Frank #include <smp.h>
17fcdc04e0SPierre Morel #include <stsi.h>
18331c31feSJanosch Frank
19331c31feSJanosch Frank static uint8_t pagebuf[PAGE_SIZE * 2] __attribute__((aligned(PAGE_SIZE * 2)));
20331c31feSJanosch Frank
test_specs(void)21331c31feSJanosch Frank static void test_specs(void)
22331c31feSJanosch Frank {
23*b108d8eeSNico Boehr int i;
24*b108d8eeSNico Boehr int cc;
25*b108d8eeSNico Boehr
26331c31feSJanosch Frank report_prefix_push("specification");
27331c31feSJanosch Frank
28*b108d8eeSNico Boehr for (i = 36; i <= 55; i++) {
29*b108d8eeSNico Boehr report_prefix_pushf("set invalid r0 bit %d", i);
30331c31feSJanosch Frank expect_pgm_int();
31*b108d8eeSNico Boehr stsi(pagebuf, 0, BIT(63 - i), 0);
32331c31feSJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
33331c31feSJanosch Frank report_prefix_pop();
34*b108d8eeSNico Boehr }
35331c31feSJanosch Frank
36*b108d8eeSNico Boehr for (i = 32; i <= 47; i++) {
37*b108d8eeSNico Boehr report_prefix_pushf("set invalid r1 bit %d", i);
38331c31feSJanosch Frank expect_pgm_int();
39*b108d8eeSNico Boehr stsi(pagebuf, 1, 0, BIT(63 - i));
40331c31feSJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
41331c31feSJanosch Frank report_prefix_pop();
42*b108d8eeSNico Boehr }
43*b108d8eeSNico Boehr
44*b108d8eeSNico Boehr for (i = 0; i < 32; i++) {
45*b108d8eeSNico Boehr report_prefix_pushf("r0 bit %d ignored", i);
46*b108d8eeSNico Boehr cc = stsi(pagebuf, 3, 2 | BIT(63 - i), 2);
47*b108d8eeSNico Boehr report(!cc, "CC = 0");
48*b108d8eeSNico Boehr report_prefix_pop();
49*b108d8eeSNico Boehr }
50*b108d8eeSNico Boehr
51*b108d8eeSNico Boehr for (i = 0; i < 32; i++) {
52*b108d8eeSNico Boehr report_prefix_pushf("r1 bit %d ignored", i);
53*b108d8eeSNico Boehr cc = stsi(pagebuf, 3, 2, 2 | BIT(63 - i));
54*b108d8eeSNico Boehr report(!cc, "CC = 0");
55*b108d8eeSNico Boehr report_prefix_pop();
56*b108d8eeSNico Boehr }
57331c31feSJanosch Frank
58331c31feSJanosch Frank report_prefix_push("unaligned");
59331c31feSJanosch Frank expect_pgm_int();
60a1bed535SJanosch Frank stsi(pagebuf + 42, 1, 1, 1);
61331c31feSJanosch Frank check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
62331c31feSJanosch Frank report_prefix_pop();
63331c31feSJanosch Frank
64331c31feSJanosch Frank report_prefix_pop();
65331c31feSJanosch Frank }
66331c31feSJanosch Frank
test_priv(void)67331c31feSJanosch Frank static void test_priv(void)
68331c31feSJanosch Frank {
69331c31feSJanosch Frank report_prefix_push("privileged");
70331c31feSJanosch Frank expect_pgm_int();
71331c31feSJanosch Frank enter_pstate();
72331c31feSJanosch Frank stsi(pagebuf, 0, 0, 0);
73331c31feSJanosch Frank check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
74331c31feSJanosch Frank report_prefix_pop();
75331c31feSJanosch Frank }
76331c31feSJanosch Frank
test_fc(void)77331c31feSJanosch Frank static void test_fc(void)
78331c31feSJanosch Frank {
79a299895bSThomas Huth report(stsi(pagebuf, 7, 0, 0) == 3, "invalid fc");
80a299895bSThomas Huth report(stsi(pagebuf, 1, 0, 1) == 3, "invalid selector 1");
81a299895bSThomas Huth report(stsi(pagebuf, 1, 1, 0) == 3, "invalid selector 2");
82242b02e3SPierre Morel report(stsi_get_fc() >= 2, "query fc >= 2");
83331c31feSJanosch Frank }
84331c31feSJanosch Frank
test_3_2_2(void)85743713f7SJanosch Frank static void test_3_2_2(void)
86743713f7SJanosch Frank {
87743713f7SJanosch Frank int rc;
88743713f7SJanosch Frank /* EBCDIC for "kvm-unit" */
89743713f7SJanosch Frank const uint8_t vm_name[] = { 0x92, 0xa5, 0x94, 0x60, 0xa4, 0x95, 0x89,
90743713f7SJanosch Frank 0xa3 };
91743713f7SJanosch Frank const uint8_t uuid[] = { 0x0f, 0xb8, 0x4a, 0x86, 0x72, 0x7c,
92743713f7SJanosch Frank 0x11, 0xea, 0xbc, 0x55, 0x02, 0x42, 0xac, 0x13,
93743713f7SJanosch Frank 0x00, 0x03 };
94743713f7SJanosch Frank /* EBCDIC for "KVM/" */
95743713f7SJanosch Frank const uint8_t cpi_kvm[] = { 0xd2, 0xe5, 0xd4, 0x61 };
960f1fe370SThomas Huth const char vm_name_ext[] = "kvm-unit-test";
97fcdc04e0SPierre Morel struct sysinfo_3_2_2 *data = (void *)pagebuf;
98743713f7SJanosch Frank
99743713f7SJanosch Frank report_prefix_push("3.2.2");
100743713f7SJanosch Frank
101743713f7SJanosch Frank /* Is the function code available at all? */
102242b02e3SPierre Morel if (stsi_get_fc() < 3) {
103743713f7SJanosch Frank report_skip("Running under lpar, no level 3 to test.");
104743713f7SJanosch Frank goto out;
105743713f7SJanosch Frank }
106743713f7SJanosch Frank
107743713f7SJanosch Frank rc = stsi(pagebuf, 3, 2, 2);
108743713f7SJanosch Frank report(!rc, "call");
109743713f7SJanosch Frank
110743713f7SJanosch Frank /* For now we concentrate on KVM/QEMU */
111743713f7SJanosch Frank if (memcmp(&data->vm[0].cpi, cpi_kvm, sizeof(cpi_kvm))) {
112743713f7SJanosch Frank report_skip("Not running under KVM/QEMU.");
113743713f7SJanosch Frank goto out;
114743713f7SJanosch Frank }
115743713f7SJanosch Frank
116743713f7SJanosch Frank report(!memcmp(data->vm[0].uuid, uuid, sizeof(uuid)), "uuid");
1179d7f9a2fSJanosch Frank report(data->vm[0].conf_cpus == smp_query_num_cpus(), "cpu count configured");
118743713f7SJanosch Frank report(data->vm[0].total_cpus ==
119743713f7SJanosch Frank data->vm[0].reserved_cpus + data->vm[0].conf_cpus,
1209d7f9a2fSJanosch Frank "cpu count total == conf + reserved");
1219d7f9a2fSJanosch Frank report(data->vm[0].standby_cpus == 0, "cpu count standby");
122743713f7SJanosch Frank report(!memcmp(data->vm[0].name, vm_name, sizeof(data->vm[0].name)),
123743713f7SJanosch Frank "VM name == kvm-unit-test");
124743713f7SJanosch Frank
125743713f7SJanosch Frank if (data->vm[0].ext_name_encoding != 2) {
126743713f7SJanosch Frank report_skip("Extended VM names are not UTF-8.");
127743713f7SJanosch Frank goto out;
128743713f7SJanosch Frank }
129743713f7SJanosch Frank report(!memcmp(data->ext_names[0], vm_name_ext, sizeof(vm_name_ext)),
130743713f7SJanosch Frank "ext VM name == kvm-unit-test");
131743713f7SJanosch Frank
132743713f7SJanosch Frank out:
133743713f7SJanosch Frank report_prefix_pop();
134743713f7SJanosch Frank }
135743713f7SJanosch Frank
main(void)136331c31feSJanosch Frank int main(void)
137331c31feSJanosch Frank {
138331c31feSJanosch Frank report_prefix_push("stsi");
139331c31feSJanosch Frank test_priv();
140331c31feSJanosch Frank test_specs();
141331c31feSJanosch Frank test_fc();
142743713f7SJanosch Frank test_3_2_2();
143331c31feSJanosch Frank return report_summary();
144331c31feSJanosch Frank }
145