IxOsalIoMem.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. * Redistribution and use in source and binary forms, with or without
  18. * modification, are permitted provided that the following conditions
  19. * are met:
  20. * 1. Redistributions of source code must retain the above copyright
  21. * notice, this list of conditions and the following disclaimer.
  22. * 2. Redistributions in binary form must reproduce the above copyright
  23. * notice, this list of conditions and the following disclaimer in the
  24. * documentation and/or other materials provided with the distribution.
  25. * 3. Neither the name of the Intel Corporation nor the names of its contributors
  26. * may be used to endorse or promote products derived from this software
  27. * without specific prior written permission.
  28. *
  29. * @par
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
  31. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  34. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  38. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  39. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  40. * SUCH DAMAGE.
  41. *
  42. * @par
  43. * -- End of Copyright Notice --
  44. */
  45. /* Access to the global mem map is only allowed in this file */
  46. #define IxOsalIoMem_C
  47. #include "IxOsal.h"
  48. #define SEARCH_PHYSICAL_ADDRESS (1)
  49. #define SEARCH_VIRTUAL_ADDRESS (2)
  50. /*
  51. * Searches for map using one of the following criteria:
  52. *
  53. * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
  54. * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
  55. * - correct coherency
  56. *
  57. * Returns a pointer to the map or NULL if a suitable map is not found.
  58. */
  59. PRIVATE IxOsalMemoryMap *
  60. ixOsalMemMapFind (UINT32 requestedAddress,
  61. UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
  62. {
  63. UINT32 mapIndex;
  64. UINT32 numMapElements =
  65. sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap);
  66. for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
  67. {
  68. IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
  69. if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
  70. && requestedAddress >= map->physicalAddress
  71. && (requestedAddress + size) <= (map->physicalAddress + map->size)
  72. && (map->mapEndianType & requestedEndianType) != 0)
  73. {
  74. return map;
  75. }
  76. else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
  77. && requestedAddress >= map->virtualAddress
  78. && requestedAddress <= (map->virtualAddress + map->size)
  79. && (map->mapEndianType & requestedEndianType) != 0)
  80. {
  81. return map;
  82. }
  83. else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
  84. {
  85. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  86. IX_OSAL_LOG_DEV_STDOUT,
  87. "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
  88. map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
  89. }
  90. }
  91. /*
  92. * not found
  93. */
  94. return NULL;
  95. }
  96. /*
  97. * This function maps an I/O mapped physical memory zone of the given size
  98. * into a virtual memory zone accessible by the caller and returns a cookie -
  99. * the start address of the virtual memory zone.
  100. * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
  101. * virtual address.
  102. * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
  103. * finished using this zone (e.g. on driver unload) using the cookie as
  104. * parameter.
  105. * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
  106. * the mapped memory, adding the necessary offsets to the address cookie.
  107. *
  108. * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP
  109. * instead.
  110. */
  111. PUBLIC void *
  112. ixOsalIoMemMap (UINT32 requestedAddress,
  113. UINT32 size, IxOsalMapEndianessType requestedEndianType)
  114. {
  115. IxOsalMemoryMap *map;
  116. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  117. IX_OSAL_LOG_DEV_STDOUT,
  118. "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
  119. requestedAddress, size, requestedEndianType, 0, 0, 0);
  120. if (requestedEndianType == IX_OSAL_LE)
  121. {
  122. ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
  123. IX_OSAL_LOG_DEV_STDOUT,
  124. "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
  125. 0, 0, 0, 0, 0, 0);
  126. return (NULL);
  127. }
  128. map = ixOsalMemMapFind (requestedAddress,
  129. size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
  130. if (map != NULL)
  131. {
  132. UINT32 offset = requestedAddress - map->physicalAddress;
  133. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  134. IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
  135. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  136. IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
  137. ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
  138. IX_OSAL_LOG_DEV_STDOUT,
  139. ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
  140. map->physicalAddress, map->virtualAddress,
  141. map->size, map->refCount, map->mapEndianType, 0);
  142. if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
  143. {
  144. if (map->mapFunction != NULL)
  145. {
  146. map->mapFunction (map);
  147. if (map->virtualAddress == 0)
  148. {
  149. /*
  150. * failed
  151. */
  152. ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
  153. IX_OSAL_LOG_DEV_STDERR,
  154. "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
  155. requestedAddress, size, requestedEndianType, 0, 0, 0);
  156. return NULL;
  157. }
  158. }
  159. else
  160. {
  161. /*
  162. * error, no map function for a dynamic map
  163. */
  164. ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
  165. IX_OSAL_LOG_DEV_STDERR,
  166. "OSAL: No map function for a dynamic map - "
  167. "[addr 0x%x:size 0x%x:endianType %d]\n",
  168. requestedAddress, size, requestedEndianType, 0, 0, 0);
  169. return NULL;
  170. }
  171. }
  172. /*
  173. * increment reference count
  174. */
  175. map->refCount++;
  176. return (void *) (map->virtualAddress + offset);
  177. }
  178. /*
  179. * requested address is not described in the global memory map
  180. */
  181. ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
  182. IX_OSAL_LOG_DEV_STDERR,
  183. "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
  184. requestedAddress, size, requestedEndianType, 0, 0, 0);
  185. return NULL;
  186. }
  187. /*
  188. * This function unmaps a previously mapped I/O memory zone using
  189. * the cookie obtained in the mapping operation. The memory zone in question
  190. * becomes unavailable to the caller once unmapped and the cookie should be
  191. * discarded.
  192. *
  193. * This function cannot fail if the given parameter is correct and does not
  194. * return a value.
  195. *
  196. * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
  197. * instead.
  198. */
  199. PUBLIC void
  200. ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
  201. {
  202. IxOsalMemoryMap *map;
  203. if (endianType == IX_OSAL_LE)
  204. {
  205. ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
  206. IX_OSAL_LOG_DEV_STDOUT,
  207. "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
  208. 0, 0, 0, 0, 0, 0);
  209. return;
  210. }
  211. if (requestedAddress == 0)
  212. {
  213. /*
  214. * invalid virtual address
  215. */
  216. return;
  217. }
  218. map =
  219. ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
  220. endianType);
  221. if (map != NULL)
  222. {
  223. if (map->refCount > 0)
  224. {
  225. /*
  226. * decrement reference count
  227. */
  228. map->refCount--;
  229. if (map->refCount == 0)
  230. {
  231. /*
  232. * no longer used, deallocate
  233. */
  234. if (map->type == IX_OSAL_DYNAMIC_MAP
  235. && map->unmapFunction != NULL)
  236. {
  237. map->unmapFunction (map);
  238. }
  239. }
  240. }
  241. }
  242. else
  243. {
  244. ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
  245. IX_OSAL_LOG_DEV_STDERR,
  246. "OSAL: ixOsServMemUnmap didn't find the requested map "
  247. "[virt addr 0x%x: endianType %d], ignoring call\n",
  248. requestedAddress, endianType, 0, 0, 0, 0);
  249. }
  250. }
  251. /*
  252. * This function Converts a virtual address into a physical
  253. * address, including the dynamically mapped memory.
  254. *
  255. * Parameters virtAddr - virtual address to convert
  256. * Return value: corresponding physical address, or NULL
  257. * if there is no physical address addressable
  258. * by the given virtual address
  259. * OS: VxWorks, Linux, WinCE, QNX, eCos
  260. * Reentrant: Yes
  261. * IRQ safe: Yes
  262. */
  263. PUBLIC UINT32
  264. ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
  265. {
  266. IxOsalMemoryMap *map =
  267. ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
  268. requestedCoherency);
  269. if (map != NULL)
  270. {
  271. return map->physicalAddress + virtualAddress - map->virtualAddress;
  272. }
  273. else
  274. {
  275. return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
  276. }
  277. }
  278. /*
  279. * This function Converts a virtual address into a physical
  280. * address, including the dynamically mapped memory.
  281. *
  282. * Parameters virtAddr - virtual address to convert
  283. * Return value: corresponding physical address, or NULL
  284. * if there is no physical address addressable
  285. * by the given virtual address
  286. * OS: VxWorks, Linux, WinCE, QNX, eCos
  287. * Reentrant: Yes
  288. * IRQ safe: Yes
  289. */
  290. PUBLIC UINT32
  291. ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
  292. {
  293. IxOsalMemoryMap *map =
  294. ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
  295. requestedCoherency);
  296. if (map != NULL)
  297. {
  298. return map->virtualAddress + physicalAddress - map->physicalAddress;
  299. }
  300. else
  301. {
  302. return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
  303. }
  304. }