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

📄 start.s

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 S
字号:
/*	$Id: start.S,v 1.2 2002/11/07 15:05:26 pefo Exp $ *//* * Copyright (c) 2000-2002 Opsycon AB  (www.opsycon.se) * Copyright (c) 2000 Rtmx, Inc   (www.rtmx.com) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed for Rtmx, Inc by *	Opsycon Open System Consulting AB, Sweden. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#define DEBUG#include "target/pmon_target.h"#ifndef INT_MASK#define INT_MASK(src, des)      rlwinm  des, src, 0, 17, 15#endif  /* INT_MASK */#define	HID0	1008#define	CTR	9#define HIADJ(x)	(x)@ha#define HI(x)		(x)@h#define LO(x)		(x)@l#define PRINTSTR(str)		\	bl	9f;		\	.asciz	str;		\	.align	2;		\9:	mflr	3;		\	bl      serial_out /* *  Use this macro to prevent reordering by as/ld and processor */#define	IORDER		eieio; sync/* *  Use this macro to address a config reg when R0 has base. */#define	MAKEADR(adr)    ori 3, 0, (adr); stwbrx 3, 0, 1; IORDER 	.space	0x100	.globl	_start	.globl	start_start:start:	.globl	pmon_stackstack = start - 0x4000		/* Place PMON stack below PMON start in RAM */pmon_stack = start		/* Top of stack */	.globl	pmon_intstackintstack = stack - 0x2000	/* 8K interrupt stack */pmon_intstack = stack		/* Top of stack *//* Clear MSR to diable interrupts and checks */	andi.	1, 1, 0x0	mtmsr	1		/* Clear MSR *//* Clear mapping registers */	li	1, 0x0	mtibatu	0, 1	mtibatl	0, 1	mtibatu	1, 1	mtibatl	1, 1	mtibatu	2, 1	mtibatl	2, 1	mtibatu	3, 1	mtibatl	3, 1	mtdbatu	0, 1	mtdbatl	0, 1	mtdbatu	1, 1	mtdbatl	1, 1	mtdbatu	2, 1	mtdbatl	2, 1	mtdbatu	3, 1	mtdbatl	3, 1	isync	sync	sync	lis	1, 0x8000	isync	mtsr	0, 1	mtsr	1, 1	mtsr	2, 1	mtsr	3, 1	mtsr	4, 1	mtsr	5, 1	mtsr	6, 1	mtsr	7, 1	mtsr	8, 1	mtsr	9, 1	mtsr	10, 1	mtsr	11, 1	mtsr	12, 1	mtsr	13, 1	mtsr	14, 1	mtsr	15, 1	isync	sync	sync/* Turn off caches and invalidate them */	mfspr   3, HID0	isync	rlwinm  4, 3, 0, 18, 15	/* clear d15 and d16 */	sync	isync	mtspr   HID0, 4 	/* turn off caches */	isync	lis	3, 0		/* XXX 604 specific code */	ori	3, 3, 0xcc00	/* Enable & invalidate bits */	or	4, 4, 3	sync	isync	mtspr	HID0, 4	andc	4, 4, 3	isync	li	11, 0	ori	11, 11, 0x2000	mtspr	CTR, 111:	bdnz	1b	isync	mtspr	HID0, 4	isync	ori	4, 4, 0x8800	isync	mtspr	HID0, 4		/* turn on i-cache for speed *//* Set r16 to the load vs link offset. */	bl	1f1:	mflr	3	lis	16, 0xffff	and.	16, 16, 3	lis	4, HI(start)	sub	16, 16, 4		/* R16 is now load offset *//* *  Find out if executing in ROM or RAM. Note memory size wired to 64Mb. */	lis	15, 0x0400		/* Memory size accumulator = 64MB */	lis	4, 0xf000		/* Last 256Mb segment */	and.	4, 4, 3	beq	in_ram			/* We are ram loaded! */	PRINTSTR("\r\n\n\nPMON2000 PowerPC Initializing. Standby...\r\n")/* *  Init the PCI/Memory controller (MPC106) */	lis	0, HI(MPC106_BASE)		/* R0 is base reg thruout */	ori	1, 0, LO(MPC106_CFG_ADDR)	/* R1 cfg addr */	ori	2, 0, LO(MPC106_CFG_DATA)	/* R2 data pointer */	MAKEADR(MPC106_REG_REV)	lbz	26, 0(2)	/* get MPC106 chip revision */	IORDER/**/	MAKEADR(MPC106_REG_MCFG1)	lwbrx	4, 0, 2	lis	3, 0x0008	andc	4, 4, 3		/* 0xfff7ffff = clear MEMG0 */	stwbrx	4, 0, 2/**/	isync			/* now do pci init */	lis	3, 0x8080	/* subtile fumbling with ISA config in */	ori	3, 3, 0x084c	/* the 82378ZB. 08 = devsel, 4c is offset */	lis	4, 0x5600	/* note! bytes reversed! */	ori	4, 4, 0x13f4	stw	4, 0(3)	IORDER	/**/	lis	3, HIADJ(P4E_MISC)	lbz	4, LO(P4E_MISC)(3)	andi.	4, 4, 0xfc		/* LED bitfail off user off */	stb	4, LO(P4E_MISC)(3)#if 1/* *  Configure L2 cache */	lis	6, HIADJ(P4E_CFG)	lbz	7, LO(P4E_CFG)(6)	/* Get L2 cache configuration *//**/	MAKEADR(MPC106_REG_CFG_AC)	lwbrx	4, 0, 2/* XXX Next two instructions looks bogus. However it's put here as a * preparation for Eagle vs. Grackle support. Eagle preserves other bits */	xor	3, 3, 3	and	4, 4, 3	lis	3, 0x103a		/* L2 Disable */	andi.	7, 7, P4E_CFG_L2	cmpwi	7, P4E_CFG_L2_NONE	beq	2f	lis	3, 0x903a		/* L2 invalidate, 2 clk snoop */	ori	3, 3, 0x04c4		/* L2 = 256K - default */	cmpwi	7, P4E_CFG_L2_IS_512K	bne	1f	ori	3, 3, 0x04d4		/* L2 = 512K */	b	2f1:	cmpwi	7, P4E_CFG_L2_IS_1M	bne	2f	ori	3, 3, 0x04e4		/* L2 = 1M */2:	or	4, 4, 3	stwbrx	4, 0, 2			/* Set cache configuration */	IORDER	lis	3, 0x1000	andc	4, 4, 3			/* L2 invalidate OFF */	lis	3, 0x4000	ori	3, 3, 0x4000	or	4, 4, 3	stwbrx	4, 0, 2			/* L2 Enable */	IORDER/* *  Set up the cache controller */	MAKEADR(MPC106_REG_CFG_A8)	lwbrx	4, 0, 2/* XXX Grackle mask 0x00000000, Eagle mask 0x00004100 (ifdefs later)*/	xor	3, 3, 3	and	4, 4, 3	lis	3, 0x7f21	oris	3, 3, 0x6		/* CPU type = 604 */	ori	3, 3, 0x1e99		/* Default = write thru cache */	ori	3, 3, 0x0004		/* PCI prefetch */	cmpwi	26, 0x40		/* Chip rev less than 4.0? */	blt	1f			/* Yes, keep write thru */	rlwinm	3, 3, 0, 0, 29		/* else */	ori	3, 3, 0x2		/* Switch to write back! */1:	or	4, 4, 3	stwbrx	4, 0, 2	IORDER#endif/* *  Init PCI command and status registers */	MAKEADR(MPC106_REG_PCI_CMD)	lhbrx	4, 0, 2	andi.	4, 4, 0xfca0		/* preserve */	ori	4, 4, 0x106	sthbrx	4, 0, 2	IORDER/**/	MAKEADR(MPC106_REG_PCI_STAT)	li	3, 2	lhbrx	4, 3, 2	ori	4, 4, 0xf900	sthbrx	4, 3, 2			/* Clear PCI stat/error bits */	IORDER/* * Set up the memory controller */	lis	3, HIADJ(P4E_MISC)	lbz	7, LO(P4E_MISC)(3)	lis	3, HIADJ(P4E_MEZZ_CFG)	lbz	8, LO(P4E_MEZZ_CFG)(3)/**/	MAKEADR(MPC106_REG_MCFG1)	lwbrx	4, 0, 2			/* Get memcfg 1 */	lis	3, 0xf702		/* Adjust ROM waitstates */	cmpwi	26, 0x40	blt	1f	oris	3, 3, 0x1		/* Chip rev 4.0+, enable parity */1:	ori	3, 3, 0xaaaa		/* 11 row bits */	and	4, 4, 3	or	4, 4, 3	stwbrx	4, 0, 2	IORDER/**/	MAKEADR(MPC106_REG_MCFG2)	lwbrx	4, 0, 2	lis	3, 0xfffc		/* Grackle preserve */	and	4, 4, 3	lis	3, 0	andi.	6, 7, P4E_MISC_MEM	cmpwi	6, P4E_MISC_MEM_16FPM	beq	1f	cmpwi	6, P4E_MISC_MEM_32FPM	beq	1f	lis	3, 11:	ori	3, 3, 0x1014	cmpwi	26, 0x40	blt	1f	ori	3, 3, 0x1		/* RMW parity enable */1:	or	4, 4, 3	stwbrx	4, 0, 2			/* Set mem config 2 */	IORDER/**/	MAKEADR(MPC106_REG_MCFG3)	lwbrx	4, 0, 2	andis.	4, 4, 0xfff0		/* Preserve bits */	oris	4, 4, 0x0002		/* RASP=0101, CAS5=001, CP4=001 */	ori	4, 4, 0x925b		/* CAS3=001, RCD2=110, RP1=011 */	stwbrx	4, 0, 2	IORDER/**/	MAKEADR(MPC106_REG_MCFG4)	lwbrx	4, 0, 2	lis	3, 0x0010		/* XXX Grackle preserve */	andc	4, 4, 3			/* 0xffefffff */	or	4, 4, 3			/* Transparent latch */	stwbrx	4, 0, 2/**/	MAKEADR(MPC106_REG_MBEN)	/* Bank enables */	li	3, 0x0	stb	3, 0(2)			/* Disables all banks */	li	4, 0x0	li	9, 0x0			/* Bank select reg */	li	14, 0x0			/* Total mem size */	li	11, 0x0			/* Bank enables */	li	15, 0x0			/* Memory size accumulator */	li	12, 0x000a		/* Bank 0,1 defaults to 11 row bits *//**/	andi.	6, 8, P4E_MEZZ1		/* Check for mezzanine memory */	cmpwi	6, P4E_MEZZ1_16FPM	beq	16f	cmpwi	6, P4E_MEZZ1_16EDO	beq	16f	cmpwi	6, P4E_MEZZ1_32FPM	beq	32f	cmpwi	6, P4E_MEZZ1_32EDO	beq	32f	cmpwi	6, P4E_MEZZ1_64EDO	beq	64f	cmpwi	6, P4E_MEZZ1_128EDO	beq	128f	b	bootinit_abort		/* Nothing found ! */16:	lis	14, 0x0100		/* 16M */	li	9, 0x000f		/* 16M ending address */	ori	11, 11, 0x0001		/* Enable bank 0 */	mr	13, 9	rlwinm	13, 13, 16, 8, 15	addis	13, 13, 1	addis	15, 15, 0x0100	b	9f32:	lis	14, 0x0200		/* 32M */	li	4, 0x1000		/* 16M in 0, 16M in 1 */	li	9, 0x1f0f		/* 16M, 32M ending address */	ori	11, 11, 0x0003		/* Enable bank 0 & 1 */	mr	13, 9	rlwinm	13, 13, 8, 8, 15	addis	13, 13, 1	addis	15, 15, 0x0200	b	9f64:	lis	14, 0x0400		/* 64M */	li	12, 0x0003	li	4, 0x0000	li	9, 0x003f	ori	11, 11, 0x0001	mr	13, 9	rlwinm	13, 13, 16, 8, 15	addis	13, 13, 1	addis	15, 15, 0x0400	b	9f128:	lis	14, 0x0800		/* 128M */	li	12, 0x000f	li	4, 0x4000	li	9, 0x7f3f	ori	11, 11, 0x0003	mr	13, 9	rlwinm	13, 13, 8, 8, 15	addis	13, 13, 1	addis	15, 15, 0x08009:	or	4, 4, 13		/* Bank 2 starting address *//**/	ori	12, 12, 0x00a0	andi.	6, 8, P4E_MEZZ2	cmpwi	6, P4E_MEZZ2_16FPM	beq	16f	cmpwi	6, P4E_MEZZ2_16EDO	beq	16f	cmpwi	6, P4E_MEZZ2_32FPM	beq	32f	cmpwi	6, P4E_MEZZ2_32EDO	beq	32f	cmpwi	6, P4E_MEZZ2_64EDO	beq	64f	cmpwi	6, P4E_MEZZ2_128EDO	beq	128f	b	9f16:	addis	14, 14, 0x0100		/* bump 16M */	addis	13, 13, 0x000f	or	9, 9, 13	ori	11, 11, 0x0004	addis	15, 15, 0x0100	b	9f32:	addis	14, 14, 0x0200		/* bump 32M */	addis	13, 13, 0x000f	or	9, 9, 13	rlwinm	13, 13, 8, 0, 7	addis	13, 13, 0x0100	or	4, 4, 13	addis	13, 13, 0x0f00	or	9, 9, 13	ori	11, 11, 0x000c	addis	15, 15, 0x0200	b	9f64:	addis	14, 14, 0x0400		/* bump 64M */	addis	13, 13, 0x003f	or	9, 9, 13	ori	11, 11, 0x0004	andi.	12, 12, 0xff0f	ori	12, 12, 0x0030	addis	15, 15, 0x0400	b	9f128:	addis	14, 14, 0x0800		/* bump 128M */	addis	13, 13, 0x003f	or	9, 9, 13	rlwinm	13, 13, 8, 0, 7	addis	13, 13, 0x0100	or	4, 4, 13	addis	13, 13, 0x3f00	or	9, 9, 13	ori	11, 11, 0x000c	andi.	12, 12, 0xff0f		/* hmm... */	ori	12, 12, 0x00f0	addis	15, 15, 0x08009:/**/	MAKEADR(MPC106_REG_MSTA_03)	stwbrx	4, 0, 2	IORDER/**/	li	4, 0	MAKEADR(MPC106_REG_MSTA_47)	stwbrx	4, 0, 2	IORDER/**/	lis	3, 0xfcfc	ori	3, 3, 0xfcfc	MAKEADR(MPC106_REG_EMSTA_03)	lwbrx	4, 0, 2	and	4, 4, 3	stwbrx	4, 0, 2	IORDER	MAKEADR(MPC106_REG_EMSTA_47)	lwbrx	4, 0, 2	and	4, 4, 3		/* r3 = 0xfcfcfcfc */	stwbrx	4, 0, 2	IORDER/**/	MAKEADR(MPC106_REG_MEND_03)	stwbrx	9, 0, 2	IORDER/**/	li	4, 0	MAKEADR(MPC106_REG_MEND_47)	stwbrx	4, 0, 2	IORDER/**/	MAKEADR(MPC106_REG_EMEND_03)	lwbrx	4, 0, 2	and	4, 4, 3		/* r3 = 0xfcfcfcfc */	stwbrx	4, 0, 2	IORDER/**/	MAKEADR(MPC106_REG_EMEND_47)	lwbrx	4, 0, 2	and	4, 4, 3		/* r3 = 0xfcfcfcfc */	stwbrx	4, 0, 2	IORDER/**/	MAKEADR(MPC106_REG_MBEN)	stb	11, 0(2)/**/	li	4, 0x2000	mtctr	41:	bdnz	1b		/* Delay to allow memory to initialize *//**/	MAKEADR(MPC106_REG_MCFG1)	lwbrx	4, 0, 2	oris	4, 4, 0x0008	or	4, 4, 12	stwbrx	4, 0, 2/**/	li	4, 0x2000	mtctr	41:	bdnz	1b		/* Delay to allow memory to initialize *//**/	mfmsr	3	INT_MASK(3, 4)		/* Disable interrupt */	ori	3, 3, 0x3002	/* set FP, ME and RI */	mtmsr	3/* *  RAM memory should now be operational, we can call C-code (some *  restrictions still do apply, like usage of initialised vars). *  We scrub the entire memory to get rid of potential parity errors. */	PRINTSTR("Scrubbing memory. Standby...\r\n")	li	4, 0x4000		/* Start from 0x4000 to preserve */	sub	3, 15, 4		/* message areas */	srwi	3, 3, 2			/* Mem size div 4 */	mtctr	31:	stw	4, 0(4)			/* Zero out what will be the stack */	addic	4, 4, 0x4	bdnz	1b	PRINTSTR("Memory scrubbing done!\r\n")in_ram:	lis	4, HI(start)	addi	1, 4, -64		/* RAM START++ will be overwritten */	stw	15, 8(1)		/* Save away memory size */	PRINTSTR("Moving PMON2000 to RAM!\r\n")	add	3, 4, 16	bl	copytoram		/* Go do PPC initialization */	cmpwi	3, 0	beq	gopmon	PRINTSTR("Verify after copy failed! Halting!!\r\n")1:	b	1bgopmon:/* *  All stations are GO for takeoff. *  Lets go to the other end of the universe! */	lwz	5, 8(1)			/* Memorysize */	PRINTSTR("Success!\r\n")	mfspr	4, HID0		ori	4, 4, 0xcc84	/* Enable D-cache */				/* Branch target cache on 604em is 0x0002 */	isync			/* Serialize disable and branch history enab */	mtspr	HID0, 4		isync	lis	r1, HIADJ(STACKBASE)	addi	r1, r1, LO(STACKBASE)	mtsprg	0, r1	addi	r1, r1, STACKSIZE-64	li	0, 0x0		/* Mark end of frames on stack */	stw	0, 0(1)	stw	0, 4(1)	lis	4, HIADJ(initppc)	addi	4, 4, LO(initppc)	mtlr	4	or	3, 5, 5	blr/**/bootinit_abort:	PRINTSTR("PMON/PPC ABORT! No RAM memory found!\r\n")1:	b	1b/* *  Simple serial output routine used to communicate messages *  during prom setup before 'real' driver is running. *  This code simply displays a string of chars on the console. */serial_out:	lis	30, HIADJ(COM1_BASE_ADDR)	addi	30, 30, LO(COM1_BASE_ADDR)	li	31, 1	stb	31, 4(30)	/* DTR on */	IORDER	li	31, 0x80	/* Get to divisor latch */	stb	31, 3(30)	IORDER	li	31, 0x4		/* Baud rate */	stb	31, 0(30)	IORDER	li	31, 0x0	stb	31, 1(30)	IORDER	li	31, 0x3		/* 8 bits no parity */	stb	31, 3(30)	IORDER	lis	31, 0x0020	/* let sio stabilize */	mtctr	311:	bdnz	1b2:	lbz	31, 0(3)	cmpwi	31, 0	beq	4f3:	lbz	31, 5(30)	andi.	31, 31, 0x20	beq	3b		/* Wait for tx buffer empty */	lbz	31, 0(3)	stb	31, 0(30)	/* send char */	addi	3, 3, 1	b	2b4:	blr			/* return *//**/	.globl	tgt_putchartgt_putchar:	lis	9, HIADJ(COM1_BASE_ADDR)	addi	9, 9, LO(COM1_BASE_ADDR)1:	lbz	0, 5(9)	andi.	0, 0, 0x20	beq	1b	stb	3, 0(9)	blr/**/

⌨️ 快捷键说明

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