180709Sjake/*-
280709Sjake * Copyright (c) 2001 Jake Burkholder.
380709Sjake * All rights reserved.
480709Sjake *
580709Sjake * Redistribution and use in source and binary forms, with or without
680709Sjake * modification, are permitted provided that the following conditions
780709Sjake * are met:
880709Sjake * 1. Redistributions of source code must retain the above copyright
980709Sjake *    notice, this list of conditions and the following disclaimer.
1080709Sjake * 2. Redistributions in binary form must reproduce the above copyright
1180709Sjake *    notice, this list of conditions and the following disclaimer in the
1280709Sjake *    documentation and/or other materials provided with the distribution.
1380709Sjake *
1481337Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1580709Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1680709Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1781337Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1880709Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1980709Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2080709Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2180709Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2280709Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2380709Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2480709Sjake * SUCH DAMAGE.
2580709Sjake */
2680709Sjake
27114188Sjake#include <machine/asm.h>
28114188Sjake__FBSDID("$FreeBSD$");
2982902Sjake
3089038Sjake#include <machine/asi.h>
3180709Sjake#include <machine/asmacros.h>
32207248Smarius#include <machine/intr_machdep.h>
3382902Sjake#include <machine/pstate.h>
34205409Smarius#include <machine/wstate.h>
3580709Sjake
3680709Sjake#include "assym.s"
3780709Sjake
3888637Sjake	.register %g2,#ignore
3988637Sjake
4083756Sjake	.globl	kernbase
41181701Smarius	.set	kernbase, KERNBASE
4283756Sjake
4380709Sjake/*
4491617Sjake * void _start(caddr_t metadata, u_long o1, u_long o2, u_long o3,
45181701Smarius *     u_long ofw_vec)
4680709Sjake */
47100843SjakeENTRY(btext)
4880709SjakeENTRY(_start)
4989038Sjake	/*
50182020Smarius	 * Initialize misc. state to known values: interrupts disabled, normal
51207248Smarius	 * globals, windows flushed (cr = 0, cs = nwindows - 1), PIL_TICK and
52203833Smarius	 * floating point disabled.
53203833Smarius	 * Note that some firmware versions don't implement a clean window
54203833Smarius	 * trap handler so we unfortunately can't clear the windows by setting
55203833Smarius	 * %cleanwin to zero here.
5689038Sjake	 */
5789038Sjake	wrpr	%g0, PSTATE_NORMAL, %pstate
5880709Sjake	flushw
59207248Smarius	wrpr	%g0, PIL_TICK, %pil
6088637Sjake	wr	%g0, 0, %fprs
6180709Sjake
6289038Sjake	/*
63181701Smarius	 * Get onto our per-CPU panic stack, which precedes the struct pcpu in
64181701Smarius	 * the per-CPU page.
6589038Sjake	 */
6691360Sjake	SET(pcpu0 + (PCPU_PAGES * PAGE_SIZE) - PC_SIZEOF, %l1, %l0)
6789038Sjake	sub	%l0, SPOFF + CCFSZ, %sp
6889038Sjake
6989038Sjake	/*
7089038Sjake	 * Do initial bootstrap to setup pmap and thread0.
7189038Sjake	 */
7280709Sjake	call	sparc64_init
7389038Sjake	 nop
7489038Sjake
7589038Sjake	/*
7689038Sjake	 * Get onto thread0's kstack.
7789038Sjake	 */
7889038Sjake	sub	PCB_REG, SPOFF + CCFSZ, %sp
7989038Sjake
8089038Sjake	/*
8189038Sjake	 * And away we go.  This doesn't return.
8289038Sjake	 */
8380709Sjake	call	mi_startup
8480709Sjake	 nop
8589038Sjake	sir
8680709Sjake	! NOTREACHED
8780709SjakeEND(_start)
8880709Sjake
8988637Sjake/*
9089038Sjake * void cpu_setregs(struct pcpu *pc)
9189038Sjake */
9289038SjakeENTRY(cpu_setregs)
9391617Sjake	ldx	[%o0 + PC_CURPCB], %o1
9489038Sjake
9589038Sjake	/*
96207248Smarius	 * Ensure we are on normal globals.
9789038Sjake	 */
9889038Sjake	wrpr	%g0, PSTATE_NORMAL, %pstate
9989038Sjake
10089038Sjake	/*
101181701Smarius	 * Normal %g6 points to the current thread's PCB, and %g7 points to
102181701Smarius	 * the per-CPU data structure.
10389038Sjake	 */
10489038Sjake	mov	%o1, PCB_REG
10589038Sjake	mov	%o0, PCPU_REG
10689038Sjake
10789038Sjake	/*
108181701Smarius	 * Switch to alternate globals.
10989038Sjake	 */
11089038Sjake	wrpr	%g0, PSTATE_ALT, %pstate
11189038Sjake
11289038Sjake	/*
113181701Smarius	 * Alternate %g5 points to a per-CPU panic stack, %g6 points to the
114181701Smarius	 * current thread's PCB, and %g7 points to the per-CPU data structure.
11589038Sjake	 */
11689038Sjake	mov	%o0, ASP_REG
11789038Sjake	mov	%o1, PCB_REG
11889038Sjake	mov	%o0, PCPU_REG
11989038Sjake
12089038Sjake	/*
121181701Smarius	 * Switch to interrupt globals.
12289038Sjake	 */
12389038Sjake	wrpr	%g0, PSTATE_INTR, %pstate
12489038Sjake
12589038Sjake	/*
126181701Smarius	 * Interrupt %g7 points to the per-CPU data structure.
12789038Sjake	 */
12889038Sjake	mov	%o0, PCPU_REG
12989038Sjake
13089038Sjake	/*
131181701Smarius	 * Switch to normal globals again.
13289038Sjake	 */
13389038Sjake	wrpr	%g0, PSTATE_NORMAL, %pstate
13489038Sjake
13589038Sjake	/*
13689038Sjake	 * Force trap level 1 and take over the trap table.
13789038Sjake	 */
13889038Sjake	SET(tl0_base, %o2, %o1)
139205409Smarius	SET(tba_taken_over, %o3, %o2)
140205409Smarius	mov	1, %o3
141205409Smarius	wrpr	%g0, WSTATE_KERNEL, %wstate
14289038Sjake	wrpr	%g0, 1, %tl
14389038Sjake	wrpr	%o1, 0, %tba
144205409Smarius	stw	%o3, [%o2]
14589038Sjake
14689038Sjake	retl
14789038Sjake	 nop
14889038SjakeEND(cpu_setregs)
149