source: SVN/cambria/redboot/packages/devs/eth/intel/npe/common/current/src/IxOsalIoMem.c @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

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

File size: 10.3 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 * -- Intel Copyright Notice --
11 *
12 * @par
13 * Copyright 2002-2004 Intel Corporation All Rights Reserved.
14 *
15 * @par
16 * The source code contained or described herein and all documents
17 * related to the source code ("Material") are owned by Intel Corporation
18 * or its suppliers or licensors.  Title to the Material remains with
19 * Intel Corporation or its suppliers and licensors.
20 *
21 * @par
22 * The Material is protected by worldwide copyright and trade secret laws
23 * and treaty provisions. No part of the Material may be used, copied,
24 * reproduced, modified, published, uploaded, posted, transmitted,
25 * distributed, or disclosed in any way except in accordance with the
26 * applicable license agreement .
27 *
28 * @par
29 * No license under any patent, copyright, trade secret or other
30 * intellectual property right is granted to or conferred upon you by
31 * disclosure or delivery of the Materials, either expressly, by
32 * implication, inducement, estoppel, except in accordance with the
33 * applicable license agreement.
34 *
35 * @par
36 * Unless otherwise agreed by Intel in writing, you may not remove or
37 * alter this notice or any other notice embedded in Materials by Intel
38 * or Intel's suppliers or licensors in any way.
39 *
40 * @par
41 * For further details, please see the file README.TXT distributed with
42 * this software.
43 *
44 * @par
45 * -- End Intel Copyright Notice --
46 */
47
48/* Access to the global mem map is only allowed in this file */
49#define IxOsalIoMem_C
50
51#include "IxOsal.h"
52
53#define SEARCH_PHYSICAL_ADDRESS (1)
54#define SEARCH_VIRTUAL_ADDRESS  (2)
55
56/*
57 * Searches for map using one of the following criteria:
58 *
59 * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
60 * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
61 * - correct coherency
62 *
63 * Returns a pointer to the map or NULL if a suitable map is not found.
64 */
65PRIVATE IxOsalMemoryMap *
66ixOsalMemMapFind (UINT32 requestedAddress,
67    UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
68{
69    UINT32 mapIndex;
70
71    UINT32 numMapElements =
72        sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap);
73
74    for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
75    {
76        IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
77
78        if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
79            && requestedAddress >= map->physicalAddress
80            && (requestedAddress + size) <= (map->physicalAddress + map->size)
81            && (map->mapEndianType & requestedEndianType) != 0)
82        {
83            return map;
84        }
85        else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
86            && requestedAddress >= map->virtualAddress
87            && requestedAddress <= (map->virtualAddress + map->size)
88            && (map->mapEndianType & requestedEndianType) != 0)
89        {
90            return map;
91        }
92        else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
93        {
94            ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
95                IX_OSAL_LOG_DEV_STDOUT,
96                "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
97                map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
98        }
99    }
100
101    /*
102     * not found
103     */
104    return NULL;
105}
106
107/*
108 * This function maps an I/O mapped physical memory zone of the given size
109 * into a virtual memory zone accessible by the caller and returns a cookie -
110 * the start address of the virtual memory zone.
111 * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned
112 * virtual address.
113 * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
114 * finished using this zone (e.g. on driver unload) using the cookie as
115 * parameter.
116 * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write
117 * the mapped memory, adding the necessary offsets to the address cookie.
118 *
119 * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP
120 * instead.
121 */
122PUBLIC void *
123ixOsalIoMemMap (UINT32 requestedAddress,
124    UINT32 size, IxOsalMapEndianessType requestedEndianType)
125{
126    IxOsalMemoryMap *map;
127
128    ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
129        IX_OSAL_LOG_DEV_STDOUT,
130        "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
131        requestedAddress, size, requestedEndianType, 0, 0, 0);
132
133    if (requestedEndianType == IX_OSAL_LE)
134    {
135        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
136            IX_OSAL_LOG_DEV_STDOUT,
137            "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
138            0, 0, 0, 0, 0, 0);
139        return (NULL);
140    }
141    map = ixOsalMemMapFind (requestedAddress,
142        size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
143    if (map != NULL)
144    {
145        UINT32 offset = requestedAddress - map->physicalAddress;
146
147        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
148            IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
149        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
150            IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
151        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
152            IX_OSAL_LOG_DEV_STDOUT,
153            ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
154            map->physicalAddress, map->virtualAddress,
155            map->size, map->refCount, map->mapEndianType, 0);
156
157        if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
158        {
159            if (map->mapFunction != NULL)
160            {
161                map->mapFunction (map);
162
163                if (map->virtualAddress == 0)
164                {
165                    /*
166                     * failed
167                     */
168                    ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
169                        IX_OSAL_LOG_DEV_STDERR,
170                        "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
171                        requestedAddress, size, requestedEndianType, 0, 0, 0);
172                    return NULL;
173                }
174            }
175            else
176            {
177                /*
178                 * error, no map function for a dynamic map
179                 */
180                ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
181                    IX_OSAL_LOG_DEV_STDERR,
182                    "OSAL: No map function for a dynamic map - "
183                    "[addr 0x%x:size 0x%x:endianType %d]\n",
184                    requestedAddress, size, requestedEndianType, 0, 0, 0);
185
186                return NULL;
187            }
188        }
189
190        /*
191         * increment reference count
192         */
193        map->refCount++;
194
195        return (void *) (map->virtualAddress + offset);
196    }
197
198    /*
199     * requested address is not described in the global memory map
200     */
201    ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
202        IX_OSAL_LOG_DEV_STDERR,
203        "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
204        requestedAddress, size, requestedEndianType, 0, 0, 0);
205    return NULL;
206}
207
208/*
209 * This function unmaps a previously mapped I/O memory zone using
210 * the cookie obtained in the mapping operation. The memory zone in question
211 * becomes unavailable to the caller once unmapped and the cookie should be
212 * discarded.
213 *
214 * This function cannot fail if the given parameter is correct and does not
215 * return a value.
216 *
217 * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
218 * instead.
219 */
220PUBLIC void
221ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
222{
223    IxOsalMemoryMap *map;
224
225    if (endianType == IX_OSAL_LE)
226    {
227        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
228            IX_OSAL_LOG_DEV_STDOUT,
229            "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
230            0, 0, 0, 0, 0, 0);
231        return;
232    }
233
234    if (requestedAddress == 0)
235    {
236        /*
237         * invalid virtual address
238         */
239        return;
240    }
241
242    map =
243        ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
244        endianType);
245
246    if (map != NULL)
247    {
248        if (map->refCount > 0)
249        {
250            /*
251             * decrement reference count
252             */
253            map->refCount--;
254
255            if (map->refCount == 0)
256            {
257                /*
258                 * no longer used, deallocate
259                 */
260                if (map->type == IX_OSAL_DYNAMIC_MAP
261                    && map->unmapFunction != NULL)
262                {
263                    map->unmapFunction (map);
264                }
265            }
266        }
267    }
268    else
269    {
270        ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
271            IX_OSAL_LOG_DEV_STDERR,
272            "OSAL: ixOsServMemUnmap didn't find the requested map "
273            "[virt addr 0x%x: endianType %d], ignoring call\n",
274            requestedAddress, endianType, 0, 0, 0, 0);
275    }
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 */
290PUBLIC UINT32
291ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
292{
293    IxOsalMemoryMap *map =
294        ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
295        requestedCoherency);
296
297    if (map != NULL)
298    {
299        return map->physicalAddress + virtualAddress - map->virtualAddress;
300    }
301    else
302    {
303        return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
304    }
305}
306
307/*
308 * This function Converts a virtual address into a physical
309 * address, including the dynamically mapped memory.
310 *
311 * Parameters   virtAddr - virtual address to convert
312 * Return value: corresponding physical address, or NULL
313 *               if there is no physical address addressable
314 *               by the given virtual address
315 * OS:  VxWorks, Linux, WinCE, QNX, eCos
316 * Reentrant: Yes
317 * IRQ safe: Yes
318 */
319PUBLIC UINT32
320ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
321{
322    IxOsalMemoryMap *map =
323        ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
324        requestedCoherency);
325
326    if (map != NULL)
327    {
328        return map->virtualAddress + physicalAddress - map->physicalAddress;
329    }
330    else
331    {
332        return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
333    }
334}
Note: See TracBrowser for help on using the repository browser.