1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020 Marvell International Ltd.
4 */
5
6/**
7 * Module to support operations on bitmap of cores. Coremask can be used to
8 * select a specific core, a group of cores, or all available cores, for
9 * initialization and differentiation of roles within a single shared binary
10 * executable image.
11 *
12 * The core numbers used in this file are the same value as what is found in
13 * the COP0_EBASE register and the rdhwr 0 instruction.
14 *
15 * For the CN78XX and other multi-node environments the core numbers are not
16 * contiguous.  The core numbers for the CN78XX are as follows:
17 *
18 * Node 0:	Cores 0 - 47
19 * Node 1:	Cores 128 - 175
20 * Node 2:	Cores 256 - 303
21 * Node 3:	Cores 384 - 431
22 *
23 * The coremask environment generally tries to be node agnostic in order to
24 * provide future compatibility if more cores are added to future processors
25 * or more nodes are supported.
26 */
27
28#ifndef __CVMX_COREMASK_H__
29#define __CVMX_COREMASK_H__
30
31#include "cvmx-regs.h"
32
33/* bits per holder */
34#define CVMX_COREMASK_HLDRSZ	((int)(sizeof(u64) * 8))
35
36/** Maximum allowed cores per node */
37#define CVMX_COREMASK_MAX_CORES_PER_NODE	(1 << CVMX_NODE_NO_SHIFT)
38
39/** Maximum number of bits actually used in the coremask */
40#define CVMX_MAX_USED_CORES_BMP	(1 << (CVMX_NODE_NO_SHIFT + CVMX_NODE_BITS))
41
42/* the number of valid bits in and the mask of the most significant holder */
43#define CVMX_COREMASK_MSHLDR_NBITS			\
44	(CVMX_MIPS_MAX_CORES % CVMX_COREMASK_HLDRSZ)
45
46#define CVMX_COREMASK_MSHLDR_MASK				\
47	((CVMX_COREMASK_MSHLDR_NBITS) ?				\
48	 (((u64)1 << CVMX_COREMASK_MSHLDR_NBITS) - 1) :		\
49	 ((u64)-1))
50
51/* cvmx_coremask size in u64 */
52#define CVMX_COREMASK_BMPSZ					\
53	((int)(CVMX_MIPS_MAX_CORES / CVMX_COREMASK_HLDRSZ +	\
54	       (CVMX_COREMASK_MSHLDR_NBITS != 0)))
55
56#define CVMX_COREMASK_USED_BMPSZ				\
57	(CVMX_MAX_USED_CORES_BMP / CVMX_COREMASK_HLDRSZ)
58
59#define CVMX_COREMASK_BMP_NODE_CORE_IDX(node, core)			\
60	((((node) << CVMX_NODE_NO_SHIFT) + (core)) / CVMX_COREMASK_HLDRSZ)
61/**
62 * Maximum available coremask.
63 */
64#define CVMX_COREMASK_MAX				\
65	{ {						\
66			0x0000FFFFFFFFFFFF, 0,		\
67				0x0000FFFFFFFFFFFF, 0,	\
68				0x0000FFFFFFFFFFFF, 0,	\
69				0x0000FFFFFFFFFFFF, 0,	\
70				0, 0,			\
71				0, 0,			\
72				0, 0,			\
73				0, 0} }
74
75/**
76 * Empty coremask
77 */
78#define CVMX_COREMASK_EMPTY					\
79	{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }
80
81struct cvmx_coremask {
82	u64 coremask_bitmap[CVMX_COREMASK_BMPSZ];
83};
84
85/**
86 * Macro to iterate through all available cores in a coremask
87 *
88 * @param core - core variable to use to iterate
89 * @param pcm - pointer to core mask
90 *
91 * Use this like a for statement
92 */
93#define cvmx_coremask_for_each_core(core, pcm)			\
94	for ((core) = -1;					\
95	     (core) = cvmx_coremask_next_core((core), pcm),	\
96		     (core) >= 0;)
97
98/**
99 * Given a node and node mask, return the next available node.
100 *
101 * @param node		starting node number
102 * @param node_mask	node mask to use to find the next node
103 *
104 * Return: next node number or -1 if no more nodes are available
105 */
106static inline int cvmx_coremask_next_node(int node, u8 node_mask)
107{
108	int next_offset;
109
110	next_offset = __builtin_ffs(node_mask >> (node + 1));
111	if (next_offset == 0)
112		return -1;
113	else
114		return node + next_offset;
115}
116
117/**
118 * Iterate through all nodes in a node mask
119 *
120 * @param node		node iterator variable
121 * @param node_mask	mask to use for iterating
122 *
123 * Use this like a for statement
124 */
125#define cvmx_coremask_for_each_node(node, node_mask)		\
126	for ((node) = __builtin_ffs(node_mask) - 1;		\
127	     (node) >= 0 && (node) < CVMX_MAX_NODES;		\
128	     (node) = cvmx_coremask_next_node(node, node_mask))
129
130/**
131 * Is ``core'' set in the coremask?
132 *
133 * @param pcm is the pointer to the coremask.
134 * @param core
135 * Return: 1 if core is set and 0 if not.
136 */
137static inline int cvmx_coremask_is_core_set(const struct cvmx_coremask *pcm,
138					    int core)
139{
140	int n, i;
141
142	n = core % CVMX_COREMASK_HLDRSZ;
143	i = core / CVMX_COREMASK_HLDRSZ;
144
145	return (pcm->coremask_bitmap[i] & ((u64)1 << n)) != 0;
146}
147
148/**
149 * Is ``current core'' set in the coremask?
150 *
151 * @param pcm is the pointer to the coremask.
152 * Return: 1 if core is set and 0 if not.
153 */
154static inline int cvmx_coremask_is_self_set(const struct cvmx_coremask *pcm)
155{
156	return cvmx_coremask_is_core_set(pcm, (int)cvmx_get_core_num());
157}
158
159/**
160 * Is coremask empty?
161 * @param pcm is the pointer to the coremask.
162 * Return: 1 if *pcm is empty (all zeros), 0 if not empty.
163 */
164static inline int cvmx_coremask_is_empty(const struct cvmx_coremask *pcm)
165{
166	int i;
167
168	for (i = 0; i < CVMX_COREMASK_USED_BMPSZ; i++)
169		if (pcm->coremask_bitmap[i] != 0)
170			return 0;
171
172	return 1;
173}
174
175/**
176 * Set ``core'' in the coremask.
177 *
178 * @param pcm is the pointer to the coremask.
179 * @param core
180 * Return: 0.
181 */
182static inline int cvmx_coremask_set_core(struct cvmx_coremask *pcm, int core)
183{
184	int n, i;
185
186	n = core % CVMX_COREMASK_HLDRSZ;
187	i = core / CVMX_COREMASK_HLDRSZ;
188	pcm->coremask_bitmap[i] |= ((u64)1 << n);
189
190	return 0;
191}
192
193/**
194 * Set ``current core'' in the coremask.
195 *
196 * @param pcm is the pointer to the coremask.
197 * Return: 0.
198 */
199static inline int cvmx_coremask_set_self(struct cvmx_coremask *pcm)
200{
201	return cvmx_coremask_set_core(pcm, (int)cvmx_get_core_num());
202}
203
204/**
205 * Clear ``core'' from the coremask.
206 *
207 * @param pcm is the pointer to the coremask.
208 * @param core
209 * Return: 0.
210 */
211static inline int cvmx_coremask_clear_core(struct cvmx_coremask *pcm, int core)
212{
213	int n, i;
214
215	n = core % CVMX_COREMASK_HLDRSZ;
216	i = core / CVMX_COREMASK_HLDRSZ;
217	pcm->coremask_bitmap[i] &= ~((u64)1 << n);
218
219	return 0;
220}
221
222/**
223 * Clear ``current core'' from the coremask.
224 *
225 * @param pcm is the pointer to the coremask.
226 * Return: 0.
227 */
228static inline int cvmx_coremask_clear_self(struct cvmx_coremask *pcm)
229{
230	return cvmx_coremask_clear_core(pcm, cvmx_get_core_num());
231}
232
233/**
234 * Toggle ``core'' in the coremask.
235 *
236 * @param pcm is the pointer to the coremask.
237 * @param core
238 * Return: 0.
239 */
240static inline int cvmx_coremask_toggle_core(struct cvmx_coremask *pcm, int core)
241{
242	int n, i;
243
244	n = core % CVMX_COREMASK_HLDRSZ;
245	i = core / CVMX_COREMASK_HLDRSZ;
246	pcm->coremask_bitmap[i] ^= ((u64)1 << n);
247
248	return 0;
249}
250
251/**
252 * Toggle ``current core'' in the coremask.
253 *
254 * @param pcm is the pointer to the coremask.
255 * Return: 0.
256 */
257static inline int cvmx_coremask_toggle_self(struct cvmx_coremask *pcm)
258{
259	return cvmx_coremask_toggle_core(pcm, cvmx_get_core_num());
260}
261
262/**
263 * Set the lower 64-bit of the coremask.
264 * @param pcm	pointer to coremask
265 * @param coremask_64	64-bit coremask to apply to the first node (0)
266 */
267static inline void cvmx_coremask_set64(struct cvmx_coremask *pcm,
268				       u64 coremask_64)
269{
270	pcm->coremask_bitmap[0] = coremask_64;
271}
272
273/**
274 * Set the 64-bit of the coremask for a particular node.
275 * @param pcm	pointer to coremask
276 * @param node	node to set
277 * @param coremask_64	64-bit coremask to apply to the specified node
278 */
279static inline void cvmx_coremask_set64_node(struct cvmx_coremask *pcm,
280					    u8 node,
281					    u64 coremask_64)
282{
283	pcm->coremask_bitmap[CVMX_COREMASK_BMP_NODE_CORE_IDX(node, 0)] =
284		coremask_64;
285}
286
287/**
288 * Gets the lower 64-bits of the coremask
289 *
290 * @param[in] pcm - pointer to coremask
291 * Return: 64-bit coremask for the first node
292 */
293static inline u64 cvmx_coremask_get64(const struct cvmx_coremask *pcm)
294{
295	return pcm->coremask_bitmap[0];
296}
297
298/**
299 * Gets the lower 64-bits of the coremask for the specified node
300 *
301 * @param[in] pcm - pointer to coremask
302 * @param node - node to get coremask for
303 * Return: 64-bit coremask for the first node
304 */
305static inline u64 cvmx_coremask_get64_node(const struct cvmx_coremask *pcm,
306					   u8 node)
307{
308	return pcm->coremask_bitmap[CVMX_COREMASK_BMP_NODE_CORE_IDX(node, 0)];
309}
310
311/**
312 * Gets the lower 32-bits of the coremask for compatibility
313 *
314 * @param[in] pcm - pointer to coremask
315 * Return: 32-bit coremask for the first node
316 * @deprecated This function is to maintain compatibility with older
317 *             SDK applications and may disappear at some point.
318 * This function is not compatible with the CN78XX or any other
319 * Octeon device with more than 32 cores.
320 */
321static inline u32 cvmx_coremask_get32(const struct cvmx_coremask *pcm)
322{
323	return pcm->coremask_bitmap[0] & 0xffffffff;
324}
325
326/*
327 * cvmx_coremask_cmp() returns an integer less than, equal to, or
328 * greater than zero if *pcm1 is found, respectively, to be less than,
329 * to match, or be greater than *pcm2.
330 */
331static inline int cvmx_coremask_cmp(const struct cvmx_coremask *pcm1,
332				    const struct cvmx_coremask *pcm2)
333{
334	int i;
335
336	/* Start from highest node for arithemtically correct result */
337	for (i = CVMX_COREMASK_USED_BMPSZ - 1; i >= 0; i--)
338		if (pcm1->coremask_bitmap[i] != pcm2->coremask_bitmap[i]) {
339			return (pcm1->coremask_bitmap[i] >
340				pcm2->coremask_bitmap[i]) ? 1 : -1;
341		}
342
343	return 0;
344}
345
346/*
347 * cvmx_coremask_OPx(pcm1, pcm2[, pcm3]), where OPx can be
348 * - and
349 * - or
350 * - xor
351 * - not
352 * ...
353 * For binary operators, pcm3 <-- pcm1 OPX pcm2.
354 * For unaries, pcm2 <-- OPx pcm1.
355 */
356#define CVMX_COREMASK_BINARY_DEFUN(binary_op, op)		\
357	static inline int cvmx_coremask_##binary_op(		\
358		struct cvmx_coremask *pcm1,				\
359		const struct cvmx_coremask *pcm2,			\
360		const struct cvmx_coremask *pcm3)			\
361	{							\
362		int i;						\
363								\
364		for (i = 0; i < CVMX_COREMASK_USED_BMPSZ; i++)	\
365			pcm1->coremask_bitmap[i] =		\
366				pcm2->coremask_bitmap[i]	\
367				op				\
368				pcm3->coremask_bitmap[i];	\
369								\
370		return 0;					\
371	}
372
373#define CVMX_COREMASK_UNARY_DEFUN(unary_op, op)			\
374	static inline int cvmx_coremask_##unary_op(		\
375		struct cvmx_coremask *pcm1,				\
376		const struct cvmx_coremask *pcm2)			\
377	{							\
378		int i;						\
379								\
380		for (i = 0; i < CVMX_COREMASK_USED_BMPSZ; i++)	\
381			pcm1->coremask_bitmap[i] =		\
382				op				\
383				pcm2->coremask_bitmap[i];	\
384								\
385		return 0;					\
386	}
387
388/* cvmx_coremask_and(pcm1, pcm2, pcm3): pcm1 = pmc2 & pmc3 */
389CVMX_COREMASK_BINARY_DEFUN(and, &)
390/* cvmx_coremask_or(pcm1, pcm2, pcm3): pcm1 = pmc2 | pmc3  */
391CVMX_COREMASK_BINARY_DEFUN(or, |)
392/* cvmx_coremask_xor(pcm1, pcm2, pcm3): pcm1 = pmc2 ^ pmc3 */
393CVMX_COREMASK_BINARY_DEFUN(xor, ^)
394/* cvmx_coremask_maskoff(pcm1, pcm2, pcm3): pcm1 = pmc2 & ~pmc3 */
395CVMX_COREMASK_BINARY_DEFUN(maskoff, & ~)
396/* cvmx_coremask_not(pcm1, pcm2): pcm1 = ~pcm2       */
397CVMX_COREMASK_UNARY_DEFUN(not, ~)
398/* cvmx_coremask_fill(pcm1, pcm2): pcm1 = -1      */
399CVMX_COREMASK_UNARY_DEFUN(fill, -1 |)
400/* cvmx_coremask_clear(pcm1, pcm2): pcm1 = 0     */
401CVMX_COREMASK_UNARY_DEFUN(clear, 0 &)
402/* cvmx_coremask_dup(pcm1, pcm2): pcm1 = pcm2       */
403CVMX_COREMASK_UNARY_DEFUN(dup, +)
404
405/*
406 * Macros using the unary functions defined w/
407 * CVMX_COREMASK_UNARY_DEFUN
408 * - set *pcm to its complement
409 * - set all bits in *pcm to 0
410 * - set all (valid) bits in *pcm to 1
411 */
412#define cvmx_coremask_complement(pcm)	cvmx_coremask_not(pcm, pcm)
413/* On clear, even clear the unused bits */
414#define cvmx_coremask_clear_all(pcm)					\
415	*(pcm) = (struct cvmx_coremask)CVMX_COREMASK_EMPTY
416#define cvmx_coremask_set_all(pcm)	cvmx_coremask_fill(pcm, NULL)
417
418/*
419 * convert a string of hex digits to struct cvmx_coremask
420 *
421 * @param pcm
422 * @param hexstr can be
423 *	- "[1-9A-Fa-f][0-9A-Fa-f]*", or
424 *	- "-1" to set the bits for all the cores.
425 * return
426 *	 0 for success,
427 *	-1 for string too long (i.e., hexstr takes more bits than
428 *	   CVMX_MIPS_MAX_CORES),
429 *	-2 for conversion problems from hex string to an unsigned
430 *	   long long, e.g., non-hex char in hexstr, and
431 *	-3 for hexstr starting with '0'.
432 * NOTE:
433 *	This function clears the bitmask in *pcm before the conversion.
434 */
435int cvmx_coremask_str2bmp(struct cvmx_coremask *pcm, char *hexstr);
436
437/*
438 * convert a struct cvmx_coremask to a string of hex digits
439 *
440 * @param pcm
441 * @param hexstr is "[1-9A-Fa-f][0-9A-Fa-f]*"
442 *
443 * return 0.
444 */
445int cvmx_coremask_bmp2str(const struct cvmx_coremask *pcm, char *hexstr);
446
447/*
448 * Returns the index of the lowest bit in a coremask holder.
449 */
450static inline int cvmx_coremask_lowest_bit(u64 h)
451{
452	return __builtin_ctzll(h);
453}
454
455/*
456 * Returns the 0-based index of the highest bit in a coremask holder.
457 */
458static inline int cvmx_coremask_highest_bit(u64 h)
459{
460	return (64 - __builtin_clzll(h) - 1);
461}
462
463/**
464 * Returns the last core within the coremask and -1 when the coremask
465 * is empty.
466 *
467 * @param[in] pcm - pointer to coremask
468 * @returns last core set in the coremask or -1 if all clear
469 *
470 */
471static inline int cvmx_coremask_get_last_core(const struct cvmx_coremask *pcm)
472{
473	int i;
474	int found = -1;
475
476	for (i = 0; i < CVMX_COREMASK_USED_BMPSZ; i++) {
477		if (pcm->coremask_bitmap[i])
478			found = i;
479	}
480
481	if (found == -1)
482		return -1;
483
484	return found * CVMX_COREMASK_HLDRSZ +
485		cvmx_coremask_highest_bit(pcm->coremask_bitmap[found]);
486}
487
488/**
489 * Returns the first core within the coremask and -1 when the coremask
490 * is empty.
491 *
492 * @param[in] pcm - pointer to coremask
493 * @returns first core set in the coremask or -1 if all clear
494 *
495 */
496static inline int cvmx_coremask_get_first_core(const struct cvmx_coremask *pcm)
497{
498	int i;
499
500	for (i = 0; i < CVMX_COREMASK_USED_BMPSZ; i++)
501		if (pcm->coremask_bitmap[i])
502			break;
503
504	if (i == CVMX_COREMASK_USED_BMPSZ)
505		return -1;
506
507	return i * CVMX_COREMASK_HLDRSZ +
508		cvmx_coremask_lowest_bit(pcm->coremask_bitmap[i]);
509}
510
511/**
512 * Given a core and coremask, return the next available core in the coremask
513 * or -1 if none are available.
514 *
515 * @param core - starting core to check (can be -1 for core 0)
516 * @param pcm - pointer to coremask to check for the next core.
517 *
518 * Return: next core following the core parameter or -1 if no more cores.
519 */
520static inline int cvmx_coremask_next_core(int core,
521					  const struct cvmx_coremask *pcm)
522{
523	int n, i;
524
525	core++;
526	n = core % CVMX_COREMASK_HLDRSZ;
527	i = core / CVMX_COREMASK_HLDRSZ;
528
529	if (pcm->coremask_bitmap[i] != 0) {
530		for (; n < CVMX_COREMASK_HLDRSZ; n++)
531			if (pcm->coremask_bitmap[i] & (1ULL << n))
532				return ((i * CVMX_COREMASK_HLDRSZ) + n);
533	}
534
535	for (i = i + 1; i < CVMX_COREMASK_USED_BMPSZ; i++) {
536		if (pcm->coremask_bitmap[i] != 0)
537			return (i * CVMX_COREMASK_HLDRSZ) +
538				cvmx_coremask_lowest_bit(pcm->coremask_bitmap[i]);
539	}
540	return -1;
541}
542
543/**
544 * Compute coremask for count cores starting with start_core.
545 * Note that the coremask for multi-node processors may have
546 * gaps.
547 *
548 * @param[out]  pcm        pointer to core mask data structure
549 * @param	start_core starting code number
550 * @param       count      number of cores
551 *
552 */
553static inline void cvmx_coremask_set_cores(struct cvmx_coremask *pcm,
554					   unsigned int start_core,
555					   unsigned int count)
556{
557	int node;
558	int core;	/** Current core in node */
559	int cores_in_node;
560	int i;
561
562	assert(CVMX_MAX_CORES < CVMX_COREMASK_HLDRSZ);
563	node = start_core >> CVMX_NODE_NO_SHIFT;
564	core = start_core & ((1 << CVMX_NODE_NO_SHIFT) - 1);
565	assert(core < CVMX_MAX_CORES);
566
567	cvmx_coremask_clear_all(pcm);
568	while (count > 0) {
569		if (count + core > CVMX_MAX_CORES)
570			cores_in_node = CVMX_MAX_CORES - core;
571		else
572			cores_in_node = count;
573
574		i = CVMX_COREMASK_BMP_NODE_CORE_IDX(node, core);
575		pcm->coremask_bitmap[i] = ((1ULL << cores_in_node) - 1) << core;
576		count -= cores_in_node;
577		core = 0;
578		node++;
579	}
580}
581
582/**
583 * Makes a copy of a coremask
584 *
585 * @param[out] dest - pointer to destination coremask
586 * @param[in]  src  - pointer to source coremask
587 */
588static inline void cvmx_coremask_copy(struct cvmx_coremask *dest,
589				      const struct cvmx_coremask *src)
590{
591	memcpy(dest, src, sizeof(*dest));
592}
593
594/**
595 * Test to see if the specified core is first core in coremask.
596 *
597 * @param[in]  pcm  pointer to the coremask to test against
598 * @param[in]  core core to check
599 *
600 * Return:  1 if the core is first core in the coremask, 0 otherwise
601 *
602 */
603static inline int cvmx_coremask_is_core_first_core(const struct cvmx_coremask *pcm,
604						   unsigned int core)
605{
606	int n, i;
607
608	n = core / CVMX_COREMASK_HLDRSZ;
609
610	for (i = 0; i < n; i++)
611		if (pcm->coremask_bitmap[i] != 0)
612			return 0;
613
614	/* From now on we only care about the core number within an entry */
615	core &= (CVMX_COREMASK_HLDRSZ - 1);
616	if (__builtin_ffsll(pcm->coremask_bitmap[n]) < (core + 1))
617		return 0;
618
619	return (__builtin_ffsll(pcm->coremask_bitmap[n]) == core + 1);
620}
621
622/*
623 * NOTE:
624 * cvmx_coremask_is_first_core() was retired due to improper usage.
625 * For inquiring about the current core being the initializing
626 * core for an application, use cvmx_is_init_core().
627 * For simply inquring if the current core is numerically
628 * lowest in a given mask, use :
629 *	cvmx_coremask_is_core_first_core( pcm, dvmx_get_core_num())
630 */
631
632/**
633 * Returns the number of 1 bits set in a coremask
634 *
635 * @param[in] pcm - pointer to core mask
636 *
637 * Return: number of bits set in the coremask
638 */
639static inline int cvmx_coremask_get_core_count(const struct cvmx_coremask *pcm)
640{
641	int i;
642	int count = 0;
643
644	for (i = 0; i < CVMX_COREMASK_USED_BMPSZ; i++)
645		count += __builtin_popcountll(pcm->coremask_bitmap[i]);
646
647	return count;
648}
649
650/**
651 * For multi-node systems, return the node a core belongs to.
652 *
653 * @param core - core number (0-1023)
654 *
655 * Return: node number core belongs to
656 */
657static inline int cvmx_coremask_core_to_node(int core)
658{
659	return (core >> CVMX_NODE_NO_SHIFT) & CVMX_NODE_MASK;
660}
661
662/**
663 * Given a core number on a multi-node system, return the core number for a
664 * particular node.
665 *
666 * @param core - global core number
667 *
668 * @returns core number local to the node.
669 */
670static inline int cvmx_coremask_core_on_node(int core)
671{
672	return (core & ((1 << CVMX_NODE_NO_SHIFT) - 1));
673}
674
675/**
676 * Returns if one coremask is a subset of another coremask
677 *
678 * @param main - main coremask to test
679 * @param subset - subset coremask to test
680 *
681 * Return: 0 if the subset contains cores not in the main coremask or 1 if
682 *         the subset is fully contained in the main coremask.
683 */
684static inline int cvmx_coremask_is_subset(const struct cvmx_coremask *main,
685					  const struct cvmx_coremask *subset)
686{
687	int i;
688
689	for (i = 0; i < CVMX_COREMASK_USED_BMPSZ; i++)
690		if ((main->coremask_bitmap[i] & subset->coremask_bitmap[i]) !=
691		    subset->coremask_bitmap[i])
692			return 0;
693	return 1;
694}
695
696/**
697 * Returns if one coremask intersects another coremask
698 *
699 * @param c1 - main coremask to test
700 * @param c2 - subset coremask to test
701 *
702 * Return: 1 if coremask c1 intersects coremask c2, 0 if they are exclusive
703 */
704static inline int cvmx_coremask_intersects(const struct cvmx_coremask *c1,
705					   const struct cvmx_coremask *c2)
706{
707	int i;
708
709	for (i = 0; i < CVMX_COREMASK_USED_BMPSZ; i++)
710		if ((c1->coremask_bitmap[i] & c2->coremask_bitmap[i]) != 0)
711			return 1;
712	return 0;
713}
714
715/**
716 * Masks a single node of a coremask
717 *
718 * @param pcm - coremask to mask [inout]
719 * @param node       - node number to mask against
720 */
721static inline void cvmx_coremask_mask_node(struct cvmx_coremask *pcm, int node)
722{
723	int i;
724
725	for (i = 0; i < CVMX_COREMASK_BMP_NODE_CORE_IDX(node, 0); i++)
726		pcm->coremask_bitmap[i] = 0;
727
728	for (i = CVMX_COREMASK_BMP_NODE_CORE_IDX(node + 1, 0);
729	     i < CVMX_COREMASK_USED_BMPSZ; i++)
730		pcm->coremask_bitmap[i] = 0;
731}
732
733/**
734 * Prints out a coremask in the form of node X: 0x... 0x...
735 *
736 * @param[in] pcm - pointer to core mask
737 *
738 * Return: nothing
739 */
740void cvmx_coremask_print(const struct cvmx_coremask *pcm);
741
742static inline void cvmx_coremask_dprint(const struct cvmx_coremask *pcm)
743{
744#if defined(DEBUG)
745	cvmx_coremask_print(pcm);
746#endif
747}
748
749struct cvmx_coremask *octeon_get_available_coremask(struct cvmx_coremask *pcm);
750
751int validate_coremask(struct cvmx_coremask *pcm);
752
753#endif /* __CVMX_COREMASK_H__ */
754