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