From aca317d889c1c307b183e4af98c02ef93ebd3359 Mon Sep 17 00:00:00 2001 From: Liav A Date: Tue, 21 Jan 2020 04:33:43 +0200 Subject: [PATCH] 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. --- Kernel/PCI/Definitions.h | 8 +++++++ Kernel/PCI/IOAccess.h | 5 ++--- Kernel/PCI/MMIOAccess.cpp | 44 +++++++-------------------------------- Kernel/PCI/MMIOAccess.h | 7 +------ 4 files changed, 19 insertions(+), 45 deletions(-) diff --git a/Kernel/PCI/Definitions.h b/Kernel/PCI/Definitions.h index d46ee7a275..d3dcf49d74 100644 --- a/Kernel/PCI/Definitions.h +++ b/Kernel/PCI/Definitions.h @@ -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; } operator bool() const { return !is_null(); } diff --git a/Kernel/PCI/IOAccess.h b/Kernel/PCI/IOAccess.h index 09b2030db1..d2a35804fa 100644 --- a/Kernel/PCI/IOAccess.h +++ b/Kernel/PCI/IOAccess.h @@ -33,7 +33,7 @@ public: virtual void enumerate_all(Function&) override final; virtual String get_access_type() override final { return "IO-Access"; }; - + virtual uint32_t get_segments_count() { return 1; }; protected: IOAccess(); @@ -44,8 +44,7 @@ private: virtual void write8_field(Address address, u32, u8) override final; virtual void write16_field(Address address, u32, u16) 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_end_bus(u32) { return 0xFF; }; }; \ No newline at end of file diff --git a/Kernel/PCI/MMIOAccess.cpp b/Kernel/PCI/MMIOAccess.cpp index 1e505d2af2..c182101921 100644 --- a/Kernel/PCI/MMIOAccess.cpp +++ b/Kernel/PCI/MMIOAccess.cpp @@ -58,25 +58,23 @@ PCI::MMIOAccess::MMIOAccess(ACPI_RAW::MCFG& raw_mcfg) , m_mapped_address(ChangeableAddress(0xFFFF, 0xFF, 0xFF, 0xFF)) { 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_with_vmobject(*m_mmio_window, m_mmio_window->size(), "PCI MMIO", Region::Access::Read | Region::Access::Write); + m_mmio_window_region = MM.allocate_kernel_region(PAGE_ROUND_UP(PCI_MMIO_CONFIG_SPACE_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 dbgprintf("PCI: Checking MCFG Table length to choose the correct mapping size\n"); #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; u8 revision = sdt->revision; kprintf("PCI: MCFG, length - %u, revision %d\n", length, revision); 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); - mmap_region(*mcfg_region, PhysicalAddress((u32)&raw_mcfg & 0xfffff000)); + 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); - 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 dbgprintf("PCI: Checking MCFG @ V 0x%x, P 0x%x\n", &mcfg, &raw_mcfg); #endif @@ -116,7 +114,8 @@ void PCI::MMIOAccess::map_device(Address address) #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()); #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; } @@ -205,33 +204,6 @@ void PCI::MMIOAccess::enumerate_all(Function& 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) : m_base_addr(segment_base_addr) , m_start_bus(start_bus) diff --git a/Kernel/PCI/MMIOAccess.h b/Kernel/PCI/MMIOAccess.h index 052abd9f78..7854b03f3b 100644 --- a/Kernel/PCI/MMIOAccess.h +++ b/Kernel/PCI/MMIOAccess.h @@ -41,7 +41,7 @@ public: virtual void enumerate_all(Function&) override final; virtual String get_access_type() override final { return "MMIO-Access"; }; - + virtual u32 get_segments_count(); protected: explicit MMIOAccess(ACPI_RAW::MCFG&); @@ -54,16 +54,11 @@ private: virtual void write32_field(Address address, u32, u32) override final; 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_end_bus(u32); ACPI_RAW::MCFG& m_mcfg; HashMap& m_segments; - RefPtr m_mmio_window; OwnPtr m_mmio_window_region; PCI::ChangeableAddress m_mapped_address; };