15b3b1688SDavid Daney/* 25b3b1688SDavid Daney * This file is subject to the terms and conditions of the GNU General Public 35b3b1688SDavid Daney * License. See the file "COPYING" in the main directory of this archive 45b3b1688SDavid Daney * for more details. 55b3b1688SDavid Daney * 65b3b1688SDavid Daney * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle 7*79add627SJustin P. Mattock * Copyright (C) 1996 David S. Miller (davem@davemloft.net) 85b3b1688SDavid Daney * Copyright (C) 1994, 1995, 1996, by Andreas Busse 95b3b1688SDavid Daney * Copyright (C) 1999 Silicon Graphics, Inc. 105b3b1688SDavid Daney * Copyright (C) 2000 MIPS Technologies, Inc. 115b3b1688SDavid Daney * written by Carsten Langgaard, carstenl@mips.com 125b3b1688SDavid Daney */ 135b3b1688SDavid Daney#include <asm/asm.h> 145b3b1688SDavid Daney#include <asm/cachectl.h> 155b3b1688SDavid Daney#include <asm/fpregdef.h> 165b3b1688SDavid Daney#include <asm/mipsregs.h> 175b3b1688SDavid Daney#include <asm/asm-offsets.h> 185b3b1688SDavid Daney#include <asm/page.h> 195b3b1688SDavid Daney#include <asm/pgtable-bits.h> 205b3b1688SDavid Daney#include <asm/regdef.h> 215b3b1688SDavid Daney#include <asm/stackframe.h> 225b3b1688SDavid Daney#include <asm/thread_info.h> 235b3b1688SDavid Daney 245b3b1688SDavid Daney#include <asm/asmmacro.h> 255b3b1688SDavid Daney 265b3b1688SDavid Daney/* 275b3b1688SDavid Daney * Offset to the current process status flags, the first 32 bytes of the 285b3b1688SDavid Daney * stack are not used. 295b3b1688SDavid Daney */ 305b3b1688SDavid Daney#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS) 315b3b1688SDavid Daney 325b3b1688SDavid Daney/* 335b3b1688SDavid Daney * task_struct *resume(task_struct *prev, task_struct *next, 345b3b1688SDavid Daney * struct thread_info *next_ti) 355b3b1688SDavid Daney */ 365b3b1688SDavid Daney .align 7 375b3b1688SDavid Daney LEAF(resume) 385b3b1688SDavid Daney .set arch=octeon 395b3b1688SDavid Daney mfc0 t1, CP0_STATUS 405b3b1688SDavid Daney LONG_S t1, THREAD_STATUS(a0) 415b3b1688SDavid Daney cpu_save_nonscratch a0 425b3b1688SDavid Daney LONG_S ra, THREAD_REG31(a0) 435b3b1688SDavid Daney 445b3b1688SDavid Daney /* check if we need to save COP2 registers */ 455b3b1688SDavid Daney PTR_L t2, TASK_THREAD_INFO(a0) 465b3b1688SDavid Daney LONG_L t0, ST_OFF(t2) 475b3b1688SDavid Daney bbit0 t0, 30, 1f 485b3b1688SDavid Daney 495b3b1688SDavid Daney /* Disable COP2 in the stored process state */ 505b3b1688SDavid Daney li t1, ST0_CU2 515b3b1688SDavid Daney xor t0, t1 525b3b1688SDavid Daney LONG_S t0, ST_OFF(t2) 535b3b1688SDavid Daney 545b3b1688SDavid Daney /* Enable COP2 so we can save it */ 555b3b1688SDavid Daney mfc0 t0, CP0_STATUS 565b3b1688SDavid Daney or t0, t1 575b3b1688SDavid Daney mtc0 t0, CP0_STATUS 585b3b1688SDavid Daney 595b3b1688SDavid Daney /* Save COP2 */ 605b3b1688SDavid Daney daddu a0, THREAD_CP2 615b3b1688SDavid Daney jal octeon_cop2_save 625b3b1688SDavid Daney dsubu a0, THREAD_CP2 635b3b1688SDavid Daney 645b3b1688SDavid Daney /* Disable COP2 now that we are done */ 655b3b1688SDavid Daney mfc0 t0, CP0_STATUS 665b3b1688SDavid Daney li t1, ST0_CU2 675b3b1688SDavid Daney xor t0, t1 685b3b1688SDavid Daney mtc0 t0, CP0_STATUS 695b3b1688SDavid Daney 705b3b1688SDavid Daney1: 715b3b1688SDavid Daney#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0 725b3b1688SDavid Daney /* Check if we need to store CVMSEG state */ 735b3b1688SDavid Daney mfc0 t0, $11,7 /* CvmMemCtl */ 745b3b1688SDavid Daney bbit0 t0, 6, 3f /* Is user access enabled? */ 755b3b1688SDavid Daney 765b3b1688SDavid Daney /* Store the CVMSEG state */ 775b3b1688SDavid Daney /* Extract the size of CVMSEG */ 785b3b1688SDavid Daney andi t0, 0x3f 795b3b1688SDavid Daney /* Multiply * (cache line size/sizeof(long)/2) */ 805b3b1688SDavid Daney sll t0, 7-LONGLOG-1 815b3b1688SDavid Daney li t1, -32768 /* Base address of CVMSEG */ 825b3b1688SDavid Daney LONG_ADDI t2, a0, THREAD_CVMSEG /* Where to store CVMSEG to */ 835b3b1688SDavid Daney synciobdma 845b3b1688SDavid Daney2: 855b3b1688SDavid Daney .set noreorder 865b3b1688SDavid Daney LONG_L t8, 0(t1) /* Load from CVMSEG */ 875b3b1688SDavid Daney subu t0, 1 /* Decrement loop var */ 885b3b1688SDavid Daney LONG_L t9, LONGSIZE(t1)/* Load from CVMSEG */ 895b3b1688SDavid Daney LONG_ADDU t1, LONGSIZE*2 /* Increment loc in CVMSEG */ 905b3b1688SDavid Daney LONG_S t8, 0(t2) /* Store CVMSEG to thread storage */ 915b3b1688SDavid Daney LONG_ADDU t2, LONGSIZE*2 /* Increment loc in thread storage */ 925b3b1688SDavid Daney bnez t0, 2b /* Loop until we've copied it all */ 935b3b1688SDavid Daney LONG_S t9, -LONGSIZE(t2)/* Store CVMSEG to thread storage */ 945b3b1688SDavid Daney .set reorder 955b3b1688SDavid Daney 965b3b1688SDavid Daney /* Disable access to CVMSEG */ 975b3b1688SDavid Daney mfc0 t0, $11,7 /* CvmMemCtl */ 985b3b1688SDavid Daney xori t0, t0, 0x40 /* Bit 6 is CVMSEG user enable */ 995b3b1688SDavid Daney mtc0 t0, $11,7 /* CvmMemCtl */ 1005b3b1688SDavid Daney#endif 1015b3b1688SDavid Daney3: 1025b3b1688SDavid Daney /* 1035b3b1688SDavid Daney * The order of restoring the registers takes care of the race 1045b3b1688SDavid Daney * updating $28, $29 and kernelsp without disabling ints. 1055b3b1688SDavid Daney */ 1065b3b1688SDavid Daney move $28, a2 1075b3b1688SDavid Daney cpu_restore_nonscratch a1 1085b3b1688SDavid Daney 1095b3b1688SDavid Daney#if (_THREAD_SIZE - 32) < 0x8000 1105b3b1688SDavid Daney PTR_ADDIU t0, $28, _THREAD_SIZE - 32 1115b3b1688SDavid Daney#else 1125b3b1688SDavid Daney PTR_LI t0, _THREAD_SIZE - 32 1135b3b1688SDavid Daney PTR_ADDU t0, $28 1145b3b1688SDavid Daney#endif 1155b3b1688SDavid Daney set_saved_sp t0, t1, t2 1165b3b1688SDavid Daney 1175b3b1688SDavid Daney mfc0 t1, CP0_STATUS /* Do we really need this? */ 1185b3b1688SDavid Daney li a3, 0xff01 1195b3b1688SDavid Daney and t1, a3 1205b3b1688SDavid Daney LONG_L a2, THREAD_STATUS(a1) 1215b3b1688SDavid Daney nor a3, $0, a3 1225b3b1688SDavid Daney and a2, a3 1235b3b1688SDavid Daney or a2, t1 1245b3b1688SDavid Daney mtc0 a2, CP0_STATUS 1255b3b1688SDavid Daney move v0, a0 1265b3b1688SDavid Daney jr ra 1275b3b1688SDavid Daney END(resume) 1285b3b1688SDavid Daney 1295b3b1688SDavid Daney/* 1305b3b1688SDavid Daney * void octeon_cop2_save(struct octeon_cop2_state *a0) 1315b3b1688SDavid Daney */ 1325b3b1688SDavid Daney .align 7 1335b3b1688SDavid Daney LEAF(octeon_cop2_save) 1345b3b1688SDavid Daney 1355b3b1688SDavid Daney dmfc0 t9, $9,7 /* CvmCtl register. */ 1365b3b1688SDavid Daney 1375b3b1688SDavid Daney /* Save the COP2 CRC state */ 1385b3b1688SDavid Daney dmfc2 t0, 0x0201 1395b3b1688SDavid Daney dmfc2 t1, 0x0202 1405b3b1688SDavid Daney dmfc2 t2, 0x0200 1415b3b1688SDavid Daney sd t0, OCTEON_CP2_CRC_IV(a0) 1425b3b1688SDavid Daney sd t1, OCTEON_CP2_CRC_LENGTH(a0) 1435b3b1688SDavid Daney sd t2, OCTEON_CP2_CRC_POLY(a0) 1445b3b1688SDavid Daney /* Skip next instructions if CvmCtl[NODFA_CP2] set */ 1455b3b1688SDavid Daney bbit1 t9, 28, 1f 1465b3b1688SDavid Daney 1475b3b1688SDavid Daney /* Save the LLM state */ 1485b3b1688SDavid Daney dmfc2 t0, 0x0402 1495b3b1688SDavid Daney dmfc2 t1, 0x040A 1505b3b1688SDavid Daney sd t0, OCTEON_CP2_LLM_DAT(a0) 1515b3b1688SDavid Daney sd t1, OCTEON_CP2_LLM_DAT+8(a0) 1525b3b1688SDavid Daney 1535b3b1688SDavid Daney1: bbit1 t9, 26, 3f /* done if CvmCtl[NOCRYPTO] set */ 1545b3b1688SDavid Daney 1555b3b1688SDavid Daney /* Save the COP2 crypto state */ 1565b3b1688SDavid Daney /* this part is mostly common to both pass 1 and later revisions */ 1575b3b1688SDavid Daney dmfc2 t0, 0x0084 1585b3b1688SDavid Daney dmfc2 t1, 0x0080 1595b3b1688SDavid Daney dmfc2 t2, 0x0081 1605b3b1688SDavid Daney dmfc2 t3, 0x0082 1615b3b1688SDavid Daney sd t0, OCTEON_CP2_3DES_IV(a0) 1625b3b1688SDavid Daney dmfc2 t0, 0x0088 1635b3b1688SDavid Daney sd t1, OCTEON_CP2_3DES_KEY(a0) 1645b3b1688SDavid Daney dmfc2 t1, 0x0111 /* only necessary for pass 1 */ 1655b3b1688SDavid Daney sd t2, OCTEON_CP2_3DES_KEY+8(a0) 1665b3b1688SDavid Daney dmfc2 t2, 0x0102 1675b3b1688SDavid Daney sd t3, OCTEON_CP2_3DES_KEY+16(a0) 1685b3b1688SDavid Daney dmfc2 t3, 0x0103 1695b3b1688SDavid Daney sd t0, OCTEON_CP2_3DES_RESULT(a0) 1705b3b1688SDavid Daney dmfc2 t0, 0x0104 1715b3b1688SDavid Daney sd t1, OCTEON_CP2_AES_INP0(a0) /* only necessary for pass 1 */ 1725b3b1688SDavid Daney dmfc2 t1, 0x0105 1735b3b1688SDavid Daney sd t2, OCTEON_CP2_AES_IV(a0) 1745b3b1688SDavid Daney dmfc2 t2, 0x0106 1755b3b1688SDavid Daney sd t3, OCTEON_CP2_AES_IV+8(a0) 1765b3b1688SDavid Daney dmfc2 t3, 0x0107 1775b3b1688SDavid Daney sd t0, OCTEON_CP2_AES_KEY(a0) 1785b3b1688SDavid Daney dmfc2 t0, 0x0110 1795b3b1688SDavid Daney sd t1, OCTEON_CP2_AES_KEY+8(a0) 1805b3b1688SDavid Daney dmfc2 t1, 0x0100 1815b3b1688SDavid Daney sd t2, OCTEON_CP2_AES_KEY+16(a0) 1825b3b1688SDavid Daney dmfc2 t2, 0x0101 1835b3b1688SDavid Daney sd t3, OCTEON_CP2_AES_KEY+24(a0) 1845b3b1688SDavid Daney mfc0 t3, $15,0 /* Get the processor ID register */ 1855b3b1688SDavid Daney sd t0, OCTEON_CP2_AES_KEYLEN(a0) 1865b3b1688SDavid Daney li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */ 1875b3b1688SDavid Daney sd t1, OCTEON_CP2_AES_RESULT(a0) 1885b3b1688SDavid Daney sd t2, OCTEON_CP2_AES_RESULT+8(a0) 1895b3b1688SDavid Daney /* Skip to the Pass1 version of the remainder of the COP2 state */ 1905b3b1688SDavid Daney beq t3, t0, 2f 1915b3b1688SDavid Daney 1925b3b1688SDavid Daney /* the non-pass1 state when !CvmCtl[NOCRYPTO] */ 1935b3b1688SDavid Daney dmfc2 t1, 0x0240 1945b3b1688SDavid Daney dmfc2 t2, 0x0241 1955b3b1688SDavid Daney dmfc2 t3, 0x0242 1965b3b1688SDavid Daney dmfc2 t0, 0x0243 1975b3b1688SDavid Daney sd t1, OCTEON_CP2_HSH_DATW(a0) 1985b3b1688SDavid Daney dmfc2 t1, 0x0244 1995b3b1688SDavid Daney sd t2, OCTEON_CP2_HSH_DATW+8(a0) 2005b3b1688SDavid Daney dmfc2 t2, 0x0245 2015b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_DATW+16(a0) 2025b3b1688SDavid Daney dmfc2 t3, 0x0246 2035b3b1688SDavid Daney sd t0, OCTEON_CP2_HSH_DATW+24(a0) 2045b3b1688SDavid Daney dmfc2 t0, 0x0247 2055b3b1688SDavid Daney sd t1, OCTEON_CP2_HSH_DATW+32(a0) 2065b3b1688SDavid Daney dmfc2 t1, 0x0248 2075b3b1688SDavid Daney sd t2, OCTEON_CP2_HSH_DATW+40(a0) 2085b3b1688SDavid Daney dmfc2 t2, 0x0249 2095b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_DATW+48(a0) 2105b3b1688SDavid Daney dmfc2 t3, 0x024A 2115b3b1688SDavid Daney sd t0, OCTEON_CP2_HSH_DATW+56(a0) 2125b3b1688SDavid Daney dmfc2 t0, 0x024B 2135b3b1688SDavid Daney sd t1, OCTEON_CP2_HSH_DATW+64(a0) 2145b3b1688SDavid Daney dmfc2 t1, 0x024C 2155b3b1688SDavid Daney sd t2, OCTEON_CP2_HSH_DATW+72(a0) 2165b3b1688SDavid Daney dmfc2 t2, 0x024D 2175b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_DATW+80(a0) 2185b3b1688SDavid Daney dmfc2 t3, 0x024E 2195b3b1688SDavid Daney sd t0, OCTEON_CP2_HSH_DATW+88(a0) 2205b3b1688SDavid Daney dmfc2 t0, 0x0250 2215b3b1688SDavid Daney sd t1, OCTEON_CP2_HSH_DATW+96(a0) 2225b3b1688SDavid Daney dmfc2 t1, 0x0251 2235b3b1688SDavid Daney sd t2, OCTEON_CP2_HSH_DATW+104(a0) 2245b3b1688SDavid Daney dmfc2 t2, 0x0252 2255b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_DATW+112(a0) 2265b3b1688SDavid Daney dmfc2 t3, 0x0253 2275b3b1688SDavid Daney sd t0, OCTEON_CP2_HSH_IVW(a0) 2285b3b1688SDavid Daney dmfc2 t0, 0x0254 2295b3b1688SDavid Daney sd t1, OCTEON_CP2_HSH_IVW+8(a0) 2305b3b1688SDavid Daney dmfc2 t1, 0x0255 2315b3b1688SDavid Daney sd t2, OCTEON_CP2_HSH_IVW+16(a0) 2325b3b1688SDavid Daney dmfc2 t2, 0x0256 2335b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_IVW+24(a0) 2345b3b1688SDavid Daney dmfc2 t3, 0x0257 2355b3b1688SDavid Daney sd t0, OCTEON_CP2_HSH_IVW+32(a0) 2365b3b1688SDavid Daney dmfc2 t0, 0x0258 2375b3b1688SDavid Daney sd t1, OCTEON_CP2_HSH_IVW+40(a0) 2385b3b1688SDavid Daney dmfc2 t1, 0x0259 2395b3b1688SDavid Daney sd t2, OCTEON_CP2_HSH_IVW+48(a0) 2405b3b1688SDavid Daney dmfc2 t2, 0x025E 2415b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_IVW+56(a0) 2425b3b1688SDavid Daney dmfc2 t3, 0x025A 2435b3b1688SDavid Daney sd t0, OCTEON_CP2_GFM_MULT(a0) 2445b3b1688SDavid Daney dmfc2 t0, 0x025B 2455b3b1688SDavid Daney sd t1, OCTEON_CP2_GFM_MULT+8(a0) 2465b3b1688SDavid Daney sd t2, OCTEON_CP2_GFM_POLY(a0) 2475b3b1688SDavid Daney sd t3, OCTEON_CP2_GFM_RESULT(a0) 2485b3b1688SDavid Daney sd t0, OCTEON_CP2_GFM_RESULT+8(a0) 2495b3b1688SDavid Daney jr ra 2505b3b1688SDavid Daney 2515b3b1688SDavid Daney2: /* pass 1 special stuff when !CvmCtl[NOCRYPTO] */ 2525b3b1688SDavid Daney dmfc2 t3, 0x0040 2535b3b1688SDavid Daney dmfc2 t0, 0x0041 2545b3b1688SDavid Daney dmfc2 t1, 0x0042 2555b3b1688SDavid Daney dmfc2 t2, 0x0043 2565b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_DATW(a0) 2575b3b1688SDavid Daney dmfc2 t3, 0x0044 2585b3b1688SDavid Daney sd t0, OCTEON_CP2_HSH_DATW+8(a0) 2595b3b1688SDavid Daney dmfc2 t0, 0x0045 2605b3b1688SDavid Daney sd t1, OCTEON_CP2_HSH_DATW+16(a0) 2615b3b1688SDavid Daney dmfc2 t1, 0x0046 2625b3b1688SDavid Daney sd t2, OCTEON_CP2_HSH_DATW+24(a0) 2635b3b1688SDavid Daney dmfc2 t2, 0x0048 2645b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_DATW+32(a0) 2655b3b1688SDavid Daney dmfc2 t3, 0x0049 2665b3b1688SDavid Daney sd t0, OCTEON_CP2_HSH_DATW+40(a0) 2675b3b1688SDavid Daney dmfc2 t0, 0x004A 2685b3b1688SDavid Daney sd t1, OCTEON_CP2_HSH_DATW+48(a0) 2695b3b1688SDavid Daney sd t2, OCTEON_CP2_HSH_IVW(a0) 2705b3b1688SDavid Daney sd t3, OCTEON_CP2_HSH_IVW+8(a0) 2715b3b1688SDavid Daney sd t0, OCTEON_CP2_HSH_IVW+16(a0) 2725b3b1688SDavid Daney 2735b3b1688SDavid Daney3: /* pass 1 or CvmCtl[NOCRYPTO] set */ 2745b3b1688SDavid Daney jr ra 2755b3b1688SDavid Daney END(octeon_cop2_save) 2765b3b1688SDavid Daney 2775b3b1688SDavid Daney/* 2785b3b1688SDavid Daney * void octeon_cop2_restore(struct octeon_cop2_state *a0) 2795b3b1688SDavid Daney */ 2805b3b1688SDavid Daney .align 7 2815b3b1688SDavid Daney .set push 2825b3b1688SDavid Daney .set noreorder 2835b3b1688SDavid Daney LEAF(octeon_cop2_restore) 2845b3b1688SDavid Daney /* First cache line was prefetched before the call */ 2855b3b1688SDavid Daney pref 4, 128(a0) 2865b3b1688SDavid Daney dmfc0 t9, $9,7 /* CvmCtl register. */ 2875b3b1688SDavid Daney 2885b3b1688SDavid Daney pref 4, 256(a0) 2895b3b1688SDavid Daney ld t0, OCTEON_CP2_CRC_IV(a0) 2905b3b1688SDavid Daney pref 4, 384(a0) 2915b3b1688SDavid Daney ld t1, OCTEON_CP2_CRC_LENGTH(a0) 2925b3b1688SDavid Daney ld t2, OCTEON_CP2_CRC_POLY(a0) 2935b3b1688SDavid Daney 2945b3b1688SDavid Daney /* Restore the COP2 CRC state */ 2955b3b1688SDavid Daney dmtc2 t0, 0x0201 2965b3b1688SDavid Daney dmtc2 t1, 0x1202 2975b3b1688SDavid Daney bbit1 t9, 28, 2f /* Skip LLM if CvmCtl[NODFA_CP2] is set */ 2985b3b1688SDavid Daney dmtc2 t2, 0x4200 2995b3b1688SDavid Daney 3005b3b1688SDavid Daney /* Restore the LLM state */ 3015b3b1688SDavid Daney ld t0, OCTEON_CP2_LLM_DAT(a0) 3025b3b1688SDavid Daney ld t1, OCTEON_CP2_LLM_DAT+8(a0) 3035b3b1688SDavid Daney dmtc2 t0, 0x0402 3045b3b1688SDavid Daney dmtc2 t1, 0x040A 3055b3b1688SDavid Daney 3065b3b1688SDavid Daney2: 3075b3b1688SDavid Daney bbit1 t9, 26, done_restore /* done if CvmCtl[NOCRYPTO] set */ 3085b3b1688SDavid Daney nop 3095b3b1688SDavid Daney 3105b3b1688SDavid Daney /* Restore the COP2 crypto state common to pass 1 and pass 2 */ 3115b3b1688SDavid Daney ld t0, OCTEON_CP2_3DES_IV(a0) 3125b3b1688SDavid Daney ld t1, OCTEON_CP2_3DES_KEY(a0) 3135b3b1688SDavid Daney ld t2, OCTEON_CP2_3DES_KEY+8(a0) 3145b3b1688SDavid Daney dmtc2 t0, 0x0084 3155b3b1688SDavid Daney ld t0, OCTEON_CP2_3DES_KEY+16(a0) 3165b3b1688SDavid Daney dmtc2 t1, 0x0080 3175b3b1688SDavid Daney ld t1, OCTEON_CP2_3DES_RESULT(a0) 3185b3b1688SDavid Daney dmtc2 t2, 0x0081 3195b3b1688SDavid Daney ld t2, OCTEON_CP2_AES_INP0(a0) /* only really needed for pass 1 */ 3205b3b1688SDavid Daney dmtc2 t0, 0x0082 3215b3b1688SDavid Daney ld t0, OCTEON_CP2_AES_IV(a0) 3225b3b1688SDavid Daney dmtc2 t1, 0x0098 3235b3b1688SDavid Daney ld t1, OCTEON_CP2_AES_IV+8(a0) 3245b3b1688SDavid Daney dmtc2 t2, 0x010A /* only really needed for pass 1 */ 3255b3b1688SDavid Daney ld t2, OCTEON_CP2_AES_KEY(a0) 3265b3b1688SDavid Daney dmtc2 t0, 0x0102 3275b3b1688SDavid Daney ld t0, OCTEON_CP2_AES_KEY+8(a0) 3285b3b1688SDavid Daney dmtc2 t1, 0x0103 3295b3b1688SDavid Daney ld t1, OCTEON_CP2_AES_KEY+16(a0) 3305b3b1688SDavid Daney dmtc2 t2, 0x0104 3315b3b1688SDavid Daney ld t2, OCTEON_CP2_AES_KEY+24(a0) 3325b3b1688SDavid Daney dmtc2 t0, 0x0105 3335b3b1688SDavid Daney ld t0, OCTEON_CP2_AES_KEYLEN(a0) 3345b3b1688SDavid Daney dmtc2 t1, 0x0106 3355b3b1688SDavid Daney ld t1, OCTEON_CP2_AES_RESULT(a0) 3365b3b1688SDavid Daney dmtc2 t2, 0x0107 3375b3b1688SDavid Daney ld t2, OCTEON_CP2_AES_RESULT+8(a0) 3385b3b1688SDavid Daney mfc0 t3, $15,0 /* Get the processor ID register */ 3395b3b1688SDavid Daney dmtc2 t0, 0x0110 3405b3b1688SDavid Daney li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */ 3415b3b1688SDavid Daney dmtc2 t1, 0x0100 3425b3b1688SDavid Daney bne t0, t3, 3f /* Skip the next stuff for non-pass1 */ 3435b3b1688SDavid Daney dmtc2 t2, 0x0101 3445b3b1688SDavid Daney 3455b3b1688SDavid Daney /* this code is specific for pass 1 */ 3465b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_DATW(a0) 3475b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_DATW+8(a0) 3485b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_DATW+16(a0) 3495b3b1688SDavid Daney dmtc2 t0, 0x0040 3505b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_DATW+24(a0) 3515b3b1688SDavid Daney dmtc2 t1, 0x0041 3525b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_DATW+32(a0) 3535b3b1688SDavid Daney dmtc2 t2, 0x0042 3545b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_DATW+40(a0) 3555b3b1688SDavid Daney dmtc2 t0, 0x0043 3565b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_DATW+48(a0) 3575b3b1688SDavid Daney dmtc2 t1, 0x0044 3585b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_IVW(a0) 3595b3b1688SDavid Daney dmtc2 t2, 0x0045 3605b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_IVW+8(a0) 3615b3b1688SDavid Daney dmtc2 t0, 0x0046 3625b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_IVW+16(a0) 3635b3b1688SDavid Daney dmtc2 t1, 0x0048 3645b3b1688SDavid Daney dmtc2 t2, 0x0049 3655b3b1688SDavid Daney b done_restore /* unconditional branch */ 3665b3b1688SDavid Daney dmtc2 t0, 0x004A 3675b3b1688SDavid Daney 3685b3b1688SDavid Daney3: /* this is post-pass1 code */ 3695b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_DATW(a0) 3705b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_DATW+8(a0) 3715b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_DATW+16(a0) 3725b3b1688SDavid Daney dmtc2 t2, 0x0240 3735b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_DATW+24(a0) 3745b3b1688SDavid Daney dmtc2 t0, 0x0241 3755b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_DATW+32(a0) 3765b3b1688SDavid Daney dmtc2 t1, 0x0242 3775b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_DATW+40(a0) 3785b3b1688SDavid Daney dmtc2 t2, 0x0243 3795b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_DATW+48(a0) 3805b3b1688SDavid Daney dmtc2 t0, 0x0244 3815b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_DATW+56(a0) 3825b3b1688SDavid Daney dmtc2 t1, 0x0245 3835b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_DATW+64(a0) 3845b3b1688SDavid Daney dmtc2 t2, 0x0246 3855b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_DATW+72(a0) 3865b3b1688SDavid Daney dmtc2 t0, 0x0247 3875b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_DATW+80(a0) 3885b3b1688SDavid Daney dmtc2 t1, 0x0248 3895b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_DATW+88(a0) 3905b3b1688SDavid Daney dmtc2 t2, 0x0249 3915b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_DATW+96(a0) 3925b3b1688SDavid Daney dmtc2 t0, 0x024A 3935b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_DATW+104(a0) 3945b3b1688SDavid Daney dmtc2 t1, 0x024B 3955b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_DATW+112(a0) 3965b3b1688SDavid Daney dmtc2 t2, 0x024C 3975b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_IVW(a0) 3985b3b1688SDavid Daney dmtc2 t0, 0x024D 3995b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_IVW+8(a0) 4005b3b1688SDavid Daney dmtc2 t1, 0x024E 4015b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_IVW+16(a0) 4025b3b1688SDavid Daney dmtc2 t2, 0x0250 4035b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_IVW+24(a0) 4045b3b1688SDavid Daney dmtc2 t0, 0x0251 4055b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_IVW+32(a0) 4065b3b1688SDavid Daney dmtc2 t1, 0x0252 4075b3b1688SDavid Daney ld t1, OCTEON_CP2_HSH_IVW+40(a0) 4085b3b1688SDavid Daney dmtc2 t2, 0x0253 4095b3b1688SDavid Daney ld t2, OCTEON_CP2_HSH_IVW+48(a0) 4105b3b1688SDavid Daney dmtc2 t0, 0x0254 4115b3b1688SDavid Daney ld t0, OCTEON_CP2_HSH_IVW+56(a0) 4125b3b1688SDavid Daney dmtc2 t1, 0x0255 4135b3b1688SDavid Daney ld t1, OCTEON_CP2_GFM_MULT(a0) 4145b3b1688SDavid Daney dmtc2 t2, 0x0256 4155b3b1688SDavid Daney ld t2, OCTEON_CP2_GFM_MULT+8(a0) 4165b3b1688SDavid Daney dmtc2 t0, 0x0257 4175b3b1688SDavid Daney ld t0, OCTEON_CP2_GFM_POLY(a0) 4185b3b1688SDavid Daney dmtc2 t1, 0x0258 4195b3b1688SDavid Daney ld t1, OCTEON_CP2_GFM_RESULT(a0) 4205b3b1688SDavid Daney dmtc2 t2, 0x0259 4215b3b1688SDavid Daney ld t2, OCTEON_CP2_GFM_RESULT+8(a0) 4225b3b1688SDavid Daney dmtc2 t0, 0x025E 4235b3b1688SDavid Daney dmtc2 t1, 0x025A 4245b3b1688SDavid Daney dmtc2 t2, 0x025B 4255b3b1688SDavid Daney 4265b3b1688SDavid Daneydone_restore: 4275b3b1688SDavid Daney jr ra 4285b3b1688SDavid Daney nop 4295b3b1688SDavid Daney END(octeon_cop2_restore) 4305b3b1688SDavid Daney .set pop 4315b3b1688SDavid Daney 4325b3b1688SDavid Daney/* 4335b3b1688SDavid Daney * void octeon_mult_save() 4345b3b1688SDavid Daney * sp is assumed to point to a struct pt_regs 4355b3b1688SDavid Daney * 4365b3b1688SDavid Daney * NOTE: This is called in SAVE_SOME in stackframe.h. It can only 4375b3b1688SDavid Daney * safely modify k0 and k1. 4385b3b1688SDavid Daney */ 4395b3b1688SDavid Daney .align 7 4405b3b1688SDavid Daney .set push 4415b3b1688SDavid Daney .set noreorder 4425b3b1688SDavid Daney LEAF(octeon_mult_save) 4435b3b1688SDavid Daney dmfc0 k0, $9,7 /* CvmCtl register. */ 4445b3b1688SDavid Daney bbit1 k0, 27, 1f /* Skip CvmCtl[NOMUL] */ 4455b3b1688SDavid Daney nop 4465b3b1688SDavid Daney 4475b3b1688SDavid Daney /* Save the multiplier state */ 4485b3b1688SDavid Daney v3mulu k0, $0, $0 4495b3b1688SDavid Daney v3mulu k1, $0, $0 4505b3b1688SDavid Daney sd k0, PT_MTP(sp) /* PT_MTP has P0 */ 4515b3b1688SDavid Daney v3mulu k0, $0, $0 4525b3b1688SDavid Daney sd k1, PT_MTP+8(sp) /* PT_MTP+8 has P1 */ 4535b3b1688SDavid Daney ori k1, $0, 1 4545b3b1688SDavid Daney v3mulu k1, k1, $0 4555b3b1688SDavid Daney sd k0, PT_MTP+16(sp) /* PT_MTP+16 has P2 */ 4565b3b1688SDavid Daney v3mulu k0, $0, $0 4575b3b1688SDavid Daney sd k1, PT_MPL(sp) /* PT_MPL has MPL0 */ 4585b3b1688SDavid Daney v3mulu k1, $0, $0 4595b3b1688SDavid Daney sd k0, PT_MPL+8(sp) /* PT_MPL+8 has MPL1 */ 4605b3b1688SDavid Daney jr ra 4615b3b1688SDavid Daney sd k1, PT_MPL+16(sp) /* PT_MPL+16 has MPL2 */ 4625b3b1688SDavid Daney 4635b3b1688SDavid Daney1: /* Resume here if CvmCtl[NOMUL] */ 4645b3b1688SDavid Daney jr ra 4655b3b1688SDavid Daney END(octeon_mult_save) 4665b3b1688SDavid Daney .set pop 4675b3b1688SDavid Daney 4685b3b1688SDavid Daney/* 4695b3b1688SDavid Daney * void octeon_mult_restore() 4705b3b1688SDavid Daney * sp is assumed to point to a struct pt_regs 4715b3b1688SDavid Daney * 4725b3b1688SDavid Daney * NOTE: This is called in RESTORE_SOME in stackframe.h. 4735b3b1688SDavid Daney */ 4745b3b1688SDavid Daney .align 7 4755b3b1688SDavid Daney .set push 4765b3b1688SDavid Daney .set noreorder 4775b3b1688SDavid Daney LEAF(octeon_mult_restore) 4785b3b1688SDavid Daney dmfc0 k1, $9,7 /* CvmCtl register. */ 4795b3b1688SDavid Daney ld v0, PT_MPL(sp) /* MPL0 */ 4805b3b1688SDavid Daney ld v1, PT_MPL+8(sp) /* MPL1 */ 4815b3b1688SDavid Daney ld k0, PT_MPL+16(sp) /* MPL2 */ 4825b3b1688SDavid Daney bbit1 k1, 27, 1f /* Skip CvmCtl[NOMUL] */ 4835b3b1688SDavid Daney /* Normally falls through, so no time wasted here */ 4845b3b1688SDavid Daney nop 4855b3b1688SDavid Daney 4865b3b1688SDavid Daney /* Restore the multiplier state */ 4875b3b1688SDavid Daney ld k1, PT_MTP+16(sp) /* P2 */ 4885b3b1688SDavid Daney MTM0 v0 /* MPL0 */ 4895b3b1688SDavid Daney ld v0, PT_MTP+8(sp) /* P1 */ 4905b3b1688SDavid Daney MTM1 v1 /* MPL1 */ 4915b3b1688SDavid Daney ld v1, PT_MTP(sp) /* P0 */ 4925b3b1688SDavid Daney MTM2 k0 /* MPL2 */ 4935b3b1688SDavid Daney MTP2 k1 /* P2 */ 4945b3b1688SDavid Daney MTP1 v0 /* P1 */ 4955b3b1688SDavid Daney jr ra 4965b3b1688SDavid Daney MTP0 v1 /* P0 */ 4975b3b1688SDavid Daney 4985b3b1688SDavid Daney1: /* Resume here if CvmCtl[NOMUL] */ 4995b3b1688SDavid Daney jr ra 5005b3b1688SDavid Daney nop 5015b3b1688SDavid Daney END(octeon_mult_restore) 5025b3b1688SDavid Daney .set pop 503