blob: f1cef0c2a07000938e42301ed7d7e07eb9d7a70f [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>
/**
* 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) \
bitmap_zero_except(((__m)->bits), (__h), SBI_HARTMASK_MAX_BITS)
/**
* Get underlying bitmap of hartmask
* @param m the hartmask pointer
*/
#define sbi_hartmask_bits(__m) ((__m)->bits)
/**
* Set a HART in hartmask
* @param h HART id to set
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_set_hart(u32 h, struct sbi_hartmask *m)
{
if (h < SBI_HARTMASK_MAX_BITS)
__set_bit(h, m->bits);
}
/**
* Clear a HART in hartmask
* @param h HART id to clear
* @param m the hartmask pointer
*/
static inline void sbi_hartmask_clear_hart(u32 h, struct sbi_hartmask *m)
{
if (h < SBI_HARTMASK_MAX_BITS)
__clear_bit(h, m->bits);
}
/**
* Test a HART in hartmask
* @param h HART id to test
* @param m the hartmask pointer
*/
static inline int sbi_hartmask_test_hart(u32 h, const struct sbi_hartmask *m)
{
if (h < SBI_HARTMASK_MAX_BITS)
return __test_bit(h, m->bits);
return 0;
}
/**
* 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 in hartmask */
#define sbi_hartmask_for_each_hart(__h, __m) \
for_each_set_bit(__h, (__m)->bits, SBI_HARTMASK_MAX_BITS)
#endif