diff --git a/drivers/interrupt_controller/ioapic_intr.c b/drivers/interrupt_controller/ioapic_intr.c index e1b511f6ab9..0acb6deb047 100644 --- a/drivers/interrupt_controller/ioapic_intr.c +++ b/drivers/interrupt_controller/ioapic_intr.c @@ -161,17 +161,17 @@ void store_flags(unsigned int irq, uint32_t flags) { /* Currently only the following three flags are modified */ if (flags & IOAPIC_LOW) { - sys_bitfield_set_bit((mem_addr_t) ioapic_suspend_buf, + sys_bitfield_set_bit(ioapic_suspend_buf, BIT_POS_FOR_IRQ_OPTION(irq, IOAPIC_BITFIELD_HI_LO)); } if (flags & IOAPIC_LEVEL) { - sys_bitfield_set_bit((mem_addr_t) ioapic_suspend_buf, + sys_bitfield_set_bit(ioapic_suspend_buf, BIT_POS_FOR_IRQ_OPTION(irq, IOAPIC_BITFIELD_LVL_EDGE)); } if (flags & IOAPIC_INT_MASK) { - sys_bitfield_set_bit((mem_addr_t) ioapic_suspend_buf, + sys_bitfield_set_bit(ioapic_suspend_buf, BIT_POS_FOR_IRQ_OPTION(irq, IOAPIC_BITFIELD_ENBL_DSBL)); } } @@ -180,17 +180,17 @@ uint32_t restore_flags(unsigned int irq) { uint32_t flags = 0; - if (sys_bitfield_test_bit((mem_addr_t) ioapic_suspend_buf, + if (sys_bitfield_test_bit(ioapic_suspend_buf, BIT_POS_FOR_IRQ_OPTION(irq, IOAPIC_BITFIELD_HI_LO))) { flags |= IOAPIC_LOW; } - if (sys_bitfield_test_bit((mem_addr_t) ioapic_suspend_buf, + if (sys_bitfield_test_bit(ioapic_suspend_buf, BIT_POS_FOR_IRQ_OPTION(irq, IOAPIC_BITFIELD_LVL_EDGE))) { flags |= IOAPIC_LEVEL; } - if (sys_bitfield_test_bit((mem_addr_t) ioapic_suspend_buf, + if (sys_bitfield_test_bit(ioapic_suspend_buf, BIT_POS_FOR_IRQ_OPTION(irq, IOAPIC_BITFIELD_ENBL_DSBL))) { flags |= IOAPIC_INT_MASK; } diff --git a/include/arch/arc/v2/asm_inline_gcc.h b/include/arch/arc/v2/asm_inline_gcc.h index 73e906bd4f0..7e037ffd286 100644 --- a/include/arch/arc/v2/asm_inline_gcc.h +++ b/include/arch/arc/v2/asm_inline_gcc.h @@ -266,29 +266,37 @@ static ALWAYS_INLINE } static ALWAYS_INLINE - void sys_bitfield_set_bit(mem_addr_t addr, unsigned int bit) + void sys_bitfield_set_bit(void *addr, unsigned int bit) { + mem_addr_t _addr = (unsigned long) addr; + /* Doing memory offsets in terms of 32-bit values to prevent - * alignment issues + * alignment issues. The 4 * is needed because void * + * arithmethic is byte based and by dividing by 32, we have + * the index of the four-byte block where the bit is. */ - sys_set_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + sys_set_bit(_addr + 4 * (bit / 32), bit & 0x1F); } static ALWAYS_INLINE - void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit) + void sys_bitfield_clear_bit(void *addr, unsigned int bit) { - sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + mem_addr_t _addr = (unsigned long) addr; + + sys_clear_bit(_addr + 4 * (bit / 32), bit & 0x1F); } static ALWAYS_INLINE - int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_bit(void *addr, unsigned int bit) { - return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + mem_addr_t _addr = (unsigned long) addr; + + return sys_test_bit(_addr + 4 * (bit / 32), bit & 0x1F); } static ALWAYS_INLINE - int sys_bitfield_test_and_set_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_and_set_bit(void *addr, unsigned int bit) { int ret; @@ -299,7 +307,7 @@ static ALWAYS_INLINE } static ALWAYS_INLINE - int sys_bitfield_test_and_clear_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_and_clear_bit(void *addr, unsigned int bit) { int ret; diff --git a/include/arch/nios2/asm_inline_gcc.h b/include/arch/nios2/asm_inline_gcc.h index 3d9b3ac8ec7..37e6f58611a 100644 --- a/include/arch/nios2/asm_inline_gcc.h +++ b/include/arch/nios2/asm_inline_gcc.h @@ -143,29 +143,36 @@ static ALWAYS_INLINE } static ALWAYS_INLINE - void sys_bitfield_set_bit(mem_addr_t addr, unsigned int bit) + void sys_bitfield_set_bit(void *addr, unsigned int bit) { /* Doing memory offsets in terms of 32-bit values to prevent * alignment issues */ - sys_set_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + mem_addr_t _addr = (unsigned long) addr; + + sys_set_bit(_addr + ((bit >> 5) << 2), bit & 0x1F); } static ALWAYS_INLINE - void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit) + void sys_bitfield_clear_bit(void *addr, unsigned int bit) { - sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + mem_addr_t _addr = (unsigned long) addr; + + sys_clear_bit(_addr + ((bit >> 5) << 2), bit & 0x1F); } + static ALWAYS_INLINE - int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_bit(const void *addr, unsigned int bit) { - return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + mem_addr_t _addr = (unsigned long) addr; + + return sys_test_bit(_addr + ((bit >> 5) << 2), bit & 0x1F); } static ALWAYS_INLINE - int sys_bitfield_test_and_set_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_and_set_bit(void *addr, unsigned int bit) { int ret; @@ -176,7 +183,7 @@ static ALWAYS_INLINE } static ALWAYS_INLINE - int sys_bitfield_test_and_clear_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_and_clear_bit(void *addr, unsigned int bit) { int ret; diff --git a/include/arch/riscv32/sys_io.h b/include/arch/riscv32/sys_io.h index fc43dd000cf..97fbca39609 100644 --- a/include/arch/riscv32/sys_io.h +++ b/include/arch/riscv32/sys_io.h @@ -85,29 +85,35 @@ static ALWAYS_INLINE } static ALWAYS_INLINE - void sys_bitfield_set_bit(mem_addr_t addr, unsigned int bit) + void sys_bitfield_set_bit(void *addr, unsigned int bit) { /* Doing memory offsets in terms of 32-bit values to prevent * alignment issues */ - sys_set_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + mem_addr_t _addr = (unsigned long) addr; + + sys_set_bit(_addr + ((bit >> 5) << 2), bit & 0x1F); } static ALWAYS_INLINE - void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit) + void sys_bitfield_clear_bit(void *addr, unsigned int bit) { - sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + mem_addr_t _addr = (unsigned long) addr; + + sys_clear_bit(_addr + ((bit >> 5) << 2), bit & 0x1F); } static ALWAYS_INLINE - int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_bit(void *addr, unsigned int bit) { - return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F); + mem_addr_t _addr = (unsigned long) addr; + + return sys_test_bit(_addr + ((bit >> 5) << 2), bit & 0x1F); } static ALWAYS_INLINE - int sys_bitfield_test_and_set_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_and_set_bit(void *addr, unsigned int bit) { int ret; @@ -118,7 +124,7 @@ static ALWAYS_INLINE } static ALWAYS_INLINE - int sys_bitfield_test_and_clear_bit(mem_addr_t addr, unsigned int bit) + int sys_bitfield_test_and_clear_bit(void *addr, unsigned int bit) { int ret; diff --git a/include/arch/x86/asm_inline_gcc.h b/include/arch/x86/asm_inline_gcc.h index bc8856457c9..e5646427094 100644 --- a/include/arch/x86/asm_inline_gcc.h +++ b/include/arch/x86/asm_inline_gcc.h @@ -474,11 +474,51 @@ static ALWAYS_INLINE return ret; } -#define sys_bitfield_set_bit sys_set_bit -#define sys_bitfield_clear_bit sys_clear_bit -#define sys_bitfield_test_bit sys_test_bit -#define sys_bitfield_test_and_set_bit sys_test_and_set_bit -#define sys_bitfield_test_and_clear_bit sys_test_and_clear_bit +static ALWAYS_INLINE +void sys_bitfield_set_bit(void *addr, unsigned int bit) +{ + mem_addr_t _addr = (unsigned long) addr; + + /* Doing memory offsets in terms of 32-bit values to prevent + * alignment issues. The 4 * is needed because void * + * arithmethic is byte based and by dividing by 32, we have + * the index of the four-byte block where the bit is. + */ + sys_set_bit(_addr + 4 * (bit / 32), bit & 0x1F); +} + +static ALWAYS_INLINE +void sys_bitfield_clear_bit(void *addr, unsigned int bit) +{ + sys_clear_bit((unsigned long) addr, bit); +} + +static ALWAYS_INLINE +int sys_bitfield_test_bit(void *addr, unsigned int bit) +{ + return sys_test_bit((mem_addr_t) addr, bit); +} + + +static ALWAYS_INLINE +int sys_bitfield_test_and_set_bit(void *addr, unsigned int bit) +{ + int ret; + + ret = sys_bitfield_test_bit(addr, bit); + sys_bitfield_set_bit(addr, bit); + return ret; +} + +static ALWAYS_INLINE +int sys_bitfield_test_and_clear_bit(void *addr, unsigned int bit) +{ + int ret; + + ret = sys_bitfield_test_bit(addr, bit); + sys_bitfield_clear_bit(addr, bit); + return ret; +} #endif /* _ASMLANGUAGE */ diff --git a/include/sys_io.h b/include/sys_io.h index 96685d01fb0..144fb775d7d 100644 --- a/include/sys_io.h +++ b/include/sys_io.h @@ -274,7 +274,7 @@ typedef uint32_t mem_addr_t; */ /** - * @fn static inline void sys_bitfield_set_bit(mem_addr_t addr, unsigned int bit) + * @fn static inline void sys_bitfield_set_bit(void * addr, unsigned int bit) * @brief Set the designated bit from addr to 1 * * This functions takes the designated bit starting from addr and sets it to 1. @@ -284,7 +284,7 @@ typedef uint32_t mem_addr_t; */ /** - * @fn static inline void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit) + * @fn static inline void sys_bitfield_clear_bit(void * addr, unsigned int bit) * @brief Clear the designated bit from addr to 0 * * This functions takes the designated bit starting from addr and sets it to 0. @@ -294,7 +294,7 @@ typedef uint32_t mem_addr_t; */ /** - * @fn static inline int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit) + * @fn static inline int sys_bitfield_test_bit(void * addr, unsigned int bit) * @brief Test the bit if it is set or not * * This functions takes the designated bit starting from addr and tests its @@ -307,7 +307,7 @@ typedef uint32_t mem_addr_t; */ /** - * @fn static inline int sys_bitfield_test_and_set_bit(mem_addr_t addr, unsigned int bit) + * @fn static inline int sys_bitfield_test_and_set_bit(void * addr, unsigned int bit) * @brief Test the bit and set it * * This functions takes the designated bit starting from addr, tests its @@ -320,7 +320,7 @@ typedef uint32_t mem_addr_t; */ /** - * @fn static inline int sys_bitfield_test_and_clear_bit(mem_addr_t addr, unsigned int bit) + * @fn static inline int sys_bitfield_test_and_clear_bit(void * addr, unsigned int bit) * @brief Test the bit and clear it * * This functions takes the designated bit starting from addr, test its @@ -333,6 +333,19 @@ typedef uint32_t mem_addr_t; */ +/** + * Define a bitfield + * + * Bitfields are an array of unsigned long integers, with as many + * of them as needed to fit bits bit, taking into account there are + * #LONG_BIT bits on each unsigned long int. + * + * @param name Name of the bitfield variable + * @param bits Number of bits in the bitfield + */ +#define DEFINE_BITFIELD(name, bits) \ + unsigned long int (name)[((bits) + LONG_BIT - 1) / LONG_BIT] + #ifdef __cplusplus } #endif diff --git a/tests/kernel/bitfield/src/bitfield.c b/tests/kernel/bitfield/src/bitfield.c index de9712ede3d..d21389d1436 100644 --- a/tests/kernel/bitfield/src/bitfield.c +++ b/tests/kernel/bitfield/src/bitfield.c @@ -9,14 +9,14 @@ #include -#define BIT_INDEX(bit) (bit >> 3) -#define BIT_VAL(bit) (1 << (bit & 0x7)) +#define BIT_INDEX(bit) (bit / LONG_BIT) +#define BIT_VAL(bit) (1 << (bit % LONG_BIT)) #define BITFIELD_SIZE 512 void main(void) { uint32_t b1 = 0; - unsigned char b2[BITFIELD_SIZE >> 3] = {0}; + DEFINE_BITFIELD(b2, BITFIELD_SIZE) = { 0 }; int failed = 0; int test_rv; unsigned int bit; @@ -105,9 +105,9 @@ void main(void) } for (bit = 0; bit < BITFIELD_SIZE; ++bit) { - sys_bitfield_set_bit((mem_addr_t)b2, bit); + sys_bitfield_set_bit(b2, bit); if (b2[BIT_INDEX(bit)] != BIT_VAL(bit)) { - TC_PRINT("got %d expected %d\n", b2[BIT_INDEX(bit)], + TC_PRINT("got %lx expected %x\n", b2[BIT_INDEX(bit)], BIT_VAL(bit)); TC_PRINT("sys_bitfield_set_bit failed for bit %d\n", bit); @@ -115,13 +115,13 @@ void main(void) failed++; } - if (!sys_bitfield_test_bit((mem_addr_t)b2, bit)) { + if (!sys_bitfield_test_bit(b2, bit)) { TC_PRINT("sys_bitfield_test_bit did not detect bit %d\n", bit); failed++; } - sys_bitfield_clear_bit((mem_addr_t)b2, bit); + sys_bitfield_clear_bit(b2, bit); if (b2[BIT_INDEX(bit)] != 0) { b2[BIT_INDEX(bit)] = 0; TC_PRINT("sys_bitfield_clear_bit failed for bit %d\n", @@ -129,13 +129,13 @@ void main(void) failed++; } - if (sys_bitfield_test_bit((mem_addr_t)b2, bit)) { + if (sys_bitfield_test_bit(b2, bit)) { TC_PRINT("sys_bitfield_test_bit erroneously detected bit %d\n", bit); failed++; } - ret = sys_bitfield_test_and_set_bit((mem_addr_t)b2, bit); + ret = sys_bitfield_test_and_set_bit(b2, bit); if (ret) { TC_PRINT("sys_bitfield_test_and_set_bit erroneously detected bit %d\n", bit); @@ -147,7 +147,7 @@ void main(void) bit); failed++; } - ret = sys_bitfield_test_and_set_bit((mem_addr_t)b2, bit); + ret = sys_bitfield_test_and_set_bit(b2, bit); if (!ret) { TC_PRINT("sys_bitfield_test_and_set_bit did not detect bit %d\n", bit); @@ -160,7 +160,7 @@ void main(void) failed++; } - ret = sys_bitfield_test_and_clear_bit((mem_addr_t)b2, bit); + ret = sys_bitfield_test_and_clear_bit(b2, bit); if (!ret) { TC_PRINT("sys_bitfield_test_and_clear_bit did not detect bit %d\n", bit); @@ -172,7 +172,7 @@ void main(void) bit); failed++; } - ret = sys_bitfield_test_and_clear_bit((mem_addr_t)b2, bit); + ret = sys_bitfield_test_and_clear_bit(b2, bit); if (ret) { TC_PRINT("sys_bitfield_test_and_clear_bit erroneously detected bit %d\n", bit); diff --git a/tests/kernel/common/src/bitfield.c b/tests/kernel/common/src/bitfield.c index d2cdf6f60c2..dcee881d04c 100644 --- a/tests/kernel/common/src/bitfield.c +++ b/tests/kernel/common/src/bitfield.c @@ -24,20 +24,24 @@ void bitfield_test(void) assert_true(b1 == (1 << bit), "sys_set_bit failed on bit"); - assert_true((sys_test_bit((mem_addr_t)&b1, bit) == 0), "sys_test_bit did not detect bit"); + assert_true((sys_test_bit((mem_addr_t)&b1, bit) == 0), + "sys_test_bit did not detect bit"); sys_clear_bit((mem_addr_t)&b1, bit); assert_true((b1 == 0), "sys_clear_bit failed for bit"); - assert_true((sys_test_bit((mem_addr_t)&b1, bit) == 0), "sys_test_bit erroneously detected bit"); + assert_true((sys_test_bit((mem_addr_t)&b1, bit) == 0), + "sys_test_bit erroneously detected bit"); - assert_true((sys_test_and_set_bit((mem_addr_t)&b1, bit) == 0), "sys_test_and_set_bit erroneously detected bit"); + assert_true((sys_test_and_set_bit((mem_addr_t)&b1, bit) == 0), + "sys_test_and_set_bit erroneously detected bit"); assert_true((b1 == (1 << bit)), "sys_test_and_set_bit"); printk("%d\n", sys_test_and_set_bit((mem_addr_t)&b1, bit)); - assert_true((sys_test_and_set_bit((mem_addr_t)&b1, bit) == 0), "sys_test_and_set_bit"); + assert_true((sys_test_and_set_bit((mem_addr_t)&b1, bit) == 0), + "sys_test_and_set_bit"); } #if 0 @@ -90,7 +94,7 @@ void bitfield_test(void) } for (bit = 0; bit < BITFIELD_SIZE; ++bit) { - sys_bitfield_set_bit((mem_addr_t)b2, bit); + sys_bitfield_set_bit(b2, bit); if (b2[BIT_INDEX(bit)] != BIT_VAL(bit)) { TC_PRINT("got %d expected %d\n", b2[BIT_INDEX(bit)], BIT_VAL(bit)); @@ -100,13 +104,13 @@ for (bit = 0; bit < BITFIELD_SIZE; ++bit) { failed++; } - if (!sys_bitfield_test_bit((mem_addr_t)b2, bit)) { + if (!sys_bitfield_test_bit(b2, bit)) { TC_PRINT("sys_bitfield_test_bit did not detect bit %d\n", bit); failed++; } - sys_bitfield_clear_bit((mem_addr_t)b2, bit); + sys_bitfield_clear_bit(b2, bit); if (b2[BIT_INDEX(bit)] != 0) { b2[BIT_INDEX(bit)] = 0; TC_PRINT("sys_bitfield_clear_bit failed for bit %d\n", @@ -114,13 +118,13 @@ for (bit = 0; bit < BITFIELD_SIZE; ++bit) { failed++; } - if (sys_bitfield_test_bit((mem_addr_t)b2, bit)) { + if (sys_bitfield_test_bit(b2, bit)) { TC_PRINT("sys_bitfield_test_bit erroneously detected bit %d\n", bit); failed++; } - ret = sys_bitfield_test_and_set_bit((mem_addr_t)b2, bit); + ret = sys_bitfield_test_and_set_bit(b2, bit); if (ret) { TC_PRINT("sys_bitfield_test_and_set_bit erroneously detected bit %d\n", bit); @@ -132,7 +136,7 @@ for (bit = 0; bit < BITFIELD_SIZE; ++bit) { bit); failed++; } - ret = sys_bitfield_test_and_set_bit((mem_addr_t)b2, bit); + ret = sys_bitfield_test_and_set_bit(b2, bit); if (!ret) { TC_PRINT("sys_bitfield_test_and_set_bit did not detect bit %d\n", bit); @@ -145,7 +149,7 @@ for (bit = 0; bit < BITFIELD_SIZE; ++bit) { failed++; } - ret = sys_bitfield_test_and_clear_bit((mem_addr_t)b2, bit); + ret = sys_bitfield_test_and_clear_bit(b2, bit); if (!ret) { TC_PRINT("sys_bitfield_test_and_clear_bit did not detect bit %d\n", bit); @@ -157,7 +161,7 @@ for (bit = 0; bit < BITFIELD_SIZE; ++bit) { bit); failed++; } - ret = sys_bitfield_test_and_clear_bit((mem_addr_t)b2, bit); + ret = sys_bitfield_test_and_clear_bit(b2, bit); if (ret) { TC_PRINT("sys_bitfield_test_and_clear_bit erroneously detected bit %d\n", bit); diff --git a/tests/ztest/src/ztest_mock.c b/tests/ztest/src/ztest_mock.c index 26a9731d8ac..d17d20657c4 100644 --- a/tests/ztest/src/ztest_mock.c +++ b/tests/ztest/src/ztest_mock.c @@ -45,19 +45,11 @@ void _init_mock(void) #else -/* - * FIXME: move to sys_io.h once the argument signature for bitmap has - * been fixed to void* or similar ZEP-1347 - */ -#define BITS_PER_UL (8 * sizeof(unsigned long int)) -#define DEFINE_BITFIELD(name, bits) \ - unsigned long int (name)[((bits) + BITS_PER_UL - 1) / BITS_PER_UL] - static inline int sys_bitfield_find_first_clear(const unsigned long *bitmap, unsigned int bits) { - unsigned int words = (bits + BITS_PER_UL - 1) / BITS_PER_UL; + unsigned int words = (bits + LONG_BIT - 1) / LONG_BIT; unsigned int cnt; unsigned int long neg_bitmap; @@ -70,9 +62,9 @@ int sys_bitfield_find_first_clear(const unsigned long *bitmap, if (neg_bitmap == 0) /* all full */ continue; else if (neg_bitmap == ~0UL) /* first bit */ - return cnt * BITS_PER_UL; + return cnt * LONG_BIT; else - return cnt * BITS_PER_UL + __builtin_ffsl(neg_bitmap); + return cnt * LONG_BIT + __builtin_ffsl(neg_bitmap); } return -1; } @@ -90,8 +82,7 @@ void free_parameter(struct parameter *param) __ASSERT(allocation_index < CONFIG_ZTEST_PARAMETER_COUNT, "param %p given to free is not in the static buffer %p:%u", param, params, CONFIG_ZTEST_PARAMETER_COUNT); - sys_bitfield_clear_bit((mem_addr_t) params_allocation, - allocation_index); + sys_bitfield_clear_bit(params_allocation, allocation_index); } static @@ -106,7 +97,7 @@ struct parameter *alloc_parameter(void) printk("No more mock parameters available for allocation\n"); ztest_test_fail(); } - sys_bitfield_set_bit((mem_addr_t) params_allocation, allocation_index); + sys_bitfield_set_bit(params_allocation, allocation_index); param = params + allocation_index; memset(param, 0, sizeof(*param)); return param;