Skip to content

Commit 74e3b99

Browse files
committed
Refactor and document I-cache, fix tag calculation
- Rename I-cache structures from ic to icache to avoid ambiguity. - Add explanations for instruction-cache definitions and masks, and align the macro names with the terminology used in the comments. - Fix tag calculation to use the precomputed tag rather than shifting the physical address.
1 parent 0e4f67b commit 74e3b99

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

riscv.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,9 @@ static void mmu_fence(hart_t *vm, uint32_t insn UNUSED)
309309
static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
310310
{
311311
/* cache hit */
312-
uint32_t idx = (addr >> IC_SHIFT) & IC_INDEX_MASK;
313-
uint32_t tag = addr >> (IC_SHIFT + IC_INDEX_BITS);
314-
ic_block_t *blk = &vm->ic.block[idx];
312+
uint32_t idx = (addr >> IC_OFFSET_BITS) & IC_INDEX_MASK;
313+
uint32_t tag = addr >> (IC_OFFSET_BITS + IC_INDEX_BITS);
314+
icache_block_t *blk = &vm->ic.block[idx];
315315

316316
if (likely(blk->valid && blk->tag == tag)) {
317317
#ifdef MMU_CACHE_STATS
@@ -346,7 +346,7 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
346346
/* fill into the cache */
347347
uint32_t block_off = (addr & RV_PAGE_MASK) & ~IC_BLOCK_MASK;
348348
blk->base = (const uint8_t *) vm->cache_fetch.page_addr + block_off;
349-
blk->tag = addr >> (IC_SHIFT + IC_INDEX_BITS);
349+
blk->tag = tag;
350350
blk->valid = true;
351351
}
352352

riscv.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,25 @@ typedef struct {
6969
typedef struct __hart_internal hart_t;
7070
typedef struct __vm_internel vm_t;
7171

72+
/* IC_BLOCKS_SIZE: Size of one instruction-cache block (line).
73+
* IC_BLOCKS: Number of blocks (lines) in the instruction cache.
74+
*
75+
* The cache address is decomposed into [ tag | index | offset ] fields:
76+
* - block-offset bits = log2(IC_BLOCKS_SIZE)
77+
* - index bits = log2(IC_BLOCKS)
78+
*
79+
* For power-of-two values, log2(x) equals the number of trailing zero bits in
80+
* x. Therefore, we use __builtin_ctz(x) (count trailing zeros) to compute these
81+
* log2 values at compile time.
82+
*/
7283
#define IC_BLOCKS_SIZE 256
7384
#define IC_BLOCKS 256
74-
#define IC_SHIFT (__builtin_ctz((IC_BLOCKS_SIZE)))
85+
#define IC_OFFSET_BITS (__builtin_ctz((IC_BLOCKS_SIZE)))
7586
#define IC_INDEX_BITS (__builtin_ctz((IC_BLOCKS)))
87+
88+
/* For power-of-two sizes, (size - 1) sets all low bits to 1,
89+
* allowing fast extraction of an address.
90+
*/
7691
#define IC_INDEX_MASK (IC_BLOCKS - 1)
7792
#define IC_BLOCK_MASK (IC_BLOCKS_SIZE - 1)
7893
#define RV_PAGE_MASK (RV_PAGE_SIZE - 1)
@@ -81,14 +96,14 @@ typedef struct {
8196
uint32_t tag;
8297
const uint8_t *base;
8398
bool valid;
84-
} ic_block_t;
99+
} icache_block_t;
85100

86101
typedef struct {
87-
ic_block_t block[IC_BLOCKS];
88-
} ic_t;
102+
icache_block_t block[IC_BLOCKS];
103+
} icache_t;
89104

90105
struct __hart_internal {
91-
ic_t ic;
106+
icache_t ic;
92107
uint32_t x_regs[32];
93108

94109
/* LR reservation virtual address. last bit is 1 if valid */

0 commit comments

Comments
 (0)