u-boot-brain/arch/powerpc/cpu/mpc86xx/cache.S
Rob Herring 7682a99826 remove unnecessary version.h includes
Various files are needlessly rebuilt every time due to the version and
build time changing. As version.h is not actually needed, remove the
include.

Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Albert Aribaud <albert.u.boot@aribaud.net>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Minkyu Kang <mk7.kang@samsung.com>
Cc: Marek Vasut <marex@denx.de>
Cc: Tom Warren <twarren@nvidia.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Macpaul Lin <macpaul@andestech.com>
Cc: Wolfgang Denk <wd@denx.de>
Cc: York Sun <yorksun@freescale.com>
Cc: Stefan Roese <sr@denx.de>
Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Philippe Reynes <tremyfr@yahoo.fr>
Cc: Eric Jarrige <eric.jarrige@armadeus.org>
Cc: "David Müller" <d.mueller@elsoft.ch>
Cc: Phil Edworthy <phil.edworthy@renesas.com>
Cc: Robert Baldyga <r.baldyga@samsung.com>
Cc: Torsten Koschorrek <koschorrek@synertronixx.de>
Cc: Anatolij Gustschin <agust@denx.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Łukasz Majewski <l.majewski@samsung.com>
2015-03-24 10:50:50 -04:00

378 lines
7.3 KiB
ArmAsm

#include <config.h>
#include <mpc86xx.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