mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
6cc1d135cd
COP2 disabled and lazily allocate COP2 context structure in exception handler. Keep kernel and userland contexts separated.
247 lines
7.4 KiB
ArmAsm
247 lines
7.4 KiB
ArmAsm
/*-
|
|
* Copyright (c) 2011 Oleksandr Tymoshenko
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
#include <machine/asm.h>
|
|
#include <machine/cpuregs.h>
|
|
#include <machine/octeon_cop2.h>
|
|
|
|
#include "assym.s"
|
|
|
|
.set noreorder
|
|
|
|
#define SAVE_COP2_REGISTER(reg) \
|
|
dmfc2 t1, reg; sd t1, reg##_OFFSET(a0)
|
|
|
|
|
|
#define RESTORE_COP2_REGISTER(reg) \
|
|
ld t1, reg##_OFFSET(a0); dmtc2 t1, reg##_SET
|
|
|
|
LEAF(octeon_cop2_save)
|
|
|
|
/* save original cop2 status in t2*/
|
|
mfc0 t2, MIPS_COP_0_STATUS
|
|
or t0, t2, MIPS_SR_COP_2_BIT
|
|
and t0, t0, ~MIPS_SR_INT_IE
|
|
mtc0 t0, MIPS_COP_0_STATUS
|
|
|
|
/* Get CvmCtl register */
|
|
dmfc0 t0, $9, 7
|
|
|
|
/* CRC state */
|
|
SAVE_COP2_REGISTER(COP2_CRC_IV)
|
|
SAVE_COP2_REGISTER(COP2_CRC_LENGTH)
|
|
SAVE_COP2_REGISTER(COP2_CRC_POLY)
|
|
|
|
/* if CvmCtl[NODFA_CP2] -> save_nodfa */
|
|
bbit1 t0, 28, save_nodfa
|
|
nop
|
|
|
|
/* LLM state */
|
|
SAVE_COP2_REGISTER(COP2_LLM_DAT0)
|
|
SAVE_COP2_REGISTER(COP2_LLM_DAT1)
|
|
|
|
save_nodfa:
|
|
/* crypto stuff is irrelevant if CvmCtl[NOCRYPTO] */
|
|
bbit1 t0, 26, save_done
|
|
nop
|
|
|
|
SAVE_COP2_REGISTER(COP2_3DES_IV)
|
|
SAVE_COP2_REGISTER(COP2_3DES_KEY0)
|
|
SAVE_COP2_REGISTER(COP2_3DES_KEY1)
|
|
SAVE_COP2_REGISTER(COP2_3DES_KEY2)
|
|
SAVE_COP2_REGISTER(COP2_3DES_RESULT)
|
|
|
|
SAVE_COP2_REGISTER(COP2_AES_INP0)
|
|
SAVE_COP2_REGISTER(COP2_AES_IV0)
|
|
SAVE_COP2_REGISTER(COP2_AES_IV1)
|
|
SAVE_COP2_REGISTER(COP2_AES_KEY0)
|
|
SAVE_COP2_REGISTER(COP2_AES_KEY1)
|
|
SAVE_COP2_REGISTER(COP2_AES_KEY2)
|
|
SAVE_COP2_REGISTER(COP2_AES_KEY3)
|
|
SAVE_COP2_REGISTER(COP2_AES_KEYLEN)
|
|
SAVE_COP2_REGISTER(COP2_AES_RESULT0)
|
|
SAVE_COP2_REGISTER(COP2_AES_RESULT1)
|
|
|
|
dmfc0 t0, $15
|
|
li t1, 0x000d0000 /* Octeon Pass1 */
|
|
beq t0, t1, save_pass1
|
|
nop
|
|
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW0)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW2)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW3)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW4)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW5)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW6)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW7)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW8)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW9)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW10)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW11)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW12)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW13)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW14)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW0)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW2)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW3)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW4)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW5)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW6)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW7)
|
|
SAVE_COP2_REGISTER(COP2_GFM_MULT0)
|
|
SAVE_COP2_REGISTER(COP2_GFM_MULT1)
|
|
SAVE_COP2_REGISTER(COP2_GFM_POLY)
|
|
SAVE_COP2_REGISTER(COP2_GFM_RESULT0)
|
|
SAVE_COP2_REGISTER(COP2_GFM_RESULT1)
|
|
/* restore saved COP2 status */
|
|
mtc0 t2, MIPS_COP_0_STATUS
|
|
jr ra
|
|
nop
|
|
|
|
save_pass1:
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW0_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW1_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW2_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW3_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW4_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW5_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_DATW6_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW0_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW1_PASS1)
|
|
SAVE_COP2_REGISTER(COP2_HSH_IVW2_PASS1)
|
|
|
|
save_done:
|
|
/* restore saved COP2 status */
|
|
mtc0 t2, MIPS_COP_0_STATUS
|
|
jr ra
|
|
nop
|
|
END(octeon_cop2_save)
|
|
|
|
LEAF(octeon_cop2_restore)
|
|
/* save original cop2 status in t2*/
|
|
mfc0 t2, MIPS_COP_0_STATUS
|
|
or t0, t2, MIPS_SR_COP_2_BIT
|
|
and t0, t0, ~MIPS_SR_INT_IE
|
|
mtc0 t0, MIPS_COP_0_STATUS
|
|
/* Get CvmCtl register */
|
|
dmfc0 t0, $9, 7
|
|
|
|
/* CRC state */
|
|
RESTORE_COP2_REGISTER(COP2_CRC_IV)
|
|
RESTORE_COP2_REGISTER(COP2_CRC_LENGTH)
|
|
RESTORE_COP2_REGISTER(COP2_CRC_POLY)
|
|
|
|
/* if CvmCtl[NODFA_CP2] -> save_nodfa */
|
|
bbit1 t0, 28, restore_nodfa
|
|
nop
|
|
|
|
/* LLM state */
|
|
RESTORE_COP2_REGISTER(COP2_LLM_DAT0)
|
|
RESTORE_COP2_REGISTER(COP2_LLM_DAT1)
|
|
|
|
restore_nodfa:
|
|
/* crypto stuff is irrelevant if CvmCtl[NOCRYPTO] */
|
|
bbit1 t0, 26, restore_done
|
|
nop
|
|
|
|
RESTORE_COP2_REGISTER(COP2_3DES_IV)
|
|
RESTORE_COP2_REGISTER(COP2_3DES_KEY0)
|
|
RESTORE_COP2_REGISTER(COP2_3DES_KEY1)
|
|
RESTORE_COP2_REGISTER(COP2_3DES_KEY2)
|
|
RESTORE_COP2_REGISTER(COP2_3DES_RESULT)
|
|
|
|
RESTORE_COP2_REGISTER(COP2_AES_INP0)
|
|
RESTORE_COP2_REGISTER(COP2_AES_IV0)
|
|
RESTORE_COP2_REGISTER(COP2_AES_IV1)
|
|
RESTORE_COP2_REGISTER(COP2_AES_KEY0)
|
|
RESTORE_COP2_REGISTER(COP2_AES_KEY1)
|
|
RESTORE_COP2_REGISTER(COP2_AES_KEY2)
|
|
RESTORE_COP2_REGISTER(COP2_AES_KEY3)
|
|
RESTORE_COP2_REGISTER(COP2_AES_KEYLEN)
|
|
RESTORE_COP2_REGISTER(COP2_AES_RESULT0)
|
|
RESTORE_COP2_REGISTER(COP2_AES_RESULT1)
|
|
|
|
dmfc0 t0, $15
|
|
li t1, 0x000d0000 /* Octeon Pass1 */
|
|
beq t0, t1, restore_pass1
|
|
nop
|
|
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW0)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW2)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW3)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW4)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW5)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW6)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW7)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW8)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW9)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW10)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW11)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW12)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW13)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW14)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW0)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW2)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW3)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW4)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW5)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW6)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW7)
|
|
RESTORE_COP2_REGISTER(COP2_GFM_MULT0)
|
|
RESTORE_COP2_REGISTER(COP2_GFM_MULT1)
|
|
RESTORE_COP2_REGISTER(COP2_GFM_POLY)
|
|
RESTORE_COP2_REGISTER(COP2_GFM_RESULT0)
|
|
RESTORE_COP2_REGISTER(COP2_GFM_RESULT1)
|
|
/* restore saved COP2 status */
|
|
mtc0 t2, MIPS_COP_0_STATUS
|
|
jr ra
|
|
nop
|
|
|
|
restore_pass1:
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW0_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW1_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW2_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW3_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW4_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW5_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_DATW6_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW0_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW1_PASS1)
|
|
RESTORE_COP2_REGISTER(COP2_HSH_IVW2_PASS1)
|
|
|
|
restore_done:
|
|
/* restore saved COP2 status */
|
|
mtc0 t2, MIPS_COP_0_STATUS
|
|
jr ra
|
|
nop
|
|
END(octeon_cop2_restore)
|