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