/* [<][>][^][v][top][bottom][index][help] */
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <kern/mips/regdefs.h>
31 #include <mips/specialreg.h>
32
33 .set noreorder
34
35 .text
36 .globl __start
37 .type __start,@function
38 .ent __start
39 __start:
40
41 /*
42 * Stack frame. We save the return address register, even though
43 * it contains nothing useful. This is for gdb's benefit when it
44 * comes disassembling. We also need 16 bytes for making a call,
45 * and we have to align to an 8-byte (64-bit) boundary, so the
46 * total frame size is 24.
47 *
48 * Note that the frame here must match the frame we set up below
49 * when we switch off the bootup stack. Otherwise, gdb gets very
50 * confused.
51 */
52 .frame sp, 24, $0 /* 24-byte sp-relative frame; return addr on stack */
53 .mask 0x80000000, -4 /* register 31 (ra) saved at (sp+24)-4 */
54 addiu sp, sp, -24
55 sw ra, 20(sp)
56
57 /*
58 * The System/161 loader sets up a boot stack for the first
59 * processor at the top of physical memory, and passes us a single
60 * string argument. The string lives on the very top of the stack.
61 * We get its address in a0.
62 *
63 * The kernel loads at virtual address 0x80000200, which is
64 * physical address 0x00000200. The space immediately below this
65 * is reserved for the exception vector code.
66 *
67 * The symbol _end is generated by the linker. It's the address of
68 * the end of the kernel. It's not a variable; the *value* of the
69 * _end symbol itself is this address. In C you'd use "&_end".
70 *
71 * We set up the memory map like this:
72 *
73 * top of memory
74 * free memory
75 * P + 0x1000
76 * first thread's stack (1 page)
77 * P
78 * wasted space (< 1 page)
79 * copy of the boot string
80 * _end
81 * kernel
82 * 0x80000200
83 * exception handlers
84 * 0x80000000
85 *
86 * where P is the next whole page after copying the argument string.
87 */
88
89 la s0, _end /* stash _end in a saved register */
90
91 move a1, a0 /* move bootstring to the second argument */
92 move a0, s0 /* make _end the first argument */
93 jal strcpy /* call strcpy(_end, bootstring) */
94 nop /* delay slot */
95
96 move a0, s0 /* make _end the first argument again */
97 jal strlen /* call strlen(_end) */
98 nop
99
100 add t0, s0, v0 /* add in the length of the string */
101 addi t0, t0, 1 /* and the null terminator */
102
103
104 addi t0, t0, 4095 /* round up to next page boundary */
105 li t1, 0xfffff000
106 and t0, t0, t1
107
108 addi t0, t0, 4096 /* add one page to hold the stack */
109
110 move sp, t0 /* start the kernel stack for the first thread here */
111
112 sw t0, firstfree /* remember the first free page for later */
113
114 /*
115 * At this point, s0 contains the boot argument string, and no other
116 * registers contain anything interesting (except the stack pointer).
117 */
118
119 /*
120 * Now set up a stack frame on the real kernel stack: a dummy saved
121 * return address and four argument slots for making function calls,
122 * plus a wasted slot for alignment.
123 *
124 * (This needs to match the stack frame set up at the top of the
125 * function, or the debugger gets confused.)
126 */
127 addiu sp, sp, -24
128 sw $0, 20(sp)
129
130 /*
131 * Now, copy the exception handler code onto the first page of memory.
132 */
133
134 li a0, EXADDR_UTLB
135 la a1, mips_utlb_handler
136 la a2, mips_utlb_end
137 sub a2, a2, a1
138 jal memmove
139 nop
140
141 li a0, EXADDR_GENERAL
142 la a1, mips_general_handler
143 la a2, mips_general_end
144 sub a2, a2, a1
145 jal memmove
146 nop
147
148 /*
149 * Flush the instruction cache to make sure the above changes show
150 * through to instruction fetch.
151 */
152 jal mips_flushicache
153 nop
154
155 /*
156 * Initialize the TLB.
157 */
158 jal tlb_reset
159 nop
160
161 /*
162 * Load NULL into the register we use for curthread.
163 */
164 li s7, 0
165
166 /*
167 * Set up the status register.
168 *
169 * The MIPS has six hardware interrupt lines and two software interrupts.
170 * These are individually maskable in the status register. However, we
171 * don't use this feature (for simplicity) - we only use the master
172 * interrupt enable/disable flag in bit 0. So enable all of those bits
173 * now and forget about them.
174 *
175 * The BEV bit in the status register, if set, causes the processor to
176 * jump to a different set of hardwired exception handling addresses.
177 * This is so that the kernel's exception handling code can be loaded
178 * into RAM and that the boot ROM's exception handling code can be ROM.
179 * This flag is normally set at boot time, and we need to be sure to
180 * clear it.
181 *
182 * The KUo/IEo/KUp/IEp/KUc/IEc bits should all start at zero.
183 *
184 * We also want all the other random control bits (mostly for cache
185 * stuff) set to zero.
186 *
187 * Thus, the actual value we write is CST_IRQMASK.
188 */
189
190 li t0, CST_IRQMASK /* get value */
191 mtc0 t0, c0_status /* set status register */
192
193 /*
194 * Load the CPU number into the PTBASE field of the CONTEXT
195 * register. This is necessary to read from cpustacks[] and
196 * cputhreads[] on trap entry from user mode. See further
197 * discussions elsewhere.
198 *
199 * Because the boot CPU is CPU 0, we can just send 0.
200 */
201 mtc0 $0, c0_context
202
203 /*
204 * Load the GP register. This is a MIPS ABI feature; the GP
205 * register points to an address in the middle of the data segment,
206 * so data can be accessed relative to GP using one instruction
207 * instead of the two it takes to set up a full 32-bit address.
208 */
209 la gp, _gp
210
211 /*
212 * We're all set up!
213 * Fetch the copy of the bootstring as the argument, and call main.
214 */
215 jal kmain
216 move a0, s0 /* in delay slot */
217
218
219 /*
220 * kmain shouldn't return. panic.
221 * Loop back just in case panic returns too.
222 */
223 1:
224 la a0, panicstr
225 jal panic
226 nop /* delay slot */
227 j 1b
228 nop /* delay slot */
229 .end __start
230
231 .rdata
232 panicstr:
233 .asciz "kmain returned\n"
234
235 /*
236 * CPUs started after the boot CPU come here.
237 */
238 .text
239 .globl cpu_start_secondary
240 .type cpu_start_secondary,@function
241 .ent cpu_start_secondary
242 cpu_start_secondary:
243
244 /*
245 * When we get here our stack points to the CRAM area of the bus
246 * controller per-CPU space. This means we can, with a bit of
247 * caution, call C functions, but nothing very deeply nesting.
248 * However, we don't need to.
249 *
250 * The a0 register contains the value that was put in the second
251 * word of the CRAM area, which is the (software) cpu number for
252 * indexing cpustacks[]. None of the other registers contain
253 * anything useful.
254 */
255
256
257 /*
258 * Stack frame. We save the return address register, even though
259 * it contains nothing useful. This is for gdb's benefit when it
260 * comes disassembling. We also need 16 bytes for making a call,
261 * and 4 bytes for alignment, so the total frame size is 24.
262 *
263 * Note that the frame here must match the frame we set up below
264 * when we switch stacks. Otherwise, gdb gets very confused.
265 */
266 .frame sp, 24, $0 /* 24-byte sp-relative frame; return addr on stack */
267 .mask 0x80000000, -4 /* register 31 (ra) saved at (sp+24)-4 */
268 addiu sp, sp, -24
269 sw ra, 20(sp)
270
271 /*
272 * Fetch the stack out of cpustacks[].
273 */
274 lui t0, %hi(cpustacks) /* load upper half of cpustacks base addr */
275 sll v0, a0, 2 /* get byte index for array (multiply by 4) */
276 addu t0, t0, v0 /* add it in */
277 lw sp, %lo(cpustacks)(t0) /* get the stack pointer */
278
279 /*
280 * Now fetch curthread out of cputhreads[].
281 */
282 lui t0, %hi(cputhreads) /* load upper half of cpustacks base addr */
283 sll v0, a0, 2 /* get byte index for array (multiply by 4) */
284 addu t0, t0, v0 /* add it in */
285 lw s7, %lo(cputhreads)(t0) /* load curthread register */
286
287 /*
288 * Initialize the TLB.
289 */
290 jal tlb_reset
291 nop
292
293 /*
294 * Set up the status register, as described above.
295 */
296 li t0, CST_IRQMASK /* get value */
297 mtc0 t0, c0_status /* set status register */
298
299 /*
300 * Load the CPU number into the PTBASE field of the CONTEXT
301 * register, as described above.
302 */
303 sll v0, a0, CTX_PTBASESHIFT
304 mtc0 v0, c0_context
305
306 /*
307 * Initialize the on-chip timer interrupt.
308 *
309 * This should be set to CPU_FREQUENCY/HZ, but we don't have either
310 * of those values here, so we'll arbitrarily set it to 100,000. It
311 * will get reset to the right thing after it first fires.
312 */
313 li v0, 100000
314 mtc0 v0, c0_compare
315
316
317 /*
318 * Load the GP register.
319 */
320 la gp, _gp
321
322 /*
323 * Set up a stack frame. Store zero into the return address slot so
324 * we show as the top of the stack.
325 */
326 addiu sp, sp, -24
327 sw z0, 20(sp)
328
329 /*
330 * Off to MI code. Pass the cpu number as the argument; it's already
331 * in the a0 register.
332 */
333 j cpu_hatch
334 nop /* delay slot for jump */
335 .end cpu_start_secondary