1 /* $NetBSD: arm32_boot.c,v 1.8 2014/09/14 20:35:45 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 126 __KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.8 2014/09/14 20:35:45 ryo Exp $"); 127 128 #include "opt_ddb.h" 129 #include "opt_kgdb.h" 130 131 #include <sys/param.h> 132 #include <sys/reboot.h> 133 #include <sys/cpu.h> 134 #include <sys/intr.h> 135 #include <sys/atomic.h> 136 #include <sys/device.h> 137 138 #include <uvm/uvm_extern.h> 139 140 #include <arm/locore.h> 141 #include <arm/undefined.h> 142 #include <arm/arm32/machdep.h> 143 144 #include <machine/db_machdep.h> 145 #include <ddb/db_extern.h> 146 147 #include <machine/bootconfig.h> 148 149 #ifdef KGDB 150 #include <sys/kgdb.h> 151 #endif 152 153 vaddr_t 154 initarm_common(vaddr_t kvm_base, vsize_t kvm_size, 155 const struct boot_physmem *bp, size_t nbp) 156 { 157 struct bootmem_info * const bmi = &bootmem_info; 158 159 #ifdef VERBOSE_INIT_ARM 160 printf("nfreeblocks = %u, free_pages = %d (%#x)\n", 161 bmi->bmi_nfreeblocks, bmi->bmi_freepages, 162 bmi->bmi_freepages); 163 #endif 164 165 /* 166 * Moved from cpu_startup() as data_abort_handler() references 167 * this during uvm init. 168 */ 169 uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); 170 171 #ifdef VERBOSE_INIT_ARM 172 printf("bootstrap done.\n"); 173 #endif 174 175 #ifdef VERBOSE_INIT_ARM 176 printf("vectors"); 177 #endif 178 arm32_vector_init(systempage.pv_va, ARM_VEC_ALL); 179 #ifdef VERBOSE_INIT_ARM 180 printf(" %#"PRIxVADDR"\n", vector_page); 181 #endif 182 183 /* 184 * Pages were allocated during the secondary bootstrap for the 185 * stacks for different CPU modes. 186 * We must now set the r13 registers in the different CPU modes to 187 * point to these stacks. 188 * Since the ARM stacks use STMFD etc. we must set r13 to the top end 189 * of the stack memory. 190 */ 191 #ifdef VERBOSE_INIT_ARM 192 printf("init subsystems: stacks "); 193 #endif 194 set_stackptr(PSR_FIQ32_MODE, 195 fiqstack.pv_va + FIQ_STACK_SIZE * PAGE_SIZE); 196 set_stackptr(PSR_IRQ32_MODE, 197 irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE); 198 set_stackptr(PSR_ABT32_MODE, 199 abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE); 200 set_stackptr(PSR_UND32_MODE, 201 undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE); 202 203 /* 204 * Well we should set a data abort handler. 205 * Once things get going this will change as we will need a proper 206 * handler. 207 * Until then we will use a handler that just panics but tells us 208 * why. 209 * Initialisation of the vectors will just panic on a data abort. 210 * This just fills in a slightly better one. 211 */ 212 #ifdef VERBOSE_INIT_ARM 213 printf("vectors "); 214 #endif 215 data_abort_handler_address = (u_int)data_abort_handler; 216 prefetch_abort_handler_address = (u_int)prefetch_abort_handler; 217 undefined_handler_address = (u_int)undefinedinstruction_bounce; 218 219 /* Initialise the undefined instruction handlers */ 220 #ifdef VERBOSE_INIT_ARM 221 printf("undefined "); 222 #endif 223 undefined_init(); 224 225 /* Load memory into UVM. */ 226 #ifdef VERBOSE_INIT_ARM 227 printf("page "); 228 #endif 229 uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ 230 231 #ifdef VERBOSE_INIT_ARM 232 printf("pmap_physload "); 233 #endif 234 KASSERT(bp != NULL || nbp == 0); 235 KASSERT(bp == NULL || nbp != 0); 236 237 for (size_t i = 0; i < bmi->bmi_nfreeblocks; i++) { 238 pv_addr_t * const pv = &bmi->bmi_freeblocks[i]; 239 paddr_t start = atop(pv->pv_pa); 240 const paddr_t end = start + atop(pv->pv_size); 241 242 while (start < end) { 243 int vm_freelist = VM_FREELIST_DEFAULT; 244 paddr_t segend = end; 245 /* 246 * This assumes the bp list is sorted in ascending 247 * order. 248 */ 249 for (size_t j = 0; j < nbp; j++) { 250 paddr_t bp_start = bp[j].bp_start; 251 paddr_t bp_end = bp_start + bp[j].bp_pages; 252 if (start < bp_start) { 253 if (segend > bp_start) { 254 segend = bp_start; 255 } 256 break; 257 } 258 if (start < bp_end) { 259 if (segend > bp_end) { 260 segend = bp_end; 261 } 262 vm_freelist = bp[j].bp_freelist; 263 break; 264 } 265 } 266 267 uvm_page_physload(start, segend, start, segend, 268 vm_freelist); 269 start = segend; 270 } 271 } 272 273 /* Boot strap pmap telling it where the kernel page table is */ 274 #ifdef VERBOSE_INIT_ARM 275 printf("pmap "); 276 #endif 277 pmap_bootstrap(kvm_base, kvm_base + kvm_size); 278 279 #ifdef __HAVE_MEMORY_DISK__ 280 md_root_setconf(memory_disk, sizeof memory_disk); 281 #endif 282 283 #ifdef BOOTHOWTO 284 boothowto |= BOOTHOWTO; 285 #endif 286 287 #ifdef KGDB 288 if (boothowto & RB_KDB) { 289 kgdb_debug_init = 1; 290 kgdb_connect(1); 291 } 292 #endif 293 294 #ifdef DDB 295 db_machine_init(); 296 ddb_init(0, NULL, NULL); 297 298 if (boothowto & RB_KDB) 299 Debugger(); 300 #endif 301 302 #ifdef VERBOSE_INIT_ARM 303 printf("done.\n"); 304 #endif 305 306 /* We return the new stack pointer address */ 307 return kernelstack.pv_va + USPACE_SVC_STACK_TOP; 308 } 309 310 #ifdef MULTIPROCESSOR 311 /* 312 * When we are called, the MMU and caches are on and we are running on the stack 313 * of the idlelwp for this cpu. 314 */ 315 void 316 cpu_hatch(struct cpu_info *ci, cpuid_t cpuid, void (*md_cpu_init)(struct cpu_info *)) 317 { 318 KASSERT(cpu_index(ci) == cpuid); 319 320 /* 321 * Raise our IPL to the max 322 */ 323 splhigh(); 324 325 #ifdef VERBOSE_INIT_ARM 326 printf("%s(%s): ", __func__, ci->ci_data.cpu_name); 327 #endif 328 uint32_t mpidr = armreg_mpidr_read(); 329 if (mpidr & MPIDR_MT) { 330 ci->ci_data.cpu_smt_id = mpidr & MPIDR_AFF0; 331 ci->ci_data.cpu_core_id = mpidr & MPIDR_AFF1; 332 ci->ci_data.cpu_package_id = mpidr & MPIDR_AFF2; 333 } else { 334 ci->ci_data.cpu_core_id = mpidr & MPIDR_AFF0; 335 ci->ci_data.cpu_package_id = mpidr & MPIDR_AFF1; 336 } 337 338 /* 339 * Make sure we have the right vector page. 340 */ 341 #ifdef VERBOSE_INIT_ARM 342 printf(" vectors"); 343 #endif 344 arm32_vector_init(systempage.pv_va, ARM_VEC_ALL); 345 346 /* 347 * Initialize the stack for each mode (we are already running on the 348 * SVC32 stack of the idlelwp). 349 */ 350 #ifdef VERBOSE_INIT_ARM 351 printf(" stacks"); 352 #endif 353 set_stackptr(PSR_FIQ32_MODE, 354 fiqstack.pv_va + cpu_index(ci) * FIQ_STACK_SIZE * PAGE_SIZE); 355 set_stackptr(PSR_IRQ32_MODE, 356 irqstack.pv_va + cpu_index(ci) * IRQ_STACK_SIZE * PAGE_SIZE); 357 set_stackptr(PSR_ABT32_MODE, 358 abtstack.pv_va + cpu_index(ci) * ABT_STACK_SIZE * PAGE_SIZE); 359 set_stackptr(PSR_UND32_MODE, 360 undstack.pv_va + cpu_index(ci) * UND_STACK_SIZE * PAGE_SIZE); 361 362 ci->ci_lastlwp = NULL; 363 ci->ci_pmap_lastuser = NULL; 364 #ifdef ARM_MMU_EXTENDED 365 #ifdef VERBOSE_INIT_ARM 366 printf(" tlb"); 367 #endif 368 /* 369 * Attach to the tlb. 370 */ 371 ci->ci_pmap_cur = pmap_kernel(); 372 ci->ci_pmap_asid_cur = KERNEL_PID; 373 #endif 374 375 #ifdef CPU_CORTEX 376 if (CPU_ID_CORTEX_P(ci->ci_arm_cpuid)) { 377 /* 378 * Start and reset the PMC Cycle Counter. 379 */ 380 armreg_pmcr_write(ARM11_PMCCTL_E|ARM11_PMCCTL_P|ARM11_PMCCTL_C); 381 armreg_pmcntenset_write(CORTEX_CNTENS_C); 382 } 383 #endif 384 385 aprint_naive("%s", device_xname(ci->ci_dev)); 386 aprint_normal("%s", device_xname(ci->ci_dev)); 387 identify_arm_cpu(ci->ci_dev, ci); 388 #ifdef VERBOSE_INIT_ARM 389 printf(" vfp"); 390 #endif 391 vfp_attach(ci); 392 393 #ifdef VERBOSE_INIT_ARM 394 printf(" interrupts"); 395 #endif 396 /* 397 * Let the interrupts do what they need to on this CPU. 398 */ 399 intr_cpu_init(ci); 400 401 #ifdef VERBOSE_INIT_ARM 402 printf(" md(%p)", md_cpu_init); 403 #endif 404 if (md_cpu_init != NULL) 405 (*md_cpu_init)(ci); 406 407 #ifdef VERBOSE_INIT_ARM 408 printf(" done!\n"); 409 #endif 410 atomic_and_32(&arm_cpu_mbox, ~(1 << cpuid)); 411 membar_producer(); 412 __asm __volatile("sev; sev; sev"); 413 } 414 #endif /* MULTIPROCESSOR */ 415