* Update Intel IXP4xx support
- Add IXP4xx NPE ethernet MAC support
- Add support for Intel IXDPG425 board
- Add support for Prodrive PDNB3 board
- Add IRQ support
Patch by Stefan Roese, 23 May 2006

[This patch does not include cpu/ixp/npe/IxNpeMicrocode.c which still
 sufferes from licensing issues. Blame Intel.]
diff --git a/cpu/ixp/npe/IxOsalIoMem.c b/cpu/ixp/npe/IxOsalIoMem.c
new file mode 100644
index 0000000..9e540c1
--- /dev/null
+++ b/cpu/ixp/npe/IxOsalIoMem.c
@@ -0,0 +1,332 @@
+/**
+ * @file IxOsalIoMem.c 
+ *
+ * @brief OS-independent IO/Mem implementation 
+ * 
+ * 
+ * @par
+ * IXP400 SW Release version 2.0
+ * 
+ * -- Copyright Notice --
+ * 
+ * @par
+ * Copyright 2001-2005, Intel Corporation.
+ * All rights reserved.
+ * 
+ * @par
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Intel Corporation nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * @par
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * @par
+ * -- End of Copyright Notice --
+ */
+
+/* Access to the global mem map is only allowed in this file */
+#define IxOsalIoMem_C
+
+#include "IxOsal.h"
+
+#define SEARCH_PHYSICAL_ADDRESS (1)
+#define SEARCH_VIRTUAL_ADDRESS  (2)
+
+/*
+ * Searches for map using one of the following criteria:
+ * 
+ * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping)
+ * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping)
+ * - correct coherency
+ *
+ * Returns a pointer to the map or NULL if a suitable map is not found.
+ */
+PRIVATE IxOsalMemoryMap *
+ixOsalMemMapFind (UINT32 requestedAddress,
+    UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType)
+{
+    UINT32 mapIndex;
+
+    UINT32 numMapElements =
+        sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap);
+
+    for (mapIndex = 0; mapIndex < numMapElements; mapIndex++)
+    {
+        IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex];
+
+        if (searchCriteria == SEARCH_PHYSICAL_ADDRESS
+            && requestedAddress >= map->physicalAddress
+            && (requestedAddress + size) <= (map->physicalAddress + map->size)
+            && (map->mapEndianType & requestedEndianType) != 0)
+        {
+            return map;
+        }
+        else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS
+            && requestedAddress >= map->virtualAddress
+            && requestedAddress <= (map->virtualAddress + map->size)
+            && (map->mapEndianType & requestedEndianType) != 0)
+        {
+            return map;
+        }
+        else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS)
+        {
+            ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+                IX_OSAL_LOG_DEV_STDOUT,
+                "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n",
+                map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0);
+        }
+    }
+
+    /*
+     * not found 
+     */
+    return NULL;
+}
+
+/*
+ * This function maps an I/O mapped physical memory zone of the given size
+ * into a virtual memory zone accessible by the caller and returns a cookie - 
+ * the start address of the virtual memory zone. 
+ * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned 
+ * virtual address.
+ * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has
+ * finished using this zone (e.g. on driver unload) using the cookie as 
+ * parameter.
+ * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write 
+ * the mapped memory, adding the necessary offsets to the address cookie.
+ *
+ * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP 
+ * instead.
+ */
+PUBLIC void *
+ixOsalIoMemMap (UINT32 requestedAddress,
+    UINT32 size, IxOsalMapEndianessType requestedEndianType)
+{
+    IxOsalMemoryMap *map;
+
+    ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+        IX_OSAL_LOG_DEV_STDOUT,
+        "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n",
+        requestedAddress, size, requestedEndianType, 0, 0, 0);
+
+    if (requestedEndianType == IX_OSAL_LE)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n",
+            0, 0, 0, 0, 0, 0);
+        return (NULL);
+    }
+    map = ixOsalMemMapFind (requestedAddress,
+        size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType);
+    if (map != NULL)
+    {
+        UINT32 offset = requestedAddress - map->physicalAddress;
+
+        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+            IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0);
+        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+            IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0);
+        ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3,
+            IX_OSAL_LOG_DEV_STDOUT,
+            ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n",
+            map->physicalAddress, map->virtualAddress,
+            map->size, map->refCount, map->mapEndianType, 0);
+
+        if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0)
+        {
+            if (map->mapFunction != NULL)
+            {
+                map->mapFunction (map);
+
+                if (map->virtualAddress == 0)
+                {
+                    /*
+                     * failed 
+                     */
+                    ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+                        IX_OSAL_LOG_DEV_STDERR,
+                        "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n",
+                        requestedAddress, size, requestedEndianType, 0, 0, 0);
+                    return NULL;
+                }
+            }
+            else
+            {
+                /*
+                 * error, no map function for a dynamic map 
+                 */
+                ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+                    IX_OSAL_LOG_DEV_STDERR,
+                    "OSAL: No map function for a dynamic map - "
+                    "[addr 0x%x:size 0x%x:endianType %d]\n",
+                    requestedAddress, size, requestedEndianType, 0, 0, 0);
+
+                return NULL;
+            }
+        }
+
+        /*
+         * increment reference count 
+         */
+        map->refCount++;
+
+        return (void *) (map->virtualAddress + offset);
+    }
+
+    /*
+     * requested address is not described in the global memory map 
+     */
+    ixOsalLog (IX_OSAL_LOG_LVL_FATAL,
+        IX_OSAL_LOG_DEV_STDERR,
+        "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n",
+        requestedAddress, size, requestedEndianType, 0, 0, 0);
+    return NULL;
+}
+
+/*
+ * This function unmaps a previously mapped I/O memory zone using
+ * the cookie obtained in the mapping operation. The memory zone in question
+ * becomes unavailable to the caller once unmapped and the cookie should be
+ * discarded.
+ *
+ * This function cannot fail if the given parameter is correct and does not
+ * return a value.
+ *
+ * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP
+ * instead.
+ */
+PUBLIC void
+ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType)
+{
+    IxOsalMemoryMap *map;
+
+    if (endianType == IX_OSAL_LE)
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
+            IX_OSAL_LOG_DEV_STDOUT,
+            "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n",
+            0, 0, 0, 0, 0, 0);
+        return;
+    }
+
+    if (requestedAddress == 0)
+    {
+        /*
+         * invalid virtual address 
+         */
+        return;
+    }
+
+    map =
+        ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS,
+        endianType);
+
+    if (map != NULL)
+    {
+        if (map->refCount > 0)
+        {
+            /*
+             * decrement reference count 
+             */
+            map->refCount--;
+
+            if (map->refCount == 0)
+            {
+                /*
+                 * no longer used, deallocate 
+                 */
+                if (map->type == IX_OSAL_DYNAMIC_MAP
+                    && map->unmapFunction != NULL)
+                {
+                    map->unmapFunction (map);
+                }
+            }
+        }
+    }
+    else
+    {
+        ixOsalLog (IX_OSAL_LOG_LVL_WARNING,
+            IX_OSAL_LOG_DEV_STDERR,
+            "OSAL: ixOsServMemUnmap didn't find the requested map "
+            "[virt addr 0x%x: endianType %d], ignoring call\n",
+            requestedAddress, endianType, 0, 0, 0, 0);
+    }
+}
+
+/* 
+ * This function Converts a virtual address into a physical 
+ * address, including the dynamically mapped memory.
+ * 
+ * Parameters	virtAddr - virtual address to convert
+ * Return value: corresponding physical address, or NULL 
+ *               if there is no physical address addressable 
+ *               by the given virtual address
+ * OS: 	VxWorks, Linux, WinCE, QNX, eCos
+ * Reentrant: Yes
+ * IRQ safe: Yes
+ */
+PUBLIC UINT32
+ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency)
+{
+    IxOsalMemoryMap *map =
+        ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS,
+        requestedCoherency);
+
+    if (map != NULL)
+    {
+        return map->physicalAddress + virtualAddress - map->virtualAddress;
+    }
+    else
+    {
+        return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress);
+    }
+}
+
+/* 
+ * This function Converts a virtual address into a physical 
+ * address, including the dynamically mapped memory.
+ * 
+ * Parameters	virtAddr - virtual address to convert
+ * Return value: corresponding physical address, or NULL 
+ *               if there is no physical address addressable 
+ *               by the given virtual address
+ * OS: 	VxWorks, Linux, WinCE, QNX, eCos
+ * Reentrant: Yes
+ * IRQ safe: Yes
+ */
+PUBLIC UINT32
+ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency)
+{
+    IxOsalMemoryMap *map =
+        ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS,
+        requestedCoherency);
+
+    if (map != NULL)
+    {
+        return map->virtualAddress + physicalAddress - map->physicalAddress;
+    }
+    else
+    {
+        return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress);
+    }
+}