arch/mips: simplify cache operations
Cache operations are simplified by removing assembly implementation and replacing it with simpler C code. BUG=chrome-os-partner:31438 TEST=tested on Pistachio bring up board; caches are properly invalidated; BRANCH=none Change-Id: I0f092660549c368e98c208ae0c991fe6f5a428d7 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: bf99849e75813cba865b15af9e110687816e61e4 Original-Change-Id: I965e7929718424f92f3556369d36a18ef67aa0d0 Original-Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com> Original-Reviewed-on: https://chromium-review.googlesource.com/250792 Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Reviewed-on: http://review.coreboot.org/9820 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
8cc3a2a467
commit
ef4e87b45b
|
@ -18,46 +18,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <arch/cache.h>
|
#include <arch/cache.h>
|
||||||
#include <symbols.h>
|
#include <arch/cpu.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
#include <symbols.h>
|
||||||
/* Cache operations */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* __get_line_size:
|
|
||||||
* Read config register
|
|
||||||
* Isolate instruction cache line size
|
|
||||||
* Interpret value as per MIPS manual: 2 << value
|
|
||||||
* Return cache line size
|
|
||||||
*/
|
|
||||||
#define __get_line_size(cfg_no, cfg_sel, lshift, nobits) \
|
|
||||||
({ int __res; \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
".set push\n\t" \
|
|
||||||
".set noreorder\n\t" \
|
|
||||||
".set mips32\n\t" \
|
|
||||||
"mfc0 $t5, "#cfg_no"," #cfg_sel"\n\t" \
|
|
||||||
".set mips0\n\t" \
|
|
||||||
"ext $t6, $t5," #lshift"," #nobits"\n\t" \
|
|
||||||
"li $t7, 2\n\t" \
|
|
||||||
"sllv %0, $t7, $t6\n\t" \
|
|
||||||
".set pop\n\t" \
|
|
||||||
: "=r" (__res)); \
|
|
||||||
__res; \
|
|
||||||
})
|
|
||||||
|
|
||||||
/* clear_L2tag: clear L23Tag register */
|
|
||||||
#define clear_L2tag() \
|
|
||||||
({ \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
".set push\n\t" \
|
|
||||||
".set noreorder\n\t" \
|
|
||||||
".set mips32\n\t" \
|
|
||||||
"mtc0 $zero, $28, 4\n\t" \
|
|
||||||
".set mips0\n\t" \
|
|
||||||
".set pop\n\t" \
|
|
||||||
); \
|
|
||||||
})
|
|
||||||
|
|
||||||
/* cache_op: issues cache operation for specified address */
|
/* cache_op: issues cache operation for specified address */
|
||||||
#define cache_op(op, addr) \
|
#define cache_op(op, addr) \
|
||||||
|
@ -73,12 +36,32 @@
|
||||||
: "i" (op), "R" (*(unsigned char *)(addr))); \
|
: "i" (op), "R" (*(unsigned char *)(addr))); \
|
||||||
})
|
})
|
||||||
|
|
||||||
static int get_cache_line(uint8_t type)
|
#define MIPS_CONFIG1_DL_SHIFT 10
|
||||||
|
#define MIPS_CONFIG1_DL_MASK (0x00000007)
|
||||||
|
#define MIPS_CONFIG1_IL_SHIFT 19
|
||||||
|
#define MIPS_CONFIG1_IL_MASK (0x00000007)
|
||||||
|
#define MIPS_CONFIG2_SL_SHIFT 4
|
||||||
|
#define MIPS_CONFIG2_SL_MASK (0x0000000F)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_cache_line_size:
|
||||||
|
* Read config register
|
||||||
|
* Isolate instruction cache line size
|
||||||
|
* Interpret value as per MIPS manual: 2 << value
|
||||||
|
* Return cache line size
|
||||||
|
*/
|
||||||
|
static int get_cache_line_size(uint8_t type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ICACHE: return get_icache_line();
|
case ICACHE:
|
||||||
case DCACHE: return get_dcache_line();
|
return 2 << ((read_c0_config1() >> MIPS_CONFIG1_IL_SHIFT) &
|
||||||
case L2CACHE: return get_L2cache_line();
|
MIPS_CONFIG1_IL_MASK);
|
||||||
|
case DCACHE:
|
||||||
|
return 2 << ((read_c0_config1() >> MIPS_CONFIG1_DL_SHIFT) &
|
||||||
|
MIPS_CONFIG1_DL_MASK);
|
||||||
|
case L2CACHE:
|
||||||
|
return 2 << ((read_c0_config2() >> MIPS_CONFIG2_SL_SHIFT) &
|
||||||
|
MIPS_CONFIG2_SL_MASK);
|
||||||
default:
|
default:
|
||||||
printk(BIOS_ERR, "%s: Error: unsupported cache type.\n",
|
printk(BIOS_ERR, "%s: Error: unsupported cache type.\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -92,7 +75,7 @@ void perform_cache_operation(uintptr_t start, size_t size, uint8_t operation)
|
||||||
u32 line_size, line_mask;
|
u32 line_size, line_mask;
|
||||||
uintptr_t end;
|
uintptr_t end;
|
||||||
|
|
||||||
line_size = get_cache_line((operation >> CACHE_TYPE_SHIFT) &
|
line_size = get_cache_line_size((operation >> CACHE_TYPE_SHIFT) &
|
||||||
CACHE_TYPE_MASK);
|
CACHE_TYPE_MASK);
|
||||||
if (!line_size)
|
if (!line_size)
|
||||||
return;
|
return;
|
||||||
|
@ -100,7 +83,7 @@ void perform_cache_operation(uintptr_t start, size_t size, uint8_t operation)
|
||||||
end = (start + (line_size - 1) + size) & line_mask;
|
end = (start + (line_size - 1) + size) & line_mask;
|
||||||
start &= line_mask;
|
start &= line_mask;
|
||||||
if ((operation & L2CACHE) == L2CACHE)
|
if ((operation & L2CACHE) == L2CACHE)
|
||||||
clear_L2tag();
|
write_c0_l23taglo(0);
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case CACHE_CODE(ICACHE, WB_INVD):
|
case CACHE_CODE(ICACHE, WB_INVD):
|
||||||
|
|
|
@ -23,10 +23,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define get_icache_line() __get_line_size($16, 1, 19, 3)
|
|
||||||
#define get_dcache_line() __get_line_size($16, 1, 10, 3)
|
|
||||||
#define get_L2cache_line() __get_line_size($16, 2, 4, 4)
|
|
||||||
|
|
||||||
#define CACHE_TYPE_SHIFT (0)
|
#define CACHE_TYPE_SHIFT (0)
|
||||||
#define CACHE_OP_SHIFT (2)
|
#define CACHE_OP_SHIFT (2)
|
||||||
#define CACHE_TYPE_MASK (0x3)
|
#define CACHE_TYPE_MASK (0x3)
|
||||||
|
|
|
@ -106,6 +106,13 @@ do { \
|
||||||
#define read_c0_config1() __read_32bit_c0_register($16, 1)
|
#define read_c0_config1() __read_32bit_c0_register($16, 1)
|
||||||
#define write_c0_config1(val) __write_32bit_c0_register($16, 1, (val))
|
#define write_c0_config1(val) __write_32bit_c0_register($16, 1, (val))
|
||||||
|
|
||||||
|
#define read_c0_config2() __read_32bit_c0_register($16, 2)
|
||||||
|
#define write_c0_config2(val) __write_32bit_c0_register($16, 2, (val))
|
||||||
|
|
||||||
|
#define read_c0_l23taglo() __read_32bit_c0_register($28, 4)
|
||||||
|
#define write_c0_l23taglo(val) __write_32bit_c0_register($28, 4, (val))
|
||||||
|
|
||||||
|
|
||||||
#define C0_ENTRYLO_PFN_SHIFT 6
|
#define C0_ENTRYLO_PFN_SHIFT 6
|
||||||
#define C0_ENTRYLO_WB (0x3 << 3) /* Cacheable, write-back, non-coherent */
|
#define C0_ENTRYLO_WB (0x3 << 3) /* Cacheable, write-back, non-coherent */
|
||||||
#define C0_ENTRYLO_D (0x1 << 2) /* Writeable */
|
#define C0_ENTRYLO_D (0x1 << 2) /* Writeable */
|
||||||
|
|
Loading…
Reference in New Issue