cvmx-coremask.h 19 KB

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