1/*	$NetBSD: locore_machdep.S,v 1.3 2001/11/23 16:09:11 uch Exp $	*/
2
3/*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *        This product includes software developed by the NetBSD
18 *        Foundation, Inc. and its contributors.
19 * 4. Neither the name of The NetBSD Foundation nor the names of its
20 *    contributors may be used to endorse or promote products derived
21 *    from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include "opt_kloader_kernel_path.h"
37
38#include <mips/asm.h>
39#include <mips/cache_r5900.h>
40#include <mips/cpuregs.h>
41
42#define D_STAT_REG	0xb000e010
43#define I_MASK_REG	0xb000f010
44
45	.set	noreorder
46	.text
47	.align 6	/* align cache line size (64B) */
48
49/*
50 * md_imask_update:
51 *	this function may be called under EXL=1. don't access KSEG2.
52 *
53 * void
54 * md_imask_update()
55 * {
56 * 	register u_int32_t cur_mask, bit;
57 *
58 * 	cur_mask = (_reg_read_4(I_MASK_REG) & 0xffff) |
59 *	    (_reg_read_4(D_STAT_REG) & 0xffff0000);
60 *
61 *	bit = (cur_mask ^ ~md_imask) | (cur_mask & md_imask);
62 *
63 * 	_reg_write_4(I_MASK_REG, bit & __intc_enabled_channel);
64 * 	_reg_write_4(D_STAT_REG, bit & D_STAT_CIM(__dmac_enabled_channel));
65 * }
66 */
67LEAF_NOPROFILE(md_imask_update)
68	lw	a0, _C_LABEL(__intc_enabled_channel)
69	li	a1, I_MASK_REG
70	lw	a3, _C_LABEL(__dmac_enabled_channel)
71	li	a2, D_STAT_REG
72	lw	t1, 0(a2)	/* D_STAT */
73	lui	t2, 0xffff
74	lw	t0, 0(a1)	/* I_MASK */
75	sll	a3, a3, 16
76	and	t1, t1, t2
77	lw	t3, _C_LABEL(md_imask)
78	nor	t2, zero, t2
79	and	t0, t0, t2
80	or	t0, t0, t1	/* cur_mask */
81	nor	t4, zero, t3
82	xor	t4, t4, t0
83	and	t3, t3, t0
84	or	t0, t3, t4
85	and	t3, t0, a0	/* INTC */
86	and	t4, t0, a3	/* DMAC */
87	sw	t3, 0(a1)
88	sw	t4, 0(a2)
89	sync.p
90	j	ra
91	nop
92END(md_imask_update)
93
94/*
95 * spllowersofthigh:
96 *	this function may be called under EXL=1. don't access KSEG2.
97 * void
98 * spllowersofthigh()
99 * {
100 * 	extern void _splnone(void);
101 *
102 * 	md_imask = __icu_mask[IPL_SOFTSERIAL];
103 * 	md_imask_update();
104 * 	_splnone();
105 * }
106 */
107NESTED_NOPROFILE(spllowersofthigh, CALLFRAME_SIZ, ra)
108	.mask	0x80000000, -4
109	subu	sp, sp, CALLFRAME_SIZ
110	sw	ra, CALLFRAME_RA(sp)
111	la	a0, _C_LABEL(__icu_mask)
112	lw	a0, 16(a0)
113	sw	a0, _C_LABEL(md_imask)
114	jal	md_imask_update
115	nop
116	lw	ra, CALLFRAME_RA(sp)
117	li	t0, (MIPS_INT_MASK | MIPS_SR_INT_IE)
118	mtc0	t0, MIPS_COP_0_STATUS
119	sync.p
120	j	ra
121	addu	sp, sp, CALLFRAME_SIZ
122END(spllowersofthigh)
123
124#ifdef KLOADER_KERNEL_PATH
125/*
126 * kloader_boot(vaddr_t entry_addr, struct kloader_page_tag *p)
127 *	must be PIC.
128 */
129EXPORT(kloader_boot_start)
130LEAF_NOPROFILE(kloader_boot)
131	di			# disable cache
132	/*
133	 * 1. load kernel image.
134	 */
135	move	t6, a1		# p
1361:
137	beqz	t6, 3f
138	 move	t7, t6
139	lw	t6, 0(t7)	# p = next
140	lw	t0, 4(t7)	# src
141	lw	t4, 8(t7)	# dst
142	lw	t2, 12(t7)	# sz
143	addu	t5, t4, t2	# dst + sz
1442:
145	lw	t3, 0(t0)	# copy
146	sw	t3, 0(t4)
147	addiu	t4, t4, 4
148	addiu	t0, t0, 4
149	bltu	t4, t5, 2b
150	 nop
151	b	1b
152	 nop
1533:
154	nop
155
156	/*
157	 * 2. Cache flush
158	 */
159	li	t1, CACHE_R5900_SIZE_I
160	li	t2, CACHE_R5900_SIZE_D
161
162	/*
163	 * Flush the data cache.
164	 */
165	li	t0, MIPS_KSEG0_START
166	srl	t2, 1		# Two way set assoc
167	addu	t1, t0, t2	# End address
168	sync.l
169	sync.p
1701:
171	# line +0
172	cache	CACHEOP_R5900_IWBINV_D,  0(t0);sync.l;sync.p	# way 0
173	cache	CACHEOP_R5900_IWBINV_D,  1(t0);sync.l;sync.p	# way 1
174	# line +1
175	cache	CACHEOP_R5900_IWBINV_D, 64(t0);sync.l;sync.p	# way 0
176	cache	CACHEOP_R5900_IWBINV_D, 65(t0);sync.l;sync.p	# way 1
177	# line +2
178	cache	CACHEOP_R5900_IWBINV_D,128(t0);sync.l;sync.p	# way 0
179	cache	CACHEOP_R5900_IWBINV_D,129(t0);sync.l;sync.p	# way 1
180	# line +3
181	cache	CACHEOP_R5900_IWBINV_D,192(t0);sync.l;sync.p	# way 0
182	cache	CACHEOP_R5900_IWBINV_D,193(t0);sync.l;sync.p	# way 1
183	addu	t0, t0, 256
184	bne	t0, t1, 1b
185	 nop
186
187	/*
188	 * Flush the instruction cache.
189	 */
190	li	t0, MIPS_KSEG0_START
191	srl	t1, 1			# Two way set assoc
192	addu	t1, t0, t1		# End address
193	sync.l
194	sync.p
1951:
196	#	[12:6]	... line
197	#	[0]	... way
198	# line +0
199	cache	CACHEOP_R5900_IINV_I,  0(t0);sync.l;sync.p	# way 0
200	cache	CACHEOP_R5900_IINV_I,  1(t0);sync.l;sync.p	# way 1
201	# line +1
202	cache	CACHEOP_R5900_IINV_I, 64(t0);sync.l;sync.p	# way 0
203	cache	CACHEOP_R5900_IINV_I, 65(t0);sync.l;sync.p	# way 1
204	# line +2
205	cache	CACHEOP_R5900_IINV_I,128(t0);sync.l;sync.p	# way 0
206	cache	CACHEOP_R5900_IINV_I,129(t0);sync.l;sync.p	# way 1
207	# line +3
208	cache	CACHEOP_R5900_IINV_I,192(t0);sync.l;sync.p	# way 0
209	cache	CACHEOP_R5900_IINV_I,193(t0);sync.l;sync.p	# way 1
210	addu	t0, t0, 256
211	bne	t0, t1, 1b
212	 nop
213
214	/*
215	 * 3. jump to kernel entry
216	 */
217	jr	a0
218	nop
219	/* NOTREACHED */
220END(kloader_boot)
221EXPORT(kloader_boot_end)
222
223#endif /* KLOADER_KERNEL_PATH */
224
225/*
226 * Unused. but for vmstat(8)
227 */
228	.data
229	.align 6	/* align cache line size (64B) */
230
231	.globl _C_LABEL(intrcnt)
232	.globl _C_LABEL(eintrcnt)
233	.globl _C_LABEL(intrnames)
234	.globl _C_LABEL(eintrnames)
235
236_C_LABEL(intrnames):
237_C_LABEL(eintrnames):
238_C_LABEL(intrcnt):
239_C_LABEL(eintrcnt):
240
241