aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c27
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c17
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c29
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h2
-rw-r--r--arch/powerpc/xmon/xmon.c6
-rw-r--r--include/asm-powerpc/spu.h8
-rw-r--r--include/asm-powerpc/spu_csa.h3
7 files changed, 60 insertions, 32 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 6bab44b7716b..b9ae675640d0 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);
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index e46d300e21a5..f093a581ac74 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -83,13 +83,18 @@ int spufs_handle_class0(struct spu_context *ctx)
83 return 0; 83 return 0;
84 84
85 if (stat & CLASS0_DMA_ALIGNMENT_INTR) 85 if (stat & CLASS0_DMA_ALIGNMENT_INTR)
86 spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_DMA_ALIGNMENT); 86 spufs_handle_event(ctx, ctx->csa.class_0_dar,
87 SPE_EVENT_DMA_ALIGNMENT);
87 88
88 if (stat & CLASS0_INVALID_DMA_COMMAND_INTR) 89 if (stat & CLASS0_INVALID_DMA_COMMAND_INTR)
89 spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_INVALID_DMA); 90 spufs_handle_event(ctx, ctx->csa.class_0_dar,
91 SPE_EVENT_INVALID_DMA);
90 92
91 if (stat & CLASS0_SPU_ERROR_INTR) 93 if (stat & CLASS0_SPU_ERROR_INTR)
92 spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_SPE_ERROR); 94 spufs_handle_event(ctx, ctx->csa.class_0_dar,
95 SPE_EVENT_SPE_ERROR);
96
97 ctx->csa.class_0_pending = 0;
93 98
94 return -EIO; 99 return -EIO;
95} 100}
@@ -119,8 +124,8 @@ int spufs_handle_class1(struct spu_context *ctx)
119 * in time, we can still expect to get the same fault 124 * in time, we can still expect to get the same fault
120 * the immediately after the context restore. 125 * the immediately after the context restore.
121 */ 126 */
122 ea = ctx->csa.dar; 127 ea = ctx->csa.class_1_dar;
123 dsisr = ctx->csa.dsisr; 128 dsisr = ctx->csa.class_1_dsisr;
124 129
125 if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) 130 if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)))
126 return 0; 131 return 0;
@@ -158,7 +163,7 @@ int spufs_handle_class1(struct spu_context *ctx)
158 * time slicing will not preempt the context while the page fault 163 * time slicing will not preempt the context while the page fault
159 * handler is running. Context switch code removes mappings. 164 * handler is running. Context switch code removes mappings.
160 */ 165 */
161 ctx->csa.dar = ctx->csa.dsisr = 0; 166 ctx->csa.class_1_dar = ctx->csa.class_1_dsisr = 0;
162 167
163 /* 168 /*
164 * If we handled the fault successfully and are in runnable 169 * If we handled the fault successfully and are in runnable
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index e764a43b544e..b7493b865812 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -11,7 +11,7 @@
11#include "spufs.h" 11#include "spufs.h"
12 12
13/* interrupt-level stop callback function. */ 13/* interrupt-level stop callback function. */
14void spufs_stop_callback(struct spu *spu) 14void spufs_stop_callback(struct spu *spu, int irq)
15{ 15{
16 struct spu_context *ctx = spu->ctx; 16 struct spu_context *ctx = spu->ctx;
17 17
@@ -24,9 +24,19 @@ void spufs_stop_callback(struct spu *spu)
24 */ 24 */
25 if (ctx) { 25 if (ctx) {
26 /* Copy exception arguments into module specific structure */ 26 /* Copy exception arguments into module specific structure */
27 ctx->csa.class_0_pending = spu->class_0_pending; 27 switch(irq) {
28 ctx->csa.dsisr = spu->dsisr; 28 case 0 :
29 ctx->csa.dar = spu->dar; 29 ctx->csa.class_0_pending = spu->class_0_pending;
30 ctx->csa.class_0_dsisr = spu->class_0_dsisr;
31 ctx->csa.class_0_dar = spu->class_0_dar;
32 break;
33 case 1 :
34 ctx->csa.class_1_dsisr = spu->class_1_dsisr;
35 ctx->csa.class_1_dar = spu->class_1_dar;
36 break;
37 case 2 :
38 break;
39 }
30 40
31 /* ensure that the exception status has hit memory before a 41 /* ensure that the exception status has hit memory before a
32 * thread waiting on the context's stop queue is woken */ 42 * thread waiting on the context's stop queue is woken */
@@ -34,11 +44,6 @@ void spufs_stop_callback(struct spu *spu)
34 44
35 wake_up_all(&ctx->stop_wq); 45 wake_up_all(&ctx->stop_wq);
36 } 46 }
37
38 /* Clear callback arguments from spu structure */
39 spu->class_0_pending = 0;
40 spu->dsisr = 0;
41 spu->dar = 0;
42} 47}
43 48
44int spu_stopped(struct spu_context *ctx, u32 *stat) 49int spu_stopped(struct spu_context *ctx, u32 *stat)
@@ -56,7 +61,11 @@ int spu_stopped(struct spu_context *ctx, u32 *stat)
56 if (!(*stat & SPU_STATUS_RUNNING) && (*stat & stopped)) 61 if (!(*stat & SPU_STATUS_RUNNING) && (*stat & stopped))
57 return 1; 62 return 1;
58 63
59 dsisr = ctx->csa.dsisr; 64 dsisr = ctx->csa.class_0_dsisr;
65 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
66 return 1;
67
68 dsisr = ctx->csa.class_1_dsisr;
60 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) 69 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
61 return 1; 70 return 1;
62 71
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index dc3a215a6a22..454c277c1457 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -332,7 +332,7 @@ size_t spu_ibox_read(struct spu_context *ctx, u32 *data);
332/* irq callback funcs. */ 332/* irq callback funcs. */
333void spufs_ibox_callback(struct spu *spu); 333void spufs_ibox_callback(struct spu *spu);
334void spufs_wbox_callback(struct spu *spu); 334void spufs_wbox_callback(struct spu *spu);
335void spufs_stop_callback(struct spu *spu); 335void spufs_stop_callback(struct spu *spu, int irq);
336void spufs_mfc_callback(struct spu *spu); 336void spufs_mfc_callback(struct spu *spu);
337void spufs_dma_callback(struct spu *spu, int type); 337void spufs_dma_callback(struct spu *spu, int type);
338 338
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 52c74780f403..1702de9395ee 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2842,9 +2842,11 @@ static void dump_spu_fields(struct spu *spu)
2842 DUMP_FIELD(spu, "0x%lx", ls_size); 2842 DUMP_FIELD(spu, "0x%lx", ls_size);
2843 DUMP_FIELD(spu, "0x%x", node); 2843 DUMP_FIELD(spu, "0x%x", node);
2844 DUMP_FIELD(spu, "0x%lx", flags); 2844 DUMP_FIELD(spu, "0x%lx", flags);
2845 DUMP_FIELD(spu, "0x%lx", dar);
2846 DUMP_FIELD(spu, "0x%lx", dsisr);
2847 DUMP_FIELD(spu, "%d", class_0_pending); 2845 DUMP_FIELD(spu, "%d", class_0_pending);
2846 DUMP_FIELD(spu, "0x%lx", class_0_dar);
2847 DUMP_FIELD(spu, "0x%lx", class_0_dsisr);
2848 DUMP_FIELD(spu, "0x%lx", class_1_dar);
2849 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
2848 DUMP_FIELD(spu, "0x%lx", irqs[0]); 2850 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2849 DUMP_FIELD(spu, "0x%lx", irqs[1]); 2851 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2850 DUMP_FIELD(spu, "0x%lx", irqs[2]); 2852 DUMP_FIELD(spu, "0x%lx", irqs[2]);
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index e3c845b0f764..882aa953968a 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -128,9 +128,11 @@ struct spu {
128 unsigned int irqs[3]; 128 unsigned int irqs[3];
129 u32 node; 129 u32 node;
130 u64 flags; 130 u64 flags;
131 u64 dar;
132 u64 dsisr;
133 u64 class_0_pending; 131 u64 class_0_pending;
132 u64 class_0_dar;
133 u64 class_0_dsisr;
134 u64 class_1_dar;
135 u64 class_1_dsisr;
134 size_t ls_size; 136 size_t ls_size;
135 unsigned int slb_replace; 137 unsigned int slb_replace;
136 struct mm_struct *mm; 138 struct mm_struct *mm;
@@ -143,7 +145,7 @@ struct spu {
143 145
144 void (* wbox_callback)(struct spu *spu); 146 void (* wbox_callback)(struct spu *spu);
145 void (* ibox_callback)(struct spu *spu); 147 void (* ibox_callback)(struct spu *spu);
146 void (* stop_callback)(struct spu *spu); 148 void (* stop_callback)(struct spu *spu, int irq);
147 void (* mfc_callback)(struct spu *spu); 149 void (* mfc_callback)(struct spu *spu);
148 150
149 char irq_c0[8]; 151 char irq_c0[8];
diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h
index 0ab6bff86078..129ec148d451 100644
--- a/include/asm-powerpc/spu_csa.h
+++ b/include/asm-powerpc/spu_csa.h
@@ -254,7 +254,8 @@ struct spu_state {
254 u64 spu_chnldata_RW[32]; 254 u64 spu_chnldata_RW[32];
255 u32 spu_mailbox_data[4]; 255 u32 spu_mailbox_data[4];
256 u32 pu_mailbox_data[1]; 256 u32 pu_mailbox_data[1];
257 u64 dar, dsisr, class_0_pending; 257 u64 class_0_dar, class_0_dsisr, class_0_pending;
258 u64 class_1_dar, class_1_dsisr;
258 unsigned long suspend_time; 259 unsigned long suspend_time;
259 spinlock_t register_lock; 260 spinlock_t register_lock;
260}; 261};