Skip to content

Commit ceb4007

Browse files
committed
Adapt mtimecmp read/write for per-hart registers
Previously, mtimecmp was accessed at a fixed MMIO address assuming a single core. Each hart has its own mtimecmp register at distinct offsets, so update mtimecmp read and write functions to index based on the current hart ID, ensuring correct timer compare handling in SMP systems.
1 parent 967b595 commit ceb4007

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

arch/riscv/hal.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,14 @@ static inline uint64_t mtime_r(void)
131131
/* Safely read the 64-bit 'mtimecmp' register. */
132132
static inline uint64_t mtimecmp_r(void)
133133
{
134-
uint32_t hi, lo;
134+
uint32_t hi, lo, hartid;
135+
136+
hartid = read_csr(mhartid);
137+
135138
do {
136-
hi = MTIMECMP_H;
137-
lo = MTIMECMP_L;
138-
} while (hi != MTIMECMP_H);
139+
hi = * (volatile uint32_t *) (CLINT_BASE + 0x4004u + 8 * hartid);
140+
lo = * (volatile uint32_t *) (CLINT_BASE + 0x4000u + 8 * hartid);
141+
} while (hi != *(volatile uint32_t *) (CLINT_BASE + 0x4004u + 8 * hartid));
139142
return CT64(hi, lo);
140143
}
141144

@@ -152,10 +155,11 @@ static inline void mtimecmp_w(uint64_t val)
152155
/* Disable interrupts during the critical section to ensure atomicity */
153156
uint32_t old_mie = read_csr(mie);
154157
write_csr(mie, old_mie & ~MIE_MTIE);
158+
uint32_t hartid = read_csr(mhartid);
155159

156-
MTIMECMP_L = 0xFFFFFFFF; /* Set to maximum to prevent spurious interrupt */
157-
MTIMECMP_H = (uint32_t) (val >> 32); /* Set high word */
158-
MTIMECMP_L = (uint32_t) val; /* Set low word to final value */
160+
* (volatile uint32_t *) (CLINT_BASE + 0x4000u + 8 * hartid) = 0xFFFFFFFF; /* Set to maximum to prevent spurious interrupt */
161+
* (volatile uint32_t *) (CLINT_BASE + 0x4004u + 8 * hartid) = (uint32_t) (val >> 32); /* Set high word */
162+
* (volatile uint32_t *) (CLINT_BASE + 0x4000u + 8 * hartid) = (uint32_t) val; /* Set low word to final value */
159163

160164
/* Re-enable timer interrupts if they were previously enabled */
161165
write_csr(mie, old_mie);

0 commit comments

Comments
 (0)