Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /*
3 : : * Copyright 2015-2019 IBM Corp.
4 : : */
5 : :
6 : : #include <config.h>
7 : :
8 : : /* The lock backtrace structures consume too much room on the skiboot heap */
9 : : #undef DEBUG_LOCKS_BACKTRACE
10 : :
11 : : #define BITS_PER_LONG (sizeof(long) * 8)
12 : :
13 : : #include "dummy-cpu.h"
14 : :
15 : : #include <stdlib.h>
16 : :
17 : 2 : static void *real_malloc(size_t size)
18 : : {
19 : 2 : return malloc(size);
20 : : }
21 : :
22 : 2 : static void real_free(void *p)
23 : : {
24 : 2 : return free(p);
25 : : }
26 : :
27 : : #undef malloc
28 : : #undef free
29 : : #undef realloc
30 : :
31 : : #include <skiboot.h>
32 : : #include <mem_region-malloc.h>
33 : :
34 : : /* We need mem_region to accept __location__ */
35 : : #define is_rodata(p) true
36 : : #include "../mem_region.c"
37 : : #include "../malloc.c"
38 : :
39 : : /* But we need device tree to make copies of names. */
40 : : #undef is_rodata
41 : : #define is_rodata(p) false
42 : : #include "../../libc/string/strdup.c"
43 : :
44 : : #include "../device.c"
45 : : #include <assert.h>
46 : : #include <stdio.h>
47 : :
48 : : enum proc_chip_quirks proc_chip_quirks;
49 : :
50 : 124 : void lock_caller(struct lock *l, const char *caller)
51 : : {
52 : : (void)caller;
53 : 124 : assert(!l->lock_val);
54 : 124 : l->lock_val++;
55 : 124 : }
56 : :
57 : 124 : void unlock(struct lock *l)
58 : : {
59 : 124 : assert(l->lock_val);
60 : 124 : l->lock_val--;
61 : 124 : }
62 : :
63 : 75 : bool lock_held_by_me(struct lock *l)
64 : : {
65 : 75 : return l->lock_val;
66 : : }
67 : :
68 : : #define TEST_HEAP_ORDER 16
69 : : #define TEST_HEAP_SIZE (1ULL << TEST_HEAP_ORDER)
70 : :
71 : 1 : static void add_mem_node(uint64_t start, uint64_t len)
72 : : {
73 : : struct dt_node *mem;
74 : : u64 reg[2];
75 : : char *name;
76 : :
77 : 1 : name = (char*)malloc(sizeof("memory@") + STR_MAX_CHARS(reg[0]));
78 : 1 : assert(name);
79 : :
80 : : /* reg contains start and length */
81 : 1 : reg[0] = cpu_to_be64(start);
82 : 1 : reg[1] = cpu_to_be64(len);
83 : :
84 : 1 : sprintf(name, "memory@%llx", (long long)start);
85 : :
86 : 1 : mem = dt_new(dt_root, name);
87 : 1 : dt_add_property_string(mem, "device_type", "memory");
88 : 1 : dt_add_property(mem, "reg", reg, sizeof(reg));
89 : 1 : free(name);
90 : 1 : }
91 : :
92 : 14 : void add_chip_dev_associativity(struct dt_node *dev __attribute__((unused)))
93 : : {
94 : 14 : }
95 : :
96 : : struct test_region {
97 : : uint64_t start;
98 : : uint64_t end;
99 : : };
100 : :
101 : : static struct test {
102 : : struct test_region regions[3];
103 : : bool reserved;
104 : : } tests[] = {
105 : : /* empty region set */
106 : : { { { 0 } }, false },
107 : :
108 : : /* single exact match */
109 : : { { { 0x1000, 0x2000 }, }, true },
110 : :
111 : : /* overlap downwards */
112 : : { { { 0x0fff, 0x2000 }, }, true },
113 : :
114 : : /* overlap upwards */
115 : : { { { 0x1000, 0x2001 }, }, true },
116 : :
117 : : /* missing first byte */
118 : : { { { 0x1001, 0x2000 }, }, false },
119 : :
120 : : /* missing last byte */
121 : : { { { 0x1000, 0x1fff }, }, false },
122 : :
123 : : /* two regions, full coverage, split before start of range */
124 : : { { { 0x0500, 0x1000 }, { 0x1000, 0x2500 } }, true },
125 : :
126 : : /* two regions, full coverage, split after start of range */
127 : : { { { 0x0500, 0x1001 }, { 0x1001, 0x2500 } }, true },
128 : :
129 : : /* two regions, full coverage, split at middle of range */
130 : : { { { 0x0500, 0x1500 }, { 0x1500, 0x2500 } }, true },
131 : :
132 : : /* two regions, full coverage, split before end of range */
133 : : { { { 0x0500, 0x1fff }, { 0x1fff, 0x2500 } }, true },
134 : :
135 : : /* two regions, full coverage, split after end of range */
136 : : { { { 0x0500, 0x2000 }, { 0x2000, 0x2500 } }, true },
137 : :
138 : : /* two regions, missing byte in middle of range */
139 : : { { { 0x0500, 0x14ff }, { 0x1500, 0x2500 } }, false },
140 : :
141 : : /* two regions, missing byte after start of range */
142 : : { { { 0x0500, 0x1000 }, { 0x1001, 0x2500 } }, false },
143 : :
144 : : /* two regions, missing byte before end of range */
145 : : { { { 0x0500, 0x1fff }, { 0x2000, 0x2500 } }, false },
146 : : };
147 : :
148 : 14 : static void run_test(struct test *test)
149 : : {
150 : : struct test_region *r;
151 : : bool reserved;
152 : :
153 : 14 : list_head_init(®ions);
154 : :
155 : 14 : mem_region_init();
156 : :
157 : : /* create our reservations */
158 : 35 : for (r = test->regions; r->start; r++)
159 : 21 : mem_reserve_fw("r", r->start, r->end - r->start);
160 : :
161 : 14 : reserved = mem_range_is_reserved(0x1000, 0x1000);
162 : :
163 : 14 : if (reserved != test->reserved) {
164 : : struct mem_region *r;
165 : 0 : fprintf(stderr, "test failed; got %s, expected %s\n",
166 : : reserved ? "reserved" : "unreserved",
167 : 0 : test->reserved ? "reserved" : "unreserved");
168 : :
169 : 0 : fprintf(stderr, "reserved regions:\n");
170 : :
171 : 0 : list_for_each(®ions, r, list) {
172 : 0 : fprintf(stderr, "\t: %08"PRIx64"[%08"PRIx64"] %s\n",
173 : : r->start, r->len, r->name);
174 : : }
175 : 0 : exit(EXIT_FAILURE);
176 : : }
177 : 14 : }
178 : :
179 : :
180 : 1 : int main(void)
181 : : {
182 : : unsigned int i;
183 : : void *buf;
184 : :
185 : : /* Use malloc for the heap, so valgrind can find issues. */
186 : 1 : skiboot_heap.start = (long)real_malloc(TEST_HEAP_SIZE);
187 : 1 : skiboot_heap.len = TEST_HEAP_SIZE;
188 : :
189 : : /* shift the OS reserve area out of the way of our playground */
190 : 1 : skiboot_os_reserve.start = 0x100000;
191 : 1 : skiboot_os_reserve.len = 0x1000;
192 : :
193 : 1 : dt_root = dt_new_root("");
194 : 1 : dt_add_property_cells(dt_root, "#address-cells", 2);
195 : 1 : dt_add_property_cells(dt_root, "#size-cells", 2);
196 : :
197 : 1 : buf = real_malloc(1024*1024);
198 : 1 : add_mem_node((unsigned long)buf, 1024*1024);
199 : :
200 : 15 : for (i = 0; i < ARRAY_SIZE(tests); i++)
201 : 14 : run_test(&tests[i]);
202 : :
203 : 1 : dt_free(dt_root);
204 : 1 : real_free(buf);
205 : 1 : real_free((void *)(long)skiboot_heap.start);
206 : 1 : return 0;
207 : : }
|