arch/x86: Fix PCI IO config accessor
In case PCI_IO_CFG_EXT=n parameter 'reg' was not properly truncated to 8 bits and it would overflow to dev.fn part of the register. A similar thing could happen with 'dev' but that value originates from PCI_DEV() macro unlike 'reg'. Change-Id: Id2888e07fc0f2b182b4633a747c1786e5c560678 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/31847 Reviewed-by: Nico Huber <nico.h@gmx.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
eed64473fd
commit
9421727c70
|
@ -21,19 +21,22 @@
|
||||||
static __always_inline
|
static __always_inline
|
||||||
uint32_t pci_io_encode_addr(pci_devfn_t dev, uint16_t reg)
|
uint32_t pci_io_encode_addr(pci_devfn_t dev, uint16_t reg)
|
||||||
{
|
{
|
||||||
if (CONFIG(PCI_IO_CFG_EXT)) {
|
uint32_t addr = 1 << 31;
|
||||||
// seg == 0
|
|
||||||
return dev >> 4 | (reg & 0xff) | ((reg & 0xf00) << 16);
|
addr |= dev >> 4;
|
||||||
} else {
|
addr |= reg & 0xfc;
|
||||||
return dev >> 4 | reg;
|
|
||||||
}
|
if (CONFIG(PCI_IO_CFG_EXT))
|
||||||
|
addr |= (reg & 0xf00) << 16;
|
||||||
|
|
||||||
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline
|
static __always_inline
|
||||||
uint8_t pci_io_read_config8(pci_devfn_t dev, uint16_t reg)
|
uint8_t pci_io_read_config8(pci_devfn_t dev, uint16_t reg)
|
||||||
{
|
{
|
||||||
uint32_t addr = pci_io_encode_addr(dev, reg);
|
uint32_t addr = pci_io_encode_addr(dev, reg);
|
||||||
outl(0x80000000 | (addr & ~3), 0xCF8);
|
outl(addr, 0xCF8);
|
||||||
return inb(0xCFC + (reg & 3));
|
return inb(0xCFC + (reg & 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +44,7 @@ static __always_inline
|
||||||
uint16_t pci_io_read_config16(pci_devfn_t dev, uint16_t reg)
|
uint16_t pci_io_read_config16(pci_devfn_t dev, uint16_t reg)
|
||||||
{
|
{
|
||||||
uint32_t addr = pci_io_encode_addr(dev, reg);
|
uint32_t addr = pci_io_encode_addr(dev, reg);
|
||||||
outl(0x80000000 | (addr & ~3), 0xCF8);
|
outl(addr, 0xCF8);
|
||||||
return inw(0xCFC + (reg & 2));
|
return inw(0xCFC + (reg & 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +52,7 @@ static __always_inline
|
||||||
uint32_t pci_io_read_config32(pci_devfn_t dev, uint16_t reg)
|
uint32_t pci_io_read_config32(pci_devfn_t dev, uint16_t reg)
|
||||||
{
|
{
|
||||||
uint32_t addr = pci_io_encode_addr(dev, reg);
|
uint32_t addr = pci_io_encode_addr(dev, reg);
|
||||||
outl(0x80000000 | (addr & ~3), 0xCF8);
|
outl(addr, 0xCF8);
|
||||||
return inl(0xCFC);
|
return inl(0xCFC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +60,7 @@ static __always_inline
|
||||||
void pci_io_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
|
void pci_io_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
|
||||||
{
|
{
|
||||||
uint32_t addr = pci_io_encode_addr(dev, reg);
|
uint32_t addr = pci_io_encode_addr(dev, reg);
|
||||||
outl(0x80000000 | (addr & ~3), 0xCF8);
|
outl(addr, 0xCF8);
|
||||||
outb(value, 0xCFC + (reg & 3));
|
outb(value, 0xCFC + (reg & 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +68,7 @@ static __always_inline
|
||||||
void pci_io_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
|
void pci_io_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
|
||||||
{
|
{
|
||||||
uint32_t addr = pci_io_encode_addr(dev, reg);
|
uint32_t addr = pci_io_encode_addr(dev, reg);
|
||||||
outl(0x80000000 | (addr & ~3), 0xCF8);
|
outl(addr, 0xCF8);
|
||||||
outw(value, 0xCFC + (reg & 2));
|
outw(value, 0xCFC + (reg & 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +76,7 @@ static __always_inline
|
||||||
void pci_io_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
|
void pci_io_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
|
||||||
{
|
{
|
||||||
uint32_t addr = pci_io_encode_addr(dev, reg);
|
uint32_t addr = pci_io_encode_addr(dev, reg);
|
||||||
outl(0x80000000 | (addr & ~3), 0xCF8);
|
outl(addr, 0xCF8);
|
||||||
outl(value, 0xCFC);
|
outl(value, 0xCFC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue