xref: /netbsd-src/sys/arch/evbmips/ingenic/cpu_startup.S (revision e63cb0d4be270b9c6f36c2d57b5c405df28357b4)
1/*	$NetBSD: cpu_startup.S,v 1.2 2023/02/23 14:56:00 riastradh Exp $ */
2
3/*-
4 * Copyright (c) 2015 Michael Lorenz
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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "opt_cputype.h"
30#include "opt_multiprocessor.h"
31
32#include <sys/cdefs.h>
33#include <sys/endian.h>
34
35#include <mips/asm.h>
36RCSID("$NetBSD: cpu_startup.S,v 1.2 2023/02/23 14:56:00 riastradh Exp $");
37
38#ifdef MULTIPROCESSOR
39
40#include <mips/cpuregs.h>
41#include <mips/cache_r4k.h>
42
43#include "assym.h"
44
45#define CACHE_SIZE (32 * 1024)
46#define CACHE_LINESIZE 32
47
48NESTED_NOPROFILE(ingenic_trampoline, 0, ra)
49	/*
50	 * We act as the idle lwp so make it CURLWP.  When know
51	 * that the cpu_info is a KSEG0 address.
52	 */
53	move	a0, a1
54	// Loop until idlelwp is filled in.
551:	PTR_L	MIPS_CURLWP, CPU_INFO_IDLELWP(a0)
56	nop
57	beqz	MIPS_CURLWP, 1b
58	 nop
59	/*
60	 * No membar needed because we're not switching from a
61	 * previous lwp, and the idle lwp we're switching to can't be
62	 * holding locks already; see cpu_switchto.
63	 */
64	PTR_S	MIPS_CURLWP, CPU_INFO_CURLWP(a0)
65
66	li	v0, 0
67	mtc0	v0, MIPS_COP_0_STATUS		# reset to known state
68	COP0_SYNC
69
70	PTR_L	sp, L_MD_UTF(MIPS_CURLWP)	# fetch KSP
71
72	/*
73	 * Indicate that no one has called us.
74	 */
75	move	ra, zero
76	REG_S	ra, CALLFRAME_RA(sp)
77
78	/*
79	 * New execution constant needs GP to be loaded.
80	 */
81	PTR_LA	gp, _C_LABEL(_gp)
82
83	/*
84	 * and off we go.
85	 */
86	j	_C_LABEL(cpu_hatch)		# does everything
87	 nop
88END(ingenic_trampoline)
89
90
91/*
92 * exception vector secondary CPUs take when started
93 */
94.p2align 16
95VECTOR(ingenic_wakeup, unknown)
96	.set	noat
97
98	mtc0	zero, MIPS_COP_0_CAUSE
99	COP0_SYNC
100
101	/* init caches */
102	li	t0, MIPS_KSEG0_START
103	ori	t1, t0, CACHE_SIZE
104	mtc0	zero, MIPS_COP_0_TAG_LO, 0
105	COP0_SYNC
1061:	cache	CACHEOP_R4K_INDEX_STORE_TAG | CACHE_R4K_I, 0(t0)
107	cache	CACHEOP_R4K_INDEX_STORE_TAG | CACHE_R4K_D, 0(t0)
108	addiu	t0, t0, CACHE_LINESIZE
109	bne	t0, t1, 1b
110	 nop
111
112	/* kseg0 cache attribute */
113	mfc0	t0, MIPS_COP_0_CONFIG, 0
114	ori	t0, t0, MIPS3_TLB_ATTR_WB_NONCOHERENT
115	mtc0	t0, MIPS_COP_0_CONFIG, 0
116	COP0_SYNC
117
118	/* pagemask */
119	mtc0	zero, MIPS_COP_0_TLB_PG_MASK, 0
120	COP0_SYNC
121
122	/*
123	 * - set a1 to corresponding cpu_info
124	 * - set sp to ci->ci_data.cpu_idlelwp->l_md.md_utf
125	 * - jump to cpu_trampoline
126	 */
127	PTR_L	a1, _C_LABEL(startup_cpu_info)
128	nop
129
130	j	ingenic_trampoline
131	  nop
132	.set	at
133VECTOR_END(ingenic_wakeup)
134
135#endif /* MULTIPROCESSOR */
136