diff options
author | David Daney <david.daney@cavium.com> | 2015-01-15 08:11:07 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-02-20 09:29:08 -0500 |
commit | 6b3a287e6351b00df6624b41c160e1c0817f40e2 (patch) | |
tree | 6315e36070f0d3ab2562382ffa624d1cb02d9e5b /arch | |
parent | d6e41525e356a8dc4b9ad6249a644d4123240881 (diff) |
MIPS: OCTEON: Save and restore CP2 SHA3 state
Allocate new save space, and then save/restore the registers if
OCTEON III.
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov@auriga.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/8935/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/octeon_switch.S | 43 |
3 files changed, 35 insertions, 11 deletions
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index be903acf4fe4..b5dcbee01fd7 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h | |||
@@ -205,6 +205,8 @@ struct octeon_cop2_state { | |||
205 | unsigned long cop2_gfm_poly; | 205 | unsigned long cop2_gfm_poly; |
206 | /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */ | 206 | /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */ |
207 | unsigned long cop2_gfm_result[2]; | 207 | unsigned long cop2_gfm_result[2]; |
208 | /* DMFC2 rt, 0x24F, DMFC2 rt, 0x50, OCTEON III */ | ||
209 | unsigned long cop2_sha3[2]; | ||
208 | }; | 210 | }; |
209 | #define COP2_INIT \ | 211 | #define COP2_INIT \ |
210 | .cp2 = {0,}, | 212 | .cp2 = {0,}, |
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 7b6c11aa1cae..dad6ce602a7c 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -383,6 +383,7 @@ void output_octeon_cop2_state_defines(void) | |||
383 | OFFSET(OCTEON_CP2_GFM_RESULT, octeon_cop2_state, cop2_gfm_result); | 383 | OFFSET(OCTEON_CP2_GFM_RESULT, octeon_cop2_state, cop2_gfm_result); |
384 | OFFSET(OCTEON_CP2_HSH_DATW, octeon_cop2_state, cop2_hsh_datw); | 384 | OFFSET(OCTEON_CP2_HSH_DATW, octeon_cop2_state, cop2_hsh_datw); |
385 | OFFSET(OCTEON_CP2_HSH_IVW, octeon_cop2_state, cop2_hsh_ivw); | 385 | OFFSET(OCTEON_CP2_HSH_IVW, octeon_cop2_state, cop2_hsh_ivw); |
386 | OFFSET(OCTEON_CP2_SHA3, octeon_cop2_state, cop2_sha3); | ||
386 | OFFSET(THREAD_CP2, task_struct, thread.cp2); | 387 | OFFSET(THREAD_CP2, task_struct, thread.cp2); |
387 | OFFSET(THREAD_CVMSEG, task_struct, thread.cvmseg.cvmseg); | 388 | OFFSET(THREAD_CVMSEG, task_struct, thread.cvmseg.cvmseg); |
388 | BLANK(); | 389 | BLANK(); |
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index 2787c014ec56..590ca2d56b6a 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S | |||
@@ -142,6 +142,8 @@ | |||
142 | * void octeon_cop2_save(struct octeon_cop2_state *a0) | 142 | * void octeon_cop2_save(struct octeon_cop2_state *a0) |
143 | */ | 143 | */ |
144 | .align 7 | 144 | .align 7 |
145 | .set push | ||
146 | .set noreorder | ||
145 | LEAF(octeon_cop2_save) | 147 | LEAF(octeon_cop2_save) |
146 | 148 | ||
147 | dmfc0 t9, $9,7 /* CvmCtl register. */ | 149 | dmfc0 t9, $9,7 /* CvmCtl register. */ |
@@ -152,17 +154,17 @@ | |||
152 | dmfc2 t2, 0x0200 | 154 | dmfc2 t2, 0x0200 |
153 | sd t0, OCTEON_CP2_CRC_IV(a0) | 155 | sd t0, OCTEON_CP2_CRC_IV(a0) |
154 | sd t1, OCTEON_CP2_CRC_LENGTH(a0) | 156 | sd t1, OCTEON_CP2_CRC_LENGTH(a0) |
155 | sd t2, OCTEON_CP2_CRC_POLY(a0) | ||
156 | /* Skip next instructions if CvmCtl[NODFA_CP2] set */ | 157 | /* Skip next instructions if CvmCtl[NODFA_CP2] set */ |
157 | bbit1 t9, 28, 1f | 158 | bbit1 t9, 28, 1f |
159 | sd t2, OCTEON_CP2_CRC_POLY(a0) | ||
158 | 160 | ||
159 | /* Save the LLM state */ | 161 | /* Save the LLM state */ |
160 | dmfc2 t0, 0x0402 | 162 | dmfc2 t0, 0x0402 |
161 | dmfc2 t1, 0x040A | 163 | dmfc2 t1, 0x040A |
162 | sd t0, OCTEON_CP2_LLM_DAT(a0) | 164 | sd t0, OCTEON_CP2_LLM_DAT(a0) |
163 | sd t1, OCTEON_CP2_LLM_DAT+8(a0) | ||
164 | 165 | ||
165 | 1: bbit1 t9, 26, 3f /* done if CvmCtl[NOCRYPTO] set */ | 166 | 1: bbit1 t9, 26, 3f /* done if CvmCtl[NOCRYPTO] set */ |
167 | sd t1, OCTEON_CP2_LLM_DAT+8(a0) | ||
166 | 168 | ||
167 | /* Save the COP2 crypto state */ | 169 | /* Save the COP2 crypto state */ |
168 | /* this part is mostly common to both pass 1 and later revisions */ | 170 | /* this part is mostly common to both pass 1 and later revisions */ |
@@ -193,18 +195,20 @@ | |||
193 | sd t2, OCTEON_CP2_AES_KEY+16(a0) | 195 | sd t2, OCTEON_CP2_AES_KEY+16(a0) |
194 | dmfc2 t2, 0x0101 | 196 | dmfc2 t2, 0x0101 |
195 | sd t3, OCTEON_CP2_AES_KEY+24(a0) | 197 | sd t3, OCTEON_CP2_AES_KEY+24(a0) |
196 | mfc0 t3, $15,0 /* Get the processor ID register */ | 198 | mfc0 v0, $15,0 /* Get the processor ID register */ |
197 | sd t0, OCTEON_CP2_AES_KEYLEN(a0) | 199 | sd t0, OCTEON_CP2_AES_KEYLEN(a0) |
198 | li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */ | 200 | li v1, 0x000d0000 /* This is the processor ID of Octeon Pass1 */ |
199 | sd t1, OCTEON_CP2_AES_RESULT(a0) | 201 | sd t1, OCTEON_CP2_AES_RESULT(a0) |
200 | sd t2, OCTEON_CP2_AES_RESULT+8(a0) | ||
201 | /* Skip to the Pass1 version of the remainder of the COP2 state */ | 202 | /* Skip to the Pass1 version of the remainder of the COP2 state */ |
202 | beq t3, t0, 2f | 203 | beq v0, v1, 2f |
204 | sd t2, OCTEON_CP2_AES_RESULT+8(a0) | ||
203 | 205 | ||
204 | /* the non-pass1 state when !CvmCtl[NOCRYPTO] */ | 206 | /* the non-pass1 state when !CvmCtl[NOCRYPTO] */ |
205 | dmfc2 t1, 0x0240 | 207 | dmfc2 t1, 0x0240 |
206 | dmfc2 t2, 0x0241 | 208 | dmfc2 t2, 0x0241 |
209 | ori v1, v1, 0x9500 /* lowest OCTEON III PrId*/ | ||
207 | dmfc2 t3, 0x0242 | 210 | dmfc2 t3, 0x0242 |
211 | subu v1, v0, v1 /* prid - lowest OCTEON III PrId */ | ||
208 | dmfc2 t0, 0x0243 | 212 | dmfc2 t0, 0x0243 |
209 | sd t1, OCTEON_CP2_HSH_DATW(a0) | 213 | sd t1, OCTEON_CP2_HSH_DATW(a0) |
210 | dmfc2 t1, 0x0244 | 214 | dmfc2 t1, 0x0244 |
@@ -257,8 +261,16 @@ | |||
257 | sd t1, OCTEON_CP2_GFM_MULT+8(a0) | 261 | sd t1, OCTEON_CP2_GFM_MULT+8(a0) |
258 | sd t2, OCTEON_CP2_GFM_POLY(a0) | 262 | sd t2, OCTEON_CP2_GFM_POLY(a0) |
259 | sd t3, OCTEON_CP2_GFM_RESULT(a0) | 263 | sd t3, OCTEON_CP2_GFM_RESULT(a0) |
260 | sd t0, OCTEON_CP2_GFM_RESULT+8(a0) | 264 | bltz v1, 4f |
265 | sd t0, OCTEON_CP2_GFM_RESULT+8(a0) | ||
266 | /* OCTEON III things*/ | ||
267 | dmfc2 t0, 0x024F | ||
268 | dmfc2 t1, 0x0050 | ||
269 | sd t0, OCTEON_CP2_SHA3(a0) | ||
270 | sd t1, OCTEON_CP2_SHA3+8(a0) | ||
271 | 4: | ||
261 | jr ra | 272 | jr ra |
273 | nop | ||
262 | 274 | ||
263 | 2: /* pass 1 special stuff when !CvmCtl[NOCRYPTO] */ | 275 | 2: /* pass 1 special stuff when !CvmCtl[NOCRYPTO] */ |
264 | dmfc2 t3, 0x0040 | 276 | dmfc2 t3, 0x0040 |
@@ -284,7 +296,9 @@ | |||
284 | 296 | ||
285 | 3: /* pass 1 or CvmCtl[NOCRYPTO] set */ | 297 | 3: /* pass 1 or CvmCtl[NOCRYPTO] set */ |
286 | jr ra | 298 | jr ra |
299 | nop | ||
287 | END(octeon_cop2_save) | 300 | END(octeon_cop2_save) |
301 | .set pop | ||
288 | 302 | ||
289 | /* | 303 | /* |
290 | * void octeon_cop2_restore(struct octeon_cop2_state *a0) | 304 | * void octeon_cop2_restore(struct octeon_cop2_state *a0) |
@@ -349,9 +363,9 @@ | |||
349 | ld t2, OCTEON_CP2_AES_RESULT+8(a0) | 363 | ld t2, OCTEON_CP2_AES_RESULT+8(a0) |
350 | mfc0 t3, $15,0 /* Get the processor ID register */ | 364 | mfc0 t3, $15,0 /* Get the processor ID register */ |
351 | dmtc2 t0, 0x0110 | 365 | dmtc2 t0, 0x0110 |
352 | li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */ | 366 | li v0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */ |
353 | dmtc2 t1, 0x0100 | 367 | dmtc2 t1, 0x0100 |
354 | bne t0, t3, 3f /* Skip the next stuff for non-pass1 */ | 368 | bne v0, t3, 3f /* Skip the next stuff for non-pass1 */ |
355 | dmtc2 t2, 0x0101 | 369 | dmtc2 t2, 0x0101 |
356 | 370 | ||
357 | /* this code is specific for pass 1 */ | 371 | /* this code is specific for pass 1 */ |
@@ -379,6 +393,7 @@ | |||
379 | 393 | ||
380 | 3: /* this is post-pass1 code */ | 394 | 3: /* this is post-pass1 code */ |
381 | ld t2, OCTEON_CP2_HSH_DATW(a0) | 395 | ld t2, OCTEON_CP2_HSH_DATW(a0) |
396 | ori v0, v0, 0x9500 /* lowest OCTEON III PrId*/ | ||
382 | ld t0, OCTEON_CP2_HSH_DATW+8(a0) | 397 | ld t0, OCTEON_CP2_HSH_DATW+8(a0) |
383 | ld t1, OCTEON_CP2_HSH_DATW+16(a0) | 398 | ld t1, OCTEON_CP2_HSH_DATW+16(a0) |
384 | dmtc2 t2, 0x0240 | 399 | dmtc2 t2, 0x0240 |
@@ -432,9 +447,15 @@ | |||
432 | dmtc2 t2, 0x0259 | 447 | dmtc2 t2, 0x0259 |
433 | ld t2, OCTEON_CP2_GFM_RESULT+8(a0) | 448 | ld t2, OCTEON_CP2_GFM_RESULT+8(a0) |
434 | dmtc2 t0, 0x025E | 449 | dmtc2 t0, 0x025E |
450 | subu v0, t3, v0 /* prid - lowest OCTEON III PrId */ | ||
435 | dmtc2 t1, 0x025A | 451 | dmtc2 t1, 0x025A |
436 | dmtc2 t2, 0x025B | 452 | bltz v0, done_restore |
437 | 453 | dmtc2 t2, 0x025B | |
454 | /* OCTEON III things*/ | ||
455 | ld t0, OCTEON_CP2_SHA3(a0) | ||
456 | ld t1, OCTEON_CP2_SHA3+8(a0) | ||
457 | dmtc2 t0, 0x0051 | ||
458 | dmtc2 t1, 0x0050 | ||
438 | done_restore: | 459 | done_restore: |
439 | jr ra | 460 | jr ra |
440 | nop | 461 | nop |