diff options
Diffstat (limited to 'include/boardobj/boardobjgrpmask.c')
-rw-r--r-- | include/boardobj/boardobjgrpmask.c | 411 |
1 files changed, 411 insertions, 0 deletions
diff --git a/include/boardobj/boardobjgrpmask.c b/include/boardobj/boardobjgrpmask.c new file mode 100644 index 0000000..a1dcd6d --- /dev/null +++ b/include/boardobj/boardobjgrpmask.c | |||
@@ -0,0 +1,411 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | * DEALINGS IN THE SOFTWARE. | ||
21 | */ | ||
22 | #include <nvgpu/gk20a.h> | ||
23 | |||
24 | #include "boardobjgrp.h" | ||
25 | #include "ctrl/ctrlboardobj.h" | ||
26 | |||
27 | /* | ||
28 | * Assures that unused bits (size .. (maskDataCount * 32 - 1)) are always zero. | ||
29 | */ | ||
30 | #define BOARDOBJGRPMASK_NORMALIZE(_pmask) \ | ||
31 | ((_pmask)->data[(_pmask)->maskdatacount-1] &= (_pmask)->lastmaskfilter) | ||
32 | |||
33 | u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize, | ||
34 | struct ctrl_boardobjgrp_mask *extmask) | ||
35 | { | ||
36 | if (mask == NULL) { | ||
37 | return -EINVAL; | ||
38 | } | ||
39 | if ((bitsize != CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) && | ||
40 | (bitsize != CTRL_BOARDOBJGRP_E255_MAX_OBJECTS)) { | ||
41 | return -EINVAL; | ||
42 | } | ||
43 | |||
44 | mask->bitcount = bitsize; | ||
45 | mask->maskdatacount = CTRL_BOARDOBJGRP_MASK_DATA_SIZE(bitsize); | ||
46 | mask->lastmaskfilter = bitsize % | ||
47 | CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; | ||
48 | |||
49 | mask->lastmaskfilter = (mask->lastmaskfilter == 0) ? | ||
50 | 0xFFFFFFFF : (u32)(BIT(mask->lastmaskfilter) - 1); | ||
51 | |||
52 | return (extmask == NULL) ? | ||
53 | boardobjgrpmask_clr(mask) : | ||
54 | boardobjgrpmask_import(mask, bitsize, extmask); | ||
55 | } | ||
56 | |||
57 | u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize, | ||
58 | struct ctrl_boardobjgrp_mask *extmask) | ||
59 | { | ||
60 | u8 index; | ||
61 | |||
62 | if (mask == NULL) { | ||
63 | return -EINVAL; | ||
64 | } | ||
65 | if (extmask == NULL) { | ||
66 | return -EINVAL; | ||
67 | } | ||
68 | if (mask->bitcount != bitsize) { | ||
69 | return -EINVAL; | ||
70 | } | ||
71 | |||
72 | for (index = 0; index < mask->maskdatacount; index++) { | ||
73 | mask->data[index] = extmask->data[index]; | ||
74 | } | ||
75 | |||
76 | BOARDOBJGRPMASK_NORMALIZE(mask); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize, | ||
82 | struct ctrl_boardobjgrp_mask *extmask) | ||
83 | { | ||
84 | u8 index; | ||
85 | |||
86 | if (mask == NULL) { | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | if (extmask == NULL) { | ||
90 | return -EINVAL; | ||
91 | } | ||
92 | if (mask->bitcount != bitsize) { | ||
93 | return -EINVAL; | ||
94 | } | ||
95 | |||
96 | for (index = 0; index < mask->maskdatacount; index++) { | ||
97 | extmask->data[index] = mask->data[index]; | ||
98 | } | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask) | ||
104 | { | ||
105 | u8 index; | ||
106 | |||
107 | if (mask == NULL) { | ||
108 | return -EINVAL; | ||
109 | } | ||
110 | for (index = 0; index < mask->maskdatacount; index++) { | ||
111 | mask->data[index] = 0; | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | u32 boardobjgrpmask_set(struct boardobjgrpmask *mask) | ||
118 | { | ||
119 | u8 index; | ||
120 | |||
121 | if (mask == NULL) { | ||
122 | return -EINVAL; | ||
123 | } | ||
124 | for (index = 0; index < mask->maskdatacount; index++) { | ||
125 | mask->data[index] = 0xFFFFFFFF; | ||
126 | } | ||
127 | BOARDOBJGRPMASK_NORMALIZE(mask); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask) | ||
132 | { | ||
133 | u8 index; | ||
134 | |||
135 | if (mask == NULL) { | ||
136 | return -EINVAL; | ||
137 | } | ||
138 | for (index = 0; index < mask->maskdatacount; index++) { | ||
139 | mask->data[index] = ~mask->data[index]; | ||
140 | } | ||
141 | BOARDOBJGRPMASK_NORMALIZE(mask); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask) | ||
146 | { | ||
147 | u8 index; | ||
148 | |||
149 | if (mask == NULL) { | ||
150 | return true; | ||
151 | } | ||
152 | for (index = 0; index < mask->maskdatacount; index++) { | ||
153 | if (mask->data[index] != 0) { | ||
154 | return false; | ||
155 | } | ||
156 | } | ||
157 | return true; | ||
158 | } | ||
159 | |||
160 | u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask) | ||
161 | { | ||
162 | u8 index; | ||
163 | u8 result = 0; | ||
164 | |||
165 | if (mask == NULL) { | ||
166 | return result; | ||
167 | } | ||
168 | |||
169 | for (index = 0; index < mask->maskdatacount; index++) { | ||
170 | u32 m = mask->data[index]; | ||
171 | |||
172 | NUMSETBITS_32(m); | ||
173 | result += (u8)m; | ||
174 | } | ||
175 | |||
176 | return result; | ||
177 | } | ||
178 | |||
179 | u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask) | ||
180 | { | ||
181 | u8 index; | ||
182 | u8 result = CTRL_BOARDOBJ_IDX_INVALID; | ||
183 | |||
184 | if (mask == NULL) { | ||
185 | return result; | ||
186 | } | ||
187 | |||
188 | for (index = 0; index < mask->maskdatacount; index++) { | ||
189 | u32 m = mask->data[index]; | ||
190 | |||
191 | if (m != 0) { | ||
192 | LOWESTBITIDX_32(m); | ||
193 | result = (u8)m + index * | ||
194 | CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; | ||
195 | break; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | return result; | ||
200 | } | ||
201 | |||
202 | u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask) | ||
203 | { | ||
204 | u8 index; | ||
205 | u8 result = CTRL_BOARDOBJ_IDX_INVALID; | ||
206 | |||
207 | if (mask == NULL) { | ||
208 | return result; | ||
209 | } | ||
210 | |||
211 | for (index = 0; index < mask->maskdatacount; index++) { | ||
212 | u32 m = mask->data[index]; | ||
213 | |||
214 | if (m != 0) { | ||
215 | HIGHESTBITIDX_32(m); | ||
216 | result = (u8)m + index * | ||
217 | CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; | ||
218 | break; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | return result; | ||
223 | } | ||
224 | |||
225 | int boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx) | ||
226 | { | ||
227 | u8 index; | ||
228 | u8 offset; | ||
229 | |||
230 | if (mask == NULL) { | ||
231 | return -EINVAL; | ||
232 | } | ||
233 | if (bitidx >= mask->bitcount) { | ||
234 | return -EINVAL; | ||
235 | } | ||
236 | |||
237 | index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); | ||
238 | offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); | ||
239 | |||
240 | mask->data[index] &= ~BIT(offset); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | int boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx) | ||
246 | { | ||
247 | u8 index; | ||
248 | u8 offset; | ||
249 | |||
250 | if (mask == NULL) { | ||
251 | return -EINVAL; | ||
252 | } | ||
253 | if (bitidx >= mask->bitcount) { | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | |||
257 | index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); | ||
258 | offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); | ||
259 | |||
260 | mask->data[index] |= BIT(offset); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx) | ||
266 | { | ||
267 | u8 index; | ||
268 | u8 offset; | ||
269 | |||
270 | if (mask == NULL) { | ||
271 | return -EINVAL; | ||
272 | } | ||
273 | if (bitidx >= mask->bitcount) { | ||
274 | return -EINVAL; | ||
275 | } | ||
276 | |||
277 | index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); | ||
278 | offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); | ||
279 | |||
280 | mask->data[index] ^= ~BIT(offset); | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx) | ||
286 | { | ||
287 | u8 index; | ||
288 | u8 offset; | ||
289 | |||
290 | if (mask == NULL) { | ||
291 | return false; | ||
292 | } | ||
293 | if (bitidx >= mask->bitcount) { | ||
294 | return false; | ||
295 | } | ||
296 | |||
297 | index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); | ||
298 | offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); | ||
299 | |||
300 | return (mask->data[index] & BIT(offset)) != 0; | ||
301 | } | ||
302 | |||
303 | u32 boardobjgrpmask_and(struct boardobjgrpmask *dst, | ||
304 | struct boardobjgrpmask *op1, | ||
305 | struct boardobjgrpmask *op2) | ||
306 | { | ||
307 | u8 index; | ||
308 | |||
309 | if (!boardobjgrpmask_sizeeq(dst, op1)) { | ||
310 | return -EINVAL; | ||
311 | } | ||
312 | if (!boardobjgrpmask_sizeeq(dst, op2)) { | ||
313 | return -EINVAL; | ||
314 | } | ||
315 | |||
316 | for (index = 0; index < dst->maskdatacount; index++) { | ||
317 | dst->data[index] = op1->data[index] & op2->data[index]; | ||
318 | } | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | u32 boardobjgrpmask_or(struct boardobjgrpmask *dst, | ||
324 | struct boardobjgrpmask *op1, | ||
325 | struct boardobjgrpmask *op2) | ||
326 | { | ||
327 | u8 index; | ||
328 | |||
329 | if (!boardobjgrpmask_sizeeq(dst, op1)) { | ||
330 | return -EINVAL; | ||
331 | } | ||
332 | if (!boardobjgrpmask_sizeeq(dst, op2)) { | ||
333 | return -EINVAL; | ||
334 | } | ||
335 | |||
336 | for (index = 0; index < dst->maskdatacount; index++) { | ||
337 | dst->data[index] = op1->data[index] | op2->data[index]; | ||
338 | } | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst, | ||
344 | struct boardobjgrpmask *op1, | ||
345 | struct boardobjgrpmask *op2) | ||
346 | { | ||
347 | u8 index; | ||
348 | |||
349 | if (!boardobjgrpmask_sizeeq(dst, op1)) { | ||
350 | return -EINVAL; | ||
351 | } | ||
352 | if (!boardobjgrpmask_sizeeq(dst, op2)) { | ||
353 | return -EINVAL; | ||
354 | } | ||
355 | |||
356 | for (index = 0; index < dst->maskdatacount; index++) { | ||
357 | dst->data[index] = op1->data[index] ^ op2->data[index]; | ||
358 | } | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst, | ||
364 | struct boardobjgrpmask *src) | ||
365 | { | ||
366 | u8 index; | ||
367 | |||
368 | if (!boardobjgrpmask_sizeeq(dst, src)) { | ||
369 | return -EINVAL; | ||
370 | } | ||
371 | |||
372 | for (index = 0; index < dst->maskdatacount; index++) { | ||
373 | dst->data[index] = src->data[index]; | ||
374 | } | ||
375 | |||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1, | ||
380 | struct boardobjgrpmask *op2) | ||
381 | { | ||
382 | if (op1 == NULL) { | ||
383 | return false; | ||
384 | } | ||
385 | if (op2 == NULL) { | ||
386 | return false; | ||
387 | } | ||
388 | |||
389 | return op1->bitcount == op2->bitcount; | ||
390 | } | ||
391 | |||
392 | bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1, | ||
393 | struct boardobjgrpmask *op2) | ||
394 | { | ||
395 | u8 index; | ||
396 | |||
397 | if (!boardobjgrpmask_sizeeq(op2, op1)) { | ||
398 | return false; | ||
399 | } | ||
400 | |||
401 | for (index = 0; index < op1->maskdatacount; index++) { | ||
402 | u32 op_1 = op1->data[index]; | ||
403 | u32 op_2 = op2->data[index]; | ||
404 | |||
405 | if ((op_1 & op_2) != op_1) { | ||
406 | return false; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | return true; | ||
411 | } | ||