11244a316a58b8fdee4d8014254d9601233ec60c
[akaros.git] / kern / arch / sparc / entry.S
1 /* See COPYRIGHT for copyright information. */
2
3 #include <arch/mmu.h>
4 #include <arch/sparc.h>
5 #include <arch/arch.h>
6 #include <ros/memlayout.h>
7
8 ///////////////////////////////////////////////////////////////////
9 // The kernel (this code) is linked at address (KERNBASE + 0x00000000),
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 ///////////////////////////////////////////////////////////////////
17 // RELOC(x) maps a symbol x from its link address to its actual
18 // location in physical memory (its load address).       
19 ///////////////////////////////////////////////////////////////////
20 #define RELOC(x) ((x) - KERNBASE)
21
22 ///////////////////////////////////////////////////////////////////
23 // entry point
24 ///////////////////////////////////////////////////////////////////
25
26 .text
27
28 .global         _start
29 _start:
30         // This is the first code that ever executes.  It executes on all
31         // cores (RAMP Gold-specific).  All we know is that PSR.S (supervisor)
32         // and PSR.ET (enable traps) are both 0.  Before we can enable traps,
33         // we must determine how many register windows we have, set up the
34         // trap table, and set up a stack frame.
35
36         // compute NWINDOWS
37
38         mov     0,%wim                          ! mark all windows valid
39         mov (PSR_PIL|PSR_S|PSR_PS),%psr ! CWP = 0
40         nop; nop; nop                   ! 3 insns between write -> read state reg
41         save                                    ! CWP = (CWP-1) % NWINDOWS = NWINDOWS-1
42         mov     %psr,%g2
43         and     %g2,PSR_CWP,%g2         ! g2 = NWINDOWS-1
44         restore                                 ! CWP = 0
45         mov     1<<1,%wim                       ! mark window 1 invalid (trap on restore)
46
47         // now g2 = NWINDOWS - 1.  Patch the window spill trap handler.
48         set     RELOC(spill_patchme),%g1
49         ld      [%g1],%g3
50         or      %g2,%g3,%g3
51         st      %g3,[%g1]
52         flush   %g1
53
54         // and patch the window fill trap handler.
55         set     RELOC(fill_patchme),%g1
56         ld      [%g1],%g3
57         or      %g2,%g3,%g3
58         st      %g3,[%g1]
59         flush   %g1
60
61         // and patch the trap entry point.
62         set     RELOC(trap_patchme),%g1
63         ld      [%g1],%g3
64         or      %g2,%g3,%g3
65         st      %g3,[%g1]
66         flush   %g1
67
68         // store NWINDOWS away for safekeeping
69         set     RELOC(NWINDOWS),%g1
70         inc     %g2
71         st      %g2,[%g1]
72
73         // set up the TBR (trap base register)
74         set     RELOC(trap_table),%g1
75         mov     %g1,%tbr
76
77         // clear frame pointer for backtrace termination
78         mov     0,%fp
79
80         // set stack pointer (-64 is space for window spill)
81         // sp = bootstacktop - core_id*KSTKSIZE - 64
82         set     RELOC(bootstacktop)-64,%sp
83         mov     CORE_ID_REG,%g1
84         sll     %g1,KSTKSHIFT,%g2
85         sub     %sp,%g2,%sp
86
87         // set up a virtual->physical mapping
88         tst     %g1
89         set     RELOC(pagetable_init_done),%l0
90         bne pagetable_init_wait
91          nop
92
93         // core 0 initializes the pagetable
94         call    pagetable_init
95          nop
96         mov     1,%g2
97         st      %g2,[%l0]
98
99 pagetable_init_wait:
100         ld      [%l0],%g1
101         tst     %g1
102         be      pagetable_init_wait
103          nop
104
105         call    mmu_init
106          nop
107
108         // relocate
109         set     trap_table,%g1
110         mov     %g1,%tbr
111         set     reloc,%g1
112         set     KERNBASE,%g2
113         jmp     %g1
114          add    %g2,%sp,%sp
115 reloc:
116         call    mmu_boot_cleanup_all
117          nop
118
119         mov     1,%g1
120         set     cores_relocated,%g2
121         set     cores_relocated_lock,%g3
122         swap    [%g3],%g1
123         tst     %g1
124         bne     reloc
125          nop
126         ld      [%g2],%g1
127         inc     %g1
128         st      %g1,[%g2]
129         st      %g0,[%g3]
130
131 wait_for_reloc:
132         ld      [%g2],%g1
133         mov     NUM_CORES_REG,%g3
134         cmp     %g1,%g3
135         bl      wait_for_reloc
136          nop
137
138         // Set our stacktop so we can find it on a trap or spill/fill
139         mov     CORE_ID_REG,%l1
140         sll     %l1,KSTKSHIFT,%l1
141         set     bootstacktop,%l2
142         sub     %l2,%l1,%l1             // %l1 now holds our current stacktop
143         mov     CORE_ID_REG,%l0
144         sll     %l0,2,%l0
145         set     core_stacktops,%l2
146         st      %l1,[%l2 + %l0]         // store the stacktop in its slot
147
148         // now it's safe to enable traps
149         mov     %psr,%g1
150         wr      %g1,PSR_ET,%psr
151         nop; nop; nop
152
153         // am i core 0?  (do i run BSD?!?)
154         mov     CORE_ID_REG,%g1
155         tst     %g1
156         bne     4f
157          nop
158
159         // only core 0 gets here
160         call    mmu_boot_cleanup_core0
161          nop
162
163         // set num_cpus
164         set     num_cpus,%l0
165         mov     NUM_CORES_REG,%l1
166         st      %l1,[%l0]
167
168         cmp     %l1,MAX_NUM_CPUS
169         tg      0x7f
170
171         // use a stack in the data section (as opposed to bss) here,
172         // since kernel_init will zero the stack
173         set     core0_bootstacktop-64,%sp
174         // reset core0's stacktop to core0_bootstacktop
175         set     core0_bootstacktop,%l1
176         set     core_stacktops,%l2
177         st      %l1,[%l2]               // store the stacktop in its slot
178
179         sub     %sp,64,%sp              ! 64 >= sizeof(multiboot_header_t)
180         call    build_multiboot_info
181          add    %sp,64,%o0
182
183         // kernel_init time!
184         // first arg is pointer to multiboot_info_t, but kernel_init
185         // expects it to be a pre-relocation address, so lop off KERNBASE
186         set     KERNBASE,%l0
187         add     %sp,64,%o0
188         call    kernel_init
189          sub    %o0,%l0,%o0
190
191         // shouldn't get here
192 3:      ba      3b
193          nop
194
195         // i'm not core 0, so i'll call smp_init when the time is nigh
196 4:      set     time_for_smp_init,%l1
197         ld      [%l1],%l0
198         tst     %l0
199         be      4b
200          nop
201
202         call    smp_init
203          nop
204
205         // shouldn't get here
206 5:      ba      5b
207          nop
208
209 ///////////////////////////////////////////////////////////////////
210 // various data
211 ///////////////////////////////////////////////////////////////////
212 .data
213
214 pagetable_init_done:
215         .word 0
216
217 cores_relocated:
218         .word 0
219 cores_relocated_lock:
220         .word 0
221
222         .global         time_for_smp_init
223 time_for_smp_init:
224         .word           0
225
226         .global         NWINDOWS
227 NWINDOWS:
228         .word           0
229
230         .global         num_cpus
231 num_cpus:
232         .word           0
233
234 ///////////////////////////////////////////////////////////////////
235 // boot stack
236 ///////////////////////////////////////////////////////////////////
237
238 .section ".bss"
239         .align          PGSIZE
240         .space          KSTKSIZE*MAX_NUM_CPUS
241         .global         bootstacktop   
242 bootstacktop:
243
244 .data
245         .align          PGSIZE
246         .space          KSTKSIZE
247         .global         core0_bootstacktop
248 core0_bootstacktop:
249
250 ///////////////////////////////////////////////////////////////////
251 // page tables
252 ///////////////////////////////////////////////////////////////////
253         .align          (NCONTEXTS+CONTEXT_TABLE_PAD)*4
254         .global         mmu_context_tables
255 mmu_context_tables:
256         .skip           MAX_NUM_CPUS*(NCONTEXTS+CONTEXT_TABLE_PAD)*4
257
258         .align          1024
259         .global         l1_page_table
260 l1_page_table:
261         .skip           1024