diff options
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/switch.c | 23 | ||||
-rw-r--r-- | include/asm-powerpc/spu.h | 1 |
3 files changed, 19 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index b9ae675640d0..70c660121ec4 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -141,6 +141,10 @@ static void spu_restart_dma(struct spu *spu) | |||
141 | 141 | ||
142 | if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) | 142 | if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) |
143 | out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); | 143 | out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); |
144 | else { | ||
145 | set_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags); | ||
146 | mb(); | ||
147 | } | ||
144 | } | 148 | } |
145 | 149 | ||
146 | static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) | 150 | static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) |
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 47c658051fcb..3df9a36eb2f5 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c | |||
@@ -139,6 +139,7 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) | |||
139 | * via a simple load. | 139 | * via a simple load. |
140 | */ | 140 | */ |
141 | set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); | 141 | set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); |
142 | clear_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags); | ||
142 | synchronize_irq(spu->irqs[0]); | 143 | synchronize_irq(spu->irqs[0]); |
143 | synchronize_irq(spu->irqs[1]); | 144 | synchronize_irq(spu->irqs[1]); |
144 | synchronize_irq(spu->irqs[2]); | 145 | synchronize_irq(spu->irqs[2]); |
@@ -739,10 +740,14 @@ static inline void set_switch_active(struct spu_state *csa, struct spu *spu) | |||
739 | /* Save, Step 48: | 740 | /* Save, Step 48: |
740 | * Restore, Step 23. | 741 | * Restore, Step 23. |
741 | * Change the software context switch pending flag | 742 | * Change the software context switch pending flag |
742 | * to context switch active. | 743 | * to context switch active. This implementation does |
744 | * not uses a switch active flag. | ||
743 | * | 745 | * |
744 | * This implementation does not uses a switch active flag. | 746 | * Now that we have saved the mfc in the csa, we can add in the |
747 | * restart command if an exception occurred. | ||
745 | */ | 748 | */ |
749 | if (test_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags)) | ||
750 | csa->priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND; | ||
746 | clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); | 751 | clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); |
747 | mb(); | 752 | mb(); |
748 | } | 753 | } |
@@ -1742,15 +1747,15 @@ static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu) | |||
1742 | */ | 1747 | */ |
1743 | out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW); | 1748 | out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW); |
1744 | eieio(); | 1749 | eieio(); |
1750 | |||
1745 | /* | 1751 | /* |
1746 | * FIXME: this is to restart a DMA that we were processing | 1752 | * The queue is put back into the same state that was evident prior to |
1747 | * before the save. better remember the fault information | 1753 | * the context switch. The suspend flag is added to the saved state in |
1748 | * in the csa instead. | 1754 | * the csa, if the operational state was suspending or suspended. In |
1755 | * this case, the code that suspended the mfc is responsible for | ||
1756 | * continuing it. Note that SPE faults do not change the operational | ||
1757 | * state of the spu. | ||
1749 | */ | 1758 | */ |
1750 | if ((csa->priv2.mfc_control_RW & MFC_CNTL_SUSPEND_DMA_QUEUE_MASK)) { | ||
1751 | out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); | ||
1752 | eieio(); | ||
1753 | } | ||
1754 | } | 1759 | } |
1755 | 1760 | ||
1756 | static inline void enable_user_access(struct spu_state *csa, struct spu *spu) | 1761 | static inline void enable_user_access(struct spu_state *csa, struct spu *spu) |
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index 882aa953968a..6abead6e681a 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h | |||
@@ -100,6 +100,7 @@ | |||
100 | 100 | ||
101 | /* Flag indicating progress during context switch. */ | 101 | /* Flag indicating progress during context switch. */ |
102 | #define SPU_CONTEXT_SWITCH_PENDING 0UL | 102 | #define SPU_CONTEXT_SWITCH_PENDING 0UL |
103 | #define SPU_CONTEXT_FAULT_PENDING 1UL | ||
103 | 104 | ||
104 | struct spu_context; | 105 | struct spu_context; |
105 | struct spu_runqueue; | 106 | struct spu_runqueue; |