/******************************************************************************* * * armGicIntReroute - reroute interrupt to specified CPU * * This routine reroutes device interrupt to requested CPU. Note that the cpu is * specified in a cpuset_t type, and this would allow for multiple cpus to be * bundled with the interrupt. Multicore processor can ensure that only one CPU * will be triggered if the interrupt occurs. * * RETURNS: OK if operation successful else ERROR * * ERRNO: N/A */ STATUS armGicIntReroute ( UINT32 vectorId, cpuset_t destCpu ) { UINT32 OlddestCpu; UINT32 TgCpuMask; int key; if((vectorId < GIC_SPI_START) || (vectorId > armGicLinesNum)) return ERROR; else { if(destCpu >= GIC_CPU_NUM ) return ERROR; else { key = intCpuLock(); OlddestCpu = *GIC_CPUTarg(vectorId); TgCpuMask =~ (BYTE_MASK << REG_BYTE(vectorId)); /*get byte mask*/ OlddestCpu &= TgCpuMask; /* only change one btye corresponding to vector*/ destCpu = destCpu << REG_BYTE(vectorId); *GIC_CPUTarg(vectorId) = OlddestCpu | destCpu; intCpuUnlock(key); } } return OK; }
LOCAL STATUS armGicLvlChg ( int vector, int level /* new interrupt level */ ) { int Lvlmask; int OldLevel; int key; /* * Validity check for level. Note that for PPI, we always return * ERROR, as PPI is not used. */ if ((vector >= SGI_INT_MAX && vector < GIC_SPI_START) || (vector >= (int)armGicLinesNum )) return ERROR; else { /*32 levels are supported maximumly*/ if(level >= GIC_LEVEL_MAX - 1) return ERROR; else { key = intCpuLock(); OldLevel = *GIC_Prio(vector); Lvlmask =~ (BYTE_MASK << REG_BYTE(vector)); OldLevel &= Lvlmask; /* only change one btye corresponding to vector*/ /*level from 0-248,in step of 8,total 32 levels*/ level = (level << 3) << REG_BYTE(vector); *GIC_Prio(vector) = (OldLevel | level); intCpuUnlock(key); } } return OK; }
STATUS sysClkConnect(FUNCPTR routine,int arg) { int key; key = intCpuLock (); timerRoutine = (CLK_FUNCPTR)routine; timerArg = arg; return OK; }
LOCAL STATUS armGicLvlDisable ( int VecId /* level to be disabled */ ) { int key; if ((VecId >= 0) && (VecId < SGI_INT_MAX)) return OK; /*SGI interrupt can not be enabled*/ if (VecId < GIC_SPI_START || VecId >= (int)armGicLinesNum) return ERROR; key = intCpuLock (); *GIC_IntEnClr(VecId) = BIT(VecId); intCpuUnlock (key); return OK; }
/******************************************************************************* * * armGicTriSet - set the interrupt trigger * * RETURNS: OK or ERROR if parameter is invalid. * * ERRNO: N/A */ int armGicSetType(UINT32 irq, enum tri_mode type) { UINT32 enablemask = 1 << (irq % 32); /*UINT32 enableoff = (irq / 32) * 4;*/ UINT32 confmask = 0x2 << ((irq % 16) * 2); /*UINT32 confoff = (irq / 16) * 4;*/ UINT32 enabled = 0; UINT32 oldLev,key; /* Interrupt configuration for SGIs can't be changed */ if (irq < 16) return ERROR; if (type != LEVEL && type !=EDGE) return ERROR; //raw_spin_lock(&irq_controller_lock); key = intCpuLock (); oldLev = *GIC_Config(irq) ; //val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type == LEVEL) oldLev &= ~confmask; else if (type == EDGE) oldLev |= confmask; /* * As recommended by the spec, disable the interrupt before changing * the configuration */ if (*GIC_IntEnable(irq) & enablemask) { *GIC_IntEnClr(irq) = enablemask; enabled = 1; } *GIC_Config(irq) = oldLev; if (enabled) *GIC_IntEnable(irq) = enablemask; intCpuUnlock(key); return 0; }
LOCAL STATUS armGicLvlEnable ( int VecId /* level to be enabled */ ) { int key; if ((VecId >= 0) && (VecId < SGI_INT_MAX)) return OK; /*SGI interrupt is enabled*/ //ppi doesn't need to enable ? if (VecId < GIC_SPI_START || VecId >= (int)armGicLinesNum ) return ERROR; key = intCpuLock (); /* LOCK INTERRUPTS */ *GIC_IntEnable(VecId) = BIT(VecId); /* enable interrupt */ intCpuUnlock (key); /* UNLOCK INTERRUPTS */ return OK; }
/****************************************************************************** ** Function: CFE_PSP_Restart() ** ** Purpose: ** Provides a common interface to reset the processor. This implementation ** may need to be customized for missions with custom reset requirements. ** ** Arguments: ** reset_type : Type of reset. ** ** Return: ** (none) */ void CFE_PSP_Restart(uint32 reset_type) { OS_printf("\nWarning: CFE PSP Restart with reset type %u!\n\n", reset_type); /* ** Delay for second or two, allow the print statement to send */ taskDelay(100); #ifndef _WRS_VX_SMP /* Changed for SMP API compatability. */ taskLock(); intLock(); #else /* Note: This only locks the current CPU core. Other cores * are still active and may continue to access system resources * or service the watchdog on an SMP system. */ taskCpuLock(); intCpuLock(); #endif if ( reset_type == CFE_ES_POWERON_RESET ) { CFE_PSP_ReservedMemoryPtr->bsp_reset_type = CFE_ES_POWERON_RESET; /* ** The sysToMonitor function flushes caches for us * * reboot(BOOT_CLEAR); */ /* ** Use the watchdog timer to assert a reset */ CFE_PSP_WatchdogEnable(); for(;;) { /* ** Set the current count value to something small */ CFE_PSP_WatchdogSet(CFE_PSP_WATCHDOG_MIN); /* ** Wait for the watchdog to expire... */ taskDelay(100); } } else { CFE_PSP_ReservedMemoryPtr->bsp_reset_type = CFE_ES_PROCESSOR_RESET; /* ** The sysToMonitor function flushes caches for us * * reboot(0); */ /* ** Use the watchdog timer to assert a reset */ CFE_PSP_WatchdogEnable(); for(;;) { /* ** Set the current count value to something small */ CFE_PSP_WatchdogSet(CFE_PSP_WATCHDOG_MIN); /* ** Wait for the watchdog to expire... */ taskDelay(100); } } }