1 /*
2  * Copyright (c) 2013-2019, 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_tnt_cache.h"
30 
31 #include "intel-pt.h"
32 
33 
34 void pt_tnt_cache_init(struct pt_tnt_cache *cache)
35 {
36 	if (!cache)
37 		return;
38 
39 	cache->tnt = 0ull;
40 	cache->index = 0ull;
41 }
42 
43 int pt_tnt_cache_is_empty(const struct pt_tnt_cache *cache)
44 {
45 	if (!cache)
46 		return -pte_invalid;
47 
48 	return cache->index == 0;
49 }
50 
51 int pt_tnt_cache_query(struct pt_tnt_cache *cache)
52 {
53 	int taken;
54 
55 	if (!cache)
56 		return -pte_invalid;
57 
58 	if (!cache->index)
59 		return -pte_bad_query;
60 
61 	taken = (cache->tnt & cache->index) != 0;
62 	cache->index >>= 1;
63 
64 	return taken;
65 }
66 
67 int pt_tnt_cache_update_tnt(struct pt_tnt_cache *cache,
68 			    const struct pt_packet_tnt *packet,
69 			    const struct pt_config *config)
70 {
71 	uint8_t bit_size;
72 
73 	(void) config;
74 
75 	if (!cache || !packet)
76 		return -pte_invalid;
77 
78 	if (cache->index)
79 		return -pte_bad_context;
80 
81 	bit_size = packet->bit_size;
82 	if (!bit_size)
83 		return -pte_bad_packet;
84 
85 	cache->tnt = packet->payload;
86 	cache->index = 1ull << (bit_size - 1);
87 
88 	return 0;
89 }
90