1210284Sjmallett/***********************license start*************** 2232812Sjmallett * Copyright (c) 2003-2010 Cavium Inc. (support@cavium.com). All rights 3215990Sjmallett * reserved. 4210284Sjmallett * 5210284Sjmallett * 6215990Sjmallett * Redistribution and use in source and binary forms, with or without 7215990Sjmallett * modification, are permitted provided that the following conditions are 8215990Sjmallett * met: 9210284Sjmallett * 10215990Sjmallett * * Redistributions of source code must retain the above copyright 11215990Sjmallett * notice, this list of conditions and the following disclaimer. 12210284Sjmallett * 13215990Sjmallett * * Redistributions in binary form must reproduce the above 14215990Sjmallett * copyright notice, this list of conditions and the following 15215990Sjmallett * disclaimer in the documentation and/or other materials provided 16215990Sjmallett * with the distribution. 17215990Sjmallett 18232812Sjmallett * * Neither the name of Cavium Inc. nor the names of 19215990Sjmallett * its contributors may be used to endorse or promote products 20215990Sjmallett * derived from this software without specific prior written 21215990Sjmallett * permission. 22215990Sjmallett 23215990Sjmallett * This Software, including technical data, may be subject to U.S. export control 24215990Sjmallett * laws, including the U.S. Export Administration Act and its associated 25215990Sjmallett * regulations, and may be subject to export or import regulations in other 26215990Sjmallett * countries. 27215990Sjmallett 28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR 30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO 31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 38210284Sjmallett ***********************license end**************************************/ 39210284Sjmallett 40210284Sjmallett 41210284Sjmallett 42210284Sjmallett 43210284Sjmallett 44210284Sjmallett 45215990Sjmallett 46210284Sjmallett/** 47210284Sjmallett * @file 48210284Sjmallett * 49210284Sjmallett * Module to support operations on bitmap of cores. Coremask can be used to 50210284Sjmallett * select a specific core, a group of cores, or all available cores, for 51210284Sjmallett * initialization and differentiation of roles within a single shared binary 52210284Sjmallett * executable image. 53210284Sjmallett * 54232812Sjmallett * <hr>$Revision: 70030 $<hr> 55210284Sjmallett * 56210284Sjmallett */ 57210284Sjmallett 58210284Sjmallett 59210284Sjmallett#ifndef __CVMX_COREMASK_H__ 60210284Sjmallett#define __CVMX_COREMASK_H__ 61210284Sjmallett 62210284Sjmallett#include "cvmx-asm.h" 63210284Sjmallett 64210284Sjmallett#ifdef __cplusplus 65210284Sjmallettextern "C" { 66210284Sjmallett#endif 67210284Sjmallett 68232812Sjmalletttypedef uint64_t cvmx_coremask_holder_t; /* basic type to hold the 69232812Sjmallett coremask bits */ 70232812Sjmallett 71232812Sjmallett#define CVMX_COREMASK_HLDRSZ ((int)(sizeof(cvmx_coremask_holder_t) * 8)) 72232812Sjmallett /* bits per holder */ 73232812Sjmallett 74232812Sjmallett#define CVMX_COREMASK_BMPSZ ((int)(CVMX_MAX_CORES / CVMX_COREMASK_HLDRSZ + 1)) 75232812Sjmallett /* bit map size */ 76232812Sjmallett 77210284Sjmallett/* 78232812Sjmallett * The macro pair implement a way to iterate active cores in the mask. 79232812Sjmallett * @param fec_pcm points to the coremask. 80232812Sjmallett * @param fec_ppid is the active core's id. 81232812Sjmallett */ 82232812Sjmallett#define CVMX_COREMASK_FOR_EACH_CORE_BEGIN(fec_pcm, fec_ppid) \ 83232812Sjmallett do { \ 84232812Sjmallett int fec_i, fec_j; \ 85232812Sjmallett \ 86232812Sjmallett for (fec_i = 0; fec_i < CVMX_COREMASK_BMPSZ; fec_i++) \ 87232812Sjmallett { \ 88232812Sjmallett for (fec_j = 0; fec_j < CVMX_COREMASK_HLDRSZ; fec_j++) \ 89232812Sjmallett { \ 90232812Sjmallett if (((cvmx_coremask_holder_t)1 << fec_j) & \ 91232812Sjmallett (fec_pcm)->coremask_bitmap[fec_i]) \ 92232812Sjmallett { \ 93232812Sjmallett fec_ppid = fec_i * CVMX_COREMASK_HLDRSZ + fec_j; 94232812Sjmallett 95232812Sjmallett 96232812Sjmallett#define CVMX_COREMASK_FOR_EACH_CORE_END \ 97232812Sjmallett } \ 98232812Sjmallett } \ 99232812Sjmallett } \ 100232812Sjmallett } while (0) 101232812Sjmallett 102232812Sjmallettstruct cvmx_coremask { 103232812Sjmallett /* 104232812Sjmallett * Big-endian. Array elems of larger indices represent cores of 105232812Sjmallett * bigger ids. So do MSBs within a cvmx_coremask_holder_t. Ditto 106232812Sjmallett * MSbs within a byte. 107232812Sjmallett */ 108232812Sjmallett cvmx_coremask_holder_t coremask_bitmap[CVMX_COREMASK_BMPSZ]; 109232812Sjmallett}; 110232812Sjmallett 111232812Sjmallett/* 112232812Sjmallett * Is ``core'' set in the coremask? 113232812Sjmallett * 114232812Sjmallett * @param pcm is the pointer to the coremask. 115232812Sjmallett * @param core 116232812Sjmallett * @return 1 if core is set and 0 if not. 117232812Sjmallett */ 118232812Sjmallettstatic inline int cvmx_coremask_is_set_core(struct cvmx_coremask *pcm, 119232812Sjmallett int core) 120232812Sjmallett{ 121232812Sjmallett int n, i; 122232812Sjmallett 123232812Sjmallett n = core % CVMX_COREMASK_HLDRSZ; 124232812Sjmallett i = core / CVMX_COREMASK_HLDRSZ; 125232812Sjmallett 126232812Sjmallett return (int)((pcm->coremask_bitmap[i] & (1ull << n)) != 0); 127232812Sjmallett} 128232812Sjmallett 129232812Sjmallett/* 130232812Sjmallett * Set ``core'' in the coremask. 131232812Sjmallett * 132232812Sjmallett * @param pcm is the pointer to the coremask. 133232812Sjmallett * @param core 134232812Sjmallett * @return 0. 135232812Sjmallett */ 136232812Sjmallettstatic inline int cvmx_coremask_set_core(struct cvmx_coremask *pcm, 137232812Sjmallett int core) 138232812Sjmallett{ 139232812Sjmallett int n, i; 140232812Sjmallett 141232812Sjmallett n = core % CVMX_COREMASK_HLDRSZ; 142232812Sjmallett i = core / CVMX_COREMASK_HLDRSZ; 143232812Sjmallett pcm->coremask_bitmap[i] |= (1ull << n); 144232812Sjmallett 145232812Sjmallett return 0; 146232812Sjmallett} 147232812Sjmallett 148232812Sjmallett/* 149232812Sjmallett * Clear ``core'' from the coremask. 150232812Sjmallett * 151232812Sjmallett * @param pcm is the pointer to the coremask. 152232812Sjmallett * @param core 153232812Sjmallett * @return 0. 154232812Sjmallett */ 155232812Sjmallettstatic inline int cvmx_coremask_clear_core(struct cvmx_coremask *pcm, 156232812Sjmallett int core) 157232812Sjmallett{ 158232812Sjmallett int n, i; 159232812Sjmallett 160232812Sjmallett n = core % CVMX_COREMASK_HLDRSZ; 161232812Sjmallett i = core / CVMX_COREMASK_HLDRSZ; 162232812Sjmallett pcm->coremask_bitmap[i] &= ~(1ull << n); 163232812Sjmallett 164232812Sjmallett return 0; 165232812Sjmallett} 166232812Sjmallett 167232812Sjmallett/* 168232812Sjmallett * Clear the coremask. 169232812Sjmallett * 170232812Sjmallett * @param pcm is the pointer to the coremask. 171232812Sjmallett * @return 0. 172232812Sjmallett */ 173232812Sjmallettstatic inline int cvmx_coremask_clear_all(struct cvmx_coremask *pcm) 174232812Sjmallett{ 175232812Sjmallett int i; 176232812Sjmallett 177232812Sjmallett for (i = 0; i < CVMX_COREMASK_BMPSZ; i++) 178232812Sjmallett pcm->coremask_bitmap[i] = 0; 179232812Sjmallett 180232812Sjmallett return 0; 181232812Sjmallett} 182232812Sjmallett 183232812Sjmallett/* 184232812Sjmallett * Is the current core the first in the coremask? 185232812Sjmallett * 186232812Sjmallett * @param pcm is the pointer to the coremask. 187232812Sjmallett * @return 1 for yes and 0 for no. 188232812Sjmallett */ 189232812Sjmallettstatic inline int cvmx_coremask_first_core_bmp(struct cvmx_coremask *pcm) 190232812Sjmallett{ 191232812Sjmallett int n, i; 192232812Sjmallett 193232812Sjmallett n = (int) cvmx_get_core_num(); 194232812Sjmallett for (i = 0; i < CVMX_COREMASK_BMPSZ; i++) 195232812Sjmallett { 196232812Sjmallett if (pcm->coremask_bitmap[i]) 197232812Sjmallett { 198232812Sjmallett if (n == 0 && pcm->coremask_bitmap[i] & 1) 199232812Sjmallett return 1; 200232812Sjmallett 201232812Sjmallett if (n >= CVMX_COREMASK_HLDRSZ) 202232812Sjmallett return 0; 203232812Sjmallett 204232812Sjmallett return ((((1ull << n) - 1) & pcm->coremask_bitmap[i]) == 0); 205232812Sjmallett } 206232812Sjmallett else 207232812Sjmallett n -= CVMX_COREMASK_HLDRSZ; 208232812Sjmallett } 209232812Sjmallett 210232812Sjmallett return 0; 211232812Sjmallett} 212232812Sjmallett 213232812Sjmallett/* 214232812Sjmallett * Is the current core a member of the coremask? 215232812Sjmallett * 216232812Sjmallett * @param pcm is the pointer to the coremask. 217232812Sjmallett * @return 1 for yes and 0 for no. 218232812Sjmallett */ 219232812Sjmallettstatic inline int cvmx_coremask_is_member_bmp(struct cvmx_coremask *pcm) 220232812Sjmallett{ 221232812Sjmallett return cvmx_coremask_is_set_core(pcm, (int)cvmx_get_core_num()); 222232812Sjmallett} 223232812Sjmallett 224232812Sjmallett/* 225210284Sjmallett * coremask is simply unsigned int (32 bits). 226210284Sjmallett * 227210284Sjmallett * NOTE: supports up to 32 cores maximum. 228210284Sjmallett * 229210284Sjmallett * union of coremasks is simply bitwise-or. 230210284Sjmallett * intersection of coremasks is simply bitwise-and. 231210284Sjmallett * 232210284Sjmallett */ 233210284Sjmallett 234210284Sjmallett#define CVMX_COREMASK_MAX 0xFFFFFFFFu /* maximum supported mask */ 235210284Sjmallett 236210284Sjmallett 237210284Sjmallett/** 238210284Sjmallett * Compute coremask for a specific core. 239210284Sjmallett * 240210284Sjmallett * @param core_id The core ID 241210284Sjmallett * 242210284Sjmallett * @return coremask for a specific core 243210284Sjmallett * 244210284Sjmallett */ 245210284Sjmallettstatic inline unsigned int cvmx_coremask_core(unsigned int core_id) 246210284Sjmallett{ 247210284Sjmallett return (1u << core_id); 248210284Sjmallett} 249210284Sjmallett 250210284Sjmallett/** 251210284Sjmallett * Compute coremask for num_cores cores starting with core 0. 252210284Sjmallett * 253210284Sjmallett * @param num_cores number of cores 254210284Sjmallett * 255210284Sjmallett * @return coremask for num_cores cores 256210284Sjmallett * 257210284Sjmallett */ 258210284Sjmallettstatic inline unsigned int cvmx_coremask_numcores(unsigned int num_cores) 259210284Sjmallett{ 260232812Sjmallett return (CVMX_COREMASK_MAX >> (CVMX_MAX_CORES - num_cores)); 261210284Sjmallett} 262210284Sjmallett 263210284Sjmallett/** 264210284Sjmallett * Compute coremask for a range of cores from core low to core high. 265210284Sjmallett * 266210284Sjmallett * @param low first core in the range 267210284Sjmallett * @param high last core in the range 268210284Sjmallett * 269210284Sjmallett * @return coremask for the range of cores 270210284Sjmallett * 271210284Sjmallett */ 272210284Sjmallettstatic inline unsigned int cvmx_coremask_range(unsigned int low, unsigned int high) 273210284Sjmallett{ 274232812Sjmallett return ((CVMX_COREMASK_MAX >> (CVMX_MAX_CORES - 1 - high + low)) << low); 275210284Sjmallett} 276210284Sjmallett 277210284Sjmallett 278210284Sjmallett/** 279210284Sjmallett * Test to see if current core is a member of coremask. 280210284Sjmallett * 281210284Sjmallett * @param coremask the coremask to test against 282210284Sjmallett * 283210284Sjmallett * @return 1 if current core is a member of coremask, 0 otherwise 284210284Sjmallett * 285210284Sjmallett */ 286210284Sjmallettstatic inline int cvmx_coremask_is_member(unsigned int coremask) 287210284Sjmallett{ 288210284Sjmallett return ((cvmx_coremask_core(cvmx_get_core_num()) & coremask) != 0); 289210284Sjmallett} 290210284Sjmallett 291210284Sjmallett/** 292210284Sjmallett * Test to see if current core is first core in coremask. 293210284Sjmallett * 294210284Sjmallett * @param coremask the coremask to test against 295210284Sjmallett * 296210284Sjmallett * @return 1 if current core is first core in the coremask, 0 otherwise 297210284Sjmallett * 298210284Sjmallett */ 299210284Sjmallettstatic inline int cvmx_coremask_first_core(unsigned int coremask) 300210284Sjmallett{ 301210284Sjmallett return cvmx_coremask_is_member(coremask) 302210284Sjmallett && ((cvmx_get_core_num() == 0) || 303210284Sjmallett ((cvmx_coremask_numcores(cvmx_get_core_num()) & coremask) == 0)); 304210284Sjmallett} 305210284Sjmallett 306210284Sjmallett/** 307210284Sjmallett * Wait (stall) until all cores in the given coremask has reached this point 308210284Sjmallett * in the program execution before proceeding. 309210284Sjmallett * 310210284Sjmallett * @param coremask the group of cores performing the barrier sync 311210284Sjmallett * 312210284Sjmallett */ 313210284Sjmallettextern void cvmx_coremask_barrier_sync(unsigned int coremask); 314210284Sjmallett 315210284Sjmallett#ifdef __cplusplus 316210284Sjmallett} 317210284Sjmallett#endif 318210284Sjmallett 319210284Sjmallett#endif /* __CVMX_COREMASK_H__ */ 320