accel/qaic: Add AIC200 support
[drm/drm-misc.git] / tools / testing / memblock / tests / common.c
blob3250c8e5124b37f18b086069fa9e754e3e225ccd
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #include "tests/common.h"
3 #include <string.h>
4 #include <getopt.h>
5 #include <linux/memory_hotplug.h>
6 #include <linux/build_bug.h>
8 #define PREFIXES_MAX 15
9 #define DELIM ": "
10 #define BASIS 10000
12 static struct test_memory memory_block;
13 static const char __maybe_unused *prefixes[PREFIXES_MAX];
14 static int __maybe_unused nr_prefixes;
16 static const char *short_opts = "hmv";
17 static const struct option long_opts[] = {
18 {"help", 0, NULL, 'h'},
19 {"movable-node", 0, NULL, 'm'},
20 {"verbose", 0, NULL, 'v'},
21 {NULL, 0, NULL, 0}
24 static const char * const help_opts[] = {
25 "display this help message and exit",
26 "disallow allocations from regions marked as hotplugged\n\t\t\t"
27 "by simulating enabling the \"movable_node\" kernel\n\t\t\t"
28 "parameter",
29 "enable verbose output, which includes the name of the\n\t\t\t"
30 "memblock function being tested, the name of the test,\n\t\t\t"
31 "and whether the test passed or failed."
34 static int verbose;
36 /* sets global variable returned by movable_node_is_enabled() stub */
37 bool movable_node_enabled;
39 void reset_memblock_regions(void)
41 memset(memblock.memory.regions, 0,
42 memblock.memory.cnt * sizeof(struct memblock_region));
43 memblock.memory.cnt = 0;
44 memblock.memory.max = INIT_MEMBLOCK_REGIONS;
45 memblock.memory.total_size = 0;
47 memset(memblock.reserved.regions, 0,
48 memblock.reserved.cnt * sizeof(struct memblock_region));
49 memblock.reserved.cnt = 0;
50 memblock.reserved.max = INIT_MEMBLOCK_RESERVED_REGIONS;
51 memblock.reserved.total_size = 0;
54 void reset_memblock_attributes(void)
56 memblock.memory.name = "memory";
57 memblock.reserved.name = "reserved";
58 memblock.bottom_up = false;
59 memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE;
62 static inline void fill_memblock(void)
64 memset(memory_block.base, 1, PHYS_MEM_SIZE);
67 void setup_memblock(void)
69 reset_memblock_regions();
70 memblock_add((phys_addr_t)memory_block.base, MEM_SIZE);
71 fill_memblock();
74 /**
75 * setup_numa_memblock:
76 * Set up a memory layout with multiple NUMA nodes in a previously allocated
77 * dummy physical memory.
78 * @node_fracs: an array representing the fraction of MEM_SIZE contained in
79 * each node in basis point units (one hundredth of 1% or 1/10000).
80 * For example, if node 0 should contain 1/8 of MEM_SIZE,
81 * node_fracs[0] = 1250.
83 * The nids will be set to 0 through NUMA_NODES - 1.
85 void setup_numa_memblock(const unsigned int node_fracs[])
87 phys_addr_t base;
88 int flags;
90 reset_memblock_regions();
91 base = (phys_addr_t)memory_block.base;
92 flags = (movable_node_is_enabled()) ? MEMBLOCK_NONE : MEMBLOCK_HOTPLUG;
94 for (int i = 0; i < NUMA_NODES; i++) {
95 assert(node_fracs[i] <= BASIS);
96 phys_addr_t size = MEM_SIZE * node_fracs[i] / BASIS;
98 memblock_add_node(base, size, i, flags);
99 base += size;
101 fill_memblock();
104 void dummy_physical_memory_init(void)
106 memory_block.base = malloc(PHYS_MEM_SIZE);
107 assert(memory_block.base);
108 fill_memblock();
111 void dummy_physical_memory_cleanup(void)
113 free(memory_block.base);
116 phys_addr_t dummy_physical_memory_base(void)
118 return (phys_addr_t)memory_block.base;
121 static void usage(const char *prog)
123 BUILD_BUG_ON(ARRAY_SIZE(help_opts) != ARRAY_SIZE(long_opts) - 1);
125 printf("Usage: %s [-%s]\n", prog, short_opts);
127 for (int i = 0; long_opts[i].name; i++) {
128 printf(" -%c, --%-12s\t%s\n", long_opts[i].val,
129 long_opts[i].name, help_opts[i]);
132 exit(1);
135 void parse_args(int argc, char **argv)
137 int c;
139 while ((c = getopt_long_only(argc, argv, short_opts, long_opts,
140 NULL)) != -1) {
141 switch (c) {
142 case 'm':
143 movable_node_enabled = true;
144 break;
145 case 'v':
146 verbose = 1;
147 break;
148 default:
149 usage(argv[0]);
154 void print_prefixes(const char *postfix)
156 for (int i = 0; i < nr_prefixes; i++)
157 test_print("%s%s", prefixes[i], DELIM);
158 test_print(postfix);
161 void test_fail(void)
163 if (verbose) {
164 ksft_test_result_fail(": ");
165 print_prefixes("failed\n");
169 void test_pass(void)
171 if (verbose) {
172 ksft_test_result_pass(": ");
173 print_prefixes("passed\n");
177 void test_print(const char *fmt, ...)
179 if (verbose) {
180 int saved_errno = errno;
181 va_list args;
183 va_start(args, fmt);
184 errno = saved_errno;
185 vprintf(fmt, args);
186 va_end(args);
190 void prefix_reset(void)
192 memset(prefixes, 0, PREFIXES_MAX * sizeof(char *));
193 nr_prefixes = 0;
196 void prefix_push(const char *prefix)
198 assert(nr_prefixes < PREFIXES_MAX);
199 prefixes[nr_prefixes] = prefix;
200 nr_prefixes++;
203 void prefix_pop(void)
205 if (nr_prefixes > 0) {
206 prefixes[nr_prefixes - 1] = 0;
207 nr_prefixes--;