Lines 50-59
Link Here
|
50 |
|
50 |
|
51 |
#include <sys/cdefs.h> |
51 |
#include <sys/cdefs.h> |
52 |
__FBSDID("$FreeBSD$"); |
52 |
__FBSDID("$FreeBSD$"); |
53 |
|
53 |
|
54 |
#include <sys/param.h> |
54 |
#include <sys/param.h> |
|
|
55 |
#include <sys/conf.h> |
55 |
#include <sys/malloc.h> |
56 |
#include <sys/malloc.h> |
56 |
#include <sys/ktr.h> |
57 |
#include <sys/ktr.h> |
57 |
#include <sys/proc.h> |
58 |
#include <sys/proc.h> |
58 |
#include <sys/user.h> |
59 |
#include <sys/user.h> |
59 |
#include <sys/queue.h> |
60 |
#include <sys/queue.h> |
Lines 98-109
__FBSDID("$FreeBSD$");
Link Here
|
98 |
#define debugf(fmt, args...) |
99 |
#define debugf(fmt, args...) |
99 |
#endif |
100 |
#endif |
100 |
|
101 |
|
101 |
#define TODO panic("%s: not implemented", __func__); |
102 |
#define TODO panic("%s: not implemented", __func__); |
102 |
|
103 |
|
103 |
extern int dumpsys_minidump; |
|
|
104 |
|
105 |
extern unsigned char _etext[]; |
104 |
extern unsigned char _etext[]; |
106 |
extern unsigned char _end[]; |
105 |
extern unsigned char _end[]; |
107 |
|
106 |
|
108 |
extern uint32_t *bootinfo; |
107 |
extern uint32_t *bootinfo; |
109 |
|
108 |
|
Lines 320-334
static void mmu_booke_kenter(mmu_t, vm_offset_t, vm_paddr_t);
Link Here
|
320 |
static void mmu_booke_kenter_attr(mmu_t, vm_offset_t, vm_paddr_t, vm_memattr_t); |
319 |
static void mmu_booke_kenter_attr(mmu_t, vm_offset_t, vm_paddr_t, vm_memattr_t); |
321 |
static void mmu_booke_kremove(mmu_t, vm_offset_t); |
320 |
static void mmu_booke_kremove(mmu_t, vm_offset_t); |
322 |
static boolean_t mmu_booke_dev_direct_mapped(mmu_t, vm_paddr_t, vm_size_t); |
321 |
static boolean_t mmu_booke_dev_direct_mapped(mmu_t, vm_paddr_t, vm_size_t); |
323 |
static void mmu_booke_sync_icache(mmu_t, pmap_t, vm_offset_t, |
322 |
static void mmu_booke_sync_icache(mmu_t, pmap_t, vm_offset_t, |
324 |
vm_size_t); |
323 |
vm_size_t); |
325 |
static vm_offset_t mmu_booke_dumpsys_map(mmu_t, struct pmap_md *, |
324 |
static void mmu_booke_dumpsys_map(mmu_t, vm_paddr_t pa, size_t, |
326 |
vm_size_t, vm_size_t *); |
325 |
void **); |
327 |
static void mmu_booke_dumpsys_unmap(mmu_t, struct pmap_md *, |
326 |
static void mmu_booke_dumpsys_unmap(mmu_t, vm_paddr_t pa, size_t, |
328 |
vm_size_t, vm_offset_t); |
327 |
void *); |
329 |
static struct pmap_md *mmu_booke_scan_md(mmu_t, struct pmap_md *); |
328 |
static void mmu_booke_scan_init(mmu_t); |
|
|
329 |
static struct md_pa *mmu_booke_scan_md(mmu_t, struct md_pa *); |
330 |
|
330 |
|
331 |
static mmu_method_t mmu_booke_methods[] = { |
331 |
static mmu_method_t mmu_booke_methods[] = { |
332 |
/* pmap dispatcher interface */ |
332 |
/* pmap dispatcher interface */ |
333 |
MMUMETHOD(mmu_clear_modify, mmu_booke_clear_modify), |
333 |
MMUMETHOD(mmu_clear_modify, mmu_booke_clear_modify), |
334 |
MMUMETHOD(mmu_copy, mmu_booke_copy), |
334 |
MMUMETHOD(mmu_copy, mmu_booke_copy), |
Lines 379-388
static mmu_method_t mmu_booke_methods[] = {
Link Here
|
379 |
MMUMETHOD(mmu_unmapdev, mmu_booke_unmapdev), |
379 |
MMUMETHOD(mmu_unmapdev, mmu_booke_unmapdev), |
380 |
|
380 |
|
381 |
/* dumpsys() support */ |
381 |
/* dumpsys() support */ |
382 |
MMUMETHOD(mmu_dumpsys_map, mmu_booke_dumpsys_map), |
382 |
MMUMETHOD(mmu_dumpsys_map, mmu_booke_dumpsys_map), |
383 |
MMUMETHOD(mmu_dumpsys_unmap, mmu_booke_dumpsys_unmap), |
383 |
MMUMETHOD(mmu_dumpsys_unmap, mmu_booke_dumpsys_unmap), |
|
|
384 |
MMUMETHOD(mmu_scan_init, mmu_booke_scan_init), |
384 |
MMUMETHOD(mmu_scan_md, mmu_booke_scan_md), |
385 |
MMUMETHOD(mmu_scan_md, mmu_booke_scan_md), |
385 |
|
386 |
|
386 |
{ 0, 0 } |
387 |
{ 0, 0 } |
387 |
}; |
388 |
}; |
388 |
|
389 |
|
Lines 2532-2674
mmu_booke_dev_direct_mapped(mmu_t mmu, vm_paddr_t pa, vm_size_t size)
Link Here
|
2532 |
} |
2533 |
} |
2533 |
|
2534 |
|
2534 |
return (EFAULT); |
2535 |
return (EFAULT); |
2535 |
} |
2536 |
} |
2536 |
|
2537 |
|
2537 |
vm_offset_t |
2538 |
void |
2538 |
mmu_booke_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs, |
2539 |
mmu_booke_dumpsys_map(mmu_t mmu, vm_paddr_t pa, size_t sz, void **va) |
2539 |
vm_size_t *sz) |
|
|
2540 |
{ |
2540 |
{ |
2541 |
vm_paddr_t pa, ppa; |
2541 |
vm_paddr_t ppa; |
2542 |
vm_offset_t va; |
2542 |
vm_offset_t ofs; |
2543 |
vm_size_t gran; |
2543 |
vm_size_t gran; |
2544 |
|
2544 |
|
2545 |
/* Raw physical memory dumps don't have a virtual address. */ |
|
|
2546 |
if (md->md_vaddr == ~0UL) { |
2547 |
/* We always map a 256MB page at 256M. */ |
2548 |
gran = 256 * 1024 * 1024; |
2549 |
pa = md->md_paddr + ofs; |
2550 |
ppa = pa & ~(gran - 1); |
2551 |
ofs = pa - ppa; |
2552 |
va = gran; |
2553 |
tlb1_set_entry(va, ppa, gran, _TLB_ENTRY_IO); |
2554 |
if (*sz > (gran - ofs)) |
2555 |
*sz = gran - ofs; |
2556 |
return (va + ofs); |
2557 |
} |
2558 |
|
2559 |
/* Minidumps are based on virtual memory addresses. */ |
2545 |
/* Minidumps are based on virtual memory addresses. */ |
2560 |
va = md->md_vaddr + ofs; |
2546 |
if (do_minidump) { |
2561 |
if (va >= kernstart + kernsize) { |
2547 |
*va = (void *)pa; |
2562 |
gran = PAGE_SIZE - (va & PAGE_MASK); |
2548 |
return; |
2563 |
if (*sz > gran) |
|
|
2564 |
*sz = gran; |
2565 |
} |
2549 |
} |
2566 |
return (va); |
2550 |
|
|
|
2551 |
/* Raw physical memory dumps don't have a virtual address. */ |
2552 |
/* We always map a 256MB page at 256M. */ |
2553 |
gran = 256 * 1024 * 1024; |
2554 |
ppa = pa & ~(gran - 1); |
2555 |
ofs = pa - ppa; |
2556 |
*va = (void *)gran; |
2557 |
tlb1_set_entry((vm_offset_t)va, ppa, gran, _TLB_ENTRY_IO); |
2558 |
|
2559 |
if (sz > (gran - ofs)) |
2560 |
tlb1_set_entry((vm_offset_t)(va + gran), ppa + gran, gran, |
2561 |
_TLB_ENTRY_IO); |
2567 |
} |
2562 |
} |
2568 |
|
2563 |
|
2569 |
void |
2564 |
void |
2570 |
mmu_booke_dumpsys_unmap(mmu_t mmu, struct pmap_md *md, vm_size_t ofs, |
2565 |
mmu_booke_dumpsys_unmap(mmu_t mmu, vm_paddr_t pa, size_t sz, void *va) |
2571 |
vm_offset_t va) |
|
|
2572 |
{ |
2566 |
{ |
|
|
2567 |
vm_paddr_t ppa; |
2568 |
vm_offset_t ofs; |
2569 |
vm_size_t gran; |
2570 |
|
2571 |
/* Minidumps are based on virtual memory addresses. */ |
2572 |
/* Nothing to do... */ |
2573 |
if (do_minidump) |
2574 |
return; |
2573 |
|
2575 |
|
2574 |
/* Raw physical memory dumps don't have a virtual address. */ |
2576 |
/* Raw physical memory dumps don't have a virtual address. */ |
2575 |
if (md->md_vaddr == ~0UL) { |
2577 |
tlb1_idx--; |
|
|
2578 |
tlb1[tlb1_idx].mas1 = 0; |
2579 |
tlb1[tlb1_idx].mas2 = 0; |
2580 |
tlb1[tlb1_idx].mas3 = 0; |
2581 |
tlb1_write_entry(tlb1_idx); |
2582 |
|
2583 |
gran = 256 * 1024 * 1024; |
2584 |
ppa = pa & ~(gran - 1); |
2585 |
ofs = pa - ppa; |
2586 |
if (sz > (gran - ofs)) { |
2576 |
tlb1_idx--; |
2587 |
tlb1_idx--; |
2577 |
tlb1[tlb1_idx].mas1 = 0; |
2588 |
tlb1[tlb1_idx].mas1 = 0; |
2578 |
tlb1[tlb1_idx].mas2 = 0; |
2589 |
tlb1[tlb1_idx].mas2 = 0; |
2579 |
tlb1[tlb1_idx].mas3 = 0; |
2590 |
tlb1[tlb1_idx].mas3 = 0; |
2580 |
tlb1_write_entry(tlb1_idx); |
2591 |
tlb1_write_entry(tlb1_idx); |
2581 |
return; |
|
|
2582 |
} |
2592 |
} |
2583 |
|
|
|
2584 |
/* Minidumps are based on virtual memory addresses. */ |
2585 |
/* Nothing to do... */ |
2586 |
} |
2593 |
} |
2587 |
|
2594 |
|
2588 |
struct pmap_md * |
2595 |
extern struct md_pa dump_map[PHYS_AVAIL_SZ + 1]; |
2589 |
mmu_booke_scan_md(mmu_t mmu, struct pmap_md *prev) |
2596 |
static struct md_pa dump_vmap[4]; |
|
|
2597 |
|
2598 |
void |
2599 |
mmu_booke_scan_init(mmu_t mmu) |
2590 |
{ |
2600 |
{ |
2591 |
static struct pmap_md md; |
|
|
2592 |
pte_t *pte; |
2593 |
vm_offset_t va; |
2601 |
vm_offset_t va; |
2594 |
|
2602 |
pte_t *pte; |
2595 |
if (dumpsys_minidump) { |
2603 |
int i; |
2596 |
md.md_paddr = ~0UL; /* Minidumps use virtual addresses. */ |
2604 |
|
2597 |
if (prev == NULL) { |
2605 |
/* Initialize phys. segments for dumpsys(). */ |
2598 |
/* 1st: kernel .data and .bss. */ |
2606 |
memset(&dump_map, 0, sizeof(dump_map)); |
2599 |
md.md_index = 1; |
2607 |
mem_regions(&physmem_regions, &physmem_regions_sz, &availmem_regions, |
2600 |
md.md_vaddr = trunc_page((uintptr_t)_etext); |
2608 |
&availmem_regions_sz); |
2601 |
md.md_size = round_page((uintptr_t)_end) - md.md_vaddr; |
2609 |
for (i = 0; i < physmem_regions_sz; i++) { |
2602 |
return (&md); |
2610 |
dump_map[i].md_start = physmem_regions[i].mr_start; |
|
|
2611 |
dump_map[i].md_size = physmem_regions[i].mr_size; |
2612 |
} |
2613 |
|
2614 |
/* Virtual segments for minidumps: */ |
2615 |
memset(&dump_vmap, 0, sizeof(dump_vmap)); |
2616 |
|
2617 |
/* 1st: kernel .data and .bss. */ |
2618 |
dump_vmap[0].md_start = trunc_page((uintptr_t)_etext); |
2619 |
dump_vmap[0].md_size = round_page((uintptr_t)_end) - dump_vmap[0].md_start; |
2620 |
|
2621 |
/* 2nd: msgbuf and tables (see pmap_bootstrap()). */ |
2622 |
dump_vmap[1].md_start = data_start; |
2623 |
dump_vmap[1].md_size = data_end - data_start; |
2624 |
|
2625 |
/* 3rd: kernel VM. */ |
2626 |
va = dump_vmap[1].md_start + dump_vmap[1].md_size; |
2627 |
/* Find start of next chunk (from va). */ |
2628 |
while (va < virtual_end) { |
2629 |
/* Don't dump the buffer cache. */ |
2630 |
if (va >= kmi.buffer_sva && va < kmi.buffer_eva) { |
2631 |
va = kmi.buffer_eva; |
2632 |
continue; |
2603 |
} |
2633 |
} |
2604 |
switch (prev->md_index) { |
2634 |
pte = pte_find(mmu, kernel_pmap, va); |
2605 |
case 1: |
2635 |
if (pte != NULL && PTE_ISVALID(pte)) |
2606 |
/* 2nd: msgbuf and tables (see pmap_bootstrap()). */ |
|
|
2607 |
md.md_index = 2; |
2608 |
md.md_vaddr = data_start; |
2609 |
md.md_size = data_end - data_start; |
2610 |
break; |
2636 |
break; |
2611 |
case 2: |
2637 |
va += PAGE_SIZE; |
2612 |
/* 3rd: kernel VM. */ |
2638 |
} |
2613 |
va = prev->md_vaddr + prev->md_size; |
2639 |
if (va < virtual_end) { |
2614 |
/* Find start of next chunk (from va). */ |
2640 |
dump_vmap[2].md_start = va; |
2615 |
while (va < virtual_end) { |
2641 |
va += PAGE_SIZE; |
2616 |
/* Don't dump the buffer cache. */ |
2642 |
/* Find last page in chunk. */ |
2617 |
if (va >= kmi.buffer_sva && |
2643 |
while (va < virtual_end) { |
2618 |
va < kmi.buffer_eva) { |
2644 |
/* Don't run into the buffer cache. */ |
2619 |
va = kmi.buffer_eva; |
2645 |
if (va == kmi.buffer_sva) |
2620 |
continue; |
|
|
2621 |
} |
2622 |
pte = pte_find(mmu, kernel_pmap, va); |
2623 |
if (pte != NULL && PTE_ISVALID(pte)) |
2624 |
break; |
2625 |
va += PAGE_SIZE; |
2626 |
} |
2627 |
if (va < virtual_end) { |
2628 |
md.md_vaddr = va; |
2629 |
va += PAGE_SIZE; |
2630 |
/* Find last page in chunk. */ |
2631 |
while (va < virtual_end) { |
2632 |
/* Don't run into the buffer cache. */ |
2633 |
if (va == kmi.buffer_sva) |
2634 |
break; |
2635 |
pte = pte_find(mmu, kernel_pmap, va); |
2636 |
if (pte == NULL || !PTE_ISVALID(pte)) |
2637 |
break; |
2638 |
va += PAGE_SIZE; |
2639 |
} |
2640 |
md.md_size = va - md.md_vaddr; |
2641 |
break; |
2646 |
break; |
2642 |
} |
2647 |
pte = pte_find(mmu, kernel_pmap, va); |
2643 |
md.md_index = 3; |
2648 |
if (pte == NULL || !PTE_ISVALID(pte)) |
2644 |
/* FALLTHROUGH */ |
2649 |
break; |
2645 |
default: |
2650 |
va += PAGE_SIZE; |
2646 |
return (NULL); |
|
|
2647 |
} |
2648 |
} else { /* minidumps */ |
2649 |
mem_regions(&physmem_regions, &physmem_regions_sz, |
2650 |
&availmem_regions, &availmem_regions_sz); |
2651 |
|
2652 |
if (prev == NULL) { |
2653 |
/* first physical chunk. */ |
2654 |
md.md_paddr = physmem_regions[0].mr_start; |
2655 |
md.md_size = physmem_regions[0].mr_size; |
2656 |
md.md_vaddr = ~0UL; |
2657 |
md.md_index = 1; |
2658 |
} else if (md.md_index < physmem_regions_sz) { |
2659 |
md.md_paddr = physmem_regions[md.md_index].mr_start; |
2660 |
md.md_size = physmem_regions[md.md_index].mr_size; |
2661 |
md.md_vaddr = ~0UL; |
2662 |
md.md_index++; |
2663 |
} else { |
2664 |
/* There's no next physical chunk. */ |
2665 |
return (NULL); |
2666 |
} |
2651 |
} |
|
|
2652 |
dump_vmap[2].md_size = va - dump_vmap[2].md_start; |
2653 |
} |
2654 |
} |
2655 |
|
2656 |
struct md_pa * |
2657 |
mmu_booke_scan_md(mmu_t mmu, struct md_pa *prev) |
2658 |
{ |
2659 |
|
2660 |
if (prev == NULL) { |
2661 |
if (do_minidump) |
2662 |
return (&dump_vmap[0]); |
2663 |
else |
2664 |
return (&dump_map[0]); |
2667 |
} |
2665 |
} |
2668 |
|
2666 |
|
2669 |
return (&md); |
2667 |
prev++; |
|
|
2668 |
/* There's no next chunk. */ |
2669 |
if (prev->md_size == 0) |
2670 |
return (NULL); |
2671 |
return (prev); |
2670 |
} |
2672 |
} |
2671 |
|
2673 |
|
2672 |
/* |
2674 |
/* |
2673 |
* Map a set of physical memory pages into the kernel virtual address space. |
2675 |
* Map a set of physical memory pages into the kernel virtual address space. |
2674 |
* Return a pointer to where it is mapped. This routine is intended to be used |
2676 |
* Return a pointer to where it is mapped. This routine is intended to be used |