登 录
作者:makethyme
当从arch/reset/init_platform_s.S中返回arch/reset/init.S的sys_platform_early_done之后。
sys_platform_early_done: /* from now on, we can use the display macro (if platform support it) */ bne v0, zero, error 根据返回值v0,判断sys_platform_early是否执行正确。 nop /* Determine processor */ MFC0(k1, C0_PRId) C0_PRId是CP0的register 15,即PRId, processor identification li t0, M_PRIdImp | M_PRIdCoID 构成Processor ID和Company ID的mask and k1, t0 /*** k1 now holds the ProcessorID fields ***/ 此时processor ID保存在k1中了 /* Perform CPU specific initialization */ DISP_STR(msg_cpu) 首先,在init.S下面有MSG(msg_cpu, “CPU”) 而宏MSG定义在archi/include/Init.h中,如下: #define MSG(name, s) / .##align 3; 表示以2的3次方即8对齐 name: .##ascillz s 即定义了标号为name的字符串s 宏DISP_STR定义于arch/include/Init.h中,如下: 宏DISP_STR会改变t9..t5,并且其默认platformID保存在k0中 #define DISP_STR(s); / la t9, s; / KSEG1A(t9); / move t8, ra ; / #将当前的ra保存在t8中,因为jal会破坏ra jal sys_disp_string ; / #调用sys_disp_string并且将返回地址保存#$31即ra中。子程序sys_disp_string定义在init_platform_s.S中 nop ; / move ra, t8 jal sys_init_processor 子程序sys_init_processor定义在arch/reset/init_cpu_s.S中 nop 1: bne v0, zero, error 判断调用sys_init_processor返回是否有错 如果是用于Simulate,则跳过cache init,否则调用sys_init_cache #ifndef _SIMULATE_ jal sys_init_cache 由于不打算使用M14K的Cache,故暂时先不理解这段 nop 1: bne v0, zero, error nop #endif
接上...
#define GCMP t0 bne k0, PRODUCT_MALTA_ID, noqcmp 如果不是Malta board,则跳转到nogcmp 下面代码只是适用于Malta board,先略去。。。 nogcmp: 此时Cache已经初始化完毕,故可以移动到kseg0了 la t0, 1f KSEG0A(t0) KSEG0A(reg) and reg, ~KSEG_MSK ; or reg, KSEG0BASE 将t0转换为kseg0地址;首先将其地址高3位情0,即得到相对于0的物理地址;然后加上kseg0的BASE address = 0x8000 0000 j t0 相对地址与绝对地址的问题,此时代码在kseg0中 nop 1 : /*从这儿开始后,由于运行于kseg0中,即经过了cache */ MFC0(t0, C0_Config) srl t0, S_ConfigAR andi t0, M_ConfigAR >> S_ConfigAR 通过查看Config的AR即Architecture release位,如果为7表示不支持MT即multi thread. beqz t0, notmtcapable nop /* Config1在MIPS32中是需要的*/ MFC0_SEL_OPCODE(R_t0, R_C0_Config1, R_C0_SelConfig1) 将Config1读入t0 #if S_Config1M != 31 sll t0, 31-S_Config1M #endif bgetz t0, notmtcapable /* no config2 register */高位为0,则表示没有Config2寄存器,跳转到notmtcapable nop MFC0_SEL_OPCODE(R_t0, R_C0_Config2, R_C0_SelConfig2) #if S_Config2M != 31 sll t0, 31-S_Config2M #endif bgez t0, notmtcapable 高位为0,则表示没有Config3存在,跳转的notmtcapable nop MFC0_SEL_OPCODE(R_t0, R_C0_Config3, R_C0_SelConfig3) 读取Config3的值到t0中 and t0, M_Config3MT 通过Config3查看MT ASE是否存在 beqz t0, notmtcapable 不存在,则跳转到notmtcapble nop
接上...,继续讨论arch/reset/init.S
/*如果是MultiThread,则继续下面的程序。由于M14K,不是MultiThread,故不执行,仅仅讨论一下.set伪指令*/ .set push .set mips32r2 .set mt .set <flag> sets(and clears) various flags that affect generated code. the following may not be a complete list noreorder: Turn off recording of instructions. when on, when the assembler is reordering, it wull put the last instruction before I or jr after the jump so it’ll be in the branch delay slot. when off, you’ll have to do it yourself. mips3: tells the assembler that it can use the MIPS III instructions. reorder: Allows the assembler to reorder instructions; see noreorder pop: not really a flag but restores the states of the flags to what it was before the last .set push; see push push: not really a flag but saves the status of the flags so it can be restored with .set pop. not realy useful(I think) outside inline assembly. use in pairs with .set pop ---------------------------------------------------------------------------------------------------- Directives to save and restore options The directives .set push and .set pop may be used to save and restore the current setting for all the options which are controlled by .set. The .set push directive saves the current setting on a stack. The .set pop diredtive pops the stack and restores the settings. These directives can be useful inside an macro which must change on option such as the ISA level or instruction reordering but does not want to change the state of the code which invoked the macro. Traditional MIPS assemblers do not support these directives. but it seem GNU assembler support. 比如,当前isa不是mips1,但想暂时使用mips1,用完后,不管之前什么isa都恢复原样,则: .set push .set mips1 … .set pop startmtconfig: 此处略去。。。 .set pop notmtcapable: /* MIPSCMP only core0 carries on from here everybody else waits… */ beqz v1, finish_initialisation nop
抱歉!评论已关闭.