14d1c9cace0e1fb791b597b53765fedc391d8a48
[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         // store NWINDOWS away for safekeeping
62         set     RELOC(NWINDOWS),%g1
63         inc     %g2
64         st      %g2,[%g1]
65
66         // set up the TBR (trap base register)
67         set     RELOC(trap_table),%g1
68         mov     %g1,%tbr
69
70         // clear frame pointer for backtrace termination
71         mov     0,%fp
72
73         // set stack pointer (-64 is space for window spill)
74         // sp = bootstacktop - core_id*KSTKSIZE - 64
75         set     RELOC(bootstacktop)-64,%sp
76         mov     CORE_ID_REG,%g1
77         sll     %g1,KSTKSHIFT,%g2
78         sub     %sp,%g2,%sp
79
80         // set up a virtual->physical mapping
81         tst     %g1
82         set     RELOC(pagetable_init_done),%l0
83         bne pagetable_init_wait
84          nop
85
86         // core 0 initializes the pagetable
87         call    pagetable_init
88          nop
89         mov     1,%g2
90         st      %g2,[%l0]
91
92 pagetable_init_wait:
93         ld      [%l0],%g1
94         tst     %g1
95         be      pagetable_init_wait
96          nop
97
98         call    mmu_init
99          nop
100
101         // relocate
102         set     trap_table,%g1
103         mov     %g1,%tbr
104         set     reloc,%g1
105         set     KERNBASE,%g2
106         jmp     %g1
107          add    %g2,%sp,%sp
108 reloc:
109         call    mmu_boot_cleanup_all
110          nop
111
112         mov     1,%g1
113         set     cores_relocated,%g2
114         set     cores_relocated_lock,%g3
115         swap    [%g3],%g1
116         tst     %g1
117         bne     reloc
118          nop
119         ld      [%g2],%g1
120         inc     %g1
121         st      %g1,[%g2]
122         st      %g0,[%g3]
123
124 wait_for_reloc:
125         ld      [%g2],%g1
126         mov     NUM_CORES_REG,%g3
127         cmp     %g1,%g3
128         bl      wait_for_reloc
129          nop
130
131         // now it's safe to enable traps
132         mov     %psr,%g1
133         wr      %g1,PSR_ET,%psr
134         nop; nop; nop
135
136         // am i core 0?  (do i run BSD?!?)
137         mov     CORE_ID_REG,%g1
138         tst     %g1
139         bne     4f
140          nop
141
142         // only core 0 gets here
143         call    mmu_boot_cleanup_core0
144          nop
145
146         // set num_cpus
147         set     num_cpus,%l0
148         mov     NUM_CORES_REG,%l1
149         st      %l1,[%l0]
150
151         cmp     %l1,MAX_NUM_CPUS
152         tg      0x7f
153
154         // use a stack in the data section (as opposed to bss) here,
155         // since kernel_init will zero the stack
156         set     core0_bootstacktop-64,%sp
157
158         sub     %sp,64,%sp              ! 64 >= sizeof(multiboot_header_t)
159         call    build_multiboot_info
160          add    %sp,64,%o0
161
162         // kernel_init time!
163         // first arg is pointer to multiboot_info_t, but kernel_init
164         // expects it to be a pre-relocation address, so lop off KERNBASE
165         set     KERNBASE,%l0
166         add     %sp,64,%o0
167         call    kernel_init
168          sub    %o0,%l0,%o0
169
170         // shouldn't get here
171 3:      ba      3b
172          nop
173
174         // i'm not core 0, so i'll call smp_init when the time is nigh
175 4:      set     time_for_smp_init,%l1
176         ld      [%l1],%l0
177         tst     %l0
178         be      4b
179          nop
180
181         call    smp_init
182          nop
183
184         // shouldn't get here
185 5:      ba      5b
186          nop
187
188 ///////////////////////////////////////////////////////////////////
189 // various data
190 ///////////////////////////////////////////////////////////////////
191 .data
192
193 pagetable_init_done:
194         .word 0
195
196 cores_relocated:
197         .word 0
198 cores_relocated_lock:
199         .word 0
200
201         .global         time_for_smp_init
202 time_for_smp_init:
203         .word           0
204
205         .global         NWINDOWS
206 NWINDOWS:
207         .word           0
208
209         .global         num_cpus
210 num_cpus:
211         .word           0
212
213 ///////////////////////////////////////////////////////////////////
214 // boot stack
215 ///////////////////////////////////////////////////////////////////
216
217 .section ".bss"
218         .align          PGSIZE
219         .space          KSTKSIZE*MAX_NUM_CPUS
220         .global         bootstacktop   
221 bootstacktop:
222
223 .data
224         .align          PGSIZE
225         .space          KSTKSIZE
226         .global         core0_bootstacktop
227 core0_bootstacktop:
228
229 ///////////////////////////////////////////////////////////////////
230 // page tables
231 ///////////////////////////////////////////////////////////////////
232         .align          (NCONTEXTS+CONTEXT_TABLE_PAD)*4
233         .global         mmu_context_tables
234 mmu_context_tables:
235         .skip           MAX_NUM_CPUS*(NCONTEXTS+CONTEXT_TABLE_PAD)*4
236
237         .align          1024
238         .global         l1_page_table
239 l1_page_table:
240         .skip           1024