Вообщем, стартап код начинается так: Reset LDR PC, ResetAddr (1*) LDR PC, UndefinedAddr LDR PC, SWI_Addr LDR PC, PrefetchAddr LDR PC, DataAbortAddr (2*) DCD 0xb9205f80 ;DCD 0xb9206e50 LDR PC, [PC, #-0x120] ; pc <- VICVectAddr using pc relative addressing (NEW) LDR PC, FIQ_Addr
ResetAddr DCD ResetInit UndefinedAddr DCD Undefined SWI_Addr DCD SWInterrupt PrefetchAddr DCD PrefetchAbort DataAbortAddr DCD DataAbort DCD 0 IRQ_Addr DCD 0 FIQ_Addr DCD FIQ_Exception
При дебагинге через JTAG процессор переходит по адресу 1* ResetAddr. В ней происходит следующее (инициализация стэков, инициализация системной периферии и вваливание в основной код):
ResetInit BL InitStack ;Initialize the stack BL TargetResetInit ;Initialize the target board B __main ;Jump to the entry point of C program
ПРОБЛЕМА: Процессор после обработки InitStack входит в режим DataAbort и переходит по метке 2* DataAbortAddr в соответствующий обработчик, где процессор ожидает вечный цикл. При этом PC успевает перейти на метку(функцию) TargetResetInit и прямо в начале этой функции проц уходит в режим DataAbort. Последнее понятно почему - скорее всего конвееризация обработки команд. Что не так с InitStack?
InitStack MOV R0, LR ;Build the SVC stack MSR CPSR_c, #SVC32Mode LDR SP, =StackSvc (размер 64*4 слов) ;Build the IRQ stack MSR CPSR_c, #IRQ32Mode LDR SP, =StackIrq (размер 256*4 слов) ;Build the FIQ stack MSR CPSR_c, #FIQ32Mode LDR SP, =StackFiq (размер 64*4 слов) ;Build the DATAABORT stack MSR CPSR_c, #ABT32Mode LDR SP, =StackAbt (размер 64*4 слов) ;Build the UDF stack MSR CPSR_c, #UDF32Mode LDR SP, =StackUnd (размер 64*4 слов) ;Build the SYS stack MSR CPSR_c, #SYS32Mode LDR SP, =StackUsr (размер 1024*4 слов) !!!!!!!!!!!!!!!! <- может слишком большой?
MOV PC, R0
|