📄 icache.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 + -