From 9df398b0d51d27df9e39cfab5291cea38fd66022 Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Wed, 2 Mar 2016 10:36:17 -0800 Subject: sys_io: introduce bitfield ops These are guaranteed to work for bitfields that are larger then 32 bits wide. Change-Id: I39a641f08a255478fae583947bced762950d12ff Signed-off-by: Andrew Boie --- include/arch/arc/v2/asm_inline_gcc.h | 44 +++++++++++++++++++++++ include/arch/x86/asm_inline_gcc.h | 6 ++++ include/sys_io.h | 70 +++++++++++++++++++++++++++++++++--- 3 files changed, 115 insertions(+), 5 deletions(-) diff --git a/include/arch/arc/v2/asm_inline_gcc.h b/include/arch/arc/v2/asm_inline_gcc.h index 6d8ece963..766a28a88 100644 --- a/include/arch/arc/v2/asm_inline_gcc.h +++ b/include/arch/arc/v2/asm_inline_gcc.h @@ -269,6 +269,50 @@ static inline __attribute__((always_inline)) return ret; } +static inline __attribute__((always_inline)) + void sys_bitfield_set_bit(mem_addr_t addr, int bit) +{ + /* Doing memory offsets in terms of 32-bit values to prevent + * alignment issues + */ + sys_set_bit(addr + ((bit >> 5) << 2), bit & 0x1F); +} + +static inline __attribute__((always_inline)) + void sys_bitfield_clear_bit(mem_addr_t addr, int bit) +{ + sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F); +} + +static inline __attribute__((always_inline)) + int sys_bitfield_test_bit(mem_addr_t addr, int bit) +{ + return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F); +} + + +static inline __attribute__((always_inline)) + int sys_bitfield_test_and_set_bit(mem_addr_t addr, int bit) +{ + int ret; + + ret = sys_bitfield_test_bit(addr, bit); + sys_bitfield_set_bit(addr, bit); + + return ret; +} + +static inline __attribute__((always_inline)) + int sys_bitfield_test_and_clear_bit(mem_addr_t addr, int bit) +{ + int ret; + + ret = sys_bitfield_test_bit(addr, bit); + sys_bitfield_clear_bit(addr, bit); + + return ret; +} + #endif /* _ASMLANGUAGE */ #ifdef __cplusplus diff --git a/include/arch/x86/asm_inline_gcc.h b/include/arch/x86/asm_inline_gcc.h index 7a949c9a2..51f6601db 100644 --- a/include/arch/x86/asm_inline_gcc.h +++ b/include/arch/x86/asm_inline_gcc.h @@ -485,6 +485,12 @@ static inline __attribute__((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 + #endif /* _ASMLANGUAGE */ #ifdef __cplusplus diff --git a/include/sys_io.h b/include/sys_io.h index c868ec5f0..ab5886913 100644 --- a/include/sys_io.h +++ b/include/sys_io.h @@ -231,7 +231,7 @@ typedef uint32_t mem_addr_t; * This functions takes the designated bit starting from addr and sets it to 1. * * @param addr the memory address from where to look for the bit - * @param bit the designated bit to set (from 0 to n) + * @param bit the designated bit to set (from 0 to 31) */ /** @@ -241,7 +241,7 @@ typedef uint32_t mem_addr_t; * This functions takes the designated bit starting from addr and sets it to 0. * * @param addr the memory address from where to look for the bit - * @param bit the designated bit to clear (from 0 to n) + * @param bit the designated bit to clear (from 0 to 31) */ /** @@ -252,7 +252,7 @@ typedef uint32_t mem_addr_t; * current setting. It will return the current setting. * * @param addr the memory address from where to look for the bit - * @param bit the designated bit to test (from 0 to n) + * @param bit the designated bit to test (from 0 to 31) * * @return 1 if it is set, 0 otherwise */ @@ -265,7 +265,7 @@ typedef uint32_t mem_addr_t; * current setting and sets it. It will return the previous setting. * * @param addr the memory address from where to look for the bit - * @param bit the designated bit to test and set (from 0 to n) + * @param bit the designated bit to test and set (from 0 to 31) * * @return 1 if it was set, 0 otherwise */ @@ -278,11 +278,71 @@ typedef uint32_t mem_addr_t; * current setting and clears it. It will return the previous setting. * * @param addr the memory address from where to look for the bit - * @param bit the designated bit to test and clear (from 0 to n) + * @param bit the designated bit to test and clear (from 0 to 31) * * @return 0 if it was clear, 1 otherwise */ +/** + * @fn static inline void sys_bitfield_set_bit(mem_addr_t addr, 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. + * + * @param addr the memory address from where to look for the bit + * @param bit the designated bit to set (arbitrary) + */ + +/** + * @fn static inline void sys_bitfield_clear_bit(mem_addr_t addr, 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. + * + * @param addr the memory address from where to look for the bit + * @param bit the designated bit to clear (arbitrary) + */ + +/** + * @fn static inline int sys_bitfield_test_bit(mem_addr_t addr, int bit) + * @brief Test the bit if it is set or not + * + * This functions takes the designated bit starting from addr and tests its + * current setting. It will return the current setting. + * + * @param addr the memory address from where to look for the bit + * @param bit the designated bit to test (arbitrary + * + * @return 1 if it is set, 0 otherwise + */ + +/** + * @fn static inline int sys_bitfield_test_and_set_bit(mem_addr_t addr, int bit) + * @brief Test the bit and set it + * + * This functions takes the designated bit starting from addr, tests its + * current setting and sets it. It will return the previous setting. + * + * @param addr the memory address from where to look for the bit + * @param bit the designated bit to test and set (arbitrary) + * + * @return 1 if it was set, 0 otherwise + */ + +/** + * @fn static inline int sys_bitfield_test_and_clear_bit(mem_addr_t addr, int bit) + * @brief Test the bit and clear it + * + * This functions takes the designated bit starting from addr, test its + * current setting and clears it. It will return the previous setting. + * + * @param addr the memory address from where to look for the bit + * @param bit the designated bit to test and clear (arbitrary) + * + * @return 0 if it was clear, 1 otherwise + */ + + #ifdef __cplusplus } #endif -- cgit v1.2.3