From owner-svn-src-all@FreeBSD.ORG Tue May 13 16:50:12 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 509F1E1E; Tue, 13 May 2014 16:50:12 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3AB58291F; Tue, 13 May 2014 16:50:12 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4DGoCgc077248; Tue, 13 May 2014 16:50:12 GMT (envelope-from ian@svn.freebsd.org) Received: (from ian@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4DGoBJK077239; Tue, 13 May 2014 16:50:11 GMT (envelope-from ian@svn.freebsd.org) Message-Id: <201405131650.s4DGoBJK077239@svn.freebsd.org> From: Ian Lepore Date: Tue, 13 May 2014 16:50:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r265952 - in stable/10/sys: conf powerpc/aim powerpc/booke powerpc/mpc85xx powerpc/powerpc X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 May 2014 16:50:12 -0000 Author: ian Date: Tue May 13 16:50:10 2014 New Revision: 265952 URL: http://svnweb.freebsd.org/changeset/base/265952 Log: MFC r256792, r256793, r256799 (by nwhitehorn): Unify AIM and booke code. Added: stable/10/sys/powerpc/powerpc/clock.c - copied unchanged from r256793, head/sys/powerpc/powerpc/clock.c stable/10/sys/powerpc/powerpc/nexus.c - copied unchanged from r256799, head/sys/powerpc/powerpc/nexus.c stable/10/sys/powerpc/powerpc/vm_machdep.c - copied unchanged from r256792, head/sys/powerpc/powerpc/vm_machdep.c Deleted: stable/10/sys/powerpc/aim/clock.c stable/10/sys/powerpc/aim/nexus.c stable/10/sys/powerpc/aim/vm_machdep.c stable/10/sys/powerpc/booke/clock.c stable/10/sys/powerpc/booke/vm_machdep.c stable/10/sys/powerpc/mpc85xx/nexus.c Modified: stable/10/sys/conf/files.powerpc stable/10/sys/powerpc/aim/machdep.c Modified: stable/10/sys/conf/files.powerpc ============================================================================== --- stable/10/sys/conf/files.powerpc Tue May 13 16:40:27 2014 (r265951) +++ stable/10/sys/conf/files.powerpc Tue May 13 16:50:10 2014 (r265952) @@ -88,7 +88,6 @@ libkern/qdivrem.c optional powerpc libkern/ucmpdi2.c optional powerpc libkern/udivdi3.c optional powerpc libkern/umoddi3.c optional powerpc -powerpc/aim/clock.c optional aim powerpc/aim/copyinout.c optional aim powerpc/aim/interrupt.c optional aim powerpc/aim/locore.S optional aim no-obj @@ -98,14 +97,11 @@ powerpc/aim/mmu_oea64.c optional aim powerpc/aim/moea64_if.m optional aim powerpc/aim/moea64_native.c optional aim powerpc/aim/mp_cpudep.c optional aim -powerpc/aim/nexus.c optional aim powerpc/aim/slb.c optional aim powerpc64 powerpc/aim/swtch32.S optional aim powerpc powerpc/aim/swtch64.S optional aim powerpc64 powerpc/aim/trap.c optional aim powerpc/aim/uma_machdep.c optional aim -powerpc/aim/vm_machdep.c optional aim -powerpc/booke/clock.c optional booke powerpc/booke/copyinout.c optional booke powerpc/booke/interrupt.c optional booke powerpc/booke/locore.S optional booke no-obj @@ -116,7 +112,6 @@ powerpc/booke/platform_bare.c optional m powerpc/booke/pmap.c optional booke powerpc/booke/swtch.S optional booke powerpc/booke/trap.c optional booke -powerpc/booke/vm_machdep.c optional booke powerpc/cpufreq/dfs.c optional cpufreq powerpc/cpufreq/pcr.c optional cpufreq aim powerpc/cpufreq/pmufreq.c optional cpufreq aim pmu @@ -141,7 +136,6 @@ powerpc/mpc85xx/i2c.c optional iicbus f powerpc/mpc85xx/isa.c optional mpc85xx isa powerpc/mpc85xx/lbc.c optional mpc85xx powerpc/mpc85xx/mpc85xx.c optional mpc85xx -powerpc/mpc85xx/nexus.c optional mpc85xx powerpc/mpc85xx/pci_fdt.c optional pci mpc85xx powerpc/ofw/ofw_cpu.c optional aim powerpc/ofw/ofw_machdep.c standard @@ -184,6 +178,7 @@ powerpc/powerpc/autoconf.c standard powerpc/powerpc/bcopy.c standard powerpc/powerpc/bus_machdep.c standard powerpc/powerpc/busdma_machdep.c standard +powerpc/powerpc/clock.c standard powerpc/powerpc/copystr.c standard powerpc/powerpc/cpu.c standard powerpc/powerpc/db_disasm.c optional ddb @@ -203,6 +198,7 @@ powerpc/powerpc/iommu_if.m standard powerpc/powerpc/mem.c optional mem powerpc/powerpc/mmu_if.m standard powerpc/powerpc/mp_machdep.c optional smp +powerpc/powerpc/nexus.c standard powerpc/powerpc/openpic.c standard powerpc/powerpc/openpic_fdt.c optional fdt powerpc/powerpc/pic_if.m standard @@ -218,6 +214,7 @@ powerpc/powerpc/suswintr.c standard powerpc/powerpc/syncicache.c standard powerpc/powerpc/sys_machdep.c standard powerpc/powerpc/uio_machdep.c standard +powerpc/powerpc/vm_machdep.c standard powerpc/ps3/ehci_ps3.c optional ps3 ehci powerpc/ps3/ohci_ps3.c optional ps3 ohci powerpc/ps3/if_glc.c optional ps3 glc Modified: stable/10/sys/powerpc/aim/machdep.c ============================================================================== --- stable/10/sys/powerpc/aim/machdep.c Tue May 13 16:40:27 2014 (r265951) +++ stable/10/sys/powerpc/aim/machdep.c Tue May 13 16:50:10 2014 (r265952) @@ -647,14 +647,6 @@ cpu_flush_dcache(void *ptr, size_t len) /* TBD */ } -void -cpu_initclocks(void) -{ - - decr_tc_init(); - cpu_initclocks_bsp(); -} - /* * Shutdown the CPU as much as possible. */ Copied: stable/10/sys/powerpc/powerpc/clock.c (from r256793, head/sys/powerpc/powerpc/clock.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/powerpc/powerpc/clock.c Tue May 13 16:50:10 2014 (r265952, copy of r256793, head/sys/powerpc/powerpc/clock.c) @@ -0,0 +1,308 @@ +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + * + * $NetBSD: clock.c,v 1.9 2000/01/19 02:52:19 msaitoh Exp $ + */ +/* + * Copyright (C) 2001 Benno Rice. + * 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 Benno Rice ``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 TOOLS GMBH 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 +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +/* + * Initially we assume a processor with a bus frequency of 12.5 MHz. + */ +static int initialized = 0; +static u_long ns_per_tick = 80; +static u_long ticks_per_sec = 12500000; +static u_long *decr_counts[MAXCPU]; + +static int decr_et_start(struct eventtimer *et, + sbintime_t first, sbintime_t period); +static int decr_et_stop(struct eventtimer *et); +static timecounter_get_t decr_get_timecount; + +struct decr_state { + int mode; /* 0 - off, 1 - periodic, 2 - one-shot. */ + int32_t div; /* Periodic divisor. */ +}; +static DPCPU_DEFINE(struct decr_state, decr_state); + +static struct eventtimer decr_et; +static struct timecounter decr_tc = { + decr_get_timecount, /* get_timecount */ + 0, /* no poll_pps */ + ~0u, /* counter_mask */ + 0, /* frequency */ + "timebase" /* name */ +}; + +/* + * Decrementer interrupt handler. + */ +void +decr_intr(struct trapframe *frame) +{ + struct decr_state *s = DPCPU_PTR(decr_state); + int nticks = 0; + int32_t val; + + if (!initialized) + return; + + (*decr_counts[curcpu])++; + +#ifdef BOOKE + /* + * Interrupt handler must reset DIS to avoid getting another + * interrupt once EE is enabled. + */ + mtspr(SPR_TSR, TSR_DIS); +#endif + + if (s->mode == 1) { + /* + * Based on the actual time delay since the last decrementer + * reload, we arrange for earlier interrupt next time. + */ + __asm ("mfdec %0" : "=r"(val)); + while (val < 0) { + val += s->div; + nticks++; + } + mtdec(val); + } else if (s->mode == 2) { + nticks = 1; + decr_et_stop(NULL); + } + + while (nticks-- > 0) { + if (decr_et.et_active) + decr_et.et_event_cb(&decr_et, decr_et.et_arg); + } +} + +void +cpu_initclocks(void) +{ + + decr_tc_init(); + cpu_initclocks_bsp(); +} + +/* + * BSP early initialization. + */ +void +decr_init(void) +{ + struct cpuref cpu; + char buf[32]; + + /* + * Check the BSP's timebase frequency. Sometimes we can't find the BSP, so fall + * back to the first CPU in this case. + */ + if (platform_smp_get_bsp(&cpu) != 0) + platform_smp_first_cpu(&cpu); + ticks_per_sec = platform_timebase_freq(&cpu); + ns_per_tick = 1000000000 / ticks_per_sec; + + set_cputicker(mftb, ticks_per_sec, 0); + snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu); + intrcnt_add(buf, &decr_counts[curcpu]); + decr_et_stop(NULL); + initialized = 1; +} + +#ifdef SMP +/* + * AP early initialization. + */ +void +decr_ap_init(void) +{ + char buf[32]; + + snprintf(buf, sizeof(buf), "cpu%d:decrementer", curcpu); + intrcnt_add(buf, &decr_counts[curcpu]); + decr_et_stop(NULL); +} +#endif + +/* + * Final initialization. + */ +void +decr_tc_init(void) +{ + + decr_tc.tc_frequency = ticks_per_sec; + tc_init(&decr_tc); + decr_et.et_name = "decrementer"; + decr_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT | + ET_FLAGS_PERCPU; + decr_et.et_quality = 1000; + decr_et.et_frequency = ticks_per_sec; + decr_et.et_min_period = (0x00000002LLU << 32) / ticks_per_sec; + decr_et.et_max_period = (0x7fffffffLLU << 32) / ticks_per_sec; + decr_et.et_start = decr_et_start; + decr_et.et_stop = decr_et_stop; + decr_et.et_priv = NULL; + et_register(&decr_et); +} + +/* + * Event timer start method. + */ +static int +decr_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period) +{ + struct decr_state *s = DPCPU_PTR(decr_state); + uint32_t fdiv; +#ifdef BOOKE + uint32_t tcr; +#endif + + if (period != 0) { + s->mode = 1; + s->div = (decr_et.et_frequency * period) >> 32; + } else { + s->mode = 2; + s->div = 0; + } + if (first != 0) + fdiv = (decr_et.et_frequency * first) >> 32; + else + fdiv = s->div; + +#ifdef BOOKE + tcr = mfspr(SPR_TCR); + tcr |= TCR_DIE; + if (s->mode == 1) { + mtspr(SPR_DECAR, s->div); + tcr |= TCR_ARE; + } else + tcr &= ~TCR_ARE; + mtdec(fdiv); + mtspr(SPR_TCR, tcr); +#else + mtdec(fdiv); +#endif + + return (0); +} + +/* + * Event timer stop method. + */ +static int +decr_et_stop(struct eventtimer *et) +{ + struct decr_state *s = DPCPU_PTR(decr_state); +#ifdef BOOKE + uint32_t tcr; +#endif + + s->mode = 0; + s->div = 0x7fffffff; +#ifdef BOOKE + tcr = mfspr(SPR_TCR); + tcr &= ~(TCR_DIE | TCR_ARE); + mtspr(SPR_TCR, tcr); +#else + mtdec(s->div); +#endif + return (0); +} + +/* + * Timecounter get method. + */ +static unsigned +decr_get_timecount(struct timecounter *tc) +{ + return (mftb()); +} + +/* + * Wait for about n microseconds (at least!). + */ +void +DELAY(int n) +{ + u_quad_t tb, ttb; + + tb = mftb(); + ttb = tb + (n * 1000 + ns_per_tick - 1) / ns_per_tick; + while (tb < ttb) + tb = mftb(); +} + Copied: stable/10/sys/powerpc/powerpc/nexus.c (from r256799, head/sys/powerpc/powerpc/nexus.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/powerpc/powerpc/nexus.c Tue May 13 16:50:10 2014 (r265952, copy of r256799, head/sys/powerpc/powerpc/nexus.c) @@ -0,0 +1,527 @@ +/*- + * Copyright 1998 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. 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. + */ +/*- + * Copyright 2001 by Thomas Moestl . 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. + * + * from: FreeBSD: src/sys/i386/i386/nexus.c,v 1.43 2001/02/09 + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include "ofw_bus_if.h" +#include "pic_if.h" + +/* + * The nexus (which is a pseudo-bus actually) iterates over the nodes that + * exist in Open Firmware and adds them as devices to this bus so that drivers + * can be attached to them. + * + * Maybe this code should get into dev/ofw to some extent, as some of it should + * work for all Open Firmware based machines... + */ + +static MALLOC_DEFINE(M_NEXUS, "nexus", "nexus device information"); + +enum nexus_ivars { + NEXUS_IVAR_NODE, + NEXUS_IVAR_NAME, + NEXUS_IVAR_DEVICE_TYPE, + NEXUS_IVAR_COMPATIBLE, +}; + +struct nexus_devinfo { + phandle_t ndi_node; + /* Some common properties. */ + const char *ndi_name; + const char *ndi_device_type; + const char *ndi_compatible; +}; + +struct nexus_softc { + struct rman sc_rman; +}; + +/* + * Device interface + */ +static int nexus_probe(device_t); +static int nexus_attach(device_t); + +/* + * Bus interface + */ +static device_t nexus_add_child(device_t, u_int, const char *, int); +static void nexus_probe_nomatch(device_t, device_t); +static int nexus_read_ivar(device_t, device_t, int, uintptr_t *); +static int nexus_write_ivar(device_t, device_t, int, uintptr_t); +#ifdef SMP +static int nexus_bind_intr(device_t dev, device_t child, + struct resource *irq, int cpu); +#endif +static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, + enum intr_polarity pol); +static int nexus_setup_intr(device_t, device_t, struct resource *, int, + driver_filter_t *, driver_intr_t *, void *, void **); +static int nexus_teardown_intr(device_t, device_t, struct resource *, + void *); +static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, + u_long, u_long, u_long, u_int); +static int nexus_activate_resource(device_t, device_t, int, int, + struct resource *); +static int nexus_deactivate_resource(device_t, device_t, int, int, + struct resource *); +static int nexus_release_resource(device_t, device_t, int, int, + struct resource *); + +/* + * OFW bus interface. + */ +static phandle_t nexus_ofw_get_node(device_t, device_t); +static const char *nexus_ofw_get_name(device_t, device_t); +static const char *nexus_ofw_get_type(device_t, device_t); +static const char *nexus_ofw_get_compat(device_t, device_t); + +/* + * Local routines + */ +static device_t nexus_device_from_node(device_t, phandle_t); + +static device_method_t nexus_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, nexus_probe), + DEVMETHOD(device_attach, nexus_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface. Resource management is business of the children... */ + DEVMETHOD(bus_add_child, nexus_add_child), + DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str), + DEVMETHOD(bus_probe_nomatch, nexus_probe_nomatch), + DEVMETHOD(bus_read_ivar, nexus_read_ivar), + DEVMETHOD(bus_write_ivar, nexus_write_ivar), + DEVMETHOD(bus_setup_intr, nexus_setup_intr), + DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), +#ifdef SMP + DEVMETHOD(bus_bind_intr, nexus_bind_intr), +#endif + DEVMETHOD(bus_config_intr, nexus_config_intr), + DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), + DEVMETHOD(bus_activate_resource, nexus_activate_resource), + DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), + DEVMETHOD(bus_release_resource, nexus_release_resource), + + /* OFW bus interface */ + DEVMETHOD(ofw_bus_get_node, nexus_ofw_get_node), + DEVMETHOD(ofw_bus_get_name, nexus_ofw_get_name), + DEVMETHOD(ofw_bus_get_type, nexus_ofw_get_type), + DEVMETHOD(ofw_bus_get_compat, nexus_ofw_get_compat), + + DEVMETHOD_END +}; + +static driver_t nexus_driver = { + "nexus", + nexus_methods, + sizeof(struct nexus_softc), +}; + +static devclass_t nexus_devclass; + +EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0, + BUS_PASS_BUS); + +static int +nexus_probe(device_t dev) +{ + bus_generic_probe(dev); + device_set_desc(dev, "Open Firmware Nexus device"); + return (0); +} + +static int +nexus_attach(device_t dev) +{ + phandle_t root; + phandle_t child; + struct nexus_softc *sc; + u_long start, end; + + sc = device_get_softc(dev); + + start = 0; + end = ~0; + + sc->sc_rman.rm_start = start; + sc->sc_rman.rm_end = end; + sc->sc_rman.rm_type = RMAN_ARRAY; + sc->sc_rman.rm_descr = "Interrupt request lines"; + if (rman_init(&sc->sc_rman) || + rman_manage_region(&sc->sc_rman, start, end)) + panic("nexus_probe IRQ rman"); + + if ((root = OF_peer(0)) == 0) + return (bus_generic_attach(dev)); + + /* + * Now walk the OFW tree to locate top-level devices + */ + for (child = OF_child(root); child != 0; child = OF_peer(child)) { + if (child == -1) + panic("nexus_probe(): OF_child failed."); + (void)nexus_device_from_node(dev, child); + + } + + return (bus_generic_attach(dev)); +} + +static void +nexus_probe_nomatch(device_t dev, device_t child) +{ + char *name, *type; + + if (BUS_READ_IVAR(dev, child, NEXUS_IVAR_NAME, + (uintptr_t *)&name) != 0 || + BUS_READ_IVAR(dev, child, NEXUS_IVAR_DEVICE_TYPE, + (uintptr_t *)&type) != 0) + return; + + if (type == NULL) + type = "(unknown)"; + + if (bootverbose) + device_printf(dev, "<%s>, type %s (no driver attached)\n", + name, type); +} + +static device_t +nexus_add_child(device_t dev, u_int order, const char *name, int unit) +{ + device_t child; + struct nexus_devinfo *dinfo; + + child = device_add_child_ordered(dev, order, name, unit); + if (child == NULL) + return (NULL); + + dinfo = malloc(sizeof(struct nexus_devinfo), M_NEXUS, M_NOWAIT|M_ZERO); + if (dinfo == NULL) + return (NULL); + + dinfo->ndi_node = -1; + dinfo->ndi_name = name; + device_set_ivars(child, dinfo); + + return (child); +} + + +static int +nexus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) +{ + struct nexus_devinfo *dinfo; + + if ((dinfo = device_get_ivars(child)) == 0) + return (ENOENT); + switch (which) { + case NEXUS_IVAR_NODE: + *result = dinfo->ndi_node; + break; + case NEXUS_IVAR_NAME: + *result = (uintptr_t)dinfo->ndi_name; + break; + case NEXUS_IVAR_DEVICE_TYPE: + *result = (uintptr_t)dinfo->ndi_device_type; + break; + case NEXUS_IVAR_COMPATIBLE: + *result = (uintptr_t)dinfo->ndi_compatible; + break; + default: + return (ENOENT); + } + return 0; +} + +static int +nexus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) +{ + struct nexus_devinfo *dinfo; + + if ((dinfo = device_get_ivars(child)) == 0) + return (ENOENT); + + switch (which) { + case NEXUS_IVAR_NAME: + return (EINVAL); + + /* Identified devices may want to set these */ + case NEXUS_IVAR_NODE: + dinfo->ndi_node = (phandle_t)value; + break; + + case NEXUS_IVAR_DEVICE_TYPE: + dinfo->ndi_device_type = (char *)value; + break; + + default: + return (ENOENT); + } + return 0; +} + +static int +nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, + driver_filter_t *filter, driver_intr_t *ihand, void *arg, void **cookiep) +{ + int error; + + /* somebody tried to setup an irq that failed to allocate! */ + if (res == NULL) + panic("nexus_setup_intr: NULL irq resource!"); + + *cookiep = 0; + if ((rman_get_flags(res) & RF_SHAREABLE) == 0) + flags |= INTR_EXCL; + + /* + * We depend here on rman_activate_resource() being idempotent. + */ + error = rman_activate_resource(res); + if (error) + return (error); + + error = powerpc_setup_intr(device_get_nameunit(child), + rman_get_start(res), filter, ihand, arg, flags, cookiep); + + return (error); +} + +static int +nexus_teardown_intr(device_t dev, device_t child, struct resource *res, + void *cookie) +{ + + return (powerpc_teardown_intr(cookie)); +} + +#ifdef SMP +static int +nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) +{ + + return (powerpc_bind_intr(rman_get_start(irq), cpu)); +} +#endif + +static int +nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, + enum intr_polarity pol) +{ + + return (powerpc_config_intr(irq, trig, pol)); +} + +/* + * Allocate resources at the behest of a child. This only handles interrupts, + * since I/O resources are handled by child busses. + */ +static struct resource * +nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct nexus_softc *sc; + struct resource *rv; + + if (type != SYS_RES_IRQ) { + device_printf(bus, "unknown resource request from %s\n", + device_get_nameunit(child)); + return (NULL); + } + + if (count == 0 || start + count - 1 != end) { + device_printf(bus, "invalid IRQ allocation from %s\n", + device_get_nameunit(child)); + return (NULL); + } + + sc = device_get_softc(bus); + + rv = rman_reserve_resource(&sc->sc_rman, start, end, count, + flags, child); + if (rv == NULL) { + device_printf(bus, "IRQ allocation failed for %s\n", + device_get_nameunit(child)); + } else + rman_set_rid(rv, *rid); + + return (rv); +} + +static int +nexus_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + + /* Not much to be done yet... */ + return (rman_activate_resource(res)); +} + +static int +nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + + /* Not much to be done yet... */ + return (rman_deactivate_resource(res)); +} + +static int +nexus_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + + if (type != SYS_RES_IRQ) { + device_printf(bus, "unknown resource request from %s\n", + device_get_nameunit(child)); + return (EINVAL); + } + + return (rman_release_resource(res)); +} + +static device_t +nexus_device_from_node(device_t parent, phandle_t node) +{ + device_t cdev; + struct nexus_devinfo *dinfo; + char *name, *type, *compatible; + + OF_getprop_alloc(node, "name", 1, (void **)&name); + OF_getprop_alloc(node, "device_type", 1, (void **)&type); + OF_getprop_alloc(node, "compatible", 1, (void **)&compatible); + cdev = device_add_child(parent, NULL, -1); + if (cdev != NULL) { + dinfo = malloc(sizeof(*dinfo), M_NEXUS, M_WAITOK); + dinfo->ndi_node = node; + dinfo->ndi_name = name; + dinfo->ndi_device_type = type; + dinfo->ndi_compatible = compatible; + device_set_ivars(cdev, dinfo); + } else + free(name, M_OFWPROP); + + return (cdev); +} + +static const char * +nexus_ofw_get_name(device_t bus, device_t dev) +{ + struct nexus_devinfo *dinfo; + + if ((dinfo = device_get_ivars(dev)) == NULL) + return (NULL); + + return (dinfo->ndi_name); +} + +static phandle_t +nexus_ofw_get_node(device_t bus, device_t dev) +{ + struct nexus_devinfo *dinfo; + + if ((dinfo = device_get_ivars(dev)) == NULL) + return (0); + + return (dinfo->ndi_node); +} + +static const char * +nexus_ofw_get_type(device_t bus, device_t dev) +{ + struct nexus_devinfo *dinfo; + + if ((dinfo = device_get_ivars(dev)) == NULL) + return (NULL); + + return (dinfo->ndi_device_type); +} + +static const char * +nexus_ofw_get_compat(device_t bus, device_t dev) +{ + struct nexus_devinfo *dinfo; + + if ((dinfo = device_get_ivars(dev)) == NULL) + return (NULL); + + return (dinfo->ndi_compatible); +} + Copied: stable/10/sys/powerpc/powerpc/vm_machdep.c (from r256792, head/sys/powerpc/powerpc/vm_machdep.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/powerpc/powerpc/vm_machdep.c Tue May 13 16:50:10 2014 (r265952, copy of r256792, head/sys/powerpc/powerpc/vm_machdep.c) @@ -0,0 +1,410 @@ +/*- + * Copyright (c) 1982, 1986 The Regents of the University of California. + * Copyright (c) 1989, 1990 William Jolitz + * Copyright (c) 1994 John Dyson + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department, and William Jolitz. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 + * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ + * $FreeBSD$ + */ +/*- + * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include +#include +#include +#include +#include *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***