All of lore.kernel.org
 help / color / mirror / Atom feed
* PCI VGA 0x3b0/0x3C0 aliases handling in Linux
@ 2017-12-05 16:43 Rudolf Marek
  2017-12-05 19:07 ` Bjorn Helgaas
  0 siblings, 1 reply; 9+ messages in thread
From: Rudolf Marek @ 2017-12-05 16:43 UTC (permalink / raw)
  To: linux-pci; +Cc: RayeR

Hi all,

Please CC us we are not subscribed. My friend  (on CC) ran into strange problems with his 
old PCI sound card under Linux. The very same card works fine in Windoze. 

It turned out that silly BIOS assigned the I/O BAR to an address which is positively decoded 
by some other PCIe bridge. The unlucky region collides with the legacy VGA
mirror region which is decoded by other PCI/PCIe bridge because bit 3 (PCI_BRIDGE_CTL_VGA) is set.

Here is a quote from random datasheet of PCI/PCIe bridge:

VGA_EN:

*  Memory accesses in the range 0x000A_0000 to 
000B_FFFF
*  I/O addresses in the first 64 Kbytes of the I/O address 
space (Address[31:16] for PCIe are 0x0000) and where 
Address[9:0] is in the range of 0x3B0 to 0x3BB or 0x3C0 
to 0x3DF (inclusive of ISA address aliases - 
Address[15:10] may possess any value and is not used in 
the decoding)

So, as you can see, it effectively forces the VGA I/O region to be mirrored all over the 64K I/O space.

What is interesting  is that the PCI bridge specs version 1.2?, added a new bit 4 (which is previously RO 0) which 
allows to decode only the full address for the 0x3b0/0x3c0 :

VGA_16BIT_EN:

This bit enables the bridge to provide 16-bit decoding of 
VGA I/O address precluding the decoding of alias addresses 
every 1 KB. This bit has meaning only if VGA Enable bit is 
set

There is not even a define in the Linux which would describe this bit. The "fix" for the problem is to simply
turn off the aliasing.

I would like to ask:

1) If there is some code already which would check this PCI resources collisions (at least issue an warning)

2) Do you think that Linux should try to fix this? (Yes the BIOS messed it up, but hey, the Windoze figured it out)

I suspect it will fix couple of problems people were seeing with old PCI cards as they tend to have the I/O regions
(I stumbled upon various reports when was suspecting the PCIe to PCI ITE chip and interrupt routing problems)

Thanks
Rudolf

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PCI VGA 0x3b0/0x3C0 aliases handling in Linux
  2017-12-05 16:43 PCI VGA 0x3b0/0x3C0 aliases handling in Linux Rudolf Marek
@ 2017-12-05 19:07 ` Bjorn Helgaas
  2017-12-05 19:34   ` rayer
  2017-12-05 20:35   ` Rudolf Marek
  0 siblings, 2 replies; 9+ messages in thread
From: Bjorn Helgaas @ 2017-12-05 19:07 UTC (permalink / raw)
  To: Rudolf Marek; +Cc: linux-pci, RayeR

On Tue, Dec 05, 2017 at 05:43:00PM +0100, Rudolf Marek wrote:
> It turned out that silly BIOS assigned the I/O BAR to an address
> which is positively decoded by some other PCIe bridge. The unlucky
> region collides with the legacy VGA mirror region which is decoded
> by other PCI/PCIe bridge because bit 3 (PCI_BRIDGE_CTL_VGA) is set.
> 
> Here is a quote from random datasheet of PCI/PCIe bridge:
> 
> VGA_EN:
> 
> *  Memory accesses in the range 0x000A_0000 to 000B_FFFF *  I/O
> addresses in the first 64 Kbytes of the I/O address space
> (Address[31:16] for PCIe are 0x0000) and where Address[9:0] is in
> the range of 0x3B0 to 0x3BB or 0x3C0 to 0x3DF (inclusive of ISA
> address aliases - Address[15:10] may possess any value and is not
> used in the decoding)
> 
> So, as you can see, it effectively forces the VGA I/O region to be
> mirrored all over the 64K I/O space.
> 
> What is interesting  is that the PCI bridge specs version 1.2?,
> added a new bit 4 (which is previously RO 0) which allows to decode
> only the full address for the 0x3b0/0x3c0 :
> 
> VGA_16BIT_EN:
> 
> This bit enables the bridge to provide 16-bit decoding of VGA I/O
> address precluding the decoding of alias addresses every 1 KB. This
> bit has meaning only if VGA Enable bit is set
> 
> There is not even a define in the Linux which would describe this
> bit. The "fix" for the problem is to simply turn off the aliasing.
> 
> I would like to ask:
> 
> 1) If there is some code already which would check this PCI
> resources collisions (at least issue an warning)

We do check for PCI resource collisions, e.g., in
pci_claim_resource(), but this does not account for aliasing.

> 2) Do you think that Linux should try to fix this? (Yes the BIOS
> messed it up, but hey, the Windoze figured it out)

So if I understand correctly, you have

  - A bridge with PCI_BRIDGE_CTL_VGA set but VGA_16BIT_EN is clear

  - A peer of the bridge with an I/O BAR set to some alias of
    0x3c0-0x3df

In this case I think both the bridge and the peer device will claim
accesses to 0x3c0-0x3df, which is a bad thing.

And your proposal is that Linux should either

  - Turn on VGA_16BIT_EN (if supported by the bridge), or

  - If VGA_16BIT_EN is not supported by the bridge, try to reassign
    the peer I/O BAR so it doesn't conflict with the 0x3c0-0x3df
    aliases

If I'm understanding correctly, this sounds very reasonable.

> I suspect it will fix couple of problems people were seeing with old
> PCI cards as they tend to have the I/O regions (I stumbled upon
> various reports when was suspecting the PCIe to PCI ITE chip and
> interrupt routing problems)

To help understand and document this better, it would be nice to see a
complete dmesg log and "lspci -vv" output (as root) showing the
problem.  A kernel.org bugzilla would be a good place to store this.

It would also be great to collect up the other reports you've found
and see if we can definitively tie them to this issue and potentially
test a fix.

Bjorn

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PCI VGA 0x3b0/0x3C0 aliases handling in Linux
  2017-12-05 19:07 ` Bjorn Helgaas
@ 2017-12-05 19:34   ` rayer
  2017-12-05 19:46     ` Bjorn Helgaas
  2017-12-05 20:35   ` Rudolf Marek
  1 sibling, 1 reply; 9+ messages in thread
From: rayer @ 2017-12-05 19:34 UTC (permalink / raw)
  To: Bjorn Helgaas, Rudolf Marek; +Cc: linux-pci

Bjorn Helgaas wrote:
> So if I understand correctly, you have
>    - A bridge with PCI_BRIDGE_CTL_VGA set but VGA_16BIT_EN is clear
>    - A peer of the bridge with an I/O BAR set to some alias of
>      0x3c0-0x3df
Yes. The tested card is SB Audigy that was assigned to IO base address 
CFC0h with 32 Bytes window by PnP BIOS mechanism. The VGA registers are 
aliasing every 400h over enite 16bit IO space and come into colision 
with SB registers. It may shoot down any other PCI card that got mapped 
to "wrong" IO base. This may then result to bugs that tlookl like IRQ 
was not assigned properly but the primary issue is IO colision.
> In this case I think both the bridge and the peer device will claim
> accesses to 0x3c0-0x3df, which is a bad thing.
>
> And your proposal is that Linux should either
>
>    - Turn on VGA_16BIT_EN (if supported by the bridge), or
>
>    - If VGA_16BIT_EN is not supported by the bridge, try to reassign
>      the peer I/O BAR so it doesn't conflict with the 0x3c0-0x3df
>      aliases
Yes, it's a question if is safe to do as implicit action or do it only 
if specific kernel parameter is given. I belive it is safe to enable 
VGA_16BIT_EN when supported.
> To help understand and document this better, it would be nice to see a
> complete dmesg log and "lspci -vv" output (as root) showing the
> problem.  A kernel.org bugzilla would be a good place to store this.
OK, I have a lot of logs, I'll send later.
> It would also be great to collect up the other reports you've found
> and see if we can definitively tie them to this issue and potentially
> test a fix.
I guess this problem is fixed on most of current motherboards but there 
still may be people running old PCH 6x with preUEFI BIOS. I observed 
this behavior on Gigabyte GA-P67-DS3-B3 MB with latest official BIOS F5.
There are also other PCI issues esp. on intel motherboards with smae ITE 
PCIe2PCI bridge but different manner - I saw they had some wrong ACPI 
table but it had similar symptoms - a PCI card worked in Windows but 
observed IRQ error mapping under Linux. So that are very different kind 
of bug that needs to be separated from this case.

RayeR

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PCI VGA 0x3b0/0x3C0 aliases handling in Linux
  2017-12-05 19:34   ` rayer
@ 2017-12-05 19:46     ` Bjorn Helgaas
  0 siblings, 0 replies; 9+ messages in thread
From: Bjorn Helgaas @ 2017-12-05 19:46 UTC (permalink / raw)
  To: rayer; +Cc: Rudolf Marek, linux-pci

On Tue, Dec 05, 2017 at 08:34:59PM +0100, rayer wrote:
> Bjorn Helgaas wrote:
> >So if I understand correctly, you have
> >   - A bridge with PCI_BRIDGE_CTL_VGA set but VGA_16BIT_EN is clear
> >   - A peer of the bridge with an I/O BAR set to some alias of
> >     0x3c0-0x3df
> Yes. The tested card is SB Audigy that was assigned to IO base
> address CFC0h with 32 Bytes window by PnP BIOS mechanism. The VGA
> registers are aliasing every 400h over enite 16bit IO space and come
> into colision with SB registers. It may shoot down any other PCI
> card that got mapped to "wrong" IO base. This may then result to
> bugs that tlookl like IRQ was not assigned properly but the primary
> issue is IO colision.
> >In this case I think both the bridge and the peer device will claim
> >accesses to 0x3c0-0x3df, which is a bad thing.
> >
> >And your proposal is that Linux should either
> >
> >   - Turn on VGA_16BIT_EN (if supported by the bridge), or
> >
> >   - If VGA_16BIT_EN is not supported by the bridge, try to reassign
> >     the peer I/O BAR so it doesn't conflict with the 0x3c0-0x3df
> >     aliases

> Yes, it's a question if is safe to do as implicit action or do it
> only if specific kernel parameter is given. I belive it is safe to
> enable VGA_16BIT_EN when supported.

I think the situation is that we're taking a situation that is known
to be broken (two devices claiming same transaction) and making a
change (enabling VGA_16BIT_EN) that might fix it.  If it *doesn't* fix
it, we're no worse off than we were before, so I think it's safe to do
by default as long as we check to see whether VGA_16BIT_EN is
writable.  In general I don't like to add kernel parameters.

Bjorn

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PCI VGA 0x3b0/0x3C0 aliases handling in Linux
  2017-12-05 19:07 ` Bjorn Helgaas
  2017-12-05 19:34   ` rayer
@ 2017-12-05 20:35   ` Rudolf Marek
  2017-12-06 18:43     ` Bjorn Helgaas
  2017-12-08 14:22     ` rayer
  1 sibling, 2 replies; 9+ messages in thread
From: Rudolf Marek @ 2017-12-05 20:35 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, RayeR, mj

Hi Bjorn,

Thanks for the quick reply.

Dne 5.12.2017 v 20:07 Bjorn Helgaas napsal(a):
> So if I understand correctly, you have
> 
>   - A bridge with PCI_BRIDGE_CTL_VGA set but VGA_16BIT_EN is clear

Yes

> 
>   - A peer of the bridge with an I/O BAR set to some alias of
>     0x3c0-0x3df

It is not a peer bridge, but some other bridge on bus 0. The non-working device is
a Audigy PCI card (05:00.0)

The path is 00:1c.3 (Intel PCIe bridge) -> 4:00.0 (ITE PCIe-PCI bridge) -> 5:00.0 (audigy)
The other bridge is 00:01.0 which connects to some VGA on bus 1.

The Audigy has only one resource:

Region 0: I/O ports at cfc0 [size=32]

Which collides with the 0x3b0. We used "isadump -f" to verify we indeed see an alias.
Rayer booted to DOS, edited the BAR and loadlin back to Linux and the device works,
so it was that. Later he reported that setting the bit4 also fixed that.
>
> In this case I think both the bridge and the peer device will claim
> accesses to 0x3c0-0x3df, which is a bad thing.

Yes, the isadump -f confirmed that.

> 
> And your proposal is that Linux should either
> 
>   - Turn on VGA_16BIT_EN (if supported by the bridge), or
> 
>   - If VGA_16BIT_EN is not supported by the bridge, try to reassign
>     the peer I/O BAR so it doesn't conflict with the 0x3c0-0x3df
>     aliases

The Aliases are:

0x3B0 - 0x3BB  and 0x3C0 - 0x3DF and it seems that also VGA palette snoops 
and VGA palette snoops: 0x3C6, 0x3C8, 0x3C9 

It seems that the VGA_16BIT_EN could also control the palette snoops alias,
so in the end it should remove all aliases.
I hope someone access to more recent PCI bridge specs can confirm.

> If I'm understanding correctly, this sounds very reasonable.

Yes exactly. Question is why the insanity alias exists in the first place. 
What Mr. PCI tried to fix or break with that alias design?
Besides making logic simpler, I have no idea.

>> I suspect it will fix couple of problems people were seeing with old
>> PCI cards as they tend to have the I/O regions (I stumbled upon
>> various reports when was suspecting the PCIe to PCI ITE chip and
>> interrupt routing problems)
> 
> To help understand and document this better, it would be nice to see a
> complete dmesg log and "lspci -vv" output (as root) showing the
> problem.  A kernel.org bugzilla would be a good place to store this.

Yes sure, in what category

drivers/pci or platform/hardware?

> It would also be great to collect up the other reports you've found
> and see if we can definitively tie them to this issue and potentially
> test a fix.

Oh, hm, those were random searches using a search engine. I was talking about [1], 
but reading it again, all issues were interrupt related.

I'll try to reproduce my searches.

Btw, latest pciutils-3.5.6 also lack of decoding of the bit4. I added to Martin Mares to CC.

I can prepare a patch for PCIutils if needed. Martin, please tell.

Thanks
Rudolf

[1] https://bugzilla.kernel.org/show_bug.cgi?id=43238

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PCI VGA 0x3b0/0x3C0 aliases handling in Linux
  2017-12-05 20:35   ` Rudolf Marek
@ 2017-12-06 18:43     ` Bjorn Helgaas
  2017-12-09 19:40       ` Rudolf Marek
  2017-12-08 14:22     ` rayer
  1 sibling, 1 reply; 9+ messages in thread
From: Bjorn Helgaas @ 2017-12-06 18:43 UTC (permalink / raw)
  To: Rudolf Marek; +Cc: linux-pci, RayeR, mj

On Tue, Dec 05, 2017 at 09:35:22PM +0100, Rudolf Marek wrote:
> Dne 5.12.2017 v 20:07 Bjorn Helgaas napsal(a):
> > So if I understand correctly, you have
> > 
> >   - A bridge with PCI_BRIDGE_CTL_VGA set but VGA_16BIT_EN is clear
> 
> Yes
> 
> >   - A peer of the bridge with an I/O BAR set to some alias of
> >     0x3c0-0x3df
> 
> It is not a peer bridge, but some other bridge on bus 0. The non-working device is
> a Audigy PCI card (05:00.0)

00:01.0 and 00:1c.3 are peers in the sense that they're both on the
same bus.  00:1c.3 doesn't have a *BAR* that contains 0x3c0, but I
think it does have an I/O *window* set to an alias of 0x3c0, like
this (we don't actually print the implicit VGA bridge windows, but
maybe we should):

  00:01.0 PCI bridge to [bus 01]
  00:01.0   implicit bridge window [io 0x03c0-0x03df] + ISA aliases
  01:xx.0 VGA device legacy resource [io 0x03c0-0x03df]
  00:1c.3 PCI bridge to [bus 04-05]
  00:1c.3   bridge window [io 0xc000-0xcfff]
  04:00.0 PCI bridge to [bus 05]
  04:00.0   bridge window [io 0xc000-0xcfff]
  05:00.0 Audigy reg 0x10: [io 0xcfc0-0xcfdf]

0xcfc0 is a 10-bit alias of 0x03c0, so both bridges (00:01.0 and
00:1c.3) will claim it.

> The path is 00:1c.3 (Intel PCIe bridge) -> 4:00.0 (ITE PCIe-PCI bridge) -> 5:00.0 (audigy)
> The other bridge is 00:01.0 which connects to some VGA on bus 1.
> 
> The Audigy has only one resource:
> 
> Region 0: I/O ports at cfc0 [size=32]
> 
> Which collides with the 0x3b0. We used "isadump -f" to verify we indeed see an alias.
> Rayer booted to DOS, edited the BAR and loadlin back to Linux and the device works,
> so it was that. Later he reported that setting the bit4 also fixed that.
> >
> > In this case I think both the bridge and the peer device will claim
> > accesses to 0x3c0-0x3df, which is a bad thing.
> 
> Yes, the isadump -f confirmed that.

> > And your proposal is that Linux should either
> > 
> >   - Turn on VGA_16BIT_EN (if supported by the bridge), or
> > 
> >   - If VGA_16BIT_EN is not supported by the bridge, try to reassign
> >     the peer I/O BAR so it doesn't conflict with the 0x3c0-0x3df
> >     aliases
> 
> The Aliases are:
> 
> 0x3B0 - 0x3BB  and 0x3C0 - 0x3DF and it seems that also VGA palette snoops 
> and VGA palette snoops: 0x3C6, 0x3C8, 0x3C9 
> 
> It seems that the VGA_16BIT_EN could also control the palette snoops alias,
> so in the end it should remove all aliases.
> I hope someone access to more recent PCI bridge specs can confirm.

The PCI-to-PCI Bridge spec, r1.2, sec 3.2.5.18, says VGA_16BIT_EN
controls the bridge decoding for "all VGA I/O register accesses that
are forwarded from primary to secondary."  I would say that would
include VGA palette snoops.

> > If I'm understanding correctly, this sounds very reasonable.
> 
> Yes exactly. Question is why the insanity alias exists in the first place. 
> What Mr. PCI tried to fix or break with that alias design?
> Besides making logic simpler, I have no idea.

I think this 10-bit aliasing is a compatibility feature for ISA.

> >> I suspect it will fix couple of problems people were seeing with old
> >> PCI cards as they tend to have the I/O regions (I stumbled upon
> >> various reports when was suspecting the PCIe to PCI ITE chip and
> >> interrupt routing problems)
> > 
> > To help understand and document this better, it would be nice to see a
> > complete dmesg log and "lspci -vv" output (as root) showing the
> > problem.  A kernel.org bugzilla would be a good place to store this.
> 
> Yes sure, in what category
> 
> drivers/pci or platform/hardware?

drivers/pci

> > It would also be great to collect up the other reports you've found
> > and see if we can definitively tie them to this issue and potentially
> > test a fix.
> 
> Oh, hm, those were random searches using a search engine. I was talking about [1], 
> but reading it again, all issues were interrupt related.
> 
> I'll try to reproduce my searches.
> 
> Btw, latest pciutils-3.5.6 also lack of decoding of the bit4. I added to Martin Mares to CC.
> 
> I can prepare a patch for PCIutils if needed. Martin, please tell.

Yes, a pciutils patch would be great.  It would be ideal if you could
prepare the patch and send it to Martin and cc linux-pci.

> [1] https://bugzilla.kernel.org/show_bug.cgi?id=43238

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PCI VGA 0x3b0/0x3C0 aliases handling in Linux
  2017-12-05 20:35   ` Rudolf Marek
  2017-12-06 18:43     ` Bjorn Helgaas
@ 2017-12-08 14:22     ` rayer
  1 sibling, 0 replies; 9+ messages in thread
From: rayer @ 2017-12-08 14:22 UTC (permalink / raw)
  To: Rudolf Marek, Bjorn Helgaas, František Ryšánek, lhc
  Cc: linux-pci, mj

[-- Attachment #1: Type: text/plain, Size: 5677 bytes --]

Hi,
I made a custom fix for this issue in my ROMOS (ISA/PCI option ROM 
module) 1.06 that I released today
http://rayer.g6.cz/romos/romose.htm
(see notes in changelog for 7.12.2017)
It's just a primitive piece of code targetted to my MoBo that is 
executed before OS boots, but anyone else can customize it for different 
chipset or different purpose. Everything works fine now. I already sent 
a bug report to Gigabyte but I don't expect they they will release BIOS 
update for 5 years old MoBo neither their 1st level support will 
understand what I'm talking about so help yourself...

In the attachment are various logs from Linux and my DOS tool (a1 in 
filename means SB Audigy, a2 is SB Audigy2, ite is my onboard PCIE2PCI 
bridge IT8892E and pericom is external PCIE2PCI adapter with  Pericom 
PI7C9X111SL bridge. Kernel logs was filtered off some unrelated messages 
like ata/usb/etc...
Bjorn, you can upload and use these logs as/where you want.

============

;%define USE_PCI_REG_PATCH       ;compile a piece code to patch a PCI register in specific PCI device (executed on every boot)
PPCI_BUS	EQU 0		;PCI to PCI bridge 8086:0101h bus number
PPCI_DEV	EQU 1		;PCI to PCI bridge 8086:0101h device number
PPCI_FUNC	EQU 0		;PCI to PCI bridge 8086:0101h function number
PPCI_REG	EQU 3Ch 	;PCI to PCI bridge 8086:0101h INTR&BCTRL 32b-aligned register number (3Ch:INTR, 3Eh:BCTRL)
PPCI_REG_ORMSK	EQU 00100000h	;OR mask to patch Bridge Control Register bit 4-VGA 16-Bit Decode enable (to supress VGA ports aliasing causing conflicts in I/O space)
PPCI_REG_ANDMSK EQU 0FFFFFFFFh	;AND mask (not used)

;EXECUTE OPTIONAL PCI DEVICE REGISTER PATCH CODE
%ifdef USE_PCI_REG_PATCH	;only if we need to patch a PCI register in specific PCI device (executed on every boot)
CPU 386 			;code compatability raised to 386
	CLI			;disable interrupts to perform atomic I/O operation
	PUSH	EAX             ;save 32-bit EAX
	MOV	DX,0CF8h	;set PCI Config Address Register I/O address
	MOV	EAX,80000000h|(PPCI_BUS<<16)|(PPCI_DEV<<11)|(PPCI_FUNC<<8)|PPCI_REG ; make PCI address: bit31=1, bit30:24=reserved, bit23:16=bus# [0-255], bit15:11=dev# [0-31], bit10:8=func# [0-7], bit7:0=cfgreg [0-255]
	OUT	DX,EAX		;write PCI address to PCI Config Address Register
	MOV	DX,0CFCh	;set PCI Config Data Register I/O address
	IN	EAX,DX		;read PCI Config Data Register to EAX
	OR	EAX,PPCI_REG_ORMSK ;set required bits to 1
;	 AND	 EAX,PPCI_REG_ANDMSK ;set required bits to 0
	OUT	DX,EAX		;write modified EAX back to PCI Config Data Register
	POP	EAX             ;restored 32-bit EAX
	STI			;enable interrupts
%endif

Martin



Rudolf Marek wrote:
> Hi Bjorn,
>
> Thanks for the quick reply.
>
> Dne 5.12.2017 v 20:07 Bjorn Helgaas napsal(a):
>> So if I understand correctly, you have
>>
>>    - A bridge with PCI_BRIDGE_CTL_VGA set but VGA_16BIT_EN is clear
> Yes
>
>>    - A peer of the bridge with an I/O BAR set to some alias of
>>      0x3c0-0x3df
> It is not a peer bridge, but some other bridge on bus 0. The non-working device is
> a Audigy PCI card (05:00.0)
>
> The path is 00:1c.3 (Intel PCIe bridge) -> 4:00.0 (ITE PCIe-PCI bridge) -> 5:00.0 (audigy)
> The other bridge is 00:01.0 which connects to some VGA on bus 1.
>
> The Audigy has only one resource:
>
> Region 0: I/O ports at cfc0 [size=32]
>
> Which collides with the 0x3b0. We used "isadump -f" to verify we indeed see an alias.
> Rayer booted to DOS, edited the BAR and loadlin back to Linux and the device works,
> so it was that. Later he reported that setting the bit4 also fixed that.
>> In this case I think both the bridge and the peer device will claim
>> accesses to 0x3c0-0x3df, which is a bad thing.
> Yes, the isadump -f confirmed that.
>
>> And your proposal is that Linux should either
>>
>>    - Turn on VGA_16BIT_EN (if supported by the bridge), or
>>
>>    - If VGA_16BIT_EN is not supported by the bridge, try to reassign
>>      the peer I/O BAR so it doesn't conflict with the 0x3c0-0x3df
>>      aliases
> The Aliases are:
>
> 0x3B0 - 0x3BB  and 0x3C0 - 0x3DF and it seems that also VGA palette snoops
> and VGA palette snoops: 0x3C6, 0x3C8, 0x3C9
>
> It seems that the VGA_16BIT_EN could also control the palette snoops alias,
> so in the end it should remove all aliases.
> I hope someone access to more recent PCI bridge specs can confirm.
>
>> If I'm understanding correctly, this sounds very reasonable.
> Yes exactly. Question is why the insanity alias exists in the first place.
> What Mr. PCI tried to fix or break with that alias design?
> Besides making logic simpler, I have no idea.
>
>>> I suspect it will fix couple of problems people were seeing with old
>>> PCI cards as they tend to have the I/O regions (I stumbled upon
>>> various reports when was suspecting the PCIe to PCI ITE chip and
>>> interrupt routing problems)
>> To help understand and document this better, it would be nice to see a
>> complete dmesg log and "lspci -vv" output (as root) showing the
>> problem.  A kernel.org bugzilla would be a good place to store this.
> Yes sure, in what category
>
> drivers/pci or platform/hardware?
>
>> It would also be great to collect up the other reports you've found
>> and see if we can definitively tie them to this issue and potentially
>> test a fix.
> Oh, hm, those were random searches using a search engine. I was talking about [1],
> but reading it again, all issues were interrupt related.
>
> I'll try to reproduce my searches.
>
> Btw, latest pciutils-3.5.6 also lack of decoding of the bit4. I added to Martin Mares to CC.
>
> I can prepare a patch for PCIutils if needed. Martin, please tell.
>
> Thanks
> Rudolf
>
> [1] https://bugzilla.kernel.org/show_bug.cgi?id=43238
>
>


[-- Attachment #2: pci-sb-test.zip --]
[-- Type: application/x-zip-compressed, Size: 89266 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PCI VGA 0x3b0/0x3C0 aliases handling in Linux
  2017-12-06 18:43     ` Bjorn Helgaas
@ 2017-12-09 19:40       ` Rudolf Marek
  2017-12-25 14:29         ` Rudolf Marek
  0 siblings, 1 reply; 9+ messages in thread
From: Rudolf Marek @ 2017-12-09 19:40 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, RayeR, mj

Hi Bjorn,

Thanks for the nice summary.

Dne 6.12.2017 v 19:43 Bjorn Helgaas napsal(a):
>> Yes exactly. Question is why the insanity alias exists in the first place. 
>> What Mr. PCI tried to fix or break with that alias design?
>> Besides making logic simpler, I have no idea.
> 
> I think this 10-bit aliasing is a compatibility feature for ISA.
> 

I looked it up in the "PCI System Architecture (4th Edition)" the whole
madness exists because there were legacy ISA drivers accessing the hardware
using the alias addresses. The same reason applies for the ISA enable bit 
on PCI bridge, where it will discards ISA accesses from primary side to 
allow the aliases propagate only to PCI/ISA bridge.

>> drivers/pci or platform/hardware?
> 
> drivers/pci
> 

OK I created  bug report available on [1], also using parts of your mails. I also tried
to summarize:

The Linux should do following:

Turn on VGA_16BIT_EN if supported by the bridge

If VGA_16BIT_EN is not supported by the bridge, try to reassign
the peer I/O BAR so it doesn't conflict with the 0x3b0-0x3df
aliases

The older PCI specs specifies the VGA_16BIT_EN as read as zero, so
it could be safe to try to turn it on all bridges, because maybe
the VGA arbiter can later switch another VGA card as primary

(I fixed the start of alias to 0x3b0 you had 0x3c0 in your mails).

It looks that:

/*
 * We don't have to worry about legacy ISA devices, so nothing to do here.
 * This is marked as __weak because multiple architectures define it; it should
 * eventually go away.
 */
resource_size_t __weak pcibios_align_resource(void *data,

Comment is not true, the aliasing problem exists on all architectures.

Thanks
Rudolf

[1] https://bugzilla.kernel.org/show_bug.cgi?id=198113

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PCI VGA 0x3b0/0x3C0 aliases handling in Linux
  2017-12-09 19:40       ` Rudolf Marek
@ 2017-12-25 14:29         ` Rudolf Marek
  0 siblings, 0 replies; 9+ messages in thread
From: Rudolf Marek @ 2017-12-25 14:29 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, RayeR

Hi all,

Dne 9.12.2017 v 20:40 Rudolf Marek napsal(a):
> Turn on VGA_16BIT_EN if supported by the bridge

It turns out, there are at least two bridges, where this bit is broken:

PEX 8114BC PCI Express-to-PCI/PCI-X Bridge Errata Documentation
PEX 8114BA PCI Express-to-PCI/PCI-X Bridge Errata Documentation

Description
In PCI or PCI-X Forward or Reverse Transparent Bridge mode, the Bridge Control
register VGA 16-Bit Decode bit (offset 3Ch[20]) does not function correctly. PCI Address
bits [9:0] are correctly decoded; however, PCI Address bits [15:10] are not decoded,
causing the PEX 8114 to ignore these Address lines.

It seems that this feature is required by windoze server edition:

"Virtual bridges that comply with PCI Express also comply with PCI-to-PCI Bridge Architecture Specification, Revision 1.1. In addition, VGA 16-bit decode (Section 3.2.5.18, "Bridge Control Register, bit 4") and SSID and SSVID (Section 3.2.5.13) from PCI-to-PCI Bridge Architecture Specification, Revision 1.2, must also be supported."


I tried to have a look, how to implement the resources to deal with the ISA aliasing, but I definitely need some pointers how to do that.

Overall approach:

For all PCI bridges, try to enable the 16-bit I/O (older bridges have this bit RO), minus the two broken above, note the state
in say, dev->hasvga16, perhaps do this in pci/quirks.c ?

During the PCI bridge enumeration, add extra resources if dev->hasvga16 is zero. I hope that the resource allocator can fix it on its own.
We should do that regardless of state of PCI_BRIDGE_CTL_VGA as pci_set_vga_state() could switch it later.

I don't know if it would be enough to modify  pci_read_bridge_bases() in drivers/pci/probe.c and add there all the ISA aliases of 0x3b0-0x3df
(similarly it adds transparent bridge resources)

There is 48 resources to be added, I hope there is no limit, seems there is just linked list.

N= 0 - F

0xN3b0-0xN3df
0xN7b0-0xN7df
0xNfb0-0xNfdf

Thanks
Rudolf

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-12-25 14:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-05 16:43 PCI VGA 0x3b0/0x3C0 aliases handling in Linux Rudolf Marek
2017-12-05 19:07 ` Bjorn Helgaas
2017-12-05 19:34   ` rayer
2017-12-05 19:46     ` Bjorn Helgaas
2017-12-05 20:35   ` Rudolf Marek
2017-12-06 18:43     ` Bjorn Helgaas
2017-12-09 19:40       ` Rudolf Marek
2017-12-25 14:29         ` Rudolf Marek
2017-12-08 14:22     ` rayer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.