summaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/hvtramp.S
blob: 9365432904d64eb7ef017506991eab7bcbea4f2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* hvtramp.S: Hypervisor start-cpu trampoline code.
 *
 * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
 */

#include <linux/init.h>

#include <asm/thread_info.h>
#include <asm/hypervisor.h>
#include <asm/scratchpad.h>
#include <asm/spitfire.h>
#include <asm/hvtramp.h>
#include <asm/pstate.h>
#include <asm/ptrace.h>
#include <asm/head.h>
#include <asm/asi.h>
#include <asm/pil.h>

	__CPUINIT
	.align		8
	.globl		hv_cpu_startup, hv_cpu_startup_end

	/* This code executes directly out of the hypervisor
	 * with physical addressing (va==pa).  %o0 contains
	 * our client argument which for Linux points to
	 * a descriptor data structure which defines the
	 * MMU entries we need to load up.
	 *
	 * After we set things up we enable the MMU and call
	 * into the kernel.
	 *
	 * First setup basic privileged cpu state.
	 */
hv_cpu_startup:
	SET_GL(0)
	wrpr		%g0, PIL_NORMAL_MAX, %pil
	wrpr		%g0, 0, %canrestore
	wrpr		%g0, 0, %otherwin
	wrpr		%g0, 6, %cansave
	wrpr		%g0, 6, %cleanwin
	wrpr		%g0, 0, %cwp
	wrpr		%g0, 0, %wstate
	wrpr		%g0, 0, %tl

	sethi		%hi(sparc64_ttable_tl0), %g1
	wrpr		%g1, %tba

	mov		%o0, %l0

	lduw		[%l0 + HVTRAMP_DESCR_CPU], %g1
	mov		SCRATCHPAD_CPUID, %g2
	stxa		%g1, [%g2] ASI_SCRATCHPAD

	ldx		[%l0 + HVTRAMP_DESCR_FAULT_INFO_VA], %g2
	stxa		%g2, [%g0] ASI_SCRATCHPAD

	mov		0, %l1
	lduw		[%l0 + HVTRAMP_DESCR_NUM_MAPPINGS], %l2
	add		%l0, HVTRAMP_DESCR_MAPS, %l3

1:	ldx		[%l3 + HVTRAMP_MAPPING_VADDR], %o0
	clr		%o1
	ldx		[%l3 + HVTRAMP_MAPPING_TTE], %o2
	mov		HV_MMU_IMMU | HV_MMU_DMMU, %o3
	mov		HV_FAST_MMU_MAP_PERM_ADDR, %o5
	ta		HV_FAST_TRAP

	brnz,pn		%o0, 80f
	 nop

	add		%l1, 1, %l1
	cmp		%l1, %l2
	blt,a,pt	%xcc, 1b
	 add		%l3, HVTRAMP_MAPPING_SIZE, %l3

	ldx		[%l0 + HVTRAMP_DESCR_FAULT_INFO_PA], %o0
	mov		HV_FAST_MMU_FAULT_AREA_CONF, %o5
	ta		HV_FAST_TRAP

	brnz,pn		%o0, 80f
	 nop

	wrpr		%g0, (PSTATE_PRIV | PSTATE_PEF), %pstate

	ldx		[%l0 + HVTRAMP_DESCR_THREAD_REG], %l6

	mov		1, %o0
	set		1f, %o1
	mov		HV_FAST_MMU_ENABLE, %o5
	ta		HV_FAST_TRAP

	ba,pt		%xcc, 80f
	 nop

1:
	wr		%g0, 0, %fprs
	wr		%g0, ASI_P, %asi

	mov		PRIMARY_CONTEXT, %g7
	stxa		%g0, [%g7] ASI_MMU
	membar		#Sync

	mov		SECONDARY_CONTEXT, %g7
	stxa		%g0, [%g7] ASI_MMU
	membar		#Sync

	mov		%l6, %g6
	ldx		[%g6 + TI_TASK], %g4

	mov		1, %g5
	sllx		%g5, THREAD_SHIFT, %g5
	sub		%g5, (STACKFRAME_SZ + STACK_BIAS), %g5
	add		%g6, %g5, %sp
	mov		0, %fp

	call		init_irqwork_curcpu
	 nop
	call		hard_smp_processor_id
	 nop

	call		sun4v_register_mondo_queues
	 nop

	call		init_cur_cpu_trap
	 mov		%g6, %o0

	wrpr		%g0, (PSTATE_PRIV | PSTATE_PEF | PSTATE_IE), %pstate

	call		smp_callin
	 nop
	call		cpu_idle
	 mov		0, %o0
	call		cpu_panic
	 nop

80:	ba,pt		%xcc, 80b
	 nop

	.align		8
hv_cpu_startup_end: