]> git.sur5r.net Git - u-boot/blob - drivers/net/npe/IxOsalIoMem.c
087fdf3ba1f19b6a31e829c01b65ad4c12f4e2b7
[u-boot] / 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  * 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
46 /* Access to the global mem map is only allowed in this file */
47 #define IxOsalIoMem_C
48
49 #include "IxOsal.h"
50
51 #define SEARCH_PHYSICAL_ADDRESS (1)
52 #define SEARCH_VIRTUAL_ADDRESS  (2)
53
54 /*
55  * Searches for map using one of the following criteria:
56  * 
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)
59  * - correct coherency
60  *
61  * Returns a pointer to the map or NULL if a suitable map is not found.
62  */
63 PRIVATE IxOsalMemoryMap *
64 ixOsalMemMapFind (UINT32 requestedAddress,
65     UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
66 {
67     UINT32 mapIndex;
68
69     UINT32 numMapElements = ARRAY_SIZE(ixOsalGlobalMemoryMap);
70
71     for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
72     {
73         IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
74
75         if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
76             && requestedAddress >= map->physicalAddress
77             && (requestedAddress + size) <= (map->physicalAddress + map->size)
78             && (map->mapEndianType & requestedEndianType) != 0)
79         {
80             return map;
81         }
82         else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
83             && requestedAddress >= map->virtualAddress
84             && requestedAddress <= (map->virtualAddress + map->size)
85             && (map->mapEndianType & requestedEndianType) != 0)
86         {
87             return map;
88         }
89         else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
90         {
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);
95         }
96     }
97
98     /*
99      * not found 
100      */
101     return NULL;
102 }
103
104 /*
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 
109  * virtual address.
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 
112  * parameter.
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.
115  *
116  * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP 
117  * instead.
118  */
119 PUBLIC void *
120 ixOsalIoMemMap (UINT32 requestedAddress,
121     UINT32 size, IxOsalMapEndianessType requestedEndianType)
122 {
123     IxOsalMemoryMap *map;
124
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);
129
130     if (requestedEndianType == IX_OSAL_LE)
131     {
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",
135             0, 0, 0, 0, 0, 0);
136         return (NULL);
137     }
138     map = ixOsalMemMapFind (requestedAddress,
139         size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
140     if (map != NULL)
141     {
142         UINT32 offset = requestedAddress - map->physicalAddress;
143
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);
153
154         if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
155         {
156             if (map->mapFunction != NULL)
157             {
158                 map->mapFunction (map);
159
160                 if (map->virtualAddress == 0)
161                 {
162                     /*
163                      * failed 
164                      */
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);
169                     return NULL;
170                 }
171             }
172             else
173             {
174                 /*
175                  * error, no map function for a dynamic map 
176                  */
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);
182
183                 return NULL;
184             }
185         }
186
187         /*
188          * increment reference count 
189          */
190         map->refCount++;
191
192         return (void *) (map->virtualAddress + offset);
193     }
194
195     /*
196      * requested address is not described in the global memory map 
197      */
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);
202     return NULL;
203 }
204
205 /*
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
209  * discarded.
210  *
211  * This function cannot fail if the given parameter is correct and does not
212  * return a value.
213  *
214  * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
215  * instead.
216  */
217 PUBLIC void
218 ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
219 {
220     IxOsalMemoryMap *map;
221
222     if (endianType == IX_OSAL_LE)
223     {
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",
227             0, 0, 0, 0, 0, 0);
228         return;
229     }
230
231     if (requestedAddress == 0)
232     {
233         /*
234          * invalid virtual address 
235          */
236         return;
237     }
238
239     map =
240         ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
241         endianType);
242
243     if (map != NULL)
244     {
245         if (map->refCount > 0)
246         {
247             /*
248              * decrement reference count 
249              */
250             map->refCount--;
251
252             if (map->refCount == 0)
253             {
254                 /*
255                  * no longer used, deallocate 
256                  */
257                 if (map->type == IX_OSAL_DYNAMIC_MAP
258                     && map->unmapFunction != NULL)
259                 {
260                     map->unmapFunction (map);
261                 }
262             }
263         }
264     }
265     else
266     {
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);
272     }
273 }
274
275 /* 
276  * This function Converts a virtual address into a physical 
277  * address, including the dynamically mapped memory.
278  * 
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
284  * Reentrant: Yes
285  * IRQ safe: Yes
286  */
287 PUBLIC UINT32
288 ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
289 {
290     IxOsalMemoryMap *map =
291         ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
292         requestedCoherency);
293
294     if (map != NULL)
295     {
296         return map->physicalAddress + virtualAddress - map->virtualAddress;
297     }
298     else
299     {
300         return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
301     }
302 }
303
304 /* 
305  * This function Converts a virtual address into a physical 
306  * address, including the dynamically mapped memory.
307  * 
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
313  * Reentrant: Yes
314  * IRQ safe: Yes
315  */
316 PUBLIC UINT32
317 ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
318 {
319     IxOsalMemoryMap *map =
320         ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
321         requestedCoherency);
322
323     if (map != NULL)
324     {
325         return map->virtualAddress + physicalAddress - map->physicalAddress;
326     }
327     else
328     {
329         return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
330     }
331 }