Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add dummy WFI implementation #470

Merged
merged 1 commit into from
Aug 18, 2024
Merged

Add dummy WFI implementation #470

merged 1 commit into from
Aug 18, 2024

Conversation

ChinYikMing
Copy link
Collaborator

The Wait for Interrupt instruction (WFI) provides a hint to the implementation that the current hart can be stalled until an interrupt might need servicing. As well, Linux kernel might call wait_for_interrupt() to enter idle state. In this commit, we could simply make PC + 4 and not really enter idle state.

Related: #310

The Wait for Interrupt instruction (WFI) provides a hint to the
implementation that the current hart can be stalled until an
interrupt might need servicing. As well, Linux kernel might call
wait_for_interrupt() to enter idle state. In this commit, we
could simply make PC + 4 and not really enter idle state.

Related: sysprog21#310
@jserv jserv changed the title Add Wait for Interrupt instruction (WFI) Add dummy WFI implementation Jul 21, 2024
Copy link
Contributor

@jserv jserv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Benchmark suite Current: 8ac3c95 Previous: f2e41a8 Ratio
Dhrystone 1630.77 Average DMIPS over 10 runs 1589.12 Average DMIPS over 10 runs 0.97
Coremark 1490.998 Average iterations/sec over 10 runs 1402.631 Average iterations/sec over 10 runs 0.94

This comment was automatically generated by workflow using github-action-benchmark.

@jserv
Copy link
Contributor

jserv commented Jul 21, 2024

You should clarify WFI implementation. WFI is crucial for SMP awareness, and I did the following incomplete work for semu. (Linux only)

static uint64_t read_time(vm_t *vm)
{
    emu_state_t *data = (emu_state_t *) vm->priv;
    return data->time;
}

static void wfi(vm_t *vm)
{
    emu_state_t *data = (emu_state_t *) vm->priv;

    struct timespec start;
    clock_gettime(CLOCK_MONOTONIC, &start);

    struct pollfd pfd[] = {
        {data->timer_fd, 0, 0},
    };

    if (data->time < data->timer) {
        int64_t ticks = data->timer - data->time;
        ticks = (ticks * 1e9) / CLOCK_FREQ;
        struct itimerspec spec = {
            {0, 0},
            {ticks / (int64_t) 1e9, ticks % (int64_t) 1e9},
        };
        timerfd_settime(data->timer_fd, 0, &spec, NULL);
        pfd[0].events |= POLLIN;
    }

    while (!(vm->sip & vm->sie)) {
        int ret = poll(pfd, sizeof(pfd) / sizeof(*pfd), -1);
        assert(ret >= 0);
        if (pfd[0].revents & POLLIN) {
            vm->sip |= RV_INT_STI_BIT;
            pfd[0].events &= ~POLLIN;
        }
    }         

    struct timespec end;
    clock_gettime(CLOCK_MONOTONIC, &end);
    int64_t ticks =
        (end.tv_sec - start.tv_sec) * 1e9 + (end.tv_nsec - start.tv_nsec);
    data->time += (ticks * CLOCK_FREQ) / 1e9;
}

@jserv jserv merged commit 4ed6317 into sysprog21:master Aug 18, 2024
8 checks passed
@ChinYikMing ChinYikMing deleted the wfi branch August 18, 2024 12:42
vestata pushed a commit to vestata/rv32emu that referenced this pull request Jan 24, 2025
Add dummy WFI implementation (uniprocessor)
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants