Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /*
3 : : * Copyright 2013-2018 IBM Corp.
4 : : */
5 : :
6 : : #include <config.h>
7 : :
8 : : #define BITS_PER_LONG (sizeof(long) * 8)
9 : :
10 : : #include "dummy-cpu.h"
11 : :
12 : : #include <stdlib.h>
13 : :
14 : 2 : static void *real_malloc(size_t size)
15 : : {
16 : 2 : return malloc(size);
17 : : }
18 : :
19 : 2 : static void real_free(void *p)
20 : : {
21 : 2 : return free(p);
22 : : }
23 : :
24 : : #undef malloc
25 : : #undef free
26 : : #undef realloc
27 : :
28 : : #include <skiboot.h>
29 : : #include <mem_region-malloc.h>
30 : :
31 : : /* We need mem_region to accept __location__ */
32 : : #define is_rodata(p) true
33 : : #include "../mem_region.c"
34 : : #include "../malloc.c"
35 : :
36 : : /* But we need device tree to make copies of names. */
37 : : #undef is_rodata
38 : : #define is_rodata(p) false
39 : : #include "../../libc/string/strdup.c"
40 : :
41 : : #include "../device.c"
42 : : #include <assert.h>
43 : : #include <stdio.h>
44 : :
45 : : enum proc_chip_quirks proc_chip_quirks;
46 : :
47 : 183 : void lock_caller(struct lock *l, const char *caller)
48 : : {
49 : : (void)caller;
50 : 183 : assert(!l->lock_val);
51 : 183 : l->lock_val++;
52 : 183 : }
53 : :
54 : 183 : void unlock(struct lock *l)
55 : : {
56 : 183 : assert(l->lock_val);
57 : 183 : l->lock_val--;
58 : 183 : }
59 : :
60 : 175 : bool lock_held_by_me(struct lock *l)
61 : : {
62 : 175 : return l->lock_val;
63 : : }
64 : :
65 : : #define TEST_HEAP_ORDER 16
66 : : #define TEST_HEAP_SIZE (1ULL << TEST_HEAP_ORDER)
67 : :
68 : 1 : static void add_mem_node(uint64_t start, uint64_t len)
69 : : {
70 : : struct dt_node *mem;
71 : : u64 reg[2];
72 : : char *name;
73 : :
74 : 1 : name = (char*)malloc(sizeof("memory@") + STR_MAX_CHARS(reg[0]));
75 : 1 : assert(name);
76 : :
77 : : /* reg contains start and length */
78 : 1 : reg[0] = cpu_to_be64(start);
79 : 1 : reg[1] = cpu_to_be64(len);
80 : :
81 : 1 : sprintf(name, "memory@%llx", (long long)start);
82 : :
83 : 1 : mem = dt_new(dt_root, name);
84 : 1 : dt_add_property_string(mem, "device_type", "memory");
85 : 1 : dt_add_property(mem, "reg", reg, sizeof(reg));
86 : 1 : free(name);
87 : 1 : }
88 : :
89 : 1 : void add_chip_dev_associativity(struct dt_node *dev __attribute__((unused)))
90 : : {
91 : 1 : }
92 : :
93 : : static struct {
94 : : const char *name;
95 : : uint64_t addr;
96 : : bool found;
97 : : } test_regions[] = {
98 : : { "test.1", 0x1000, false },
99 : : { "test.2", 0x2000, false },
100 : : { "test.3", 0x4000, false },
101 : : };
102 : :
103 : 1 : static void check_property_reservations(void)
104 : : {
105 : : const struct dt_property *names, *ranges;
106 : : unsigned int i, l;
107 : : const char *name;
108 : : uint64_t *rangep;
109 : : const char *at;
110 : :
111 : : /* check dt properties */
112 : 1 : names = dt_find_property(dt_root, "reserved-names");
113 : 1 : ranges = dt_find_property(dt_root, "reserved-ranges");
114 : :
115 : 1 : assert(names && ranges);
116 : :
117 : : /* walk through names & ranges properies, ensuring that the test
118 : : * regions are all present */
119 : 1 : for (name = names->prop, rangep = (uint64_t *)ranges->prop;
120 : 9 : name < names->prop + names->len;
121 : 8 : name += l, rangep += 2) {
122 : : uint64_t addr;
123 : :
124 : 8 : addr = dt_get_number(rangep, 2);
125 : 8 : l = strlen(name) + 1;
126 : :
127 : 32 : for (i = 0; i < ARRAY_SIZE(test_regions); i++) {
128 : 24 : at = strchr(name, '@');
129 : 48 : if (strncmp(test_regions[i].name, name,
130 : 24 : at ? at-name: strlen(name)))
131 : 21 : continue;
132 : 3 : assert(test_regions[i].addr == addr);
133 : 3 : assert(!test_regions[i].found);
134 : 3 : test_regions[i].found = true;
135 : : }
136 : : }
137 : :
138 : 4 : for (i = 0; i < ARRAY_SIZE(test_regions); i++) {
139 : 3 : assert(test_regions[i].found);
140 : 3 : test_regions[i].found = false;
141 : : }
142 : 1 : }
143 : :
144 : 1 : static void check_node_reservations(void)
145 : : {
146 : : struct dt_node *parent, *node;
147 : : unsigned int i;
148 : :
149 : 1 : parent = dt_find_by_name(dt_root, "reserved-memory");
150 : 1 : assert(parent);
151 : :
152 : 1 : assert(dt_prop_get_cell(parent, "#address-cells", 0) == 2);
153 : 1 : assert(dt_prop_get_cell(parent, "#size-cells", 0) == 2);
154 : 1 : dt_require_property(parent, "ranges", 0);
155 : :
156 : 9 : dt_for_each_child(parent, node) {
157 : : uint64_t addr, size;
158 : :
159 : 8 : addr = dt_get_address(node, 0, &size);
160 : :
161 : 32 : for (i = 0; i < ARRAY_SIZE(test_regions); i++) {
162 : 24 : if (strncmp(test_regions[i].name, node->name,
163 : : strlen(test_regions[i].name)))
164 : 21 : continue;
165 : :
166 : 3 : assert(!test_regions[i].found);
167 : 3 : assert(test_regions[i].addr == addr);
168 : 3 : assert(size == 0x1000);
169 : 3 : test_regions[i].found = true;
170 : : }
171 : : }
172 : :
173 : 4 : for (i = 0; i < ARRAY_SIZE(test_regions); i++) {
174 : 3 : assert(test_regions[i].found);
175 : 3 : test_regions[i].found = false;
176 : : }
177 : 1 : }
178 : :
179 : 1 : int main(void)
180 : : {
181 : : struct mem_region *r;
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 : 1 : skiboot_os_reserve.len = skiboot_heap.start;
189 : :
190 : 1 : dt_root = dt_new_root("");
191 : 1 : dt_add_property_cells(dt_root, "#address-cells", 2);
192 : 1 : dt_add_property_cells(dt_root, "#size-cells", 2);
193 : :
194 : 1 : buf = real_malloc(1024*1024);
195 : 1 : add_mem_node((unsigned long)buf, 1024*1024);
196 : :
197 : : /* add pre-init reservations */
198 : 4 : for (i = 0; i < ARRAY_SIZE(test_regions); i++)
199 : 3 : mem_reserve_fw(test_regions[i].name,
200 : : test_regions[i].addr, 0x1000);
201 : :
202 : : /* Now convert. */
203 : 1 : mem_region_init();
204 : :
205 : : /* add a post-init reservation */
206 : 1 : mem_reserve_fw("test.4", 0x5000, 0x1000);
207 : :
208 : : /* release unused */
209 : 1 : mem_region_release_unused();
210 : :
211 : : /* and create reservations */
212 : 1 : mem_region_add_dt_reserved();
213 : :
214 : : /* ensure we can't create further reservations */
215 : 1 : r = new_region("test.5", 0x5000, 0x1000, NULL, REGION_RESERVED);
216 : 1 : assert(!add_region(r));
217 : :
218 : : /* check old property-style reservations */
219 : 1 : check_property_reservations();
220 : :
221 : : /* and new node-style reservations */
222 : 1 : check_node_reservations();
223 : :
224 : 1 : dt_free(dt_root);
225 : 1 : real_free(buf);
226 : 1 : real_free((void *)(long)skiboot_heap.start);
227 : 1 : return 0;
228 : : }
|