1/* 2 * trampoline.S: SMP cpu boot-up trampoline code. 3 * 4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 5 * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 6 */ 7 8#include <linux/init.h> 9#include <asm/head.h> 10#include <asm/psr.h> 11#include <asm/page.h> 12#include <asm/asi.h> 13#include <asm/ptrace.h> 14#include <asm/vaddrs.h> 15#include <asm/contregs.h> 16#include <asm/thread_info.h> 17 18 .globl sun4m_cpu_startup, __smp4m_processor_id, __leon_processor_id 19 .globl sun4d_cpu_startup, __smp4d_processor_id 20 21 __CPUINIT 22 .align 4 23 24/* When we start up a cpu for the first time it enters this routine. 25 * This initializes the chip from whatever state the prom left it 26 * in and sets PIL in %psr to 15, no irqs. 27 */ 28 29sun4m_cpu_startup: 30cpu1_startup: 31 sethi %hi(trapbase_cpu1), %g3 32 b 1f 33 or %g3, %lo(trapbase_cpu1), %g3 34 35cpu2_startup: 36 sethi %hi(trapbase_cpu2), %g3 37 b 1f 38 or %g3, %lo(trapbase_cpu2), %g3 39 40cpu3_startup: 41 sethi %hi(trapbase_cpu3), %g3 42 b 1f 43 or %g3, %lo(trapbase_cpu3), %g3 44 451: 46 /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ 47 set (PSR_PIL | PSR_S | PSR_PS), %g1 48 wr %g1, 0x0, %psr ! traps off though 49 WRITE_PAUSE 50 51 /* Our %wim is one behind CWP */ 52 mov 2, %g1 53 wr %g1, 0x0, %wim 54 WRITE_PAUSE 55 56 /* This identifies "this cpu". */ 57 wr %g3, 0x0, %tbr 58 WRITE_PAUSE 59 60 /* Give ourselves a stack and curptr. */ 61 set current_set, %g5 62 srl %g3, 10, %g4 63 and %g4, 0xc, %g4 64 ld [%g5 + %g4], %g6 65 66 sethi %hi(THREAD_SIZE - STACKFRAME_SZ), %sp 67 or %sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp 68 add %g6, %sp, %sp 69 70 /* Turn on traps (PSR_ET). */ 71 rd %psr, %g1 72 wr %g1, PSR_ET, %psr ! traps on 73 WRITE_PAUSE 74 75 /* Init our caches, etc. */ 76 set poke_srmmu, %g5 77 ld [%g5], %g5 78 call %g5 79 nop 80 81 /* Start this processor. */ 82 call smp4m_callin 83 nop 84 85 b,a smp_do_cpu_idle 86 87 .text 88 .align 4 89 90smp_do_cpu_idle: 91 call cpu_idle 92 mov 0, %o0 93 94 call cpu_panic 95 nop 96 97__smp4m_processor_id: 98 rd %tbr, %g2 99 srl %g2, 12, %g2 100 and %g2, 3, %g2 101 retl 102 mov %g1, %o7 103 104__smp4d_processor_id: 105 lda [%g0] ASI_M_VIKING_TMP1, %g2 106 retl 107 mov %g1, %o7 108 109__leon_processor_id: 110 rd %asr17,%g2 111 srl %g2,28,%g2 112 retl 113 mov %g1, %o7 114 115/* CPUID in bootbus can be found at PA 0xff0140000 */ 116#define SUN4D_BOOTBUS_CPUID 0xf0140000 117 118 __CPUINIT 119 .align 4 120 121sun4d_cpu_startup: 122 /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ 123 set (PSR_PIL | PSR_S | PSR_PS), %g1 124 wr %g1, 0x0, %psr ! traps off though 125 WRITE_PAUSE 126 127 /* Our %wim is one behind CWP */ 128 mov 2, %g1 129 wr %g1, 0x0, %wim 130 WRITE_PAUSE 131 132 /* Set tbr - we use just one trap table. */ 133 set trapbase, %g1 134 wr %g1, 0x0, %tbr 135 WRITE_PAUSE 136 137 /* Get our CPU id out of bootbus */ 138 set SUN4D_BOOTBUS_CPUID, %g3 139 lduba [%g3] ASI_M_CTL, %g3 140 and %g3, 0xf8, %g3 141 srl %g3, 3, %g1 142 sta %g1, [%g0] ASI_M_VIKING_TMP1 143 144 /* Give ourselves a stack and curptr. */ 145 set current_set, %g5 146 srl %g3, 1, %g4 147 ld [%g5 + %g4], %g6 148 149 sethi %hi(THREAD_SIZE - STACKFRAME_SZ), %sp 150 or %sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp 151 add %g6, %sp, %sp 152 153 /* Turn on traps (PSR_ET). */ 154 rd %psr, %g1 155 wr %g1, PSR_ET, %psr ! traps on 156 WRITE_PAUSE 157 158 /* Init our caches, etc. */ 159 set poke_srmmu, %g5 160 ld [%g5], %g5 161 call %g5 162 nop 163 164 /* Start this processor. */ 165 call smp4d_callin 166 nop 167 168 b,a smp_do_cpu_idle 169 170#ifdef CONFIG_SPARC_LEON 171 172 __CPUINIT 173 .align 4 174 .global leon_smp_cpu_startup, smp_penguin_ctable 175 176leon_smp_cpu_startup: 177 178 set smp_penguin_ctable,%g1 179 ld [%g1+4],%g1 180 srl %g1,4,%g1 181 set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */ 182 sta %g1, [%g5] ASI_M_MMUREGS 183 184 /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ 185 set (PSR_PIL | PSR_S | PSR_PS), %g1 186 wr %g1, 0x0, %psr ! traps off though 187 WRITE_PAUSE 188 189 /* Our %wim is one behind CWP */ 190 mov 2, %g1 191 wr %g1, 0x0, %wim 192 WRITE_PAUSE 193 194 /* Set tbr - we use just one trap table. */ 195 set trapbase, %g1 196 wr %g1, 0x0, %tbr 197 WRITE_PAUSE 198 199 /* Get our CPU id */ 200 rd %asr17,%g3 201 202 /* Give ourselves a stack and curptr. */ 203 set current_set, %g5 204 srl %g3, 28, %g4 205 sll %g4, 2, %g4 206 ld [%g5 + %g4], %g6 207 208 sethi %hi(THREAD_SIZE - STACKFRAME_SZ), %sp 209 or %sp, %lo(THREAD_SIZE - STACKFRAME_SZ), %sp 210 add %g6, %sp, %sp 211 212 /* Turn on traps (PSR_ET). */ 213 rd %psr, %g1 214 wr %g1, PSR_ET, %psr ! traps on 215 WRITE_PAUSE 216 217 /* Init our caches, etc. */ 218 set poke_srmmu, %g5 219 ld [%g5], %g5 220 call %g5 221 nop 222 223 /* Start this processor. */ 224 call leon_callin 225 nop 226 227 b,a smp_do_cpu_idle 228 229#endif 230