4 * @brief OS-independent IO/Mem implementation
8 * IXP400 SW Release version 2.0
10 * -- Copyright Notice --
13 * Copyright 2001-2005, Intel Corporation.
14 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
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.
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
43 * -- End of Copyright Notice --
46 /* Access to the global mem map is only allowed in this file */
51 #define SEARCH_PHYSICAL_ADDRESS (1)
52 #define SEARCH_VIRTUAL_ADDRESS (2)
55 * Searches for map using one of the following criteria:
57 * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
58 * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
61 * Returns a pointer to the map or NULL if a suitable map is not found.
63 PRIVATE IxOsalMemoryMap *
64 ixOsalMemMapFind (UINT32 requestedAddress,
65 UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
69 UINT32 numMapElements = ARRAY_SIZE(ixOsalGlobalMemoryMap);
71 for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
73 IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
75 if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
76 && requestedAddress >= map->physicalAddress
77 && (requestedAddress + size) <= (map->physicalAddress + map->size)
78 && (map->mapEndianType & requestedEndianType) != 0)
82 else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
83 && requestedAddress >= map->virtualAddress
84 && requestedAddress <= (map->virtualAddress + map->size)
85 && (map->mapEndianType & requestedEndianType) != 0)
89 else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
91 ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
92 IX_OSAL_LOG_DEV_STDOUT,
93 "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
94 map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
105 * This function maps an I/O mapped physical memory zone of the given size
106 * into a virtual memory zone accessible by the caller and returns a cookie -
107 * the start address of the virtual memory zone.
108 * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
110 * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
111 * finished using this zone (e.g. on driver unload) using the cookie as
113 * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
114 * the mapped memory, adding the necessary offsets to the address cookie.
116 * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP
120 ixOsalIoMemMap (UINT32 requestedAddress,
121 UINT32 size, IxOsalMapEndianessType requestedEndianType)
123 IxOsalMemoryMap *map;
125 ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
126 IX_OSAL_LOG_DEV_STDOUT,
127 "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
128 requestedAddress, size, requestedEndianType, 0, 0, 0);
130 if (requestedEndianType == IX_OSAL_LE)
132 ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
133 IX_OSAL_LOG_DEV_STDOUT,
134 "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
138 map = ixOsalMemMapFind (requestedAddress,
139 size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
142 UINT32 offset = requestedAddress - map->physicalAddress;
144 ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
145 IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
146 ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
147 IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
148 ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
149 IX_OSAL_LOG_DEV_STDOUT,
150 ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
151 map->physicalAddress, map->virtualAddress,
152 map->size, map->refCount, map->mapEndianType, 0);
154 if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
156 if (map->mapFunction != NULL)
158 map->mapFunction (map);
160 if (map->virtualAddress == 0)
165 ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
166 IX_OSAL_LOG_DEV_STDERR,
167 "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
168 requestedAddress, size, requestedEndianType, 0, 0, 0);
175 * error, no map function for a dynamic map
177 ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
178 IX_OSAL_LOG_DEV_STDERR,
179 "OSAL: No map function for a dynamic map - "
180 "[addr 0x%x:size 0x%x:endianType %d]\n",
181 requestedAddress, size, requestedEndianType, 0, 0, 0);
188 * increment reference count
192 return (void *) (map->virtualAddress + offset);
196 * requested address is not described in the global memory map
198 ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
199 IX_OSAL_LOG_DEV_STDERR,
200 "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
201 requestedAddress, size, requestedEndianType, 0, 0, 0);
206 * This function unmaps a previously mapped I/O memory zone using
207 * the cookie obtained in the mapping operation. The memory zone in question
208 * becomes unavailable to the caller once unmapped and the cookie should be
211 * This function cannot fail if the given parameter is correct and does not
214 * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
218 ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
220 IxOsalMemoryMap *map;
222 if (endianType == IX_OSAL_LE)
224 ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
225 IX_OSAL_LOG_DEV_STDOUT,
226 "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
231 if (requestedAddress == 0)
234 * invalid virtual address
240 ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
245 if (map->refCount > 0)
248 * decrement reference count
252 if (map->refCount == 0)
255 * no longer used, deallocate
257 if (map->type == IX_OSAL_DYNAMIC_MAP
258 && map->unmapFunction != NULL)
260 map->unmapFunction (map);
267 ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
268 IX_OSAL_LOG_DEV_STDERR,
269 "OSAL: ixOsServMemUnmap didn't find the requested map "
270 "[virt addr 0x%x: endianType %d], ignoring call\n",
271 requestedAddress, endianType, 0, 0, 0, 0);
276 * This function Converts a virtual address into a physical
277 * address, including the dynamically mapped memory.
279 * Parameters virtAddr - virtual address to convert
280 * Return value: corresponding physical address, or NULL
281 * if there is no physical address addressable
282 * by the given virtual address
283 * OS: VxWorks, Linux, WinCE, QNX, eCos
288 ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
290 IxOsalMemoryMap *map =
291 ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
296 return map->physicalAddress + virtualAddress - map->virtualAddress;
300 return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
305 * This function Converts a virtual address into a physical
306 * address, including the dynamically mapped memory.
308 * Parameters virtAddr - virtual address to convert
309 * Return value: corresponding physical address, or NULL
310 * if there is no physical address addressable
311 * by the given virtual address
312 * OS: VxWorks, Linux, WinCE, QNX, eCos
317 ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
319 IxOsalMemoryMap *map =
320 ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
325 return map->virtualAddress + physicalAddress - map->physicalAddress;
329 return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);