for risc-v, assume all cores boot at same time
[akaros.git] / kern / arch / riscv / boot.S
1 /* See COPYRIGHT for copyright information. */
2
3 #include <arch/pcr.h>
4 #include <ros/arch/arch.h>
5 #include <ros/memlayout.h>
6 #incldue <arch/mmu.h>
7
8 ///////////////////////////////////////////////////////////////////
9 // The kernel (this code) is linked at address 0xFFFFFFFF80000000,
10 // but we tell the bootloader to load it at physical address 
11 // 0x00000000, which is the start of extended memory.
12 // (See kernel.ld)
13 ///////////////////////////////////////////////////////////////////
14
15 ///////////////////////////////////////////////////////////////////
16 // entry point
17 ///////////////////////////////////////////////////////////////////
18
19 #define PCR0 (SR_S | SR_S64 | (1 << (IRQ_IPI + SR_IM_SHIFT)))
20 .text
21
22 .global _start
23 .ent _start
24 _start:
25   // This is the first kernel code that executes; it is run only by core 0.
26
27   // set up trap entry point.  this is not a relocated address, as we
28   // do not support trapping before the MMU is set up.
29   la     t0, trap_entry
30   mtpcr  t0, ASM_CR(PCR_EVEC)
31
32   // clear IPIs and enable traps
33   mtpcr  zero, ASM_CR(PCR_CLR_IPI)
34   li     t0, PCR0
35   mtpcr  t0, ASM_CR(PCR_SR)
36
37   // core 0?
38   mfpcr  t0, ASM_CR(PCR_COREID)
39   bnez   t0, notcore0
40
41   // terminate frame pointer for backtracing and set up stack
42   li     s9, 0
43   la     sp, percore_stacks + KSTKSIZE
44   li     t1, KERN_LOAD_ADDR
45   sub    sp, sp, t1
46
47   // get memory size and core count from first two words of memory
48   lw     s0, 0(zero)
49   lw     s1, 4(zero)
50
51   // set up initial page mappings
52   move   a0, s0
53   la     a1, l1pt
54   sub    a1, a1, t1
55   la     a2, l1pt_boot
56   sub    a2, a2, t1
57 #ifdef __riscv64
58   la     a3, l2pt
59   sub    a3, a3, t1
60 #endif
61   jal    pagetable_init
62   jal    enable_mmu
63
64   // relocate stack and call into C code using absolute jump, not pc-relative
65   move   a0, s0
66   move   a1, s1
67   la     sp, percore_stacks + KSTKSIZE
68   la     t0, cmain
69   jr     t0
70
71 notcore0:
72   // wait for core 0 to boot
73   la     t2, num_cpus_booted - KERN_LOAD_ADDR
74 1:lw     t3, 0(t2)
75   beqz   t3, 1b
76
77   // set up stack: sp = percoore_stacks+(core_id()+1)*KSTKSIZE
78   la     sp, percore_stacks
79   add    t0, t0, 1
80   sll    t0, t0, KSTKSHIFT
81   add    sp, sp, t0
82   li     t1, KERN_LOAD_ADDR
83   sub    sp, sp, t1
84   
85   jal    enable_mmu
86
87   // relocate stack and call into C code
88   li     t1, KERN_LOAD_ADDR
89   add    sp, sp, t1
90   la     t0, smp_init
91   jr     t0
92
93 .end _start
94
95 .ent enable_mmu
96 enable_mmu:
97   la     t0, l1pt_boot
98   li     t1, KERN_LOAD_ADDR
99   sub    t0, t0, t1
100   mtpcr  t0, ASM_CR(PCR_PTBR)
101   li     t0, PCR0 | SR_VM
102   mtpcr  t0, ASM_CR(PCR_SR)
103   ret
104 .end enable_mmu
105
106 ///////////////////////////////////////////////////////////////////
107 // boot stack and regular stacks.
108 // (boot stack cannot be in .bss, as .bss is later zereoed by the kernel.)
109 ///////////////////////////////////////////////////////////////////
110
111 .data
112   .align  PGSHIFT
113 l1pt_boot:
114   .space  PGSIZE
115 .global l1pt
116 l1pt:
117   .space  PGSIZE
118 l2pt:
119   .space  PGSIZE
120
121   .global percore_stacks
122 percore_stacks:
123   .space  KSTKSIZE*MAX_NUM_CPUS