mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 19:17:41 +00:00
Kernel: More work on Ethernet support.
This commit is contained in:
parent
97664fad60
commit
1678ac69ef
8 changed files with 62 additions and 9 deletions
|
@ -157,9 +157,9 @@ void E1000NetworkAdapter::handle_irq()
|
||||||
kprintf("E1000: threshold\n");
|
kprintf("E1000: threshold\n");
|
||||||
}
|
}
|
||||||
if (status & 0x80) {
|
if (status & 0x80) {
|
||||||
//receive();
|
kprintf("E1000: receive...\n");
|
||||||
|
receive();
|
||||||
}
|
}
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void E1000NetworkAdapter::detect_eeprom()
|
void E1000NetworkAdapter::detect_eeprom()
|
||||||
|
@ -282,7 +282,6 @@ void E1000NetworkAdapter::out32(word address, dword data)
|
||||||
{
|
{
|
||||||
if (m_use_mmio) {
|
if (m_use_mmio) {
|
||||||
auto* ptr = (volatile dword*)(m_mmio_base.get() + address);
|
auto* ptr = (volatile dword*)(m_mmio_base.get() + address);
|
||||||
kprintf("ptr <-- %p\n", ptr);
|
|
||||||
*ptr = data;
|
*ptr = data;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -310,7 +309,7 @@ dword E1000NetworkAdapter::in32(word address)
|
||||||
return IO::in32(m_io_base + address);
|
return IO::in32(m_io_base + address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void E1000NetworkAdapter::send(const byte* data, int length)
|
void E1000NetworkAdapter::send_raw(const byte* data, int length)
|
||||||
{
|
{
|
||||||
kprintf("E1000: Sending packet (%d bytes)\n", length);
|
kprintf("E1000: Sending packet (%d bytes)\n", length);
|
||||||
auto& descriptor = m_tx_descriptors[m_tx_current];
|
auto& descriptor = m_tx_descriptors[m_tx_current];
|
||||||
|
@ -323,3 +322,18 @@ void E1000NetworkAdapter::send(const byte* data, int length)
|
||||||
;
|
;
|
||||||
kprintf("E1000: Sent packet!\n");
|
kprintf("E1000: Sent packet!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void E1000NetworkAdapter::receive()
|
||||||
|
{
|
||||||
|
while (m_rx_descriptors[m_rx_current].status & 1) {
|
||||||
|
auto* buffer = (byte*)m_rx_descriptors[m_rx_current].addr;
|
||||||
|
word length = m_rx_descriptors[m_rx_current].length;
|
||||||
|
|
||||||
|
kprintf("E1000: Received 1 packet @ %p (%u) bytes!\n", buffer, length);
|
||||||
|
|
||||||
|
m_rx_descriptors[m_rx_current].status = 0;
|
||||||
|
auto old_current = m_rx_current;
|
||||||
|
m_rx_current = (m_rx_current + 1) % number_of_rx_descriptors;
|
||||||
|
out32(REG_RXDESCTAIL, old_current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
E1000NetworkAdapter(PCI::Address, byte irq);
|
E1000NetworkAdapter(PCI::Address, byte irq);
|
||||||
virtual ~E1000NetworkAdapter() override;
|
virtual ~E1000NetworkAdapter() override;
|
||||||
|
|
||||||
virtual void send(const byte*, int) override;
|
virtual void send_raw(const byte*, int) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void handle_irq() override;
|
virtual void handle_irq() override;
|
||||||
|
@ -57,6 +57,8 @@ private:
|
||||||
word in16(word address);
|
word in16(word address);
|
||||||
dword in32(word address);
|
dword in32(word address);
|
||||||
|
|
||||||
|
void receive();
|
||||||
|
|
||||||
PCI::Address m_pci_address;
|
PCI::Address m_pci_address;
|
||||||
word m_io_base { 0 };
|
word m_io_base { 0 };
|
||||||
PhysicalAddress m_mmio_base;
|
PhysicalAddress m_mmio_base;
|
||||||
|
|
|
@ -16,13 +16,14 @@ public:
|
||||||
word ether_type() const { return (m_ether_type & 0xff) << 16 | ((m_ether_type >> 16) & 0xff); }
|
word ether_type() const { return (m_ether_type & 0xff) << 16 | ((m_ether_type >> 16) & 0xff); }
|
||||||
void set_ether_type(word ether_type) { m_ether_type = (ether_type & 0xff) << 16 | ((ether_type >> 16) & 0xff); }
|
void set_ether_type(word ether_type) { m_ether_type = (ether_type & 0xff) << 16 | ((ether_type >> 16) & 0xff); }
|
||||||
|
|
||||||
const void* raw() const { return this; }
|
const void* payload() const { return &m_payload[0]; }
|
||||||
void* raw() { return this; }
|
void* payload() { return &m_payload[0]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MACAddress m_destination;
|
MACAddress m_destination;
|
||||||
MACAddress m_source;
|
MACAddress m_source;
|
||||||
word m_ether_type { 0 };
|
word m_ether_type { 0 };
|
||||||
|
dword m_payload[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(EthernetFrameHeader) == 14);
|
static_assert(sizeof(EthernetFrameHeader) == 14);
|
||||||
|
|
|
@ -99,6 +99,7 @@ void MemoryManager::initialize_paging()
|
||||||
dbgprintf("MM: Quickmap will use P%x\n", m_quickmap_addr.get());
|
dbgprintf("MM: Quickmap will use P%x\n", m_quickmap_addr.get());
|
||||||
dbgprintf("MM: Installing page directory\n");
|
dbgprintf("MM: Installing page directory\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
asm volatile("movl %%eax, %%cr3"::"a"(kernel_page_directory().cr3()));
|
asm volatile("movl %%eax, %%cr3"::"a"(kernel_page_directory().cr3()));
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"movl %%cr0, %%eax\n"
|
"movl %%cr0, %%eax\n"
|
||||||
|
@ -442,6 +443,12 @@ void MemoryManager::enter_process_paging_scope(Process& process)
|
||||||
asm volatile("movl %%eax, %%cr3"::"a"(process.page_directory().cr3()):"memory");
|
asm volatile("movl %%eax, %%cr3"::"a"(process.page_directory().cr3()):"memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MemoryManager::enter_kernel_paging_scope()
|
||||||
|
{
|
||||||
|
InterruptDisabler disabler;
|
||||||
|
asm volatile("movl %%eax, %%cr3"::"a"(kernel_page_directory().cr3()):"memory");
|
||||||
|
}
|
||||||
|
|
||||||
void MemoryManager::flush_entire_tlb()
|
void MemoryManager::flush_entire_tlb()
|
||||||
{
|
{
|
||||||
asm volatile(
|
asm volatile(
|
||||||
|
|
|
@ -242,6 +242,7 @@ public:
|
||||||
void populate_page_directory(PageDirectory&);
|
void populate_page_directory(PageDirectory&);
|
||||||
|
|
||||||
void enter_process_paging_scope(Process&);
|
void enter_process_paging_scope(Process&);
|
||||||
|
void enter_kernel_paging_scope();
|
||||||
|
|
||||||
bool validate_user_read(const Process&, LinearAddress) const;
|
bool validate_user_read(const Process&, LinearAddress) const;
|
||||||
bool validate_user_write(const Process&, LinearAddress) const;
|
bool validate_user_write(const Process&, LinearAddress) const;
|
||||||
|
@ -413,3 +414,8 @@ struct ProcessPagingScope {
|
||||||
ProcessPagingScope(Process& process) { MM.enter_process_paging_scope(process); }
|
ProcessPagingScope(Process& process) { MM.enter_process_paging_scope(process); }
|
||||||
~ProcessPagingScope() { MM.enter_process_paging_scope(*current); }
|
~ProcessPagingScope() { MM.enter_process_paging_scope(*current); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct KernelPagingScope {
|
||||||
|
KernelPagingScope() { MM.enter_kernel_paging_scope(); }
|
||||||
|
~KernelPagingScope() { MM.enter_process_paging_scope(*current); }
|
||||||
|
};
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
#include <Kernel/NetworkAdapter.h>
|
#include <Kernel/NetworkAdapter.h>
|
||||||
#include <Kernel/StdLib.h>
|
#include <Kernel/StdLib.h>
|
||||||
|
#include <Kernel/EthernetFrameHeader.h>
|
||||||
|
#include <Kernel/kmalloc.h>
|
||||||
|
|
||||||
NetworkAdapter::NetworkAdapter()
|
NetworkAdapter::NetworkAdapter()
|
||||||
{
|
{
|
||||||
memset(&m_mac_address, 0, sizeof(m_mac_address));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkAdapter::~NetworkAdapter()
|
NetworkAdapter::~NetworkAdapter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkAdapter::send(const MACAddress& destination, const ARPPacket& packet)
|
||||||
|
{
|
||||||
|
int size_in_bytes = sizeof(EthernetFrameHeader) + sizeof(ARPPacket) + 4;
|
||||||
|
auto* eth = (EthernetFrameHeader*)kmalloc(size_in_bytes);
|
||||||
|
eth->set_source(mac_address());
|
||||||
|
eth->set_destination(destination);
|
||||||
|
memcpy(eth->payload(), &packet, sizeof(ARPPacket));
|
||||||
|
send_raw((byte*)eth, size_in_bytes);
|
||||||
|
kfree(eth);
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/MACAddress.h>
|
#include <Kernel/MACAddress.h>
|
||||||
|
#include <Kernel/ARPPacket.h>
|
||||||
|
|
||||||
class NetworkAdapter {
|
class NetworkAdapter {
|
||||||
public:
|
public:
|
||||||
|
@ -10,11 +11,12 @@ public:
|
||||||
virtual const char* class_name() const = 0;
|
virtual const char* class_name() const = 0;
|
||||||
MACAddress mac_address() { return m_mac_address; }
|
MACAddress mac_address() { return m_mac_address; }
|
||||||
|
|
||||||
virtual void send(const byte*, int) = 0;
|
void send(const MACAddress&, const ARPPacket&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NetworkAdapter();
|
NetworkAdapter();
|
||||||
void set_mac_address(const MACAddress& mac_address) { m_mac_address = mac_address; }
|
void set_mac_address(const MACAddress& mac_address) { m_mac_address = mac_address; }
|
||||||
|
virtual void send_raw(const byte*, int) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MACAddress m_mac_address;
|
MACAddress m_mac_address;
|
||||||
|
|
|
@ -1922,6 +1922,16 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
||||||
|
|
||||||
int Process::sys$ioctl(int fd, unsigned request, unsigned arg)
|
int Process::sys$ioctl(int fd, unsigned request, unsigned arg)
|
||||||
{
|
{
|
||||||
|
if (auto* e1000 = E1000NetworkAdapter::the()) {
|
||||||
|
ARPPacket arp;
|
||||||
|
arp.hardware_type = 1; // Ethernet
|
||||||
|
arp.hardware_address_length = 6; // MAC length
|
||||||
|
arp.protocol_type = 0x0800; // IPv4
|
||||||
|
arp.protocol_address_length = 4; // IP length
|
||||||
|
arp.operation = 1; // 1 (request)
|
||||||
|
e1000->send(MACAddress(), arp);
|
||||||
|
}
|
||||||
|
|
||||||
auto* descriptor = file_descriptor(fd);
|
auto* descriptor = file_descriptor(fd);
|
||||||
if (!descriptor)
|
if (!descriptor)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue