1 1.8 martin /* $NetBSD: srt0.s,v 1.8 2019/11/28 14:21:25 martin Exp $ */ 2 1.1 mrg 3 1.1 mrg /* 4 1.1 mrg * Copyright (C) 1995, 1996 Wolfgang Solfrank. 5 1.1 mrg * Copyright (C) 1995, 1996 TooLs GmbH. 6 1.1 mrg * All rights reserved. 7 1.1 mrg * 8 1.1 mrg * Redistribution and use in source and binary forms, with or without 9 1.1 mrg * modification, are permitted provided that the following conditions 10 1.1 mrg * are met: 11 1.1 mrg * 1. Redistributions of source code must retain the above copyright 12 1.1 mrg * notice, this list of conditions and the following disclaimer. 13 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 mrg * notice, this list of conditions and the following disclaimer in the 15 1.1 mrg * documentation and/or other materials provided with the distribution. 16 1.1 mrg * 3. All advertising materials mentioning features or use of this software 17 1.1 mrg * must display the following acknowledgement: 18 1.1 mrg * This product includes software developed by TooLs GmbH. 19 1.1 mrg * 4. The name of TooLs GmbH may not be used to endorse or promote products 20 1.1 mrg * derived from this software without specific prior written permission. 21 1.1 mrg * 22 1.1 mrg * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 23 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 mrg * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 1.1 mrg * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 1.1 mrg * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 28 1.1 mrg * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 1.1 mrg * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 1.1 mrg * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 1.1 mrg * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 mrg */ 33 1.1 mrg 34 1.1 mrg #include <machine/psl.h> 35 1.1 mrg #include <machine/param.h> 36 1.1 mrg #include <machine/frame.h> 37 1.1 mrg #include <machine/asm.h> 38 1.3 cdi #include <machine/ctlreg.h> 39 1.3 cdi 40 1.3 cdi 41 1.3 cdi #ifdef _LP64 42 1.3 cdi #define LDPTR ldx 43 1.3 cdi #else 44 1.3 cdi #define LDPTR lduw 45 1.3 cdi #endif 46 1.3 cdi 47 1.2 petrov 48 1.2 petrov .register %g2,#ignore 49 1.2 petrov .register %g3,#ignore 50 1.1 mrg 51 1.1 mrg /* 52 1.1 mrg * Globals 53 1.1 mrg */ 54 1.1 mrg .globl _esym 55 1.1 mrg .data 56 1.1 mrg _esym: .word 0 /* end of symbol table */ 57 1.1 mrg 58 1.1 mrg /* 59 1.1 mrg * Startup entry 60 1.1 mrg */ 61 1.1 mrg .text 62 1.1 mrg .globl _start, _C_LABEL(kernel_text) 63 1.1 mrg _C_LABEL(kernel_text) = _start 64 1.1 mrg _start: 65 1.1 mrg nop ! For some reason this is needed to fixup the text section 66 1.8 martin b 1f 67 1.8 martin nop 68 1.8 martin .zero 8192-(.-_start) /* hack for OpenBIOS, see port-sparc64/54719 */ 69 1.8 martin 1: 70 1.1 mrg /* 71 1.1 mrg * Start by creating a stack for ourselves. 72 1.1 mrg */ 73 1.1 mrg #ifdef _LP64 74 1.1 mrg /* 64-bit stack */ 75 1.1 mrg btst 1, %sp 76 1.1 mrg set CC64FSZ, %g1 ! Frame Size (negative) 77 1.1 mrg bnz 1f 78 1.1 mrg set BIAS, %g2 ! Bias (negative) 79 1.1 mrg andn %sp, 0x0f, %sp ! 16 byte align, per ELF spec. 80 1.1 mrg add %g1, %g2, %g1 ! Frame + Bias 81 1.1 mrg 1: 82 1.1 mrg sub %sp, %g1, %g1 83 1.1 mrg save %g1, %g0, %sp 84 1.1 mrg #else 85 1.1 mrg /* 32-bit stack */ 86 1.1 mrg btst 1, %sp 87 1.1 mrg set CC64FSZ, %g1 ! Frame Size (negative) 88 1.1 mrg bz 1f 89 1.1 mrg set BIAS, %g2 90 1.1 mrg sub %g1, %g2, %g1 91 1.1 mrg 1: 92 1.1 mrg sub %sp, %g1, %g1 ! This is so we properly sign-extend things 93 1.1 mrg andn %g1, 0x7, %g1 94 1.1 mrg save %g1, %g0, %sp 95 1.1 mrg #endif 96 1.3 cdi 97 1.1 mrg /* 98 1.1 mrg * Set the psr into a known state: 99 1.1 mrg * Set supervisor mode, interrupt level >= 13, traps enabled 100 1.1 mrg */ 101 1.1 mrg wrpr %g0, 0, %pil ! So I lied 102 1.1 mrg wrpr %g0, PSTATE_PRIV+PSTATE_IE, %pstate 103 1.1 mrg 104 1.1 mrg clr %g4 ! Point %g4 to start of data segment 105 1.1 mrg ! only problem is that apparently the 106 1.1 mrg ! start of the data segment is 0 107 1.3 cdi 108 1.1 mrg /* 109 1.3 cdi * void 110 1.3 cdi * main(void *openfirmware) 111 1.1 mrg */ 112 1.1 mrg call _C_LABEL(main) 113 1.3 cdi mov %i4, %o0 114 1.3 cdi call _C_LABEL(OF_exit) 115 1.1 mrg nop 116 1.1 mrg 117 1.1 mrg /* 118 1.1 mrg * void syncicache(void* start, int size) 119 1.1 mrg * 120 1.1 mrg * I$ flush. Really simple. Just flush over the whole range. 121 1.1 mrg */ 122 1.1 mrg .align 8 123 1.1 mrg .globl _C_LABEL(syncicache) 124 1.1 mrg _C_LABEL(syncicache): 125 1.1 mrg dec 4, %o1 126 1.1 mrg flush %o0 127 1.1 mrg brgz,a,pt %o1, _C_LABEL(syncicache) 128 1.1 mrg inc 4, %o0 129 1.1 mrg retl 130 1.1 mrg nop 131 1.1 mrg 132 1.1 mrg /* 133 1.1 mrg * openfirmware(cell* param); 134 1.1 mrg * 135 1.1 mrg * OpenFirmware entry point 136 1.1 mrg * 137 1.1 mrg * If we're running in 32-bit mode we need to convert to a 64-bit stack 138 1.1 mrg * and 64-bit cells. The cells we'll allocate off the stack for simplicity. 139 1.1 mrg */ 140 1.1 mrg .align 8 141 1.1 mrg .globl _C_LABEL(openfirmware) 142 1.1 mrg FTYPE(openfirmware) 143 1.1 mrg _C_LABEL(openfirmware): 144 1.1 mrg andcc %sp, 1, %g0 145 1.1 mrg bz,pt %icc, 1f 146 1.1 mrg sethi %hi(_C_LABEL(romp)), %o1 147 1.1 mrg 148 1.3 cdi LDPTR [%o1+%lo(_C_LABEL(romp))], %o4 ! v9 stack, just load the addr and callit 149 1.1 mrg save %sp, -CC64FSZ, %sp 150 1.1 mrg mov %i0, %o0 ! Copy over our parameter 151 1.1 mrg mov %g1, %l1 152 1.1 mrg mov %g2, %l2 153 1.1 mrg mov %g3, %l3 154 1.1 mrg mov %g4, %l4 155 1.1 mrg mov %g5, %l5 156 1.1 mrg mov %g6, %l6 157 1.1 mrg mov %g7, %l7 158 1.1 mrg rdpr %pstate, %l0 159 1.1 mrg jmpl %i4, %o7 160 1.1 mrg wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate 161 1.1 mrg wrpr %l0, %g0, %pstate 162 1.1 mrg mov %l1, %g1 163 1.1 mrg mov %l2, %g2 164 1.1 mrg mov %l3, %g3 165 1.1 mrg mov %l4, %g4 166 1.1 mrg mov %l5, %g5 167 1.1 mrg mov %l6, %g6 168 1.1 mrg mov %l7, %g7 169 1.1 mrg ret 170 1.1 mrg restore %o0, %g0, %o0 171 1.1 mrg 172 1.1 mrg 1: ! v8 -- need to screw with stack & params 173 1.1 mrg save %sp, -CC64FSZ, %sp ! Get a new 64-bit stack frame 174 1.1 mrg add %sp, -BIAS, %sp 175 1.1 mrg sethi %hi(_C_LABEL(romp)), %o1 176 1.1 mrg rdpr %pstate, %l0 177 1.3 cdi LDPTR [%o1+%lo(_C_LABEL(romp))], %o1 ! Do the actual call 178 1.1 mrg srl %sp, 0, %sp 179 1.1 mrg mov %i0, %o0 180 1.1 mrg mov %g1, %l1 181 1.1 mrg mov %g2, %l2 182 1.1 mrg mov %g3, %l3 183 1.1 mrg mov %g4, %l4 184 1.1 mrg mov %g5, %l5 185 1.1 mrg mov %g6, %l6 186 1.1 mrg mov %g7, %l7 187 1.1 mrg jmpl %o1, %o7 188 1.1 mrg wrpr %g0, PSTATE_PROM|PSTATE_IE, %pstate ! Enable 64-bit addresses for the prom 189 1.1 mrg wrpr %l0, 0, %pstate 190 1.1 mrg mov %l1, %g1 191 1.1 mrg mov %l2, %g2 192 1.1 mrg mov %l3, %g3 193 1.1 mrg mov %l4, %g4 194 1.1 mrg mov %l5, %g5 195 1.1 mrg mov %l6, %g6 196 1.1 mrg mov %l7, %g7 197 1.1 mrg ret 198 1.1 mrg restore %o0, %g0, %o0 199 1.1 mrg 200 1.3 cdi /* 201 1.3 cdi * vaddr_t 202 1.3 cdi * itlb_va_to_pa(vaddr_t) 203 1.3 cdi * 204 1.3 cdi * Find out if there is a mapping in iTLB for a given virtual address, 205 1.3 cdi * return -1 if there is none. 206 1.3 cdi */ 207 1.3 cdi .align 8 208 1.3 cdi .globl _C_LABEL(itlb_va_to_pa) 209 1.3 cdi _C_LABEL(itlb_va_to_pa): 210 1.5 martin set _C_LABEL(itlb_slot_max), %o3 211 1.5 martin ld [%o3], %o3 212 1.5 martin dec %o3 213 1.5 martin sllx %o3, 3, %o3 214 1.3 cdi clr %o1 215 1.3 cdi 0: ldxa [%o1] ASI_IMMU_TLB_TAG, %o2 216 1.3 cdi cmp %o2, %o0 217 1.3 cdi bne,a %xcc, 1f 218 1.3 cdi nop 219 1.3 cdi /* return PA of matching entry */ 220 1.3 cdi ldxa [%o1] ASI_IMMU_TLB_DATA, %o0 221 1.3 cdi sllx %o0, 23, %o0 222 1.3 cdi srlx %o0, PGSHIFT+23, %o0 223 1.3 cdi sllx %o0, PGSHIFT, %o0 224 1.3 cdi retl 225 1.3 cdi mov %o0, %o1 226 1.5 martin 1: cmp %o1, %o3 227 1.3 cdi blu %xcc, 0b 228 1.3 cdi add %o1, 8, %o1 229 1.3 cdi clr %o0 230 1.3 cdi retl 231 1.3 cdi not %o0 232 1.3 cdi 233 1.3 cdi /* 234 1.3 cdi * vaddr_t 235 1.3 cdi * dtlb_va_to_pa(vaddr_t) 236 1.3 cdi * 237 1.3 cdi * Find out if there is a mapping in dTLB for a given virtual address, 238 1.3 cdi * return -1 if there is none. 239 1.3 cdi */ 240 1.3 cdi .align 8 241 1.3 cdi .globl _C_LABEL(dtlb_va_to_pa) 242 1.3 cdi _C_LABEL(dtlb_va_to_pa): 243 1.5 martin set _C_LABEL(dtlb_slot_max), %o3 244 1.5 martin ld [%o3], %o3 245 1.5 martin dec %o3 246 1.5 martin sllx %o3, 3, %o3 247 1.3 cdi clr %o1 248 1.3 cdi 0: ldxa [%o1] ASI_DMMU_TLB_TAG, %o2 249 1.3 cdi cmp %o2, %o0 250 1.3 cdi bne,a %xcc, 1f 251 1.3 cdi nop 252 1.3 cdi /* return PA of matching entry */ 253 1.3 cdi ldxa [%o1] ASI_DMMU_TLB_DATA, %o0 254 1.3 cdi sllx %o0, 23, %o0 255 1.3 cdi srlx %o0, PGSHIFT+23, %o0 256 1.3 cdi sllx %o0, PGSHIFT, %o0 257 1.3 cdi retl 258 1.3 cdi mov %o0, %o1 259 1.5 martin 1: cmp %o1, %o3 260 1.3 cdi blu %xcc, 0b 261 1.3 cdi add %o1, 8, %o1 262 1.3 cdi clr %o0 263 1.3 cdi retl 264 1.3 cdi not %o0 265 1.3 cdi 266 1.3 cdi /* 267 1.3 cdi * void 268 1.4 uwe * itlb_enter(vaddr_t vpn, uint32_t data_hi, uint32_t data_lo) 269 1.3 cdi * 270 1.3 cdi * Insert new mapping into iTLB. Data tag is passed in two different 271 1.3 cdi * registers so that it works even with 32-bit compilers. 272 1.3 cdi */ 273 1.3 cdi .align 8 274 1.3 cdi .globl _C_LABEL(itlb_enter) 275 1.3 cdi _C_LABEL(itlb_enter): 276 1.3 cdi sllx %o1, 32, %o1 277 1.3 cdi or %o1, %o2, %o1 278 1.3 cdi rdpr %pstate, %o4 279 1.3 cdi wrpr %o4, PSTATE_IE, %pstate 280 1.3 cdi mov TLB_TAG_ACCESS, %o3 281 1.3 cdi stxa %o0, [%o3] ASI_IMMU 282 1.3 cdi stxa %o1, [%g0] ASI_IMMU_DATA_IN 283 1.3 cdi membar #Sync 284 1.3 cdi retl 285 1.3 cdi wrpr %o4, 0, %pstate 286 1.3 cdi 287 1.5 martin 288 1.5 martin /* 289 1.5 martin * void 290 1.5 martin * dtlb_replace(vaddr_t vpn, uint32_t data_hi, uint32_t data_lo) 291 1.5 martin * 292 1.5 martin * Replace mapping in dTLB. Data tag is passed in two different 293 1.5 martin * registers so that it works even with 32-bit compilers. 294 1.5 martin */ 295 1.5 martin .align 8 296 1.5 martin .globl _C_LABEL(dtlb_replace) 297 1.5 martin _C_LABEL(dtlb_replace): 298 1.5 martin sllx %o1, 32, %o1 299 1.5 martin or %o1, %o2, %o1 300 1.5 martin rdpr %pstate, %o4 301 1.5 martin wrpr %o4, PSTATE_IE, %pstate 302 1.5 martin /* loop over dtlb entries */ 303 1.5 martin clr %o5 304 1.5 martin 0: 305 1.5 martin ldxa [%o5] ASI_DMMU_TLB_TAG, %o2 306 1.5 martin cmp %o2, %o0 307 1.5 martin bne,a %xcc, 1f 308 1.5 martin nop 309 1.5 martin /* found - modify entry */ 310 1.5 martin mov TLB_TAG_ACCESS, %o2 311 1.5 martin stxa %o0, [%o2] ASI_DMMU 312 1.5 martin stxa %o1, [%o5] ASI_DMMU_TLB_DATA 313 1.5 martin membar #Sync 314 1.5 martin retl 315 1.5 martin wrpr %o4, 0, %pstate 316 1.5 martin 317 1.5 martin /* advance to next tlb entry */ 318 1.5 martin 1: cmp %o5, 63<<3 319 1.5 martin blu %xcc, 0b 320 1.5 martin add %o5, 8, %o5 321 1.5 martin retl 322 1.5 martin nop 323 1.5 martin 324 1.3 cdi /* 325 1.3 cdi * void 326 1.4 uwe * dtlb_enter(vaddr_t vpn, uint32_t data_hi, uint32_t data_lo) 327 1.3 cdi * 328 1.3 cdi * Insert new mapping into dTLB. Data tag is passed in two different 329 1.3 cdi * registers so that it works even with 32-bit compilers. 330 1.3 cdi */ 331 1.3 cdi .align 8 332 1.3 cdi .globl _C_LABEL(dtlb_enter) 333 1.3 cdi _C_LABEL(dtlb_enter): 334 1.3 cdi sllx %o1, 32, %o1 335 1.3 cdi or %o1, %o2, %o1 336 1.3 cdi rdpr %pstate, %o4 337 1.3 cdi wrpr %o4, PSTATE_IE, %pstate 338 1.3 cdi mov TLB_TAG_ACCESS, %o3 339 1.3 cdi stxa %o0, [%o3] ASI_DMMU 340 1.3 cdi stxa %o1, [%g0] ASI_DMMU_DATA_IN 341 1.3 cdi membar #Sync 342 1.3 cdi retl 343 1.3 cdi wrpr %o4, 0, %pstate 344 1.3 cdi 345 1.3 cdi /* 346 1.3 cdi * u_int 347 1.3 cdi * get_cpuid(void); 348 1.3 cdi * 349 1.3 cdi * Return UPA identifier for the CPU we're running on. 350 1.3 cdi */ 351 1.3 cdi .align 8 352 1.3 cdi .globl _C_LABEL(get_cpuid) 353 1.3 cdi _C_LABEL(get_cpuid): 354 1.3 cdi UPA_GET_MID(%o0) 355 1.3 cdi retl 356 1.3 cdi nop 357 1.3 cdi 358 1.1 mrg #if 0 359 1.1 mrg .data 360 1.1 mrg .align 8 361 1.1 mrg bootstack: 362 1.1 mrg #define STACK_SIZE 0x14000 363 1.1 mrg .skip STACK_SIZE 364 1.1 mrg ebootstack: ! end (top) of boot stack 365 1.1 mrg #endif 366