1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle 7 * Copyright (C) 1996 David S. Miller (davem@davemloft.net) 8 * Copyright (C) 1994, 1995, 1996, by Andreas Busse 9 * Copyright (C) 1999 Silicon Graphics, Inc. 10 * Copyright (C) 2000 MIPS Technologies, Inc. 11 * written by Carsten Langgaard, carstenl@mips.com 12 */ 13#include <asm/asm.h> 14#include <asm/asm-offsets.h> 15#include <asm/mipsregs.h> 16#include <asm/regdef.h> 17#include <asm/stackframe.h> 18 19/* 20 * task_struct *resume(task_struct *prev, task_struct *next, 21 * struct thread_info *next_ti) 22 */ 23 .align 7 24 LEAF(resume) 25 .set arch=octeon 26 mfc0 t1, CP0_STATUS 27 LONG_S t1, THREAD_STATUS(a0) 28 cpu_save_nonscratch a0 29 LONG_S ra, THREAD_REG31(a0) 30 31#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0 32 /* Check if we need to store CVMSEG state */ 33 dmfc0 t0, $11,7 /* CvmMemCtl */ 34 bbit0 t0, 6, 3f /* Is user access enabled? */ 35 36 /* Store the CVMSEG state */ 37 /* Extract the size of CVMSEG */ 38 andi t0, 0x3f 39 /* Multiply * (cache line size/sizeof(long)/2) */ 40 sll t0, 7-LONGLOG-1 41 li t1, -32768 /* Base address of CVMSEG */ 42 LONG_ADDI t2, a0, THREAD_CVMSEG /* Where to store CVMSEG to */ 43 synciobdma 442: 45 .set noreorder 46 LONG_L t8, 0(t1) /* Load from CVMSEG */ 47 subu t0, 1 /* Decrement loop var */ 48 LONG_L t9, LONGSIZE(t1)/* Load from CVMSEG */ 49 LONG_ADDU t1, LONGSIZE*2 /* Increment loc in CVMSEG */ 50 LONG_S t8, 0(t2) /* Store CVMSEG to thread storage */ 51 LONG_ADDU t2, LONGSIZE*2 /* Increment loc in thread storage */ 52 bnez t0, 2b /* Loop until we've copied it all */ 53 LONG_S t9, -LONGSIZE(t2)/* Store CVMSEG to thread storage */ 54 .set reorder 55 56 /* Disable access to CVMSEG */ 57 dmfc0 t0, $11,7 /* CvmMemCtl */ 58 xori t0, t0, 0x40 /* Bit 6 is CVMSEG user enable */ 59 dmtc0 t0, $11,7 /* CvmMemCtl */ 60#endif 613: 62 63#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) 64 PTR_LA t8, __stack_chk_guard 65 LONG_L t9, TASK_STACK_CANARY(a1) 66 LONG_S t9, 0(t8) 67#endif 68 69 /* 70 * The order of restoring the registers takes care of the race 71 * updating $28, $29 and kernelsp without disabling ints. 72 */ 73 move $28, a2 74 cpu_restore_nonscratch a1 75 76 PTR_ADDU t0, $28, _THREAD_SIZE - 32 77 set_saved_sp t0, t1, t2 78 79 mfc0 t1, CP0_STATUS /* Do we really need this? */ 80 li a3, 0xff01 81 and t1, a3 82 LONG_L a2, THREAD_STATUS(a1) 83 nor a3, $0, a3 84 and a2, a3 85 or a2, t1 86 mtc0 a2, CP0_STATUS 87 move v0, a0 88 jr ra 89 END(resume) 90 91/* 92 * void octeon_cop2_save(struct octeon_cop2_state *a0) 93 */ 94 .align 7 95 .set push 96 .set noreorder 97 LEAF(octeon_cop2_save) 98 99 dmfc0 t9, $9,7 /* CvmCtl register. */ 100 101 /* Save the COP2 CRC state */ 102 dmfc2 t0, 0x0201 103 dmfc2 t1, 0x0202 104 dmfc2 t2, 0x0200 105 sd t0, OCTEON_CP2_CRC_IV(a0) 106 sd t1, OCTEON_CP2_CRC_LENGTH(a0) 107 /* Skip next instructions if CvmCtl[NODFA_CP2] set */ 108 bbit1 t9, 28, 1f 109 sd t2, OCTEON_CP2_CRC_POLY(a0) 110 111 /* Save the LLM state */ 112 dmfc2 t0, 0x0402 113 dmfc2 t1, 0x040A 114 sd t0, OCTEON_CP2_LLM_DAT(a0) 115 1161: bbit1 t9, 26, 3f /* done if CvmCtl[NOCRYPTO] set */ 117 sd t1, OCTEON_CP2_LLM_DAT+8(a0) 118 119 /* Save the COP2 crypto state */ 120 /* this part is mostly common to both pass 1 and later revisions */ 121 dmfc2 t0, 0x0084 122 dmfc2 t1, 0x0080 123 dmfc2 t2, 0x0081 124 dmfc2 t3, 0x0082 125 sd t0, OCTEON_CP2_3DES_IV(a0) 126 dmfc2 t0, 0x0088 127 sd t1, OCTEON_CP2_3DES_KEY(a0) 128 dmfc2 t1, 0x0111 /* only necessary for pass 1 */ 129 sd t2, OCTEON_CP2_3DES_KEY+8(a0) 130 dmfc2 t2, 0x0102 131 sd t3, OCTEON_CP2_3DES_KEY+16(a0) 132 dmfc2 t3, 0x0103 133 sd t0, OCTEON_CP2_3DES_RESULT(a0) 134 dmfc2 t0, 0x0104 135 sd t1, OCTEON_CP2_AES_INP0(a0) /* only necessary for pass 1 */ 136 dmfc2 t1, 0x0105 137 sd t2, OCTEON_CP2_AES_IV(a0) 138 dmfc2 t2, 0x0106 139 sd t3, OCTEON_CP2_AES_IV+8(a0) 140 dmfc2 t3, 0x0107 141 sd t0, OCTEON_CP2_AES_KEY(a0) 142 dmfc2 t0, 0x0110 143 sd t1, OCTEON_CP2_AES_KEY+8(a0) 144 dmfc2 t1, 0x0100 145 sd t2, OCTEON_CP2_AES_KEY+16(a0) 146 dmfc2 t2, 0x0101 147 sd t3, OCTEON_CP2_AES_KEY+24(a0) 148 mfc0 v0, $15,0 /* Get the processor ID register */ 149 sd t0, OCTEON_CP2_AES_KEYLEN(a0) 150 li v1, 0x000d0000 /* This is the processor ID of Octeon Pass1 */ 151 sd t1, OCTEON_CP2_AES_RESULT(a0) 152 /* Skip to the Pass1 version of the remainder of the COP2 state */ 153 beq v0, v1, 2f 154 sd t2, OCTEON_CP2_AES_RESULT+8(a0) 155 156 /* the non-pass1 state when !CvmCtl[NOCRYPTO] */ 157 dmfc2 t1, 0x0240 158 dmfc2 t2, 0x0241 159 ori v1, v1, 0x9500 /* lowest OCTEON III PrId*/ 160 dmfc2 t3, 0x0242 161 subu v1, v0, v1 /* prid - lowest OCTEON III PrId */ 162 dmfc2 t0, 0x0243 163 sd t1, OCTEON_CP2_HSH_DATW(a0) 164 dmfc2 t1, 0x0244 165 sd t2, OCTEON_CP2_HSH_DATW+8(a0) 166 dmfc2 t2, 0x0245 167 sd t3, OCTEON_CP2_HSH_DATW+16(a0) 168 dmfc2 t3, 0x0246 169 sd t0, OCTEON_CP2_HSH_DATW+24(a0) 170 dmfc2 t0, 0x0247 171 sd t1, OCTEON_CP2_HSH_DATW+32(a0) 172 dmfc2 t1, 0x0248 173 sd t2, OCTEON_CP2_HSH_DATW+40(a0) 174 dmfc2 t2, 0x0249 175 sd t3, OCTEON_CP2_HSH_DATW+48(a0) 176 dmfc2 t3, 0x024A 177 sd t0, OCTEON_CP2_HSH_DATW+56(a0) 178 dmfc2 t0, 0x024B 179 sd t1, OCTEON_CP2_HSH_DATW+64(a0) 180 dmfc2 t1, 0x024C 181 sd t2, OCTEON_CP2_HSH_DATW+72(a0) 182 dmfc2 t2, 0x024D 183 sd t3, OCTEON_CP2_HSH_DATW+80(a0) 184 dmfc2 t3, 0x024E 185 sd t0, OCTEON_CP2_HSH_DATW+88(a0) 186 dmfc2 t0, 0x0250 187 sd t1, OCTEON_CP2_HSH_DATW+96(a0) 188 dmfc2 t1, 0x0251 189 sd t2, OCTEON_CP2_HSH_DATW+104(a0) 190 dmfc2 t2, 0x0252 191 sd t3, OCTEON_CP2_HSH_DATW+112(a0) 192 dmfc2 t3, 0x0253 193 sd t0, OCTEON_CP2_HSH_IVW(a0) 194 dmfc2 t0, 0x0254 195 sd t1, OCTEON_CP2_HSH_IVW+8(a0) 196 dmfc2 t1, 0x0255 197 sd t2, OCTEON_CP2_HSH_IVW+16(a0) 198 dmfc2 t2, 0x0256 199 sd t3, OCTEON_CP2_HSH_IVW+24(a0) 200 dmfc2 t3, 0x0257 201 sd t0, OCTEON_CP2_HSH_IVW+32(a0) 202 dmfc2 t0, 0x0258 203 sd t1, OCTEON_CP2_HSH_IVW+40(a0) 204 dmfc2 t1, 0x0259 205 sd t2, OCTEON_CP2_HSH_IVW+48(a0) 206 dmfc2 t2, 0x025E 207 sd t3, OCTEON_CP2_HSH_IVW+56(a0) 208 dmfc2 t3, 0x025A 209 sd t0, OCTEON_CP2_GFM_MULT(a0) 210 dmfc2 t0, 0x025B 211 sd t1, OCTEON_CP2_GFM_MULT+8(a0) 212 sd t2, OCTEON_CP2_GFM_POLY(a0) 213 sd t3, OCTEON_CP2_GFM_RESULT(a0) 214 bltz v1, 4f 215 sd t0, OCTEON_CP2_GFM_RESULT+8(a0) 216 /* OCTEON III things*/ 217 dmfc2 t0, 0x024F 218 dmfc2 t1, 0x0050 219 sd t0, OCTEON_CP2_SHA3(a0) 220 sd t1, OCTEON_CP2_SHA3+8(a0) 2214: 222 jr ra 223 nop 224 2252: /* pass 1 special stuff when !CvmCtl[NOCRYPTO] */ 226 dmfc2 t3, 0x0040 227 dmfc2 t0, 0x0041 228 dmfc2 t1, 0x0042 229 dmfc2 t2, 0x0043 230 sd t3, OCTEON_CP2_HSH_DATW(a0) 231 dmfc2 t3, 0x0044 232 sd t0, OCTEON_CP2_HSH_DATW+8(a0) 233 dmfc2 t0, 0x0045 234 sd t1, OCTEON_CP2_HSH_DATW+16(a0) 235 dmfc2 t1, 0x0046 236 sd t2, OCTEON_CP2_HSH_DATW+24(a0) 237 dmfc2 t2, 0x0048 238 sd t3, OCTEON_CP2_HSH_DATW+32(a0) 239 dmfc2 t3, 0x0049 240 sd t0, OCTEON_CP2_HSH_DATW+40(a0) 241 dmfc2 t0, 0x004A 242 sd t1, OCTEON_CP2_HSH_DATW+48(a0) 243 sd t2, OCTEON_CP2_HSH_IVW(a0) 244 sd t3, OCTEON_CP2_HSH_IVW+8(a0) 245 sd t0, OCTEON_CP2_HSH_IVW+16(a0) 246 2473: /* pass 1 or CvmCtl[NOCRYPTO] set */ 248 jr ra 249 nop 250 END(octeon_cop2_save) 251 .set pop 252 253/* 254 * void octeon_cop2_restore(struct octeon_cop2_state *a0) 255 */ 256 .align 7 257 .set push 258 .set noreorder 259 LEAF(octeon_cop2_restore) 260 /* First cache line was prefetched before the call */ 261 pref 4, 128(a0) 262 dmfc0 t9, $9,7 /* CvmCtl register. */ 263 264 pref 4, 256(a0) 265 ld t0, OCTEON_CP2_CRC_IV(a0) 266 pref 4, 384(a0) 267 ld t1, OCTEON_CP2_CRC_LENGTH(a0) 268 ld t2, OCTEON_CP2_CRC_POLY(a0) 269 270 /* Restore the COP2 CRC state */ 271 dmtc2 t0, 0x0201 272 dmtc2 t1, 0x1202 273 bbit1 t9, 28, 2f /* Skip LLM if CvmCtl[NODFA_CP2] is set */ 274 dmtc2 t2, 0x4200 275 276 /* Restore the LLM state */ 277 ld t0, OCTEON_CP2_LLM_DAT(a0) 278 ld t1, OCTEON_CP2_LLM_DAT+8(a0) 279 dmtc2 t0, 0x0402 280 dmtc2 t1, 0x040A 281 2822: 283 bbit1 t9, 26, done_restore /* done if CvmCtl[NOCRYPTO] set */ 284 nop 285 286 /* Restore the COP2 crypto state common to pass 1 and pass 2 */ 287 ld t0, OCTEON_CP2_3DES_IV(a0) 288 ld t1, OCTEON_CP2_3DES_KEY(a0) 289 ld t2, OCTEON_CP2_3DES_KEY+8(a0) 290 dmtc2 t0, 0x0084 291 ld t0, OCTEON_CP2_3DES_KEY+16(a0) 292 dmtc2 t1, 0x0080 293 ld t1, OCTEON_CP2_3DES_RESULT(a0) 294 dmtc2 t2, 0x0081 295 ld t2, OCTEON_CP2_AES_INP0(a0) /* only really needed for pass 1 */ 296 dmtc2 t0, 0x0082 297 ld t0, OCTEON_CP2_AES_IV(a0) 298 dmtc2 t1, 0x0098 299 ld t1, OCTEON_CP2_AES_IV+8(a0) 300 dmtc2 t2, 0x010A /* only really needed for pass 1 */ 301 ld t2, OCTEON_CP2_AES_KEY(a0) 302 dmtc2 t0, 0x0102 303 ld t0, OCTEON_CP2_AES_KEY+8(a0) 304 dmtc2 t1, 0x0103 305 ld t1, OCTEON_CP2_AES_KEY+16(a0) 306 dmtc2 t2, 0x0104 307 ld t2, OCTEON_CP2_AES_KEY+24(a0) 308 dmtc2 t0, 0x0105 309 ld t0, OCTEON_CP2_AES_KEYLEN(a0) 310 dmtc2 t1, 0x0106 311 ld t1, OCTEON_CP2_AES_RESULT(a0) 312 dmtc2 t2, 0x0107 313 ld t2, OCTEON_CP2_AES_RESULT+8(a0) 314 mfc0 t3, $15,0 /* Get the processor ID register */ 315 dmtc2 t0, 0x0110 316 li v0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */ 317 dmtc2 t1, 0x0100 318 bne v0, t3, 3f /* Skip the next stuff for non-pass1 */ 319 dmtc2 t2, 0x0101 320 321 /* this code is specific for pass 1 */ 322 ld t0, OCTEON_CP2_HSH_DATW(a0) 323 ld t1, OCTEON_CP2_HSH_DATW+8(a0) 324 ld t2, OCTEON_CP2_HSH_DATW+16(a0) 325 dmtc2 t0, 0x0040 326 ld t0, OCTEON_CP2_HSH_DATW+24(a0) 327 dmtc2 t1, 0x0041 328 ld t1, OCTEON_CP2_HSH_DATW+32(a0) 329 dmtc2 t2, 0x0042 330 ld t2, OCTEON_CP2_HSH_DATW+40(a0) 331 dmtc2 t0, 0x0043 332 ld t0, OCTEON_CP2_HSH_DATW+48(a0) 333 dmtc2 t1, 0x0044 334 ld t1, OCTEON_CP2_HSH_IVW(a0) 335 dmtc2 t2, 0x0045 336 ld t2, OCTEON_CP2_HSH_IVW+8(a0) 337 dmtc2 t0, 0x0046 338 ld t0, OCTEON_CP2_HSH_IVW+16(a0) 339 dmtc2 t1, 0x0048 340 dmtc2 t2, 0x0049 341 b done_restore /* unconditional branch */ 342 dmtc2 t0, 0x004A 343 3443: /* this is post-pass1 code */ 345 ld t2, OCTEON_CP2_HSH_DATW(a0) 346 ori v0, v0, 0x9500 /* lowest OCTEON III PrId*/ 347 ld t0, OCTEON_CP2_HSH_DATW+8(a0) 348 ld t1, OCTEON_CP2_HSH_DATW+16(a0) 349 dmtc2 t2, 0x0240 350 ld t2, OCTEON_CP2_HSH_DATW+24(a0) 351 dmtc2 t0, 0x0241 352 ld t0, OCTEON_CP2_HSH_DATW+32(a0) 353 dmtc2 t1, 0x0242 354 ld t1, OCTEON_CP2_HSH_DATW+40(a0) 355 dmtc2 t2, 0x0243 356 ld t2, OCTEON_CP2_HSH_DATW+48(a0) 357 dmtc2 t0, 0x0244 358 ld t0, OCTEON_CP2_HSH_DATW+56(a0) 359 dmtc2 t1, 0x0245 360 ld t1, OCTEON_CP2_HSH_DATW+64(a0) 361 dmtc2 t2, 0x0246 362 ld t2, OCTEON_CP2_HSH_DATW+72(a0) 363 dmtc2 t0, 0x0247 364 ld t0, OCTEON_CP2_HSH_DATW+80(a0) 365 dmtc2 t1, 0x0248 366 ld t1, OCTEON_CP2_HSH_DATW+88(a0) 367 dmtc2 t2, 0x0249 368 ld t2, OCTEON_CP2_HSH_DATW+96(a0) 369 dmtc2 t0, 0x024A 370 ld t0, OCTEON_CP2_HSH_DATW+104(a0) 371 dmtc2 t1, 0x024B 372 ld t1, OCTEON_CP2_HSH_DATW+112(a0) 373 dmtc2 t2, 0x024C 374 ld t2, OCTEON_CP2_HSH_IVW(a0) 375 dmtc2 t0, 0x024D 376 ld t0, OCTEON_CP2_HSH_IVW+8(a0) 377 dmtc2 t1, 0x024E 378 ld t1, OCTEON_CP2_HSH_IVW+16(a0) 379 dmtc2 t2, 0x0250 380 ld t2, OCTEON_CP2_HSH_IVW+24(a0) 381 dmtc2 t0, 0x0251 382 ld t0, OCTEON_CP2_HSH_IVW+32(a0) 383 dmtc2 t1, 0x0252 384 ld t1, OCTEON_CP2_HSH_IVW+40(a0) 385 dmtc2 t2, 0x0253 386 ld t2, OCTEON_CP2_HSH_IVW+48(a0) 387 dmtc2 t0, 0x0254 388 ld t0, OCTEON_CP2_HSH_IVW+56(a0) 389 dmtc2 t1, 0x0255 390 ld t1, OCTEON_CP2_GFM_MULT(a0) 391 dmtc2 t2, 0x0256 392 ld t2, OCTEON_CP2_GFM_MULT+8(a0) 393 dmtc2 t0, 0x0257 394 ld t0, OCTEON_CP2_GFM_POLY(a0) 395 dmtc2 t1, 0x0258 396 ld t1, OCTEON_CP2_GFM_RESULT(a0) 397 dmtc2 t2, 0x0259 398 ld t2, OCTEON_CP2_GFM_RESULT+8(a0) 399 dmtc2 t0, 0x025E 400 subu v0, t3, v0 /* prid - lowest OCTEON III PrId */ 401 dmtc2 t1, 0x025A 402 bltz v0, done_restore 403 dmtc2 t2, 0x025B 404 /* OCTEON III things*/ 405 ld t0, OCTEON_CP2_SHA3(a0) 406 ld t1, OCTEON_CP2_SHA3+8(a0) 407 dmtc2 t0, 0x0051 408 dmtc2 t1, 0x0050 409done_restore: 410 jr ra 411 nop 412 END(octeon_cop2_restore) 413 .set pop 414 415/* 416 * void octeon_mult_save() 417 * sp is assumed to point to a struct pt_regs 418 * 419 * NOTE: This is called in SAVE_TEMP in stackframe.h. It can 420 * safely modify v1,k0, k1,$10-$15, and $24. It will 421 * be overwritten with a processor specific version of the code. 422 */ 423 .p2align 7 424 .set push 425 .set noreorder 426 LEAF(octeon_mult_save) 427 jr ra 428 nop 429 .space 30 * 4, 0 430 EXPORT(octeon_mult_save_end) 431 END(octeon_mult_save) 432 433 LEAF(octeon_mult_save2) 434 /* Save the multiplier state OCTEON II and earlier*/ 435 v3mulu k0, $0, $0 436 v3mulu k1, $0, $0 437 sd k0, PT_MTP(sp) /* PT_MTP has P0 */ 438 v3mulu k0, $0, $0 439 sd k1, PT_MTP+8(sp) /* PT_MTP+8 has P1 */ 440 ori k1, $0, 1 441 v3mulu k1, k1, $0 442 sd k0, PT_MTP+16(sp) /* PT_MTP+16 has P2 */ 443 v3mulu k0, $0, $0 444 sd k1, PT_MPL(sp) /* PT_MPL has MPL0 */ 445 v3mulu k1, $0, $0 446 sd k0, PT_MPL+8(sp) /* PT_MPL+8 has MPL1 */ 447 jr ra 448 sd k1, PT_MPL+16(sp) /* PT_MPL+16 has MPL2 */ 449 EXPORT(octeon_mult_save2_end) 450 END(octeon_mult_save2) 451 452 LEAF(octeon_mult_save3) 453 /* Save the multiplier state OCTEON III */ 454 v3mulu $10, $0, $0 /* read P0 */ 455 v3mulu $11, $0, $0 /* read P1 */ 456 v3mulu $12, $0, $0 /* read P2 */ 457 sd $10, PT_MTP+(0*8)(sp) /* store P0 */ 458 v3mulu $10, $0, $0 /* read P3 */ 459 sd $11, PT_MTP+(1*8)(sp) /* store P1 */ 460 v3mulu $11, $0, $0 /* read P4 */ 461 sd $12, PT_MTP+(2*8)(sp) /* store P2 */ 462 ori $13, $0, 1 463 v3mulu $12, $0, $0 /* read P5 */ 464 sd $10, PT_MTP+(3*8)(sp) /* store P3 */ 465 v3mulu $13, $13, $0 /* P4-P0 = MPL5-MPL1, $13 = MPL0 */ 466 sd $11, PT_MTP+(4*8)(sp) /* store P4 */ 467 v3mulu $10, $0, $0 /* read MPL1 */ 468 sd $12, PT_MTP+(5*8)(sp) /* store P5 */ 469 v3mulu $11, $0, $0 /* read MPL2 */ 470 sd $13, PT_MPL+(0*8)(sp) /* store MPL0 */ 471 v3mulu $12, $0, $0 /* read MPL3 */ 472 sd $10, PT_MPL+(1*8)(sp) /* store MPL1 */ 473 v3mulu $10, $0, $0 /* read MPL4 */ 474 sd $11, PT_MPL+(2*8)(sp) /* store MPL2 */ 475 v3mulu $11, $0, $0 /* read MPL5 */ 476 sd $12, PT_MPL+(3*8)(sp) /* store MPL3 */ 477 sd $10, PT_MPL+(4*8)(sp) /* store MPL4 */ 478 jr ra 479 sd $11, PT_MPL+(5*8)(sp) /* store MPL5 */ 480 EXPORT(octeon_mult_save3_end) 481 END(octeon_mult_save3) 482 .set pop 483 484/* 485 * void octeon_mult_restore() 486 * sp is assumed to point to a struct pt_regs 487 * 488 * NOTE: This is called in RESTORE_TEMP in stackframe.h. 489 */ 490 .p2align 7 491 .set push 492 .set noreorder 493 LEAF(octeon_mult_restore) 494 jr ra 495 nop 496 .space 30 * 4, 0 497 EXPORT(octeon_mult_restore_end) 498 END(octeon_mult_restore) 499 500 LEAF(octeon_mult_restore2) 501 ld v0, PT_MPL(sp) /* MPL0 */ 502 ld v1, PT_MPL+8(sp) /* MPL1 */ 503 ld k0, PT_MPL+16(sp) /* MPL2 */ 504 /* Restore the multiplier state */ 505 ld k1, PT_MTP+16(sp) /* P2 */ 506 mtm0 v0 /* MPL0 */ 507 ld v0, PT_MTP+8(sp) /* P1 */ 508 mtm1 v1 /* MPL1 */ 509 ld v1, PT_MTP(sp) /* P0 */ 510 mtm2 k0 /* MPL2 */ 511 mtp2 k1 /* P2 */ 512 mtp1 v0 /* P1 */ 513 jr ra 514 mtp0 v1 /* P0 */ 515 EXPORT(octeon_mult_restore2_end) 516 END(octeon_mult_restore2) 517 518 LEAF(octeon_mult_restore3) 519 ld $12, PT_MPL+(0*8)(sp) /* read MPL0 */ 520 ld $13, PT_MPL+(3*8)(sp) /* read MPL3 */ 521 ld $10, PT_MPL+(1*8)(sp) /* read MPL1 */ 522 ld $11, PT_MPL+(4*8)(sp) /* read MPL4 */ 523 .word 0x718d0008 524 /* mtm0 $12, $13 restore MPL0 and MPL3 */ 525 ld $12, PT_MPL+(2*8)(sp) /* read MPL2 */ 526 .word 0x714b000c 527 /* mtm1 $10, $11 restore MPL1 and MPL4 */ 528 ld $13, PT_MPL+(5*8)(sp) /* read MPL5 */ 529 ld $10, PT_MTP+(0*8)(sp) /* read P0 */ 530 ld $11, PT_MTP+(3*8)(sp) /* read P3 */ 531 .word 0x718d000d 532 /* mtm2 $12, $13 restore MPL2 and MPL5 */ 533 ld $12, PT_MTP+(1*8)(sp) /* read P1 */ 534 .word 0x714b0009 535 /* mtp0 $10, $11 restore P0 and P3 */ 536 ld $13, PT_MTP+(4*8)(sp) /* read P4 */ 537 ld $10, PT_MTP+(2*8)(sp) /* read P2 */ 538 ld $11, PT_MTP+(5*8)(sp) /* read P5 */ 539 .word 0x718d000a 540 /* mtp1 $12, $13 restore P1 and P4 */ 541 jr ra 542 .word 0x714b000b 543 /* mtp2 $10, $11 restore P2 and P5 */ 544 545 EXPORT(octeon_mult_restore3_end) 546 END(octeon_mult_restore3) 547 .set pop 548