Index: sys/powerpc/aim/mmu_oea64.c =================================================================== --- sys/powerpc/aim/mmu_oea64.c +++ sys/powerpc/aim/mmu_oea64.c @@ -695,12 +695,27 @@ unmapped_buf_allowed = hw_direct_map; } +/* Quick sort callout for comparing physical addresses. */ +static int +pa_cmp(const void *a, const void *b) +{ + const vm_paddr_t *pa = a, *pb = b; + + if (*pa < *pb) + return (-1); + else if (*pa > *pb) + return (1); + else + return (0); +} + void moea64_early_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) { int i, j; vm_size_t physsz, hwphyssz; vm_paddr_t kernelphysstart, kernelphysend; + int rm_pavail; #ifndef __powerpc64__ /* We don't have a direct map since there is no BAT */ @@ -763,10 +778,18 @@ } /* Check for overlap with the kernel and exception vectors */ + rm_pavail = 0; for (j = 0; j < 2*phys_avail_count; j+=2) { if (phys_avail[j] < EXC_LAST) phys_avail[j] += EXC_LAST; + if (phys_avail[j] >= kernelphysstart && + phys_avail[j+1] <= kernelphysend) { + phys_avail[j] = phys_avail[j+1] = ~0; + rm_pavail++; + continue; + } + if (kernelphysstart >= phys_avail[j] && kernelphysstart < phys_avail[j+1]) { if (kernelphysend < phys_avail[j+1]) { @@ -794,6 +817,16 @@ } } + /* Remove physical available regions marked for removal (~0) */ + if (rm_pavail) { + qsort(phys_avail, 2*phys_avail_count, sizeof(phys_avail[0]), + pa_cmp); + phys_avail_count -= rm_pavail; + for (i = 2*phys_avail_count; + i < 2*(phys_avail_count + rm_pavail); i+=2) + phys_avail[i] = phys_avail[i+1] = 0; + } + physmem = btoc(physsz); #ifdef PTEGCOUNT