예제 #1
0
// Returns true if anything was executed.
bool __RunOnePendingInterrupt()
{
	if (inInterrupt)
	{
		// Already in an interrupt! We'll keep going when it's done.
		return false;
	}
	// Can easily prioritize between different kinds of interrupts if necessary.
	if (pendingInterrupts.size())
	{
		PendingInterrupt pend = pendingInterrupts.front();
		pendingInterrupts.pop_front();
		intState.save();
		pend.handler->copyArgsToCPU(pend);

		currentMIPS->r[MIPS_REG_RA] = __KernelInterruptReturnAddress();
		inInterrupt = true;
		return true;
	}
	else
	{
		// DEBUG_LOG(HLE, "No more interrupts!");
		return false;
	}
}
예제 #2
0
// Returns true if anything was executed.
bool __RunOnePendingInterrupt()
{
	bool needsThreadReturn = false;

	if (inInterrupt || !interruptsEnabled) {
		// Already in an interrupt! We'll keep going when it's done.
		return false;
	}
	// Can easily prioritize between different kinds of interrupts if necessary.
retry:
	if (!pendingInterrupts.empty()) {
		PendingInterrupt pend = pendingInterrupts.front();

		IntrHandler* handler = intrHandlers[pend.intr];
		if (handler == NULL) {
			WARN_LOG(SCEINTC, "Ignoring interrupt");
			pendingInterrupts.pop_front();
			goto retry;
		}

		// If we came from CoreTiming::Advance(), we might've come from a waiting thread's callback.
		// To avoid "injecting" return values into our saved state, we context switch here.
		SceUID savedThread = __KernelGetCurThread();
		if (__KernelSwitchOffThread("interrupt")) {
			threadBeforeInterrupt = savedThread;
			needsThreadReturn = true;
		}

		intState.save();
		inInterrupt = true;

		if (!handler->run(pend)) {
			pendingInterrupts.pop_front();
			inInterrupt = false;
			goto retry;
		}

		currentMIPS->r[MIPS_REG_RA] = __KernelInterruptReturnAddress();
		return true;
	} else {
		if (needsThreadReturn)
			__KernelSwitchToThread(threadBeforeInterrupt, "left interrupt");
		// DEBUG_LOG(SCEINTC, "No more interrupts!");
		return false;
	}
}
예제 #3
0
// Returns true if anything was executed.
bool __RunOnePendingInterrupt()
{
	if (inInterrupt || !interruptsEnabled)
	{
		// Already in an interrupt! We'll keep going when it's done.
		return false;
	}
	// Can easily prioritize between different kinds of interrupts if necessary.
retry:
	if (pendingInterrupts.size())
	{
		// If we came from CoreTiming::Advance(), we might've come from a waiting thread's callback.
		// To avoid "injecting" return values into our saved state, we context switch here.
		__KernelSwitchOffThread("interrupt");

		PendingInterrupt pend = pendingInterrupts.front();
		SubIntrHandler *handler = intrHandlers[pend.intr].get(pend.subintr);
		if (handler == NULL)
		{
			WARN_LOG(HLE, "Ignoring interrupt, already been released.");
			pendingInterrupts.pop_front();
			goto retry;
		}

		intState.save();
		handler->copyArgsToCPU(pend);

		currentMIPS->r[MIPS_REG_RA] = __KernelInterruptReturnAddress();
		inInterrupt = true;
		return true;
	}
	else
	{
		// DEBUG_LOG(HLE, "No more interrupts!");
		return false;
	}
}