Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bitwise operation APIs are defined and used in a lot of PMDs, which caused a huge code duplication. To reduce duplication, this patch consolidates them into a common API family. Signed-off-by: Joyce Kong <joyce.kong@arm.com> Reviewed-by: Gavin Hu <gavin.hu@arm.com> Reviewed-by: Phil Yang <phil.yang@arm.com> Acked-by: Morten Brørup <mb@smartsharesystems.com>
- Loading branch information
1 parent
2a5d547
commit 7f3aa08
Showing
4 changed files
with
264 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
/* SPDX-License-Identifier: BSD-3-Clause | ||
* Copyright(c) 2020 Arm Limited | ||
*/ | ||
|
||
#ifndef _RTE_BITOPS_H_ | ||
#define _RTE_BITOPS_H_ | ||
|
||
/** | ||
* @file | ||
* Bit Operations | ||
* | ||
* This file defines a family of APIs for bit operations | ||
* without enforcing memory ordering. | ||
*/ | ||
|
||
#include <stdint.h> | ||
#include <rte_debug.h> | ||
#include <rte_compat.h> | ||
|
||
/*------------------------ 32-bit relaxed operations ------------------------*/ | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Get the target bit from a 32-bit value without memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to get. | ||
* @param addr | ||
* The address holding the bit. | ||
* @return | ||
* The target bit. | ||
*/ | ||
__rte_experimental | ||
static inline uint32_t | ||
rte_bit_relaxed_get32(unsigned int nr, volatile uint32_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 32); | ||
|
||
uint32_t mask = UINT32_C(1) << nr; | ||
return (*addr) & mask; | ||
} | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Set the target bit in a 32-bit value to 1 without memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to set. | ||
* @param addr | ||
* The address holding the bit. | ||
*/ | ||
__rte_experimental | ||
static inline void | ||
rte_bit_relaxed_set32(unsigned int nr, volatile uint32_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 32); | ||
|
||
uint32_t mask = UINT32_C(1) << nr; | ||
*addr = (*addr) | mask; | ||
} | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Clear the target bit in a 32-bit value to 0 without memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to clear. | ||
* @param addr | ||
* The address holding the bit. | ||
*/ | ||
__rte_experimental | ||
static inline void | ||
rte_bit_relaxed_clear32(unsigned int nr, volatile uint32_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 32); | ||
|
||
uint32_t mask = UINT32_C(1) << nr; | ||
*addr = (*addr) & (~mask); | ||
} | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Return the original bit from a 32-bit value, then set it to 1 without | ||
* memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to get and set. | ||
* @param addr | ||
* The address holding the bit. | ||
* @return | ||
* The original bit. | ||
*/ | ||
__rte_experimental | ||
static inline uint32_t | ||
rte_bit_relaxed_test_and_set32(unsigned int nr, volatile uint32_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 32); | ||
|
||
uint32_t mask = UINT32_C(1) << nr; | ||
uint32_t val = *addr; | ||
*addr = val | mask; | ||
return val & mask; | ||
} | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Return the original bit from a 32-bit value, then clear it to 0 without | ||
* memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to get and clear. | ||
* @param addr | ||
* The address holding the bit. | ||
* @return | ||
* The original bit. | ||
*/ | ||
__rte_experimental | ||
static inline uint32_t | ||
rte_bit_relaxed_test_and_clear32(unsigned int nr, volatile uint32_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 32); | ||
|
||
uint32_t mask = UINT32_C(1) << nr; | ||
uint32_t val = *addr; | ||
*addr = val & (~mask); | ||
return val & mask; | ||
} | ||
|
||
/*------------------------ 64-bit relaxed operations ------------------------*/ | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Get the target bit from a 64-bit value without memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to get. | ||
* @param addr | ||
* The address holding the bit. | ||
* @return | ||
* The target bit. | ||
*/ | ||
__rte_experimental | ||
static inline uint64_t | ||
rte_bit_relaxed_get64(unsigned int nr, volatile uint64_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 64); | ||
|
||
uint64_t mask = UINT64_C(1) << nr; | ||
return (*addr) & mask; | ||
} | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Set the target bit in a 64-bit value to 1 without memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to set. | ||
* @param addr | ||
* The address holding the bit. | ||
*/ | ||
__rte_experimental | ||
static inline void | ||
rte_bit_relaxed_set64(unsigned int nr, volatile uint64_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 64); | ||
|
||
uint64_t mask = UINT64_C(1) << nr; | ||
(*addr) = (*addr) | mask; | ||
} | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Clear the target bit in a 64-bit value to 0 without memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to clear. | ||
* @param addr | ||
* The address holding the bit. | ||
*/ | ||
__rte_experimental | ||
static inline void | ||
rte_bit_relaxed_clear64(unsigned int nr, volatile uint64_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 64); | ||
|
||
uint64_t mask = UINT64_C(1) << nr; | ||
*addr = (*addr) & (~mask); | ||
} | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Return the original bit from a 64-bit value, then set it to 1 without | ||
* memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to get and set. | ||
* @param addr | ||
* The address holding the bit. | ||
* @return | ||
* The original bit. | ||
*/ | ||
__rte_experimental | ||
static inline uint64_t | ||
rte_bit_relaxed_test_and_set64(unsigned int nr, volatile uint64_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 64); | ||
|
||
uint64_t mask = UINT64_C(1) << nr; | ||
uint64_t val = *addr; | ||
*addr = val | mask; | ||
return val; | ||
} | ||
|
||
/** | ||
* @warning | ||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice | ||
* | ||
* Return the original bit from a 64-bit value, then clear it to 0 without | ||
* memory ordering. | ||
* | ||
* @param nr | ||
* The target bit to get and clear. | ||
* @param addr | ||
* The address holding the bit. | ||
* @return | ||
* The original bit. | ||
*/ | ||
__rte_experimental | ||
static inline uint64_t | ||
rte_bit_relaxed_test_and_clear64(unsigned int nr, volatile uint64_t *addr) | ||
{ | ||
RTE_ASSERT(nr < 64); | ||
|
||
uint64_t mask = UINT64_C(1) << nr; | ||
uint64_t val = *addr; | ||
*addr = val & (~mask); | ||
return val & mask; | ||
} | ||
|
||
#endif /* _RTE_BITOPS_H_ */ |