2005-01-07 02:29:27 +00:00
|
|
|
/*-
|
2001-11-09 20:19:58 +00:00
|
|
|
* Copyright (c) 1999, 2000 Matthew R. Green
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
* Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org>
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
* Copyright (c) 2005 - 2006 Marius Strobl <marius@FreeBSD.org>
|
2001-11-09 20:19:58 +00:00
|
|
|
* 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. The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
|
|
|
|
*
|
2002-02-13 16:07:59 +00:00
|
|
|
* from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
2001-11-09 20:19:58 +00:00
|
|
|
/*
|
2005-12-03 13:08:05 +00:00
|
|
|
* Support for `Hummingbird' (UltraSPARC IIe), `Psycho' and `Psycho+'
|
|
|
|
* (UltraSPARC II) and `Sabre' (UltraSPARC IIi) UPA to PCI bridges.
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
|
|
|
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
#include "opt_ofw_pci.h"
|
2001-11-09 20:19:58 +00:00
|
|
|
#include "opt_psycho.h"
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/bus.h>
|
2007-11-30 23:02:42 +00:00
|
|
|
#include <sys/endian.h>
|
2004-07-10 23:06:41 +00:00
|
|
|
#include <sys/kdb.h>
|
2001-11-09 20:19:58 +00:00
|
|
|
#include <sys/kernel.h>
|
2007-06-16 23:46:41 +00:00
|
|
|
#include <sys/lock.h>
|
2001-11-09 20:19:58 +00:00
|
|
|
#include <sys/malloc.h>
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
#include <sys/module.h>
|
2007-06-16 23:46:41 +00:00
|
|
|
#include <sys/mutex.h>
|
2002-12-01 23:30:26 +00:00
|
|
|
#include <sys/pcpu.h>
|
2005-12-03 16:36:54 +00:00
|
|
|
#include <sys/reboot.h>
|
2007-08-05 11:56:44 +00:00
|
|
|
#include <sys/rman.h>
|
2013-03-02 00:37:31 +00:00
|
|
|
#include <sys/sysctl.h>
|
2001-11-09 20:19:58 +00:00
|
|
|
|
- Introduce an ofw_bus kobj-interface for retrieving the OFW node and a
subset ("compatible", "device_type", "model" and "name") of the standard
properties in drivers for devices on Open Firmware supported busses. The
standard properties "reg", "interrupts" und "address" are not covered by
this interface because they are only of interest in the respective bridge
code. There's a remaining standard property "status" which is unclear how
to support properly but which also isn't used in FreeBSD at present.
This ofw_bus kobj-interface allows to replace the various (ebus_get_node(),
ofw_pci_get_node(), etc.) and partially inconsistent (central_get_type()
vs. sbus_get_device_type(), etc.) existing IVAR ones with a common one.
This in turn allows to simplify and remove code-duplication in drivers for
devices that can hang off of more than one OFW supported bus.
- Convert the sparc64 Central, EBus, FHC, PCI and SBus bus drivers and the
drivers for their children to use the ofw_bus kobj-interface. The IVAR-
interfaces of the Central, EBus and FHC are entirely replaced by this. The
PCI bus driver used its own kobj-interface and now also uses the ofw_bus
one. The IVARs special to the SBus, e.g. for retrieving the burst size,
remain.
Beware: this causes an ABI-breakage for modules of drivers which used the
IVAR-interfaces, i.e. esp(4), hme(4), isp(4) and uart(4), which need to be
recompiled.
The style-inconsistencies introduced in some of the bus drivers will be
fixed by tmm@ in a generic clean-up of the respective drivers later (he
requested to add the changes in the "new" style).
- Convert the powerpc MacIO bus driver and the drivers for its children to
use the ofw_bus kobj-interface. This invloves removing the IVARs related
to the "reg" property which were unused and a leftover from the NetBSD
origini of the code. There's no ABI-breakage caused by this because none
of these driver are currently built as modules.
There are other powerpc bus drivers which can be converted to the ofw_bus
kobj-interface, e.g. the PCI bus driver, which should be done together
with converting powerpc to use the OFW PCI code from sparc64.
- Make the SBus and FHC front-end of zs(4) and the sparc64 eeprom(4) take
advantage of the ofw_bus kobj-interface and simplify them a bit.
Reviewed by: grehan, tmm
Approved by: re (scottl)
Discussed with: tmm
Tested with: Sun AX1105, AXe, Ultra 2, Ultra 60; PPC cross-build on i386
2004-08-12 17:41:33 +00:00
|
|
|
#include <dev/ofw/ofw_bus.h>
|
2003-08-23 00:11:16 +00:00
|
|
|
#include <dev/ofw/ofw_pci.h>
|
- Introduce an ofw_bus kobj-interface for retrieving the OFW node and a
subset ("compatible", "device_type", "model" and "name") of the standard
properties in drivers for devices on Open Firmware supported busses. The
standard properties "reg", "interrupts" und "address" are not covered by
this interface because they are only of interest in the respective bridge
code. There's a remaining standard property "status" which is unclear how
to support properly but which also isn't used in FreeBSD at present.
This ofw_bus kobj-interface allows to replace the various (ebus_get_node(),
ofw_pci_get_node(), etc.) and partially inconsistent (central_get_type()
vs. sbus_get_device_type(), etc.) existing IVAR ones with a common one.
This in turn allows to simplify and remove code-duplication in drivers for
devices that can hang off of more than one OFW supported bus.
- Convert the sparc64 Central, EBus, FHC, PCI and SBus bus drivers and the
drivers for their children to use the ofw_bus kobj-interface. The IVAR-
interfaces of the Central, EBus and FHC are entirely replaced by this. The
PCI bus driver used its own kobj-interface and now also uses the ofw_bus
one. The IVARs special to the SBus, e.g. for retrieving the burst size,
remain.
Beware: this causes an ABI-breakage for modules of drivers which used the
IVAR-interfaces, i.e. esp(4), hme(4), isp(4) and uart(4), which need to be
recompiled.
The style-inconsistencies introduced in some of the bus drivers will be
fixed by tmm@ in a generic clean-up of the respective drivers later (he
requested to add the changes in the "new" style).
- Convert the powerpc MacIO bus driver and the drivers for its children to
use the ofw_bus kobj-interface. This invloves removing the IVARs related
to the "reg" property which were unused and a leftover from the NetBSD
origini of the code. There's no ABI-breakage caused by this because none
of these driver are currently built as modules.
There are other powerpc bus drivers which can be converted to the ofw_bus
kobj-interface, e.g. the PCI bus driver, which should be done together
with converting powerpc to use the OFW PCI code from sparc64.
- Make the SBus and FHC front-end of zs(4) and the sparc64 eeprom(4) take
advantage of the ofw_bus kobj-interface and simplify them a bit.
Reviewed by: grehan, tmm
Approved by: re (scottl)
Discussed with: tmm
Tested with: Sun AX1105, AXe, Ultra 2, Ultra 60; PPC cross-build on i386
2004-08-12 17:41:33 +00:00
|
|
|
#include <dev/ofw/openfirm.h>
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
#include <machine/bus.h>
|
|
|
|
#include <machine/bus_common.h>
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
#include <machine/bus_private.h>
|
2007-01-08 01:26:47 +00:00
|
|
|
#include <machine/iommureg.h>
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
#include <machine/iommuvar.h>
|
2001-11-09 20:19:58 +00:00
|
|
|
#include <machine/resource.h>
|
2005-11-22 22:32:50 +00:00
|
|
|
#include <machine/ver.h>
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2007-01-08 01:26:47 +00:00
|
|
|
#include <dev/pci/pcireg.h>
|
2003-08-22 07:39:05 +00:00
|
|
|
#include <dev/pci/pcivar.h>
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
#include <sparc64/pci/ofw_pci.h>
|
|
|
|
#include <sparc64/pci/psychoreg.h>
|
|
|
|
#include <sparc64/pci/psychovar.h>
|
|
|
|
|
|
|
|
#include "pcib_if.h"
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
static const struct psycho_desc *psycho_find_desc(const struct psycho_desc *,
|
|
|
|
const char *);
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
static const struct psycho_desc *psycho_get_desc(device_t);
|
2007-09-06 19:16:30 +00:00
|
|
|
static void psycho_set_intr(struct psycho_softc *, u_int, bus_addr_t,
|
2013-03-02 13:04:58 +00:00
|
|
|
driver_filter_t, driver_intr_t);
|
2007-09-06 19:16:30 +00:00
|
|
|
static int psycho_find_intrmap(struct psycho_softc *, u_int, bus_addr_t *,
|
2002-02-13 16:07:59 +00:00
|
|
|
bus_addr_t *, u_long *);
|
2011-03-26 16:52:31 +00:00
|
|
|
static void sabre_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map,
|
|
|
|
bus_dmasync_op_t op);
|
2007-09-06 19:16:30 +00:00
|
|
|
static void psycho_intr_enable(void *);
|
|
|
|
static void psycho_intr_disable(void *);
|
2008-04-23 20:04:38 +00:00
|
|
|
static void psycho_intr_assign(void *);
|
|
|
|
static void psycho_intr_clear(void *);
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
/* Interrupt handlers */
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
static driver_filter_t psycho_ue;
|
|
|
|
static driver_filter_t psycho_ce;
|
|
|
|
static driver_filter_t psycho_pci_bus;
|
2013-03-02 00:37:31 +00:00
|
|
|
static driver_filter_t psycho_powerdebug;
|
2013-03-02 13:04:58 +00:00
|
|
|
static driver_intr_t psycho_powerdown;
|
|
|
|
static driver_intr_t psycho_overtemp;
|
2001-11-09 20:19:58 +00:00
|
|
|
#ifdef PSYCHO_MAP_WAKEUP
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
static driver_filter_t psycho_wakeup;
|
2001-11-09 20:19:58 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* IOMMU support */
|
2005-11-22 22:32:50 +00:00
|
|
|
static void psycho_iommu_init(struct psycho_softc *, int, uint32_t);
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
/*
|
2005-11-22 21:34:26 +00:00
|
|
|
* Methods
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
static device_probe_t psycho_probe;
|
|
|
|
static device_attach_t psycho_attach;
|
|
|
|
static bus_read_ivar_t psycho_read_ivar;
|
|
|
|
static bus_setup_intr_t psycho_setup_intr;
|
|
|
|
static bus_alloc_resource_t psycho_alloc_resource;
|
|
|
|
static bus_activate_resource_t psycho_activate_resource;
|
2011-10-02 23:22:38 +00:00
|
|
|
static bus_adjust_resource_t psycho_adjust_resource;
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
static bus_get_dma_tag_t psycho_get_dma_tag;
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
static pcib_maxslots_t psycho_maxslots;
|
|
|
|
static pcib_read_config_t psycho_read_config;
|
|
|
|
static pcib_write_config_t psycho_write_config;
|
|
|
|
static pcib_route_interrupt_t psycho_route_interrupt;
|
- Introduce an ofw_bus kobj-interface for retrieving the OFW node and a
subset ("compatible", "device_type", "model" and "name") of the standard
properties in drivers for devices on Open Firmware supported busses. The
standard properties "reg", "interrupts" und "address" are not covered by
this interface because they are only of interest in the respective bridge
code. There's a remaining standard property "status" which is unclear how
to support properly but which also isn't used in FreeBSD at present.
This ofw_bus kobj-interface allows to replace the various (ebus_get_node(),
ofw_pci_get_node(), etc.) and partially inconsistent (central_get_type()
vs. sbus_get_device_type(), etc.) existing IVAR ones with a common one.
This in turn allows to simplify and remove code-duplication in drivers for
devices that can hang off of more than one OFW supported bus.
- Convert the sparc64 Central, EBus, FHC, PCI and SBus bus drivers and the
drivers for their children to use the ofw_bus kobj-interface. The IVAR-
interfaces of the Central, EBus and FHC are entirely replaced by this. The
PCI bus driver used its own kobj-interface and now also uses the ofw_bus
one. The IVARs special to the SBus, e.g. for retrieving the burst size,
remain.
Beware: this causes an ABI-breakage for modules of drivers which used the
IVAR-interfaces, i.e. esp(4), hme(4), isp(4) and uart(4), which need to be
recompiled.
The style-inconsistencies introduced in some of the bus drivers will be
fixed by tmm@ in a generic clean-up of the respective drivers later (he
requested to add the changes in the "new" style).
- Convert the powerpc MacIO bus driver and the drivers for its children to
use the ofw_bus kobj-interface. This invloves removing the IVARs related
to the "reg" property which were unused and a leftover from the NetBSD
origini of the code. There's no ABI-breakage caused by this because none
of these driver are currently built as modules.
There are other powerpc bus drivers which can be converted to the ofw_bus
kobj-interface, e.g. the PCI bus driver, which should be done together
with converting powerpc to use the OFW PCI code from sparc64.
- Make the SBus and FHC front-end of zs(4) and the sparc64 eeprom(4) take
advantage of the ofw_bus kobj-interface and simplify them a bit.
Reviewed by: grehan, tmm
Approved by: re (scottl)
Discussed with: tmm
Tested with: Sun AX1105, AXe, Ultra 2, Ultra 60; PPC cross-build on i386
2004-08-12 17:41:33 +00:00
|
|
|
static ofw_bus_get_node_t psycho_get_node;
|
2011-03-26 16:52:31 +00:00
|
|
|
static ofw_pci_setup_device_t psycho_setup_device;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
static device_method_t psycho_methods[] = {
|
|
|
|
/* Device interface */
|
|
|
|
DEVMETHOD(device_probe, psycho_probe),
|
|
|
|
DEVMETHOD(device_attach, psycho_attach),
|
2006-01-26 21:14:32 +00:00
|
|
|
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
|
|
|
DEVMETHOD(device_suspend, bus_generic_suspend),
|
|
|
|
DEVMETHOD(device_resume, bus_generic_resume),
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
/* Bus interface */
|
|
|
|
DEVMETHOD(bus_read_ivar, psycho_read_ivar),
|
2005-11-22 21:34:26 +00:00
|
|
|
DEVMETHOD(bus_setup_intr, psycho_setup_intr),
|
2011-03-26 16:52:31 +00:00
|
|
|
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
|
2001-11-09 20:19:58 +00:00
|
|
|
DEVMETHOD(bus_alloc_resource, psycho_alloc_resource),
|
2011-10-02 23:22:38 +00:00
|
|
|
DEVMETHOD(bus_activate_resource, psycho_activate_resource),
|
|
|
|
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
|
|
|
|
DEVMETHOD(bus_adjust_resource, psycho_adjust_resource),
|
|
|
|
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
DEVMETHOD(bus_get_dma_tag, psycho_get_dma_tag),
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
/* pcib interface */
|
|
|
|
DEVMETHOD(pcib_maxslots, psycho_maxslots),
|
|
|
|
DEVMETHOD(pcib_read_config, psycho_read_config),
|
|
|
|
DEVMETHOD(pcib_write_config, psycho_write_config),
|
|
|
|
DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt),
|
|
|
|
|
- Introduce an ofw_bus kobj-interface for retrieving the OFW node and a
subset ("compatible", "device_type", "model" and "name") of the standard
properties in drivers for devices on Open Firmware supported busses. The
standard properties "reg", "interrupts" und "address" are not covered by
this interface because they are only of interest in the respective bridge
code. There's a remaining standard property "status" which is unclear how
to support properly but which also isn't used in FreeBSD at present.
This ofw_bus kobj-interface allows to replace the various (ebus_get_node(),
ofw_pci_get_node(), etc.) and partially inconsistent (central_get_type()
vs. sbus_get_device_type(), etc.) existing IVAR ones with a common one.
This in turn allows to simplify and remove code-duplication in drivers for
devices that can hang off of more than one OFW supported bus.
- Convert the sparc64 Central, EBus, FHC, PCI and SBus bus drivers and the
drivers for their children to use the ofw_bus kobj-interface. The IVAR-
interfaces of the Central, EBus and FHC are entirely replaced by this. The
PCI bus driver used its own kobj-interface and now also uses the ofw_bus
one. The IVARs special to the SBus, e.g. for retrieving the burst size,
remain.
Beware: this causes an ABI-breakage for modules of drivers which used the
IVAR-interfaces, i.e. esp(4), hme(4), isp(4) and uart(4), which need to be
recompiled.
The style-inconsistencies introduced in some of the bus drivers will be
fixed by tmm@ in a generic clean-up of the respective drivers later (he
requested to add the changes in the "new" style).
- Convert the powerpc MacIO bus driver and the drivers for its children to
use the ofw_bus kobj-interface. This invloves removing the IVARs related
to the "reg" property which were unused and a leftover from the NetBSD
origini of the code. There's no ABI-breakage caused by this because none
of these driver are currently built as modules.
There are other powerpc bus drivers which can be converted to the ofw_bus
kobj-interface, e.g. the PCI bus driver, which should be done together
with converting powerpc to use the OFW PCI code from sparc64.
- Make the SBus and FHC front-end of zs(4) and the sparc64 eeprom(4) take
advantage of the ofw_bus kobj-interface and simplify them a bit.
Reviewed by: grehan, tmm
Approved by: re (scottl)
Discussed with: tmm
Tested with: Sun AX1105, AXe, Ultra 2, Ultra 60; PPC cross-build on i386
2004-08-12 17:41:33 +00:00
|
|
|
/* ofw_bus interface */
|
|
|
|
DEVMETHOD(ofw_bus_get_node, psycho_get_node),
|
|
|
|
|
2011-03-26 16:52:31 +00:00
|
|
|
/* ofw_pci interface */
|
|
|
|
DEVMETHOD(ofw_pci_setup_device, psycho_setup_device),
|
|
|
|
|
2011-11-22 21:28:20 +00:00
|
|
|
DEVMETHOD_END
|
2001-11-09 20:19:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static devclass_t psycho_devclass;
|
|
|
|
|
2007-11-30 23:02:42 +00:00
|
|
|
DEFINE_CLASS_0(pcib, psycho_driver, psycho_methods,
|
|
|
|
sizeof(struct psycho_softc));
|
2013-03-02 00:37:31 +00:00
|
|
|
EARLY_DRIVER_MODULE(psycho, nexus, psycho_driver, psycho_devclass, NULL, NULL,
|
2010-11-15 21:58:10 +00:00
|
|
|
BUS_PASS_BUS);
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2013-03-02 00:37:31 +00:00
|
|
|
static SYSCTL_NODE(_hw, OID_AUTO, psycho, CTLFLAG_RD, 0, "psycho parameters");
|
|
|
|
|
|
|
|
static u_int psycho_powerfail = 1;
|
|
|
|
TUNABLE_INT("hw.psycho.powerfail", &psycho_powerfail);
|
|
|
|
SYSCTL_UINT(_hw_psycho, OID_AUTO, powerfail, CTLFLAG_RDTUN, &psycho_powerfail,
|
|
|
|
0, "powerfail action (0: none, 1: shutdown (default), 2: debugger)");
|
|
|
|
|
2007-06-18 21:49:42 +00:00
|
|
|
static SLIST_HEAD(, psycho_softc) psycho_softcs =
|
2002-10-16 17:03:36 +00:00
|
|
|
SLIST_HEAD_INITIALIZER(psycho_softcs);
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2007-09-06 19:16:30 +00:00
|
|
|
static const struct intr_controller psycho_ic = {
|
|
|
|
psycho_intr_enable,
|
|
|
|
psycho_intr_disable,
|
2008-04-23 20:04:38 +00:00
|
|
|
psycho_intr_assign,
|
|
|
|
psycho_intr_clear
|
2007-09-06 19:16:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct psycho_icarg {
|
|
|
|
struct psycho_softc *pica_sc;
|
|
|
|
bus_addr_t pica_map;
|
|
|
|
bus_addr_t pica_clr;
|
|
|
|
};
|
|
|
|
|
2010-03-31 22:19:00 +00:00
|
|
|
#define PSYCHO_READ8(sc, off) \
|
2007-06-16 23:46:41 +00:00
|
|
|
bus_read_8((sc)->sc_mem_res, (off))
|
2010-03-31 22:19:00 +00:00
|
|
|
#define PSYCHO_WRITE8(sc, off, v) \
|
2007-06-16 23:46:41 +00:00
|
|
|
bus_write_8((sc)->sc_mem_res, (off), (v))
|
2010-03-31 22:19:00 +00:00
|
|
|
#define PCICTL_READ8(sc, off) \
|
2002-02-13 16:07:59 +00:00
|
|
|
PSYCHO_READ8((sc), (sc)->sc_pcictl + (off))
|
2010-03-31 22:19:00 +00:00
|
|
|
#define PCICTL_WRITE8(sc, off, v) \
|
2002-02-13 16:07:59 +00:00
|
|
|
PSYCHO_WRITE8((sc), (sc)->sc_pcictl + (off), (v))
|
|
|
|
|
2001-11-09 20:19:58 +00:00
|
|
|
/*
|
2005-11-22 21:34:26 +00:00
|
|
|
* "Sabre" is the UltraSPARC IIi onboard UPA to PCI bridge. It manages a
|
2001-11-09 20:19:58 +00:00
|
|
|
* single PCI bus and does not have a streaming buffer. It often has an APB
|
|
|
|
* (advanced PCI bridge) connected to it, which was designed specifically for
|
2013-03-07 13:24:49 +00:00
|
|
|
* the IIi. The APB lets the IIi handle two independent PCI buses, and
|
2005-11-22 21:34:26 +00:00
|
|
|
* appears as two "Simba"'s underneath the Sabre.
|
2001-11-09 20:19:58 +00:00
|
|
|
*
|
2005-12-03 13:08:05 +00:00
|
|
|
* "Hummingbird" is the UltraSPARC IIe onboard UPA to PCI bridge. It's
|
|
|
|
* basically the same as Sabre but without an APB underneath it.
|
|
|
|
*
|
2009-12-29 14:03:38 +00:00
|
|
|
* "Psycho" and "Psycho+" are dual UPA to PCI bridges. They sit on the UPA
|
|
|
|
* bus and manage two PCI buses. "Psycho" has two 64-bit 33MHz buses, while
|
2005-11-22 21:34:26 +00:00
|
|
|
* "Psycho+" controls both a 64-bit 33Mhz and a 64-bit 66Mhz PCI bus. You
|
|
|
|
* will usually find a "Psycho+" since I don't think the original "Psycho"
|
2001-12-21 21:35:47 +00:00
|
|
|
* ever shipped, and if it did it would be in the U30.
|
2001-11-09 20:19:58 +00:00
|
|
|
*
|
2005-11-22 21:34:26 +00:00
|
|
|
* Each "Psycho" PCI bus appears as a separate OFW node, but since they are
|
2001-11-09 20:19:58 +00:00
|
|
|
* both part of the same IC, they only have a single register space. As such,
|
|
|
|
* they need to be configured together, even though the autoconfiguration will
|
|
|
|
* attach them separately.
|
|
|
|
*
|
2005-11-22 21:34:26 +00:00
|
|
|
* On UltraIIi machines, "Sabre" itself usually takes pci0, with "Simba" often
|
2001-11-09 20:19:58 +00:00
|
|
|
* as pci1 and pci2, although they have been implemented with other PCI bus
|
|
|
|
* numbers on some machines.
|
|
|
|
*
|
2005-11-22 21:34:26 +00:00
|
|
|
* On UltraII machines, there can be any number of "Psycho+" ICs, each
|
2001-12-21 21:35:47 +00:00
|
|
|
* providing two PCI buses.
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
2007-02-23 12:19:07 +00:00
|
|
|
|
2002-10-16 17:37:50 +00:00
|
|
|
struct psycho_desc {
|
2005-11-22 21:34:26 +00:00
|
|
|
const char *pd_string;
|
|
|
|
int pd_mode;
|
|
|
|
const char *pd_name;
|
2002-10-16 17:37:50 +00:00
|
|
|
};
|
|
|
|
|
2012-11-05 19:16:27 +00:00
|
|
|
static const struct psycho_desc psycho_compats[] = {
|
2002-10-16 17:37:50 +00:00
|
|
|
{ "pci108e,8000", PSYCHO_MODE_PSYCHO, "Psycho compatible" },
|
2005-12-03 13:08:05 +00:00
|
|
|
{ "pci108e,a000", PSYCHO_MODE_SABRE, "Sabre compatible" },
|
|
|
|
{ "pci108e,a001", PSYCHO_MODE_SABRE, "Hummingbird compatible" },
|
2002-10-16 17:37:50 +00:00
|
|
|
{ NULL, 0, NULL }
|
|
|
|
};
|
|
|
|
|
2012-11-05 19:16:27 +00:00
|
|
|
static const struct psycho_desc psycho_models[] = {
|
2002-10-16 17:37:50 +00:00
|
|
|
{ "SUNW,psycho", PSYCHO_MODE_PSYCHO, "Psycho" },
|
|
|
|
{ "SUNW,sabre", PSYCHO_MODE_SABRE, "Sabre" },
|
|
|
|
{ NULL, 0, NULL }
|
|
|
|
};
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
static const struct psycho_desc *
|
|
|
|
psycho_find_desc(const struct psycho_desc *table, const char *string)
|
2002-10-16 17:37:50 +00:00
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
const struct psycho_desc *desc;
|
2002-10-16 17:37:50 +00:00
|
|
|
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
if (string == NULL)
|
|
|
|
return (NULL);
|
|
|
|
for (desc = table; desc->pd_string != NULL; desc++)
|
2002-10-16 17:37:50 +00:00
|
|
|
if (strcmp(desc->pd_string, string) == 0)
|
|
|
|
return (desc);
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
static const struct psycho_desc *
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
psycho_get_desc(device_t dev)
|
2002-10-16 17:37:50 +00:00
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
const struct psycho_desc *rv;
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
|
|
|
|
rv = psycho_find_desc(psycho_models, ofw_bus_get_model(dev));
|
|
|
|
if (rv == NULL)
|
2009-12-29 14:03:38 +00:00
|
|
|
rv = psycho_find_desc(psycho_compats,
|
|
|
|
ofw_bus_get_compat(dev));
|
2002-10-16 17:37:50 +00:00
|
|
|
return (rv);
|
|
|
|
}
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
psycho_probe(device_t dev)
|
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
const char *dtype;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
dtype = ofw_bus_get_type(dev);
|
2009-09-13 14:47:31 +00:00
|
|
|
if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCI) == 0 &&
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
psycho_get_desc(dev) != NULL) {
|
2001-11-09 20:19:58 +00:00
|
|
|
device_set_desc(dev, "U2P UPA-PCI bridge");
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
return (ENXIO);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
psycho_attach(device_t dev)
|
|
|
|
{
|
2007-09-06 19:16:30 +00:00
|
|
|
struct psycho_icarg *pica;
|
2007-01-08 01:26:47 +00:00
|
|
|
struct psycho_softc *asc, *sc, *osc;
|
2005-12-03 19:52:20 +00:00
|
|
|
struct ofw_pci_ranges *range;
|
2005-11-22 21:34:26 +00:00
|
|
|
const struct psycho_desc *desc;
|
2007-09-06 19:16:30 +00:00
|
|
|
bus_addr_t intrclr, intrmap;
|
2007-01-08 01:26:47 +00:00
|
|
|
uint64_t csr, dr;
|
2011-03-26 16:52:31 +00:00
|
|
|
phandle_t node;
|
2008-08-24 16:22:04 +00:00
|
|
|
uint32_t dvmabase, prop, prop_array[2];
|
2009-03-19 20:52:46 +00:00
|
|
|
u_int rerun, ver;
|
2009-12-29 14:03:38 +00:00
|
|
|
int i, j;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
node = ofw_bus_get_node(dev);
|
2001-11-09 20:19:58 +00:00
|
|
|
sc = device_get_softc(dev);
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
desc = psycho_get_desc(dev);
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
sc->sc_node = node;
|
|
|
|
sc->sc_dev = dev;
|
2002-10-16 17:37:50 +00:00
|
|
|
sc->sc_mode = desc->pd_mode;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
/*
|
2005-11-22 21:34:26 +00:00
|
|
|
* The Psycho gets three register banks:
|
2001-11-09 20:19:58 +00:00
|
|
|
* (0) per-PBM configuration and status registers
|
|
|
|
* (1) per-PBM PCI configuration space, containing only the
|
|
|
|
* PBM 256-byte PCI header
|
2005-11-22 21:34:26 +00:00
|
|
|
* (2) the shared Psycho configuration registers
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
|
|
|
if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
|
2009-03-19 20:52:46 +00:00
|
|
|
i = 2;
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
sc->sc_pcictl =
|
|
|
|
bus_get_resource_start(dev, SYS_RES_MEMORY, 0) -
|
|
|
|
bus_get_resource_start(dev, SYS_RES_MEMORY, 2);
|
Fix interrupt assignment for non-builtin PCI devices on e450s.
This machine uses a non-standard scheme to specify the interrupts to
be assigned for devices in PCI slots; instead of giving the INO
or full interrupt number (which is done for the other devices in this
box), the firmware interrupt properties contain intpin numbers, which
have to be swizzled as usual on PCI-PCI bridges; however, the PCI host
bridge nodes have no interrupt map, so we need to guess the
correct INO by slot number of the device or the closest PCI-PCI
bridge leading to it, and the intpin.
To do this, this fix makes the following changes:
- Add a newbus method for sparc64 PCI host bridges to guess
the INO, and glue code in ofw_pci_orb_callback() to invoke it based
on a new quirk entry. The guessing is only done for interrupt numbers
too low to contain any IGN found on e450s.
- Create another new quirk entry was created to prevent mapping of EBus
interrupts at PCI level; the e450 has full INOs in the interrupt
properties of EBus devices, so trying to remap them could cause
problems.
- Set both quirk entries for e450s; remove the no-swizzle entry.
- Determine the psycho half (bus A or B) a driver instance manages
in psycho_attach()
- Implement the new guessing method for psycho, using the slot number,
psycho half and property value (intpin).
Thanks go to the testers, especially Brian Denehy, who tested many kernels
for me until I had found the right workaround.
Tested by: Brian Denehy <B.Denehy@90east.com>, jake, fenner,
Marius Strobl <marius@alchemy.franken.de>,
Marian Dobre <mari@onix.ro>
Approved by: re (scottl)
2003-05-30 20:48:05 +00:00
|
|
|
switch (sc->sc_pcictl) {
|
|
|
|
case PSR_PCICTL0:
|
|
|
|
sc->sc_half = 0;
|
|
|
|
break;
|
|
|
|
case PSR_PCICTL1:
|
|
|
|
sc->sc_half = 1;
|
|
|
|
break;
|
|
|
|
default:
|
2005-11-22 21:34:26 +00:00
|
|
|
panic("%s: bogus PCI control register location",
|
|
|
|
__func__);
|
2008-08-22 20:28:19 +00:00
|
|
|
/* NOTREACHED */
|
Fix interrupt assignment for non-builtin PCI devices on e450s.
This machine uses a non-standard scheme to specify the interrupts to
be assigned for devices in PCI slots; instead of giving the INO
or full interrupt number (which is done for the other devices in this
box), the firmware interrupt properties contain intpin numbers, which
have to be swizzled as usual on PCI-PCI bridges; however, the PCI host
bridge nodes have no interrupt map, so we need to guess the
correct INO by slot number of the device or the closest PCI-PCI
bridge leading to it, and the intpin.
To do this, this fix makes the following changes:
- Add a newbus method for sparc64 PCI host bridges to guess
the INO, and glue code in ofw_pci_orb_callback() to invoke it based
on a new quirk entry. The guessing is only done for interrupt numbers
too low to contain any IGN found on e450s.
- Create another new quirk entry was created to prevent mapping of EBus
interrupts at PCI level; the e450 has full INOs in the interrupt
properties of EBus devices, so trying to remap them could cause
problems.
- Set both quirk entries for e450s; remove the no-swizzle entry.
- Determine the psycho half (bus A or B) a driver instance manages
in psycho_attach()
- Implement the new guessing method for psycho, using the slot number,
psycho half and property value (intpin).
Thanks go to the testers, especially Brian Denehy, who tested many kernels
for me until I had found the right workaround.
Tested by: Brian Denehy <B.Denehy@90east.com>, jake, fenner,
Marius Strobl <marius@alchemy.franken.de>,
Marian Dobre <mari@onix.ro>
Approved by: re (scottl)
2003-05-30 20:48:05 +00:00
|
|
|
}
|
2001-11-09 20:19:58 +00:00
|
|
|
} else {
|
2009-03-19 20:52:46 +00:00
|
|
|
i = 0;
|
Fix interrupt assignment for non-builtin PCI devices on e450s.
This machine uses a non-standard scheme to specify the interrupts to
be assigned for devices in PCI slots; instead of giving the INO
or full interrupt number (which is done for the other devices in this
box), the firmware interrupt properties contain intpin numbers, which
have to be swizzled as usual on PCI-PCI bridges; however, the PCI host
bridge nodes have no interrupt map, so we need to guess the
correct INO by slot number of the device or the closest PCI-PCI
bridge leading to it, and the intpin.
To do this, this fix makes the following changes:
- Add a newbus method for sparc64 PCI host bridges to guess
the INO, and glue code in ofw_pci_orb_callback() to invoke it based
on a new quirk entry. The guessing is only done for interrupt numbers
too low to contain any IGN found on e450s.
- Create another new quirk entry was created to prevent mapping of EBus
interrupts at PCI level; the e450 has full INOs in the interrupt
properties of EBus devices, so trying to remap them could cause
problems.
- Set both quirk entries for e450s; remove the no-swizzle entry.
- Determine the psycho half (bus A or B) a driver instance manages
in psycho_attach()
- Implement the new guessing method for psycho, using the slot number,
psycho half and property value (intpin).
Thanks go to the testers, especially Brian Denehy, who tested many kernels
for me until I had found the right workaround.
Tested by: Brian Denehy <B.Denehy@90east.com>, jake, fenner,
Marius Strobl <marius@alchemy.franken.de>,
Marian Dobre <mari@onix.ro>
Approved by: re (scottl)
2003-05-30 20:48:05 +00:00
|
|
|
sc->sc_pcictl = PSR_PCICTL0;
|
|
|
|
sc->sc_half = 0;
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
2009-03-19 20:52:46 +00:00
|
|
|
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i,
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
(sc->sc_mode == PSYCHO_MODE_PSYCHO ? RF_SHAREABLE : 0) |
|
|
|
|
RF_ACTIVE);
|
|
|
|
if (sc->sc_mem_res == NULL)
|
|
|
|
panic("%s: could not allocate registers", __func__);
|
2001-11-09 20:19:58 +00:00
|
|
|
|
|
|
|
/*
|
2009-03-19 20:52:46 +00:00
|
|
|
* Match other Psychos that are already configured against
|
2008-05-07 21:22:15 +00:00
|
|
|
* the base physical address. This will be the same for a
|
2001-11-09 20:19:58 +00:00
|
|
|
* pair of devices that share register space.
|
|
|
|
*/
|
2007-01-08 01:26:47 +00:00
|
|
|
osc = NULL;
|
2002-10-16 17:03:36 +00:00
|
|
|
SLIST_FOREACH(asc, &psycho_softcs, sc_link) {
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
if (rman_get_start(asc->sc_mem_res) ==
|
|
|
|
rman_get_start(sc->sc_mem_res)) {
|
2005-11-22 21:34:26 +00:00
|
|
|
/* Found partner. */
|
2002-10-16 17:03:36 +00:00
|
|
|
osc = asc;
|
|
|
|
break;
|
|
|
|
}
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
2007-06-16 23:46:41 +00:00
|
|
|
if (osc == NULL) {
|
|
|
|
sc->sc_mtx = malloc(sizeof(*sc->sc_mtx), M_DEVBUF,
|
|
|
|
M_NOWAIT | M_ZERO);
|
|
|
|
if (sc->sc_mtx == NULL)
|
|
|
|
panic("%s: could not malloc mutex", __func__);
|
|
|
|
mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN);
|
|
|
|
} else {
|
2009-03-19 20:52:46 +00:00
|
|
|
if (sc->sc_mode != PSYCHO_MODE_PSYCHO)
|
|
|
|
panic("%s: no partner expected", __func__);
|
2007-06-16 23:46:41 +00:00
|
|
|
if (mtx_initialized(osc->sc_mtx) == 0)
|
|
|
|
panic("%s: mutex not initialized", __func__);
|
|
|
|
sc->sc_mtx = osc->sc_mtx;
|
|
|
|
}
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2002-02-13 16:07:59 +00:00
|
|
|
csr = PSYCHO_READ8(sc, PSR_CS);
|
2007-01-08 01:26:47 +00:00
|
|
|
ver = PSYCHO_GCSR_VERS(csr);
|
2007-09-06 19:16:30 +00:00
|
|
|
sc->sc_ign = 0x1f; /* Hummingbird/Sabre IGN is always 0x1f. */
|
2002-02-13 16:07:59 +00:00
|
|
|
if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
|
2007-09-06 19:16:30 +00:00
|
|
|
sc->sc_ign = PSYCHO_GCSR_IGN(csr);
|
2008-08-24 16:22:04 +00:00
|
|
|
if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1)
|
|
|
|
prop = 33000000;
|
2002-02-13 16:07:59 +00:00
|
|
|
|
2008-08-24 16:22:04 +00:00
|
|
|
device_printf(dev,
|
|
|
|
"%s, impl %d, version %d, IGN %#x, bus %c, %dMHz\n",
|
2007-01-08 01:26:47 +00:00
|
|
|
desc->pd_name, (u_int)PSYCHO_GCSR_IMPL(csr), ver, sc->sc_ign,
|
2008-08-24 16:22:04 +00:00
|
|
|
'A' + sc->sc_half, prop / 1000 / 1000);
|
2007-01-08 01:26:47 +00:00
|
|
|
|
|
|
|
/* Set up the PCI control and PCI diagnostic registers. */
|
2002-02-13 16:07:59 +00:00
|
|
|
|
|
|
|
csr = PCICTL_READ8(sc, PCR_CS);
|
2007-01-08 01:26:47 +00:00
|
|
|
csr &= ~PCICTL_ARB_PARK;
|
2011-03-26 16:52:31 +00:00
|
|
|
if (OF_getproplen(node, "no-bus-parking") < 0)
|
2007-01-08 01:26:47 +00:00
|
|
|
csr |= PCICTL_ARB_PARK;
|
|
|
|
|
|
|
|
/* Workarounds for version specific bugs. */
|
|
|
|
dr = PCICTL_READ8(sc, PCR_DIAG);
|
|
|
|
switch (ver) {
|
|
|
|
case 0:
|
|
|
|
dr |= DIAG_RTRY_DIS;
|
|
|
|
dr &= ~DIAG_DWSYNC_DIS;
|
2009-03-19 20:52:46 +00:00
|
|
|
rerun = 0;
|
2007-01-08 01:26:47 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
csr &= ~PCICTL_ARB_PARK;
|
|
|
|
dr |= DIAG_RTRY_DIS | DIAG_DWSYNC_DIS;
|
2009-03-19 20:52:46 +00:00
|
|
|
rerun = 0;
|
2007-01-08 01:26:47 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
dr |= DIAG_DWSYNC_DIS;
|
|
|
|
dr &= ~DIAG_RTRY_DIS;
|
2009-03-19 20:52:46 +00:00
|
|
|
rerun = 1;
|
2007-01-08 01:26:47 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-09-18 19:45:22 +00:00
|
|
|
csr |= PCICTL_ERRINTEN | PCICTL_ARB_4;
|
2007-01-08 01:26:47 +00:00
|
|
|
csr &= ~(PCICTL_SBHINTEN | PCICTL_WAKEUPEN);
|
|
|
|
#ifdef PSYCHO_DEBUG
|
|
|
|
device_printf(dev, "PCI CSR 0x%016llx -> 0x%016llx\n",
|
|
|
|
(unsigned long long)PCICTL_READ8(sc, PCR_CS),
|
|
|
|
(unsigned long long)csr);
|
|
|
|
#endif
|
2002-02-13 16:07:59 +00:00
|
|
|
PCICTL_WRITE8(sc, PCR_CS, csr);
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2007-01-08 01:26:47 +00:00
|
|
|
dr &= ~DIAG_ISYNC_DIS;
|
|
|
|
#ifdef PSYCHO_DEBUG
|
|
|
|
device_printf(dev, "PCI DR 0x%016llx -> 0x%016llx\n",
|
|
|
|
(unsigned long long)PCICTL_READ8(sc, PCR_DIAG),
|
|
|
|
(unsigned long long)dr);
|
|
|
|
#endif
|
|
|
|
PCICTL_WRITE8(sc, PCR_DIAG, dr);
|
|
|
|
|
2003-01-06 16:51:06 +00:00
|
|
|
if (sc->sc_mode == PSYCHO_MODE_SABRE) {
|
2004-04-25 00:30:28 +00:00
|
|
|
/* Use the PROM preset for now. */
|
2003-01-06 16:51:06 +00:00
|
|
|
csr = PCICTL_READ8(sc, PCR_TAS);
|
|
|
|
if (csr == 0)
|
2005-12-03 13:08:05 +00:00
|
|
|
panic("%s: Hummingbird/Sabre TAS not initialized.",
|
|
|
|
__func__);
|
2005-11-22 22:32:50 +00:00
|
|
|
dvmabase = (ffs(csr) - 1) << PCITAS_ADDR_SHIFT;
|
2003-01-06 16:51:06 +00:00
|
|
|
} else
|
2005-11-22 22:32:50 +00:00
|
|
|
dvmabase = -1;
|
2003-01-06 16:51:06 +00:00
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
/* Initialize memory and I/O rmans. */
|
|
|
|
sc->sc_pci_io_rman.rm_type = RMAN_ARRAY;
|
|
|
|
sc->sc_pci_io_rman.rm_descr = "Psycho PCI I/O Ports";
|
|
|
|
if (rman_init(&sc->sc_pci_io_rman) != 0 ||
|
|
|
|
rman_manage_region(&sc->sc_pci_io_rman, 0, PSYCHO_IO_SIZE) != 0)
|
|
|
|
panic("%s: failed to set up I/O rman", __func__);
|
|
|
|
sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY;
|
|
|
|
sc->sc_pci_mem_rman.rm_descr = "Psycho PCI Memory";
|
|
|
|
if (rman_init(&sc->sc_pci_mem_rman) != 0 ||
|
|
|
|
rman_manage_region(&sc->sc_pci_mem_rman, 0, PSYCHO_MEM_SIZE) != 0)
|
|
|
|
panic("%s: failed to set up memory rman", __func__);
|
|
|
|
|
2009-12-29 14:03:38 +00:00
|
|
|
i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range);
|
2005-11-22 22:32:50 +00:00
|
|
|
/*
|
2008-05-07 21:22:15 +00:00
|
|
|
* Make sure that the expected ranges are present. The
|
|
|
|
* OFW_PCI_CS_MEM64 one is not currently used though.
|
2005-11-22 22:32:50 +00:00
|
|
|
*/
|
2009-12-29 14:03:38 +00:00
|
|
|
if (i != PSYCHO_NRANGE)
|
2005-11-22 22:32:50 +00:00
|
|
|
panic("%s: unsupported number of ranges", __func__);
|
2001-11-09 20:19:58 +00:00
|
|
|
/*
|
|
|
|
* Find the addresses of the various bus spaces.
|
|
|
|
* There should not be multiple ones of one kind.
|
|
|
|
* The physical start addresses of the ranges are the configuration,
|
2005-11-22 21:34:26 +00:00
|
|
|
* memory and I/O handles.
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
2009-12-29 14:03:38 +00:00
|
|
|
for (i = 0; i < PSYCHO_NRANGE; i++) {
|
|
|
|
j = OFW_PCI_RANGE_CS(&range[i]);
|
|
|
|
if (sc->sc_pci_bh[j] != 0)
|
|
|
|
panic("%s: duplicate range for space %d",
|
|
|
|
__func__, j);
|
|
|
|
sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
2005-11-22 22:32:50 +00:00
|
|
|
free(range, M_OFWPROP);
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
/* Register the softc, this is needed for paired Psychos. */
|
2002-10-16 17:03:36 +00:00
|
|
|
SLIST_INSERT_HEAD(&psycho_softcs, sc, sc_link);
|
|
|
|
|
2005-12-03 16:36:54 +00:00
|
|
|
/*
|
2007-09-06 19:16:30 +00:00
|
|
|
* If we're a Hummingbird/Sabre or the first of a pair of Psychos
|
|
|
|
* to arrive here, do the interrupt setup and start up the IOMMU.
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
|
|
|
if (osc == NULL) {
|
2007-09-06 19:16:30 +00:00
|
|
|
/*
|
|
|
|
* Hunt through all the interrupt mapping regs and register
|
|
|
|
* our interrupt controller for the corresponding interrupt
|
2009-03-19 20:52:46 +00:00
|
|
|
* vectors. We do this early in order to be able to catch
|
|
|
|
* stray interrupts.
|
2007-09-06 19:16:30 +00:00
|
|
|
*/
|
2009-12-29 14:03:38 +00:00
|
|
|
for (i = 0; i <= PSYCHO_MAX_INO; i++) {
|
|
|
|
if (psycho_find_intrmap(sc, i, &intrmap, &intrclr,
|
2007-09-06 19:16:30 +00:00
|
|
|
NULL) == 0)
|
|
|
|
continue;
|
|
|
|
pica = malloc(sizeof(*pica), M_DEVBUF, M_NOWAIT);
|
|
|
|
if (pica == NULL)
|
|
|
|
panic("%s: could not allocate interrupt "
|
|
|
|
"controller argument", __func__);
|
|
|
|
pica->pica_sc = sc;
|
|
|
|
pica->pica_map = intrmap;
|
|
|
|
pica->pica_clr = intrclr;
|
|
|
|
#ifdef PSYCHO_DEBUG
|
|
|
|
/*
|
|
|
|
* Enable all interrupts and clear all interrupt
|
2008-05-07 21:22:15 +00:00
|
|
|
* states. This aids the debugging of interrupt
|
2007-09-06 19:16:30 +00:00
|
|
|
* routing problems.
|
|
|
|
*/
|
|
|
|
device_printf(dev,
|
|
|
|
"intr map (INO %d, %s) %#lx: %#lx, clr: %#lx\n",
|
2009-12-29 14:03:38 +00:00
|
|
|
i, intrmap <= PSR_PCIB3_INT_MAP ? "PCI" : "OBIO",
|
|
|
|
(u_long)intrmap, (u_long)PSYCHO_READ8(sc,
|
|
|
|
intrmap), (u_long)intrclr);
|
|
|
|
PSYCHO_WRITE8(sc, intrmap, INTMAP_VEC(sc->sc_ign, i));
|
2010-03-31 22:19:00 +00:00
|
|
|
PSYCHO_WRITE8(sc, intrclr, INTCLR_IDLE);
|
2007-09-06 19:16:30 +00:00
|
|
|
PSYCHO_WRITE8(sc, intrmap,
|
2009-12-29 14:03:38 +00:00
|
|
|
INTMAP_ENABLE(INTMAP_VEC(sc->sc_ign, i),
|
2007-09-06 19:16:30 +00:00
|
|
|
PCPU_GET(mid)));
|
|
|
|
#endif
|
2009-12-29 14:03:38 +00:00
|
|
|
j = intr_controller_register(INTMAP_VEC(sc->sc_ign,
|
|
|
|
i), &psycho_ic, pica);
|
|
|
|
if (j != 0)
|
2009-03-19 20:52:46 +00:00
|
|
|
device_printf(dev, "could not register "
|
|
|
|
"interrupt controller for INO %d (%d)\n",
|
2009-12-29 14:03:38 +00:00
|
|
|
i, j);
|
2007-09-06 19:16:30 +00:00
|
|
|
}
|
|
|
|
|
2009-03-19 20:52:46 +00:00
|
|
|
if (sc->sc_mode == PSYCHO_MODE_PSYCHO)
|
2008-05-07 21:22:15 +00:00
|
|
|
sparc64_counter_init(device_get_nameunit(dev),
|
|
|
|
rman_get_bustag(sc->sc_mem_res),
|
2007-06-16 23:46:41 +00:00
|
|
|
rman_get_bushandle(sc->sc_mem_res), PSR_TC0);
|
2002-02-13 16:07:59 +00:00
|
|
|
|
2001-11-09 20:19:58 +00:00
|
|
|
/*
|
2007-01-08 01:26:47 +00:00
|
|
|
* Set up IOMMU and PCI configuration if we're the first
|
2009-03-19 20:52:46 +00:00
|
|
|
* of a pair of Psychos to arrive here or a Hummingbird
|
|
|
|
* or Sabre.
|
2001-11-09 20:19:58 +00:00
|
|
|
*
|
|
|
|
* We should calculate a TSB size based on amount of RAM
|
2002-12-30 21:18:15 +00:00
|
|
|
* and number of bus controllers and number and type of
|
2001-11-09 20:19:58 +00:00
|
|
|
* child devices.
|
|
|
|
*
|
|
|
|
* For the moment, 32KB should be more than enough.
|
|
|
|
*/
|
2011-03-29 19:48:03 +00:00
|
|
|
sc->sc_is = malloc(sizeof(*sc->sc_is), M_DEVBUF, M_NOWAIT |
|
|
|
|
M_ZERO);
|
2002-02-13 16:07:59 +00:00
|
|
|
if (sc->sc_is == NULL)
|
2011-03-29 19:48:03 +00:00
|
|
|
panic("%s: could not malloc IOMMU state", __func__);
|
2010-01-02 15:19:33 +00:00
|
|
|
sc->sc_is->is_flags = IOMMU_PRESERVE_PROM;
|
2011-03-26 16:52:31 +00:00
|
|
|
if (sc->sc_mode == PSYCHO_MODE_SABRE) {
|
2011-03-29 19:48:03 +00:00
|
|
|
sc->sc_dma_methods =
|
|
|
|
malloc(sizeof(*sc->sc_dma_methods), M_DEVBUF,
|
|
|
|
M_NOWAIT);
|
|
|
|
if (sc->sc_dma_methods == NULL)
|
|
|
|
panic("%s: could not malloc DMA methods",
|
|
|
|
__func__);
|
|
|
|
memcpy(sc->sc_dma_methods, &iommu_dma_methods,
|
|
|
|
sizeof(*sc->sc_dma_methods));
|
|
|
|
sc->sc_dma_methods->dm_dmamap_sync =
|
2011-03-26 16:52:31 +00:00
|
|
|
sabre_dmamap_sync;
|
2007-08-05 11:56:44 +00:00
|
|
|
sc->sc_is->is_pmaxaddr =
|
|
|
|
IOMMU_MAXADDR(SABRE_IOMMU_BITS);
|
2011-03-29 19:48:03 +00:00
|
|
|
} else {
|
|
|
|
sc->sc_dma_methods = &iommu_dma_methods;
|
2007-08-05 11:56:44 +00:00
|
|
|
sc->sc_is->is_pmaxaddr =
|
|
|
|
IOMMU_MAXADDR(PSYCHO_IOMMU_BITS);
|
2011-03-29 19:48:03 +00:00
|
|
|
}
|
2009-03-19 20:52:46 +00:00
|
|
|
sc->sc_is->is_sb[0] = sc->sc_is->is_sb[1] = 0;
|
2005-11-22 21:34:26 +00:00
|
|
|
if (OF_getproplen(node, "no-streaming-cache") < 0)
|
2002-02-13 16:07:59 +00:00
|
|
|
sc->sc_is->is_sb[0] = sc->sc_pcictl + PCR_STRBUF;
|
2009-03-19 20:52:46 +00:00
|
|
|
sc->sc_is->is_flags |= (rerun != 1) ? IOMMU_RERUN_DISABLE : 0;
|
2005-11-22 22:32:50 +00:00
|
|
|
psycho_iommu_init(sc, 3, dvmabase);
|
2001-11-09 20:19:58 +00:00
|
|
|
} else {
|
2005-12-03 13:08:05 +00:00
|
|
|
/* Just copy IOMMU state, config tag and address. */
|
2011-03-29 19:48:03 +00:00
|
|
|
sc->sc_dma_methods = &iommu_dma_methods;
|
2001-11-09 20:19:58 +00:00
|
|
|
sc->sc_is = osc->sc_is;
|
2005-11-22 21:34:26 +00:00
|
|
|
if (OF_getproplen(node, "no-streaming-cache") < 0)
|
2002-02-13 16:07:59 +00:00
|
|
|
sc->sc_is->is_sb[1] = sc->sc_pcictl + PCR_STRBUF;
|
|
|
|
iommu_reset(sc->sc_is);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
2003-06-11 20:30:52 +00:00
|
|
|
/* Allocate our tags. */
|
2013-10-24 17:06:41 +00:00
|
|
|
sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, PCI_IO_BUS_SPACE);
|
2011-10-02 23:22:38 +00:00
|
|
|
if (sc->sc_pci_iot == NULL)
|
|
|
|
panic("%s: could not allocate PCI I/O tag", __func__);
|
2013-10-24 17:06:41 +00:00
|
|
|
sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, PCI_CONFIG_BUS_SPACE);
|
2011-10-02 23:22:38 +00:00
|
|
|
if (sc->sc_pci_cfgt == NULL)
|
|
|
|
panic("%s: could not allocate PCI configuration space tag",
|
|
|
|
__func__);
|
2007-08-05 11:56:44 +00:00
|
|
|
if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
|
|
|
|
sc->sc_is->is_pmaxaddr, ~0, NULL, NULL, sc->sc_is->is_pmaxaddr,
|
|
|
|
0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0)
|
2011-10-02 23:22:38 +00:00
|
|
|
panic("%s: could not create PCI DMA tag", __func__);
|
2003-06-11 20:30:52 +00:00
|
|
|
/* Customize the tag. */
|
2005-11-22 21:34:26 +00:00
|
|
|
sc->sc_pci_dmat->dt_cookie = sc->sc_is;
|
2011-03-29 19:48:03 +00:00
|
|
|
sc->sc_pci_dmat->dt_mt = sc->sc_dma_methods;
|
2003-06-11 20:30:52 +00:00
|
|
|
|
2009-12-29 14:03:38 +00:00
|
|
|
i = OF_getprop(node, "bus-range", (void *)prop_array,
|
2008-04-17 12:38:00 +00:00
|
|
|
sizeof(prop_array));
|
2009-12-29 14:03:38 +00:00
|
|
|
if (i == -1)
|
2007-01-08 01:26:47 +00:00
|
|
|
panic("%s: could not get bus-range", __func__);
|
2009-12-29 14:03:38 +00:00
|
|
|
if (i != sizeof(prop_array))
|
|
|
|
panic("%s: broken bus-range (%d)", __func__, i);
|
2010-01-02 15:19:33 +00:00
|
|
|
sc->sc_pci_secbus = prop_array[0];
|
|
|
|
sc->sc_pci_subbus = prop_array[1];
|
2008-04-17 12:38:00 +00:00
|
|
|
if (bootverbose)
|
|
|
|
device_printf(dev, "bus range %u to %u; PCI bus %d\n",
|
2010-01-02 15:19:33 +00:00
|
|
|
sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus);
|
2007-01-08 01:26:47 +00:00
|
|
|
|
2008-09-18 19:45:22 +00:00
|
|
|
/* Clear any pending PCI error bits. */
|
2008-04-17 12:38:00 +00:00
|
|
|
PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
|
2008-09-18 19:45:22 +00:00
|
|
|
PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_pci_secbus,
|
|
|
|
PCS_DEVICE, PCS_FUNC, PCIR_STATUS, 2), 2);
|
|
|
|
PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS));
|
|
|
|
PCICTL_WRITE8(sc, PCR_AFS, PCICTL_READ8(sc, PCR_AFS));
|
|
|
|
|
|
|
|
if (osc == NULL) {
|
|
|
|
/*
|
|
|
|
* Establish handlers for interesting interrupts...
|
|
|
|
*
|
|
|
|
* XXX We need to remember these and remove this to support
|
|
|
|
* hotplug on the UPA/FHC bus.
|
|
|
|
*
|
|
|
|
* XXX Not all controllers have these, but installing them
|
|
|
|
* is better than trying to sort through this mess.
|
|
|
|
*/
|
2013-03-02 13:04:58 +00:00
|
|
|
psycho_set_intr(sc, 1, PSR_UE_INT_MAP, psycho_ue, NULL);
|
|
|
|
psycho_set_intr(sc, 2, PSR_CE_INT_MAP, psycho_ce, NULL);
|
2013-03-02 00:37:31 +00:00
|
|
|
switch (psycho_powerfail) {
|
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
psycho_set_intr(sc, 3, PSR_POWER_INT_MAP,
|
2013-03-02 13:04:58 +00:00
|
|
|
psycho_powerdebug, NULL);
|
2013-03-02 00:37:31 +00:00
|
|
|
break;
|
|
|
|
default:
|
2013-03-02 13:04:58 +00:00
|
|
|
psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, NULL,
|
2013-03-02 00:37:31 +00:00
|
|
|
psycho_powerdown);
|
|
|
|
break;
|
|
|
|
}
|
2008-09-18 19:45:22 +00:00
|
|
|
if (sc->sc_mode == PSYCHO_MODE_PSYCHO) {
|
|
|
|
/*
|
|
|
|
* Hummingbirds/Sabres do not have the following two
|
|
|
|
* interrupts.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The spare hardware interrupt is used for the
|
|
|
|
* over-temperature interrupt.
|
|
|
|
*/
|
2013-03-02 13:04:58 +00:00
|
|
|
psycho_set_intr(sc, 4, PSR_SPARE_INT_MAP, NULL,
|
2013-03-02 00:37:31 +00:00
|
|
|
psycho_overtemp);
|
2008-09-18 19:45:22 +00:00
|
|
|
#ifdef PSYCHO_MAP_WAKEUP
|
|
|
|
/*
|
|
|
|
* psycho_wakeup() doesn't do anything useful right
|
|
|
|
* now.
|
|
|
|
*/
|
|
|
|
psycho_set_intr(sc, 5, PSR_PWRMGT_INT_MAP,
|
2013-03-02 13:04:58 +00:00
|
|
|
psycho_wakeup, NULL);
|
2008-09-18 19:45:22 +00:00
|
|
|
#endif /* PSYCHO_MAP_WAKEUP */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Register a PCI bus error interrupt handler according to which
|
|
|
|
* half this is. Hummingbird/Sabre don't have a PCI bus B error
|
|
|
|
* interrupt but they are also only used for PCI bus A.
|
|
|
|
*/
|
|
|
|
psycho_set_intr(sc, 0, sc->sc_half == 0 ? PSR_PCIAERR_INT_MAP :
|
2013-03-02 13:04:58 +00:00
|
|
|
PSR_PCIBERR_INT_MAP, psycho_pci_bus, NULL);
|
2007-01-08 01:26:47 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the latency timer register as this isn't always done by the
|
|
|
|
* firmware.
|
|
|
|
*/
|
2008-04-17 12:38:00 +00:00
|
|
|
PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
|
2008-08-22 20:28:19 +00:00
|
|
|
PCIR_LATTIMER, OFW_PCI_LATENCY, 1);
|
2002-06-12 19:20:57 +00:00
|
|
|
|
2009-12-29 14:03:38 +00:00
|
|
|
for (i = PCIR_VENDOR; i < PCIR_STATUS; i += sizeof(uint16_t))
|
|
|
|
le16enc(&sc->sc_pci_hpbcfg[i], bus_space_read_2(
|
2007-11-30 23:02:42 +00:00
|
|
|
sc->sc_pci_cfgt, sc->sc_pci_bh[OFW_PCI_CS_CONFIG],
|
|
|
|
PSYCHO_CONF_OFF(sc->sc_pci_secbus, PCS_DEVICE,
|
2009-12-29 14:03:38 +00:00
|
|
|
PCS_FUNC, i)));
|
|
|
|
for (i = PCIR_REVID; i <= PCIR_BIST; i += sizeof(uint8_t))
|
|
|
|
sc->sc_pci_hpbcfg[i] = bus_space_read_1(sc->sc_pci_cfgt,
|
2007-11-30 23:02:42 +00:00
|
|
|
sc->sc_pci_bh[OFW_PCI_CS_CONFIG], PSYCHO_CONF_OFF(
|
2009-12-29 14:03:38 +00:00
|
|
|
sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, i));
|
2007-11-30 23:02:42 +00:00
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t));
|
2005-11-22 22:32:50 +00:00
|
|
|
/*
|
2005-12-03 13:08:05 +00:00
|
|
|
* On E250 the interrupt map entry for the EBus bridge is wrong,
|
|
|
|
* causing incorrect interrupts to be assigned to some devices on
|
2008-05-07 21:22:15 +00:00
|
|
|
* the EBus. Work around it by changing our copy of the interrupt
|
|
|
|
* map mask to perform a full comparison of the INO. That way
|
2005-12-03 13:08:05 +00:00
|
|
|
* the interrupt map entry for the EBus bridge won't match at all
|
|
|
|
* and the INOs specified in the "interrupts" properties of the
|
|
|
|
* EBus devices will be used directly instead.
|
2005-11-22 22:32:50 +00:00
|
|
|
*/
|
|
|
|
if (strcmp(sparc64_model, "SUNW,Ultra-250") == 0 &&
|
|
|
|
sc->sc_pci_iinfo.opi_imapmsk != NULL)
|
|
|
|
*(ofw_pci_intr_t *)(&sc->sc_pci_iinfo.opi_imapmsk[
|
|
|
|
sc->sc_pci_iinfo.opi_addrc]) = INTMAP_INO_MASK;
|
2001-12-21 21:35:47 +00:00
|
|
|
|
2008-04-17 12:38:00 +00:00
|
|
|
device_add_child(dev, "pci", -1);
|
2001-11-09 20:19:58 +00:00
|
|
|
return (bus_generic_attach(dev));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-09-06 19:16:30 +00:00
|
|
|
psycho_set_intr(struct psycho_softc *sc, u_int index, bus_addr_t intrmap,
|
2013-03-02 13:04:58 +00:00
|
|
|
driver_filter_t filt, driver_intr_t intr)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
2007-09-06 19:16:30 +00:00
|
|
|
u_long vec;
|
2007-06-16 23:46:41 +00:00
|
|
|
int rid;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2005-12-03 16:36:54 +00:00
|
|
|
rid = index;
|
2009-12-29 14:03:38 +00:00
|
|
|
sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev,
|
|
|
|
SYS_RES_IRQ, &rid, RF_ACTIVE);
|
2009-03-19 20:52:46 +00:00
|
|
|
if (sc->sc_irq_res[index] == NULL && intrmap >= PSR_POWER_INT_MAP) {
|
|
|
|
/*
|
|
|
|
* These interrupts aren't mandatory and not available
|
|
|
|
* with all controllers (not even Psychos).
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
2007-06-16 23:46:41 +00:00
|
|
|
if (sc->sc_irq_res[index] == NULL ||
|
2009-12-29 14:03:38 +00:00
|
|
|
INTIGN(vec = rman_get_start(sc->sc_irq_res[index])) !=
|
|
|
|
sc->sc_ign ||
|
2007-09-06 19:16:30 +00:00
|
|
|
INTVEC(PSYCHO_READ8(sc, intrmap)) != vec ||
|
|
|
|
intr_vectors[vec].iv_ic != &psycho_ic ||
|
2009-03-19 20:52:46 +00:00
|
|
|
bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index],
|
2013-03-02 13:04:58 +00:00
|
|
|
INTR_TYPE_MISC | INTR_BRIDGE, filt, intr, sc,
|
2009-03-19 20:52:46 +00:00
|
|
|
&sc->sc_ihand[index]) != 0)
|
2007-06-16 23:46:41 +00:00
|
|
|
panic("%s: failed to set up interrupt %d", __func__, index);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2009-12-29 14:03:38 +00:00
|
|
|
psycho_find_intrmap(struct psycho_softc *sc, u_int ino,
|
|
|
|
bus_addr_t *intrmapptr, bus_addr_t *intrclrptr, bus_addr_t *intrdiagptr)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
2007-09-06 19:16:30 +00:00
|
|
|
bus_addr_t intrclr, intrmap;
|
|
|
|
uint64_t diag;
|
2001-11-09 20:19:58 +00:00
|
|
|
int found;
|
|
|
|
|
2007-09-06 19:16:30 +00:00
|
|
|
/*
|
|
|
|
* XXX we only compare INOs rather than INRs since the firmware may
|
|
|
|
* not provide the IGN and the IGN is constant for all devices on
|
|
|
|
* that PCI controller.
|
|
|
|
* This could cause problems for the FFB/external interrupt which
|
|
|
|
* has a full vector that can be set arbitrarily.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (ino > PSYCHO_MAX_INO) {
|
|
|
|
device_printf(sc->sc_dev, "out of range INO %d requested\n",
|
|
|
|
ino);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2001-11-09 20:19:58 +00:00
|
|
|
found = 0;
|
2007-09-06 19:16:30 +00:00
|
|
|
/* Hunt through OBIO first. */
|
2002-02-13 16:07:59 +00:00
|
|
|
diag = PSYCHO_READ8(sc, PSR_OBIO_INT_DIAG);
|
|
|
|
for (intrmap = PSR_SCSI_INT_MAP, intrclr = PSR_SCSI_INT_CLR;
|
2007-09-06 19:16:30 +00:00
|
|
|
intrmap <= PSR_PWRMGT_INT_MAP; intrmap += 8, intrclr += 8,
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
diag >>= 2) {
|
2007-09-06 19:16:30 +00:00
|
|
|
if (sc->sc_mode == PSYCHO_MODE_SABRE &&
|
|
|
|
(intrmap == PSR_TIMER0_INT_MAP ||
|
|
|
|
intrmap == PSR_TIMER1_INT_MAP ||
|
|
|
|
intrmap == PSR_PCIBERR_INT_MAP ||
|
|
|
|
intrmap == PSR_PWRMGT_INT_MAP))
|
|
|
|
continue;
|
|
|
|
if (INTINO(PSYCHO_READ8(sc, intrmap)) == ino) {
|
2001-11-09 20:19:58 +00:00
|
|
|
diag &= 2;
|
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
2002-02-13 16:07:59 +00:00
|
|
|
diag = PSYCHO_READ8(sc, PSR_PCI_INT_DIAG);
|
2005-12-03 13:08:05 +00:00
|
|
|
/* Now do PCI interrupts. */
|
2002-02-13 16:07:59 +00:00
|
|
|
for (intrmap = PSR_PCIA0_INT_MAP, intrclr = PSR_PCIA0_INT_CLR;
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
intrmap <= PSR_PCIB3_INT_MAP; intrmap += 8, intrclr += 32,
|
|
|
|
diag >>= 8) {
|
2002-12-01 23:21:15 +00:00
|
|
|
if (sc->sc_mode == PSYCHO_MODE_PSYCHO &&
|
|
|
|
(intrmap == PSR_PCIA2_INT_MAP ||
|
2007-09-06 19:16:30 +00:00
|
|
|
intrmap == PSR_PCIA3_INT_MAP))
|
2002-12-01 23:21:15 +00:00
|
|
|
continue;
|
2007-09-06 19:16:30 +00:00
|
|
|
if (((PSYCHO_READ8(sc, intrmap) ^ ino) & 0x3c) == 0) {
|
2002-02-13 16:07:59 +00:00
|
|
|
intrclr += 8 * (ino & 3);
|
2001-11-09 20:19:58 +00:00
|
|
|
diag = (diag >> ((ino & 3) * 2)) & 2;
|
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (intrmapptr != NULL)
|
|
|
|
*intrmapptr = intrmap;
|
|
|
|
if (intrclrptr != NULL)
|
|
|
|
*intrclrptr = intrclr;
|
|
|
|
if (intrdiagptr != NULL)
|
|
|
|
*intrdiagptr = diag;
|
|
|
|
return (found);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2005-11-22 21:34:26 +00:00
|
|
|
* Interrupt handlers
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
2007-02-23 12:19:07 +00:00
|
|
|
static int
|
2001-11-09 20:19:58 +00:00
|
|
|
psycho_ue(void *arg)
|
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
struct psycho_softc *sc = arg;
|
|
|
|
uint64_t afar, afsr;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2002-02-13 16:07:59 +00:00
|
|
|
afar = PSYCHO_READ8(sc, PSR_UE_AFA);
|
|
|
|
afsr = PSYCHO_READ8(sc, PSR_UE_AFS);
|
2002-03-23 20:42:23 +00:00
|
|
|
/*
|
|
|
|
* On the UltraSPARC-IIi/IIe, IOMMU misses/protection faults cause
|
|
|
|
* the AFAR to be set to the physical address of the TTE entry that
|
2008-05-07 21:22:15 +00:00
|
|
|
* was invalid/write protected. Call into the IOMMU code to have
|
2007-01-08 01:26:47 +00:00
|
|
|
* them decoded to virtual I/O addresses.
|
2002-03-23 20:42:23 +00:00
|
|
|
*/
|
|
|
|
if ((afsr & UEAFSR_P_DTE) != 0)
|
|
|
|
iommu_decode_fault(sc->sc_is, afar);
|
2003-01-06 16:51:06 +00:00
|
|
|
panic("%s: uncorrectable DMA error AFAR %#lx AFSR %#lx",
|
2010-03-31 22:32:56 +00:00
|
|
|
device_get_nameunit(sc->sc_dev), (u_long)afar, (u_long)afsr);
|
2007-02-23 12:19:07 +00:00
|
|
|
return (FILTER_HANDLED);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
2007-02-23 12:19:07 +00:00
|
|
|
static int
|
2001-11-09 20:19:58 +00:00
|
|
|
psycho_ce(void *arg)
|
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
struct psycho_softc *sc = arg;
|
|
|
|
uint64_t afar, afsr;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2007-06-16 23:46:41 +00:00
|
|
|
mtx_lock_spin(sc->sc_mtx);
|
2002-02-13 16:07:59 +00:00
|
|
|
afar = PSYCHO_READ8(sc, PSR_CE_AFA);
|
|
|
|
afsr = PSYCHO_READ8(sc, PSR_CE_AFS);
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
device_printf(sc->sc_dev, "correctable DMA error AFAR %#lx "
|
|
|
|
"AFSR %#lx\n", (u_long)afar, (u_long)afsr);
|
2003-09-04 15:25:10 +00:00
|
|
|
/* Clear the error bits that we caught. */
|
2008-09-18 19:45:22 +00:00
|
|
|
PSYCHO_WRITE8(sc, PSR_CE_AFS, afsr);
|
2007-06-16 23:46:41 +00:00
|
|
|
mtx_unlock_spin(sc->sc_mtx);
|
2007-02-23 12:19:07 +00:00
|
|
|
return (FILTER_HANDLED);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
2007-02-23 12:19:07 +00:00
|
|
|
static int
|
2005-12-03 16:36:54 +00:00
|
|
|
psycho_pci_bus(void *arg)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
struct psycho_softc *sc = arg;
|
|
|
|
uint64_t afar, afsr;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2005-12-03 16:36:54 +00:00
|
|
|
afar = PCICTL_READ8(sc, PCR_AFA);
|
|
|
|
afsr = PCICTL_READ8(sc, PCR_AFS);
|
|
|
|
panic("%s: PCI bus %c error AFAR %#lx AFSR %#lx",
|
2010-03-31 22:32:56 +00:00
|
|
|
device_get_nameunit(sc->sc_dev), 'A' + sc->sc_half, (u_long)afar,
|
2005-12-03 16:36:54 +00:00
|
|
|
(u_long)afsr);
|
2007-02-23 12:19:07 +00:00
|
|
|
return (FILTER_HANDLED);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
2007-02-23 12:19:07 +00:00
|
|
|
static int
|
2013-03-02 00:37:31 +00:00
|
|
|
psycho_powerdebug(void *arg __unused)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
2002-03-13 05:58:45 +00:00
|
|
|
|
2007-12-25 17:52:02 +00:00
|
|
|
kdb_enter(KDB_WHY_POWERFAIL, "powerfail");
|
2013-03-02 00:37:31 +00:00
|
|
|
return (FILTER_HANDLED);
|
|
|
|
}
|
|
|
|
|
2013-03-02 13:04:58 +00:00
|
|
|
static void
|
2013-03-02 00:37:31 +00:00
|
|
|
psycho_powerdown(void *arg __unused)
|
|
|
|
{
|
2007-09-06 19:16:30 +00:00
|
|
|
static int shutdown;
|
|
|
|
|
|
|
|
/* As the interrupt is cleared we may be called multiple times. */
|
|
|
|
if (shutdown != 0)
|
2013-03-02 13:04:58 +00:00
|
|
|
return;
|
2007-09-06 19:16:30 +00:00
|
|
|
shutdown++;
|
2001-11-09 20:19:58 +00:00
|
|
|
printf("Power Failure Detected: Shutting down NOW.\n");
|
2013-03-02 00:37:31 +00:00
|
|
|
shutdown_nice(RB_POWEROFF);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
2013-03-02 13:04:58 +00:00
|
|
|
static void
|
2013-03-02 00:37:31 +00:00
|
|
|
psycho_overtemp(void *arg __unused)
|
2005-12-03 16:36:54 +00:00
|
|
|
{
|
2007-09-06 19:16:30 +00:00
|
|
|
static int shutdown;
|
2005-12-03 16:36:54 +00:00
|
|
|
|
2007-09-06 19:16:30 +00:00
|
|
|
/* As the interrupt is cleared we may be called multiple times. */
|
|
|
|
if (shutdown != 0)
|
2013-03-02 13:04:58 +00:00
|
|
|
return;
|
2007-09-06 19:16:30 +00:00
|
|
|
shutdown++;
|
2005-12-03 16:36:54 +00:00
|
|
|
printf("DANGER: OVER TEMPERATURE detected.\nShutting down NOW.\n");
|
|
|
|
shutdown_nice(RB_POWEROFF);
|
|
|
|
}
|
|
|
|
|
2001-11-09 20:19:58 +00:00
|
|
|
#ifdef PSYCHO_MAP_WAKEUP
|
2007-02-23 12:19:07 +00:00
|
|
|
static int
|
2001-11-09 20:19:58 +00:00
|
|
|
psycho_wakeup(void *arg)
|
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
struct psycho_softc *sc = arg;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2009-12-29 14:03:38 +00:00
|
|
|
/* We don't really have a framework to deal with this properly. */
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
device_printf(sc->sc_dev, "power management wakeup\n");
|
2007-02-23 12:19:07 +00:00
|
|
|
return (FILTER_HANDLED);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
#endif /* PSYCHO_MAP_WAKEUP */
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
static void
|
2005-11-22 22:32:50 +00:00
|
|
|
psycho_iommu_init(struct psycho_softc *sc, int tsbsize, uint32_t dvmabase)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
2002-02-13 16:07:59 +00:00
|
|
|
struct iommu_state *is = sc->sc_is;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
/* Punch in our copies. */
|
2007-06-16 23:46:41 +00:00
|
|
|
is->is_bustag = rman_get_bustag(sc->sc_mem_res);
|
|
|
|
is->is_bushandle = rman_get_bushandle(sc->sc_mem_res);
|
2002-02-13 16:07:59 +00:00
|
|
|
is->is_iommu = PSR_IOMMU;
|
|
|
|
is->is_dtag = PSR_IOMMU_TLB_TAG_DIAG;
|
|
|
|
is->is_ddram = PSR_IOMMU_TLB_DATA_DIAG;
|
|
|
|
is->is_dqueue = PSR_IOMMU_QUEUE_DIAG;
|
|
|
|
is->is_dva = PSR_IOMMU_SVADIAG;
|
|
|
|
is->is_dtcmp = PSR_IOMMU_TLB_CMP_DIAG;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2008-05-07 21:22:15 +00:00
|
|
|
iommu_init(device_get_nameunit(sc->sc_dev), is, tsbsize, dvmabase, 0);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
psycho_maxslots(device_t dev)
|
|
|
|
{
|
|
|
|
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
/* XXX: is this correct? */
|
|
|
|
return (PCI_SLOTMAX);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
static uint32_t
|
2001-11-09 20:19:58 +00:00
|
|
|
psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
|
2005-11-22 21:34:26 +00:00
|
|
|
int width)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
|
|
|
struct psycho_softc *sc;
|
|
|
|
bus_space_handle_t bh;
|
|
|
|
u_long offset = 0;
|
2005-11-22 21:34:26 +00:00
|
|
|
uint8_t byte;
|
|
|
|
uint16_t shrt;
|
2007-11-30 23:02:42 +00:00
|
|
|
uint32_t r, wrd;
|
2001-12-21 21:35:47 +00:00
|
|
|
int i;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
sc = device_get_softc(dev);
|
2010-01-02 15:19:33 +00:00
|
|
|
if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
|
|
|
|
slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
|
|
|
|
return (-1);
|
|
|
|
|
2005-12-03 19:52:20 +00:00
|
|
|
bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
|
2007-11-30 23:02:42 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The Hummingbird and Sabre bridges are picky in that they
|
|
|
|
* only allow their config space to be accessed using the
|
|
|
|
* "native" width of the respective register being accessed
|
|
|
|
* and return semi-random other content of their config space
|
2008-05-07 21:22:15 +00:00
|
|
|
* otherwise. Given that the PCI specs don't say anything
|
2007-11-30 23:02:42 +00:00
|
|
|
* about such a (unusual) limitation and lots of stuff expects
|
|
|
|
* to be able to access the contents of the config space at
|
2008-05-07 21:22:15 +00:00
|
|
|
* any width we allow just that. We do this by using a copy
|
2007-11-30 23:02:42 +00:00
|
|
|
* of the header of the bridge (the rest is all zero anyway)
|
|
|
|
* read during attach (expect for PCIR_STATUS) in order to
|
|
|
|
* simplify things.
|
|
|
|
* The Psycho bridges contain a dupe of their header at 0x80
|
|
|
|
* which we nullify that way also.
|
|
|
|
*/
|
|
|
|
if (bus == sc->sc_pci_secbus && slot == PCS_DEVICE &&
|
|
|
|
func == PCS_FUNC) {
|
|
|
|
if (offset % width != 0)
|
|
|
|
return (-1);
|
|
|
|
|
2007-12-01 19:42:33 +00:00
|
|
|
if (reg >= sizeof(sc->sc_pci_hpbcfg))
|
2007-11-30 23:02:42 +00:00
|
|
|
return (0);
|
|
|
|
|
|
|
|
if ((reg < PCIR_STATUS && reg + width > PCIR_STATUS) ||
|
|
|
|
reg == PCIR_STATUS || reg == PCIR_STATUS + 1)
|
|
|
|
le16enc(&sc->sc_pci_hpbcfg[PCIR_STATUS],
|
|
|
|
bus_space_read_2(sc->sc_pci_cfgt, bh,
|
|
|
|
PSYCHO_CONF_OFF(sc->sc_pci_secbus,
|
|
|
|
PCS_DEVICE, PCS_FUNC, PCIR_STATUS)));
|
|
|
|
|
|
|
|
switch (width) {
|
|
|
|
case 1:
|
|
|
|
return (sc->sc_pci_hpbcfg[reg]);
|
|
|
|
case 2:
|
|
|
|
return (le16dec(&sc->sc_pci_hpbcfg[reg]));
|
|
|
|
case 4:
|
|
|
|
return (le32dec(&sc->sc_pci_hpbcfg[reg]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
offset = PSYCHO_CONF_OFF(bus, slot, func, reg);
|
2001-11-09 20:19:58 +00:00
|
|
|
switch (width) {
|
|
|
|
case 1:
|
2005-11-22 21:34:26 +00:00
|
|
|
i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte);
|
2003-06-22 01:26:08 +00:00
|
|
|
r = byte;
|
2001-11-09 20:19:58 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2005-11-22 21:34:26 +00:00
|
|
|
i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt);
|
2003-06-22 01:26:08 +00:00
|
|
|
r = shrt;
|
2001-11-09 20:19:58 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2005-11-22 21:34:26 +00:00
|
|
|
i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd);
|
2003-06-22 01:26:08 +00:00
|
|
|
r = wrd;
|
2001-11-09 20:19:58 +00:00
|
|
|
break;
|
|
|
|
default:
|
2005-11-22 21:34:26 +00:00
|
|
|
panic("%s: bad width", __func__);
|
2008-08-22 20:28:19 +00:00
|
|
|
/* NOTREACHED */
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
2003-06-22 01:26:08 +00:00
|
|
|
|
|
|
|
if (i) {
|
|
|
|
#ifdef PSYCHO_DEBUG
|
2007-01-08 01:26:47 +00:00
|
|
|
printf("%s: read data error reading: %d.%d.%d: 0x%x\n",
|
|
|
|
__func__, bus, slot, func, reg);
|
2003-06-22 01:26:08 +00:00
|
|
|
#endif
|
|
|
|
r = -1;
|
|
|
|
}
|
2001-11-09 20:19:58 +00:00
|
|
|
return (r);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-12-29 14:03:38 +00:00
|
|
|
psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func,
|
|
|
|
u_int reg, uint32_t val, int width)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
|
|
|
struct psycho_softc *sc;
|
|
|
|
bus_space_handle_t bh;
|
|
|
|
u_long offset = 0;
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
sc = device_get_softc(dev);
|
2010-01-02 15:19:33 +00:00
|
|
|
if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus ||
|
|
|
|
slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX)
|
|
|
|
return;
|
|
|
|
|
2001-11-09 20:19:58 +00:00
|
|
|
offset = PSYCHO_CONF_OFF(bus, slot, func, reg);
|
2005-12-03 19:52:20 +00:00
|
|
|
bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG];
|
2001-11-09 20:19:58 +00:00
|
|
|
switch (width) {
|
|
|
|
case 1:
|
2005-11-22 21:34:26 +00:00
|
|
|
bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val);
|
2001-11-09 20:19:58 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2005-11-22 21:34:26 +00:00
|
|
|
bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val);
|
2001-11-09 20:19:58 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2005-11-22 21:34:26 +00:00
|
|
|
bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val);
|
2001-11-09 20:19:58 +00:00
|
|
|
break;
|
|
|
|
default:
|
2005-11-22 21:34:26 +00:00
|
|
|
panic("%s: bad width", __func__);
|
2008-08-22 20:28:19 +00:00
|
|
|
/* NOTREACHED */
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
psycho_route_interrupt(device_t bridge, device_t dev, int pin)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
struct psycho_softc *sc;
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
struct ofw_pci_register reg;
|
|
|
|
bus_addr_t intrmap;
|
|
|
|
ofw_pci_intr_t pintr, mintr;
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
sc = device_get_softc(bridge);
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
pintr = pin;
|
2009-12-29 14:03:38 +00:00
|
|
|
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo,
|
|
|
|
®, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
|
2013-12-17 15:11:24 +00:00
|
|
|
NULL))
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
return (mintr);
|
|
|
|
/*
|
|
|
|
* If this is outside of the range for an intpin, it's likely a full
|
2005-11-22 21:34:26 +00:00
|
|
|
* INO, and no mapping is required at all; this happens on the U30,
|
2008-05-07 21:22:15 +00:00
|
|
|
* where there's no interrupt map at the Psycho node. Fortunately,
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
* there seem to be no INOs in the intpin range on this boxen, so
|
|
|
|
* this easy heuristics will do.
|
|
|
|
*/
|
|
|
|
if (pin > 4)
|
|
|
|
return (pin);
|
|
|
|
/*
|
|
|
|
* Guess the INO; we always assume that this is a non-OBIO
|
2008-05-07 21:22:15 +00:00
|
|
|
* device, and that pin is a "real" intpin number. Determine
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
* the mapping register to be used by the slot number.
|
2005-11-22 21:34:26 +00:00
|
|
|
* We only need to do this on E450s, it seems; here, the slot numbers
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
* for bus A are one-based, while those for bus B seemingly have an
|
|
|
|
* offset of 2 (hence the factor of 3 below).
|
|
|
|
*/
|
|
|
|
intrmap = PSR_PCIA0_INT_MAP +
|
|
|
|
8 * (pci_get_slot(dev) - 1 + 3 * sc->sc_half);
|
|
|
|
mintr = INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1;
|
2009-12-29 14:03:38 +00:00
|
|
|
device_printf(bridge,
|
|
|
|
"guessing interrupt %d for device %d.%d pin %d\n",
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
(int)mintr, pci_get_slot(dev), pci_get_function(dev), pin);
|
|
|
|
return (mintr);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2002-02-13 16:07:59 +00:00
|
|
|
psycho_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
|
|
|
struct psycho_softc *sc;
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
sc = device_get_softc(dev);
|
2001-11-09 20:19:58 +00:00
|
|
|
switch (which) {
|
2007-09-30 11:05:18 +00:00
|
|
|
case PCIB_IVAR_DOMAIN:
|
2008-04-17 12:38:00 +00:00
|
|
|
*result = device_get_unit(dev);
|
2007-09-30 11:05:18 +00:00
|
|
|
return (0);
|
2001-11-09 20:19:58 +00:00
|
|
|
case PCIB_IVAR_BUS:
|
2005-11-22 21:34:26 +00:00
|
|
|
*result = sc->sc_pci_secbus;
|
2001-11-09 20:19:58 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
return (ENOENT);
|
|
|
|
}
|
|
|
|
|
2011-03-26 16:52:31 +00:00
|
|
|
static void
|
|
|
|
sabre_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
|
2007-06-06 22:19:23 +00:00
|
|
|
{
|
2011-03-26 16:52:31 +00:00
|
|
|
struct iommu_state *is = dt->dt_cookie;
|
|
|
|
|
|
|
|
if ((map->dm_flags & DMF_LOADED) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ((op & BUS_DMASYNC_POSTREAD) != 0)
|
|
|
|
(void)bus_space_read_8(is->is_bustag, is->is_bushandle,
|
|
|
|
PSR_DMA_WRITE_SYNC);
|
2007-06-06 22:19:23 +00:00
|
|
|
|
2011-03-26 16:52:31 +00:00
|
|
|
if ((op & BUS_DMASYNC_PREWRITE) != 0)
|
|
|
|
membar(Sync);
|
2007-06-06 22:19:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-09-06 19:16:30 +00:00
|
|
|
psycho_intr_enable(void *arg)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
2007-09-06 19:16:30 +00:00
|
|
|
struct intr_vector *iv = arg;
|
|
|
|
struct psycho_icarg *pica = iv->iv_icarg;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2007-09-06 19:16:30 +00:00
|
|
|
PSYCHO_WRITE8(pica->pica_sc, pica->pica_map,
|
|
|
|
INTMAP_ENABLE(iv->iv_vec, iv->iv_mid));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
psycho_intr_disable(void *arg)
|
|
|
|
{
|
|
|
|
struct intr_vector *iv = arg;
|
|
|
|
struct psycho_icarg *pica = iv->iv_icarg;
|
|
|
|
|
|
|
|
PSYCHO_WRITE8(pica->pica_sc, pica->pica_map, iv->iv_vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-04-23 20:04:38 +00:00
|
|
|
psycho_intr_assign(void *arg)
|
|
|
|
{
|
|
|
|
struct intr_vector *iv = arg;
|
|
|
|
struct psycho_icarg *pica = iv->iv_icarg;
|
|
|
|
|
|
|
|
PSYCHO_WRITE8(pica->pica_sc, pica->pica_map, INTMAP_TID(
|
|
|
|
PSYCHO_READ8(pica->pica_sc, pica->pica_map), iv->iv_mid));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
psycho_intr_clear(void *arg)
|
2007-09-06 19:16:30 +00:00
|
|
|
{
|
|
|
|
struct intr_vector *iv = arg;
|
|
|
|
struct psycho_icarg *pica = iv->iv_icarg;
|
|
|
|
|
2010-03-31 22:19:00 +00:00
|
|
|
PSYCHO_WRITE8(pica->pica_sc, pica->pica_clr, INTCLR_IDLE);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2005-11-22 21:34:26 +00:00
|
|
|
psycho_setup_intr(device_t dev, device_t child, struct resource *ires,
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
|
2007-02-23 12:19:07 +00:00
|
|
|
void **cookiep)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
|
|
|
struct psycho_softc *sc;
|
2007-09-06 19:16:30 +00:00
|
|
|
u_long vec;
|
2007-02-23 12:19:07 +00:00
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
sc = device_get_softc(dev);
|
2001-11-09 20:19:58 +00:00
|
|
|
/*
|
2007-09-06 19:16:30 +00:00
|
|
|
* Make sure the vector is fully specified and we registered
|
|
|
|
* our interrupt controller for it.
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
2007-01-08 01:26:47 +00:00
|
|
|
vec = rman_get_start(ires);
|
2007-09-06 19:16:30 +00:00
|
|
|
if (INTIGN(vec) != sc->sc_ign ||
|
|
|
|
intr_vectors[vec].iv_ic != &psycho_ic) {
|
|
|
|
device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
|
2007-01-08 01:26:47 +00:00
|
|
|
return (EINVAL);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
2007-09-06 19:16:30 +00:00
|
|
|
return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
|
|
|
|
arg, cookiep));
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct resource *
|
|
|
|
psycho_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 psycho_softc *sc;
|
|
|
|
struct resource *rv;
|
|
|
|
struct rman *rm;
|
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
sc = device_get_softc(bus);
|
2011-10-02 23:22:38 +00:00
|
|
|
switch (type) {
|
|
|
|
case SYS_RES_IRQ:
|
2001-11-09 20:19:58 +00:00
|
|
|
/*
|
|
|
|
* XXX: Don't accept blank ranges for now, only single
|
2008-05-07 21:22:15 +00:00
|
|
|
* interrupts. The other case should not happen with
|
|
|
|
* the MI PCI code...
|
2005-11-22 21:34:26 +00:00
|
|
|
* XXX: This may return a resource that is out of the
|
2008-05-07 21:22:15 +00:00
|
|
|
* range that was specified. Is this correct...?
|
2001-11-09 20:19:58 +00:00
|
|
|
*/
|
|
|
|
if (start != end)
|
2005-11-22 21:34:26 +00:00
|
|
|
panic("%s: XXX: interrupt range", __func__);
|
2007-09-06 19:16:30 +00:00
|
|
|
start = end = INTMAP_VEC(sc->sc_ign, end);
|
2011-10-02 23:22:38 +00:00
|
|
|
return (bus_generic_alloc_resource(bus, child, type, rid,
|
|
|
|
start, end, count, flags));
|
2001-11-09 20:19:58 +00:00
|
|
|
case SYS_RES_MEMORY:
|
2005-11-22 21:34:26 +00:00
|
|
|
rm = &sc->sc_pci_mem_rman;
|
2001-11-09 20:19:58 +00:00
|
|
|
break;
|
|
|
|
case SYS_RES_IOPORT:
|
2005-11-22 21:34:26 +00:00
|
|
|
rm = &sc->sc_pci_io_rman;
|
2001-11-09 20:19:58 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2011-10-02 23:22:38 +00:00
|
|
|
rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
|
|
|
|
child);
|
2001-11-09 20:19:58 +00:00
|
|
|
if (rv == NULL)
|
|
|
|
return (NULL);
|
2006-04-20 04:20:41 +00:00
|
|
|
rman_set_rid(rv, *rid);
|
2011-10-02 23:22:38 +00:00
|
|
|
|
|
|
|
if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
|
|
|
|
*rid, rv) != 0) {
|
|
|
|
rman_release_resource(rv);
|
|
|
|
return (NULL);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
return (rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
psycho_activate_resource(device_t bus, device_t child, int type, int rid,
|
|
|
|
struct resource *r)
|
|
|
|
{
|
2011-10-02 23:22:38 +00:00
|
|
|
struct psycho_softc *sc;
|
|
|
|
struct bus_space_tag *tag;
|
2001-11-09 20:19:58 +00:00
|
|
|
|
2011-10-02 23:22:38 +00:00
|
|
|
sc = device_get_softc(bus);
|
|
|
|
switch (type) {
|
|
|
|
case SYS_RES_IRQ:
|
|
|
|
return (bus_generic_activate_resource(bus, child, type, rid,
|
|
|
|
r));
|
|
|
|
case SYS_RES_MEMORY:
|
2013-10-24 17:06:41 +00:00
|
|
|
tag = sparc64_alloc_bus_tag(r, PCI_MEMORY_BUS_SPACE);
|
2011-10-02 23:22:38 +00:00
|
|
|
if (tag == NULL)
|
|
|
|
return (ENOMEM);
|
|
|
|
rman_set_bustag(r, tag);
|
|
|
|
rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
|
|
|
|
rman_get_start(r));
|
|
|
|
break;
|
|
|
|
case SYS_RES_IOPORT:
|
|
|
|
rman_set_bustag(r, sc->sc_pci_iot);
|
|
|
|
rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
|
|
|
|
rman_get_start(r));
|
|
|
|
break;
|
2002-03-24 01:51:29 +00:00
|
|
|
}
|
2001-11-09 20:19:58 +00:00
|
|
|
return (rman_activate_resource(r));
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2011-10-02 23:22:38 +00:00
|
|
|
psycho_adjust_resource(device_t bus, device_t child, int type,
|
|
|
|
struct resource *r, u_long start, u_long end)
|
2001-11-09 20:19:58 +00:00
|
|
|
{
|
2011-10-02 23:22:38 +00:00
|
|
|
struct psycho_softc *sc;
|
|
|
|
struct rman *rm;
|
2001-12-21 21:35:47 +00:00
|
|
|
|
2011-10-02 23:22:38 +00:00
|
|
|
sc = device_get_softc(bus);
|
|
|
|
switch (type) {
|
|
|
|
case SYS_RES_IRQ:
|
|
|
|
return (bus_generic_adjust_resource(bus, child, type, r,
|
|
|
|
start, end));
|
|
|
|
case SYS_RES_MEMORY:
|
|
|
|
rm = &sc->sc_pci_mem_rman;
|
|
|
|
break;
|
|
|
|
case SYS_RES_IOPORT:
|
|
|
|
rm = &sc->sc_pci_io_rman;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return (EINVAL);
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
2011-10-02 23:22:38 +00:00
|
|
|
if (rman_is_region_manager(r, rm) == 0)
|
|
|
|
return (EINVAL);
|
|
|
|
return (rman_adjust_resource(r, start, end));
|
2001-11-09 20:19:58 +00:00
|
|
|
}
|
|
|
|
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
static bus_dma_tag_t
|
2011-03-26 16:52:31 +00:00
|
|
|
psycho_get_dma_tag(device_t bus, device_t child __unused)
|
Rototill the sparc64 nexus(4) (actually this brings in the code the
sun4v nexus(4) in turn is based on):
o Change nexus(4) to manage the resources of its children so the
respective device drivers don't need to figure them out of OFW
themselves.
o Change nexus(4) to provide the ofw_bus KOBJ interface instead of
using IVARs for supplying the OFW node and the subset of standard
properties of its children. Together with the previous change this
also allows to fully take advantage of newbus in that drivers like
fhc(4), which attach on multiple parent busses, no longer require
different bus front-ends as obtaining the OFW node and properties
as well as resource allocation works the same for all supported
busses. As such this change also is part 4/4 of allowing creator(4)
to work in USIII-based machines as it allows this driver to attach
on both nexus(4) and upa(4). On the other hand removing these IVARs
breaks API compatibility with the powerpc nexus(4) but which isn't
that bad as a) sparc64 currently doesn't share any device driver
hanging off of nexus(4) with powerpc and b) they were no longer
compatible regarding OFW-related extensions at the pci(4) level
since quite some time.
o Provide bus_get_dma_tag methods in nexus(4) and its children in
order to handle DMA tags in a hierarchical way and get rid of the
sparc64_root_dma_tag kludge. Together with the previous two items
this changes also allows to completely get rid of the nexus(4)
IVAR interface. It also includes:
- pushing the constraints previously specified by the nexus_dmatag
down into the DMA tags of psycho(4) and sbus(4) as it's their
IOMMUs which induce these restrictions (and nothing at the
nexus(4) or anything that would warrant specifying them there),
- fixing some obviously wrong constraints of the psycho(4) and
sbus(4) DMA tags, which happened to not actually be used with
the sparc64_root_dma_tag kludge in place and therefore didn't
cause problems so far,
- replacing magic constants for constraints with macros as far
as it is obvious as to where they come from.
This doesn't include taking advantage of the newbus way to get
the parent DMA tags implemented by this change in order to divorce
the IOTSBs of the PCI and SBus IOMMUs or for implementing the
workaround for the DMA sync bug in Sabre (and Tomatillo) bridges,
yet, though.
o Get rid of the notion that nexus(4) (mostly) reflects an UPA bus
by replacing ofw_upa.h and with ofw_nexus.h (which was repo-copied
from ofw_upa.h) and renaming its content, which actually applies to
all of Fireplane/Safari, JBus and UPA (in the host bus case), as
appropriate.
o Just use M_DEVBUF instead of a separate M_NEXUS malloc type for
allocating the device info for the children of nexus(4). This is
done in order to not need to export M_NEXUS when deriving drivers
for subordinate busses from the nexus(4) class.
o Use the DEFINE_CLASS_0() macro to declare the nexus(4) driver so
we can derive subclasses from it.
o Const'ify the nexus_excl_name and nexus_excl_type arrays as well
as add 'associations' and 'rsc', which are pseudo-devices without
resources and therefore of no real interest for nexus(4), to the
former.
o Let the nexus(4) device memory rman manage the entire 64-bit address
space instead of just the UPA_MEMSTART to UPA_MEMEND subregion as
Fireplane/Safari- and JBus-based machines use multiple ranges,
which can't be as easily divided as in the case of UPA (limiting
the address space only served for sanity checking anyway).
o Use M_WAITOK instead of M_NOWAIT when allocating the device info
for children of nexus(4) in order to give one less opportunity
for adding devices to nexus(4) to fail.
o While adapting the drivers affected by the above nexus(4) changes,
change them to take advantage of rman_get_rid() instead of caching
the RIDs assigned to allocated resources, now that the RIDs of
resources are correctly set.
o In iommu(4) and nexus(4) replace hard-coded functions names, which
actually became outdated in several places, in panic strings and
status massages with __func__. [1]
o Use driver_filter_t in prototypes where appropriate.
o Add my copyright to creator(4), fhc(4), nexus(4), psycho(4) and
sbus(4) as I changed considerable amounts of these drivers as well
as added a bunch of new features, workarounds for silicon bugs etc.
o Fix some white space nits.
Due to lack of access to Exx00 hardware, these changes, i.e. central(4)
and fhc(4), couldn't be runtime tested on such a machine. Exx00 are
currently reported to panic before trying to attach nexus(4) anyway
though.
PR: 76052 [1]
Approved by: re (kensmith)
2007-03-07 21:13:51 +00:00
|
|
|
{
|
|
|
|
struct psycho_softc *sc;
|
|
|
|
|
|
|
|
sc = device_get_softc(bus);
|
|
|
|
return (sc->sc_pci_dmat);
|
|
|
|
}
|
|
|
|
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
static phandle_t
|
2011-03-26 16:52:31 +00:00
|
|
|
psycho_get_node(device_t bus, device_t child __unused)
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
{
|
2005-11-22 21:34:26 +00:00
|
|
|
struct psycho_softc *sc;
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
|
2005-11-22 21:34:26 +00:00
|
|
|
sc = device_get_softc(bus);
|
Add the new sparc64 OFW PCI framework, conditional on options OFW_NEWPCI
for now. It introduces a OFW PCI bus driver and a generic OFW PCI-PCI
bridge driver. By utilizing these, the PCI handling is much more elegant
now.
The advantages of the new approach are:
- Device enumeration should hopefully be more like on Solaris now,
so unit numbers should match what's printed on the box more
closely.
- Real interrupt routing is implemented now, so cardbus bridges
etc. have at least a chance to work.
- The quirk tables are gone and have been replaced by (hopefully
sufficient) heuristics.
- Much cleaner code.
There was also a report that previously bogus interrupt assignments
are fixed now, which can be attributed to the new heuristics.
A pitfall, and the reason why this is not the default yet, is that
it changes device enumeration, as mentioned above, which can make
it necessary to change the system configuration if more than one
unit of a device type is present (on a system with two hme cars,
for example, it is possible that hme0 becomes hme1 and vice versa
after enabling the option). Systems with multiple disk controllers
may need to be booted into single user (and require manual specification
of the root file system on boot) to adjust the fstab.
Nevertheless, I would like to encourage users to use this option,
so that it can be made the default soon.
In detail, the changes are:
- Introduce an OFW PCI bus driver; it inherits most methods from the
generic PCI bus driver, but uses the firmware for enumeration,
performs additional initialization for devices and firmware-specific
interrupt routing. It also implements an OFW-specific method to allow
child devices to get their firmware nodes.
- Introduce an OFW PCI-PCI bridge driver; again, it inherits most
of the generic PCI-PCI bridge driver; it has it's own method for
interrupt routing, as well as some sparc64-specific methods (one to
get the node again, and one to adjust the bridge bus range, since
we need to reenumerate all PCI buses).
- Convert the apb driver to the new way of handling things.
- Provide a common framework for OFW bridge drivers, used be the two
drivers above.
- Provide a small common framework for interrupt routing (for all
bridge types).
- Convert the psycho driver to the new framework; this gets rid of a
bunch of old kludges in pci_read_config(), and the whole
preinitialization (ofw_pci_init()).
- Convert the ISA MD part and the EBus driver to the new way
interrupts and nodes are handled.
- Introduce types for firmware interrupt properties.
- Rename the old sparcbus_if to ofw_pci_if by repo copy (it is only
required for PCI), and move it to a more correct location (new
support methodsx were also added, and an old one was deprecated).
- Fix a bunch of minor bugs, perform some cleanups.
In some cases, I introduced some minor code duplication to keep the
new code clean, in hopes that the old code will be unifdef'ed soon.
Reviewed in part by: imp
Tested by: jake, Marius Strobl <marius@alchemy.franken.de>,
Sergey Mokryshev <mokr@mokr.net>,
Chris Jackman <cjackNOSPAM@klatsch.org>
Info on u30 firmware provided by: kris
2003-07-01 14:52:47 +00:00
|
|
|
/* We only have one child, the PCI bus, which needs our own node. */
|
|
|
|
return (sc->sc_node);
|
|
|
|
}
|
|
|
|
|
2011-03-26 16:52:31 +00:00
|
|
|
static void
|
|
|
|
psycho_setup_device(device_t bus, device_t child)
|
|
|
|
{
|
|
|
|
struct psycho_softc *sc;
|
|
|
|
uint32_t rev;
|
|
|
|
|
|
|
|
sc = device_get_softc(bus);
|
|
|
|
/*
|
|
|
|
* Revision 0 EBus bridges have a bug which prevents them from
|
|
|
|
* working when bus parking is enabled.
|
|
|
|
*/
|
|
|
|
if ((strcmp(ofw_bus_get_name(child), "ebus") == 0 ||
|
|
|
|
strcmp(ofw_bus_get_name(child), "pci108e,1000") == 0) &&
|
|
|
|
OF_getprop(ofw_bus_get_node(child), "revision-id", &rev,
|
|
|
|
sizeof(rev)) > 0 && rev == 0)
|
|
|
|
PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS) &
|
|
|
|
~PCICTL_ARB_PARK);
|
|
|
|
}
|