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