Commit Graph

8 Commits

Author SHA1 Message Date
Marius Strobl
33368e9fe8 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
Scott Long
770fffe05b Retire BUS_DMAMAP_NSEGS for sparc64 2004-06-28 04:04:43 +00:00
Thomas Moestl
928a49644f Lock down the IOMMU bus_dma implementation to make it safe to use
without Giant held.

A quick outline of the locking strategy:
Since all IOMMUs are synchronized, there is a single lock, iommu_mtx,
which protects the hardware registers (where needed) and the global and
per-IOMMU software states. As soon as the IOMMUs are divorced, each struct
iommu_state will have its own mutex (and the remaining global state
will be moved into the struct).
The dvma rman has its own internal mutex; the TSB slots may only be
accessed by the owner of the corresponding resource, so neither needs
extra protection.
Since there is a second access path to maps via LRU queues, the consumer-
provided locking is not sufficient; therefore, each map which is on a
queue is additionally protected by iommu_mtx (in part, there is one
member which only the map owner may access). Each map on a queue may
be accessed and removed from or repositioned in a queue in any context as
long as the lock is held; only the owner may insert a map.
To reduce lock contention, some bus_dma functions remove the map from
the queue temporarily (on behalf of the map owner) for some operations and
reinsert it when they are done. Shorter operations and operations which are
not done on behalf of the lock owner are completely covered by the lock.

To facilitate the locking, reorganize the streaming buffer handling;
while being there, fix an old oversight which would cause the streaming
buffer to always be flushed, regardless of whether streaming was enabled
in the TSB entry. The streaming buffer is still disabled for now, since
there are a number of drivers which lack critical bus_dmamp_sync() calls.

Additional testing by:	jake
2003-07-10 23:27:35 +00:00
Thomas Moestl
6d3b2a3cad Further cleanup of the sparc64 busdma implementation:
- Move prototypes for sparc64-specific helper functions from bus.h to
  bus_private.h
- Move the method pointers from struct bus_dma_tag into a separate
  structure; this saves some memory, and allows to use a single method
  table for each busdma backend, so that the bus drivers need no longer
  be changed if the methods tables need to be modified.
- Remove the hierarchical tag method lookup. It was never really useful,
  since the layering is fixed, and the current implementations do not
  need to call into parent implementations anyway. Each tag inherits
  its method table pointer and cookie from the parent (or the root tag)
  now, and the method wrapper macros directly use the method table
  of the tag.
- Add a method table to the non-IOMMU backend, remove unnecessary
  prototypes, remove the extra parent tag argument.
- Rename sparc64_dmamem_alloc_map() and sparc64_dmamem_free_map() to
  sparc64_dma_alloc_map() and sparc64_dma_free_map(), move them to a
  better place and use them for all map allocations and deallocations.
- Add a method table to the iommu backend, and staticize functions,
  remove the extra parent tag argument.
- Change the psycho and sbus drivers to just set cookie and method table
  in the root tag.
- Miscellaneous small fixes.
2003-06-18 16:41:36 +00:00
Thomas Moestl
a00f3148b6 Fixes for a number of problems in the IOMMU code:
1.) Fix an off-by-one in the DVMA space handling, which would make it
    possible to allocate one page beyond the end of the DVMA area.
    This page was aliased to the first page. Apparently, this bug was
    responsible for the trashed nvram/eeprom some people were reporting,
    in conjunction with a number of unfortunate coincidences.
2.) Fix broken boundary and and lowaddr calculations.
3.) Fix a memory leak on an error path.
4.) Update a outdated comment to reflect the introduction of IOMMU_MAX_PRE,
    make the usage of IOMMU_MAX_PRE more consistent and KASSERT that the
    preallocation size is not 0.
5.) Fix a case where an error return was lost.
6.) When signalling an error to the caller by invoking the callback, do
    not use a segment pointer of NULL for compatability with existing
    drivers.

Also, increase the maximum segment number to 64; it is rather arbitrary,
with the exception of the of the stack space consumed by the segment
array.

Special thanks go to Harti Brandt <brandt@fokus.fraunhofer.de> for
spotting 4 and 5, and testing many iterations of patches.

Pointy hats to:	tmm
2003-01-21 18:22:26 +00:00
Thomas Moestl
fe461235a2 Change the iommu code to be able to handle more than one DVMA area per
map. Use this new feature to implement iommu_dvmamap_load_mbuf() and
iommu_dvmamap_load_uio() functions in terms of a new helper function,
iommu_dvmamap_load_buffer(). Reimplement the iommu_dvmamap_load()
to use it, too.
This requires some changes to the map format; in addition to that,
remove unused or redundant members.
Add SBus and Psycho wrappers for the new functions, and make them
available through the respective DMA tags.
2003-01-06 21:59:54 +00:00
Thomas Moestl
702f83a807 - remove the unused parent DMA tag argument from
_nexus_dmamap_load_buffer()
- implement nexus_dmamap_load() in terms of _nexus_dmamap_load_buffer().
  Note that this is untested, as this code is not currently used (but
  might be later for UPA devices).
- move BUS_DMAMAP_NSEGS to bus_private.h
- disable the ecache flushing in nexus_dmamap_sync(); it should not be
  needed, although the docs are not entirely clear on that.
2003-01-06 20:54:07 +00:00
Thomas Moestl
e8e2c56650 Revamp the busdma implementation a bit:
- change the IOMMU support code so that it supports overcommittting the
  available DVMA memory, while still allocating as lazily as possible.
  This is achieved by limiting the preallocation, and deferring the
  allocation to map load time when it fails. In the latter case, the
  DVMA memory reserved for unloaded maps can be stolen to free up enough
  memory for loading a map.
- allow NULL settings in the method tables, and search the parent tags
  until an appropriate implementation is found. This allows to remove some
  kluges in the old implementation.
2002-03-24 02:50:53 +00:00