Re: MSI-X support

2016-09-01 Thread Hrvoje Popovski
On 4.5.2016. 16:32, Mark Kettenis wrote:
>>> This is great, thanks for doing this!  I'm a bit surprised that
>>> we don't need to the same suspend/resume dance in ppb(4) as with
>>> MSI.
>>>
>>
>> That is an excellent point I overlooked. Kettenis, do we?
> 
> Almost certainly.  I committed the diff, but left the bits out that
> start using it in em(4) and xhci(4).
> 

Hi all,

is it a good time to enable msi-x on em(4) ?



Re: MSI-X support

2016-05-04 Thread Mark Kettenis
> Date: Wed, 4 May 2016 07:14:15 -0700
> From: Mike Larkin 
> 
> On Wed, May 04, 2016 at 04:01:54PM +0200, Mike Belopuhov wrote:
> > On Tue, May 03, 2016 at 21:40 +0200, Mark Kettenis wrote:
> > > Today mpi@ reminded me that I had written support for MSI-X some time
> > > ago.  Since he is interested in using multiple vectors, I extended the
> > > code I had a bit to support that feature as well.  This introduces a
> > > new function:
> > > 
> > > int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);
> > > 
> > > You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
> > > pass it a vector number as the 2nd argument.  Typically you'll pass 0,
> > > wich will map the 1st vector, which is always there on hardware with
> > > MSI-X support.  Some hardware supports more than 1 vector.  Typical
> > > examples are network cards that support multiple rings.  Please be
> > > aware that on architectures like i386 and amd64, the number of
> > > interrupt vectors at each level is limited.  If you consume too many
> > > of them, devices may fail to attach.
> > > 
> > > As for the implementation.  This only adds code for amd64.  I'll
> > > probably add support for sparc64 as well.  I'm hesitant about i386
> > > because it has even less available interrupt vectors than amd64.
> > > 
> > > Notice that the amd64 implementation uses _bus_space_map() and
> > > _bus_space_unmap().  That is deliberate.  The MSI-X registers miht
> > > share a BAR with other registers that our drivers already map.  The
> > > underscored versions of the mapping routines make sure that we don't
> > > fail to map things in that case.
> > > 
> > > ok?
> > > 
> > 
> > This is great, thanks for doing this!  I'm a bit surprised that
> > we don't need to the same suspend/resume dance in ppb(4) as with
> > MSI.
> > 
> 
> That is an excellent point I overlooked. Kettenis, do we?

Almost certainly.  I committed the diff, but left the bits out that
start using it in em(4) and xhci(4).



Re: MSI-X support

2016-05-04 Thread Mike Belopuhov
On Tue, May 03, 2016 at 21:40 +0200, Mark Kettenis wrote:
> Today mpi@ reminded me that I had written support for MSI-X some time
> ago.  Since he is interested in using multiple vectors, I extended the
> code I had a bit to support that feature as well.  This introduces a
> new function:
> 
> int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);
> 
> You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
> pass it a vector number as the 2nd argument.  Typically you'll pass 0,
> wich will map the 1st vector, which is always there on hardware with
> MSI-X support.  Some hardware supports more than 1 vector.  Typical
> examples are network cards that support multiple rings.  Please be
> aware that on architectures like i386 and amd64, the number of
> interrupt vectors at each level is limited.  If you consume too many
> of them, devices may fail to attach.
> 
> As for the implementation.  This only adds code for amd64.  I'll
> probably add support for sparc64 as well.  I'm hesitant about i386
> because it has even less available interrupt vectors than amd64.
> 
> Notice that the amd64 implementation uses _bus_space_map() and
> _bus_space_unmap().  That is deliberate.  The MSI-X registers miht
> share a BAR with other registers that our drivers already map.  The
> underscored versions of the mapping routines make sure that we don't
> fail to map things in that case.
> 
> ok?
> 

This is great, thanks for doing this!  I'm a bit surprised that
we don't need to the same suspend/resume dance in ppb(4) as with
MSI.



Re: MSI-X support

2016-05-04 Thread Mike Larkin
On Wed, May 04, 2016 at 04:01:54PM +0200, Mike Belopuhov wrote:
> On Tue, May 03, 2016 at 21:40 +0200, Mark Kettenis wrote:
> > Today mpi@ reminded me that I had written support for MSI-X some time
> > ago.  Since he is interested in using multiple vectors, I extended the
> > code I had a bit to support that feature as well.  This introduces a
> > new function:
> > 
> > int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);
> > 
> > You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
> > pass it a vector number as the 2nd argument.  Typically you'll pass 0,
> > wich will map the 1st vector, which is always there on hardware with
> > MSI-X support.  Some hardware supports more than 1 vector.  Typical
> > examples are network cards that support multiple rings.  Please be
> > aware that on architectures like i386 and amd64, the number of
> > interrupt vectors at each level is limited.  If you consume too many
> > of them, devices may fail to attach.
> > 
> > As for the implementation.  This only adds code for amd64.  I'll
> > probably add support for sparc64 as well.  I'm hesitant about i386
> > because it has even less available interrupt vectors than amd64.
> > 
> > Notice that the amd64 implementation uses _bus_space_map() and
> > _bus_space_unmap().  That is deliberate.  The MSI-X registers miht
> > share a BAR with other registers that our drivers already map.  The
> > underscored versions of the mapping routines make sure that we don't
> > fail to map things in that case.
> > 
> > ok?
> > 
> 
> This is great, thanks for doing this!  I'm a bit surprised that
> we don't need to the same suspend/resume dance in ppb(4) as with
> MSI.
> 

That is an excellent point I overlooked. Kettenis, do we?



Re: MSI-X support

2016-05-04 Thread Mike Larkin
On Wed, May 04, 2016 at 08:50:53AM +0200, Mark Kettenis wrote:
> > Date: Tue, 3 May 2016 15:23:07 -0700
> > From: Mike Larkin 
> > 
> > On Tue, May 03, 2016 at 09:40:28PM +0200, Mark Kettenis wrote:
> > > Today mpi@ reminded me that I had written support for MSI-X some time
> > > ago.  Since he is interested in using multiple vectors, I extended the
> > > code I had a bit to support that feature as well.  This introduces a
> > > new function:
> > > 
> > > int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);
> > > 
> > > You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
> > > pass it a vector number as the 2nd argument.  Typically you'll pass 0,
> > > wich will map the 1st vector, which is always there on hardware with
> > > MSI-X support.  Some hardware supports more than 1 vector.  Typical
> > > examples are network cards that support multiple rings.  Please be
> > > aware that on architectures like i386 and amd64, the number of
> > > interrupt vectors at each level is limited.  If you consume too many
> > > of them, devices may fail to attach.
> > > 
> > > As for the implementation.  This only adds code for amd64.  I'll
> > > probably add support for sparc64 as well.  I'm hesitant about i386
> > > because it has even less available interrupt vectors than amd64.
> > > 
> > > Notice that the amd64 implementation uses _bus_space_map() and
> > > _bus_space_unmap().  That is deliberate.  The MSI-X registers miht
> > > share a BAR with other registers that our drivers already map.  The
> > > underscored versions of the mapping routines make sure that we don't
> > > fail to map things in that case.
> > > 
> > > ok?
> > > 
> > 
> > Did you want to include the if_em and xhci bits too?
> 
> Yes.  They seem to work.  But I can leave them out if people deem this
> too risky.  They'll be separate commits anyway.
> 

Just checking. ok mlarkin@ if you didn't move on this already.

> > > Index: arch/alpha/pci/pci_machdep.h
> > > ===
> > > RCS file: /cvs/src/sys/arch/alpha/pci/pci_machdep.h,v
> > > retrieving revision 1.29
> > > diff -u -p -r1.29 pci_machdep.h
> > > --- arch/alpha/pci/pci_machdep.h  26 Jul 2015 05:09:44 -  1.29
> > > +++ arch/alpha/pci/pci_machdep.h  3 May 2016 19:26:30 -
> > > @@ -104,6 +104,7 @@ int alpha_sysctl_chipset(int *, u_int, c
> > >  #define  pci_conf_write(c, t, r, v)  
> > > \
> > >  (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
> > >  #define  pci_intr_map_msi(pa, ihp)   (-1)
> > > +#define  pci_intr_map_msix(pa, vec, ihp) (-1)
> > >  #define  pci_intr_string(c, ih)  
> > > \
> > >  (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
> > >  #define  pci_intr_line(c, ih)
> > > \
> > > Index: arch/amd64/include/i82093var.h
> > > ===
> > > RCS file: /cvs/src/sys/arch/amd64/include/i82093var.h,v
> > > retrieving revision 1.4
> > > diff -u -p -r1.4 i82093var.h
> > > --- arch/amd64/include/i82093var.h21 May 2011 15:58:27 -  
> > > 1.4
> > > +++ arch/amd64/include/i82093var.h3 May 2016 19:26:30 -
> > > @@ -70,6 +70,7 @@ struct ioapic_softc {
> > >  
> > >  #define APIC_INT_VIA_APIC0x1000
> > >  #define APIC_INT_VIA_MSG 0x2000
> > > +#define APIC_INT_VIA_MSGX0x4000
> > >  #define APIC_INT_APIC_MASK   0x00ff
> > >  #define APIC_INT_APIC_SHIFT  16
> > >  #define APIC_INT_PIN_MASK0xff00
> > > Index: arch/amd64/include/pci_machdep.h
> > > ===
> > > RCS file: /cvs/src/sys/arch/amd64/include/pci_machdep.h,v
> > > retrieving revision 1.24
> > > diff -u -p -r1.24 pci_machdep.h
> > > --- arch/amd64/include/pci_machdep.h  29 Oct 2015 23:08:45 -  
> > > 1.24
> > > +++ arch/amd64/include/pci_machdep.h  3 May 2016 19:26:30 -
> > > @@ -82,7 +82,10 @@ intpci_conf_size(pci_chipset_tag_t, pc
> > >  pcireg_t pci_conf_read(pci_chipset_tag_t, pcit

Re: MSI-X support

2016-05-04 Thread Hrvoje Popovski
On 4.5.2016. 8:50, Mark Kettenis wrote:
>> Date: Tue, 3 May 2016 15:23:07 -0700
>> From: Mike Larkin 
>>
>> On Tue, May 03, 2016 at 09:40:28PM +0200, Mark Kettenis wrote:
>>> Today mpi@ reminded me that I had written support for MSI-X some time
>>> ago.  Since he is interested in using multiple vectors, I extended the
>>> code I had a bit to support that feature as well.  This introduces a
>>> new function:
>>>
>>> int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);
>>>
>>> You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
>>> pass it a vector number as the 2nd argument.  Typically you'll pass 0,
>>> wich will map the 1st vector, which is always there on hardware with
>>> MSI-X support.  Some hardware supports more than 1 vector.  Typical
>>> examples are network cards that support multiple rings.  Please be
>>> aware that on architectures like i386 and amd64, the number of
>>> interrupt vectors at each level is limited.  If you consume too many
>>> of them, devices may fail to attach.
>>>
>>> As for the implementation.  This only adds code for amd64.  I'll
>>> probably add support for sparc64 as well.  I'm hesitant about i386
>>> because it has even less available interrupt vectors than amd64.
>>>
>>> Notice that the amd64 implementation uses _bus_space_map() and
>>> _bus_space_unmap().  That is deliberate.  The MSI-X registers miht
>>> share a BAR with other registers that our drivers already map.  The
>>> underscored versions of the mapping routines make sure that we don't
>>> fail to map things in that case.
>>>
>>> ok?
>>>
>>
>> Did you want to include the if_em and xhci bits too?
> 
> Yes.  They seem to work.  But I can leave them out if people deem this
> too risky.  They'll be separate commits anyway.

Hi,

it seems to work fine here ...

em0 at pci9 dev 0 function 0 "Intel I350" rev 0x01: msix, address
40:f2:e9:10:56:1c
em1 at pci9 dev 0 function 1 "Intel I350" rev 0x01: msix, address
40:f2:e9:10:56:1d
em2 at pci9 dev 0 function 2 "Intel I350" rev 0x01: msix, address
40:f2:e9:10:56:1e
em3 at pci9 dev 0 function 3 "Intel I350" rev 0x01: msix, address
40:f2:e9:10:56:1f


dmesg
OpenBSD 5.9-current (GENERIC.MP) #1: Tue May  3 23:41:02 CEST 2016
r...@x3550m4.my.domain:/usr/src/sys/arch/amd64/compile/GENERIC.MP
RTC BIOS diagnostic error 80
real mem = 34314878976 (32725MB)
avail mem = 33270431744 (31729MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.7 @ 0x7e67c000 (84 entries)
bios0: vendor IBM version "-[D7E146CUS-1.82]-" date 04/09/2015
bios0: IBM IBM System x3550 M4 Server -[7914T91]-
acpi0 at bios0: rev 2
acpi0: sleep states S0 S5
acpi0: tables DSDT FACP TCPA ERST HEST HPET APIC MCFG OEM0 OEM1 SLIT
SRAT SLIC SSDT SSDT SSDT SSDT SSDT SSDT DMAR
acpi0: wakeup devices MRP1(S4) DCC0(S4) MRP3(S4) MRP5(S4) EHC2(S5)
PEX0(S5) PEX7(S5) EHC1(S5) IP2P(S3) MRPB(S4) MRPC(S4) MRPD(S4) MRPF(S4)
MRPG(S4) MRPH(S4) MRPI(S4) [...]
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpihpet0 at acpi0: 14318179 Hz
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, 2400.40 MHz
cpu0:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,DCA,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,LONG,LAHF,PERF,ITSC,FSGSBASE,SMEP,ERMS,SENSOR,ARAT
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
cpu0: apic clock running at 99MHz
cpu0: mwait min=64, max=64, C-substates=0.2.1.1, IBE
cpu1 at mainbus0: apid 2 (application processor)
cpu1: Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, 2400.00 MHz
cpu1:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,DCA,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,LONG,LAHF,PERF,ITSC,FSGSBASE,SMEP,ERMS,SENSOR,ARAT
cpu1: 256KB 64b/line 8-way L2 cache
cpu1: smt 0, core 1, package 0
cpu2 at mainbus0: apid 4 (application processor)
cpu2: Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz, 2400.00 MHz
cpu2:
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-CPL,VMX,SMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,PCID,DCA,SSE4.1,SSE4.2,x2APIC,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,

Re: MSI-X support

2016-05-03 Thread Mark Kettenis
> Date: Tue, 3 May 2016 15:23:07 -0700
> From: Mike Larkin 
> 
> On Tue, May 03, 2016 at 09:40:28PM +0200, Mark Kettenis wrote:
> > Today mpi@ reminded me that I had written support for MSI-X some time
> > ago.  Since he is interested in using multiple vectors, I extended the
> > code I had a bit to support that feature as well.  This introduces a
> > new function:
> > 
> > int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);
> > 
> > You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
> > pass it a vector number as the 2nd argument.  Typically you'll pass 0,
> > wich will map the 1st vector, which is always there on hardware with
> > MSI-X support.  Some hardware supports more than 1 vector.  Typical
> > examples are network cards that support multiple rings.  Please be
> > aware that on architectures like i386 and amd64, the number of
> > interrupt vectors at each level is limited.  If you consume too many
> > of them, devices may fail to attach.
> > 
> > As for the implementation.  This only adds code for amd64.  I'll
> > probably add support for sparc64 as well.  I'm hesitant about i386
> > because it has even less available interrupt vectors than amd64.
> > 
> > Notice that the amd64 implementation uses _bus_space_map() and
> > _bus_space_unmap().  That is deliberate.  The MSI-X registers miht
> > share a BAR with other registers that our drivers already map.  The
> > underscored versions of the mapping routines make sure that we don't
> > fail to map things in that case.
> > 
> > ok?
> > 
> 
> Did you want to include the if_em and xhci bits too?

Yes.  They seem to work.  But I can leave them out if people deem this
too risky.  They'll be separate commits anyway.

> > Index: arch/alpha/pci/pci_machdep.h
> > ===
> > RCS file: /cvs/src/sys/arch/alpha/pci/pci_machdep.h,v
> > retrieving revision 1.29
> > diff -u -p -r1.29 pci_machdep.h
> > --- arch/alpha/pci/pci_machdep.h26 Jul 2015 05:09:44 -  1.29
> > +++ arch/alpha/pci/pci_machdep.h3 May 2016 19:26:30 -
> > @@ -104,6 +104,7 @@ int alpha_sysctl_chipset(int *, u_int, c
> >  #definepci_conf_write(c, t, r, v)  
> > \
> >  (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
> >  #definepci_intr_map_msi(pa, ihp)   (-1)
> > +#definepci_intr_map_msix(pa, vec, ihp) (-1)
> >  #definepci_intr_string(c, ih)  
> > \
> >  (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
> >  #definepci_intr_line(c, ih)
> > \
> > Index: arch/amd64/include/i82093var.h
> > ===
> > RCS file: /cvs/src/sys/arch/amd64/include/i82093var.h,v
> > retrieving revision 1.4
> > diff -u -p -r1.4 i82093var.h
> > --- arch/amd64/include/i82093var.h  21 May 2011 15:58:27 -  1.4
> > +++ arch/amd64/include/i82093var.h  3 May 2016 19:26:30 -
> > @@ -70,6 +70,7 @@ struct ioapic_softc {
> >  
> >  #define APIC_INT_VIA_APIC  0x1000
> >  #define APIC_INT_VIA_MSG   0x2000
> > +#define APIC_INT_VIA_MSGX  0x4000
> >  #define APIC_INT_APIC_MASK 0x00ff
> >  #define APIC_INT_APIC_SHIFT16
> >  #define APIC_INT_PIN_MASK  0xff00
> > Index: arch/amd64/include/pci_machdep.h
> > ===
> > RCS file: /cvs/src/sys/arch/amd64/include/pci_machdep.h,v
> > retrieving revision 1.24
> > diff -u -p -r1.24 pci_machdep.h
> > --- arch/amd64/include/pci_machdep.h29 Oct 2015 23:08:45 -  
> > 1.24
> > +++ arch/amd64/include/pci_machdep.h3 May 2016 19:26:30 -
> > @@ -82,7 +82,10 @@ int  pci_conf_size(pci_chipset_tag_t, pc
> >  pcireg_t   pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
> >  void   pci_conf_write(pci_chipset_tag_t, pcitag_t, int,
> > pcireg_t);
> > -intpci_intr_map_msi(struct pci_attach_args *, 
> > pci_intr_handle_t *);
> > +intpci_intr_map_msi(struct pci_attach_args *,
> > +   pci_intr_handle_t *);
> > +intpci_intr_map_msix(struct pci_attach_args *,
> > +   int, pci_intr_handle_t *);
> >  intpci_intr_map(struct pci_attach_args *, 
> > pci_intr_handle_t *);
> >  const char *pci_intr_string(pci_ch

Re: MSI-X support

2016-05-03 Thread Mike Larkin
On Tue, May 03, 2016 at 09:40:28PM +0200, Mark Kettenis wrote:
> Today mpi@ reminded me that I had written support for MSI-X some time
> ago.  Since he is interested in using multiple vectors, I extended the
> code I had a bit to support that feature as well.  This introduces a
> new function:
> 
> int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);
> 
> You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
> pass it a vector number as the 2nd argument.  Typically you'll pass 0,
> wich will map the 1st vector, which is always there on hardware with
> MSI-X support.  Some hardware supports more than 1 vector.  Typical
> examples are network cards that support multiple rings.  Please be
> aware that on architectures like i386 and amd64, the number of
> interrupt vectors at each level is limited.  If you consume too many
> of them, devices may fail to attach.
> 
> As for the implementation.  This only adds code for amd64.  I'll
> probably add support for sparc64 as well.  I'm hesitant about i386
> because it has even less available interrupt vectors than amd64.
> 
> Notice that the amd64 implementation uses _bus_space_map() and
> _bus_space_unmap().  That is deliberate.  The MSI-X registers miht
> share a BAR with other registers that our drivers already map.  The
> underscored versions of the mapping routines make sure that we don't
> fail to map things in that case.
> 
> ok?
> 

Did you want to include the if_em and xhci bits too?

-ml

> 
> Index: arch/alpha/pci/pci_machdep.h
> ===
> RCS file: /cvs/src/sys/arch/alpha/pci/pci_machdep.h,v
> retrieving revision 1.29
> diff -u -p -r1.29 pci_machdep.h
> --- arch/alpha/pci/pci_machdep.h  26 Jul 2015 05:09:44 -  1.29
> +++ arch/alpha/pci/pci_machdep.h  3 May 2016 19:26:30 -
> @@ -104,6 +104,7 @@ int alpha_sysctl_chipset(int *, u_int, c
>  #define  pci_conf_write(c, t, r, v)  
> \
>  (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
>  #define  pci_intr_map_msi(pa, ihp)   (-1)
> +#define  pci_intr_map_msix(pa, vec, ihp) (-1)
>  #define  pci_intr_string(c, ih)  
> \
>  (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
>  #define  pci_intr_line(c, ih)
> \
> Index: arch/amd64/include/i82093var.h
> ===
> RCS file: /cvs/src/sys/arch/amd64/include/i82093var.h,v
> retrieving revision 1.4
> diff -u -p -r1.4 i82093var.h
> --- arch/amd64/include/i82093var.h21 May 2011 15:58:27 -  1.4
> +++ arch/amd64/include/i82093var.h3 May 2016 19:26:30 -
> @@ -70,6 +70,7 @@ struct ioapic_softc {
>  
>  #define APIC_INT_VIA_APIC0x1000
>  #define APIC_INT_VIA_MSG 0x2000
> +#define APIC_INT_VIA_MSGX0x4000
>  #define APIC_INT_APIC_MASK   0x00ff
>  #define APIC_INT_APIC_SHIFT  16
>  #define APIC_INT_PIN_MASK0xff00
> Index: arch/amd64/include/pci_machdep.h
> ===
> RCS file: /cvs/src/sys/arch/amd64/include/pci_machdep.h,v
> retrieving revision 1.24
> diff -u -p -r1.24 pci_machdep.h
> --- arch/amd64/include/pci_machdep.h  29 Oct 2015 23:08:45 -  1.24
> +++ arch/amd64/include/pci_machdep.h  3 May 2016 19:26:30 -
> @@ -82,7 +82,10 @@ intpci_conf_size(pci_chipset_tag_t, pc
>  pcireg_t pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
>  void pci_conf_write(pci_chipset_tag_t, pcitag_t, int,
>   pcireg_t);
> -int  pci_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *);
> +int  pci_intr_map_msi(struct pci_attach_args *,
> + pci_intr_handle_t *);
> +int  pci_intr_map_msix(struct pci_attach_args *,
> + int, pci_intr_handle_t *);
>  int  pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
>  const char   *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
>  void *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
> Index: arch/amd64/pci/pci_machdep.c
> ===
> RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
> retrieving revision 1.62
> diff -u -p -r1.62 pci_machdep.c
> --- arch/amd64/pci/pci_machdep.c  14 Mar 2015 03:38:46 -  1.62
> +++ arch/amd64/pci/pci_machdep.c  3 May 2016 19:26:30 -
> @@ -395,6 +395,143 @@ pci_intr_map_msi(struct pci_attach_args 
>   return 0;
>  }
>  
> +void msix_hwmask(struct pic *, i

MSI-X support

2016-05-03 Thread Mark Kettenis
Today mpi@ reminded me that I had written support for MSI-X some time
ago.  Since he is interested in using multiple vectors, I extended the
code I had a bit to support that feature as well.  This introduces a
new function:

int pci_intr_map_msix(struct pci_attach_args *, int, pci_intr_handle_t *);

You use it like pci_intr_map_msi(9) and pci_intr_map(9), buthave to
pass it a vector number as the 2nd argument.  Typically you'll pass 0,
wich will map the 1st vector, which is always there on hardware with
MSI-X support.  Some hardware supports more than 1 vector.  Typical
examples are network cards that support multiple rings.  Please be
aware that on architectures like i386 and amd64, the number of
interrupt vectors at each level is limited.  If you consume too many
of them, devices may fail to attach.

As for the implementation.  This only adds code for amd64.  I'll
probably add support for sparc64 as well.  I'm hesitant about i386
because it has even less available interrupt vectors than amd64.

Notice that the amd64 implementation uses _bus_space_map() and
_bus_space_unmap().  That is deliberate.  The MSI-X registers miht
share a BAR with other registers that our drivers already map.  The
underscored versions of the mapping routines make sure that we don't
fail to map things in that case.

ok?


Index: arch/alpha/pci/pci_machdep.h
===
RCS file: /cvs/src/sys/arch/alpha/pci/pci_machdep.h,v
retrieving revision 1.29
diff -u -p -r1.29 pci_machdep.h
--- arch/alpha/pci/pci_machdep.h26 Jul 2015 05:09:44 -  1.29
+++ arch/alpha/pci/pci_machdep.h3 May 2016 19:26:30 -
@@ -104,6 +104,7 @@ int alpha_sysctl_chipset(int *, u_int, c
 #definepci_conf_write(c, t, r, v)  
\
 (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v))
 #definepci_intr_map_msi(pa, ihp)   (-1)
+#definepci_intr_map_msix(pa, vec, ihp) (-1)
 #definepci_intr_string(c, ih)  
\
 (*(c)->pc_intr_string)((c)->pc_intr_v, (ih))
 #definepci_intr_line(c, ih)
\
Index: arch/amd64/include/i82093var.h
===
RCS file: /cvs/src/sys/arch/amd64/include/i82093var.h,v
retrieving revision 1.4
diff -u -p -r1.4 i82093var.h
--- arch/amd64/include/i82093var.h  21 May 2011 15:58:27 -  1.4
+++ arch/amd64/include/i82093var.h  3 May 2016 19:26:30 -
@@ -70,6 +70,7 @@ struct ioapic_softc {
 
 #define APIC_INT_VIA_APIC  0x1000
 #define APIC_INT_VIA_MSG   0x2000
+#define APIC_INT_VIA_MSGX  0x4000
 #define APIC_INT_APIC_MASK 0x00ff
 #define APIC_INT_APIC_SHIFT16
 #define APIC_INT_PIN_MASK  0xff00
Index: arch/amd64/include/pci_machdep.h
===
RCS file: /cvs/src/sys/arch/amd64/include/pci_machdep.h,v
retrieving revision 1.24
diff -u -p -r1.24 pci_machdep.h
--- arch/amd64/include/pci_machdep.h29 Oct 2015 23:08:45 -  1.24
+++ arch/amd64/include/pci_machdep.h3 May 2016 19:26:30 -
@@ -82,7 +82,10 @@ int  pci_conf_size(pci_chipset_tag_t, pc
 pcireg_t   pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
 void   pci_conf_write(pci_chipset_tag_t, pcitag_t, int,
pcireg_t);
-intpci_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *);
+intpci_intr_map_msi(struct pci_attach_args *,
+   pci_intr_handle_t *);
+intpci_intr_map_msix(struct pci_attach_args *,
+   int, pci_intr_handle_t *);
 intpci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
 const char *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
 void   *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
Index: arch/amd64/pci/pci_machdep.c
===
RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
retrieving revision 1.62
diff -u -p -r1.62 pci_machdep.c
--- arch/amd64/pci/pci_machdep.c14 Mar 2015 03:38:46 -  1.62
+++ arch/amd64/pci/pci_machdep.c3 May 2016 19:26:30 -
@@ -395,6 +395,143 @@ pci_intr_map_msi(struct pci_attach_args 
return 0;
 }
 
+void msix_hwmask(struct pic *, int);
+void msix_hwunmask(struct pic *, int);
+void msix_addroute(struct pic *, struct cpu_info *, int, int, int);
+void msix_delroute(struct pic *, struct cpu_info *, int, int, int);
+
+struct pic msix_pic = {
+   {0, {NULL}, NULL, 0, "msix", NULL, 0, 0},
+   PIC_MSI,
+#ifdef MULTIPROCESSOR
+   {},
+#endif
+   msix_hwmask,
+   msix_hwunmask,
+   msix_addroute,
+   msix_delroute,
+   NULL,
+   ioapic_edge_stubs
+};
+
+/*
+ * We pack the MSI-X vector number into the lower 8 bits of