xref: /kvm-unit-tests/riscv/selftest.c (revision 48d5952451de62a4db23cf73024f702cf1a64fc3)
1bd744d46SAndrew Jones // SPDX-License-Identifier: GPL-2.0-only
2bd744d46SAndrew Jones /*
3bd744d46SAndrew Jones  * Test the framework itself. These tests confirm that setup works.
4bd744d46SAndrew Jones  *
5bd744d46SAndrew Jones  * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
6bd744d46SAndrew Jones  */
7bd744d46SAndrew Jones #include <libcflat.h>
822f287f4SAndrew Jones #include <cpumask.h>
9*9c92b28eSAndrew Jones #include <on-cpus.h>
10386561f8SAndrew Jones #include <asm/processor.h>
1122f287f4SAndrew Jones #include <asm/setup.h>
12*9c92b28eSAndrew Jones #include <asm/smp.h>
13bd744d46SAndrew Jones 
check_cpus(void)1422f287f4SAndrew Jones static void check_cpus(void)
15bd744d46SAndrew Jones {
1622f287f4SAndrew Jones 	int cpu;
1722f287f4SAndrew Jones 
1822f287f4SAndrew Jones 	for_each_present_cpu(cpu)
19386561f8SAndrew Jones 		report_info("CPU%3d: hartid=%08lx", cpu, cpus[cpu].hartid);
20386561f8SAndrew Jones }
21386561f8SAndrew Jones 
22386561f8SAndrew Jones static bool exceptions_work;
23386561f8SAndrew Jones 
handler(struct pt_regs * regs)24386561f8SAndrew Jones static void handler(struct pt_regs *regs)
25386561f8SAndrew Jones {
26386561f8SAndrew Jones 	exceptions_work = true;
27386561f8SAndrew Jones 	regs->epc += 2;
28386561f8SAndrew Jones }
29386561f8SAndrew Jones 
check_exceptions(void)30386561f8SAndrew Jones static void check_exceptions(void)
31386561f8SAndrew Jones {
32386561f8SAndrew Jones 	install_exception_handler(EXC_INST_ILLEGAL, handler);
33386561f8SAndrew Jones 	asm volatile(".4byte 0");
34386561f8SAndrew Jones 	install_exception_handler(EXC_INST_ILLEGAL, NULL);
35386561f8SAndrew Jones 	report(exceptions_work, "exceptions");
3622f287f4SAndrew Jones }
3722f287f4SAndrew Jones 
38*9c92b28eSAndrew Jones static cpumask_t cpus_alive;
39*9c92b28eSAndrew Jones 
check_secondary(void * data)40*9c92b28eSAndrew Jones static void check_secondary(void *data)
41*9c92b28eSAndrew Jones {
42*9c92b28eSAndrew Jones 	cpumask_set_cpu(smp_processor_id(), &cpus_alive);
43*9c92b28eSAndrew Jones }
44*9c92b28eSAndrew Jones 
check_smp(void)45*9c92b28eSAndrew Jones static void check_smp(void)
46*9c92b28eSAndrew Jones {
47*9c92b28eSAndrew Jones 	int cpu, me = smp_processor_id();
48*9c92b28eSAndrew Jones 	bool fail = false;
49*9c92b28eSAndrew Jones 
50*9c92b28eSAndrew Jones 	on_cpus(check_secondary, NULL);
51*9c92b28eSAndrew Jones 
52*9c92b28eSAndrew Jones 	report(cpumask_full(&cpu_online_mask), "Brought up all cpus");
53*9c92b28eSAndrew Jones 	report(cpumask_full(&cpus_alive), "check_secondary");
54*9c92b28eSAndrew Jones 
55*9c92b28eSAndrew Jones 	for_each_present_cpu(cpu) {
56*9c92b28eSAndrew Jones 		if (cpu == me)
57*9c92b28eSAndrew Jones 			continue;
58*9c92b28eSAndrew Jones 		if (!cpu_idle(cpu)) {
59*9c92b28eSAndrew Jones 			fail = true;
60*9c92b28eSAndrew Jones 			break;
61*9c92b28eSAndrew Jones 		}
62*9c92b28eSAndrew Jones 	}
63*9c92b28eSAndrew Jones 	report(!fail, "All secondaries are idle");
64*9c92b28eSAndrew Jones }
65*9c92b28eSAndrew Jones 
main(int argc,char ** argv)6622f287f4SAndrew Jones int main(int argc, char **argv)
6722f287f4SAndrew Jones {
6822f287f4SAndrew Jones 	bool r;
6922f287f4SAndrew Jones 
7022f287f4SAndrew Jones 	report_prefix_push("selftest");
7122f287f4SAndrew Jones 
7222f287f4SAndrew Jones 	report(!strncmp(argv[0], "selftest", 8), "program name");
7322f287f4SAndrew Jones 
7422f287f4SAndrew Jones 	if (argc > 1) {
7522f287f4SAndrew Jones 		r = !strcmp(argv[1], "foo");
7622f287f4SAndrew Jones 		if (argc > 2)
7722f287f4SAndrew Jones 			r &= !strcmp(argv[2], "bar");
7822f287f4SAndrew Jones 		if (argc > 3)
7922f287f4SAndrew Jones 			r &= !strcmp(argv[3], "baz");
8022f287f4SAndrew Jones 		report_info("matched %d command line parameters", argc - 1);
8122f287f4SAndrew Jones 		report(r, "command line parsing");
8222f287f4SAndrew Jones 	} else {
8322f287f4SAndrew Jones 		report_skip("command line parsing");
8422f287f4SAndrew Jones 	}
8522f287f4SAndrew Jones 
8622f287f4SAndrew Jones 	if (getenv("FOO")) {
8722f287f4SAndrew Jones 		r = !strcmp(getenv("FOO"), "foo");
8822f287f4SAndrew Jones 		r &= !strcmp(getenv("BAR"), "bar");
8922f287f4SAndrew Jones 		r &= !strcmp(getenv("BAZ"), "baz");
9022f287f4SAndrew Jones 		report(r, "environ parsing");
9122f287f4SAndrew Jones 	} else {
9222f287f4SAndrew Jones 		report_skip("environ parsing");
9322f287f4SAndrew Jones 	}
9422f287f4SAndrew Jones 
95386561f8SAndrew Jones 	check_exceptions();
9622f287f4SAndrew Jones 	check_cpus();
97*9c92b28eSAndrew Jones 	check_smp();
9822f287f4SAndrew Jones 
9922f287f4SAndrew Jones 	return report_summary();
100bd744d46SAndrew Jones }
101