start.S (2376B)
1 // Copyright 2022, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0 3 4 #include <hw/riscv.h> 5 6 // We start running at the physical start of memory (0x40008000) 7 // We are linked at the virtual address 0xC0000000 8 9 // So we must first setup an initial page table that maps 10 // ram to 0xC0000000, maps the first megapage of ram 11 // to 0x40000000 (so we don't pull the rug out from under us 12 // when we switch on the MMU), and maps the start of MMIO 13 // space at 0xF0000000 so we can still talk to the serial port 14 15 #define PTE_BITS_RWX (PTE_A | PTE_D | PTE_X | PTE_W | PTE_R | PTE_V) 16 #define PTE_BITS_RW (PTE_A | PTE_D | PTE_W | PTE_R | PTE_V) 17 18 .globl _start 19 _start: 20 // zero BSS 21 la t0, __bss_start 22 la t1, __bss_end 23 zero_loop: 24 beq t0, t1, zero_done 25 sw zero, 0(t0) 26 add t0, t0, 4 27 j zero_loop 28 zero_done: 29 30 // physical memory top 31 // (since it's pc relative and pc is physical right now) 32 la sp, __memory_top 33 34 // use the next to last page (before the stack) 35 // for a bootstrap MMU page directory 36 li t4, 4096 37 sub t1, sp, t4 // t1 = end of pagetable 38 sub t0, t1, t4 // t0 = start of pagetable 39 mv t2, t0 // t2 = pagetable 40 41 // virtual memory top / boot stack 42 lw sp, start_sp 43 44 ptbl_zero_loop: 45 sw zero, 0(t0) 46 addi t0, t0, 4 47 bne t0, t1, ptbl_zero_loop 48 49 // identity map a 4MB page where we're running now 50 li t0, (0x40000000 >> 2) | PTE_BITS_RWX 51 li t1, (0x40000000 >> 20) // offset of pte 52 add t1, t2, t1 53 sw t0, 0(t1) 54 55 // map ram at 0xC0000000 where the kernel is linked 56 li t1, (0xC0000000 >> 20) // offset of pte at start of ram 57 srli t3, sp, 20 // offset of pte at end of ram 58 li t4, (0x00400000 >> 2) // 4MB ppn increment 59 ptbl_map_loop: 60 add t5, t2, t1 // t5 = pagetable + pte offset 61 sw t0, 0(t5) // store pte 62 add t1, t1, 4 // increment offset to next pte 63 add t0, t0, t4 // increment ppn to next megapage 64 bne t1, t3, ptbl_map_loop 65 66 // identity map the first 4MB of the mmio space 67 li t0, (0xF0000000 >> 2) | PTE_BITS_RW 68 li t1, (0xF0000000 >> 20) // offset of pte 69 add t1, t2, t1 70 sw t0, 0(t1) 71 72 // enable paging 73 srli t0, t2, 12 74 li t1, SATP_MODE_SV32 75 or t0, t0, t1 76 csrw satp, t0 77 78 // flush TLB 79 sfence.vma zero,zero 80 81 nop 82 nop 83 nop 84 nop 85 nop 86 87 // absolute jump to kernel start 88 lw t0, start_pc 89 jr t0 90 91 start_sp: 92 .word __memory_top 93 start_pc: 94 .word start