Skip to content

Commit 7b0c3f3

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 8825b96 commit 7b0c3f3

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
@@ -369,9 +369,9 @@ static void mmu_fence(hart_t *vm, uint32_t insn UNUSED)
369369
static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
370370
{
371371
/* cache hit */
372-
uint32_t idx = (addr >> IC_SHIFT) & IC_INDEX_MASK;
373-
uint32_t tag = addr >> (IC_SHIFT + IC_INDEX_BITS);
374-
ic_block_t *blk = &vm->ic.block[idx];
372+
uint32_t idx = (addr >> IC_OFFSET_BITS) & IC_INDEX_MASK;
373+
uint32_t tag = addr >> (IC_OFFSET_BITS + IC_INDEX_BITS);
374+
icache_block_t *blk = &vm->ic.block[idx];
375375

376376
if (likely(blk->valid && blk->tag == tag)) {
377377
#ifdef MMU_CACHE_STATS
@@ -406,7 +406,7 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
406406
/* fill into the cache */
407407
uint32_t block_off = (addr & RV_PAGE_MASK) & ~IC_BLOCK_MASK;
408408
blk->base = (const uint8_t *) vm->cache_fetch.page_addr + block_off;
409-
blk->tag = addr >> (IC_SHIFT + IC_INDEX_BITS);
409+
blk->tag = tag;
410410
blk->valid = true;
411411
}
412412

riscv.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,25 @@ typedef struct {
7575
typedef struct __hart_internal hart_t;
7676
typedef struct __vm_internel vm_t;
7777

78+
/* IC_BLOCKS_SIZE: Size of one instruction-cache block (line).
79+
* IC_BLOCKS: Number of blocks (lines) in the instruction cache.
80+
*
81+
* The cache address is decomposed into [ tag | index | offset ] fields:
82+
* - block-offset bits = log2(IC_BLOCKS_SIZE)
83+
* - index bits = log2(IC_BLOCKS)
84+
*
85+
* For power-of-two values, log2(x) equals the number of trailing zero bits in
86+
* x. Therefore, we use __builtin_ctz(x) (count trailing zeros) to compute these
87+
* log2 values at compile time.
88+
*/
7889
#define IC_BLOCKS_SIZE 256
7990
#define IC_BLOCKS 256
80-
#define IC_SHIFT (__builtin_ctz((IC_BLOCKS_SIZE)))
91+
#define IC_OFFSET_BITS (__builtin_ctz((IC_BLOCKS_SIZE)))
8192
#define IC_INDEX_BITS (__builtin_ctz((IC_BLOCKS)))
93+
94+
/* For power-of-two sizes, (size - 1) sets all low bits to 1,
95+
* allowing fast extraction of an address.
96+
*/
8297
#define IC_INDEX_MASK (IC_BLOCKS - 1)
8398
#define IC_BLOCK_MASK (IC_BLOCKS_SIZE - 1)
8499
#define RV_PAGE_MASK (RV_PAGE_SIZE - 1)
@@ -87,14 +102,14 @@ typedef struct {
87102
uint32_t tag;
88103
const uint8_t *base;
89104
bool valid;
90-
} ic_block_t;
105+
} icache_block_t;
91106

92107
typedef struct {
93-
ic_block_t block[IC_BLOCKS];
94-
} ic_t;
108+
icache_block_t block[IC_BLOCKS];
109+
} icache_t;
95110

96111
struct __hart_internal {
97-
ic_t ic;
112+
icache_t ic;
98113
uint32_t x_regs[32];
99114

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

0 commit comments

Comments
 (0)