[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.17

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

CVSweb <webmaster@jp.NetBSD.org>