Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/aim/mmu_oea64.c
Show First 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
* correct. | * correct. | ||||
*/ | */ | ||||
#include "opt_compat.h" | #include "opt_compat.h" | ||||
#include "opt_kstack_pages.h" | #include "opt_kstack_pages.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/conf.h> | |||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/cpuset.h> | #include <sys/cpuset.h> | ||||
#include <sys/ktr.h> | #include <sys/ktr.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/msgbuf.h> | #include <sys/msgbuf.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | struct ofw_map { | ||||
cell_t om_len; | cell_t om_len; | ||||
uint64_t om_pa; | uint64_t om_pa; | ||||
cell_t om_mode; | cell_t om_mode; | ||||
}; | }; | ||||
extern unsigned char _etext[]; | extern unsigned char _etext[]; | ||||
extern unsigned char _end[]; | extern unsigned char _end[]; | ||||
extern int dumpsys_minidump; | |||||
/* | /* | ||||
* Map of physical memory regions. | * Map of physical memory regions. | ||||
*/ | */ | ||||
static struct mem_region *regions; | static struct mem_region *regions; | ||||
static struct mem_region *pregions; | static struct mem_region *pregions; | ||||
static u_int phys_avail_count; | static u_int phys_avail_count; | ||||
static int regions_sz, pregions_sz; | static int regions_sz, pregions_sz; | ||||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | |||||
void *moea64_mapdev_attr(mmu_t, vm_offset_t, vm_size_t, vm_memattr_t); | void *moea64_mapdev_attr(mmu_t, vm_offset_t, vm_size_t, vm_memattr_t); | ||||
void moea64_unmapdev(mmu_t, vm_offset_t, vm_size_t); | void moea64_unmapdev(mmu_t, vm_offset_t, vm_size_t); | ||||
vm_paddr_t moea64_kextract(mmu_t, vm_offset_t); | vm_paddr_t moea64_kextract(mmu_t, vm_offset_t); | ||||
void moea64_page_set_memattr(mmu_t, vm_page_t m, vm_memattr_t ma); | void moea64_page_set_memattr(mmu_t, vm_page_t m, vm_memattr_t ma); | ||||
void moea64_kenter_attr(mmu_t, vm_offset_t, vm_offset_t, vm_memattr_t ma); | void moea64_kenter_attr(mmu_t, vm_offset_t, vm_offset_t, vm_memattr_t ma); | ||||
void moea64_kenter(mmu_t, vm_offset_t, vm_paddr_t); | void moea64_kenter(mmu_t, vm_offset_t, vm_paddr_t); | ||||
boolean_t moea64_dev_direct_mapped(mmu_t, vm_paddr_t, vm_size_t); | boolean_t moea64_dev_direct_mapped(mmu_t, vm_paddr_t, vm_size_t); | ||||
static void moea64_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t); | static void moea64_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t); | ||||
vm_offset_t moea64_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs, | void moea64_dumpsys_map(mmu_t mmu, vm_paddr_t pa, size_t sz, | ||||
vm_size_t *sz); | void **va); | ||||
struct pmap_md * moea64_scan_md(mmu_t mmu, struct pmap_md *prev); | void moea64_scan_init(mmu_t mmu); | ||||
static mmu_method_t moea64_methods[] = { | static mmu_method_t moea64_methods[] = { | ||||
MMUMETHOD(mmu_clear_modify, moea64_clear_modify), | MMUMETHOD(mmu_clear_modify, moea64_clear_modify), | ||||
MMUMETHOD(mmu_copy_page, moea64_copy_page), | MMUMETHOD(mmu_copy_page, moea64_copy_page), | ||||
MMUMETHOD(mmu_copy_pages, moea64_copy_pages), | MMUMETHOD(mmu_copy_pages, moea64_copy_pages), | ||||
MMUMETHOD(mmu_enter, moea64_enter), | MMUMETHOD(mmu_enter, moea64_enter), | ||||
MMUMETHOD(mmu_enter_object, moea64_enter_object), | MMUMETHOD(mmu_enter_object, moea64_enter_object), | ||||
MMUMETHOD(mmu_enter_quick, moea64_enter_quick), | MMUMETHOD(mmu_enter_quick, moea64_enter_quick), | ||||
Show All 29 Lines | static mmu_method_t moea64_methods[] = { | ||||
/* Internal interfaces */ | /* Internal interfaces */ | ||||
MMUMETHOD(mmu_mapdev, moea64_mapdev), | MMUMETHOD(mmu_mapdev, moea64_mapdev), | ||||
MMUMETHOD(mmu_mapdev_attr, moea64_mapdev_attr), | MMUMETHOD(mmu_mapdev_attr, moea64_mapdev_attr), | ||||
MMUMETHOD(mmu_unmapdev, moea64_unmapdev), | MMUMETHOD(mmu_unmapdev, moea64_unmapdev), | ||||
MMUMETHOD(mmu_kextract, moea64_kextract), | MMUMETHOD(mmu_kextract, moea64_kextract), | ||||
MMUMETHOD(mmu_kenter, moea64_kenter), | MMUMETHOD(mmu_kenter, moea64_kenter), | ||||
MMUMETHOD(mmu_kenter_attr, moea64_kenter_attr), | MMUMETHOD(mmu_kenter_attr, moea64_kenter_attr), | ||||
MMUMETHOD(mmu_dev_direct_mapped,moea64_dev_direct_mapped), | MMUMETHOD(mmu_dev_direct_mapped,moea64_dev_direct_mapped), | ||||
MMUMETHOD(mmu_scan_md, moea64_scan_md), | MMUMETHOD(mmu_scan_init, moea64_scan_init), | ||||
MMUMETHOD(mmu_dumpsys_map, moea64_dumpsys_map), | MMUMETHOD(mmu_dumpsys_map, moea64_dumpsys_map), | ||||
{ 0, 0 } | { 0, 0 } | ||||
}; | }; | ||||
MMU_DEF(oea64_mmu, "mmu_oea64_base", moea64_methods, 0); | MMU_DEF(oea64_mmu, "mmu_oea64_base", moea64_methods, 0); | ||||
static __inline u_int | static __inline u_int | ||||
▲ Show 20 Lines • Show All 2,220 Lines • ▼ Show 20 Lines | if (pvo != NULL && !(pvo->pvo_pte.lpte.pte_lo & LPTE_I)) { | ||||
moea64_syncicache(mmu, pm, va, pa, len); | moea64_syncicache(mmu, pm, va, pa, len); | ||||
} | } | ||||
va += len; | va += len; | ||||
sz -= len; | sz -= len; | ||||
} | } | ||||
PMAP_UNLOCK(pm); | PMAP_UNLOCK(pm); | ||||
} | } | ||||
vm_offset_t | void | ||||
moea64_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs, | moea64_dumpsys_map(mmu_t mmu, vm_paddr_t pa, size_t sz, void **va) | ||||
vm_size_t *sz) | |||||
{ | { | ||||
if (md->md_vaddr == ~0UL) | |||||
return (md->md_paddr + ofs); | *va = (void *)pa; | ||||
else | |||||
return (md->md_vaddr + ofs); | |||||
} | } | ||||
struct pmap_md * | extern struct md_pa dump_map[PHYS_AVAIL_SZ + 1]; | ||||
moea64_scan_md(mmu_t mmu, struct pmap_md *prev) | |||||
void | |||||
moea64_scan_init(mmu_t mmu) | |||||
{ | { | ||||
static struct pmap_md md; | |||||
struct pvo_entry *pvo; | struct pvo_entry *pvo; | ||||
vm_offset_t va; | vm_offset_t va; | ||||
int i; | |||||
if (dumpsys_minidump) { | if (!do_minidump) { | ||||
md.md_paddr = ~0UL; /* Minidumps use virtual addresses. */ | /* Initialize phys. segments for dumpsys(). */ | ||||
if (prev == NULL) { | memset(&dump_map, 0, sizeof(dump_map)); | ||||
/* 1st: kernel .data and .bss. */ | mem_regions(&pregions, &pregions_sz, ®ions, ®ions_sz); | ||||
md.md_index = 1; | for (i = 0; i < pregions_sz; i++) { | ||||
md.md_vaddr = trunc_page((uintptr_t)_etext); | dump_map[i].md_start = pregions[i].mr_start; | ||||
md.md_size = round_page((uintptr_t)_end) - md.md_vaddr; | dump_map[i].md_size = pregions[i].mr_size; | ||||
return (&md); | |||||
} | } | ||||
switch (prev->md_index) { | return; | ||||
case 1: | } | ||||
/* Virtual segments for minidumps: */ | |||||
memset(&dump_map, 0, sizeof(dump_map)); | |||||
/* 1st: kernel .data and .bss. */ | |||||
dump_map[0].md_start = trunc_page((uintptr_t)_etext); | |||||
dump_map[0].md_size = round_page((uintptr_t)_end) - dump_map[0].md_start; | |||||
/* 2nd: msgbuf and tables (see pmap_bootstrap()). */ | /* 2nd: msgbuf and tables (see pmap_bootstrap()). */ | ||||
md.md_index = 2; | dump_map[1].md_start = (vm_paddr_t)msgbufp->msg_ptr; | ||||
md.md_vaddr = (vm_offset_t)msgbufp->msg_ptr; | dump_map[1].md_size = round_page(msgbufp->msg_size); | ||||
md.md_size = round_page(msgbufp->msg_size); | |||||
break; | |||||
case 2: | |||||
/* 3rd: kernel VM. */ | /* 3rd: kernel VM. */ | ||||
va = prev->md_vaddr + prev->md_size; | va = dump_map[1].md_start + dump_map[1].md_size; | ||||
/* Find start of next chunk (from va). */ | /* Find start of next chunk (from va). */ | ||||
while (va < virtual_end) { | while (va < virtual_end) { | ||||
/* Don't dump the buffer cache. */ | /* Don't dump the buffer cache. */ | ||||
if (va >= kmi.buffer_sva && | if (va >= kmi.buffer_sva && va < kmi.buffer_eva) { | ||||
va < kmi.buffer_eva) { | |||||
va = kmi.buffer_eva; | va = kmi.buffer_eva; | ||||
continue; | continue; | ||||
} | } | ||||
pvo = moea64_pvo_find_va(kernel_pmap, | pvo = moea64_pvo_find_va(kernel_pmap, va & ~ADDR_POFF); | ||||
va & ~ADDR_POFF); | if (pvo != NULL && (pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) | ||||
if (pvo != NULL && | |||||
(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) | |||||
break; | break; | ||||
va += PAGE_SIZE; | va += PAGE_SIZE; | ||||
} | } | ||||
if (va < virtual_end) { | if (va < virtual_end) { | ||||
md.md_vaddr = va; | dump_map[2].md_start = va; | ||||
va += PAGE_SIZE; | va += PAGE_SIZE; | ||||
/* Find last page in chunk. */ | /* Find last page in chunk. */ | ||||
while (va < virtual_end) { | while (va < virtual_end) { | ||||
/* Don't run into the buffer cache. */ | /* Don't run into the buffer cache. */ | ||||
if (va == kmi.buffer_sva) | if (va == kmi.buffer_sva) | ||||
break; | break; | ||||
pvo = moea64_pvo_find_va(kernel_pmap, | pvo = moea64_pvo_find_va(kernel_pmap, va & ~ADDR_POFF); | ||||
va & ~ADDR_POFF); | |||||
if (pvo == NULL || | if (pvo == NULL || | ||||
!(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) | !(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) | ||||
break; | break; | ||||
va += PAGE_SIZE; | va += PAGE_SIZE; | ||||
} | } | ||||
md.md_size = va - md.md_vaddr; | dump_map[2].md_size = va - dump_map[2].md_start; | ||||
break; | |||||
} | } | ||||
md.md_index = 3; | |||||
/* FALLTHROUGH */ | |||||
default: | |||||
return (NULL); | |||||
} | |||||
} else { /* minidumps */ | |||||
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); | |||||
} | } |