|
| From: | Philippe Mathieu-Daudé |
| Subject: | Re: [PATCH v6 1/4] bswap: Add the ability to store to an unaligned 24 bit field |
| Date: | Fri, 19 May 2023 18:43:28 +0200 |
| User-agent: | Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 |
On 19/5/23 18:24, Jonathan Cameron wrote:
On Fri, 19 May 2023 18:08:30 +0200 Philippe Mathieu-Daudé <philmd@linaro.org> wrote:On 19/5/23 16:18, Jonathan Cameron wrote:From: Ira Weiny <ira.weiny@intel.com> CXL has 24 bit unaligned fields which need to be stored to. CXL is specified as little endian. Define st24_le_p() and the supporting functions to store such a field from a 32 bit host native value. The use of b, w, l, q as the size specifier is limiting. So "24" was used for the size part of the function name. Signed-off-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> --- docs/devel/loads-stores.rst | 1 + include/qemu/bswap.h | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst index d2cefc77a2..82a79e91d9 100644 --- a/docs/devel/loads-stores.rst +++ b/docs/devel/loads-stores.rst @@ -36,6 +36,7 @@ store: ``st{size}_{endian}_p(ptr, val)`` ``size`` - ``b`` : 8 bits - ``w`` : 16 bits + - ``24`` : 24 bits - ``l`` : 32 bits - ``q`` : 64 bitsdiff --git a/include/qemu/bswap.h b/include/qemu/bswap.hindex 15a78c0db5..f546b1fc06 100644 --- a/include/qemu/bswap.h +++ b/include/qemu/bswap.h @@ -8,11 +8,25 @@ #undef bswap64 #define bswap64(_x) __builtin_bswap64(_x)+static inline uint32_t bswap24(uint32_t x)+{ + assert((x & 0xff000000U) == 0);Asserting here is a bit violent. In particular because there is no contract description that x should be less than N bits for bswapN() in "qemu/bswap.h" API. But if you rather to assert ...I'm fine either way. You asked for it when reviewing v4... https://lore.kernel.org/all/28a9d97a-b252-a33f-1ac0-cd36264b29ab@linaro.org/
Never too late to improve oneself ;) One month later I'm afraid the assertion would fire too often, resulting in unnecessary pain to developers (in particular the non-QEMU ones).
+ + return (((x & 0x000000ffU) << 16) | + ((x & 0x0000ff00U) << 0) | + ((x & 0x00ff0000U) >> 16)); +} + static inline void bswap16s(uint16_t *s) { *s = __builtin_bswap16(*s); }+static inline void bswap24s(uint32_t *s)+{ + *s = bswap24(*s & 0x00ffffffU);... and sanitize the value here ...+} + static inline void bswap32s(uint32_t *s) { *s = __builtin_bswap32(*s); @@ -26,11 +40,13 @@ static inline void bswap64s(uint64_t *s) #if HOST_BIG_ENDIAN #define be_bswap(v, size) (v) #define le_bswap(v, size) glue(__builtin_bswap, size)(v) +#define le_bswap24(v) bswap24(v)... then shouldn't you sanitize also here?Good point. I forgot that detail whilst fighting with s390 cross builds earlier ;)Personally I'd just drop the assertion.I'm fine with doing that. Jonathan#define be_bswaps(v, size) #define le_bswaps(p, size) \ do { *p = glue(__builtin_bswap, size)(*p); } while (0) #else #define le_bswap(v, size) (v) +#define le_bswap24(v) (v) #define be_bswap(v, size) glue(__builtin_bswap, size)(v) #define le_bswaps(v, size) #define be_bswaps(p, size) \ @@ -176,6 +192,7 @@ CPU_CONVERT(le, 64, uint64_t) * size is: * b: 8 bits * w: 16 bits + * 24: 24 bits * l: 32 bits * q: 64 bits * @@ -248,6 +265,11 @@ static inline void stw_he_p(void *ptr, uint16_t v) __builtin_memcpy(ptr, &v, sizeof(v)); }+static inline void st24_he_p(void *ptr, uint32_t v)+{ + __builtin_memcpy(ptr, &v, 3); +} + static inline int ldl_he_p(const void *ptr) { int32_t r; @@ -297,6 +319,11 @@ static inline void stw_le_p(void *ptr, uint16_t v) stw_he_p(ptr, le_bswap(v, 16)); }+static inline void st24_le_p(void *ptr, uint32_t v)+{ + st24_he_p(ptr, le_bswap24(v)); +} + static inline void stl_le_p(void *ptr, uint32_t v) { stl_he_p(ptr, le_bswap(v, 32));Conditional to removing the assertion in bswap24(): Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
| [Prev in Thread] | Current Thread | [Next in Thread] |