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 | }; |
