summaryrefslogtreecommitdiff
path: root/kernel/src/arch/riscv64/riscv64.cpp
blob: 2db83bf89b78022ef5c8297a83c621b6e3461666 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

#include <cstdint>
#include <generic/arch.hpp>
#include <arch/riscv64/features.hpp>

namespace arch {
    [[gnu::weak]] void disable_interrupts() {
        asm volatile("csrc sstatus, %0" : : "r"(1 << 1)); 
    }

    [[gnu::weak]] void enable_interrupts() {
        asm volatile("csrs sstatus, %0" : : "r"(1 << 1));
    }

    [[gnu::weak]] void wait_for_interrupt() {
        asm volatile("wfi"); 
    }
    
    [[gnu::weak]] void hcf() {
        disable_interrupts();
        while(true) {
            wait_for_interrupt();
        }
    }

    [[gnu::weak]] void pause() {
#ifdef __riscv_zihintpause
        asm volatile("pause");
#else
        asm volatile("nop");
#endif
    }

    [[gnu::weak]] void tlb_flush(std::uintptr_t hint, std::uintptr_t len) {
        if (len / PAGE_SIZE > 256 || len == 0) {
            asm volatile("sfence.vma");
        } else {
            for (std::uintptr_t i = 0; i < len; i += PAGE_SIZE) {
                asm volatile("sfence.vma %0" : : "r"(hint + i) : "memory");
            }
        }
    }

    [[gnu::weak]] const char* name() {
        return "riscv64";
    }

    [[gnu::weak]] int level_paging() {
        return riscv64::get_paging_level();
    }

    [[gnu::weak]] void init(int stage) {
        (void)stage;
    }

}