Commit Graph

162 Commits

Author SHA1 Message Date
John Baldwin
d3da228f37 Add a read-only sysctl hw.pci.mcfg to mirror the tunable by the same name.
MFC after:	1 week
2009-05-18 21:47:32 +00:00
John Baldwin
6cad8eb41d Fall back to using configuration type 1 accesses for PCI config requests if
the requested PCI bus falls outside of the bus range given in the ACPI
MCFG table.  Several BIOSes seem to not include all of the PCI busses in
systems in their MCFG tables.  It maybe that the BIOS is simply buggy and
does support all the busses, but it is more conservative to just fall back
to the old method unless it is certain that memory accesses will work.
2009-03-24 18:10:22 +00:00
Warner Losh
d9d53b2a54 Correct parameter types for pcib_{read,write}_config by fixing the
protptyoes for the legacy_* impelemtnations of these kobj methods.
2009-02-08 07:02:42 +00:00
John Baldwin
3591fea8b0 Add a 'hw.pci.mcfg' tunable. It can be set to 0 to disable memory-mapped
PCI config access.
2008-09-11 21:42:11 +00:00
John Baldwin
2d10570afe Some K8 chipsets don't expose all of the PCI devices on bus 0 via PCIe
memory-mapped config access.  Add a workaround for these systems by
checking the first function of each slot on bus 0 using both the
memory-mapped config access and the older type 1 I/O port config access.
If we find a slot that is only visible via the type 1 I/O port config
access, we flag that slot.  Future PCI config transactions to flagged
slots on bus 0 use type 1 I/O port config access rather than memory mapped
config access.
2008-09-10 18:06:08 +00:00
John Baldwin
d320e05ca5 Extend the support for PCI-e memory mapped configuration space access:
- Rename pciereg_cfgopen() to pcie_cfgregopen() and expose it to the
  rest of the kernel.  It now also accepts parameters via function
  arguments rather than global variables.
- Add a notion of minimum and maximum bus numbers and reject requests for
  an out of range bus.
- Add more range checks on slot/func/reg/bytes parameters to the cfg reg
  read/write routines.  Don't panic on any invalid parameters, just fail
  the request (writes do nothing, reads return -1).  This matches the
  behavior of the other cfg mechanisms.
- Port the memory mapped configuration space access to amd64.  On amd64
  we simply use the direct map (via pmap_mapdev()) for the memory mapped
  window.
- During acpi_attach() just after loading the ACPI tables, check for a
  MCFG table.  If it exists, call pciereg_cfgopen() on each subtable
  (memory mapped window).  For now we only support windows for domain 0
  that start with bus 0.  This removes the need for more chipset-specific
  quirks in the MD code.
- Remove the chipset-specific quirks for the Intel 5000P/V/Z chipsets
  since these machines should all have MCFG tables via ACPI.
- Updated pci_cfgregopen() to DTRT if ACPI had invoked pcie_cfgregopen()
  earlier.

MFC after:	2 weeks
2008-08-22 02:14:23 +00:00
John Baldwin
98bbce55fa Adjust the code to probe for the PCI config mechanism to use.
- On amd64, just assume type #1 is always used.  PCI 2.0 mandated
  deprecated type #2 and required type #1 for all future bridges which
  was well before amd64 existed.
- For i386, ignore whatever value was in 0xcf8 before testing for type #1
  and instead rely on the other tests to determine if type #1 works.  Some
  newer machines leave garbage in 0xcf8 during boot and as a result the
  kernel doesn't find PCI at all (which greatly confuses ACPI which expects
  PCI to exist when PCI busses are in the namespace).

MFC after:	3 days
Discussed with:	scottl
2007-11-28 22:20:08 +00:00
Marius Strobl
55aaf894e8 Make the PCI code aware of PCI domains (aka PCI segments) so we can
support machines having multiple independently numbered PCI domains
and don't support reenumeration without ambiguity amongst the
devices as seen by the OS and represented by PCI location strings.
This includes introducing a function pci_find_dbsf(9) which works
like pci_find_bsf(9) but additionally takes a domain number argument
and limiting pci_find_bsf(9) to only search devices in domain 0 (the
only domain in single-domain systems). Bge(4) and ofw_pcibus(4) are
changed to use pci_find_dbsf(9) instead of pci_find_bsf(9) in order
to no longer report false positives when searching for siblings and
dupe devices in the same domain respectively.
Along with this change the sole host-PCI bridge driver converted to
actually make use of PCI domain support is uninorth(4), the others
continue to use domain 0 only for now and need to be converted as
appropriate later on.
Note that this means that the format of the location strings as used
by pciconf(8) has been changed and that consumers of <sys/pciio.h>
potentially need to be recompiled.

Suggested by:	jhb
Reviewed by:	grehan, jhb, marcel
Approved by:	re (kensmith), jhb (PCI maintainer hat)
2007-09-30 11:05:18 +00:00
John Baldwin
e706f7f0c7 Revamp the MSI/MSI-X code a bit to achieve two main goals:
- Simplify the amount of work that has be done for each architecture by
  pushing more of the truly MI code down into the PCI bus driver.
- Don't bind MSI-X indicies to IRQs so that we can allow a driver to map
  multiple MSI-X messages into a single IRQ when handling a message
  shortage.

The changes include:
- Add a new pcib_if method: PCIB_MAP_MSI() which is called by the PCI bus
  to calculate the address and data values for a given MSI/MSI-X IRQ.
  The x86 nexus drivers map this into a call to a new 'msi_map()' function
  in msi.c that does the mapping.
- Retire the pcib_if method PCIB_REMAP_MSIX() and remove the 'index'
  parameter from PCIB_ALLOC_MSIX().  MD code no longer has any knowledge
  of the MSI-X index for a given MSI-X IRQ.
- The PCI bus driver now stores more MSI-X state in a child's ivars.
  Specifically, it now stores an array of IRQs (called "message vectors" in
  the code) that have associated address and data values, and a small
  virtual version of the MSI-X table that specifies the message vector
  that a given MSI-X table entry uses.  Sparse mappings are permitted in
  the virtual table.
- The PCI bus driver now configures the MSI and MSI-X address/data
  registers directly via custom bus_setup_intr() and bus_teardown_intr()
  methods.  pci_setup_intr() invokes PCIB_MAP_MSI() to determine the
  address and data values for a given message as needed.  The MD code
  no longer has to call back down into the PCI bus code to set these
  values from the nexus' bus_setup_intr() handler.
- The PCI bus code provides a callout (pci_remap_msi_irq()) that the MD
  code can call to force the PCI bus to re-invoke PCIB_MAP_MSI() to get
  new values of the address and data fields for a given IRQ.  The x86
  MSI code uses this when an MSI IRQ is moved to a different CPU, requiring
  a new value of the 'address' field.
- The x86 MSI psuedo-driver loses a lot of code, and in fact the separate
  MSI/MSI-X pseudo-PICs are collapsed down into a single MSI PIC driver
  since the only remaining diff between the two is a substring in a
  bootverbose printf.
- The PCI bus driver will now restore MSI-X state (including programming
  entries in the MSI-X table) on device resume.
- The interface for pci_remap_msix() has changed.  Instead of accepting
  indices for the allocated vectors, it accepts a mini-virtual table
  (with a new length parameter).  This table is an array of u_ints, where
  each value specifies which allocated message vector to use for the
  corresponding MSI-X message.  A vector of 0 forces a message to not
  have an associated IRQ.  The device may choose to only use some of the
  IRQs assigned, in which case the unused IRQs must be at the "end" and
  will be released back to the system.  This allows a driver to use the
  same remap table for different shortage values.  For example, if a driver
  wants 4 messages, it can use the same remap table (which only uses the
  first two messages) for the cases when it only gets 2 or 3 messages and
  in the latter case the PCI bus will release the 3rd IRQ back to the
  system.

MFC after:	1 month
2007-05-02 17:50:36 +00:00
John Baldwin
5fe82bca57 Expand the MSI/MSI-X API to address some deficiencies in the MSI-X support.
- First off, device drivers really do need to know if they are allocating
  MSI or MSI-X messages.  MSI requires allocating powerof2() messages for
  example where MSI-X does not.  To address this, split out the MSI-X
  support from pci_msi_count() and pci_alloc_msi() into new driver-visible
  functions pci_msix_count() and pci_alloc_msix().  As a result,
  pci_msi_count() now just returns a count of the max supported MSI
  messages for the device, and pci_alloc_msi() only tries to allocate MSI
  messages.  To get a count of the max supported MSI-X messages, use
  pci_msix_count().  To allocate MSI-X messages, use pci_alloc_msix().
  pci_release_msi() still handles both MSI and MSI-X messages, however.
  As a result of this change, drivers using the existing API will only
  use MSI messages and will no longer try to use MSI-X messages.
- Because MSI-X allows for each message to have its own data and address
  values (and thus does not require all of the messages to have their
  MD vectors allocated as a group), some devices allow for "sparse" use
  of MSI-X message slots.  For example, if a device supports 8 messages
  but the OS is only able to allocate 2 messages, the device may make the
  best use of 2 IRQs if it enables the messages at slots 1 and 4 rather
  than default of using the first N slots (or indicies) at 1 and 2.  To
  support this, add a new pci_remap_msix() function that a driver may call
  after a successful pci_alloc_msix() (but before allocating any of the
  SYS_RES_IRQ resources) to allow the allocated IRQ resources to be
  assigned to different message indices.  For example, from the earlier
  example, after pci_alloc_msix() returned a value of 2, the driver would
  call pci_remap_msix() passing in array of integers { 1, 4 } as the
  new message indices to use.  The rid's for the SYS_RES_IRQ resources
  will always match the message indices.  Thus, after the call to
  pci_remap_msix() the driver would be able to access the first message
  in slot 1 at SYS_RES_IRQ rid 1, and the second message at slot 4 at
  SYS_RES_IRQ rid 4.  Note that the message slots/indices are 1-based
  rather than 0-based so that they will always correspond to the rid
  values (SYS_RES_IRQ rid 0 is reserved for the legacy INTx interrupt).
  To support this API, a new PCIB_REMAP_MSIX() method was added to the
  pcib interface to change the message index for a single IRQ.

Tested by:	scottl
2007-01-22 21:48:44 +00:00
John Baldwin
8964299ac8 Give Host-PCI bridge drivers their own pcib_alloc_msi() and
pcib_alloc_msix() methods instead of using the method from the generic
PCI-PCI bridge driver as the PCI-PCI methods will be gaining some PCI-PCI
specific logic soon.
2006-12-12 19:27:01 +00:00
John Baldwin
4184900911 MD support for PCI Message Signalled Interrupts on amd64 and i386:
- Add a new apic_alloc_vectors() method to the local APIC support code
  to allocate N contiguous IDT vectors (aligned on a M >= N boundary).
  This function is used to allocate IDT vectors for a group of MSI
  messages.
- Add MSI and MSI-X PICs.  The PIC code here provides methods to manage
  edge-triggered MSI messages as x86 interrupt sources.  In addition to
  the PIC methods, msi.c also includes methods to allocate and release
  MSI and MSI-X messages.  For x86, we allow for up to 128 different
  MSI IRQs starting at IRQ 256 (IRQs 0-15 are reserved for ISA IRQs,
  16-254 for APIC PCI IRQs, and IRQ 255 is reserved).
- Add pcib_(alloc|release)_msi[x]() methods to the MD x86 PCI bridge
  drivers to bubble the request up to the nexus driver.
- Add pcib_(alloc|release)_msi[x]() methods to the x86 nexus drivers that
  ask the MSI PIC code to allocate resources and IDT vectors.

MFC after:	2 months
2006-11-13 22:23:34 +00:00
Peter Wemm
31b2d08a2d MFi386: rename pcib_devclass to hostb_devclass (cosmetic here) 2006-03-13 23:58:40 +00:00
John Baldwin
04dda605c5 - Make pcib_devclass private to sys/dev/pci/pci_pci.c and change all the
various pcib drivers to use their own private devclass_t variables for
  their modules.
- Use the DEFINE_CLASS_0() macro to declare drivers for the various pcib
  drivers while I'm here.
2006-01-06 19:22:19 +00:00
John Baldwin
5b2119223e Move the hostb driver out of the i386 and amd64 PCI code (where it was
duplicated anyways) and into a single MI driver.  Extend the driver a bit
to implement the bus and PCI kobj interfaces such that other drivers can
attach to it and transparently act as if their parent device is the PCI
bus (for the most part).
2005-12-20 21:09:45 +00:00
Bill Paul
ba3af76df7 Modify the pci_cfgdisable() routine to bring it more in line with
other OSes (Solaris, Linux, VxWorks). It's not necessary to write a 0
to the config address register when using config mechanism 1 to turn
off config access. In fact, it can be downright troublesome, since it
seems to confuse the PCI-PCI bridge in the AMD8111 chipset and cause
it to sporadically botch reads from some devices. This is the cause
of the missing USP ports problem I was experiencing with my Sun Opteron
system.

Also correct the case for mechanism 2: it's only necessary to write
a 0 to the ENABLE port.
2005-10-25 04:53:29 +00:00
Warner Losh
62061bf002 MFi386: pci attribute allocation fixes. 2005-09-18 01:42:43 +00:00
Peter Wemm
ba2426ff44 MFi386: whitespace, copyright header, etc updates 2005-01-21 05:56:41 +00:00
Warner Losh
46280ae719 Begin all license/copyright comments with /*- 2005-01-05 20:17:21 +00:00
Dag-Erling Smørgrav
b0e1e474f7 Add TUNABLE_LONG and TUNABLE_ULONG, and use the latter for the
hw.pci.host_mem_start tunable.  Add comments to TUNABLE_INT and
TUNABLE_QUAD recommending against their use.

MFC after:	3 weeks
2004-10-31 15:50:33 +00:00
Dag-Erling Smørgrav
38228f7221 Whitespace cleanup 2004-10-31 15:02:53 +00:00
Peter Wemm
598f31f75a MFi386: sync with latest updates 2004-10-11 21:51:27 +00:00
Poul-Henning Kamp
fd360128ff Add missing <sys/module.h> instances which were shadowed by the nested
include in <sys/kernel.h>
2004-06-03 05:58:30 +00:00
Peter Wemm
463e5aa66e MFi386: numerous interrupt and acpi updates 2004-05-16 20:30:47 +00:00
Peter Wemm
f502c2725e Drastically clean up the legacy host-pci bridge table. We don't need
all the ancient Intel/VIA/SIS/etc chipsets on amd64 systems.  Even the
newer intel stuff won't need this since we use acpi by default and we
don't have all their magic programming information.  Just use a generic
"Host to PCI bridge" name if we ever hit this code.
2004-03-13 19:21:35 +00:00
Peter Wemm
10884719f8 MFi386: nuke pci_cfgintr 2004-03-13 19:19:13 +00:00
Peter Wemm
d0f2d056fa MFi386: change an outb to a DELAY() 2004-01-28 20:46:31 +00:00
Peter Wemm
21616ec307 Various whitespace and cosmetic sync-up's with i386.
Approved by:  re (scottl)
2003-12-06 23:19:47 +00:00
Peter Wemm
0d2a298904 Initial landing of SMP support for FreeBSD/amd64.
- This is heavily derived from John Baldwin's apic/pci cleanup on i386.
- I have completely rewritten or drastically cleaned up some other parts.
  (in particular, bootstrap)
- This is still a WIP.  It seems that there are some highly bogus bioses
  on nVidia nForce3-150 boards.  I can't stress how broken these boards
  are.  I have a workaround in mind, but right now the Asus SK8N is broken.
  The Gigabyte K8NPro (nVidia based) is also mind-numbingly hosed.
- Most of my testing has been with SCHED_ULE.  SCHED_4BSD works.
- the apic and acpi components are 'standard'.
- If you have an nVidia nForce3-150 board, you are stuck with 'device
  atpic' in addition, because they somehow managed to forget to connect the
  8254 timer to the apic, even though its in the same silicon!  ARGH!
  This directly violates the ACPI spec.
2003-11-17 08:58:16 +00:00
Peter Wemm
ee3ce1c29c GC unused child variable 2003-09-23 00:04:28 +00:00
Peter Wemm
4295ddf26f MFi386 pci_bus.c 1.102 legacyvar.h 1.4: rename nexus_pcib to legacy_pcib
However, leave legacy_pcib_route_interrupt() since there is no pcibios to
call.
2003-09-23 00:03:44 +00:00
John Baldwin
729d7ffbcf - Rename PCIx_HEADERTYPE* to PCIx_HDRTYPE* so the constants aren't so long.
- Add a new PCIM_HDRTYPE constant for the field in PCIR_HDRTYPE that holds
  the header type.
- Replace several magic numbers with appropriate constants for the header
  type register and a couple of PCI_FUNCMAX.
- Merge to amd64 the fix to the i386 bridge code to skip devices with
  unknown header types.

Requested by:	imp (1, 2)
2003-08-28 21:22:25 +00:00
Warner Losh
d2c5276d96 Prefer new location of pci include files (which have only been in the
tree for two or more years now), except in a few places where there's
code to be compatible with older versions of FreeBSD.
2003-08-22 07:39:05 +00:00
David E. O'Brien
56ae44c5df Use __FBSDID().
Brought to you by:	a boring talk at Ottawa Linux Symposium
2003-07-25 21:19:19 +00:00
Peter Wemm
afa8862328 Commit MD parts of a loosely functional AMD64 port. This is based on
a heavily stripped down FreeBSD/i386 (brutally stripped down actually) to
attempt to get a stable base to start from.  There is a lot missing still.
Worth noting:
- The kernel runs at 1GB in order to cheat with the pmap code.  pmap uses
  a variation of the PAE code in order to avoid having to worry about 4
  levels of page tables yet.
- It boots in 64 bit "long mode" with a tiny trampoline embedded in the
  i386 loader.  This simplifies locore.s greatly.
- There are still quite a few fragments of i386-specific code that have
  not been translated yet, and some that I cheated and wrote dumb C
  versions of (bcopy etc).
- It has both int 0x80 for syscalls (but using registers for argument
  passing, as is native on the amd64 ABI), and the 'syscall' instruction
  for syscalls.  int 0x80 preserves all registers, 'syscall' does not.
- I have tried to minimize looking at the NetBSD code, except in a couple
  of places (eg: to find which register they use to replace the trashed
  %rcx register in the syscall instruction).  As a result, there is not a
  lot of similarity.  I did look at NetBSD a few times while debugging to
  get some ideas about what I might have done wrong in my first attempt.
2003-05-01 01:05:25 +00:00
Peter Wemm
af3d516f55 Initiate de-orbit burn for USE_PCI_BIOS_FOR_READ_WRITE. This has been
#if'ed out for a while.  Complete the deed and tidy up some other bits.

We need to be able to call this stuff from outer edges of interrupt
handlers for devices that have the ISR bits in pci config space.  Making
the bios code mpsafe was just too hairy.  We had also stubbed it out some
time ago due to there simply being too much brokenness in too many systems.
This adds a leaf lock so that it is safe to use pci_read_config() and
pci_write_config() from interrupt handlers.  We still will use pcibios
to do interrupt routing if there is no acpi.. [yes, I tested this]

Briefly glanced at by:  imp
2003-02-18 03:36:49 +00:00
Poul-Henning Kamp
152e80d952 Outdent the string rather than use concatenation. 2002-12-23 22:12:17 +00:00
Warner Losh
a4bbd12ff1 MFp4:
o Fix small style nit.  This was supposed to be part of the last batch of
  style fixes, but somehow didn't get merged.
2002-11-14 05:22:37 +00:00
Peter Wemm
41f778bb99 Recognize the Serverworks CIOB30 host to pci bridge. 2002-11-13 21:30:44 +00:00
Warner Losh
ce494452fe MFp4:
o It turns out that we always need to try to route the interrupts for
  the case where the $PIR tells us there can be only one.  Some machines
  require this, while others fail when we try to do this (bogusly, imho).
  Since we have no apriori way of knowing which is which, we always try to
  do the routing and hope for the best if things fail.
o Add some additional comments that state the obvious, but amplify it in
  non-obvious ways (judging from the questions I've gotten).

This should un-break older laptops that still have to use PCIBIOS to route
interrupts.

Tested by: sam
2002-11-02 22:35:24 +00:00
Warner Losh
984de797ff Use 0xffffffff instead of -1 for id to compare against.
Use exact width types, since this is a MD file and won't be used elsewhere.
Fix a couple of resulting printf breakages

Bug found by: phk using Flexlint
2002-11-02 22:32:04 +00:00
Poul-Henning Kamp
7f30cdf366 Revert last commit, there actually was a -1 waaaaay down in pcireg_cfgread(). 2002-10-20 17:54:17 +00:00
Poul-Henning Kamp
a67ee49294 "id" is never going to be -1 when it is unsigned.
Spotted by:	FlexeLint
2002-10-20 17:21:43 +00:00
John Baldwin
a73f15c7a8 Use the global pcib devclass instead of our own static copy. 2002-10-16 18:38:35 +00:00
Warner Losh
ea5420299c o go ahead and route the interupt, even if it is supposedly unique.
there are some strange machines that seem to need this.
o delete bogus comment.
o don't use the the bios for read/writing config space.  They interact badly
  with SMP and being called from ISR.  This brings -current in line with
  -stable.

# make the latter #ifdef on USE_PCI_BIOS_FOR_READ_WRITE in case we
# need to go back in a hurry.
2002-10-07 05:15:05 +00:00
Mitsuru IWASAKI
2f00e60504 Add 2 Ids for new ServerWorks host to PCI bridge chipset.
These are still unknown name but these are working as well
as the other ServerWorks chipset.
Description strings should be corrected when the chipsets
are known.

MFC after:	1 week
2002-10-02 17:50:38 +00:00
Poul-Henning Kamp
cb8e433232 Don't call function in return() for a void function. 2002-09-28 17:36:29 +00:00
John Baldwin
b8581e0d56 Now that we only probe host-PCI bridges once, we no longer have to check to
see if we have been probed before by checking for a pciX bus device.
2002-09-23 18:14:31 +00:00
John Baldwin
8ff25e9763 Put verbose printf's in the PCI BIOS interrupt routing code under
if (bootverbose).
2002-09-23 18:13:42 +00:00
John Baldwin
2ab55f4392 Change the nexus_pcib driver (eventually to be renamed to legacy_pcib) to
hang off of the legacy driver instead of the nexus.
2002-09-23 15:52:30 +00:00