162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci#include <stddef.h> 362306a36Sopenharmony_ci#include <asm/hwprobe.h> 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * Rather than relying on having a new enough libc to define this, just do it 762306a36Sopenharmony_ci * ourselves. This way we don't need to be coupled to a new-enough libc to 862306a36Sopenharmony_ci * contain the call. 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_cilong riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count, 1162306a36Sopenharmony_ci size_t cpu_count, unsigned long *cpus, unsigned int flags); 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ciint main(int argc, char **argv) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci struct riscv_hwprobe pairs[8]; 1662306a36Sopenharmony_ci unsigned long cpus; 1762306a36Sopenharmony_ci long out; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci /* Fake the CPU_SET ops. */ 2062306a36Sopenharmony_ci cpus = -1; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci /* 2362306a36Sopenharmony_ci * Just run a basic test: pass enough pairs to get up to the base 2462306a36Sopenharmony_ci * behavior, and then check to make sure it's sane. 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci for (long i = 0; i < 8; i++) 2762306a36Sopenharmony_ci pairs[i].key = i; 2862306a36Sopenharmony_ci out = riscv_hwprobe(pairs, 8, 1, &cpus, 0); 2962306a36Sopenharmony_ci if (out != 0) 3062306a36Sopenharmony_ci return -1; 3162306a36Sopenharmony_ci for (long i = 0; i < 4; ++i) { 3262306a36Sopenharmony_ci /* Fail if the kernel claims not to recognize a base key. */ 3362306a36Sopenharmony_ci if ((i < 4) && (pairs[i].key != i)) 3462306a36Sopenharmony_ci return -2; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci if (pairs[i].key != RISCV_HWPROBE_KEY_BASE_BEHAVIOR) 3762306a36Sopenharmony_ci continue; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci if (pairs[i].value & RISCV_HWPROBE_BASE_BEHAVIOR_IMA) 4062306a36Sopenharmony_ci continue; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci return -3; 4362306a36Sopenharmony_ci } 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci /* 4662306a36Sopenharmony_ci * This should also work with a NULL CPU set, but should not work 4762306a36Sopenharmony_ci * with an improperly supplied CPU set. 4862306a36Sopenharmony_ci */ 4962306a36Sopenharmony_ci out = riscv_hwprobe(pairs, 8, 0, 0, 0); 5062306a36Sopenharmony_ci if (out != 0) 5162306a36Sopenharmony_ci return -4; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci out = riscv_hwprobe(pairs, 8, 0, &cpus, 0); 5462306a36Sopenharmony_ci if (out == 0) 5562306a36Sopenharmony_ci return -5; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci out = riscv_hwprobe(pairs, 8, 1, 0, 0); 5862306a36Sopenharmony_ci if (out == 0) 5962306a36Sopenharmony_ci return -6; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci /* 6262306a36Sopenharmony_ci * Check that keys work by providing one that we know exists, and 6362306a36Sopenharmony_ci * checking to make sure the resultig pair is what we asked for. 6462306a36Sopenharmony_ci */ 6562306a36Sopenharmony_ci pairs[0].key = RISCV_HWPROBE_KEY_BASE_BEHAVIOR; 6662306a36Sopenharmony_ci out = riscv_hwprobe(pairs, 1, 1, &cpus, 0); 6762306a36Sopenharmony_ci if (out != 0) 6862306a36Sopenharmony_ci return -7; 6962306a36Sopenharmony_ci if (pairs[0].key != RISCV_HWPROBE_KEY_BASE_BEHAVIOR) 7062306a36Sopenharmony_ci return -8; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* 7362306a36Sopenharmony_ci * Check that an unknown key gets overwritten with -1, 7462306a36Sopenharmony_ci * but doesn't block elements after it. 7562306a36Sopenharmony_ci */ 7662306a36Sopenharmony_ci pairs[0].key = 0x5555; 7762306a36Sopenharmony_ci pairs[1].key = 1; 7862306a36Sopenharmony_ci pairs[1].value = 0xAAAA; 7962306a36Sopenharmony_ci out = riscv_hwprobe(pairs, 2, 0, 0, 0); 8062306a36Sopenharmony_ci if (out != 0) 8162306a36Sopenharmony_ci return -9; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci if (pairs[0].key != -1) 8462306a36Sopenharmony_ci return -10; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if ((pairs[1].key != 1) || (pairs[1].value == 0xAAAA)) 8762306a36Sopenharmony_ci return -11; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci return 0; 9062306a36Sopenharmony_ci} 91