1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Head.S contains the MIPS exception handler and startup code.
7 *
8 * Copyright (C) 1994, 1995 Waldorf Electronics
9 * Written by Ralf Baechle and Andreas Busse
10 * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle
11 * Copyright (C) 1999 Silicon Graphics, Inc.
12 */
13#include <linux/config.h>
14#include <linux/init.h>
15#include <asm/asm.h>
16#include <asm/regdef.h>
17#include <asm/processor.h>
18#include <asm/mipsregs.h>
19#include <asm/stackframe.h>
20#include <asm/pgtable.h>
21#include <asm/sn/addrs.h>
22#include <asm/sn/sn0/hubni.h>
23#include <asm/sn/klkernvars.h>
24
25	.macro	ARC64_TWIDDLE_PC
26#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL)
27	/* We get launched at a XKPHYS address but the kernel is linked to
28	   run at a KSEG0 address, so jump there.  */
29	PTR_LA	t0, \@f
30	jr	t0
31\@:
32#endif
33	.endm
34
35#ifdef CONFIG_SGI_IP27
36	/*
37	 * outputs the local nasid into res.  IP27 stuff.
38	 */
39	.macro GET_NASID_ASM res
40	dli	\res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
41	ld	\res, (\res)
42	and	\res, NSRI_NODEID_MASK
43	dsrl	\res, NSRI_NODEID_SHFT
44	.endm
45#endif /* CONFIG_SGI_IP27 */
46
47	/*
48	 * inputs are the text nasid in t1, data nasid in t2.
49	 */
50	.macro MAPPED_KERNEL_SETUP_TLB
51#ifdef CONFIG_MAPPED_KERNEL
52	/*
53	 * This needs to read the nasid - assume 0 for now.
54	 * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
55	 * 0+DVG in tlblo_1.
56	 */
57	dli	t0, 0xffffffffc0000000
58	dmtc0	t0, CP0_ENTRYHI
59	li	t0, 0x1c000		# Offset of text into node memory
60	dsll	t1, NASID_SHFT		# Shift text nasid into place
61	dsll	t2, NASID_SHFT		# Same for data nasid
62	or	t1, t1, t0		# Physical load address of kernel text
63	or	t2, t2, t0		# Physical load address of kernel data
64	dsrl	t1, 12			# 4K pfn
65	dsrl	t2, 12			# 4K pfn
66	dsll	t1, 6			# Get pfn into place
67	dsll	t2, 6			# Get pfn into place
68	li	t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6)
69	or	t0, t0, t1
70	mtc0	t0, CP0_ENTRYLO0	# physaddr, VG, cach exlwr
71	li	t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6)
72	or	t0, t0, t2
73	mtc0	t0, CP0_ENTRYLO1	# physaddr, DVG, cach exlwr
74	li	t0, 0x1ffe000		# MAPPED_KERN_TLBMASK, TLBPGMASK_16M
75	mtc0	t0, CP0_PAGEMASK
76	li	t0, 0			# KMAP_INX
77	mtc0	t0, CP0_INDEX
78	li	t0, 1
79	mtc0	t0, CP0_WIRED
80	tlbwi
81#else
82	mtc0	zero, CP0_WIRED
83#endif
84	.endm
85
86	.text
87
88EXPORT(stext)					# used for profiling
89EXPORT(_stext)
90
91	__INIT
92
93NESTED(kernel_entry, 16, sp)			# kernel entry point
94
95	ori	sp, 0xf				# align stack on 16 byte.
96	xori	sp, 0xf
97
98#ifdef CONFIG_SGI_IP27
99	GET_NASID_ASM	t1
100	move	t2, t1				# text and data are here
101	MAPPED_KERNEL_SETUP_TLB
102#endif /* IP27 */
103
104	ARC64_TWIDDLE_PC
105
106	CLI					# disable interrupts
107
108	/*
109	 * The firmware/bootloader passes argc/argp/envp
110	 * to us as arguments.  But clear bss first because
111	 * the romvec and other important info is stored there
112	 * by prom_init().
113	 */
114	PTR_LA	t0, _edata
115	sd	zero, (t0)
116	PTR_LA	t1, (_end - 8)
1171:
118	daddiu	t0, 8
119	sd	zero, (t0)
120	bne	t0, t1, 1b
121
122	PTR_LA	$28, init_task_union		# init current pointer
123	daddiu	sp, $28, KERNEL_STACK_SIZE-32
124	set_saved_sp	sp, t0, t1
125	dsubu	sp, 4*SZREG			# init stack pointer
126
127	j	init_arch
128	END(kernel_entry)
129
130#ifdef CONFIG_SMP
131/*
132 * SMP slave cpus entry point.  Board specific code for bootstrap calls this
133 * function after setting up the stack and gp registers.
134 */
135NESTED(smp_bootstrap, 16, sp)
136#ifdef CONFIG_SGI_IP27
137	GET_NASID_ASM	t1
138	dli	t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
139		    KLDIR_OFF_POINTER + K0BASE
140	dsll	t1, NASID_SHFT
141	or	t0, t0, t1
142	ld	t0, 0(t0)			# t0 points to kern_vars struct
143	lh	t1, KV_RO_NASID_OFFSET(t0)
144	lh	t2, KV_RW_NASID_OFFSET(t0)
145	MAPPED_KERNEL_SETUP_TLB
146	ARC64_TWIDDLE_PC
147#endif /* CONFIG_SGI_IP27 */
148
149	CLI
150
151	/*
152	 * For the moment set ST0_KU so the CPU will not spit fire when
153	 * executing 64-bit instructions.  The full initialization of the
154	 * CPU's status register is done later in per_cpu_trap_init().
155	 */
156        mfc0	t0, CP0_STATUS
157        or	t0, ST0_KX
158	mtc0	t0, CP0_STATUS
159
160	jal	start_secondary			# XXX: IP27: cboot
161
162	END(smp_bootstrap)
163#endif /* CONFIG_SMP */
164
165	__FINIT
166
167	declare_saved_sp
168
169	.macro	page name, order=0
170	.globl	\name
171\name:	.size	\name, (_PAGE_SIZE << \order)
172	.org	. + (_PAGE_SIZE << \order)
173	.type	\name, @object
174	.endm
175
176	.data
177	.align	12
178
179	page	swapper_pg_dir, _PGD_ORDER
180	page	invalid_pmd_table, _PMD_ORDER
181	page	invalid_pte_table, _PTE_ORDER
182	page	kptbl, _PGD_ORDER
183	.globl	ekptbl
184	page	kpmdtbl, 0
185ekptbl:
186