⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icache.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
#include "koala.hh"// Reset the L1 instruction cache.voidKoala::reset_icache(){    for (int i = 0; i < icache.sets; ++i) {	for (int j = 0; j < icache.assoc; ++j)	    icache.set[i].line[j].tag = bad_tag;	icache.set[i].lru_init();    }    ibuf[0].tag = bad_ibuf_tag;    ibuf[1].tag = bad_ibuf_tag;}// Perform a cache operation (for use by decode_cache()).voidKoala::control_icache(VA va, PA pa, int op, int type){    if (type)	return; // secondary cache not presents    switch (op) {    case 0:    {	// Index Invalidate.	icache.set[icache.index(va)].line[icache.block(va)].tag = bad_tag;	break;    }    case 1:    {	// Index Load Tag.  This cannot be implemented properly as I don't	// store the tag for invalidated entries.	assert(TODO);	break;    }    case 2:    {	// Index Store Tag.  The comment from (1) applies. As ``Index Load	// Tag'' is not implemented, this may be left as a noop.	break;    }    case 4:    {	// Hit Invalidate.	UInt32 tag = icache.set[icache.index(va)].line[icache.block(va)].tag;	if (tag == icache.tag(pa))	    icache.set[icache.index(va)].line[icache.block(va)].tag = bad_tag;	break;    }    case 5:    {	// Fill.	UInt32 tag = icache.tag(pa);	ICache::Set* set = &icache.set[icache.index(va)];	ICache::Line* line = &set->line[icache.block(va)];	const VA line_mask = icache.line_size - 1;	ClockValue latency =	    bus->read(pa & ~line_mask, line->data, icache.line_size);	line->tag = (is_bus_error(latency)) ? bad_tag : tag;	break;    }    case 6:	// Hit Writeback.	break; // secondary cache not present    case 7:	// Hit Set Virtual.	break; // secondary cache not present    default:	// Everything else is ignored.	break;    }    // In all cases, invalidate the ibufs.    ibuf[0].tag  = bad_ibuf_tag;    ibuf[1].tag  = bad_ibuf_tag;}// Fetch an instruction from the virtual address (va). The address translation// has already been performed and the physical address is (pa). The coherency// algorithm to use is encoded in high-order bits of (pa) using the same// encoding as that of the xkphys address space region.// WARNING: currently, the memory access latencies are not simulated.Koala::InstrKoala::fetch(VA va, PA pa){    ClockValue latency;    int i;    int ca = coherency_algorithm(pa);    if (ca == uncached) {	// A direct memory access.	UInt64 x;	ClockValue latency = bus->read(swizzle<word>(pa), &x, 4);	if (is_bus_error(latency))	    process_bus_error(instr_fetch);	return reverse_endian() ? byte_swap(Instr(x)) : x;    }    // A cached memory access.    UInt32 index = icache.index(va);    UInt32 tag = icache.tag(pa);    ICache::Set* set = &(icache.set[index]);    ICache::Line* line = &(set->line[0]);    const VA line_mask = icache.line_size - 1;    // Find the correct entry in the set (if any).    for (int i = 0; i < icache.assoc; ++i, ++line) {	if (line->tag == tag) {	    set->lru_touch(i);	    goto cache_hit;	}    }        // Otherwise, we've got a cache miss.    i = icache.set[index].lru_replace();    line = &(icache.set[index].line[i]);    // Fill the cache line from the main memory.    latency = bus->read(pa & ~line_mask, line->data, icache.line_size);    if (is_bus_error(latency)) {	line->tag = bad_tag;	process_bus_error(instr_fetch);    }    line->tag = tag;    set->lru_touch(i); cache_hit:        // Finally, fetch the data from the cache.    ibuf[lru_ibuf].tag  = va >> log2_icache_line;    ibuf[lru_ibuf].line = line->data;    lru_ibuf = !lru_ibuf;    return swizzle<word>(line->data[(pa & line_mask) / 8], va);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -