From owner-svn-src-head@FreeBSD.ORG Thu Apr 25 00:39:43 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 98BBEFD2; Thu, 25 Apr 2013 00:39:43 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 89043163E; Thu, 25 Apr 2013 00:39:43 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3P0dhg3001898; Thu, 25 Apr 2013 00:39:43 GMT (envelope-from jhibbits@svn.freebsd.org) Received: (from jhibbits@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3P0dhG1001897; Thu, 25 Apr 2013 00:39:43 GMT (envelope-from jhibbits@svn.freebsd.org) Message-Id: <201304250039.r3P0dhG1001897@svn.freebsd.org> From: Justin Hibbits Date: Thu, 25 Apr 2013 00:39:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r249864 - head/sys/powerpc/aim X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Apr 2013 00:39:43 -0000 Author: jhibbits Date: Thu Apr 25 00:39:43 2013 New Revision: 249864 URL: http://svnweb.freebsd.org/changeset/base/249864 Log: Introduce kernel coredumps to ppc32 AIM. Leeched from the booke code. MFC after: 2 weeks Modified: head/sys/powerpc/aim/mmu_oea.c Modified: head/sys/powerpc/aim/mmu_oea.c ============================================================================== --- head/sys/powerpc/aim/mmu_oea.c Wed Apr 24 23:38:04 2013 (r249863) +++ head/sys/powerpc/aim/mmu_oea.c Thu Apr 25 00:39:43 2013 (r249864) @@ -167,6 +167,11 @@ struct ofw_map { u_int om_mode; }; +extern unsigned char _etext[]; +extern unsigned char _end[]; + +extern int dumpsys_minidump; + /* * Map of physical memory regions. */ @@ -316,6 +321,9 @@ void moea_kenter(mmu_t, vm_offset_t, vm_ void moea_page_set_memattr(mmu_t mmu, vm_page_t m, vm_memattr_t ma); boolean_t moea_dev_direct_mapped(mmu_t, vm_paddr_t, vm_size_t); static void moea_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t); +vm_offset_t moea_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs, + vm_size_t *sz); +struct pmap_md * moea_scan_md(mmu_t mmu, struct pmap_md *prev); static mmu_method_t moea_methods[] = { MMUMETHOD(mmu_change_wiring, moea_change_wiring), @@ -363,6 +371,8 @@ static mmu_method_t moea_methods[] = { MMUMETHOD(mmu_kenter, moea_kenter), MMUMETHOD(mmu_kenter_attr, moea_kenter_attr), MMUMETHOD(mmu_dev_direct_mapped,moea_dev_direct_mapped), + MMUMETHOD(mmu_scan_md, moea_scan_md), + MMUMETHOD(mmu_dumpsys_map, moea_dumpsys_map), { 0, 0 } }; @@ -2567,3 +2577,104 @@ moea_sync_icache(mmu_t mmu, pmap_t pm, v } PMAP_UNLOCK(pm); } + +vm_offset_t +moea_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs, + vm_size_t *sz) +{ + if (md->md_vaddr == ~0UL) + return (md->md_paddr + ofs); + else + return (md->md_vaddr + ofs); +} + +/* TODO: Run this on minbar, single calls, to check addresses, offsets, and + * sizes. It should be doing more than just single pages. + */ +struct pmap_md * +moea_scan_md(mmu_t mmu, struct pmap_md *prev) +{ + static struct pmap_md md; + struct pvo_entry *pvo; + vm_offset_t va; + + if (dumpsys_minidump) { + md.md_paddr = ~0UL; /* Minidumps use virtual addresses. */ + if (prev == NULL) { + /* 1st: kernel .data and .bss. */ + md.md_index = 1; + md.md_vaddr = trunc_page((uintptr_t)_etext); + md.md_size = round_page((uintptr_t)_end) - md.md_vaddr; + return (&md); + } + switch (prev->md_index) { + case 1: + /* 2nd: msgbuf and tables (see pmap_bootstrap()). */ + md.md_index = 2; + md.md_vaddr = (vm_offset_t)msgbufp->msg_ptr; + md.md_size = round_page(msgbufp->msg_size); + break; + case 2: + /* 3rd: kernel VM. */ + va = prev->md_vaddr + prev->md_size; + /* Find start of next chunk (from va). */ + while (va < virtual_end) { + /* Don't dump the buffer cache. */ + if (va >= kmi.buffer_sva && + va < kmi.buffer_eva) { + va = kmi.buffer_eva; + continue; + } + pvo = moea_pvo_find_va(kernel_pmap, + va & ~ADDR_POFF, NULL); + if (pvo != NULL && + (pvo->pvo_pte.pte.pte_hi & PTE_VALID)) + break; + va += PAGE_SIZE; + } + if (va < virtual_end) { + md.md_vaddr = va; + va += PAGE_SIZE; + /* Find last page in chunk. */ + while (va < virtual_end) { + /* Don't run into the buffer cache. */ + if (va == kmi.buffer_sva) + break; + pvo = moea_pvo_find_va(kernel_pmap, + va & ~ADDR_POFF, NULL); + if (pvo == NULL || + !(pvo->pvo_pte.pte.pte_hi & PTE_VALID)) + break; + va += PAGE_SIZE; + } + md.md_size = va - md.md_vaddr; + break; + } + md.md_index = 3; + /* FALLTHROUGH */ + default: + return (NULL); + } + } else { /* minidumps */ + mem_regions(&pregions, &pregions_sz, + ®ions, ®ions_sz); + + if (prev == NULL) { + /* first physical chunk. */ + md.md_paddr = pregions[0].mr_start; + md.md_size = pregions[0].mr_size; + md.md_vaddr = ~0UL; + md.md_index = 1; + } else if (md.md_index < pregions_sz) { + md.md_paddr = pregions[md.md_index].mr_start; + md.md_size = pregions[md.md_index].mr_size; + md.md_vaddr = ~0UL; + md.md_index++; + } else { + /* There's no next physical chunk. */ + return (NULL); + } + } + + return (&md); +}