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