1 /*
2  * Copyright (c) 2013-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 "ptunit.h"
30 
31 #include "pt_tnt_cache.h"
32 
33 #include "intel-pt.h"
34 
35 #include <string.h>
36 
37 
38 static struct ptunit_result init(void)
39 {
40 	struct pt_tnt_cache tnt_cache;
41 
42 	memset(&tnt_cache, 0xcd, sizeof(tnt_cache));
43 
44 	pt_tnt_cache_init(&tnt_cache);
45 
46 	ptu_uint_eq(tnt_cache.tnt, 0ull);
47 	ptu_uint_eq(tnt_cache.index, 0ull);
48 
49 	return ptu_passed();
50 }
51 
52 static struct ptunit_result init_null(void)
53 {
54 	pt_tnt_cache_init(NULL);
55 
56 	return ptu_passed();
57 }
58 
59 static struct ptunit_result is_empty_initial(void)
60 {
61 	struct pt_tnt_cache tnt_cache;
62 	int status;
63 
64 	pt_tnt_cache_init(&tnt_cache);
65 
66 	status = pt_tnt_cache_is_empty(&tnt_cache);
67 	ptu_int_eq(status, 1);
68 
69 	return ptu_passed();
70 }
71 
72 static struct ptunit_result is_empty_no(void)
73 {
74 	struct pt_tnt_cache tnt_cache;
75 	int status;
76 
77 	tnt_cache.index = 1ull;
78 
79 	status = pt_tnt_cache_is_empty(&tnt_cache);
80 	ptu_int_eq(status, 0);
81 
82 	return ptu_passed();
83 }
84 
85 static struct ptunit_result is_empty_yes(void)
86 {
87 	struct pt_tnt_cache tnt_cache;
88 	int status;
89 
90 	tnt_cache.index = 0ull;
91 
92 	status = pt_tnt_cache_is_empty(&tnt_cache);
93 	ptu_int_eq(status, 1);
94 
95 	return ptu_passed();
96 }
97 
98 static struct ptunit_result is_empty_null(void)
99 {
100 	int status;
101 
102 	status = pt_tnt_cache_is_empty(NULL);
103 	ptu_int_eq(status, -pte_invalid);
104 
105 	return ptu_passed();
106 }
107 
108 static struct ptunit_result query_taken(void)
109 {
110 	struct pt_tnt_cache tnt_cache;
111 	int status;
112 
113 	tnt_cache.tnt = 1ull;
114 	tnt_cache.index = 1ull;
115 
116 	status = pt_tnt_cache_query(&tnt_cache);
117 	ptu_int_eq(status, 1);
118 	ptu_uint_eq(tnt_cache.index, 0);
119 
120 	return ptu_passed();
121 }
122 
123 static struct ptunit_result query_not_taken(void)
124 {
125 	struct pt_tnt_cache tnt_cache;
126 	int status;
127 
128 	tnt_cache.tnt = 0ull;
129 	tnt_cache.index = 1ull;
130 
131 	status = pt_tnt_cache_query(&tnt_cache);
132 	ptu_int_eq(status, 0);
133 	ptu_uint_eq(tnt_cache.index, 0);
134 
135 	return ptu_passed();
136 }
137 
138 static struct ptunit_result query_empty(void)
139 {
140 	struct pt_tnt_cache tnt_cache;
141 	int status;
142 
143 	tnt_cache.index = 0ull;
144 
145 	status = pt_tnt_cache_query(&tnt_cache);
146 	ptu_int_eq(status, -pte_bad_query);
147 
148 	return ptu_passed();
149 }
150 
151 static struct ptunit_result query_null(void)
152 {
153 	int status;
154 
155 	status = pt_tnt_cache_query(NULL);
156 	ptu_int_eq(status, -pte_invalid);
157 
158 	return ptu_passed();
159 }
160 
161 static struct ptunit_result update_tnt(void)
162 {
163 	struct pt_tnt_cache tnt_cache;
164 	struct pt_packet_tnt packet;
165 	int errcode;
166 
167 	pt_tnt_cache_init(&tnt_cache);
168 
169 	packet.bit_size = 4ull;
170 	packet.payload = 8ull;
171 
172 	errcode = pt_tnt_cache_update_tnt(&tnt_cache, &packet, NULL);
173 	ptu_int_eq(errcode, 0);
174 	ptu_uint_eq(tnt_cache.tnt, 8ull);
175 	ptu_uint_eq(tnt_cache.index, 1ull << 3);
176 
177 	return ptu_passed();
178 }
179 
180 static struct ptunit_result update_tnt_not_empty(void)
181 {
182 	struct pt_tnt_cache tnt_cache;
183 	struct pt_packet_tnt packet;
184 	int errcode;
185 
186 	tnt_cache.tnt = 42ull;
187 	tnt_cache.index = 12ull;
188 
189 	errcode = pt_tnt_cache_update_tnt(&tnt_cache, &packet, NULL);
190 	ptu_int_eq(errcode, -pte_bad_context);
191 	ptu_uint_eq(tnt_cache.tnt, 42ull);
192 	ptu_uint_eq(tnt_cache.index, 12ull);
193 
194 	return ptu_passed();
195 }
196 
197 static struct ptunit_result update_tnt_null_tnt(void)
198 {
199 	struct pt_packet_tnt packet;
200 	int errcode;
201 
202 	errcode = pt_tnt_cache_update_tnt(NULL, &packet, NULL);
203 	ptu_int_eq(errcode, -pte_invalid);
204 
205 	return ptu_passed();
206 }
207 
208 static struct ptunit_result update_tnt_null_packet(void)
209 {
210 	struct pt_tnt_cache tnt_cache;
211 	int errcode;
212 
213 	tnt_cache.tnt = 42ull;
214 	tnt_cache.index = 12ull;
215 
216 	errcode = pt_tnt_cache_update_tnt(&tnt_cache, NULL, NULL);
217 	ptu_int_eq(errcode, -pte_invalid);
218 	ptu_uint_eq(tnt_cache.tnt, 42ull);
219 	ptu_uint_eq(tnt_cache.index, 12ull);
220 
221 	return ptu_passed();
222 }
223 
224 int main(int argc, char **argv)
225 {
226 	struct ptunit_suite suite;
227 
228 	suite = ptunit_mk_suite(argc, argv);
229 
230 	ptu_run(suite, init);
231 	ptu_run(suite, init_null);
232 	ptu_run(suite, is_empty_initial);
233 	ptu_run(suite, is_empty_no);
234 	ptu_run(suite, is_empty_yes);
235 	ptu_run(suite, is_empty_null);
236 	ptu_run(suite, query_taken);
237 	ptu_run(suite, query_not_taken);
238 	ptu_run(suite, query_empty);
239 	ptu_run(suite, query_null);
240 	ptu_run(suite, update_tnt);
241 	ptu_run(suite, update_tnt_not_empty);
242 	ptu_run(suite, update_tnt_null_tnt);
243 	ptu_run(suite, update_tnt_null_packet);
244 
245 	return ptunit_report(&suite);
246 }
247