:: limine / common / sys / smp_trampoline.asm_riscv64 2.2 KB raw

1
.section .text
2
3
.global smp_trampoline_start
4
smp_trampoline_start:
5
.option norelax
6
        // The AP begins executing here with the following state:
7
        //      satp            = 0
8
        //      sstatus.SIE     = 0
9
        //      a0              = hartid
10
        //      a1              = struct trampoline_passed_info *
11
        //
12
        // All other registers are undefined.
13
14
#define smp_tpl_booted_flag     0
15
#define smp_tpl_satp            8
16
#define smp_tpl_info_struct     16
17
#define smp_tpl_hhdm_offset     24
18
19
        ld      a0, smp_tpl_info_struct(a1)
20
        ld      t1, smp_tpl_hhdm_offset(a1)
21
22
        // Set `stvec` so we page fault into the higher half after loading `satp`.
23
        lla     t0, 0f
24
        add     t0, t1, t0
25
        csrw    stvec, t0
26
        ld      t0, smp_tpl_satp(a1)
27
        csrw    satp, t0
28
        sfence.vma
29
        unimp
30
0:
31
        // Relocate the smp_info and passed_info pointers to the higher half.
32
        add     a0, t1, a0
33
        add     a1, t1, a1
34
35
        // Tell the BSP we've started.
36
        li      t0, 1
37
        fence   rw, w
38
        sd      t0, (a1)
39
40
        // Zero all the things.
41
        // Preserve a0
42
        mv      a1, zero
43
        mv      a2, zero
44
        mv      a3, zero
45
        mv      a4, zero
46
        mv      a5, zero
47
        mv      a6, zero
48
        mv      a7, zero
49
        mv      s0, zero
50
        mv      s1, zero
51
        mv      s2, zero
52
        mv      s3, zero
53
        mv      s4, zero
54
        mv      s5, zero
55
        mv      s6, zero
56
        mv      s7, zero
57
        mv      s8, zero
58
        mv      s9, zero
59
        mv      s10, zero
60
        mv      s11, zero
61
        mv      t1, zero
62
        mv      t2, zero
63
        mv      t3, zero
64
        mv      t4, zero
65
        mv      t5, zero
66
        mv      t6, zero
67
        mv      tp, zero
68
        mv      gp, zero
69
        mv      ra, zero
70
71
        li      t0, (2 << 32)
72
        csrw    sstatus, t0
73
        csrw    sie, zero
74
        csrw    stvec, zero
75
76
        // Wait for kernel to tell us where to go.
77
0:      .4byte 0x0100000f    // pause
78
        ld      t0, 24(a0)
79
        fence   r, rw
80
        beqz    t0, 0b
81
82
        // Load sp from reserved field of info struct
83
        ld      sp, 16(a0)
84
85
        jr      t0
86
87
.section .note.GNU-stack,"",%progbits
tab: 248 wrap: offon