📄 boot-sa1100.s
字号:
/****************************************************************************//* Copyright 2000 Compaq Computer Corporation. *//* . *//* Copying or modifying this code for any purpose is permitted, *//* provided that this copyright notice is preserved in its entirety *//* in all copies or modifications. COMPAQ COMPUTER CORPORATION *//* MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, AS TO THE USEFULNESS *//* OR CORRECTNESS OF THIS CODE OR ITS FITNESS FOR ANY PARTICULAR *//* PURPOSE. *//****************************************************************************//* ;; boot.s ;; Compaq Personal Server Monitor Boot Code ;; ;; Copyright 1999 Compaq Computer Corporation ;; All Rights Reserved ;; ;; ;; ;; This code is a very minimalist loader -- it jumps straight to ;; main() after initalizing SDRAM,PCI,and the UART. ;; boot.s from the Digital StrongARM uHAL provided inspiration for ;; this loader.*/ #ifdef __NetBSD__#include <arm32/asm.h>#else#define __ASSEMBLY__ #include <linux/linkage.h>#define ASENTRY(x_) ENTRY(x_) #define _C_FUNC(x_) (/**/x_/**/)#endif#include "bootconfig.h"#if 0#include <asm/arch-sa1100/hardware.h>#endif #include "sa1100.h" /*; *************************/ /*; Start of executable code*/ /*; *************************/ASENTRY(_start) ENTRY(ResetEntryPoint) /* 0x00: */ b HiReset /* 0x04: */ UndefEntryPoint: b HandleUndef /* 0x08: */ SWIEntryPoint: b HandleSWI /* 0x0c: */ PrefetchAbortEntryPoint: b HandlePrefetchAbort /* 0x10: */ DataAbortEntryPoint: b HandleDataAbort /* 0x14: */ NotUsedEntryPoint: b HandleNotUsed/* 0x18: */ IRQEntryPoint: b HandleIRQ /* 0x1c: */ FIQEntryPoint: b HandleFIQ /* 0x20: */ .long BOOTLDR_MAGIC /* magic number so we can verify that we only put bootldr's into flash in the bootldr region *//* 0x24: */ .long BOOTLDR_VERSION/* 0x28: */ .long _start /* where this bootldr was linked, so we can put it in memory in the right place */HandleUndef: /* save all user registers */ adr r13, AbortStorage stm r13, {r0-r12} mov r12, r14 bl EnableUart3Transceiver ldr r0,STR_UNDEF ldr r1,Ser3Base BL PrintWord mov r0, r12 ldr r1,Ser3Base BL PrintHexWord mrc p15, 0, r0, c6, c0, 0 /* fault address */ ldr r1,Ser3Base BL PrintHexWord mov r14, r12 /* restore registers */ ldm r13, {r0-r12} /* now loop */1: b 1b HandleSWI: /* save all user registers */ adr r13, AbortStorage stm r13, {r0-r12} mov r12, r14 bl EnableUart3Transceiver ldr r0,STR_SWI ldr r1,Ser3Base BL PrintWord mov r0, r12 ldr r1,Ser3Base BL PrintHexWord mrc p15, 0, r0, c6, c0, 0 /* fault address */ ldr r1,Ser3Base BL PrintHexWord mov r14, r12 /* restore registers */ ldm r13, {r0-r12} /* now loop */1: b 1b HandlePrefetchAbort: /* save all user registers */ adr r13, AbortStorage stm r13, {r0-r12} mov r12, r14 bl EnableUart3Transceiver ldr r0,STR_PREFETCH_ABORT ldr r1,Ser3Base BL PrintWord mov r0, r12 ldr r1,Ser3Base BL PrintHexWord mrc p15, 0, r0, c6, c0, 0 /* fault address */ ldr r1,Ser3Base BL PrintHexWord mov r14, r12 /* restore registers */ ldm r13, {r0-r12} /* now loop */1: b 1b AbortStorage: .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 .word 0 HandleDataAbort: /* save all user registers */ adr r13, AbortStorage stm r13, {r0-r12} mov r12, r14 bl EnableUart3Transceiver ldr r0,STR_DATA_ABORT ldr r1,Ser3Base BL PrintWord mov r0, r12 ldr r1,Ser3Base BL PrintHexWord mrc p15, 0, r0, c6, c0, 0 /* fault address */ ldr r1,Ser3Base BL PrintHexWord mov r14, r12 /* restore registers */ ldm r13, {r0-r12} /* now loop */1: b 1bHandleIRQ: /* save all user registers */ adr r13, AbortStorage stm r13, {r0-r12} mov r12, r14 bl EnableUart3Transceiver ldr r0,STR_IRQ ldr r1,Ser3Base BL PrintWord mov r0, r12 ldr r1,Ser3Base BL PrintHexWord mov r14, r12 /* restore registers */ ldm r13, {r0-r12} /* now loop */1: b 1b HandleFIQ: /* save all user registers */ adr r13, AbortStorage stm r13, {r0-r12} mov r12, r14 bl EnableUart3Transceiver ldr r0,STR_FIQ ldr r1,Ser3Base BL PrintWord mov r0, r12 ldr r1,Ser3Base BL PrintHexWord mov r14, r12 /* restore registers */ ldm r13, {r0-r12} /* now loop */1: b 1b HandleNotUsed: /* save all user registers */ adr r13, AbortStorage stm r13, {r0-r12} mov r12, r14 bl EnableUart3Transceiver ldr r0,STR_NOT_USED ldr r1,Ser3Base BL PrintWord mov r0, r12 ldr r1,Ser3Base BL PrintHexWord mov r14, r12 /* restore registers */ ldm r13, {r0-r12} /* now loop */1: b 1b ASENTRY(WaitForInput) ldr r1,Ser3Base1: ldr r2,[r1,#SA1100_UTSR1] tst r2,#SA1100_UTSR1_RNE beq 1b mov pc, lr ConsumeInput: ldr r1,Ser3Base ldr r2,[r1,#SA1100_UTDR] ldr r0,[r1,#SA1100_UTSR1] tst r0,#SA1100_UTSR1_RNE bne ConsumeInput HiReset: /* disable all interrupts */ ldr r1, SA1100_ICMR_ADDRESS mov r0, #0 str r0, [r1, #0] #ifdef MODIFY_CPSR # put us in the right frame of mind ... msr cpsr_c, #(F_BIT | I_BIT | SVC_MODE)#endif /* set clock speed to 191.7MHz */ ldr r1, SA1100_PPCR_ADDRESS mov r0, #SA1100_PPCR_191MHZ str r0, [r1, #0] /* make sure TX fifo is empty by printing a character */ mov r1, #0 ldr r1, Ser3Base bl PrintChar /*; Initialize the UARTs */ bl InitUART1 bl InitUART3 bl EnableUart3Transceiver mov r0, #'\r' ldr r1, Ser3Base bl PrintChar mov r0, #'\n' ldr r1, Ser3Base bl PrintChar mov r0, #'@' ldr r1, Ser3Base bl PrintChar mov r0, pc ldr r1, Ser3Base bl PrintHexWord/* check to see if we're operating out of DRAM */ bic r4, pc, #0x000000FF bic r4, r4, #0x0000FF00 bic r4, r4, #0x00FF0000 cmp r4, #DRAM_BASE0 bne RunningInFlash RunningInDRAM: mov r0, #'D' ldr r1, Ser3Base bl PrintChar b 22f RunningInFlash: mov r0, #'F' ldr r1, Ser3Base bl PrintChar /* otherwise, assume we're running in Flash and do a complete reset *//*; Initialize SDRAM and Flash*/ bl InitMem/*; debug print*/ mov r0,#'\r' ldr r1, Ser3Base bl PrintChar mov r0,#'\n' ldr r1, Ser3Base bl PrintChar mov r0,#'*' ldr r1, Ser3Base bl PrintChar ldr r0, STR_MTST ldr r1, Ser3Base bl PrintWordTestDramBank0: /* some test code */ mov r5, #DRAM_BASE0 mov r6, #0x00000001TestDramBank0Loop: mov r0, r6 str r0, [r5, #48] ldr r0, [r5, #48] ldr r1, Ser3Base bl PrintHexWord tst r6, #0x80000000 bne TestDramBank0Done mov r6, r6, lsl #1 b TestDramBank0LoopTestDramBank0Done: #ifdef CONFIG_DRAM_BANK2 ldr r0, STR_MB2 ldr r1, Ser3Base bl PrintWord mov r5, #DRAM_BASE1 mov r6, #0x00000001TestDramBank1Loop: mov r0, r6 ldr r1, Ser3Base bl PrintHexWord mov r0, r6 str r0, [r5, #48] ldr r0, [r5, #48] ldr r1, Ser3Base bl PrintHexWord tst r6, #0x80000000 bne TestDramBank1Done mov r6, r6, lsl #1 b TestDramBank1LoopTestDramBank1Done:#endif /* CONFIG_DRAM_BANK2 *//*; debug print*/DebugPrintAfterTestDram: ldr r0, STR_ENDM ldr r1, Ser3Base bl PrintWord#ifdef NOTDEFmemTest: /* Initial - fill memory */ mov r0,#DRAM_BASE0 add r1,r0,#DRAM_SIZE0 ldr r2,CRC32POLY mov r3,#-1 mov r4,#110: orrs r3,r4,r3,lsl#1 eorcs r3,r3,r2 str r3,[r0], #4 mov r6,r0 mov r7,r1 mov r8,r2 mov r9,r3 mov r10,r4 bl PrintHexWord mov r0,r6 mov r1,r7 mov r2,r8 mov r3,r9 mov r4,r10 cmp r0,r1 bne 10b /* Phase two, check */ mov r0,#DRAM_BASE0 mov r3,#-120: orrs r3,r4,r3,lsl #1 eorcs r3,r3,r2 ldr r5,[r0],#4 cmp r5,r3 bne memError mov r6,r0 mov r7,r1 mov r8,r2 mov r9,r3 mov r10,r4 bl PrintHexWord mov r0,r6 mov r1,r7 mov r2,r8 mov r3,r9 mov r4,r10 cmp r0,r1 bne 20b b memNoError memError: ldr r0, STR_MEM_ERROR ldr r1, Ser3Base bl PrintWordmemError1: b memError1 memNoError: #endif 22: /* execution also continues here from the RunningFromDRAM path */EnableCaches: #ifdef CACHE_ENABLED/*; debug print*/ ldr r0, STR_PRECACHE ldr r1, Ser3Base bl PrintWord /*; Enable the Icache*/#ifdef ICACHE_ENABLED mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #0x1000 /* bit 12 is ICACHE enable*/ mcr p15, 0, r0, c1, c0, 0#endif /*; flush the I/D caches*/ /*; c7 == cache control operation register*/ /*; crm==c7 opc2==0 indicates Flush I+D Cache*/ /*; r0 is ignored*/ mcr p15, 0, r0, c7, c7, 0x00 /*; flush the I+D TLB*/ /*; c8 is TLB operation register*/ /*; crm=c7 opc2==0 indicates Flush I+D TLB*/ /*; r0 is ignored*/ mcr p15, 0, r0, c8, c7, 0x00 /*; Flush the data cache*/ ldr r0,DW_CACHE_FLUSH_REGION bl _C_FUNC(writeBackDcache)/*; debug print*/ ldr r0, STR_POSTCACHE ldr r1, Ser3Base bl PrintWord#endif #ifdef CACHE_ENABLED /*; Flush the data cache*/ ldr r0,DW_CACHE_FLUSH_REGION bl _C_FUNC(writeBackDcache) ldr r0, STR_POSTFLUSH ldr r1, Ser3Base bl PrintWord#endif /*; Get ready to call C functions*/ ldr r0, STR_STACK bl PrintWord ldr r0, DW_STACK_START bl PrintHexWord setupStack: ldr sp,DW_STACK_START mov fp,#0 /* no previous frame, so fp=0*/#if 0 adr r0, _start bl PrintHexWord ldr r0, _start + 0x28 bl PrintHexWord#endif adr r0, _start ldr r1, _start + 0x28 cmp r0, r1 beq call_main /* the bootldr is loaded where it's linked */relocateBootldr:#if 0 adr r0, relocateBootldr bl PrintHexWord#endif /* otherwise, copy it where it's linked */#ifdef ASM_COPY ldr r0, _start + 0x28 /* dest */ adr r1, _start /* source */ add r2, r1, #SZ_256K /* end of source */1: ldmia r1, {r5, r6, r7, r8} stmia r0, {r5, r6, r7, r8} cmp r1, r2 bne 1b#endif ldr r0, _start + 0x28 /* dest */ adr r1, _start /* source */ mov r2, #SZ_256K /* length */ bl memcpy#if 0 ldr r0, _start + 0x28 add r0, r0, #(call_main - _start) bl PrintHexWord /* now branch to call_main adjusted to where the bootldr was linked (not PC relative) */ ldr r0, _start + 0x28 add r0, r0, #(call_main - _start) mov pc, r0#endif call_main: #if 0 adr r0, call_main bl PrintHexWord#endif ldr sp,DW_STACK_START mov fp,#0 /* no previous frame, so fp=0*/ mov a1, #0 /* set argc to 0*/ mov a2, #0 /* set argv to NUL*/ bl main /* call main*/ mov pc, #FLASH_BASE /* reboot */ /**************************************************************/ /* ResetWhileRunningInDRAM */ /* Bootldr is running from DRAM */ /* MMU may be enabled */ /* Disable MMU, then do standard configuration */ /**************************************************************/ ResetWhileRunningInDRAM: mov r11, lr mov r0,#'^' ldr r1, Ser3Base bl PrintChar
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -