summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sbi/sbi_hartmask.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/include/sbi/sbi_hartmask.h b/include/sbi/sbi_hartmask.h
new file mode 100644
index 0000000..77e42cb
--- /dev/null
+++ b/include/sbi/sbi_hartmask.h
@@ -0,0 +1,141 @@
+/*
+ * 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, 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