📄 appl_if.s
字号:
/************************************************************************
*
* appl_if.S
*
* Assembler functions used for shell/user application interface
*
*
* ######################################################################
*
* Copyright (c) 1999-2000 MIPS Technologies, Inc. All rights reserved.
*
* Unpublished rights reserved under the Copyright Laws of the United States of
* America.
*
* This document contains information that is proprietary to MIPS Technologies,
* Inc. ("MIPS Technologies"). Any copying, modifying or use of this information
* (in whole or in part) which is not expressly permitted in writing by MIPS
* Technologies or a contractually-authorized third party is strictly
* prohibited. At a minimum, this information is protected under unfair
* competition laws and the expression of the information contained herein is
* protected under federal copyright laws. Violations thereof may result in
* criminal penalties and fines.
* MIPS Technologies or any contractually-authorized third party reserves the
* right to change the information contained in this document to improve
* function, design or otherwise. MIPS Technologies does not assume any
* liability arising out of the application or use of this information. Any
* license under patent rights or any other intellectual property rights owned
* by MIPS Technologies or third parties shall be conveyed by MIPS Technologies
* or any contractually-authorized third party in a separate license agreement
* between the parties.
* The information contained in this document constitutes one or more of the
* following: commercial computer software, commercial computer software
* documentation or other commercial items. If the user of this information, or
* any related documentation of any kind, including related technical data or
* manuals, is an agency, department, or other entity of the United States
* government ("Government"), the use, duplication, reproduction, release,
* modification, disclosure, or transfer of this information, or any related
* documentation of any kind, is restricted in accordance with Federal
* Acquisition Regulation 12.212 for civilian agencies and Defense Federal
* Acquisition Regulation Supplement 227.7202 for military agencies. The use of
* this information by the Government is further restricted in accordance with
* the terms of the license agreement(s) and/or applicable contract terms and
* conditions covering this information from MIPS Technologies or any
* contractually-authorized third party.
*
************************************************************************/
/************************************************************************
* Include files
************************************************************************/
#include <sysdefs.h>
#include <mips.h>
#include <shell_api.h>
#include <excep_api.h>
/************************************************************************
* Definitions
************************************************************************/
/************************************************************************
* Public variables
************************************************************************/
/************************************************************************
* Static variables
************************************************************************/
.align 3
/* Space for 32 64 bit CPU registers (not all used) */
store_cpuregs64:
.space 32*8
/* Space for 9 32 bit CPU registers */
store_cpuregs:
.space 9*4
#define REG_A0 0x0
#define REG_A1 0x4
#define REG_A2 0x8
#define REG_A3 0xc
#define REG_V0 0x10
#define REG_T0 0x14
#define REG_RA 0x18
#define REG_K0 0x1c
#define REG_K1 0x20
.align 3
/* Space for 2 32 bit CP0 registers (STATUS and CAUSE)
* and 1 32/64 bit CP0 register (EPC)
*/
store_cp0regs:
.space 4*4
#define REG_STATUS 0x0
#define REG_CAUSE 0x4
#define REG_EPC 0x8
/************************************************************************
* Implementation : Public functions
************************************************************************/
.set noreorder
LEAF( shell_return )
/* Function code */
li t0, SHELL_FUNC_EXIT_CODE
b user2yamon
nop
END( shell_return )
LEAF( shell_exit )
/* Move exit code to v0, so that acts the same as a user 'return' */
move v0, a0
/* Function code */
li t0, SHELL_FUNC_EXIT_CODE
b user2yamon
nop
END( shell_exit )
LEAF( shell_print_count )
/* Function code */
li t0, SHELL_FUNC_PRINT_COUNT_CODE
b user2yamon
nop
END( shell_print_count )
LEAF( shell_print )
/* Function code */
li t0, SHELL_FUNC_PRINT_CODE
b user2yamon
nop
END( shell_print )
LEAF( shell_getchar )
/* Function code */
li t0, SHELL_FUNC_GETCHAR_CODE
b user2yamon
nop
END( shell_getchar )
LEAF( shell_syscon_read )
/* Function code */
li t0, SHELL_FUNC_SYSCON_READ_CODE
b user2yamon
nop
END( shell_syscon_read )
LEAF( shell_flush )
/* Function code */
li t0, SHELL_FUNC_FLUSH_CODE
b user2yamon
nop
END( shell_flush )
LEAF( shell_register_cpu_isr )
/* Function code */
li t0, SHELL_FUNC_REGISTER_CPU_ISR_CODE
b user2yamon
nop
END( shell_register_cpu_isr )
LEAF( shell_deregister_cpu_isr )
/* Function code */
li t0, SHELL_FUNC_DEREGISTER_CPU_ISR_CODE
b user2yamon
nop
END( shell_deregister_cpu_isr )
LEAF( shell_register_ic_isr )
/* Function code */
li t0, SHELL_FUNC_REGISTER_IC_ISR_CODE
b user2yamon
nop
END( shell_register_ic_isr )
LEAF( shell_deregister_ic_isr )
/* Function code */
li t0, SHELL_FUNC_DEREGISTER_IC_ISR_CODE
b user2yamon
nop
END( shell_deregister_ic_isr )
LEAF( shell_register_esr )
/* Function code */
li t0, SHELL_FUNC_REGISTER_ESR_CODE
b user2yamon
nop
END( shell_register_esr )
LEAF( shell_deregister_esr )
/* Function code */
li t0, SHELL_FUNC_DEREGISTER_ESR_CODE
b user2yamon
nop
END( shell_deregister_esr )
SLEAF( user2yamon )
/* Store CP0 STATUS */
la t1, store_cp0regs
MFC0( t2, C0_STATUS )
sw t2, REG_STATUS(t1)
/* Clear BEV so that we use RAM exception handlers.
* Clear ERL and EXL.
* Also clear UM so that we remain in kernel mode.
* Clear IE bit in case user appl. has reenabled interrupts.
*/
li t3, ~(C0_STATUS_BEV_BIT | C0_STATUS_UM_BIT |\
C0_STATUS_IE_BIT)
and t2, t3
MTC0( t2, C0_STATUS )
li t3, ~(C0_STATUS_ERL_BIT | C0_STATUS_EXL_BIT)
and t2, t3
MTC0( t2, C0_STATUS )
/* Store CP0 CAUSE */
MFC0( t2, C0_CAUSE )
sw t2, REG_CAUSE(t1)
/* Branch based on 32 or 64 bit processor */
la t2, sys_64bit
lb t2, 0(t2)
bne t2, zero, user2yamon64bit
nop
/**** 32 bit CPU ****/
/* Store CP0 EPC */
MFC0( t2, C0_EPC )
sw t2, REG_EPC(t1)
la t1, store_cpuregs
sw a0, REG_A0(t1)
sw a1, REG_A1(t1)
sw a2, REG_A2(t1)
sw a3, REG_A3(t1)
sw v0, REG_V0(t1)
sw t0, REG_T0(t1)
sw ra, REG_RA(t1)
sw k0, REG_K0(t1)
sw k1, REG_K1(t1)
/* Install normal exception handler in case application
* has corrupted this
*/
move a0, zero
move a1, zero
jal EXCEP_install_exc_in_ram
nop
la t1, store_cpuregs
lw a0, REG_A0(t1)
lw a1, REG_A1(t1)
lw a2, REG_A2(t1)
lw a3, REG_A3(t1)
lw v0, REG_V0(t1)
lw t0, REG_T0(t1)
/* Force BREAK exception in order to shift to shell context */
jal shell_force_break
nop
/* Restore general exception vector */
la t1, store_cpuregs
sw v0, REG_V0(t1)
li a0, 1
move a1, zero
jal EXCEP_install_exc_in_ram
nop
la t1, store_cpuregs
lw v0, REG_V0(t1)
lw t0, REG_T0(t1)
lw ra, REG_RA(t1)
lw k0, REG_K0(t1)
lw k1, REG_K1(t1)
/* Restore CP0 EPC */
la t1, store_cp0regs
lw a0, REG_EPC(t1)
MTC0( a0, C0_EPC )
b restore_cp0
nop
user2yamon64bit :
/**** 64 bit CPU ****/
/* Store CP0 EPC */
MFC0( t2, C0_EPC )
OPCODE_SD( SYS_CPUREG_T2, REG_EPC, SYS_CPUREG_T1 )
/* We don't assume that YAMON functions like
* EXCEP_install_exc_in_ram, which we are calling below,
* will save the 64 bit state of "static" CPU registers
* (32 bit state is off course saved), so we save all static
* registers as well as the non-static, which we are
* responsible for.
*/
la t1, store_cpuregs64
OPCODE_SD( SYS_CPUREG_AT, SYS_CPUREG_AT * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_V0, SYS_CPUREG_V0 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_A0, SYS_CPUREG_A0 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_A1, SYS_CPUREG_A1 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_A2, SYS_CPUREG_A2 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_A3, SYS_CPUREG_A3 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_T0, SYS_CPUREG_T0 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S0, SYS_CPUREG_S0 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S1, SYS_CPUREG_S1 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S2, SYS_CPUREG_S2 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S3, SYS_CPUREG_S3 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S4, SYS_CPUREG_S4 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S5, SYS_CPUREG_S5 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S6, SYS_CPUREG_S6 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S7, SYS_CPUREG_S7 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_K0, SYS_CPUREG_K0 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_K1, SYS_CPUREG_K1 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_GP, SYS_CPUREG_GP * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_SP, SYS_CPUREG_SP * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_S8, SYS_CPUREG_S8 * 8, SYS_CPUREG_T1 )
OPCODE_SD( SYS_CPUREG_RA, SYS_CPUREG_RA * 8, SYS_CPUREG_T1 )
/* Install normal exception handler in case application
* has corrupted this
*/
move a0, zero
move a1, zero
jal EXCEP_install_exc_in_ram
nop
la t1, store_cpuregs64
OPCODE_LD( SYS_CPUREG_A0, SYS_CPUREG_A0 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_A1, SYS_CPUREG_A1 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_A2, SYS_CPUREG_A2 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_A3, SYS_CPUREG_A3 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_V0, SYS_CPUREG_V0 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_T0, SYS_CPUREG_T0 * 8, SYS_CPUREG_T1 )
/* Force BREAK exception in order to shift to shell context */
jal shell_force_break
nop
/* Restore general exception vector */
la t1, store_cpuregs64
OPCODE_SD( SYS_CPUREG_V0, SYS_CPUREG_V0 * 8, SYS_CPUREG_T1 )
li a0, 1
move a1, zero
jal EXCEP_install_exc_in_ram
nop
la t1, store_cpuregs64
OPCODE_LD( SYS_CPUREG_AT, SYS_CPUREG_AT * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_V0, SYS_CPUREG_V0 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_T0, SYS_CPUREG_T0 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S0, SYS_CPUREG_S0 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S1, SYS_CPUREG_S1 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S2, SYS_CPUREG_S2 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S3, SYS_CPUREG_S3 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S4, SYS_CPUREG_S4 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S5, SYS_CPUREG_S5 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S6, SYS_CPUREG_S6 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S7, SYS_CPUREG_S7 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_K0, SYS_CPUREG_K0 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_K1, SYS_CPUREG_K1 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_GP, SYS_CPUREG_GP * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_SP, SYS_CPUREG_SP * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_S8, SYS_CPUREG_S8 * 8, SYS_CPUREG_T1 )
OPCODE_LD( SYS_CPUREG_RA, SYS_CPUREG_RA * 8, SYS_CPUREG_T1 )
/* Restore CP0 EPC */
la t1, store_cp0regs
OPCODE_LD( SYS_CPUREG_A0, REG_EPC, SYS_CPUREG_T1 )
MTC0( a0, C0_EPC )
restore_cp0 :
/* Restore CP0 CAUSE */
lw a0, REG_CAUSE(t1)
MTC0( a0, C0_CAUSE )
/* Restore CP0 STATUS */
lw a0, REG_STATUS(t1)
li t1, SHELL_FUNC_REGISTER_CPU_ISR_CODE
beq t0, t1, set_imask
nop
li t1, SHELL_FUNC_DEREGISTER_CPU_ISR_CODE
bne t0, t1, set_status
nop
set_imask :
/* Set IM field of STATUS register identical to YAMON context.
* Otherwise, the application would have to enable the required
* interrupts after registering an ISR.
*/
li t0, ~C0_STATUS_IM_MSK
and a0, t0
li t0, C0_STATUS_IM_MSK
/* v0 was set to the YAMON context STATUS register setting */
and v0, t0
or a0, v0
set_status :
MTC0( a0, C0_STATUS )
/* Return to caller */
jr ra
nop
END( user2yamon )
LEAF( shell_force_break )
/* Force BREAK exception */
break
jr ra
nop
END( shell_force_break )
/************************************************************************
* Implementation : Static functions
************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -