| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 | /* * File      : mips_cache.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team * *  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., *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date           Author       Notes * 2016-09-07    Urey         the first version */#include <rtthread.h>#include "mips.h"extern void cache_init(rt_ubase_t cache_size, rt_ubase_t cache_line_size);void r4k_cache_init(void){//	cache_init(dcache_size, cpu_dcache_line_size);}void r4k_cache_flush_all(void){    blast_dcache16();    blast_icache16();}void r4k_icache_flush_all(void){    blast_icache16();}void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size){	rt_ubase_t end, a;    if (size > g_mips_core.icache_size)    {        blast_icache16();    }    else    {    	rt_ubase_t ic_lsize = g_mips_core.icache_line_size;        a = addr & ~(ic_lsize - 1);        end = ((addr + size) - 1) & ~(ic_lsize - 1);        while (1)        {            flush_icache_line(a);            if (a == end)                break;            a += ic_lsize;        }    }}void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size){	rt_ubase_t end, a;	rt_ubase_t ic_lsize = g_mips_core.icache_line_size;    a = addr & ~(ic_lsize - 1);    end = ((addr + size) - 1) & ~(ic_lsize - 1);    while (1)    {        lock_icache_line(a);        if (a == end)            break;        a += ic_lsize;    }}void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size){	rt_ubase_t end, a;    rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;    a = addr & ~(dc_lsize - 1);    end = ((addr + size) - 1) & ~(dc_lsize - 1);    while (1)    {        invalidate_dcache_line(a);        if (a == end)            break;        a += dc_lsize;    }}void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size){	rt_ubase_t end, a;    if (size >= g_mips_core.dcache_size)    {        blast_dcache16();    }    else    {    	rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;        a = addr & ~(dc_lsize - 1);        end = ((addr + size) - 1) & ~(dc_lsize - 1);        while (1)        {            flush_dcache_line(a);            if (a == end)                break;            a += dc_lsize;        }    }}#define dma_cache_wback_inv(start,size) \    do { (void) (start); (void) (size); } while (0)#define dma_cache_wback(start,size) \    do { (void) (start); (void) (size); } while (0)#define dma_cache_inv(start,size)   \    do { (void) (start); (void) (size); } while (0)void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction){    switch (direction)    {        case DMA_TO_DEVICE:            r4k_dcache_wback_inv(addr, size);        break;        case DMA_FROM_DEVICE:            r4k_dcache_wback_inv(addr, size);        break;        case DMA_BIDIRECTIONAL:            dma_cache_wback_inv(addr, size);        break;        default:            RT_ASSERT(0) ;    }}
 |