summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2020-03-06 21:40:36 +0200
committerAndreas Kling <kling@serenityos.org>2020-03-08 14:13:30 +0100
commit9dbc2736753d1513bf5439634da116fb6440e168 (patch)
treed3bae6cfb46512e2c703c381a15096985eaf210a /Kernel
parentd6e122fd3a2719bdd532523435a73c7a04fa9fc3 (diff)
downloadserenity-9dbc2736753d1513bf5439634da116fb6440e168.zip
Kernel: Ensure E1000NetworkAdapter uses virtual memory correctly
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Net/E1000NetworkAdapter.cpp50
-rw-r--r--Kernel/Net/E1000NetworkAdapter.h7
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;
};
}