⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 start.s.svn-base

📁 PowerPC83系列的產品開機程式uboot是linuxOS BASED的程式碼
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1998  Dan Malek <dmalek@jlc.net> * Copyright (C) 1999  Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> * Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de> * Copyright 2004 Freescale Semiconductor, Inc. * * See file CREDITS for list of people who contributed to this * project. * * 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 *//* *  U-Boot - Startup Code for MPC83xx PowerPC based Embedded Boards */#include <config.h>#include <mpc83xx.h>#include <version.h>#define CONFIG_83XX	1		/* needed for Linux kernel header files*/#define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file */#include <ppc_asm.tmpl>#include <ppc_defs.h>#include <asm/cache.h>#include <asm/mmu.h>#ifndef  CONFIG_IDENT_STRING#define  CONFIG_IDENT_STRING "MPC83XX"#endif/* We don't want the  MMU yet. */#undef	MSR_KERNEL/* * Floating Point enable, Machine Check and Recoverable Interr. */#ifdef DEBUG#define MSR_KERNEL (MSR_FP|MSR_RI)#else#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)#endif/* * Set up GOT: Global Offset Table * * Use r14 to access the GOT */	START_GOT	GOT_ENTRY(_GOT2_TABLE_)	GOT_ENTRY(_FIXUP_TABLE_)	GOT_ENTRY(_start)	GOT_ENTRY(_start_of_vectors)	GOT_ENTRY(_end_of_vectors)	GOT_ENTRY(transfer_to_handler)	GOT_ENTRY(__init_end)	GOT_ENTRY(_end)	GOT_ENTRY(__bss_start)	END_GOT/* * Version string - must be in data segment because MPC83xx uses the * first 256 bytes for the Hard Reset Configuration Word table (see * below).  Similarly, can't have the U-Boot Magic Number as the first * thing in the image - don't know how this will affect the image tools, * but I guess I'll find out soon. */	.data	.globl	version_stringversion_string:	.ascii U_BOOT_VERSION	.ascii " (", __DATE__, " - ", __TIME__, ")"	.ascii " ", CONFIG_IDENT_STRING, "\0"	.text#define _HRCW_TABLE_ENTRY(w)		\	.fill	8,1,(((w)>>24)&0xff);	\	.fill	8,1,(((w)>>16)&0xff);	\	.fill	8,1,(((w)>> 8)&0xff);	\	.fill	8,1,(((w)    )&0xff)	_HRCW_TABLE_ENTRY(CFG_HRCW_LOW)	_HRCW_TABLE_ENTRY(CFG_HRCW_HIGH)#ifndef CONFIG_DEFAULT_IMMR#error CONFIG_DEFAULT_IMMR must be defined#endif /* CFG_DEFAULT_IMMR */#ifndef CFG_IMMRBAR#define CFG_IMMRBAR CONFIG_DEFAULT_IMMR#endif /* CFG_IMMRBAR *//* * After configuration, a system reset exception is executed using the * vector at offset 0x100 relative to the base set by MSR[IP]. If * MSR[IP] is 0, the base address is 0x00000000. If MSR[IP] is 1, the * base address is 0xfff00000. In the case of a Power On Reset or Hard * Reset, the value of MSR[IP] is determined by the CIP field in the * HRCW. * * Other bits in the HRCW set up the Base Address and Port Size in BR0. * This determines the location of the boot ROM (flash or EPROM) in the * processor's address space at boot time. As long as the HRCW is set up * so that we eventually end up executing the code below when the * processor executes the reset exception, the actual values used should * not matter. * * Once we have got here, the address mask in OR0 is cleared so that the * bottom 32K of the boot ROM is effectively repeated all throughout the * processor's address space, after which we can jump to the absolute * address at which the boot ROM was linked at compile time, and proceed * to initialise the memory controller without worrying if the rug will * be pulled out from under us, so to speak (it will be fine as long as * we configure BR0 with the same boot ROM link address). */	. = EXC_OFF_SYS_RESET	.globl	_start_start: /* time t 0 */	li	r21, BOOTFLAG_COLD  /* Normal Power-On: Boot from FLASH*/	nop	b	boot_cold	. = EXC_OFF_SYS_RESET + 0x10	.globl	_start_warm_start_warm:	li	r21, BOOTFLAG_WARM	/* Software reboot	*/	b	boot_warmboot_cold: /* time t 3 */	lis	r4, CONFIG_DEFAULT_IMMR@h	nopboot_warm: /* time t 5 */	mfmsr	r5			/* save msr contents	*/	lis	r3, CFG_IMMRBAR@h	ori	r3, r3, CFG_IMMRBAR@l	stw	r3, IMMRBAR(r4)	/* Initialise the E300 processor core		*/	/*------------------------------------------*/	bl	init_e300_core#ifndef CFG_RAMBOOT	/* Inflate flash location so it appears everywhere, calculate */	/* the absolute address in final location of the FLASH, jump  */	/* there and deflate the flash size back to minimal size      */	/*------------------------------------------------------------*/	bl map_flash_by_law1	lis r4, (CFG_MONITOR_BASE)@h	ori r4, r4, (CFG_MONITOR_BASE)@l	addi r5, r4, in_flash - _start + EXC_OFF_SYS_RESET	mtlr r5	blrin_flash:#if 1 /* Remapping flash with LAW0. */	bl remap_flash_by_law0#endif#endif	/* CFG_RAMBOOT */	/* setup the bats */	bl	setup_bats	sync	/*	 * Cache must be enabled here for stack-in-cache trick.	 * This means we need to enable the BATS.	 * This means:	 *   1) for the EVB, original gt regs need to be mapped	 *   2) need to have an IBAT for the 0xf region,	 *      we are running there!	 * Cache should be turned on after BATs, since by default	 * everything is write-through.	 * The init-mem BAT can be reused after reloc. The old	 * gt-regs BAT can be reused after board_init_f calls	 * board_early_init_f (EVB only).	 */	/* enable address translation */	bl	enable_addr_trans	sync	/* enable and invalidate the data cache */	bl	dcache_enable	sync#ifdef CFG_INIT_RAM_LOCK	bl	lock_ram_in_cache	sync#endif	/* set up the stack pointer in our newly created	 * cache-ram (r1) */	lis	r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h	ori	r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l	li	r0, 0		/* Make room for stack frame header and	*/	stwu	r0, -4(r1)	/* clear final stack frame so that	*/	stwu	r0, -4(r1)	/* stack backtraces terminate cleanly	*/	/* let the C-code set up the rest	                    */	/*				                            */	/* Be careful to keep code relocatable & stack humble   */	/*------------------------------------------------------*/	GET_GOT			/* initialize GOT access	*/	/* r3: IMMR */	lis	r3, CFG_IMMRBAR@h	/* run low-level CPU init code (in Flash)*/	bl	cpu_init_f	/* r3: BOOTFLAG */	mr	r3, r21	/* run 1st part of board init code (in Flash)*/	bl	board_init_f/* * Vector Table */	.globl	_start_of_vectors_start_of_vectors:/* Machine check */	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)/* Data Storage exception. */	STD_EXCEPTION(0x300, DataStorage, UnknownException)/* Instruction Storage exception. */	STD_EXCEPTION(0x400, InstStorage, UnknownException)/* External Interrupt exception. */#ifndef FIXME	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)#endif/* Alignment exception. */	. = 0x600Alignment:	EXCEPTION_PROLOG	mfspr	r4,DAR	stw	r4,_DAR(r21)	mfspr	r5,DSISR	stw	r5,_DSISR(r21)	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */	rlwimi	r20,r23,0,25,25		/* copy IP bit from saved MSR */	lwz	r6,GOT(transfer_to_handler)	mtlr	r6	blrl.L_Alignment:	.long	AlignmentException - _start + EXC_OFF_SYS_RESET	.long	int_return - _start + EXC_OFF_SYS_RESET/* Program check exception */	. = 0x700ProgramCheck:	EXCEPTION_PROLOG	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */	rlwimi	r20,r23,0,25,25		/* copy IP bit from saved MSR */	lwz	r6,GOT(transfer_to_handler)	mtlr	r6	blrl.L_ProgramCheck:	.long	ProgramCheckException - _start + EXC_OFF_SYS_RESET	.long	int_return - _start + EXC_OFF_SYS_RESET	STD_EXCEPTION(0x800, FPUnavailable, UnknownException)	/* I guess we could implement decrementer, and may have	 * to someday for timekeeping.	 */	STD_EXCEPTION(0x900, Decrementer, timer_interrupt)	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)	STD_EXCEPTION(0xb00, Trap_0b, UnknownException)	STD_EXCEPTION(0xc00, SystemCall, UnknownException)	STD_EXCEPTION(0xd00, SingleStep, UnknownException)	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)	STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)	STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)	STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)#ifdef DEBUG	. = 0x1300	/*	 * This exception occurs when the program counter matches the	 * Instruction Address Breakpoint Register (IABR).	 *	 * I want the cpu to halt if this occurs so I can hunt around	 * with the debugger and look at things.	 *	 * When DEBUG is defined, both machine check enable (in the MSR)	 * and checkstop reset enable (in the reset mode register) are	 * turned off and so a checkstop condition will result in the cpu	 * halting.	 *	 * I force the cpu into a checkstop condition by putting an illegal	 * instruction here (at least this is the theory).	 *	 * well - that didnt work, so just do an infinite loop!	 */1:	b	1b#else	STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)#endif	STD_EXCEPTION(0x1400, SMI, UnknownException)	STD_EXCEPTION(0x1500, Trap_15, UnknownException)	STD_EXCEPTION(0x1600, Trap_16, UnknownException)	STD_EXCEPTION(0x1700, Trap_17, UnknownException)	STD_EXCEPTION(0x1800, Trap_18, UnknownException)	STD_EXCEPTION(0x1900, Trap_19, UnknownException)	STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)	STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)	STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)	STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)	STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)	STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)	STD_EXCEPTION(0x2000, Trap_20, UnknownException)	STD_EXCEPTION(0x2100, Trap_21, UnknownException)	STD_EXCEPTION(0x2200, Trap_22, UnknownException)	STD_EXCEPTION(0x2300, Trap_23, UnknownException)	STD_EXCEPTION(0x2400, Trap_24, UnknownException)	STD_EXCEPTION(0x2500, Trap_25, UnknownException)	STD_EXCEPTION(0x2600, Trap_26, UnknownException)	STD_EXCEPTION(0x2700, Trap_27, UnknownException)	STD_EXCEPTION(0x2800, Trap_28, UnknownException)	STD_EXCEPTION(0x2900, Trap_29, UnknownException)	STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)	STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)	STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)	STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)	STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)	STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)	.globl	_end_of_vectors_end_of_vectors:	. = 0x3000/* * This code finishes saving the registers to the exception frame * and jumps to the appropriate handler for the exception. * Register r21 is pointer into trap frame, r1 has new stack pointer. */	.globl	transfer_to_handlertransfer_to_handler:	stw	r22,_NIP(r21)	lis	r22,MSR_POW@h	andc	r23,r23,r22	stw	r23,_MSR(r21)	SAVE_GPR(7, r21)	SAVE_4GPRS(8, r21)	SAVE_8GPRS(12, r21)	SAVE_8GPRS(24, r21)	mflr	r23	andi.	r24,r23,0x3f00		/* get vector offset */	stw	r24,TRAP(r21)	li	r22,0	stw	r22,RESULT(r21)	lwz	r24,0(r23)		/* virtual address of handler */	lwz	r23,4(r23)		/* where to go when done */	mtspr	SRR0,r24	mtspr	SRR1,r20	mtlr	r23	SYNC	rfi				/* jump to handler, enable MMU */int_return:	mfmsr	r28		/* Disable interrupts */	li	r4,0	ori	r4,r4,MSR_EE	andc	r28,r28,r4	SYNC			/* Some chip revs need this... */	mtmsr	r28	SYNC	lwz	r2,_CTR(r1)	lwz	r0,_LINK(r1)	mtctr	r2	mtlr	r0	lwz	r2,_XER(r1)	lwz	r0,_CCR(r1)	mtspr	XER,r2	mtcrf	0xFF,r0	REST_10GPRS(3, r1)	REST_10GPRS(13, r1)	REST_8GPRS(23, r1)	REST_GPR(31, r1)	lwz	r2,_NIP(r1)	/* Restore environment */	lwz	r0,_MSR(r1)	mtspr	SRR0,r2	mtspr	SRR1,r0	lwz	r0,GPR0(r1)	lwz	r2,GPR2(r1)	lwz	r1,GPR1(r1)	SYNC	rfi/* * This code initialises the E300 processor core * (conforms to PowerPC 603e spec) * Note: expects original MSR contents to be in r5. */	.globl	init_e300_coreinit_e300_core: /* time t 10 */	/* Initialize machine status; enable machine check interrupt */	/*-----------------------------------------------------------*/	li	r3, MSR_KERNEL			/* Set ME and RI flags */	rlwimi	r3, r5, 0, 25, 25	/* preserve IP bit set by HRCW */#ifdef DEBUG	rlwimi	r3, r5, 0, 21, 22   /* debugger might set SE & BE bits */#endif	SYNC						/* Some chip revs need this... */	mtmsr	r3	SYNC	mtspr	SRR1, r3			/* Make SRR1 match MSR */	lis	r3, CFG_IMMRBAR@h#if defined(CONFIG_WATCHDOG)	/* Initialise the Wathcdog values and reset it (if req) */	/*------------------------------------------------------*/	lis r4, CFG_WATCHDOG_VALUE	ori r4, r4, (SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR)	stw r4, SWCRR(r3)	/* and reset it */	li	r4, 0x556C	sth	r4, SWSRR@l(r3)	li	r4, 0xAA39	sth	r4, SWSRR@l(r3)#else	/* Disable Wathcdog  */	/*-------------------*/	lwz r4, SWCRR(r3)	/* Check to see if its enabled for disabling	   once disabled by SW you can't re-enable */	andi. r4, r4, 0x4	beq 1f	xor r4, r4, r4	stw r4, SWCRR(r3)1:#endif /* CONFIG_WATCHDOG */	/* Initialize the Hardware Implementation-dependent Registers */	/* HID0 also contains cache control			*/	/*------------------------------------------------------*/	lis	r3, CFG_HID0_INIT@h	ori	r3, r3, CFG_HID0_INIT@l	SYNC	mtspr	HID0, r3	lis	r3, CFG_HID0_FINAL@h	ori	r3, r3, CFG_HID0_FINAL@l	SYNC	mtspr	HID0, r3	lis	r3, CFG_HID2@h	ori	r3, r3, CFG_HID2@l	SYNC	mtspr	HID2, r3	/* clear all BAT's					*/	/*----------------------------------*/	xor	r0, r0, r0	mtspr	DBAT0U, r0	mtspr	DBAT0L, r0	mtspr	DBAT1U, r0	mtspr	DBAT1L, r0	mtspr	DBAT2U, r0	mtspr	DBAT2L, r0	mtspr	DBAT3U, r0	mtspr	DBAT3L, r0	mtspr	IBAT0U, r0	mtspr	IBAT0L, r0	mtspr	IBAT1U, r0	mtspr	IBAT1L, r0	mtspr	IBAT2U, r0	mtspr	IBAT2L, r0	mtspr	IBAT3U, r0	mtspr	IBAT3L, r0	SYNC	/* invalidate all tlb's	 *	 * From the 603e User Manual: "The 603e provides the ability to	 * invalidate a TLB entry. The TLB Invalidate Entry (tlbie)	 * instruction invalidates the TLB entry indexed by the EA, and	 * operates on both the instruction and data TLBs simultaneously	 * invalidating four TLB entries (both sets in each TLB). The	 * index corresponds to bits 15-19 of the EA. To invalidate all	 * entries within both TLBs, 32 tlbie instructions should be	 * issued, incrementing this field by one each time."	 *	 * "Note that the tlbia instruction is not implemented on the	 * 603e."	 *	 * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000	 * incrementing by 0x1000 each time. The code below is sort of	 * based on code in "flush_tlbs" from arch/ppc/kernel/head.S	 *	 */	li	r3, 32	mtctr	r3	li	r3, 01:	tlbie	r3	addi	r3, r3, 0x1000	bdnz	1b	SYNC	/* Done!						*/	/*------------------------------*/	blr	.globl	invalidate_batsinvalidate_bats:	/* invalidate BATs */	mtspr	IBAT0U, r0	mtspr	IBAT1U, r0	mtspr	IBAT2U, r0	mtspr	IBAT3U, r0#if (CFG_HID2 & HID2_HBE)	mtspr   IBAT4U, r0	mtspr   IBAT5U, r0	mtspr   IBAT6U, r0	mtspr   IBAT7U, r0#endif	isync	mtspr	DBAT0U, r0	mtspr	DBAT1U, r0	mtspr	DBAT2U, r0	mtspr	DBAT3U, r0#if (CFG_HID2 & HID2_HBE)	mtspr   DBAT4U, r0	mtspr   DBAT5U, r0	mtspr   DBAT6U, r0	mtspr   DBAT7U, r0#endif	isync	sync	blr	/* setup_bats - set them up to some initial state */	.globl	setup_batssetup_bats:	addis	r0, r0, 0x0000	/* IBAT 0 */	addis	r4, r0, CFG_IBAT0L@h	ori	r4, r4, CFG_IBAT0L@l	addis	r3, r0, CFG_IBAT0U@h	ori	r3, r3, CFG_IBAT0U@l	mtspr	IBAT0L, r4	mtspr	IBAT0U, r3	isync	/* DBAT 0 */	addis	r4, r0, CFG_DBAT0L@h	ori	r4, r4, CFG_DBAT0L@l	addis	r3, r0, CFG_DBAT0U@h	ori	r3, r3, CFG_DBAT0U@l	mtspr	DBAT0L, r4	mtspr	DBAT0U, r3	isync	/* IBAT 1 */	addis	r4, r0, CFG_IBAT1L@h	ori	r4, r4, CFG_IBAT1L@l	addis	r3, r0, CFG_IBAT1U@h	ori	r3, r3, CFG_IBAT1U@l	mtspr	IBAT1L, r4	mtspr	IBAT1U, r3	isync	/* DBAT 1 */	addis	r4, r0, CFG_DBAT1L@h	ori	r4, r4, CFG_DBAT1L@l	addis	r3, r0, CFG_DBAT1U@h	ori	r3, r3, CFG_DBAT1U@l	mtspr	DBAT1L, r4	mtspr	DBAT1U, r3	isync	/* IBAT 2 */	addis	r4, r0, CFG_IBAT2L@h	ori	r4, r4, CFG_IBAT2L@l	addis	r3, r0, CFG_IBAT2U@h	ori	r3, r3, CFG_IBAT2U@l	mtspr	IBAT2L, r4	mtspr	IBAT2U, r3	isync	/* DBAT 2 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -