1/* $NetBSD: arm32_boot.c,v 1.45 2022/12/22 06:58:08 ryo Exp $ */ 2 3/* 4 * Copyright (c) 2002, 2003, 2005 Genetec Corporation. All rights reserved. 5 * Written by Hiroyuki Bessho for Genetec Corporation. 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 * 3. The name of Genetec Corporation may not be used to endorse or 16 * promote products derived from this software without specific prior 17 * written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Copyright (c) 2001 Wasabi Systems, Inc. 32 * All rights reserved. 33 * 34 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed for the NetBSD Project by 47 * Wasabi Systems, Inc. 48 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 49 * or promote products derived from this software without specific prior 50 * written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 62 * POSSIBILITY OF SUCH DAMAGE. 63 * 64 * Copyright (c) 1997,1998 Mark Brinicombe. 65 * Copyright (c) 1997,1998 Causality Limited. 66 * All rights reserved. 67 * 68 * Redistribution and use in source and binary forms, with or without 69 * modification, are permitted provided that the following conditions 70 * are met: 71 * 1. Redistributions of source code must retain the above copyright 72 * notice, this list of conditions and the following disclaimer. 73 * 2. Redistributions in binary form must reproduce the above copyright 74 * notice, this list of conditions and the following disclaimer in the 75 * documentation and/or other materials provided with the distribution. 76 * 3. All advertising materials mentioning features or use of this software 77 * must display the following acknowledgement: 78 * This product includes software developed by Mark Brinicombe 79 * for the NetBSD Project. 80 * 4. The name of the company nor the name of the author may be used to 81 * endorse or promote products derived from this software without specific 82 * prior written permission. 83 * 84 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 85 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 86 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 87 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 88 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 89 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 90 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 91 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 92 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 93 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 94 * SUCH DAMAGE. 95 * 96 * Copyright (c) 2007 Microsoft 97 * All rights reserved. 98 * 99 * Redistribution and use in source and binary forms, with or without 100 * modification, are permitted provided that the following conditions 101 * are met: 102 * 1. Redistributions of source code must retain the above copyright 103 * notice, this list of conditions and the following disclaimer. 104 * 2. Redistributions in binary form must reproduce the above copyright 105 * notice, this list of conditions and the following disclaimer in the 106 * documentation and/or other materials provided with the distribution. 107 * 3. All advertising materials mentioning features or use of this software 108 * must display the following acknowledgement: 109 * This product includes software developed by Microsoft 110 * 111 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 112 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 113 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 114 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, 115 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 116 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 117 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 118 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 119 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 120 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 121 * SUCH DAMAGE. 122 */ 123 124#include <sys/cdefs.h> 125__KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.45 2022/12/22 06:58:08 ryo Exp $"); 126 127#include "opt_arm_debug.h" 128#include "opt_cputypes.h" 129#include "opt_ddb.h" 130#include "opt_kgdb.h" 131#include "opt_multiprocessor.h" 132 133#include <sys/param.h> 134 135#include <sys/asan.h> 136#include <sys/atomic.h> 137#include <sys/cpu.h> 138#include <sys/device.h> 139#include <sys/intr.h> 140#include <sys/reboot.h> 141 142#include <uvm/uvm_extern.h> 143 144#include <arm/locore.h> 145#include <arm/undefined.h> 146#include <arm/arm32/machdep.h> 147 148#include <machine/db_machdep.h> 149#include <ddb/db_extern.h> 150 151#include <machine/bootconfig.h> 152 153#ifdef KGDB 154#include <sys/kgdb.h> 155#endif 156 157#ifdef VERBOSE_INIT_ARM 158#define VPRINTF(...) printf(__VA_ARGS__) 159#else 160#define VPRINTF(...) __nothing 161#endif 162 163vaddr_t 164initarm_common(vaddr_t kvm_base, vsize_t kvm_size, 165 const struct boot_physmem *bp, size_t nbp) 166{ 167 struct bootmem_info * const bmi = &bootmem_info; 168 169 VPRINTF("nfreeblocks = %u, free_pages = %d (%#x)\n", 170 bmi->bmi_nfreeblocks, bmi->bmi_freepages, 171 bmi->bmi_freepages); 172 173 /* 174 * Moved from cpu_startup() as data_abort_handler() references 175 * this during uvm init. 176 */ 177 uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); 178 179 struct lwp * const l = &lwp0; 180 struct pcb * const pcb = lwp_getpcb(l); 181 182 /* Zero out the PCB. */ 183 memset(pcb, 0, sizeof(*pcb)); 184 185 pcb->pcb_ksp = uvm_lwp_getuarea(l) + USPACE_SVC_STACK_TOP; 186 pcb->pcb_ksp -= sizeof(struct trapframe); 187 188 struct trapframe * tf = (struct trapframe *)pcb->pcb_ksp; 189 190 /* Zero out the trapframe. */ 191 memset(tf, 0, sizeof(*tf)); 192 lwp_settrapframe(l, tf); 193 194 tf->tf_spsr = PSR_USR32_MODE; 195#ifdef _ARM_ARCH_BE8 196 tf->tf_spsr |= PSR_E_BIT; 197#endif 198 199 VPRINTF("bootstrap done.\n"); 200 201 VPRINTF("vectors"); 202 arm32_vector_init(systempage.pv_va, ARM_VEC_ALL); 203 VPRINTF(" %#"PRIxVADDR"\n", vector_page); 204 205 /* 206 * Pages were allocated during the secondary bootstrap for the 207 * stacks for different CPU modes. 208 * We must now set the r13 registers in the different CPU modes to 209 * point to these stacks. 210 * Since the ARM stacks use STMFD etc. we must set r13 to the top end 211 * of the stack memory. 212 */ 213 VPRINTF("init subsystems: stacks "); 214 set_stackptr(PSR_FIQ32_MODE, 215 fiqstack.pv_va + FIQ_STACK_SIZE * PAGE_SIZE); 216 set_stackptr(PSR_IRQ32_MODE, 217 irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE); 218 set_stackptr(PSR_ABT32_MODE, 219 abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE); 220 set_stackptr(PSR_UND32_MODE, 221 undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE); 222 223 /* 224 * Well we should set a data abort handler. 225 * Once things get going this will change as we will need a proper 226 * handler. 227 * Until then we will use a handler that just panics but tells us 228 * why. 229 * Initialisation of the vectors will just panic on a data abort. 230 * This just fills in a slightly better one. 231 */ 232 VPRINTF("vectors "); 233 data_abort_handler_address = (u_int)data_abort_handler; 234 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 235 undefined_handler_address = (u_int)undefinedinstruction_bounce; 236 237 /* Initialise the undefined instruction handlers */ 238 VPRINTF("undefined "); 239 undefined_init(); 240 241#ifdef FPU_VFP 242 /* vfp_detect uses an undefined handler */ 243 VPRINTF("vfp "); 244 vfp_detect(curcpu()); 245#endif 246 247 /* Load memory into UVM. */ 248 VPRINTF("page "); 249 uvm_md_init(); 250 251 VPRINTF("pmap_physload\n"); 252 KASSERT(bp != NULL || nbp == 0); 253 KASSERT(bp == NULL || nbp != 0); 254 255 for (size_t i = 0; i < bmi->bmi_nfreeblocks; i++) { 256 pv_addr_t * const pv = &bmi->bmi_freeblocks[i]; 257 paddr_t start = atop(pv->pv_pa); 258 const paddr_t end = start + atop(pv->pv_size); 259 int vm_freelist = VM_FREELIST_DEFAULT; 260 261 VPRINTF("block %2zu start %08lx end %08lx", i, 262 pv->pv_pa, pv->pv_pa + pv->pv_size); 263 264 if (!bp) { 265 VPRINTF("... loading in freelist %d\n", vm_freelist); 266 uvm_page_physload(start, end, start, end, VM_FREELIST_DEFAULT); 267 continue; 268 } 269 VPRINTF("\n"); 270 271 /* 272 * This assumes the bp list is sorted in ascending 273 * order. 274 */ 275 paddr_t segend = end; 276 for (size_t j = 0; j < nbp && start < end; j++) { 277 paddr_t bp_start = bp[j].bp_start; 278 paddr_t bp_end = bp_start + bp[j].bp_pages; 279 280 VPRINTF(" bp %2zu start %08lx end %08lx\n", 281 j, ptoa(bp_start), ptoa(bp_end)); 282 283 KASSERT(bp_start < bp_end); 284 if (start >= bp_end || segend < bp_start) 285 continue; 286 287 if (start < bp_start) 288 start = bp_start; 289 290 if (start < bp_end) { 291 if (segend > bp_end) { 292 segend = bp_end; 293 } 294 vm_freelist = bp[j].bp_freelist; 295 296 VPRINTF(" start %08lx end %08lx" 297 "... loading in freelist %d\n", ptoa(start), 298 ptoa(segend), vm_freelist); 299 300 uvm_page_physload(start, segend, start, segend, 301 vm_freelist); 302 303 start = segend; 304 segend = end; 305 } 306 } 307 } 308 309 /* 310 * Bootstrap pmap telling it where the managed kernel virtual memory 311 * is. 312 */ 313 VPRINTF("pmap "); 314 pmap_bootstrap(kvm_base, kvm_base + kvm_size); 315 316 kasan_init(); 317 318#ifdef __HAVE_MEMORY_DISK__ 319 md_root_setconf(memory_disk, sizeof memory_disk); 320#endif 321 322#ifdef BOOTHOWTO 323 boothowto |= BOOTHOWTO; 324#endif 325 326#ifdef KGDB 327 if (boothowto & RB_KDB) { 328 kgdb_debug_init = 1; 329 kgdb_connect(1); 330 } 331#endif 332 333#ifdef DDB 334 db_machine_init(); 335 ddb_init(0, NULL, NULL); 336 337 if (boothowto & RB_KDB) 338 Debugger(); 339#endif 340 341#ifdef MULTIPROCESSOR 342 /* 343 * Ensure BP cache is flushed to memory so that APs start cache 344 * coherency with correct view. 345 */ 346 cpu_dcache_wbinv_all(); 347#endif 348 349 VPRINTF("done.\n"); 350 351 /* We return the new stack pointer address */ 352 return pcb->pcb_ksp; 353} 354 355#ifdef MULTIPROCESSOR 356/* 357 * When we are called, the MMU and caches are on and we are running on the stack 358 * of the idlelwp for this cpu. 359 */ 360void 361cpu_hatch(struct cpu_info *ci, u_int cpuindex, void (*md_cpu_init)(struct cpu_info *)) 362{ 363 KASSERT(cpu_index(ci) == cpuindex); 364 365 /* 366 * Raise our IPL to the max 367 */ 368 splhigh(); 369 370 VPRINTF("%s(%s): ", __func__, cpu_name(ci)); 371 /* mpidr/midr filled in by cpu_init_secondary_processor */ 372 373 /* 374 * Make sure we have the right vector page. 375 */ 376 VPRINTF(" vectors"); 377 arm32_vector_init(systempage.pv_va, ARM_VEC_ALL); 378 379 /* 380 * Initialize the stack for each mode (we are already running on the 381 * SVC32 stack of the idlelwp). 382 */ 383 VPRINTF(" stacks"); 384 set_stackptr(PSR_FIQ32_MODE, 385 fiqstack.pv_va + (cpu_index(ci) + 1) * FIQ_STACK_SIZE * PAGE_SIZE); 386 set_stackptr(PSR_IRQ32_MODE, 387 irqstack.pv_va + (cpu_index(ci) + 1) * IRQ_STACK_SIZE * PAGE_SIZE); 388 set_stackptr(PSR_ABT32_MODE, 389 abtstack.pv_va + (cpu_index(ci) + 1) * ABT_STACK_SIZE * PAGE_SIZE); 390 set_stackptr(PSR_UND32_MODE, 391 undstack.pv_va + (cpu_index(ci) + 1) * UND_STACK_SIZE * PAGE_SIZE); 392 393 ci->ci_lastlwp = NULL; 394 ci->ci_pmap_lastuser = NULL; 395#ifdef ARM_MMU_EXTENDED 396 VPRINTF(" tlb"); 397 /* 398 * Attach to the tlb. 399 */ 400 ci->ci_pmap_cur = pmap_kernel(); 401 ci->ci_pmap_asid_cur = KERNEL_PID; 402#endif 403 404#ifdef CPU_CORTEX 405 if (CPU_ID_CORTEX_P(ci->ci_arm_cpuid)) { 406 /* 407 * Start and reset the PMC Cycle Counter. 408 */ 409 armreg_pmcr_write(ARM11_PMCCTL_E|ARM11_PMCCTL_P|ARM11_PMCCTL_C); 410 armreg_pmintenclr_write(PMINTEN_C | PMINTEN_P); 411 armreg_pmcntenset_write(CORTEX_CNTENS_C); 412 } 413#endif 414 415 VPRINTF(" md(%p)", md_cpu_init); 416 if (md_cpu_init != NULL) 417 (*md_cpu_init)(ci); 418 419 VPRINTF(" interrupts"); 420 /* 421 * Let the interrupts do what they need to on this CPU. 422 */ 423 intr_cpu_init(ci); 424 425 VPRINTF(" done!\n"); 426 cpu_clr_mbox(cpuindex); 427} 428#endif /* MULTIPROCESSOR */ 429