快乐虾
http://blog.csdn.net/lights_joy/
lights@hb165.com
本文适用于
ADI bf561 DSP
uclinux-2008r1.5-rc3 ( 移植到 vdsp5)
Visual DSP++ 5.0(update 5)
欢迎转载,但请保留作者信息
/* This section keeps the processor in supervisor mode
* during kernel boot. Switches to user mode at end of boot.
* See page 3-9 of Hardware Reference manual for documentation.
*/
/* EVT15 = _real_start */
p0.l = lo(EVT15);
p0.h = hi(EVT15);
p1.l = _real_start;
p1.h = _real_start;
[p0] = p1;
csync;
p0.l = lo(IMASK);
p0.h = hi(IMASK);
p1.l = IMASK_IVG15;
p1.h = 0x0;
[p0] = p1;
csync;
raise 15;
p0.l = .LWAIT_HERE;
p0.h = .LWAIT_HERE;
reti = p0;
#if ANOMALY_05000281
nop; nop; nop;
#endif
rti;
.LWAIT_HERE:
jump .LWAIT_HERE;
ENDPROC(__start)
这段代码设置了 EVT15 的入口,打开中断 15 的掩码,然后直接使用一个软中断,这样在 rti 之后将跳转到 _real_start 开始执行。这么做的原因在 Hardware Reference manual 中说明,看看到底是么回事:
For non-OS environments, application code should remain in Supervisor mode so that it can access all core and system resources. When RESET is de-asserted, the processor initiates operation by servicing the reset event. Emulation is the only event that can pre-empt this activity. Therefore, lower priority events cannot be processed.
One way of keeping the processor in Supervisor mode and still allowing lower priority events to be processed is to set up and force the lowest priority interrupt ( IVG15 ). Events and interrupts are described further in "Events and Sequencing" on another page . After the low priority interrupt has been forced using the RAISE15 instruction, RETI can be loaded with a return address that points to user code that can execute until IVG15 is issued. After RETI has been loaded, the RTI instruction can be issued to return from the reset event.
The interrupt handler for IVG15 can be set to jump to the application code starting address. An additional RTI is not required. As a result, the processor remains in Supervisor mode because IPEND[15] remains set. At this point, the processor is servicing the lowest priority interrupt. This ensures that higher priority interrupts can be processed.
要理解这段话,先得理解 561 内核的几种模式及其转换:
在 dsp 复位后,实际处于 RESET 的状态,所执行的第一行代码实际是做为 reset 中断服务例程来运行的,因此在最后使用了一个 rti 语句结束此中断服务程序,此时将进入 user 模式,由于在 rti 之前设置了 reti 寄存器的值, pc 将进入 .LWAIT_HERE 的这个死循环。又由于之前使用了 raise 15 触发了一个软中断,因此进入中断 15 的服务程序,即 _real_start 。
在使用 u-boot 引导的时候,由于同样的原因, u-boot 的主循环一直是在中断 15 的服务程序中的,引导内核时同样处于这种状态,此时 rti 退出的将是 u-boot 的那个中断服务。
1 参考资料
head.s 分析 (1) :保存 u-boot 传递过来的指针 (2009-1-19)
head.s 分析 (2) : SYSCFG 配置 (2009-1-19)
head.s 分析 (3) :数据及指针寄存器清 0 (2009-1-19)
head.s 分析 (4) :关闭 CACHE (2009-01-19)
head.s 分析 (5) :关闭串口 (2009-01-19)
head.s 分析 (6) :栈指针初始化 (2009-01-19)
head.s 分析 (7) : init_early_exception_vectors (2009-1-19)
head.s 分析 (8) :配置 PLL 及 SDRAM (2009-01-20)
head.s 分析 (9) : EBIU 配置 (2009-01-20)