| /* |
| * 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 |