/* * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2020 Western Digital Corporation or its affiliates. * * Authors: * Anup Patel */ #ifndef __SBI_HARTMASK_H__ #define __SBI_HARTMASK_H__ #include /** * 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