* 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/IxNpeDlImageMgr.c b/cpu/ixp/npe/IxNpeDlImageMgr.c
new file mode 100644
index 0000000..e05c228
--- /dev/null
+++ b/cpu/ixp/npe/IxNpeDlImageMgr.c
@@ -0,0 +1,675 @@
+/**
+ * @file IxNpeDlImageMgr.c
+ *
+ * @author Intel Corporation
+ * @date 09 January 2002
+ *
+ * @brief This file contains the implementation of the private API for the 
+ *        IXP425 NPE Downloader ImageMgr module
+ *
+ * 
+ * @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 --
+*/
+
+
+/*
+ * Put the system defined include files required.
+ */
+#include "IxOsal.h"
+
+/*
+ * Put the user defined include files required.
+ */
+#include "IxNpeDlImageMgr_p.h"
+#include "IxNpeDlMacros_p.h"
+
+/*
+ * define the flag which toggles the firmare inclusion
+ */
+#define IX_NPE_MICROCODE_FIRMWARE_INCLUDED 1
+#include "IxNpeMicrocode.h"
+
+/*
+ * Indicates the start of an NPE Image, in new NPE Image Library format.
+ * 2 consecutive occurances indicates the end of the NPE Image Library
+ */
+#define NPE_IMAGE_MARKER 0xfeedf00d
+
+/*
+ * Typedefs whose scope is limited to this file.
+ */
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef struct
+{
+    UINT32 size;
+    UINT32 offset;
+    UINT32 id;
+} IxNpeDlImageMgrImageEntry;
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef union
+{
+    IxNpeDlImageMgrImageEntry image;
+    UINT32 eohMarker;
+} IxNpeDlImageMgrHeaderEntry;
+
+/*
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+typedef struct
+{
+    UINT32 signature;
+    /* 1st entry in the header (there may be more than one) */
+    IxNpeDlImageMgrHeaderEntry entry[1];
+} IxNpeDlImageMgrImageLibraryHeader;
+
+
+/*
+ * NPE Image Header definition, used in new NPE Image Library format
+ */
+typedef struct
+{
+    UINT32 marker;
+    UINT32 id;
+    UINT32 size;
+} IxNpeDlImageMgrImageHeader;
+
+/* module statistics counters */
+typedef struct
+{
+    UINT32 invalidSignature;
+    UINT32 imageIdListOverflow;
+    UINT32 imageIdNotFound;
+} IxNpeDlImageMgrStats;
+
+
+/*
+ * Variable declarations global to this file only.  Externs are followed by
+ * static variables.
+ */
+static IxNpeDlImageMgrStats ixNpeDlImageMgrStats;
+
+/* default image */
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+static UINT32 *IxNpeMicroCodeImageLibrary = NULL;  /* Gets set to proper value at runtime */
+#else
+static UINT32 *IxNpeMicroCodeImageLibrary = (UINT32 *)IxNpeMicrocode_array;
+#endif
+
+
+/*
+ * static function prototypes.
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary);
+
+PRIVATE void  
+ixNpeDlImageMgrImageIdFormat (UINT32 rawImageId, IxNpeDlImageId *imageId);
+
+PRIVATE BOOL
+ixNpeDlImageMgrImageIdCompare (IxNpeDlImageId *imageIdA, 
+				 IxNpeDlImageId *imageIdB);
+				 
+PRIVATE BOOL
+ixNpeDlImageMgrNpeFunctionIdCompare (IxNpeDlImageId *imageIdA,
+    				       IxNpeDlImageId *imageIdB);
+
+PRIVATE IX_STATUS
+ixNpeDlImageMgrImageFind_legacy (UINT32 *imageLibrary,
+                                 UINT32 imageId,
+                                 UINT32 **imagePtr,
+                                 UINT32 *imageSize);
+
+/*
+ * Function definition: ixNpeDlImageMgrMicrocodeImageLibraryOverride
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrMicrocodeImageLibraryOverride (
+    UINT32 *clientImageLibrary)
+{
+    IX_STATUS status = IX_SUCCESS;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlImageMgrMicrocodeImageLibraryOverride\n");
+
+    if (ixNpeDlImageMgrSignatureCheck (clientImageLibrary))
+    {
+	IxNpeMicroCodeImageLibrary = clientImageLibrary;
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrMicrocodeImageLibraryOverride: "
+			       "Client-supplied image has invalid signature\n");
+	status = IX_FAIL;
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Exiting ixNpeDlImageMgrMicrocodeImageLibraryOverride: status = %d\n",
+		     status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageListExtract
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrImageListExtract (
+    IxNpeDlImageId *imageListPtr,
+    UINT32 *numImages)
+{
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    IX_STATUS status = IX_SUCCESS;
+    UINT32 imageCount = 0;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Entering ixNpeDlImageMgrImageListExtract\n");
+
+    header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+
+    if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+    {
+	/* for each image entry in the image header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    /*
+	     * if the image list container from calling function has capacity,
+	     * add the image id to the list 
+	     */
+	    if ((imageListPtr != NULL) && (imageCount < *numImages))
+	    {
+		rawImageId = header->entry[imageCount].image.id;
+	        ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+		imageListPtr[imageCount] = formattedImageId;
+	    }
+	    /* imageCount reflects no. of image entries in image library header */
+	    imageCount++;  
+	}
+	
+	/*
+	 * if image list container from calling function was too small to
+	 * contain all image ids in the header, set return status to FAIL
+	 */
+	if ((imageListPtr != NULL) && (imageCount > *numImages))
+	{
+	    status = IX_FAIL;
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
+				   "number of Ids found exceeds list capacity\n");
+	    ixNpeDlImageMgrStats.imageIdListOverflow++;
+	}
+	/* return number of image ids found in image library header */
+	*numImages = imageCount;  
+    }
+    else
+    {
+	status = IX_FAIL;
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: "
+			       "invalid signature in image\n");
+    }
+    
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
+		     "Exiting ixNpeDlImageMgrImageListExtract: status = %d\n",
+		     status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageLocate
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrImageLocate (
+    IxNpeDlImageId *imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    UINT32 imageOffset;
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    /* used to index image entries in image library header */
+    UINT32 imageCount = 0;   
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrImageLocate\n");
+
+    header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+
+    if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+    {
+	/* for each image entry in the image library header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    rawImageId = header->entry[imageCount].image.id;
+	    ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+	    /* if a match for imageId is found in the image library header... */
+	    if (ixNpeDlImageMgrImageIdCompare (imageId, &formattedImageId))
+	    {
+		/*
+		 * get pointer to the image in the image library using offset from
+		 * 1st word in image library
+		 */
+		imageOffset = header->entry[imageCount].image.offset;
+		*imagePtr = &IxNpeMicroCodeImageLibrary[imageOffset];
+		/* get the image size */
+		*imageSize = header->entry[imageCount].image.size;
+		status = IX_SUCCESS;
+		break;
+	    }
+	    imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrImageLocate: status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrLatestImageExtract
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+IX_STATUS
+ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId)
+{
+    UINT32 imageCount = 0; 
+    UINT32 rawImageId;
+    IxNpeDlImageId formattedImageId;
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+    
+    
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrLatestImageExtract\n");
+		     
+    header = (IxNpeDlImageMgrImageLibraryHeader *) IxNpeMicroCodeImageLibrary;
+    
+    if (ixNpeDlImageMgrSignatureCheck (IxNpeMicroCodeImageLibrary))
+    {
+	/* for each image entry in the image library header ... */
+	while (header->entry[imageCount].eohMarker !=
+	       IX_NPEDL_IMAGEMGR_END_OF_HEADER)
+	{
+	    rawImageId = header->entry[imageCount].image.id;
+	    ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId);
+	    /* 
+	     * if a match for the npe Id and functionality Id of the imageId is
+	     *  found in the image library header... 
+	     */
+            if(ixNpeDlImageMgrNpeFunctionIdCompare(imageId, &formattedImageId))
+            {
+                if(imageId->major <= formattedImageId.major)
+                {
+                    if(imageId->minor < formattedImageId.minor)
+                    {
+                        imageId->minor = formattedImageId.minor;
+                    }
+                    imageId->major = formattedImageId.major;
+                }
+                status = IX_SUCCESS;
+            }
+            imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageExtract: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageGet: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrLatestImageGet: status = %d\n", status);
+    return status;
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrSignatureCheck
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary)
+{
+    IxNpeDlImageMgrImageLibraryHeader *header =
+	(IxNpeDlImageMgrImageLibraryHeader *) microCodeImageLibrary;
+    BOOL result = TRUE;
+
+    if (header->signature != IX_NPEDL_IMAGEMGR_SIGNATURE)
+    {
+	result = FALSE;
+	ixNpeDlImageMgrStats.invalidSignature++;
+    }
+
+    return result;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageIdFormat
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE void
+ixNpeDlImageMgrImageIdFormat (
+    UINT32 rawImageId, 
+    IxNpeDlImageId *imageId)
+{  
+    imageId->npeId = (rawImageId >>
+				IX_NPEDL_IMAGEID_NPEID_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->functionalityId = (rawImageId >> 
+				  IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->major = (rawImageId >>
+				IX_NPEDL_IMAGEID_MAJOR_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+    imageId->minor = (rawImageId >>
+				IX_NPEDL_IMAGEID_MINOR_OFFSET) &
+	IX_NPEDL_NPEIMAGE_FIELD_MASK;
+
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageIdCompare
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrImageIdCompare (
+    IxNpeDlImageId *imageIdA,
+    IxNpeDlImageId *imageIdB)
+{
+    if ((imageIdA->npeId   == imageIdB->npeId)   &&
+	(imageIdA->functionalityId == imageIdB->functionalityId) &&
+	(imageIdA->major   == imageIdB->major)   &&
+	(imageIdA->minor   == imageIdB->minor))
+    {
+	return TRUE;
+    }
+    else
+    {
+	return FALSE;
+    }
+}
+
+/*
+ * Function definition: ixNpeDlImageMgrNpeFunctionIdCompare
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE BOOL
+ixNpeDlImageMgrNpeFunctionIdCompare (
+    IxNpeDlImageId *imageIdA,
+    IxNpeDlImageId *imageIdB)
+{
+    if ((imageIdA->npeId   == imageIdB->npeId)   &&
+	(imageIdA->functionalityId == imageIdB->functionalityId))
+    {
+	return TRUE;
+    }
+    else
+    {
+	return FALSE;
+    }
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrStatsShow
+ */
+void
+ixNpeDlImageMgrStatsShow (void)
+{
+    ixOsalLog (IX_OSAL_LOG_LVL_USER,
+               IX_OSAL_LOG_DEV_STDOUT,
+               "\nixNpeDlImageMgrStatsShow:\n"
+               "\tInvalid Image Signatures: %u\n"
+               "\tImage Id List capacity too small: %u\n"
+               "\tImage Id not found: %u\n\n",
+               ixNpeDlImageMgrStats.invalidSignature,
+               ixNpeDlImageMgrStats.imageIdListOverflow,
+               ixNpeDlImageMgrStats.imageIdNotFound,
+               0,0,0);
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrStatsReset
+ */
+void
+ixNpeDlImageMgrStatsReset (void)
+{
+    ixNpeDlImageMgrStats.invalidSignature = 0;
+    ixNpeDlImageMgrStats.imageIdListOverflow = 0;
+    ixNpeDlImageMgrStats.imageIdNotFound = 0;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageFind_legacy
+ *
+ * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT
+ * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE
+ */
+PRIVATE IX_STATUS
+ixNpeDlImageMgrImageFind_legacy (
+    UINT32 *imageLibrary,
+    UINT32 imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    UINT32 imageOffset;
+    /* used to index image entries in image library header */
+    UINT32 imageCount = 0;   
+    IX_STATUS status = IX_FAIL;
+    IxNpeDlImageMgrImageLibraryHeader *header;
+    BOOL imageFound = FALSE;
+
+    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Entering ixNpeDlImageMgrImageFind\n");
+
+
+    /* If user didn't specify a library to use, use the default
+     * one from IxNpeMicrocode.h
+     */
+    if (imageLibrary == NULL)
+    {
+	imageLibrary = IxNpeMicroCodeImageLibrary;
+    }
+    
+    if (ixNpeDlImageMgrSignatureCheck (imageLibrary))
+    {
+	header = (IxNpeDlImageMgrImageLibraryHeader *) imageLibrary;
+    
+	/* for each image entry in the image library header ... */
+	while ((header->entry[imageCount].eohMarker !=
+               IX_NPEDL_IMAGEMGR_END_OF_HEADER) && !(imageFound))
+	{
+	    /* if a match for imageId is found in the image library header... */
+	    if (imageId == header->entry[imageCount].image.id)
+	    {
+		/*
+		 * get pointer to the image in the image library using offset from
+		 * 1st word in image library
+		 */
+		imageOffset = header->entry[imageCount].image.offset;
+		*imagePtr = &imageLibrary[imageOffset];
+		/* get the image size */
+		*imageSize = header->entry[imageCount].image.size;
+		status = IX_SUCCESS;
+		imageFound = TRUE;
+	    }
+	    imageCount++;
+	}
+	if (status != IX_SUCCESS)
+	{
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+	}
+    }
+    else
+    {
+	IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+			       "invalid signature in image library\n");
+    }
+
+    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
+		     "Exiting ixNpeDlImageMgrImageFind: status = %d\n", status);
+    return status;
+}
+
+
+/*
+ * Function definition: ixNpeDlImageMgrImageFind
+ */
+IX_STATUS
+ixNpeDlImageMgrImageFind (
+    UINT32 *imageLibrary,
+    UINT32 imageId,
+    UINT32 **imagePtr,
+    UINT32 *imageSize)
+{
+    IxNpeDlImageMgrImageHeader *image;
+    UINT32 offset = 0;
+
+    /* If user didn't specify a library to use, use the default
+     * one from IxNpeMicrocode.h
+     */
+    if (imageLibrary == NULL)
+    {
+#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE
+	if (ixNpeMicrocode_binaryArray == NULL)
+        {
+	    printk (KERN_ERR "ixp400.o:  ERROR, no Microcode found in memory\n");
+	    return IX_FAIL;
+	}
+	else
+	{
+	    imageLibrary = ixNpeMicrocode_binaryArray;
+	}
+#else
+	imageLibrary = IxNpeMicroCodeImageLibrary;
+#endif /* IX_NPEDL_READ_MICROCODE_FROM_FILE */
+    }
+
+    /* For backward's compatibility with previous image format */
+    if (ixNpeDlImageMgrSignatureCheck(imageLibrary))
+    {
+        return ixNpeDlImageMgrImageFind_legacy(imageLibrary,
+                                               imageId,
+                                               imagePtr,
+                                               imageSize);
+    }
+
+    while (*(imageLibrary+offset) == NPE_IMAGE_MARKER)
+    {
+        image = (IxNpeDlImageMgrImageHeader *)(imageLibrary+offset);
+        offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(UINT32);
+        
+        if (image->id == imageId)
+        {
+            *imagePtr = imageLibrary + offset;
+            *imageSize = image->size;
+            return IX_SUCCESS;
+        }
+        /* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */
+        else if (image->id == NPE_IMAGE_MARKER)
+        {
+	    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+				   "imageId not found in image library header\n");
+	    ixNpeDlImageMgrStats.imageIdNotFound++;
+            /* reached end of library, image not found */
+            return IX_FAIL;
+        }
+        offset += image->size;
+    }
+
+    /* If we get here, our image library may be corrupted */
+    IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: "
+                           "image library format may be invalid or corrupted\n");
+    return IX_FAIL;
+}
+