1/*
2 * Copyright (c) 2015-2016, 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
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation 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#ifndef MPV_INTERNAL_H
30#define MPV_INTERNAL_H
31
32#include "ue2common.h"
33
34#define MPV_DOT 0
35#define MPV_VERM 1
36#define MPV_SHUFTI 2
37#define MPV_TRUFFLE 3
38#define MPV_NVERM 4
39
40struct mpv_puffette {
41 u32 repeats;
42 char unbounded;
43
44 /**
45 * \brief Report is simple-exhaustible.
46 *
47 * If this is true, we do best-effort suppression of runs of reports, only
48 * delivering the first one.
49 */
50 char simple_exhaust;
51
52 ReportID report;
53};
54
55struct mpv_kilopuff {
56 u32 counter_offset; /**< offset (in full stream state) to the counter that
57 * this kilopuff refers to */
58 u32 count; /**< number of real (non sentinel mpv puffettes) */
59 u32 puffette_offset; /**< relative to base of mpv, points past the 1st
60 * sent */
61 u64a dead_point;
62 u8 auto_restart;
63 u8 type; /* MPV_DOT, MPV_VERM, etc */
64 union {
65 struct {
66 char c;
67 } verm;
68 struct {
69 m128 mask_lo;
70 m128 mask_hi;
71 } shuf;
72 struct {
73 m128 mask1;
74 m128 mask2;
75 } truffle;
76 } u;
77};
78
79struct mpv_counter_info {
80 u64a max_counter; /**< maximum value this counter needs to track */
81 u32 counter_size; /**< number of bytes to represent the counter in stream
82 * state */
83 u32 counter_offset; /**< offset that this counter is stored at in the
84 * full stream state */
85 u32 kilo_begin; /**< first kilo to turn on when the counter is started */
86 u32 kilo_end; /**< 1 + last kilo to turn on when the counter is started */
87};
88
89struct ALIGN_AVX_DIRECTIVE mpv {
90 u32 kilo_count; /**< number of kilopuffs following */
91 u32 counter_count; /**< number of counters managed by the mpv */
92 u32 puffette_count; /**< total number of puffettes under all the kilos */
93 u32 pq_offset; /**< offset to the priority queue in the decompressed
94 * state */
95 u32 reporter_offset; /**< offset to the reporter mmbit in the decompressed
96 * state */
97 u32 report_list_offset; /**< offset to the report list scratch space in the
98 * decompressed state */
99 u32 active_offset; /**< offset to the active kp mmbit in the compressed
100 * state */
101 u32 top_kilo_begin; /**< first kilo to switch on when top arrives */
102 u32 top_kilo_end; /**< one past the last kilo to switch on when top
103 * arrives */
104};
105
106struct mpv_decomp_kilo {
107 u64a limit;
108 const struct mpv_puffette *curr;
109};
110
111/* note: size varies on different platforms */
112struct mpv_decomp_state {
113 u32 pq_size;
114 char filled;
115 u64a counter_adj; /**< progress not yet written to the real counters */
116 struct mpv_decomp_kilo active[];
117};
118
119/* ---
120 * | | mpv
121 * ---
122 * | |
123 * | | kilo_count * mpv_kilopuffs
124 * | |
125 * ...
126 * | |
127 * ---
128 * | |
129 * | | counter_count * mpv_counter_infos
130 * | |
131 * ...
132 * | |
133 * ---
134 * | | sentinel mpv_puffette
135 * ---
136 * | | mpv_puffettes for 1st kilopuff
137 * | | (mpv_puffettes are ordered by minimum number of repeats)
138 * | |
139 * ---
140 * | | sentinel mpv_puffette
141 * ---
142 * | | mpv_puffettes for 2nd kilopuff
143 * ...
144 * | |
145 * ---
146 * | | sentinel mpv_puffette
147 * ---
148 */
149
150/*
151 * Stream State
152 * [Compressed Counter 0]
153 * [Compressed Counter 1]
154 * ...
155 * [Compressed Counter N]
156 * [mmbit of active kilopuffs]
157 *
158 * Decompressed State
159 * [header (limit pq_size)]
160 * [
161 * [kilo 1 current reports]
162 * ...
163 * [kilo N current reports]
164 * ]
165 * [
166 * [Full Counter 0]
167 * [Full Counter 1]
168 * ...
169 * [Full Counter N]
170 * ]
171 * [pq of kilo changes]
172 * [scratch space for current report lists (total number of puffettes)]
173 * [mmbit of kilopuffs with active reports]
174 */
175
176struct mpv_pq_item {
177 u64a trigger_loc;
178 u32 kilo;
179};
180
181/* returns pointer to first non sentinel mpv_puff */
182static really_inline
183const struct mpv_puffette *get_puff_array(const struct mpv *m,
184 const struct mpv_kilopuff *kp) {
185 return (const struct mpv_puffette *)((const char *)m + kp->puffette_offset);
186}
187
188static really_inline
189const struct mpv_counter_info *get_counter_info(const struct mpv *m) {
190 return (const struct mpv_counter_info *)((const char *)(m + 1)
191 + m->kilo_count * sizeof(struct mpv_kilopuff));
192}
193
194#define MPV_DEAD_VALUE (~0ULL)
195#define INVALID_REPORT (~0U)
196
197#endif
198