IX_STATUS ixParityENAccEbcPEParityInterruptClear ( IxParityENAccEbcPEParityConfigSource ixEbcParityErrSrc) { /* Clear off Parity Error due to Inbound Write by an External Master? */ if (IXP400_PARITYENACC_PE_EBC_EXTMST == ixEbcParityErrSrc) { /* Write '1' to clear off the InBound Parity Error Status */ IXP400_PARITYENACC_REG_BIT_SET( ixParityENAccEbcPEConfig.ebcPERegisters.expParityStatus, IXP400_PARITYENACC_EBC_PARITY_STATUS_INERRSTS); return IX_SUCCESS; } /* end of if */ /* Clear off Parity Error due to Outbound Read by EBC? */ if (IXP400_PARITYENACC_PE_EBC_CS == ixEbcParityErrSrc) { /* Write '1' to clear off the Outbound Parity Error Status */ IXP400_PARITYENACC_REG_BIT_SET( ixParityENAccEbcPEConfig.ebcPERegisters.expParityStatus, IXP400_PARITYENACC_EBC_PARITY_STATUS_OUTERRSTS); return IX_SUCCESS; } /* end of if */ return IX_FAIL; } /* end of ixParityENAccEbcPEParityInterruptClear() function */
/* Set parity error interrupt status to clear */ void ixParityENAccPbcPEParityErrorStatusClear (void) { /* Update the PCI Controller PCI Config SRCR register */ IXP400_PARITYENACC_REG_WRITE(ixParityENAccPbcPEConfig.pbcPERegisters.pciCrpAdCbe, IXP400_PARITYENACC_PBC_PCICSR_SRCR_WRITE); IXP400_PARITYENACC_REG_WRITE(ixParityENAccPbcPEConfig.pbcPERegisters.pciCrpWdata, ixParityENAccPbcPEConfig.pbcParityErrorStatus.pciSrcrValue); /* Clear off Parity Error Interrupt Status by writing '1' onto PPE bit */ IXP400_PARITYENACC_REG_BIT_SET(ixParityENAccPbcPEConfig.pbcPERegisters.pciIsr, IXP400_PARITYENACC_PBC_ISR_PPE); } /* end of ixParityENAccPbcPEParityErrorStatusClear() function */
IX_STATUS ixParityENAccMcuPEInit (IxParityENAccInternalCallback ixMcuPECallback) { UINT32 virtualBaseAddr = 0; /* Verify parameters */ if ((IxParityENAccInternalCallback)NULL == ixMcuPECallback) { return IX_FAIL; } /* end of if */ /* Memory mapping of the MCU registers */ if ((UINT32)NULL == (virtualBaseAddr = (UINT32) IX_OSAL_MEM_MAP ( IXP400_PARITYENACC_MCU_BASEADDR, IXP400_PARITYENACC_MCU_MEMMAP_SIZE))) { return IX_FAIL; } /* end of if */ /* Virtual Addresses assignment for MCU Registers */ ixParityENAccMcuPEConfig.mcuPERegisters.mcuEccr = virtualBaseAddr + IXP400_PARITYENACC_MCU_ECCR_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuElog0 = virtualBaseAddr + IXP400_PARITYENACC_MCU_ELOG0_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuElog1 = virtualBaseAddr + IXP400_PARITYENACC_MCU_ELOG1_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuEcar0 = virtualBaseAddr + IXP400_PARITYENACC_MCU_ECAR0_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuEcar1 = virtualBaseAddr + IXP400_PARITYENACC_MCU_ECAR1_OFFSET; ixParityENAccMcuPEConfig.mcuPERegisters.mcuMcisr = virtualBaseAddr + IXP400_PARITYENACC_MCU_MCISR_OFFSET; /* Register main module internal callback routine */ ixParityENAccMcuPEConfig.mcuPECallback = ixMcuPECallback; /* Interrupt Service Routine Info for debug purpose only */ ixParityENAccMcuPEConfig.mcuIsrInfo.mcuInterruptId = IRQ_IXP400_INTC_PARITYENACC_MCU; ixParityENAccMcuPEConfig.mcuIsrInfo.mcuIsr = ixParityENAccMcuPEIsr; /* * Disable parity error detection for both single and multi-bit ECC * and correction of single bit parity using ECC */ IXP400_PARITYENACC_REG_BIT_CLEAR( ixParityENAccMcuPEConfig.mcuPERegisters.mcuEccr, IXP400_PARITYENACC_MCU_SBIT_CORRECT_MASK | IXP400_PARITYENACC_MCU_MBIT_REPORT_MASK | IXP400_PARITYENACC_MCU_SBIT_REPORT_MASK); /* Clear off the pending interrupts, if any */ IXP400_PARITYENACC_REG_BIT_SET( ixParityENAccMcuPEConfig.mcuPERegisters.mcuMcisr, IXP400_PARITYENACC_MCU_ERROR0_MASK | IXP400_PARITYENACC_MCU_ERROR1_MASK | IXP400_PARITYENACC_MCU_ERRORN_MASK); /* Install MCU Interrupt Service Routine after disabling the interrupt */ { INT32 lockKey = ixOsalIrqLock(); if ((IX_SUCCESS != ixOsalIrqBind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_MCU, (IxOsalVoidFnVoidPtr) ixParityENAccMcuPEIsr, (void *) NULL)) || (IX_SUCCESS != ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_MCU_PARITY_INTERRUPT))) { ixOsalIrqUnlock(lockKey); IX_OSAL_MEM_UNMAP (virtualBaseAddr); return IX_FAIL; } /* end of if */ ixOsalIrqUnlock(lockKey); } return IX_SUCCESS; } /* end of ixParityENAccMcuPEInit() function */
IX_STATUS ixParityENAccPbcPEInit(IxParityENAccInternalCallback ixPbcPECallback) { UINT32 pbcVirtualBaseAddr = 0; register IxParityENAccPbcPERegisters *pbcPERegisters = &ixParityENAccPbcPEConfig.pbcPERegisters; /* Verify parameters */ if ((IxParityENAccInternalCallback)NULL == ixPbcPECallback) { return IX_FAIL; } /* end of if */ /* Memory mapping of the PBC registers */ if ((UINT32)NULL == (pbcVirtualBaseAddr = (UINT32) IX_OSAL_MEM_MAP ( IXP400_PARITYENACC_PBC_PCICSR_BASEADDR, IXP400_PARITYENACC_PBC_PCICSR_MEMMAP_SIZE))) { return IX_FAIL; } /* end of if */ ixPbcVirtualBaseAddr = pbcVirtualBaseAddr; /* Virtual Addresses assignment for PBC Control and Status Registers */ pbcPERegisters->pciCrpAdCbe = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_CRP_AD_CBE_OFFSET; pbcPERegisters->pciCrpWdata = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_CRP_WDATA_OFFSET; pbcPERegisters->pciCrpRdata = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_CRP_RDATA_OFFSET; pbcPERegisters->pciCsr = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_CSR_OFFSET; pbcPERegisters->pciIsr = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_ISR_OFFSET; pbcPERegisters->pciInten = pbcVirtualBaseAddr + IXP400_PARITYENACC_PBC_INTEN_OFFSET; /* Register main module internal callback routine */ ixParityENAccPbcPEConfig.pbcPECallback = ixPbcPECallback; /* Interrupt Service Routine Info for debug purpose */ ixParityENAccPbcPEConfig.pbcIsrInfo.pbcInterruptId = IRQ_IXP400_INTC_PARITYENACC_PBC; ixParityENAccPbcPEConfig.pbcIsrInfo.pbcIsr = ixParityENAccPbcPEIsr; /* Disable parity error detection */ /* Write '1' to clear-off the PPE bit */ IXP400_PARITYENACC_REG_BIT_SET( pbcPERegisters->pciIsr, IXP400_PARITYENACC_PBC_ISR_PPE); IXP400_PARITYENACC_REG_BIT_CLEAR( pbcPERegisters->pciInten, IXP400_PARITYENACC_PBC_INTEN_PPE); /* Install PBC Interrupt Service Routine */ { INT32 lockKey = ixOsalIrqLock(); if ((IX_SUCCESS != ixOsalIrqBind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_PBC, (IxOsalVoidFnVoidPtr) ixParityENAccPbcPEIsr, (void *) NULL)) || (IX_FAIL == ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_PBC_PARITY_INTERRUPT))) { ixOsalIrqUnlock(lockKey); IX_OSAL_MEM_UNMAP(pbcVirtualBaseAddr); return IX_FAIL; } /* end of if */ ixOsalIrqUnlock(lockKey); } return IX_SUCCESS; } /* end of ixParityENAccPbcPEInit() function */
IX_STATUS ixParityENAccPbcPEDetectionConfigure(IxParityENAccPbcPEConfigOption ixPbcPDCfg) { UINT32 pbcPDCfgStatus = 0; UINT32 pbcTmpPDCfgStatus = 0; int loopIdx = 0; /* Read the PCI Controller PCI Config SRCR register */ IXP400_PARITYENACC_REG_WRITE( ixParityENAccPbcPEConfig.pbcPERegisters.pciCrpAdCbe, IXP400_PARITYENACC_PBC_PCICSR_SRCR_READ); IXP400_PARITYENACC_REG_READ( ixParityENAccPbcPEConfig.pbcPERegisters.pciCrpRdata, &pbcPDCfgStatus); /* * Set/Clear the PER bit of SRCR register & * Enable/Disable Parity Error Notification */ if (IXP400_PARITYENACC_PE_ENABLE == ixPbcPDCfg) { /* Set the PER bit of SRCR register */ IXP400_PARITYENACC_VAL_BIT_SET(pbcPDCfgStatus, IXP400_PARITYENACC_PBC_PCICFG_SRCR_PER); /* Enable the PCI Parity Error Interrupt Notification */ IXP400_PARITYENACC_REG_BIT_SET( ixParityENAccPbcPEConfig.pbcPERegisters.pciInten, IXP400_PARITYENACC_PBC_INTEN_PPE); } /* else of if */ else { /* Clear the PER bit of SRCR register */ IXP400_PARITYENACC_VAL_BIT_CLEAR(pbcPDCfgStatus, IXP400_PARITYENACC_PBC_PCICFG_SRCR_PER); /* Disable the PCI Parity Error Interrupt Notification */ IXP400_PARITYENACC_REG_BIT_CLEAR( ixParityENAccPbcPEConfig.pbcPERegisters.pciInten, IXP400_PARITYENACC_PBC_INTEN_PPE); } /* end of if */ /* Write back the PCI Controller PCI Config SRCR register */ IXP400_PARITYENACC_REG_WRITE( ixParityENAccPbcPEConfig.pbcPERegisters.pciCrpAdCbe, IXP400_PARITYENACC_PBC_PCICSR_SRCR_WRITE); IXP400_PARITYENACC_REG_WRITE( ixParityENAccPbcPEConfig.pbcPERegisters.pciCrpWdata, pbcPDCfgStatus); loopIdx = 10; while (loopIdx--) { /* Verify that the configuration is successful or not */ IXP400_PARITYENACC_REG_WRITE( ixParityENAccPbcPEConfig.pbcPERegisters.pciCrpAdCbe, IXP400_PARITYENACC_PBC_PCICSR_SRCR_READ); IXP400_PARITYENACC_REG_READ( ixParityENAccPbcPEConfig.pbcPERegisters.pciCrpRdata, &pbcTmpPDCfgStatus); } if (TRUE == IXP400_PARITYENACC_VAL_BIT_CHECK(pbcPDCfgStatus, pbcTmpPDCfgStatus)) { /* Enable/Disable the corresponding interrupt at Interrupt Controller */ return (IXP400_PARITYENACC_PE_ENABLE == ixPbcPDCfg) ? ixParityENAccIcInterruptEnable( IXP400_PARITYENACC_INTC_PBC_PARITY_INTERRUPT) : ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_PBC_PARITY_INTERRUPT); } else { return IX_FAIL; } /* end of if */ } /* end of ixParityENAccPbcPEDetectionConfigure() function */