Exemplo n.º 1
0
/**
* Sets the target CPU for the interrupt of a peripheral
*
* @param	InstancePtr is a pointer to the instance to be worked on.
* @param	Cpu_Id is a CPU number for which the interrupt has to be targeted
* @param	Int_Id is the IRQ source number to modify
*
* @return	None.
*
* @note		None
*
*****************************************************************************/
void XScuGic_InterruptMaptoCpu(XScuGic *InstancePtr, u8 Cpu_Id, u32 Int_Id)
{
	u32 RegValue, Offset;
	RegValue = XScuGic_DistReadReg(InstancePtr,
			XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id));

	Offset =  (Int_Id & 0x3);

	RegValue = (RegValue | (~(0xFF << (Offset*8))) );
	RegValue |= ((Cpu_Id) << (Offset*8));

	XScuGic_DistWriteReg(InstancePtr,
						 XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
						 RegValue);
}
Exemplo n.º 2
0
/**
*
* DistInit initializes the distributor of the GIC. The
* initialization entails:
*
* - Write the trigger mode, priority and target CPU
* - All interrupt sources are disabled
* - Enable the distributor
*
* @param	InstancePtr is a pointer to the XScuGic instance.
* @param	CpuID is the Cpu ID to be initialized.
*
* @return	None
*
* @note		None.
*
******************************************************************************/
static void DistInit(XScuGic_Config *Config, u32 CpuID)
{
	u32 Int_Id;

#if USE_AMP==1
	#warning "Building GIC for AMP"

	/*
	 * The distrubutor should not be initialized by FreeRTOS in the case of
	 * AMP -- it is assumed that Linux is the master of this device in that
	 * case.
	 */
	return;
#endif

	XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET, 0UL);

	/*
	 * Set the security domains in the int_security registers for non-secure
	 * interrupts. All are secure, so leave at the default. Set to 1 for
	 * non-secure interrupts.
	 */


	/*
	 * For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
	 */

	/*
	 * 1. The trigger mode in the int_config register
	 * Only write to the SPI interrupts, so start at 32
	 */
	for (Int_Id = 32; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=16) {
	/*
	 * Each INT_ID uses two bits, or 16 INT_ID per register
	 * Set them all to be level sensitive, active HIGH.
	 */
		XScuGic_WriteReg(Config->DistBaseAddress,
			XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id), 0UL);
	}


#define DEFAULT_PRIORITY	0xa0a0a0a0UL
	for (Int_Id = 0; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=4) {
		/*
		 * 2. The priority using int the priority_level register
		 * The priority_level and spi_target registers use one byte per
		 * INT_ID.
		 * Write a default value that can be changed elsewhere.
		 */
		XScuGic_WriteReg(Config->DistBaseAddress,
				XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
				DEFAULT_PRIORITY);
	}

	for (Int_Id = 32; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=4) {
		/*
		 * 3. The CPU interface in the spi_target register
		 * Only write to the SPI interrupts, so start at 32
		 */
		CpuID |= CpuID << 8;
		CpuID |= CpuID << 16;

		XScuGic_WriteReg(Config->DistBaseAddress,
 				XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), CpuID);
	}

	for (Int_Id = 0; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=32) {
	/*
	 * 4. Enable the SPI using the enable_set register. Leave all disabled
	 * for now.
	 */
		XScuGic_WriteReg(Config->DistBaseAddress,
		XSCUGIC_ENABLE_DISABLE_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET,
		Int_Id),
		0xFFFFFFFFUL);

	}

	XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET,
						XSCUGIC_EN_INT_MASK);

}
Exemplo n.º 3
0
/**
*
* Hardware initialization.
*
* @return   none
*
*****************************************************************************/
void hal_hardware_init(void)
{
    cyg_uint32 dw_i, dwCPUID;
    
    // -------- Ininializing GIC -------------------------------------------
    
    // Connect GIC to CORE0
    dwCPUID = 1;
    
    HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + XSCUGIC_DIST_EN_OFFSET, 0UL);
    
    // For the Shared Peripheral Interrupts INT_ID[MAX..32], set:

    //
    // 1. The trigger mode in the int_config register
    // Only write to the SPI interrupts, so start at 32
    //
    for (dw_i = 32; dw_i < XSCUGIC_MAX_NUM_INTR_INPUTS; dw_i += 16) {
        //
        // Each INT_ID uses two bits, or 16 INT_ID per register
        // Set them all to be level sensitive, active HIGH.
        //
        HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + 
                    XSCUGIC_INT_CFG_OFFSET_CALC(dw_i),
                    0UL);
    }
    
    for (dw_i = 0; dw_i < XSCUGIC_MAX_NUM_INTR_INPUTS; dw_i += 4) {
        //
        // 2. The priority using int the priority_level register
        // The priority_level and spi_target registers use one byte per
        // INT_ID.
        // Write a default value that can be changed elsewhere.
        //
        HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + 
                    XSCUGIC_PRIORITY_OFFSET_CALC(dw_i),
                    DEFAULT_PRIORITY);
    }
    
    for (dw_i = 32; dw_i < XSCUGIC_MAX_NUM_INTR_INPUTS; dw_i += 4) {
        //
        // 3. The CPU interface in the spi_target register
        // Only write to the SPI interrupts, so start at 32
        //
        dwCPUID |= dwCPUID << 8;
        dwCPUID |= dwCPUID << 16;

        HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + 
                     XSCUGIC_SPI_TARGET_OFFSET_CALC(dw_i),
                     dwCPUID);
    }

    for (dw_i = 0; dw_i < XSCUGIC_MAX_NUM_INTR_INPUTS; dw_i += 32) {
        //
        // 4. Enable the SPI using the enable_set register. Leave all
        // disabled for now.
        //
        HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + 
        XSCUGIC_ENABLE_DISABLE_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, dw_i),
            0xFFFFFFFFUL);

    }

    HAL_WRITE_UINT32(XC7Z_SCUGIC_DIST_BASEADDR + XSCUGIC_DIST_EN_OFFSET,
                        XSCUGIC_EN_INT_MASK);
                        
    //
    // Program the priority mask of the CPU using the Priority mask register
    //
    HAL_WRITE_UINT32(XC7Z_SCUGIC_CPU_BASEADDR + XSCUGIC_CPU_PRIOR_OFFSET, 0xF0);
    
    //
    // If the CPU operates in both security domains, set parameters in the
    // control_s register.
    // 1. Set FIQen=1 to use FIQ for secure interrupts,
    // 2. Program the AckCtl bit
    // 3. Program the SBPR bit to select the binary pointer behavior
    // 4. Set EnableS = 1 to enable secure interrupts
    // 5. Set EnbleNS = 1 to enable non secure interrupts
    //

    //
    // If the CPU operates only in the secure domain, setup the
    // control_s register.
    // 1. Set FIQen=1,
    // 2. Set EnableS=1, to enable the CPU interface to signal secure interrupts.
    // Only enable the IRQ output unless secure interrupts are needed.
    //
    HAL_WRITE_UINT32(XC7Z_SCUGIC_CPU_BASEADDR + XSCUGIC_CONTROL_OFFSET, 0x07);  

#ifdef HAL_PLF_HARDWARE_INIT
    // Perform any platform specific initializations
    HAL_PLF_HARDWARE_INIT();
#endif

#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
    HAL_DCACHE_ENABLE();        // Enable DCache
#endif
#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
    HAL_ICACHE_ENABLE();        // Enable ICache
#endif

    // Set up eCos/ROM interfaces
    hal_if_init();

	HAL_CLOCK_INITIALIZE(CYGNUM_HAL_RTC_PERIOD);

#ifdef CYGPKG_HAL_SMP_SUPPORT
    cyg_uint32 reg;
    /* Disable the distributor */
    HAL_READ_UINT32(XC7Z_ICD_DCR_BASEADDR, reg);
    reg &= ~(0x2);
    HAL_WRITE_UINT32(XC7Z_ICD_DCR_BASEADDR, reg);

    /* Clear pending interrupts */
    HAL_WRITE_UINT32(XC7Z_ICD_ICPR0_BASEADDR, 0xffffffff);
    HAL_WRITE_UINT32(XC7Z_ICD_ICPR1_BASEADDR, 0xffffffff);
    HAL_WRITE_UINT32(XC7Z_ICD_ICPR2_BASEADDR, 0xffffffff);

    /* Re-enable the distributor */
    HAL_READ_UINT32(XC7Z_ICD_DCR_BASEADDR, reg);
    reg |= 0x2;
    HAL_WRITE_UINT32(XC7Z_ICD_DCR_BASEADDR, reg);

    /* Start the cpu */
    cyg_hal_smp_init();
    hal_interrupt_init_cpu();
    cyg_hal_smp_cpu_start_first();
#endif
}
Exemplo n.º 4
0
/**
*
* DistributorInit initializes the distributor of the GIC. The
* initialization entails:
*
* - Write the trigger mode, priority and target CPU
* - All interrupt sources are disabled
* - Enable the distributor
*
* @param	InstancePtr is a pointer to the XScuGic instance.
* @param	CpuID is the Cpu ID to be initialized.
*
* @return	None
*
* @note		None.
*
******************************************************************************/
static void DistributorInit(XScuGic *InstancePtr, u32 CpuID)
{
	u32 Int_Id;
	u32 LocalCpuID = CpuID;

#if USE_AMP==1
	#warning "Building GIC for AMP"
#ifdef ARMR5
    u32 RegValue;

	/*
	 * The overall distributor should not be initialized in AMP case where
	 * another CPU is taking care of it.
	 */
	LocalCpuID |= LocalCpuID << 8U;
	LocalCpuID |= LocalCpuID << 16U;
	for (Int_Id = 32U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+4U) {
		RegValue = XScuGic_DistReadReg(InstancePtr,
						XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id));
		RegValue |= LocalCpuID;
		XScuGic_DistWriteReg(InstancePtr,
				     XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
				     RegValue);
	}
#endif
	return;
#endif

	Xil_AssertVoid(InstancePtr != NULL);
	XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, 0U);

	/*
	 * Set the security domains in the int_security registers for
	 * non-secure interrupts
	 * All are secure, so leave at the default. Set to 1 for non-secure
	 * interrupts.
	 */

	/*
	 * For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
	 */

	/*
	 * 1. The trigger mode in the int_config register
	 * Only write to the SPI interrupts, so start at 32
	 */
	for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id=Int_Id+16U) {
		/*
		 * Each INT_ID uses two bits, or 16 INT_ID per register
		 * Set them all to be level sensitive, active HIGH.
		 */
		XScuGic_DistWriteReg(InstancePtr,
					XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
					0U);
	}


#define DEFAULT_PRIORITY    0xa0a0a0a0U
	for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id=Int_Id+4U) {
		/*
		 * 2. The priority using int the priority_level register
		 * The priority_level and spi_target registers use one byte per
		 * INT_ID.
		 * Write a default value that can be changed elsewhere.
		 */
		XScuGic_DistWriteReg(InstancePtr,
					XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
					DEFAULT_PRIORITY);
	}

	for (Int_Id = 32U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+4U) {
		/*
		 * 3. The CPU interface in the spi_target register
		 * Only write to the SPI interrupts, so start at 32
		 */
		LocalCpuID |= LocalCpuID << 8U;
		LocalCpuID |= LocalCpuID << 16U;

		XScuGic_DistWriteReg(InstancePtr,
				     XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
				     LocalCpuID);
	}

	for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+32U) {
		/*
		 * 4. Enable the SPI using the enable_set register. Leave all
		 * disabled for now.
		 */
		XScuGic_DistWriteReg(InstancePtr,
		XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, Int_Id),
			0xFFFFFFFFU);

	}

	XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET,
						XSCUGIC_EN_INT_MASK);

}