Changeset View
Changeset View
Standalone View
Standalone View
head/sys/mips/mips/nexus.c
Show All 30 Lines | |||||
/* | /* | ||||
* This code implements a `root nexus' for MIPS Architecture | * This code implements a `root nexus' for MIPS Architecture | ||||
* machines. The function of the root nexus is to serve as an | * machines. The function of the root nexus is to serve as an | ||||
* attachment point for both processors and buses, and to manage | * attachment point for both processors and buses, and to manage | ||||
* resources which are common to all of them. In particular, | * resources which are common to all of them. In particular, | ||||
* this code implements the core resource managers for interrupt | * this code implements the core resource managers for interrupt | ||||
* requests and memory address space. | * requests and memory address space. | ||||
*/ | */ | ||||
#include "opt_platform.h" | |||||
#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/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <sys/interrupt.h> | #include <sys/interrupt.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <machine/intr_machdep.h> | |||||
#include <machine/pmap.h> | #include <machine/pmap.h> | ||||
#include <machine/resource.h> | #include <machine/resource.h> | ||||
#include <machine/vmparam.h> | #include <machine/vmparam.h> | ||||
#ifdef MIPS_INTRNG | |||||
#include <machine/intr.h> | |||||
#else | |||||
#include <machine/intr_machdep.h> | |||||
#endif | |||||
#include "opt_platform.h" | #include "opt_platform.h" | ||||
#ifdef FDT | |||||
#include <machine/fdt.h> | |||||
#include "ofw_bus_if.h" | |||||
#endif | |||||
#undef NEXUS_DEBUG | #undef NEXUS_DEBUG | ||||
#ifdef NEXUS_DEBUG | #ifdef NEXUS_DEBUG | ||||
#define dprintf printf | #define dprintf printf | ||||
#else | #else | ||||
#define dprintf(x, arg...) | #define dprintf(x, arg...) | ||||
#endif /* NEXUS_DEBUG */ | #endif /* NEXUS_DEBUG */ | ||||
#define NUM_MIPS_IRQS 6 | #define NUM_MIPS_IRQS 6 | ||||
Show All 31 Lines | |||||
static int nexus_deactivate_resource(device_t, device_t, int, int, | static int nexus_deactivate_resource(device_t, device_t, int, int, | ||||
struct resource *); | struct resource *); | ||||
static void nexus_hinted_child(device_t, const char *, int); | static void nexus_hinted_child(device_t, const char *, int); | ||||
static int nexus_setup_intr(device_t dev, device_t child, | static int nexus_setup_intr(device_t dev, device_t child, | ||||
struct resource *res, int flags, driver_filter_t *filt, | struct resource *res, int flags, driver_filter_t *filt, | ||||
driver_intr_t *intr, void *arg, void **cookiep); | driver_intr_t *intr, void *arg, void **cookiep); | ||||
static int nexus_teardown_intr(device_t, device_t, struct resource *, | static int nexus_teardown_intr(device_t, device_t, struct resource *, | ||||
void *); | void *); | ||||
#ifdef MIPS_INTRNG | |||||
#ifdef SMP | |||||
static int nexus_bind_intr(device_t, device_t, struct resource *, int); | |||||
#endif | |||||
#ifdef FDT | |||||
static int nexus_ofw_map_intr(device_t dev, device_t child, | |||||
phandle_t iparent, int icells, pcell_t *intr); | |||||
#endif | |||||
static int nexus_describe_intr(device_t dev, device_t child, | |||||
struct resource *irq, void *cookie, const char *descr); | |||||
static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, | |||||
enum intr_polarity pol); | |||||
#endif | |||||
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, nexus_add_child), | DEVMETHOD(bus_add_child, nexus_add_child), | ||||
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), | DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), | ||||
DEVMETHOD(bus_delete_resource, nexus_delete_resource), | DEVMETHOD(bus_delete_resource, nexus_delete_resource), | ||||
DEVMETHOD(bus_get_resource, nexus_get_resource), | DEVMETHOD(bus_get_resource, nexus_get_resource), | ||||
DEVMETHOD(bus_get_resource_list, nexus_get_reslist), | DEVMETHOD(bus_get_resource_list, nexus_get_reslist), | ||||
DEVMETHOD(bus_print_child, nexus_print_child), | DEVMETHOD(bus_print_child, nexus_print_child), | ||||
DEVMETHOD(bus_release_resource, nexus_release_resource), | DEVMETHOD(bus_release_resource, nexus_release_resource), | ||||
DEVMETHOD(bus_set_resource, nexus_set_resource), | DEVMETHOD(bus_set_resource, nexus_set_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), | ||||
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_hinted_child, nexus_hinted_child), | DEVMETHOD(bus_hinted_child, nexus_hinted_child), | ||||
#ifdef MIPS_INTRNG | |||||
DEVMETHOD(bus_config_intr, nexus_config_intr), | |||||
DEVMETHOD(bus_describe_intr, nexus_describe_intr), | |||||
#ifdef SMP | |||||
DEVMETHOD(bus_bind_intr, nexus_bind_intr), | |||||
#endif | |||||
#ifdef FDT | |||||
DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), | |||||
#endif | |||||
#endif | |||||
{ 0, 0 } | { 0, 0 } | ||||
}; | }; | ||||
static driver_t nexus_driver = { | static driver_t nexus_driver = { | ||||
"nexus", | "nexus", | ||||
nexus_methods, | nexus_methods, | ||||
1 /* no softc */ | 1 /* no softc */ | ||||
▲ Show 20 Lines • Show All 273 Lines • ▼ Show 20 Lines | nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, | ||||
return (rman_deactivate_resource(r)); | return (rman_deactivate_resource(r)); | ||||
} | } | ||||
static int | static int | ||||
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, | nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, | ||||
driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) | driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) | ||||
{ | { | ||||
register_t s; | |||||
int irq; | int irq; | ||||
#ifdef MIPS_INTRNG | |||||
for (irq = rman_get_start(res); irq <= rman_get_end(res); irq++) { | |||||
intr_irq_add_handler(child, filt, intr, arg, irq, flags, | |||||
cookiep); | |||||
} | |||||
#else | |||||
register_t s; | |||||
s = intr_disable(); | s = intr_disable(); | ||||
irq = rman_get_start(res); | irq = rman_get_start(res); | ||||
if (irq >= NUM_MIPS_IRQS) { | if (irq >= NUM_MIPS_IRQS) { | ||||
intr_restore(s); | intr_restore(s); | ||||
return (0); | return (0); | ||||
} | } | ||||
cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg, | cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg, | ||||
irq, flags, cookiep); | irq, flags, cookiep); | ||||
intr_restore(s); | intr_restore(s); | ||||
#endif | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) | nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) | ||||
{ | { | ||||
#ifdef MIPS_INTRNG | |||||
return (intr_irq_remove_handler(child, rman_get_start(r), ih)); | |||||
#else | |||||
printf("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__); | printf("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__); | ||||
return (0); | return (0); | ||||
#endif | |||||
} | } | ||||
#ifdef MIPS_INTRNG | |||||
static int | |||||
nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, | |||||
enum intr_polarity pol) | |||||
{ | |||||
return (intr_irq_config(irq, trig, pol)); | |||||
} | |||||
static int | |||||
nexus_describe_intr(device_t dev, device_t child, struct resource *irq, | |||||
void *cookie, const char *descr) | |||||
{ | |||||
return (intr_irq_describe(rman_get_start(irq), cookie, descr)); | |||||
} | |||||
#ifdef SMP | |||||
static int | |||||
nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) | |||||
{ | |||||
return (intr_irq_bind(rman_get_start(irq), cpu)); | |||||
} | |||||
#endif | |||||
#ifdef FDT | |||||
static int | |||||
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells, | |||||
pcell_t *intr) | |||||
{ | |||||
return (intr_fdt_map_irq(iparent, intr, icells)); | |||||
} | |||||
#endif | |||||
#endif /* MIPS_INTRNG */ | |||||
static void | static void | ||||
nexus_hinted_child(device_t bus, const char *dname, int dunit) | nexus_hinted_child(device_t bus, const char *dname, int dunit) | ||||
{ | { | ||||
device_t child; | device_t child; | ||||
long maddr; | long maddr; | ||||
int msize; | int msize; | ||||
int order; | int order; | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |