1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 1999-2002 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29/*
30 * cb_srt0.s - cprboot startup code
31 */
32#include <sys/asm_linkage.h>
33#include <sys/machthread.h>
34#include <sys/privregs.h>
35#include <sys/cpr_impl.h>
36#include <sys/param.h>
37#include <sys/mmu.h>
38
39#if defined(lint)
40#include <sys/cpr.h>
41void *estack;
42caddr_t _end[1];
43#endif
44
45#include "cprboot.h"
46
47
48#if defined(lint)
49
50/* ARGSUSED */
51void
52_start(void *a, ...)
53{}
54
55#else	/* !lint */
56
57	.seg	".bss"
58	.align	MMU_PAGESIZE
59	.skip	CB_SSS
60eslave_stack:				! top of slave cpu stack
61	.skip	CB_MSS
62estack:					! top of cprboot stack
63	.global	estack
64
65	.seg	".data"
66	.align	8
67local_cif:
68	.xword	0			! space for prom cookie
69
70	.seg	".text"
71	.align	8
72
73	!
74	! regs on entry:
75	! %o4 = prom cookie
76	!
77	ENTRY(_start)
78	set	estack - STACK_BIAS, %o5
79	save	%o5, -SA(MINFRAME), %sp
80
81	!
82	! clear the bss
83	!
84	set	_edata, %o0
85	set	_end, %g2
86	call	bzero
87	sub	%g2, %o0, %o1		! bss size = (_end - _edata)
88
89	!
90	! Set pstate to a known state:
91	! enable fp, privilege, interrupt enable
92	!
93	wrpr	%g0, PSTATE_PEF|PSTATE_PRIV|PSTATE_IE, %pstate
94
95	!
96	! first stage
97	!
98	set	local_cif, %g2
99	stx	%i4, [%g2]
100	mov	%i4, %o0		! SPARCV9/CIF
101	call	main			! Mcprboot [tag]
102	mov	1, %o1			! first=true
103
104	!
105	! switch to new stack
106	!
107	set	CB_STACK_VIRT + CB_STACK_SIZE, %o5
108	sub	%o5, STACK_BIAS + SA(MINFRAME), %sp
109
110	!
111	! second stage
112	!
113	set	local_cif, %g2
114	ldx	[%g2], %o0		! SPARCV9/CIF
115	call	main			! Mcprboot [tag]
116	mov	0, %o1			! first=false
117
118	call	prom_exit_to_mon	! can't happen... :-)
119	nop
120	SET_SIZE(_start)
121
122#endif	/* lint */
123
124
125#if defined(lint)
126
127/*
128 * args from cprboot main:
129 * 	%o0	prom cookie
130 *	%o1	struct sun4u_machdep *mdp
131 *
132 * Any change to this register assignment requires
133 * changes to uts/sun4u/ml/cpr_resume_setup.s
134 */
135
136/* ARGSUSED */
137void
138exit_to_kernel(void *cookie, csu_md_t *mdp)
139{}
140
141#else	/* lint */
142
143	ENTRY(exit_to_kernel)
144	!
145	! setup temporary stack and adjust
146	! by the saved kernel stack bias
147	!
148	set	tmp_stack, %g1			! g1 = &tmp_stack
149	ldx	[%g1], %l2			! l2 =  tmp_stack
150	sub	%l2, SA(MINFRAME), %l2
151	ld	[%o1 + CPR_MD_KSB], %l4		! mdp->ksb
152	sub	%l2, %l4, %sp
153
154	!
155	! set pstate and wstate from saved values
156	!
157	lduh	[%o1 + CPR_MD_KPSTATE], %l4	! l4 = mdp->kpstate
158	wrpr	%g0, %l4, %pstate
159	lduh	[%o1 + CPR_MD_KWSTATE], %l4	! l4 = mdp->kwstate
160	wrpr	%g0, %l4, %wstate
161
162	!
163	! jump to kernel with %o0 and %o1 unchanged
164	!
165	ldx	[%o1 + CPR_MD_FUNC], %l3	! l3 = mdp->func
166	jmpl	%l3, %g0
167	nop
168
169	/* there is no return from here */
170	unimp	0
171	SET_SIZE(exit_to_kernel)
172
173#endif	/* lint */
174
175
176#if defined(lint)
177
178/* ARGSUSED */
179int
180client_handler(void *cif_handler, void *arg_array)
181{ return (0); }
182
183#else
184
185	!
186	! 64/64 client interface for ieee1275 prom
187	!
188	ENTRY(client_handler)
189	mov	%o7, %g1
190	mov	%o0, %g5
191	mov	%o1, %o0
192	jmp	%g5
193	mov	%g1, %o7
194	SET_SIZE(client_handler)
195
196#endif	/* lint */
197
198
199#if defined(lint)
200
201/* ARGSUSED */
202void
203bzero(void *base, size_t len)
204{}
205
206#else
207
208	ENTRY(bzero)
209	brz,pn	%o1, 2f
210	nop
211	mov	%o0, %o2
212	mov	%o1, %o3
2131:
214	stub	%g0, [%o2]
215	dec	%o3
216	brgz,pt	%o3, 1b
217	inc	%o2
2182:
219	retl
220	nop
221	SET_SIZE(bzero)
222
223#endif	/* lint */
224
225
226#if defined(lint)
227
228/* ARGSUSED */
229void
230phys_xcopy(physaddr_t phys_src, physaddr_t phys_dst, size_t len)
231{}
232
233#else
234
235	!
236	! copy len bytes from src to dst phys addrs;
237	! requires src/dst/len 8-byte alignment;
238	! used only for copying phys pages
239	!
240	ENTRY(phys_xcopy)
241	brz,pn	%o2, 2f
242	mov	%o0, %o3			! %o3 = src
243	mov	%o1, %o4			! %o4 = dst
2441:
245	ldxa	[%o3]ASI_MEM, %o5		! %o5  = *src
246	stxa	%o5, [%o4]ASI_MEM		! *dst = %o5
247	dec	8, %o2				! len  -= 8
248	inc	8, %o3				! src  += 8
249	brgz,pt	%o2, 1b				! branch when (len > 0)
250	inc	8, %o4				! dst  += 8
2512:
252	retl
253	nop
254	SET_SIZE(phys_xcopy)
255
256#endif
257
258
259#if defined(lint)
260
261/* ARGSUSED */
262void
263get_dtlb_entry(int index, caddr_t *vaddrp, tte_t *tte)
264{}
265
266#else	/* lint */
267
268	ENTRY(get_dtlb_entry)
269	sllx	%o0, 3, %o0
270	ldxa	[%o0]ASI_DTLB_ACCESS, %o3
271	stx	%o3, [%o2]
272	ldxa	[%o0]ASI_DTLB_TAGREAD, %o4
273	retl
274	stx	%o4, [%o1]
275	SET_SIZE(get_dtlb_entry)
276
277#endif
278
279
280#if defined(lint)
281
282/* ARGSUSED */
283void
284set_itlb_entry(int index, caddr_t vaddr, tte_t *tte)
285{}
286
287/* ARGSUSED */
288void
289set_dtlb_entry(int index, caddr_t vaddr, tte_t *tte)
290{}
291
292#else	/* lint */
293
294	ENTRY(set_dtlb_entry)
295	sllx    %o0, 3, %o0
296	srlx	%o1, MMU_PAGESHIFT, %o1
297	sllx	%o1, MMU_PAGESHIFT, %o1
298	set	MMU_TAG_ACCESS, %o4
299	ldx	[%o2], %o3
300	stxa	%o1, [%o4]ASI_DMMU
301	stxa	%o3, [%o0]ASI_DTLB_ACCESS
302	membar	#Sync
303	retl
304	nop
305	SET_SIZE(set_dtlb_entry)
306
307	ENTRY(set_itlb_entry)
308	sllx    %o0, 3, %o0
309	srlx	%o1, MMU_PAGESHIFT, %o1
310	sllx	%o1, MMU_PAGESHIFT, %o1
311	set	MMU_TAG_ACCESS, %o4
312	ldx	[%o2], %o3
313	stxa	%o1, [%o4]ASI_IMMU
314	stxa	%o3, [%o0]ASI_ITLB_ACCESS
315	membar	#Sync
316	retl
317	nop
318	SET_SIZE(set_itlb_entry)
319
320#endif
321
322
323#if defined(lint)
324
325uint_t
326getmid(void)
327{ return (0); }
328
329#else	/* lint */
330
331	ENTRY(getmid)
332	CPU_INDEX(%o0, %o1)
333	retl
334	nop
335	SET_SIZE(getmid)
336
337#endif
338
339
340#if defined(lint)
341
342/* ARGSUSED */
343void
344cpu_launch(int cpuid)
345{
346	slave_init(cpuid);
347}
348
349#else	/* lint */
350
351	ENTRY(cpu_launch)
352	set	CB_STACK_VIRT + CB_SSS, %o5
353	sub	%o5, STACK_BIAS + SA(MINFRAME), %sp
354	wrpr	%g0, PSTATE_PEF|PSTATE_PRIV|PSTATE_IE, %pstate
355	call	slave_init
356	nop
357	unimp	0
358	SET_SIZE(cpu_launch)
359
360#endif
361
362
363#if defined(lint)
364
365void
366membar_stld(void)
367{}
368
369#else	/* lint */
370
371	ENTRY(membar_stld)
372	retl
373	membar	#StoreLoad
374	SET_SIZE(membar_stld)
375
376#endif
377
378
379#if defined(lint)
380
381/* ARGSUSED */
382void
383cb_usec_wait(int usecs)
384{}
385
386#else
387
388	.align	32			! cache alignment for next 8 instr
389	ENTRY(cb_usec_wait)
390
391	sethi	%hi(cpu_delay), %o1
392	ld	[%o1 + %lo(cpu_delay)], %o1
393	mov	%o1, %o2
3941:	brnz,pt	%o2, 1b			! usec countdown loop
395	dec	%o2			! 2 instr in loop
396
397	dec	%o0			! for each usec:
398	brgz,pt	%o0, 1b			! run the above loop
399	mov	%o1, %o2
400
401	retl
402	nop
403	SET_SIZE(cb_usec_wait)
404
405#endif
406