【干货分享】 MPSoC的芯片启动流程

作者:付汉杰,hankf@xilinx.com,文章转载自:赛灵思中文社区论坛

MPSoC A53执行的第一条代码定义在BSP工程的目录\psu_cortexa53_0\libsrc\standalone_v7_0\src\asm_vectors.S里。

去掉Xen相关代码后,简化如下:

.org 0

.section .vectors, "a"

_vector_table:
.set	VBAR, _vector_table
.org VBAR

	b	_boot
.org (VBAR + 0x200)
	b	SynchronousInterruptHandler

.org (VBAR + 0x280)
	b	IRQInterruptHandler

.org (VBAR + 0x300)
	b	FIQInterruptHandler

.org (VBAR + 0x380)
	b	SErrorInterruptHandler

上述代码的地址,由《ARM® Architecture Reference Manual,ARMv8, for ARMv8-A architecture profile》(ARM DDI 0487C)定义,可以参考Table D1-7 Vector offsets from vector table base address。

EL0的Synchronous offset是0x0。其他EL级别,Synchronous offset是0x200,IRQ or vIRQ offset是0x280, FIQ or vFIQ offset是0x300, SError or vSError offset是0x380,
MPSoC A53启动后,在EL0,执行的第一条代码是“b _boot”。

符号_boot的定义在BSP工程的目录\psu_cortexa53_0\libsrc\standalone_v7_0\src\boot.S里。简化后的代码如下。

/* this initializes the various processor modes */
_prestart:
_boot:
	mov      x0, #0
... ...
	mov      x30, #0
#if 0 //dont put other a53 cpus in wfi
   //Which core am I
   // ----------------
	mrs      x0, MPIDR_EL1
	and      x0, x0, #0xFF                        //Mask off to leave Aff0
	cbz      x0, OKToRun                          //If core 0, run the primary init code
EndlessLoop0:
	wfi
	b        EndlessLoop0
#endif
OKToRun:

	mrs	x0, currentEL
	cmp	x0, #0xC
	beq	InitEL3

	cmp	x0, #0x4
	beq	InitEL1

	b 	error			// go to error if current exception level is neither EL3 nor EL1

InitEL3/InitEL1会设置reset vector address,Invalidate cache,设置stack pointer。
执行上述代码后,会执行“bl _startup”。

符号_startup的定义在BSP工程的目录\psu_cortexa53_0\libsrc\standalone_v7_0\src\xil-crt0.S里。符号_startup先清除SBSS和BSS段,然后运行global constructors,再跳到C语言的定义在文件xfsbl_main.c里的入口函数main。

FSBL的main()里的调用关系是XFsbl_Initialize()->XFsbl_SystemInit()->XFsbl_HookPsuInit()->psu_init().。

psu_init由Vivado导出,含有芯片的管脚、pll、DDR初始化,主要代码如下。

psu_init(void)
{
	status &= psu_mio_init_data();
	status &=   psu_pll_init_data();
	status &=   psu_clock_init_data();
	status &=  psu_ddr_init_data();
	status &=  psu_ddr_phybringup_data();
	status &=  psu_peripherals_init_data();
	status &=  init_serdes();
	init_peripheral();
	
	status &=  psu_peripherals_powerdwn_data();
	status &=    psu_afi_config();
}

上述流程,可以在SDK里双击应用程序的ELF文件,查看应用程序的反汇编文件确认。

最新文章

最新文章