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

📄 rominit.s

📁 MPC8241:本程序是freescale的824*系列的BSP源程序
💻 S
📖 第 1 页 / 共 2 页
字号:


/******************************************************************************
*
* mpc8240Scrub - PCI configuration register modification.
*
* DESCRIPTION: mpc8240Scrub
*     this subroutine's purpose is to initialize (i.e., scrub)
*     DRAM, the MPC8240 ASIC protects DRAM by utilizing ECC, so
*     the scrub insures that the entire DRAM array's check bits
*     are initialized to a known state
*
*     mpc8240Scrub(start-address, end-address, control-flag);
*     r1	= don't care, no stack is needed
*     r3	= starting address of DRAM
*     r4	= ending address of DRAM (plus 1)
*     spr8	= return program counter
*
* RETURNS:
*     r3	= 1, DRAM ECC error detected
*    		= 0, no DRAM ECC errors occurred
*/

	.data
	.align	3
	.globl	mpc8240ScrubData
mpc8240ScrubData:
	.long	0x00000000, 0x00000000

	.text
	.align	3
	.globl	mpc8240Scrub
mpc8240Scrub:
	mfspr	r16,8			/* save return instruction pointer */
	or	r13,r3,r3		/* save argument #1 */
	or	r14,r4,r4		/* save argument #2 */
	addis	r0,r0,0			/* insure r0 is zero */
	ori	r0,r0,0			/* insure r0 is zero */

        /* load 64-bit number to initialize memory with */

	addis	r6,r0,HI(mpc8240ScrubData)
	ori	r6,r6,LO(mpc8240ScrubData)
/*
 * setup loop specifics
 *
 * attempt a fpu register access only if mpc8240 has fpu enabled,
 * based on HID1 bit 0 being a 1 or 0.  0 = FPU enabled, 1 = FPU disabled
 */

	mfspr	r5,1009			/* load hid1 contents */
	andi.	r5,r5,0x0001		/* extract FPU available bit and test */
	bc	4,2,mpc8240FpuDisabled	/* if 1, don't load FPU register */

	lfdu	0,0(r6)
	subf	r18,r13,r14		/* calculate number of bytes */
	rlwinm	r18,r18,29,3,31		/* calculate number of doubles */
	addi	r17,r13,-8		/* starting address munged */
	mtspr	9,r18			/* load number of doubles/words */
	b	mpc8240ScrubLoopFpu

mpc8240FpuDisabled:
	lwz	r8,0(r6)
	subf	r18,r13,r14		/* calculate number of bytes */
	rlwinm	r18,r18,30,2,31		/* calculate number of words */
	addi	r17,r13,-4		/* starting address munged */
	mtspr	9,r18			/* load number of doubles/words */
	b	mpc8240ScrubLoopNoFpu	/* branch to loop */

        /* Loop through the entire DRAM array, initialize memory */

mpc8240ScrubLoopFpu:
	stfdu	0,8(r17)
	bc	16,0,mpc8240ScrubLoopFpu	/* branch till counter == 0 */
	sync				/* synchronize the data stream */
	b	mpc8240ScrubExit

mpc8240ScrubLoopNoFpu:
        /* 
         * Flicker fail LED while scrubbing (demonstrates how slow 
         * (~5 secs) this is. 
         */

#ifdef DEBUG_STARTUP 
        addis	r3,r0,HIADJ(PRPMC600_SYS_STAT_REG2)	
        ori	r3,r3,LO(PRPMC600_SYS_STAT_REG2)
	addis	r4,r0,HIADJ(PRPMC600_BD_FAIL)
	ori	r4,r4,LO(PRPMC600_BD_FAIL)
	andc	r5,r5,r4		/* and in complement of BD_FAIL */
	stwbrx	r5,r0,r3		/* write new STAT */
	sync				/* ensure memory access is complete */
#endif /* DEBUG_STARTUP */

	stw	r8,4(r17)

#ifdef DEBUG_STARTUP 
        addis	r3,r0,HIADJ(PRPMC600_SYS_STAT_REG2)	
        ori	r3,r3,LO(PRPMC600_SYS_STAT_REG2)
        addis	r4,r0,HIADJ(PRPMC600_BD_FAIL)
        ori	r4,r4,LO(PRPMC600_BD_FAIL)
	stwbrx	r4,r0,r3		/* write new STAT */
	sync				/* ensure memory access is complete */
#endif /* DEBUG_STARTUP */
	bc	16,0,mpc8240ScrubLoopNoFpu /* branch till counter == 0 */
	sync				/* synchronize the data stream */

        /* exit */

mpc8240ScrubExit:
	addi	r3,r0,0			/* initialize error indicator, none */
	mtspr	8,r16			/* restore return instruction pointer */
	bclr    0x14,0x0		/* return to caller */


/******************************************************************************
*
* mpc8240RegMod - PCI configuration register modification.
*
* This function provides modification control for Mpc8240's
* configuration registers.  It performs the necessary byte
* swapping.
*
* call:
*     mpc8240RegMod(regOffset, regSize, mask, data)
*
*     regOffset	= (r3) address of device register to be modified
*     regSize		= (r4) register size
*         1, byte (8 bit) register
*         2, half word (16 bit/2 byte) register
*         4, word (32 bit/4 byte) register
*     mask		= (r5) mask for current register value
*     data		= (r6) data to be inserted into register
*     spr8		= return program counter
*
* registers used (and not saved):
*	r3, r4, r5, r6, r7, r8, r9, r20
*
* RETURNS:
*    (r3) data read from register if read operation (otherwise return 0)
*/

	.text
	.align	2
	.globl	mpc8240RegMod
mpc8240RegMod:
	sync				/* ensure instructions are complete */
	eieio				/* ensures memory access is complete */
	xor	r0,r0,r0		/* clear r0 */

        /* load register addresses to device-register, PCI_CAR, and PCI_CDR */

	addis	r7,r0,HIADJ(CNFG_PCI_HOST_BRDG)
	ori	r7,r7,LO(CNFG_PCI_HOST_BRDG)
	add	r7,r7,r3		/* add register offset */
	addis	r8,r0,HIADJ(PCI_MSTR_PRIMARY_CAR)
	ori	r8,r8,LO(PCI_MSTR_PRIMARY_CAR)
	addis	r9,r0,HIADJ(PCI_MSTR_PRIMARY_CDR)
	ori	r9,r9,LO(PCI_MSTR_PRIMARY_CDR)

        /* adjust the addresses to CDR and device-register */

	andi.	r12,r3,0x3		/* mask register offset */
	add	r9,r9,r12		/* adjust it */
	addi	r12,r0,0x3		/* load mask (lower 2-bits) */
	andc	r7,r7,r12		/* mask of lower 2-bits */

        /* write register value to CAR */

	stwbrx	r7,r0,r8		/* write register value to CAR */
	eieio				/* ensure memory access is complete */
	sync				/* ensure memory access is complete */

        /* determine the size of the data operation */

	cmpli	0,0,r4,0x04		/* is this a word i/o operation? */
	bc	0x0c,0x02,andor32	/* branch to word i/o code */
	cmpli	0,0,r4,0x02		/* is this a half-word i/o operation? */
	bc	0x0c,0x02,andor16	/* branch to half-word i/o code */
	cmpli	0,0,r4,0x01		/* is this a byte i/o operation? */
	bc	0x0c,0x02,andor8	/* branch to byte i/o code */
	bclr	0x14,0x0		/* return to caller */

        /* word size data operations */

andor32:				/* READ/MODIFY(AND/OR)/WRITE */
	lwbrx	r7,r0,r9		/* load(read) device data into r7 */
	and	r7,r7,r5		/* reg7 &= reg5 */
	or	r7,r7,r6		/* reg7 |= reg6 */
	stwbrx	r7,r0,r9		/* store(write) r7 to device reg */
	eieio				/* ensure memory access is complete */
	sync				/* ensure memory access is complete */
	bclr    0x14,0x0		/* return to caller */

        /* half-word size data operations */

andor16:				/* READ/MODIFY(AND/OR)/WRITE */
	lhbrx	r7,r0,r9		/* load(read) device data into r7 */
	eieio				/* ensure memory access is complete */
	sync				/* ensure memory access is complete */
	and	r7,r7,r5		/* reg7 &= reg5 */
	or	r7,r7,r6		/* reg7 |= reg6 */
	sthbrx	r7,r0,r9		/* store(write) r7 to device reg */
	eieio				/* ensure memory access is complete */
	sync				/* ensure memory access is complete */
	bclr    0x14,0x0		/* return to caller */

        /* byte data size operations */

andor8:					/* READ/MODIFY(AND/OR)/WRITE */
	lbz	r7,0(r9)		/* load(read) device data into r7 */
	eieio				/* ensure memory access is complete */
	sync				/* ensure memory access is complete */
	and	r7,r7,r5		/* reg7 &= reg5 */
	or	r7,r7,r6		/* reg7 |= reg6 */
	stb	r7,0(r9)		/* store(write) r7 to device reg */
	eieio				/* ensure memory access is complete */
	sync				/* ensure memory access is complete */
	bclr    0x14,0x0		/* return to caller */


/******************************************************************************
*
* mpc8240DefInit - configure memory controller with default memory settings.
*
* This function initializes the Mpc8240 memory controller
* to bank 0, 32Mg and assumes a 83.3MHz clock.
*
* registers used (and not saved):
*	r3, r4, r5, r6, r7, r8, r9, r20
*
* RETURNS:
*     none
*/

	.text
	.align	3
	.globl	mpc8240DefInit
mpc8240DefInit:
	addis	r0,r0,0			/* insure r0 is zero */
	ori	r0,r0,0			/* insure r0 is zero */
	or	r22,r0,r0		/* preset to no memory available */
	mfspr	r20,8			/* save return instruction pointer */

	bl	mpc8240InitTableBasicPtr	/* branch around tables */
/*
 *	register data table (initialization values)
 *
 *	this table places the Mpc8240 into a known state, other tables
 *	exist for specific memory configurations
 */
mpc8240InitTableBasic:
/*
 *              reg size  data        mask
 *              === ====  ====        ====
 */
 	.long MPC8240_CFG_COMMAND,			 2, 0x0006,		0x0000
 	.long MPC8240_CFG_CACHE_LINE_SIZE,   1, 0x08,       0x00
	.long MPC8240_CFG_PCI_ARBITER_CNTL,  2, 0x8000,     0x1B60
	.long MPC8240_CFG_PERF_MON_CMND_REG, 4, 0x00000000, 0x00000000
	.long MPC8240_CFG_PERF_MON_CNTL_REG, 2, 0x0020,     0x3F0E
	.long MPC8240_CFG_PERF_MON_COUNTER0, 4, 0x00000000, 0x00000000
	.long MPC8240_CFG_PERF_MON_COUNTER1, 4, 0x00000000, 0x00000000
	.long MPC8240_CFG_PERF_MON_COUNTER2, 4, 0x00000000, 0x00000000
	.long MPC8240_CFG_PERF_MON_COUNTER3, 4, 0x00000000, 0x00000000
	.long MPC8240_CFG_PWR_MGT_CFG_REG,   2, 0x0001,     0x2B40 /*donot change, maybe 0x2b40*/
	.long MPC8240_CFG_PWR_MGT_CFG_REG2,  1, 0x80,       0x08
	.long MPC8240_CFG_OUTPUT_DRIVER_REG, 1, 0x05,       0x00 /*changed*/
	.long MPC8240_CFG_CLOCK_DRIVER_REG,  2, 0x0000,     0x0306
	.long MPC8240_CFG_EUMBBAR,           4, MPC8240_EUMB_BASE, 0x0
	.long MPC8240_CFG_MISC_REG1,         4, 0x000000c0, 0xFFFFFF1F 
	.long MPC8240_CFG_MISC_REG1,         4, 0x000000e0, 0xFFFFFF1F
	.long MPC8240_CFG_MISC_REG1,         4, 0x000000c0, 0xFFFFFF1F 

/*
 * The 66.66 and 83.33 boards will
 * work with the following memory controller settings.
 *
 *              reg size  data        mask
 *              === ====  ====        ====
 */

	/* .long MPC8240_CFG_MEM_CNTL_CFG_REG1,    4, 0x8f600002, 0x00600000 */ /*for 128M*/
	.long MPC8240_CFG_MEM_CNTL_CFG_REG1,    4, 0x8f600000, 0x00600000 /*for 64M*/
	.long MPC8240_CFG_MEM_CNTL_CFG_REG2,    4, 0x000006b8, 0x00000000
	.long MPC8240_CFG_MEM_CNTL_CFG_REG3,    4, 0x78400000, 0x00000000
	.long MPC8240_CFG_MEM_CNTL_CFG_REG4,    4, 0x35323239, 0x00A00000

	.long MPC8240_CFG_MEM_STRT_ADR_REG,     4, 0x00000000, 0x00000000
	.long MPC8240_CFG_MEM_STRT_UADR_REG,    4, 0x00000000, 0x00000000
	.long MPC8240_CFG_EXT_MEM_STRT_ADR_REG, 4, 0x00000000, 0xFCFCFCFC
	.long MPC8240_CFG_EXT_MEM_ST_UADR_REG,  4, 0x00000000, 0xFCFCFCFC

	/* .long MPC8240_CFG_MEM_END_ADR_REG,      4, 0xFFFFFF7F, 0x00000000 */ /*for 128M*/
        .long MPC8240_CFG_MEM_END_ADR_REG,      4, 0x7F5F3F1F, 0x00000000 /*for 32M*/  
	.long MPC8240_CFG_MEM_END_UADR_REG,     4, 0xFFFFFFFF, 0x00000000
	.long MPC8240_CFG_EXT_MEM_END_ADR_REG,  4, 0x00000000, 0xFCFCFCFC
	.long MPC8240_CFG_EXT_MEM_END_UADR_REG, 4, 0x00000000, 0xFCFCFCFC

	.long MPC8240_CFG_PAGE_MODE_CTR_TIMER,  1, 0x50,       0x00
	.long MPC8240_CFG_MEM_BANK_ENABLE_REG,  1, 0x01,       0x00
	.long MPC8240_CFG_PROC_IF_CFG1,         4, 0xff141b88, 0xFF39E483
	.long MPC8240_CFG_PROC_IF_CFG2,         4, 0x00040604, 0xD1F3FFF3	
	.long MPC8240_CFG_ECC_ERROR_CTR,        1, 0x00,       0x00	
	.long MPC8240_CFG_ECC_ERROR_TRIG,       1, 0x00,       0x00	
	.long MPC8240_CFG_ERROR_ENABLE1,        1, 0x01,       0x00 /* modified by zoutl for test: 0x01--> 0xff */
	.long MPC8240_CFG_ERROR_DETECT1,        1, 0x0,       0x00
	.long MPC8240_CFG_CPU_BUS_ERR_STAT,     1, 0x10,       0x00
	.long MPC8240_CFG_ERROR_ENABLE2,        1, 0x00,       0x72 /* modified by zoutl for test: 0x00--> 0xcf */
	.long MPC8240_CFG_ERROR_DETECT2,        1, 0x0,       0x72
	.long MPC8240_CFG_PCI_BUS_ERR_STAT,     1, 0x0,       0xE0

	.long MPC8240_CFG_MEM_CNTL_CFG_REG1,   4, MPC8240_MCC1_MEMGO, 0xFFF7FFFF
	.long -1,  -1, -1,         -1		/* table end marker */

mpc8240InitTableBasicPtr:
	mfspr	r21,8			/* load pointer to table */
mpc8240InitBLoop:
	lwz	r3,0(r21)		/* load offset */
	lwz	r4,4(r21)		/* load size */
	lwz	r5,12(r21)		/* load mask (and-data) */
	lwz	r6,8(r21)		/* load data (or-data) */
	cmpi	0,0,r5,-1		/* table end? */
	bc	12,2,mpc8240InitDone	/* if equal, yes, branch */
	bl	mpc8240RegMod		/* perform register mod operation */
	addi	r21,r21,16		/* bump to next entry */
	b	mpc8240InitBLoop	/* play it again sam */


mpc8240InitDone:

/* exit routine, return to caller (probably start.s) */

	or	r3,r22,r22		/* return memory size in bytes */
	mtspr	8,r20			/* restore return instruction pointer */
	bclr	20,0			/* return to caller */

	.align	3


/******************************************************************************
*
* waitRefresh - delays for at least 100 microseconds.
*
* This subroutine's purpose is delay execution for at least
* 100 micro seconds to allow a memory refresh to occur
* The routine assumes the fastest prpmc600 clock (83.33MHz).
* 83.33MHz = 83,333,333 Hz or clock cycles/sec
* Decrementer counts down 1 value in 4 clock cycles.
* Want to wait 100 usecs or .0001 seconds.
*
*	  83,333,333 * .0001 = 8333 clock cycles.
*         8333/4 = 2083 clocks. 
*
* registers used (and not saved):
*	r3
*
* RETURNS:
*     none
*/

	.text
	.align	3
	.globl	waitRefresh

waitRefresh:

	sync				/* ensure instructions are complete */
	eieio				/* ensures memory access is complete */

	li	r4, 8000              
	mtctr	r4
	eieio
	sync
PPMC8240wait8ref:
	eieio
	bdnz	PPMC8240wait8ref
/*	addis     r6,0,0x0000
	ori       r6,r6,0x1f40      
	mtctr	r6
	eieio
	sync
PPMC8240wait8ref:
	eieio
	bc	16,0,PPMC8240wait8ref*/	
	sync				
	bclr	20,0			


	.align	3

⌨️ 快捷键说明

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