| 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 |