mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-23 02:18:51 +09:00
![Wolfgang Denk](/assets/img/avatar_default.png)
Signed-off-by: Wolfgang Denk <wd@denx.de> [trini: Fixup common/cmd_io.c] Signed-off-by: Tom Rini <trini@ti.com>
474 lines
8.0 KiB
ArmAsm
474 lines
8.0 KiB
ArmAsm
/*
|
|
* (C) Copyright 2007
|
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
|
*
|
|
* Author: Igor Lisitsin <igor@emcraft.com>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <post.h>
|
|
#include <ppc_asm.tmpl>
|
|
#include <ppc_defs.h>
|
|
#include <asm/cache.h>
|
|
#include <asm/mmu.h>
|
|
|
|
#if CONFIG_POST & CONFIG_SYS_POST_CACHE
|
|
|
|
.text
|
|
|
|
/*
|
|
* All 44x variants deal with cache management differently
|
|
* because they have the address translation always enabled.
|
|
* The 40x ppc's don't use address translation in U-Boot at all,
|
|
* so we have to distinguish here between 40x and 44x.
|
|
*/
|
|
#ifdef CONFIG_440
|
|
/* void cache_post_disable (int tlb)
|
|
*/
|
|
cache_post_disable:
|
|
tlbre r0, r3, 0x0002
|
|
ori r0, r0, TLB_WORD2_I_ENABLE@l
|
|
tlbwe r0, r3, 0x0002
|
|
sync
|
|
isync
|
|
blr
|
|
|
|
/* void cache_post_wt (int tlb)
|
|
*/
|
|
cache_post_wt:
|
|
tlbre r0, r3, 0x0002
|
|
ori r0, r0, TLB_WORD2_W_ENABLE@l
|
|
andi. r0, r0, ~TLB_WORD2_I_ENABLE@l
|
|
tlbwe r0, r3, 0x0002
|
|
sync
|
|
isync
|
|
blr
|
|
|
|
/* void cache_post_wb (int tlb)
|
|
*/
|
|
cache_post_wb:
|
|
tlbre r0, r3, 0x0002
|
|
andi. r0, r0, ~TLB_WORD2_W_ENABLE@l
|
|
andi. r0, r0, ~TLB_WORD2_I_ENABLE@l
|
|
tlbwe r0, r3, 0x0002
|
|
sync
|
|
isync
|
|
blr
|
|
#else
|
|
/* void cache_post_disable (int tlb)
|
|
*/
|
|
cache_post_disable:
|
|
lis r0, 0x0000
|
|
ori r0, r0, 0x0000
|
|
mtdccr r0
|
|
sync
|
|
isync
|
|
blr
|
|
|
|
/* void cache_post_wt (int tlb)
|
|
*/
|
|
cache_post_wt:
|
|
lis r0, 0x8000
|
|
ori r0, r0, 0x0000
|
|
mtdccr r0
|
|
lis r0, 0x8000
|
|
ori r0, r0, 0x0000
|
|
mtdcwr r0
|
|
sync
|
|
isync
|
|
blr
|
|
|
|
/* void cache_post_wb (int tlb)
|
|
*/
|
|
cache_post_wb:
|
|
lis r0, 0x8000
|
|
ori r0, r0, 0x0000
|
|
mtdccr r0
|
|
lis r0, 0x0000
|
|
ori r0, r0, 0x0000
|
|
mtdcwr r0
|
|
sync
|
|
isync
|
|
blr
|
|
#endif
|
|
|
|
/* void cache_post_dinvalidate (void *p, int size)
|
|
*/
|
|
cache_post_dinvalidate:
|
|
dcbi r0, r3
|
|
addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
|
|
subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
|
|
bgt cache_post_dinvalidate
|
|
sync
|
|
blr
|
|
|
|
/* void cache_post_dstore (void *p, int size)
|
|
*/
|
|
cache_post_dstore:
|
|
dcbst r0, r3
|
|
addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
|
|
subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
|
|
bgt cache_post_dstore
|
|
sync
|
|
blr
|
|
|
|
/* void cache_post_dtouch (void *p, int size)
|
|
*/
|
|
cache_post_dtouch:
|
|
dcbt r0, r3
|
|
addi r3, r3, CONFIG_SYS_CACHELINE_SIZE
|
|
subic. r4, r4, CONFIG_SYS_CACHELINE_SIZE
|
|
bgt cache_post_dtouch
|
|
sync
|
|
blr
|
|
|
|
/* void cache_post_iinvalidate (void)
|
|
*/
|
|
cache_post_iinvalidate:
|
|
iccci r0, r0
|
|
sync
|
|
blr
|
|
|
|
/* void cache_post_memset (void *p, int val, int size)
|
|
*/
|
|
cache_post_memset:
|
|
mtctr r5
|
|
1:
|
|
stb r4, 0(r3)
|
|
addi r3, r3, 1
|
|
bdnz 1b
|
|
blr
|
|
|
|
/* int cache_post_check (void *p, int size)
|
|
*/
|
|
cache_post_check:
|
|
mtctr r4
|
|
1:
|
|
lbz r0, 0(r3)
|
|
addi r3, r3, 1
|
|
cmpwi r0, 0xff
|
|
bne 2f
|
|
bdnz 1b
|
|
li r3, 0
|
|
blr
|
|
2:
|
|
li r3, -1
|
|
blr
|
|
|
|
#define CACHE_POST_DISABLE() \
|
|
mr r3, r10; \
|
|
bl cache_post_disable
|
|
|
|
#define CACHE_POST_WT() \
|
|
mr r3, r10; \
|
|
bl cache_post_wt
|
|
|
|
#define CACHE_POST_WB() \
|
|
mr r3, r10; \
|
|
bl cache_post_wb
|
|
|
|
#define CACHE_POST_DINVALIDATE() \
|
|
mr r3, r11; \
|
|
mr r4, r12; \
|
|
bl cache_post_dinvalidate
|
|
|
|
#define CACHE_POST_DFLUSH() \
|
|
mr r3, r11; \
|
|
mr r4, r12; \
|
|
bl cache_post_dflush
|
|
|
|
#define CACHE_POST_DSTORE() \
|
|
mr r3, r11; \
|
|
mr r4, r12; \
|
|
bl cache_post_dstore
|
|
|
|
#define CACHE_POST_DTOUCH() \
|
|
mr r3, r11; \
|
|
mr r4, r12; \
|
|
bl cache_post_dtouch
|
|
|
|
#define CACHE_POST_IINVALIDATE() \
|
|
bl cache_post_iinvalidate
|
|
|
|
#define CACHE_POST_MEMSET(val) \
|
|
mr r3, r11; \
|
|
li r4, val; \
|
|
mr r5, r12; \
|
|
bl cache_post_memset
|
|
|
|
#define CACHE_POST_CHECK() \
|
|
mr r3, r11; \
|
|
mr r4, r12; \
|
|
bl cache_post_check; \
|
|
mr r13, r3
|
|
|
|
/*
|
|
* Write and read 0xff pattern with caching enabled.
|
|
*/
|
|
.global cache_post_test1
|
|
cache_post_test1:
|
|
mflr r9
|
|
mr r10, r3 /* tlb */
|
|
mr r11, r4 /* p */
|
|
mr r12, r5 /* size */
|
|
|
|
CACHE_POST_WB()
|
|
CACHE_POST_DINVALIDATE()
|
|
|
|
/* Write the negative pattern to the test area */
|
|
CACHE_POST_MEMSET(0xff)
|
|
|
|
/* Read the test area */
|
|
CACHE_POST_CHECK()
|
|
|
|
CACHE_POST_DINVALIDATE()
|
|
CACHE_POST_DISABLE()
|
|
|
|
mr r3, r13
|
|
mtlr r9
|
|
blr
|
|
|
|
/*
|
|
* Write zeroes with caching enabled.
|
|
* Write 0xff pattern with caching disabled.
|
|
* Read 0xff pattern with caching enabled.
|
|
*/
|
|
.global cache_post_test2
|
|
cache_post_test2:
|
|
mflr r9
|
|
mr r10, r3 /* tlb */
|
|
mr r11, r4 /* p */
|
|
mr r12, r5 /* size */
|
|
|
|
CACHE_POST_WB()
|
|
CACHE_POST_DINVALIDATE()
|
|
|
|
/* Write the zero pattern to the test area */
|
|
CACHE_POST_MEMSET(0)
|
|
|
|
CACHE_POST_DINVALIDATE()
|
|
CACHE_POST_DISABLE()
|
|
|
|
/* Write the negative pattern to the test area */
|
|
CACHE_POST_MEMSET(0xff)
|
|
|
|
CACHE_POST_WB()
|
|
|
|
/* Read the test area */
|
|
CACHE_POST_CHECK()
|
|
|
|
CACHE_POST_DINVALIDATE()
|
|
CACHE_POST_DISABLE()
|
|
|
|
mr r3, r13
|
|
mtlr r9
|
|
blr
|
|
|
|
/*
|
|
* Write-through mode test.
|
|
* Write zeroes, store the cache, write 0xff pattern.
|
|
* Invalidate the cache.
|
|
* Check that 0xff pattern is read.
|
|
*/
|
|
.global cache_post_test3
|
|
cache_post_test3:
|
|
mflr r9
|
|
mr r10, r3 /* tlb */
|
|
mr r11, r4 /* p */
|
|
mr r12, r5 /* size */
|
|
|
|
CACHE_POST_WT()
|
|
CACHE_POST_DINVALIDATE()
|
|
|
|
/* Cache the test area */
|
|
CACHE_POST_DTOUCH()
|
|
|
|
/* Write the zero pattern to the test area */
|
|
CACHE_POST_MEMSET(0)
|
|
|
|
CACHE_POST_DSTORE()
|
|
|
|
/* Write the negative pattern to the test area */
|
|
CACHE_POST_MEMSET(0xff)
|
|
|
|
CACHE_POST_DINVALIDATE()
|
|
CACHE_POST_DISABLE()
|
|
|
|
/* Read the test area */
|
|
CACHE_POST_CHECK()
|
|
|
|
mr r3, r13
|
|
mtlr r9
|
|
blr
|
|
|
|
/*
|
|
* Write-back mode test.
|
|
* Write 0xff pattern, store the cache, write zeroes.
|
|
* Invalidate the cache.
|
|
* Check that 0xff pattern is read.
|
|
*/
|
|
.global cache_post_test4
|
|
cache_post_test4:
|
|
mflr r9
|
|
mr r10, r3 /* tlb */
|
|
mr r11, r4 /* p */
|
|
mr r12, r5 /* size */
|
|
|
|
CACHE_POST_WB()
|
|
CACHE_POST_DINVALIDATE()
|
|
|
|
/* Cache the test area */
|
|
CACHE_POST_DTOUCH()
|
|
|
|
/* Write the negative pattern to the test area */
|
|
CACHE_POST_MEMSET(0xff)
|
|
|
|
CACHE_POST_DSTORE()
|
|
|
|
/* Write the zero pattern to the test area */
|
|
CACHE_POST_MEMSET(0)
|
|
|
|
CACHE_POST_DINVALIDATE()
|
|
CACHE_POST_DISABLE()
|
|
|
|
/* Read the test area */
|
|
CACHE_POST_CHECK()
|
|
|
|
mr r3, r13
|
|
mtlr r9
|
|
blr
|
|
|
|
/*
|
|
* Load the test instructions into the instruction cache.
|
|
* Replace the test instructions.
|
|
* Check that the original instructions are executed.
|
|
*/
|
|
.global cache_post_test5
|
|
cache_post_test5:
|
|
mflr r9
|
|
mr r10, r3 /* tlb */
|
|
mr r11, r4 /* p */
|
|
mr r12, r5 /* size */
|
|
|
|
CACHE_POST_WT()
|
|
CACHE_POST_IINVALIDATE()
|
|
|
|
/* Compute r13 = cache_post_test_inst */
|
|
bl cache_post_test5_reloc
|
|
cache_post_test5_reloc:
|
|
mflr r13
|
|
lis r0, (cache_post_test_inst - cache_post_test5_reloc)@h
|
|
ori r0, r0, (cache_post_test_inst - cache_post_test5_reloc)@l
|
|
add r13, r13, r0
|
|
|
|
/* Copy the test instructions to the test area */
|
|
lwz r0, 0(r13)
|
|
stw r0, 0(r11)
|
|
lwz r0, 8(r13)
|
|
stw r0, 4(r11)
|
|
sync
|
|
|
|
/* Invalidate the cache line */
|
|
icbi r0, r11
|
|
sync
|
|
isync
|
|
|
|
/* Execute the test instructions */
|
|
mtlr r11
|
|
blrl
|
|
|
|
/* Replace the test instruction */
|
|
lwz r0, 4(r13)
|
|
stw r0, 0(r11)
|
|
sync
|
|
|
|
/* Do not invalidate the cache line */
|
|
isync
|
|
|
|
/* Execute the test instructions */
|
|
mtlr r11
|
|
blrl
|
|
mr r13, r3
|
|
|
|
CACHE_POST_IINVALIDATE()
|
|
CACHE_POST_DINVALIDATE()
|
|
CACHE_POST_DISABLE()
|
|
|
|
mr r3, r13
|
|
mtlr r9
|
|
blr
|
|
|
|
/*
|
|
* Load the test instructions into the instruction cache.
|
|
* Replace the test instructions and invalidate the cache.
|
|
* Check that the replaced instructions are executed.
|
|
*/
|
|
.global cache_post_test6
|
|
cache_post_test6:
|
|
mflr r9
|
|
mr r10, r3 /* tlb */
|
|
mr r11, r4 /* p */
|
|
mr r12, r5 /* size */
|
|
|
|
CACHE_POST_WT()
|
|
CACHE_POST_IINVALIDATE()
|
|
|
|
/* Compute r13 = cache_post_test_inst */
|
|
bl cache_post_test6_reloc
|
|
cache_post_test6_reloc:
|
|
mflr r13
|
|
lis r0, (cache_post_test_inst - cache_post_test6_reloc)@h
|
|
ori r0, r0, (cache_post_test_inst - cache_post_test6_reloc)@l
|
|
add r13, r13, r0
|
|
|
|
/* Copy the test instructions to the test area */
|
|
lwz r0, 4(r13)
|
|
stw r0, 0(r11)
|
|
lwz r0, 8(r13)
|
|
stw r0, 4(r11)
|
|
sync
|
|
|
|
/* Invalidate the cache line */
|
|
icbi r0, r11
|
|
sync
|
|
isync
|
|
|
|
/* Execute the test instructions */
|
|
mtlr r11
|
|
blrl
|
|
|
|
/* Replace the test instruction */
|
|
lwz r0, 0(r13)
|
|
stw r0, 0(r11)
|
|
sync
|
|
|
|
/* Invalidate the cache line */
|
|
icbi r0, r11
|
|
sync
|
|
isync
|
|
|
|
/* Execute the test instructions */
|
|
mtlr r11
|
|
blrl
|
|
mr r13, r3
|
|
|
|
CACHE_POST_IINVALIDATE()
|
|
CACHE_POST_DINVALIDATE()
|
|
CACHE_POST_DISABLE()
|
|
|
|
mr r3, r13
|
|
mtlr r9
|
|
blr
|
|
|
|
/* Test instructions.
|
|
*/
|
|
cache_post_test_inst:
|
|
li r3, 0
|
|
li r3, -1
|
|
blr
|
|
|
|
#endif /* CONFIG_POST & CONFIG_SYS_POST_CACHE */
|