diff options
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 27 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/fault.c | 17 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/run.c | 29 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 2 | ||||
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 6 | ||||
-rw-r--r-- | include/asm-powerpc/spu.h | 8 | ||||
-rw-r--r-- | include/asm-powerpc/spu_csa.h | 3 |
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. */ |
14 | void spufs_stop_callback(struct spu *spu) | 14 | void 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 | ||
44 | int spu_stopped(struct spu_context *ctx, u32 *stat) | 49 | int 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. */ |
333 | void spufs_ibox_callback(struct spu *spu); | 333 | void spufs_ibox_callback(struct spu *spu); |
334 | void spufs_wbox_callback(struct spu *spu); | 334 | void spufs_wbox_callback(struct spu *spu); |
335 | void spufs_stop_callback(struct spu *spu); | 335 | void spufs_stop_callback(struct spu *spu, int irq); |
336 | void spufs_mfc_callback(struct spu *spu); | 336 | void spufs_mfc_callback(struct spu *spu); |
337 | void spufs_dma_callback(struct spu *spu, int type); | 337 | void 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 | }; |