Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 1 | /* |
| 2 | * @file IxOsalIoMem.h |
Wolfgang Denk | 53677ef | 2008-05-20 16:00:29 +0200 | [diff] [blame] | 3 | * @author Intel Corporation |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 4 | * @date 25-08-2004 |
| 5 | * |
| 6 | * @brief description goes here |
| 7 | */ |
| 8 | |
| 9 | /** |
| 10 | * @par |
| 11 | * IXP400 SW Release version 2.0 |
| 12 | * |
| 13 | * -- Copyright Notice -- |
| 14 | * |
| 15 | * @par |
| 16 | * Copyright 2001-2005, Intel Corporation. |
| 17 | * All rights reserved. |
| 18 | * |
| 19 | * @par |
Wolfgang Denk | cb3761e | 2013-07-28 22:12:47 +0200 | [diff] [blame^] | 20 | * SPDX-License-Identifier: BSD-3-Clause |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 21 | * @par |
| 22 | * -- End of Copyright Notice -- |
| 23 | */ |
| 24 | |
| 25 | #ifndef IxOsalIoMem_H |
| 26 | #define IxOsalIoMem_H |
| 27 | |
| 28 | |
| 29 | /* |
| 30 | * Decide OS and Endianess, such as IX_OSAL_VXWORKS_LE. |
| 31 | */ |
| 32 | #include "IxOsalEndianess.h" |
| 33 | |
| 34 | /** |
| 35 | * @defgroup IxOsalIoMem Osal IoMem module |
| 36 | * |
| 37 | * @brief I/O memory and endianess support. |
| 38 | * |
| 39 | * @{ |
| 40 | */ |
| 41 | |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 42 | /* Low-level conversion macros - DO NOT USE UNLESS ABSOLUTELY NEEDED */ |
| 43 | #ifndef __wince |
| 44 | |
| 45 | |
| 46 | /* |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 47 | * Private function to swap word |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 48 | */ |
| 49 | #ifdef __XSCALE__ |
| 50 | static __inline__ UINT32 |
| 51 | ixOsalCoreWordSwap (UINT32 wordIn) |
| 52 | { |
| 53 | /* |
| 54 | * Storage for the swapped word |
| 55 | */ |
| 56 | UINT32 wordOut; |
| 57 | |
| 58 | /* |
| 59 | * wordIn = A, B, C, D |
| 60 | */ |
| 61 | __asm__ (" eor r1, %1, %1, ror #16;" /* R1 = A^C, B^D, C^A, D^B */ |
| 62 | " bic r1, r1, #0x00ff0000;" /* R1 = A^C, 0 , C^A, D^B */ |
| 63 | " mov %0, %1, ror #8;" /* wordOut = D, A, B, C */ |
| 64 | " eor %0, %0, r1, lsr #8;" /* wordOut = D, C, B, A */ |
| 65 | : "=r" (wordOut): "r" (wordIn):"r1"); |
| 66 | |
| 67 | return wordOut; |
| 68 | } |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 69 | |
| 70 | #define IX_OSAL_SWAP_LONG(wData) (ixOsalCoreWordSwap(wData)) |
| 71 | #else |
| 72 | #define IX_OSAL_SWAP_LONG(wData) ((wData >> 24) | (((wData >> 16) & 0xFF) << 8) | (((wData >> 8) & 0xFF) << 16) | ((wData & 0xFF) << 24)) |
| 73 | #endif |
| 74 | |
| 75 | #else /* ndef __wince */ |
| 76 | #define IX_OSAL_SWAP_LONG(wData) ((((UINT32)wData << 24) | ((UINT32)wData >> 24)) | (((wData << 8) & 0xff0000) | ((wData >> 8) & 0xff00))) |
| 77 | #endif /* ndef __wince */ |
| 78 | |
| 79 | #define IX_OSAL_SWAP_SHORT(sData) ((sData >> 8) | ((sData & 0xFF) << 8)) |
| 80 | #define IX_OSAL_SWAP_SHORT_ADDRESS(sAddr) ((sAddr) ^ 0x2) |
| 81 | #define IX_OSAL_SWAP_BYTE_ADDRESS(bAddr) ((bAddr) ^ 0x3) |
| 82 | |
| 83 | #define IX_OSAL_BE_XSTOBUSL(wData) (wData) |
| 84 | #define IX_OSAL_BE_XSTOBUSS(sData) (sData) |
| 85 | #define IX_OSAL_BE_XSTOBUSB(bData) (bData) |
| 86 | #define IX_OSAL_BE_BUSTOXSL(wData) (wData) |
| 87 | #define IX_OSAL_BE_BUSTOXSS(sData) (sData) |
| 88 | #define IX_OSAL_BE_BUSTOXSB(bData) (bData) |
| 89 | |
| 90 | #define IX_OSAL_LE_AC_XSTOBUSL(wAddr) (wAddr) |
| 91 | #define IX_OSAL_LE_AC_XSTOBUSS(sAddr) IX_OSAL_SWAP_SHORT_ADDRESS(sAddr) |
| 92 | #define IX_OSAL_LE_AC_XSTOBUSB(bAddr) IX_OSAL_SWAP_BYTE_ADDRESS(bAddr) |
| 93 | #define IX_OSAL_LE_AC_BUSTOXSL(wAddr) (wAddr) |
| 94 | #define IX_OSAL_LE_AC_BUSTOXSS(sAddr) IX_OSAL_SWAP_SHORT_ADDRESS(sAddr) |
| 95 | #define IX_OSAL_LE_AC_BUSTOXSB(bAddr) IX_OSAL_SWAP_BYTE_ADDRESS(bAddr) |
| 96 | |
| 97 | #define IX_OSAL_LE_DC_XSTOBUSL(wData) IX_OSAL_SWAP_LONG(wData) |
| 98 | #define IX_OSAL_LE_DC_XSTOBUSS(sData) IX_OSAL_SWAP_SHORT(sData) |
| 99 | #define IX_OSAL_LE_DC_XSTOBUSB(bData) (bData) |
| 100 | #define IX_OSAL_LE_DC_BUSTOXSL(wData) IX_OSAL_SWAP_LONG(wData) |
| 101 | #define IX_OSAL_LE_DC_BUSTOXSS(sData) IX_OSAL_SWAP_SHORT(sData) |
| 102 | #define IX_OSAL_LE_DC_BUSTOXSB(bData) (bData) |
| 103 | |
| 104 | |
| 105 | /* |
| 106 | * Decide SDRAM mapping, then implement read/write |
| 107 | */ |
| 108 | #include "IxOsalMemAccess.h" |
| 109 | |
| 110 | |
| 111 | /** |
| 112 | * @ingroup IxOsalIoMem |
| 113 | * @enum IxOsalMapEntryType |
| 114 | * @brief This is an emum for OSAL I/O mem map type. |
| 115 | */ |
| 116 | typedef enum |
| 117 | { |
| 118 | IX_OSAL_STATIC_MAP = 0, /**<Set map entry type to static map */ |
| 119 | IX_OSAL_DYNAMIC_MAP /**<Set map entry type to dynamic map */ |
| 120 | } IxOsalMapEntryType; |
| 121 | |
| 122 | |
| 123 | /** |
| 124 | * @ingroup IxOsalIoMem |
| 125 | * @enum IxOsalMapEndianessType |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 126 | * @brief This is an emum for OSAL I/O mem Endianess and Coherency mode. |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 127 | */ |
| 128 | typedef enum |
| 129 | { |
| 130 | IX_OSAL_BE = 0x1, /**<Set map endian mode to Big Endian */ |
| 131 | IX_OSAL_LE_AC = 0x2, /**<Set map endian mode to Little Endian, Address Coherent */ |
| 132 | IX_OSAL_LE_DC = 0x4, /**<Set map endian mode to Little Endian, Data Coherent */ |
| 133 | IX_OSAL_LE = 0x8 /**<Set map endian mode to Little Endian without specifying coherency mode */ |
| 134 | } IxOsalMapEndianessType; |
| 135 | |
| 136 | |
| 137 | /** |
| 138 | * @struct IxOsalMemoryMap |
| 139 | * @brief IxOsalMemoryMap structure |
| 140 | */ |
| 141 | typedef struct _IxOsalMemoryMap |
| 142 | { |
| 143 | IxOsalMapEntryType type; /**< map type - IX_OSAL_STATIC_MAP or IX_OSAL_DYNAMIC_MAP */ |
| 144 | |
| 145 | UINT32 physicalAddress; /**< physical address of the memory mapped I/O zone */ |
| 146 | |
| 147 | UINT32 size; /**< size of the map */ |
| 148 | |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 149 | UINT32 virtualAddress; /**< virtual address of the zone; must be predefined |
| 150 | in the global memory map for static maps and has |
| 151 | to be NULL for dynamic maps (populated on allocation) |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 152 | */ |
| 153 | /* |
| 154 | * pointer to a map function called to map a dynamic map; |
| 155 | * will populate the virtualAddress field |
| 156 | */ |
| 157 | void (*mapFunction) (struct _IxOsalMemoryMap * map); /**< pointer to a map function called to map a dynamic map */ |
| 158 | |
| 159 | /* |
| 160 | * pointer to a map function called to unmap a dynamic map; |
| 161 | * will reset the virtualAddress field to NULL |
| 162 | */ |
| 163 | void (*unmapFunction) (struct _IxOsalMemoryMap * map); /**< pointer to a map function called to unmap a dynamic map */ |
| 164 | |
| 165 | /* |
| 166 | * reference count describing how many components share this map; |
| 167 | * actual allocation/deallocation for dynamic maps is done only |
| 168 | * between 0 <=> 1 transitions of the counter |
| 169 | */ |
| 170 | UINT32 refCount; /**< reference count describing how many components share this map */ |
| 171 | |
| 172 | /* |
| 173 | * memory endian type for the map; can be a combination of IX_OSAL_BE (Big |
| 174 | * Endian) and IX_OSAL_LE or IX_OSAL_LE_AC or IX_OSAL_LE_DC |
| 175 | * (Little Endian, Address Coherent or Data Coherent). Any combination is |
| 176 | * allowed provided it contains at most one LE flag - e.g. |
| 177 | * (IX_OSAL_BE), (IX_OSAL_LE_AC), (IX_OSAL_BE | IX_OSAL_LE_DC) are valid |
| 178 | * combinations while (IX_OSAL_BE | IX_OSAL_LE_DC | IX_OSAL_LE_AC) is not. |
| 179 | */ |
| 180 | IxOsalMapEndianessType mapEndianType; /**< memory endian type for the map */ |
| 181 | |
| 182 | char *name; /**< user-friendly name */ |
| 183 | } IxOsalMemoryMap; |
| 184 | |
| 185 | |
| 186 | |
| 187 | |
| 188 | /* Internal function to map a memory zone |
| 189 | * NOTE - This should not be called by the user. |
| 190 | * Use the macro IX_OSAL_MEM_MAP instead |
| 191 | */ |
| 192 | PUBLIC void *ixOsalIoMemMap (UINT32 requestedAddress, |
| 193 | UINT32 size, |
| 194 | IxOsalMapEndianessType requestedCoherency); |
| 195 | |
| 196 | |
| 197 | /* Internal function to unmap a memory zone mapped with ixOsalIoMemMap |
| 198 | * NOTE - This should not be called by the user. |
| 199 | * Use the macro IX_OSAL_MEM_UNMAP instead |
| 200 | */ |
| 201 | PUBLIC void ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 coherency); |
| 202 | |
| 203 | |
| 204 | /* Internal function to convert virtual address to physical address |
| 205 | * NOTE - This should not be called by the user. |
| 206 | * Use the macro IX_OSAL_MMAP_VIRT_TO_PHYS */ |
| 207 | PUBLIC UINT32 ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 coherency); |
| 208 | |
| 209 | |
| 210 | /* Internal function to convert physical address to virtual address |
| 211 | * NOTE - This should not be called by the user. |
| 212 | * Use the macro IX_OSAL_MMAP_PHYS_TO_VIRT */ |
| 213 | PUBLIC UINT32 |
| 214 | ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 coherency); |
| 215 | |
| 216 | /** |
| 217 | * @ingroup IxOsalIoMem |
| 218 | * |
| 219 | * @def IX_OSAL_MEM_MAP(physAddr, size) |
| 220 | * |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 221 | * @brief Map an I/O mapped physical memory zone to virtual zone and return virtual |
| 222 | * pointer. |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 223 | * @param physAddr - the physical address |
| 224 | * @param size - the size |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 225 | * @return start address of the virtual memory zone. |
| 226 | * |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 227 | * @note This function maps an I/O mapped physical memory zone of the given size |
| 228 | * into a virtual memory zone accessible by the caller and returns a cookie - |
| 229 | * the start address of the virtual memory zone. |
| 230 | * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned |
| 231 | * virtual address. |
| 232 | * The memory zone is to be unmapped using IX_OSAL_MEM_UNMAP once the caller has |
| 233 | * finished using this zone (e.g. on driver unload) using the cookie as |
| 234 | * parameter. |
| 235 | * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 236 | * the mapped memory, adding the necessary offsets to the address cookie. |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 237 | */ |
| 238 | #define IX_OSAL_MEM_MAP(physAddr, size) \ |
| 239 | ixOsalIoMemMap((physAddr), (size), IX_OSAL_COMPONENT_MAPPING) |
| 240 | |
| 241 | |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 242 | /** |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 243 | * @ingroup IxOsalIoMem |
| 244 | * |
| 245 | * @def IX_OSAL_MEM_UNMAP(virtAddr) |
| 246 | * |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 247 | * @brief Unmap a previously mapped I/O memory zone using virtual pointer obtained |
| 248 | * during the mapping operation. |
| 249 | * pointer. |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 250 | * @param virtAddr - the virtual pointer to the zone to be unmapped. |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 251 | * @return none |
| 252 | * |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 253 | * @note This function unmaps a previously mapped I/O memory zone using |
| 254 | * the cookie obtained in the mapping operation. The memory zone in question |
| 255 | * becomes unavailable to the caller once unmapped and the cookie should be |
| 256 | * discarded. |
| 257 | * |
| 258 | * This function cannot fail if the given parameter is correct and does not |
| 259 | * return a value. |
| 260 | */ |
| 261 | #define IX_OSAL_MEM_UNMAP(virtAddr) \ |
| 262 | ixOsalIoMemUnmap ((virtAddr), IX_OSAL_COMPONENT_MAPPING) |
| 263 | |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 264 | /** |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 265 | * @ingroup IxOsalIoMem |
| 266 | * |
| 267 | * @def IX_OSAL_MMAP_VIRT_TO_PHYS(virtAddr) |
| 268 | * |
| 269 | * @brief This function Converts a virtual address into a physical |
| 270 | * address, including the dynamically mapped memory. |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 271 | * |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 272 | * @param virtAddr - virtual address to convert |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 273 | * Return value: corresponding physical address, or NULL |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 274 | */ |
| 275 | #define IX_OSAL_MMAP_VIRT_TO_PHYS(virtAddr) \ |
| 276 | ixOsalIoMemVirtToPhys(virtAddr, IX_OSAL_COMPONENT_MAPPING) |
| 277 | |
| 278 | |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 279 | /** |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 280 | * @ingroup IxOsalIoMem |
| 281 | * |
| 282 | * @def IX_OSAL_MMAP_PHYS_TO_VIRT(physAddr) |
| 283 | * |
| 284 | * @brief This function Converts a virtual address into a physical |
| 285 | * address, including the dynamically mapped memory. |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 286 | * |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 287 | * @param physAddr - physical address to convert |
Wolfgang Denk | d945527 | 2006-05-30 15:58:20 +0200 | [diff] [blame] | 288 | * Return value: corresponding virtual address, or NULL |
| 289 | * |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 290 | */ |
| 291 | #define IX_OSAL_MMAP_PHYS_TO_VIRT(physAddr) \ |
| 292 | ixOsalIoMemPhysToVirt(physAddr, IX_OSAL_COMPONENT_MAPPING) |
| 293 | |
Wolfgang Denk | ba94a1b | 2006-05-30 15:56:48 +0200 | [diff] [blame] | 294 | /** |
| 295 | * @} IxOsalIoMem |
| 296 | */ |
| 297 | |
| 298 | #endif /* IxOsalIoMem_H */ |