Fixed lots of bugs in the SPARC port wrt multithreading
[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     -1,%wim                 ! mark all windows invalid.
39         mov     (PSR_S|PSR_PS),%psr
40         nop                             ! 3 insns between wrwim/rdwim
41         mov     0,%g2           ! g2 will contain NWINDOWS-1
42         mov     %wim,%g1        ! get wim. nonexistent windows set to 0
43
44 1:      srl     %g1,1,%g1
45         tst     %g1
46         bne,a   1b
47          inc    %g2
48
49         # now g2 = NWINDOWS - 1.  Patch the window spill trap handler.
50         set     RELOC(spill_patchme),%g1
51         ld      [%g1],%g3
52         or      %g2,%g3,%g3
53         st      %g3,[%g1]
54         flush   %g1
55
56         # and patch the window fill trap handler.
57         set     RELOC(fill_patchme),%g1
58         ld      [%g1],%g3
59         or      %g2,%g3,%g3
60         st      %g3,[%g1]
61         flush   %g1
62
63         # store NWINDOWS away for safekeeping
64         set     RELOC(NWINDOWS),%g1
65         inc     %g2
66         st      %g2,[%g1]
67
68         # PSR.CWP (current window pointer) == 0.
69         # Set WIM so we'll trap on the next save instruction.
70         mov     1 << 1,%wim
71
72         # set up the TBR (trap base register)
73         set     RELOC(trap_table),%g1
74         mov     %g1,%tbr
75
76         # clear frame pointer for backtrace termination
77         mov     0,%fp
78
79         # set stack pointer (-64 is space for window spill)
80         # sp = bootstacktop - core_id*KSTKSIZE - 64
81         set     RELOC(bootstacktop)-64,%sp
82         mov     CORE_ID_REG,%g1
83         sll     %g1,KSTKSHIFT,%g1
84         sub     %sp,%g1,%sp
85
86         # set up a virtual->physical mapping and relocate
87         call    mmu_boot
88          nop
89
90         # now we're relocated, so set %sp and TBR again
91         set     KERNBASE,%g1
92         add     %sp,%g1,%sp
93         set     trap_table,%g1
94         mov     %g1,%tbr
95
96         # now it's safe to enable traps
97         mov     %psr,%g1
98         wr      %g1,PSR_ET,%psr
99         nop; nop; nop
100
101         # am i core 0?  (do i run BSD?!?)
102         mov     CORE_ID_REG,%g1
103         tst     %g1
104         bne     4f
105          nop
106
107         # only core 0 gets here
108         # set num_cpus
109         set     num_cpus,%l0
110         mov     NUM_CORES_REG,%l1
111         st      %l1,[%l0]
112
113         cmp     %l1,MAX_NUM_CPUS
114         tg      0x7f
115
116         sub     %sp,64,%sp              ! 64 >= sizeof(multiboot_header_t)
117         call    build_multiboot_info
118          add    %sp,64,%o0
119
120         # kernel_init time!
121         # first arg is pointer to multiboot_info_t, but kernel_init
122         # expects it to be a pre-relocation address, so lop off KERNBASE
123         set     KERNBASE,%l0
124         add     %sp,64,%o0
125         call    kernel_init
126          sub    %o0,%l0,%o0
127
128         # shouldn't get here
129 3:      ba      3b
130          nop
131
132         # i'm not core 0, so i'll call smp_init when the time is nigh
133 4:      set     time_for_smp_init,%l1
134         ld      [%l1],%l0
135         tst     %l0
136         be      4b
137          nop
138
139         call    smp_init
140          nop
141
142         # shouldn't get here
143 5:      ba      5b
144          nop
145
146
147
148 # this function (against the ABI!) relocates its caller's stack pointer
149 # and return address, then returns to the caller, relocated
150
151 .global         relocate
152 relocate:
153         set     KERNBASE,%o0
154         inc     8,%o7
155         add     %i7,%o0,%i7
156         jmp     %o7+%o0
157         add     %sp,%o0,%sp
158
159 .data
160
161 ###################################################################
162 # various data
163 ###################################################################
164
165         .global         time_for_smp_init
166 time_for_smp_init:
167         .word           0
168
169         .global         NWINDOWS
170 NWINDOWS:
171         .word           0
172
173         .global         num_cpus
174 num_cpus:
175         .word           0
176
177 ###################################################################
178 # boot stack
179 ###################################################################
180
181         .align          PGSIZE          ! force page alignment
182         .global         bootstack
183 bootstack:
184         .space          KSTKSIZE*MAX_NUM_CPUS
185         .global         bootstacktop   
186 bootstacktop:
187
188 ###################################################################
189 # page tables
190 ###################################################################
191         .align          (NCONTEXTS+CONTEXT_TABLE_PAD)*4
192         .global         mmu_context_tables
193 mmu_context_tables:
194         .skip           MAX_NUM_CPUS*(NCONTEXTS+CONTEXT_TABLE_PAD)*4
195
196         .align          1024
197         .global         l1_page_table
198 l1_page_table:
199         .skip           1024