xref: /netbsd-src/sys/arch/mips/mips/locore_octeon.S (revision 75c01b644eb91cf50cc05744830868a27a1eb2c4)
1/*	$NetBSD: locore_octeon.S,v 1.14 2022/07/20 10:07:49 riastradh Exp $	*/
2
3/*
4 * Copyright (c) 2007 Internet Initiative Japan, 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 *
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <mips/asm.h>
30RCSID("$NetBSD: locore_octeon.S,v 1.14 2022/07/20 10:07:49 riastradh Exp $")
31
32#include "cpunode.h"			/* for NWDOG */
33#include "opt_cputype.h"
34#include "opt_ddb.h"
35#include "opt_multiprocessor.h"
36
37#include <mips/cpuregs.h>
38#include <arch/mips/cavium/dev/octeon_corereg.h>
39
40RCSID("$NetBSD: locore_octeon.S,v 1.14 2022/07/20 10:07:49 riastradh Exp $")
41
42#include "assym.h"
43
44#define	_CP0_READ64(_cp0)				\
45	dmfc0	v0, _cp0;				\
46	j	ra;					\
47	 nop
48
49#define	_CP0_WRITE64(_cp0)				\
50	dmtc0	a0, _cp0;				\
51	j	ra;					\
52	 nop
53
54	.set	noreorder
55	.set	noat
56	.set	arch=octeon
57
58	.text
59
60LEAF(mips_cp0_cvmctl_read)
61	_CP0_READ64(MIPS_COP_0_CVMCTL)
62END(mips_cp0_cvmctl_read)
63
64#ifdef notyet /* the rest of these aren't used (yet) */
65LEAF(mips_cp0_cvmctl_write)
66	_CP0_WRITE64(MIPS_COP_0_CVMCTL)
67END(mips_cp0_cvmctl_write)
68
69LEAF(mips_cp0_cvmmemctl_read)
70	_CP0_READ64(MIPS_COP_0_CVMMEMCTL)
71END(mips_cp0_cvmmemctl_read)
72
73LEAF(mips_cp0_cvmmemctl_write)
74	_CP0_WRITE64(MIPS_COP_0_CVMMEMCTL)
75END(mips_cp0_cvmmemctl_write)
76
77LEAF(mips_cp0_cvmcnt_read)
78	_CP0_READ64(MIPS_COP_0_CVMCNT)
79END(mips_cp0_cvmcnt_read)
80
81LEAF(mips_cp0_cvmcnt_write)
82	_CP0_WRITE64(MIPS_COP_0_CVMCNT)
83END(mips_cp0_cvmcnt_write)
84
85LEAF(mips_cp0_performance_counter_control0_read)
86	_CP0_READ64(MIPS_COP_0_PERFCNT0_CTL)
87END(mips_cp0_performance_counter_control0_read)
88
89LEAF(mips_cp0_performance_counter_control0_write)
90	_CP0_WRITE64(MIPS_COP_0_PERFCNT0_CTL)
91END(mips_cp0_performance_counter_control0_write)
92
93LEAF(mips_cp0_performance_counter_control1_read)
94	_CP0_READ64(MIPS_COP_0_PERFCNT1_CTL)
95END(mips_cp0_performance_counter_control1_read)
96
97LEAF(mips_cp0_performance_counter_control1_write)
98	_CP0_WRITE64(MIPS_COP_0_PERFCNT1_CTL)
99END(mips_cp0_performance_counter_control1_write)
100
101LEAF(mips_cp0_performance_counter_counter0_read)
102	_CP0_READ64(MIPS_COP_0_PERFCNT0_CNT)
103END(mips_cp0_performance_counter_counter0_read)
104
105LEAF(mips_cp0_performance_counter_counter0_write)
106	_CP0_WRITE64(MIPS_COP_0_PERFCNT0_CNT)
107END(mips_cp0_performance_counter_counter0_write)
108
109LEAF(mips_cp0_performance_counter_counter1_read)
110	_CP0_READ64(MIPS_COP_0_PERFCNT1_CNT)
111END(mips_cp0_performance_counter_counter1_read)
112
113LEAF(mips_cp0_performance_counter_counter1_write)
114	_CP0_WRITE64(MIPS_COP_0_PERFCNT1_CNT)
115END(mips_cp0_performance_counter_counter1_write)
116#endif /* notyet */
117
118#ifdef MULTIPROCESSOR
119
120NESTED_NOPROFILE(octeon_cpu_spinup, 0, ra)
121	//
122	// Since the OCTEON cpus doesn't a COP0 OSCONTEXT register, each core
123	// must has its own exception vector page.  The exceptions will be
124	// modified to refer to that CPU's cpu_info structure.
125	//
126	mfc0	s1, MIPS_COP_0_EBASE	# get EBASE
127	andi	s0, s1, MIPS_EBASE_CPUNUM # fetch cpunum
128	# insert cpunum as exception address base:
129	ins	s1, s0, MIPS_EBASE_EXC_BASE_SHIFT, MIPS_EBASE_CPUNUM_WIDTH
130	ehb
131	mtc0	s1, MIPS_COP_0_EBASE	# set EBASE
132	COP0_SYNC
133
134	// Indicate this CPU was started by u-boot
135	PTR_LA	a0, _C_LABEL(cpus_booted)
136	li	a1, 1
137	jal	_C_LABEL(atomic_or_64)
138	 sllv	a1, a1, s0		# shift cpu number to bit position
139
140	// Wait until cpuid_infos[cpunum] is not NULL.
141	PTR_LA	a1, _C_LABEL(cpuid_infos)
142	dsll	v0, s0, PTR_SCALESHIFT	# cpunum -> array index
143	PTR_ADD	t0, a1, v0		# add to array start
1441:	PTR_L	a1, (t0)		# get cpu_info pointer
145	SYNC_ACQ			# PTR_L/SYNC_ACQ matches
146					#   atomic_store_release in
147					#   cpu_attach_common
148	beqz	a1, 1b			# loop until non-NULL
149	 nop
150
151	j	_C_LABEL(cpu_trampoline)
152	 nop
153END(octeon_cpu_spinup)
154#endif /* MULTIPROCESSOR */
155
156#if NWDOG > 0 || defined(DDB)
157
158#define	UINT64_C(x)	(x)
159
160#include <mips/cavium/dev/octeon_ciureg.h>
161
162NESTED_NOPROFILE(octeon_reset_vector, 0, ra)
163	mfc0	k0, MIPS_COP_0_STATUS	# get cp0 status
164	bbit1	k0, V_MIPS3_SR_SR, 1f	# MIPS3_SR_SR
165	 ins	k0, zero, V_MIPS_SR_BEV, 1 # clear boot exception vectors
166	mtc0	k0, MIPS_COP_0_STATUS	# write cp0 status
167	ehb				# hazard barrier
168#ifdef MULTIPROCESSOR
169	mfc0	k0, MIPS_COP_0_EBASE	# get EBASE
170	andi	k0, k0, MIPS_EBASE_CPUNUM # fetch cpunum
171	dsll	k0, k0, PTR_SCALESHIFT	# cpunum -> array index
172	PTR_LA	k1, _C_LABEL(cpuid_infos)
173	PTR_ADDU k1, k1, k0		# add to array start
174	PTR_L	k0, (k1)		# get cpu_info
175#else
176	PTR_LA	k0, _C_LABEL(cpu_info_store) # get cpu_info
177#endif
178	j	_C_LABEL(mips64r2_kern_nonmaskable_intr)
179	 sd	zero, CIU_NMI_OFFSET(k1)# clear NMI
1801:
181	li	k1, ((MIPS_XKPHYS_START|CIU_BASE) >> 32)	# CIU base (MSW)
182	dsll	k1, 32			# shift it place
183	ld	k0, CIU_FUSE_OFFSET(k1)	# get mask of CPUs
184	sd	k0, CIU_SOFT_RST_OFFSET(k1)	# reset them
185	ld	v0, CIU_SOFT_RST_OFFSET(k1)	# force a load
186	sd	k0, CIU_SOFT_RST_OFFSET(k1)	# do it again.
1872:
188	wait				# wait forever
189	b	2b			# and loop until reset
190	 nop
191END(octeon_reset_vector)
192#endif
193