xref: /freebsd-src/contrib/processor-trace/libipt/test/src/ptunit-image_section_cache.c (revision 85f87cf491bec6f90948a85b10f5523ea24db9e3)
174fe6c29SRuslan Bukin /*
2*85f87cf4SRuslan Bukin  * Copyright (c) 2016-2019, Intel Corporation
374fe6c29SRuslan Bukin  *
474fe6c29SRuslan Bukin  * Redistribution and use in source and binary forms, with or without
574fe6c29SRuslan Bukin  * modification, are permitted provided that the following conditions are met:
674fe6c29SRuslan Bukin  *
774fe6c29SRuslan Bukin  *  * Redistributions of source code must retain the above copyright notice,
874fe6c29SRuslan Bukin  *    this list of conditions and the following disclaimer.
974fe6c29SRuslan Bukin  *  * Redistributions in binary form must reproduce the above copyright notice,
1074fe6c29SRuslan Bukin  *    this list of conditions and the following disclaimer in the documentation
1174fe6c29SRuslan Bukin  *    and/or other materials provided with the distribution.
1274fe6c29SRuslan Bukin  *  * Neither the name of Intel Corporation nor the names of its contributors
1374fe6c29SRuslan Bukin  *    may be used to endorse or promote products derived from this software
1474fe6c29SRuslan Bukin  *    without specific prior written permission.
1574fe6c29SRuslan Bukin  *
1674fe6c29SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1774fe6c29SRuslan Bukin  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1874fe6c29SRuslan Bukin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1974fe6c29SRuslan Bukin  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2074fe6c29SRuslan Bukin  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2174fe6c29SRuslan Bukin  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2274fe6c29SRuslan Bukin  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2374fe6c29SRuslan Bukin  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2474fe6c29SRuslan Bukin  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2574fe6c29SRuslan Bukin  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2674fe6c29SRuslan Bukin  * POSSIBILITY OF SUCH DAMAGE.
2774fe6c29SRuslan Bukin  */
2874fe6c29SRuslan Bukin 
2974fe6c29SRuslan Bukin #include "pt_image_section_cache.h"
3074fe6c29SRuslan Bukin 
3174fe6c29SRuslan Bukin #include "ptunit_threads.h"
3274fe6c29SRuslan Bukin 
3374fe6c29SRuslan Bukin #include "intel-pt.h"
3474fe6c29SRuslan Bukin 
3574fe6c29SRuslan Bukin #include <stdlib.h>
3674fe6c29SRuslan Bukin 
3774fe6c29SRuslan Bukin 
3874fe6c29SRuslan Bukin struct pt_section {
3974fe6c29SRuslan Bukin 	/* The filename.  We only support string literals for testing. */
4074fe6c29SRuslan Bukin 	const char *filename;
4174fe6c29SRuslan Bukin 
4274fe6c29SRuslan Bukin 	/* The file offset and size. */
4374fe6c29SRuslan Bukin 	uint64_t offset;
4474fe6c29SRuslan Bukin 	uint64_t size;
4574fe6c29SRuslan Bukin 
4674fe6c29SRuslan Bukin 	/* The bcache size. */
4774fe6c29SRuslan Bukin 	uint64_t bcsize;
4874fe6c29SRuslan Bukin 
4974fe6c29SRuslan Bukin 	/* The iscache back link. */
5074fe6c29SRuslan Bukin 	struct pt_image_section_cache *iscache;
5174fe6c29SRuslan Bukin 
5274fe6c29SRuslan Bukin 	/* The file content. */
5374fe6c29SRuslan Bukin 	uint8_t content[0x10];
5474fe6c29SRuslan Bukin 
5574fe6c29SRuslan Bukin 	/* The use count. */
5674fe6c29SRuslan Bukin 	int ucount;
5774fe6c29SRuslan Bukin 
5874fe6c29SRuslan Bukin 	/* The attach count. */
5974fe6c29SRuslan Bukin 	int acount;
6074fe6c29SRuslan Bukin 
6174fe6c29SRuslan Bukin 	/* The map count. */
6274fe6c29SRuslan Bukin 	int mcount;
6374fe6c29SRuslan Bukin 
6474fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
6574fe6c29SRuslan Bukin 	/* A lock protecting this section. */
6674fe6c29SRuslan Bukin 	mtx_t lock;
6774fe6c29SRuslan Bukin 	/* A lock protecting the iscache and acount fields. */
6874fe6c29SRuslan Bukin 	mtx_t alock;
6974fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
7074fe6c29SRuslan Bukin };
7174fe6c29SRuslan Bukin 
72*85f87cf4SRuslan Bukin extern int pt_mk_section(struct pt_section **psection, const char *filename,
73*85f87cf4SRuslan Bukin 			 uint64_t offset, uint64_t size);
7474fe6c29SRuslan Bukin 
7574fe6c29SRuslan Bukin extern int pt_section_get(struct pt_section *section);
7674fe6c29SRuslan Bukin extern int pt_section_put(struct pt_section *section);
7774fe6c29SRuslan Bukin extern int pt_section_attach(struct pt_section *section,
7874fe6c29SRuslan Bukin 			     struct pt_image_section_cache *iscache);
7974fe6c29SRuslan Bukin extern int pt_section_detach(struct pt_section *section,
8074fe6c29SRuslan Bukin 			     struct pt_image_section_cache *iscache);
8174fe6c29SRuslan Bukin 
8274fe6c29SRuslan Bukin extern int pt_section_map(struct pt_section *section);
8374fe6c29SRuslan Bukin extern int pt_section_map_share(struct pt_section *section);
8474fe6c29SRuslan Bukin extern int pt_section_unmap(struct pt_section *section);
8574fe6c29SRuslan Bukin extern int pt_section_request_bcache(struct pt_section *section);
8674fe6c29SRuslan Bukin 
8774fe6c29SRuslan Bukin extern const char *pt_section_filename(const struct pt_section *section);
8874fe6c29SRuslan Bukin extern uint64_t pt_section_offset(const struct pt_section *section);
8974fe6c29SRuslan Bukin extern uint64_t pt_section_size(const struct pt_section *section);
9074fe6c29SRuslan Bukin extern int pt_section_memsize(struct pt_section *section, uint64_t *size);
9174fe6c29SRuslan Bukin 
9274fe6c29SRuslan Bukin extern int pt_section_read(const struct pt_section *section, uint8_t *buffer,
9374fe6c29SRuslan Bukin 			   uint16_t size, uint64_t offset);
9474fe6c29SRuslan Bukin 
9574fe6c29SRuslan Bukin 
pt_mk_section(struct pt_section ** psection,const char * filename,uint64_t offset,uint64_t size)96*85f87cf4SRuslan Bukin int pt_mk_section(struct pt_section **psection, const char *filename,
97*85f87cf4SRuslan Bukin 		  uint64_t offset, uint64_t size)
9874fe6c29SRuslan Bukin {
9974fe6c29SRuslan Bukin 	struct pt_section *section;
100*85f87cf4SRuslan Bukin 	uint8_t idx;
10174fe6c29SRuslan Bukin 
10274fe6c29SRuslan Bukin 	section = malloc(sizeof(*section));
103*85f87cf4SRuslan Bukin 	if (!section)
104*85f87cf4SRuslan Bukin 		return -pte_nomem;
10574fe6c29SRuslan Bukin 
10674fe6c29SRuslan Bukin 	memset(section, 0, sizeof(*section));
10774fe6c29SRuslan Bukin 	section->filename = filename;
10874fe6c29SRuslan Bukin 	section->offset = offset;
10974fe6c29SRuslan Bukin 	section->size = size;
11074fe6c29SRuslan Bukin 	section->ucount = 1;
11174fe6c29SRuslan Bukin 
11274fe6c29SRuslan Bukin 	for (idx = 0; idx < sizeof(section->content); ++idx)
11374fe6c29SRuslan Bukin 		section->content[idx] = idx;
11474fe6c29SRuslan Bukin 
11574fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
11674fe6c29SRuslan Bukin 	{
11774fe6c29SRuslan Bukin 		int errcode;
11874fe6c29SRuslan Bukin 
11974fe6c29SRuslan Bukin 		errcode = mtx_init(&section->lock, mtx_plain);
12074fe6c29SRuslan Bukin 		if (errcode != thrd_success) {
12174fe6c29SRuslan Bukin 			free(section);
122*85f87cf4SRuslan Bukin 			return -pte_bad_lock;
12374fe6c29SRuslan Bukin 		}
12474fe6c29SRuslan Bukin 
12574fe6c29SRuslan Bukin 		errcode = mtx_init(&section->alock, mtx_plain);
12674fe6c29SRuslan Bukin 		if (errcode != thrd_success) {
12774fe6c29SRuslan Bukin 			mtx_destroy(&section->lock);
12874fe6c29SRuslan Bukin 			free(section);
129*85f87cf4SRuslan Bukin 			return -pte_bad_lock;
13074fe6c29SRuslan Bukin 		}
13174fe6c29SRuslan Bukin 	}
13274fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
13374fe6c29SRuslan Bukin 
134*85f87cf4SRuslan Bukin 	*psection = section;
135*85f87cf4SRuslan Bukin 
136*85f87cf4SRuslan Bukin 	return 0;
13774fe6c29SRuslan Bukin }
13874fe6c29SRuslan Bukin 
pt_section_lock(struct pt_section * section)13974fe6c29SRuslan Bukin static int pt_section_lock(struct pt_section *section)
14074fe6c29SRuslan Bukin {
14174fe6c29SRuslan Bukin 	if (!section)
14274fe6c29SRuslan Bukin 		return -pte_internal;
14374fe6c29SRuslan Bukin 
14474fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
14574fe6c29SRuslan Bukin 	{
14674fe6c29SRuslan Bukin 		int errcode;
14774fe6c29SRuslan Bukin 
14874fe6c29SRuslan Bukin 		errcode = mtx_lock(&section->lock);
14974fe6c29SRuslan Bukin 		if (errcode != thrd_success)
15074fe6c29SRuslan Bukin 			return -pte_bad_lock;
15174fe6c29SRuslan Bukin 	}
15274fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
15374fe6c29SRuslan Bukin 
15474fe6c29SRuslan Bukin 	return 0;
15574fe6c29SRuslan Bukin }
15674fe6c29SRuslan Bukin 
pt_section_unlock(struct pt_section * section)15774fe6c29SRuslan Bukin static int pt_section_unlock(struct pt_section *section)
15874fe6c29SRuslan Bukin {
15974fe6c29SRuslan Bukin 	if (!section)
16074fe6c29SRuslan Bukin 		return -pte_internal;
16174fe6c29SRuslan Bukin 
16274fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
16374fe6c29SRuslan Bukin 	{
16474fe6c29SRuslan Bukin 		int errcode;
16574fe6c29SRuslan Bukin 
16674fe6c29SRuslan Bukin 		errcode = mtx_unlock(&section->lock);
16774fe6c29SRuslan Bukin 		if (errcode != thrd_success)
16874fe6c29SRuslan Bukin 			return -pte_bad_lock;
16974fe6c29SRuslan Bukin 	}
17074fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
17174fe6c29SRuslan Bukin 
17274fe6c29SRuslan Bukin 	return 0;
17374fe6c29SRuslan Bukin }
17474fe6c29SRuslan Bukin 
pt_section_lock_attach(struct pt_section * section)17574fe6c29SRuslan Bukin static int pt_section_lock_attach(struct pt_section *section)
17674fe6c29SRuslan Bukin {
17774fe6c29SRuslan Bukin 	if (!section)
17874fe6c29SRuslan Bukin 		return -pte_internal;
17974fe6c29SRuslan Bukin 
18074fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
18174fe6c29SRuslan Bukin 	{
18274fe6c29SRuslan Bukin 		int errcode;
18374fe6c29SRuslan Bukin 
18474fe6c29SRuslan Bukin 		errcode = mtx_lock(&section->alock);
18574fe6c29SRuslan Bukin 		if (errcode != thrd_success)
18674fe6c29SRuslan Bukin 			return -pte_bad_lock;
18774fe6c29SRuslan Bukin 	}
18874fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
18974fe6c29SRuslan Bukin 
19074fe6c29SRuslan Bukin 	return 0;
19174fe6c29SRuslan Bukin }
19274fe6c29SRuslan Bukin 
pt_section_unlock_attach(struct pt_section * section)19374fe6c29SRuslan Bukin static int pt_section_unlock_attach(struct pt_section *section)
19474fe6c29SRuslan Bukin {
19574fe6c29SRuslan Bukin 	if (!section)
19674fe6c29SRuslan Bukin 		return -pte_internal;
19774fe6c29SRuslan Bukin 
19874fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
19974fe6c29SRuslan Bukin 	{
20074fe6c29SRuslan Bukin 		int errcode;
20174fe6c29SRuslan Bukin 
20274fe6c29SRuslan Bukin 		errcode = mtx_unlock(&section->alock);
20374fe6c29SRuslan Bukin 		if (errcode != thrd_success)
20474fe6c29SRuslan Bukin 			return -pte_bad_lock;
20574fe6c29SRuslan Bukin 	}
20674fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
20774fe6c29SRuslan Bukin 
20874fe6c29SRuslan Bukin 	return 0;
20974fe6c29SRuslan Bukin }
21074fe6c29SRuslan Bukin 
pt_section_get(struct pt_section * section)21174fe6c29SRuslan Bukin int pt_section_get(struct pt_section *section)
21274fe6c29SRuslan Bukin {
21374fe6c29SRuslan Bukin 	int errcode, ucount;
21474fe6c29SRuslan Bukin 
21574fe6c29SRuslan Bukin 	if (!section)
21674fe6c29SRuslan Bukin 		return -pte_internal;
21774fe6c29SRuslan Bukin 
21874fe6c29SRuslan Bukin 	errcode = pt_section_lock(section);
21974fe6c29SRuslan Bukin 	if (errcode < 0)
22074fe6c29SRuslan Bukin 		return errcode;
22174fe6c29SRuslan Bukin 
22274fe6c29SRuslan Bukin 	ucount = ++section->ucount;
22374fe6c29SRuslan Bukin 
22474fe6c29SRuslan Bukin 	errcode = pt_section_unlock(section);
22574fe6c29SRuslan Bukin 	if (errcode < 0)
22674fe6c29SRuslan Bukin 		return errcode;
22774fe6c29SRuslan Bukin 
22874fe6c29SRuslan Bukin 	if (!ucount)
22974fe6c29SRuslan Bukin 		return -pte_internal;
23074fe6c29SRuslan Bukin 
23174fe6c29SRuslan Bukin 	return 0;
23274fe6c29SRuslan Bukin }
23374fe6c29SRuslan Bukin 
pt_section_put(struct pt_section * section)23474fe6c29SRuslan Bukin int pt_section_put(struct pt_section *section)
23574fe6c29SRuslan Bukin {
23674fe6c29SRuslan Bukin 	int errcode, ucount;
23774fe6c29SRuslan Bukin 
23874fe6c29SRuslan Bukin 	if (!section)
23974fe6c29SRuslan Bukin 		return -pte_internal;
24074fe6c29SRuslan Bukin 
24174fe6c29SRuslan Bukin 	errcode = pt_section_lock(section);
24274fe6c29SRuslan Bukin 	if (errcode < 0)
24374fe6c29SRuslan Bukin 		return errcode;
24474fe6c29SRuslan Bukin 
24574fe6c29SRuslan Bukin 	ucount = --section->ucount;
24674fe6c29SRuslan Bukin 
24774fe6c29SRuslan Bukin 	errcode = pt_section_unlock(section);
24874fe6c29SRuslan Bukin 	if (errcode < 0)
24974fe6c29SRuslan Bukin 		return errcode;
25074fe6c29SRuslan Bukin 
25174fe6c29SRuslan Bukin 	if (!ucount) {
25274fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
25374fe6c29SRuslan Bukin 		mtx_destroy(&section->alock);
25474fe6c29SRuslan Bukin 		mtx_destroy(&section->lock);
25574fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
25674fe6c29SRuslan Bukin 		free(section);
25774fe6c29SRuslan Bukin 	}
25874fe6c29SRuslan Bukin 
25974fe6c29SRuslan Bukin 	return 0;
26074fe6c29SRuslan Bukin }
26174fe6c29SRuslan Bukin 
pt_section_attach(struct pt_section * section,struct pt_image_section_cache * iscache)26274fe6c29SRuslan Bukin int pt_section_attach(struct pt_section *section,
26374fe6c29SRuslan Bukin 		      struct pt_image_section_cache *iscache)
26474fe6c29SRuslan Bukin {
26574fe6c29SRuslan Bukin 	int errcode, ucount, acount;
26674fe6c29SRuslan Bukin 
26774fe6c29SRuslan Bukin 	if (!section || !iscache)
26874fe6c29SRuslan Bukin 		return -pte_internal;
26974fe6c29SRuslan Bukin 
27074fe6c29SRuslan Bukin 	errcode = pt_section_lock_attach(section);
27174fe6c29SRuslan Bukin 	if (errcode < 0)
27274fe6c29SRuslan Bukin 		return errcode;
27374fe6c29SRuslan Bukin 
27474fe6c29SRuslan Bukin 	ucount = section->ucount;
27574fe6c29SRuslan Bukin 	acount = section->acount;
27674fe6c29SRuslan Bukin 	if (!acount) {
27774fe6c29SRuslan Bukin 		if (section->iscache || !ucount)
27874fe6c29SRuslan Bukin 			goto out_unlock;
27974fe6c29SRuslan Bukin 
28074fe6c29SRuslan Bukin 		section->iscache = iscache;
28174fe6c29SRuslan Bukin 		section->acount = 1;
28274fe6c29SRuslan Bukin 
28374fe6c29SRuslan Bukin 		return pt_section_unlock_attach(section);
28474fe6c29SRuslan Bukin 	}
28574fe6c29SRuslan Bukin 
28674fe6c29SRuslan Bukin 	acount += 1;
28774fe6c29SRuslan Bukin 	if (!acount) {
28874fe6c29SRuslan Bukin 		(void) pt_section_unlock_attach(section);
28974fe6c29SRuslan Bukin 		return -pte_overflow;
29074fe6c29SRuslan Bukin 	}
29174fe6c29SRuslan Bukin 
29274fe6c29SRuslan Bukin 	if (ucount < acount)
29374fe6c29SRuslan Bukin 		goto out_unlock;
29474fe6c29SRuslan Bukin 
29574fe6c29SRuslan Bukin 	if (section->iscache != iscache)
29674fe6c29SRuslan Bukin 		goto out_unlock;
29774fe6c29SRuslan Bukin 
29874fe6c29SRuslan Bukin 	section->acount = acount;
29974fe6c29SRuslan Bukin 
30074fe6c29SRuslan Bukin 	return pt_section_unlock_attach(section);
30174fe6c29SRuslan Bukin 
30274fe6c29SRuslan Bukin  out_unlock:
30374fe6c29SRuslan Bukin 	(void) pt_section_unlock_attach(section);
30474fe6c29SRuslan Bukin 	return -pte_internal;
30574fe6c29SRuslan Bukin }
30674fe6c29SRuslan Bukin 
pt_section_detach(struct pt_section * section,struct pt_image_section_cache * iscache)30774fe6c29SRuslan Bukin int pt_section_detach(struct pt_section *section,
30874fe6c29SRuslan Bukin 		      struct pt_image_section_cache *iscache)
30974fe6c29SRuslan Bukin {
31074fe6c29SRuslan Bukin 	int errcode, ucount, acount;
31174fe6c29SRuslan Bukin 
31274fe6c29SRuslan Bukin 	if (!section || !iscache)
31374fe6c29SRuslan Bukin 		return -pte_internal;
31474fe6c29SRuslan Bukin 
31574fe6c29SRuslan Bukin 	errcode = pt_section_lock_attach(section);
31674fe6c29SRuslan Bukin 	if (errcode < 0)
31774fe6c29SRuslan Bukin 		return errcode;
31874fe6c29SRuslan Bukin 
31974fe6c29SRuslan Bukin 	if (section->iscache != iscache)
32074fe6c29SRuslan Bukin 		goto out_unlock;
32174fe6c29SRuslan Bukin 
32274fe6c29SRuslan Bukin 	acount = section->acount;
32374fe6c29SRuslan Bukin 	if (!acount)
32474fe6c29SRuslan Bukin 		goto out_unlock;
32574fe6c29SRuslan Bukin 
32674fe6c29SRuslan Bukin 	acount -= 1;
32774fe6c29SRuslan Bukin 	ucount = section->ucount;
32874fe6c29SRuslan Bukin 	if (ucount < acount)
32974fe6c29SRuslan Bukin 		goto out_unlock;
33074fe6c29SRuslan Bukin 
33174fe6c29SRuslan Bukin 	section->acount = acount;
33274fe6c29SRuslan Bukin 	if (!acount)
33374fe6c29SRuslan Bukin 		section->iscache = NULL;
33474fe6c29SRuslan Bukin 
33574fe6c29SRuslan Bukin 	return pt_section_unlock_attach(section);
33674fe6c29SRuslan Bukin 
33774fe6c29SRuslan Bukin  out_unlock:
33874fe6c29SRuslan Bukin 	(void) pt_section_unlock_attach(section);
33974fe6c29SRuslan Bukin 	return -pte_internal;
34074fe6c29SRuslan Bukin }
34174fe6c29SRuslan Bukin 
pt_section_map(struct pt_section * section)34274fe6c29SRuslan Bukin int pt_section_map(struct pt_section *section)
34374fe6c29SRuslan Bukin {
34474fe6c29SRuslan Bukin 	struct pt_image_section_cache *iscache;
34574fe6c29SRuslan Bukin 	int errcode, status;
34674fe6c29SRuslan Bukin 
34774fe6c29SRuslan Bukin 	if (!section)
34874fe6c29SRuslan Bukin 		return -pte_internal;
34974fe6c29SRuslan Bukin 
35074fe6c29SRuslan Bukin 	errcode = pt_section_map_share(section);
35174fe6c29SRuslan Bukin 	if (errcode < 0)
35274fe6c29SRuslan Bukin 		return errcode;
35374fe6c29SRuslan Bukin 
35474fe6c29SRuslan Bukin 	errcode = pt_section_lock_attach(section);
35574fe6c29SRuslan Bukin 	if (errcode < 0)
35674fe6c29SRuslan Bukin 		return errcode;
35774fe6c29SRuslan Bukin 
35874fe6c29SRuslan Bukin 	status = 0;
35974fe6c29SRuslan Bukin 	iscache = section->iscache;
36074fe6c29SRuslan Bukin 	if (iscache)
36174fe6c29SRuslan Bukin 		status = pt_iscache_notify_map(iscache, section);
36274fe6c29SRuslan Bukin 
36374fe6c29SRuslan Bukin 	errcode = pt_section_unlock_attach(section);
36474fe6c29SRuslan Bukin 
36574fe6c29SRuslan Bukin 	return (status < 0) ? status : errcode;
36674fe6c29SRuslan Bukin }
36774fe6c29SRuslan Bukin 
pt_section_map_share(struct pt_section * section)36874fe6c29SRuslan Bukin int pt_section_map_share(struct pt_section *section)
36974fe6c29SRuslan Bukin {
37074fe6c29SRuslan Bukin 	int errcode, mcount;
37174fe6c29SRuslan Bukin 
37274fe6c29SRuslan Bukin 	if (!section)
37374fe6c29SRuslan Bukin 		return -pte_internal;
37474fe6c29SRuslan Bukin 
37574fe6c29SRuslan Bukin 	errcode = pt_section_lock(section);
37674fe6c29SRuslan Bukin 	if (errcode < 0)
37774fe6c29SRuslan Bukin 		return errcode;
37874fe6c29SRuslan Bukin 
37974fe6c29SRuslan Bukin 	mcount = ++section->mcount;
38074fe6c29SRuslan Bukin 
38174fe6c29SRuslan Bukin 	errcode = pt_section_unlock(section);
38274fe6c29SRuslan Bukin 	if (errcode < 0)
38374fe6c29SRuslan Bukin 		return errcode;
38474fe6c29SRuslan Bukin 
38574fe6c29SRuslan Bukin 	if (mcount <= 0)
38674fe6c29SRuslan Bukin 		return -pte_internal;
38774fe6c29SRuslan Bukin 
38874fe6c29SRuslan Bukin 	return 0;
38974fe6c29SRuslan Bukin }
39074fe6c29SRuslan Bukin 
pt_section_unmap(struct pt_section * section)39174fe6c29SRuslan Bukin int pt_section_unmap(struct pt_section *section)
39274fe6c29SRuslan Bukin {
39374fe6c29SRuslan Bukin 	int errcode, mcount;
39474fe6c29SRuslan Bukin 
39574fe6c29SRuslan Bukin 	if (!section)
39674fe6c29SRuslan Bukin 		return -pte_internal;
39774fe6c29SRuslan Bukin 
39874fe6c29SRuslan Bukin 	errcode = pt_section_lock(section);
39974fe6c29SRuslan Bukin 	if (errcode < 0)
40074fe6c29SRuslan Bukin 		return errcode;
40174fe6c29SRuslan Bukin 
40274fe6c29SRuslan Bukin 	section->bcsize = 0ull;
40374fe6c29SRuslan Bukin 	mcount = --section->mcount;
40474fe6c29SRuslan Bukin 
40574fe6c29SRuslan Bukin 	errcode = pt_section_unlock(section);
40674fe6c29SRuslan Bukin 	if (errcode < 0)
40774fe6c29SRuslan Bukin 		return errcode;
40874fe6c29SRuslan Bukin 
40974fe6c29SRuslan Bukin 	if (mcount < 0)
41074fe6c29SRuslan Bukin 		return -pte_internal;
41174fe6c29SRuslan Bukin 
41274fe6c29SRuslan Bukin 	return 0;
41374fe6c29SRuslan Bukin }
41474fe6c29SRuslan Bukin 
pt_section_request_bcache(struct pt_section * section)41574fe6c29SRuslan Bukin int pt_section_request_bcache(struct pt_section *section)
41674fe6c29SRuslan Bukin {
41774fe6c29SRuslan Bukin 	struct pt_image_section_cache *iscache;
41874fe6c29SRuslan Bukin 	uint64_t memsize;
41974fe6c29SRuslan Bukin 	int errcode;
42074fe6c29SRuslan Bukin 
42174fe6c29SRuslan Bukin 	if (!section)
42274fe6c29SRuslan Bukin 		return -pte_internal;
42374fe6c29SRuslan Bukin 
42474fe6c29SRuslan Bukin 	errcode = pt_section_lock_attach(section);
42574fe6c29SRuslan Bukin 	if (errcode < 0)
42674fe6c29SRuslan Bukin 		return errcode;
42774fe6c29SRuslan Bukin 
42874fe6c29SRuslan Bukin 	errcode = pt_section_lock(section);
42974fe6c29SRuslan Bukin 	if (errcode < 0)
43074fe6c29SRuslan Bukin 		goto out_alock;
43174fe6c29SRuslan Bukin 
43274fe6c29SRuslan Bukin 	if (section->bcsize)
43374fe6c29SRuslan Bukin 		goto out_lock;
43474fe6c29SRuslan Bukin 
43574fe6c29SRuslan Bukin 	section->bcsize = section->size * 3;
43674fe6c29SRuslan Bukin 	memsize = section->size + section->bcsize;
43774fe6c29SRuslan Bukin 
43874fe6c29SRuslan Bukin 	errcode = pt_section_unlock(section);
43974fe6c29SRuslan Bukin 	if (errcode < 0)
44074fe6c29SRuslan Bukin 		goto out_alock;
44174fe6c29SRuslan Bukin 
44274fe6c29SRuslan Bukin 	iscache = section->iscache;
44374fe6c29SRuslan Bukin 	if (iscache) {
44474fe6c29SRuslan Bukin 		errcode = pt_iscache_notify_resize(iscache, section, memsize);
44574fe6c29SRuslan Bukin 		if (errcode < 0)
44674fe6c29SRuslan Bukin 			goto out_alock;
44774fe6c29SRuslan Bukin 	}
44874fe6c29SRuslan Bukin 
44974fe6c29SRuslan Bukin 	return pt_section_unlock_attach(section);
45074fe6c29SRuslan Bukin 
45174fe6c29SRuslan Bukin 
45274fe6c29SRuslan Bukin out_lock:
45374fe6c29SRuslan Bukin 	(void) pt_section_unlock(section);
45474fe6c29SRuslan Bukin 
45574fe6c29SRuslan Bukin out_alock:
45674fe6c29SRuslan Bukin 	(void) pt_section_unlock_attach(section);
45774fe6c29SRuslan Bukin 	return errcode;
45874fe6c29SRuslan Bukin }
45974fe6c29SRuslan Bukin 
pt_section_filename(const struct pt_section * section)46074fe6c29SRuslan Bukin const char *pt_section_filename(const struct pt_section *section)
46174fe6c29SRuslan Bukin {
46274fe6c29SRuslan Bukin 	if (!section)
46374fe6c29SRuslan Bukin 		return NULL;
46474fe6c29SRuslan Bukin 
46574fe6c29SRuslan Bukin 	return section->filename;
46674fe6c29SRuslan Bukin }
46774fe6c29SRuslan Bukin 
pt_section_offset(const struct pt_section * section)46874fe6c29SRuslan Bukin uint64_t pt_section_offset(const struct pt_section *section)
46974fe6c29SRuslan Bukin {
47074fe6c29SRuslan Bukin 	if (!section)
47174fe6c29SRuslan Bukin 		return 0ull;
47274fe6c29SRuslan Bukin 
47374fe6c29SRuslan Bukin 	return section->offset;
47474fe6c29SRuslan Bukin }
47574fe6c29SRuslan Bukin 
pt_section_size(const struct pt_section * section)47674fe6c29SRuslan Bukin uint64_t pt_section_size(const struct pt_section *section)
47774fe6c29SRuslan Bukin {
47874fe6c29SRuslan Bukin 	if (!section)
47974fe6c29SRuslan Bukin 		return 0ull;
48074fe6c29SRuslan Bukin 
48174fe6c29SRuslan Bukin 	return section->size;
48274fe6c29SRuslan Bukin }
48374fe6c29SRuslan Bukin 
pt_section_memsize(struct pt_section * section,uint64_t * size)48474fe6c29SRuslan Bukin int pt_section_memsize(struct pt_section *section, uint64_t *size)
48574fe6c29SRuslan Bukin {
48674fe6c29SRuslan Bukin 	if (!section || !size)
48774fe6c29SRuslan Bukin 		return -pte_internal;
48874fe6c29SRuslan Bukin 
48974fe6c29SRuslan Bukin 	*size = section->mcount ? section->size + section->bcsize : 0ull;
49074fe6c29SRuslan Bukin 
49174fe6c29SRuslan Bukin 	return 0;
49274fe6c29SRuslan Bukin }
49374fe6c29SRuslan Bukin 
pt_section_read(const struct pt_section * section,uint8_t * buffer,uint16_t size,uint64_t offset)49474fe6c29SRuslan Bukin int pt_section_read(const struct pt_section *section, uint8_t *buffer,
49574fe6c29SRuslan Bukin 		    uint16_t size, uint64_t offset)
49674fe6c29SRuslan Bukin {
49774fe6c29SRuslan Bukin 	uint64_t begin, end, max;
49874fe6c29SRuslan Bukin 
49974fe6c29SRuslan Bukin 	if (!section || !buffer)
50074fe6c29SRuslan Bukin 		return -pte_internal;
50174fe6c29SRuslan Bukin 
50274fe6c29SRuslan Bukin 	begin = offset;
50374fe6c29SRuslan Bukin 	end = begin + size;
50474fe6c29SRuslan Bukin 	max = sizeof(section->content);
50574fe6c29SRuslan Bukin 
50674fe6c29SRuslan Bukin 	if (max <= begin)
50774fe6c29SRuslan Bukin 		return -pte_nomap;
50874fe6c29SRuslan Bukin 
50974fe6c29SRuslan Bukin 	if (max < end)
51074fe6c29SRuslan Bukin 		end = max;
51174fe6c29SRuslan Bukin 
51274fe6c29SRuslan Bukin 	if (end <= begin)
51374fe6c29SRuslan Bukin 		return -pte_invalid;
51474fe6c29SRuslan Bukin 
51574fe6c29SRuslan Bukin 	memcpy(buffer, &section->content[begin], (size_t) (end - begin));
51674fe6c29SRuslan Bukin 	return (int) (end - begin);
51774fe6c29SRuslan Bukin }
51874fe6c29SRuslan Bukin 
51974fe6c29SRuslan Bukin enum {
52074fe6c29SRuslan Bukin 	/* The number of test sections. */
52174fe6c29SRuslan Bukin 	num_sections	= 8,
52274fe6c29SRuslan Bukin 
52374fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
52474fe6c29SRuslan Bukin 
52574fe6c29SRuslan Bukin 	num_threads	= 8,
52674fe6c29SRuslan Bukin 
52774fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
52874fe6c29SRuslan Bukin 
52974fe6c29SRuslan Bukin 	num_iterations	= 0x1000
53074fe6c29SRuslan Bukin };
53174fe6c29SRuslan Bukin 
53274fe6c29SRuslan Bukin struct iscache_fixture {
53374fe6c29SRuslan Bukin 	/* Threading support. */
53474fe6c29SRuslan Bukin 	struct ptunit_thrd_fixture thrd;
53574fe6c29SRuslan Bukin 
53674fe6c29SRuslan Bukin 	/* The image section cache under test. */
53774fe6c29SRuslan Bukin 	struct pt_image_section_cache iscache;
53874fe6c29SRuslan Bukin 
53974fe6c29SRuslan Bukin 	/* A bunch of test sections. */
54074fe6c29SRuslan Bukin 	struct pt_section *section[num_sections];
54174fe6c29SRuslan Bukin 
54274fe6c29SRuslan Bukin 	/* The test fixture initialization and finalization functions. */
54374fe6c29SRuslan Bukin 	struct ptunit_result (*init)(struct iscache_fixture *);
54474fe6c29SRuslan Bukin 	struct ptunit_result (*fini)(struct iscache_fixture *);
54574fe6c29SRuslan Bukin };
54674fe6c29SRuslan Bukin 
dfix_init(struct iscache_fixture * cfix)54774fe6c29SRuslan Bukin static struct ptunit_result dfix_init(struct iscache_fixture *cfix)
54874fe6c29SRuslan Bukin {
54974fe6c29SRuslan Bukin 	int idx;
55074fe6c29SRuslan Bukin 
55174fe6c29SRuslan Bukin 	ptu_test(ptunit_thrd_init, &cfix->thrd);
55274fe6c29SRuslan Bukin 
55374fe6c29SRuslan Bukin 	memset(cfix->section, 0, sizeof(cfix->section));
55474fe6c29SRuslan Bukin 
55574fe6c29SRuslan Bukin 	for (idx = 0; idx < num_sections; ++idx) {
55674fe6c29SRuslan Bukin 		struct pt_section *section;
557*85f87cf4SRuslan Bukin 		int errcode;
55874fe6c29SRuslan Bukin 
559*85f87cf4SRuslan Bukin 		errcode = pt_mk_section(&section, "some-filename",
56074fe6c29SRuslan Bukin 					idx % 3 == 0 ? 0x1000 : 0x2000,
56174fe6c29SRuslan Bukin 					idx % 2 == 0 ? 0x1000 : 0x2000);
562*85f87cf4SRuslan Bukin 		ptu_int_eq(errcode, 0);
56374fe6c29SRuslan Bukin 		ptu_ptr(section);
56474fe6c29SRuslan Bukin 
56574fe6c29SRuslan Bukin 		cfix->section[idx] = section;
56674fe6c29SRuslan Bukin 	}
56774fe6c29SRuslan Bukin 
56874fe6c29SRuslan Bukin 	return ptu_passed();
56974fe6c29SRuslan Bukin }
57074fe6c29SRuslan Bukin 
cfix_init(struct iscache_fixture * cfix)57174fe6c29SRuslan Bukin static struct ptunit_result cfix_init(struct iscache_fixture *cfix)
57274fe6c29SRuslan Bukin {
57374fe6c29SRuslan Bukin 	int errcode;
57474fe6c29SRuslan Bukin 
57574fe6c29SRuslan Bukin 	ptu_test(dfix_init, cfix);
57674fe6c29SRuslan Bukin 
57774fe6c29SRuslan Bukin 	errcode = pt_iscache_init(&cfix->iscache, NULL);
57874fe6c29SRuslan Bukin 	ptu_int_eq(errcode, 0);
57974fe6c29SRuslan Bukin 
58074fe6c29SRuslan Bukin 	return ptu_passed();
58174fe6c29SRuslan Bukin }
58274fe6c29SRuslan Bukin 
sfix_init(struct iscache_fixture * cfix)58374fe6c29SRuslan Bukin static struct ptunit_result sfix_init(struct iscache_fixture *cfix)
58474fe6c29SRuslan Bukin {
58574fe6c29SRuslan Bukin 	int status, idx;
58674fe6c29SRuslan Bukin 
58774fe6c29SRuslan Bukin 	ptu_test(cfix_init, cfix);
58874fe6c29SRuslan Bukin 
58974fe6c29SRuslan Bukin 	cfix->iscache.limit = 0x7800;
59074fe6c29SRuslan Bukin 
59174fe6c29SRuslan Bukin 	for (idx = 0; idx < num_sections; ++idx) {
59274fe6c29SRuslan Bukin 		status = pt_iscache_add(&cfix->iscache, cfix->section[idx],
59374fe6c29SRuslan Bukin 					0ull);
59474fe6c29SRuslan Bukin 		ptu_int_ge(status, 0);
59574fe6c29SRuslan Bukin 	}
59674fe6c29SRuslan Bukin 
59774fe6c29SRuslan Bukin 	return ptu_passed();
59874fe6c29SRuslan Bukin }
59974fe6c29SRuslan Bukin 
cfix_fini(struct iscache_fixture * cfix)60074fe6c29SRuslan Bukin static struct ptunit_result cfix_fini(struct iscache_fixture *cfix)
60174fe6c29SRuslan Bukin {
60274fe6c29SRuslan Bukin 	int idx, errcode;
60374fe6c29SRuslan Bukin 
60474fe6c29SRuslan Bukin 	ptu_test(ptunit_thrd_fini, &cfix->thrd);
60574fe6c29SRuslan Bukin 
60674fe6c29SRuslan Bukin 	for (idx = 0; idx < cfix->thrd.nthreads; ++idx)
60774fe6c29SRuslan Bukin 		ptu_int_eq(cfix->thrd.result[idx], 0);
60874fe6c29SRuslan Bukin 
60974fe6c29SRuslan Bukin 	pt_iscache_fini(&cfix->iscache);
61074fe6c29SRuslan Bukin 
61174fe6c29SRuslan Bukin 	for (idx = 0; idx < num_sections; ++idx) {
61274fe6c29SRuslan Bukin 		ptu_int_eq(cfix->section[idx]->ucount, 1);
61374fe6c29SRuslan Bukin 		ptu_int_eq(cfix->section[idx]->acount, 0);
61474fe6c29SRuslan Bukin 		ptu_int_eq(cfix->section[idx]->mcount, 0);
61574fe6c29SRuslan Bukin 		ptu_null(cfix->section[idx]->iscache);
61674fe6c29SRuslan Bukin 
61774fe6c29SRuslan Bukin 		errcode = pt_section_put(cfix->section[idx]);
61874fe6c29SRuslan Bukin 		ptu_int_eq(errcode, 0);
61974fe6c29SRuslan Bukin 	}
62074fe6c29SRuslan Bukin 
62174fe6c29SRuslan Bukin 	return ptu_passed();
62274fe6c29SRuslan Bukin }
62374fe6c29SRuslan Bukin 
62474fe6c29SRuslan Bukin 
init_null(void)62574fe6c29SRuslan Bukin static struct ptunit_result init_null(void)
62674fe6c29SRuslan Bukin {
62774fe6c29SRuslan Bukin 	int errcode;
62874fe6c29SRuslan Bukin 
62974fe6c29SRuslan Bukin 	errcode = pt_iscache_init(NULL, NULL);
63074fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
63174fe6c29SRuslan Bukin 
63274fe6c29SRuslan Bukin 	return ptu_passed();
63374fe6c29SRuslan Bukin }
63474fe6c29SRuslan Bukin 
fini_null(void)63574fe6c29SRuslan Bukin static struct ptunit_result fini_null(void)
63674fe6c29SRuslan Bukin {
63774fe6c29SRuslan Bukin 	pt_iscache_fini(NULL);
63874fe6c29SRuslan Bukin 
63974fe6c29SRuslan Bukin 	return ptu_passed();
64074fe6c29SRuslan Bukin }
64174fe6c29SRuslan Bukin 
name_null(void)64274fe6c29SRuslan Bukin static struct ptunit_result name_null(void)
64374fe6c29SRuslan Bukin {
64474fe6c29SRuslan Bukin 	const char *name;
64574fe6c29SRuslan Bukin 
64674fe6c29SRuslan Bukin 	name = pt_iscache_name(NULL);
64774fe6c29SRuslan Bukin 	ptu_null(name);
64874fe6c29SRuslan Bukin 
64974fe6c29SRuslan Bukin 	return ptu_passed();
65074fe6c29SRuslan Bukin }
65174fe6c29SRuslan Bukin 
add_null(void)65274fe6c29SRuslan Bukin static struct ptunit_result add_null(void)
65374fe6c29SRuslan Bukin {
65474fe6c29SRuslan Bukin 	struct pt_image_section_cache iscache;
65574fe6c29SRuslan Bukin 	struct pt_section section;
65674fe6c29SRuslan Bukin 	int errcode;
65774fe6c29SRuslan Bukin 
65874fe6c29SRuslan Bukin 	errcode = pt_iscache_add(NULL, &section, 0ull);
65974fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
66074fe6c29SRuslan Bukin 
66174fe6c29SRuslan Bukin 	errcode = pt_iscache_add(&iscache, NULL, 0ull);
66274fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
66374fe6c29SRuslan Bukin 
66474fe6c29SRuslan Bukin 	return ptu_passed();
66574fe6c29SRuslan Bukin }
66674fe6c29SRuslan Bukin 
find_null(void)66774fe6c29SRuslan Bukin static struct ptunit_result find_null(void)
66874fe6c29SRuslan Bukin {
66974fe6c29SRuslan Bukin 	int errcode;
67074fe6c29SRuslan Bukin 
67174fe6c29SRuslan Bukin 	errcode = pt_iscache_find(NULL, "filename", 0ull, 0ull, 0ull);
67274fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
67374fe6c29SRuslan Bukin 
67474fe6c29SRuslan Bukin 	return ptu_passed();
67574fe6c29SRuslan Bukin }
67674fe6c29SRuslan Bukin 
lookup_null(void)67774fe6c29SRuslan Bukin static struct ptunit_result lookup_null(void)
67874fe6c29SRuslan Bukin {
67974fe6c29SRuslan Bukin 	struct pt_image_section_cache iscache;
68074fe6c29SRuslan Bukin 	struct pt_section *section;
68174fe6c29SRuslan Bukin 	uint64_t laddr;
68274fe6c29SRuslan Bukin 	int errcode;
68374fe6c29SRuslan Bukin 
68474fe6c29SRuslan Bukin 	errcode = pt_iscache_lookup(NULL, &section, &laddr, 0);
68574fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
68674fe6c29SRuslan Bukin 
68774fe6c29SRuslan Bukin 	errcode = pt_iscache_lookup(&iscache, NULL, &laddr, 0);
68874fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
68974fe6c29SRuslan Bukin 
69074fe6c29SRuslan Bukin 	errcode = pt_iscache_lookup(&iscache, &section, NULL, 0);
69174fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
69274fe6c29SRuslan Bukin 
69374fe6c29SRuslan Bukin 	return ptu_passed();
69474fe6c29SRuslan Bukin }
69574fe6c29SRuslan Bukin 
clear_null(void)69674fe6c29SRuslan Bukin static struct ptunit_result clear_null(void)
69774fe6c29SRuslan Bukin {
69874fe6c29SRuslan Bukin 	int errcode;
69974fe6c29SRuslan Bukin 
70074fe6c29SRuslan Bukin 	errcode = pt_iscache_clear(NULL);
70174fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
70274fe6c29SRuslan Bukin 
70374fe6c29SRuslan Bukin 	return ptu_passed();
70474fe6c29SRuslan Bukin }
70574fe6c29SRuslan Bukin 
free_null(void)70674fe6c29SRuslan Bukin static struct ptunit_result free_null(void)
70774fe6c29SRuslan Bukin {
70874fe6c29SRuslan Bukin 	pt_iscache_free(NULL);
70974fe6c29SRuslan Bukin 
71074fe6c29SRuslan Bukin 	return ptu_passed();
71174fe6c29SRuslan Bukin }
71274fe6c29SRuslan Bukin 
add_file_null(void)71374fe6c29SRuslan Bukin static struct ptunit_result add_file_null(void)
71474fe6c29SRuslan Bukin {
71574fe6c29SRuslan Bukin 	struct pt_image_section_cache iscache;
71674fe6c29SRuslan Bukin 	int errcode;
71774fe6c29SRuslan Bukin 
71874fe6c29SRuslan Bukin 	errcode = pt_iscache_add_file(NULL, "filename", 0ull, 0ull, 0ull);
71974fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_invalid);
72074fe6c29SRuslan Bukin 
72174fe6c29SRuslan Bukin 	errcode = pt_iscache_add_file(&iscache, NULL, 0ull, 0ull, 0ull);
72274fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_invalid);
72374fe6c29SRuslan Bukin 
72474fe6c29SRuslan Bukin 	return ptu_passed();
72574fe6c29SRuslan Bukin }
72674fe6c29SRuslan Bukin 
read_null(void)72774fe6c29SRuslan Bukin static struct ptunit_result read_null(void)
72874fe6c29SRuslan Bukin {
72974fe6c29SRuslan Bukin 	struct pt_image_section_cache iscache;
73074fe6c29SRuslan Bukin 	uint8_t buffer;
73174fe6c29SRuslan Bukin 	int errcode;
73274fe6c29SRuslan Bukin 
73374fe6c29SRuslan Bukin 	errcode = pt_iscache_read(NULL, &buffer, sizeof(buffer), 1ull, 0ull);
73474fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_invalid);
73574fe6c29SRuslan Bukin 
73674fe6c29SRuslan Bukin 	errcode = pt_iscache_read(&iscache, NULL, sizeof(buffer), 1ull, 0ull);
73774fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_invalid);
73874fe6c29SRuslan Bukin 
73974fe6c29SRuslan Bukin 	errcode = pt_iscache_read(&iscache, &buffer, 0ull, 1, 0ull);
74074fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_invalid);
74174fe6c29SRuslan Bukin 
74274fe6c29SRuslan Bukin 	return ptu_passed();
74374fe6c29SRuslan Bukin }
74474fe6c29SRuslan Bukin 
init_fini(struct iscache_fixture * cfix)74574fe6c29SRuslan Bukin static struct ptunit_result init_fini(struct iscache_fixture *cfix)
74674fe6c29SRuslan Bukin {
74774fe6c29SRuslan Bukin 	(void) cfix;
74874fe6c29SRuslan Bukin 
74974fe6c29SRuslan Bukin 	/* The actual init and fini calls are in cfix_init() and cfix_fini(). */
75074fe6c29SRuslan Bukin 	return ptu_passed();
75174fe6c29SRuslan Bukin }
75274fe6c29SRuslan Bukin 
name(struct iscache_fixture * cfix)75374fe6c29SRuslan Bukin static struct ptunit_result name(struct iscache_fixture *cfix)
75474fe6c29SRuslan Bukin {
75574fe6c29SRuslan Bukin 	const char *name;
75674fe6c29SRuslan Bukin 
75774fe6c29SRuslan Bukin 	pt_iscache_init(&cfix->iscache, "iscache-name");
75874fe6c29SRuslan Bukin 
75974fe6c29SRuslan Bukin 	name = pt_iscache_name(&cfix->iscache);
76074fe6c29SRuslan Bukin 	ptu_str_eq(name, "iscache-name");
76174fe6c29SRuslan Bukin 
76274fe6c29SRuslan Bukin 	return ptu_passed();
76374fe6c29SRuslan Bukin }
76474fe6c29SRuslan Bukin 
name_none(struct iscache_fixture * cfix)76574fe6c29SRuslan Bukin static struct ptunit_result name_none(struct iscache_fixture *cfix)
76674fe6c29SRuslan Bukin {
76774fe6c29SRuslan Bukin 	const char *name;
76874fe6c29SRuslan Bukin 
76974fe6c29SRuslan Bukin 	pt_iscache_init(&cfix->iscache, NULL);
77074fe6c29SRuslan Bukin 
77174fe6c29SRuslan Bukin 	name = pt_iscache_name(&cfix->iscache);
77274fe6c29SRuslan Bukin 	ptu_null(name);
77374fe6c29SRuslan Bukin 
77474fe6c29SRuslan Bukin 	return ptu_passed();
77574fe6c29SRuslan Bukin }
77674fe6c29SRuslan Bukin 
add(struct iscache_fixture * cfix)77774fe6c29SRuslan Bukin static struct ptunit_result add(struct iscache_fixture *cfix)
77874fe6c29SRuslan Bukin {
77974fe6c29SRuslan Bukin 	int isid;
78074fe6c29SRuslan Bukin 
78174fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
78274fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
78374fe6c29SRuslan Bukin 
78474fe6c29SRuslan Bukin 	/* The cache attaches and gets a reference on success. */
78574fe6c29SRuslan Bukin 	ptu_int_eq(cfix->section[0]->ucount, 2);
78674fe6c29SRuslan Bukin 	ptu_int_eq(cfix->section[0]->acount, 1);
78774fe6c29SRuslan Bukin 
78874fe6c29SRuslan Bukin 	/* The added section must be implicitly put in pt_iscache_fini. */
78974fe6c29SRuslan Bukin 	return ptu_passed();
79074fe6c29SRuslan Bukin }
79174fe6c29SRuslan Bukin 
add_no_name(struct iscache_fixture * cfix)79274fe6c29SRuslan Bukin static struct ptunit_result add_no_name(struct iscache_fixture *cfix)
79374fe6c29SRuslan Bukin {
79474fe6c29SRuslan Bukin 	struct pt_section section;
79574fe6c29SRuslan Bukin 	int errcode;
79674fe6c29SRuslan Bukin 
79774fe6c29SRuslan Bukin 	memset(&section, 0, sizeof(section));
79874fe6c29SRuslan Bukin 
79974fe6c29SRuslan Bukin 	errcode = pt_iscache_add(&cfix->iscache, &section, 0ull);
80074fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
80174fe6c29SRuslan Bukin 
80274fe6c29SRuslan Bukin 	return ptu_passed();
80374fe6c29SRuslan Bukin }
80474fe6c29SRuslan Bukin 
add_file(struct iscache_fixture * cfix)80574fe6c29SRuslan Bukin static struct ptunit_result add_file(struct iscache_fixture *cfix)
80674fe6c29SRuslan Bukin {
80774fe6c29SRuslan Bukin 	int isid;
80874fe6c29SRuslan Bukin 
80974fe6c29SRuslan Bukin 	isid = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull);
81074fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
81174fe6c29SRuslan Bukin 
81274fe6c29SRuslan Bukin 	return ptu_passed();
81374fe6c29SRuslan Bukin }
81474fe6c29SRuslan Bukin 
find(struct iscache_fixture * cfix)81574fe6c29SRuslan Bukin static struct ptunit_result find(struct iscache_fixture *cfix)
81674fe6c29SRuslan Bukin {
81774fe6c29SRuslan Bukin 	struct pt_section *section;
81874fe6c29SRuslan Bukin 	int found, isid;
81974fe6c29SRuslan Bukin 
82074fe6c29SRuslan Bukin 	section = cfix->section[0];
82174fe6c29SRuslan Bukin 	ptu_ptr(section);
82274fe6c29SRuslan Bukin 
82374fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, section, 0ull);
82474fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
82574fe6c29SRuslan Bukin 
82674fe6c29SRuslan Bukin 	found = pt_iscache_find(&cfix->iscache, section->filename,
82774fe6c29SRuslan Bukin 				section->offset, section->size, 0ull);
82874fe6c29SRuslan Bukin 	ptu_int_eq(found, isid);
82974fe6c29SRuslan Bukin 
83074fe6c29SRuslan Bukin 	return ptu_passed();
83174fe6c29SRuslan Bukin }
83274fe6c29SRuslan Bukin 
find_empty(struct iscache_fixture * cfix)83374fe6c29SRuslan Bukin static struct ptunit_result find_empty(struct iscache_fixture *cfix)
83474fe6c29SRuslan Bukin {
83574fe6c29SRuslan Bukin 	struct pt_section *section;
83674fe6c29SRuslan Bukin 	int found;
83774fe6c29SRuslan Bukin 
83874fe6c29SRuslan Bukin 	section = cfix->section[0];
83974fe6c29SRuslan Bukin 	ptu_ptr(section);
84074fe6c29SRuslan Bukin 
84174fe6c29SRuslan Bukin 	found = pt_iscache_find(&cfix->iscache, section->filename,
84274fe6c29SRuslan Bukin 				section->offset, section->size, 0ull);
84374fe6c29SRuslan Bukin 	ptu_int_eq(found, 0);
84474fe6c29SRuslan Bukin 
84574fe6c29SRuslan Bukin 	return ptu_passed();
84674fe6c29SRuslan Bukin }
84774fe6c29SRuslan Bukin 
find_bad_filename(struct iscache_fixture * cfix)84874fe6c29SRuslan Bukin static struct ptunit_result find_bad_filename(struct iscache_fixture *cfix)
84974fe6c29SRuslan Bukin {
85074fe6c29SRuslan Bukin 	struct pt_section *section;
85174fe6c29SRuslan Bukin 	int found, isid;
85274fe6c29SRuslan Bukin 
85374fe6c29SRuslan Bukin 	section = cfix->section[0];
85474fe6c29SRuslan Bukin 	ptu_ptr(section);
85574fe6c29SRuslan Bukin 
85674fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, section, 0ull);
85774fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
85874fe6c29SRuslan Bukin 
85974fe6c29SRuslan Bukin 	found = pt_iscache_find(&cfix->iscache, "bad-filename",
86074fe6c29SRuslan Bukin 				section->offset, section->size, 0ull);
86174fe6c29SRuslan Bukin 	ptu_int_eq(found, 0);
86274fe6c29SRuslan Bukin 
86374fe6c29SRuslan Bukin 	return ptu_passed();
86474fe6c29SRuslan Bukin }
86574fe6c29SRuslan Bukin 
find_null_filename(struct iscache_fixture * cfix)86674fe6c29SRuslan Bukin static struct ptunit_result find_null_filename(struct iscache_fixture *cfix)
86774fe6c29SRuslan Bukin {
86874fe6c29SRuslan Bukin 	int errcode;
86974fe6c29SRuslan Bukin 
87074fe6c29SRuslan Bukin 	errcode = pt_iscache_find(&cfix->iscache, NULL, 0ull, 0ull, 0ull);
87174fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_internal);
87274fe6c29SRuslan Bukin 
87374fe6c29SRuslan Bukin 	return ptu_passed();
87474fe6c29SRuslan Bukin }
87574fe6c29SRuslan Bukin 
find_bad_offset(struct iscache_fixture * cfix)87674fe6c29SRuslan Bukin static struct ptunit_result find_bad_offset(struct iscache_fixture *cfix)
87774fe6c29SRuslan Bukin {
87874fe6c29SRuslan Bukin 	struct pt_section *section;
87974fe6c29SRuslan Bukin 	int found, isid;
88074fe6c29SRuslan Bukin 
88174fe6c29SRuslan Bukin 	section = cfix->section[0];
88274fe6c29SRuslan Bukin 	ptu_ptr(section);
88374fe6c29SRuslan Bukin 
88474fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, section, 0ull);
88574fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
88674fe6c29SRuslan Bukin 
88774fe6c29SRuslan Bukin 	found = pt_iscache_find(&cfix->iscache, section->filename, 0ull,
88874fe6c29SRuslan Bukin 				section->size, 0ull);
88974fe6c29SRuslan Bukin 	ptu_int_eq(found, 0);
89074fe6c29SRuslan Bukin 
89174fe6c29SRuslan Bukin 	return ptu_passed();
89274fe6c29SRuslan Bukin }
89374fe6c29SRuslan Bukin 
find_bad_size(struct iscache_fixture * cfix)89474fe6c29SRuslan Bukin static struct ptunit_result find_bad_size(struct iscache_fixture *cfix)
89574fe6c29SRuslan Bukin {
89674fe6c29SRuslan Bukin 	struct pt_section *section;
89774fe6c29SRuslan Bukin 	int found, isid;
89874fe6c29SRuslan Bukin 
89974fe6c29SRuslan Bukin 	section = cfix->section[0];
90074fe6c29SRuslan Bukin 	ptu_ptr(section);
90174fe6c29SRuslan Bukin 
90274fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, section, 0ull);
90374fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
90474fe6c29SRuslan Bukin 
90574fe6c29SRuslan Bukin 	found = pt_iscache_find(&cfix->iscache, section->filename,
90674fe6c29SRuslan Bukin 				section->offset, 0ull, 0ull);
90774fe6c29SRuslan Bukin 	ptu_int_eq(found, 0);
90874fe6c29SRuslan Bukin 
90974fe6c29SRuslan Bukin 	return ptu_passed();
91074fe6c29SRuslan Bukin }
91174fe6c29SRuslan Bukin 
find_bad_laddr(struct iscache_fixture * cfix)91274fe6c29SRuslan Bukin static struct ptunit_result find_bad_laddr(struct iscache_fixture *cfix)
91374fe6c29SRuslan Bukin {
91474fe6c29SRuslan Bukin 	struct pt_section *section;
91574fe6c29SRuslan Bukin 	int found, isid;
91674fe6c29SRuslan Bukin 
91774fe6c29SRuslan Bukin 	section = cfix->section[0];
91874fe6c29SRuslan Bukin 	ptu_ptr(section);
91974fe6c29SRuslan Bukin 
92074fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, section, 0ull);
92174fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
92274fe6c29SRuslan Bukin 
92374fe6c29SRuslan Bukin 	found = pt_iscache_find(&cfix->iscache, section->filename,
92474fe6c29SRuslan Bukin 				section->offset, section->size, 1ull);
92574fe6c29SRuslan Bukin 	ptu_int_eq(found, 0);
92674fe6c29SRuslan Bukin 
92774fe6c29SRuslan Bukin 	return ptu_passed();
92874fe6c29SRuslan Bukin }
92974fe6c29SRuslan Bukin 
lookup(struct iscache_fixture * cfix)93074fe6c29SRuslan Bukin static struct ptunit_result lookup(struct iscache_fixture *cfix)
93174fe6c29SRuslan Bukin {
93274fe6c29SRuslan Bukin 	struct pt_section *section;
93374fe6c29SRuslan Bukin 	uint64_t laddr;
93474fe6c29SRuslan Bukin 	int errcode, isid;
93574fe6c29SRuslan Bukin 
93674fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
93774fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
93874fe6c29SRuslan Bukin 
93974fe6c29SRuslan Bukin 	errcode = pt_iscache_lookup(&cfix->iscache, &section, &laddr, isid);
94074fe6c29SRuslan Bukin 	ptu_int_eq(errcode, 0);
94174fe6c29SRuslan Bukin 	ptu_ptr_eq(section, cfix->section[0]);
94274fe6c29SRuslan Bukin 	ptu_uint_eq(laddr, 0ull);
94374fe6c29SRuslan Bukin 
94474fe6c29SRuslan Bukin 	errcode = pt_section_put(section);
94574fe6c29SRuslan Bukin 	ptu_int_eq(errcode, 0);
94674fe6c29SRuslan Bukin 
94774fe6c29SRuslan Bukin 	return ptu_passed();
94874fe6c29SRuslan Bukin }
94974fe6c29SRuslan Bukin 
lookup_bad_isid(struct iscache_fixture * cfix)95074fe6c29SRuslan Bukin static struct ptunit_result lookup_bad_isid(struct iscache_fixture *cfix)
95174fe6c29SRuslan Bukin {
95274fe6c29SRuslan Bukin 	struct pt_section *section;
95374fe6c29SRuslan Bukin 	uint64_t laddr;
95474fe6c29SRuslan Bukin 	int errcode, isid;
95574fe6c29SRuslan Bukin 
95674fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
95774fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
95874fe6c29SRuslan Bukin 
95974fe6c29SRuslan Bukin 	errcode = pt_iscache_lookup(&cfix->iscache, &section, &laddr, 0);
96074fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_bad_image);
96174fe6c29SRuslan Bukin 
96274fe6c29SRuslan Bukin 	errcode = pt_iscache_lookup(&cfix->iscache, &section, &laddr, -isid);
96374fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_bad_image);
96474fe6c29SRuslan Bukin 
96574fe6c29SRuslan Bukin 	errcode = pt_iscache_lookup(&cfix->iscache, &section, &laddr, isid + 1);
96674fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_bad_image);
96774fe6c29SRuslan Bukin 
96874fe6c29SRuslan Bukin 	return ptu_passed();
96974fe6c29SRuslan Bukin }
97074fe6c29SRuslan Bukin 
clear_empty(struct iscache_fixture * cfix)97174fe6c29SRuslan Bukin static struct ptunit_result clear_empty(struct iscache_fixture *cfix)
97274fe6c29SRuslan Bukin {
97374fe6c29SRuslan Bukin 	int errcode;
97474fe6c29SRuslan Bukin 
97574fe6c29SRuslan Bukin 	errcode = pt_iscache_clear(&cfix->iscache);
97674fe6c29SRuslan Bukin 	ptu_int_eq(errcode, 0);
97774fe6c29SRuslan Bukin 
97874fe6c29SRuslan Bukin 	return ptu_passed();
97974fe6c29SRuslan Bukin }
98074fe6c29SRuslan Bukin 
clear_find(struct iscache_fixture * cfix)98174fe6c29SRuslan Bukin static struct ptunit_result clear_find(struct iscache_fixture *cfix)
98274fe6c29SRuslan Bukin {
98374fe6c29SRuslan Bukin 	struct pt_section *section;
98474fe6c29SRuslan Bukin 	int errcode, found, isid;
98574fe6c29SRuslan Bukin 
98674fe6c29SRuslan Bukin 	section = cfix->section[0];
98774fe6c29SRuslan Bukin 	ptu_ptr(section);
98874fe6c29SRuslan Bukin 
98974fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, section, 0ull);
99074fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
99174fe6c29SRuslan Bukin 
99274fe6c29SRuslan Bukin 	errcode = pt_iscache_clear(&cfix->iscache);
99374fe6c29SRuslan Bukin 	ptu_int_eq(errcode, 0);
99474fe6c29SRuslan Bukin 
99574fe6c29SRuslan Bukin 
99674fe6c29SRuslan Bukin 	found = pt_iscache_find(&cfix->iscache, section->filename,
99774fe6c29SRuslan Bukin 				section->offset, section->size, 0ull);
99874fe6c29SRuslan Bukin 	ptu_int_eq(found, 0);
99974fe6c29SRuslan Bukin 
100074fe6c29SRuslan Bukin 	return ptu_passed();
100174fe6c29SRuslan Bukin }
100274fe6c29SRuslan Bukin 
clear_lookup(struct iscache_fixture * cfix)100374fe6c29SRuslan Bukin static struct ptunit_result clear_lookup(struct iscache_fixture *cfix)
100474fe6c29SRuslan Bukin {
100574fe6c29SRuslan Bukin 	struct pt_section *section;
100674fe6c29SRuslan Bukin 	uint64_t laddr;
100774fe6c29SRuslan Bukin 	int errcode, isid;
100874fe6c29SRuslan Bukin 
100974fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
101074fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
101174fe6c29SRuslan Bukin 
101274fe6c29SRuslan Bukin 	errcode = pt_iscache_clear(&cfix->iscache);
101374fe6c29SRuslan Bukin 	ptu_int_eq(errcode, 0);
101474fe6c29SRuslan Bukin 
101574fe6c29SRuslan Bukin 	errcode = pt_iscache_lookup(&cfix->iscache, &section, &laddr, isid);
101674fe6c29SRuslan Bukin 	ptu_int_eq(errcode, -pte_bad_image);
101774fe6c29SRuslan Bukin 
101874fe6c29SRuslan Bukin 	return ptu_passed();
101974fe6c29SRuslan Bukin }
102074fe6c29SRuslan Bukin 
add_twice(struct iscache_fixture * cfix)102174fe6c29SRuslan Bukin static struct ptunit_result add_twice(struct iscache_fixture *cfix)
102274fe6c29SRuslan Bukin {
102374fe6c29SRuslan Bukin 	int isid[2];
102474fe6c29SRuslan Bukin 
102574fe6c29SRuslan Bukin 	isid[0] = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
102674fe6c29SRuslan Bukin 	ptu_int_gt(isid[0], 0);
102774fe6c29SRuslan Bukin 
102874fe6c29SRuslan Bukin 	isid[1] = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
102974fe6c29SRuslan Bukin 	ptu_int_gt(isid[1], 0);
103074fe6c29SRuslan Bukin 
103174fe6c29SRuslan Bukin 	/* The second add should be ignored. */
103274fe6c29SRuslan Bukin 	ptu_int_eq(isid[1], isid[0]);
103374fe6c29SRuslan Bukin 
103474fe6c29SRuslan Bukin 	return ptu_passed();
103574fe6c29SRuslan Bukin }
103674fe6c29SRuslan Bukin 
add_same(struct iscache_fixture * cfix)103774fe6c29SRuslan Bukin static struct ptunit_result add_same(struct iscache_fixture *cfix)
103874fe6c29SRuslan Bukin {
103974fe6c29SRuslan Bukin 	int isid[2];
104074fe6c29SRuslan Bukin 
104174fe6c29SRuslan Bukin 	isid[0] = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
104274fe6c29SRuslan Bukin 	ptu_int_gt(isid[0], 0);
104374fe6c29SRuslan Bukin 
104474fe6c29SRuslan Bukin 	cfix->section[1]->offset = cfix->section[0]->offset;
104574fe6c29SRuslan Bukin 	cfix->section[1]->size = cfix->section[0]->size;
104674fe6c29SRuslan Bukin 
104774fe6c29SRuslan Bukin 	isid[1] = pt_iscache_add(&cfix->iscache, cfix->section[1], 0ull);
104874fe6c29SRuslan Bukin 	ptu_int_gt(isid[1], 0);
104974fe6c29SRuslan Bukin 
105074fe6c29SRuslan Bukin 	/* The second add should be ignored. */
105174fe6c29SRuslan Bukin 	ptu_int_eq(isid[1], isid[0]);
105274fe6c29SRuslan Bukin 
105374fe6c29SRuslan Bukin 	return ptu_passed();
105474fe6c29SRuslan Bukin }
105574fe6c29SRuslan Bukin 
105674fe6c29SRuslan Bukin static struct ptunit_result
add_twice_different_laddr(struct iscache_fixture * cfix)105774fe6c29SRuslan Bukin add_twice_different_laddr(struct iscache_fixture *cfix)
105874fe6c29SRuslan Bukin {
105974fe6c29SRuslan Bukin 	int isid[2];
106074fe6c29SRuslan Bukin 
106174fe6c29SRuslan Bukin 	isid[0] = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
106274fe6c29SRuslan Bukin 	ptu_int_gt(isid[0], 0);
106374fe6c29SRuslan Bukin 
106474fe6c29SRuslan Bukin 	isid[1] = pt_iscache_add(&cfix->iscache, cfix->section[0], 1ull);
106574fe6c29SRuslan Bukin 	ptu_int_gt(isid[1], 0);
106674fe6c29SRuslan Bukin 
106774fe6c29SRuslan Bukin 	/* We must get different identifiers. */
106874fe6c29SRuslan Bukin 	ptu_int_ne(isid[1], isid[0]);
106974fe6c29SRuslan Bukin 
107074fe6c29SRuslan Bukin 	/* We attach twice and take two references - one for each entry. */
107174fe6c29SRuslan Bukin 	ptu_int_eq(cfix->section[0]->ucount, 3);
107274fe6c29SRuslan Bukin 	ptu_int_eq(cfix->section[0]->acount, 2);
107374fe6c29SRuslan Bukin 
107474fe6c29SRuslan Bukin 	return ptu_passed();
107574fe6c29SRuslan Bukin }
107674fe6c29SRuslan Bukin 
107774fe6c29SRuslan Bukin static struct ptunit_result
add_same_different_laddr(struct iscache_fixture * cfix)107874fe6c29SRuslan Bukin add_same_different_laddr(struct iscache_fixture *cfix)
107974fe6c29SRuslan Bukin {
108074fe6c29SRuslan Bukin 	int isid[2];
108174fe6c29SRuslan Bukin 
108274fe6c29SRuslan Bukin 	isid[0] = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
108374fe6c29SRuslan Bukin 	ptu_int_gt(isid[0], 0);
108474fe6c29SRuslan Bukin 
108574fe6c29SRuslan Bukin 	cfix->section[1]->offset = cfix->section[0]->offset;
108674fe6c29SRuslan Bukin 	cfix->section[1]->size = cfix->section[0]->size;
108774fe6c29SRuslan Bukin 
108874fe6c29SRuslan Bukin 	isid[1] = pt_iscache_add(&cfix->iscache, cfix->section[1], 1ull);
108974fe6c29SRuslan Bukin 	ptu_int_gt(isid[1], 0);
109074fe6c29SRuslan Bukin 
109174fe6c29SRuslan Bukin 	/* We must get different identifiers. */
109274fe6c29SRuslan Bukin 	ptu_int_ne(isid[1], isid[0]);
109374fe6c29SRuslan Bukin 
109474fe6c29SRuslan Bukin 	return ptu_passed();
109574fe6c29SRuslan Bukin }
109674fe6c29SRuslan Bukin 
109774fe6c29SRuslan Bukin static struct ptunit_result
add_different_same_laddr(struct iscache_fixture * cfix)109874fe6c29SRuslan Bukin add_different_same_laddr(struct iscache_fixture *cfix)
109974fe6c29SRuslan Bukin {
110074fe6c29SRuslan Bukin 	int isid[2];
110174fe6c29SRuslan Bukin 
110274fe6c29SRuslan Bukin 	isid[0] = pt_iscache_add(&cfix->iscache, cfix->section[0], 0ull);
110374fe6c29SRuslan Bukin 	ptu_int_gt(isid[0], 0);
110474fe6c29SRuslan Bukin 
110574fe6c29SRuslan Bukin 	isid[1] = pt_iscache_add(&cfix->iscache, cfix->section[1], 0ull);
110674fe6c29SRuslan Bukin 	ptu_int_gt(isid[1], 0);
110774fe6c29SRuslan Bukin 
110874fe6c29SRuslan Bukin 	/* We must get different identifiers. */
110974fe6c29SRuslan Bukin 	ptu_int_ne(isid[1], isid[0]);
111074fe6c29SRuslan Bukin 
111174fe6c29SRuslan Bukin 	return ptu_passed();
111274fe6c29SRuslan Bukin }
111374fe6c29SRuslan Bukin 
add_file_same(struct iscache_fixture * cfix)111474fe6c29SRuslan Bukin static struct ptunit_result add_file_same(struct iscache_fixture *cfix)
111574fe6c29SRuslan Bukin {
111674fe6c29SRuslan Bukin 	int isid[2];
111774fe6c29SRuslan Bukin 
111874fe6c29SRuslan Bukin 	isid[0] = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull);
111974fe6c29SRuslan Bukin 	ptu_int_gt(isid[0], 0);
112074fe6c29SRuslan Bukin 
112174fe6c29SRuslan Bukin 	isid[1] = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull);
112274fe6c29SRuslan Bukin 	ptu_int_gt(isid[1], 0);
112374fe6c29SRuslan Bukin 
112474fe6c29SRuslan Bukin 	/* The second add should be ignored. */
112574fe6c29SRuslan Bukin 	ptu_int_eq(isid[1], isid[0]);
112674fe6c29SRuslan Bukin 
112774fe6c29SRuslan Bukin 	return ptu_passed();
112874fe6c29SRuslan Bukin }
112974fe6c29SRuslan Bukin 
113074fe6c29SRuslan Bukin static struct ptunit_result
add_file_same_different_laddr(struct iscache_fixture * cfix)113174fe6c29SRuslan Bukin add_file_same_different_laddr(struct iscache_fixture *cfix)
113274fe6c29SRuslan Bukin {
113374fe6c29SRuslan Bukin 	int isid[2];
113474fe6c29SRuslan Bukin 
113574fe6c29SRuslan Bukin 	isid[0] = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull);
113674fe6c29SRuslan Bukin 	ptu_int_gt(isid[0], 0);
113774fe6c29SRuslan Bukin 
113874fe6c29SRuslan Bukin 	isid[1] = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 1ull);
113974fe6c29SRuslan Bukin 	ptu_int_gt(isid[1], 0);
114074fe6c29SRuslan Bukin 
114174fe6c29SRuslan Bukin 	/* We must get different identifiers. */
114274fe6c29SRuslan Bukin 	ptu_int_ne(isid[1], isid[0]);
114374fe6c29SRuslan Bukin 
114474fe6c29SRuslan Bukin 	return ptu_passed();
114574fe6c29SRuslan Bukin }
114674fe6c29SRuslan Bukin 
114774fe6c29SRuslan Bukin static struct ptunit_result
add_file_different_same_laddr(struct iscache_fixture * cfix)114874fe6c29SRuslan Bukin add_file_different_same_laddr(struct iscache_fixture *cfix)
114974fe6c29SRuslan Bukin {
115074fe6c29SRuslan Bukin 	int isid[2];
115174fe6c29SRuslan Bukin 
115274fe6c29SRuslan Bukin 	isid[0] = pt_iscache_add_file(&cfix->iscache, "name", 0ull, 1ull, 0ull);
115374fe6c29SRuslan Bukin 	ptu_int_gt(isid[0], 0);
115474fe6c29SRuslan Bukin 
115574fe6c29SRuslan Bukin 	isid[1] = pt_iscache_add_file(&cfix->iscache, "name", 1ull, 1ull, 0ull);
115674fe6c29SRuslan Bukin 	ptu_int_gt(isid[1], 0);
115774fe6c29SRuslan Bukin 
115874fe6c29SRuslan Bukin 	/* We must get different identifiers. */
115974fe6c29SRuslan Bukin 	ptu_int_ne(isid[1], isid[0]);
116074fe6c29SRuslan Bukin 
116174fe6c29SRuslan Bukin 	return ptu_passed();
116274fe6c29SRuslan Bukin }
116374fe6c29SRuslan Bukin 
read(struct iscache_fixture * cfix)116474fe6c29SRuslan Bukin static struct ptunit_result read(struct iscache_fixture *cfix)
116574fe6c29SRuslan Bukin {
116674fe6c29SRuslan Bukin 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
116774fe6c29SRuslan Bukin 	int status, isid;
116874fe6c29SRuslan Bukin 
116974fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
117074fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
117174fe6c29SRuslan Bukin 
117274fe6c29SRuslan Bukin 	status = pt_iscache_read(&cfix->iscache, buffer, 2ull, isid, 0xa008ull);
117374fe6c29SRuslan Bukin 	ptu_int_eq(status, 2);
117474fe6c29SRuslan Bukin 	ptu_uint_eq(buffer[0], 0x8);
117574fe6c29SRuslan Bukin 	ptu_uint_eq(buffer[1], 0x9);
117674fe6c29SRuslan Bukin 	ptu_uint_eq(buffer[2], 0xcc);
117774fe6c29SRuslan Bukin 
117874fe6c29SRuslan Bukin 	return ptu_passed();
117974fe6c29SRuslan Bukin }
118074fe6c29SRuslan Bukin 
read_truncate(struct iscache_fixture * cfix)118174fe6c29SRuslan Bukin static struct ptunit_result read_truncate(struct iscache_fixture *cfix)
118274fe6c29SRuslan Bukin {
118374fe6c29SRuslan Bukin 	uint8_t buffer[] = { 0xcc, 0xcc };
118474fe6c29SRuslan Bukin 	int status, isid;
118574fe6c29SRuslan Bukin 
118674fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
118774fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
118874fe6c29SRuslan Bukin 
118974fe6c29SRuslan Bukin 	status = pt_iscache_read(&cfix->iscache, buffer, sizeof(buffer), isid,
119074fe6c29SRuslan Bukin 				 0xa00full);
119174fe6c29SRuslan Bukin 	ptu_int_eq(status, 1);
119274fe6c29SRuslan Bukin 	ptu_uint_eq(buffer[0], 0xf);
119374fe6c29SRuslan Bukin 	ptu_uint_eq(buffer[1], 0xcc);
119474fe6c29SRuslan Bukin 
119574fe6c29SRuslan Bukin 	return ptu_passed();
119674fe6c29SRuslan Bukin }
119774fe6c29SRuslan Bukin 
read_bad_vaddr(struct iscache_fixture * cfix)119874fe6c29SRuslan Bukin static struct ptunit_result read_bad_vaddr(struct iscache_fixture *cfix)
119974fe6c29SRuslan Bukin {
120074fe6c29SRuslan Bukin 	uint8_t buffer[] = { 0xcc };
120174fe6c29SRuslan Bukin 	int status, isid;
120274fe6c29SRuslan Bukin 
120374fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
120474fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
120574fe6c29SRuslan Bukin 
120674fe6c29SRuslan Bukin 	status = pt_iscache_read(&cfix->iscache, buffer, 1ull, isid, 0xb000ull);
120774fe6c29SRuslan Bukin 	ptu_int_eq(status, -pte_nomap);
120874fe6c29SRuslan Bukin 	ptu_uint_eq(buffer[0], 0xcc);
120974fe6c29SRuslan Bukin 
121074fe6c29SRuslan Bukin 	return ptu_passed();
121174fe6c29SRuslan Bukin }
121274fe6c29SRuslan Bukin 
read_bad_isid(struct iscache_fixture * cfix)121374fe6c29SRuslan Bukin static struct ptunit_result read_bad_isid(struct iscache_fixture *cfix)
121474fe6c29SRuslan Bukin {
121574fe6c29SRuslan Bukin 	uint8_t buffer[] = { 0xcc };
121674fe6c29SRuslan Bukin 	int status, isid;
121774fe6c29SRuslan Bukin 
121874fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
121974fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
122074fe6c29SRuslan Bukin 
122174fe6c29SRuslan Bukin 	status = pt_iscache_read(&cfix->iscache, buffer, 1ull, isid + 1,
122274fe6c29SRuslan Bukin 				 0xa000ull);
122374fe6c29SRuslan Bukin 	ptu_int_eq(status, -pte_bad_image);
122474fe6c29SRuslan Bukin 	ptu_uint_eq(buffer[0], 0xcc);
122574fe6c29SRuslan Bukin 
122674fe6c29SRuslan Bukin 	return ptu_passed();
122774fe6c29SRuslan Bukin }
122874fe6c29SRuslan Bukin 
lru_map(struct iscache_fixture * cfix)122974fe6c29SRuslan Bukin static struct ptunit_result lru_map(struct iscache_fixture *cfix)
123074fe6c29SRuslan Bukin {
123174fe6c29SRuslan Bukin 	int status, isid;
123274fe6c29SRuslan Bukin 
123374fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size;
123474fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
123574fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
123674fe6c29SRuslan Bukin 
123774fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
123874fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
123974fe6c29SRuslan Bukin 
124074fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
124174fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
124274fe6c29SRuslan Bukin 
124374fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
124474fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
124574fe6c29SRuslan Bukin 
124674fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru);
124774fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->section, cfix->section[0]);
124874fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru->next);
124974fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, cfix->section[0]->size);
125074fe6c29SRuslan Bukin 
125174fe6c29SRuslan Bukin 	return ptu_passed();
125274fe6c29SRuslan Bukin }
125374fe6c29SRuslan Bukin 
lru_read(struct iscache_fixture * cfix)125474fe6c29SRuslan Bukin static struct ptunit_result lru_read(struct iscache_fixture *cfix)
125574fe6c29SRuslan Bukin {
125674fe6c29SRuslan Bukin 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
125774fe6c29SRuslan Bukin 	int status, isid;
125874fe6c29SRuslan Bukin 
125974fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size;
126074fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
126174fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
126274fe6c29SRuslan Bukin 
126374fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
126474fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
126574fe6c29SRuslan Bukin 
126674fe6c29SRuslan Bukin 	status = pt_iscache_read(&cfix->iscache, buffer, 2ull, isid, 0xa008ull);
126774fe6c29SRuslan Bukin 	ptu_int_eq(status, 2);
126874fe6c29SRuslan Bukin 
126974fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru);
127074fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->section, cfix->section[0]);
127174fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru->next);
127274fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, cfix->section[0]->size);
127374fe6c29SRuslan Bukin 
127474fe6c29SRuslan Bukin 	return ptu_passed();
127574fe6c29SRuslan Bukin }
127674fe6c29SRuslan Bukin 
lru_map_nodup(struct iscache_fixture * cfix)127774fe6c29SRuslan Bukin static struct ptunit_result lru_map_nodup(struct iscache_fixture *cfix)
127874fe6c29SRuslan Bukin {
127974fe6c29SRuslan Bukin 	int status, isid;
128074fe6c29SRuslan Bukin 
128174fe6c29SRuslan Bukin 	cfix->iscache.limit = 2 * cfix->section[0]->size;
128274fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
128374fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
128474fe6c29SRuslan Bukin 
128574fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
128674fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
128774fe6c29SRuslan Bukin 
128874fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
128974fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
129074fe6c29SRuslan Bukin 
129174fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
129274fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
129374fe6c29SRuslan Bukin 
129474fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
129574fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
129674fe6c29SRuslan Bukin 
129774fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
129874fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
129974fe6c29SRuslan Bukin 
130074fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru);
130174fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->section, cfix->section[0]);
130274fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru->next);
130374fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, cfix->section[0]->size);
130474fe6c29SRuslan Bukin 
130574fe6c29SRuslan Bukin 	return ptu_passed();
130674fe6c29SRuslan Bukin }
130774fe6c29SRuslan Bukin 
lru_map_too_big(struct iscache_fixture * cfix)130874fe6c29SRuslan Bukin static struct ptunit_result lru_map_too_big(struct iscache_fixture *cfix)
130974fe6c29SRuslan Bukin {
131074fe6c29SRuslan Bukin 	int status, isid;
131174fe6c29SRuslan Bukin 
131274fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size - 1;
131374fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
131474fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
131574fe6c29SRuslan Bukin 
131674fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
131774fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
131874fe6c29SRuslan Bukin 
131974fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
132074fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
132174fe6c29SRuslan Bukin 
132274fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
132374fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
132474fe6c29SRuslan Bukin 
132574fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
132674fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
132774fe6c29SRuslan Bukin 
132874fe6c29SRuslan Bukin 	return ptu_passed();
132974fe6c29SRuslan Bukin }
133074fe6c29SRuslan Bukin 
lru_map_add_front(struct iscache_fixture * cfix)133174fe6c29SRuslan Bukin static struct ptunit_result lru_map_add_front(struct iscache_fixture *cfix)
133274fe6c29SRuslan Bukin {
133374fe6c29SRuslan Bukin 	int status, isid;
133474fe6c29SRuslan Bukin 
133574fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size + cfix->section[1]->size;
133674fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
133774fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
133874fe6c29SRuslan Bukin 
133974fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
134074fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
134174fe6c29SRuslan Bukin 
134274fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[1], 0xa000ull);
134374fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
134474fe6c29SRuslan Bukin 
134574fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
134674fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
134774fe6c29SRuslan Bukin 
134874fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
134974fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
135074fe6c29SRuslan Bukin 
135174fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[1]);
135274fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
135374fe6c29SRuslan Bukin 
135474fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[1]);
135574fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
135674fe6c29SRuslan Bukin 
135774fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru);
135874fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->section, cfix->section[1]);
135974fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru->next);
136074fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->next->section, cfix->section[0]);
136174fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru->next->next);
136274fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used,
136374fe6c29SRuslan Bukin 		    cfix->section[0]->size + cfix->section[1]->size);
136474fe6c29SRuslan Bukin 
136574fe6c29SRuslan Bukin 	return ptu_passed();
136674fe6c29SRuslan Bukin }
136774fe6c29SRuslan Bukin 
lru_map_move_front(struct iscache_fixture * cfix)136874fe6c29SRuslan Bukin static struct ptunit_result lru_map_move_front(struct iscache_fixture *cfix)
136974fe6c29SRuslan Bukin {
137074fe6c29SRuslan Bukin 	int status, isid;
137174fe6c29SRuslan Bukin 
137274fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size + cfix->section[1]->size;
137374fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
137474fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
137574fe6c29SRuslan Bukin 
137674fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
137774fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
137874fe6c29SRuslan Bukin 
137974fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[1], 0xa000ull);
138074fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
138174fe6c29SRuslan Bukin 
138274fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
138374fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
138474fe6c29SRuslan Bukin 
138574fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
138674fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
138774fe6c29SRuslan Bukin 
138874fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[1]);
138974fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
139074fe6c29SRuslan Bukin 
139174fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[1]);
139274fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
139374fe6c29SRuslan Bukin 
139474fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
139574fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
139674fe6c29SRuslan Bukin 
139774fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
139874fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
139974fe6c29SRuslan Bukin 
140074fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru);
140174fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->section, cfix->section[0]);
140274fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru->next);
140374fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->next->section, cfix->section[1]);
140474fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru->next->next);
140574fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used,
140674fe6c29SRuslan Bukin 		    cfix->section[0]->size + cfix->section[1]->size);
140774fe6c29SRuslan Bukin 
140874fe6c29SRuslan Bukin 	return ptu_passed();
140974fe6c29SRuslan Bukin }
141074fe6c29SRuslan Bukin 
lru_map_evict(struct iscache_fixture * cfix)141174fe6c29SRuslan Bukin static struct ptunit_result lru_map_evict(struct iscache_fixture *cfix)
141274fe6c29SRuslan Bukin {
141374fe6c29SRuslan Bukin 	int status, isid;
141474fe6c29SRuslan Bukin 
141574fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size +
141674fe6c29SRuslan Bukin 		cfix->section[1]->size - 1;
141774fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
141874fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
141974fe6c29SRuslan Bukin 
142074fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
142174fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
142274fe6c29SRuslan Bukin 
142374fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[1], 0xa000ull);
142474fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
142574fe6c29SRuslan Bukin 
142674fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
142774fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
142874fe6c29SRuslan Bukin 
142974fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
143074fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
143174fe6c29SRuslan Bukin 
143274fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[1]);
143374fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
143474fe6c29SRuslan Bukin 
143574fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[1]);
143674fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
143774fe6c29SRuslan Bukin 
143874fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru);
143974fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->section, cfix->section[1]);
144074fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru->next);
144174fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, cfix->section[1]->size);
144274fe6c29SRuslan Bukin 
144374fe6c29SRuslan Bukin 	return ptu_passed();
144474fe6c29SRuslan Bukin }
144574fe6c29SRuslan Bukin 
lru_bcache_evict(struct iscache_fixture * cfix)144674fe6c29SRuslan Bukin static struct ptunit_result lru_bcache_evict(struct iscache_fixture *cfix)
144774fe6c29SRuslan Bukin {
144874fe6c29SRuslan Bukin 	int status, isid;
144974fe6c29SRuslan Bukin 
145074fe6c29SRuslan Bukin 	cfix->iscache.limit = 4 * cfix->section[0]->size +
145174fe6c29SRuslan Bukin 		cfix->section[1]->size - 1;
145274fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
145374fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
145474fe6c29SRuslan Bukin 
145574fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
145674fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
145774fe6c29SRuslan Bukin 
145874fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[1], 0xa000ull);
145974fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
146074fe6c29SRuslan Bukin 
146174fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
146274fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
146374fe6c29SRuslan Bukin 
146474fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
146574fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
146674fe6c29SRuslan Bukin 
146774fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[1]);
146874fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
146974fe6c29SRuslan Bukin 
147074fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[1]);
147174fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
147274fe6c29SRuslan Bukin 
147374fe6c29SRuslan Bukin 	status = pt_section_request_bcache(cfix->section[0]);
147474fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
147574fe6c29SRuslan Bukin 
147674fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru);
147774fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->section, cfix->section[0]);
147874fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru->next);
147974fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 4 * cfix->section[0]->size);
148074fe6c29SRuslan Bukin 
148174fe6c29SRuslan Bukin 	return ptu_passed();
148274fe6c29SRuslan Bukin }
148374fe6c29SRuslan Bukin 
lru_bcache_clear(struct iscache_fixture * cfix)148474fe6c29SRuslan Bukin static struct ptunit_result lru_bcache_clear(struct iscache_fixture *cfix)
148574fe6c29SRuslan Bukin {
148674fe6c29SRuslan Bukin 	int status, isid;
148774fe6c29SRuslan Bukin 
148874fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size + cfix->section[1]->size;
148974fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
149074fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
149174fe6c29SRuslan Bukin 
149274fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
149374fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
149474fe6c29SRuslan Bukin 
149574fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[1], 0xa000ull);
149674fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
149774fe6c29SRuslan Bukin 
149874fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
149974fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
150074fe6c29SRuslan Bukin 
150174fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
150274fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
150374fe6c29SRuslan Bukin 
150474fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[1]);
150574fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
150674fe6c29SRuslan Bukin 
150774fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[1]);
150874fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
150974fe6c29SRuslan Bukin 
151074fe6c29SRuslan Bukin 	status = pt_section_request_bcache(cfix->section[0]);
151174fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
151274fe6c29SRuslan Bukin 
151374fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
151474fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
151574fe6c29SRuslan Bukin 
151674fe6c29SRuslan Bukin 	return ptu_passed();
151774fe6c29SRuslan Bukin }
151874fe6c29SRuslan Bukin 
lru_limit_evict(struct iscache_fixture * cfix)151974fe6c29SRuslan Bukin static struct ptunit_result lru_limit_evict(struct iscache_fixture *cfix)
152074fe6c29SRuslan Bukin {
152174fe6c29SRuslan Bukin 	int status, isid;
152274fe6c29SRuslan Bukin 
152374fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size + cfix->section[1]->size;
152474fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
152574fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
152674fe6c29SRuslan Bukin 
152774fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
152874fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
152974fe6c29SRuslan Bukin 
153074fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[1], 0xa000ull);
153174fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
153274fe6c29SRuslan Bukin 
153374fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
153474fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
153574fe6c29SRuslan Bukin 
153674fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
153774fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
153874fe6c29SRuslan Bukin 
153974fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[1]);
154074fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
154174fe6c29SRuslan Bukin 
154274fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[1]);
154374fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
154474fe6c29SRuslan Bukin 
154574fe6c29SRuslan Bukin 	status = pt_iscache_set_limit(&cfix->iscache,
154674fe6c29SRuslan Bukin 				      cfix->section[0]->size +
154774fe6c29SRuslan Bukin 				      cfix->section[1]->size - 1);
154874fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
154974fe6c29SRuslan Bukin 
155074fe6c29SRuslan Bukin 	ptu_ptr(cfix->iscache.lru);
155174fe6c29SRuslan Bukin 	ptu_ptr_eq(cfix->iscache.lru->section, cfix->section[1]);
155274fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru->next);
155374fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, cfix->section[1]->size);
155474fe6c29SRuslan Bukin 
155574fe6c29SRuslan Bukin 	return ptu_passed();
155674fe6c29SRuslan Bukin }
155774fe6c29SRuslan Bukin 
lru_clear(struct iscache_fixture * cfix)155874fe6c29SRuslan Bukin static struct ptunit_result lru_clear(struct iscache_fixture *cfix)
155974fe6c29SRuslan Bukin {
156074fe6c29SRuslan Bukin 	int status, isid;
156174fe6c29SRuslan Bukin 
156274fe6c29SRuslan Bukin 	cfix->iscache.limit = cfix->section[0]->size;
156374fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
156474fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
156574fe6c29SRuslan Bukin 
156674fe6c29SRuslan Bukin 	isid = pt_iscache_add(&cfix->iscache, cfix->section[0], 0xa000ull);
156774fe6c29SRuslan Bukin 	ptu_int_gt(isid, 0);
156874fe6c29SRuslan Bukin 
156974fe6c29SRuslan Bukin 	status = pt_section_map(cfix->section[0]);
157074fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
157174fe6c29SRuslan Bukin 
157274fe6c29SRuslan Bukin 	status = pt_section_unmap(cfix->section[0]);
157374fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
157474fe6c29SRuslan Bukin 
157574fe6c29SRuslan Bukin 	status = pt_iscache_clear(&cfix->iscache);
157674fe6c29SRuslan Bukin 	ptu_int_eq(status, 0);
157774fe6c29SRuslan Bukin 
157874fe6c29SRuslan Bukin 	ptu_null(cfix->iscache.lru);
157974fe6c29SRuslan Bukin 	ptu_uint_eq(cfix->iscache.used, 0ull);
158074fe6c29SRuslan Bukin 
158174fe6c29SRuslan Bukin 	return ptu_passed();
158274fe6c29SRuslan Bukin }
158374fe6c29SRuslan Bukin 
worker_add(void * arg)158474fe6c29SRuslan Bukin static int worker_add(void *arg)
158574fe6c29SRuslan Bukin {
158674fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
158774fe6c29SRuslan Bukin 	int it;
158874fe6c29SRuslan Bukin 
158974fe6c29SRuslan Bukin 	cfix = arg;
159074fe6c29SRuslan Bukin 	if (!cfix)
159174fe6c29SRuslan Bukin 		return -pte_internal;
159274fe6c29SRuslan Bukin 
159374fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
159474fe6c29SRuslan Bukin 		uint64_t laddr;
159574fe6c29SRuslan Bukin 		int sec;
159674fe6c29SRuslan Bukin 
159774fe6c29SRuslan Bukin 		laddr = 0x1000ull * (it % 23);
159874fe6c29SRuslan Bukin 
159974fe6c29SRuslan Bukin 		for (sec = 0; sec < num_sections; ++sec) {
160074fe6c29SRuslan Bukin 			struct pt_section *section;
160174fe6c29SRuslan Bukin 			uint64_t addr;
160274fe6c29SRuslan Bukin 			int isid, errcode;
160374fe6c29SRuslan Bukin 
160474fe6c29SRuslan Bukin 			isid = pt_iscache_add(&cfix->iscache,
160574fe6c29SRuslan Bukin 					      cfix->section[sec], laddr);
160674fe6c29SRuslan Bukin 			if (isid < 0)
160774fe6c29SRuslan Bukin 				return isid;
160874fe6c29SRuslan Bukin 
160974fe6c29SRuslan Bukin 			errcode = pt_iscache_lookup(&cfix->iscache, &section,
161074fe6c29SRuslan Bukin 						    &addr, isid);
161174fe6c29SRuslan Bukin 			if (errcode < 0)
161274fe6c29SRuslan Bukin 				return errcode;
161374fe6c29SRuslan Bukin 
161474fe6c29SRuslan Bukin 			if (laddr != addr)
161574fe6c29SRuslan Bukin 				return -pte_noip;
161674fe6c29SRuslan Bukin 
161774fe6c29SRuslan Bukin 			/* We may not get the image we added but the image we
161874fe6c29SRuslan Bukin 			 * get must have similar attributes.
161974fe6c29SRuslan Bukin 			 *
162074fe6c29SRuslan Bukin 			 * We're using the same filename string literal for all
162174fe6c29SRuslan Bukin 			 * sections, though.
162274fe6c29SRuslan Bukin 			 */
162374fe6c29SRuslan Bukin 			if (section->offset != cfix->section[sec]->offset)
162474fe6c29SRuslan Bukin 				return -pte_bad_image;
162574fe6c29SRuslan Bukin 
162674fe6c29SRuslan Bukin 			if (section->size != cfix->section[sec]->size)
162774fe6c29SRuslan Bukin 				return -pte_bad_image;
162874fe6c29SRuslan Bukin 
162974fe6c29SRuslan Bukin 			errcode = pt_section_put(section);
163074fe6c29SRuslan Bukin 			if (errcode < 0)
163174fe6c29SRuslan Bukin 				return errcode;
163274fe6c29SRuslan Bukin 		}
163374fe6c29SRuslan Bukin 	}
163474fe6c29SRuslan Bukin 
163574fe6c29SRuslan Bukin 	return 0;
163674fe6c29SRuslan Bukin }
163774fe6c29SRuslan Bukin 
worker_add_file(void * arg)163874fe6c29SRuslan Bukin static int worker_add_file(void *arg)
163974fe6c29SRuslan Bukin {
164074fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
164174fe6c29SRuslan Bukin 	int it;
164274fe6c29SRuslan Bukin 
164374fe6c29SRuslan Bukin 	cfix = arg;
164474fe6c29SRuslan Bukin 	if (!cfix)
164574fe6c29SRuslan Bukin 		return -pte_internal;
164674fe6c29SRuslan Bukin 
164774fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
164874fe6c29SRuslan Bukin 		uint64_t offset, size, laddr;
164974fe6c29SRuslan Bukin 		int sec;
165074fe6c29SRuslan Bukin 
165174fe6c29SRuslan Bukin 		offset = it % 7 == 0 ? 0x1000 : 0x2000;
165274fe6c29SRuslan Bukin 		size = it % 5 == 0 ? 0x1000 : 0x2000;
165374fe6c29SRuslan Bukin 		laddr = it % 3 == 0 ? 0x1000 : 0x2000;
165474fe6c29SRuslan Bukin 
165574fe6c29SRuslan Bukin 		for (sec = 0; sec < num_sections; ++sec) {
165674fe6c29SRuslan Bukin 			struct pt_section *section;
165774fe6c29SRuslan Bukin 			uint64_t addr;
165874fe6c29SRuslan Bukin 			int isid, errcode;
165974fe6c29SRuslan Bukin 
166074fe6c29SRuslan Bukin 			isid = pt_iscache_add_file(&cfix->iscache, "name",
166174fe6c29SRuslan Bukin 						   offset, size, laddr);
166274fe6c29SRuslan Bukin 			if (isid < 0)
166374fe6c29SRuslan Bukin 				return isid;
166474fe6c29SRuslan Bukin 
166574fe6c29SRuslan Bukin 			errcode = pt_iscache_lookup(&cfix->iscache, &section,
166674fe6c29SRuslan Bukin 						    &addr, isid);
166774fe6c29SRuslan Bukin 			if (errcode < 0)
166874fe6c29SRuslan Bukin 				return errcode;
166974fe6c29SRuslan Bukin 
167074fe6c29SRuslan Bukin 			if (laddr != addr)
167174fe6c29SRuslan Bukin 				return -pte_noip;
167274fe6c29SRuslan Bukin 
167374fe6c29SRuslan Bukin 			if (section->offset != offset)
167474fe6c29SRuslan Bukin 				return -pte_bad_image;
167574fe6c29SRuslan Bukin 
167674fe6c29SRuslan Bukin 			if (section->size != size)
167774fe6c29SRuslan Bukin 				return -pte_bad_image;
167874fe6c29SRuslan Bukin 
167974fe6c29SRuslan Bukin 			errcode = pt_section_put(section);
168074fe6c29SRuslan Bukin 			if (errcode < 0)
168174fe6c29SRuslan Bukin 				return errcode;
168274fe6c29SRuslan Bukin 		}
168374fe6c29SRuslan Bukin 	}
168474fe6c29SRuslan Bukin 
168574fe6c29SRuslan Bukin 	return 0;
168674fe6c29SRuslan Bukin }
168774fe6c29SRuslan Bukin 
worker_map(void * arg)168874fe6c29SRuslan Bukin static int worker_map(void *arg)
168974fe6c29SRuslan Bukin {
169074fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
169174fe6c29SRuslan Bukin 	int it, sec, status;
169274fe6c29SRuslan Bukin 
169374fe6c29SRuslan Bukin 	cfix = arg;
169474fe6c29SRuslan Bukin 	if (!cfix)
169574fe6c29SRuslan Bukin 		return -pte_internal;
169674fe6c29SRuslan Bukin 
169774fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
169874fe6c29SRuslan Bukin 		for (sec = 0; sec < num_sections; ++sec) {
169974fe6c29SRuslan Bukin 
170074fe6c29SRuslan Bukin 			status = pt_section_map(cfix->section[sec]);
170174fe6c29SRuslan Bukin 			if (status < 0)
170274fe6c29SRuslan Bukin 				return status;
170374fe6c29SRuslan Bukin 
170474fe6c29SRuslan Bukin 			status = pt_section_unmap(cfix->section[sec]);
170574fe6c29SRuslan Bukin 			if (status < 0)
170674fe6c29SRuslan Bukin 				return status;
170774fe6c29SRuslan Bukin 		}
170874fe6c29SRuslan Bukin 	}
170974fe6c29SRuslan Bukin 
171074fe6c29SRuslan Bukin 	return 0;
171174fe6c29SRuslan Bukin }
171274fe6c29SRuslan Bukin 
worker_map_limit(void * arg)171374fe6c29SRuslan Bukin static int worker_map_limit(void *arg)
171474fe6c29SRuslan Bukin {
171574fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
171674fe6c29SRuslan Bukin 	uint64_t limits[] = { 0x8000, 0x3000, 0x12000, 0x0 }, limit;
171774fe6c29SRuslan Bukin 	int it, sec, errcode, lim;
171874fe6c29SRuslan Bukin 
171974fe6c29SRuslan Bukin 	cfix = arg;
172074fe6c29SRuslan Bukin 	if (!cfix)
172174fe6c29SRuslan Bukin 		return -pte_internal;
172274fe6c29SRuslan Bukin 
172374fe6c29SRuslan Bukin 	lim = 0;
172474fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
172574fe6c29SRuslan Bukin 		for (sec = 0; sec < num_sections; ++sec) {
172674fe6c29SRuslan Bukin 
172774fe6c29SRuslan Bukin 			errcode = pt_section_map(cfix->section[sec]);
172874fe6c29SRuslan Bukin 			if (errcode < 0)
172974fe6c29SRuslan Bukin 				return errcode;
173074fe6c29SRuslan Bukin 
173174fe6c29SRuslan Bukin 			errcode = pt_section_unmap(cfix->section[sec]);
173274fe6c29SRuslan Bukin 			if (errcode < 0)
173374fe6c29SRuslan Bukin 				return errcode;
173474fe6c29SRuslan Bukin 		}
173574fe6c29SRuslan Bukin 
173674fe6c29SRuslan Bukin 		if (it % 23 != 0)
173774fe6c29SRuslan Bukin 			continue;
173874fe6c29SRuslan Bukin 
173974fe6c29SRuslan Bukin 		limit = limits[lim++];
174074fe6c29SRuslan Bukin 		lim %= sizeof(limits) / sizeof(*limits);
174174fe6c29SRuslan Bukin 
174274fe6c29SRuslan Bukin 		errcode = pt_iscache_set_limit(&cfix->iscache, limit);
174374fe6c29SRuslan Bukin 		if (errcode < 0)
174474fe6c29SRuslan Bukin 			return errcode;
174574fe6c29SRuslan Bukin 	}
174674fe6c29SRuslan Bukin 
174774fe6c29SRuslan Bukin 	return 0;
174874fe6c29SRuslan Bukin }
174974fe6c29SRuslan Bukin 
worker_map_bcache(void * arg)175074fe6c29SRuslan Bukin static int worker_map_bcache(void *arg)
175174fe6c29SRuslan Bukin {
175274fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
175374fe6c29SRuslan Bukin 	int it, sec, status;
175474fe6c29SRuslan Bukin 
175574fe6c29SRuslan Bukin 	cfix = arg;
175674fe6c29SRuslan Bukin 	if (!cfix)
175774fe6c29SRuslan Bukin 		return -pte_internal;
175874fe6c29SRuslan Bukin 
175974fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
176074fe6c29SRuslan Bukin 		for (sec = 0; sec < num_sections; ++sec) {
176174fe6c29SRuslan Bukin 			struct pt_section *section;
176274fe6c29SRuslan Bukin 
176374fe6c29SRuslan Bukin 			section = cfix->section[sec];
176474fe6c29SRuslan Bukin 
176574fe6c29SRuslan Bukin 			status = pt_section_map(section);
176674fe6c29SRuslan Bukin 			if (status < 0)
176774fe6c29SRuslan Bukin 				return status;
176874fe6c29SRuslan Bukin 
176974fe6c29SRuslan Bukin 			if (it % 13 == 0) {
177074fe6c29SRuslan Bukin 				status = pt_section_request_bcache(section);
177174fe6c29SRuslan Bukin 				if (status < 0) {
177274fe6c29SRuslan Bukin 					(void) pt_section_unmap(section);
177374fe6c29SRuslan Bukin 					return status;
177474fe6c29SRuslan Bukin 				}
177574fe6c29SRuslan Bukin 			}
177674fe6c29SRuslan Bukin 
177774fe6c29SRuslan Bukin 			status = pt_section_unmap(section);
177874fe6c29SRuslan Bukin 			if (status < 0)
177974fe6c29SRuslan Bukin 				return status;
178074fe6c29SRuslan Bukin 		}
178174fe6c29SRuslan Bukin 	}
178274fe6c29SRuslan Bukin 
178374fe6c29SRuslan Bukin 	return 0;
178474fe6c29SRuslan Bukin }
178574fe6c29SRuslan Bukin 
worker_add_map(void * arg)178674fe6c29SRuslan Bukin static int worker_add_map(void *arg)
178774fe6c29SRuslan Bukin {
178874fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
178974fe6c29SRuslan Bukin 	struct pt_section *section;
179074fe6c29SRuslan Bukin 	int it;
179174fe6c29SRuslan Bukin 
179274fe6c29SRuslan Bukin 	cfix = arg;
179374fe6c29SRuslan Bukin 	if (!cfix)
179474fe6c29SRuslan Bukin 		return -pte_internal;
179574fe6c29SRuslan Bukin 
179674fe6c29SRuslan Bukin 	section = cfix->section[0];
179774fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
179874fe6c29SRuslan Bukin 		uint64_t laddr;
179974fe6c29SRuslan Bukin 		int isid, errcode;
180074fe6c29SRuslan Bukin 
180174fe6c29SRuslan Bukin 		laddr = (uint64_t) it << 3;
180274fe6c29SRuslan Bukin 
180374fe6c29SRuslan Bukin 		isid = pt_iscache_add(&cfix->iscache, section, laddr);
180474fe6c29SRuslan Bukin 		if (isid < 0)
180574fe6c29SRuslan Bukin 			return isid;
180674fe6c29SRuslan Bukin 
180774fe6c29SRuslan Bukin 		errcode = pt_section_map(section);
180874fe6c29SRuslan Bukin 		if (errcode < 0)
180974fe6c29SRuslan Bukin 			return errcode;
181074fe6c29SRuslan Bukin 
181174fe6c29SRuslan Bukin 		errcode = pt_section_unmap(section);
181274fe6c29SRuslan Bukin 		if (errcode < 0)
181374fe6c29SRuslan Bukin 			return errcode;
181474fe6c29SRuslan Bukin 	}
181574fe6c29SRuslan Bukin 
181674fe6c29SRuslan Bukin 	return 0;
181774fe6c29SRuslan Bukin }
181874fe6c29SRuslan Bukin 
worker_add_clear(void * arg)181974fe6c29SRuslan Bukin static int worker_add_clear(void *arg)
182074fe6c29SRuslan Bukin {
182174fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
182274fe6c29SRuslan Bukin 	struct pt_section *section;
182374fe6c29SRuslan Bukin 	int it;
182474fe6c29SRuslan Bukin 
182574fe6c29SRuslan Bukin 	cfix = arg;
182674fe6c29SRuslan Bukin 	if (!cfix)
182774fe6c29SRuslan Bukin 		return -pte_internal;
182874fe6c29SRuslan Bukin 
182974fe6c29SRuslan Bukin 	section = cfix->section[0];
183074fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
183174fe6c29SRuslan Bukin 		uint64_t laddr;
183274fe6c29SRuslan Bukin 		int isid, errcode;
183374fe6c29SRuslan Bukin 
183474fe6c29SRuslan Bukin 		laddr = (uint64_t) it << 3;
183574fe6c29SRuslan Bukin 
183674fe6c29SRuslan Bukin 		isid = pt_iscache_add(&cfix->iscache, section, laddr);
183774fe6c29SRuslan Bukin 		if (isid < 0)
183874fe6c29SRuslan Bukin 			return isid;
183974fe6c29SRuslan Bukin 
184074fe6c29SRuslan Bukin 		errcode = pt_iscache_clear(&cfix->iscache);
184174fe6c29SRuslan Bukin 		if (errcode < 0)
184274fe6c29SRuslan Bukin 			return errcode;
184374fe6c29SRuslan Bukin 	}
184474fe6c29SRuslan Bukin 
184574fe6c29SRuslan Bukin 	return 0;
184674fe6c29SRuslan Bukin }
184774fe6c29SRuslan Bukin 
worker_add_file_map(void * arg)184874fe6c29SRuslan Bukin static int worker_add_file_map(void *arg)
184974fe6c29SRuslan Bukin {
185074fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
185174fe6c29SRuslan Bukin 	int it;
185274fe6c29SRuslan Bukin 
185374fe6c29SRuslan Bukin 	cfix = arg;
185474fe6c29SRuslan Bukin 	if (!cfix)
185574fe6c29SRuslan Bukin 		return -pte_internal;
185674fe6c29SRuslan Bukin 
185774fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
185874fe6c29SRuslan Bukin 		struct pt_section *section;
185974fe6c29SRuslan Bukin 		uint64_t offset, size, laddr, addr;
186074fe6c29SRuslan Bukin 		int isid, errcode;
186174fe6c29SRuslan Bukin 
186274fe6c29SRuslan Bukin 		offset = it % 7 < 4 ? 0x1000 : 0x2000;
186374fe6c29SRuslan Bukin 		size = it % 5 < 3 ? 0x1000 : 0x2000;
186474fe6c29SRuslan Bukin 		laddr = it % 3 < 2 ? 0x1000 : 0x2000;
186574fe6c29SRuslan Bukin 
186674fe6c29SRuslan Bukin 		isid = pt_iscache_add_file(&cfix->iscache, "name",
186774fe6c29SRuslan Bukin 					   offset, size, laddr);
186874fe6c29SRuslan Bukin 		if (isid < 0)
186974fe6c29SRuslan Bukin 			return isid;
187074fe6c29SRuslan Bukin 
187174fe6c29SRuslan Bukin 		errcode = pt_iscache_lookup(&cfix->iscache, &section,
187274fe6c29SRuslan Bukin 					    &addr, isid);
187374fe6c29SRuslan Bukin 		if (errcode < 0)
187474fe6c29SRuslan Bukin 			return errcode;
187574fe6c29SRuslan Bukin 
187674fe6c29SRuslan Bukin 		if (addr != laddr)
187774fe6c29SRuslan Bukin 			return -pte_internal;
187874fe6c29SRuslan Bukin 
187974fe6c29SRuslan Bukin 		errcode = pt_section_map(section);
188074fe6c29SRuslan Bukin 		if (errcode < 0)
188174fe6c29SRuslan Bukin 			return errcode;
188274fe6c29SRuslan Bukin 
188374fe6c29SRuslan Bukin 		errcode = pt_section_unmap(section);
188474fe6c29SRuslan Bukin 		if (errcode < 0)
188574fe6c29SRuslan Bukin 			return errcode;
188674fe6c29SRuslan Bukin 	}
188774fe6c29SRuslan Bukin 
188874fe6c29SRuslan Bukin 	return 0;
188974fe6c29SRuslan Bukin }
189074fe6c29SRuslan Bukin 
worker_add_file_clear(void * arg)189174fe6c29SRuslan Bukin static int worker_add_file_clear(void *arg)
189274fe6c29SRuslan Bukin {
189374fe6c29SRuslan Bukin 	struct iscache_fixture *cfix;
189474fe6c29SRuslan Bukin 	int it;
189574fe6c29SRuslan Bukin 
189674fe6c29SRuslan Bukin 	cfix = arg;
189774fe6c29SRuslan Bukin 	if (!cfix)
189874fe6c29SRuslan Bukin 		return -pte_internal;
189974fe6c29SRuslan Bukin 
190074fe6c29SRuslan Bukin 	for (it = 0; it < num_iterations; ++it) {
190174fe6c29SRuslan Bukin 		uint64_t offset, size, laddr;
190274fe6c29SRuslan Bukin 		int isid, errcode;
190374fe6c29SRuslan Bukin 
190474fe6c29SRuslan Bukin 		offset = it % 7 < 4 ? 0x1000 : 0x2000;
190574fe6c29SRuslan Bukin 		size = it % 5 < 3 ? 0x1000 : 0x2000;
190674fe6c29SRuslan Bukin 		laddr = it % 3 < 2 ? 0x1000 : 0x2000;
190774fe6c29SRuslan Bukin 
190874fe6c29SRuslan Bukin 		isid = pt_iscache_add_file(&cfix->iscache, "name",
190974fe6c29SRuslan Bukin 					   offset, size, laddr);
191074fe6c29SRuslan Bukin 		if (isid < 0)
191174fe6c29SRuslan Bukin 			return isid;
191274fe6c29SRuslan Bukin 
191374fe6c29SRuslan Bukin 		if (it % 11 < 9)
191474fe6c29SRuslan Bukin 			continue;
191574fe6c29SRuslan Bukin 
191674fe6c29SRuslan Bukin 		errcode = pt_iscache_clear(&cfix->iscache);
191774fe6c29SRuslan Bukin 		if (errcode < 0)
191874fe6c29SRuslan Bukin 			return errcode;
191974fe6c29SRuslan Bukin 	}
192074fe6c29SRuslan Bukin 
192174fe6c29SRuslan Bukin 	return 0;
192274fe6c29SRuslan Bukin }
192374fe6c29SRuslan Bukin 
stress(struct iscache_fixture * cfix,int (* worker)(void *))192474fe6c29SRuslan Bukin static struct ptunit_result stress(struct iscache_fixture *cfix,
192574fe6c29SRuslan Bukin 				   int (*worker)(void *))
192674fe6c29SRuslan Bukin {
192774fe6c29SRuslan Bukin 	int errcode;
192874fe6c29SRuslan Bukin 
192974fe6c29SRuslan Bukin #if defined(FEATURE_THREADS)
193074fe6c29SRuslan Bukin 	{
193174fe6c29SRuslan Bukin 		int thrd;
193274fe6c29SRuslan Bukin 
193374fe6c29SRuslan Bukin 		for (thrd = 0; thrd < num_threads; ++thrd)
193474fe6c29SRuslan Bukin 			ptu_test(ptunit_thrd_create, &cfix->thrd, worker, cfix);
193574fe6c29SRuslan Bukin 	}
193674fe6c29SRuslan Bukin #endif /* defined(FEATURE_THREADS) */
193774fe6c29SRuslan Bukin 
193874fe6c29SRuslan Bukin 	errcode = worker(cfix);
193974fe6c29SRuslan Bukin 	ptu_int_eq(errcode, 0);
194074fe6c29SRuslan Bukin 
194174fe6c29SRuslan Bukin 	return ptu_passed();
194274fe6c29SRuslan Bukin }
main(int argc,char ** argv)194374fe6c29SRuslan Bukin int main(int argc, char **argv)
194474fe6c29SRuslan Bukin {
194574fe6c29SRuslan Bukin 	struct iscache_fixture cfix, dfix, sfix;
194674fe6c29SRuslan Bukin 	struct ptunit_suite suite;
194774fe6c29SRuslan Bukin 
194874fe6c29SRuslan Bukin 	cfix.init = cfix_init;
194974fe6c29SRuslan Bukin 	cfix.fini = cfix_fini;
195074fe6c29SRuslan Bukin 
195174fe6c29SRuslan Bukin 	dfix.init = dfix_init;
195274fe6c29SRuslan Bukin 	dfix.fini = cfix_fini;
195374fe6c29SRuslan Bukin 
195474fe6c29SRuslan Bukin 	sfix.init = sfix_init;
195574fe6c29SRuslan Bukin 	sfix.fini = cfix_fini;
195674fe6c29SRuslan Bukin 
195774fe6c29SRuslan Bukin 	suite = ptunit_mk_suite(argc, argv);
195874fe6c29SRuslan Bukin 
195974fe6c29SRuslan Bukin 	ptu_run(suite, init_null);
196074fe6c29SRuslan Bukin 	ptu_run(suite, fini_null);
196174fe6c29SRuslan Bukin 	ptu_run(suite, name_null);
196274fe6c29SRuslan Bukin 	ptu_run(suite, add_null);
196374fe6c29SRuslan Bukin 	ptu_run(suite, find_null);
196474fe6c29SRuslan Bukin 	ptu_run(suite, lookup_null);
196574fe6c29SRuslan Bukin 	ptu_run(suite, clear_null);
196674fe6c29SRuslan Bukin 	ptu_run(suite, free_null);
196774fe6c29SRuslan Bukin 	ptu_run(suite, add_file_null);
196874fe6c29SRuslan Bukin 	ptu_run(suite, read_null);
196974fe6c29SRuslan Bukin 
197074fe6c29SRuslan Bukin 	ptu_run_f(suite, name, dfix);
197174fe6c29SRuslan Bukin 	ptu_run_f(suite, name_none, dfix);
197274fe6c29SRuslan Bukin 
197374fe6c29SRuslan Bukin 	ptu_run_f(suite, init_fini, cfix);
197474fe6c29SRuslan Bukin 	ptu_run_f(suite, add, cfix);
197574fe6c29SRuslan Bukin 	ptu_run_f(suite, add_no_name, cfix);
197674fe6c29SRuslan Bukin 	ptu_run_f(suite, add_file, cfix);
197774fe6c29SRuslan Bukin 
197874fe6c29SRuslan Bukin 	ptu_run_f(suite, find, cfix);
197974fe6c29SRuslan Bukin 	ptu_run_f(suite, find_empty, cfix);
198074fe6c29SRuslan Bukin 	ptu_run_f(suite, find_bad_filename, cfix);
198174fe6c29SRuslan Bukin 	ptu_run_f(suite, find_null_filename, cfix);
198274fe6c29SRuslan Bukin 	ptu_run_f(suite, find_bad_offset, cfix);
198374fe6c29SRuslan Bukin 	ptu_run_f(suite, find_bad_size, cfix);
198474fe6c29SRuslan Bukin 	ptu_run_f(suite, find_bad_laddr, cfix);
198574fe6c29SRuslan Bukin 
198674fe6c29SRuslan Bukin 	ptu_run_f(suite, lookup, cfix);
198774fe6c29SRuslan Bukin 	ptu_run_f(suite, lookup_bad_isid, cfix);
198874fe6c29SRuslan Bukin 
198974fe6c29SRuslan Bukin 	ptu_run_f(suite, clear_empty, cfix);
199074fe6c29SRuslan Bukin 	ptu_run_f(suite, clear_find, cfix);
199174fe6c29SRuslan Bukin 	ptu_run_f(suite, clear_lookup, cfix);
199274fe6c29SRuslan Bukin 
199374fe6c29SRuslan Bukin 	ptu_run_f(suite, add_twice, cfix);
199474fe6c29SRuslan Bukin 	ptu_run_f(suite, add_same, cfix);
199574fe6c29SRuslan Bukin 	ptu_run_f(suite, add_twice_different_laddr, cfix);
199674fe6c29SRuslan Bukin 	ptu_run_f(suite, add_same_different_laddr, cfix);
199774fe6c29SRuslan Bukin 	ptu_run_f(suite, add_different_same_laddr, cfix);
199874fe6c29SRuslan Bukin 
199974fe6c29SRuslan Bukin 	ptu_run_f(suite, add_file_same, cfix);
200074fe6c29SRuslan Bukin 	ptu_run_f(suite, add_file_same_different_laddr, cfix);
200174fe6c29SRuslan Bukin 	ptu_run_f(suite, add_file_different_same_laddr, cfix);
200274fe6c29SRuslan Bukin 
200374fe6c29SRuslan Bukin 	ptu_run_f(suite, read, cfix);
200474fe6c29SRuslan Bukin 	ptu_run_f(suite, read_truncate, cfix);
200574fe6c29SRuslan Bukin 	ptu_run_f(suite, read_bad_vaddr, cfix);
200674fe6c29SRuslan Bukin 	ptu_run_f(suite, read_bad_isid, cfix);
200774fe6c29SRuslan Bukin 
200874fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_map, cfix);
200974fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_read, cfix);
201074fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_map_nodup, cfix);
201174fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_map_too_big, cfix);
201274fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_map_add_front, cfix);
201374fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_map_move_front, cfix);
201474fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_map_evict, cfix);
201574fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_limit_evict, cfix);
201674fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_bcache_evict, cfix);
201774fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_bcache_clear, cfix);
201874fe6c29SRuslan Bukin 	ptu_run_f(suite, lru_clear, cfix);
201974fe6c29SRuslan Bukin 
202074fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, cfix, worker_add);
202174fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, cfix, worker_add_file);
202274fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, sfix, worker_map);
202374fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, sfix, worker_map_limit);
202474fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, sfix, worker_map_bcache);
202574fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, cfix, worker_add_map);
202674fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, cfix, worker_add_clear);
202774fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, cfix, worker_add_file_map);
202874fe6c29SRuslan Bukin 	ptu_run_fp(suite, stress, cfix, worker_add_file_clear);
202974fe6c29SRuslan Bukin 
203074fe6c29SRuslan Bukin 	return ptunit_report(&suite);
203174fe6c29SRuslan Bukin }
2032