Rework how the nexus(4) device works on x86 to better handle the idea of
different "platforms" on x86 machines. The existing code already handles having two platforms: ACPI and legacy. However, the existing approach was rather hardcoded and difficult to extend. These changes take the approach that each x86 hardware platform should provide its own nexus(4) driver (it can inherit most of its behavior from the default legacy nexus(4) driver) which is responsible for probing for the platform and performing appropriate platform-specific setup during attach (such as adding a platform-specific bus device). This does mean changing the x86 platform busses to no longer use an identify routine for probing, but to move that logic into their matching nexus(4) driver instead. - Make the default nexus(4) driver in nexus.c on i386 and amd64 handle the legacy platform. It's probe routine now returns BUS_PROBE_GENERIC so it can be overriden. - Expose a nexus_init_resources() routine which initializes the various resource managers so that subclassed nexus(4) drivers can invoke it from their attach routine. - The legacy nexus(4) driver explicitly adds a legacy0 device in its attach routine. - The ACPI driver no longer contains an new-bus identify method. Instead it exposes a public function (acpi_identify()) which is a probe routine that the MD nexus(4) drivers can use to probe for ACPI. All of the probe logic in acpi_probe() is now moved into acpi_identify() and acpi_probe() is just a stub. - On i386 and amd64, an ACPI-specific nexus(4) driver checks for ACPI via acpi_identify() and claims the nexus0 device if the probe succeeds. It then explicitly adds an acpi0 device in its attach routine. - The legacy(4) driver no longer knows anything about the acpi0 device. - On ia64 if acpi_identify() fails you basically end up with no devices. This matches the previous behavior where the old acpi_identify() would fail to add an acpi0 device again leaving you with no devices. Discussed with: imp Silence on: arch@
This commit is contained in:
parent
6c62df7e49
commit
5217af301c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=177157
@ -29,10 +29,14 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <contrib/dev/acpica/acpi.h>
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
||||
#include <machine/nexusvar.h>
|
||||
|
||||
static int intr_model = ACPI_INTR_PIC;
|
||||
|
||||
int
|
||||
@ -67,3 +71,43 @@ acpi_cpu_c1()
|
||||
{
|
||||
__asm __volatile("sti; hlt");
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI nexus(4) driver.
|
||||
*/
|
||||
static int
|
||||
nexus_acpi_probe(device_t dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = acpi_identify();
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
nexus_acpi_attach(device_t dev)
|
||||
{
|
||||
|
||||
nexus_init_resources();
|
||||
bus_generic_probe(dev);
|
||||
if (BUS_ADD_CHILD(dev, 10, "acpi", 0) == NULL)
|
||||
panic("failed to add acpi0 device");
|
||||
|
||||
return (bus_generic_attach(dev));
|
||||
}
|
||||
|
||||
static device_method_t nexus_acpi_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, nexus_acpi_probe),
|
||||
DEVMETHOD(device_attach, nexus_acpi_attach),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1, nexus_driver);
|
||||
static devclass_t nexus_devclass;
|
||||
|
||||
DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_devclass, 0, 0);
|
||||
|
@ -57,7 +57,6 @@ struct legacy_device {
|
||||
|
||||
#define DEVTOAT(dev) ((struct legacy_device *)device_get_ivars(dev))
|
||||
|
||||
static void legacy_identify(driver_t *driver, device_t parent);
|
||||
static int legacy_probe(device_t);
|
||||
static int legacy_attach(device_t);
|
||||
static int legacy_print_child(device_t, device_t);
|
||||
@ -68,7 +67,6 @@ static int legacy_write_ivar(device_t, device_t, int, uintptr_t);
|
||||
|
||||
static device_method_t legacy_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_identify, legacy_identify),
|
||||
DEVMETHOD(device_probe, legacy_probe),
|
||||
DEVMETHOD(device_attach, legacy_attach),
|
||||
DEVMETHOD(device_detach, bus_generic_detach),
|
||||
@ -100,29 +98,10 @@ static devclass_t legacy_devclass;
|
||||
|
||||
DRIVER_MODULE(legacy, nexus, legacy_driver, legacy_devclass, 0, 0);
|
||||
|
||||
static void
|
||||
legacy_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
|
||||
/*
|
||||
* Add child device with order of 11 so it gets probed
|
||||
* after ACPI (which is at order 10).
|
||||
*/
|
||||
if (BUS_ADD_CHILD(parent, 11, "legacy", 0) == NULL)
|
||||
panic("legacy: could not attach");
|
||||
}
|
||||
|
||||
static int
|
||||
legacy_probe(device_t dev)
|
||||
{
|
||||
device_t acpi;
|
||||
|
||||
/*
|
||||
* Fail to probe if ACPI is ok.
|
||||
*/
|
||||
acpi = devclass_get_device(devclass_find("acpi"), 0);
|
||||
if (acpi != NULL && device_is_alive(acpi))
|
||||
return (ENXIO);
|
||||
device_set_desc(dev, "legacy system");
|
||||
device_quiet(dev);
|
||||
return (0);
|
||||
|
@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/pmap.h>
|
||||
|
||||
#include <machine/metadata.h>
|
||||
#include <machine/nexusvar.h>
|
||||
#include <machine/resource.h>
|
||||
#include <machine/pc/bios.h>
|
||||
|
||||
@ -73,13 +74,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/rtprio.h>
|
||||
|
||||
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
|
||||
struct nexus_device {
|
||||
struct resource_list nx_resources;
|
||||
};
|
||||
|
||||
#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
|
||||
|
||||
static struct rman irq_rman, drq_rman, port_rman, mem_rman;
|
||||
struct rman irq_rman, drq_rman, port_rman, mem_rman;
|
||||
|
||||
static int nexus_probe(device_t);
|
||||
static int nexus_attach(device_t);
|
||||
@ -146,11 +144,7 @@ static device_method_t nexus_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t nexus_driver = {
|
||||
"nexus",
|
||||
nexus_methods,
|
||||
1, /* no softc */
|
||||
};
|
||||
DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, 1);
|
||||
static devclass_t nexus_devclass;
|
||||
|
||||
DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
|
||||
@ -158,9 +152,15 @@ DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
|
||||
static int
|
||||
nexus_probe(device_t dev)
|
||||
{
|
||||
int irq;
|
||||
|
||||
device_quiet(dev); /* suppress attach message for neatness */
|
||||
return (BUS_PROBE_GENERIC);
|
||||
}
|
||||
|
||||
void
|
||||
nexus_init_resources(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
/*
|
||||
* XXX working notes:
|
||||
@ -185,7 +185,7 @@ nexus_probe(device_t dev)
|
||||
irq_rman.rm_descr = "Interrupt request lines";
|
||||
irq_rman.rm_end = NUM_IO_INTS - 1;
|
||||
if (rman_init(&irq_rman))
|
||||
panic("nexus_probe irq_rman");
|
||||
panic("nexus_init_resources irq_rman");
|
||||
|
||||
/*
|
||||
* We search for regions of existing IRQs and add those to the IRQ
|
||||
@ -194,7 +194,7 @@ nexus_probe(device_t dev)
|
||||
for (irq = 0; irq < NUM_IO_INTS; irq++)
|
||||
if (intr_lookup_source(irq) != NULL)
|
||||
if (rman_manage_region(&irq_rman, irq, irq) != 0)
|
||||
panic("nexus_probe irq_rman add");
|
||||
panic("nexus_init_resources irq_rman add");
|
||||
|
||||
/*
|
||||
* ISA DMA on PCI systems is implemented in the ISA part of each
|
||||
@ -209,7 +209,7 @@ nexus_probe(device_t dev)
|
||||
if (rman_init(&drq_rman)
|
||||
|| rman_manage_region(&drq_rman,
|
||||
drq_rman.rm_start, drq_rman.rm_end))
|
||||
panic("nexus_probe drq_rman");
|
||||
panic("nexus_init_resources drq_rman");
|
||||
|
||||
/*
|
||||
* However, IO ports and Memory truely are global at this level,
|
||||
@ -222,7 +222,7 @@ nexus_probe(device_t dev)
|
||||
port_rman.rm_descr = "I/O ports";
|
||||
if (rman_init(&port_rman)
|
||||
|| rman_manage_region(&port_rman, 0, 0xffff))
|
||||
panic("nexus_probe port_rman");
|
||||
panic("nexus_init_resources port_rman");
|
||||
|
||||
mem_rman.rm_start = 0;
|
||||
mem_rman.rm_end = ~0u;
|
||||
@ -230,16 +230,23 @@ nexus_probe(device_t dev)
|
||||
mem_rman.rm_descr = "I/O memory addresses";
|
||||
if (rman_init(&mem_rman)
|
||||
|| rman_manage_region(&mem_rman, 0, ~0))
|
||||
panic("nexus_probe mem_rman");
|
||||
|
||||
return 0;
|
||||
panic("nexus_init_resources mem_rman");
|
||||
}
|
||||
|
||||
static int
|
||||
nexus_attach(device_t dev)
|
||||
{
|
||||
|
||||
nexus_init_resources();
|
||||
bus_generic_probe(dev);
|
||||
|
||||
/*
|
||||
* Explicitly add the legacy0 device here. Other platform
|
||||
* types (such as ACPI), use their own nexus(4) subclass
|
||||
* driver to override this routine and add their own root bus.
|
||||
*/
|
||||
if (BUS_ADD_CHILD(dev, 10, "legacy", 0) == NULL)
|
||||
panic("legacy: could not attach");
|
||||
bus_generic_attach(dev);
|
||||
return 0;
|
||||
}
|
||||
|
45
sys/amd64/include/nexusvar.h
Normal file
45
sys/amd64/include/nexusvar.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_NEXUSVAR_H_
|
||||
#define _MACHINE_NEXUSVAR_H_
|
||||
|
||||
struct nexus_device {
|
||||
struct resource_list nx_resources;
|
||||
};
|
||||
|
||||
DECLARE_CLASS(nexus_driver);
|
||||
|
||||
extern struct rman irq_rman, drq_rman, port_rman, mem_rman;
|
||||
|
||||
void nexus_init_resources(void);
|
||||
|
||||
#endif /* !_MACHINE_NEXUSVAR_H_ */
|
@ -91,7 +91,6 @@ struct mtx acpi_mutex;
|
||||
int acpi_quirks;
|
||||
|
||||
static int acpi_modevent(struct module *mod, int event, void *junk);
|
||||
static void acpi_identify(driver_t *driver, device_t parent);
|
||||
static int acpi_probe(device_t dev);
|
||||
static int acpi_attach(device_t dev);
|
||||
static int acpi_suspend(device_t dev);
|
||||
@ -156,7 +155,6 @@ static int acpi_child_pnpinfo_str_method(device_t acdev, device_t child,
|
||||
|
||||
static device_method_t acpi_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_identify, acpi_identify),
|
||||
DEVMETHOD(device_probe, acpi_probe),
|
||||
DEVMETHOD(device_attach, acpi_attach),
|
||||
DEVMETHOD(device_shutdown, acpi_shutdown),
|
||||
@ -219,6 +217,9 @@ static struct rman acpi_rman_io, acpi_rman_mem;
|
||||
static const char* sleep_state_names[] = {
|
||||
"S0", "S1", "S2", "S3", "S4", "S5", "NONE"};
|
||||
|
||||
/* Holds the description of the acpi0 device. */
|
||||
static char acpi_desc[ACPI_OEM_ID_SIZE + ACPI_OEM_TABLE_ID_SIZE + 2];
|
||||
|
||||
SYSCTL_NODE(_debug, OID_AUTO, acpi, CTLFLAG_RD, NULL, "ACPI debugging");
|
||||
static char acpi_ca_version[12];
|
||||
SYSCTL_STRING(_debug_acpi, OID_AUTO, acpi_ca_version, CTLFLAG_RD,
|
||||
@ -316,39 +317,62 @@ acpi_Startup(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect ACPI, perform early initialisation
|
||||
* Detect ACPI and perform early initialisation.
|
||||
*/
|
||||
static void
|
||||
acpi_identify(driver_t *driver, device_t parent)
|
||||
int
|
||||
acpi_identify(void)
|
||||
{
|
||||
device_t child;
|
||||
ACPI_TABLE_RSDP *rsdp;
|
||||
ACPI_TABLE_HEADER *rsdt;
|
||||
ACPI_PHYSICAL_ADDRESS paddr;
|
||||
struct sbuf sb;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
if (!cold)
|
||||
return_VOID;
|
||||
return (ENXIO);
|
||||
|
||||
/* Check that we haven't been disabled with a hint. */
|
||||
if (resource_disabled("acpi", 0))
|
||||
return_VOID;
|
||||
return (ENXIO);
|
||||
|
||||
/* Make sure we're not being doubly invoked. */
|
||||
if (device_find_child(parent, "acpi", 0) != NULL)
|
||||
return_VOID;
|
||||
|
||||
snprintf(acpi_ca_version, sizeof(acpi_ca_version), "%x", ACPI_CA_VERSION);
|
||||
/* Check for other PM systems. */
|
||||
if (power_pm_get_type() != POWER_PM_TYPE_NONE &&
|
||||
power_pm_get_type() != POWER_PM_TYPE_ACPI) {
|
||||
printf("ACPI identify failed, other PM system enabled.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Initialize root tables. */
|
||||
if (ACPI_FAILURE(acpi_Startup())) {
|
||||
printf("ACPI: Try disabling either ACPI or apic support.\n");
|
||||
return_VOID;
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Attach the actual ACPI device. */
|
||||
if ((child = BUS_ADD_CHILD(parent, 10, "acpi", 0)) == NULL) {
|
||||
device_printf(parent, "device_identify failed\n");
|
||||
return_VOID;
|
||||
}
|
||||
if ((paddr = AcpiOsGetRootPointer()) == 0 ||
|
||||
(rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP))) == NULL)
|
||||
return (ENXIO);
|
||||
if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress != 0)
|
||||
paddr = (ACPI_PHYSICAL_ADDRESS)rsdp->XsdtPhysicalAddress;
|
||||
else
|
||||
paddr = (ACPI_PHYSICAL_ADDRESS)rsdp->RsdtPhysicalAddress;
|
||||
AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP));
|
||||
|
||||
if ((rsdt = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER))) == NULL)
|
||||
return (ENXIO);
|
||||
sbuf_new(&sb, acpi_desc, sizeof(acpi_desc), SBUF_FIXEDLEN);
|
||||
sbuf_bcat(&sb, rsdt->OemId, ACPI_OEM_ID_SIZE);
|
||||
sbuf_trim(&sb);
|
||||
sbuf_putc(&sb, ' ');
|
||||
sbuf_bcat(&sb, rsdt->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
|
||||
sbuf_trim(&sb);
|
||||
sbuf_finish(&sb);
|
||||
sbuf_delete(&sb);
|
||||
AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER));
|
||||
|
||||
snprintf(acpi_ca_version, sizeof(acpi_ca_version), "%x", ACPI_CA_VERSION);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -357,41 +381,10 @@ acpi_identify(driver_t *driver, device_t parent)
|
||||
static int
|
||||
acpi_probe(device_t dev)
|
||||
{
|
||||
ACPI_TABLE_RSDP *rsdp;
|
||||
ACPI_TABLE_HEADER *rsdt;
|
||||
ACPI_PHYSICAL_ADDRESS paddr;
|
||||
char buf[ACPI_OEM_ID_SIZE + ACPI_OEM_TABLE_ID_SIZE + 2];
|
||||
struct sbuf sb;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
if (power_pm_get_type() != POWER_PM_TYPE_NONE &&
|
||||
power_pm_get_type() != POWER_PM_TYPE_ACPI) {
|
||||
device_printf(dev, "probe failed, other PM system enabled.\n");
|
||||
return_VALUE (ENXIO);
|
||||
}
|
||||
|
||||
if ((paddr = AcpiOsGetRootPointer()) == 0 ||
|
||||
(rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP))) == NULL)
|
||||
return_VALUE (ENXIO);
|
||||
if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress != 0)
|
||||
paddr = (ACPI_PHYSICAL_ADDRESS)rsdp->XsdtPhysicalAddress;
|
||||
else
|
||||
paddr = (ACPI_PHYSICAL_ADDRESS)rsdp->RsdtPhysicalAddress;
|
||||
AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP));
|
||||
|
||||
if ((rsdt = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER))) == NULL)
|
||||
return_VALUE (ENXIO);
|
||||
sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN);
|
||||
sbuf_bcat(&sb, rsdt->OemId, ACPI_OEM_ID_SIZE);
|
||||
sbuf_trim(&sb);
|
||||
sbuf_putc(&sb, ' ');
|
||||
sbuf_bcat(&sb, rsdt->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
|
||||
sbuf_trim(&sb);
|
||||
sbuf_finish(&sb);
|
||||
device_set_desc_copy(dev, sbuf_data(&sb));
|
||||
sbuf_delete(&sb);
|
||||
AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER));
|
||||
device_set_desc(dev, acpi_desc);
|
||||
|
||||
return_VALUE (0);
|
||||
}
|
||||
|
@ -364,6 +364,7 @@ struct acpi_parse_resource_set {
|
||||
|
||||
extern struct acpi_parse_resource_set acpi_res_parse_set;
|
||||
|
||||
int acpi_identify(void);
|
||||
void acpi_config_intr(device_t dev, ACPI_RESOURCE *res);
|
||||
ACPI_STATUS acpi_lookup_irq_resource(device_t dev, int rid,
|
||||
struct resource *res, ACPI_RESOURCE *acpi_res);
|
||||
|
@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/uio.h>
|
||||
@ -44,6 +45,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/acpica/acpivar.h>
|
||||
#include <dev/acpica/acpiio.h>
|
||||
|
||||
#include <machine/nexusvar.h>
|
||||
|
||||
/*
|
||||
* APM driver emulation
|
||||
*/
|
||||
@ -549,3 +552,43 @@ acpi_cpu_c1()
|
||||
{
|
||||
__asm __volatile("sti; hlt");
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI nexus(4) driver.
|
||||
*/
|
||||
static int
|
||||
nexus_acpi_probe(device_t dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = acpi_identify();
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
nexus_acpi_attach(device_t dev)
|
||||
{
|
||||
|
||||
nexus_init_resources();
|
||||
bus_generic_probe(dev);
|
||||
if (BUS_ADD_CHILD(dev, 10, "acpi", 0) == NULL)
|
||||
panic("failed to add acpi0 device");
|
||||
|
||||
return (bus_generic_attach(dev));
|
||||
}
|
||||
|
||||
static device_method_t nexus_acpi_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, nexus_acpi_probe),
|
||||
DEVMETHOD(device_attach, nexus_acpi_attach),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1, nexus_driver);
|
||||
static devclass_t nexus_devclass;
|
||||
|
||||
DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_devclass, 0, 0);
|
||||
|
@ -62,7 +62,6 @@ struct legacy_device {
|
||||
|
||||
#define DEVTOAT(dev) ((struct legacy_device *)device_get_ivars(dev))
|
||||
|
||||
static void legacy_identify(driver_t *driver, device_t parent);
|
||||
static int legacy_probe(device_t);
|
||||
static int legacy_attach(device_t);
|
||||
static int legacy_print_child(device_t, device_t);
|
||||
@ -73,7 +72,6 @@ static int legacy_write_ivar(device_t, device_t, int, uintptr_t);
|
||||
|
||||
static device_method_t legacy_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_identify, legacy_identify),
|
||||
DEVMETHOD(device_probe, legacy_probe),
|
||||
DEVMETHOD(device_attach, legacy_attach),
|
||||
DEVMETHOD(device_detach, bus_generic_detach),
|
||||
@ -105,29 +103,10 @@ static devclass_t legacy_devclass;
|
||||
|
||||
DRIVER_MODULE(legacy, nexus, legacy_driver, legacy_devclass, 0, 0);
|
||||
|
||||
static void
|
||||
legacy_identify(driver_t *driver, device_t parent)
|
||||
{
|
||||
|
||||
/*
|
||||
* Add child device with order of 11 so it gets probed
|
||||
* after ACPI (which is at order 10).
|
||||
*/
|
||||
if (BUS_ADD_CHILD(parent, 11, "legacy", 0) == NULL)
|
||||
panic("legacy: could not attach");
|
||||
}
|
||||
|
||||
static int
|
||||
legacy_probe(device_t dev)
|
||||
{
|
||||
device_t acpi;
|
||||
|
||||
/*
|
||||
* Fail to probe if ACPI is ok.
|
||||
*/
|
||||
acpi = devclass_get_device(devclass_find("acpi"), 0);
|
||||
if (acpi != NULL && device_is_alive(acpi))
|
||||
return (ENXIO);
|
||||
device_set_desc(dev, "legacy system");
|
||||
device_quiet(dev);
|
||||
return (0);
|
||||
|
@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
#include <machine/nexusvar.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#ifdef DEV_APIC
|
||||
@ -77,13 +78,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/rtprio.h>
|
||||
|
||||
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
|
||||
struct nexus_device {
|
||||
struct resource_list nx_resources;
|
||||
};
|
||||
|
||||
#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
|
||||
|
||||
static struct rman irq_rman, drq_rman, port_rman, mem_rman;
|
||||
struct rman irq_rman, drq_rman, port_rman, mem_rman;
|
||||
|
||||
static int nexus_probe(device_t);
|
||||
static int nexus_attach(device_t);
|
||||
@ -154,11 +152,7 @@ static device_method_t nexus_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static driver_t nexus_driver = {
|
||||
"nexus",
|
||||
nexus_methods,
|
||||
1, /* no softc */
|
||||
};
|
||||
DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, 1);
|
||||
static devclass_t nexus_devclass;
|
||||
|
||||
DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
|
||||
@ -166,9 +160,15 @@ DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
|
||||
static int
|
||||
nexus_probe(device_t dev)
|
||||
{
|
||||
int irq;
|
||||
|
||||
device_quiet(dev); /* suppress attach message for neatness */
|
||||
return (BUS_PROBE_GENERIC);
|
||||
}
|
||||
|
||||
void
|
||||
nexus_init_resources(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
/*
|
||||
* XXX working notes:
|
||||
@ -193,7 +193,7 @@ nexus_probe(device_t dev)
|
||||
irq_rman.rm_descr = "Interrupt request lines";
|
||||
irq_rman.rm_end = NUM_IO_INTS - 1;
|
||||
if (rman_init(&irq_rman))
|
||||
panic("nexus_probe irq_rman");
|
||||
panic("nexus_init_resources irq_rman");
|
||||
|
||||
/*
|
||||
* We search for regions of existing IRQs and add those to the IRQ
|
||||
@ -202,7 +202,7 @@ nexus_probe(device_t dev)
|
||||
for (irq = 0; irq < NUM_IO_INTS; irq++)
|
||||
if (intr_lookup_source(irq) != NULL)
|
||||
if (rman_manage_region(&irq_rman, irq, irq) != 0)
|
||||
panic("nexus_probe irq_rman add");
|
||||
panic("nexus_init_resources irq_rman add");
|
||||
|
||||
/*
|
||||
* ISA DMA on PCI systems is implemented in the ISA part of each
|
||||
@ -221,7 +221,7 @@ nexus_probe(device_t dev)
|
||||
if (rman_init(&drq_rman)
|
||||
|| rman_manage_region(&drq_rman,
|
||||
drq_rman.rm_start, drq_rman.rm_end))
|
||||
panic("nexus_probe drq_rman");
|
||||
panic("nexus_init_resources drq_rman");
|
||||
|
||||
/*
|
||||
* However, IO ports and Memory truely are global at this level,
|
||||
@ -234,7 +234,7 @@ nexus_probe(device_t dev)
|
||||
port_rman.rm_descr = "I/O ports";
|
||||
if (rman_init(&port_rman)
|
||||
|| rman_manage_region(&port_rman, 0, 0xffff))
|
||||
panic("nexus_probe port_rman");
|
||||
panic("nexus_init_resources port_rman");
|
||||
|
||||
mem_rman.rm_start = 0;
|
||||
mem_rman.rm_end = ~0u;
|
||||
@ -242,16 +242,23 @@ nexus_probe(device_t dev)
|
||||
mem_rman.rm_descr = "I/O memory addresses";
|
||||
if (rman_init(&mem_rman)
|
||||
|| rman_manage_region(&mem_rman, 0, ~0))
|
||||
panic("nexus_probe mem_rman");
|
||||
|
||||
return 0;
|
||||
panic("nexus_init_resources mem_rman");
|
||||
}
|
||||
|
||||
static int
|
||||
nexus_attach(device_t dev)
|
||||
{
|
||||
|
||||
nexus_init_resources();
|
||||
bus_generic_probe(dev);
|
||||
|
||||
/*
|
||||
* Explicitly add the legacy0 device here. Other platform
|
||||
* types (such as ACPI), use their own nexus(4) subclass
|
||||
* driver to override this routine and add their own root bus.
|
||||
*/
|
||||
if (BUS_ADD_CHILD(dev, 10, "legacy", 0) == NULL)
|
||||
panic("legacy: could not attach");
|
||||
bus_generic_attach(dev);
|
||||
return 0;
|
||||
}
|
||||
|
45
sys/i386/include/nexusvar.h
Normal file
45
sys/i386/include/nexusvar.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_NEXUSVAR_H_
|
||||
#define _MACHINE_NEXUSVAR_H_
|
||||
|
||||
struct nexus_device {
|
||||
struct resource_list nx_resources;
|
||||
};
|
||||
|
||||
DECLARE_CLASS(nexus_driver);
|
||||
|
||||
extern struct rman irq_rman, drq_rman, port_rman, mem_rman;
|
||||
|
||||
void nexus_init_resources(void);
|
||||
|
||||
#endif /* !_MACHINE_NEXUSVAR_H_ */
|
@ -60,6 +60,9 @@
|
||||
#include <machine/sapicvar.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
#include <contrib/dev/acpica/acpi.h>
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
||||
#include <isa/isareg.h>
|
||||
#include <sys/rtprio.h>
|
||||
|
||||
@ -217,12 +220,15 @@ nexus_probe(device_t dev)
|
||||
static int
|
||||
nexus_attach(device_t dev)
|
||||
{
|
||||
|
||||
/*
|
||||
* Mask the legacy PICs - we will use the I/O SAPIC for interrupt.
|
||||
*/
|
||||
outb(IO_ICU1+1, 0xff);
|
||||
outb(IO_ICU2+1, 0xff);
|
||||
|
||||
if (acpi_identify() == 0)
|
||||
BUS_ADD_CHILD(dev, 10, "acpi", 0);
|
||||
bus_generic_attach(dev);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user