Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/arm/minidump_machdep.c
Show First 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | #endif | ||||
if (c != -1) | if (c != -1) | ||||
printf(" (CTRL-C to abort) "); | printf(" (CTRL-C to abort) "); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
/* A buffer for general use. Its size must be one page at least. */ | /* A buffer for general use. Its size must be one page at least. */ | ||||
static char dumpbuf[PAGE_SIZE]; | static char dumpbuf[PAGE_SIZE] __aligned(sizeof(uint64_t)); | ||||
CTASSERT(sizeof(dumpbuf) % sizeof(pt2_entry_t) == 0); | CTASSERT(sizeof(dumpbuf) % sizeof(pt2_entry_t) == 0); | ||||
int | int | ||||
minidumpsys(struct dumperinfo *di) | minidumpsys(struct dumperinfo *di) | ||||
{ | { | ||||
struct minidumphdr mdhdr; | struct minidumphdr mdhdr; | ||||
uint64_t dumpsize; | 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; | ||||
int error; | 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 | ||||
Show All 10 Lines | for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) { | ||||
if (pa != 0 && is_dumpable(pa)) | if (pa != 0 && 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; | ||||
dumpsize += round_page(msgbufp->msg_size); | dumpsize += round_page(msgbufp->msg_size); | ||||
dumpsize += round_page(sizeof(dump_avail)); | dumpsize += round_page(nitems(dump_avail) * sizeof(uint64_t)); | ||||
dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages)); | dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages)); | ||||
VM_PAGE_DUMP_FOREACH(pa) { | VM_PAGE_DUMP_FOREACH(pa) { | ||||
/* Clear out undumpable pages now if needed */ | /* Clear out undumpable pages now if needed */ | ||||
if (is_dumpable(pa)) | if (is_dumpable(pa)) | ||||
dumpsize += PAGE_SIZE; | dumpsize += PAGE_SIZE; | ||||
else | else | ||||
dump_drop_page(pa); | dump_drop_page(pa); | ||||
} | } | ||||
dumpsize += PAGE_SIZE; | dumpsize += PAGE_SIZE; | ||||
progress = dumpsize; | progress = dumpsize; | ||||
/* Initialize mdhdr */ | /* Initialize mdhdr */ | ||||
bzero(&mdhdr, sizeof(mdhdr)); | bzero(&mdhdr, sizeof(mdhdr)); | ||||
strcpy(mdhdr.magic, MINIDUMP_MAGIC); | strcpy(mdhdr.magic, MINIDUMP_MAGIC); | ||||
mdhdr.version = MINIDUMP_VERSION; | mdhdr.version = MINIDUMP_VERSION; | ||||
mdhdr.msgbufsize = msgbufp->msg_size; | mdhdr.msgbufsize = msgbufp->msg_size; | ||||
mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages)); | mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages)); | ||||
mdhdr.ptesize = ptesize; | mdhdr.ptesize = ptesize; | ||||
mdhdr.kernbase = KERNBASE; | mdhdr.kernbase = KERNBASE; | ||||
mdhdr.arch = __ARM_ARCH; | mdhdr.arch = __ARM_ARCH; | ||||
mdhdr.mmuformat = MINIDUMP_MMU_FORMAT_V6; | mdhdr.mmuformat = MINIDUMP_MMU_FORMAT_V6; | ||||
mdhdr.dumpavailsize = round_page(sizeof(dump_avail)); | mdhdr.dumpavailsize = round_page(nitems(dump_avail) * sizeof(uint64_t)); | ||||
dump_init_header(di, &kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, | dump_init_header(di, &kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, | ||||
dumpsize); | dumpsize); | ||||
error = dump_start(di, &kdh); | error = dump_start(di, &kdh); | ||||
if (error != 0) | if (error != 0) | ||||
goto fail; | goto fail; | ||||
printf("Physical memory: %u MB\n", ptoa((uintmax_t)physmem) / 1048576); | printf("Physical memory: %u MB\n", ptoa((uintmax_t)physmem) / 1048576); | ||||
printf("Dumping %llu MB:", (long long)dumpsize >> 20); | printf("Dumping %llu MB:", (long long)dumpsize >> 20); | ||||
/* Dump my header */ | /* Dump my header */ | ||||
bzero(dumpbuf, sizeof(dumpbuf)); | bzero(dumpbuf, sizeof(dumpbuf)); | ||||
bcopy(&mdhdr, dumpbuf, sizeof(mdhdr)); | bcopy(&mdhdr, dumpbuf, sizeof(mdhdr)); | ||||
error = blk_write(di, dumpbuf, 0, PAGE_SIZE); | error = blk_write(di, dumpbuf, 0, PAGE_SIZE); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
/* Dump msgbuf up front */ | /* Dump msgbuf up front */ | ||||
error = blk_write(di, (char *)msgbufp->msg_ptr, 0, | error = blk_write(di, (char *)msgbufp->msg_ptr, 0, | ||||
round_page(msgbufp->msg_size)); | round_page(msgbufp->msg_size)); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
/* Dump dump_avail */ | /* Dump dump_avail. Make a copy using 64-bit physical addresses. */ | ||||
_Static_assert(sizeof(dump_avail) <= sizeof(dumpbuf), | _Static_assert(nitems(dump_avail) * sizeof(uint64_t) <= sizeof(dumpbuf), | ||||
"Large dump_avail not handled"); | "Large dump_avail not handled"); | ||||
bzero(dumpbuf, sizeof(dumpbuf)); | bzero(dumpbuf, sizeof(dumpbuf)); | ||||
memcpy(dumpbuf, dump_avail, sizeof(dump_avail)); | dump_avail_buf = (uint64_t *)dumpbuf; | ||||
for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) { | |||||
dump_avail_buf[i] = dump_avail[i]; | |||||
dump_avail_buf[i + 1] = dump_avail[i + 1]; | |||||
} | |||||
error = blk_write(di, dumpbuf, 0, PAGE_SIZE); | error = blk_write(di, dumpbuf, 0, PAGE_SIZE); | ||||
if (error) | if (error) | ||||
goto fail; | goto fail; | ||||
/* 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) | ||||
▲ Show 20 Lines • Show All 70 Lines • Show Last 20 Lines |