📄 idtmem.s
字号:
_oploopn(kva, n, cache_linesize, tag, ops) ; \9:#define icacheop(kva, n, cache_size, cache_linesize, op) \ icacheopn(kva, n, cache_size, cache_linesize, 1, (op))#define vcacheop(kva, n, cache_size, cache_linesize, op) \ vcacheopn(kva, n, cache_size, cache_linesize, 1, (op)) .text/* * static void _size_cache() R4000 * * Internal routine to determine cache sizes by looking at R4000 config * register. Sizes are returned in registers, as follows: * t2 icache size * t3 dcache size * t6 scache size * t4 icache line size * t5 dcache line size * t7 scache line size */LEAF(_size_cache) mfc0 t0,C0_CONFIG and t1,t0,CFG_ICMASK srl t1,CFG_ICSHIFT li t2,0x1000 sll t2,t1 and t1,t0,CFG_DCMASK srl t1,CFG_DCSHIFT li t3,0x1000 sll t3,t1 li t4,32 and t1,t0,CFG_IB bnez t1,1f li t4,161: li t5,32 and t1,t0,CFG_DB bnez t1,1f li t5,161: move t6,zero # default to no scache move t7,zero # and t1,t0,CFG_C_UNCACHED # test config register bnez t1,1f # no scache if uncached/non-coherent li t6,0x100000 # assume 1Mb scache <<-NOTE and t1,t0,CFG_SBMASK srl t1,CFG_SBSHIFT li t7,16 sll t7,t11: j raEND(_size_cache)/* * void config_cache() R4000 * * Work out size of I, D & S caches, assuming they are already initialised. */LEAF(config_cache) lw t0,icache_size bgtz t0,8f # already known? move v0,ra bal _size_cache move ra,v0 sw t2,icache_size sw t3,dcache_size sw t6,scache_size sw t4,icache_linesize sw t5,dcache_linesize sw t7,scache_linesize8: j raEND(config_cache)/* * void _init_cache() R4000 */LEAF(_init_cache) /* * First work out the sizes */ move v0,ra bal _size_cache move ra,v0 /* * The caches may be in an indeterminate state, * so we force good parity into them by doing an * invalidate, load/fill, invalidate for each line. */ /* disable all i/u and cache exceptions */ mfc0 v0,C0_SR and v1,v0,~SR_IE or v1,SR_DE mtc0 v1,C0_SR mtc0 zero,C0_TAGLO mtc0 zero,C0_TAGHI /* assume bottom of RAM will generate good parity for the cache */ li a0,PHYS_TO_K0(0) move a2,t2 # icache_size move a3,t4 # icache_linesize move a1,a2 icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill_I)) li a0,PHYS_TO_K0(0) move a2,t3 # dcache_size move a3,t5 # dcache_linesize move a1,a2 icacheopn(a0,a1,a2,a3,1lw1,(Index_Store_Tag_D)) /* assume unified I & D in scache <<-NOTE */ blez t6,1f li a0,PHYS_TO_K0(0) move a2,t6 move a3,t7 move a1,a2 icacheopn(a0,a1,a2,a3,1lw1,(Index_Store_Tag_SD))1: mtc0 v0,C0_SR j raEND(_init_cache) /* * void flush_cache (void) R4000 * * Flush and invalidate all caches */LEAF(flush_cache) /* secondary cacheops do all the work if present */ lw a2,scache_size blez a2,1f lw a3,scache_linesize li a0,PHYS_TO_K0(0) move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_SD) b 2f1: lw a2,icache_size blez a2,2f lw a3,icache_linesize li a0,PHYS_TO_K0(0) move a1,a2 icacheop(a0,a1,a2,a3,Index_Invalidate_I) lw a2,dcache_size lw a3,dcache_linesize li a0,PHYS_TO_K0(0) move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)2: j raEND(flush_cache) /* * void flush_cache_nowrite (void) R4000 * * Invalidate all caches */LEAF(flush_cache_nowrite) mfc0 v0,C0_SR and v1,v0,~SR_IE mtc0 v1,C0_SR mtc0 zero,C0_TAGLO mtc0 zero,C0_TAGHI lw a2,icache_size blez a2,2f lw a3,icache_linesize li a0,PHYS_TO_K0(0) move a1,a2 icacheop(a0,a1,a2,a3,Index_Invalidate_I) lw a2,dcache_size lw a3,dcache_linesize li a0,PHYS_TO_K0(0) move a1,a2 icacheop(a0,a1,a2,a3,Index_Store_Tag_D) lw a2,scache_size blez a2,2f lw a3,scache_linesize li a0,PHYS_TO_K0(0) move a1,a2 icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)2: mtc0 v0,C0_SR j raEND(flush_cache_nowrite) /* * void clean_cache (unsigned kva, size_t n) R4000 * * Writeback and invalidate address range in all caches */LEAF(clean_cache)XLEAF(clear_cache) /* secondary cacheops do all the work (if fitted) */ lw a2,scache_size blez a2,1f lw a3,scache_linesize vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_SD) b 2f1: lw a2,icache_size blez a2,2f lw a3,icache_linesize /* save kva & n for subsequent loop */ move t8,a0 move t9,a1 vcacheop(a0,a1,a2,a3,Hit_Invalidate_I) lw a2,dcache_size lw a3,dcache_linesize /* restore kva & n */ move a0,t8 move a1,t9 vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_D)2: j raEND(clean_cache) /* * void clean_dcache (unsigned kva, size_t n) R4000 * * Writeback and invalidate address range in primary data cache */LEAF(clean_dcache) lw a2,dcache_size blez a2,2f lw a3,dcache_linesize vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_D)2: j raEND(clean_dcache) /* * void clean_dcache_indexed (unsigned kva, size_t n) R4000 * * Writeback and invalidate indexed range in primary data cache */LEAF(clean_dcache_indexed) lw a2,dcache_size blez a2,2f lw a3,dcache_linesize#ifdef CPU_ORION srl a2,1 # do one set (half cache) at a time move t8,a0 # save kva & n move t9,a1 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D) addu a0,t8,a2 # do next set move a1,t9 # restore n#endif icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)2: j raEND(clean_dcache_indexed) /* * void clean_dcache_nowrite (unsigned kva, size_t n) R4000 * * Invalidate an address range in primary data cache */LEAF(clean_dcache_nowrite) lw a2,dcache_size blez a2,2f lw a3,dcache_linesize vcacheop(a0,a1,a2,a3,Hit_Invalidate_D)2: j raEND(clean_dcache_nowrite) /* * void clean_dcache_nowrite_indexed (unsigned kva, size_t n) R4000 * * Invalidate indexed range in primary data cache */LEAF(clean_dcache_nowrite_indexed) mfc0 v0,C0_SR and v1,v0,~SR_IE mtc0 v1,C0_SR mtc0 zero,C0_TAGLO mtc0 zero,C0_TAGHI lw a2,dcache_size blez a2,2f lw a3,dcache_linesize#ifdef CPU_ORION srl a2,1 # do one set (half cache) at a time move t8,a0 # save kva & n move t9,a1 icacheop(a0,a1,a2,a3,Index_Store_Tag_D) addu a0,t8,a2 # do next set move a1,t9 # restore n#endif icacheop(a0,a1,a2,a3,Index_Store_Tag_D)2: mtc0 v0,C0_SR j raEND(clean_dcache_nowrite_indexed) /* * void clean_icache (unsigned kva, size_t n) R4000 * * Invalidate address range in primary instruction cache */LEAF(clean_icache) lw a2,icache_size blez a2,2f lw a3,icache_linesize vcacheop(a0,a1,a2,a3,Hit_Invalidate_I)2: j raEND(clean_icache) /* * void clean_icache_indexed (unsigned kva, size_t n) R4000 * * Invalidate indexed range in primary instruction cache */LEAF(clean_icache_indexed) lw a2,icache_size blez a2,2f lw a3,icache_linesize#ifdef CPU_ORION srl a2,1 # do one set (half cache) at a time move t8,a0 # save kva & n move t9,a1 icacheop(a0,a1,a2,a3,Index_Invalidate_I) addu a0,t8,a2 # do next set move a1,t9 # restore n#endif icacheop(a0,a1,a2,a3,Index_Invalidate_I)2: j raEND(clean_icache_indexed) /* * void clean_scache (unsigned kva, size_t n) R4000 * * Writeback and invalidate address range in secondary cache */LEAF(clean_scache) lw a2,scache_size blez a2,2f lw a3,scache_linesize vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_SD)2: j raEND(clean_scache) /* * void clean_scache_indexed (unsigned kva, size_t n) R4000 * * Writeback and invalidate indexed range in secondary cache */LEAF(clean_scache_indexed) lw a2,scache_size blez a2,2f lw a3,scache_linesize icacheop(a0,a1,a2,a3,Index_Writeback_Inv_SD)2: j raEND(clean_scache_indexed) /* * void clean_scache_nowrite (unsigned kva, size_t n) R4000 * * Invalidate an address range in secondary cache */LEAF(clean_scache_nowrite) lw a2,scache_size blez a2,2f lw a3,scache_linesize vcacheop(a0,a1,a2,a3,Hit_Invalidate_SD)2: j raEND(clean_scache_nowrite) /* * void clean_scache_nowrite_indexed (unsigned kva, size_t n) R4000 * * Invalidate indexed range in secondary cache */LEAF(clean_scache_nowrite_indexed) mfc0 v0,C0_SR and v1,v0,~SR_IE mtc0 v1,C0_SR mtc0 zero,C0_TAGLO mtc0 zero,C0_TAGHI lw a2,scache_size blez a2,2f lw a3,scache_linesize icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)2: mtc0 v0,C0_SR j raEND(clean_scache_nowrite_indexed) /****************************************************************************** get_mem_conf - get memory configuration R4000*****************************************************************************/FRAME(get_mem_conf,sp,0,ra) lw t6, mem_size sw t6, 0(a0) lw t7, icache_size sw t7, 4(a0) lw t8, dcache_size sw t8, 8(a0) lw t7, scache_size sw t7, 12(a0) j raENDFRAME(get_mem_conf)#endif /* defined(CPU_R4000) *//* * void set_mem_size (mem_size) * * config_memory()'s memory size gets written into mem_size here. * Now we don't need to call config_cache() with memory size - New to IDTC6.0 */FRAME(set_memory_size,sp,0,ra) sw a0, mem_size j raENDFRAME(set_memory_size)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -