Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/powerpc/nexus.c
Show All 32 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/kdb.h> | |||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/pcpu.h> | #include <sys/pcpu.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <sys/smp.h> | |||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#include <dev/ofw/openfirm.h> | #include <dev/ofw/openfirm.h> | ||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <machine/intr_machdep.h> | #include <machine/intr_machdep.h> | ||||
#include <machine/resource.h> | #include <machine/resource.h> | ||||
/* | /* | ||||
* The nexus handles root-level resource allocation requests and interrupt | * The nexus handles root-level resource allocation requests and interrupt | ||||
* mapping. All direct subdevices of nexus are attached by DEVICE_IDENTIFY(). | * mapping. All direct subdevices of nexus are attached by DEVICE_IDENTIFY(). | ||||
*/ | */ | ||||
static device_probe_t nexus_probe; | static device_probe_t nexus_probe; | ||||
static device_attach_t nexus_attach; | static device_attach_t nexus_attach; | ||||
static bus_setup_intr_t nexus_setup_intr; | static bus_setup_intr_t nexus_setup_intr; | ||||
static bus_teardown_intr_t nexus_teardown_intr; | static bus_teardown_intr_t nexus_teardown_intr; | ||||
static bus_activate_resource_t nexus_activate_resource; | static bus_activate_resource_t nexus_activate_resource; | ||||
static bus_deactivate_resource_t nexus_deactivate_resource; | static bus_deactivate_resource_t nexus_deactivate_resource; | ||||
static bus_space_tag_t nexus_get_bus_tag(device_t, device_t); | static bus_space_tag_t nexus_get_bus_tag(device_t, device_t); | ||||
static int nexus_get_cpus(device_t, device_t, enum cpu_sets, size_t, | |||||
cpuset_t *); | |||||
#ifdef SMP | #ifdef SMP | ||||
static bus_bind_intr_t nexus_bind_intr; | static bus_bind_intr_t nexus_bind_intr; | ||||
#endif | #endif | ||||
static bus_config_intr_t nexus_config_intr; | static bus_config_intr_t nexus_config_intr; | ||||
static ofw_bus_map_intr_t nexus_ofw_map_intr; | static ofw_bus_map_intr_t nexus_ofw_map_intr; | ||||
static device_method_t nexus_methods[] = { | static device_method_t nexus_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_probe, nexus_probe), | DEVMETHOD(device_probe, nexus_probe), | ||||
DEVMETHOD(device_attach, nexus_attach), | DEVMETHOD(device_attach, nexus_attach), | ||||
/* Bus interface */ | /* Bus interface */ | ||||
DEVMETHOD(bus_add_child, bus_generic_add_child), | DEVMETHOD(bus_add_child, bus_generic_add_child), | ||||
DEVMETHOD(bus_activate_resource, nexus_activate_resource), | DEVMETHOD(bus_activate_resource, nexus_activate_resource), | ||||
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), | DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), | ||||
DEVMETHOD(bus_setup_intr, nexus_setup_intr), | DEVMETHOD(bus_setup_intr, nexus_setup_intr), | ||||
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), | DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), | ||||
#ifdef SMP | #ifdef SMP | ||||
DEVMETHOD(bus_bind_intr, nexus_bind_intr), | DEVMETHOD(bus_bind_intr, nexus_bind_intr), | ||||
#endif | #endif | ||||
DEVMETHOD(bus_config_intr, nexus_config_intr), | DEVMETHOD(bus_config_intr, nexus_config_intr), | ||||
DEVMETHOD(bus_get_bus_tag, nexus_get_bus_tag), | DEVMETHOD(bus_get_bus_tag, nexus_get_bus_tag), | ||||
DEVMETHOD(bus_get_cpus, nexus_get_cpus), | |||||
/* ofw_bus interface */ | /* ofw_bus interface */ | ||||
DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), | DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), | ||||
DEVMETHOD_END | DEVMETHOD_END | ||||
}; | }; | ||||
static devclass_t nexus_devclass; | static devclass_t nexus_devclass; | ||||
Show All 22 Lines | nexus_attach(device_t dev) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
nexus_setup_intr(device_t bus __unused, device_t child, struct resource *r, | nexus_setup_intr(device_t bus __unused, device_t child, struct resource *r, | ||||
int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, | int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, | ||||
void **cookiep) | void **cookiep) | ||||
{ | { | ||||
int error; | int error, domain; | ||||
if (r == NULL) | if (r == NULL) | ||||
panic("%s: NULL interrupt resource!", __func__); | panic("%s: NULL interrupt resource!", __func__); | ||||
if (cookiep != NULL) | |||||
*cookiep = NULL; | |||||
if ((rman_get_flags(r) & RF_SHAREABLE) == 0) | if ((rman_get_flags(r) & RF_SHAREABLE) == 0) | ||||
flags |= INTR_EXCL; | flags |= INTR_EXCL; | ||||
/* We depend here on rman_activate_resource() being idempotent. */ | /* We depend here on rman_activate_resource() being idempotent. */ | ||||
error = rman_activate_resource(r); | error = rman_activate_resource(r); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
if (bus_get_domain(child, &domain) != 0) { | |||||
if(bootverbose) | |||||
device_printf(child, "no domain found\n"); | |||||
domain = 0; | |||||
} | |||||
error = powerpc_setup_intr(device_get_nameunit(child), | error = powerpc_setup_intr(device_get_nameunit(child), | ||||
rman_get_start(r), filt, intr, arg, flags, cookiep); | rman_get_start(r), filt, intr, arg, flags, cookiep, domain); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
nexus_teardown_intr(device_t bus __unused, device_t child __unused, | nexus_teardown_intr(device_t bus __unused, device_t child __unused, | ||||
struct resource *r, void *ih) | struct resource *r, void *ih) | ||||
{ | { | ||||
if (r == NULL) | if (r == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
return (powerpc_teardown_intr(ih)); | return (powerpc_teardown_intr(ih)); | ||||
} | } | ||||
static bus_space_tag_t | static bus_space_tag_t | ||||
nexus_get_bus_tag(device_t bus __unused, device_t child __unused) | nexus_get_bus_tag(device_t bus __unused, device_t child __unused) | ||||
{ | { | ||||
return(&bs_be_tag); | return(&bs_be_tag); | ||||
} | |||||
static int | |||||
nexus_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, | |||||
cpuset_t *cpuset) | |||||
{ | |||||
switch (op) { | |||||
#ifdef SMP | |||||
case INTR_CPUS: | |||||
if (setsize != sizeof(cpuset_t)) | |||||
return (EINVAL); | |||||
*cpuset = all_cpus; | |||||
return (0); | |||||
#endif | |||||
default: | |||||
return (bus_generic_get_cpus(dev, child, op, setsize, cpuset)); | |||||
} | |||||
} | } | ||||
#ifdef SMP | #ifdef SMP | ||||
static int | static int | ||||
nexus_bind_intr(device_t bus __unused, device_t child __unused, | nexus_bind_intr(device_t bus __unused, device_t child __unused, | ||||
struct resource *r, int cpu) | struct resource *r, int cpu) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 64 Lines • Show Last 20 Lines |