URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [OpenRISC_SIM_GCC/] [arch/] [cache.c] - Rev 799
Compare with Previous | Blame | View Log
/* * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi> * (C) Copyright 2011, Julius Baxter <julius@opencores.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ /* * copied from u-boot for OpenRISC */ #include "spr_defs.h" #include "support.h" void flush_dcache_range(unsigned long addr, unsigned long stop) { unsigned long block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16; while (addr < stop) { mtspr(SPR_DCBFR, addr); addr += block_size; } } void invalidate_dcache_range(unsigned long addr, unsigned long stop) { unsigned long block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16; while (addr < stop) { mtspr(SPR_DCBIR, addr); addr += block_size; } } static void invalidate_icache_range(unsigned long addr, unsigned long stop) { unsigned long block_size = (mfspr(SPR_ICCFGR) & SPR_ICCFGR_CBS) ? 32 : 16; unsigned long ie = icache_status(); icache_disable(); while (addr < stop) { mtspr(SPR_ICBIR, addr); addr += block_size; } if (ie) icache_enable(); } void flush_cache(unsigned long addr, unsigned long size) { flush_dcache_range(addr, addr + size); invalidate_icache_range(addr, addr + size); } int icache_status(void) { return mfspr(SPR_SR) & SPR_SR_ICE; } int checkicache(void) { unsigned long iccfgr; unsigned long cache_set_size; unsigned long cache_ways; unsigned long cache_block_size; iccfgr = mfspr(SPR_ICCFGR); cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW); cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3); cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16; return cache_set_size * cache_ways * cache_block_size; } int dcache_status(void) { return mfspr(SPR_SR) & SPR_SR_DCE; } int checkdcache(void) { unsigned long dccfgr; unsigned long cache_set_size; unsigned long cache_ways; unsigned long cache_block_size; dccfgr = mfspr(SPR_DCCFGR); cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW); cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3); cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16; return cache_set_size * cache_ways * cache_block_size; } void dcache_enable(void) { mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); } void dcache_disable(void) { mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE); } void icache_enable(void) { mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); asm volatile("l.nop"); } void icache_disable(void) { mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE); } int cache_init(void) { if (mfspr(SPR_UPR) & SPR_UPR_ICP) { icache_disable(); invalidate_icache_range(0, checkicache()); icache_enable(); } if (mfspr(SPR_UPR) & SPR_UPR_DCP) { dcache_disable(); invalidate_dcache_range(0, checkdcache()); dcache_enable(); } return 0; }