zephyr/include/arch/common/sys_bitops.h
Siew Chin Lim 5b6c59397e include: common: Add sys_set_bits and set_clear_bits inline functions
Add new common inline functions sys_set_bits and set_clear_bits to set
and clear multiple bits via bit mask in single function call.

Signed-off-by: Siew Chin Lim <elly.siew.chin.lim@intel.com>
2021-10-12 08:37:03 -04:00

131 lines
2.6 KiB
C

/*
* Copyright (c) 2020, Wind River Systems, Inc.
* Copyright (c) 2017, Oticon A/S
* Copyright (c) 2020, Synopsys
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Memory bits manipulation functions in non-arch-specific C code */
#ifndef ZEPHYR_INCLUDE_ARCH_COMMON_SYS_BITOPS_H_
#define ZEPHYR_INCLUDE_ARCH_COMMON_SYS_BITOPS_H_
#ifndef _ASMLANGUAGE
#include <toolchain.h>
#include <zephyr/types.h>
#include <sys/sys_io.h>
#ifdef __cplusplus
extern "C" {
#endif
static ALWAYS_INLINE void sys_set_bit(mem_addr_t addr, unsigned int bit)
{
uint32_t temp = *(volatile uint32_t *)addr;
*(volatile uint32_t *)addr = temp | (1 << bit);
}
static ALWAYS_INLINE void sys_clear_bit(mem_addr_t addr, unsigned int bit)
{
uint32_t temp = *(volatile uint32_t *)addr;
*(volatile uint32_t *)addr = temp & ~(1 << bit);
}
static ALWAYS_INLINE int sys_test_bit(mem_addr_t addr, unsigned int bit)
{
uint32_t temp = *(volatile uint32_t *)addr;
return temp & (1 << bit);
}
static ALWAYS_INLINE void sys_set_bits(mem_addr_t addr, unsigned int mask)
{
uint32_t temp = *(volatile uint32_t *)addr;
*(volatile uint32_t *)addr = temp | mask;
}
static ALWAYS_INLINE void sys_clear_bits(mem_addr_t addr, unsigned int mask)
{
uint32_t temp = *(volatile uint32_t *)addr;
*(volatile uint32_t *)addr = temp & ~mask;
}
static ALWAYS_INLINE
void sys_bitfield_set_bit(mem_addr_t 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);
}
static ALWAYS_INLINE
void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit)
{
sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
}
static ALWAYS_INLINE
int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit)
{
return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
}
static ALWAYS_INLINE
int sys_test_and_set_bit(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_test_bit(addr, bit);
sys_set_bit(addr, bit);
return ret;
}
static ALWAYS_INLINE
int sys_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_test_bit(addr, bit);
sys_clear_bit(addr, bit);
return ret;
}
static ALWAYS_INLINE
int sys_bitfield_test_and_set_bit(mem_addr_t 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(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_bitfield_test_bit(addr, bit);
sys_bitfield_clear_bit(addr, bit);
return ret;
}
#ifdef __cplusplus
}
#endif
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_ARCH_COMMON_SYS_BITOPS_H_ */