1 /* mp.S: Multiprocessor low-level routines on the Sparc. 2 * 3 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 4 */ 5
6 #include <asm/cprefix.h>
7 #include <asm/head.h>
8 #include <asm/psr.h>
9 #include <asm/asi.h>
10 #include <asm/vaddrs.h>
11 #include <asm/contregs.h>
12
13
14 .text
15 .align 4
16
17 /* When we start up a cpu for the first time it enters this routine. 18 * This initializes the chip from whatever state the prom left it 19 * in and sets PIL in %psr to 15, no irqs. 20 */ 21
22 .globl C_LABEL(sparc_cpu_startup)
23 C_LABEL(sparc_cpu_startup):
24 /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ 25 set (PSR_PIL | PSR_S | PSR_PS), %g1
26 wr %g1, 0x0, %psr ! traps off though
27 WRITE_PAUSE
28
29 /* Our %wim is one behind CWP */ 30 wr %g0, 0x2, %wim
31
32 rd %tbr, %g4
33 or %g0, 0x3, %g5
34 sll %g5, 20, %g5
35 and %g4, %g5, %g4 ! Mask cpu-id bits
36
37 /* Give ourselves a stack. */ 38 set PERCPU_VADDR, %g1
39 add %g1, %g4, %g1
40 set PERCPU_KSTACK_OFFSET, %g5
41 add %g1, %g5, %g1
42 set 0x1000, %g5
43 add %g1, %g5, %g1 ! end of stack
44 sub %g1, (96+96+80), %g1 ! set up a frame
45 andn %g1, 0x7, %g1
46 or %g1, 0x0, %fp ! bottom of frame
47 add %fp, (96+80), %sp ! top of frame
48
49 /* Set up per-cpu trap table pointer. In actuality, the virtual 50 * address for the trap table on every cpu points to the same 51 * physical address, this virtual address is only used for cpu 52 * identification purposes. 53 */ 54 #if 0
55 /* set PERCPU_VADDR, %g1 */ 56 /* add %g1, %g4, %g1 */ 57 /* add %g1, PERCPU_TBR_OFFSET, %g1 */ 58 set C_LABEL(thiscpus_tbr), %g1
59 ld [%g1], %g1
60 wr %g1, 0x0, %tbr
61 WRITE_PAUSE
62 #else 63 set C_LABEL(trapbase), %g3
64 wr %g3, 0x0, %tbr
65 WRITE_PAUSE
66 #endif 67
68 /* Turn on traps (PSR_ET). */ 69 rd %psr, %g1
70 wr %g1, PSR_ET, %psr ! traps on
71
72 #if 0
73 1: nop
74 b 1b
75 nop
76 #endif 77
78 /* Call C-code to do the rest of the real work. */ 79 call C_LABEL(sparc_cpu_init)
80 nop
81
82 /* Call cpu-idle routine so we can start it up later on. */ 83 call C_LABEL(sparc_cpu_idle)
84 nop
85
86 /* Done... This cpu should me spinning in a test loop. 87 * If execution gets here, something really bad happened. 88 */ 89 call C_LABEL(prom_halt) ! Seems reasonable...
90 nop
91