📄 start.s
字号:
/* * start.S: blob start code * * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *//* * This is the blob start code. The SA-1100 jumps to address 0x00000000 * after a reset. We put a single branch code at this position which jumps * to a safe region to do the actual setup. All other vectors just point * to an endless loop for the moment. * * Documentation: * [1] Intel Corporation, "Intel StrongARM SA-1100 Microprocessor * Developer's Manual", April 1999 * [2] S. Furber, "ARM System Architecture", Addison Wesley Longman * Ltd., Essex, England, 1996. * [3] Intel Corporation, "Intel StrongARM SA-1110 Microprocessor * Advanced Developer's manual, December 1999 */.ident "$Id: start.S,v 1.2 2001/08/06 22:44:52 erikm Exp $"#ifdef HAVE_CONFIG_H# include <config.h>#endif.text/* Jump vector table as in table 3.1 in [1] */.globl _start_start: b reset b undefined_instruction b software_interrupt b prefetch_abort b data_abort b not_used b irq b fiq/* some defines to make life easier *//* Register addresses can be found in [1] Appendix A */IC_BASE: .word 0x90050000#define ICMR 0x04 PWR_BASE: .word 0x90020000#define PSPR 0x08#define PPCR 0x14 RST_BASE: .word 0x90030000#define RCSR 0x04/* main memory starts at 0xc0000000 */MEM_START: .long 0xc0000000/* The initial CPU speed. Note that the SA11x0 CPUs can be safely overclocked: * 190 MHz CPUs are able to run at 221 MHz, 133 MHz CPUs can do 206 Mhz. */#if (defined ASSABET) || (defined CLART) || (defined LART) \ || (defined NESA) || (defined NESA)cpuspeed: .long 0x0b /* 221 MHz */#elif defined SHANNONcpuspeed: .long 0x09 /* 191.7 MHz */#else#warning "FIXME: Include code to use the correct clock speed for your board"cpuspeed: .long 0x05 /* safe 133 MHz speed */#endif/* the actual reset code */reset: /* First, mask **ALL** interrupts */ ldr r0, IC_BASE mov r1, #0x00 str r1, [r0, #ICMR] /* switch CPU to correct speed */ ldr r0, PWR_BASE LDR r1, cpuspeed str r1, [r0, #PPCR] /* setup memory */ bl memsetup /* init LED */ bl ledinit /* check if this is a wake-up from sleep */ ldr r0, RST_BASE ldr r1, [r0, #RCSR] and r1, r1, #0x0f teq r1, #0x08 bne normal_boot /* no, continue booting */ /* yes, a wake-up. clear RCSR by writing a 1 (see 9.6.2.1 from [1]) */ mov r1, #0x08 str r1, [r0, #RCSR] ; /* get the value from the PSPR and jump to it */ ldr r0, PWR_BASE ldr r1, [r0, #PSPR] mov pc, r1normal_boot: /* enable I-cache */ mrc p15, 0, r1, c1, c0, 0 @ read control reg orr r1, r1, #0x1000 @ set Icache mcr p15, 0, r1, c1, c0, 0 @ write it back /* check the first 1MB in increments of 4k */ mov r7, #0x1000 mov r6, r7, lsl #8 /* 4k << 2^8 = 1MB */ ldr r5, MEM_STARTmem_test_loop: mov r0, r5 bl testram teq r0, #1 beq badram add r5, r5, r7 subs r6, r6, r7 bne mem_test_loop /* the first megabyte is OK, so let's clear it */ mov r0, #((1024 * 1024) / (8 * 4)) /* 1MB in steps of 32 bytes */ ldr r1, MEM_START mov r2, #0 mov r3, #0 mov r4, #0 mov r5, #0 mov r6, #0 mov r7, #0 mov r8, #0 mov r9, #0clear_loop: stmia r1!, {r2-r9} subs r0, r0, #(8 * 4) bne clear_loop /* get a clue where we are running, so we know what to copy */ and r0, pc, #0xff000000 /* we don't care about the low bits */ /* relocate the second stage loader */ add r2, r0, #(128 * 1024) /* blob is 128kB */ add r0, r0, #0x400 /* skip first 1024 bytes */ ldr r1, MEM_START add r1, r1, #0x400 /* skip over here as well */ /* r0 = source address * r1 = target address * r2 = source end address */copy_loop: ldmia r0!, {r3-r10} stmia r1!, {r3-r10} cmp r0, r2 ble copy_loop /* turn off the LED. if it stays off it is an indication that * we didn't make it into the C code */ bl led_off /* set up the stack pointer */ ldr r0, MEM_START add r1, r0, #(1024 * 1024) sub sp, r1, #0x04 /* blob is copied to ram, so jump to it */ add r0, r0, #0x400 mov pc, r0badram: b blinky blinky: /* This is test code to blink the LED very useful if nothing else works */ bl led_on bl wait_loop bl led_off bl wait_loop b blinkywait_loop: /* busy wait loop*/ mov r2, #0x1000000wait_loop1: subs r2, r2, #1 bne wait_loop1 mov pc, lr undefined_instruction: b blinkysoftware_interrupt: /* NOTE: This is NOT an error! If you think that blob should return * from software interrupts, you're plain WRONG. The source of the * problem is in the kernel: you should *disable* CONFIG_ANGELBOOT * simply because blob is not angel. -- Erik */ b blinkyprefetch_abort: b blinkydata_abort: b blinkynot_used: b blinkyirq: b blinkyfiq: b blinky
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -