void ampscu_attach(struct device *parent, struct device *self, void *args) { struct ampscu_softc *sc = (struct ampscu_softc *)self; struct cortex_attach_args *ca = args; sc->sc_iot = ca->ca_iot; if (bus_space_map(sc->sc_iot, ca->ca_periphbase + SCU_ADDR, SCU_SIZE, 0, &sc->sc_ioh)) panic("ampscu_attach: bus_space_map failed!"); ncpusfound = ampscu_ncpus(sc); printf(": %d CPUs\n", ncpusfound); #ifdef MULTIPROCESSOR /* ARM Errata 764369 */ if ((curcpu()->ci_arm_cpuid & CPU_ID_CORTEX_A9_MASK) == CPU_ID_CORTEX_A9) bus_space_write_4(sc->sc_iot, sc->sc_ioh, 0x30, bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0x30) | 1); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SCU_CTRL, bus_space_read_4(sc->sc_iot, sc->sc_ioh, SCU_CTRL) | 1); /* Flush ALL the caches. */ cpu_drain_writebuf(); cpu_idcache_wbinv_all(); cpu_sdcache_wbinv_all(); cpu_drain_writebuf(); #endif }
void dumpsys() { const struct bdevsw *bdev; daddr_t blkno; int psize; int error; int addr; int block; int len; vaddr_t dumpspace; kcore_seg_t *kseg_p; cpu_kcore_hdr_t *chdr_p; char dump_hdr[dbtob(1)]; /* assumes header fits in one block */ /* Save registers. */ savectx(&dumppcb); /* flush everything out of caches */ cpu_dcache_wbinv_all(); cpu_sdcache_wbinv_all(); if (dumpdev == NODEV) return; if (dumpsize == 0) { dumpconf(); if (dumpsize == 0) return; } if (dumplo <= 0) { printf("\ndump to dev %u,%u not possible\n", major(dumpdev), minor(dumpdev)); return; } printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), minor(dumpdev), dumplo); #ifdef UVM_SWAP_ENCRYPT uvm_swap_finicrypt_all(); #endif blkno = dumplo; dumpspace = (vaddr_t) memhook; bdev = bdevsw_lookup(dumpdev); if (bdev == NULL || bdev->d_psize == NULL) return; psize = (*bdev->d_psize)(dumpdev); printf("dump "); if (psize == -1) { printf("area unavailable\n"); return; } /* Setup the dump header */ kseg_p = (kcore_seg_t *)dump_hdr; chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))]; bzero(dump_hdr, sizeof(dump_hdr)); CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); kseg_p->c_size = sizeof(dump_hdr) - ALIGN(sizeof(*kseg_p)); *chdr_p = cpu_kcore_hdr; error = (*bdev->d_dump)(dumpdev, blkno++, (caddr_t)dump_hdr, sizeof(dump_hdr)); if (error != 0) goto abort; len = 0; for (block = 0; block < bootconfig.dramblocks && error == 0; ++block) { addr = bootconfig.dram[block].address; for (;addr < (bootconfig.dram[block].address + (bootconfig.dram[block].pages * PAGE_SIZE)); addr += PAGE_SIZE) { if ((len % (1024*1024)) == 0) printf("%d ", len / (1024*1024)); pmap_kenter_pa(dumpspace, addr, PROT_READ); pmap_update(pmap_kernel()); error = (*bdev->d_dump)(dumpdev, blkno, (caddr_t) dumpspace, PAGE_SIZE); pmap_kremove(dumpspace, PAGE_SIZE); pmap_update(pmap_kernel()); if (error) break; blkno += btodb(PAGE_SIZE); len += PAGE_SIZE; } } abort: switch (error) { case ENXIO: printf("device bad\n"); break; case EFAULT: printf("device not ready\n"); break; case EINVAL: printf("area improper\n"); break; case EIO: printf("i/o error\n"); break; case EINTR: printf("aborted from console\n"); break; default: printf("succeeded\n"); break; } printf("\n\n"); delay(1000000); }