xref: /openbsd-src/sys/arch/octeon/octeon/locore.S (revision 5b34c8b171a4ddaff75b436d37df77a3c2241a24)
1/*	$OpenBSD: locore.S,v 1.22 2021/02/11 14:44:14 visa Exp $ */
2
3/*
4 * Copyright (c) 2001-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28#include <sys/errno.h>
29#include <sys/syscall.h>
30
31#include <machine/param.h>
32#include <machine/asm.h>
33#include <machine/cpu.h>
34#include <mips64/mips_cpu.h>
35#include <machine/regnum.h>
36#include <machine/cpustate.h>
37#include <octeon/dev/cn30xxcorereg.h>
38
39#include "assym.h"
40#include "octboot.h"
41
42#define RNG_CONTROL_ADDR	0x9001180040000000
43#define RNG_CONTROL_ENABLE	0x3
44#define RNG_ENTROPY_ADDR	0x9001400000000000
45
46	.set	noreorder		# Noreorder is default style!
47	.set	mips64r2
48	.globl	locore_start
49	.ent	locore_start, 0
50locore_start:
51/* initialize ebase */
52	dla	t0, 0xffffffff80000000
53	mtc0	t0, COP_0_EBASE
54
55/* initialize cvmctl */
56	dli     t0, COP_0_CVMCTL_FUSE_START_BIT|COP_0_CVMCTL_NOFDA_CP2|\
57		    COP_0_CVMCTL_IPPCI|COP_0_CVMCTL_IPTI
58	dmtc0	t0, COP_0_CVMCTL
59
60/* initialize cvmmemctl */
61#if 0
62	dli	t0, 0x1846104 # If you want to skip write buffer, use this
63#else
64	dli	t0, 0x46104
65#endif
66	dmtc0	t0, COP_0_CVMMEMCTL
67
68	mfc0    v0, COP_0_STATUS_REG
69	li	v1, ~(SR_INT_ENAB | SR_ERL | SR_EXL)
70	and	v0, v1
71	mtc0    v0, COP_0_STATUS_REG    # disable all interrupts
72
73	mtc0	zero, COP_0_CAUSE_REG	# Clear soft interrupts
74
75	/* Let the init core continue. The others have to wait. */
76	bne	a2, zero, 2f
77	nop
78#if defined(MULTIPROCESSOR)
79	rdhwr   t2, $0
80	LA	t1, cpu_spinup_mask
811:	ll	t0, 0(t1)
82	bne	t2, t0, 1b
83	nop
84	move	t0, zero
85	sc	t0, 0(t1)
86	beqz	t0, 1b
87	nop
88	j	hw_cpu_spinup_trampoline
89	nop
90#elif NOCTBOOT > 0
91	LA	t0, octeon_boot_ready
921:	lw	t1, (t0)
93	beq	t1, zero, 1b
94	nop
95
96	LA	t0, octeon_boot_entry
97	ld	t0, (t0)			# get entry point
98	cache	1, 0(zero)			# flush and invalidate dcache
99	jr	t0
100	cache	0, 0(zero)			# invalidate icache
101#else
102	/* Halt extra cores on single-processor kernel. */
1031:	wait
104	j	1b
105	nop
106#endif
1072:
108	/*
109	 * Augment the randomdata section using entropy from the RNG.
110	 */
111
112	/* Enable the RNG. */
113	dli	t0, RNG_CONTROL_ADDR
114	ld	t1, (t0)
115	ori	t1, RNG_CONTROL_ENABLE
116	sd	t1, (t0)
117
118	LA	t0, __kernel_randomdata
119	LA	t1, __kernel_randomdata_end
120	dli	t2, RNG_ENTROPY_ADDR
1211:
122	/* Delay to let entropy accumulate. */
123	li	v0, 0x1000
1242:
125	bne	v0, zero, 2b
126	subu	v0, v0, 1
127	/* Mix entropy. */
128	ld	v0, (t0)			# load from randomdata
129	ld	v1, (t2)			# load entropy
130	xor	v0, v0, v1			# mix entropy
131	daddu	t0, t0, 8			# advance ptr
132	blt	t0, t1, 1b
133	sd	v0, -8(t0)			# store to randomdata
134
135	/*
136	 * Clear the compiled BSS segment in OpenBSD code.
137	 * U-Boot is supposed to have done this, though.
138	 */
139	LA	t0, edata
140	LA	t1, end
1411:
142	daddu	t0, t0, 8
143	blt	t0, t1, 1b
144	sd	zero, -8(t0)
145
146	/*
147	 * Initialize stack and call machine startup.
148	 */
149	LA	t0, initstack_end - FRAMESZ(CF_SZ)
150	PTR_S	ra, CF_RA_OFFS(t0)		# save uboot return address
151	PTR_S	sp, 0(t0)			# and stack
152	move	sp, t0
153	jal	mips_init			# mips_init(argc, argv, envp,
154	nop					#    callvec, esym)
155
156	beqz	v0, 1f				# upon failure, return to uboot
157	nop
158
159	PTR_S	zero, CF_RA_OFFS(sp)		# Zero out old ra for debugger
160	move	sp, v0				# switch to new stack
161	jal	main				# main(regs)
162	move	a0, zero
163	PANIC("Startup failed!")
164
1651:	PTR_L	ra, CF_RA_OFFS(sp)
166	PTR_L	sp, 0(sp)
167	jr	ra
168	nop
169	.end	locore_start
170
171/*
172 * void octeon_sync_tc(vaddr_t reg, uint64_t mul, uint64_t frac)
173 */
174LEAF(octeon_sync_tc, 0)
175	/*
176	 * The measurement is done several times in a loop.
177	 * The initial iterations warm up the icache and train the branch
178	 * predictor to reduce jitter.
179	 * The final iteration performs the actual synchronization.
180	 */
181	li	t0, 5				# set number of iterations
182	di	t3				# disable all interrupts
183	MTC0_SR_IE_HAZARD
1841:
185	ld	t1, (a0)			# load data clock counter
186	dmultu	t1, a1				# multiply with mul
187	mflo	t1				# fetch result
188	beqz	a2, 2f				# skip if frac == 2^64
189	subu	t0, 1
190	dmultu	t1, a2				# multiply with frac
191	mfhi	t1				# fetch result divided by 2^64
1922:
193	mtc0	t1, COP_0_COUNT			# set core clock counter
194	MTC0_HAZARD
195	bnez	t0, 1b
196	nop
197	mtc0	t3, COP_0_STATUS_REG		# restore status register
198	MTC0_SR_IE_HAZARD
199	jr	ra
200	nop
201END(octeon_sync_tc)
202
203#if defined(MULTIPROCESSOR)
204LEAF(hw_cpu_spinup_trampoline, 0)
205	LA	t0, cpu_spinup_a0
206	ld	a0, 0(t0)
207	LA	t0, cpu_spinup_sp
208	ld	sp, 0(t0)
209	jal	hw_cpu_hatch
210	nop
211END(hw_cpu_spinup_trampoline)
212#endif /* MULTIPROCESSOR */
213
214/*
215 * Bootstrap stack for mips_init()
216 */
217	.bss
218	.align	3
219initstack:
220	.space	4096
221initstack_end:
222