Kernel: Fix PCI bugs

IO BarRegion used vaddr instead of the correct paddr. Add API for
memory region iobase query.
This commit is contained in:
Bananymous 2023-10-16 16:50:49 +03:00
parent 31aa157201
commit 6f8fce94a0
2 changed files with 17 additions and 11 deletions

View File

@ -29,8 +29,9 @@ namespace Kernel::PCI
~BarRegion(); ~BarRegion();
BarType type() const { return m_type; } BarType type() const { return m_type; }
vaddr_t vaddr() const { return m_vaddr; } vaddr_t iobase() const { ASSERT(m_type == BarType::IO); return m_paddr; }
paddr_t paddr() const { return m_paddr; } vaddr_t vaddr() const { ASSERT(m_type == BarType::MEM); return m_vaddr; }
paddr_t paddr() const { ASSERT(m_type == BarType::MEM); return m_paddr; }
size_t size() const { return m_size; } size_t size() const { return m_size; }
void write8(off_t, uint8_t); void write8(off_t, uint8_t);

View File

@ -77,7 +77,7 @@ namespace Kernel::PCI
uint32_t temp = read_config_dword(bus, dev, func, offset & ~3); uint32_t temp = read_config_dword(bus, dev, func, offset & ~3);
temp &= ~(0xFF << byte); temp &= ~(0xFF << byte);
temp |= (uint32_t)value << byte; temp |= (uint32_t)value << byte;
write_config_dword(bus, dev, func, offset, temp); write_config_dword(bus, dev, func, offset & ~3, temp);
} }
static uint16_t get_vendor_id(uint8_t bus, uint8_t dev, uint8_t func) static uint16_t get_vendor_id(uint8_t bus, uint8_t dev, uint8_t func)
@ -252,8 +252,13 @@ namespace Kernel::PCI
device.func() device.func()
); );
dprintln(" type: {}", region->type() == BarType::IO ? "IO" : "MEM"); dprintln(" type: {}", region->type() == BarType::IO ? "IO" : "MEM");
dprintln(" paddr {}", (void*)region->paddr()); if (region->type() == BarType::IO)
dprintln(" vaddr {}", (void*)region->vaddr()); dprintln(" iobase {8H}", region->iobase());
else
{
dprintln(" paddr {}", (void*)region->paddr());
dprintln(" vaddr {}", (void*)region->vaddr());
}
dprintln(" size {}", region->size()); dprintln(" size {}", region->size());
#endif #endif
@ -290,42 +295,42 @@ namespace Kernel::PCI
void BarRegion::write8(off_t reg, uint8_t val) void BarRegion::write8(off_t reg, uint8_t val)
{ {
if (m_type == BarType::IO) if (m_type == BarType::IO)
return IO::outb(m_vaddr + reg, val); return IO::outb(m_paddr + reg, val);
MMIO::write8(m_vaddr + reg, val); MMIO::write8(m_vaddr + reg, val);
} }
void BarRegion::write16(off_t reg, uint16_t val) void BarRegion::write16(off_t reg, uint16_t val)
{ {
if (m_type == BarType::IO) if (m_type == BarType::IO)
return IO::outw(m_vaddr + reg, val); return IO::outw(m_paddr + reg, val);
MMIO::write16(m_vaddr + reg, val); MMIO::write16(m_vaddr + reg, val);
} }
void BarRegion::write32(off_t reg, uint32_t val) void BarRegion::write32(off_t reg, uint32_t val)
{ {
if (m_type == BarType::IO) if (m_type == BarType::IO)
return IO::outl(m_vaddr + reg, val); return IO::outl(m_paddr + reg, val);
MMIO::write32(m_vaddr + reg, val); MMIO::write32(m_vaddr + reg, val);
} }
uint8_t BarRegion::read8(off_t reg) uint8_t BarRegion::read8(off_t reg)
{ {
if (m_type == BarType::IO) if (m_type == BarType::IO)
return IO::inb(m_vaddr + reg); return IO::inb(m_paddr + reg);
return MMIO::read8(m_vaddr + reg); return MMIO::read8(m_vaddr + reg);
} }
uint16_t BarRegion::read16(off_t reg) uint16_t BarRegion::read16(off_t reg)
{ {
if (m_type == BarType::IO) if (m_type == BarType::IO)
return IO::inw(m_vaddr + reg); return IO::inw(m_paddr + reg);
return MMIO::read16(m_vaddr + reg); return MMIO::read16(m_vaddr + reg);
} }
uint32_t BarRegion::read32(off_t reg) uint32_t BarRegion::read32(off_t reg)
{ {
if (m_type == BarType::IO) if (m_type == BarType::IO)
return IO::inl(m_vaddr + reg); return IO::inl(m_paddr + reg);
return MMIO::read32(m_vaddr + reg); return MMIO::read32(m_vaddr + reg);
} }