1/*
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License.  See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 1999 by Helge Deller
8 * Copyright 1999 SuSE GmbH (Philipp Rumpf)
9 * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
10 *
11 * Initial Version 04-23-1999 by Helge Deller <deller@gmx.de>
12 */
13
14#include <linux/autoconf.h>	/* for CONFIG_SMP */
15
16#include <asm/offset.h>
17#include <asm/psw.h>
18
19#include <asm/assembly.h>
20#include <asm/pgtable.h>
21
22
23	.level 1.1
24
25	.section	.initcall.init
26	.align		4
27	.export __initcall_start
28__initcall_start:
29	.export __initcall_end
30__initcall_end:
31	.export __setup_start
32__setup_start:
33	.export __setup_end
34__setup_end:
35
36	.data
37
38	.export boot_args
39boot_args:
40	.word 0 /* arg0 */
41	.word 0 /* arg1 */
42	.word 0 /* arg2 */
43	.word 0 /* arg3 */
44
45	.text
46	.align	4
47	.import init_task_union,data
48	.import	$global$		/* forward declaration */
49	.import fault_vector_11,code	/* IVA parisc 1.1 32 bit */
50	.import fault_vector_20,code	/* IVA parisc 2.0 32 bit */
51	.import start_parisc,code	/* then enable VM and go here */
52
53	.export stext
54	.export _stext,data		/* Kernel want it this way! */
55_stext:
56stext:
57	.proc
58	.callinfo
59
60	/* Make sure sr4-sr7 are set to zero for the kernel address space */
61	mtsp	%r0,%sr4
62	mtsp	%r0,%sr5
63	mtsp	%r0,%sr6
64	mtsp	%r0,%sr7
65
66	/* Clear BSS (shouldn't the boot loader do this?) */
67
68	.import _edata,data
69	.import _end,data
70
71	ldil            L%PA(_edata),%r3
72	ldo             R%PA(_edata)(%r3),%r3
73	ldil            L%PA(_end),%r4
74	ldo             R%PA(_end)(%r4),%r4
75$bss_loop:
76	cmpb,<<,n       %r3,%r4,$bss_loop
77	stw,ma          %r0,4(%r3)
78
79	/* Save away the arguments the boot loader passed in (32 bit args) */
80
81	ldil            L%PA(boot_args),%r1
82	ldo             R%PA(boot_args)(%r1),%r1
83	stw,ma          %arg0,4(%r1)
84	stw,ma          %arg1,4(%r1)
85	stw,ma          %arg2,4(%r1)
86	stw,ma          %arg3,4(%r1)
87
88	/* Initialize startup VM. Just map first 8 MB of memory */
89	ldil		L%PA(pg0),%r1
90	ldo		R%PA(pg0)(%r1),%r1
91	ldo		_PAGE_TABLE(%r1),%r3
92
93	ldil		L%PA(swapper_pg_dir),%r4
94	ldo		R%PA(swapper_pg_dir)(%r4),%r4
95	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
96	mtctl		%r4,%cr25	/* Initialize user root pointer */
97
98#if (__PAGE_OFFSET != 0x10000000UL)
99Error! Code below (the next two stw's) needs to be changed
100#endif
101
102	stw             %r3,0x100(%r4)  /* Hardwired 0x1... kernel Vaddr start*/
103	ldo		0x1000(%r3),%r3
104	stw             %r3,0x104(%r4)
105	ldo		_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
106$pgt_fill_loop:
107	stwm		%r3,4(%r1)
108	ldo		0x1000(%r3),%r3
109	bb,>=		%r3,8,$pgt_fill_loop
110	nop
111
112
113	/* Load the return address...er...crash 'n burn */
114	copy		%r0,%r2
115
116	/* And the RFI Target address too */
117	ldil            L%start_kernel,%r11
118	ldo             R%start_kernel(%r11),%r11
119
120	/* And the initial task pointer */
121
122	ldil            L%init_task_union,%r6
123	ldo             R%init_task_union(%r6),%r6
124	mtctl           %r6,%cr30
125
126	/* And the stack pointer too */
127
128	ldo             TASK_SZ_ALGN(%r6),%sp
129
130	/* And the interrupt stack */
131
132	ldil            L%interrupt_stack,%r6
133	ldo             R%interrupt_stack(%r6),%r6
134	mtctl           %r6,%cr31
135
136#ifdef CONFIG_SMP
137	/* Set the smp rendevous address into page zero.
138	** It would be safer to do this in init_smp_config() but
139	** it's just way easier to deal with here because
140	** of 64-bit function ptrs and the address is local to this file.
141	*/
142	ldil		L%PA(smp_slave_stext),%r10
143	ldo		R%PA(smp_slave_stext)(%r10),%r10
144	stw		%r10,0x10(%r0)	/* MEM_RENDEZ */
145	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI - assume addr < 4GB */
146
147	/* FALLTHROUGH */
148	.procend
149
150	/*
151	** Code Common to both Monarch and Slave processors.
152	** Entry:
153	**    %r11 must contain RFI target address.
154	**    %r25/%r26 args to pass to target function
155	**    %r2  in case rfi target decides it didn't like something
156	**
157	** Caller must init: SR4-7, %sp, %r10, %cr24/25,
158	*/
159common_stext:
160	.proc
161	.callinfo
162#else
163	/* Clear PDC entry point - we won't use it */
164	stw		%r0,0x10(%r0)	/* MEM_RENDEZ */
165	stw		%r0,0x28(%r0)	/* MEM_RENDEZ_HI */
166#endif
167
168	/* PARANOID: clear user scratch/user space SR's */
169	mtsp	%r0,%sr0
170	mtsp	%r0,%sr1
171	mtsp	%r0,%sr2
172	mtsp	%r0,%sr3
173
174	/* Initialize Protection Registers */
175	mtctl	%r0,%cr8
176	mtctl	%r0,%cr9
177	mtctl	%r0,%cr12
178	mtctl	%r0,%cr13
179
180	/* Initialize the global data pointer */
181	ldil		L%$global$,%dp
182	ldo		R%$global$(%dp),%dp
183
184	/*
185	 * Set up our interrupt table.  HPMCs might not work after this!
186	 *
187	 * We need to install the correct iva for PA1.1 or PA2.0. The
188	 * following short sequence of instructions can determine this
189	 * (without being illegal on a PA1.1 machine).
190	 */
191	ldi		32,%r10
192	mtctl		%r10,%cr11
193	.level 2.0
194	mfctl,w		%cr11,%r10
195	.level 1.1
196	comib,<>,n	0,%r10,$is_pa20
197	ldil		L%PA(fault_vector_11),%r10
198	b		$install_iva
199	ldo		R%PA(fault_vector_11)(%r10),%r10
200
201$is_pa20:
202	ldil		L%PA(fault_vector_20),%r10
203	ldo		R%PA(fault_vector_20)(%r10),%r10
204
205$install_iva:
206	mtctl		%r10,%cr14
207
208	/* Disable Q bit so we can load the iia queue */
209	rsm            PSW_SM_Q,%r0
210
211	/* kernel PSW:
212	 *  - no interruptions except HPMC and TOC (which are handled by PDC)
213	 *  - Q bit set (IODC / PDC interruptions)
214	 *  - big-endian
215	 *  - virtually mapped
216	 */
217	ldil		L%KERNEL_PSW,%r10
218	ldo		R%KERNEL_PSW(%r10),%r10
219	mtctl		%r10,%ipsw
220
221	/* Set the space pointers for the post-RFI world
222	** Clear the two-level IIA Space Queue, effectively setting
223	** Kernel space.
224	*/
225	mtctl		%r0,%cr17
226	mtctl		%r0,%cr17
227
228	/* Load RFI target into PC queue */
229	mtctl		%r11,%cr18
230	ldo		4(%r11),%r11
231	mtctl		%r11,%cr18
232
233	/* Jump to hyperspace */
234	rfi
235	nop
236
237	.procend
238
239#ifdef CONFIG_SMP
240
241	.import smp_init_current_idle_task,data
242	.import	smp_callin,code
243
244smp_callin_rtn:
245        .proc
246	.callinfo
247	break	1,1		/*  Break if returned from start_secondary */
248	nop
249	nop
250        .procend
251
252/***************************************************************************
253*
254* smp_slave_stext is executed by all non-monarch Processors when the Monarch
255* pokes the slave CPUs in smp.c:smp_boot_cpus().
256*
257* Once here, registers values are initialized in order to branch to virtual
258* mode. Once all available/eligible CPUs are in virtual mode, all are
259* released and start out by executing their own idle task.
260*****************************************************************************/
261
262
263smp_slave_stext:
264        .proc
265	.callinfo
266
267	/*
268	** Initialize Space registers
269	*/
270	mtsp	   %r0,%sr4
271	mtsp	   %r0,%sr5
272	mtsp	   %r0,%sr6
273	mtsp	   %r0,%sr7
274
275	/*  Initialize the SP - monarch sets up smp_init_current_idle_task */
276	ldil		L%PA(smp_init_current_idle_task),%sp
277	ldo		R%PA(smp_init_current_idle_task)(%sp),%sp
278	ldw		0(%sp),%sp	/* load task address */
279	mtctl           %sp,%cr30       /* store in cr30 */
280	addil		L%TASK_SZ_ALGN,%sp	/* stack is above task */
281	ldo		R%TASK_SZ_ALGN(%r1),%sp
282
283	/* point CPU to kernel page tables */
284	ldil		L%PA(swapper_pg_dir),%r4
285	ldo		R%PA(swapper_pg_dir)(%r4),%r4
286	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
287	mtctl		%r4,%cr25	/* Initialize user root pointer */
288
289	/* Load RFI *return* address in case smp_callin bails */
290	ldil		L%smp_callin_rtn,%r2
291	ldo		R%smp_callin_rtn(%r2),%r2
292
293	/* Load RFI target address.  */
294	ldil		L%smp_callin,%r11
295	ldo		R%smp_callin(%r11),%r11
296
297	/* ok...common code can handle the rest */
298	b		common_stext
299	nop
300
301	.procend
302#endif /* CONFIG_SMP */
303
304	.data
305
306	.align	4
307	.export	$global$,data
308
309	.type	$global$,@object
310	.size	$global$,4
311$global$:
312	.word 0
313