xref: /spdk/test/common/lib/test_env.c (revision 22898a91b9b6f289933db19b0175821cfb7e7820)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/stdinc.h"
35 
36 #include "spdk_internal/mock.h"
37 
38 #include "spdk/env.h"
39 
40 /*
41  * NOTE:
42  * Functions in this file are mocks for SPDK based functions
43  * and work conceptually in the same way that mocks work in
44  * /lib/ut_mock. However, the globals that control the behavior
45  * of the mock are defined here, with each function, as
46  * opposed to being defined as part of the macro that defines
47  * the stub or wrapper for other types of functions. Be sure
48  * to use the correct global variable naming convention when
49  * working with these functions. See /lib/ut_mock for details.
50  */
51 
52 /*
53  * these stubs have a return value set with one of the MOCK_SET macros
54  */
55 DEFINE_STUB(spdk_process_is_primary, bool, (void), true)
56 
57 DEFINE_STUB_VP(spdk_memzone_lookup, (const char *name), NULL)
58 
59 /*
60  * these mocks don't fit well with the library macro model because
61  * they do 'something' other than just return a pre-set value
62  */
63 
64 /* setup the mock control to pass thru by default */
65 void *ut_p_spdk_memzone_reserve = MOCK_PASS_THRU_P;
66 void *
67 spdk_memzone_reserve(const char *name, size_t len, int socket_id, unsigned flags)
68 {
69 	if (ut_p_spdk_memzone_reserve &&
70 	    ut_p_spdk_memzone_reserve == MOCK_PASS_THRU_P) {
71 		return malloc(len);
72 	} else {
73 		return ut_p_spdk_memzone_reserve;
74 	}
75 }
76 
77 void *
78 spdk_dma_malloc(size_t size, size_t align, uint64_t *phys_addr)
79 {
80 	void *buf = NULL;
81 	if (posix_memalign(&buf, align, size)) {
82 		return NULL;
83 	}
84 	if (phys_addr) {
85 		*phys_addr = (uint64_t)buf;
86 	}
87 	return buf;
88 }
89 
90 int ut_spdk_dma_zmalloc = (int)MOCK_PASS_THRU;
91 void *ut_p_spdk_dma_zmalloc = &ut_spdk_dma_zmalloc;
92 void *
93 spdk_dma_zmalloc(size_t size, size_t align, uint64_t *phys_addr)
94 {
95 	if (ut_p_spdk_dma_zmalloc &&
96 	    ut_spdk_dma_zmalloc == (int)MOCK_PASS_THRU) {
97 		void *buf = spdk_dma_malloc(size, align, phys_addr);
98 
99 		if (buf != NULL) {
100 			memset(buf, 0, size);
101 		}
102 		return buf;
103 	} else {
104 		return ut_p_spdk_dma_zmalloc;
105 	}
106 }
107 
108 void *
109 spdk_dma_malloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id)
110 {
111 	return spdk_dma_malloc(size, align, phys_addr);
112 }
113 
114 void *
115 spdk_dma_zmalloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id)
116 {
117 	return spdk_dma_zmalloc(size, align, phys_addr);
118 }
119 
120 void *
121 spdk_dma_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr)
122 {
123 	return realloc(buf, size);
124 }
125 
126 void spdk_dma_free(void *buf)
127 {
128 	if (ut_p_spdk_dma_zmalloc &&
129 	    ut_spdk_dma_zmalloc == (int)MOCK_PASS_THRU) {
130 		free(buf);
131 	}
132 }
133 
134 bool ut_fail_vtophys = false;
135 uint64_t spdk_vtophys(void *buf)
136 {
137 	if (ut_fail_vtophys) {
138 		return (uint64_t) - 1;
139 	} else {
140 		return (uintptr_t)buf;
141 	}
142 }
143 
144 void
145 spdk_memzone_dump(FILE *f)
146 {
147 	return;
148 }
149 
150 int
151 spdk_memzone_free(const char *name)
152 {
153 	return 0;
154 }
155 
156 struct test_mempool {
157 	size_t	count;
158 };
159 
160 struct spdk_mempool *
161 spdk_mempool_create(const char *name, size_t count,
162 		    size_t ele_size, size_t cache_size, int socket_id)
163 {
164 	struct test_mempool *mp;
165 
166 	mp = calloc(1, sizeof(*mp));
167 	if (mp == NULL) {
168 		return NULL;
169 	}
170 
171 	mp->count = count;
172 
173 	return (struct spdk_mempool *)mp;
174 }
175 
176 void
177 spdk_mempool_free(struct spdk_mempool *_mp)
178 {
179 	struct test_mempool *mp = (struct test_mempool *)_mp;
180 
181 	free(mp);
182 }
183 
184 void *
185 spdk_mempool_get(struct spdk_mempool *_mp)
186 {
187 	struct test_mempool *mp = (struct test_mempool *)_mp;
188 	void *buf;
189 
190 	if (mp && mp->count == 0) {
191 		return NULL;
192 	}
193 
194 	if (posix_memalign(&buf, 64, 0x1000)) {
195 		return NULL;
196 	} else {
197 		if (mp) {
198 			mp->count--;
199 		}
200 		return buf;
201 	}
202 }
203 
204 void
205 spdk_mempool_put(struct spdk_mempool *_mp, void *ele)
206 {
207 	struct test_mempool *mp = (struct test_mempool *)_mp;
208 
209 	if (mp) {
210 		mp->count++;
211 	}
212 	free(ele);
213 }
214 
215 size_t
216 spdk_mempool_count(const struct spdk_mempool *_mp)
217 {
218 	struct test_mempool *mp = (struct test_mempool *)_mp;
219 
220 	if (mp) {
221 		return mp->count;
222 	} else {
223 		return 1024;
224 	}
225 }
226 
227 uint64_t ut_tsc = 0;
228 uint64_t spdk_get_ticks(void)
229 {
230 	return ut_tsc;
231 }
232 
233 uint64_t spdk_get_ticks_hz(void)
234 {
235 	return 1000000;
236 }
237 
238 void spdk_delay_us(unsigned int us)
239 {
240 	ut_tsc += us;
241 }
242 
243 int
244 spdk_pci_addr_parse(struct spdk_pci_addr *addr, const char *bdf)
245 {
246 	unsigned domain, bus, dev, func;
247 
248 	if (addr == NULL || bdf == NULL) {
249 		return -EINVAL;
250 	}
251 
252 	if ((sscanf(bdf, "%x:%x:%x.%x", &domain, &bus, &dev, &func) == 4) ||
253 	    (sscanf(bdf, "%x.%x.%x.%x", &domain, &bus, &dev, &func) == 4)) {
254 		/* Matched a full address - all variables are initialized */
255 	} else if (sscanf(bdf, "%x:%x:%x", &domain, &bus, &dev) == 3) {
256 		func = 0;
257 	} else if ((sscanf(bdf, "%x:%x.%x", &bus, &dev, &func) == 3) ||
258 		   (sscanf(bdf, "%x.%x.%x", &bus, &dev, &func) == 3)) {
259 		domain = 0;
260 	} else if ((sscanf(bdf, "%x:%x", &bus, &dev) == 2) ||
261 		   (sscanf(bdf, "%x.%x", &bus, &dev) == 2)) {
262 		domain = 0;
263 		func = 0;
264 	} else {
265 		return -EINVAL;
266 	}
267 
268 	if (bus > 0xFF || dev > 0x1F || func > 7) {
269 		return -EINVAL;
270 	}
271 
272 	addr->domain = domain;
273 	addr->bus = bus;
274 	addr->dev = dev;
275 	addr->func = func;
276 
277 	return 0;
278 }
279 
280 int
281 spdk_pci_addr_fmt(char *bdf, size_t sz, const struct spdk_pci_addr *addr)
282 {
283 	int rc;
284 
285 	rc = snprintf(bdf, sz, "%04x:%02x:%02x.%x",
286 		      addr->domain, addr->bus,
287 		      addr->dev, addr->func);
288 
289 	if (rc > 0 && (size_t)rc < sz) {
290 		return 0;
291 	}
292 
293 	return -1;
294 }
295 
296 int
297 spdk_pci_addr_compare(const struct spdk_pci_addr *a1, const struct spdk_pci_addr *a2)
298 {
299 	if (a1->domain > a2->domain) {
300 		return 1;
301 	} else if (a1->domain < a2->domain) {
302 		return -1;
303 	} else if (a1->bus > a2->bus) {
304 		return 1;
305 	} else if (a1->bus < a2->bus) {
306 		return -1;
307 	} else if (a1->dev > a2->dev) {
308 		return 1;
309 	} else if (a1->dev < a2->dev) {
310 		return -1;
311 	} else if (a1->func > a2->func) {
312 		return 1;
313 	} else if (a1->func < a2->func) {
314 		return -1;
315 	}
316 
317 	return 0;
318 }
319 
320 uint32_t
321 spdk_env_get_core_count(void)
322 {
323 	return 1;
324 }
325