Skip to content

Commit 2a26163

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 a9e59e6 commit 2a26163

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
@@ -136,11 +136,14 @@ static inline uint64_t mtime_r(void)
136136
/* Safely read the 64-bit 'mtimecmp' register */
137137
static inline uint64_t mtimecmp_r(void)
138138
{
139-
uint32_t hi, lo;
139+
uint32_t hi, lo, hartid;
140+
141+
hartid = read_csr(mhartid);
142+
140143
do {
141-
hi = MTIMECMP_H;
142-
lo = MTIMECMP_L;
143-
} while (hi != MTIMECMP_H);
144+
hi = * (volatile uint32_t *) (CLINT_BASE + 0x4004u + 8 * hartid);
145+
lo = * (volatile uint32_t *) (CLINT_BASE + 0x4000u + 8 * hartid);
146+
} while (hi != *(volatile uint32_t *) (CLINT_BASE + 0x4004u + 8 * hartid));
144147
return CT64(hi, lo);
145148
}
146149

@@ -157,10 +160,11 @@ static inline void mtimecmp_w(uint64_t val)
157160
/* Disable timer interrupts during the critical section */
158161
uint32_t old_mie = read_csr(mie);
159162
write_csr(mie, old_mie & ~MIE_MTIE);
163+
uint32_t hartid = read_csr(mhartid);
160164

161-
MTIMECMP_L = 0xFFFFFFFF; /* Set to maximum to prevent spurious interrupt */
162-
MTIMECMP_H = (uint32_t) (val >> 32); /* Set high word */
163-
MTIMECMP_L = (uint32_t) val; /* Set low word to final value */
165+
* (volatile uint32_t *) (CLINT_BASE + 0x4000u + 8 * hartid) = 0xFFFFFFFF; /* Set to maximum to prevent spurious interrupt */
166+
* (volatile uint32_t *) (CLINT_BASE + 0x4004u + 8 * hartid) = (uint32_t) (val >> 32); /* Set high word */
167+
* (volatile uint32_t *) (CLINT_BASE + 0x4000u + 8 * hartid) = (uint32_t) val; /* Set low word to final value */
164168

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

0 commit comments

Comments
 (0)