1*3117ece4Schristos /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ 2*3117ece4Schristos /* 3*3117ece4Schristos * Copyright (c) Meta Platforms, Inc. and affiliates. 4*3117ece4Schristos * All rights reserved. 5*3117ece4Schristos * 6*3117ece4Schristos * This source code is licensed under both the BSD-style license (found in the 7*3117ece4Schristos * LICENSE file in the root directory of this source tree) and the GPLv2 (found 8*3117ece4Schristos * in the COPYING file in the root directory of this source tree). 9*3117ece4Schristos * You may select, at your option, one of the above-listed licenses. 10*3117ece4Schristos */ 11*3117ece4Schristos 12*3117ece4Schristos #ifndef MEM_H_MODULE 13*3117ece4Schristos #define MEM_H_MODULE 14*3117ece4Schristos 15*3117ece4Schristos /*-**************************************** 16*3117ece4Schristos * Dependencies 17*3117ece4Schristos ******************************************/ 18*3117ece4Schristos #include <asm/unaligned.h> /* get_unaligned, put_unaligned* */ 19*3117ece4Schristos #include <linux/compiler.h> /* inline */ 20*3117ece4Schristos #include <linux/swab.h> /* swab32, swab64 */ 21*3117ece4Schristos #include <linux/types.h> /* size_t, ptrdiff_t */ 22*3117ece4Schristos #include "debug.h" /* DEBUG_STATIC_ASSERT */ 23*3117ece4Schristos 24*3117ece4Schristos /*-**************************************** 25*3117ece4Schristos * Compiler specifics 26*3117ece4Schristos ******************************************/ 27*3117ece4Schristos #undef MEM_STATIC /* may be already defined from common/compiler.h */ 28*3117ece4Schristos #define MEM_STATIC static inline 29*3117ece4Schristos 30*3117ece4Schristos /*-************************************************************** 31*3117ece4Schristos * Basic Types 32*3117ece4Schristos *****************************************************************/ 33*3117ece4Schristos typedef uint8_t BYTE; 34*3117ece4Schristos typedef uint8_t U8; 35*3117ece4Schristos typedef int8_t S8; 36*3117ece4Schristos typedef uint16_t U16; 37*3117ece4Schristos typedef int16_t S16; 38*3117ece4Schristos typedef uint32_t U32; 39*3117ece4Schristos typedef int32_t S32; 40*3117ece4Schristos typedef uint64_t U64; 41*3117ece4Schristos typedef int64_t S64; 42*3117ece4Schristos 43*3117ece4Schristos /*-************************************************************** 44*3117ece4Schristos * Memory I/O API 45*3117ece4Schristos *****************************************************************/ 46*3117ece4Schristos /*=== Static platform detection ===*/ 47*3117ece4Schristos MEM_STATIC unsigned MEM_32bits(void); 48*3117ece4Schristos MEM_STATIC unsigned MEM_64bits(void); 49*3117ece4Schristos MEM_STATIC unsigned MEM_isLittleEndian(void); 50*3117ece4Schristos 51*3117ece4Schristos /*=== Native unaligned read/write ===*/ 52*3117ece4Schristos MEM_STATIC U16 MEM_read16(const void* memPtr); 53*3117ece4Schristos MEM_STATIC U32 MEM_read32(const void* memPtr); 54*3117ece4Schristos MEM_STATIC U64 MEM_read64(const void* memPtr); 55*3117ece4Schristos MEM_STATIC size_t MEM_readST(const void* memPtr); 56*3117ece4Schristos 57*3117ece4Schristos MEM_STATIC void MEM_write16(void* memPtr, U16 value); 58*3117ece4Schristos MEM_STATIC void MEM_write32(void* memPtr, U32 value); 59*3117ece4Schristos MEM_STATIC void MEM_write64(void* memPtr, U64 value); 60*3117ece4Schristos 61*3117ece4Schristos /*=== Little endian unaligned read/write ===*/ 62*3117ece4Schristos MEM_STATIC U16 MEM_readLE16(const void* memPtr); 63*3117ece4Schristos MEM_STATIC U32 MEM_readLE24(const void* memPtr); 64*3117ece4Schristos MEM_STATIC U32 MEM_readLE32(const void* memPtr); 65*3117ece4Schristos MEM_STATIC U64 MEM_readLE64(const void* memPtr); 66*3117ece4Schristos MEM_STATIC size_t MEM_readLEST(const void* memPtr); 67*3117ece4Schristos 68*3117ece4Schristos MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val); 69*3117ece4Schristos MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val); 70*3117ece4Schristos MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32); 71*3117ece4Schristos MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64); 72*3117ece4Schristos MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val); 73*3117ece4Schristos 74*3117ece4Schristos /*=== Big endian unaligned read/write ===*/ 75*3117ece4Schristos MEM_STATIC U32 MEM_readBE32(const void* memPtr); 76*3117ece4Schristos MEM_STATIC U64 MEM_readBE64(const void* memPtr); 77*3117ece4Schristos MEM_STATIC size_t MEM_readBEST(const void* memPtr); 78*3117ece4Schristos 79*3117ece4Schristos MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32); 80*3117ece4Schristos MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64); 81*3117ece4Schristos MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val); 82*3117ece4Schristos 83*3117ece4Schristos /*=== Byteswap ===*/ 84*3117ece4Schristos MEM_STATIC U32 MEM_swap32(U32 in); 85*3117ece4Schristos MEM_STATIC U64 MEM_swap64(U64 in); 86*3117ece4Schristos MEM_STATIC size_t MEM_swapST(size_t in); 87*3117ece4Schristos 88*3117ece4Schristos /*-************************************************************** 89*3117ece4Schristos * Memory I/O Implementation 90*3117ece4Schristos *****************************************************************/ 91*3117ece4Schristos MEM_STATIC unsigned MEM_32bits(void) 92*3117ece4Schristos { 93*3117ece4Schristos return sizeof(size_t) == 4; 94*3117ece4Schristos } 95*3117ece4Schristos 96*3117ece4Schristos MEM_STATIC unsigned MEM_64bits(void) 97*3117ece4Schristos { 98*3117ece4Schristos return sizeof(size_t) == 8; 99*3117ece4Schristos } 100*3117ece4Schristos 101*3117ece4Schristos #if defined(__LITTLE_ENDIAN) 102*3117ece4Schristos #define MEM_LITTLE_ENDIAN 1 103*3117ece4Schristos #else 104*3117ece4Schristos #define MEM_LITTLE_ENDIAN 0 105*3117ece4Schristos #endif 106*3117ece4Schristos 107*3117ece4Schristos MEM_STATIC unsigned MEM_isLittleEndian(void) 108*3117ece4Schristos { 109*3117ece4Schristos return MEM_LITTLE_ENDIAN; 110*3117ece4Schristos } 111*3117ece4Schristos 112*3117ece4Schristos MEM_STATIC U16 MEM_read16(const void *memPtr) 113*3117ece4Schristos { 114*3117ece4Schristos return get_unaligned((const U16 *)memPtr); 115*3117ece4Schristos } 116*3117ece4Schristos 117*3117ece4Schristos MEM_STATIC U32 MEM_read32(const void *memPtr) 118*3117ece4Schristos { 119*3117ece4Schristos return get_unaligned((const U32 *)memPtr); 120*3117ece4Schristos } 121*3117ece4Schristos 122*3117ece4Schristos MEM_STATIC U64 MEM_read64(const void *memPtr) 123*3117ece4Schristos { 124*3117ece4Schristos return get_unaligned((const U64 *)memPtr); 125*3117ece4Schristos } 126*3117ece4Schristos 127*3117ece4Schristos MEM_STATIC size_t MEM_readST(const void *memPtr) 128*3117ece4Schristos { 129*3117ece4Schristos return get_unaligned((const size_t *)memPtr); 130*3117ece4Schristos } 131*3117ece4Schristos 132*3117ece4Schristos MEM_STATIC void MEM_write16(void *memPtr, U16 value) 133*3117ece4Schristos { 134*3117ece4Schristos put_unaligned(value, (U16 *)memPtr); 135*3117ece4Schristos } 136*3117ece4Schristos 137*3117ece4Schristos MEM_STATIC void MEM_write32(void *memPtr, U32 value) 138*3117ece4Schristos { 139*3117ece4Schristos put_unaligned(value, (U32 *)memPtr); 140*3117ece4Schristos } 141*3117ece4Schristos 142*3117ece4Schristos MEM_STATIC void MEM_write64(void *memPtr, U64 value) 143*3117ece4Schristos { 144*3117ece4Schristos put_unaligned(value, (U64 *)memPtr); 145*3117ece4Schristos } 146*3117ece4Schristos 147*3117ece4Schristos /*=== Little endian r/w ===*/ 148*3117ece4Schristos 149*3117ece4Schristos MEM_STATIC U16 MEM_readLE16(const void *memPtr) 150*3117ece4Schristos { 151*3117ece4Schristos return get_unaligned_le16(memPtr); 152*3117ece4Schristos } 153*3117ece4Schristos 154*3117ece4Schristos MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val) 155*3117ece4Schristos { 156*3117ece4Schristos put_unaligned_le16(val, memPtr); 157*3117ece4Schristos } 158*3117ece4Schristos 159*3117ece4Schristos MEM_STATIC U32 MEM_readLE24(const void *memPtr) 160*3117ece4Schristos { 161*3117ece4Schristos return MEM_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16); 162*3117ece4Schristos } 163*3117ece4Schristos 164*3117ece4Schristos MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val) 165*3117ece4Schristos { 166*3117ece4Schristos MEM_writeLE16(memPtr, (U16)val); 167*3117ece4Schristos ((BYTE *)memPtr)[2] = (BYTE)(val >> 16); 168*3117ece4Schristos } 169*3117ece4Schristos 170*3117ece4Schristos MEM_STATIC U32 MEM_readLE32(const void *memPtr) 171*3117ece4Schristos { 172*3117ece4Schristos return get_unaligned_le32(memPtr); 173*3117ece4Schristos } 174*3117ece4Schristos 175*3117ece4Schristos MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32) 176*3117ece4Schristos { 177*3117ece4Schristos put_unaligned_le32(val32, memPtr); 178*3117ece4Schristos } 179*3117ece4Schristos 180*3117ece4Schristos MEM_STATIC U64 MEM_readLE64(const void *memPtr) 181*3117ece4Schristos { 182*3117ece4Schristos return get_unaligned_le64(memPtr); 183*3117ece4Schristos } 184*3117ece4Schristos 185*3117ece4Schristos MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64) 186*3117ece4Schristos { 187*3117ece4Schristos put_unaligned_le64(val64, memPtr); 188*3117ece4Schristos } 189*3117ece4Schristos 190*3117ece4Schristos MEM_STATIC size_t MEM_readLEST(const void *memPtr) 191*3117ece4Schristos { 192*3117ece4Schristos if (MEM_32bits()) 193*3117ece4Schristos return (size_t)MEM_readLE32(memPtr); 194*3117ece4Schristos else 195*3117ece4Schristos return (size_t)MEM_readLE64(memPtr); 196*3117ece4Schristos } 197*3117ece4Schristos 198*3117ece4Schristos MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val) 199*3117ece4Schristos { 200*3117ece4Schristos if (MEM_32bits()) 201*3117ece4Schristos MEM_writeLE32(memPtr, (U32)val); 202*3117ece4Schristos else 203*3117ece4Schristos MEM_writeLE64(memPtr, (U64)val); 204*3117ece4Schristos } 205*3117ece4Schristos 206*3117ece4Schristos /*=== Big endian r/w ===*/ 207*3117ece4Schristos 208*3117ece4Schristos MEM_STATIC U32 MEM_readBE32(const void *memPtr) 209*3117ece4Schristos { 210*3117ece4Schristos return get_unaligned_be32(memPtr); 211*3117ece4Schristos } 212*3117ece4Schristos 213*3117ece4Schristos MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32) 214*3117ece4Schristos { 215*3117ece4Schristos put_unaligned_be32(val32, memPtr); 216*3117ece4Schristos } 217*3117ece4Schristos 218*3117ece4Schristos MEM_STATIC U64 MEM_readBE64(const void *memPtr) 219*3117ece4Schristos { 220*3117ece4Schristos return get_unaligned_be64(memPtr); 221*3117ece4Schristos } 222*3117ece4Schristos 223*3117ece4Schristos MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64) 224*3117ece4Schristos { 225*3117ece4Schristos put_unaligned_be64(val64, memPtr); 226*3117ece4Schristos } 227*3117ece4Schristos 228*3117ece4Schristos MEM_STATIC size_t MEM_readBEST(const void *memPtr) 229*3117ece4Schristos { 230*3117ece4Schristos if (MEM_32bits()) 231*3117ece4Schristos return (size_t)MEM_readBE32(memPtr); 232*3117ece4Schristos else 233*3117ece4Schristos return (size_t)MEM_readBE64(memPtr); 234*3117ece4Schristos } 235*3117ece4Schristos 236*3117ece4Schristos MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val) 237*3117ece4Schristos { 238*3117ece4Schristos if (MEM_32bits()) 239*3117ece4Schristos MEM_writeBE32(memPtr, (U32)val); 240*3117ece4Schristos else 241*3117ece4Schristos MEM_writeBE64(memPtr, (U64)val); 242*3117ece4Schristos } 243*3117ece4Schristos 244*3117ece4Schristos MEM_STATIC U32 MEM_swap32(U32 in) 245*3117ece4Schristos { 246*3117ece4Schristos return swab32(in); 247*3117ece4Schristos } 248*3117ece4Schristos 249*3117ece4Schristos MEM_STATIC U64 MEM_swap64(U64 in) 250*3117ece4Schristos { 251*3117ece4Schristos return swab64(in); 252*3117ece4Schristos } 253*3117ece4Schristos 254*3117ece4Schristos MEM_STATIC size_t MEM_swapST(size_t in) 255*3117ece4Schristos { 256*3117ece4Schristos if (MEM_32bits()) 257*3117ece4Schristos return (size_t)MEM_swap32((U32)in); 258*3117ece4Schristos else 259*3117ece4Schristos return (size_t)MEM_swap64((U64)in); 260*3117ece4Schristos } 261*3117ece4Schristos 262*3117ece4Schristos #endif /* MEM_H_MODULE */ 263