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

📄 sbmemc.s

📁 一个很好的嵌入式linux平台下的bootloader
💻 S
📖 第 1 页 / 共 2 页
字号:
	li	a1,MEMC_CONTROL_INIT7	sw	a1,MEMC_CONTROL(a0)	/* Wait for SDRAM controller to refresh.	 * We want 8uS delay. (Assumes >= 160ns per iteration)	 */	li	t8,501:	lw	a1,R_SBIDLOW(a0)	lw	a1,R_SBIDHIGH(a0)	bnez	t8,1b	subu	t8,1	jr	t7	nop/* *  Routines for initializing SDR SDRAM */	memc_sdr_init:	beqz	t3,sdr_find_ncdl	# Do we have ncdl values?	nop	li	t4,-1	bne	t3,t4,break_sdr_ncdl	nopsdr_find_ncdl:/* Register usage */#define	pass_count	s0#define	clkdsum		s1#define	pass_countmax	s2#define	strmmax		s3#define	strdmax		s4#define	clkdmax		s5#define	clkdlim		s6#define	strm		t2#define	strd		t3#define	clkd		t4#define	STRMLIM		4#define	STRDLIM		16#define	CLKDLIM		128#define	CLKDLIM_IC	256	/* Initialize counter & saved values */	move	pass_countmax,zero	move	strmmax,zero	move	strdmax,zero	li	clkdlim,CLKDLIM	and	strm,t0,0x2000		# Test for internal clock (Using strm as a temp)	beqz	strm,strmloop	nop	li	clkdlim,CLKDLIM_IC	move	strm,zero		# strm loopstrmloop:	move	strd,zerostrdloop:	move	pass_count,zero	move	clkdsum,zero	move	clkd,zero	/* Inner loop:	call sdr_do_init to re-initialize and the test mem */clkdloop:	bal	sdr_do_init	nop	bal	test_mem	nop	beqz	v0,failclkd	nop	/* Memory is ok */	addi	pass_count,1	add	clkdsum,clkdsum,clkd	b	nextclkd	nopfailclkd:	bnez	pass_count,clkdout	# End of passing range, leave clkd loop	nopnextclkd:	addi	clkd,clkd,1	blt	clkd,clkdlim,clkdloop	nopclkdout:	/* If no passing values, skip to next strm */	beqz	pass_count,nextstrm	nop	/* If this is a new max, Save the values */	ble	pass_count,pass_countmax,nextstrd	nop	move	pass_countmax,pass_count	div	zero,clkdsum,pass_count	mflo	clkdmax	move	strdmax,strd	move	strmmax,strmnextstrd:	addi	strd,strd,1	blt	strd,STRDLIM,strdloop	nopnextstrm:	addi	strm,strm,1	blt	strm,STRMLIM,strmloop	nop	/* All done, program the new ncdl values */		beqz	pass_countmax,1f	nop	move	clkd,clkdmax	move	strd,strdmax	move	strm,strmmax	b	sdr_got_ncdl	nop	/* No passing values, panic! (use defaults) */1:#ifdef MEMSDR	li	t3,MEMC_SDR_NCDL	# If rev0, 2:	bne	v1,1,2f	nop	li	t3,MEMC_SDR1_NCDL	# rev1:#else	li	t3,MEMC_DDR_NCDL		# If rev0, 2:	bne	v1,1,2f	nop	li	t3,MEMC_DDR1_NCDL		# rev1:#endif2:break_sdr_ncdl:	andi	t4,t3,0xff		# t4:	cd	srl	t2,t3,16		# t2:	sm	andi	t2,t2,3			#	sm is 2 bits only	srl	t3,t3,8			# t3:	sd	andi	t3,t3,0xf		#	sd is 4 bitssdr_got_ncdl:	bal	sdr_do_init	nop	b	szmem	nop		/* Do an init of the memc core for sdr	 *	a0:	memc core pointer	 *	t0:	memc config value	 *	t1:	memc mode value	 *	t2:	memc strobe mode ncdl value	 *	t3:	memc strobe delay ncdl value	 *	t4:	memc clock delay ncdl value	 *	 * Uses a1, t7, t8, t9 (here and by calling sb_core_reset)	 */sdr_do_init:	/* Save return address */	move	t7,ra	bal	sb_core_reset	li	a1,0x40	/* Initialize SDRAM */	li	a1,MEMC_SD_CONFIG_INIT	or	a1,a1,t0	sw	a1,MEMC_CONFIG(a0)	li	a1,MEMC_SD_DRAMTIM3_INIT	# Assume CAS latency of 3	andi	t8,t1,0xf0			# Find out the CAS latency	bne	t8,0x20,1f	nop	li	a1,MEMC_SD_DRAMTIM2_INIT	# CAS latency is 21:		sw	a1,MEMC_DRAMTIM(a0)	andi	t8,t4,0xff	ble	t8,MEMC_CD_THRESHOLD,1f		# if (cd <= 128) rd = cd	nop	li	t8,MEMC_CD_THRESHOLD		# else rd = 1281:						# t8 is now rd	sll	a1,t8,8				#  .. replicate it 4 times	or	a1,a1,t8	sll	t8,a1,16	or	t8,t8,a1	li	a1,MEMC_SD_RDNCDLCOR_INIT	or	a1,a1,t8	sw	a1,MEMC_RDNCDLCOR(a0)	li	a1,MEMC_SD1_WRNCDLCOR_INIT	# rev1	beq	v1,1,1f	nop	li	a1,MEMC_SD_WRNCDLCOR_INIT	# rev0, 21:	li	t8,0	ble	t4,MEMC_CD_THRESHOLD,2f		# if (cd <= 128) wr = 0	nop		andi	t8,t4,0xff			# else wr = cd - 128	sub	t8,t8,MEMC_CD_THRESHOLD	andi	t8,t8,0xff2:						# t8 is now wr, a0 is extra bits	or	a1,a1,t8	sw	a1,MEMC_WRNCDLCOR(a0)	andi	t8,t2,3	sll	a1,t8,28	andi	t8,t3,0xf	sll	t8,t8,24	or	t8,t8,a1	li	a1,MEMC_SD_MISCDLYCTL_INIT	bne	v1,1,3f				# If rev0, 2:	nop	li	a1,MEMC_SD1_MISCDLYCTL_INIT	# rev1:3:	or	a1,a1,t8	sw	a1,MEMC_MISCDLYCTL(a0)	li	a1,MEMC_SD_CONTROL_INIT0	sw	a1,MEMC_CONTROL(a0)	li	a1,MEMC_SD_CONTROL_INIT1	sw	a1,MEMC_CONTROL(a0)	li	a1,MEMC_SD_CONTROL_INIT2	sw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	li	a1,MEMC_SD_CONTROL_INIT2	sw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	li	a1,MEMC_SD_CONTROL_INIT2	sw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	lw	a1,MEMC_CONTROL(a0)	li	a1,MEMC_SD_REFRESH_INIT	sw	a1,MEMC_REFRESH(a0)	li	a1,MEMC_SD_MODEBUF_INIT	or	a1,a1,t1	sw	a1,MEMC_MODEBUF(a0)	li	a1,MEMC_SD_CONTROL_INIT3	sw	a1,MEMC_CONTROL(a0)	li	a1,MEMC_SD_CONTROL_INIT4	sw	a1,MEMC_CONTROL(a0)	li	t8,501:	lw	a1,R_SBIDLOW(a0)	lw	a1,R_SBIDHIGH(a0)	bnez	t8,1b	subu	t8,1	jr	t7	nop/* *  Common exit code and subroutines shared by SDR and DDR initialization. */			/* Determine memory size and return	 *	 * Somewhat simplistic, assumes size is a power of 2 and looks	 * for aliases of location 0.	 */szmem:	li	t0,PHYS_TO_K1(0)	li	t2,0xaa55beef	sw	t2,0(t0)	li	v0,4		/* Assume minimum of 4MB */1:	sll	t0,v0,20	or	t0,PHYS_TO_K1(0)	lw	t1,0(t0)	beq	t1,t2,done	nop	sll	v0,v0,1	bne	v0,128,1b	/* Fully populated at 128MB, no alias */	nopdone:	jr	t6		nop	/*	 * Test memory	 *	 * Uses arg in t2(wr/sd), t3(rd/sm) and t4(g/clkd)	 * Returns success (1) or failure (0) in v0	 * Uses a1, a2, a3 & t5	 */test_mem:	/* Use t4 to generate a semi-random address in the second KB */	li	a1,0xa0000000	addi	a2,t4,255	sll	a2,a2,2	add	a1,a1,a2	/* First set: 0 & its negation */	li	a2,0	sw	a2,0(a1)	not	a3,a2	sw	a3,4(a1)	nop	lw	t5,0(a1)	bne	a2,t5,bad_mem	nop	lw	t5,4(a1)	bne	a3,t5,bad_mem	nop	/* Second set: 0xaaaaaaaa & its negation */	li	a2,0xaaaaaaaa	sw	a2,0(a1)	not	a3,a2	sw	a3,4(a1)	nop	lw	t5,0(a1)	bne	a2,t5,bad_mem	nop	lw	t5,4(a1)	bne	a3,t5,bad_mem	nop	/* Third set: 0x12345678 & its negation */	li	a2,0x12345678	sw	a2,0(a1)	not	a3,a2	sw	a3,4(a1)	nop	lw	t5,0(a1)	bne	a2,t5,bad_mem	nop	lw	t5,4(a1)	bne	a3,t5,bad_mem	nop	/* Fourth set: the ncdl & its negation */	sll	a2,t2,8	or	a2,t3	sll	a2,a2,8	or	a2,t4	sw	a2,0(a1)	not	a3,a2	sw	a3,4(a1)	nop	lw	t5,0(a1)	bne	a2,t5,bad_mem	nop	lw	t5,4(a1)	bne	a3,t5,bad_mem	nop	/* Fifth set: the CPU count register & its negation */	mfc0	a2,$9	sw	a2,0(a1)	not	a3,a2	sw	a3,4(a1)	nop	lw	t5,0(a1)	bne	a2,t5,bad_mem	nop	lw	t5,4(a1)	bne	a3,t5,bad_mem	nop	jr	ra	li	v0,1bad_mem:	jr	ra	li	v0,0		/* Special sb_core_reset that makes sure the first time	 * clock is enabled, address line 6 is in the state specified	 * by a1.	 *	 * a0:	Core pointer	 * a1:	0x40 if a6 needs to be 1, 0 otherwise	 * uses t8, t9	 */	.align 6sb_core_reset:	/* Save return address */	move	t9,ra        	/* run uncached */	bal     kseg1_switch	nop                                	/* Figure out our address */	bal	h0	noph0:	add	t8,ra,24		# This is (h1 - h0)	andi	t8,t8,0x40	bne	t8,a1,alt_core_reset	nop	/* Set reset while enabling the clock */	li	t8,(M_SBTS_FC | M_SBTS_CE | M_SBTS_RS)	# 2 instructionsh1:	sw	t8,R_SBTMSTATELOW(a0)	b	cont	nop	/* Now pad to 0x40: We want (h2 - h1) == 0x40 and there	 * are 5 instructions in between them.	 */	.space	(0x40 - 20)alt_core_reset:	/* Set reset while enabling the clock */	li	t8,(M_SBTS_FC | M_SBTS_CE | M_SBTS_RS)	# 2 instructionsh2:	sw	t8,R_SBTMSTATELOW(a0)cont:	/* Read back and delay */	lw	t8, R_SBTMSTATELOW(a0)	lw	t8, R_SBTMSTATELOW(a0)	lw	t8, R_SBTMSTATELOW(a0)	/* Clear reset */	li	t8, (M_SBTS_FC | M_SBTS_CE)	sw	t8, R_SBTMSTATELOW(a0)	/* Read back and delay */	lw	t8, R_SBTMSTATELOW(a0)	lw	t8, R_SBTMSTATELOW(a0)	lw	t8, R_SBTMSTATELOW(a0)	/* Leave clock enabled */	li	t8, M_SBTS_CE	sw	t8, R_SBTMSTATELOW(a0)	/* Read back and delay */	lw	t8, R_SBTMSTATELOW(a0)	lw	t8, R_SBTMSTATELOW(a0)	lw	t8, R_SBTMSTATELOW(a0)	jr	t9	nop        kseg1_switch:	and     ra, ra, 0x1fffffff	or      ra, ra, PHYS_TO_K1(0)	jr      ra	nop         	.set	reorder	END(board_draminit)

⌨️ 快捷键说明

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