⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 excep_s.s

📁 MIPS下的boottloader yamon 的源代码
💻 S
📖 第 1 页 / 共 2 页
字号:

/************************************************************************
 *
 *  excep_s.S
 *
 *  First level exception handling functions.
 *
 *
 * ######################################################################
 *
 * 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 <gdb_stub.h>
#include <sys_api.h>	

/************************************************************************
 *  Definitions
 ************************************************************************/

#define CAUSE_EXC	0
#define CAUSE_EJTAG	1

/* Offset to 32 bit word in 64 bit storage area */
#ifdef EB
#define OFS_END		4
#else
#define OFS_END		0
#endif

/************************************************************************
 *  Public variables
 ************************************************************************/

	BSS
	
	.globl EXCEP_gdb_regs

	/* 64 bit align */
	.align 3
	
EXCEP_gdb_regs:
	.space	EXCEP_SIZE_CONTEXT

/************************************************************************
 *  Static variables
 ************************************************************************/

temp_stack:
	.space  SYS_STACK_SIZE
temp_stack_end :		

old_data:
	.space	7*4*4	/* 7 exc vector of each 4 words */

scratchpad:		/* Storage for s0..s8 */
	.space  9*4	

registered_exc_handler:	
	.space  4

cause:
	.space  4
	
/************************************************************************
 *  Implementation : Public functions
 ************************************************************************/

	.globl EXCEP_return
	
/************************************************************************
 *
 *                          EXCEP_install_exc_in_ram
 *  Description :
 *  -------------
 *
 *  Install jump instructions to exc handler at exception vector locations
 *  Stores/restores old data at exception vector locations depending
 *  on a0 register (see description of parameters)
 *
 *  Parameters :
 *  ------------
 *
 *  a0 = 0 -> Install ram handler, store old data
 *  a0 = 1 -> Restore old data
 *
 *  a1 = exc handler to be called after storing context
 *       (NULL -> ignore this)
	
 *  Return values :
 *  ---------------
 *
 *  None
 *
 ************************************************************************/
LEAF( EXCEP_install_exc_in_ram )

	.set noreorder
	
	/* Install RAM exception vectors */

	/*  First store s0..s8 since we plan to use them here and 
	 *  in setup_vector() 
	 */

	la      t0, scratchpad
	sw	s0, 0(t0)
	sw	s1, 4(t0)
	sw	s2, 8(t0)
	sw	s3, 12(t0)
	sw	s4, 16(t0)
	sw	s5, 20(t0)
	sw	s6, 24(t0)
	sw	s7, 28(t0)
	sw	s8, 32(t0)
				
#define RA			s0
#define NEW_HANDLER		s1
#define OLD_HANDLER		s2
#define STATUS_INT		s3
#define ADDR			s4
	
	move	RA, ra

	/* Disable interrupts */
	MFC0(   STATUS_INT, C0_STATUS )
	li	t1,         ~C0_STATUS_IE_MSK
	and	t1,	    STATUS_INT	
	MTC0(   t1,	    C0_STATUS )
	li	t1,	    C0_STATUS_IE_MSK
	and	STATUS_INT, t1
	
	/* If available, store exception handler to be called after context store */
	beq	a1, zero, 1f
	nop
	/* Store default handler */
	la	t1, registered_exc_handler
	sw	a1, 0(t1)

1:
	/* Determine data to store */
	bne	a0, zero, restore_old
	nop

	/**** Install ram handler ****/
	la	NEW_HANDLER, ram_handler_normal
	la	OLD_HANDLER, old_data

	/* Install the vectors */
	jal	setup_vector
	li	ADDR, 0x0	/* TLB refill     */

	addu	OLD_HANDLER, 4*4
	jal	setup_vector
	li	ADDR, 0x80	/* XTLB refill    */

	addu	OLD_HANDLER, 4*4
	jal	setup_vector
	li	ADDR, 0x100	/* Cache error    */

	addu	OLD_HANDLER, 4*4
	jal	setup_vector
	li	ADDR, 0x180	/* General        */

	/*  NMI exception.
	 *  Always uses address 0xbfc00000 (reset vector), but YAMON
	 *  will jump to 0x800000000 + SYS_NMI_RAM_VECTOR_OFS 
	 *  if it detects an NMI.
	 */
	addu	OLD_HANDLER, 4*4	
	jal	setup_vector
	li	ADDR, SYS_NMI_RAM_VECTOR_OFS
	
	la	NEW_HANDLER, ram_handler_interrupt
	addu	OLD_HANDLER, 4*4	
	jal	setup_vector
	li	ADDR, 0x200	/* Int, CauseIV=1 */	

	/*  EJTAG Debug exception.
	 *  Always uses address 0xbfc00480, but YAMON has installed
	 *  a jump to KSEG0(SYS_EJTAG_RAM_VECTOR) at that vector location.
	 */
	la	NEW_HANDLER, ram_handler_ejtag	
	addu	OLD_HANDLER, 4*4	
	jal	setup_vector
	li	ADDR, SYS_EJTAG_RAM_VECTOR_OFS

	j	install_done
	nop

restore_old:

	/**** Restore old data ****/
	la	NEW_HANDLER, old_data
	move	OLD_HANDLER, zero

	/* Install the vectors */
	jal	setup_vector
	li	ADDR, 0x0	/* TLB refill     */

	addu	NEW_HANDLER, 4*4
	jal	setup_vector
	li	ADDR, 0x80	/* XTLB refill    */

	addu	NEW_HANDLER, 4*4
	jal	setup_vector
	li	ADDR, 0x100	/* Cache error    */

	addu	NEW_HANDLER, 4*4
	jal	setup_vector
	li	ADDR, 0x180	/* General        */

	/*  NMI exception.
	 *  Always uses address 0xbfc00000 (reset vector), but YAMON
	 *  will jump to 0x800000000 + SYS_NMI_RAM_VECTOR_OFS 
	 *  if it detects an NMI.
	 */
	addu	NEW_HANDLER, 4*4	
	jal	setup_vector
	li	ADDR, SYS_NMI_RAM_VECTOR_OFS
	
	addu	NEW_HANDLER, 4*4	
	jal	setup_vector
	li	ADDR, 0x200	/* Int, CauseIV=1 */	

	/*  EJTAG Debug exception.
	 *  Always uses address 0xbf000480, but YAMON has installed
	 *  a jump to KSEG0(SYS_EJTAG_RAM_VECTOR) at that vector location.
	 */
	addu	NEW_HANDLER, 4*4	
	jal	setup_vector
	li	ADDR, SYS_EJTAG_RAM_VECTOR_OFS


install_done:
	
	/* Clear BEV so that ram handlers are used */
	MFC0(   a0, C0_STATUS)
	li	a1, ~C0_STATUS_BEV_BIT
	and	a0, a1
	MTC0(   a0, C0_STATUS)

	/* Restore interrupt enable state */
	MFC0(   t1, C0_STATUS )
	or	t1, STATUS_INT
	MTC0(   t1, C0_STATUS )

	move	ra, RA

	/* Restore s0..s8 */
	la      t0, scratchpad
	lw	s0, 0(t0)
	lw	s1, 4(t0)
	lw	s2, 8(t0)
	lw	s3, 12(t0)
	lw	s4, 16(t0)
	lw	s5, 20(t0)
	lw	s6, 24(t0)
	lw	s7, 28(t0)
	lw	s8, 32(t0)
	
	/* Done */
	jr	ra
	move	v0, zero


	
setup_vector:

	/* Copy ram handler_start code to exception vector location */

	move	s5, ra

#define SRC		s6
#define OLD		s7
#define END_ADDR	s8	
		
	/* Calc addresses */
	KSEG0A( ADDR )			/* Destination   */
	move	SRC,      NEW_HANDLER	/* Source        */
	move	OLD,      OLD_HANDLER	/* Old data	 */
	addu	END_ADDR, SRC, 4*4	/* copy 4 words  */

1:
	/* Possibly fetch and Store old data   */
	beq	OLD, zero, 2f
	nop
	lw	a3, 0(ADDR)
	sw	a3, 0(OLD)
	addiu	OLD, 4
2:
	/* Install new instruction    */
	lw	a3, 0(SRC)
	sw	a3, 0(ADDR)

	/* Whenever an instruction has been stored to KSEG0, we must
	 * make sure the instruction has been flushed to physical memory
	 * and invalidate the corresponding I-Cache line.
	 */

	move	a0, ADDR
	jal     sys_dcache_flush_addr
	nop
	move	a0, ADDR
	jal	sys_icache_invalidate_addr
	nop
			
	/* Loop */
	add	SRC, 4
	bne	SRC, END_ADDR, 1b
	add	ADDR, 4

	jr	s5
	nop


ram_handler_normal:
	/*  This code is copied to the various ram exception vector
	 *  locations (4 words are copied).
	 */
	la	k0, exc_handler
	jr	k0
	li	k0, CAUSE_EXC
	nop  /* Depending on above la, this may skipped */

ram_handler_ejtag:
	/*  This code is copied to the exception vector
	 *  location reserved (by YAMON) for EJTAG (i.e. 0x80000300)
	 *  (4 words are copied).
	 */
	la	k0, exc_handler
	jr	k0
	li	k0, CAUSE_EJTAG
	nop  /* Depending on above la, this may skipped */

ram_handler_interrupt:
	/*  This code is copied to the various ram exception vector
	 *  locations (4 words are copied).
	 */
	la	k0, exc_handler
	jr	k0
	li	k0, CAUSE_EXC
	nop  /* Depending on above la, this may skipped */
	

exc_handler:

	/**** Store context ****/

	la	k1,   sys_64bit
	lb	k1,   0(k1)
	bne	k1,   zero, store_64bit
	nop

	/* Store 32 bit CPU Registers */
	la	k1,   EXCEP_gdb_regs

	sw	$0,   (GDB_FR_REG0  + OFS_END)(k1)
	.set noat
	sw	$1,   (GDB_FR_REG1  + OFS_END)(k1)
	.set at
	sw	$2,   (GDB_FR_REG2  + OFS_END)(k1)
	sw	$3,   (GDB_FR_REG3  + OFS_END)(k1)
	sw	$4,   (GDB_FR_REG4  + OFS_END)(k1)
	sw	$5,   (GDB_FR_REG5  + OFS_END)(k1)
	sw	$6,   (GDB_FR_REG6  + OFS_END)(k1)
	sw	$7,   (GDB_FR_REG7  + OFS_END)(k1)
	sw	$8,   (GDB_FR_REG8  + OFS_END)(k1)
	sw	$9,   (GDB_FR_REG9  + OFS_END)(k1)
	sw	$10,  (GDB_FR_REG10 + OFS_END)(k1)
	sw	$11,  (GDB_FR_REG11 + OFS_END)(k1)
	sw	$12,  (GDB_FR_REG12 + OFS_END)(k1)
	sw	$13,  (GDB_FR_REG13 + OFS_END)(k1)
	sw	$14,  (GDB_FR_REG14 + OFS_END)(k1)
	sw	$15,  (GDB_FR_REG15 + OFS_END)(k1)
	sw	$16,  (GDB_FR_REG16 + OFS_END)(k1)
	sw	$17,  (GDB_FR_REG17 + OFS_END)(k1)
	sw	$18,  (GDB_FR_REG18 + OFS_END)(k1)
	sw	$19,  (GDB_FR_REG19 + OFS_END)(k1)
	sw	$20,  (GDB_FR_REG20 + OFS_END)(k1)
	sw	$21,  (GDB_FR_REG21 + OFS_END)(k1)
	sw	$22,  (GDB_FR_REG22 + OFS_END)(k1)
	sw	$23,  (GDB_FR_REG23 + OFS_END)(k1)
	sw	$24,  (GDB_FR_REG24 + OFS_END)(k1)
	sw	$25,  (GDB_FR_REG25 + OFS_END)(k1)
	/* Not k0, k1 = $26, $27 */
	sw	$28,  (GDB_FR_REG28 + OFS_END)(k1)
	sw	$29,  (GDB_FR_REG29 + OFS_END)(k1)
	sw	$30,  (GDB_FR_REG30 + OFS_END)(k1)
	sw	$31,  (GDB_FR_REG31 + OFS_END)(k1)

	b	store_cp0
	nop

store_64bit :
	/* Store 64 bit CPU Registers */
	la	k1,   EXCEP_gdb_regs

	OPCODE_SD      (0,  GDB_FR_REG0,  SYS_CPUREG_K1 )
	OPCODE_SD      (1,  GDB_FR_REG1,  SYS_CPUREG_K1 )
	OPCODE_SD      (2,  GDB_FR_REG2,  SYS_CPUREG_K1 )
	OPCODE_SD      (3,  GDB_FR_REG3,  SYS_CPUREG_K1 )
	OPCODE_SD      (4,  GDB_FR_REG4,  SYS_CPUREG_K1 )
	OPCODE_SD      (5,  GDB_FR_REG5,  SYS_CPUREG_K1 )
	OPCODE_SD      (6,  GDB_FR_REG6,  SYS_CPUREG_K1 )
	OPCODE_SD      (7,  GDB_FR_REG7,  SYS_CPUREG_K1 )
	OPCODE_SD      (8,  GDB_FR_REG8,  SYS_CPUREG_K1 )
	OPCODE_SD      (9,  GDB_FR_REG9,  SYS_CPUREG_K1 )
	OPCODE_SD      (10, GDB_FR_REG10, SYS_CPUREG_K1 )
	OPCODE_SD      (11, GDB_FR_REG11, SYS_CPUREG_K1 )
	OPCODE_SD      (12, GDB_FR_REG12, SYS_CPUREG_K1 )
	OPCODE_SD      (13, GDB_FR_REG13, SYS_CPUREG_K1 )
	OPCODE_SD      (14, GDB_FR_REG14, SYS_CPUREG_K1 )
	OPCODE_SD      (15, GDB_FR_REG15, SYS_CPUREG_K1 )
	OPCODE_SD      (16, GDB_FR_REG16, SYS_CPUREG_K1 )
	OPCODE_SD      (17, GDB_FR_REG17, SYS_CPUREG_K1 )
	OPCODE_SD      (18, GDB_FR_REG18, SYS_CPUREG_K1 )
	OPCODE_SD      (19, GDB_FR_REG19, SYS_CPUREG_K1 )
	OPCODE_SD      (20, GDB_FR_REG20, SYS_CPUREG_K1 )
	OPCODE_SD      (21, GDB_FR_REG21, SYS_CPUREG_K1 )
	OPCODE_SD      (22, GDB_FR_REG22, SYS_CPUREG_K1 )
	OPCODE_SD      (23, GDB_FR_REG23, SYS_CPUREG_K1 )
	OPCODE_SD      (24, GDB_FR_REG24, SYS_CPUREG_K1 )
	OPCODE_SD      (25, GDB_FR_REG25, SYS_CPUREG_K1 )
	/* Not k0, k1 = $26, $27 */
	OPCODE_SD      (28, GDB_FR_REG28, SYS_CPUREG_K1 )
	OPCODE_SD      (29, GDB_FR_REG29, SYS_CPUREG_K1 )
	OPCODE_SD      (30, GDB_FR_REG30, SYS_CPUREG_K1 )
	OPCODE_SD      (31, GDB_FR_REG31, SYS_CPUREG_K1 )

store_cp0 :
	/* Store CP0 registers */
	move	a0, k1
	jal	sys_store_cp0_regs
	nop

	/* Store cause (CAUSE_EXC/CAUSE_EJTAG) */
	la	t0, cause
	sw	k0, 0(t0)
	
	/*  A registered exception handler is allowed to call
	 *  EXCEP_return (see below) in case it does not want to
	 *  handle the exception. 
	 *  The address of EXCEP_return was returned when the 
	 *  exception handler was registered.
	 *  We need to flag whether this is the initial handling
	 *  of an exception or such a return from a registered 
	 *  exception handler. This is done using the 
	 *  EXCEP_return_flag variable.
	 */
	
	/* Clear 'EXCEP_return_flag' */
	la	t0, EXCEP_return_flag
	sb	zero, 0(t0)
	b	1f
	nop

EXCEP_return :

	/* Set 'EXCEP_return_flag' */
	la      t0, EXCEP_return_flag
	li	t1, 1
	sb	t1, 0(t0)
	nop
1:	     
	/* Get cause (CAUSE_EXC/CAUSE_EJTAG) */
	la	t0, cause
	lw	k0, 0(t0)
				
	/*  Restore gp and set sp to the exception stack space */
	la	gp, _gp
	la	sp, temp_stack_end
	addiu	sp, -4*4

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -