查看64位多核 MIPS 异常和中断内核代码分析 (1)的源代码
←
64位多核 MIPS 异常和中断内核代码分析 (1)
跳转到:
导航
,
搜索
因为以下原因,你没有权限编辑本页:
您刚才请求的操作只有这个用户组中的用户才能使用:
用户
您可以查看并复制此页面的源代码:
==== Loongson 2E Cache Error ==== Cache Error 例外入口初始化,位于: <source lang=c> [arch/mips/mm/c-r4k.c] void __init r4k_cache_init() { ...... set_uncached_handler(0x100, &except_vec2_generic, 0x80); ...... } </source> 因为 cache 错误时可以 cache 的 KSEG0 段不能用了,则 cache 错误例外处理函数位于 KSEG1 之0xFFFF FFFF A000 0000 + 0x100 处,长度最大为128 Bytes(32 条指令),处理函数为 except_vec2_generic,定义于: <source lang=c> [arch/mips/mm/cex-gen.S] /* * Game over. Go to the button. Press gently. Swear where allowed by * legislation. */ LEAF(except_vec2_generic) .set noreorder .set noat .set mips0 /* * This is a very bad place to be. Our cache error * detection has triggered. If we have write-back data * in the cache, we may not be able to recover. As a * first-order desperate measure, turn off KSEG0 cacheing. */ mfc0 k0,CP0_CONFIG li k1,~CONF_CM_CMASK and k0,k0,k1 ori k0,k0,CONF_CM_UNCACHED # 改变 KSEG0 为 Uncached mtc0 k0,CP0_CONFIG /* Give it a few cycles to sink in... */ nop nop nop j cache_parity_error nop END(except_vec2_generic) </source> 发生 Cache Error 后,Cache 已不再可信,因此原 KSEG0 不能再使用 Cache,首先改变其为 Uncached,然后进入真正的处理函数 cache_parity_error: <source lang=c> [arch/mips/kernel/traps.c] asmlinkage void cache_parity_error(void) { const int field = 2 * sizeof(unsigned long); unsigned int reg_val; /* For the moment, report the problem and hang. */ printk("Cache error exception:\n"); printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); reg_val = read_c0_cacheerr(); printk("c0_cacheerr == %08x\n", reg_val); printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", reg_val & (1<<30) ? "secondary" : "primary", reg_val & (1<<31) ? "data" : "insn"); printk("Error bits: %s%s%s%s%s%s%s\n", reg_val & (1<<29) ? "ED " : "", reg_val & (1<<28) ? "ET " : "", reg_val & (1<<26) ? "EE " : "", reg_val & (1<<25) ? "EB " : "", reg_val & (1<<24) ? "EI " : "", reg_val & (1<<23) ? "E1 " : "", reg_val & (1<<22) ? "E0 " : ""); printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1)); #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) if (reg_val & (1<<22)) printk("DErrAddr0: 0x%0*lx\n", field, read_c0_derraddr0()); if (reg_val & (1<<23)) printk("DErrAddr1: 0x%0*lx\n", field, read_c0_derraddr1()); #endif panic("Can't handle the cache error!"); } </source> 事实上,当出现 Cache Error 时,系统已经没法修复,只能打出一些可供判断的信息后 panic :( 另外 set_uncached_handler 定义于: <source lang=c> [arch/mips/kernel/traps.c] /* * Install uncached CPU exception handler. * This is suitable only for the cache error exception which is the only * exception handler that is being run uncached. */ void __cpuinit set_uncached_handler(unsigned long offset, void *addr, unsigned long size) { unsigned long uncached_ebase = CKSEG1ADDR(ebase); if (!addr) panic(panic_null_cerr); memcpy((void *)(uncached_ebase + offset), addr, size); } </source> 其中 CKSEG1ADDR 的宏用于将虚址 ebase 转化为对应的 uncached 段的虚址 0xFFFF FFFF A000 0000。可以看到这个函数负责把例外处理函数 except_vec2_generic 复制到 Cache Error 例外的入口 0xFFFF FFFFF A000 0100 处,即物理地址 0x100 处
返回到
64位多核 MIPS 异常和中断内核代码分析 (1)
。
个人工具
登录
名字空间
页面
讨论
变换
查看
阅读
查看源代码
查看历史
操作
搜索
导航
首页
社区专页
新闻动态
最近更改
随机页面
帮助
工具箱
链入页面
相关更改
特殊页面