mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:07:35 +00:00
Kernel: PCI MMIO no longer uses map_for_kernel()
PCI MMIO access is done by modifying the related PhysicalPage directly, then we request to remap the region to create the mapping.
This commit is contained in:
parent
24f2596345
commit
aca317d889
4 changed files with 19 additions and 45 deletions
|
@ -94,6 +94,14 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Address(const Address& address)
|
||||||
|
: m_seg(address.seg())
|
||||||
|
, m_bus(address.bus())
|
||||||
|
, m_slot(address.slot())
|
||||||
|
, m_function(address.function())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool is_null() const { return !m_bus && !m_slot && !m_function; }
|
bool is_null() const { return !m_bus && !m_slot && !m_function; }
|
||||||
operator bool() const { return !is_null(); }
|
operator bool() const { return !is_null(); }
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
virtual void enumerate_all(Function<void(Address, ID)>&) override final;
|
virtual void enumerate_all(Function<void(Address, ID)>&) override final;
|
||||||
|
|
||||||
virtual String get_access_type() override final { return "IO-Access"; };
|
virtual String get_access_type() override final { return "IO-Access"; };
|
||||||
|
virtual uint32_t get_segments_count() { return 1; };
|
||||||
protected:
|
protected:
|
||||||
IOAccess();
|
IOAccess();
|
||||||
|
|
||||||
|
@ -44,8 +44,7 @@ private:
|
||||||
virtual void write8_field(Address address, u32, u8) override final;
|
virtual void write8_field(Address address, u32, u8) override final;
|
||||||
virtual void write16_field(Address address, u32, u16) override final;
|
virtual void write16_field(Address address, u32, u16) override final;
|
||||||
virtual void write32_field(Address address, u32, u32) override final;
|
virtual void write32_field(Address address, u32, u32) override final;
|
||||||
|
|
||||||
virtual uint32_t get_segments_count() { return 1; };
|
|
||||||
virtual uint8_t get_segment_start_bus(u32) { return 0x0; };
|
virtual uint8_t get_segment_start_bus(u32) { return 0x0; };
|
||||||
virtual uint8_t get_segment_end_bus(u32) { return 0xFF; };
|
virtual uint8_t get_segment_end_bus(u32) { return 0xFF; };
|
||||||
};
|
};
|
|
@ -58,25 +58,23 @@ PCI::MMIOAccess::MMIOAccess(ACPI_RAW::MCFG& raw_mcfg)
|
||||||
, m_mapped_address(ChangeableAddress(0xFFFF, 0xFF, 0xFF, 0xFF))
|
, m_mapped_address(ChangeableAddress(0xFFFF, 0xFF, 0xFF, 0xFF))
|
||||||
{
|
{
|
||||||
kprintf("PCI: Using MMIO Mechanism for PCI Configuartion Space Access\n");
|
kprintf("PCI: Using MMIO Mechanism for PCI Configuartion Space Access\n");
|
||||||
m_mmio_window = *AnonymousVMObject::create_with_size(PAGE_ROUND_UP(PCI_MMIO_CONFIG_SPACE_SIZE));
|
m_mmio_window_region = MM.allocate_kernel_region(PAGE_ROUND_UP(PCI_MMIO_CONFIG_SPACE_SIZE), "PCI MMIO", Region::Access::Read | Region::Access::Write);
|
||||||
m_mmio_window_region = MM.allocate_kernel_region_with_vmobject(*m_mmio_window, m_mmio_window->size(), "PCI MMIO", Region::Access::Read | Region::Access::Write);
|
|
||||||
|
|
||||||
auto checkup_region = MM.allocate_kernel_region((PAGE_SIZE * 2), "PCI MCFG Checkup", Region::Access::Read | Region::Access::Write);
|
auto checkup_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)&raw_mcfg)),(PAGE_SIZE * 2), "PCI MCFG Checkup", Region::Access::Read | Region::Access::Write);
|
||||||
#ifdef PCI_DEBUG
|
#ifdef PCI_DEBUG
|
||||||
dbgprintf("PCI: Checking MCFG Table length to choose the correct mapping size\n");
|
dbgprintf("PCI: Checking MCFG Table length to choose the correct mapping size\n");
|
||||||
#endif
|
#endif
|
||||||
mmap_region(*checkup_region, PhysicalAddress((u32)&raw_mcfg & 0xfffff000));
|
|
||||||
ACPI_RAW::SDTHeader* sdt = (ACPI_RAW::SDTHeader*)(checkup_region->vaddr().get() + ((u32)&raw_mcfg & 0xfff));
|
ACPI_RAW::SDTHeader* sdt = (ACPI_RAW::SDTHeader*)checkup_region->vaddr().offset(offset_in_page((u32)&raw_mcfg)).as_ptr();
|
||||||
u32 length = sdt->length;
|
u32 length = sdt->length;
|
||||||
u8 revision = sdt->revision;
|
u8 revision = sdt->revision;
|
||||||
|
|
||||||
kprintf("PCI: MCFG, length - %u, revision %d\n", length, revision);
|
kprintf("PCI: MCFG, length - %u, revision %d\n", length, revision);
|
||||||
checkup_region->unmap();
|
checkup_region->unmap();
|
||||||
|
|
||||||
auto mcfg_region = MM.allocate_kernel_region(PAGE_ROUND_UP(length) + PAGE_SIZE, "PCI Parsing MCFG", Region::Access::Read | Region::Access::Write);
|
auto mcfg_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)&raw_mcfg)), PAGE_ROUND_UP(length) + PAGE_SIZE, "PCI Parsing MCFG", Region::Access::Read | Region::Access::Write);
|
||||||
mmap_region(*mcfg_region, PhysicalAddress((u32)&raw_mcfg & 0xfffff000));
|
|
||||||
|
|
||||||
ACPI_RAW::MCFG& mcfg = *((ACPI_RAW::MCFG*)(mcfg_region->vaddr().get() + ((u32)&raw_mcfg & 0xfff)));
|
auto& mcfg = *(ACPI_RAW::MCFG*)mcfg_region->vaddr().offset(offset_in_page((u32)&raw_mcfg)).as_ptr();
|
||||||
#ifdef PCI_DEBUG
|
#ifdef PCI_DEBUG
|
||||||
dbgprintf("PCI: Checking MCFG @ V 0x%x, P 0x%x\n", &mcfg, &raw_mcfg);
|
dbgprintf("PCI: Checking MCFG @ V 0x%x, P 0x%x\n", &mcfg, &raw_mcfg);
|
||||||
#endif
|
#endif
|
||||||
|
@ -116,7 +114,8 @@ void PCI::MMIOAccess::map_device(Address address)
|
||||||
#ifdef PCI_DEBUG
|
#ifdef PCI_DEBUG
|
||||||
dbgprintf("PCI: Mapping device @ pci (%w:%b:%b.%b), V 0x%x, P 0x%x\n", address.seg(), address.bus(), address.slot(), address.function(), m_mmio_window_region->vaddr().get(), device_physical_mmio_space.get());
|
dbgprintf("PCI: Mapping device @ pci (%w:%b:%b.%b), V 0x%x, P 0x%x\n", address.seg(), address.bus(), address.slot(), address.function(), m_mmio_window_region->vaddr().get(), device_physical_mmio_space.get());
|
||||||
#endif
|
#endif
|
||||||
MM.map_for_kernel(m_mmio_window_region->vaddr(), device_physical_mmio_space);
|
m_mmio_window_region->vmobject().physical_pages()[0] = PhysicalPage::create(device_physical_mmio_space,false,false);
|
||||||
|
m_mmio_window_region->remap();
|
||||||
m_mapped_address = address;
|
m_mapped_address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,33 +204,6 @@ void PCI::MMIOAccess::enumerate_all(Function<void(Address, ID)>& callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCI::MMIOAccess::mmap(VirtualAddress vaddr, PhysicalAddress paddr, u32 length)
|
|
||||||
{
|
|
||||||
unsigned i = 0;
|
|
||||||
while (length >= PAGE_SIZE) {
|
|
||||||
MM.map_for_kernel(VirtualAddress(vaddr.offset(i * PAGE_SIZE).get()), PhysicalAddress(paddr.offset(i * PAGE_SIZE).get()));
|
|
||||||
#ifdef PCI_DEBUG
|
|
||||||
dbgprintf("PCI: map - V 0x%x -> P 0x%x\n", vaddr.offset(i * PAGE_SIZE).get(), paddr.offset(i * PAGE_SIZE).get());
|
|
||||||
#endif
|
|
||||||
length -= PAGE_SIZE;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (length > 0) {
|
|
||||||
MM.map_for_kernel(vaddr.offset(i * PAGE_SIZE), paddr.offset(i * PAGE_SIZE), true);
|
|
||||||
}
|
|
||||||
#ifdef PCI_DEBUG
|
|
||||||
dbgprintf("PCI: Finished mapping\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCI::MMIOAccess::mmap_region(Region& region, PhysicalAddress paddr)
|
|
||||||
{
|
|
||||||
#ifdef PCI_DEBUG
|
|
||||||
dbgprintf("PCI: Mapping region, size - %u\n", region.size());
|
|
||||||
#endif
|
|
||||||
mmap(region.vaddr(), paddr, region.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
PCI::MMIOSegment::MMIOSegment(PhysicalAddress segment_base_addr, u8 start_bus, u8 end_bus)
|
PCI::MMIOSegment::MMIOSegment(PhysicalAddress segment_base_addr, u8 start_bus, u8 end_bus)
|
||||||
: m_base_addr(segment_base_addr)
|
: m_base_addr(segment_base_addr)
|
||||||
, m_start_bus(start_bus)
|
, m_start_bus(start_bus)
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
virtual void enumerate_all(Function<void(Address, ID)>&) override final;
|
virtual void enumerate_all(Function<void(Address, ID)>&) override final;
|
||||||
|
|
||||||
virtual String get_access_type() override final { return "MMIO-Access"; };
|
virtual String get_access_type() override final { return "MMIO-Access"; };
|
||||||
|
virtual u32 get_segments_count();
|
||||||
protected:
|
protected:
|
||||||
explicit MMIOAccess(ACPI_RAW::MCFG&);
|
explicit MMIOAccess(ACPI_RAW::MCFG&);
|
||||||
|
|
||||||
|
@ -54,16 +54,11 @@ private:
|
||||||
virtual void write32_field(Address address, u32, u32) override final;
|
virtual void write32_field(Address address, u32, u32) override final;
|
||||||
|
|
||||||
void map_device(Address address);
|
void map_device(Address address);
|
||||||
void mmap(VirtualAddress preferred_vaddr, PhysicalAddress paddr, u32);
|
|
||||||
void mmap_region(Region& region, PhysicalAddress paddr);
|
|
||||||
|
|
||||||
virtual u32 get_segments_count();
|
|
||||||
virtual u8 get_segment_start_bus(u32);
|
virtual u8 get_segment_start_bus(u32);
|
||||||
virtual u8 get_segment_end_bus(u32);
|
virtual u8 get_segment_end_bus(u32);
|
||||||
|
|
||||||
ACPI_RAW::MCFG& m_mcfg;
|
ACPI_RAW::MCFG& m_mcfg;
|
||||||
HashMap<u16, MMIOSegment*>& m_segments;
|
HashMap<u16, MMIOSegment*>& m_segments;
|
||||||
RefPtr<VMObject> m_mmio_window;
|
|
||||||
OwnPtr<Region> m_mmio_window_region;
|
OwnPtr<Region> m_mmio_window_region;
|
||||||
PCI::ChangeableAddress m_mapped_address;
|
PCI::ChangeableAddress m_mapped_address;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue