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
38static 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
52static struct ptunit_result init_null(void)
53{
54	pt_tnt_cache_init(NULL);
55
56	return ptu_passed();
57}
58
59static 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
72static 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
85static 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
98static 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
108static 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
123static 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
138static 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
151static 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
161static 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
180static 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
197static 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
208static 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
224int 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