source: SVN/rincon/u-boot/cpu/ixp/npe/IxOsalIoMem.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 10.6 KB
Line 
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 */
63PRIVATE IxOsalMemoryMap *
64ixOsalMemMapFind (UINT32 requestedAddress,
65    UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
66{
67    UINT32 mapIndex;
68
69    UINT32 numMapElements =
70        sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap);
71
72    for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
73    {
74        IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
75
76        if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
77            && requestedAddress >= map->physicalAddress
78            && (requestedAddress + size) <= (map->physicalAddress + map->size)
79            && (map->mapEndianType & requestedEndianType) != 0)
80        {
81            return map;
82        }
83        else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
84            && requestedAddress >= map->virtualAddress
85            && requestedAddress <= (map->virtualAddress + map->size)
86            && (map->mapEndianType & requestedEndianType) != 0)
87        {
88            return map;
89        }
90        else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
91        {
92            ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
93                IX_OSAL_LOG_DEV_STDOUT,
94                "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
95                map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
96        }
97    }
98
99    /*
100     * not found
101     */
102    return NULL;
103}
104
105/*
106 * This function maps an I/O mapped physical memory zone of the given size
107 * into a virtual memory zone accessible by the caller and returns a cookie -
108 * the start address of the virtual memory zone.
109 * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
110 * virtual address.
111 * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
112 * finished using this zone (e.g. on driver unload) using the cookie as
113 * parameter.
114 * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
115 * the mapped memory, adding the necessary offsets to the address cookie.
116 *
117 * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP
118 * instead.
119 */
120PUBLIC void *
121ixOsalIoMemMap (UINT32 requestedAddress,
122    UINT32 size, IxOsalMapEndianessType requestedEndianType)
123{
124    IxOsalMemoryMap *map;
125
126    ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
127        IX_OSAL_LOG_DEV_STDOUT,
128        "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
129        requestedAddress, size, requestedEndianType, 0, 0, 0);
130
131    if (requestedEndianType == IX_OSAL_LE)
132    {
133        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
134            IX_OSAL_LOG_DEV_STDOUT,
135            "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
136            0, 0, 0, 0, 0, 0);
137        return (NULL);
138    }
139    map = ixOsalMemMapFind (requestedAddress,
140        size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
141    if (map != NULL)
142    {
143        UINT32 offset = requestedAddress - map->physicalAddress;
144
145        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
146            IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
147        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
148            IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
149        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
150            IX_OSAL_LOG_DEV_STDOUT,
151            ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
152            map->physicalAddress, map->virtualAddress,
153            map->size, map->refCount, map->mapEndianType, 0);
154
155        if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
156        {
157            if (map->mapFunction != NULL)
158            {
159                map->mapFunction (map);
160
161                if (map->virtualAddress == 0)
162                {
163                    /*
164                     * failed
165                     */
166                    ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
167                        IX_OSAL_LOG_DEV_STDERR,
168                        "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
169                        requestedAddress, size, requestedEndianType, 0, 0, 0);
170                    return NULL;
171                }
172            }
173            else
174            {
175                /*
176                 * error, no map function for a dynamic map
177                 */
178                ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
179                    IX_OSAL_LOG_DEV_STDERR,
180                    "OSAL: No map function for a dynamic map - "
181                    "[addr 0x%x:size 0x%x:endianType %d]\n",
182                    requestedAddress, size, requestedEndianType, 0, 0, 0);
183
184                return NULL;
185            }
186        }
187
188        /*
189         * increment reference count
190         */
191        map->refCount++;
192
193        return (void *) (map->virtualAddress + offset);
194    }
195
196    /*
197     * requested address is not described in the global memory map
198     */
199    ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
200        IX_OSAL_LOG_DEV_STDERR,
201        "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
202        requestedAddress, size, requestedEndianType, 0, 0, 0);
203    return NULL;
204}
205
206/*
207 * This function unmaps a previously mapped I/O memory zone using
208 * the cookie obtained in the mapping operation. The memory zone in question
209 * becomes unavailable to the caller once unmapped and the cookie should be
210 * discarded.
211 *
212 * This function cannot fail if the given parameter is correct and does not
213 * return a value.
214 *
215 * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
216 * instead.
217 */
218PUBLIC void
219ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
220{
221    IxOsalMemoryMap *map;
222
223    if (endianType == IX_OSAL_LE)
224    {
225        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
226            IX_OSAL_LOG_DEV_STDOUT,
227            "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
228            0, 0, 0, 0, 0, 0);
229        return;
230    }
231
232    if (requestedAddress == 0)
233    {
234        /*
235         * invalid virtual address
236         */
237        return;
238    }
239
240    map =
241        ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
242        endianType);
243
244    if (map != NULL)
245    {
246        if (map->refCount > 0)
247        {
248            /*
249             * decrement reference count
250             */
251            map->refCount--;
252
253            if (map->refCount == 0)
254            {
255                /*
256                 * no longer used, deallocate
257                 */
258                if (map->type == IX_OSAL_DYNAMIC_MAP
259                    && map->unmapFunction != NULL)
260                {
261                    map->unmapFunction (map);
262                }
263            }
264        }
265    }
266    else
267    {
268        ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
269            IX_OSAL_LOG_DEV_STDERR,
270            "OSAL: ixOsServMemUnmap didn't find the requested map "
271            "[virt addr 0x%x: endianType %d], ignoring call\n",
272            requestedAddress, endianType, 0, 0, 0, 0);
273    }
274}
275
276/*
277 * This function Converts a virtual address into a physical
278 * address, including the dynamically mapped memory.
279 *
280 * Parameters   virtAddr - virtual address to convert
281 * Return value: corresponding physical address, or NULL
282 *               if there is no physical address addressable
283 *               by the given virtual address
284 * OS:  VxWorks, Linux, WinCE, QNX, eCos
285 * Reentrant: Yes
286 * IRQ safe: Yes
287 */
288PUBLIC UINT32
289ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
290{
291    IxOsalMemoryMap *map =
292        ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
293        requestedCoherency);
294
295    if (map != NULL)
296    {
297        return map->physicalAddress + virtualAddress - map->virtualAddress;
298    }
299    else
300    {
301        return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
302    }
303}
304
305/*
306 * This function Converts a virtual address into a physical
307 * address, including the dynamically mapped memory.
308 *
309 * Parameters   virtAddr - virtual address to convert
310 * Return value: corresponding physical address, or NULL
311 *               if there is no physical address addressable
312 *               by the given virtual address
313 * OS:  VxWorks, Linux, WinCE, QNX, eCos
314 * Reentrant: Yes
315 * IRQ safe: Yes
316 */
317PUBLIC UINT32
318ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
319{
320    IxOsalMemoryMap *map =
321        ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
322        requestedCoherency);
323
324    if (map != NULL)
325    {
326        return map->virtualAddress + physicalAddress - map->physicalAddress;
327    }
328    else
329    {
330        return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
331    }
332}
Note: See TracBrowser for help on using the repository browser.