| /** | 
 |  * @file IxFeatureCtrl.c | 
 |  * | 
 |  * @author Intel Corporation | 
 |  * @date 29-Jan-2003 | 
 |  * | 
 |  * @brief Feature Control Public API 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 -- | 
 | */ | 
 |  | 
 | #include "IxOsal.h" | 
 | #include "IxVersionId.h" | 
 | #include "IxFeatureCtrl.h" | 
 |  | 
 | /* Macro to read from the Feature Control Register */ | 
 | #define IX_FEATURE_CTRL_READ(result) \ | 
 | do { \ | 
 | ixFeatureCtrlExpMap(); \ | 
 | (result) = IX_OSAL_READ_LONG(ixFeatureCtrlRegister); \ | 
 | } while (0) | 
 |  | 
 | /* Macro to write to the Feature Control Register */ | 
 | #define IX_FEATURE_CTRL_WRITE(value) \ | 
 | do { \ | 
 | ixFeatureCtrlExpMap(); \ | 
 | IX_OSAL_WRITE_LONG(ixFeatureCtrlRegister, (value)); \ | 
 | } while (0) | 
 |  | 
 | /* | 
 |  * This is the offset of the feature register relative to the base of the | 
 |  * Expansion Bus Controller MMR. | 
 |  */ | 
 | #define IX_FEATURE_CTRL_REG_OFFSET (0x00000028) | 
 |  | 
 |  | 
 | /* Boolean to mark the fact that the EXP_CONFIG address space was mapped */ | 
 | PRIVATE BOOL ixFeatureCtrlExpCfgRegionMapped = FALSE; | 
 |  | 
 | /* Pointer holding the virtual address of the Feature Control Register */ | 
 | PRIVATE VUINT32 *ixFeatureCtrlRegister = NULL; | 
 |  | 
 | /* Place holder to store the software configuration */ | 
 | PRIVATE BOOL swConfiguration[IX_FEATURECTRL_SWCONFIG_MAX]; | 
 |  | 
 | /* Flag to control swConfiguration[] is initialized once */ | 
 | PRIVATE BOOL swConfigurationFlag = FALSE ; | 
 |  | 
 | /* Array containing component mask values */ | 
 | #ifdef __ixp42X | 
 | UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = { | 
 |     (0x1<<IX_FEATURECTRL_RCOMP), | 
 |     (0x1<<IX_FEATURECTRL_USB), | 
 |     (0x1<<IX_FEATURECTRL_HASH), | 
 |     (0x1<<IX_FEATURECTRL_AES), | 
 |     (0x1<<IX_FEATURECTRL_DES), | 
 |     (0x1<<IX_FEATURECTRL_HDLC), | 
 |     (0x1<<IX_FEATURECTRL_AAL), | 
 |     (0x1<<IX_FEATURECTRL_HSS), | 
 |     (0x1<<IX_FEATURECTRL_UTOPIA), | 
 |     (0x1<<IX_FEATURECTRL_ETH0), | 
 |     (0x1<<IX_FEATURECTRL_ETH1), | 
 |     (0x1<<IX_FEATURECTRL_NPEA), | 
 |     (0x1<<IX_FEATURECTRL_NPEB), | 
 |     (0x1<<IX_FEATURECTRL_NPEC), | 
 |     (0x1<<IX_FEATURECTRL_PCI), | 
 |     IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE, | 
 |     (0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT), | 
 |     (0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2), | 
 |     IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE, | 
 |     IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE, | 
 |     IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE, | 
 |     IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE, | 
 |     IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE | 
 | }; | 
 | #elif defined (__ixp46X) | 
 | UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = { | 
 |     (0x1<<IX_FEATURECTRL_RCOMP), | 
 |     (0x1<<IX_FEATURECTRL_USB), | 
 |     (0x1<<IX_FEATURECTRL_HASH), | 
 |     (0x1<<IX_FEATURECTRL_AES), | 
 |     (0x1<<IX_FEATURECTRL_DES), | 
 |     (0x1<<IX_FEATURECTRL_HDLC), | 
 |     IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE,  /* AAL component is always on */ | 
 |     (0x1<<IX_FEATURECTRL_HSS), | 
 |     (0x1<<IX_FEATURECTRL_UTOPIA), | 
 |     (0x1<<IX_FEATURECTRL_ETH0), | 
 |     (0x1<<IX_FEATURECTRL_ETH1), | 
 |     (0x1<<IX_FEATURECTRL_NPEA), | 
 |     (0x1<<IX_FEATURECTRL_NPEB), | 
 |     (0x1<<IX_FEATURECTRL_NPEC), | 
 |     (0x1<<IX_FEATURECTRL_PCI), | 
 |     (0x1<<IX_FEATURECTRL_ECC_TIMESYNC), | 
 |     (0x3<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT), | 
 |     (0x1<<IX_FEATURECTRL_UTOPIA_PHY_LIMIT_BIT2), /* NOT TO BE USED */ | 
 |     (0x1<<IX_FEATURECTRL_USB_HOST_CONTROLLER), | 
 |     (0x1<<IX_FEATURECTRL_NPEA_ETH), | 
 |     (0x1<<IX_FEATURECTRL_NPEB_ETH), | 
 |     (0x1<<IX_FEATURECTRL_RSA), | 
 |     (0x3<<IX_FEATURECTRL_XSCALE_MAX_FREQ), | 
 |     (0x1<<IX_FEATURECTRL_XSCALE_MAX_FREQ_BIT2) | 
 | }; | 
 | #endif /* __ixp42X */ | 
 |  | 
 | /** | 
 |  * Forward declaration | 
 |  */ | 
 | PRIVATE | 
 | void ixFeatureCtrlExpMap(void); | 
 |  | 
 | PRIVATE  | 
 | void ixFeatureCtrlSwConfigurationInit(void); | 
 |  | 
 | /** | 
 |  * Function to map EXP_CONFIG space | 
 |  */ | 
 | PRIVATE | 
 | void ixFeatureCtrlExpMap(void) | 
 | { | 
 |     UINT32 expCfgBaseAddress = 0; | 
 |  | 
 |     /* If the EXP Configuration space has already been mapped then | 
 |      * return */ | 
 |     if (ixFeatureCtrlExpCfgRegionMapped == TRUE) | 
 |     { | 
 | 	return; | 
 |     } | 
 |  | 
 |     /* Map (get virtual address) for the EXP_CONFIG space */ | 
 |     expCfgBaseAddress = (UINT32) | 
 | 	(IX_OSAL_MEM_MAP(IX_OSAL_IXP400_EXP_BUS_REGS_PHYS_BASE, | 
 | 			   IX_OSAL_IXP400_EXP_REG_MAP_SIZE)); | 
 |  | 
 |     /* Assert that the mapping operation succeeded */ | 
 |     IX_OSAL_ASSERT(expCfgBaseAddress); | 
 |  | 
 |     /* Set the address of the Feature register */ | 
 |     ixFeatureCtrlRegister = | 
 | 	(VUINT32 *) (expCfgBaseAddress + IX_FEATURE_CTRL_REG_OFFSET); | 
 |  | 
 |     /* Mark the fact that the EXP_CONFIG space has already been mapped */ | 
 |     ixFeatureCtrlExpCfgRegionMapped = TRUE; | 
 | } | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlSwConfigurationInit | 
 |  * This function will only initialize software configuration once. | 
 |  */ | 
 | PRIVATE void ixFeatureCtrlSwConfigurationInit(void) | 
 | { | 
 |   UINT32 i; | 
 |   if (FALSE == swConfigurationFlag) | 
 |   { | 
 |     for (i=0; i<IX_FEATURECTRL_SWCONFIG_MAX ; i++) | 
 |     { | 
 |         /* By default, all software configuration are enabled */ | 
 |         swConfiguration[i]= TRUE ; | 
 |     } | 
 |     /*Make sure this function only initializes swConfiguration[] once*/ | 
 |     swConfigurationFlag = TRUE ; | 
 |   }   | 
 | } | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlRead | 
 |  */ | 
 | IxFeatureCtrlReg  | 
 | ixFeatureCtrlRead (void) | 
 | { | 
 |     IxFeatureCtrlReg result; | 
 |  | 
 | #if CPU!=SIMSPARCSOLARIS | 
 |     /* Read the feature control register */ | 
 |     IX_FEATURE_CTRL_READ(result); | 
 |     return result; | 
 | #else | 
 |     /* Return an invalid value for VxWorks simulation */ | 
 |     result = 0xFFFFFFFF; | 
 |     return result; | 
 | #endif | 
 | } | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlWrite | 
 |  */ | 
 | void | 
 | ixFeatureCtrlWrite (IxFeatureCtrlReg expUnitReg) | 
 | { | 
 | #if CPU!=SIMSPARCSOLARIS | 
 |     /* Write value to feature control register */ | 
 |     IX_FEATURE_CTRL_WRITE(expUnitReg); | 
 | #endif | 
 | } | 
 |  | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlHwCapabilityRead | 
 |  */ | 
 | IxFeatureCtrlReg | 
 | ixFeatureCtrlHwCapabilityRead (void) | 
 | {  | 
 |   IxFeatureCtrlReg currentReg, hwCapability; | 
 |    | 
 |   /* Capture a copy of feature control register */ | 
 |   currentReg = ixFeatureCtrlRead();  | 
 |  | 
 |   /* Try to enable all hardware components.  | 
 |    * Only software disable hardware can be enabled again */ | 
 |   ixFeatureCtrlWrite(0); | 
 |    | 
 |   /* Read feature control register to know the hardware capability. */  | 
 |   hwCapability = ixFeatureCtrlRead(); | 
 |       | 
 |   /* Restore initial feature control value */ | 
 |   ixFeatureCtrlWrite(currentReg); | 
 |  | 
 |   /* return Hardware Capability */ | 
 |   return hwCapability;   | 
 | } | 
 |  | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlComponentCheck | 
 |  */ | 
 | IX_STATUS  | 
 | ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType) | 
 | { | 
 |   IxFeatureCtrlReg expUnitReg;  | 
 |   UINT32 mask = 0; | 
 |  | 
 |   /* Lookup mask of component */ | 
 |   mask=componentMask[componentType]; | 
 |  | 
 |   /* Check if mask is available or not */ | 
 |   if(IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE == mask) | 
 |   { | 
 |       return IX_FEATURE_CTRL_COMPONENT_DISABLED; | 
 |   } | 
 |  | 
 |   if(IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE == mask) | 
 |   { | 
 |       return IX_FEATURE_CTRL_COMPONENT_ENABLED; | 
 |   } | 
 |  | 
 |   /* Read feature control register to know current hardware capability. */  | 
 |   expUnitReg = ixFeatureCtrlRead(); | 
 |  | 
 |   /* For example: To check for Hashing Coprocessor (bit-2)  | 
 |    *                   expUniteg    = 0x0010 | 
 |    *                  ~expUnitReg   = 0x1101  | 
 |    *                  componentType = 0x0100 | 
 |    *    ~expUnitReg & componentType = 0x0100 (Not zero)                       | 
 |    */ | 
 |   | 
 |   /*  | 
 |    * Inverse the bit value because available component is 0 in value  | 
 |    */ | 
 |   expUnitReg = ~expUnitReg ; | 
 |  | 
 |   if (expUnitReg & mask) | 
 |   { | 
 |      return (IX_FEATURE_CTRL_COMPONENT_ENABLED); | 
 |   }    | 
 |   else | 
 |   {   | 
 |      return (IX_FEATURE_CTRL_COMPONENT_DISABLED); | 
 |   }  | 
 | } | 
 |  | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlProductIdRead | 
 |  */ | 
 | IxFeatureCtrlProductId | 
 | ixFeatureCtrlProductIdRead () | 
 | { | 
 | #if CPU!=SIMSPARCSOLARIS | 
 |   IxFeatureCtrlProductId  pdId = 0 ; | 
 |     | 
 |   /* Use ARM instruction to move register0 from coprocessor to ARM register */  | 
 |      | 
 | #ifndef __wince | 
 |     __asm__("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(pdId) :); | 
 | #else | 
 |        | 
 | #ifndef IN_KERNEL | 
 |         BOOL  mode; | 
 | #endif | 
 |     extern  IxFeatureCtrlProductId AsmixFeatureCtrlProductIdRead(); | 
 |      | 
 | #ifndef IN_KERNEL | 
 |     mode = SetKMode(TRUE); | 
 | #endif | 
 |     pdId = AsmixFeatureCtrlProductIdRead(); | 
 | #ifndef IN_KERNEL | 
 |     SetKMode(mode); | 
 | #endif | 
 |  | 
 | #endif | 
 |   return (pdId); | 
 | #else | 
 |   /* Return an invalid value for VxWorks simulation */ | 
 |   return 0xffffffff; | 
 | #endif | 
 | } | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlDeviceRead | 
 |  */ | 
 | IxFeatureCtrlDeviceId | 
 | ixFeatureCtrlDeviceRead () | 
 | { | 
 |   return ((ixFeatureCtrlProductIdRead() >> IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET)  | 
 |              & IX_FEATURE_CTRL_DEVICE_TYPE_MASK); | 
 | } /* End function ixFeatureCtrlDeviceRead */ | 
 |  | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlSwConfigurationCheck | 
 |  */ | 
 | IX_STATUS | 
 | ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType) | 
 | { | 
 |   if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)   | 
 |   { | 
 |      ixOsalLog(IX_OSAL_LOG_LVL_WARNING,  | 
 |                IX_OSAL_LOG_DEV_STDOUT, | 
 |                "FeatureCtrl: Invalid software configuraiton input.\n", | 
 |                0, 0, 0, 0, 0, 0);   | 
 |  | 
 |      return IX_FEATURE_CTRL_SWCONFIG_DISABLED; | 
 |   } | 
 |  | 
 |   /* The function will only initialize once. */ | 
 |   ixFeatureCtrlSwConfigurationInit(); | 
 |    | 
 |   /* Check and return software configuration */ | 
 |   return  ((swConfiguration[(UINT32)swConfigType] == TRUE) ? IX_FEATURE_CTRL_SWCONFIG_ENABLED: IX_FEATURE_CTRL_SWCONFIG_DISABLED); | 
 | } | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlSwConfigurationWrite | 
 |  */ | 
 | void | 
 | ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled) | 
 | { | 
 |   if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX)   | 
 |   { | 
 |      ixOsalLog(IX_OSAL_LOG_LVL_WARNING,  | 
 |                IX_OSAL_LOG_DEV_STDOUT, | 
 |                "FeatureCtrl: Invalid software configuraiton input.\n", | 
 |                0, 0, 0, 0, 0, 0);   | 
 |  | 
 |      return; | 
 |   } | 
 |  | 
 |   /* The function will only initialize once. */ | 
 |   ixFeatureCtrlSwConfigurationInit(); | 
 |    | 
 |   /* Write software configuration */ | 
 |   swConfiguration[(UINT32)swConfigType]=enabled ; | 
 | } | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlIxp400SwVersionShow | 
 |  */ | 
 | void | 
 | ixFeatureCtrlIxp400SwVersionShow (void) | 
 | { | 
 |     printf ("\nIXP400 Software Release %s %s\n\n", IX_VERSION_ID, IX_VERSION_INTERNAL_ID); | 
 |  | 
 | } | 
 |  | 
 | /** | 
 |  * Function definition: ixFeatureCtrlSoftwareBuildGet | 
 |  */ | 
 | IxFeatureCtrlBuildDevice | 
 | ixFeatureCtrlSoftwareBuildGet (void) | 
 | { | 
 |     #ifdef __ixp42X | 
 |     return IX_FEATURE_CTRL_SW_BUILD_IXP42X; | 
 |     #else | 
 |     return IX_FEATURE_CTRL_SW_BUILD_IXP46X; | 
 |     #endif | 
 | } |