aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spu_base.c
diff options
context:
space:
mode:
authorLuke Browning <lukebr@linux.vnet.ibm.com>2008-04-27 14:41:55 -0400
committerJeremy Kerr <jk@ozlabs.org>2008-05-04 23:33:44 -0400
commitf3d69e0507f84903059d456c5d19f10b2df3ac69 (patch)
treef8aa4062bc1a0939d7bdb3a634c01869f2bb32a2 /arch/powerpc/platforms/cell/spu_base.c
parent7a2142002f29a7b398c49da9bdec712dc57087c7 (diff)
[POWERPC] spufs: fix concurrent delivery of class 0 & 1 exceptions
SPU class 0 & 1 exceptions may occur in parallel, so we may end up overwriting csa.dsisr. This change adds dedicated fields for each class to the spu and the spu context so that fault data is not overwritten. Signed-off-by: Luke Browning <lukebr@linux.vnet.ibm.com> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spu_base.c')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 6bab44b7716..b9ae675640d 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -226,11 +226,13 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
226 return 0; 226 return 0;
227 } 227 }
228 228
229 spu->class_0_pending = 0; 229 spu->class_1_dar = ea;
230 spu->dar = ea; 230 spu->class_1_dsisr = dsisr;
231 spu->dsisr = dsisr; 231
232 spu->stop_callback(spu, 1);
232 233
233 spu->stop_callback(spu); 234 spu->class_1_dar = 0;
235 spu->class_1_dsisr = 0;
234 236
235 return 0; 237 return 0;
236} 238}
@@ -318,11 +320,15 @@ spu_irq_class_0(int irq, void *data)
318 stat = spu_int_stat_get(spu, 0) & mask; 320 stat = spu_int_stat_get(spu, 0) & mask;
319 321
320 spu->class_0_pending |= stat; 322 spu->class_0_pending |= stat;
321 spu->dsisr = spu_mfc_dsisr_get(spu); 323 spu->class_0_dsisr = spu_mfc_dsisr_get(spu);
322 spu->dar = spu_mfc_dar_get(spu); 324 spu->class_0_dar = spu_mfc_dar_get(spu);
323 spin_unlock(&spu->register_lock); 325 spin_unlock(&spu->register_lock);
324 326
325 spu->stop_callback(spu); 327 spu->stop_callback(spu, 0);
328
329 spu->class_0_pending = 0;
330 spu->class_0_dsisr = 0;
331 spu->class_0_dar = 0;
326 332
327 spu_int_stat_clear(spu, 0, stat); 333 spu_int_stat_clear(spu, 0, stat);
328 334
@@ -363,6 +369,9 @@ spu_irq_class_1(int irq, void *data)
363 if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR) 369 if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR)
364 ; 370 ;
365 371
372 spu->class_1_dsisr = 0;
373 spu->class_1_dar = 0;
374
366 return stat ? IRQ_HANDLED : IRQ_NONE; 375 return stat ? IRQ_HANDLED : IRQ_NONE;
367} 376}
368 377
@@ -396,10 +405,10 @@ spu_irq_class_2(int irq, void *data)
396 spu->ibox_callback(spu); 405 spu->ibox_callback(spu);
397 406
398 if (stat & CLASS2_SPU_STOP_INTR) 407 if (stat & CLASS2_SPU_STOP_INTR)
399 spu->stop_callback(spu); 408 spu->stop_callback(spu, 2);
400 409
401 if (stat & CLASS2_SPU_HALT_INTR) 410 if (stat & CLASS2_SPU_HALT_INTR)
402 spu->stop_callback(spu); 411 spu->stop_callback(spu, 2);
403 412
404 if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR) 413 if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR)
405 spu->mfc_callback(spu); 414 spu->mfc_callback(spu);