//------------------------------------------------------------------------------ // // Function: BSPIntrActiveIrq // // This function is called from interrupt handler to give BSP chance to // translate IRQ in case of secondary interrupt controller. // UINT32 BSPIntrActiveIrq(UINT32 irq) { UINT8 data; UINT32 doneIrq; OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+BSPIntrActiveIrq(%d)\r\n", irq)); switch(irq) { case IRQ_GPIO: // Check whether alarm happen if(OALRTCAlarmIntrHandler() == FALSE) { irq = OAL_INTR_IRQ_UNDEFINED; } // Acknowledge GPIO interrupt OUTREG32(&g_pVRC5477Regs->GIUINSTAT, 0xffffffff); // Re-enable IRQ_GPIO interrupt on VRC5477 doneIrq = IRQ_GPIO; OALIntrDoneIrqs(1, &doneIrq); break; case IRQ_INTC: // Read PIC1 interrupt OUTREG8(&g_pPIC1Regs->ctrl, 0x0E); data = INREG8(&g_pPIC1Regs->data) & 0x07; if (data != 2) { irq = IRQ_PIC_0 + data; SETREG8(&g_pPIC1Regs->mask, 1 << data); } else { // Read PIC2 interrupt OUTREG8(&g_pPIC2Regs->ctrl, 0x0E); data = INREG8(&g_pPIC2Regs->data) & 0x07; irq = IRQ_PIC_8 + data; SETREG8(&g_pPIC2Regs->mask, 1 << data); // End interrupt on PIC2 OUTREG8(&g_pPIC2Regs->ctrl, 0x20); } // End interrupt on PIC1 OUTREG8(&g_pPIC1Regs->ctrl, 0x20); // Re-enable IRQ_INTC interrupt on VRC5477 doneIrq = IRQ_INTC; OALIntrDoneIrqs(1, &doneIrq); break; } OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrActiveIrq(%d)\r\n", irq)); return irq; }
//------------------------------------------------------------------------------ // // Function: OEMInterruptDone // // OEMInterruptDone is called by the kernel when a device driver // calls InterruptDone(). The system is not preemtible when this // function is called. // VOID OEMInterruptDone(DWORD sysIntr) { OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OEMInterruptDone(%d)\r\n", sysIntr)); // Re-enable interrupts OALIntrDoneIrqs(1, &g_oalSysIntr2Irq[sysIntr]); OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptDone\r\n")); }
//------------------------------------------------------------------------------ // // Function: OEMSetAlarmTime // // Set the RTC alarm time. // BOOL OEMSetAlarmTime(SYSTEMTIME *pTime) { BOOL rc = FALSE; volatile S3C6400_RTC_REG *pRTCReg; UINT32 irq; if (pTime == NULL) goto cleanUp; OALMSG(OAL_RTC&&OAL_FUNC, ( L"+OEMSetAlarmTime(%d/%d/%d %d:%d:%d.%03d)\r\n", pTime->wMonth, pTime->wDay, pTime->wYear, pTime->wHour, pTime->wMinute, pTime->wSecond, pTime->wMilliseconds)); OALMSG(TRUE, ( L"+OEMSetAlarmTime(%d/%d/%d %d:%d:%d.%03d)\r\n", pTime->wMonth, pTime->wDay, pTime->wYear, pTime->wHour, pTime->wMinute, pTime->wSecond, pTime->wMilliseconds)); // Get uncached virtual address pRTCReg = (S3C6400_RTC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_RTC, FALSE); // Enable RTC control pRTCReg->RTCCON |= (1<<0); pRTCReg->ALMSEC = TO_BCD(pTime->wSecond); pRTCReg->ALMMIN = TO_BCD(pTime->wMinute); pRTCReg->ALMHOUR = TO_BCD(pTime->wHour); pRTCReg->ALMDATE = TO_BCD(pTime->wDay); pRTCReg->ALMMON = TO_BCD(pTime->wMonth); pRTCReg->ALMYEAR = TO_BCD(pTime->wYear - RTC_YEAR_DATUM); // Enable the RTC Alarm pRTCReg->RTCALM = 0x7f; // Disable RTC control. pRTCReg->RTCCON &= ~(1<<0); // Clear RTC Alarm Interrupt Pending pRTCReg->INTP |= (1<<1); // Enable and Clear RTC Alarm Interrupt irq = IRQ_RTC_ALARM; OALIntrDoneIrqs(1, &irq); // Done rc = TRUE; cleanUp: OALMSG(OAL_RTC&&OAL_FUNC, (L"-OEMSetAlarmTime(rc = %d)\r\n", rc)); return rc; }
//------------------------------------------------------------------------------ // // Function: OEMProfileTimerEnable // // This function is called by kernel to start kernel profiling timer. // VOID OEMProfileTimerEnable(DWORD interval) { BOOL enabled; UINT32 irq; OALMSG(TRUE, (L"+OEMProfileTimerEnable(%d)\r\n", interval)); // We can't enable timer second time if (g_profiler.enabled) return; // How many hi-res ticks per profiler hit g_profiler.countsPerHit = (g_oalTimer.countsPerMSec * interval)/1000; // Following code should not be interrupted enabled = INTERRUPTS_ENABLE(FALSE); // Configure profiling ISR callback function. g_pProfilerISR = OALProfileIntrHandler; // Obtain pointers to OST and INTC registers. // g_XllpOSTHandle.pOSTRegs = OALPAtoVA(BULVERDE_BASE_REG_PA_OST, FALSE); g_XllpOSTHandle.pINTCRegs = OALPAtoVA(BULVERDE_BASE_REG_PA_INTC, FALSE); // XLLI initializes oier and rtsr to zeroes, so no further // initialization needs to be done. Match timers and // alarms are disabled. // // Current usage of Match registers: // M0 - Scheduler // M1 - Touch Panel // M2 - Profiler // Update the compare register for the next profile hit. // XllpOstConfigureMatchReg( &g_XllpOSTHandle, MatchReg2, g_profiler.countsPerHit ); // Enable interrupts INTERRUPTS_ENABLE(enabled); irq = IRQ_OSMR2; OALIntrDoneIrqs(1, &irq); // Set flag g_profiler.enabled = TRUE; OALMSG(TRUE, (L"-OEMProfileTimerEnable\r\n")); }
//------------------------------------------------------------------------------ // // Function: OALProfileIntrHandler // // This is timer interrupt handler which replace default handler in time when // kernel profiling is active. It calls original interrupt handler in // appropriate times. // UINT32 OALProfileIntrHandler(UINT32 ra) { UINT32 irq; // Update the compare register for the next profile hit. ConfigureNextProfilerCount(g_profiler.countsPerHit); // First call profiler ProfilerHit(ra); // Enable interrupts irq = IRQ_TIMER2; OALIntrDoneIrqs(1, &irq); return(SYSINTR_NOP); }
//------------------------------------------------------------------------------ // // Function: OALProfileIntrHandler // // This is timer interrupt handler which replace default handler in time when // kernel profiling is active. It calls original interrupt handler in // appropriate times. // UINT32 OALProfileIntrHandler(UINT32 ra) { UINT32 irq; // Update the compare register for the next profile hit. XllpOstConfigureMatchReg( &g_XllpOSTHandle, MatchReg2, g_profiler.countsPerHit ); // First call profiler ProfilerHit(ra); // Enable interrupts irq = IRQ_OSMR2; OALIntrDoneIrqs(1, &irq); return SYSINTR_NOP; }
//------------------------------------------------------------------------------ // // Function: OEMSetAlarmTime // // Set the RTC alarm time. // BOOL OEMSetAlarmTime(SYSTEMTIME *pTime) { BOOL rc = FALSE; S3C2410X_RTC_REG *pRTCReg; UINT32 irq; OALMSG(OAL_RTC&&OAL_FUNC, ( L"+OEMSetAlarmTime(%d/%d/%d %d:%d:%d.%03d)\r\n", pTime->wMonth, pTime->wDay, pTime->wYear, pTime->wHour, pTime->wMinute, pTime->wSecond, pTime->wMilliseconds )); if (pTime == NULL) goto cleanUp; // Get uncached virtual address pRTCReg = OALPAtoVA(S3C2410X_BASE_REG_PA_RTC, FALSE); // Enable RTC control SETREG32(&pRTCReg->RTCCON, 1); OUTPORT32(&pRTCReg->ALMSEC, TO_BCD(pTime->wSecond)); OUTPORT32(&pRTCReg->ALMMIN, TO_BCD(pTime->wMinute)); OUTPORT32(&pRTCReg->ALMHOUR, TO_BCD(pTime->wHour)); OUTPORT32(&pRTCReg->ALMDATE, TO_BCD(pTime->wDay)); OUTPORT32(&pRTCReg->ALMMON, TO_BCD(pTime->wMonth)); OUTPORT32(&pRTCReg->ALMYEAR, TO_BCD(pTime->wYear - RTC_YEAR_DATUM)); // Enable the RTC alarm interrupt OUTPORT32(&pRTCReg->RTCALM, 0x7F); // Disable RTC control. CLRREG32(&pRTCReg->RTCCON, 1); // Enable/clear RTC interrupt irq = IRQ_RTC; OALIntrDoneIrqs(1, &irq); // Done rc = TRUE; cleanUp: OALMSG(OAL_RTC&&OAL_FUNC, (L"-OEMSetAlarmTime(rc = %d)\r\n", rc)); return rc; }
//------------------------------------------------------------------------------ // // Function: OEMInterruptDone // // OEMInterruptDone is called by the kernel when a device driver // calls InterruptDone(). The system is not preemtible when this // function is called. // VOID OEMInterruptDone(DWORD sysIntr) { const UINT32 *pIrqs; UINT32 count; //BOOL bPrevIntrState; //OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OEMInterruptDone(%d)\r\n", sysIntr)); // Make sure interrupts are disabled //bPrevIntrState = INTERRUPTS_ENABLE(FALSE); if (OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) { OALIntrDoneIrqs(count, pIrqs); } // Return interrupts to last state //INTERRUPTS_ENABLE(bPrevIntrState); //OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptDone\r\n")); }
//------------------------------------------------------------------------------ // // Function: OEMProfileTimerEnable // // This function is called by kernel to start kernel profiling timer. // VOID OEMProfileTimerEnable(DWORD interval) { BOOL enabled; UINT32 irq; OALMSG(TRUE, (L"+OEMProfileTimerEnable(%d)\r\n", interval)); // We can't enable timer second time if (g_profiler.enabled) return; // Obtain a pointer to the PWM registers. if (!g_pPWMRegs) { g_pPWMRegs = (S3C2450_PWM_REG *) OALPAtoVA(S3C2450_BASE_REG_PA_PWM, FALSE); } // How many hi-res ticks per profiler hit g_profiler.countsPerHit = (g_oalTimer.countsPerMSec * interval)/1000; // Following code should not be interrupted enabled = INTERRUPTS_ENABLE(FALSE); // Configure profiling ISR callback function. g_pProfilerISR = OALProfileIntrHandler; // Update the compare register for the next profile hit. ConfigureNextProfilerCount(g_profiler.countsPerHit); // Enable interrupts INTERRUPTS_ENABLE(enabled); irq = IRQ_TIMER2; OALIntrDoneIrqs(1, &irq); // Set flag g_profiler.enabled = TRUE; OALMSG(TRUE, (L"-OEMProfileTimerEnable\r\n")); }
//------------------------------------------------------------------------------ // // Function: OEMSetAlarmTime // // Set the RTC alarm time. // BOOL OEMSetAlarmTime(SYSTEMTIME *pTime) { BOOL rc = FALSE; volatile S3C6410_RTC_REG *pRTCReg; UINT32 irq; BOOL csEnter; /* can get called before IoctlHalInitRTC, if so then don't try to enter (uninitialized) cs (kernel should be single-proc, single-threaded here) */ if (g_oalRTCcsInit) { EnterCriticalSection(&g_oalRTCcs); csEnter = TRUE; } else csEnter = FALSE; if (pTime == NULL) goto cleanUp; OALMSG(OAL_RTC&&OAL_FUNC, ( L"+OEMSetAlarmTime(%d/%d/%d %d:%d:%d.%03d)\r\n", pTime->wMonth, pTime->wDay, pTime->wYear, pTime->wHour, pTime->wMinute, pTime->wSecond, pTime->wMilliseconds)); OALMSG(TRUE, ( L"+OEMSetAlarmTime(%d/%d/%d %d:%d:%d.%03d)\r\n", pTime->wMonth, pTime->wDay, pTime->wYear, pTime->wHour, pTime->wMinute, pTime->wSecond, pTime->wMilliseconds)); // The RTC will only support a BCD year value of 0 - 99. The year datum is // 1980, so any dates greater than 2079 will fail unless the datum is // adjusted. if ((pTime->wYear <RTC_YEAR_DATUM) || ((pTime->wYear - RTC_YEAR_DATUM) > 99)) { OALMSG(OAL_ERROR, (L"ERROR: OEMSetRealTime: " L"RTC cannot support a year greater than %d or less than %d " L"(value %d)\r\n", (RTC_YEAR_DATUM + 99), RTC_YEAR_DATUM, pTime->wYear)); goto cleanUp; } // Get uncached virtual address pRTCReg = (S3C6410_RTC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_RTC, FALSE); // Enable RTC control pRTCReg->RTCCON |= (1<<0); pRTCReg->ALMSEC = TO_BCD(pTime->wSecond); pRTCReg->ALMMIN = TO_BCD(pTime->wMinute); pRTCReg->ALMHOUR = TO_BCD(pTime->wHour); pRTCReg->ALMDATE = TO_BCD(pTime->wDay); pRTCReg->ALMMON = TO_BCD(pTime->wMonth); pRTCReg->ALMYEAR = TO_BCD(pTime->wYear - RTC_YEAR_DATUM); // Enable the RTC Alarm pRTCReg->RTCALM = 0x7f; // Disable RTC control. pRTCReg->RTCCON &= ~(1<<0); // Clear RTC Alarm Interrupt Pending pRTCReg->INTP |= (1<<1); // Enable and Clear RTC Alarm Interrupt irq = IRQ_RTC_ALARM; OALIntrDoneIrqs(1, &irq); // Done rc = TRUE; cleanUp: OALMSG(OAL_RTC&&OAL_FUNC, (L"-OEMSetAlarmTime(rc = %d)\r\n", rc)); if (csEnter) LeaveCriticalSection(&g_oalRTCcs); return rc; }