1/*
2 * Copyright (c) 2017-2018, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 *  * Redistributions of source code must retain the above copyright notice,
8 *    this list of conditions and the following disclaimer.
9 *  * Redistributions in binary form must reproduce the above copyright notice,
10 *    this list of conditions and the following disclaimer in the documentation
11 *    and/or other materials provided with the distribution.
12 *  * Neither the name of Intel Corporation nor the names of its contributors
13 *    may be used to endorse or promote products derived from this software
14 *    without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "pt_msec_cache.h"
30#include "pt_section.h"
31#include "pt_image.h"
32
33#include <string.h>
34
35
36int pt_msec_cache_init(struct pt_msec_cache *cache)
37{
38	if (!cache)
39		return -pte_internal;
40
41	memset(cache, 0, sizeof(*cache));
42
43	return 0;
44}
45
46void pt_msec_cache_fini(struct pt_msec_cache *cache)
47{
48	if (!cache)
49		return;
50
51	(void) pt_msec_cache_invalidate(cache);
52	pt_msec_fini(&cache->msec);
53}
54
55int pt_msec_cache_invalidate(struct pt_msec_cache *cache)
56{
57	struct pt_section *section;
58	int errcode;
59
60	if (!cache)
61		return -pte_internal;
62
63	section = pt_msec_section(&cache->msec);
64	if (!section)
65		return 0;
66
67	errcode = pt_section_unmap(section);
68	if (errcode < 0)
69		return errcode;
70
71	cache->msec.section = NULL;
72
73	return pt_section_put(section);
74}
75
76int pt_msec_cache_read(struct pt_msec_cache *cache,
77		       const struct pt_mapped_section **pmsec,
78		       struct pt_image *image, uint64_t vaddr)
79{
80	struct pt_mapped_section *msec;
81	int isid, errcode;
82
83	if (!cache || !pmsec)
84		return -pte_internal;
85
86	msec = &cache->msec;
87	isid = cache->isid;
88
89	errcode = pt_image_validate(image, msec, vaddr, isid);
90	if (errcode < 0)
91		return errcode;
92
93	*pmsec = msec;
94
95	return isid;
96
97}
98
99int pt_msec_cache_fill(struct pt_msec_cache *cache,
100		       const struct pt_mapped_section **pmsec,
101		       struct pt_image *image, const struct pt_asid *asid,
102		       uint64_t vaddr)
103{
104	struct pt_mapped_section *msec;
105	struct pt_section *section;
106	int errcode, isid;
107
108	if (!cache || !pmsec)
109		return -pte_internal;
110
111	errcode = pt_msec_cache_invalidate(cache);
112	if (errcode < 0)
113		return errcode;
114
115	msec = &cache->msec;
116
117	isid = pt_image_find(image, msec, asid, vaddr);
118	if (isid < 0)
119		return isid;
120
121	section = pt_msec_section(msec);
122
123	errcode = pt_section_map(section);
124	if (errcode < 0) {
125		(void) pt_section_put(section);
126		msec->section = NULL;
127
128		return errcode;
129	}
130
131	*pmsec = msec;
132
133	cache->isid = isid;
134
135	return isid;
136}
137