免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7738 | 回复: 13
打印 上一主题 下一主题

[中断] arm中断异常时cpsr显示都是svc模式? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-07-11 09:11 |只看该作者 |倒序浏览
有个疑问,
在中断处理中,打印cpsr发现mode=0x13 处于svc mode。
data abort处理中,打印cpsr发现mode=0x13
看来kernel只用了user mode和svc mode。

1. 如果是这样的,那么怎样实现只用两种mode的呢?
2. 如果是这样的,那么中断异常处理中(从usr mode到svc mode), sp是从usr sp自动切换到svc sp的,硬件自动处理吗,从文档上没有看到相关部分。


论坛徽章:
10
戌狗
日期:2013-10-17 09:43:0215-16赛季CBA联赛之广东
日期:2018-02-05 11:22:1215-16赛季CBA联赛之八一
日期:2016-07-04 12:26:1815-16赛季CBA联赛之青岛
日期:2016-06-08 11:15:4115-16赛季CBA联赛之辽宁
日期:2016-04-05 10:10:1415-16赛季CBA联赛之辽宁
日期:2016-03-11 11:11:48酉鸡
日期:2014-12-18 14:35:48狮子座
日期:2014-02-20 10:14:07寅虎
日期:2013-12-02 13:48:2915-16赛季CBA联赛之广夏
日期:2018-03-21 08:51:10
2 [报告]
发表于 2013-07-11 10:36 |只看该作者
blake326 发表于 2013-07-11 09:11
有个疑问,
在中断处理中,打印cpsr发现mode=0x13 处于svc mode。
data abort处理中,打印cpsr发现mode=0 ...

个人认为,有内核态,用户态就够用了。
对于异常和中断,应该有不同。通常中断由硬件处理,异常就不一定。异常/系统调用只是提供从用户态到内核态的方法,可以软件具体实现。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
3 [报告]
发表于 2013-07-18 21:32 |只看该作者
中断异常时是切换到了svc模式下去处理的

在irq模式下,只是将lr r0 spsr入栈,irq模式的栈size只有3个word,刚好够放这三个寄存器
然后将irq模式的栈基地址填到r0中,然后切换到svc模式
在svc模式下通过r0就可以取出lr r0 spsr,然后将lr和r0和r1-sp都压入svc模式的栈(此时是借用的被中断的线程的栈),将spsr写入svc模式的spsr
然后就进行中断处理
处理完之后,就可以直接从svc模式返回到发生中断之前的模式

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
4 [报告]
发表于 2013-07-19 02:50 |只看该作者
回复 2# daniel_11


    嵌套中断的要求:

论坛徽章:
0
5 [报告]
发表于 2013-07-19 13:03 |只看该作者
回复 3# arm-linux-gcc

》》》》》》》》》》》
    然后将irq模式的栈基地址填到r0中,然后切换到svc模式
》》》》》》》》》》

你的意思是发生中断后,会进入irq模式,然后保存了r0,lr,spsr之后,kernel就立刻切换到了svc模式?那么这个切换的动作在哪里的,svc_entry? 我看代码没有找到这个动作。

论坛徽章:
0
6 [报告]
发表于 2013-07-19 13:07 |只看该作者
回复 4# smalloc


    那么你的意思是在中断处理中,arm处于irq mode吗?
    但是我打出来的都是arm处于svc mode,不过我的板子用了vlx虚拟机,可能有影响。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
7 [报告]
发表于 2013-07-19 18:29 |只看该作者
本帖最后由 arm-linux-gcc 于 2013-07-19 18:55 编辑

回复 6# blake326

从irq到svc的切换过程如下:

        .macro        vector_stub, name, mode, correction=0
        .align        5

vector_\name:
        .if \correction
        sub        lr, lr, #\correction
        .endif

        @
        @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
        @ (parent CPSR)
        @
        stmia        sp, {r0, lr}                @ save r0, lr
        mrs        lr, spsr
        str        lr, [sp, #8]                @ save spsr

        @
        @ Prepare for SVC32 mode.  IRQs remain disabled.
        @
        mrs        r0, cpsr
        eor        r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)         
        msr        spsr_cxsf, r0
以上3句是将spsr中的模式位改为svc,注意这里只是修改了irq的spsr,还未切换状态

        @
        @ the branch table must immediately follow this code
        @
        and        lr, lr, #0x0f                    取出spsr中的[M3:M0],这里不用取M4,因为M4是表示26位还是32位寻址的,如果只想知道模式的话,取[M3:M0]就够了
THUMB(        adr        r0, 1f                        )
THUMB(        ldr        lr, [r0, lr, lsl #2]        )
        mov        r0, sp                            将irq模式的栈基地址填到r0,以后在svc_entry中可以通过r0去读取irq的栈
ARM(        ldr        lr, [pc, lr, lsl #2]        )         直接将[M3:M0]乘以4再加上pc就可以计算出入口(因为一个entry占4个字节),结果为__irq_usr或__irq_svc,具体是usr还是svc要看发生中断之前是什么模式
        movs        pc, lr                        @ branch to handler in SVC mode        跳进入口(__irq_usr或__irq_svc),同时做模式切换(mov带了s,就会给pc赋值的同时将用spsr去填cpsr)
ENDPROC(vector_\name)


        vector_stub        irq, IRQ_MODE, 4                        宏vector_\name展开,展开之后的结果,使得上述 ARM(ldr lr,[pc,lr,lsl #2])处的pc值就是下面的.long        __irq_usr处的地址

        .long        __irq_usr                        @  0  (USR_26 / USR_32)           [M3:M0]为0
        .long        __irq_invalid                        @  1  (FIQ_26 / FIQ_32)
        .long        __irq_invalid                        @  2  (IRQ_26 / IRQ_32)
        .long        __irq_svc                        @  3  (SVC_26 / SVC_32)           [M3:M0]为3
        .long        __irq_invalid                        @  4
        .long        __irq_invalid                        @  5
        .long        __irq_invalid                        @  6
        .long        __irq_invalid                        @  7
        .long        __irq_invalid                        @  8
        .long        __irq_invalid                        @  9
        .long        __irq_invalid                        @  a
        .long        __irq_invalid                        @  b
        .long        __irq_invalid                        @  c
        .long        __irq_invalid                        @  d
        .long        __irq_invalid                        @  e
        .long        __irq_invalid                        @  f
其中一些是占位符,这里刚好16个,对应了[M3:M0]的所有可能取值,所以entry的地址就可以用[M3:M0]很快的算出来,之所以弄16个entry,是因为[M3:M0]在各种模式的取值中并不是连续的


你在svc_entry是看不到模式切换的,因为在进入svc_entry之前就已经做了,你可以去直接看irq的栈,可以查看以下数据结构
arch/arm/kernel/setup.c,他们分别是irq abt und模式的栈
struct stack {
        u32 irq[3];
        u32 abt[3];
        u32 und[3];
} ____cacheline_aligned;




写的挺乱的,不知道说清楚没,向来不善于写这类东西


论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
8 [报告]
发表于 2013-07-19 18:59 |只看该作者
本帖最后由 arm-linux-gcc 于 2013-07-19 18:59 编辑

另贴一个CPSR的模式位以便对比看


M4 M3 M2 M1 M0
0   0   0   0   0     User26 模式
0   0   0   0   1     FIQ26 模式
0   0   0   1   0     IRQ26 模式
0   0   0   1   1     SVC26 模式
1   0   0   0   0     User 模式
1   0   0   0   1     FIQ 模式
1   0   0   1   0     IRQ 模式
1   0   0   1   1     SVC 模式
1   0   1   1   1     ABT 模式
1   1   0   1   1     UND 模式

论坛徽章:
0
9 [报告]
发表于 2013-07-19 19:47 |只看该作者
回复 7# arm-linux-gcc

》》》》》》
          movs        pc, lr                        @ branch to handler in SVC mode   


谢谢。这段代码我也看过几遍,原来是在这句切到svc mode的。没有注意到 movs指令。

论坛徽章:
46
2015小元宵徽章
日期:2015-03-06 15:58:18羊年新春福章
日期:2015-04-14 10:37:422015年亚洲杯之阿曼
日期:2015-04-14 10:41:50NBA常规赛纪念章
日期:2015-05-04 22:32:03NBA季后赛大富翁
日期:2015-05-04 22:34:11菠菜明灯
日期:2015-05-04 22:35:49新奥尔良黄蜂
日期:2015-05-04 22:49:2315-16赛季CBA联赛之广夏
日期:2015-12-11 15:02:342015年亚洲杯之巴勒斯坦
日期:2015-03-04 19:56:562015年亚洲杯之阿联酋
日期:2015-03-04 11:19:04休斯顿火箭
日期:2015-03-02 16:32:11纽约尼克斯
日期:2015-03-02 16:09:04
10 [报告]
发表于 2014-05-30 17:21 |只看该作者
为何irq模式的栈只有3个word,irq的sp是在哪赋值的?多谢
回复 3# arm-linux-gcc


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP