diff options
author | Liav A <liavalb@gmail.com> | 2020-03-06 21:40:36 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-08 14:13:30 +0100 |
commit | 9dbc2736753d1513bf5439634da116fb6440e168 (patch) | |
tree | d3bae6cfb46512e2c703c381a15096985eaf210a /Kernel | |
parent | d6e122fd3a2719bdd532523435a73c7a04fa9fc3 (diff) | |
download | serenity-9dbc2736753d1513bf5439634da116fb6440e168.zip |
Kernel: Ensure E1000NetworkAdapter uses virtual memory correctly
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Net/E1000NetworkAdapter.cpp | 50 | ||||
-rw-r--r-- | Kernel/Net/E1000NetworkAdapter.h | 7 |
2 files changed, 25 insertions, 32 deletions
diff --git a/Kernel/Net/E1000NetworkAdapter.cpp b/Kernel/Net/E1000NetworkAdapter.cpp index c89186630b..6f021c6f5f 100644 --- a/Kernel/Net/E1000NetworkAdapter.cpp +++ b/Kernel/Net/E1000NetworkAdapter.cpp @@ -136,6 +136,8 @@ void E1000NetworkAdapter::detect(const PCI::Address& address) E1000NetworkAdapter::E1000NetworkAdapter(PCI::Address address, u8 irq) : PCI::Device(address, irq) , m_io_base(PCI::get_BAR1(pci_address()) & ~1) + , m_rx_descriptors_region(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(sizeof(e1000_rx_desc) * number_of_rx_descriptors + 16), "E1000 RX", Region::Access::Read | Region::Access::Write)) + , m_tx_descriptors_region(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(sizeof(e1000_tx_desc) * number_of_tx_descriptors + 16), "E1000 TX", Region::Access::Read | Region::Access::Write)) { set_interface_name("e1k"); @@ -250,21 +252,15 @@ bool E1000NetworkAdapter::link_up() void E1000NetworkAdapter::initialize_rx_descriptors() { - auto ptr = (FlatPtr)kmalloc_eternal(sizeof(e1000_rx_desc) * number_of_rx_descriptors + 16); - // Make sure it's 16-byte aligned. - if (ptr % 16) - ptr = (ptr + 16) - (ptr % 16); - m_rx_descriptors = (e1000_rx_desc*)ptr; + auto* rx_descriptors = (e1000_tx_desc*)m_rx_descriptors_region->vaddr().as_ptr(); for (int i = 0; i < number_of_rx_descriptors; ++i) { - auto& descriptor = m_rx_descriptors[i]; - auto addr = (FlatPtr)kmalloc_eternal(8192 + 16); - if (addr % 16) - addr = (addr + 16) - (addr % 16); - descriptor.addr = addr - 0xc0000000; + auto& descriptor = rx_descriptors[i]; + m_rx_buffers_regions.append(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(8192), "E1000 RX buffer", Region::Access::Read | Region::Access::Write)); + descriptor.addr = m_rx_buffers_regions[i]->vmobject().physical_pages()[0]->paddr().get(); descriptor.status = 0; } - out32(REG_RXDESCLO, (u32)ptr - 0xc0000000); + out32(REG_RXDESCLO, m_rx_descriptors_region->vmobject().physical_pages()[0]->paddr().get()); out32(REG_RXDESCHI, 0); out32(REG_RXDESCLEN, number_of_rx_descriptors * sizeof(e1000_rx_desc)); out32(REG_RXDESCHEAD, 0); @@ -275,21 +271,15 @@ void E1000NetworkAdapter::initialize_rx_descriptors() void E1000NetworkAdapter::initialize_tx_descriptors() { - auto ptr = (FlatPtr)kmalloc_eternal(sizeof(e1000_tx_desc) * number_of_tx_descriptors + 16); - // Make sure it's 16-byte aligned. - if (ptr % 16) - ptr = (ptr + 16) - (ptr % 16); - m_tx_descriptors = (e1000_tx_desc*)ptr; + auto* tx_descriptors = (e1000_tx_desc*)m_tx_descriptors_region->vaddr().as_ptr(); for (int i = 0; i < number_of_tx_descriptors; ++i) { - auto& descriptor = m_tx_descriptors[i]; - auto addr = (FlatPtr)kmalloc_eternal(8192 + 16); - if (addr % 16) - addr = (addr + 16) - (addr % 16); - descriptor.addr = addr - 0xc0000000; + auto& descriptor = tx_descriptors[i]; + m_tx_buffers_regions.append(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(8192), "E1000 TX buffer", Region::Access::Read | Region::Access::Write)); + descriptor.addr = m_tx_buffers_regions[i]->vmobject().physical_pages()[0]->paddr().get(); descriptor.cmd = 0; } - out32(REG_TXDESCLO, (u32)ptr - 0xc0000000); + out32(REG_TXDESCLO, m_tx_descriptors_region->vmobject().physical_pages()[0]->paddr().get()); out32(REG_TXDESCHI, 0); out32(REG_TXDESCLEN, number_of_tx_descriptors * sizeof(e1000_tx_desc)); out32(REG_TXDESCHEAD, 0); @@ -375,9 +365,10 @@ void E1000NetworkAdapter::send_raw(const u8* data, size_t length) #ifdef E1000_DEBUG klog() << "E1000: Sending packet (" << length << " bytes)"; #endif - auto& descriptor = m_tx_descriptors[tx_current]; + auto* tx_descriptors = (e1000_tx_desc*)m_tx_descriptors_region->vaddr().as_ptr(); + auto& descriptor = tx_descriptors[tx_current]; ASSERT(length <= 8192); - auto* vptr = (void*)(descriptor.addr + 0xc0000000); + auto* vptr = (void*)m_tx_buffers_regions[tx_current]->vaddr().as_ptr(); memcpy(vptr, data, length); descriptor.length = length; descriptor.status = 0; @@ -397,27 +388,28 @@ void E1000NetworkAdapter::send_raw(const u8* data, size_t length) Thread::current->wait_on(m_wait_queue); } #ifdef E1000_DEBUG - klog() << "E1000: Sent packet, status is now " << String::format("%b",descriptor.status) << "!"; + klog() << "E1000: Sent packet, status is now " << String::format("%b", descriptor.status) << "!"; #endif } void E1000NetworkAdapter::receive() { + auto* rx_descriptors = (e1000_tx_desc*)m_rx_descriptors_region->vaddr().as_ptr(); u32 rx_current; for (;;) { rx_current = in32(REG_RXDESCTAIL); if (rx_current == in32(REG_RXDESCHEAD)) return; rx_current = (rx_current + 1) % number_of_rx_descriptors; - if (!(m_rx_descriptors[rx_current].status & 1)) + if (!(rx_descriptors[rx_current].status & 1)) break; - auto* buffer = (u8*)(m_rx_descriptors[rx_current].addr + 0xc0000000); - u16 length = m_rx_descriptors[rx_current].length; + auto* buffer = m_rx_buffers_regions[rx_current]->vaddr().as_ptr(); + u16 length = rx_descriptors[rx_current].length; #ifdef E1000_DEBUG klog() << "E1000: Received 1 packet @ " << buffer << " (" << length << ") bytes!"; #endif did_receive(buffer, length); - m_rx_descriptors[rx_current].status = 0; + rx_descriptors[rx_current].status = 0; out32(REG_RXDESCTAIL, rx_current); } } diff --git a/Kernel/Net/E1000NetworkAdapter.h b/Kernel/Net/E1000NetworkAdapter.h index 3951429c13..a36953fec6 100644 --- a/Kernel/Net/E1000NetworkAdapter.h +++ b/Kernel/Net/E1000NetworkAdapter.h @@ -94,6 +94,10 @@ private: IOAddress m_io_base; VirtualAddress m_mmio_base; + OwnPtr<Region> m_rx_descriptors_region; + OwnPtr<Region> m_tx_descriptors_region; + Vector<OwnPtr<Region>> m_rx_buffers_regions; + Vector<OwnPtr<Region>> m_tx_buffers_regions; OwnPtr<Region> m_mmio_region; u8 m_interrupt_line { 0 }; bool m_has_eeprom { false }; @@ -102,9 +106,6 @@ private: static const int number_of_rx_descriptors = 32; static const int number_of_tx_descriptors = 8; - e1000_rx_desc* m_rx_descriptors; - e1000_tx_desc* m_tx_descriptors; - WaitQueue m_wait_queue; }; } |