diff options
author | Roman Yeryomin <roman@advem.lv> | 2013-08-16 11:44:04 +0300 |
---|---|---|
committer | Roman Yeryomin <roman@advem.lv> | 2013-08-16 11:44:04 +0300 |
commit | dee99ab0143122146ab7713cfe171790bc796dd3 (patch) | |
tree | 907ad856f6ceae17a70dd1df004a1adee8a1b2fd /target/linux/realtek/image/lzma-loader/src/cache.c | |
parent | 4ed5985ada0f0420d69d7d959ecc3c9c8515efa0 (diff) |
Get rid of rtkload. Use OpenWrt lzma-loader (with kernel_entry hack). Use mgbin for unified tftp image generation.
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Diffstat (limited to 'target/linux/realtek/image/lzma-loader/src/cache.c')
-rw-r--r-- | target/linux/realtek/image/lzma-loader/src/cache.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/target/linux/realtek/image/lzma-loader/src/cache.c b/target/linux/realtek/image/lzma-loader/src/cache.c new file mode 100644 index 000000000..6ecb07071 --- /dev/null +++ b/target/linux/realtek/image/lzma-loader/src/cache.c @@ -0,0 +1,137 @@ +/* + * LZMA compressed kernel loader for Realtek rtl819xx + * + * Copyright (C) 2013 Roman Yeryomin <roman@advem.lv> + * + * The cache manipulation routines has been taken from + * Realtek SDK (rtlkoad utility). + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ +#include <linux/autoconf.h> +#include <linux/linkage.h> +#include <asm/ptrace.h> +#include <asm/rlxregs.h> +#include <asm/addrspace.h> + +/* For Realtek RTL865XC Network platform series */ +#define _ICACHE_SIZE (16 * 1024) /* 16K bytes */ +#define _DCACHE_SIZE (8 * 1024) /* 8K bytes */ +#define _CACHE_LINE_SIZE 4 /* 4 words */ + +void flush_cache(void); +static void flush_icache(unsigned int start, unsigned int end); +static void flush_dcache(unsigned int start, unsigned int end); + +void flush_cache(void) +{ + + flush_dcache(KSEG0, KSEG0+_DCACHE_SIZE); + flush_icache(KSEG0, KSEG0+_ICACHE_SIZE); + +} + +static void flush_icache(unsigned int start, unsigned int end) +{ + /* + * Flush data cache at first in write-back platform. + * + * Ghhuang (2007/3/9): + * RD-Center suggest that we need to flush D-cache entries which + * might match to same address as I-cache when we flush I-cache. + * (Maybe some data is treated as data/instruction, both.) + */ + flush_dcache(start, end); + + /* Invalidate I-Cache */ + __asm__ volatile( + "mtc0 $0,$20\n\t" + "nop\n\t" + "li $8,2\n\t" + "mtc0 $8,$20\n\t" + "nop\n\t" + "nop\n\t" + "mtc0 $0,$20\n\t" + "nop" + : /* no output */ + : /* no input */ + ); + +} + +static void flush_dcache(unsigned int start, unsigned int end) +{ + /* Flush D-Cache using its range */ + unsigned char *p; + unsigned int size; + unsigned int flags; + unsigned int i; + + size = end - start; + + /* correctness check : flush all if any parameter is illegal */ +// david +// if ((size >= dcache_size) || + if ((size >= _DCACHE_SIZE) || (KSEGX(start) != KSEG0)) + { + /* + * ghhguang: + * For Realtek Lexra CPU, + * the cache would NOT be flushed only if the Address to-be-flushed + * is the EXPLICIT address (which is really stored in that cache line). + * For the aliased addresses, the cache entry would NOT be flushed even + * if it matchs same cache-index. + * + * This is different from traditional MIPS-based CPU's configuration. + * So if we want to flush ALL-cache entries, we would need to use "mtc0" + * instruction instead of simply modifying the "size" to "dcache_size" + * and "start" to "KSEG0". + */ + __asm__ volatile( + "mtc0 $0,$20\n\t" + "nop\n\t" + "li $8,512\n\t" + "mtc0 $8,$20\n\t" + "nop\n\t" + "nop\n\t" + "mtc0 $0,$20\n\t" + "nop" + : /* no output */ + : /* no input */ + ); + } + else + { + /* Start to isolate cache space */ + p = (char *)start; + + flags = read_c0_status(); + + /* isolate cache space */ + write_c0_status( (ST0_ISC | flags) &~ ST0_IEC ); + + for (i = 0; i < size; i += 0x040) + { + asm ( + #ifdef OPEN_RSDK_RTL865x + ".word 0xbc750000\n\t" + ".word 0xbc750010\n\t" + ".word 0xbc750020\n\t" + ".word 0xbc750030\n\t" + #endif + "cache 0x15, 0x000(%0)\n\t" + "cache 0x15, 0x010(%0)\n\t" + "cache 0x15, 0x020(%0)\n\t" + "cache 0x15, 0x030(%0)\n\t" + : /* No output registers */ + :"r"(p) /* input : 'p' as %0 */ + ); + p += 0x040; + } + + write_c0_status(flags); + } +} |