From 918097ae949cfc1eb890dda1aa666892f3f62a81 Mon Sep 17 00:00:00 2001 From: Liav A Date: Thu, 9 Jan 2020 23:34:26 +0200 Subject: [PATCH] Kernel: Fixing E1000 MMIO access Now E1000 driver no longer use identity-mapping to do IO operations. Also, print messages were fixed, and debug messages were added for IO methods. --- Kernel/Net/E1000NetworkAdapter.cpp | 34 ++++++++++++++++++++++-------- Kernel/Net/E1000NetworkAdapter.h | 3 ++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Kernel/Net/E1000NetworkAdapter.cpp b/Kernel/Net/E1000NetworkAdapter.cpp index d35cec36ce..dd9b268893 100644 --- a/Kernel/Net/E1000NetworkAdapter.cpp +++ b/Kernel/Net/E1000NetworkAdapter.cpp @@ -2,6 +2,8 @@ #include #include +//#define E1000_DEBUG + #define REG_CTRL 0x0000 #define REG_STATUS 0x0008 #define REG_EEPROM 0x0014 @@ -113,22 +115,18 @@ E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address pci_address, u8 irq) { set_interface_name("e1k"); - kprintf("E1000: Found at PCI address %b:%b:%b\n", pci_address.bus(), pci_address.slot(), pci_address.function()); + kprintf("E1000: Found at PCI address @ %w:%b:%b.%b\n", pci_address.seg(), pci_address.bus(), pci_address.slot(), pci_address.function()); enable_bus_mastering(m_pci_address); - m_mmio_base = PhysicalAddress(PCI::get_BAR0(m_pci_address)); - u32 mmio_base_size = PCI::get_BAR_Space_Size(pci_address, 0); - MM.map_for_kernel(VirtualAddress(m_mmio_base.get()), m_mmio_base); - MM.map_for_kernel(VirtualAddress(m_mmio_base.offset(4096).get()), m_mmio_base.offset(4096)); - MM.map_for_kernel(VirtualAddress(m_mmio_base.offset(8192).get()), m_mmio_base.offset(8192)); - MM.map_for_kernel(VirtualAddress(m_mmio_base.offset(12288).get()), m_mmio_base.offset(12288)); - MM.map_for_kernel(VirtualAddress(m_mmio_base.offset(16384).get()), m_mmio_base.offset(16384)); + size_t mmio_base_size = PCI::get_BAR_Space_Size(pci_address, 0); + m_mmio_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(PCI::get_BAR0(m_pci_address))), PAGE_ROUND_UP(mmio_base_size), "E1000 MMIO", Region::Access::Read | Region::Access::Write, false, false); + m_mmio_base = m_mmio_region->vaddr(); m_use_mmio = true; m_io_base = PCI::get_BAR1(m_pci_address) & ~1; m_interrupt_line = PCI::get_interrupt_line(m_pci_address); kprintf("E1000: IO port base: %w\n", m_io_base); - kprintf("E1000: MMIO base: P%x\n", m_mmio_base); + kprintf("E1000: MMIO base: P%x\n", PCI::get_BAR0(pci_address) & 0xfffffffc); kprintf("E1000: MMIO base size: %u bytes\n", mmio_base_size); kprintf("E1000: Interrupt line: %u\n", m_interrupt_line); detect_eeprom(); @@ -274,6 +272,9 @@ void E1000NetworkAdapter::initialize_tx_descriptors() void E1000NetworkAdapter::out8(u16 address, u8 data) { +#ifdef E1000_DEBUG + dbgprintf("E1000: OUT @ 0x%x\n", address); +#endif if (m_use_mmio) { auto* ptr = (volatile u8*)(m_mmio_base.get() + address); *ptr = data; @@ -284,6 +285,9 @@ void E1000NetworkAdapter::out8(u16 address, u8 data) void E1000NetworkAdapter::out16(u16 address, u16 data) { +#ifdef E1000_DEBUG + dbgprintf("E1000: OUT @ 0x%x\n", address); +#endif if (m_use_mmio) { auto* ptr = (volatile u16*)(m_mmio_base.get() + address); *ptr = data; @@ -294,6 +298,9 @@ void E1000NetworkAdapter::out16(u16 address, u16 data) void E1000NetworkAdapter::out32(u16 address, u32 data) { +#ifdef E1000_DEBUG + dbgprintf("E1000: OUT @ 0x%x\n", address); +#endif if (m_use_mmio) { auto* ptr = (volatile u32*)(m_mmio_base.get() + address); *ptr = data; @@ -304,6 +311,9 @@ void E1000NetworkAdapter::out32(u16 address, u32 data) u8 E1000NetworkAdapter::in8(u16 address) { +#ifdef E1000_DEBUG + dbgprintf("E1000: IN @ 0x%x\n", address); +#endif if (m_use_mmio) return *(volatile u8*)(m_mmio_base.get() + address); return IO::in8(m_io_base + address); @@ -311,6 +321,9 @@ u8 E1000NetworkAdapter::in8(u16 address) u16 E1000NetworkAdapter::in16(u16 address) { +#ifdef E1000_DEBUG + dbgprintf("E1000: IN @ 0x%x\n", address); +#endif if (m_use_mmio) return *(volatile u16*)(m_mmio_base.get() + address); return IO::in16(m_io_base + address); @@ -318,6 +331,9 @@ u16 E1000NetworkAdapter::in16(u16 address) u32 E1000NetworkAdapter::in32(u16 address) { +#ifdef E1000_DEBUG + dbgprintf("E1000: IN @ 0x%x\n", address); +#endif if (m_use_mmio) return *(volatile u32*)(m_mmio_base.get() + address); return IO::in32(m_io_base + address); diff --git a/Kernel/Net/E1000NetworkAdapter.h b/Kernel/Net/E1000NetworkAdapter.h index b1c99e5774..25d4399e66 100644 --- a/Kernel/Net/E1000NetworkAdapter.h +++ b/Kernel/Net/E1000NetworkAdapter.h @@ -62,7 +62,8 @@ private: PCI::Address m_pci_address; u16 m_io_base { 0 }; - PhysicalAddress m_mmio_base; + VirtualAddress m_mmio_base; + OwnPtr m_mmio_region; u8 m_interrupt_line { 0 }; bool m_has_eeprom { false }; bool m_use_mmio { false };