Massive cleanup of SPARC kernel entry code
[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         // now it's safe to enable traps
139         mov     %psr,%g1
140         wr      %g1,PSR_ET,%psr
141         nop; nop; nop
142
143         // am i core 0?  (do i run BSD?!?)
144         mov     CORE_ID_REG,%g1
145         tst     %g1
146         bne     4f
147          nop
148
149         // only core 0 gets here
150         call    mmu_boot_cleanup_core0
151          nop
152
153         // set num_cpus
154         set     num_cpus,%l0
155         mov     NUM_CORES_REG,%l1
156         st      %l1,[%l0]
157
158         cmp     %l1,MAX_NUM_CPUS
159         tg      0x7f
160
161         // use a stack in the data section (as opposed to bss) here,
162         // since kernel_init will zero the stack
163         set     core0_bootstacktop-64,%sp
164
165         sub     %sp,64,%sp              ! 64 >= sizeof(multiboot_header_t)
166         call    build_multiboot_info
167          add    %sp,64,%o0
168
169         // kernel_init time!
170         // first arg is pointer to multiboot_info_t, but kernel_init
171         // expects it to be a pre-relocation address, so lop off KERNBASE
172         set     KERNBASE,%l0
173         add     %sp,64,%o0
174         call    kernel_init
175          sub    %o0,%l0,%o0
176
177         // shouldn't get here
178 3:      ba      3b
179          nop
180
181         // i'm not core 0, so i'll call smp_init when the time is nigh
182 4:      set     time_for_smp_init,%l1
183         ld      [%l1],%l0
184         tst     %l0
185         be      4b
186          nop
187
188         call    smp_init
189          nop
190
191         // shouldn't get here
192 5:      ba      5b
193          nop
194
195 ///////////////////////////////////////////////////////////////////
196 // various data
197 ///////////////////////////////////////////////////////////////////
198 .data
199
200 pagetable_init_done:
201         .word 0
202
203 cores_relocated:
204         .word 0
205 cores_relocated_lock:
206         .word 0
207
208         .global         time_for_smp_init
209 time_for_smp_init:
210         .word           0
211
212         .global         NWINDOWS
213 NWINDOWS:
214         .word           0
215
216         .global         num_cpus
217 num_cpus:
218         .word           0
219
220 ///////////////////////////////////////////////////////////////////
221 // boot stack
222 ///////////////////////////////////////////////////////////////////
223
224 .section ".bss"
225         .align          PGSIZE
226         .space          KSTKSIZE*MAX_NUM_CPUS
227         .global         bootstacktop   
228 bootstacktop:
229
230 .data
231         .align          PGSIZE
232         .space          KSTKSIZE
233         .global         core0_bootstacktop
234 core0_bootstacktop:
235
236 ///////////////////////////////////////////////////////////////////
237 // page tables
238 ///////////////////////////////////////////////////////////////////
239         .align          (NCONTEXTS+CONTEXT_TABLE_PAD)*4
240         .global         mmu_context_tables
241 mmu_context_tables:
242         .skip           MAX_NUM_CPUS*(NCONTEXTS+CONTEXT_TABLE_PAD)*4
243
244         .align          1024
245         .global         l1_page_table
246 l1_page_table:
247         .skip           1024