1*8d92fc86Smartin/* $NetBSD: srt0.S,v 1.12 2016/03/10 20:22:52 martin Exp $ */ 27cedf69cSmrg 32a1ecde6Spk/*- 42a1ecde6Spk * Copyright (c) 1999 The NetBSD Foundation, Inc. 57cedf69cSmrg * All rights reserved. 67cedf69cSmrg * 72a1ecde6Spk * This code is derived from software contributed to The NetBSD Foundation 82a1ecde6Spk * by Paul Kranenburg. 92a1ecde6Spk * 107cedf69cSmrg * Redistribution and use in source and binary forms, with or without 117cedf69cSmrg * modification, are permitted provided that the following conditions 127cedf69cSmrg * are met: 137cedf69cSmrg * 1. Redistributions of source code must retain the above copyright 147cedf69cSmrg * notice, this list of conditions and the following disclaimer. 157cedf69cSmrg * 2. Redistributions in binary form must reproduce the above copyright 167cedf69cSmrg * notice, this list of conditions and the following disclaimer in the 177cedf69cSmrg * documentation and/or other materials provided with the distribution. 187cedf69cSmrg * 192a1ecde6Spk * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 202a1ecde6Spk * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 212a1ecde6Spk * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 222a1ecde6Spk * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 232a1ecde6Spk * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 242a1ecde6Spk * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 252a1ecde6Spk * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 262a1ecde6Spk * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 272a1ecde6Spk * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 282a1ecde6Spk * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 292a1ecde6Spk * POSSIBILITY OF SUCH DAMAGE. 307cedf69cSmrg */ 317cedf69cSmrg 32d292580fSpk#define _LOCORE /* XXX - fix Makefile */ 33d292580fSpk 347cedf69cSmrg#include <machine/param.h> 35da1407c4Spk#include <machine/asm.h> 367cedf69cSmrg#include <machine/psl.h> 377cedf69cSmrg 387cedf69cSmrg#define CCFSZ 96 397cedf69cSmrg 407cedf69cSmrg .file "str0.s" 417cedf69cSmrg 42da1407c4Spk .comm _C_LABEL(romp), 4 43da1407c4Spk .comm _C_LABEL(cputyp), 4 44da1407c4Spk .comm _C_LABEL(nbpg), 4 45da1407c4Spk .comm _C_LABEL(pgofset), 4 46da1407c4Spk .comm _C_LABEL(pgshift), 4 477cedf69cSmrg 487cedf69cSmrg .text 497cedf69cSmrg .globl start 507cedf69cSmrg 517cedf69cSmrgstart: 527cedf69cSmrg /* 537cedf69cSmrg * Set up a stack. 547cedf69cSmrg */ 557cedf69cSmrg set start, %o1 567cedf69cSmrg save %o1, -CCFSZ, %sp 577cedf69cSmrg 587cedf69cSmrg /* 598390d190Suwe * Find which address we are at. 607cedf69cSmrg */ 617cedf69cSmrg1: call 2f 628390d190Suwe sethi %hi(1b), %l0 638390d190Suwe2: or %l0, %lo(1b), %l0 648390d190Suwe cmp %l0, %o7 ! %o7 contains actual address of 1b 658390d190Suwe beq 4f ! already there, no need to relocate 667cedf69cSmrg nop 678390d190Suwe 688390d190Suwe /* 698390d190Suwe * Relocate. 708390d190Suwe */ 718390d190Suwe add %o7, (start-1b), %l0 727cedf69cSmrg set start, %l1 7344f6bd0dSpk set _edata, %o0 747cedf69cSmrg sub %o0, %l1, %l2 ! length 757cedf69cSmrg3: ld [%l0], %o0 767cedf69cSmrg add %l0, 4, %l0 777cedf69cSmrg st %o0, [%l1] 787cedf69cSmrg subcc %l2, 4, %l2 797cedf69cSmrg bg 3b 807cedf69cSmrg add %l1, 4, %l1 817cedf69cSmrg 828390d190Suwe /* 838390d190Suwe * Jump to our relocated self. 848390d190Suwe */ 857cedf69cSmrg set 4f, %g1 867cedf69cSmrg jmp %g1 877cedf69cSmrg nop 887cedf69cSmrg 897cedf69cSmrg4: 907cedf69cSmrg#ifdef notyet 917cedf69cSmrg /* 927cedf69cSmrg * Enable traps 937cedf69cSmrg */ 947cedf69cSmrg wr %g0, 0, %wim ! make sure we can set psr 957cedf69cSmrg nop; nop; nop 967cedf69cSmrg wr %g0, PSR_S|PSR_PS|PSR_PIL, %psr ! set initial psr 977cedf69cSmrg nop; nop; nop 987cedf69cSmrg wr %g0, 2, %wim ! set initial %wim (w1 invalid) 997cedf69cSmrg 1007cedf69cSmrg rd %psr, %l0 1017cedf69cSmrg wr %l0, PSR_ET, %psr 1027cedf69cSmrg nop; nop; nop 1037cedf69cSmrg#endif 1047cedf69cSmrg 1057cedf69cSmrg /* 1067cedf69cSmrg * Clear BSS 1077cedf69cSmrg */ 1087cedf69cSmrg set _edata, %o0 ! bzero(edata, end - edata) 109*8d92fc86Smartin1: ! check if %o0 is well aligned 110*8d92fc86Smartin andcc %o0, 3, %o2 111*8d92fc86Smartin bz 2f 112*8d92fc86Smartin nop 113*8d92fc86Smartin stb %g0, [%o0] 114*8d92fc86Smartin b 1b 115*8d92fc86Smartin add %o0, 1, %o0 116*8d92fc86Smartin 117*8d92fc86Smartin2: ! now we have %o0 4 byte aligned 1187cedf69cSmrg set _end, %o1 119d292580fSpk subcc %o1, %o0, %o1 120d292580fSpk bz 2f ! in case there is no BSS 121d292580fSpk 122*8d92fc86Smartin srl %o1, 2, %o1 ! we do 4 byte writes now 123d292580fSpk1: 124d292580fSpk st %g0, [%o0] ! while (n--) 125d292580fSpk subcc %o1, 1, %o1 ! *p = 0; etc.. 126d292580fSpk bnz 1b 127d292580fSpk add %o0, 4, %o0 128d292580fSpk2: 1297cedf69cSmrg 1307cedf69cSmrg /* 1317cedf69cSmrg * Enable interrupts, but only above level 11. This enables "L1-A", 1327cedf69cSmrg * but avoids spurious interrupt bites from most other devices. 1337cedf69cSmrg */ 1347cedf69cSmrg rd %psr, %o0 1357cedf69cSmrg andn %o0, PSR_PIL, %o0 1367cedf69cSmrg wr %o0, 0xb00, %psr ! (11 << 8) 1377cedf69cSmrg nop; nop; nop 1387cedf69cSmrg 1397cedf69cSmrg /* 1407cedf69cSmrg * Set CPU type that we are running on. 1417cedf69cSmrg */ 142da1407c4Spk sethi %hi(_C_LABEL(cputyp)), %o0 1437cedf69cSmrg set 0x4000, %g7 1447cedf69cSmrg cmp %i0, %g7 145d292580fSpk beq is_sun4 1467cedf69cSmrg nop 1477cedf69cSmrg 148d292580fSpk mov CPU_SUN4C, %g4 149d292580fSpk mov SUN4CM_PGSHIFT, %g5 150d292580fSpk 1517cedf69cSmrg /* 15243adc870Suwe * OpenProm machines pass PROM vector in %o0 (%i0 after save) 15343adc870Suwe * OpenFirm machines pass OF entry in %o3 (%i3 after save) 1547cedf69cSmrg */ 15543adc870Suwe cmp %i0, 0 15643adc870Suwe be is_openfirm 15743adc870Suwe nop 15843adc870Suwe 15943adc870Suwe ! save address of PROM vector 160da1407c4Spk sethi %hi(_C_LABEL(romp)), %o1 161da1407c4Spk st %i0, [%o1 + %lo(_C_LABEL(romp))] 16243adc870Suwe b,a is_sun4cm 1637cedf69cSmrg 16443adc870Suweis_openfirm: 1655fe7a8a8Suwe ! only javastations have OFW, so we know it is a sun4m 1665fe7a8a8Suwe mov CPU_SUN4M, %g4 16743adc870Suwe ! save address of OpenFirmware client interface handler 16843adc870Suwe sethi %hi(_C_LABEL(romp)), %o1 16943adc870Suwe st %i3, [%o1 + %lo(_C_LABEL(romp))] 170d292580fSpk b,a is_sun4cm 1717cedf69cSmrg 172d292580fSpkis_sun4: 1737cedf69cSmrg mov CPU_SUN4, %g4 1747cedf69cSmrg mov SUN4_PGSHIFT, %g5 1757cedf69cSmrg 176d292580fSpkis_sun4cm: 177da1407c4Spk st %g4, [%o0 + %lo(_C_LABEL(cputyp))] 178da1407c4Spk sethi %hi(_C_LABEL(pgshift)), %o0 ! pgshift = log2(nbpg) 179da1407c4Spk st %g5, [%o0 + %lo(_C_LABEL(pgshift))] 1807cedf69cSmrg 1817cedf69cSmrg mov 1, %o0 ! nbpg = 1 << pgshift 1827cedf69cSmrg sll %o0, %g5, %g5 183da1407c4Spk sethi %hi(_C_LABEL(nbpg)), %o0 ! nbpg = bytes in a page 184da1407c4Spk st %g5, [%o0 + %lo(_C_LABEL(nbpg))] 1857cedf69cSmrg 1867cedf69cSmrg sub %g5, 1, %g5 187da1407c4Spk sethi %hi(_C_LABEL(pgofset)), %o0 ! page offset = nbpg - 1 188da1407c4Spk st %g5, [%o0 + %lo(_C_LABEL(pgofset))] 1897cedf69cSmrg 190da1407c4Spk call _C_LABEL(main) 1917cedf69cSmrg mov %i0, %o0 1927cedf69cSmrg 1937cedf69cSmrg ret 1947cedf69cSmrg restore 1957cedf69cSmrg 196d292580fSpk/* 197d292580fSpk * NO-OP place holder function. 198d292580fSpk */ 199da1407c4SpkENTRY(sparc_noop) 200d292580fSpk retl 201d292580fSpk nop 202d292580fSpk 20324bb9554Spk/* 20424bb9554Spk * Openfirmware entry point: openfirmware(void *args) 20524bb9554Spk */ 20624bb9554SpkENTRY(openfirmware) 20724bb9554Spk sethi %hi(_C_LABEL(romp)), %o1 20824bb9554Spk ld [%o1 + %lo(_C_LABEL(romp))], %o2 20924bb9554Spk jmp %o2 21024bb9554Spk nop 2117cedf69cSmrg 2127cedf69cSmrg#ifdef TIGHT 2137cedf69cSmrg 2147cedf69cSmrg/* 2157cedf69cSmrg * XXX - Space saving .div & .rem routines (small & non-negative numbres only) 2167cedf69cSmrg */ 2177cedf69cSmrg .align 4 2187cedf69cSmrg .global .div, .udiv 2197cedf69cSmrg! int n = 0; while (a >= b) { a -= b; n++; }; return n; 2207cedf69cSmrg.div: 2217cedf69cSmrg.udiv: 2227cedf69cSmrg cmp %o0, %o1 2237cedf69cSmrg bl 2f 2247cedf69cSmrg mov 0, %o5 2257cedf69cSmrg1: 2267cedf69cSmrg sub %o0, %o1, %o0 2277cedf69cSmrg cmp %o0, %o1 2287cedf69cSmrg bge 1b 2297cedf69cSmrg add %o5, 1, %o5 2307cedf69cSmrg2: 2317cedf69cSmrg retl 2327cedf69cSmrg mov %o5, %o0 2337cedf69cSmrg 2347cedf69cSmrg .align 4 2357cedf69cSmrg .global .rem, .urem 2367cedf69cSmrg! while (a>=b) a -= b; return a; 2377cedf69cSmrg.rem: 2387cedf69cSmrg.urem: 2397cedf69cSmrg cmp %o0, %o1 2407cedf69cSmrg bl 2f 2417cedf69cSmrg nop 2427cedf69cSmrg sub %o0, %o1, %o0 2437cedf69cSmrg1: 2447cedf69cSmrg cmp %o0, %o1 2457cedf69cSmrg bge,a 1b 2467cedf69cSmrg sub %o0, %o1, %o0 2477cedf69cSmrg2: 2487cedf69cSmrg retl 2497cedf69cSmrg nop 2507cedf69cSmrg 2517cedf69cSmrg#endif /* TIGHT */ 252