head.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:17k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: head.S,v 1.86 2001/12/05 01:02:16 davem Exp $
  2.  * head.S: Initial boot code for the Sparc64 port of Linux.
  3.  *
  4.  * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
  5.  * Copyright (C) 1996 David Sitsky (David.Sitsky@anu.edu.au)
  6.  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  7.  * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
  8.  */
  9. #include <linux/config.h>
  10. #include <linux/version.h>
  11. #include <linux/errno.h>
  12. #include <asm/asm_offsets.h>
  13. #include <asm/asi.h>
  14. #include <asm/pstate.h>
  15. #include <asm/ptrace.h>
  16. #include <asm/spitfire.h>
  17. #include <asm/page.h>
  18. #include <asm/pgtable.h>
  19. #include <asm/errno.h>
  20. #include <asm/signal.h>
  21. #include <asm/processor.h>
  22. #include <asm/lsu.h>
  23. #include <asm/dcr.h>
  24. #include <asm/dcu.h>
  25. #include <asm/head.h>
  26. #include <asm/ttable.h>
  27. /* This section from from _start to sparc64_boot_end should fit into
  28.  * 0x0000.0000.0040.4000 to 0x0000.0000.0040.8000 and will be sharing space
  29.  * with bootup_user_stack, which is from 0x0000.0000.0040.4000 to
  30.  * 0x0000.0000.0040.6000 and empty_bad_page, which is from
  31.  * 0x0000.0000.0040.6000 to 0x0000.0000.0040.8000. 
  32.  */
  33. .text
  34. .globl start, _start, stext, _stext
  35. _start:
  36. start:
  37. _stext:
  38. stext:
  39. bootup_user_stack:
  40. ! 0x0000000000404000
  41. b sparc64_boot
  42.  flushw /* Flush register file.      */
  43. /* This stuff has to be in sync with SILO and other potential boot loaders
  44.  * Fields should be kept upward compatible and whenever any change is made,
  45.  * HdrS version should be incremented.
  46.  */
  47.         .global root_flags, ram_flags, root_dev
  48.         .global sparc_ramdisk_image, sparc_ramdisk_size
  49. .globl silo_args
  50.         .ascii  "HdrS"
  51.         .word   LINUX_VERSION_CODE
  52.         .half   0x0203          /* HdrS version */
  53. root_flags:
  54.         .half   1
  55. root_dev:
  56.         .half   0
  57. ram_flags:
  58.         .half   0
  59. sparc_ramdisk_image:
  60.         .word   0
  61. sparc_ramdisk_size:
  62.         .word   0
  63.         .xword  reboot_command
  64. .xword bootstr_len
  65. .word _end
  66. /* We must be careful, 32-bit OpenBOOT will get confused if it
  67.  * tries to save away a register window to a 64-bit kernel
  68.  * stack address.  Flush all windows, disable interrupts,
  69.  * remap if necessary, jump onto kernel trap table, then kernel
  70.  * stack, or else we die.
  71.  *
  72.  * PROM entry point is on %o4
  73.  */
  74. sparc64_boot:
  75. BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_boot)
  76. BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_boot)
  77. ba,pt %xcc, spitfire_boot
  78.  nop
  79. cheetah_plus_boot:
  80. /* Preserve OBP choosen DCU and DCR register settings.  */
  81. ba,pt %xcc, cheetah_generic_boot
  82.  nop
  83. cheetah_boot:
  84. mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
  85. wr %g1, %asr18
  86. sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
  87. or %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
  88. sllx %g5, 32, %g5
  89. or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
  90. stxa %g5, [%g0] ASI_DCU_CONTROL_REG
  91. membar #Sync
  92. cheetah_generic_boot:
  93. mov TSB_EXTENSION_P, %g3
  94. stxa %g0, [%g3] ASI_DMMU
  95. stxa %g0, [%g3] ASI_IMMU
  96. membar #Sync
  97. mov TSB_EXTENSION_S, %g3
  98. stxa %g0, [%g3] ASI_DMMU
  99. membar #Sync
  100. mov TSB_EXTENSION_N, %g3
  101. stxa %g0, [%g3] ASI_DMMU
  102. stxa %g0, [%g3] ASI_IMMU
  103. membar #Sync
  104. wrpr    %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
  105. wr %g0, 0, %fprs
  106. /* Just like for Spitfire, we probe itlb-2 for a mapping which
  107.  * matches our current %pc.  We take the physical address in
  108.  * that mapping and use it to make our own.
  109.  */
  110. /* %g5 holds the tlb data */
  111.         sethi   %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
  112.         sllx    %g5, 32, %g5
  113.         or      %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
  114. /* Put PADDR tlb data mask into %g3. */
  115. sethi %uhi(_PAGE_PADDR), %g3
  116. or %g3, %ulo(_PAGE_PADDR), %g3
  117. sllx %g3, 32, %g3
  118. sethi %hi(_PAGE_PADDR), %g7
  119. or %g7, %lo(_PAGE_PADDR), %g7
  120. or %g3, %g7, %g3
  121. set 2 << 16, %l0 /* TLB entry walker. */
  122. set 0x1fff, %l2 /* Page mask. */
  123. rd %pc, %l3
  124. andn %l3, %l2, %g2 /* vaddr comparator */
  125. 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
  126. membar #Sync
  127. andn %g1, %l2, %g1
  128. cmp %g1, %g2
  129. be,pn %xcc, cheetah_got_tlbentry
  130.  nop
  131. and %l0, (127 << 3), %g1
  132. cmp %g1, (127 << 3)
  133. blu,pt %xcc, 1b
  134.  add %l0, (1 << 3), %l0
  135. cheetah_got_tlbentry:
  136. ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g0
  137. ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1
  138. membar #Sync
  139. and %g1, %g3, %g1
  140. sub %g1, %g2, %g1
  141. or %g5, %g1, %g5
  142. /* Clear out any KERNBASE area entries. */
  143. set 2 << 16, %l0
  144. sethi %hi(KERNBASE), %g3
  145. sethi %hi(KERNBASE<<1), %g7
  146. mov TLB_TAG_ACCESS, %l7
  147. /* First, check ITLB */
  148. 1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
  149. membar #Sync
  150. andn %g1, %l2, %g1
  151. cmp %g1, %g3
  152. blu,pn %xcc, 2f
  153.  cmp %g1, %g7
  154. bgeu,pn %xcc, 2f
  155.  nop
  156. stxa %g0, [%l7] ASI_IMMU
  157. membar #Sync
  158. stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS
  159. membar #Sync
  160. 2: and %l0, (127 << 3), %g1
  161. cmp %g1, (127 << 3)
  162. blu,pt %xcc, 1b
  163.  add %l0, (1 << 3), %l0
  164. /* Next, check DTLB */
  165. set 2 << 16, %l0
  166. 1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1
  167. membar #Sync
  168. andn %g1, %l2, %g1
  169. cmp %g1, %g3
  170. blu,pn %xcc, 2f
  171.  cmp %g1, %g7
  172. bgeu,pn %xcc, 2f
  173.  nop
  174. stxa %g0, [%l7] ASI_DMMU
  175. membar #Sync
  176. stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
  177. membar #Sync
  178. 2: and %l0, (511 << 3), %g1
  179. cmp %g1, (511 << 3)
  180. blu,pt %xcc, 1b
  181.  add %l0, (1 << 3), %l0
  182. /* On Cheetah+, have to check second DTLB.  */
  183. BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,l0,2f)
  184. ba,pt %xcc, 9f
  185.  nop
  186. 2: set 3 << 16, %l0
  187. 1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1
  188. membar #Sync
  189. andn %g1, %l2, %g1
  190. cmp %g1, %g3
  191. blu,pn %xcc, 2f
  192.  cmp %g1, %g7
  193. bgeu,pn %xcc, 2f
  194.  nop
  195. stxa %g0, [%l7] ASI_DMMU
  196. membar #Sync
  197. stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
  198. membar #Sync
  199. 2: and %l0, (511 << 3), %g1
  200. cmp %g1, (511 << 3)
  201. blu,pt %xcc, 1b
  202.  add %l0, (1 << 3), %l0
  203. 9:
  204. /* Now lock the TTE we created into ITLB-0 and DTLB-0,
  205.  * entry 15 (and maybe 14 too).
  206.  */
  207. sethi %hi(KERNBASE), %g3
  208. set (0 << 16) | (15 << 3), %g7
  209. stxa %g3, [%l7] ASI_DMMU
  210. membar #Sync
  211. stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
  212. membar #Sync
  213. stxa %g3, [%l7] ASI_IMMU
  214. membar #Sync
  215. stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
  216. membar #Sync
  217. flush %g3
  218. membar #Sync
  219. sethi %hi(_end), %g3 /* Check for bigkernel case */
  220. or %g3, %lo(_end), %g3
  221. srl %g3, 23, %g3 /* Check if _end > 8M */
  222. brz,pt %g3, 1f
  223.  sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
  224. sethi %hi(0x400000), %g3
  225. or %g3, %lo(0x400000), %g3
  226. add %g5, %g3, %g5 /* New tte data */
  227. andn %g5, (_PAGE_G), %g5
  228. sethi %hi(KERNBASE+0x400000), %g3
  229. or %g3, %lo(KERNBASE+0x400000), %g3
  230. set (0 << 16) | (14 << 3), %g7
  231. stxa %g3, [%l7] ASI_DMMU
  232. membar #Sync
  233. stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
  234. membar #Sync
  235. stxa %g3, [%l7] ASI_IMMU
  236. membar #Sync
  237. stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
  238. membar #Sync
  239. flush %g3
  240. membar #Sync
  241. sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
  242. ba,pt %xcc, 1f
  243.  nop
  244. 1: set sun4u_init, %g2
  245. jmpl    %g2 + %g0, %g0
  246.  nop
  247. spitfire_boot:
  248. /* Typically PROM has already enabled both MMU's and both on-chip
  249.  * caches, but we do it here anyway just to be paranoid.
  250.  */
  251. mov (LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM), %g1
  252. stxa %g1, [%g0] ASI_LSU_CONTROL
  253. membar #Sync
  254. /*
  255.  * Make sure we are in privileged mode, have address masking,
  256.          * using the ordinary globals and have enabled floating
  257.          * point.
  258.  *
  259.  * Again, typically PROM has left %pil at 13 or similar, and
  260.  * (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE) in %pstate.
  261.          */
  262. wrpr    %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
  263. wr %g0, 0, %fprs
  264. spitfire_create_mappings:
  265. /* %g5 holds the tlb data */
  266.         sethi   %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
  267.         sllx    %g5, 32, %g5
  268.         or      %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
  269. /* Base of physical memory cannot reliably be assumed to be
  270.  * at 0x0!  Figure out where it happens to be. -DaveM
  271.  */
  272. /* Put PADDR tlb data mask into %g3. */
  273. sethi %uhi(_PAGE_PADDR_SF), %g3
  274. or %g3, %ulo(_PAGE_PADDR_SF), %g3
  275. sllx %g3, 32, %g3
  276. sethi %hi(_PAGE_PADDR_SF), %g7
  277. or %g7, %lo(_PAGE_PADDR_SF), %g7
  278. or %g3, %g7, %g3
  279. /* Walk through entire ITLB, looking for entry which maps
  280.  * our %pc currently, stick PADDR from there into %g5 tlb data.
  281.  */
  282. clr %l0 /* TLB entry walker. */
  283. set 0x1fff, %l2 /* Page mask. */
  284. rd %pc, %l3
  285. andn %l3, %l2, %g2 /* vaddr comparator */
  286. 1:
  287. /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
  288. ldxa [%l0] ASI_ITLB_TAG_READ, %g1
  289. nop
  290. nop
  291. nop
  292. andn %g1, %l2, %g1 /* Get vaddr */
  293. cmp %g1, %g2
  294. be,a,pn %xcc, spitfire_got_tlbentry
  295.  ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1
  296. cmp %l0, (63 << 3)
  297. blu,pt %xcc, 1b
  298.  add %l0, (1 << 3), %l0
  299. spitfire_got_tlbentry:
  300. /* Nops here again, perhaps Cheetah/Blackbird are better behaved... */
  301. nop
  302. nop
  303. nop
  304. and %g1, %g3, %g1 /* Mask to just get paddr bits.       */
  305. sub %g1, %g2, %g1 /* Get rid of %pc offset to get base. */
  306. /* NOTE: We hold on to %g1 paddr base as we need it below to lock
  307.  * NOTE: the PROM cif code into the TLB.
  308.  */
  309. or %g5, %g1, %g5 /* Or it into TAG being built.        */
  310. clr %l0 /* TLB entry walker. */
  311. sethi %hi(KERNBASE), %g3 /* 4M lower limit */
  312. sethi %hi(KERNBASE<<1), %g7 /* 8M upper limit */
  313. mov TLB_TAG_ACCESS, %l7
  314. 1:
  315. /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
  316. ldxa [%l0] ASI_ITLB_TAG_READ, %g1
  317. nop
  318. nop
  319. nop
  320. andn %g1, %l2, %g1 /* Get vaddr */
  321. cmp %g1, %g3
  322. blu,pn %xcc, 2f
  323.  cmp %g1, %g7
  324. bgeu,pn %xcc, 2f
  325.  nop
  326. stxa %g0, [%l7] ASI_IMMU
  327. stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS
  328. membar #Sync
  329. 2:
  330. cmp %l0, (63 << 3)
  331. blu,pt %xcc, 1b
  332.  add %l0, (1 << 3), %l0
  333. nop; nop; nop
  334. clr %l0 /* TLB entry walker. */
  335. 1:
  336. /* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
  337. ldxa [%l0] ASI_DTLB_TAG_READ, %g1
  338. nop
  339. nop
  340. nop
  341. andn %g1, %l2, %g1 /* Get vaddr */
  342. cmp %g1, %g3
  343. blu,pn %xcc, 2f
  344.  cmp %g1, %g7
  345. bgeu,pn %xcc, 2f
  346.  nop
  347. stxa %g0, [%l7] ASI_DMMU
  348. stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
  349. membar #Sync
  350. 2:
  351. cmp %l0, (63 << 3)
  352. blu,pt %xcc, 1b
  353.  add %l0, (1 << 3), %l0
  354. nop; nop; nop
  355. /* PROM never puts any TLB entries into the MMU with the lock bit
  356.  * set.  So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too.
  357.  */
  358. sethi %hi(KERNBASE), %g3
  359. mov (63 << 3), %g7
  360. stxa %g3, [%l7] ASI_DMMU /* KERNBASE into TLB TAG */
  361. stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS /* TTE into TLB DATA */
  362. membar #Sync
  363. stxa %g3, [%l7] ASI_IMMU /* KERNBASE into TLB TAG */
  364. stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS /* TTE into TLB DATA */
  365. membar #Sync
  366. flush %g3
  367. membar #Sync
  368. sethi %hi(_end), %g3 /* Check for bigkernel case */
  369. or %g3, %lo(_end), %g3
  370. srl %g3, 23, %g3 /* Check if _end > 8M */
  371. brz,pt %g3, 2f
  372.  sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
  373. sethi %hi(0x400000), %g3
  374. or %g3, %lo(0x400000), %g3
  375. add %g5, %g3, %g5 /* New tte data */
  376. andn %g5, (_PAGE_G), %g5
  377. sethi %hi(KERNBASE+0x400000), %g3
  378. or %g3, %lo(KERNBASE+0x400000), %g3
  379. mov (62 << 3), %g7
  380. stxa %g3, [%l7] ASI_DMMU
  381. stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
  382. membar #Sync
  383. stxa %g3, [%l7] ASI_IMMU
  384. stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
  385. membar #Sync
  386. flush %g3
  387. membar #Sync
  388. sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
  389. 2: ba,pt %xcc, 1f
  390.  nop
  391. 1:
  392. set sun4u_init, %g2
  393. jmpl    %g2 + %g0, %g0
  394.  nop
  395. sun4u_init:
  396. /* Set ctx 0 */
  397. mov PRIMARY_CONTEXT, %g7
  398. stxa %g0, [%g7] ASI_DMMU
  399. membar #Sync
  400. mov SECONDARY_CONTEXT, %g7
  401. stxa %g0, [%g7] ASI_DMMU
  402. membar #Sync
  403. sethi %uhi(PAGE_OFFSET), %g4
  404. sllx %g4, 32, %g4
  405. /* We are now safely (we hope) in Nucleus context (0), rewrite
  406.  * the KERNBASE TTE's so they no longer have the global bit set.
  407.  * Don't forget to setup TAG_ACCESS first 8-)
  408.  */
  409. mov TLB_TAG_ACCESS, %g2
  410. stxa %g3, [%g2] ASI_IMMU
  411. stxa %g3, [%g2] ASI_DMMU
  412. membar #Sync
  413. BRANCH_IF_ANY_CHEETAH(g1,g5,cheetah_tlb_fixup)
  414. ba,pt %xcc, spitfire_tlb_fixup
  415.  nop
  416. cheetah_tlb_fixup:
  417. set (0 << 16) | (15 << 3), %g7
  418. ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g0
  419. ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1
  420. andn %g1, (_PAGE_G), %g1
  421. stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS
  422. membar #Sync
  423. ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g0
  424. ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1
  425. andn %g1, (_PAGE_G), %g1
  426. stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS
  427. membar #Sync
  428. /* Kill instruction prefetch queues. */
  429. flush %g3
  430. membar #Sync
  431. mov 2, %g2 /* Set TLB type to cheetah+. */
  432. BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g5,g7,1f)
  433. mov 1, %g2 /* Set TLB type to cheetah. */
  434. 1: sethi %hi(tlb_type), %g5
  435. stw %g2, [%g5 + %lo(tlb_type)]
  436. /* Patch copy/page operations to cheetah optimized versions. */
  437. call cheetah_patch_copyops
  438.  nop
  439. call cheetah_patch_pgcopyops
  440.  nop
  441. call cheetah_patch_cachetlbops
  442.  nop
  443. ba,pt %xcc, tlb_fixup_done
  444.  nop
  445. spitfire_tlb_fixup:
  446. mov (63 << 3), %g7
  447. ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1
  448. andn %g1, (_PAGE_G), %g1
  449. stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS
  450. membar #Sync
  451. ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1
  452. andn %g1, (_PAGE_G), %g1
  453. stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS
  454. membar #Sync
  455. /* Kill instruction prefetch queues. */
  456. flush %g3
  457. membar #Sync
  458. /* Set TLB type to spitfire. */
  459. mov 0, %g2
  460. sethi %hi(tlb_type), %g5
  461. stw %g2, [%g5 + %lo(tlb_type)]
  462. tlb_fixup_done:
  463. sethi %hi(init_task_union), %g6
  464. or %g6, %lo(init_task_union), %g6
  465. mov %sp, %l6
  466. mov %o4, %l7
  467. #if 0 /* We don't do it like this anymore, but for historical hack value
  468.  * I leave this snippet here to show how crazy we can be sometimes. 8-)
  469.  */
  470. /* Setup "Linux Current Register", thanks Sun 8-) */
  471. wr %g0, 0x1, %pcr
  472. /* Blackbird errata workaround.  See commentary in
  473.  * smp.c:smp_percpu_timer_interrupt() for more
  474.  * information.
  475.  */
  476. ba,pt %xcc, 99f
  477.  nop
  478. .align 64
  479. 99: wr %g6, %g0, %pic
  480. rd %pic, %g0
  481. #endif
  482. wr %g0, ASI_P, %asi
  483. mov 1, %g5
  484. sllx %g5, THREAD_SHIFT, %g5
  485. sub %g5, (REGWIN_SZ + STACK_BIAS), %g5
  486. add %g6, %g5, %sp
  487. mov 0, %fp
  488. wrpr %g0, 0, %wstate
  489. wrpr %g0, 0x0, %tl
  490. /* Clear the bss */
  491. sethi %hi(__bss_start), %o0
  492. or %o0, %lo(__bss_start), %o0
  493. sethi %hi(_end), %o1
  494. or %o1, %lo(_end), %o1
  495. call __bzero
  496.  sub %o1, %o0, %o1
  497. mov %l6, %o1 ! OpenPROM stack
  498. call prom_init
  499.  mov %l7, %o0 ! OpenPROM cif handler
  500. /* Off we go.... */
  501. call start_kernel
  502.  nop
  503. /* Not reached... */
  504. /* IMPORTANT NOTE: Whenever making changes here, check
  505.  * trampoline.S as well. -jj */
  506. .globl setup_tba
  507. setup_tba: /* i0 = is_starfire */
  508. save %sp, -160, %sp
  509. rdpr %tba, %g7
  510. sethi %hi(prom_tba), %o1
  511. or %o1, %lo(prom_tba), %o1
  512. stx %g7, [%o1]
  513. /* Setup "Linux" globals 8-) */
  514. rdpr %pstate, %o1
  515. mov %g6, %o2
  516. wrpr %o1, (PSTATE_AG|PSTATE_IE), %pstate
  517. sethi %hi(sparc64_ttable_tl0), %g5
  518. wrpr %g5, %tba
  519. mov %o2, %g6
  520. /* Set up MMU globals */
  521. wrpr %o1, (PSTATE_MG|PSTATE_IE), %pstate
  522. /* Set fixed globals used by dTLB miss handler. */
  523. #define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)
  524. #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
  525. mov TSB_REG, %g1
  526. stxa %g0, [%g1] ASI_DMMU
  527. membar #Sync
  528. mov TLB_SFSR, %g1
  529. sethi %uhi(KERN_HIGHBITS), %g2
  530. or %g2, %ulo(KERN_HIGHBITS), %g2
  531. sllx %g2, 32, %g2
  532. or %g2, KERN_LOWBITS, %g2
  533. BRANCH_IF_ANY_CHEETAH(g3,g7,cheetah_vpte_base)
  534. ba,pt %xcc, spitfire_vpte_base
  535.  nop
  536. cheetah_vpte_base:
  537. sethi %uhi(VPTE_BASE_CHEETAH), %g3
  538. or %g3, %ulo(VPTE_BASE_CHEETAH), %g3
  539. ba,pt %xcc, 2f
  540.  sllx %g3, 32, %g3
  541. spitfire_vpte_base:
  542. sethi %uhi(VPTE_BASE_SPITFIRE), %g3
  543. or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3
  544. sllx %g3, 32, %g3
  545. 2:
  546. clr %g7
  547. #undef KERN_HIGHBITS
  548. #undef KERN_LOWBITS
  549. /* Setup Interrupt globals */
  550. wrpr %o1, (PSTATE_IG|PSTATE_IE), %pstate
  551. #ifndef CONFIG_SMP
  552. sethi %hi(__up_workvec), %g5
  553. or %g5, %lo(__up_workvec), %g6
  554. #else
  555. /* By definition of where we are, this is boot_cpu. */
  556. brz,pt %i0, not_starfire
  557.  sethi %hi(0x1fff4000), %g1
  558. or %g1, %lo(0x1fff4000), %g1
  559. sllx %g1, 12, %g1
  560. or %g1, 0xd0, %g1
  561. lduwa [%g1] ASI_PHYS_BYPASS_EC_E, %g1
  562. b,pt %xcc, set_worklist
  563.  nop
  564. not_starfire:
  565. BRANCH_IF_ANY_CHEETAH(g1,g5,is_cheetah)
  566. ba,pt %xcc, not_cheetah
  567.  nop
  568. is_cheetah:
  569. ldxa [%g0] ASI_SAFARI_CONFIG, %g1
  570. srlx %g1, 17, %g1
  571. ba,pt %xcc, set_worklist
  572.  and %g1, 0x3ff, %g1 ! 10bit Safari Agent ID
  573. not_cheetah:
  574. ldxa [%g0] ASI_UPA_CONFIG, %g1
  575. srlx %g1, 17, %g1
  576. and %g1, 0x1f, %g1
  577. /* In theory this is: &(cpu_data[boot_cpu_id].irq_worklists[0]) */
  578. set_worklist:
  579. sethi %hi(cpu_data), %g5
  580. or %g5, %lo(cpu_data), %g5
  581. sllx %g1, 7, %g1
  582. add %g5, %g1, %g5
  583. add %g5, 64, %g6
  584. #endif
  585. /* Kill PROM timer */
  586. wr %g0, 0, %tick_cmpr
  587. BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
  588. ba,pt %xcc, 2f
  589.  nop
  590. /* Disable STICK_INT interrupts. */
  591. 1:
  592. sethi %hi(0x80000000), %g1
  593. sllx %g1, 32, %g1
  594. wr %g1, %asr25
  595. /* Ok, we're done setting up all the state our trap mechanims needs,
  596.  * now get back into normal globals and let the PROM know what is up.
  597.  */
  598. 2:
  599. wrpr %g0, %g0, %wstate
  600. wrpr %o1, PSTATE_IE, %pstate
  601. sethi %hi(sparc64_ttable_tl0), %g5
  602. call prom_set_trap_table
  603.  mov %g5, %o0
  604. rdpr %pstate, %o1
  605. or %o1, PSTATE_IE, %o1
  606. wrpr %o1, 0, %pstate
  607. ret
  608.  restore
  609. /*
  610.  * The following skips make sure the trap table in ttable.S is aligned
  611.  * on a 32K boundary as required by the v9 specs for TBA register.
  612.  */
  613. sparc64_boot_end:
  614. .skip 0x2000 + _start - sparc64_boot_end
  615. bootup_user_stack_end:
  616. .skip 0x2000
  617. #ifdef CONFIG_SBUS
  618. /* This is just a hack to fool make depend config.h discovering
  619.    strategy: As the .S files below need config.h, but
  620.    make depend does not find it for them, we include config.h
  621.    in head.S */
  622. #endif
  623. ! 0x0000000000408000
  624. #include "ttable.S"
  625. #include "systbls.S"
  626. .align 1024
  627. .globl swapper_pg_dir
  628. swapper_pg_dir:
  629. .word 0
  630. #include "etrap.S"
  631. #include "rtrap.S"
  632. #include "winfixup.S"
  633. #include "entry.S"
  634. /* This is just anal retentiveness on my part... */
  635. .align 16384
  636. .data
  637. .align 8
  638. .globl prom_tba
  639. prom_tba: .xword 0
  640. .section ".fixup",#alloc,#execinstr
  641. .globl __ret_efault
  642. __ret_efault:
  643. ret
  644.  restore %g0, -EFAULT, %o0