IxOsalIoMem.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /**
  2. * @file IxOsalIoMem.c
  3. *
  4. * @brief OS-independent IO/Mem implementation
  5. *
  6. *
  7. * @par
  8. * IXP400 SW Release version 2.0
  9. *
  10. * -- Copyright Notice --
  11. *
  12. * @par
  13. * Copyright 2001-2005, Intel Corporation.
  14. * All rights reserved.
  15. *
  16. * @par
  17. * SPDX-License-Identifier: BSD-3-Clause
  18. * @par
  19. * -- End of Copyright Notice --
  20. */
  21. /* Access to the global mem map is only allowed in this file */
  22. #define IxOsalIoMem_C
  23. #include "IxOsal.h"
  24. #define SEARCH_PHYSICAL_ADDRESS (1)
  25. #define SEARCH_VIRTUAL_ADDRESS (2)
  26. /*
  27. * Searches for map using one of the following criteria:
  28. *
  29. * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
  30. * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
  31. * - correct coherency
  32. *
  33. * Returns a pointer to the map or NULL if a suitable map is not found.
  34. */
  35. PRIVATE IxOsalMemoryMap *
  36. ixOsalMemMapFind (UINT32 requestedAddress,
  37. UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
  38. {
  39. UINT32 mapIndex;
  40. UINT32 numMapElements = ARRAY_SIZE(ixOsalGlobalMemoryMap);
  41. for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
  42. {
  43. IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
  44. if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
  45. && requestedAddress >= map->physicalAddress
  46. && (requestedAddress + size) <= (map->physicalAddress + map->size)
  47. && (map->mapEndianType & requestedEndianType) != 0)
  48. {
  49. return map;
  50. }
  51. else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
  52. && requestedAddress >= map->virtualAddress
  53. && requestedAddress <= (map->virtualAddress + map->size)
  54. && (map->mapEndianType & requestedEndianType) != 0)
  55. {
  56. return map;
  57. }
  58. else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
  59. {
  60. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  61. IX_OSAL_LOG_DEV_STDOUT,
  62. "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
  63. map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
  64. }
  65. }
  66. /*
  67. * not found
  68. */
  69. return NULL;
  70. }
  71. /*
  72. * This function maps an I/O mapped physical memory zone of the given size
  73. * into a virtual memory zone accessible by the caller and returns a cookie -
  74. * the start address of the virtual memory zone.
  75. * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
  76. * virtual address.
  77. * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
  78. * finished using this zone (e.g. on driver unload) using the cookie as
  79. * parameter.
  80. * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
  81. * the mapped memory, adding the necessary offsets to the address cookie.
  82. *
  83. * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP
  84. * instead.
  85. */
  86. PUBLIC void *
  87. ixOsalIoMemMap (UINT32 requestedAddress,
  88. UINT32 size, IxOsalMapEndianessType requestedEndianType)
  89. {
  90. IxOsalMemoryMap *map;
  91. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  92. IX_OSAL_LOG_DEV_STDOUT,
  93. "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
  94. requestedAddress, size, requestedEndianType, 0, 0, 0);
  95. if (requestedEndianType == IX_OSAL_LE)
  96. {
  97. ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
  98. IX_OSAL_LOG_DEV_STDOUT,
  99. "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
  100. 0, 0, 0, 0, 0, 0);
  101. return (NULL);
  102. }
  103. map = ixOsalMemMapFind (requestedAddress,
  104. size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
  105. if (map != NULL)
  106. {
  107. UINT32 offset = requestedAddress - map->physicalAddress;
  108. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  109. IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
  110. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  111. IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
  112. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  113. IX_OSAL_LOG_DEV_STDOUT,
  114. ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
  115. map->physicalAddress, map->virtualAddress,
  116. map->size, map->refCount, map->mapEndianType, 0);
  117. if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
  118. {
  119. if (map->mapFunction != NULL)
  120. {
  121. map->mapFunction (map);
  122. if (map->virtualAddress == 0)
  123. {
  124. /*
  125. * failed
  126. */
  127. ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
  128. IX_OSAL_LOG_DEV_STDERR,
  129. "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
  130. requestedAddress, size, requestedEndianType, 0, 0, 0);
  131. return NULL;
  132. }
  133. }
  134. else
  135. {
  136. /*
  137. * error, no map function for a dynamic map
  138. */
  139. ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
  140. IX_OSAL_LOG_DEV_STDERR,
  141. "OSAL: No map function for a dynamic map - "
  142. "[addr 0x%x:size 0x%x:endianType %d]\n",
  143. requestedAddress, size, requestedEndianType, 0, 0, 0);
  144. return NULL;
  145. }
  146. }
  147. /*
  148. * increment reference count
  149. */
  150. map->refCount++;
  151. return (void *) (map->virtualAddress + offset);
  152. }
  153. /*
  154. * requested address is not described in the global memory map
  155. */
  156. ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
  157. IX_OSAL_LOG_DEV_STDERR,
  158. "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
  159. requestedAddress, size, requestedEndianType, 0, 0, 0);
  160. return NULL;
  161. }
  162. /*
  163. * This function unmaps a previously mapped I/O memory zone using
  164. * the cookie obtained in the mapping operation. The memory zone in question
  165. * becomes unavailable to the caller once unmapped and the cookie should be
  166. * discarded.
  167. *
  168. * This function cannot fail if the given parameter is correct and does not
  169. * return a value.
  170. *
  171. * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
  172. * instead.
  173. */
  174. PUBLIC void
  175. ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
  176. {
  177. IxOsalMemoryMap *map;
  178. if (endianType == IX_OSAL_LE)
  179. {
  180. ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
  181. IX_OSAL_LOG_DEV_STDOUT,
  182. "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
  183. 0, 0, 0, 0, 0, 0);
  184. return;
  185. }
  186. if (requestedAddress == 0)
  187. {
  188. /*
  189. * invalid virtual address
  190. */
  191. return;
  192. }
  193. map =
  194. ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
  195. endianType);
  196. if (map != NULL)
  197. {
  198. if (map->refCount > 0)
  199. {
  200. /*
  201. * decrement reference count
  202. */
  203. map->refCount--;
  204. if (map->refCount == 0)
  205. {
  206. /*
  207. * no longer used, deallocate
  208. */
  209. if (map->type == IX_OSAL_DYNAMIC_MAP
  210. && map->unmapFunction != NULL)
  211. {
  212. map->unmapFunction (map);
  213. }
  214. }
  215. }
  216. }
  217. else
  218. {
  219. ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
  220. IX_OSAL_LOG_DEV_STDERR,
  221. "OSAL: ixOsServMemUnmap didn't find the requested map "
  222. "[virt addr 0x%x: endianType %d], ignoring call\n",
  223. requestedAddress, endianType, 0, 0, 0, 0);
  224. }
  225. }
  226. /*
  227. * This function Converts a virtual address into a physical
  228. * address, including the dynamically mapped memory.
  229. *
  230. * Parameters virtAddr - virtual address to convert
  231. * Return value: corresponding physical address, or NULL
  232. * if there is no physical address addressable
  233. * by the given virtual address
  234. * OS: VxWorks, Linux, WinCE, QNX, eCos
  235. * Reentrant: Yes
  236. * IRQ safe: Yes
  237. */
  238. PUBLIC UINT32
  239. ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
  240. {
  241. IxOsalMemoryMap *map =
  242. ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
  243. requestedCoherency);
  244. if (map != NULL)
  245. {
  246. return map->physicalAddress + virtualAddress - map->virtualAddress;
  247. }
  248. else
  249. {
  250. return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
  251. }
  252. }
  253. /*
  254. * This function Converts a virtual address into a physical
  255. * address, including the dynamically mapped memory.
  256. *
  257. * Parameters virtAddr - virtual address to convert
  258. * Return value: corresponding physical address, or NULL
  259. * if there is no physical address addressable
  260. * by the given virtual address
  261. * OS: VxWorks, Linux, WinCE, QNX, eCos
  262. * Reentrant: Yes
  263. * IRQ safe: Yes
  264. */
  265. PUBLIC UINT32
  266. ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
  267. {
  268. IxOsalMemoryMap *map =
  269. ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
  270. requestedCoherency);
  271. if (map != NULL)
  272. {
  273. return map->virtualAddress + physicalAddress - map->physicalAddress;
  274. }
  275. else
  276. {
  277. return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
  278. }
  279. }