44 lines
1.1 KiB
C
44 lines
1.1 KiB
C
#include "tb_cxxrtl_io.h"
|
|
#include <stdint.h>
|
|
|
|
// Serve timer IRQs in the background whilst performing AMOs in a loop in the
|
|
// foreground.
|
|
|
|
#define IRQ_INTERVAL 201
|
|
#define N_AMOS 1000
|
|
|
|
volatile uint32_t amo_count, irq_count;
|
|
|
|
void __attribute__((interrupt)) isr_machine_timer() {
|
|
mm_timer->mtimecmp = mm_timer->mtimecmp + IRQ_INTERVAL;
|
|
++irq_count;
|
|
}
|
|
|
|
int main() {
|
|
amo_count = 0;
|
|
irq_count = 0;
|
|
|
|
asm volatile ("csrw mie, %0" : : "r" (0x80));
|
|
mm_timer->mtime = 0;
|
|
// Will take first timer interrupt immediately:
|
|
asm volatile ("csrsi mstatus, 0x8");
|
|
|
|
for (uint32_t i = 0; i < N_AMOS; i = i + 1) {
|
|
uint32_t fetch;
|
|
asm volatile (
|
|
"amoadd.w %0, %1, (%2)"
|
|
: "=r" (fetch)
|
|
: "r" (1), "r" (&amo_count)
|
|
);
|
|
tb_assert(fetch == i, "Bad fetch, expected %u, got %u\n", i, fetch);
|
|
}
|
|
|
|
asm volatile ("csrci mstatus, 0x8");
|
|
uint32_t current_time = mm_timer->mtime;
|
|
tb_printf("At time %u, received %u IRQs\n", current_time, irq_count);
|
|
tb_assert(current_time / IRQ_INTERVAL + 1 == irq_count, "Bad IRQ count\n");
|
|
tb_assert(amo_count == N_AMOS, "Bad final AMO count %u\n", N_AMOS);
|
|
|
|
return 0;
|
|
}
|