Skip to content

Commit 50ecbf7

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 7277124 commit 50ecbf7

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
@@ -318,9 +318,9 @@ static void mmu_fence(hart_t *vm, uint32_t insn UNUSED)
318318
static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
319319
{
320320
/* cache hit */
321-
uint32_t idx = (addr >> IC_SHIFT) & IC_INDEX_MASK;
322-
uint32_t tag = addr >> (IC_SHIFT + IC_INDEX_BITS);
323-
ic_block_t *blk = &vm->ic.block[idx];
321+
uint32_t idx = (addr >> IC_OFFSET_BITS) & IC_INDEX_MASK;
322+
uint32_t tag = addr >> (IC_OFFSET_BITS + IC_INDEX_BITS);
323+
icache_block_t *blk = &vm->ic.block[idx];
324324

325325
if (likely(blk->valid && blk->tag == tag)) {
326326
#ifdef MMU_CACHE_STATS
@@ -355,7 +355,7 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
355355
/* fill into the cache */
356356
uint32_t block_off = (addr & RV_PAGE_MASK) & ~IC_BLOCK_MASK;
357357
blk->base = (const uint8_t *) vm->cache_fetch.page_addr + block_off;
358-
blk->tag = addr >> (IC_SHIFT + IC_INDEX_BITS);
358+
blk->tag = tag;
359359
blk->valid = true;
360360
}
361361

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)