【龙芯1c库】龙芯1c的中断分析
封装龙芯1c上常见外设接口,便于在裸机程序或实时操作系统中使用,类似于STM32库,正在不断添加中。Git地址是https://gitee.com/caogos/OpenLoongsonLib1c
龙芯1c中断结构分析
异常和中断的区别
在MIPS体系结构中,中断、自陷、系统调用以及其它打断程序正常执行流程的事件称为异常,
即异常包括中断,中断是一种特定类型的异常。
龙芯1c的异常分为四级
第一级: 各种情况下异常的总入口
第二级:各个异常的入口,其中ExcCode=0的异常为外设中断的总入口
第三级: 外设中断的每组的总入口(龙芯1c将所有外设分为五组)
第四级: 每个外设中断的入口
第一级——各种情况下异常的总入口
异常向量间的距离缺省为128字节(0x80)。
上表中,龙芯1C的BASE为0x80000000。
异常地址BASE+0x180对应的所有其它异常(包括我们关心的中断),在linux中的源码为
void __init trap_init(void)
{
……
set_handler(0x180, &except_vec3_generic, 0x80);
……
}函数set_handler()的源码为
/* Install CPU exception handler */
void __init set_handler(unsigned long offset, void *addr, unsigned long size)
{memcpy((void *)(ebase + offset), addr, size);local_flush_icache_range(ebase + offset, ebase + offset + size);
}简单来说,就是把函数except_vec3_generic()复制到BASE+0x180开始的长度为0x80的空间内,并且还有个刷cache的操作。这和其它单片机的中断处理函数名是在汇编中指定不太一样,但实现的功能是一样的。
函数except_vec3_generic()位于genex.S中,使用汇编实现的,如下
/** General exception vector for all other CPUs.** Be careful when changing this, it has to be at most 128 bytes* to fit into space reserved for the exception handler.*/
NESTED(except_vec3_generic, 0, sp).set push.set noat
#if R5432_CP0_INTERRUPT_WARmfc0 k0, CP0_INDEX
#endifmfc0 k1, CP0_CAUSEandi k1, k1, 0x7c
#ifdef CONFIG_64BITdsll k1, k1, 1
#endifPTR_L k0, exception_handlers(k1)jr k0.set popEND(except_vec3_generic)
其中,命令mfc0 k1, CP0_CAUSEandi k1, k1, 0x7c
取协处理器0的cause寄存器中[2,6]位,即ExcCode,如下
并将ExcCode作为索引,命令
PTR_L k0, exception_handlers(k1)jr k0
跳转到对应的异常处理函数中。
exception_handlers的注册在traps.c中用函数set_except_vector()实现
void __init *set_except_vector(int n, void *addr)
{unsigned long handler = (unsigned long) addr;unsigned long old_handler = exception_handlers[n];exception_handlers[n] = handler;if (n
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
