staticint spu_backing_mbox_read(struct spu_context *ctx, u32 * data)
{
u32 mbox_stat; int ret = 0;
spin_lock(&ctx->csa.register_lock);
mbox_stat = ctx->csa.prob.mb_stat_R; if (mbox_stat & 0x0000ff) { /* Read the first available word. * Implementation note: the depth * of pu_mb_R is currently 1.
*/
*data = ctx->csa.prob.pu_mb_R;
ctx->csa.prob.mb_stat_R &= ~(0x0000ff);
ctx->csa.spu_chnlcnt_RW[28] = 1;
gen_spu_event(ctx, MFC_PU_MAILBOX_AVAILABLE_EVENT);
ret = 4;
}
spin_unlock(&ctx->csa.register_lock); return ret;
}
ret = 0;
spin_lock_irq(&ctx->csa.register_lock);
stat = ctx->csa.prob.mb_stat_R;
/* if the requested event is there, return the poll mask, otherwise enable the interrupt to get notified, but first mark any pending interrupts as done so
we don't get woken up unnecessarily */
if (events & (EPOLLIN | EPOLLRDNORM)) { if (stat & 0xff0000)
ret |= EPOLLIN | EPOLLRDNORM; else {
ctx->csa.priv1.int_stat_class2_RW &=
~CLASS2_MAILBOX_INTR;
ctx->csa.priv1.int_mask_class2_RW |=
CLASS2_ENABLE_MAILBOX_INTR;
}
} if (events & (EPOLLOUT | EPOLLWRNORM)) { if (stat & 0x00ff00)
ret = EPOLLOUT | EPOLLWRNORM; else {
ctx->csa.priv1.int_stat_class2_RW &=
~CLASS2_MAILBOX_THRESHOLD_INTR;
ctx->csa.priv1.int_mask_class2_RW |=
CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR;
}
}
spin_unlock_irq(&ctx->csa.register_lock); return ret;
}
staticint spu_backing_ibox_read(struct spu_context *ctx, u32 * data)
{ int ret;
spin_lock(&ctx->csa.register_lock); if (ctx->csa.prob.mb_stat_R & 0xff0000) { /* Read the first available word. * Implementation note: the depth * of puint_mb_R is currently 1.
*/
*data = ctx->csa.priv2.puint_mb_R;
ctx->csa.prob.mb_stat_R &= ~(0xff0000);
ctx->csa.spu_chnlcnt_RW[30] = 1;
gen_spu_event(ctx, MFC_PU_INT_MAILBOX_AVAILABLE_EVENT);
ret = 4;
} else { /* make sure we get woken up by the interrupt */
ctx->csa.priv1.int_mask_class2_RW |= CLASS2_ENABLE_MAILBOX_INTR;
ret = 0;
}
spin_unlock(&ctx->csa.register_lock); return ret;
}
staticint spu_backing_wbox_write(struct spu_context *ctx, u32 data)
{ int ret;
spin_lock(&ctx->csa.register_lock); if ((ctx->csa.prob.mb_stat_R) & 0x00ff00) { int slot = ctx->csa.spu_chnlcnt_RW[29]; int avail = (ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8;
/* We have space to write wbox_data. * Implementation note: the depth * of spu_mb_W is currently 4.
*/
BUG_ON(avail != (4 - slot));
ctx->csa.spu_mailbox_data[slot] = data;
ctx->csa.spu_chnlcnt_RW[29] = ++slot;
ctx->csa.prob.mb_stat_R &= ~(0x00ff00);
ctx->csa.prob.mb_stat_R |= (((4 - slot) & 0xff) << 8);
gen_spu_event(ctx, MFC_SPU_MAILBOX_WRITTEN_EVENT);
ret = 4;
} else { /* make sure we get woken up by the interrupt when space
becomes available */
ctx->csa.priv1.int_mask_class2_RW |=
CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR;
ret = 0;
}
spin_unlock(&ctx->csa.register_lock); return ret;
}
spin_lock(&ctx->csa.register_lock);
ret = -EAGAIN; if (prob->dma_querytype_RW) goto out;
ret = 0; /* FIXME: what are the side-effects of this? */
prob->dma_querymask_RW = mask;
prob->dma_querytype_RW = mode; /* In the current implementation, the SPU context is always * acquired in runnable state when new bits are added to the * mask (tagwait), so it's sufficient just to mask * dma_tagstatus_R with the 'mask' parameter here.
*/
ctx->csa.prob.dma_tagstatus_R &= mask;
out:
spin_unlock(&ctx->csa.register_lock);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.