mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-23 11:33:32 +00:00
609 lines
18 KiB
C
609 lines
18 KiB
C
|
/**
|
||
|
* @file IxNpeMhConfig.c
|
||
|
*
|
||
|
* @author Intel Corporation
|
||
|
* @date 18 Jan 2002
|
||
|
*
|
||
|
* @brief This file contains the implementation of the private API for the
|
||
|
* Configuration 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.
|
||
|
*/
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Put the user defined include files required.
|
||
|
*/
|
||
|
|
||
|
#include "IxOsal.h"
|
||
|
|
||
|
#include "IxNpeMhMacros_p.h"
|
||
|
|
||
|
#include "IxNpeMhConfig_p.h"
|
||
|
|
||
|
/*
|
||
|
* #defines and macros used in this file.
|
||
|
*/
|
||
|
#define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
|
||
|
* retries before
|
||
|
* timeout
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Typedefs whose scope is limited to this file.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @struct IxNpeMhConfigStats
|
||
|
*
|
||
|
* @brief This structure is used to maintain statistics for the
|
||
|
* Configuration module.
|
||
|
*/
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
UINT32 outFifoReads; /**< outFifo reads */
|
||
|
UINT32 inFifoWrites; /**< inFifo writes */
|
||
|
UINT32 maxInFifoFullRetries; /**< max retries if inFIFO full */
|
||
|
UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */
|
||
|
} IxNpeMhConfigStats;
|
||
|
|
||
|
/*
|
||
|
* Variable declarations global to this file only. Externs are followed by
|
||
|
* static variables.
|
||
|
*/
|
||
|
|
||
|
IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] =
|
||
|
{
|
||
|
{
|
||
|
0,
|
||
|
IX_NPEMH_NPEA_INT,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
NULL,
|
||
|
FALSE
|
||
|
},
|
||
|
{
|
||
|
0,
|
||
|
IX_NPEMH_NPEB_INT,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
NULL,
|
||
|
FALSE
|
||
|
},
|
||
|
{
|
||
|
0,
|
||
|
IX_NPEMH_NPEC_INT,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
NULL,
|
||
|
FALSE
|
||
|
}
|
||
|
};
|
||
|
|
||
|
PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES];
|
||
|
|
||
|
/*
|
||
|
* Extern function prototypes.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Static function prototypes.
|
||
|
*/
|
||
|
PRIVATE
|
||
|
void ixNpeMhConfigIsr (void *parameter);
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigIsr
|
||
|
*/
|
||
|
|
||
|
PRIVATE
|
||
|
void ixNpeMhConfigIsr (void *parameter)
|
||
|
{
|
||
|
IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter;
|
||
|
UINT32 ofint;
|
||
|
volatile UINT32 *statusReg =
|
||
|
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister;
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
|
||
|
"ixNpeMhConfigIsr\n");
|
||
|
|
||
|
/* get the OFINT (OutFifo interrupt) bit of the status register */
|
||
|
IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT);
|
||
|
|
||
|
/* if the OFINT status bit is set */
|
||
|
if (ofint)
|
||
|
{
|
||
|
/* if there is an ISR registered for this NPE */
|
||
|
if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
|
||
|
{
|
||
|
/* invoke the ISR routine */
|
||
|
ixNpeMhConfigNpeInfo[npeId].isr (npeId);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* if we don't service the interrupt the NPE will continue */
|
||
|
/* to trigger the interrupt indefinitely */
|
||
|
IX_NPEMH_ERROR_REPORT ("No ISR registered to service "
|
||
|
"interrupt\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
|
||
|
"ixNpeMhConfigIsr\n");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigInitialize
|
||
|
*/
|
||
|
|
||
|
void ixNpeMhConfigInitialize (
|
||
|
IxNpeMhNpeInterrupts npeInterrupts)
|
||
|
{
|
||
|
IxNpeMhNpeId npeId;
|
||
|
UINT32 virtualAddr[IX_NPEMH_NUM_NPES];
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
|
||
|
"ixNpeMhConfigInitialize\n");
|
||
|
|
||
|
/* Request a mapping for the NPE-A config register address space */
|
||
|
virtualAddr[IX_NPEMH_NPEID_NPEA] =
|
||
|
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE,
|
||
|
IX_OSAL_IXP400_NPEA_MAP_SIZE);
|
||
|
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]);
|
||
|
|
||
|
/* Request a mapping for the NPE-B config register address space */
|
||
|
virtualAddr[IX_NPEMH_NPEID_NPEB] =
|
||
|
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE,
|
||
|
IX_OSAL_IXP400_NPEB_MAP_SIZE);
|
||
|
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]);
|
||
|
|
||
|
/* Request a mapping for the NPE-C config register address space */
|
||
|
virtualAddr[IX_NPEMH_NPEID_NPEC] =
|
||
|
(UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE,
|
||
|
IX_OSAL_IXP400_NPEC_MAP_SIZE);
|
||
|
IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]);
|
||
|
|
||
|
/* for each NPE ... */
|
||
|
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
|
||
|
{
|
||
|
/* declare a convenience pointer */
|
||
|
IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
|
||
|
|
||
|
/* store the virtual addresses of the NPE registers for later use */
|
||
|
npeInfo->virtualRegisterBase = virtualAddr[npeId];
|
||
|
npeInfo->statusRegister = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET;
|
||
|
npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET;
|
||
|
npeInfo->inFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
|
||
|
npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET;
|
||
|
|
||
|
/* for test purposes - to verify the register addresses */
|
||
|
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register = "
|
||
|
"0x%08X\n", npeId, npeInfo->statusRegister);
|
||
|
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = "
|
||
|
"0x%08X\n", npeId, npeInfo->controlRegister);
|
||
|
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register = "
|
||
|
"0x%08X\n", npeId, npeInfo->inFifoRegister);
|
||
|
IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = "
|
||
|
"0x%08X\n", npeId, npeInfo->outFifoRegister);
|
||
|
|
||
|
/* connect our ISR to the NPE interrupt */
|
||
|
(void) ixOsalIrqBind (
|
||
|
npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId);
|
||
|
|
||
|
/* initialise a mutex for this NPE */
|
||
|
(void) ixOsalMutexInit (&npeInfo->mutex);
|
||
|
|
||
|
/* if we should service the NPE's "outFIFO not empty" interrupt */
|
||
|
if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES)
|
||
|
{
|
||
|
/* enable the NPE's "outFIFO not empty" interrupt */
|
||
|
ixNpeMhConfigNpeInterruptEnable (npeId);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* disable the NPE's "outFIFO not empty" interrupt */
|
||
|
ixNpeMhConfigNpeInterruptDisable (npeId);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
|
||
|
"ixNpeMhConfigInitialize\n");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigUninit
|
||
|
*/
|
||
|
|
||
|
void ixNpeMhConfigUninit (void)
|
||
|
{
|
||
|
IxNpeMhNpeId npeId;
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
|
||
|
"ixNpeMhConfigUninit\n");
|
||
|
|
||
|
/* for each NPE ... */
|
||
|
for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
|
||
|
{
|
||
|
/* declare a convenience pointer */
|
||
|
IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId];
|
||
|
|
||
|
/* disconnect ISR */
|
||
|
ixOsalIrqUnbind(npeInfo->interruptId);
|
||
|
|
||
|
/* destroy mutex associated with this NPE */
|
||
|
ixOsalMutexDestroy(&npeInfo->mutex);
|
||
|
|
||
|
IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase);
|
||
|
|
||
|
npeInfo->virtualRegisterBase = 0;
|
||
|
npeInfo->statusRegister = 0;
|
||
|
npeInfo->controlRegister = 0;
|
||
|
npeInfo->inFifoRegister = 0;
|
||
|
npeInfo->outFifoRegister = 0;
|
||
|
}
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
|
||
|
"ixNpeMhConfigUninit\n");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigIsrRegister
|
||
|
*/
|
||
|
|
||
|
void ixNpeMhConfigIsrRegister (
|
||
|
IxNpeMhNpeId npeId,
|
||
|
IxNpeMhConfigIsr isr)
|
||
|
{
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
|
||
|
"ixNpeMhConfigIsrRegister\n");
|
||
|
|
||
|
/* check if there is already an ISR registered for this NPE */
|
||
|
if (ixNpeMhConfigNpeInfo[npeId].isr != NULL)
|
||
|
{
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n");
|
||
|
}
|
||
|
|
||
|
/* save the ISR routine with the NPE info */
|
||
|
ixNpeMhConfigNpeInfo[npeId].isr = isr;
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
|
||
|
"ixNpeMhConfigIsrRegister\n");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigNpeInterruptEnable
|
||
|
*/
|
||
|
|
||
|
BOOL ixNpeMhConfigNpeInterruptEnable (
|
||
|
IxNpeMhNpeId npeId)
|
||
|
{
|
||
|
UINT32 ofe;
|
||
|
volatile UINT32 *controlReg =
|
||
|
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
|
||
|
|
||
|
/* get the OFE (OutFifoEnable) bit of the control register */
|
||
|
IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
|
||
|
|
||
|
/* if the interrupt is disabled then we must enable it */
|
||
|
if (!ofe)
|
||
|
{
|
||
|
/* set the OFE (OutFifoEnable) bit of the control register */
|
||
|
/* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
|
||
|
/* time for the write to have effect */
|
||
|
IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
|
||
|
(IX_NPEMH_NPE_CTL_OFE |
|
||
|
IX_NPEMH_NPE_CTL_OFEWE),
|
||
|
(IX_NPEMH_NPE_CTL_OFE |
|
||
|
IX_NPEMH_NPE_CTL_OFEWE));
|
||
|
}
|
||
|
|
||
|
/* return the previous state of the interrupt */
|
||
|
return (ofe != 0);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigNpeInterruptDisable
|
||
|
*/
|
||
|
|
||
|
BOOL ixNpeMhConfigNpeInterruptDisable (
|
||
|
IxNpeMhNpeId npeId)
|
||
|
{
|
||
|
UINT32 ofe;
|
||
|
volatile UINT32 *controlReg =
|
||
|
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister;
|
||
|
|
||
|
/* get the OFE (OutFifoEnable) bit of the control register */
|
||
|
IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE);
|
||
|
|
||
|
/* if the interrupt is enabled then we must disable it */
|
||
|
if (ofe)
|
||
|
{
|
||
|
/* unset the OFE (OutFifoEnable) bit of the control register */
|
||
|
/* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */
|
||
|
/* time for the write to have effect */
|
||
|
IX_NPEMH_REGISTER_WRITE_BITS (controlReg,
|
||
|
(0 |
|
||
|
IX_NPEMH_NPE_CTL_OFEWE),
|
||
|
(IX_NPEMH_NPE_CTL_OFE |
|
||
|
IX_NPEMH_NPE_CTL_OFEWE));
|
||
|
}
|
||
|
|
||
|
/* return the previous state of the interrupt */
|
||
|
return (ofe != 0);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigMessageIdGet
|
||
|
*/
|
||
|
|
||
|
IxNpeMhMessageId ixNpeMhConfigMessageIdGet (
|
||
|
IxNpeMhMessage message)
|
||
|
{
|
||
|
/* return the most-significant byte of the first word of the */
|
||
|
/* message */
|
||
|
return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigNpeIdIsValid
|
||
|
*/
|
||
|
|
||
|
BOOL ixNpeMhConfigNpeIdIsValid (
|
||
|
IxNpeMhNpeId npeId)
|
||
|
{
|
||
|
/* check that the npeId parameter is within the range of valid IDs */
|
||
|
return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigLockGet
|
||
|
*/
|
||
|
|
||
|
void ixNpeMhConfigLockGet (
|
||
|
IxNpeMhNpeId npeId)
|
||
|
{
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
|
||
|
"ixNpeMhConfigLockGet\n");
|
||
|
|
||
|
/* lock the mutex for this NPE */
|
||
|
(void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex,
|
||
|
IX_OSAL_WAIT_FOREVER);
|
||
|
|
||
|
/* disable the NPE's "outFIFO not empty" interrupt */
|
||
|
ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
|
||
|
ixNpeMhConfigNpeInterruptDisable (npeId);
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
|
||
|
"ixNpeMhConfigLockGet\n");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigLockRelease
|
||
|
*/
|
||
|
|
||
|
void ixNpeMhConfigLockRelease (
|
||
|
IxNpeMhNpeId npeId)
|
||
|
{
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
|
||
|
"ixNpeMhConfigLockRelease\n");
|
||
|
|
||
|
/* if the interrupt was previously enabled */
|
||
|
if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState)
|
||
|
{
|
||
|
/* enable the NPE's "outFIFO not empty" interrupt */
|
||
|
ixNpeMhConfigNpeInfo[npeId].oldInterruptState =
|
||
|
ixNpeMhConfigNpeInterruptEnable (npeId);
|
||
|
}
|
||
|
|
||
|
/* unlock the mutex for this NPE */
|
||
|
(void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex);
|
||
|
|
||
|
IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
|
||
|
"ixNpeMhConfigLockRelease\n");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigInFifoWrite
|
||
|
*/
|
||
|
|
||
|
IX_STATUS ixNpeMhConfigInFifoWrite (
|
||
|
IxNpeMhNpeId npeId,
|
||
|
IxNpeMhMessage message)
|
||
|
{
|
||
|
volatile UINT32 *npeInFifo =
|
||
|
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister;
|
||
|
UINT32 retriesCount = 0;
|
||
|
|
||
|
/* write the first word of the message to the NPE's inFIFO */
|
||
|
IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]);
|
||
|
|
||
|
/* need to wait for room to write second word - see SCR #493,
|
||
|
poll for maximum number of retries, if exceed maximum
|
||
|
retries, exit from while loop */
|
||
|
while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
|
||
|
&& ixNpeMhConfigInFifoIsFull (npeId))
|
||
|
{
|
||
|
retriesCount++;
|
||
|
}
|
||
|
|
||
|
/* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
|
||
|
if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
|
||
|
{
|
||
|
return IX_NPEMH_CRITICAL_NPE_ERR;
|
||
|
}
|
||
|
|
||
|
/* write the second word of the message to the NPE's inFIFO */
|
||
|
IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]);
|
||
|
|
||
|
/* record in the stats the maximum number of retries needed */
|
||
|
if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount)
|
||
|
{
|
||
|
ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount;
|
||
|
}
|
||
|
|
||
|
/* update statistical info */
|
||
|
ixNpeMhConfigStats[npeId].inFifoWrites++;
|
||
|
|
||
|
return IX_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigOutFifoRead
|
||
|
*/
|
||
|
|
||
|
IX_STATUS ixNpeMhConfigOutFifoRead (
|
||
|
IxNpeMhNpeId npeId,
|
||
|
IxNpeMhMessage *message)
|
||
|
{
|
||
|
volatile UINT32 *npeOutFifo =
|
||
|
(UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister;
|
||
|
UINT32 retriesCount = 0;
|
||
|
|
||
|
/* read the first word of the message from the NPE's outFIFO */
|
||
|
IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]);
|
||
|
|
||
|
/* need to wait for NPE to write second word - see SCR #493
|
||
|
poll for maximum number of retries, if exceed maximum
|
||
|
retries, exit from while loop */
|
||
|
while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount)
|
||
|
&& ixNpeMhConfigOutFifoIsEmpty (npeId))
|
||
|
{
|
||
|
retriesCount++;
|
||
|
}
|
||
|
|
||
|
/* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */
|
||
|
if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount)
|
||
|
{
|
||
|
return IX_NPEMH_CRITICAL_NPE_ERR;
|
||
|
}
|
||
|
|
||
|
/* read the second word of the message from the NPE's outFIFO */
|
||
|
IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]);
|
||
|
|
||
|
/* record in the stats the maximum number of retries needed */
|
||
|
if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount)
|
||
|
{
|
||
|
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount;
|
||
|
}
|
||
|
|
||
|
/* update statistical info */
|
||
|
ixNpeMhConfigStats[npeId].outFifoReads++;
|
||
|
|
||
|
return IX_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigShow
|
||
|
*/
|
||
|
|
||
|
void ixNpeMhConfigShow (
|
||
|
IxNpeMhNpeId npeId)
|
||
|
{
|
||
|
/* show the message fifo read counter */
|
||
|
IX_NPEMH_SHOW ("Message FIFO reads",
|
||
|
ixNpeMhConfigStats[npeId].outFifoReads);
|
||
|
|
||
|
/* show the message fifo write counter */
|
||
|
IX_NPEMH_SHOW ("Message FIFO writes",
|
||
|
ixNpeMhConfigStats[npeId].inFifoWrites);
|
||
|
|
||
|
/* show the max retries performed when inFIFO full */
|
||
|
IX_NPEMH_SHOW ("Max inFIFO Full retries",
|
||
|
ixNpeMhConfigStats[npeId].maxInFifoFullRetries);
|
||
|
|
||
|
/* show the max retries performed when outFIFO empty */
|
||
|
IX_NPEMH_SHOW ("Max outFIFO Empty retries",
|
||
|
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries);
|
||
|
|
||
|
/* show the current status of the inFifo */
|
||
|
ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
|
||
|
"InFifo is %s and %s\n",
|
||
|
(ixNpeMhConfigInFifoIsEmpty (npeId) ?
|
||
|
(int) "EMPTY" : (int) "NOT EMPTY"),
|
||
|
(ixNpeMhConfigInFifoIsFull (npeId) ?
|
||
|
(int) "FULL" : (int) "NOT FULL"),
|
||
|
0, 0, 0, 0);
|
||
|
|
||
|
/* show the current status of the outFifo */
|
||
|
ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT,
|
||
|
"OutFifo is %s and %s\n",
|
||
|
(ixNpeMhConfigOutFifoIsEmpty (npeId) ?
|
||
|
(int) "EMPTY" : (int) "NOT EMPTY"),
|
||
|
(ixNpeMhConfigOutFifoIsFull (npeId) ?
|
||
|
(int) "FULL" : (int) "NOT FULL"),
|
||
|
0, 0, 0, 0);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function definition: ixNpeMhConfigShowReset
|
||
|
*/
|
||
|
|
||
|
void ixNpeMhConfigShowReset (
|
||
|
IxNpeMhNpeId npeId)
|
||
|
{
|
||
|
/* reset the message fifo read counter */
|
||
|
ixNpeMhConfigStats[npeId].outFifoReads = 0;
|
||
|
|
||
|
/* reset the message fifo write counter */
|
||
|
ixNpeMhConfigStats[npeId].inFifoWrites = 0;
|
||
|
|
||
|
/* reset the max inFIFO Full retries counter */
|
||
|
ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0;
|
||
|
|
||
|
/* reset the max outFIFO empty retries counter */
|
||
|
ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0;
|
||
|
}
|
||
|
|
||
|
|