xref: /netbsd-src/sys/arch/sparc/stand/common/srt0.S (revision 8d92fc86f061af01a8a5c47adc2a8020aa2eee77)
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