| // SPDX-License-Identifier: GPL-2.0-only |
| /* |
| * Test the framework itself. These tests confirm that setup works. |
| * |
| * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com> |
| */ |
| #include <libcflat.h> |
| #include <cpumask.h> |
| #include <on-cpus.h> |
| #include <asm/processor.h> |
| #include <asm/setup.h> |
| #include <asm/smp.h> |
| |
| static void check_cpus(void) |
| { |
| int cpu; |
| |
| for_each_present_cpu(cpu) |
| report_info("CPU%3d: hartid=%08lx", cpu, cpus[cpu].hartid); |
| } |
| |
| static bool exceptions_work; |
| |
| static void handler(struct pt_regs *regs) |
| { |
| exceptions_work = true; |
| regs->epc += 2; |
| } |
| |
| static void check_exceptions(void) |
| { |
| install_exception_handler(EXC_INST_ILLEGAL, handler); |
| asm volatile(".4byte 0"); |
| install_exception_handler(EXC_INST_ILLEGAL, NULL); |
| report(exceptions_work, "exceptions"); |
| } |
| |
| static cpumask_t cpus_alive; |
| |
| static void check_secondary(void *data) |
| { |
| cpumask_set_cpu(smp_processor_id(), &cpus_alive); |
| } |
| |
| static void check_smp(void) |
| { |
| int cpu, me = smp_processor_id(); |
| bool fail = false; |
| |
| on_cpus(check_secondary, NULL); |
| |
| report(cpumask_full(&cpu_online_mask), "Brought up all cpus"); |
| report(cpumask_full(&cpus_alive), "check_secondary"); |
| |
| for_each_present_cpu(cpu) { |
| if (cpu == me) |
| continue; |
| if (!cpu_idle(cpu)) { |
| fail = true; |
| break; |
| } |
| } |
| report(!fail, "All secondaries are idle"); |
| } |
| |
| int main(int argc, char **argv) |
| { |
| bool r; |
| |
| report_prefix_push("selftest"); |
| |
| report(!strncmp(argv[0], "selftest", 8), "program name"); |
| |
| if (argc > 1) { |
| r = !strcmp(argv[1], "foo"); |
| if (argc > 2) |
| r &= !strcmp(argv[2], "bar"); |
| if (argc > 3) |
| r &= !strcmp(argv[3], "baz"); |
| report_info("matched %d command line parameters", argc - 1); |
| report(r, "command line parsing"); |
| } else { |
| report_skip("command line parsing"); |
| } |
| |
| if (getenv("FOO")) { |
| r = !strcmp(getenv("FOO"), "foo"); |
| r &= !strcmp(getenv("BAR"), "bar"); |
| r &= !strcmp(getenv("BAZ"), "baz"); |
| report(r, "environ parsing"); |
| } else { |
| report_skip("environ parsing"); |
| } |
| |
| check_exceptions(); |
| check_cpus(); |
| check_smp(); |
| |
| return report_summary(); |
| } |