1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * SBI verification 4 * 5 * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com> 6 */ 7 #include <libcflat.h> 8 #include <stdlib.h> 9 #include <asm/sbi.h> 10 11 static void help(void) 12 { 13 puts("Test SBI\n"); 14 puts("An environ must be provided where expected values are given.\n"); 15 } 16 17 static struct sbiret __base_sbi_ecall(int fid, unsigned long arg0) 18 { 19 return sbi_ecall(SBI_EXT_BASE, fid, arg0, 0, 0, 0, 0, 0); 20 } 21 22 static bool env_or_skip(const char *env) 23 { 24 if (!getenv(env)) { 25 report_skip("missing %s environment variable", env); 26 return false; 27 } 28 29 return true; 30 } 31 32 static void gen_report(struct sbiret *ret, 33 long expected_error, long expected_value) 34 { 35 bool check_error = ret->error == expected_error; 36 bool check_value = ret->value == expected_value; 37 38 if (!check_error || !check_value) 39 report_info("expected (error: %ld, value: %ld), received: (error: %ld, value %ld)", 40 expected_error, expected_value, ret->error, ret->value); 41 42 report(check_error, "expected sbi.error"); 43 report(check_value, "expected sbi.value"); 44 } 45 46 static void check_base(void) 47 { 48 struct sbiret ret; 49 long expected; 50 51 report_prefix_push("base"); 52 53 ret = __base_sbi_ecall(SBI_EXT_BASE_GET_SPEC_VERSION, 0); 54 if (ret.error || ret.value < 2) { 55 report_skip("SBI spec version 0.2 or higher required"); 56 return; 57 } 58 59 report_prefix_push("spec_version"); 60 if (env_or_skip("SPEC_VERSION")) { 61 expected = strtol(getenv("SPEC_VERSION"), NULL, 0); 62 gen_report(&ret, 0, expected); 63 } 64 report_prefix_pop(); 65 66 report_prefix_push("impl_id"); 67 if (env_or_skip("IMPL_ID")) { 68 expected = strtol(getenv("IMPL_ID"), NULL, 0); 69 ret = __base_sbi_ecall(SBI_EXT_BASE_GET_IMP_ID, 0); 70 gen_report(&ret, 0, expected); 71 } 72 report_prefix_pop(); 73 74 report_prefix_push("impl_version"); 75 if (env_or_skip("IMPL_VERSION")) { 76 expected = strtol(getenv("IMPL_VERSION"), NULL, 0); 77 ret = __base_sbi_ecall(SBI_EXT_BASE_GET_IMP_VERSION, 0); 78 gen_report(&ret, 0, expected); 79 } 80 report_prefix_pop(); 81 82 report_prefix_push("probe_ext"); 83 expected = getenv("PROBE_EXT") ? strtol(getenv("PROBE_EXT"), NULL, 0) : 1; 84 ret = __base_sbi_ecall(SBI_EXT_BASE_PROBE_EXT, SBI_EXT_BASE); 85 gen_report(&ret, 0, expected); 86 report_prefix_push("unavailable"); 87 ret = __base_sbi_ecall(SBI_EXT_BASE_PROBE_EXT, 0xb000000); 88 gen_report(&ret, 0, 0); 89 report_prefix_pop(); 90 report_prefix_pop(); 91 92 report_prefix_push("mvendorid"); 93 if (env_or_skip("MVENDORID")) { 94 expected = strtol(getenv("MVENDORID"), NULL, 0); 95 ret = __base_sbi_ecall(SBI_EXT_BASE_GET_MVENDORID, 0); 96 gen_report(&ret, 0, expected); 97 } 98 report_prefix_pop(); 99 100 report_prefix_push("marchid"); 101 if (env_or_skip("MARCHID")) { 102 expected = strtol(getenv("MARCHID"), NULL, 0); 103 ret = __base_sbi_ecall(SBI_EXT_BASE_GET_MARCHID, 0); 104 gen_report(&ret, 0, expected); 105 } 106 report_prefix_pop(); 107 108 report_prefix_push("mimpid"); 109 if (env_or_skip("MIMPID")) { 110 expected = strtol(getenv("MIMPID"), NULL, 0); 111 ret = __base_sbi_ecall(SBI_EXT_BASE_GET_MIMPID, 0); 112 gen_report(&ret, 0, expected); 113 } 114 report_prefix_pop(); 115 116 report_prefix_pop(); 117 } 118 119 int main(int argc, char **argv) 120 { 121 122 if (argc > 1 && !strcmp(argv[1], "-h")) { 123 help(); 124 exit(0); 125 } 126 127 report_prefix_push("sbi"); 128 check_base(); 129 130 return report_summary(); 131 } 132