[BACK]Return to arm32_boot.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / arm / arm32

Annotation of src/sys/arch/arm/arm32/arm32_boot.c, Revision 1.44

1.44    ! skrll       1: /*     $NetBSD: arm32_boot.c,v 1.43 2021/06/03 07:06:22 skrll Exp $    */
1.1       matt        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>
1.44    ! skrll     125: __KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.43 2021/06/03 07:06:22 skrll Exp $");
1.3       skrll     126:
1.20      skrll     127: #include "opt_arm_debug.h"
1.21      skrll     128: #include "opt_cputypes.h"
1.3       skrll     129: #include "opt_ddb.h"
                    130: #include "opt_kgdb.h"
1.9       skrll     131: #include "opt_multiprocessor.h"
1.1       matt      132:
                    133: #include <sys/param.h>
1.38      skrll     134:
1.39      skrll     135: #include <sys/asan.h>
1.38      skrll     136: #include <sys/atomic.h>
1.1       matt      137: #include <sys/cpu.h>
1.38      skrll     138: #include <sys/device.h>
1.1       matt      139: #include <sys/intr.h>
1.38      skrll     140: #include <sys/reboot.h>
1.1       matt      141:
                    142: #include <uvm/uvm_extern.h>
                    143:
1.5       matt      144: #include <arm/locore.h>
1.1       matt      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:
1.3       skrll     153: #ifdef KGDB
                    154: #include <sys/kgdb.h>
                    155: #endif
                    156:
1.20      skrll     157: #ifdef VERBOSE_INIT_ARM
                    158: #define VPRINTF(...)   printf(__VA_ARGS__)
                    159: #else
1.23      skrll     160: #define VPRINTF(...)   __nothing
1.20      skrll     161: #endif
                    162:
1.1       matt      163: vaddr_t
                    164: initarm_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:
1.20      skrll     169:        VPRINTF("nfreeblocks = %u, free_pages = %d (%#x)\n",
1.1       matt      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:
1.19      skrll     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;
1.41      rin       195: #ifdef _ARM_ARCH_BE8
                    196:        tf->tf_spsr |= PSR_E_BIT;
1.19      skrll     197: #endif
                    198:
1.20      skrll     199:        VPRINTF("bootstrap done.\n");
1.1       matt      200:
1.20      skrll     201:        VPRINTF("vectors");
1.1       matt      202:        arm32_vector_init(systempage.pv_va, ARM_VEC_ALL);
1.20      skrll     203:        VPRINTF(" %#"PRIxVADDR"\n", vector_page);
1.1       matt      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:         */
1.20      skrll     213:        VPRINTF("init subsystems: stacks ");
1.1       matt      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:         */
1.20      skrll     232:        VPRINTF("vectors ");
1.1       matt      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 */
1.20      skrll     238:        VPRINTF("undefined ");
1.1       matt      239:        undefined_init();
                    240:
1.44    ! skrll     241: #ifdef FPU_VFP
        !           242:        /* vfp_detect uses an undefined handler */
        !           243:        VPRINTF("vfp ");
        !           244:        vfp_detect(curcpu());
        !           245: #endif
        !           246:
1.1       matt      247:        /* Load memory into UVM. */
1.20      skrll     248:        VPRINTF("page ");
1.18      cherry    249:        uvm_md_init();
1.1       matt      250:
1.24      skrll     251:        VPRINTF("pmap_physload\n");
1.2       matt      252:        KASSERT(bp != NULL || nbp == 0);
                    253:        KASSERT(bp == NULL || nbp != 0);
1.1       matt      254:
1.2       matt      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);
1.24      skrll     259:                int vm_freelist = VM_FREELIST_DEFAULT;
1.2       matt      260:
1.24      skrll     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:                }
1.27      skrll     269:                VPRINTF("\n");
1.43      skrll     270:
                    271:                /*
                    272:                 * This assumes the bp list is sorted in ascending
                    273:                 * order.
                    274:                 */
1.24      skrll     275:                paddr_t segend = end;
1.43      skrll     276:                for (size_t j = 0; j < nbp && start < end; j++) {
1.24      skrll     277:                        paddr_t bp_start = bp[j].bp_start;
                    278:                        paddr_t bp_end = bp_start + bp[j].bp_pages;
                    279:
1.27      skrll     280:                        VPRINTF("   bp %2zu start %08lx  end %08lx\n",
1.24      skrll     281:                            j, ptoa(bp_start), ptoa(bp_end));
1.43      skrll     282:
1.24      skrll     283:                        KASSERT(bp_start < bp_end);
1.43      skrll     284:                        if (start >= bp_end || segend < bp_start)
1.24      skrll     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;
1.2       matt      293:                                }
1.24      skrll     294:                                vm_freelist = bp[j].bp_freelist;
                    295:
                    296:                                VPRINTF("         start %08lx  end %08lx"
1.27      skrll     297:                                    "... loading in freelist %d\n", ptoa(start),
1.25      skrll     298:                                    ptoa(segend), vm_freelist);
1.43      skrll     299:
                    300:                                uvm_page_physload(start, segend, start, segend,
                    301:                                    vm_freelist);
                    302:
1.24      skrll     303:                                start = segend;
                    304:                                segend = end;
1.2       matt      305:                        }
1.1       matt      306:                }
                    307:        }
                    308:
1.40      skrll     309:        /*
                    310:         * Bootstrap pmap telling it where the managed kernel virtual memory
                    311:         * is.
                    312:         */
1.20      skrll     313:        VPRINTF("pmap ");
1.1       matt      314:        pmap_bootstrap(kvm_base, kvm_base + kvm_size);
1.17      skrll     315:
1.39      skrll     316:        kasan_init();
                    317:
1.1       matt      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:
1.11      jmcneill  341: #ifdef MULTIPROCESSOR
1.33      skrll     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();
1.11      jmcneill  347: #endif
                    348:
1.20      skrll     349:        VPRINTF("done.\n");
1.1       matt      350:
                    351:        /* We return the new stack pointer address */
1.19      skrll     352:        return pcb->pcb_ksp;
1.1       matt      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:  */
                    360: void
1.28      skrll     361: cpu_hatch(struct cpu_info *ci, u_int cpuindex, void (*md_cpu_init)(struct cpu_info *))
1.1       matt      362: {
1.28      skrll     363:        KASSERT(cpu_index(ci) == cpuindex);
1.1       matt      364:
                    365:        /*
                    366:         * Raise our IPL to the max
                    367:         */
                    368:        splhigh();
                    369:
1.28      skrll     370:        VPRINTF("%s(%s): ", __func__, cpu_name(ci));
1.44    ! skrll     371:        /* mpidr/midr filled in by cpu_init_secondary_processor */
1.29      jmcneill  372:
1.1       matt      373:        /*
                    374:         * Make sure we have the right vector page.
                    375:         */
1.20      skrll     376:        VPRINTF(" vectors");
1.1       matt      377:        arm32_vector_init(systempage.pv_va, ARM_VEC_ALL);
                    378:
                    379:        /*
1.7       matt      380:         * Initialize the stack for each mode (we are already running on the
                    381:         * SVC32 stack of the idlelwp).
1.1       matt      382:         */
1.20      skrll     383:        VPRINTF(" stacks");
1.1       matt      384:        set_stackptr(PSR_FIQ32_MODE,
1.10      matt      385:            fiqstack.pv_va + (cpu_index(ci) + 1) * FIQ_STACK_SIZE * PAGE_SIZE);
1.1       matt      386:        set_stackptr(PSR_IRQ32_MODE,
1.10      matt      387:            irqstack.pv_va + (cpu_index(ci) + 1) * IRQ_STACK_SIZE * PAGE_SIZE);
1.1       matt      388:        set_stackptr(PSR_ABT32_MODE,
1.10      matt      389:            abtstack.pv_va + (cpu_index(ci) + 1) * ABT_STACK_SIZE * PAGE_SIZE);
1.1       matt      390:        set_stackptr(PSR_UND32_MODE,
1.10      matt      391:            undstack.pv_va + (cpu_index(ci) + 1) * UND_STACK_SIZE * PAGE_SIZE);
1.1       matt      392:
1.6       matt      393:        ci->ci_lastlwp = NULL;
                    394:        ci->ci_pmap_lastuser = NULL;
                    395: #ifdef ARM_MMU_EXTENDED
1.20      skrll     396:        VPRINTF(" tlb");
1.1       matt      397:        /*
1.6       matt      398:         * Attach to the tlb.
1.1       matt      399:         */
1.6       matt      400:        ci->ci_pmap_cur = pmap_kernel();
                    401:        ci->ci_pmap_asid_cur = KERNEL_PID;
1.1       matt      402: #endif
1.6       matt      403:
1.1       matt      404: #ifdef CPU_CORTEX
                    405:        if (CPU_ID_CORTEX_P(ci->ci_arm_cpuid)) {
                    406:                /*
                    407:                 * Start and reset the PMC Cycle Counter.
1.17      skrll     408:                 */
1.1       matt      409:                armreg_pmcr_write(ARM11_PMCCTL_E|ARM11_PMCCTL_P|ARM11_PMCCTL_C);
                    410:                armreg_pmcntenset_write(CORTEX_CNTENS_C);
                    411:        }
                    412: #endif
                    413:
1.24      skrll     414:        VPRINTF(" md(%p)", md_cpu_init);
                    415:        if (md_cpu_init != NULL)
                    416:                (*md_cpu_init)(ci);
                    417:
1.20      skrll     418:        VPRINTF(" interrupts");
1.1       matt      419:        /*
                    420:         * Let the interrupts do what they need to on this CPU.
                    421:         */
                    422:        intr_cpu_init(ci);
                    423:
1.24      skrll     424:        VPRINTF(" done!\n");
1.37      skrll     425:        cpu_clr_mbox(cpuindex);
1.1       matt      426: }
                    427: #endif /* MULTIPROCESSOR */

CVSweb <webmaster@jp.NetBSD.org>