mips_linux中断与异常(转)
来源:互联网 发布:新网域名管理登录 编辑:程序博客网 时间:2024/06/05 22:43
1. 中断
中断/异常入口基址ebase设置并不在0x80000000,而是其它地址。
中断配制成矢量模式,vector offset配置成0x100。Int0~int7(int0/int1:sw;int2~int7:hw;int7-count/compare)
Ebase:0x8045f000;Int0 entry:0x8045f200;Int2 entry:0x8045f200+(2*0x100)
a) 矢量中断入口注册
set_vi_handler(2, mips_int2_handler);
void *set_vi_handler(int n, vi_handler_t addr)
{
return set_vi_srs_handler(n, addr, 0);
}
static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
{
extern char except_vec_vi, except_vec_vi_lui;
extern char except_vec_vi_ori, except_vec_vi_end;
extern char rollback_except_vec_vi;
char *vec_start = (cpu_wait == r4k_wait) ?
&rollback_except_vec_vi : &except_vec_vi;
const int handler_len = &except_vec_vi_end - vec_start;
const int lui_offset = &except_vec_vi_lui - vec_start;
const int ori_offset = &except_vec_vi_ori - vec_start;
if (handler_len > VECTORSPACING) {
/*
* Sigh... panicing won't help as the console
* is probably not configured :(
*/
panic("VECTORSPACING too small");
}
memcpy(b, vec_start, handler_len); //拷贝一段公用的中断处理入口代码片段
w = (u32 *)(b + lui_offset); //修改中断处理函数的地址
*w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff);
w = (u32 *)(b + ori_offset); //修改中断处理函数的地址
*w = (*w & 0xffff0000) | ((u32)handler & 0xffff);
local_flush_icache_range((unsigned long)b,
(unsigned long)(b+handler_len)); //刷icache
}
b) 中断处理服务程序注册
setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
setup_irq(MIPS_CPU_IRQ_BASE + 3, &dma_irqaction);
setup_irq(ASOC_IRQ_BASE + DMA_INT, &cascade_irqaction);
setup_irq(ASOC_IRQ_BASE + PC_INT, &cascade_irqaction);
#define IRQ_TIMER0 (ASOC_IRQ_BASE+10) //对应irq分配策略
request_irq(IRQ_TIMER0, mips_timer_interrupt, 0, "timer", (void *)0);
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
{
…
setup_irq(irq, action);
…
}
c) setup_irq的参数irq与irq分配策略有关。
原则上是任意一个硬件中断源可以随意配置到任意一个中断信号上(int0~int7)。每一个中断信号上也都可以挂多个中断源。从实现和效率角度看,将一些优先级高的中断源独立的挂在一个中断信号上,其它都挂载一个公用的中断上是比较合理的。下图是一种分配方式。
d) 中断服务程序执行流程
Int2_handler
8045f400: 401a7000 mfc0 k0,c0_epc
8045f404: 3c1b8010 lui k1,0x8010
8045f408: 277b0640 addiu k1,k1,1600
8045f40c: 375a001f ori k0,k0,0x1f
8045f410: 3b5a001f xori k0,k0,0x1f
8045f414: 175b0002 bne k0,k1,8045f420
8045f418: 00000000 nop
8045f41c: 409a7000 mtc0 k0,c0_epc
8045f420: 401a6000 mfc0 k0,c0_status
8045f424: 001ad0c0 sll k0,k0,0x3
8045f428: 07400003 bltz k0,8045f438
8045f42c: 03a0d821 move k1,sp
8045f430: 3c1b8041 lui k1,0x8041
8045f434: 8f7be938 lw k1,-5832(k1)
8045f438: 03a0d021 move k0,sp
8045f43c: 277dff50 addiu sp,k1,-176
8045f440: afba008c sw k0,140(sp)
8045f444: afa30024 sw v1,36(sp)
8045f448: afa00018 sw zero,24(sp)
8045f44c: 40036000 mfc0 v1,c0_status
8045f450: afa20020 sw v0,32(sp)
8045f454: afa30098 sw v1,152(sp)
8045f458: afa40028 sw a0,40(sp)
8045f45c: 40036800 mfc0 v1,c0_cause
8045f460: afa5002c sw a1,44(sp)
8045f464: afa300a8 sw v1,168(sp)
8045f468: afa60030 sw a2,48(sp)
8045f46c: 40037000 mfc0 v1,c0_epc
8045f470: afa70034 sw a3,52(sp)
8045f474: afa300ac sw v1,172(sp)
8045f478: afb9007c sw t9,124(sp)
8045f47c: afbc0088 sw gp,136(sp)
8045f480: afbf0094 sw ra,148(sp)
8045f484: 37bc1fff ori gp,sp,0x1fff
8045f488: 3b9c1fff xori gp,gp,0x1fff
8045f48c: afa1001c sw at,28(sp)
8045f490: 3c028010 lui v0,0x8010 //对应set_vi_srs_handler中的地址修改(lui)
8045f494: 0804020d j 80100834 // except_vec_vi_handler
8045f498: 34428278 ori v0,v0,0x8278 //对应set_vi_srs_handler中的地址修改(ori)
except_vec_vi_handler
NESTED(except_vec_vi_handler, 0, sp)
SAVE_TEMP
SAVE_STATIC
CLI
LONG_L s0, TI_REGS($28)
LONG_S sp, TI_REGS($28)
PTR_LA ra, ret_from_irq //中断总出口
jr v0 // mips_int2_handler
END(except_vec_vi_handler)
asmlinkage void mips_int2_handler(void)
{
xxx_irqdispatch();
}
static void xxx_irqdispatch(void)
{
int irq;
u32 intc0_pending = readl(IC0_PD);
u32 intc0_mask = readl(IC0_MASK);
u32 intc0_req0 = intc0_pending & intc0_mask;
u32 intc0_ext_int = 0;
if (!intc0_req0) {
spurious_interrupt();
goto exit;
}
irq = ffs(intc0_req0) - 1;
if (irq != EXTERNAL_INT){
do_IRQ(ASOC_IRQ_BASE + irq); //对应irq分配策略
goto exit;
}
else
{
…
}
exit:
return;
}
2. 异常
a) tlb_refill
8045f000: 3c1b8041 lui k1,0x8041
8045f004: 401a4000 mfc0 k0,c0_badvaddr
8045f008: 8f7b3000 lw k1,12288(k1) //pgd_current
8045f00c: 001ad582 srl k0,k0,0x16
8045f010: 001ad080 sll k0,k0,0x2
8045f014: 037ad821 addu k1,k1,k0
8045f018: 401a2000 mfc0 k0,c0_context
8045f01c: 8f7b0000 lw k1,0(k1)
8045f020: 001ad042 srl k0,k0,0x1
8045f024: 335a0ff8 andi k0,k0,0xff8
8045f028: 037ad821 addu k1,k1,k0
8045f02c: 8f7a0000 lw k0,0(k1)
8045f030: 8f7b0004 lw k1,4(k1)
8045f034: 001ad182 srl k0,k0,0x6
8045f038: 409a1000 mtc0 k0,c0_entrylo0
8045f03c: 001bd982 srl k1,k1,0x6
8045f040: 409b1800 mtc0 k1,c0_entrylo1
8045f044: 000000c0 ehb
8045f048: 42000006 tlbwr
8045f04c: 42000018 eret
8045f050: 00000000 nop
b) general_exception
8045f180: 401b6800 mfc0 k1,c0_cause
8045f184: 337b007c andi k1,k1,0x7c
8045f188: 3c1a8041 lui k0,0x8041
8045f18c: 035bd021 addu k0,k0,k1
8045f190: 8f5aeac0 lw k0,-5440(k0) //exception_handlers[i]
8045f194: 03400008 jr k0
8045f198: 00000000 nop
c) 设置异常处理函数入口
void *set_except_vector(int n, void *addr)
set_except_vector(0, rollback ? rollback_handle_int : handle_int);
set_except_vector(1, handle_tlbm);
set_except_vector(2, handle_tlbl);
set_except_vector(3, handle_tlbs);
set_except_vector(4, handle_adel);
set_except_vector(5, handle_ades);
set_except_vector(6, handle_ibe);
set_except_vector(7, handle_dbe);
set_except_vector(8, handle_sys);
set_except_vector(9, handle_bp);
set_except_vector(10, rdhwr_noopt ? handle_ri :(cpu_has_vtag_icache ? handle_ri_rdhwr_vivt : handle_ri_rdhwr));
set_except_vector(11, handle_cpu);
set_except_vector(12, handle_ov);
set_except_vector(13, handle_tr);
set_except_vector(14, handle_mc);
set_except_vector(15, handle_ndc);
set_except_vector(15, handle_fpe);
set_except_vector(22, handle_mdmx);
set_except_vector(24, handle_mcheck);
set_except_vector(25, handle_mt);
set_except_vector(26, handle_dsp);
- mips_linux中断与异常(转)
- 中断分类(异常 与 中断)
- 中断与异常(一)
- linux中断(与异常)处理过程
- 操作系统的中断与异常(陷阱)
- 中断与异常详解(一)
- 中断与异常详解(二)
- 中断与异常详解(三)
- 中断与异常详解(四)
- 中断与异常详解(五)
- [嵌入式]异常与中断(上)
- 中断与异常
- 3.中断与异常
- ARM异常与中断
- 中断与异常
- 关于中断与异常
- 中断与异常处理
- ARM7异常与中断
- 执行netca或dbca时UnsatisfiedLinkError exception loading native library: njni10错误解决
- 网线的直连线与交叉线之间的区别
- Android 学习笔记(一)
- 网页实现pdf在线阅读------纯属自己测试总结
- 博客
- mips_linux中断与异常(转)
- 寄我的第一台笔记本电脑
- 从Long.ValueOf("String")与Long.parseLong("String")看JAVA包装类的封箱与拆箱
- VC控件自绘制
- TP-Link wr340g+无法拨号问题
- MySQL辅助库文件
- detached entity passed to persist
- 不使用临时变量交换两个变量的值
- 关于 LoadLibrary 的疑问