Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/arm/minidump_machdep.c
Show First 20 Lines • Show All 153 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state) | cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state) | ||||
{ | { | ||||
struct minidumphdr mdhdr; | struct minidumphdr mdhdr; | ||||
uint64_t dumpsize, *dump_avail_buf; | uint64_t dumpsize, *dump_avail_buf; | ||||
uint32_t ptesize; | uint32_t ptesize; | ||||
uint32_t pa, prev_pa = 0, count = 0; | uint32_t pa, prev_pa = 0, count = 0; | ||||
vm_offset_t va; | vm_offset_t va, kva_end; | ||||
int error, i; | int error, i; | ||||
char *addr; | char *addr; | ||||
/* | /* | ||||
* Flush caches. Note that in the SMP case this operates only on the | * Flush caches. Note that in the SMP case this operates only on the | ||||
* current CPU's L1 cache. Before we reach this point, code in either | * current CPU's L1 cache. Before we reach this point, code in either | ||||
* the system shutdown or kernel debugger has called stop_cpus() to stop | * the system shutdown or kernel debugger has called stop_cpus() to stop | ||||
* all cores other than this one. Part of the ARM handling of | * all cores other than this one. Part of the ARM handling of | ||||
* stop_cpus() is to call wbinv_all() on that core's local L1 cache. So | * stop_cpus() is to call wbinv_all() on that core's local L1 cache. So | ||||
* by time we get to here, all that remains is to flush the L1 for the | * by time we get to here, all that remains is to flush the L1 for the | ||||
* current CPU, then the L2. | * current CPU, then the L2. | ||||
*/ | */ | ||||
dcache_wbinv_poc_all(); | dcache_wbinv_poc_all(); | ||||
/* Walk page table pages, set bits in vm_page_dump */ | /* Snapshot the KVA upper bound in case it grows. */ | ||||
kva_end = kernel_vm_end; | |||||
/* | |||||
* Walk the kernel page table pages, setting the active entries in the | |||||
* dump bitmap. | |||||
*/ | |||||
ptesize = 0; | ptesize = 0; | ||||
for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) { | for (va = KERNBASE; va < kva_end; va += PAGE_SIZE) { | ||||
pa = pmap_dump_kextract(va, NULL); | pa = pmap_dump_kextract(va, NULL); | ||||
if (pa != 0 && vm_phys_is_dumpable(pa)) | if (pa != 0 && vm_phys_is_dumpable(pa)) | ||||
dump_add_page(pa); | dump_add_page(pa); | ||||
ptesize += sizeof(pt2_entry_t); | ptesize += sizeof(pt2_entry_t); | ||||
} | } | ||||
/* Calculate dump size. */ | /* Calculate dump size. */ | ||||
dumpsize = ptesize; | dumpsize = ptesize; | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | cpu_minidumpsys(struct dumperinfo *di, const struct minidumpstate *state) | ||||
/* Dump bitmap */ | /* Dump bitmap */ | ||||
error = blk_write(di, (char *)vm_page_dump, 0, | error = blk_write(di, (char *)vm_page_dump, 0, | ||||
round_page(BITSET_SIZE(vm_page_dump_pages))); | round_page(BITSET_SIZE(vm_page_dump_pages))); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
/* Dump kernel page table pages */ | /* Dump kernel page table pages */ | ||||
addr = dumpbuf; | addr = dumpbuf; | ||||
for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) { | for (va = KERNBASE; va < kva_end; va += PAGE_SIZE) { | ||||
pmap_dump_kextract(va, (pt2_entry_t *)addr); | pmap_dump_kextract(va, (pt2_entry_t *)addr); | ||||
addr += sizeof(pt2_entry_t); | addr += sizeof(pt2_entry_t); | ||||
if (addr == dumpbuf + sizeof(dumpbuf)) { | if (addr == dumpbuf + sizeof(dumpbuf)) { | ||||
error = blk_write(di, dumpbuf, 0, sizeof(dumpbuf)); | error = blk_write(di, dumpbuf, 0, sizeof(dumpbuf)); | ||||
if (error != 0) | if (error != 0) | ||||
goto fail; | goto fail; | ||||
addr = dumpbuf; | addr = dumpbuf; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |