summaryrefslogtreecommitdiff
path: root/src/kernel/sbi.cc
blob: 5ae7edb1c5ddd9c4e37981a09829bb5cff78c492 (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
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2026 Richard QIn
 */
#include "common/types.h"
#include "kernel/sbi.h"

namespace SBI
{
    struct sbiret
    {
        long error;
        long value;
    };

    struct sbiret sbi_call(int ext, int fid, uint64 arg0, uint64 arg1, uint64 arg2)
    {
        struct sbiret ret;
        register uint64 a0 asm("a0") = arg0;
        register uint64 a1 asm("a1") = arg1;
        register uint64 a2 asm("a2") = arg2;
        register uint64 a6 asm("a6") = fid;
        register uint64 a7 asm("a7") = ext;

        asm volatile(
            "ecall"
            : "=r"(a0), "=r"(a1)
            : "r"(a0), "r"(a1), "r"(a2), "r"(a6), "r"(a7)
            : "memory");
        ret.error = a0;
        ret.value = a1;
        return ret;
    }

    void set_timer(uint64 stime_value)
    {
        sbi_call(0x54494D45, 0, stime_value, 0, 0);
    }

    void sbi_shutdown()
    {
        sbi_call(0x53525354, 0, 0, 0, 0);
        sbi_call(0x08, 0, 0, 0, 0);
        while (1)
            ;
    }

    void sbi_reboot()
    {
        sbi_call(SBI_EID_SRST, SBI_FID_SRST_RESET, SBI_SRST_TYPE_COLD_REBOOT, SBI_SRST_REASON_NONE, 0);
    }
}