Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions src/drivers/e1000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include <malloc.h>
// loosely based on OSdev article http://wiki.osdev.org/Intel_Ethernet_i217

static int deferred_event = 0;
static std::vector<e1000*> deferred_devices;

e1000::e1000(hw::PCI_Device& d) :
Link(Link_protocol{{this, &e1000::transmit}, mac()}, bufstore_),
m_pcidev(d), bufstore_{1024, 2048}
Expand All @@ -40,6 +43,11 @@ e1000::e1000(hw::PCI_Device& d) :
__arch_enable_legacy_irq(this->m_irq);
INFO2("Subscribed on IRQ %u", this->m_irq);

if (deferred_event == 0)
{
deferred_event = Events::get().subscribe(&e1000::do_deferred_xmit);
}

// shared-memory & I/O address
this->shm_base = d.get_bar(0);
this->io_base = d.iobase();
Expand Down Expand Up @@ -208,6 +216,8 @@ void e1000::event_handler()

void e1000::recv_handler()
{
uint16_t old_idx = 0xffff;

while (rx.desc[rx.current].status & 1)
{
auto& tk = rx.desc[rx.current];
Expand All @@ -221,11 +231,11 @@ void e1000::recv_handler()
tk.addr = (uint64_t) this->new_rx_packet();
tk.status = 0;
// go to next index
uint16_t old_idx = rx.current;
old_idx = rx.current;
rx.current = (rx.current + 1) % NUM_RX_DESC;
write_cmd(REG_RXDESCTAIL, old_idx);
}

if (old_idx != 0xffff)
write_cmd(REG_RXDESCTAIL, old_idx);
}

void e1000::transmit(net::Packet_ptr pckt)
Expand Down Expand Up @@ -265,12 +275,28 @@ void e1000::transmit_data(uint8_t* data, uint16_t length)
tk.status = 0;

tx.current = (tx.current + 1) % NUM_TX_DESC;
if (tx.deferred == false)
{
tx.deferred = true;
deferred_devices.push_back(this);
Events::get().trigger_event(deferred_event);
}
}
void e1000::xmit_kick()
{
write_cmd(REG_TXDESCTAIL, tx.current);
tx.deferred = false;
}
void e1000::do_deferred_xmit()
{
for (auto& dev : deferred_devices)
dev->xmit_kick();
deferred_devices.clear();
}

void e1000::flush()
{

this->transmit(std::move(sendq));
}
void e1000::poll()
{
Expand All @@ -283,7 +309,7 @@ void e1000::deactivate()
}
void e1000::move_to_this_cpu()
{

// TODO: implement me
}

#include <kernel/pci_manager.hpp>
Expand All @@ -294,5 +320,6 @@ static void register_func()
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x100E, &e1000::new_instance);
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x100F, &e1000::new_instance);
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x153A, &e1000::new_instance);
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x1539, &e1000::new_instance);
PCI_manager::register_nic(PCI::VENDOR_INTEL, 0x10EA, &e1000::new_instance);
}
3 changes: 3 additions & 0 deletions src/drivers/e1000.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class e1000 : public net::Link_layer<net::Ethernet>
void recv_handler();
bool can_transmit();
void transmit_data(uint8_t*, uint16_t);
void xmit_kick();
static void do_deferred_xmit();

hw::PCI_Device& m_pcidev;
std::vector<uint8_t> irqs;
Expand Down Expand Up @@ -127,6 +129,7 @@ class e1000 : public net::Link_layer<net::Ethernet>
struct tx_t {
tx_desc desc[NUM_TX_DESC];
uint16_t current = 0;
bool deferred = false;
} tx;

// sendq as packet chain
Expand Down
5 changes: 5 additions & 0 deletions vmrunner/vm.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@
"vga" : {
"description" : "Enable VGA screen",
"enum" : ["std", "cirrus", "vmware", "qxl", "xenfb", "tcx", "cg3", "virtio", "none"]
},

"vfio" : {
"description" : "VFIO PCI-passthrough on device",
"type" : "string"
}
}

Expand Down
6 changes: 5 additions & 1 deletion vmrunner/vmrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,17 @@ def boot(self, multiboot, kernel_args = "", image_name = None):
if "vga" in self._config:
vga_arg = ["-vga", str(self._config["vga"])]

pci_arg = []
if "vfio" in self._config:
pci_arg = ["-device", "vfio-pci,host=" + self._config["vfio"]]

# TODO: sudo is only required for tap networking and kvm. Check for those.
command = ["sudo", "--preserve-env", "qemu-system-x86_64"]
if self._kvm_present: command.extend(["--enable-kvm"])

command += kernel_args

command += disk_args + net_args + mem_arg + vga_arg + mod_args
command += disk_args + net_args + mem_arg + vga_arg + pci_arg + mod_args

#command_str = " ".join(command)
#command_str.encode('ascii','ignore')
Expand Down