123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- /*
- * Cache Ops For Loongson GS232
- *
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2010-07-09 Bernard first version
- * 2011-08-08 lgnq modified for LS1B
- * 2015-07-08 chinesebear modified for loongson 1c
- */
- #include <rtthread.h>
- #include <mips.h>
- #define K0BASE 0x80000000
- #define PRID_LS1C 0x4220
- extern void Clear_TagLo (void);
- extern void Invalidate_Icache_Ls1c(unsigned int);
- extern void Invalidate_Dcache_ClearTag_Ls1c(unsigned int);
- extern void Invalidate_Dcache_Fill_Ls1c(unsigned int);
- extern void Writeback_Invalidate_Dcache(unsigned int);
- extern void enable_cpu_cache(void);
- typedef struct cacheinfo_t
- {
- unsigned int icache_size;
- unsigned int dcache_size;
- unsigned int icacheline_size;
- unsigned int dcacheline_size;
- } cacheinfo_t ;
- typedef struct cacheop_t
- {
- void (*Clear_TagLo) (void);
- void (*Invalidate_Icache) (unsigned int);
- void (*Invalidate_Dcache_Fill) (unsigned int);
- void (*Invalidate_Dcache_ClearTag) (unsigned int);
- void (*Init_Cache)(void);
- } cacheop_t ;
- static cacheop_t cacheop, *pcacheop;
- static cacheinfo_t cacheinfo, *pcacheinfo;
- int identify_cpu(void)
- {
- unsigned int cpu_id;
- pcacheop = &cacheop;
- pcacheinfo = &cacheinfo;
- rt_kprintf("CPU configure: 0x%08x\n", read_c0_config());
- cpu_id = read_c0_prid();
- switch (cpu_id)
- {
- case PRID_LS1C:
- rt_kprintf("CPU:Loongson 1C\n");
- pcacheop->Clear_TagLo = Clear_TagLo;
- pcacheop->Invalidate_Icache = Invalidate_Icache_Ls1c;
- pcacheop->Invalidate_Dcache_Fill = Invalidate_Dcache_Fill_Ls1c;
- pcacheop->Invalidate_Dcache_ClearTag = Invalidate_Dcache_ClearTag_Ls1c;
- break;
- default:
- rt_kprintf("Unknown CPU type, system halted!\n");
- while (1)
- {
- ;
- }
- break;
- }
- return 0;
- }
- void probe_cache(void)
- {
- unsigned int config1 = read_c0_config1();
- unsigned int icache_size, icache_line_size, icache_sets, icache_ways;
- unsigned int dcache_size, dcache_line_size, dcache_sets, dcache_ways;
- if ((icache_line_size = ((config1 >> 19) & 7)))
- icache_line_size = 2 << icache_line_size;
- else
- icache_line_size = icache_line_size;
- icache_sets = 64 << ((config1 >> 22) & 7);
- icache_ways = 1 + ((config1 >> 16) & 7);
- icache_size = icache_sets * icache_ways * icache_line_size;
- if ((dcache_line_size = ((config1 >> 10) & 7)))
- dcache_line_size = 2 << dcache_line_size;
- else
- dcache_line_size = dcache_line_size;
- dcache_sets = 64 << ((config1 >> 13) & 7);
- dcache_ways = 1 + ((config1 >> 7) & 7);
- dcache_size = dcache_sets * dcache_ways * dcache_line_size;
- rt_kprintf("DCache %2dkb, linesize %d bytes.\n", dcache_size >> 10, dcache_line_size);
- rt_kprintf("ICache %2dkb, linesize %d bytes.\n", icache_size >> 10, icache_line_size);
- pcacheinfo->icache_size = icache_size;
- pcacheinfo->dcache_size = dcache_size;
- pcacheinfo->icacheline_size = icache_line_size;
- pcacheinfo->dcacheline_size = dcache_line_size;
- return ;
- }
- void invalidate_writeback_dcache_all(void)
- {
- unsigned int start = K0BASE;
- unsigned int end = (start + pcacheinfo->dcache_size);
- while (start < end)
- {
- Writeback_Invalidate_Dcache(start); //hit writeback invalidate
- start += pcacheinfo->dcacheline_size;
- }
- }
- void invalidate_writeback_dcache(unsigned long addr, int size)
- {
- unsigned long start, end;
- start = (addr +pcacheinfo->dcacheline_size -1) & (- pcacheinfo->dcacheline_size);
- end = (end + size + pcacheinfo->dcacheline_size -1) & ( -pcacheinfo->dcacheline_size);
- while (start <end)
- {
- Writeback_Invalidate_Dcache(start);
- start += pcacheinfo->dcacheline_size;
- }
- }
- void invalidate_icache_all(void)
- {
- unsigned int start = K0BASE;
- unsigned int end = (start + pcacheinfo->icache_size);
- while (start < end)
- {
- pcacheop->Invalidate_Icache(start);
- start += pcacheinfo->icacheline_size;
- }
- }
- void invalidate_dcache_all(void)
- {
- unsigned int start = K0BASE;
- unsigned int end = (start + pcacheinfo->dcache_size);
- while (start <end)
- {
- Invalidate_Dcache_Fill_Ls1c(start);
- start += pcacheinfo->icacheline_size;
- }
- }
- //with cache disabled
- void init_dcache(void)
- {
- unsigned int start = K0BASE;
- unsigned int end = (start + pcacheinfo->dcache_size);
- while (start < end)
- {
- pcacheop->Invalidate_Dcache_ClearTag(start);
- start += pcacheinfo->dcacheline_size;
- }
- }
- void rt_hw_cache_init(void)
- {
- unsigned int start, end;
- /* 1. identify cpu and probe cache */
- identify_cpu();
- probe_cache();
- start = K0BASE;
- end = (start + pcacheinfo->icache_size);
- /*
- * 2. clear CP0 taglo/taghi register;
- */
- pcacheop->Clear_TagLo();
- /*
- * 3. invalidate instruction cache;
- */
- while (start < end)
- {
- pcacheop->Invalidate_Icache(start); //index invalidate icache
- start += pcacheinfo->icacheline_size;
- }
- /*
- * 4. invalidate data cache;
- */
- start = K0BASE;
- end = (start + pcacheinfo->dcache_size);
- while(start < end)
- {
- pcacheop->Invalidate_Dcache_ClearTag(start);
- start += pcacheinfo->dcacheline_size;
- }
- start = K0BASE;
- while(start < end)
- {
- pcacheop->Invalidate_Dcache_Fill(start); //index invalidate dcache
- start += pcacheinfo->dcacheline_size;
- }
- start = K0BASE;
- while(start < end)
- {
- pcacheop->Invalidate_Dcache_ClearTag(start);
- start += pcacheinfo->dcacheline_size;
- }
- /* enable cache */
- enable_cpu_cache();
- rt_kprintf("enable cpu cache done\n");
- return ;
- }
|