os-workshop

same materials and sample source for RV32 OS projects
git clone http://frotz.net/git/os-workshop.git
Log | Files | Refs

start.mmu.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