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