示例#1
0
文件: platform.cpp 项目: gardhi/PM
EXTERN_C VOID WINAPI
PlatformResumeSystem (void)
{
	SETFNAME (_T ("PlatformResumeSystem"));

	PMLOGMSG (ZONE_RESUME, (_T ("+%s: suspend flag is %d\r\n"), pszFname, gfSystemSuspended));

	// Was this an unexpected resume event?  If so, there may be a thread priority problem
	// or some piece of software suspended the system without calling SetSystemPowerState().

	DEBUGCHK (gfSystemSuspended);
	if (!gfSystemSuspended)
	{
		// Unexpected resume -- go to the resuming state.  This should not happen unless
		// somebody is illegally calling PowerOffSystem() directly.

		PMLOGMSG (ZONE_WARN || ZONE_RESUME, (_T ("%s: WARNING: unexpected resume!\r\n"), pszFname));

		// Go into the new state.  OEMs that choose to support unexpected resumes may want to
		// lock PM variables with PMLOCK(), then set the curDx and actualDx values for all
		// devices to PwrDeviceUnspecified before calling PmSetSystemPowerState_I().  This will
		// force an update IOCTL to all devices.

		DEBUGCHK (ghevRestartTimers != NULL);
		SetEvent (ghevRestartTimers);
	}
	else
	{
		DWORD dwWakeSource, dwBytesReturned;
		BOOL fOk;

		// Get the system wake source to help determine which power state we resume into:
		fOk = KernelIoControl (IOCTL_HAL_GET_WAKE_SOURCE, NULL, 0, &dwWakeSource,
							   sizeof (dwWakeSource), &dwBytesReturned);
		if (fOk)
		{
			// IOCTL succeeded (not all platforms necessarily support it), but sanity check
			// the return value, just in case.

			if (dwBytesReturned != sizeof (dwWakeSource))
			{
				PMLOGMSG (ZONE_WARN, (_T ("%s: KernelIoControl() returned an invalid size %d\r\n"),
									  pszFname, dwBytesReturned));
			}
			else
			{
				// Look for an activity timer corresponding to this wake source.
				PACTIVITY_TIMER pat = ActivityTimerFindByWakeSource (dwWakeSource);

				if (pat != NULL)
				{
					PMLOGMSG (ZONE_RESUME, (_T ("%s: signaling '%s' activity at resume\r\n"),
											pszFname, pat->pszName));

					// Is there an activity timer we need to reset?
					if (pat->hevReset != NULL)
					{
						// Found a timer, elevate the timer management priority thread so that it
						// executes before the suspending thread.

						DWORD dwOldPriority = CeGetThreadPriority (ghtActivityTimers);
						DWORD dwNewPriority = (CeGetThreadPriority (GetCurrentThread ()) - 1);

						DEBUGCHK (dwNewPriority >= 0);
						SetEvent (pat->hevReset);
						CeSetThreadPriority (ghtActivityTimers, dwNewPriority);
						CeSetThreadPriority (ghtActivityTimers, dwOldPriority);
					}
				}
			}
		}
	}
	PMLOGMSG (ZONE_RESUME, (_T ("-%s\r\n"), pszFname));
}
示例#2
0
void S3C2450DISP::SetVisibleSurface( GPESurf *pTempSurf, BOOL bWaitForVBlank)
{
	static int timeoutcnt=0;
    DWORD we;
#ifdef	HIGH_PRIORITY_INTR
	int iPriority;
	HANDLE hThread;

	hThread = GetCurrentThread();
	iPriority = CeGetThreadPriority(hThread);
	CeSetThreadPriority(hThread, DISPDRV_IST_PRIORITY);
#endif	
	S3C2450Surf *pSurf = (S3C2450Surf *) pTempSurf;
	EnterCriticalSection(&m_CS);
	// assume Synchronous to VSYNC

	EnableInterrupt();
	we = WaitForSingleObject(m_hVSYNCInterruptEvent,1000/*INFINITE*/);
	DisableInterrupt();
	InterruptDone(m_dwVSYNCSysIntr);

	if(we != WAIT_OBJECT_0)
	{
		timeoutcnt++;
		RETAILMSG(1,(TEXT("Surface Flipping Time Out  %d !!!\n"), timeoutcnt));
		for(int i=0;i<78;i++)
			RETAILMSG(1,(TEXT("0x%08X = 0x%08X\n"),(DWORD*)((DWORD*)m_pLCDReg + i),*(DWORD*)((DWORD*)m_pLCDReg + i)));
			
		RETAILMSG(1,(TEXT("saved_x=%d"),saved_x));
		RETAILMSG(1,(TEXT("saved_y=%d"),saved_y));
		RETAILMSG(1,(TEXT("saved_width=%d"),saved_width));
		RETAILMSG(1,(TEXT("saved_height=%d"),saved_height));				
		while(1);
	}

	if(pSurf->m_bIsOverlay == FALSE)
	{
		//RETAILMSG(1,(TEXT("pSurf->OffsetInVideoMemory()=0x%08X\n"),pSurf->OffsetInVideoMemory()));
		m_pVisibleSurface = pSurf;
		m_pLCDReg->VIDW00ADD0B0 = (UINT32)(pSurf->OffsetInVideoMemory() + IMAGE_FRAMEBUFFER_DMA_BASE);		
				// buffer end address
		m_pLCDReg->VIDW00ADD1B0 = (UINT32)(pSurf->OffsetInVideoMemory() + IMAGE_FRAMEBUFFER_DMA_BASE) + (LCD_XSIZE_TFT*LCD_YSIZE_TFT*2);
				// buffer size 
		m_pLCDReg->VIDW00ADD2B0 = (0<<VIDWxADD2_OFFSET_SIZE_S)|(LCD_XSIZE_TFT*2);
	}
	else
	{

		m_pLCDReg->VIDW01ADD0 = (UINT32)(pSurf->OffsetInVideoMemory() + IMAGE_FRAMEBUFFER_DMA_BASE);		
				// buffer end address
		m_pLCDReg->VIDW01ADD1 = (UINT32)(pSurf->OffsetInVideoMemory() + IMAGE_FRAMEBUFFER_DMA_BASE) + 
														(pSurf->Width()*pSurf->Height()*2);
				// buffer size 
		m_pLCDReg->VIDW01ADD2 = (0<<VIDWxADD2_OFFSET_SIZE_S)|(pSurf->Width()*2);		
	}
	RETAILMSG(DBGLCD, (TEXT("S3C2450DISP::SetVisibleSurface\r\n")));
	LeaveCriticalSection(&m_CS);

#ifdef	HIGH_PRIORITY_INTR
	CeSetThreadPriority(hThread, iPriority);
#endif	
}
示例#3
0
文件: platform.cpp 项目: gardhi/PM
EXTERN_C DWORD WINAPI
PlatformSetSystemPowerState (LPCTSTR pszName, BOOL fForce, BOOL fInternal)
{
	DWORD dwStatus = ERROR_SUCCESS;
	PSYSTEM_POWER_STATE pNewSystemPowerState = NULL;
	PDEVICE_POWER_RESTRICTION pNewCeilingDx = NULL;
	BOOL fDoTransition = FALSE;
	INT iPreSuspendPriority = 0;
	static BOOL fFirstCall = TRUE;

	SETFNAME (_T ("PlatformSetSystemPowerState"));

	// Read system power state variables and construct new lists:

	if (gfFileSystemsAvailable)
		PmUpdateSystemPowerStatesIfChanged ();
	dwStatus = RegReadSystemPowerState (pszName, &pNewSystemPowerState, &pNewCeilingDx);

	// Did we get registry information about the new power state?

	if (dwStatus == ERROR_SUCCESS)
	{
		BOOL fSuspendSystem = FALSE;
		static BOOL fWantStartupScreen = FALSE;
		DWORD dwNewStateFlags = pNewSystemPowerState->dwFlags;

		// Assume we will update the system power state:
		fDoTransition = TRUE;

		// Are we going to suspend the system as a whole?
		if ((dwNewStateFlags &
			 (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL | POWER_STATE_RESET)) != 0)
		{
			fSuspendSystem = TRUE;
		}

		// A "critical" suspend might mean we have totally lost battery power and need
		// to suspend really quickly.  Depending on the platform, OEMs may be able
		// to bypass driver notification entirely and rely on xxx_PowerDown() notifications
		// to suspend gracefully.  Or they may be able to implement a critical suspend
		// kernel ioctl.  This sample implementation is very generic and simply sets the
		// POWER_FORCE flag, which is not used.

		if (dwNewStateFlags & (POWER_STATE_CRITICAL | POWER_STATE_OFF | POWER_STATE_RESET))
		{
			fForce = TRUE;
		}

		// If everything seems OK, do the set operation:

		if (fDoTransition)
		{
			POWER_BROADCAST_BUFFER pbb;
			PDEVICE_LIST pdl;
			BOOL fResumeSystem = FALSE;

			// Send out system power state change notifications:
			pbb.Message = PBT_TRANSITION;
			pbb.Flags = pNewSystemPowerState->dwFlags;
			pbb.Length = _tcslen (pNewSystemPowerState->pszName) + 1;	// Char count not byte count for now
			if (pbb.Length > MAX_PATH)
			{
				// Truncate the system power state name -- note, we actually have MAX_PATH + 1
				// characters available.
				pbb.Length = MAX_PATH;
			}
			_tcsncpy_s (pbb.SystemPowerState, _countof (pbb.SystemPowerState),
						pNewSystemPowerState->pszName, pbb.Length);
			pbb.Length *= sizeof (pbb.SystemPowerState[0]);	           // Convert to byte count
			GenerateNotifications ((PPOWER_BROADCAST) & pbb);

			// Is GWES ready?
			if (!gfGwesReady)
			{
				if (WaitForAPIReady (SH_GDI, 0) == WAIT_OBJECT_0)
				{
					gfGwesReady = TRUE;
				}
			}

			// Are we suspending?
			if (fSuspendSystem && gpfnGwesPowerDown != NULL)
			{
				// Start the process of suspending GWES:
				if (gfGwesReady)
				{
					fWantStartupScreen = gpfnGwesPowerDown ();
				}
			}

			// Update global system state variables:
			PMLOCK ();
			PSYSTEM_POWER_STATE pOldSystemPowerState = gpSystemPowerState;
			PDEVICE_POWER_RESTRICTION pOldCeilingDx = gpCeilingDx;

			if (gpSystemPowerState != NULL
				&& (gpSystemPowerState->
					dwFlags & (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL)) != 0)
			{
				// We are exiting a suspended state:
				fResumeSystem = TRUE;
			}
			gpSystemPowerState = pNewSystemPowerState;
			gpCeilingDx = pNewCeilingDx;
			PMUNLOCK ();

			// Are we suspending, resuming, or neither?
			if (fSuspendSystem)
			{
				INT iCurrentPriority;

				// We're suspending: update all devices other than block devices,
				// in case any of them need to access the registry or write files.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: suspending - notifying non-block drivers\r\n"), pszFname));
				for (pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext)
				{
					if (*pdl->pGuid != idBlockDevices)
					{
						UpdateClassDeviceStates (pdl);
					}
				}

				// Notify the kernel that we are about to suspend.  This gives the
				// kernel an opportunity to clear wake source flags before we initiate
				// the suspend process.  If we don't do this and a wake source interrupt
				// occurs between the time we call PowerOffSystem() and the time
				// OEMPowerOff() is invoked, it is hard for the kernel to know whether or
				// not to suspend.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: calling KernelIoControl(IOCTL_HAL_PRESUSPEND)\r\n"), pszFname));
				KernelIoControl (IOCTL_HAL_PRESUSPEND, NULL, 0, NULL, 0, NULL);
				iCurrentPriority = CeGetThreadPriority (GetCurrentThread ());
				DEBUGCHK (iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN);
				if (iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN)
				{
					CeSetThreadPriority (GetCurrentThread (), giPreSuspendPriority);
					Sleep (0);
					CeSetThreadPriority (GetCurrentThread (), iCurrentPriority);
				}

				// Notify file systems that their block drivers will soon go away.
				// After making this call, this thread is the only one that can access
				// the file system (including registry and device drivers) without
				// blocking.  Unfortunately, this API takes and holds the file system
				// critical section, so other threads attempting to access the registry
				// or files may cause priority inversions.  To avoid priority problem
				// that may starve the Power Manager, we may raise our own priority to a
				// high level.  Do this if giSuspendPriority is non-zero.

				if (giSuspendPriority != 0)
				{
					iPreSuspendPriority = CeGetThreadPriority (GetCurrentThread ());
					DEBUGCHK (iPreSuspendPriority != THREAD_PRIORITY_ERROR_RETURN);
					PMLOGMSG (ZONE_PLATFORM,
							  (_T
							   ("%s: suspending: raising thread priority for 0x%08x from %d to %d\r\n"),
							   pszFname, GetCurrentThreadId (), iPreSuspendPriority,
							   giSuspendPriority));
					CeSetThreadPriority (GetCurrentThread (), giSuspendPriority);
				}

                // Discard code pages from drivers.  This is a diagnostic tool to
                // forcibly expose paging-related bugs that could cause apparently
                // random system crashes or hangs.  Optionally, OEMs can disable this
                // for production systems to speed up resume times.  We have to call
                // PageOutMode before FileSys Shutdown. Otherwise, it cause dead lock
                // between filesystem and loader.

				if (gfPageOutAllModules)
				{
					ForcePageout ();
				}

				if (g_pSysRegistryAccess)
					g_pSysRegistryAccess->EnterLock ();
				gfFileSystemsAvailable = FALSE;

				if ((dwNewStateFlags & POWER_STATE_RESET) != 0)
				{
					// Is this to be a cold boot?
					if (_tcscmp (pszName, _T ("coldreboot")) == 0)
					{
						SetCleanRebootFlag ();
					}
				}

				FileSystemPowerFunction (FSNOTIFY_POWER_OFF);

				// Update block device power states:
				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: suspending - notifying block drivers\r\n"), pszFname));
				pdl = GetDeviceListFromClass (&idBlockDevices);
				if (pdl != NULL)
				{
					UpdateClassDeviceStates (pdl);
				}

				// Handle resets and shutdowns here, after flushing files.  Since Windows CE does
				// not define a standard mechanism for handling shutdown (via POWER_STATE_OFF),
				// OEMs will need to fill in the appropriate code here.  Similarly, if an OEM does
				// not support IOCTL_HAL_REBOOT, they should not support POWER_STATE_RESET.

				if ((dwNewStateFlags & POWER_STATE_RESET) != 0)
				{
					// Should not return from this call, but if we do just suspend the system:
					KernelLibIoControl ((HANDLE) KMOD_OAL, IOCTL_HAL_REBOOT, NULL, 0, NULL, 0,
										NULL);
					RETAILMSG (TRUE,
							   (_T
								("PM: PlatformSetSystemPowerState: KernelIoControl(IOCTL_HAL_REBOOT) returned!\r\n")));
					DEBUGCHK (FALSE);	// Break into the debugger.
				}
			}
			else if (fResumeSystem)
			{
				// We're waking up from a resume -- update block device power states
				// so we can access the registry and/or files.

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: resuming - notifying block drivers\r\n"), pszFname));
				pdl = GetDeviceListFromClass (&idBlockDevices);
				if (pdl != NULL)
				{
					UpdateClassDeviceStates (pdl);
				}

				// Notify file systems that their block drivers are back.

				FileSystemPowerFunction (FSNOTIFY_POWER_ON);
				gfFileSystemsAvailable = TRUE;
				if (g_pSysRegistryAccess)
					g_pSysRegistryAccess->LeaveLock ();

				// Update all devices other than block devices:

				PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME,
						  (_T ("%s: resuming - notifying block drivers\r\n"), pszFname));
				for (pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext)
				{
					if (*pdl->pGuid != idBlockDevices)
					{
						UpdateClassDeviceStates (pdl);
					}
				}

				// Tell GWES to wake up:
				if (gpfnGwesPowerUp != NULL && gfGwesReady)
				{
					gpfnGwesPowerUp (fWantStartupScreen);
					fWantStartupScreen = FALSE;
				}

				// Send out resume notification:
				pbb.Message = PBT_RESUME;
				pbb.Flags = 0;
				pbb.Length = 0;
				pbb.SystemPowerState[0] = 0;
				GenerateNotifications ((PPOWER_BROADCAST) & pbb);
			}
			else
			{
				// Update all devices without any particular ordering:
				UpdateAllDeviceStates ();
			}

			// Release the old state information:
			SystemPowerStateDestroy (pOldSystemPowerState);
			while (pOldCeilingDx != NULL)
			{
				PDEVICE_POWER_RESTRICTION pdpr = pOldCeilingDx->pNext;

				PowerRestrictionDestroy (pOldCeilingDx);
				pOldCeilingDx = pdpr;
			}

			// Are we suspending?
			if (fSuspendSystem)
			{
				// Set a flag to notify the resume thread that this was a controlled suspend.
				gfSystemSuspended = TRUE;

				PMLOGMSG (ZONE_PLATFORM
						  || ZONE_RESUME, (_T ("%s: calling PowerOffSystem()\r\n"), pszFname));
				PowerOffSystem ();	    // Sets a flag in the kernel for the scheduler.
				Sleep (0);	            // Force the scheduler to run.
				PMLOGMSG (ZONE_PLATFORM
						  || ZONE_RESUME, (_T ("%s: back from PowerOffSystem()\r\n"), pszFname));

				// Clear the suspend flag:
				gfSystemSuspended = FALSE;
			}
		}
		else
		{
			// Release the unused new state information:
			SystemPowerStateDestroy (pNewSystemPowerState);
			while (pNewCeilingDx != NULL)
			{
				PDEVICE_POWER_RESTRICTION pdpr = pNewCeilingDx->pNext;

				PowerRestrictionDestroy (pNewCeilingDx);
				pNewCeilingDx = pdpr;
			}
		}
	}

	// Restore our priority if we updated it during a suspend transition:
	if (giSuspendPriority != 0 && iPreSuspendPriority != 0)
	{
		PMLOGMSG (ZONE_PLATFORM, (_T ("%s: restoring thread priority to %d\r\n"),
								  pszFname, iPreSuspendPriority));
		CeSetThreadPriority (GetCurrentThread (), iPreSuspendPriority);
	}

	return dwStatus;
}