/* __ipipe_walk_pipeline(): Plays interrupts pending in the log. Must
be called with local hw interrupts disabled. */
void fastcall __ipipe_walk_pipeline(struct list_head *pos, int cpuid)
{
struct ipipe_domain *this_domain = ipipe_percpu_domain[cpuid];
while (pos != &__ipipe_pipeline) {
struct ipipe_domain *next_domain =
list_entry(pos, struct ipipe_domain, p_link);
if (test_bit
(IPIPE_STALL_FLAG,
&next_domain->cpudata[cpuid].status))
break; /* Stalled stage -- do not go further.
*/
if (next_domain->cpudata[cpuid].irq_pending_hi != 0) {
if (next_domain == this_domain)
__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
else {
__ipipe_switch_to(this_domain,
next_domain,
cpuid);
ipipe_load_cpuid(); /* Processor
might have changed. */
if (this_domain->cpudata[cpuid].
irq_pending_hi != 0
&& !test_bit(IPIPE_STALL_FLAG,
&this_domain->cpudata[cpuid].status))
__ipipe_sync_pipeline(IPIPE_IRQMASK_ANY);
}
break;
} else if (next_domain == this_domain)
break;
pos = next_domain->p_link.next;
}
}
/* Called with hw interrupts off. */
static inline void __ipipe_switch_to(struct ipipe_domain *out,
struct ipipe_domain *in, int cpuid)
{
void ipipe_suspend_domain(void);
/-----------------------------------------------------------------------
-
Strange statement here - but "ipipe_suspend_domain()" will not be called
------------------------------------------------------------------------
/
/*
* "in" is guaranteed to be closer than "out" from the head of
the
* pipeline (and obviously different).
*/
ipipe_percpu_domain[cpuid] = in;
ipipe_suspend_domain(); /* Sync stage and propagate interrupts.
*/
ipipe_load_cpuid(); /* Processor might have changed. */
if (ipipe_percpu_domain[cpuid] == in)
/*
* Otherwise, something has changed the current domain
under
* our feet recycling the register set; do not override.
*/
ipipe_percpu_domain[cpuid] = out;
}
No comments:
Post a Comment