Date: Fri, 12 Nov 2010 04:18:20 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r215159 - in head/sys: powerpc/aim powerpc/booke powerpc/include powerpc/powerpc sys Message-ID: <201011120418.oAC4IKJE095194@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Fri Nov 12 04:18:19 2010 New Revision: 215159 URL: http://svn.freebsd.org/changeset/base/215159 Log: Add some platform KOBJ extensions and continue integrating PowerPC hypervisor infrastructure support: - Fix coexistence of multiple platform modules in the same kernel - Allow platform modules to provide an SMP topology - PowerPC hypervisors limit the amount of memory accessible in real mode. Allow the platform modules to specify the maximum real-mode address, and modify the bits of the kernel that need to allocate real-mode-accessible buffers to respect this limits. Modified: head/sys/powerpc/aim/mmu_oea64.c head/sys/powerpc/aim/ofw_machdep.c head/sys/powerpc/aim/slb.c head/sys/powerpc/booke/machdep.c head/sys/powerpc/include/platform.h head/sys/powerpc/powerpc/mp_machdep.c head/sys/powerpc/powerpc/platform.c head/sys/powerpc/powerpc/platform_if.m head/sys/sys/smp.h Modified: head/sys/powerpc/aim/mmu_oea64.c ============================================================================== --- head/sys/powerpc/aim/mmu_oea64.c Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/powerpc/aim/mmu_oea64.c Fri Nov 12 04:18:19 2010 (r215159) @@ -2385,6 +2385,9 @@ moea64_bootstrap_alloc(vm_size_t size, u if (s < phys_avail[i] || e > phys_avail[i + 1]) continue; + if (s + size > platform_real_maxaddr()) + continue; + if (s == phys_avail[i]) { phys_avail[i] += size; } else if (e == phys_avail[i + 1]) { Modified: head/sys/powerpc/aim/ofw_machdep.c ============================================================================== --- head/sys/powerpc/aim/ofw_machdep.c Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/powerpc/aim/ofw_machdep.c Fri Nov 12 04:18:19 2010 (r215159) @@ -692,16 +692,3 @@ OF_decode_addr(phandle_t dev, int regno, return (bus_space_map(*tag, addr, size, 0, handle)); } -int -mem_valid(vm_offset_t addr, int len) -{ - int i; - - for (i = 0; i < nOFmem; i++) - if ((addr >= OFmem[i].mr_start) - && (addr + len < OFmem[i].mr_start + OFmem[i].mr_size)) - return (0); - - return (EFAULT); -} - Modified: head/sys/powerpc/aim/slb.c ============================================================================== --- head/sys/powerpc/aim/slb.c Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/powerpc/aim/slb.c Fri Nov 12 04:18:19 2010 (r215159) @@ -36,9 +36,14 @@ #include <vm/vm.h> #include <vm/pmap.h> #include <vm/uma.h> +#include <vm/vm.h> #include <vm/vm_map.h> +#include <vm/vm_page.h> +#include <vm/vm_pageout.h> +#include <vm/vm_phys.h> #include <machine/md_var.h> +#include <machine/platform.h> #include <machine/pmap.h> #include <machine/vmparam.h> @@ -474,6 +479,51 @@ slb_insert_user(pmap_t pm, struct slb *s pm->pm_slb[i] = slb; } +static void * +slb_uma_real_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait) +{ + static vm_offset_t realmax = 0; + void *va; + vm_page_t m; + int pflags; + + if (realmax == 0) + realmax = platform_real_maxaddr(); + + *flags = UMA_SLAB_PRIV; + if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT) + pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED; + else + pflags = VM_ALLOC_SYSTEM | VM_ALLOC_WIRED; + if (wait & M_ZERO) + pflags |= VM_ALLOC_ZERO; + + for (;;) { + m = vm_phys_alloc_contig(1, 0, realmax, PAGE_SIZE, + PAGE_SIZE); + if (m == NULL) { + if (wait & M_NOWAIT) + return (NULL); + VM_WAIT; + } else + break; + } + + va = (void *) VM_PAGE_TO_PHYS(m); + + if (!hw_direct_map) + pmap_kenter((vm_offset_t)va, VM_PAGE_TO_PHYS(m)); + + if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0) + bzero(va, PAGE_SIZE); + + /* vm_phys_alloc_contig does not track wiring */ + atomic_add_int(&cnt.v_wire_count, 1); + m->wire_count = 1; + + return (va); +} + static void slb_zone_init(void *dummy) { @@ -482,6 +532,11 @@ slb_zone_init(void *dummy) NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM); slb_cache_zone = uma_zcreate("SLB cache", 64*sizeof(struct slb *), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM); + + if (platform_real_maxaddr() != VM_MAX_ADDRESS) { + uma_zone_set_allocf(slb_cache_zone, slb_uma_real_alloc); + uma_zone_set_allocf(slbt_zone, slb_uma_real_alloc); + } } struct slb ** Modified: head/sys/powerpc/booke/machdep.c ============================================================================== --- head/sys/powerpc/booke/machdep.c Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/powerpc/booke/machdep.c Fri Nov 12 04:18:19 2010 (r215159) @@ -597,12 +597,3 @@ bzero(void *buf, size_t len) } } -/* - * XXX what is the better/proper place for this routine? - */ -int -mem_valid(vm_offset_t addr, int len) -{ - - return (1); -} Modified: head/sys/powerpc/include/platform.h ============================================================================== --- head/sys/powerpc/include/platform.h Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/powerpc/include/platform.h Fri Nov 12 04:18:19 2010 (r215159) @@ -44,6 +44,7 @@ struct mem_region { }; void mem_regions(struct mem_region **, int *, struct mem_region **, int *); +vm_offset_t platform_real_maxaddr(void); u_long platform_timebase_freq(struct cpuref *); Modified: head/sys/powerpc/powerpc/mp_machdep.c ============================================================================== --- head/sys/powerpc/powerpc/mp_machdep.c Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/powerpc/powerpc/mp_machdep.c Fri Nov 12 04:18:19 2010 (r215159) @@ -98,13 +98,6 @@ machdep_ap_bootstrap(void) sched_throw(NULL); } -struct cpu_group * -cpu_topo(void) -{ - - return (smp_topo_none()); -} - void cpu_mp_setmaxid(void) { Modified: head/sys/powerpc/powerpc/platform.c ============================================================================== --- head/sys/powerpc/powerpc/platform.c Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/powerpc/powerpc/platform.c Fri Nov 12 04:18:19 2010 (r215159) @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <sys/ktr.h> #include <sys/mutex.h> #include <sys/systm.h> +#include <sys/smp.h> #include <sys/sysctl.h> #include <sys/types.h> @@ -47,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_page.h> #include <machine/cpu.h> +#include <machine/md_var.h> #include <machine/platform.h> #include <machine/platformvar.h> #include <machine/smp.h> @@ -62,11 +64,45 @@ static char plat_name[64] = ""; SYSCTL_STRING(_hw, OID_AUTO, platform, CTLFLAG_RD | CTLFLAG_TUN, plat_name, 0, "Platform currently in use"); +static struct mem_region *pregions = NULL; +static struct mem_region *aregions = NULL; +static int npregions, naregions; + void mem_regions(struct mem_region **phys, int *physsz, struct mem_region **avail, int *availsz) { - PLATFORM_MEM_REGIONS(plat_obj, phys, physsz, avail, availsz); + if (pregions == NULL) + PLATFORM_MEM_REGIONS(plat_obj, &pregions, &npregions, + &aregions, &naregions); + + *phys = pregions; + *avail = aregions; + *physsz = npregions; + *availsz = naregions; +} + +int +mem_valid(vm_offset_t addr, int len) +{ + int i; + + if (pregions == NULL) + PLATFORM_MEM_REGIONS(plat_obj, &pregions, &npregions, + &aregions, &naregions); + + for (i = 0; i < npregions; i++) + if ((addr >= pregions[i].mr_start) + && (addr + len < pregions[i].mr_start + pregions[i].mr_size)) + return (0); + + return (EFAULT); +} + +vm_offset_t +platform_real_maxaddr(void) +{ + return (PLATFORM_REAL_MAXADDR(plat_obj)); } const char * @@ -105,6 +141,14 @@ platform_smp_start_cpu(struct pcpu *cpu) return (PLATFORM_SMP_START_CPU(plat_obj, cpu)); } +#ifdef SMP +struct cpu_group * +cpu_topo(void) +{ + return (PLATFORM_SMP_TOPO(plat_obj)); +} +#endif + /* * Reset back to firmware. */ @@ -164,9 +208,10 @@ platform_probe_and_attach() } /* - * We can't free the KOBJ, since it is static. Luckily, - * this has no ill effects since it gets reset every time. + * We can't free the KOBJ, since it is static. Reset the ops + * member of this class so that we can come back later. */ + platp->ops = NULL; } if (plat_def_impl == NULL) Modified: head/sys/powerpc/powerpc/platform_if.m ============================================================================== --- head/sys/powerpc/powerpc/platform_if.m Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/powerpc/powerpc/platform_if.m Fri Nov 12 04:18:19 2010 (r215159) @@ -30,10 +30,12 @@ #include <sys/lock.h> #include <sys/mutex.h> #include <sys/systm.h> +#include <sys/smp.h> #include <machine/platform.h> #include <machine/platformvar.h> #include <machine/smp.h> +#include <machine/vmparam.h> /** * @defgroup PLATFORM platform - KObj methods for PowerPC platform @@ -66,6 +68,18 @@ CODE { { return (ENOENT); } + static struct cpu_group *platform_null_smp_topo(platform_t plat) + { +#ifdef SMP + return (smp_topo_none()); +#else + return (NULL); +#endif + } + static vm_offset_t platform_null_real_maxaddr(platform_t plat) + { + return (VM_MAX_ADDRESS); + } }; /** @@ -109,6 +123,15 @@ METHOD void mem_regions { }; /** + * @brief Return the maximum address accessible in real mode + * (for use with hypervisors) + */ +METHOD vm_offset_t real_maxaddr { + platform_t _plat; +} DEFAULT platform_null_real_maxaddr; + + +/** * @brief Get the CPU's timebase frequency, in ticks per second. * * @param _cpu CPU whose timebase to query @@ -162,6 +185,13 @@ METHOD int smp_start_cpu { }; /** + * @brief Return SMP topology + */ +METHOD cpu_group_t smp_topo { + platform_t _plat; +} DEFAULT platform_null_smp_topo; + +/** * @brief Reset system */ METHOD void reset { Modified: head/sys/sys/smp.h ============================================================================== --- head/sys/sys/smp.h Fri Nov 12 04:13:48 2010 (r215158) +++ head/sys/sys/smp.h Fri Nov 12 04:18:19 2010 (r215159) @@ -16,8 +16,6 @@ #ifndef LOCORE -#ifdef SMP - /* * Topology of a NUMA or HTT system. * @@ -41,6 +39,8 @@ struct cpu_group { int8_t cg_flags; /* Traversal modifiers. */ }; +typedef struct cpu_group *cpu_group_t; + /* * Defines common resources for CPUs in the group. The highest level * resource should be used when multiple are shared. @@ -60,6 +60,7 @@ struct cpu_group { /* * Convenience routines for building topologies. */ +#ifdef SMP struct cpu_group *smp_topo(void); struct cpu_group *smp_topo_none(void); struct cpu_group *smp_topo_1level(int l1share, int l1count, int l1flags);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011120418.oAC4IKJE095194>