⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mallib.c

📁 WINDRIVER SBC405 BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
/* malLib.c - IBM Memory Access Layer (MAL) library *//*******************************************************************************   This source and object code has been made available to you by IBM on an   AS-IS basis.   IT IS PROVIDED WITHOUT WARRANTY OF ANY KIND, INCLUDING THE WARRANTIES OF   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE OR OF NONINFRINGEMENT   OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL IBM OR ITS LICENSORS BE LIABLE   FOR INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES.  IBM'S OR ITS LICENSOR'S   DAMAGES FOR ANY CAUSE OF ACTION, WHETHER IN CONTRACT OR IN TORT, AT LAW OR   AT EQUITY, SHALL BE LIMITED TO A MAXIMUM OF $1,000 PER LICENSE.  No license   under IBM patents or patent applications is to be implied by the copyright   license.   Any user of this software should understand that neither IBM nor its   licensors will be responsible for any consequences resulting from the use   of this software.   Any person who transfers this source code or any derivative work must   include the IBM copyright notice, this paragraph, and the preceding two   paragraphs in the transferred software.   Any person who transfers this object code or any derivative work must   include the IBM copyright notice in the transferred software.   COPYRIGHT   I B M   CORPORATION 2000   LICENSED MATERIAL  -  PROGRAM PROPERTY OF  I B M"*******************************************************************************/#include "malLib.h"#include "sysDcr.h"#include "string.h" /* for memset *//* modification history-----------------------01h,26nov01,mcg  don't enable PLB bursting if 440GP rev 1.0 or 1.101g,18oct01,mcg  changed return(0) to return(OK)01f,16may01,mcg  common driver for walnut (405GP), cedar (NPe405x)                 optimized malTXEobInt and malRXEobInt01e,01mar01,ajm  port to cedar from walnut01d,22may00,mcg  all MAL descriptor table memory allocation moved to malInit01c,15may00,mcg  register name updates to match 405GP User Manual01b,15jan00,mcg  added arrays for ctp and rcbs register access functions01a,18oct99,mcg  created*//*This library provides functions to initialize and configure the Memory AccessLayer core.  This hardware core resides between system memory and one or morepacket oriented communications macros (COMMACs) such as Ethernet, SCC, and soon.  Its job is to handle the transfer of data between the COMMACs and a bufferdescriptor structure that resides in memory.*//* * No Globals because MAL driver may be used by multiple physical MAL cores * malInit() creates a driver control structure for each instance. *//* * Forward declarations */LOCAL void malSerrInt (void);LOCAL void malTXEobInt(MAL_DATA *pMalData);LOCAL void malRXEobInt(MAL_DATA *pMalData);LOCAL void malTXDeInt (MAL_DATA *pMalData);LOCAL void malRXDeInt (MAL_DATA *pMalData);/* Macros */#define  MAL_BASE_REG  pMalData->malInit.dcrBaseReg/********************************************************************************* malReset() - Resets the entire Memory Access Layer (MAL) core.** This routine performs a software reset on the Memory Access Layer (MAL) core.** RETURNS: N/A**/void malReset    (    UINT dcrBaseReg    )    {    /*     * Reset the MAL core using the MAL configuration register.     * The software reset bit will clear when this has completed.     */    sysDcrOutLong(dcrBaseReg + MAL_CFG, MAL_CFG_SR);    while(sysDcrInLong(dcrBaseReg + MAL_CFG) & MAL_CFG_SR);    return;    }/********************************************************************************* malInit() - Initialize the Memory Access Layer (MAL) core.** This routine initializes the Memory Access Layer core.  This hardware* device resides between packet oriented communcications cores (COMMACs) and* and system memory.** RETURNS: pointer to MAL driver control structure**/MAL_DATA * malInit    (    MAL_INIT * pMalInit    )    {    int        i;    int        numValidChannels = 0;    UINT       chanMask;    char *     tempPtr;    int        descBlockSize;    MAL_DATA * pMalData;    /*     * Check and save the list of valid TX and RX channels, If no valid channels     * are specified, return an error.     */    if (!(pMalInit->validChannels[MAL_TX_TYPE]) &&        !(pMalInit->validChannels[MAL_RX_TYPE]))        return(NULL);    /* Allocate a MAL driver control structure */    pMalData = malloc(sizeof(MAL_DATA));    if (pMalData == NULL)        return(NULL);    bzero((char *)pMalData, sizeof(MAL_DATA));    /* Copy Initialization parameters */    bcopy((char *)pMalInit, (char *)&pMalData->malInit, sizeof(MAL_INIT));    /*     * Software reset the MAL core.     */    malReset(pMalData->malInit.dcrBaseReg);    /*     * Count the total number of valid channels to determine how much memory     * must be allocated for descriptor tables.     */    for (i=0; i < MAL_MAX_CHANNELS; i++)        {        chanMask = 0x80000000 >> i;        if (pMalData->malInit.validChannels[MAL_TX_TYPE] & chanMask)            numValidChannels++;        if (pMalData->malInit.validChannels[MAL_RX_TYPE] & chanMask)            numValidChannels++;        }    /*     * Allocate enough memory to hold the maximum sized descriptor table (256     * entries) for each valid channel.  The alignment of this block of memory     * is important as bits 0:12 of all MAL TX channel table pointer regs must     * be the same, and bits 0:12 of all MAL RX channel table pointer regs must     * also be the same.  When allocating cached memory, if one block is     * allocated on a 512KB boundary large enough to hold all descriptor tables     * of all valid channels, then both requirements will be satisfied.  When     * allocating uncached memory, check to be sure it doesn't cross a 512KB     * boundary.     */    descBlockSize = numValidChannels * MAL_MAX_DESC_TBL_SIZE;    if (CACHE_DMA_IS_WRITE_COHERENT())        {        /*         * MMU is being used, memory allocated will be uncached.         * Getting the proper alignment can be extra work.         * The maximum size block is:         *    64 channels * 256 entries * 8 bytes per entry = 128KB         */        pMalData->descTablesAlloc = cacheDmaMalloc(descBlockSize);        if (pMalData->descTablesAlloc == NULL)            {            printf("malLib cacheDmaMalloc failed\n");            return(NULL);            }        /* Allocated memory cannot cross a 512KB boundary */        if (((UINT)pMalData->descTablesAlloc & 0xFFF80000) !=           (((UINT)pMalData->descTablesAlloc + descBlockSize) & 0xFFF80000 ))            {            /*             * First attempt did not meet alignment restrictions.             * Free and allocate again, this time 2x what is needed.             * So if the max size is 128KB, and we allocate 256KB, we can be             * sure to get 128KB that does not cross a 512KB boundary.             */            cacheDmaFree(pMalData->descTablesAlloc);            pMalData->descTablesAlloc = cacheDmaMalloc(descBlockSize*2);            /*             * Apply the same test to see if the first half of what             * was allocated crossses a 512KB boundary. If it doesn't,             * use it.  If it does, use the second half of what was             * allocated.             */            if (((UINT)pMalData->descTablesAlloc & 0xFFF80000) !=               (((UINT)pMalData->descTablesAlloc + descBlockSize) & 0xFFF80000 ))                {                pMalData->descTables = pMalData->descTablesAlloc + descBlockSize;                }            else                {                pMalData->descTables = pMalData->descTablesAlloc;                }            }        else            {            pMalData->descTables = pMalData->descTablesAlloc;            }        }    else        {        /* MMU is not being used, memory allocated will be cached */        pMalData->descTablesAlloc = memalign(MAL_DESC_REQ_ALIGN, descBlockSize);        if (pMalData->descTablesAlloc == NULL)            return(NULL);        pMalData->descTables = pMalData->descTablesAlloc;        }    /* Initialize all descriptor tables */    bzero((char *)pMalData->descTables, descBlockSize);    /* Flush is necessary only if cached memory was allocated above */    if (!(CACHE_DMA_IS_WRITE_COHERENT()))        {        cacheFlush (DATA_CACHE, pMalData->descTables, descBlockSize);        }    /*     * Chop up the block just allocated into descriptor tables for each     * valid channel.  Call the appropriate function to set up the TX or RX     * channel descriptor table pointer register for each valid channel.     */    tempPtr = pMalData->descTables;    for (i=0; i < MAL_MAX_CHANNELS; i++)        {        chanMask = 0x80000000 >> i;        if (pMalData->malInit.validChannels[MAL_TX_TYPE] & chanMask)            {            sysDcrOutLong(MAL_BASE_REG + MAL_TXCTPxR + i, (UINT)tempPtr);            tempPtr += MAL_MAX_DESC_TBL_SIZE;            }        if (pMalData->malInit.validChannels[MAL_RX_TYPE] & chanMask)            {            sysDcrOutLong(MAL_BASE_REG + MAL_RXCTPxR +i, (UINT)tempPtr);            tempPtr += MAL_MAX_DESC_TBL_SIZE;            }        }    /*     * Set up the MAL Configuration Register.     * Enable PLB Bursting and set the PLB latency timer to the maximum value.     * End-of-buffer interrupt enable is not set.  It is up to the     * communication core drivers to set the individual EOB Interrupt bits     * in each descriptor ring entry if an EOB interrupt is desired.     */    /* MAL PLB bursting is broken in PPC440GP 1.0 and 1.1.  See errata MAL_1 */#ifdef	MAL_PLB_BURST_ERRATA    sysDcrOutLong(MAL_BASE_REG + MAL_CFG, MAL_CFG_PLBLT_MASK);#else    sysDcrOutLong(MAL_BASE_REG + MAL_CFG, MAL_CFG_PLBLT_MASK | MAL_CFG_PLBB);#endif    /*     * Specify the events that will cause a MAL System ERRor (SERR) interrupt.     * All events except descriptor errors because the separate TX and RX     * descriptor error exceptions are utilized.     */    sysDcrOutLong(MAL_BASE_REG + MAL_IER,                  MAL_IER_NE | MAL_IER_TE | MAL_IER_OPBE | MAL_IER_PLBE);    /*     * Connect the various MAL interrupt sources to their handling functions.     * MAL System ERRor, TX End-Of-Buffer, RX End-Of-Buffer, TX Descriptor     * Error, and RX Descriptor Error.     */    intConnect(INUM_TO_IVEC(pMalData->malInit.intVecSerr),  malSerrInt,  (int)pMalData);    intConnect(INUM_TO_IVEC(pMalData->malInit.intVecTxeob), malTXEobInt, (int)pMalData);    intConnect(INUM_TO_IVEC(pMalData->malInit.intVecRxeob), malRXEobInt, (int)pMalData);    intConnect(INUM_TO_IVEC(pMalData->malInit.intVecTxde),  malTXDeInt,  (int)pMalData);    intConnect(INUM_TO_IVEC(pMalData->malInit.intVecRxde),  malRXDeInt,  (int)pMalData);    /*     * Enable the MAL interrupts.     */    intEnable(pMalData->malInit.intLvlSerr);    intEnable(pMalData->malInit.intLvlTxeob);    intEnable(pMalData->malInit.intLvlRxeob);    intEnable(pMalData->malInit.intLvlTxde);    intEnable(pMalData->malInit.intLvlRxde);    return(pMalData);    }/********************************************************************************* malChannelInit()- Initializes a specific Memory Access Layer (MAL) channel.** This routine initializes a MAL channel and readies it for operation.  It* does not start the channel.** RETURNS: N/A**/STATUS malChannelInit    (    MAL_DATA    * pMalData,    MAL_CHANNEL * pChannel    )    {    UINT channelBit;    UINT type;    if (pChannel->channelNum > (MAL_MAX_CHANNELS - 1))        return(ERROR);    channelBit = 1 << (32 - pChannel->channelNum - 1);    type = pChannel->channelType;    /* Check if the channel is valid. Return error if not. */    if ((channelBit & pMalData->malInit.validChannels[type]) == 0)        return(ERROR);    /*     * Check if the channel has already been initialized.     * Return error if it is.     */    if (channelBit & pMalData->malInitializedChannels[type])        return(ERROR);    /* Set up MAL channel specific registers */    if (type == MAL_RX_TYPE)        {        /*         * Set the MAL RX channel buffer size register for this channel.  The         * buffer size is specified in increments of 16 bytes.         */        sysDcrOutLong(MAL_BASE_REG + MAL_RCBSx + pChannel->channelNum,                      pChannel->bufferSizeRX / 16);        }    /* Copy the channel parameters into the local channel array */    memcpy(&pMalData->malChannelArray[type][pChannel->channelNum],           pChannel, sizeof(MAL_CHANNEL));    /* Mark the channel as initialized.*/    pMalData->malInitializedChannels[type] |= channelBit;    /* Initially mask all interrupts for the channel. */    pMalData->malChannelArray[type][pChannel->channelNum].channelIntMask = MAL_NO_INTS;    return(OK);    }/********************************************************************************* malChannelDelete()- Removes a channel from the set MAL is currently managing.** This routine removes a MAL channel from the set of channels MAL is currently* managing.  The channel must not be active when this function is called.** RETURNS: N/A**/STATUS malChannelDelete    (    MAL_DATA * pMalData,    UINT channelType,    UINT channelNum    )    {    UINT channelBit;    UINT carr;    channelBit = 1 << (32 - channelNum - 1);    /*     * Check the channel active reset reg to make sure it isn't running.     * If not running, delete it.     */    switch (channelType)        {        case  MAL_TX_TYPE :            carr = sysDcrInLong(MAL_BASE_REG + MAL_TXCARR);            break;        case  MAL_RX_TYPE :            carr = sysDcrInLong(MAL_BASE_REG + MAL_RXCARR);            break;        default :            return(ERROR);        }    if (carr & channelBit)        return(ERROR);                      /* can't delete a running channel */    /* Clear the channel entry from the local structures */    pMalData->malInitializedChannels[channelType] &= ~channelBit;    memset((char *)&pMalData->malChannelArray[channelType][channelNum],0,                  sizeof(MAL_CHANNEL));    return(OK);    }/********************************************************************************* malChannelActivate()- Activates a MAL channel.** This routine activates a MAL channel.  The channel must have been previously* initialized with the malChannelInit() function.** RETURNS: N/A**/STATUS malChannelActivate    (    MAL_DATA * pMalData,    UINT channelType,    UINT channelNum    )    {    UINT channelBit;    UINT regtemp;    channelBit = 1 << (32 - channelNum - 1);    /*     * Check to make sure the channel has been defined with a call to     * MalChannelInit(). If so, set the bit for the channel in the appropriate     * Channel Active Set register.     */    switch (channelType)        {        case  MAL_TX_TYPE :            regtemp = sysDcrInLong(MAL_BASE_REG + MAL_TXCASR);            if (pMalData->malInitializedChannels[MAL_TX_TYPE] & channelBit)                sysDcrOutLong(MAL_BASE_REG + MAL_TXCASR, regtemp | channelBit);            break;        case  MAL_RX_TYPE :            regtemp = sysDcrInLong(MAL_BASE_REG + MAL_RXCASR);            if (pMalData->malInitializedChannels[MAL_RX_TYPE] & channelBit)                sysDcrOutLong(MAL_BASE_REG + MAL_RXCASR, regtemp | channelBit);            break;        default :            return(ERROR);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -