diff options
-rw-r--r-- | arch/powerpc/include/asm/ppc_asm.h | 83 | ||||
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 23 | ||||
-rw-r--r-- | arch/powerpc/kernel/fpu.S | 12 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 8 |
6 files changed, 134 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index c2d0e58aba31..54219cea9e88 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h | |||
@@ -123,6 +123,89 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | |||
123 | #define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) | 123 | #define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) |
124 | #define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) | 124 | #define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) |
125 | 125 | ||
126 | /* Save/restore FPRs, VRs and VSRs from their checkpointed backups in | ||
127 | * thread_struct: | ||
128 | */ | ||
129 | #define SAVE_FPR_TRANSACT(n, base) stfd n,THREAD_TRANSACT_FPR0+ \ | ||
130 | 8*TS_FPRWIDTH*(n)(base) | ||
131 | #define SAVE_2FPRS_TRANSACT(n, base) SAVE_FPR_TRANSACT(n, base); \ | ||
132 | SAVE_FPR_TRANSACT(n+1, base) | ||
133 | #define SAVE_4FPRS_TRANSACT(n, base) SAVE_2FPRS_TRANSACT(n, base); \ | ||
134 | SAVE_2FPRS_TRANSACT(n+2, base) | ||
135 | #define SAVE_8FPRS_TRANSACT(n, base) SAVE_4FPRS_TRANSACT(n, base); \ | ||
136 | SAVE_4FPRS_TRANSACT(n+4, base) | ||
137 | #define SAVE_16FPRS_TRANSACT(n, base) SAVE_8FPRS_TRANSACT(n, base); \ | ||
138 | SAVE_8FPRS_TRANSACT(n+8, base) | ||
139 | #define SAVE_32FPRS_TRANSACT(n, base) SAVE_16FPRS_TRANSACT(n, base); \ | ||
140 | SAVE_16FPRS_TRANSACT(n+16, base) | ||
141 | |||
142 | #define REST_FPR_TRANSACT(n, base) lfd n,THREAD_TRANSACT_FPR0+ \ | ||
143 | 8*TS_FPRWIDTH*(n)(base) | ||
144 | #define REST_2FPRS_TRANSACT(n, base) REST_FPR_TRANSACT(n, base); \ | ||
145 | REST_FPR_TRANSACT(n+1, base) | ||
146 | #define REST_4FPRS_TRANSACT(n, base) REST_2FPRS_TRANSACT(n, base); \ | ||
147 | REST_2FPRS_TRANSACT(n+2, base) | ||
148 | #define REST_8FPRS_TRANSACT(n, base) REST_4FPRS_TRANSACT(n, base); \ | ||
149 | REST_4FPRS_TRANSACT(n+4, base) | ||
150 | #define REST_16FPRS_TRANSACT(n, base) REST_8FPRS_TRANSACT(n, base); \ | ||
151 | REST_8FPRS_TRANSACT(n+8, base) | ||
152 | #define REST_32FPRS_TRANSACT(n, base) REST_16FPRS_TRANSACT(n, base); \ | ||
153 | REST_16FPRS_TRANSACT(n+16, base) | ||
154 | |||
155 | |||
156 | #define SAVE_VR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VR0+(16*(n)); \ | ||
157 | stvx n,b,base | ||
158 | #define SAVE_2VRS_TRANSACT(n,b,base) SAVE_VR_TRANSACT(n,b,base); \ | ||
159 | SAVE_VR_TRANSACT(n+1,b,base) | ||
160 | #define SAVE_4VRS_TRANSACT(n,b,base) SAVE_2VRS_TRANSACT(n,b,base); \ | ||
161 | SAVE_2VRS_TRANSACT(n+2,b,base) | ||
162 | #define SAVE_8VRS_TRANSACT(n,b,base) SAVE_4VRS_TRANSACT(n,b,base); \ | ||
163 | SAVE_4VRS_TRANSACT(n+4,b,base) | ||
164 | #define SAVE_16VRS_TRANSACT(n,b,base) SAVE_8VRS_TRANSACT(n,b,base); \ | ||
165 | SAVE_8VRS_TRANSACT(n+8,b,base) | ||
166 | #define SAVE_32VRS_TRANSACT(n,b,base) SAVE_16VRS_TRANSACT(n,b,base); \ | ||
167 | SAVE_16VRS_TRANSACT(n+16,b,base) | ||
168 | |||
169 | #define REST_VR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VR0+(16*(n)); \ | ||
170 | lvx n,b,base | ||
171 | #define REST_2VRS_TRANSACT(n,b,base) REST_VR_TRANSACT(n,b,base); \ | ||
172 | REST_VR_TRANSACT(n+1,b,base) | ||
173 | #define REST_4VRS_TRANSACT(n,b,base) REST_2VRS_TRANSACT(n,b,base); \ | ||
174 | REST_2VRS_TRANSACT(n+2,b,base) | ||
175 | #define REST_8VRS_TRANSACT(n,b,base) REST_4VRS_TRANSACT(n,b,base); \ | ||
176 | REST_4VRS_TRANSACT(n+4,b,base) | ||
177 | #define REST_16VRS_TRANSACT(n,b,base) REST_8VRS_TRANSACT(n,b,base); \ | ||
178 | REST_8VRS_TRANSACT(n+8,b,base) | ||
179 | #define REST_32VRS_TRANSACT(n,b,base) REST_16VRS_TRANSACT(n,b,base); \ | ||
180 | REST_16VRS_TRANSACT(n+16,b,base) | ||
181 | |||
182 | |||
183 | #define SAVE_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \ | ||
184 | STXVD2X(n,R##base,R##b) | ||
185 | #define SAVE_2VSRS_TRANSACT(n,b,base) SAVE_VSR_TRANSACT(n,b,base); \ | ||
186 | SAVE_VSR_TRANSACT(n+1,b,base) | ||
187 | #define SAVE_4VSRS_TRANSACT(n,b,base) SAVE_2VSRS_TRANSACT(n,b,base); \ | ||
188 | SAVE_2VSRS_TRANSACT(n+2,b,base) | ||
189 | #define SAVE_8VSRS_TRANSACT(n,b,base) SAVE_4VSRS_TRANSACT(n,b,base); \ | ||
190 | SAVE_4VSRS_TRANSACT(n+4,b,base) | ||
191 | #define SAVE_16VSRS_TRANSACT(n,b,base) SAVE_8VSRS_TRANSACT(n,b,base); \ | ||
192 | SAVE_8VSRS_TRANSACT(n+8,b,base) | ||
193 | #define SAVE_32VSRS_TRANSACT(n,b,base) SAVE_16VSRS_TRANSACT(n,b,base); \ | ||
194 | SAVE_16VSRS_TRANSACT(n+16,b,base) | ||
195 | |||
196 | #define REST_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \ | ||
197 | LXVD2X(n,R##base,R##b) | ||
198 | #define REST_2VSRS_TRANSACT(n,b,base) REST_VSR_TRANSACT(n,b,base); \ | ||
199 | REST_VSR_TRANSACT(n+1,b,base) | ||
200 | #define REST_4VSRS_TRANSACT(n,b,base) REST_2VSRS_TRANSACT(n,b,base); \ | ||
201 | REST_2VSRS_TRANSACT(n+2,b,base) | ||
202 | #define REST_8VSRS_TRANSACT(n,b,base) REST_4VSRS_TRANSACT(n,b,base); \ | ||
203 | REST_4VSRS_TRANSACT(n+4,b,base) | ||
204 | #define REST_16VSRS_TRANSACT(n,b,base) REST_8VSRS_TRANSACT(n,b,base); \ | ||
205 | REST_8VSRS_TRANSACT(n+8,b,base) | ||
206 | #define REST_32VSRS_TRANSACT(n,b,base) REST_16VSRS_TRANSACT(n,b,base); \ | ||
207 | REST_16VSRS_TRANSACT(n+16,b,base) | ||
208 | |||
126 | /* Save the lower 32 VSRs in the thread VSR region */ | 209 | /* Save the lower 32 VSRs in the thread VSR region */ |
127 | #define SAVE_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); STXVD2X(n,R##base,R##b) | 210 | #define SAVE_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); STXVD2X(n,R##base,R##b) |
128 | #define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base) | 211 | #define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base) |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index fc41ab3aa114..7ff9eaa3ea6c 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -152,6 +152,7 @@ typedef struct { | |||
152 | #define TS_FPROFFSET 0 | 152 | #define TS_FPROFFSET 0 |
153 | #define TS_VSRLOWOFFSET 1 | 153 | #define TS_VSRLOWOFFSET 1 |
154 | #define TS_FPR(i) fpr[i][TS_FPROFFSET] | 154 | #define TS_FPR(i) fpr[i][TS_FPROFFSET] |
155 | #define TS_TRANS_FPR(i) transact_fpr[i][TS_FPROFFSET] | ||
155 | 156 | ||
156 | struct thread_struct { | 157 | struct thread_struct { |
157 | unsigned long ksp; /* Kernel stack pointer */ | 158 | unsigned long ksp; /* Kernel stack pointer */ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index e295a09b1f06..0fdc97496d7c 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -125,6 +125,29 @@ int main(void) | |||
125 | #ifdef CONFIG_PPC_BOOK3S_64 | 125 | #ifdef CONFIG_PPC_BOOK3S_64 |
126 | DEFINE(THREAD_TAR, offsetof(struct thread_struct, tar)); | 126 | DEFINE(THREAD_TAR, offsetof(struct thread_struct, tar)); |
127 | #endif | 127 | #endif |
128 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | ||
129 | DEFINE(THREAD_TM_TFHAR, offsetof(struct thread_struct, tm_tfhar)); | ||
130 | DEFINE(THREAD_TM_TEXASR, offsetof(struct thread_struct, tm_texasr)); | ||
131 | DEFINE(THREAD_TM_TFIAR, offsetof(struct thread_struct, tm_tfiar)); | ||
132 | DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs)); | ||
133 | DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct, | ||
134 | transact_vr[0])); | ||
135 | DEFINE(THREAD_TRANSACT_VSCR, offsetof(struct thread_struct, | ||
136 | transact_vscr)); | ||
137 | DEFINE(THREAD_TRANSACT_VRSAVE, offsetof(struct thread_struct, | ||
138 | transact_vrsave)); | ||
139 | DEFINE(THREAD_TRANSACT_FPR0, offsetof(struct thread_struct, | ||
140 | transact_fpr[0])); | ||
141 | DEFINE(THREAD_TRANSACT_FPSCR, offsetof(struct thread_struct, | ||
142 | transact_fpscr)); | ||
143 | #ifdef CONFIG_VSX | ||
144 | DEFINE(THREAD_TRANSACT_VSR0, offsetof(struct thread_struct, | ||
145 | transact_fpr[0])); | ||
146 | #endif | ||
147 | /* Local pt_regs on stack for Transactional Memory funcs. */ | ||
148 | DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD + | ||
149 | sizeof(struct pt_regs) + 16); | ||
150 | #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ | ||
128 | 151 | ||
129 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | 152 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); |
130 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); | 153 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); |
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index e0ada05f2df3..adb155195394 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S | |||
@@ -35,6 +35,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ | |||
35 | 2: REST_32VSRS(n,c,base); \ | 35 | 2: REST_32VSRS(n,c,base); \ |
36 | 3: | 36 | 3: |
37 | 37 | ||
38 | #define __REST_32FPVSRS_TRANSACT(n,c,base) \ | ||
39 | BEGIN_FTR_SECTION \ | ||
40 | b 2f; \ | ||
41 | END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ | ||
42 | REST_32FPRS_TRANSACT(n,base); \ | ||
43 | b 3f; \ | ||
44 | 2: REST_32VSRS_TRANSACT(n,c,base); \ | ||
45 | 3: | ||
46 | |||
38 | #define __SAVE_32FPVSRS(n,c,base) \ | 47 | #define __SAVE_32FPVSRS(n,c,base) \ |
39 | BEGIN_FTR_SECTION \ | 48 | BEGIN_FTR_SECTION \ |
40 | b 2f; \ | 49 | b 2f; \ |
@@ -45,9 +54,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ | |||
45 | 3: | 54 | 3: |
46 | #else | 55 | #else |
47 | #define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) | 56 | #define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) |
57 | #define __REST_32FPVSRS_TRANSACT(n,b,base) REST_32FPRS(n, base) | ||
48 | #define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) | 58 | #define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) |
49 | #endif | 59 | #endif |
50 | #define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) | 60 | #define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) |
61 | #define REST_32FPVSRS_TRANSACT(n,c,base) \ | ||
62 | __REST_32FPVSRS_TRANSACT(n,__REG_##c,__REG_##base) | ||
51 | #define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) | 63 | #define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) |
52 | 64 | ||
53 | /* | 65 | /* |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 96e31de89b43..b0a0321e4bb6 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -57,6 +57,13 @@ | |||
57 | #include <linux/kprobes.h> | 57 | #include <linux/kprobes.h> |
58 | #include <linux/kdebug.h> | 58 | #include <linux/kdebug.h> |
59 | 59 | ||
60 | /* Transactional Memory debug */ | ||
61 | #ifdef TM_DEBUG_SW | ||
62 | #define TM_DEBUG(x...) printk(KERN_INFO x) | ||
63 | #else | ||
64 | #define TM_DEBUG(x...) do { } while(0) | ||
65 | #endif | ||
66 | |||
60 | extern unsigned long _get_SP(void); | 67 | extern unsigned long _get_SP(void); |
61 | 68 | ||
62 | #ifndef CONFIG_SMP | 69 | #ifndef CONFIG_SMP |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index a008cf5c0fce..bd5de5deaf51 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -78,6 +78,13 @@ EXPORT_SYMBOL(__debugger_break_match); | |||
78 | EXPORT_SYMBOL(__debugger_fault_handler); | 78 | EXPORT_SYMBOL(__debugger_fault_handler); |
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | /* Transactional Memory trap debug */ | ||
82 | #ifdef TM_DEBUG_SW | ||
83 | #define TM_DEBUG(x...) printk(KERN_INFO x) | ||
84 | #else | ||
85 | #define TM_DEBUG(x...) do { } while(0) | ||
86 | #endif | ||
87 | |||
81 | /* | 88 | /* |
82 | * Trap & Exception support | 89 | * Trap & Exception support |
83 | */ | 90 | */ |
@@ -350,6 +357,7 @@ static inline int check_io_access(struct pt_regs *regs) | |||
350 | exception is in the MSR. */ | 357 | exception is in the MSR. */ |
351 | #define get_reason(regs) ((regs)->msr) | 358 | #define get_reason(regs) ((regs)->msr) |
352 | #define get_mc_reason(regs) ((regs)->msr) | 359 | #define get_mc_reason(regs) ((regs)->msr) |
360 | #define REASON_TM 0x200000 | ||
353 | #define REASON_FP 0x100000 | 361 | #define REASON_FP 0x100000 |
354 | #define REASON_ILLEGAL 0x80000 | 362 | #define REASON_ILLEGAL 0x80000 |
355 | #define REASON_PRIVILEGED 0x40000 | 363 | #define REASON_PRIVILEGED 0x40000 |