- 论坛徽章:
- 0
|
有一点必须明确:
arm的R13是bank register,arm的七种处理器模式有各自的R13(user模式和system模式共用一个,总共六个不同的R13),也就是arm汇编默认的SP(堆栈指针),就是说一旦产生了模式切换(IRQ,FIQ,异常等), 接着的代码就使用模式对应的SP.
linux2.6.14源代码中对arm fiq几乎没有处理,因此所有用到FIQ的代码都必须自己实现.
从你的代码看,你用到了FIQ的SP(R13_fiq),不知道你在系统初始化的时候有没有对FIQ的SP初始化,如果没有,则肯定要出问题的.
arm\kernel\setup.c中对用到的IRQ, ABT, UND模式的SP都作了初始化,但FIQ没有
struct stack {
u32 irq[3];
u32 abt[3];
u32 und[3];
} ____cacheline_aligned;
void cpu_init(void)
{
unsigned int cpu = smp_processor_id();
struct stack *stk = &stacks[cpu];
if (cpu >= NR_CPUS) {
printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
BUG();
}
if (system_state == SYSTEM_BOOTING)
dump_cpu_info(cpu);
/*
* setup stacks for re-entrant exception handlers
*/
__asm__ (
"msr cpsr_c, %1\n\t" //切换到IRQ_MODE
"add sp, %0, %2\n\t" //设置r13_irq,此时sp是r13_irq
"msr cpsr_c, %3\n\t" //切换到ABT_MODE
"add sp, %0, %4\n\t" //设置r13_abt,此时sp是r13_abt
"msr cpsr_c, %5\n\t" //切换到UND_MODE
"add sp, %0, %6\n\t" //设置r13_und,此时sp是r13_und
"msr cpsr_c, %7" //切换回SVC_MODE
:
: "r" (stk),
"I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
"I" (offsetof(struct stack, irq[0])),
"I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
"I" (offsetof(struct stack, abt[0])),
"I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
"I" (offsetof(struct stack, und[0])),
"I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
: "r14");
}
你应该在此处对FIQ做相应的SP初始化
可以看到,IRQ, ABT, UND模式的堆栈大小都只有3个int,
你可能会问,进入这三个模式后, 怎么保存大量的寄存器?
呵呵,进入这三种模式后,linux会把模式切换到SVC_MODE,使用的是SVC_MODE的堆栈.
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 //R13_<mode>保存两个int
mrs lr, spsr
str lr, [sp, #8] @ save spsr //R13_<mode>再保存一个int
@
@ Prepare for SVC32 mode. IRQs remain disabled.
@
mrs r0, cpsr
eor r0, r0, #(\mode ^ SVC_MODE) //切换到SVC,之后的堆栈操作都用R13_svc,sp都是R13_svc的值
msr spsr_cxsf, r0
@
@ the branch table must immediately follow this code
@
and lr, lr, #0x0f
mov r0, sp
ldr lr, [pc, lr, lsl #2]
movs pc, lr @ branch to handler in SVC mode
.endm
具体FIQ的堆栈怎么处理就看你怎么实现了.
[ 本帖最后由 readkernel 于 2009-12-26 14:08 编辑 ] |
|