最新文章:

首页 code

5281 part bare-metal exception handle

发布时间:2016年09月06日 评论数:抢沙发 阅读数:17013

    1) link script 增加段

    	.text.tlbmiss 0x80000000 :
    	{
    		*(.text.tlbmiss)
    	}
    	.text.trap 0x80000080 :
    	{
    		*(.text.trap)
    	}



    2) 在初始化代码中初始化程序异常寄存器,打开中断等


    3) 异常处理段的代码

    #include "rlx_regdef.h"
    
    .file   "HAL_RLX.S"
    	.set noreorder
    
    /*
     * Exception handlers
     *
     * TLB_Handler is installed at 0x80000000 (not actually used)
     * Trap_Handler is installed at 0x80000080
     */
    /*--------------------------- TLB_handler -----------------------------------*/
    	.section ".text.tlbmiss", "ax"
    	.globl TLB_Handler
    	.ent TLB_Handler
    TLB_Handler:
    /*	check TLB again */
    /*	mfc0  k1, CP0_CAUSE
    	__COP_HAZARD
    	andi  k0, k1, 0x0008
    
    	beqz  k0, Trap_Err
    	nop
    */
    /*	specify TLB exception type :
    	1.TLB Instruction address exception pri:4 exccode:2
    	2.TLB data address exception pri:11 exccode:2
    */
    	mfc0  k0, CP0_BADVADDR
    	__COP_HAZARD
    	mfc0  k1, CP0_EPC
    	__COP_HAZARD
    	xor   k0, k1
    	beqz  k0, 1f
    	nop
    	j     2f
    /*	print info, need save context? */
    1:	li    a0, 0x15
    	jal   print_exc_info
    	nop
    2:	li    a0, 0x16
    //	la    ra, Trap_Err
    	jal   print_exc_info
    	nop
    	addi  k1, 4
    	jr    k1
    	rfe
    	.end  TLB_Handler
    
    /*--------------------------- Trap_Handler ---------------------------------*/
    	.section ".text.trap", "ax"
    	.balign 0x80
    	.globl Trap_Err
    	.globl Trap_Handler
    	.ent Trap_Handler
    Trap_Handler:
    /*	check ADEL instruction first, or it may be treated as RI*/
    	mfc0  k0, CP0_EPC
    	__COP_HAZARD
    	andi  k0, 0x3
    	bnez  k0, Trap_ADEL
    	nop
    /*	check ExcCode @ CAUSE[6:2] */
    	mfc0  k1, CP0_CAUSE
    	 __COP_HAZARD
    	andi  k0, k1, 0x007c
    	# Branch to exception-specific handlers
    	# Interrupts are handled by common handler
    	beqz  k0, Trap_Int            # common handler to deal with all hardware interrupts
    	andi  k1, 0xff00
    /*	check BREAK instruction trap Pri:7 exccode:9 */
    	xori  k1, k0, 0x24
    	beqz  k1, Trap_Bp
    	nop
    /*	check AdEL trap Pri:3 exccode:4 */
    	xori  k1, k0, 0x10
    	beqz  k1, Trap_ADEL
    	nop
    /*	check Reserved instruction trap Pri:7 exccode:10 */
    	xori  k1, k0, 0x28
    	beqz  k1, Trap_RI
    	nop
    /*	handle syscall Pri:7 exccode:8 */              #                 0 | 000_00 (ExcCode) | 00
    	andi  k0, 0x0020              # for Sys,        0 | 010_00 (ExcCode) | 00
    	bnez  k0, Trap_Sys
    	nop
    
    Trap_Err:
    	mfc0  k1, CP0_EPC             # Reserve the values k0: Excode, k1: EPC
    	move  k0,  a0
    	la    a0, _exit               # Jump to _exit with return code 125
    	jr    a0
    	 li   a0,  125
    
    /*	check soft interrupts IP1/IP0 LSB [9:8] Pri:13 exccode:0 */
    Trap_Int:
    	mfc0  k0, CP0_STATUS
    	__COP_HAZARD
    	and   k0, k1
    	srl   k0, k0, STATUSB_IP0
    	move  k1, k0
    	andi  k1, k1, 0x1
    	bnez  k1, Trap_Int0
    	nop
    	andi  k0, k0, 0x2
    	bnez  k0, Trap_Int1
    	nop
    	j     Trap_Err
    
    Trap_Sys:
    	li    a0, 0x8
    	jal   print_exc_info
    	nop
    	mfc0  k0, CP0_EPC
    	addi  k0, 4
    	jr    k0
    	rfe
    
    Trap_Bp:
    	li    a0, 0x9
    	jal   print_exc_info
    	nop
    	mfc0  k0, CP0_EPC
    	addi  k0, 4
    	jr    k0
    	rfe
    
    Trap_ADEL:
    /*	specify ADEL exception type :
    	1.ADEL Instruction address exception pri:4 exccode:2
    	2.ADEL data address exception pri:11 exccode:2
    */
    	mfc0  k0, CP0_BADVADDR
    	__COP_HAZARD
    	mfc0  k1, CP0_EPC
    	__COP_HAZARD
    	xor   k0, k1
    	beqz  k0, 1f
    	nop
    	j     2f
    1:	li    a0, 0x29
    	jal   print_exc_info
    	nop
    2:	li    a0, 0x2a
    	jal   print_exc_info
    	nop
    	addi  k1, 4
    	jr    k1
    	rfe
    
    Trap_RI:
    	li    a0, 0xa
    	jal   print_exc_info
    	nop
    	mfc0  k0, CP0_EPC
    	addi  k0, 4
    	jr    k0
    	rfe
    
    Trap_Int0:
    /*	clear CAUSE */
    	mfc0  k0, CP0_CAUSE
    	li    k1, 0xfffffeff
    	and   k0, k1
    	mtc0  k0, CP0_CAUSE
    /*	re-enable irq, or use rfe */
    	mfc0  k0, CP0_STATUS
    	__COP_HAZARD
    	ori   k0, 0x1
    	mtc0  k0, CP0_STATUS
    /*	set return address */
    //	mfc0  ra, CP0_EPC
    	li    a0, 0x0
    	jal    print_exc_info
    	nop
    	mfc0  k0, CP0_EPC
    	jr    k0
    
    Trap_Int1:
    /*	clear CAUSE */
    	mfc0  k0, CP0_CAUSE
    	li    k1, 0xfffffdff
    	and   k0, k1
    	mtc0  k0, CP0_CAUSE
    /*	re-enable irq */
    	mfc0  k0, CP0_STATUS
    	__COP_HAZARD
    	ori   k0, 0x1
    	mtc0  k0, CP0_STATUS
    /*	set return address */
    	mfc0  ra, CP0_EPC
    	li    a0, 0x1
    	la    k0, print_exc_info
    	jr    k0
    	.end  Trap_Handler
    
    /*	LEAF hardware init is moved to Crt0.S */

    4) 异常测试


    /*
     *	bare-metal exception handle program on RLX5281
     *
     *	Author: crane_jiang@realsil.com.cn @Aug,2016
    */
    
    #include <string.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int print_exc_info(int a);
    
    int main (void)
    {
    	unsigned int data0;
    	unsigned int data1;
    	
    	printf("start exception test\n");
    
    	// trap: soft interrupt 0
    	asm volatile( \
    		"mfc0  %0, $13\n" \
    		"ori   %1, %0, 0x0100\n" \
    		"mtc0  %1, $13\n":"=r"(data0):"r"(data1) \
    	);
    	printf("Back from SoftInt0\n\n");
    
    	//trap: fork
    	if (( newtask=fork() )==0)
    		printf("I'm child process,pid=%d,ppid=%d\n",getpid(),getppid());
    	else
    		printf("I'm parent process,pid=%d\n",getpid());	
    
    	// trap: TLBL-data
    	asm volatile( \
    		"li  %0, 0x7f000000\n" \
    		"lw  %1, 0(%0)\n":"=r"(data0):"r"(data1) \
    	);
    	printf("Back from TLBL-data exception\n\n");
    
    	// trap: AdEL-data
    	asm volatile( \
    		"li    %0, 0x80001001\n" \
    		"lw    %1, 0(%0)\n":"=r"(data0):"r"(data1) \
    	);
    	printf("Back from AdEL-data exception\n\n");
    
    	// trap: Sys
    	asm volatile("syscall\n");
    	printf("Back from SysCall\n\n");
    
    	// trap: Bp
    	asm volatile("break\n");
    	printf("Back from Bp exception\n\n");
    
    	// trap: RI
    	asm volatile(".word 0xfc000000\n");
    	printf("Back from RI exception\n\n");
    
    	// tarp: soft interrupt 1
    	asm volatile( \
    		"mfc0  %0, $13\n" \
    		"ori   %1, %0, 0x0200\n" \
    		"mtc0  %1, $13\n":"=r"(data0):"r"(data1) \
    	);
    	printf("Back from SoftInt1\n\n");
    
    	// trap: AdEL-instruction, can't handle, exit
    	asm volatile( \
    		"li    %0, 0x80001001\n" \
    		"jr    %0\n" \
    		"nop\n":"=r"(data0) \
    	);
    //	printf("Back from AdEL-instruction exception\n\n");
    
    	// trap: TLBL-instruction, can't handle, exit
    	asm volatile( \
    		"li    %0, 0x7f000000\n" \
    		"jr    %0\n" \
    		"nop\n":"=r"(data0) \
    	);
    //	printf("Back from TLBL-instruction exception\n\n");
    
    	printf("exception test finish\n");
    	return 0;
    }
    
    int print_exc_info(int a)
    {
    	switch (a)
    	{
    	case 0 : printf("handle Softirq 0 exception\n");break;
    	case 1 : printf("handle Softirq 1 exception\n");break;
    	case 21: printf("unable to handle TLBL-instruction exception, exit\n");Trap_Err();break;
    	case 22: printf("handle TLBL-data exception\n");break;
    	case 41: printf("unable to handle ADEL-instruction exception, exit\n");Trap_Err();break;
    	case 42: printf("handle ADEL-data exception\n");break;
    	case 8 : printf("handle Syscall exception\n");break;
    	case 9 : printf("handle Bp exception\n");break;
    	case 10: printf("handle RI exception\n");break;
    	default: printf("No match exception, para a=%d\n",a);break;
    	}
    	return 0;
    }


    5281 异常表


二维码加载中...
本文作者:admin      文章标题: 5281 part bare-metal exception handle
本文地址:http://jiang.shuang.he.cn/blog/?post=7
版权声明:若无注明,本文皆为“”原创,转载请保留文章出处。
挤眼 亲亲 咆哮 开心 想想 可怜 糗大了 委屈 哈哈 小声点 右哼哼 左哼哼 疑问 坏笑 赚钱啦 悲伤 耍酷 勾引 厉害 握手 耶 嘻嘻 害羞 鼓掌 馋嘴 抓狂 抱抱 围观 威武 给力
提交评论

清空信息
关闭评论