11.2Sriastrad/*	$NetBSD: cpu_startup.S,v 1.2 2023/02/23 14:56:00 riastradh Exp $ */
21.1Smacallan
31.1Smacallan/*-
41.1Smacallan * Copyright (c) 2015 Michael Lorenz
51.1Smacallan * All rights reserved.
61.1Smacallan *
71.1Smacallan * Redistribution and use in source and binary forms, with or without
81.1Smacallan * modification, are permitted provided that the following conditions
91.1Smacallan * are met:
101.1Smacallan * 1. Redistributions of source code must retain the above copyright
111.1Smacallan *    notice, this list of conditions and the following disclaimer.
121.1Smacallan * 2. Redistributions in binary form must reproduce the above copyright
131.1Smacallan *    notice, this list of conditions and the following disclaimer in the
141.1Smacallan *    documentation and/or other materials provided with the distribution.
151.1Smacallan *
161.1Smacallan * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
171.1Smacallan * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
181.1Smacallan * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
191.1Smacallan * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
201.1Smacallan * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211.1Smacallan * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
221.1Smacallan * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
231.1Smacallan * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
241.1Smacallan * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
251.1Smacallan * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
261.1Smacallan * POSSIBILITY OF SUCH DAMAGE.
271.1Smacallan */
281.1Smacallan
291.1Smacallan#include "opt_cputype.h"
301.1Smacallan#include "opt_multiprocessor.h"
311.1Smacallan
321.1Smacallan#include <sys/cdefs.h>
331.1Smacallan#include <sys/endian.h>
341.1Smacallan
351.1Smacallan#include <mips/asm.h>
361.2SriastradRCSID("$NetBSD: cpu_startup.S,v 1.2 2023/02/23 14:56:00 riastradh Exp $");
371.1Smacallan
381.1Smacallan#ifdef MULTIPROCESSOR
391.1Smacallan
401.1Smacallan#include <mips/cpuregs.h>
411.1Smacallan#include <mips/cache_r4k.h>
421.1Smacallan
431.1Smacallan#include "assym.h"
441.1Smacallan
451.1Smacallan#define CACHE_SIZE (32 * 1024)
461.1Smacallan#define CACHE_LINESIZE 32
471.1Smacallan
481.1SmacallanNESTED_NOPROFILE(ingenic_trampoline, 0, ra)
491.1Smacallan	/*
501.1Smacallan	 * We act as the idle lwp so make it CURLWP.  When know
511.1Smacallan	 * that the cpu_info is a KSEG0 address.
521.1Smacallan	 */
531.1Smacallan	move	a0, a1
541.1Smacallan	// Loop until idlelwp is filled in.
551.1Smacallan1:	PTR_L	MIPS_CURLWP, CPU_INFO_IDLELWP(a0)
561.1Smacallan	nop
571.1Smacallan	beqz	MIPS_CURLWP, 1b
581.1Smacallan	 nop
591.2Sriastrad	/*
601.2Sriastrad	 * No membar needed because we're not switching from a
611.2Sriastrad	 * previous lwp, and the idle lwp we're switching to can't be
621.2Sriastrad	 * holding locks already; see cpu_switchto.
631.2Sriastrad	 */
641.1Smacallan	PTR_S	MIPS_CURLWP, CPU_INFO_CURLWP(a0)
651.1Smacallan
661.1Smacallan	li	v0, 0
671.1Smacallan	mtc0	v0, MIPS_COP_0_STATUS		# reset to known state
681.1Smacallan	COP0_SYNC
691.1Smacallan
701.1Smacallan	PTR_L	sp, L_MD_UTF(MIPS_CURLWP)	# fetch KSP
711.1Smacallan
721.1Smacallan	/*
731.1Smacallan	 * Indicate that no one has called us.
741.1Smacallan	 */
751.1Smacallan	move	ra, zero
761.1Smacallan	REG_S	ra, CALLFRAME_RA(sp)
771.1Smacallan
781.1Smacallan	/*
791.1Smacallan	 * New execution constant needs GP to be loaded.
801.1Smacallan	 */
811.1Smacallan	PTR_LA	gp, _C_LABEL(_gp)
821.1Smacallan
831.1Smacallan	/*
841.1Smacallan	 * and off we go.
851.1Smacallan	 */
861.1Smacallan	j	_C_LABEL(cpu_hatch)		# does everything
871.1Smacallan	 nop
881.1SmacallanEND(ingenic_trampoline)
891.1Smacallan
901.1Smacallan
911.1Smacallan/*
921.1Smacallan * exception vector secondary CPUs take when started
931.1Smacallan */
941.1Smacallan.p2align 16
951.1SmacallanVECTOR(ingenic_wakeup, unknown)
961.1Smacallan	.set	noat
971.1Smacallan
981.1Smacallan	mtc0	zero, MIPS_COP_0_CAUSE
991.1Smacallan	COP0_SYNC
1001.1Smacallan
1011.1Smacallan	/* init caches */
1021.1Smacallan	li	t0, MIPS_KSEG0_START
1031.1Smacallan	ori	t1, t0, CACHE_SIZE
1041.1Smacallan	mtc0	zero, MIPS_COP_0_TAG_LO, 0
1051.1Smacallan	COP0_SYNC
1061.1Smacallan1:	cache	CACHEOP_R4K_INDEX_STORE_TAG | CACHE_R4K_I, 0(t0)
1071.1Smacallan	cache	CACHEOP_R4K_INDEX_STORE_TAG | CACHE_R4K_D, 0(t0)
1081.1Smacallan	addiu	t0, t0, CACHE_LINESIZE
1091.1Smacallan	bne	t0, t1, 1b
1101.1Smacallan	 nop
1111.1Smacallan
1121.1Smacallan	/* kseg0 cache attribute */
1131.1Smacallan	mfc0	t0, MIPS_COP_0_CONFIG, 0
1141.1Smacallan	ori	t0, t0, MIPS3_TLB_ATTR_WB_NONCOHERENT
1151.1Smacallan	mtc0	t0, MIPS_COP_0_CONFIG, 0
1161.1Smacallan	COP0_SYNC
1171.1Smacallan
1181.1Smacallan	/* pagemask */
1191.1Smacallan	mtc0	zero, MIPS_COP_0_TLB_PG_MASK, 0
1201.1Smacallan	COP0_SYNC
1211.1Smacallan
1221.1Smacallan	/*
1231.1Smacallan	 * - set a1 to corresponding cpu_info
1241.1Smacallan	 * - set sp to ci->ci_data.cpu_idlelwp->l_md.md_utf
1251.1Smacallan	 * - jump to cpu_trampoline
1261.1Smacallan	 */
1271.1Smacallan	PTR_L	a1, _C_LABEL(startup_cpu_info)
1281.1Smacallan	nop
1291.1Smacallan
1301.1Smacallan	j	ingenic_trampoline
1311.1Smacallan	  nop
1321.1Smacallan	.set	at
1331.1SmacallanVECTOR_END(ingenic_wakeup)
1341.1Smacallan
1351.1Smacallan#endif /* MULTIPROCESSOR */
136