xref: /titanic_52/usr/src/uts/sun4u/ml/cpr_resume_setup.s (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate/*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate/*
23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate
29*7c478bd9Sstevel@tonic-gate#if defined(lint)
30*7c478bd9Sstevel@tonic-gate#include <sys/types.h>
31*7c478bd9Sstevel@tonic-gate#else   /* lint */
32*7c478bd9Sstevel@tonic-gate#include "assym.h"
33*7c478bd9Sstevel@tonic-gate#endif  /* lint */
34*7c478bd9Sstevel@tonic-gate
35*7c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
36*7c478bd9Sstevel@tonic-gate#include <sys/machthread.h>		/* for reg definition */
37*7c478bd9Sstevel@tonic-gate
38*7c478bd9Sstevel@tonic-gate#include <sys/machasi.h>		/* sun4u ASI */
39*7c478bd9Sstevel@tonic-gate#include <sys/mmu.h>
40*7c478bd9Sstevel@tonic-gate#include <sys/privregs.h>
41*7c478bd9Sstevel@tonic-gate#include <sys/machparam.h>
42*7c478bd9Sstevel@tonic-gate#include <vm/hat_sfmmu.h>
43*7c478bd9Sstevel@tonic-gate#include <sys/cpr_impl.h>
44*7c478bd9Sstevel@tonic-gate#include <sys/intreg.h>
45*7c478bd9Sstevel@tonic-gate#include <sys/clock.h>
46*7c478bd9Sstevel@tonic-gate
47*7c478bd9Sstevel@tonic-gate/*
48*7c478bd9Sstevel@tonic-gate * resume kernel entry point from cprboot
49*7c478bd9Sstevel@tonic-gate * 	1. restore I/D TSB registers
50*7c478bd9Sstevel@tonic-gate *	2. restore primary and secondary context registers
51*7c478bd9Sstevel@tonic-gate *	3. initialize cpu state registers
52*7c478bd9Sstevel@tonic-gate *	4. set up the thread and lwp registers for the cpr process
53*7c478bd9Sstevel@tonic-gate *	5. switch to kernel trap
54*7c478bd9Sstevel@tonic-gate *	6. restore checkpoint pc and stack pointer
55*7c478bd9Sstevel@tonic-gate *	7. longjmp back to kernel
56*7c478bd9Sstevel@tonic-gate *
57*7c478bd9Sstevel@tonic-gate * registers from cprboot:exit_to_kernel()
58*7c478bd9Sstevel@tonic-gate *	%o0	prom cookie
59*7c478bd9Sstevel@tonic-gate *	%o1	struct sun4u_machdep *mdp
60*7c478bd9Sstevel@tonic-gate *
61*7c478bd9Sstevel@tonic-gate * Any change to this register assignment
62*7c478bd9Sstevel@tonic-gate * require changes to cprboot_srt0.s
63*7c478bd9Sstevel@tonic-gate */
64*7c478bd9Sstevel@tonic-gate
65*7c478bd9Sstevel@tonic-gate#if defined(lint)
66*7c478bd9Sstevel@tonic-gate
67*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
68*7c478bd9Sstevel@tonic-gatevoid
69*7c478bd9Sstevel@tonic-gatei_cpr_resume_setup(void *cookie, csu_md_t *mdp)
70*7c478bd9Sstevel@tonic-gate{}
71*7c478bd9Sstevel@tonic-gate
72*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
73*7c478bd9Sstevel@tonic-gateint
74*7c478bd9Sstevel@tonic-gatei_cpr_cif_wrapper(void *args)
75*7c478bd9Sstevel@tonic-gate{ return (0); }
76*7c478bd9Sstevel@tonic-gate
77*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
78*7c478bd9Sstevel@tonic-gatevoid
79*7c478bd9Sstevel@tonic-gatedtlb_wr_entry(uint_t index, tte_t *tte, uint64_t *va_tag)
80*7c478bd9Sstevel@tonic-gate{}
81*7c478bd9Sstevel@tonic-gate
82*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
83*7c478bd9Sstevel@tonic-gatevoid
84*7c478bd9Sstevel@tonic-gateitlb_wr_entry(uint_t index, tte_t *tte, uint64_t *va_tag)
85*7c478bd9Sstevel@tonic-gate{}
86*7c478bd9Sstevel@tonic-gate
87*7c478bd9Sstevel@tonic-gate#else	/* lint */
88*7c478bd9Sstevel@tonic-gate
89*7c478bd9Sstevel@tonic-gate	!
90*7c478bd9Sstevel@tonic-gate	! reserve 4k for cpr tmp stack; tstack should be first,
91*7c478bd9Sstevel@tonic-gate	! any new data symbols should be added after tstack.
92*7c478bd9Sstevel@tonic-gate	!
93*7c478bd9Sstevel@tonic-gate	.seg	".data"
94*7c478bd9Sstevel@tonic-gate	.global	i_cpr_data_page, i_cpr_tstack_size
95*7c478bd9Sstevel@tonic-gate	.global	i_cpr_orig_cif
96*7c478bd9Sstevel@tonic-gate
97*7c478bd9Sstevel@tonic-gate	.align	MMU_PAGESIZE
98*7c478bd9Sstevel@tonic-gatei_cpr_data_page:
99*7c478bd9Sstevel@tonic-gate	.skip	4096
100*7c478bd9Sstevel@tonic-gatei_cpr_tstack:
101*7c478bd9Sstevel@tonic-gate	.word	0
102*7c478bd9Sstevel@tonic-gatei_cpr_tstack_size:
103*7c478bd9Sstevel@tonic-gate	.word	4096
104*7c478bd9Sstevel@tonic-gate
105*7c478bd9Sstevel@tonic-gate	.align	8
106*7c478bd9Sstevel@tonic-gateprom_tba:
107*7c478bd9Sstevel@tonic-gate	.word	0, 0
108*7c478bd9Sstevel@tonic-gatei_cpr_orig_cif:
109*7c478bd9Sstevel@tonic-gate	.nword	0
110*7c478bd9Sstevel@tonic-gatei_cpr_tmp_cif:
111*7c478bd9Sstevel@tonic-gate	.nword	0
112*7c478bd9Sstevel@tonic-gate
113*7c478bd9Sstevel@tonic-gate
114*7c478bd9Sstevel@tonic-gate	!
115*7c478bd9Sstevel@tonic-gate	! set text to begin at a page boundary so we can
116*7c478bd9Sstevel@tonic-gate	! map this one page and jump to it from cprboot
117*7c478bd9Sstevel@tonic-gate	!
118*7c478bd9Sstevel@tonic-gate	.seg	".text"
119*7c478bd9Sstevel@tonic-gate	.align	MMU_PAGESIZE
120*7c478bd9Sstevel@tonic-gate
121*7c478bd9Sstevel@tonic-gate	ENTRY(i_cpr_resume_setup)
122*7c478bd9Sstevel@tonic-gate	!
123*7c478bd9Sstevel@tonic-gate	! save %o args to locals
124*7c478bd9Sstevel@tonic-gate	!
125*7c478bd9Sstevel@tonic-gate	mov	%o0, %l4
126*7c478bd9Sstevel@tonic-gate	mov	%o1, %l5
127*7c478bd9Sstevel@tonic-gate
128*7c478bd9Sstevel@tonic-gate	!
129*7c478bd9Sstevel@tonic-gate	! Restore PCONTEXT
130*7c478bd9Sstevel@tonic-gate	!
131*7c478bd9Sstevel@tonic-gate	sethi	%hi(FLUSH_ADDR), %g3
132*7c478bd9Sstevel@tonic-gate	ld	[%l5 + CPR_MD_PRI], %g1		! mdp->mmu_ctx_pri
133*7c478bd9Sstevel@tonic-gate	set	MMU_PCONTEXT, %g2
134*7c478bd9Sstevel@tonic-gate	stxa	%g1, [%g2]ASI_DMMU
135*7c478bd9Sstevel@tonic-gate	flush	%g3
136*7c478bd9Sstevel@tonic-gate
137*7c478bd9Sstevel@tonic-gate	!
138*7c478bd9Sstevel@tonic-gate	! Restore SCONTEXT.  We do not need to set up the TSB
139*7c478bd9Sstevel@tonic-gate	! registers.  Since we are restoring INVALID_CONTEXT into
140*7c478bd9Sstevel@tonic-gate	! the secondary context the HAT will do that for us.
141*7c478bd9Sstevel@tonic-gate	!
142*7c478bd9Sstevel@tonic-gate	ld	[%l5 + CPR_MD_SEC], %g1		! mdp->mmu_ctx_sec
143*7c478bd9Sstevel@tonic-gate	set	MMU_SCONTEXT, %g2
144*7c478bd9Sstevel@tonic-gate	stxa	%g1, [%g2]ASI_DMMU
145*7c478bd9Sstevel@tonic-gate	flush	%g3
146*7c478bd9Sstevel@tonic-gate
147*7c478bd9Sstevel@tonic-gate	!
148*7c478bd9Sstevel@tonic-gate	! Allow user rdtick, and rdstick if applicable
149*7c478bd9Sstevel@tonic-gate	!
150*7c478bd9Sstevel@tonic-gate	CLEARTICKNPT
151*7c478bd9Sstevel@tonic-gate
152*7c478bd9Sstevel@tonic-gate	!
153*7c478bd9Sstevel@tonic-gate	! copy saved thread pointer to %g7
154*7c478bd9Sstevel@tonic-gate	!
155*7c478bd9Sstevel@tonic-gate	ldx	[%l5 + CPR_MD_THRP], THREAD_REG		! mdp->thrp
156*7c478bd9Sstevel@tonic-gate
157*7c478bd9Sstevel@tonic-gate	!
158*7c478bd9Sstevel@tonic-gate	! since csu_md_t lives in a cprboot data page,
159*7c478bd9Sstevel@tonic-gate	! copy select data to registers for later use
160*7c478bd9Sstevel@tonic-gate	! before freeing cprboot text/data pages
161*7c478bd9Sstevel@tonic-gate	!
162*7c478bd9Sstevel@tonic-gate	ldx	[%l5 + CPR_MD_QSAV_PC], %l7	! l7 = mdp->qsav_pc
163*7c478bd9Sstevel@tonic-gate	ldx	[%l5 + CPR_MD_QSAV_SP], %l6	! l6 = mdp->qsav_sp
164*7c478bd9Sstevel@tonic-gate
165*7c478bd9Sstevel@tonic-gate	!
166*7c478bd9Sstevel@tonic-gate	! save cookie from the new/tmp prom
167*7c478bd9Sstevel@tonic-gate	!
168*7c478bd9Sstevel@tonic-gate	set	i_cpr_tmp_cif, %g1
169*7c478bd9Sstevel@tonic-gate	stn	%l4, [%g1]
170*7c478bd9Sstevel@tonic-gate
171*7c478bd9Sstevel@tonic-gate	!
172*7c478bd9Sstevel@tonic-gate	! save prom tba
173*7c478bd9Sstevel@tonic-gate	!
174*7c478bd9Sstevel@tonic-gate	set	prom_tba, %g1
175*7c478bd9Sstevel@tonic-gate	rdpr	%tba, %g2
176*7c478bd9Sstevel@tonic-gate	stx	%g2, [%g1]
177*7c478bd9Sstevel@tonic-gate
178*7c478bd9Sstevel@tonic-gate	!
179*7c478bd9Sstevel@tonic-gate	! start slave cpus, pause them within kernel text,
180*7c478bd9Sstevel@tonic-gate	! and restore the original prom pages
181*7c478bd9Sstevel@tonic-gate	!
182*7c478bd9Sstevel@tonic-gate	call	i_cpr_mp_setup
183*7c478bd9Sstevel@tonic-gate	nop
184*7c478bd9Sstevel@tonic-gate
185*7c478bd9Sstevel@tonic-gate	!
186*7c478bd9Sstevel@tonic-gate	! since this routine is entered only by a jmp from cprboot,
187*7c478bd9Sstevel@tonic-gate	! we can set cpr_suspend_succeeded here
188*7c478bd9Sstevel@tonic-gate	!
189*7c478bd9Sstevel@tonic-gate	set	cpr_suspend_succeeded, %l0
190*7c478bd9Sstevel@tonic-gate	mov	1, %l1
191*7c478bd9Sstevel@tonic-gate	st	%l1, [%l0]
192*7c478bd9Sstevel@tonic-gate
193*7c478bd9Sstevel@tonic-gate	!
194*7c478bd9Sstevel@tonic-gate	! special shortened version of longjmp
195*7c478bd9Sstevel@tonic-gate	! Don't need to flushw
196*7c478bd9Sstevel@tonic-gate	!
197*7c478bd9Sstevel@tonic-gate	mov	%l7, %i7		! i7 = saved pc
198*7c478bd9Sstevel@tonic-gate	mov	%l6, %fp		! i6 = saved sp
199*7c478bd9Sstevel@tonic-gate	ret				! return 1
200*7c478bd9Sstevel@tonic-gate	restore	%g0, 1, %o0		! takes underflow, switches stack
201*7c478bd9Sstevel@tonic-gate	SET_SIZE(i_cpr_resume_setup)
202*7c478bd9Sstevel@tonic-gate
203*7c478bd9Sstevel@tonic-gate
204*7c478bd9Sstevel@tonic-gate	!
205*7c478bd9Sstevel@tonic-gate	! while running on the new/tmp prom, the prom's trap table
206*7c478bd9Sstevel@tonic-gate	! must be used to handle translations within prom space
207*7c478bd9Sstevel@tonic-gate	! since the kernel's mappings may not match this prom.
208*7c478bd9Sstevel@tonic-gate	!
209*7c478bd9Sstevel@tonic-gate	! always set %tba to the prom's trap table before calling
210*7c478bd9Sstevel@tonic-gate	! any prom service; after returning, read %tba again;
211*7c478bd9Sstevel@tonic-gate	! if the %tba wasn't changed by the prom service,
212*7c478bd9Sstevel@tonic-gate	! restore the original %tba.
213*7c478bd9Sstevel@tonic-gate	!
214*7c478bd9Sstevel@tonic-gate	! a call stack looks like this:
215*7c478bd9Sstevel@tonic-gate	!
216*7c478bd9Sstevel@tonic-gate	! current prom cookie
217*7c478bd9Sstevel@tonic-gate	! [i_cpr_cif_wrapper]
218*7c478bd9Sstevel@tonic-gate	! client_handler
219*7c478bd9Sstevel@tonic-gate	! p1275_sparc_cif_handler
220*7c478bd9Sstevel@tonic-gate	! prom_xxx
221*7c478bd9Sstevel@tonic-gate	!
222*7c478bd9Sstevel@tonic-gate	ENTRY(i_cpr_cif_wrapper)
223*7c478bd9Sstevel@tonic-gate	save	%sp, -SA64(MINFRAME64 + 8), %sp
224*7c478bd9Sstevel@tonic-gate	rdpr	%tba, %o5		! read original %tba
225*7c478bd9Sstevel@tonic-gate	stx	%o5, [%fp + V9BIAS64 - 8]
226*7c478bd9Sstevel@tonic-gate	set	prom_tba, %l4
227*7c478bd9Sstevel@tonic-gate	ldx	[%l4], %o4		! read prom_tba
228*7c478bd9Sstevel@tonic-gate	wrpr	%o4, %tba		! switch to prom trap table
229*7c478bd9Sstevel@tonic-gate
230*7c478bd9Sstevel@tonic-gate	set	i_cpr_tmp_cif, %g3	! cookie for new/tmp prom
231*7c478bd9Sstevel@tonic-gate	ldn	[%g3], %g4
232*7c478bd9Sstevel@tonic-gate	jmpl	%g4, %o7		! call prom service
233*7c478bd9Sstevel@tonic-gate	mov	%i0, %o0
234*7c478bd9Sstevel@tonic-gate
235*7c478bd9Sstevel@tonic-gate	ldx	[%l4], %o4		! read prom_tba
236*7c478bd9Sstevel@tonic-gate	rdpr	%tba, %o3		! read current %tba
237*7c478bd9Sstevel@tonic-gate	cmp	%o3, %o4		! did prom change %tba ?
238*7c478bd9Sstevel@tonic-gate	bne,pn	%xcc, 1f		! yes, dont reset %tba
239*7c478bd9Sstevel@tonic-gate	nop
240*7c478bd9Sstevel@tonic-gate	ldx	[%fp + V9BIAS64 - 8], %o5
241*7c478bd9Sstevel@tonic-gate	wrpr	%o5, %tba		! no change, restore orignal
242*7c478bd9Sstevel@tonic-gate1:
243*7c478bd9Sstevel@tonic-gate	ret
244*7c478bd9Sstevel@tonic-gate	restore	%g0, %o0, %o0
245*7c478bd9Sstevel@tonic-gate	SET_SIZE(i_cpr_cif_wrapper)
246*7c478bd9Sstevel@tonic-gate
247*7c478bd9Sstevel@tonic-gate
248*7c478bd9Sstevel@tonic-gate	!
249*7c478bd9Sstevel@tonic-gate	! write dtlb entry at index
250*7c478bd9Sstevel@tonic-gate	!
251*7c478bd9Sstevel@tonic-gate	ENTRY(dtlb_wr_entry)
252*7c478bd9Sstevel@tonic-gate	sllx    %o0, 3, %o0			! index << 3
253*7c478bd9Sstevel@tonic-gate	ldx	[%o1], %o5			! o5 = tte.ll
254*7c478bd9Sstevel@tonic-gate	ldx	[%o2], %o4			! o4 = va_tag
255*7c478bd9Sstevel@tonic-gate	srlx	%o4, MMU_PAGESHIFT, %o4		! clear any page offset
256*7c478bd9Sstevel@tonic-gate	sllx	%o4, MMU_PAGESHIFT, %o4		! o4 = va_tag & PAGEMASK
257*7c478bd9Sstevel@tonic-gate	set	MMU_TAG_ACCESS, %o3
258*7c478bd9Sstevel@tonic-gate	stxa	%o4, [%o3]ASI_DMMU
259*7c478bd9Sstevel@tonic-gate	stxa	%o5, [%o0]ASI_DTLB_ACCESS
260*7c478bd9Sstevel@tonic-gate	membar	#Sync
261*7c478bd9Sstevel@tonic-gate	retl
262*7c478bd9Sstevel@tonic-gate	nop
263*7c478bd9Sstevel@tonic-gate	SET_SIZE(dtlb_wr_entry)
264*7c478bd9Sstevel@tonic-gate
265*7c478bd9Sstevel@tonic-gate
266*7c478bd9Sstevel@tonic-gate	!
267*7c478bd9Sstevel@tonic-gate	! write itlb entry at index
268*7c478bd9Sstevel@tonic-gate	!
269*7c478bd9Sstevel@tonic-gate	ENTRY(itlb_wr_entry)
270*7c478bd9Sstevel@tonic-gate	sllx    %o0, 3, %o0			! index << 3
271*7c478bd9Sstevel@tonic-gate	ldx	[%o1], %o5			! o5 = tte.ll
272*7c478bd9Sstevel@tonic-gate	ldx	[%o2], %o4			! o4 = va_tag
273*7c478bd9Sstevel@tonic-gate	srlx	%o4, MMU_PAGESHIFT, %o4		! clear any page offset
274*7c478bd9Sstevel@tonic-gate	sllx	%o4, MMU_PAGESHIFT, %o4		! o4 = va_tag & PAGEMASK
275*7c478bd9Sstevel@tonic-gate	set	MMU_TAG_ACCESS, %o3
276*7c478bd9Sstevel@tonic-gate	stxa	%o4, [%o3]ASI_IMMU
277*7c478bd9Sstevel@tonic-gate	stxa	%o5, [%o0]ASI_ITLB_ACCESS
278*7c478bd9Sstevel@tonic-gate	membar	#Sync
279*7c478bd9Sstevel@tonic-gate	retl
280*7c478bd9Sstevel@tonic-gate	nop
281*7c478bd9Sstevel@tonic-gate	SET_SIZE(itlb_wr_entry)
282*7c478bd9Sstevel@tonic-gate
283*7c478bd9Sstevel@tonic-gate#endif /* !lint */
284