1 /*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2020 Western Digital Corporation or its affiliates.
5 *
6 * Authors:
7 * Anup Patel <anup.patel@wdc.com>
8 */
9
10 #ifndef __SBI_HARTMASK_H__
11 #define __SBI_HARTMASK_H__
12
13 #include <sbi/sbi_bitmap.h>
14
15 /**
16 * Maximum number of bits in a hartmask
17 *
18 * The hartmask is indexed using physical HART id so this define
19 * also represents the maximum number of HART ids generic OpenSBI
20 * can handle.
21 */
22 #define SBI_HARTMASK_MAX_BITS 128
23
24 /** Representation of hartmask */
25 struct sbi_hartmask {
26 DECLARE_BITMAP(bits, SBI_HARTMASK_MAX_BITS);
27 };
28
29 /** Initialize hartmask to zero */
30 #define SBI_HARTMASK_INIT(__m) \
31 bitmap_zero(((__m)->bits), SBI_HARTMASK_MAX_BITS)
32
33 /** Initialize hartmask to zero except a particular HART id */
34 #define SBI_HARTMASK_INIT_EXCEPT(__m, __h) \
35 bitmap_zero_except(((__m)->bits), (__h), SBI_HARTMASK_MAX_BITS)
36
37 /**
38 * Get underlying bitmap of hartmask
39 * @param m the hartmask pointer
40 */
41 #define sbi_hartmask_bits(__m) ((__m)->bits)
42
43 /**
44 * Set a HART in hartmask
45 * @param h HART id to set
46 * @param m the hartmask pointer
47 */
sbi_hartmask_set_hart(u32 h,struct sbi_hartmask * m)48 static inline void sbi_hartmask_set_hart(u32 h, struct sbi_hartmask *m)
49 {
50 if (h < SBI_HARTMASK_MAX_BITS)
51 __set_bit(h, m->bits);
52 }
53
54 /**
55 * Clear a HART in hartmask
56 * @param h HART id to clear
57 * @param m the hartmask pointer
58 */
sbi_hartmask_clear_hart(u32 h,struct sbi_hartmask * m)59 static inline void sbi_hartmask_clear_hart(u32 h, struct sbi_hartmask *m)
60 {
61 if (h < SBI_HARTMASK_MAX_BITS)
62 __clear_bit(h, m->bits);
63 }
64
65 /**
66 * Test a HART in hartmask
67 * @param h HART id to test
68 * @param m the hartmask pointer
69 */
sbi_hartmask_test_hart(u32 h,const struct sbi_hartmask * m)70 static inline int sbi_hartmask_test_hart(u32 h, const struct sbi_hartmask *m)
71 {
72 if (h < SBI_HARTMASK_MAX_BITS)
73 return __test_bit(h, m->bits);
74 return 0;
75 }
76
77 /**
78 * Set all HARTs in a hartmask
79 * @param dstp the hartmask pointer
80 */
sbi_hartmask_set_all(struct sbi_hartmask * dstp)81 static inline void sbi_hartmask_set_all(struct sbi_hartmask *dstp)
82 {
83 bitmap_fill(sbi_hartmask_bits(dstp), SBI_HARTMASK_MAX_BITS);
84 }
85
86 /**
87 * Clear all HARTs in a hartmask
88 * @param dstp the hartmask pointer
89 */
sbi_hartmask_clear_all(struct sbi_hartmask * dstp)90 static inline void sbi_hartmask_clear_all(struct sbi_hartmask *dstp)
91 {
92 bitmap_zero(sbi_hartmask_bits(dstp), SBI_HARTMASK_MAX_BITS);
93 }
94
95 /**
96 * *dstp = *src1p & *src2p
97 * @param dstp the hartmask result
98 * @param src1p the first input
99 * @param src2p the second input
100 */
sbi_hartmask_and(struct sbi_hartmask * dstp,const struct sbi_hartmask * src1p,const struct sbi_hartmask * src2p)101 static inline void sbi_hartmask_and(struct sbi_hartmask *dstp,
102 const struct sbi_hartmask *src1p,
103 const struct sbi_hartmask *src2p)
104 {
105 bitmap_and(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
106 sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
107 }
108
109 /**
110 * *dstp = *src1p | *src2p
111 * @param dstp the hartmask result
112 * @param src1p the first input
113 * @param src2p the second input
114 */
sbi_hartmask_or(struct sbi_hartmask * dstp,const struct sbi_hartmask * src1p,const struct sbi_hartmask * src2p)115 static inline void sbi_hartmask_or(struct sbi_hartmask *dstp,
116 const struct sbi_hartmask *src1p,
117 const struct sbi_hartmask *src2p)
118 {
119 bitmap_or(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
120 sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
121 }
122
123 /**
124 * *dstp = *src1p ^ *src2p
125 * @param dstp the hartmask result
126 * @param src1p the first input
127 * @param src2p the second input
128 */
sbi_hartmask_xor(struct sbi_hartmask * dstp,const struct sbi_hartmask * src1p,const struct sbi_hartmask * src2p)129 static inline void sbi_hartmask_xor(struct sbi_hartmask *dstp,
130 const struct sbi_hartmask *src1p,
131 const struct sbi_hartmask *src2p)
132 {
133 bitmap_xor(sbi_hartmask_bits(dstp), sbi_hartmask_bits(src1p),
134 sbi_hartmask_bits(src2p), SBI_HARTMASK_MAX_BITS);
135 }
136
137 /** Iterate over each HART in hartmask */
138 #define sbi_hartmask_for_each_hart(__h, __m) \
139 for_each_set_bit(__h, (__m)->bits, SBI_HARTMASK_MAX_BITS)
140
141 #endif
142