blob: bcfa50db12e7b7c64ff641ded2f345c70234c51a [file] [log] [blame]
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Western Digital Corporation or its affiliates.
*
* Authors:
* Anup Patel <anup.patel@wdc.com>
*/
#ifndef __SBI_HARTMASK_H__
#define __SBI_HARTMASK_H__
#include <sbi/sbi_bitmap.h>
#include <sbi/sbi_scratch.h>
/**
* Maximum number of bits in a hartmask
*
* The hartmask is indexed using physical HART id so this define
* also represents the maximum number of HART ids generic OpenSBI
* can handle.
*/
#define SBI_HARTMASK_MAX_BITS 128
/** Representation of hartmask */
struct sbi_hartmask {
DECLARE_BITMAP(bits, SBI_HARTMASK_MAX_BITS);
};
/** Initialize hartmask to zero */
#define SBI_HARTMASK_INIT(__m) \
bitmap_zero(((__m)->bits), SBI_HARTMASK_MAX_BITS)
/** Initialize hartmask to zero except a particular HART id */
#define SBI_HARTMASK_INIT_EXCEPT(__m, __h) \
do { \
u32 __i = sbi_hartid_to_hartindex(__h); \
bitmap_zero_except(((__m)->bits), __i, SBI_HARTMASK_MAX_BITS); \
} while(0)
/**
* Get underlying bitmap of hartmask
* @param m the hartmask pointer
*/
#define sbi_hartmask_bits(__m) ((__m)->bits)
/**
* Set a HART index in hartmask
* @param i HART index to set
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_set_hartindex(u32 i, struct sbi_hartmask *m)
{
if (i < SBI_HARTMASK_MAX_BITS)
__set_bit(i, m->bits);
}
/**
* Set a HART id in hartmask
* @param h HART id to set
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_set_hartid(u32 h, struct sbi_hartmask *m)
{
sbi_hartmask_set_hartindex(sbi_hartid_to_hartindex(h), m);
}
/**
* Clear a HART index in hartmask
* @param i HART index to clear
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_clear_hartindex(u32 i, struct sbi_hartmask *m)
{
if (i < SBI_HARTMASK_MAX_BITS)
__clear_bit(i, m->bits);
}
/**
* Clear a HART id in hartmask
* @param h HART id to clear
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_clear_hartid(u32 h, struct sbi_hartmask *m)
{
sbi_hartmask_clear_hartindex(sbi_hartid_to_hartindex(h), m);
}
/**
* Test a HART index in hartmask
* @param i HART index to test
* @param m the hartmask pointer
*/
static inline int sbi_hartmask_test_hartindex(u32 i,
const struct sbi_hartmask *m)
{
if (i < SBI_HARTMASK_MAX_BITS)
return __test_bit(i, m->bits);
return 0;
}
/**
* Test a HART id in hartmask
* @param h HART id to test
* @param m the hartmask pointer
*/
static inline int sbi_hartmask_test_hartid(u32 h, const struct sbi_hartmask *m)
{
return sbi_hartmask_test_hartindex(sbi_hartid_to_hartindex(h), m);
}
/**
* Set all HARTs in a hartmask
* @param dstp the hartmask pointer
*/
static inline void sbi_hartmask_set_all(struct sbi_hartmask *dstp)
{
bitmap_fill(sbi_hartmask_bits(dstp), SBI_HARTMASK_MAX_BITS);
}
/**
* Clear all HARTs in a hartmask
* @param dstp the hartmask pointer
*/
static inline void sbi_hartmask_clear_all(struct sbi_hartmask *dstp)
{
bitmap_zero(sbi_hartmask_bits(dstp), SBI_HARTMASK_MAX_BITS);
}
/**
* *dstp = *src1p & *src2p
* @param dstp the hartmask result
* @param src1p the first input
* @param src2p the second input
*/
static inline void sbi_hartmask_and(struct sbi_hartmask *dstp,
const struct sbi_hartmask *src1p,
const struct sbi_hartmask *src2p)
{
bitmap_and(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
}
/**
* *dstp = *src1p | *src2p
* @param dstp the hartmask result
* @param src1p the first input
* @param src2p the second input
*/
static inline void sbi_hartmask_or(struct sbi_hartmask *dstp,
const struct sbi_hartmask *src1p,
const struct sbi_hartmask *src2p)
{
bitmap_or(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
}
/**
* *dstp = *src1p ^ *src2p
* @param dstp the hartmask result
* @param src1p the first input
* @param src2p the second input
*/
static inline void sbi_hartmask_xor(struct sbi_hartmask *dstp,
const struct sbi_hartmask *src1p,
const struct sbi_hartmask *src2p)
{
bitmap_xor(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
}
/**
* Iterate over each HART index in hartmask
* __i hart index
* __m hartmask
*/
#define sbi_hartmask_for_each_hartindex(__i, __m) \
for((__i) = find_first_bit((__m)->bits, SBI_HARTMASK_MAX_BITS); \
(__i) < SBI_HARTMASK_MAX_BITS; \
(__i) = find_next_bit((__m)->bits, SBI_HARTMASK_MAX_BITS, (__i) + 1))
#endif