Index: stable/10/sys/ia64/ia64/physmem.c =================================================================== --- stable/10/sys/ia64/ia64/physmem.c (revision 310507) +++ stable/10/sys/ia64/ia64/physmem.c (revision 310508) @@ -1,258 +1,264 @@ /*- * Copyright (c) 2012 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include static u_int phys_avail_segs; vm_paddr_t phys_avail[2 * VM_PHYSSEG_MAX + 2]; vm_paddr_t paddr_max; - +long Maxmem; long realmem; static u_int ia64_physmem_find(vm_paddr_t base, vm_paddr_t lim) { u_int idx; for (idx = 0; phys_avail[idx + 1] != 0; idx += 2) { if (phys_avail[idx] >= lim || phys_avail[idx + 1] > base) break; } return (idx); } static int ia64_physmem_insert(u_int idx, vm_paddr_t base, vm_paddr_t lim) { u_int ridx; if (phys_avail_segs == VM_PHYSSEG_MAX) return (ENOMEM); ridx = phys_avail_segs * 2; while (idx < ridx) { phys_avail[ridx + 1] = phys_avail[ridx - 1]; phys_avail[ridx] = phys_avail[ridx - 2]; ridx -= 2; } phys_avail[idx] = base; phys_avail[idx + 1] = lim; phys_avail_segs++; return (0); } static int ia64_physmem_remove(u_int idx) { if (phys_avail_segs == 0) return (ENOENT); do { phys_avail[idx] = phys_avail[idx + 2]; phys_avail[idx + 1] = phys_avail[idx + 3]; idx += 2; } while (phys_avail[idx + 1] != 0); phys_avail_segs--; return (0); } int ia64_physmem_add(vm_paddr_t base, vm_size_t len) { vm_paddr_t lim; u_int idx; realmem += len; lim = base + len; idx = ia64_physmem_find(base, lim); if (phys_avail[idx] == lim) { phys_avail[idx] = base; return (0); } if (idx > 0 && phys_avail[idx - 1] == base) { phys_avail[idx - 1] = lim; return (0); } return (ia64_physmem_insert(idx, base, lim)); } int ia64_physmem_delete(vm_paddr_t base, vm_size_t len) { vm_paddr_t lim; u_int idx; lim = base + len; idx = ia64_physmem_find(base, lim); if (phys_avail[idx] >= lim || phys_avail[idx + 1] == 0) return (ENOENT); if (phys_avail[idx] < base && phys_avail[idx + 1] > lim) { len = phys_avail[idx + 1] - lim; phys_avail[idx + 1] = base; base = lim; lim = base + len; return (ia64_physmem_insert(idx + 2, base, lim)); } else { if (phys_avail[idx] == base) phys_avail[idx] = lim; if (phys_avail[idx + 1] == lim) phys_avail[idx + 1] = base; if (phys_avail[idx] >= phys_avail[idx + 1]) return (ia64_physmem_remove(idx)); } return (0); } int ia64_physmem_fini(void) { vm_paddr_t base, lim, size; u_int idx; idx = 0; while (phys_avail[idx + 1] != 0) { base = round_page(phys_avail[idx]); lim = trunc_page(phys_avail[idx + 1]); if (base < lim) { phys_avail[idx] = base; phys_avail[idx + 1] = lim; size = lim - base; physmem += atop(size); paddr_max = lim; idx += 2; } else ia64_physmem_remove(idx); } /* * Round realmem to a multple of 128MB. Hopefully that compensates * for any loss of DRAM that isn't accounted for in the memory map. * I'm thinking legacy BIOS or VGA here. In any case, it's ok if * we got it wrong, because we don't actually use realmem. It's * just for show... */ size = 1U << 27; realmem = (realmem + size - 1) & ~(size - 1); realmem = atop(realmem); + + /* + * Maxmem isn't the "maximum memory", it's one larger than the + * highest page of the physical address space. + */ + Maxmem = atop(paddr_max); return (0); } int ia64_physmem_init(void) { /* Nothing to do just yet. */ return (0); } int ia64_physmem_track(vm_paddr_t base, vm_size_t len) { realmem += len; return (0); } void * ia64_physmem_alloc(vm_size_t len, vm_size_t align) { vm_paddr_t base, lim, pa; void *ptr; u_int idx; if (phys_avail_segs == 0) return (NULL); len = round_page(len); /* * Try and allocate with least effort. */ idx = phys_avail_segs * 2; while (idx > 0) { idx -= 2; base = phys_avail[idx]; lim = phys_avail[idx + 1]; if (lim - base < len) continue; /* First try from the end. */ pa = lim - len; if ((pa & (align - 1)) == 0) { if (pa == base) ia64_physmem_remove(idx); else phys_avail[idx + 1] = pa; goto gotit; } /* Try from the start next. */ pa = base; if ((pa & (align - 1)) == 0) { if (pa + len == lim) ia64_physmem_remove(idx); else phys_avail[idx] += len; goto gotit; } } /* * Find a good segment and split it up. */ idx = phys_avail_segs * 2; while (idx > 0) { idx -= 2; base = phys_avail[idx]; lim = phys_avail[idx + 1]; pa = (base + align - 1) & ~(align - 1); if (pa + len <= lim) { ia64_physmem_delete(pa, len); goto gotit; } } /* Out of luck. */ return (NULL); gotit: ptr = (void *)IA64_PHYS_TO_RR7(pa); bzero(ptr, len); return (ptr); } Index: stable/10/sys/ia64/include/md_var.h =================================================================== --- stable/10/sys/ia64/include/md_var.h (revision 310507) +++ stable/10/sys/ia64/include/md_var.h (revision 310508) @@ -1,123 +1,124 @@ /*- * Copyright (c) 1998 Doug Rabson * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _MACHINE_MD_VAR_H_ #define _MACHINE_MD_VAR_H_ /* * Miscellaneous machine-dependent declarations. */ struct ia64_fdesc { uint64_t func; uint64_t gp; }; #define FDESC_FUNC(fn) (((struct ia64_fdesc *) fn)->func) #define FDESC_GP(fn) (((struct ia64_fdesc *) fn)->gp) /* Convenience macros to decompose CFM & ar.pfs. */ #define IA64_CFM_SOF(x) ((x) & 0x7f) #define IA64_CFM_SOL(x) (((x) >> 7) & 0x7f) #define IA64_CFM_SOR(x) (((x) >> 14) & 0x0f) #define IA64_CFM_RRB_GR(x) (((x) >> 18) & 0x7f) #define IA64_CFM_RRB_FR(x) (((x) >> 25) & 0x7f) #define IA64_CFM_RRB_PR(x) (((x) >> 32) & 0x3f) /* Convenience function (inline) to adjust backingstore pointers. */ static __inline uint64_t ia64_bsp_adjust(uint64_t bsp, int nslots) { int bias = ((unsigned int)bsp & 0x1f8) >> 3; nslots += (nslots + bias + 63*8) / 63 - 8; return bsp + (nslots << 3); } #ifdef _KERNEL struct _special; struct pcpu; struct thread; struct trapframe; /* * Return value from ia64_init. Describes stack to switch to. */ struct ia64_init_return { uint64_t bspstore; uint64_t sp; }; extern uint64_t ia64_lapic_addr; extern vm_paddr_t paddr_max; +extern long Maxmem; extern u_int busdma_swi_pending; void *acpi_find_table(const char *sig); void busdma_swi(void); int copyout_regstack(struct thread *, uint64_t *, uint64_t *); void cpu_mp_add(u_int, u_int, u_int); void cpu_pcpu_setup(struct pcpu *, u_int, u_int); int do_ast(struct trapframe *); void ia32_trap(int, struct trapframe *); int ia64_count_cpus(void); int ia64_emulate(struct trapframe *, struct thread *); int ia64_flush_dirty(struct thread *, struct _special *); uint64_t ia64_get_hcdp(void); int ia64_highfp_drop(struct thread *); int ia64_highfp_enable(struct thread *, struct trapframe *); int ia64_highfp_save(struct thread *); int ia64_highfp_save_ipi(void); struct ia64_init_return ia64_init(void); u_int ia64_itc_freq(void); int ia64_physmem_add(vm_paddr_t, vm_size_t); void *ia64_physmem_alloc(vm_size_t, vm_size_t); int ia64_physmem_delete(vm_paddr_t, vm_size_t); int ia64_physmem_fini(void); int ia64_physmem_init(void); int ia64_physmem_track(vm_paddr_t, vm_size_t); void ia64_probe_sapics(void); void ia64_sync_icache(vm_offset_t, vm_size_t); void *ia64_xtrace_alloc(void); void ia64_xtrace_init_ap(void *); void ia64_xtrace_init_bsp(void); void ia64_xtrace_save(void); void ia64_xtrace_stop(void); void interrupt(struct trapframe *); void map_gateway_page(void); void map_pal_code(void); void map_vhpt(uintptr_t); void os_boot_rendez(void); void os_mca(void); int syscall(struct trapframe *); void trap(int, struct trapframe *); void trap_panic(int, struct trapframe *); int unaligned_fixup(struct trapframe *, struct thread *); #endif /* _KERNEL */ #endif /* !_MACHINE_MD_VAR_H_ */