mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 12:08:19 +00:00 
			
		
		
		
	As discussed on the list, move "arch/ppc" to "arch/powerpc" to better match the Linux directory structure. Please note that this patch also changes the "ppc" target in MAKEALL to "powerpc" to match this new infrastructure. But "ppc" is kept as an alias for now, to not break compatibility with scripts using this name. Signed-off-by: Stefan Roese <sr@denx.de> Acked-by: Wolfgang Denk <wd@denx.de> Acked-by: Detlev Zundel <dzu@denx.de> Acked-by: Kim Phillips <kim.phillips@freescale.com> Cc: Peter Tyser <ptyser@xes-inc.com> Cc: Anatolij Gustschin <agust@denx.de>
		
			
				
	
	
		
			379 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			379 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| #include <config.h>
 | |
| #include <mpc86xx.h>
 | |
| #include <version.h>
 | |
| 
 | |
| #include <ppc_asm.tmpl>
 | |
| #include <ppc_defs.h>
 | |
| 
 | |
| #include <asm/cache.h>
 | |
| #include <asm/mmu.h>
 | |
| 
 | |
| #ifndef CACHE_LINE_SIZE
 | |
| # define CACHE_LINE_SIZE L1_CACHE_BYTES
 | |
| #endif
 | |
| 
 | |
| #if CACHE_LINE_SIZE == 128
 | |
| #define LG_CACHE_LINE_SIZE 7
 | |
| #elif CACHE_LINE_SIZE == 32
 | |
| #define LG_CACHE_LINE_SIZE 5
 | |
| #elif CACHE_LINE_SIZE == 16
 | |
| #define LG_CACHE_LINE_SIZE 4
 | |
| #elif CACHE_LINE_SIZE == 8
 | |
| #define LG_CACHE_LINE_SIZE 3
 | |
| #else
 | |
| # error "Invalid cache line size!"
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * Most of this code is taken from 74xx_7xx/cache.S
 | |
|  * and then cleaned up a bit
 | |
|  */
 | |
| 
 | |
| /*
 | |
|  * Invalidate L1 instruction cache.
 | |
|  */
 | |
| _GLOBAL(invalidate_l1_instruction_cache)
 | |
| 	/* use invalidate-all bit in HID0 */
 | |
| 	mfspr	r3,HID0
 | |
| 	ori	r3,r3,HID0_ICFI
 | |
| 	mtspr	HID0,r3
 | |
| 	isync
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Invalidate L1 data cache.
 | |
|  */
 | |
| _GLOBAL(invalidate_l1_data_cache)
 | |
| 	mfspr	r3,HID0
 | |
| 	ori	r3,r3,HID0_DCFI
 | |
| 	mtspr	HID0,r3
 | |
| 	isync
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Flush data cache.
 | |
|  */
 | |
| _GLOBAL(flush_dcache)
 | |
| 	lis	r3,0
 | |
| 	lis	r5,CACHE_LINE_SIZE
 | |
| flush:
 | |
| 	cmp	0,1,r3,r5
 | |
| 	bge	done
 | |
| 	lwz	r5,0(r3)
 | |
| 	lis	r5,CACHE_LINE_SIZE
 | |
| 	addi	r3,r3,0x4
 | |
| 	b	flush
 | |
| done:
 | |
| 	blr
 | |
| /*
 | |
|  * Write any modified data cache blocks out to memory
 | |
|  * and invalidate the corresponding instruction cache blocks.
 | |
|  * This is a no-op on the 601.
 | |
|  *
 | |
|  * flush_icache_range(unsigned long start, unsigned long stop)
 | |
|  */
 | |
| _GLOBAL(flush_icache_range)
 | |
| 	li	r5,CACHE_LINE_SIZE-1
 | |
| 	andc	r3,r3,r5
 | |
| 	subf	r4,r3,r4
 | |
| 	add	r4,r4,r5
 | |
| 	srwi.	r4,r4,LG_CACHE_LINE_SIZE
 | |
| 	beqlr
 | |
| 	mtctr	r4
 | |
| 	mr	r6,r3
 | |
| 1:	dcbst	0,r3
 | |
| 	addi	r3,r3,CACHE_LINE_SIZE
 | |
| 	bdnz	1b
 | |
| 	sync				/* wait for dcbst's to get to ram */
 | |
| 	mtctr	r4
 | |
| 2:	icbi	0,r6
 | |
| 	addi	r6,r6,CACHE_LINE_SIZE
 | |
| 	bdnz	2b
 | |
| 	sync				/* additional sync needed on g4 */
 | |
| 	isync
 | |
| 	blr
 | |
| /*
 | |
|  * Write any modified data cache blocks out to memory.
 | |
|  * Does not invalidate the corresponding cache lines (especially for
 | |
|  * any corresponding instruction cache).
 | |
|  *
 | |
|  * clean_dcache_range(unsigned long start, unsigned long stop)
 | |
|  */
 | |
| _GLOBAL(clean_dcache_range)
 | |
| 	li	r5,CACHE_LINE_SIZE-1
 | |
| 	andc	r3,r3,r5	/* align r3 down to cache line */
 | |
| 	subf	r4,r3,r4	/* r4 = offset of stop from start of cache line */
 | |
| 	add	r4,r4,r5	/* r4 += cache_line_size-1 */
 | |
| 	srwi.	r4,r4,LG_CACHE_LINE_SIZE  /* r4 = number of cache lines to flush */
 | |
| 	beqlr				  /* if r4 == 0 return */
 | |
| 	mtctr	r4			  /* ctr = r4 */
 | |
| 
 | |
| 	sync
 | |
| 1:	dcbst	0,r3
 | |
| 	addi	r3,r3,CACHE_LINE_SIZE
 | |
| 	bdnz	1b
 | |
| 	sync				/* wait for dcbst's to get to ram */
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Write any modified data cache blocks out to memory
 | |
|  * and invalidate the corresponding instruction cache blocks.
 | |
|  *
 | |
|  * flush_dcache_range(unsigned long start, unsigned long stop)
 | |
|  */
 | |
| _GLOBAL(flush_dcache_range)
 | |
| 	li	r5,CACHE_LINE_SIZE-1
 | |
| 	andc	r3,r3,r5
 | |
| 	subf	r4,r3,r4
 | |
| 	add	r4,r4,r5
 | |
| 	srwi.	r4,r4,LG_CACHE_LINE_SIZE
 | |
| 	beqlr
 | |
| 	mtctr	r4
 | |
| 
 | |
| 	sync
 | |
| 1:	dcbf	0,r3
 | |
| 	addi	r3,r3,CACHE_LINE_SIZE
 | |
| 	bdnz	1b
 | |
| 	sync				/* wait for dcbf's to get to ram */
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Like above, but invalidate the D-cache.  This is used by the 8xx
 | |
|  * to invalidate the cache so the PPC core doesn't get stale data
 | |
|  * from the CPM (no cache snooping here :-).
 | |
|  *
 | |
|  * invalidate_dcache_range(unsigned long start, unsigned long stop)
 | |
|  */
 | |
| _GLOBAL(invalidate_dcache_range)
 | |
| 	li	r5,CACHE_LINE_SIZE-1
 | |
| 	andc	r3,r3,r5
 | |
| 	subf	r4,r3,r4
 | |
| 	add	r4,r4,r5
 | |
| 	srwi.	r4,r4,LG_CACHE_LINE_SIZE
 | |
| 	beqlr
 | |
| 	mtctr	r4
 | |
| 
 | |
| 	sync
 | |
| 1:	dcbi	0,r3
 | |
| 	addi	r3,r3,CACHE_LINE_SIZE
 | |
| 	bdnz	1b
 | |
| 	sync				/* wait for dcbi's to get to ram */
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Flush a particular page from the data cache to RAM.
 | |
|  * Note: this is necessary because the instruction cache does *not*
 | |
|  * snoop from the data cache.
 | |
|  *
 | |
|  *	void __flush_page_to_ram(void *page)
 | |
|  */
 | |
| _GLOBAL(__flush_page_to_ram)
 | |
| 	rlwinm	r3,r3,0,0,19		/* Get page base address */
 | |
| 	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
 | |
| 	mtctr	r4
 | |
| 	mr	r6,r3
 | |
| 0:	dcbst	0,r3			/* Write line to ram */
 | |
| 	addi	r3,r3,CACHE_LINE_SIZE
 | |
| 	bdnz	0b
 | |
| 	sync
 | |
| 	mtctr	r4
 | |
| 1:	icbi	0,r6
 | |
| 	addi	r6,r6,CACHE_LINE_SIZE
 | |
| 	bdnz	1b
 | |
| 	sync
 | |
| 	isync
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Flush a particular page from the instruction cache.
 | |
|  * Note: this is necessary because the instruction cache does *not*
 | |
|  * snoop from the data cache.
 | |
|  *
 | |
|  *	void __flush_icache_page(void *page)
 | |
|  */
 | |
| _GLOBAL(__flush_icache_page)
 | |
| 	li	r4,4096/CACHE_LINE_SIZE	/* Number of lines in a page */
 | |
| 	mtctr	r4
 | |
| 1:	icbi	0,r3
 | |
| 	addi	r3,r3,CACHE_LINE_SIZE
 | |
| 	bdnz	1b
 | |
| 	sync
 | |
| 	isync
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Clear a page using the dcbz instruction, which doesn't cause any
 | |
|  * memory traffic (except to write out any cache lines which get
 | |
|  * displaced).  This only works on cacheable memory.
 | |
|  */
 | |
| _GLOBAL(clear_page)
 | |
| 	li	r0,4096/CACHE_LINE_SIZE
 | |
| 	mtctr	r0
 | |
| 1:	dcbz	0,r3
 | |
| 	addi	r3,r3,CACHE_LINE_SIZE
 | |
| 	bdnz	1b
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Enable L1 Instruction cache
 | |
|  */
 | |
| _GLOBAL(icache_enable)
 | |
| 	mfspr	r3, HID0
 | |
| 	li	r5, HID0_ICFI|HID0_ILOCK
 | |
| 	andc	r3, r3, r5
 | |
| 	ori	r3, r3, HID0_ICE
 | |
| 	ori	r5, r3, HID0_ICFI
 | |
| 	mtspr	HID0, r5
 | |
| 	mtspr	HID0, r3
 | |
| 	isync
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Disable L1 Instruction cache
 | |
|  */
 | |
| _GLOBAL(icache_disable)
 | |
| 	mflr	r4
 | |
| 	bl	invalidate_l1_instruction_cache		/* uses r3 */
 | |
| 	sync
 | |
| 	mtlr	r4
 | |
| 	mfspr	r3, HID0
 | |
| 	li	r5, 0
 | |
| 	ori	r5, r5, HID0_ICE
 | |
| 	andc	r3, r3, r5
 | |
| 	mtspr	HID0, r3
 | |
| 	isync
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Is instruction cache enabled?
 | |
|  */
 | |
| _GLOBAL(icache_status)
 | |
| 	mfspr	r3, HID0
 | |
| 	andi.	r3, r3, HID0_ICE
 | |
| 	blr
 | |
| 
 | |
| 
 | |
| _GLOBAL(l1dcache_enable)
 | |
| 	mfspr	r3, HID0
 | |
| 	li	r5, HID0_DCFI|HID0_DLOCK
 | |
| 	andc	r3, r3, r5
 | |
| 	mtspr	HID0, r3		/* no invalidate, unlock */
 | |
| 	ori	r3, r3, HID0_DCE
 | |
| 	ori	r5, r3, HID0_DCFI
 | |
| 	mtspr	HID0, r5		/* enable + invalidate */
 | |
| 	mtspr	HID0, r3		/* enable */
 | |
| 	sync
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Enable data cache(s) - L1 and optionally L2
 | |
|  * Calls l2cache_enable. LR saved in r5
 | |
|  */
 | |
| _GLOBAL(dcache_enable)
 | |
| 	mfspr	r3, HID0
 | |
| 	li	r5, HID0_DCFI|HID0_DLOCK
 | |
| 	andc	r3, r3, r5
 | |
| 	mtspr	HID0, r3		/* no invalidate, unlock */
 | |
| 	ori	r3, r3, HID0_DCE
 | |
| 	ori	r5, r3, HID0_DCFI
 | |
| 	mtspr	HID0, r5		/* enable + invalidate */
 | |
| 	mtspr	HID0, r3		/* enable */
 | |
| 	sync
 | |
| #ifdef CONFIG_SYS_L2
 | |
| 	mflr	r5
 | |
| 	bl	l2cache_enable		/* uses r3 and r4 */
 | |
| 	sync
 | |
| 	mtlr	r5
 | |
| #endif
 | |
| 	blr
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Disable data cache(s) - L1 and optionally L2
 | |
|  * Calls flush_dcache and l2cache_disable_no_flush.
 | |
|  * LR saved in r4
 | |
|  */
 | |
| _GLOBAL(dcache_disable)
 | |
| 	mflr	r4			/* save link register */
 | |
| 	bl	flush_dcache	/* uses r3 and r5 */
 | |
| 	sync
 | |
| 	mfspr	r3, HID0
 | |
| 	li	r5, HID0_DCFI|HID0_DLOCK
 | |
| 	andc	r3, r3, r5
 | |
| 	mtspr	HID0, r3		/* no invalidate, unlock */
 | |
| 	li	r5, HID0_DCE|HID0_DCFI
 | |
| 	andc	r3, r3, r5		/* no enable, no invalidate */
 | |
| 	mtspr	HID0, r3
 | |
| 	sync
 | |
| #ifdef CONFIG_SYS_L2
 | |
| 	bl	l2cache_disable_no_flush /* uses r3 */
 | |
| #endif
 | |
| 	mtlr	r4			/* restore link register */
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Is data cache enabled?
 | |
|  */
 | |
| _GLOBAL(dcache_status)
 | |
| 	mfspr	r3, HID0
 | |
| 	andi.	r3, r3, HID0_DCE
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Invalidate L2 cache using L2I, assume L2 is enabled
 | |
|  */
 | |
| _GLOBAL(l2cache_invalidate)
 | |
| 	mfspr	r3, l2cr
 | |
| 	rlwinm.	r3, r3, 0, 0, 0
 | |
| 	beq	1f
 | |
| 
 | |
| 	mfspr	r3, l2cr
 | |
| 	rlwinm	r3, r3, 0, 1, 31
 | |
| 
 | |
| #ifdef	CONFIG_ALTIVEC
 | |
| 	dssall
 | |
| #endif
 | |
| 	sync
 | |
| 	mtspr	l2cr, r3
 | |
| 	sync
 | |
| 1:	mfspr	r3, l2cr
 | |
| 	oris	r3, r3, L2CR_L2I@h
 | |
| 	mtspr	l2cr, r3
 | |
| 
 | |
| invl2:
 | |
| 	mfspr	r3, l2cr
 | |
| 	andis.	r3, r3, L2CR_L2I@h
 | |
| 	bne	invl2
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Enable L2 cache
 | |
|  * Calls l2cache_invalidate. LR is saved in r4
 | |
|  */
 | |
| _GLOBAL(l2cache_enable)
 | |
| 	mflr	r4			/* save link register */
 | |
| 	bl	l2cache_invalidate	/* uses r3 */
 | |
| 	sync
 | |
| 	lis	r3, L2_ENABLE@h
 | |
| 	ori	r3, r3, L2_ENABLE@l
 | |
| 	mtspr	l2cr, r3
 | |
| 	isync
 | |
| 	mtlr	r4			/* restore link register */
 | |
| 	blr
 | |
| 
 | |
| /*
 | |
|  * Disable L2 cache
 | |
|  * Calls flush_dcache. LR is saved in r4
 | |
|  */
 | |
| _GLOBAL(l2cache_disable)
 | |
| 	mflr	r4			/* save link register */
 | |
| 	bl	flush_dcache		/* uses r3 and r5 */
 | |
| 	sync
 | |
| 	mtlr	r4			/* restore link register */
 | |
| l2cache_disable_no_flush:		/* provide way to disable L2 w/o flushing */
 | |
| 	lis	r3, L2_INIT@h
 | |
| 	ori	r3, r3, L2_INIT@l
 | |
| 	mtspr	l2cr, r3
 | |
| 	isync
 | |
| 	blr
 |