xref: /netbsd-src/sys/arch/arm/arm32/arm32_boot.c (revision 2e48165927e03a27266b31d5f58f9528ab747c66)
1*2e481659Sryo /*	$NetBSD: arm32_boot.c,v 1.45 2022/12/22 06:58:08 ryo Exp $	*/
21f4278e1Smatt 
31f4278e1Smatt /*
41f4278e1Smatt  * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
51f4278e1Smatt  * Written by Hiroyuki Bessho for Genetec Corporation.
61f4278e1Smatt  *
71f4278e1Smatt  * Redistribution and use in source and binary forms, with or without
81f4278e1Smatt  * modification, are permitted provided that the following conditions
91f4278e1Smatt  * are met:
101f4278e1Smatt  * 1. Redistributions of source code must retain the above copyright
111f4278e1Smatt  *    notice, this list of conditions and the following disclaimer.
121f4278e1Smatt  * 2. Redistributions in binary form must reproduce the above copyright
131f4278e1Smatt  *    notice, this list of conditions and the following disclaimer in the
141f4278e1Smatt  *    documentation and/or other materials provided with the distribution.
151f4278e1Smatt  * 3. The name of Genetec Corporation may not be used to endorse or
161f4278e1Smatt  *    promote products derived from this software without specific prior
171f4278e1Smatt  *    written permission.
181f4278e1Smatt  *
191f4278e1Smatt  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
201f4278e1Smatt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
211f4278e1Smatt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221f4278e1Smatt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
231f4278e1Smatt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241f4278e1Smatt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251f4278e1Smatt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261f4278e1Smatt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271f4278e1Smatt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281f4278e1Smatt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291f4278e1Smatt  * POSSIBILITY OF SUCH DAMAGE.
301f4278e1Smatt  *
311f4278e1Smatt  * Copyright (c) 2001 Wasabi Systems, Inc.
321f4278e1Smatt  * All rights reserved.
331f4278e1Smatt  *
341f4278e1Smatt  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
351f4278e1Smatt  *
361f4278e1Smatt  * Redistribution and use in source and binary forms, with or without
371f4278e1Smatt  * modification, are permitted provided that the following conditions
381f4278e1Smatt  * are met:
391f4278e1Smatt  * 1. Redistributions of source code must retain the above copyright
401f4278e1Smatt  *    notice, this list of conditions and the following disclaimer.
411f4278e1Smatt  * 2. Redistributions in binary form must reproduce the above copyright
421f4278e1Smatt  *    notice, this list of conditions and the following disclaimer in the
431f4278e1Smatt  *    documentation and/or other materials provided with the distribution.
441f4278e1Smatt  * 3. All advertising materials mentioning features or use of this software
451f4278e1Smatt  *    must display the following acknowledgement:
461f4278e1Smatt  *	This product includes software developed for the NetBSD Project by
471f4278e1Smatt  *	Wasabi Systems, Inc.
481f4278e1Smatt  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
491f4278e1Smatt  *    or promote products derived from this software without specific prior
501f4278e1Smatt  *    written permission.
511f4278e1Smatt  *
521f4278e1Smatt  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
531f4278e1Smatt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
541f4278e1Smatt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
551f4278e1Smatt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
561f4278e1Smatt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
571f4278e1Smatt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
581f4278e1Smatt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
591f4278e1Smatt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
601f4278e1Smatt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
611f4278e1Smatt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
621f4278e1Smatt  * POSSIBILITY OF SUCH DAMAGE.
631f4278e1Smatt  *
641f4278e1Smatt  * Copyright (c) 1997,1998 Mark Brinicombe.
651f4278e1Smatt  * Copyright (c) 1997,1998 Causality Limited.
661f4278e1Smatt  * All rights reserved.
671f4278e1Smatt  *
681f4278e1Smatt  * Redistribution and use in source and binary forms, with or without
691f4278e1Smatt  * modification, are permitted provided that the following conditions
701f4278e1Smatt  * are met:
711f4278e1Smatt  * 1. Redistributions of source code must retain the above copyright
721f4278e1Smatt  *    notice, this list of conditions and the following disclaimer.
731f4278e1Smatt  * 2. Redistributions in binary form must reproduce the above copyright
741f4278e1Smatt  *    notice, this list of conditions and the following disclaimer in the
751f4278e1Smatt  *    documentation and/or other materials provided with the distribution.
761f4278e1Smatt  * 3. All advertising materials mentioning features or use of this software
771f4278e1Smatt  *    must display the following acknowledgement:
781f4278e1Smatt  *	This product includes software developed by Mark Brinicombe
791f4278e1Smatt  *	for the NetBSD Project.
801f4278e1Smatt  * 4. The name of the company nor the name of the author may be used to
811f4278e1Smatt  *    endorse or promote products derived from this software without specific
821f4278e1Smatt  *    prior written permission.
831f4278e1Smatt  *
841f4278e1Smatt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
851f4278e1Smatt  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
861f4278e1Smatt  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
871f4278e1Smatt  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
881f4278e1Smatt  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
891f4278e1Smatt  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
901f4278e1Smatt  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
911f4278e1Smatt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
921f4278e1Smatt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
931f4278e1Smatt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
941f4278e1Smatt  * SUCH DAMAGE.
951f4278e1Smatt  *
961f4278e1Smatt  * Copyright (c) 2007 Microsoft
971f4278e1Smatt  * All rights reserved.
981f4278e1Smatt  *
991f4278e1Smatt  * Redistribution and use in source and binary forms, with or without
1001f4278e1Smatt  * modification, are permitted provided that the following conditions
1011f4278e1Smatt  * are met:
1021f4278e1Smatt  * 1. Redistributions of source code must retain the above copyright
1031f4278e1Smatt  *    notice, this list of conditions and the following disclaimer.
1041f4278e1Smatt  * 2. Redistributions in binary form must reproduce the above copyright
1051f4278e1Smatt  *    notice, this list of conditions and the following disclaimer in the
1061f4278e1Smatt  *    documentation and/or other materials provided with the distribution.
1071f4278e1Smatt  * 3. All advertising materials mentioning features or use of this software
1081f4278e1Smatt  *    must display the following acknowledgement:
1091f4278e1Smatt  *	This product includes software developed by Microsoft
1101f4278e1Smatt  *
1111f4278e1Smatt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
1121f4278e1Smatt  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1131f4278e1Smatt  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1141f4278e1Smatt  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
1151f4278e1Smatt  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1161f4278e1Smatt  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1171f4278e1Smatt  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1181f4278e1Smatt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1191f4278e1Smatt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1201f4278e1Smatt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1211f4278e1Smatt  * SUCH DAMAGE.
1221f4278e1Smatt  */
1231f4278e1Smatt 
1241f4278e1Smatt #include <sys/cdefs.h>
125*2e481659Sryo __KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.45 2022/12/22 06:58:08 ryo Exp $");
12676df768bSskrll 
127c3b674b9Sskrll #include "opt_arm_debug.h"
128fee210abSskrll #include "opt_cputypes.h"
12976df768bSskrll #include "opt_ddb.h"
13076df768bSskrll #include "opt_kgdb.h"
131cd0fc78fSskrll #include "opt_multiprocessor.h"
1321f4278e1Smatt 
1331f4278e1Smatt #include <sys/param.h>
134b7d6af89Sskrll 
135d329adb0Sskrll #include <sys/asan.h>
136d6e299a9Smatt #include <sys/atomic.h>
137b7d6af89Sskrll #include <sys/cpu.h>
138d6e299a9Smatt #include <sys/device.h>
139b7d6af89Sskrll #include <sys/intr.h>
140b7d6af89Sskrll #include <sys/reboot.h>
1411f4278e1Smatt 
1421f4278e1Smatt #include <uvm/uvm_extern.h>
1431f4278e1Smatt 
144ab152917Smatt #include <arm/locore.h>
1451f4278e1Smatt #include <arm/undefined.h>
1461f4278e1Smatt #include <arm/arm32/machdep.h>
1471f4278e1Smatt 
1481f4278e1Smatt #include <machine/db_machdep.h>
1491f4278e1Smatt #include <ddb/db_extern.h>
1501f4278e1Smatt 
1511f4278e1Smatt #include <machine/bootconfig.h>
1521f4278e1Smatt 
15376df768bSskrll #ifdef KGDB
15476df768bSskrll #include <sys/kgdb.h>
15576df768bSskrll #endif
15676df768bSskrll 
157c3b674b9Sskrll #ifdef VERBOSE_INIT_ARM
158c3b674b9Sskrll #define VPRINTF(...)	printf(__VA_ARGS__)
159c3b674b9Sskrll #else
1602505ba45Sskrll #define VPRINTF(...)	__nothing
161c3b674b9Sskrll #endif
162c3b674b9Sskrll 
1631f4278e1Smatt vaddr_t
initarm_common(vaddr_t kvm_base,vsize_t kvm_size,const struct boot_physmem * bp,size_t nbp)1641f4278e1Smatt initarm_common(vaddr_t kvm_base, vsize_t kvm_size,
1651f4278e1Smatt 	const struct boot_physmem *bp, size_t nbp)
1661f4278e1Smatt {
1671f4278e1Smatt 	struct bootmem_info * const bmi = &bootmem_info;
1681f4278e1Smatt 
169c3b674b9Sskrll 	VPRINTF("nfreeblocks = %u, free_pages = %d (%#x)\n",
1701f4278e1Smatt 	    bmi->bmi_nfreeblocks, bmi->bmi_freepages,
1711f4278e1Smatt 	    bmi->bmi_freepages);
1721f4278e1Smatt 
1731f4278e1Smatt 	/*
1741f4278e1Smatt 	 * Moved from cpu_startup() as data_abort_handler() references
1751f4278e1Smatt 	 * this during uvm init.
1761f4278e1Smatt 	 */
1771f4278e1Smatt 	uvm_lwp_setuarea(&lwp0, kernelstack.pv_va);
1781f4278e1Smatt 
179d3419f91Sskrll 	struct lwp * const l = &lwp0;
180d3419f91Sskrll 	struct pcb * const pcb = lwp_getpcb(l);
181d3419f91Sskrll 
182d3419f91Sskrll 	/* Zero out the PCB. */
183d3419f91Sskrll  	memset(pcb, 0, sizeof(*pcb));
184d3419f91Sskrll 
185d3419f91Sskrll 	pcb->pcb_ksp = uvm_lwp_getuarea(l) + USPACE_SVC_STACK_TOP;
186d3419f91Sskrll 	pcb->pcb_ksp -= sizeof(struct trapframe);
187d3419f91Sskrll 
188d3419f91Sskrll 	struct trapframe * tf = (struct trapframe *)pcb->pcb_ksp;
189d3419f91Sskrll 
190d3419f91Sskrll 	/* Zero out the trapframe. */
191d3419f91Sskrll 	memset(tf, 0, sizeof(*tf));
192d3419f91Sskrll 	lwp_settrapframe(l, tf);
193d3419f91Sskrll 
194d3419f91Sskrll  	tf->tf_spsr = PSR_USR32_MODE;
195e092cf89Srin #ifdef _ARM_ARCH_BE8
196e092cf89Srin 	tf->tf_spsr |= PSR_E_BIT;
197d3419f91Sskrll #endif
198d3419f91Sskrll 
199c3b674b9Sskrll 	VPRINTF("bootstrap done.\n");
2001f4278e1Smatt 
201c3b674b9Sskrll 	VPRINTF("vectors");
2021f4278e1Smatt 	arm32_vector_init(systempage.pv_va, ARM_VEC_ALL);
203c3b674b9Sskrll 	VPRINTF(" %#"PRIxVADDR"\n", vector_page);
2041f4278e1Smatt 
2051f4278e1Smatt 	/*
2061f4278e1Smatt 	 * Pages were allocated during the secondary bootstrap for the
2071f4278e1Smatt 	 * stacks for different CPU modes.
2081f4278e1Smatt 	 * We must now set the r13 registers in the different CPU modes to
2091f4278e1Smatt 	 * point to these stacks.
2101f4278e1Smatt 	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
2111f4278e1Smatt 	 * of the stack memory.
2121f4278e1Smatt 	 */
213c3b674b9Sskrll 	VPRINTF("init subsystems: stacks ");
2141f4278e1Smatt 	set_stackptr(PSR_FIQ32_MODE,
2151f4278e1Smatt 	    fiqstack.pv_va + FIQ_STACK_SIZE * PAGE_SIZE);
2161f4278e1Smatt 	set_stackptr(PSR_IRQ32_MODE,
2171f4278e1Smatt 	    irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
2181f4278e1Smatt 	set_stackptr(PSR_ABT32_MODE,
2191f4278e1Smatt 	    abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
2201f4278e1Smatt 	set_stackptr(PSR_UND32_MODE,
2211f4278e1Smatt 	    undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
2221f4278e1Smatt 
2231f4278e1Smatt 	/*
2241f4278e1Smatt 	 * Well we should set a data abort handler.
2251f4278e1Smatt 	 * Once things get going this will change as we will need a proper
2261f4278e1Smatt 	 * handler.
2271f4278e1Smatt 	 * Until then we will use a handler that just panics but tells us
2281f4278e1Smatt 	 * why.
2291f4278e1Smatt 	 * Initialisation of the vectors will just panic on a data abort.
2301f4278e1Smatt 	 * This just fills in a slightly better one.
2311f4278e1Smatt 	 */
232c3b674b9Sskrll 	VPRINTF("vectors ");
2331f4278e1Smatt 	data_abort_handler_address = (u_int)data_abort_handler;
2341f4278e1Smatt 	prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
2351f4278e1Smatt 	undefined_handler_address = (u_int)undefinedinstruction_bounce;
2361f4278e1Smatt 
2371f4278e1Smatt 	/* Initialise the undefined instruction handlers */
238c3b674b9Sskrll 	VPRINTF("undefined ");
2391f4278e1Smatt 	undefined_init();
2401f4278e1Smatt 
241e677f16fSskrll #ifdef FPU_VFP
242e677f16fSskrll 	/* vfp_detect uses an undefined handler */
243e677f16fSskrll 	VPRINTF("vfp ");
244e677f16fSskrll 	vfp_detect(curcpu());
245e677f16fSskrll #endif
246e677f16fSskrll 
2471f4278e1Smatt 	/* Load memory into UVM. */
248c3b674b9Sskrll 	VPRINTF("page ");
249e08917efScherry 	uvm_md_init();
2501f4278e1Smatt 
251e6c2e807Sskrll 	VPRINTF("pmap_physload\n");
252f88bd6b7Smatt 	KASSERT(bp != NULL || nbp == 0);
253f88bd6b7Smatt 	KASSERT(bp == NULL || nbp != 0);
2541f4278e1Smatt 
2551f4278e1Smatt 	for (size_t i = 0; i < bmi->bmi_nfreeblocks; i++) {
2561f4278e1Smatt 		pv_addr_t * const pv = &bmi->bmi_freeblocks[i];
257f88bd6b7Smatt 		paddr_t start = atop(pv->pv_pa);
2581f4278e1Smatt 		const paddr_t end = start + atop(pv->pv_size);
259f88bd6b7Smatt 		int vm_freelist = VM_FREELIST_DEFAULT;
260e6c2e807Sskrll 
261e6c2e807Sskrll 		VPRINTF("block %2zu start %08lx  end %08lx", i,
262e6c2e807Sskrll 		    pv->pv_pa, pv->pv_pa + pv->pv_size);
263e6c2e807Sskrll 
264e6c2e807Sskrll 		if (!bp) {
265e6c2e807Sskrll 			VPRINTF("... loading in freelist %d\n", vm_freelist);
266e6c2e807Sskrll 			uvm_page_physload(start, end, start, end, VM_FREELIST_DEFAULT);
267e6c2e807Sskrll 			continue;
268e6c2e807Sskrll 		}
26944c35374Sskrll 		VPRINTF("\n");
2709873ab93Sskrll 
2719873ab93Sskrll 		/*
2729873ab93Sskrll 		 * This assumes the bp list is sorted in ascending
2739873ab93Sskrll 		 * order.
2749873ab93Sskrll 		 */
275f88bd6b7Smatt 		paddr_t segend = end;
2769873ab93Sskrll 		for (size_t j = 0; j < nbp && start < end; j++) {
277f88bd6b7Smatt 			paddr_t bp_start = bp[j].bp_start;
278f88bd6b7Smatt 			paddr_t bp_end = bp_start + bp[j].bp_pages;
279e6c2e807Sskrll 
28044c35374Sskrll 			VPRINTF("   bp %2zu start %08lx  end %08lx\n",
281e6c2e807Sskrll 			    j, ptoa(bp_start), ptoa(bp_end));
2829873ab93Sskrll 
283e6c2e807Sskrll 			KASSERT(bp_start < bp_end);
2849873ab93Sskrll 			if (start >= bp_end || segend < bp_start)
285e6c2e807Sskrll 				continue;
286e6c2e807Sskrll 
287e6c2e807Sskrll 			if (start < bp_start)
288e6c2e807Sskrll 				start = bp_start;
289e6c2e807Sskrll 
290f88bd6b7Smatt 			if (start < bp_end) {
291f88bd6b7Smatt 				if (segend > bp_end) {
292f88bd6b7Smatt 					segend = bp_end;
293f88bd6b7Smatt 				}
294f88bd6b7Smatt 				vm_freelist = bp[j].bp_freelist;
2951f4278e1Smatt 
296e6c2e807Sskrll 				VPRINTF("         start %08lx  end %08lx"
29744c35374Sskrll 				    "... loading in freelist %d\n", ptoa(start),
298089d3c98Sskrll 				    ptoa(segend), vm_freelist);
2999873ab93Sskrll 
3009873ab93Sskrll 				uvm_page_physload(start, segend, start, segend,
3019873ab93Sskrll 				    vm_freelist);
3029873ab93Sskrll 
303f88bd6b7Smatt 				start = segend;
304e6c2e807Sskrll 				segend = end;
305e6c2e807Sskrll 			}
3061f4278e1Smatt 		}
3071f4278e1Smatt 	}
3081f4278e1Smatt 
309ec646468Sskrll 	/*
310ec646468Sskrll 	 * Bootstrap pmap telling it where the managed kernel virtual memory
311ec646468Sskrll 	 * is.
312ec646468Sskrll 	 */
313c3b674b9Sskrll 	VPRINTF("pmap ");
3141f4278e1Smatt 	pmap_bootstrap(kvm_base, kvm_base + kvm_size);
3151f4278e1Smatt 
316d329adb0Sskrll 	kasan_init();
317d329adb0Sskrll 
3181f4278e1Smatt #ifdef __HAVE_MEMORY_DISK__
3191f4278e1Smatt 	md_root_setconf(memory_disk, sizeof memory_disk);
3201f4278e1Smatt #endif
3211f4278e1Smatt 
3221f4278e1Smatt #ifdef BOOTHOWTO
3231f4278e1Smatt 	boothowto |= BOOTHOWTO;
3241f4278e1Smatt #endif
3251f4278e1Smatt 
3261f4278e1Smatt #ifdef KGDB
3271f4278e1Smatt 	if (boothowto & RB_KDB) {
3281f4278e1Smatt 		kgdb_debug_init = 1;
3291f4278e1Smatt 		kgdb_connect(1);
3301f4278e1Smatt 	}
3311f4278e1Smatt #endif
3321f4278e1Smatt 
3331f4278e1Smatt #ifdef DDB
3341f4278e1Smatt 	db_machine_init();
3351f4278e1Smatt 	ddb_init(0, NULL, NULL);
3361f4278e1Smatt 
3371f4278e1Smatt 	if (boothowto & RB_KDB)
3381f4278e1Smatt 		Debugger();
3391f4278e1Smatt #endif
3401f4278e1Smatt 
341845151e8Sjmcneill #ifdef MULTIPROCESSOR
34207964189Sskrll 	/*
34307964189Sskrll 	 * Ensure BP cache is flushed to memory so that APs start cache
34407964189Sskrll 	 * coherency with correct view.
34507964189Sskrll 	 */
34607964189Sskrll 	cpu_dcache_wbinv_all();
347845151e8Sjmcneill #endif
348845151e8Sjmcneill 
349c3b674b9Sskrll 	VPRINTF("done.\n");
3501f4278e1Smatt 
3511f4278e1Smatt 	/* We return the new stack pointer address */
352d3419f91Sskrll 	return pcb->pcb_ksp;
3531f4278e1Smatt }
3541f4278e1Smatt 
3551f4278e1Smatt #ifdef MULTIPROCESSOR
3561f4278e1Smatt /*
3571f4278e1Smatt  * When we are called, the MMU and caches are on and we are running on the stack
3581f4278e1Smatt  * of the idlelwp for this cpu.
3591f4278e1Smatt  */
3601f4278e1Smatt void
cpu_hatch(struct cpu_info * ci,u_int cpuindex,void (* md_cpu_init)(struct cpu_info *))361030faca8Sskrll cpu_hatch(struct cpu_info *ci, u_int cpuindex, void (*md_cpu_init)(struct cpu_info *))
3621f4278e1Smatt {
363030faca8Sskrll 	KASSERT(cpu_index(ci) == cpuindex);
3641f4278e1Smatt 
3651f4278e1Smatt 	/*
3661f4278e1Smatt 	 * Raise our IPL to the max
3671f4278e1Smatt 	 */
3681f4278e1Smatt 	splhigh();
3691f4278e1Smatt 
370030faca8Sskrll 	VPRINTF("%s(%s): ", __func__, cpu_name(ci));
371e677f16fSskrll 	/* mpidr/midr filled in by cpu_init_secondary_processor */
372eef1da71Sjmcneill 
3731f4278e1Smatt 	/*
3741f4278e1Smatt 	 * Make sure we have the right vector page.
3751f4278e1Smatt 	 */
376c3b674b9Sskrll 	VPRINTF(" vectors");
3771f4278e1Smatt 	arm32_vector_init(systempage.pv_va, ARM_VEC_ALL);
3781f4278e1Smatt 
3791f4278e1Smatt 	/*
380d6e299a9Smatt 	 * Initialize the stack for each mode (we are already running on the
381d6e299a9Smatt 	 * SVC32 stack of the idlelwp).
3821f4278e1Smatt 	 */
383c3b674b9Sskrll 	VPRINTF(" stacks");
3841f4278e1Smatt 	set_stackptr(PSR_FIQ32_MODE,
385c2d23e72Smatt 	    fiqstack.pv_va + (cpu_index(ci) + 1) * FIQ_STACK_SIZE * PAGE_SIZE);
3861f4278e1Smatt 	set_stackptr(PSR_IRQ32_MODE,
387c2d23e72Smatt 	    irqstack.pv_va + (cpu_index(ci) + 1) * IRQ_STACK_SIZE * PAGE_SIZE);
3881f4278e1Smatt 	set_stackptr(PSR_ABT32_MODE,
389c2d23e72Smatt 	    abtstack.pv_va + (cpu_index(ci) + 1) * ABT_STACK_SIZE * PAGE_SIZE);
3901f4278e1Smatt 	set_stackptr(PSR_UND32_MODE,
391c2d23e72Smatt 	    undstack.pv_va + (cpu_index(ci) + 1) * UND_STACK_SIZE * PAGE_SIZE);
3921f4278e1Smatt 
3935132b1cdSmatt 	ci->ci_lastlwp = NULL;
3945132b1cdSmatt 	ci->ci_pmap_lastuser = NULL;
3955132b1cdSmatt #ifdef ARM_MMU_EXTENDED
396c3b674b9Sskrll 	VPRINTF(" tlb");
3971f4278e1Smatt 	/*
3985132b1cdSmatt 	 * Attach to the tlb.
3991f4278e1Smatt 	 */
4005132b1cdSmatt 	ci->ci_pmap_cur = pmap_kernel();
4015132b1cdSmatt 	ci->ci_pmap_asid_cur = KERNEL_PID;
4021f4278e1Smatt #endif
4035132b1cdSmatt 
4041f4278e1Smatt #ifdef CPU_CORTEX
4051f4278e1Smatt 	if (CPU_ID_CORTEX_P(ci->ci_arm_cpuid)) {
4061f4278e1Smatt 		/*
4071f4278e1Smatt 		 * Start and reset the PMC Cycle Counter.
4081f4278e1Smatt 		 */
4091f4278e1Smatt 		armreg_pmcr_write(ARM11_PMCCTL_E|ARM11_PMCCTL_P|ARM11_PMCCTL_C);
410*2e481659Sryo 		armreg_pmintenclr_write(PMINTEN_C | PMINTEN_P);
4111f4278e1Smatt 		armreg_pmcntenset_write(CORTEX_CNTENS_C);
4121f4278e1Smatt 	}
4131f4278e1Smatt #endif
4141f4278e1Smatt 
415e6c2e807Sskrll 	VPRINTF(" md(%p)", md_cpu_init);
416e6c2e807Sskrll 	if (md_cpu_init != NULL)
417e6c2e807Sskrll 		(*md_cpu_init)(ci);
418e6c2e807Sskrll 
419c3b674b9Sskrll 	VPRINTF(" interrupts");
4201f4278e1Smatt 	/*
4211f4278e1Smatt 	 * Let the interrupts do what they need to on this CPU.
4221f4278e1Smatt 	 */
4231f4278e1Smatt 	intr_cpu_init(ci);
4241f4278e1Smatt 
425c3b674b9Sskrll 	VPRINTF(" done!\n");
426e1281176Sskrll 	cpu_clr_mbox(cpuindex);
4271f4278e1Smatt }
4281f4278e1Smatt #endif /* MULTIPROCESSOR */
429