Esempio n. 1
0
//------------------------------------------------------------------------------
//
//  Function:  OEMSetAlarmTime
//
//  This function is called by the kernel to set the real-time clock alarm.
//
BOOL
OEMSetAlarmTime(
    SYSTEMTIME *pSystemTime
    ) 
{
    BOOL rc = FALSE;

    OALMSG(OAL_TIMER && OAL_FUNC, (L"+OEMSetAlarmTime(%s)\r\n", SystemTimeToString(pSystemTime)));

    if (s_rtc.initialized)
        {
        // Save time to global structure
        EnterCriticalSection(&s_rtc.cs);

        if (g_ResumeRTC)
    		{
            OALIoCtlHalRtcTime(0, NULL, 0, NULL, 0, NULL);
            g_ResumeRTC = FALSE;
	    	}

        // Round to seconds
        pSystemTime->wMilliseconds = 0;

        // Convert to filetime
        if (NKSystemTimeToFileTime(pSystemTime, (FILETIME*)&s_rtc.alarmFiletime))
            {
            UCHAR   status;
            UCHAR   bcdTime[6];

            //  Adjust alarm time by secure offset
            s_rtc.alarmFiletime  = s_rtc.alarmFiletime - s_rtc.baseOffset;

            //  Convert to BCD time format
            FiletimeToHWTime( s_rtc.alarmFiletime, bcdTime );

            //  Write alarm registers
            TWLWriteByteReg(s_rtc.hTWL, TWL_ALARM_YEARS_REG, bcdTime[5]);
            TWLWriteByteReg(s_rtc.hTWL, TWL_ALARM_MONTHS_REG, bcdTime[4]);
            TWLWriteByteReg(s_rtc.hTWL, TWL_ALARM_DAYS_REG, bcdTime[3]);
            TWLWriteByteReg(s_rtc.hTWL, TWL_ALARM_HOURS_REG, bcdTime[2]);
            TWLWriteByteReg(s_rtc.hTWL, TWL_ALARM_MINUTES_REG, bcdTime[1]);
            TWLWriteByteReg(s_rtc.hTWL, TWL_ALARM_SECONDS_REG, bcdTime[0]);

            //  Set toggle bit to latch alarm registers
            TWLReadByteReg(s_rtc.hTWL, TWL_RTC_CTRL_REG, &status);

            status |= TWL_RTC_CTRL_RUN | TWL_RTC_CTRL_GET_TIME;
            TWLWriteByteReg(s_rtc.hTWL, TWL_RTC_CTRL_REG, status);

            // Done
            rc = TRUE;
            }

        LeaveCriticalSection(&s_rtc.cs);
        }
    
    return rc;
}
Esempio n. 2
0
//------------------------------------------------------------------------------
//
//  Function:  OEMSetRealTime
//
//  This function is called by the kernel to set the real-time clock. A secure
//  timer requirement means that the time change is noted in baseOffset and
//  used to compute the time delta from the non-alterable RTC in T2
//
BOOL
OEMSetRealTime(
    SYSTEMTIME *pSystemTime
    ) 
{
    BOOL        rc = FALSE;
    ULONGLONG   fileTime;
    DWORD       tickDelta;

    OALMSG(OAL_TIMER && OAL_FUNC, (L"+OEMSetRealTime(%s)\r\n", SystemTimeToString(pSystemTime)));

    if (s_rtc.initialized)
        {
        // Save time to global structure
        EnterCriticalSection(&s_rtc.cs);

        if (g_ResumeRTC)
    		{
            OALIoCtlHalRtcTime(0, NULL, 0, NULL, 0, NULL);
            g_ResumeRTC = FALSE;
	    	}
		
        // Round to seconds
        pSystemTime->wMilliseconds = 0;

        // Convert to filetime
        if (NKSystemTimeToFileTime(pSystemTime, (FILETIME*)&fileTime))
            {
            // Compute the tick delta (indicates the time in the RTC)
            tickDelta = OEMGetTickCount() - s_rtc.baseTickCount;
            
            // Update all the parameters
            s_rtc.baseFiletime  = s_rtc.baseFiletime + ((ULONGLONG)tickDelta)*10000;
            s_rtc.baseOffset    = fileTime - s_rtc.baseFiletime;
            s_rtc.baseTickCount = OEMGetTickCount();

            //  Save off base offset to the backup regs
            WriteBaseOffset( &s_rtc.baseOffset ); 

            // Done
            rc = TRUE;
            }

        LeaveCriticalSection(&s_rtc.cs);
        }
    
    OALMSG(OAL_TIMER && OAL_FUNC, (L"-OEMSetRealTime\r\n"));

    return rc;
}
Esempio n. 3
0
//------------------------------------------------------------------------------
//
//  Function:  OEMGetRealTime
//
//  This function is called by the kernel to retrieve the time from
//  the real-time clock.
//
BOOL
OEMGetRealTime(
    SYSTEMTIME *pSystemTime
    ) 
{
    DWORD       delta;
    ULONGLONG   time;

    OALMSG(OAL_TIMER && OAL_FUNC, (L"+OEMGetRealTime()\r\n"));

    if (!s_rtc.initialized)
        {
        // Return default time if RTC isn't initialized
        pSystemTime->wYear   = RTC_BASE_YEAR_MIN;
        pSystemTime->wMonth  = 1;
        pSystemTime->wDay    = 1;
        pSystemTime->wHour   = 0;
        pSystemTime->wMinute = 0;
        pSystemTime->wSecond = 0;
        pSystemTime->wDayOfWeek    = 0;
        pSystemTime->wMilliseconds = 0;
        }
    else
        {
        EnterCriticalSection(&s_rtc.cs);
        if (g_ResumeRTC)
    		{
            // suspend/resume occured, sync RTC
            OALIoCtlHalRtcTime(0, NULL, 0, NULL, 0, NULL);
            g_ResumeRTC = FALSE;
	    	}
        delta = OEMGetTickCount() - s_rtc.baseTickCount;
        time = s_rtc.baseFiletime + s_rtc.baseOffset + ((ULONGLONG)delta) * 10000;
        NKFileTimeToSystemTime((FILETIME*)&time, pSystemTime);
        pSystemTime->wMilliseconds = 0;
        LeaveCriticalSection(&s_rtc.cs);
        }

    OALMSG(OAL_TIMER && OAL_FUNC, (L"-OEMGetRealTime() = %s\r\n", SystemTimeToString(pSystemTime)));

    return TRUE;
}
Esempio n. 4
0
//------------------------------------------------------------------------------
//
//  Function:  OEMPowerOff
//
//  Called when the system is to transition to it's lowest power mode (off)
//
VOID
OEMPowerOff(
    )
{
    DWORD i;
    UINT32 sysIntr;
    UINT intr[3];
    BOOL bPowerOn;
    BOOL bPrevIntrState;
    UINT irq = 0;
    UINT32 mask = 0;
	
    // disable interrupts (note: this should not be needed)
    bPrevIntrState = INTERRUPTS_ENABLE(FALSE);

    // UNDONE: verify if this is still necessary
    // Disable hardware watchdog
    OALWatchdogEnable(FALSE);
    
    // Make sure that KITL is powered off
    bPowerOn = FALSE;
    KITLIoctl(IOCTL_KITL_POWER_CALL, &bPowerOn, sizeof(bPowerOn), NULL, 0, NULL);    

	
    //Save Perf Timer
    OALContextSavePerfTimer();
    // Disable GPTimer2 (used for high perf/monte carlo profiling)
    EnableDeviceClocks(BSPGetGPTPerfDevice(), FALSE);

    // Give chance to do board specific stuff
    BSPPowerOff();

    //----------------------------------------------
    // capture all enabled interrupts and disable interrupts
    intr[0] = INREG32(&g_pIntr->pICLRegs->INTC_MIR0);
    intr[1] = INREG32(&g_pIntr->pICLRegs->INTC_MIR1);
    intr[2] = INREG32(&g_pIntr->pICLRegs->INTC_MIR2);

    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET0, OMAP_MPUIC_MASKALL);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET1, OMAP_MPUIC_MASKALL);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_SET2, OMAP_MPUIC_MASKALL);

    //----------------------------------------------
    // Context Save/Restore       
	// Save state then mask all GPIO interrupts
	for (i=0; i<g_pIntr->nbGpioBank; i++)
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

		// Save current state
		pCurrGpioCtxt->restoreCtxt.IRQENABLE1 = INREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1);
		pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE = INREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE);

		// Disable all GPIO interrupts in the bank
        OUTREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1, 0);
        OUTREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE, 0);

		OALIntrEnableIrqs(1,&pCurrGpioCtxt->bank_irq);

	}

    //----------------------------------------------
    // Clear all enabled IO PAD wakeups for GPIOs
    for (i = 0; i < g_pIntr->nbGpioBank; ++i) 
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

        irq = BSPGetGpioIrq(0) + (i * 32);
        mask = pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE;
        while (mask != 0)
        {
            // If a GPIO was wakeup enabled, then clear the wakeup
            if (mask & 0x1)
            {
                OEMEnableIOPadWakeup((irq - BSPGetGpioIrq(0)), FALSE);
            }
            
            irq++;
            mask >>= 1;    
        }
    }

    //----------------------------------------------
    // Enable wake sources interrupts
    for (sysIntr = SYSINTR_DEVICES; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
        {
        // Skip if sysIntr isn't allowed as wake source
        if (!OALPowerWakeSource(sysIntr)) 
		    continue;

        // Enable it as interrupt
        OEMInterruptEnable(sysIntr, NULL, 0);
        }

    // enter full retention
    PrcmSuspend();
    
    //----------------------------------------------
    // Find wakeup source
    for (sysIntr = SYSINTR_DEVICES; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
        {            
        // Skip if sysIntr isn't allowed as wake source
        if (!OALPowerWakeSource(sysIntr)) 
		    continue;

        // When this sysIntr is pending we find wake source
        if (OEMInterruptPending(sysIntr))
            {
            g_oalWakeSource = sysIntr;
            break;
            }
        }
  
    //----------------------------------------------
    // Context Save/Restore
    // Put GPIO interrupt state back to the way it was before suspend
    for (i=0; i<g_pIntr->nbGpioBank; i++)
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];		

        // Write registers with the previously saved values
        OUTREG32(&pCurrGpioCtxt->pRegs->IRQENABLE1, pCurrGpioCtxt->restoreCtxt.IRQENABLE1);
        OUTREG32(&pCurrGpioCtxt->pRegs->WAKEUPENABLE, pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE);

    }

    //-------------------------------------------------------
    // Enable all previously enabled IO PAD wakeups for GPIOs
    for (i = 0; i < g_pIntr->nbGpioBank; ++i) 
    {
		INTR_GPIO_CTXT* pCurrGpioCtxt = &g_pIntr->pGpioCtxt[i];

        irq = BSPGetGpioIrq(0) + (i * 32);
        mask = pCurrGpioCtxt->restoreCtxt.WAKEUPENABLE;
        while (mask != 0)
        {
            // If a GPIO was wakeup enabled, then clear the wakeup
            if (mask & 0x1)
            {
                OEMEnableIOPadWakeup((irq - BSPGetGpioIrq(0)), TRUE);
            }
            
            irq++;
            mask >>= 1;    
        }
    }

    //----------------------------------------------
    // Re-enable interrupts    
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR0, ~intr[0]);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR1, ~intr[1]);
    OUTREG32(&g_pIntr->pICLRegs->INTC_MIR_CLEAR2, ~intr[2]);  
    
    //----------------------------------------------
    // Do board specific stuff    
    BSPPowerOn();   
        
    //Sync to Hardware RTC after suspend\resume
    OALIoCtlHalRtcTime( 0,  NULL, 0, NULL, 0, NULL);    

    // Enable GPTimer (used for high perf/monte carlo profiling)
    EnableDeviceClocks(BSPGetGPTPerfDevice(), TRUE);	
    //Restore Perf Timer
    OALContextRestorePerfTimer();
		
    // Reinitialize KITL
    bPowerOn = TRUE;
    KITLIoctl(IOCTL_KITL_POWER_CALL, &bPowerOn, sizeof(bPowerOn), NULL, 0, NULL);    
    
    // Enable hardware watchdog
    OALWatchdogEnable(TRUE);
	
#ifndef SHIP_BUILD
    if (g_PrcmDebugSuspendResume)
	{
        OALMSG(1, (L"Enabled wake sources:\r\n"));
        for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++)
        {
            if (OALPowerWakeSource(sysIntr)) 
                OALMSG(1, (L"  SYSINTR %d\r\n", sysIntr));
        }

    	OALMSG(1, (L"\r\nWake due to SYSINTR %d\r\n", g_oalWakeSource));
        OALWakeupLatency_DumpSnapshot();
        PrcmDumpSavedRefCounts();
        DumpPrcmRegsSnapshot();
    }
#endif

    // restore interrupts
    INTERRUPTS_ENABLE(bPrevIntrState);
}