start.S 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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. #include <kern/mips/regdefs.h>
  30. #include <mips/specialreg.h>
  31. .set noreorder
  32. .text
  33. .globl __start
  34. .type __start,@function
  35. .ent __start
  36. __start:
  37. /*
  38. * Stack frame. We save the return address register, even though
  39. * it contains nothing useful. This is for gdb's benefit when it
  40. * comes disassembling. We also need 16 bytes for making a call,
  41. * and we have to align to an 8-byte (64-bit) boundary, so the
  42. * total frame size is 24.
  43. *
  44. * Note that the frame here must match the frame we set up below
  45. * when we switch off the bootup stack. Otherwise, gdb gets very
  46. * confused.
  47. */
  48. .frame sp, 24, $0 /* 24-byte sp-relative frame; return addr on stack */
  49. .mask 0x80000000, -4 /* register 31 (ra) saved at (sp+24)-4 */
  50. addiu sp, sp, -24
  51. sw ra, 20(sp)
  52. /*
  53. * The System/161 loader sets up a boot stack for the first
  54. * processor at the top of physical memory, and passes us a single
  55. * string argument. The string lives on the very top of the stack.
  56. * We get its address in a0.
  57. *
  58. * The kernel loads at virtual address 0x80000200, which is
  59. * physical address 0x00000200. The space immediately below this
  60. * is reserved for the exception vector code.
  61. *
  62. * The symbol _end is generated by the linker. It's the address of
  63. * the end of the kernel. It's not a variable; the *value* of the
  64. * _end symbol itself is this address. In C you'd use "&_end".
  65. *
  66. * We set up the memory map like this:
  67. *
  68. * top of memory
  69. * free memory
  70. * P + 0x1000
  71. * first thread's stack (1 page)
  72. * P
  73. * wasted space (< 1 page)
  74. * copy of the boot string
  75. * _end
  76. * kernel
  77. * 0x80000200
  78. * exception handlers
  79. * 0x80000000
  80. *
  81. * where P is the next whole page after copying the argument string.
  82. */
  83. la s0, _end /* stash _end in a saved register */
  84. move a1, a0 /* move bootstring to the second argument */
  85. move a0, s0 /* make _end the first argument */
  86. jal strcpy /* call strcpy(_end, bootstring) */
  87. nop /* delay slot */
  88. move a0, s0 /* make _end the first argument again */
  89. jal strlen /* call strlen(_end) */
  90. nop
  91. add t0, s0, v0 /* add in the length of the string */
  92. addi t0, t0, 1 /* and the null terminator */
  93. addi t0, t0, 4095 /* round up to next page boundary */
  94. li t1, 0xfffff000
  95. and t0, t0, t1
  96. addi t0, t0, 4096 /* add one page to hold the stack */
  97. move sp, t0 /* start the kernel stack for the first thread here */
  98. sw t0, firstfree /* remember the first free page for later */
  99. /*
  100. * At this point, s0 contains the boot argument string, and no other
  101. * registers contain anything interesting (except the stack pointer).
  102. */
  103. /*
  104. * Now set up a stack frame on the real kernel stack: a dummy saved
  105. * return address and four argument slots for making function calls,
  106. * plus a wasted slot for alignment.
  107. *
  108. * (This needs to match the stack frame set up at the top of the
  109. * function, or the debugger gets confused.)
  110. */
  111. addiu sp, sp, -24
  112. sw $0, 20(sp)
  113. /*
  114. * Now, copy the exception handler code onto the first page of memory.
  115. */
  116. li a0, EXADDR_UTLB
  117. la a1, mips_utlb_handler
  118. la a2, mips_utlb_end
  119. sub a2, a2, a1
  120. jal memmove
  121. nop
  122. li a0, EXADDR_GENERAL
  123. la a1, mips_general_handler
  124. la a2, mips_general_end
  125. sub a2, a2, a1
  126. jal memmove
  127. nop
  128. /*
  129. * Flush the instruction cache to make sure the above changes show
  130. * through to instruction fetch.
  131. */
  132. jal mips_flushicache
  133. nop
  134. /*
  135. * Initialize the TLB.
  136. */
  137. jal tlb_reset
  138. nop
  139. /*
  140. * Load NULL into the register we use for curthread.
  141. */
  142. li s7, 0
  143. /*
  144. * Set up the status register.
  145. *
  146. * The MIPS has six hardware interrupt lines and two software interrupts.
  147. * These are individually maskable in the status register. However, we
  148. * don't use this feature (for simplicity) - we only use the master
  149. * interrupt enable/disable flag in bit 0. So enable all of those bits
  150. * now and forget about them.
  151. *
  152. * The BEV bit in the status register, if set, causes the processor to
  153. * jump to a different set of hardwired exception handling addresses.
  154. * This is so that the kernel's exception handling code can be loaded
  155. * into RAM and that the boot ROM's exception handling code can be ROM.
  156. * This flag is normally set at boot time, and we need to be sure to
  157. * clear it.
  158. *
  159. * The KUo/IEo/KUp/IEp/KUc/IEc bits should all start at zero.
  160. *
  161. * We also want all the other random control bits (mostly for cache
  162. * stuff) set to zero.
  163. *
  164. * Thus, the actual value we write is CST_IRQMASK.
  165. */
  166. li t0, CST_IRQMASK /* get value */
  167. mtc0 t0, c0_status /* set status register */
  168. /*
  169. * Load the CPU number into the PTBASE field of the CONTEXT
  170. * register. This is necessary to read from cpustacks[] and
  171. * cputhreads[] on trap entry from user mode. See further
  172. * discussions elsewhere.
  173. *
  174. * Because the boot CPU is CPU 0, we can just send 0.
  175. */
  176. mtc0 $0, c0_context
  177. /*
  178. * Load the GP register. This is a MIPS ABI feature; the GP
  179. * register points to an address in the middle of the data segment,
  180. * so data can be accessed relative to GP using one instruction
  181. * instead of the two it takes to set up a full 32-bit address.
  182. */
  183. la gp, _gp
  184. /*
  185. * We're all set up!
  186. * Fetch the copy of the bootstring as the argument, and call main.
  187. */
  188. jal kmain
  189. move a0, s0 /* in delay slot */
  190. /*
  191. * kmain shouldn't return. panic.
  192. * Loop back just in case panic returns too.
  193. */
  194. 1:
  195. la a0, panicstr
  196. jal panic
  197. nop /* delay slot */
  198. j 1b
  199. nop /* delay slot */
  200. .end __start
  201. .rdata
  202. panicstr:
  203. .asciz "kmain returned\n"
  204. /*
  205. * CPUs started after the boot CPU come here.
  206. */
  207. .text
  208. .globl cpu_start_secondary
  209. .type cpu_start_secondary,@function
  210. .ent cpu_start_secondary
  211. cpu_start_secondary:
  212. /*
  213. * When we get here our stack points to the CRAM area of the bus
  214. * controller per-CPU space. This means we can, with a bit of
  215. * caution, call C functions, but nothing very deeply nesting.
  216. * However, we don't need to.
  217. *
  218. * The a0 register contains the value that was put in the second
  219. * word of the CRAM area, which is the (software) cpu number for
  220. * indexing cpustacks[]. None of the other registers contain
  221. * anything useful.
  222. */
  223. /*
  224. * Stack frame. We save the return address register, even though
  225. * it contains nothing useful. This is for gdb's benefit when it
  226. * comes disassembling. We also need 16 bytes for making a call,
  227. * and 4 bytes for alignment, so the total frame size is 24.
  228. *
  229. * Note that the frame here must match the frame we set up below
  230. * when we switch stacks. Otherwise, gdb gets very confused.
  231. */
  232. .frame sp, 24, $0 /* 24-byte sp-relative frame; return addr on stack */
  233. .mask 0x80000000, -4 /* register 31 (ra) saved at (sp+24)-4 */
  234. addiu sp, sp, -24
  235. sw ra, 20(sp)
  236. /*
  237. * Fetch the stack out of cpustacks[].
  238. */
  239. lui t0, %hi(cpustacks) /* load upper half of cpustacks base addr */
  240. sll v0, a0, 2 /* get byte index for array (multiply by 4) */
  241. addu t0, t0, v0 /* add it in */
  242. lw sp, %lo(cpustacks)(t0) /* get the stack pointer */
  243. /*
  244. * Now fetch curthread out of cputhreads[].
  245. */
  246. lui t0, %hi(cputhreads) /* load upper half of cpustacks base addr */
  247. sll v0, a0, 2 /* get byte index for array (multiply by 4) */
  248. addu t0, t0, v0 /* add it in */
  249. lw s7, %lo(cputhreads)(t0) /* load curthread register */
  250. /*
  251. * Initialize the TLB.
  252. */
  253. jal tlb_reset
  254. nop
  255. /*
  256. * Set up the status register, as described above.
  257. */
  258. li t0, CST_IRQMASK /* get value */
  259. mtc0 t0, c0_status /* set status register */
  260. /*
  261. * Load the CPU number into the PTBASE field of the CONTEXT
  262. * register, as described above.
  263. */
  264. sll v0, a0, CTX_PTBASESHIFT
  265. mtc0 v0, c0_context
  266. /*
  267. * Initialize the on-chip timer interrupt.
  268. *
  269. * This should be set to CPU_FREQUENCY/HZ, but we don't have either
  270. * of those values here, so we'll arbitrarily set it to 100,000. It
  271. * will get reset to the right thing after it first fires.
  272. */
  273. li v0, 100000
  274. mtc0 v0, c0_compare
  275. /*
  276. * Load the GP register.
  277. */
  278. la gp, _gp
  279. /*
  280. * Set up a stack frame. Store zero into the return address slot so
  281. * we show as the top of the stack.
  282. */
  283. addiu sp, sp, -24
  284. sw z0, 20(sp)
  285. /*
  286. * Off to MI code. Pass the cpu number as the argument; it's already
  287. * in the a0 register.
  288. */
  289. j cpu_hatch
  290. nop /* delay slot for jump */
  291. .end cpu_start_secondary