Prechádzať zdrojové kódy

Kernel: Ensure RTL8139NetworkAdapter uses virtual memory correctly

Liav A 5 rokov pred
rodič
commit
4479e874da

+ 15 - 16
Kernel/Net/RTL8139NetworkAdapter.cpp

@@ -140,7 +140,10 @@ void RTL8139NetworkAdapter::detect(const PCI::Address& address)
 RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq)
     : PCI::Device(address, irq)
     , m_io_base(PCI::get_BAR0(pci_address()) & ~1)
+    , m_rx_buffer(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(RX_BUFFER_SIZE + PACKET_SIZE_MAX), "RTL8139 RX", Region::Access::Read | Region::Access::Write))
+    , m_packet_buffer(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(PACKET_SIZE_MAX), "RTL8139 Packet buffer", Region::Access::Read | Region::Access::Write))
 {
+    m_tx_buffers.ensure_capacity(RTL8139_TX_BUFFER_COUNT);
     set_interface_name("rtl8139");
 
     klog() << "RTL8139: Found at PCI address " << String::format("%w", pci_address().seg()) << ":" << String::format("%b", pci_address().bus()) << ":" << String::format("%b", pci_address().slot()) << "." << String::format("%b", pci_address().function());
@@ -154,17 +157,13 @@ RTL8139NetworkAdapter::RTL8139NetworkAdapter(PCI::Address address, u8 irq)
     // we add space to account for overhang from the last packet - the rtl8139
     // can optionally guarantee that packets will be contiguous by
     // purposefully overrunning the rx buffer
-    m_rx_buffer_addr = (FlatPtr)virtual_to_low_physical(kmalloc_aligned(RX_BUFFER_SIZE + PACKET_SIZE_MAX, 16));
-    klog() << "RTL8139: RX buffer: " << PhysicalAddress(m_rx_buffer_addr);
+    klog() << "RTL8139: RX buffer: " << m_rx_buffer->vmobject().physical_pages()[0]->paddr();
 
-    auto tx_buffer_addr = (FlatPtr)virtual_to_low_physical(kmalloc_aligned(TX_BUFFER_SIZE * 4, 16));
     for (int i = 0; i < RTL8139_TX_BUFFER_COUNT; i++) {
-        m_tx_buffer_addr[i] = tx_buffer_addr + TX_BUFFER_SIZE * i;
-        klog() << "RTL8139: TX buffer " << i << ": "  << PhysicalAddress(m_tx_buffer_addr[i]);
+        m_tx_buffers.append(MM.allocate_contiguous_kernel_region(PAGE_ROUND_UP(TX_BUFFER_SIZE), "RTL8139 TX", Region::Access::Write | Region::Access::Read));
+        klog() << "RTL8139: TX buffer " << i << ": " << m_tx_buffers[i]->vmobject().physical_pages()[0]->paddr();
     }
 
-    m_packet_buffer = (FlatPtr)kmalloc(PACKET_SIZE_MAX);
-
     reset();
 
     read_mac_address();
@@ -250,7 +249,7 @@ void RTL8139NetworkAdapter::reset()
     // device might be in sleep mode, this will take it out
     out8(REG_CONFIG1, 0);
     // set up rx buffer
-    out32(REG_RXBUF, m_rx_buffer_addr);
+    out32(REG_RXBUF, m_rx_buffer->vmobject().physical_pages()[0]->paddr().get());
     // reset missed packet counter
     out8(REG_MPC, 0);
     // "basic mode control register" options - 100mbit, full duplex, auto
@@ -268,7 +267,7 @@ void RTL8139NetworkAdapter::reset()
     out32(REG_TXCFG, TXCFG_TXRR_ZERO | TXCFG_MAX_DMA_1K | TXCFG_IFG11);
     // tell the chip where we want it to DMA from for outgoing packets.
     for (int i = 0; i < 4; i++)
-        out32(REG_TXADDR0 + (i * 4), m_tx_buffer_addr[i]);
+        out32(REG_TXADDR0 + (i * 4), m_tx_buffers[i]->vmobject().physical_pages()[0]->paddr().get());
     // re-lock config registers
     out8(REG_CFG9346, CFG9346_NONE);
     // enable rx/tx again in case they got turned off (apparently some cards
@@ -320,8 +319,8 @@ void RTL8139NetworkAdapter::send_raw(const u8* data, size_t length)
         m_tx_next_buffer = (hw_buffer + 1) % 4;
     }
 
-    memcpy((void*)low_physical_to_virtual(m_tx_buffer_addr[hw_buffer]), data, length);
-    memset((void*)(low_physical_to_virtual(m_tx_buffer_addr[hw_buffer]) + length), 0, TX_BUFFER_SIZE - length);
+    memcpy(m_tx_buffers[hw_buffer]->vaddr().as_ptr(), data, length);
+    memset(m_tx_buffers[hw_buffer]->vaddr().as_ptr() + length, 0, TX_BUFFER_SIZE - length);
 
     // the rtl8139 will not actually emit packets onto the network if they're
     // smaller than 64 bytes. the rtl8139 adds a checksum to the end of each
@@ -339,17 +338,17 @@ void RTL8139NetworkAdapter::send_raw(const u8* data, size_t length)
 
 void RTL8139NetworkAdapter::receive()
 {
-    auto* start_of_packet = (const u8*)(low_physical_to_virtual(m_rx_buffer_addr) + m_rx_buffer_offset);
+    auto* start_of_packet = m_rx_buffer->vaddr().as_ptr() + m_rx_buffer_offset;
 
     u16 status = *(const u16*)(start_of_packet + 0);
     u16 length = *(const u16*)(start_of_packet + 2);
 
 #ifdef RTL8139_DEBUG
-    klog() << "RTL8139NetworkAdapter::receive status=0x" << String::format("%x",status) << " length=" << length << " offset=" << m_rx_buffer_offset;
+    klog() << "RTL8139NetworkAdapter::receive status=0x" << String::format("%x", status) << " length=" << length << " offset=" << m_rx_buffer_offset;
 #endif
 
     if (!(status & RX_OK) || (status & (RX_INVALID_SYMBOL_ERROR | RX_CRC_ERROR | RX_FRAME_ALIGNMENT_ERROR)) || (length >= PACKET_SIZE_MAX) || (length < PACKET_SIZE_MIN)) {
-        klog() << "RTL8139NetworkAdapter::receive got bad packet status=0x" << String::format("%x",status) << " length=" << length;
+        klog() << "RTL8139NetworkAdapter::receive got bad packet status=0x" << String::format("%x", status) << " length=" << length;
         reset();
         return;
     }
@@ -357,13 +356,13 @@ void RTL8139NetworkAdapter::receive()
     // we never have to worry about the packet wrapping around the buffer,
     // since we set RXCFG_WRAP_INHIBIT, which allows the rtl8139 to write data
     // past the end of the alloted space.
-    memcpy((u8*)m_packet_buffer, (const u8*)(start_of_packet + 4), length - 4);
+    memcpy(m_packet_buffer->vaddr().as_ptr(), (const u8*)(start_of_packet + 4), length - 4);
     // let the card know that we've read this data
     m_rx_buffer_offset = ((m_rx_buffer_offset + length + 4 + 3) & ~3) % RX_BUFFER_SIZE;
     out16(REG_CAPR, m_rx_buffer_offset - 0x10);
     m_rx_buffer_offset %= RX_BUFFER_SIZE;
 
-    did_receive((const u8*)m_packet_buffer, length - 4);
+    did_receive(m_packet_buffer->vaddr().as_ptr(), length - 4);
 }
 
 void RTL8139NetworkAdapter::out8(u16 address, u8 data)

+ 3 - 3
Kernel/Net/RTL8139NetworkAdapter.h

@@ -67,11 +67,11 @@ private:
 
     IOAddress m_io_base;
     u8 m_interrupt_line { 0 };
-    u32 m_rx_buffer_addr { 0 };
+    OwnPtr<Region> m_rx_buffer;
     u16 m_rx_buffer_offset { 0 };
-    u32 m_tx_buffer_addr[RTL8139_TX_BUFFER_COUNT];
+    Vector<OwnPtr<Region>> m_tx_buffers;
     u8 m_tx_next_buffer { 0 };
-    u32 m_packet_buffer { 0 };
+    OwnPtr<Region> m_packet_buffer;
     bool m_link_up { false };
 };
 }