Skip to content
Snippets Groups Projects
Commit 9907cc2e authored by Dor Laor's avatar Dor Laor
Browse files

Add a wake-able thread in virtio that serves as an interrupt like handler.

At the moment it's hard coded as queue '0' but further on it should be a function
of the device requirements. It is also possible to move it towards the device function
since this thread doesn't do anything other than wake up the driver worker.
parent 208b6446
No related branches found
No related tags found
No related merge requests found
......@@ -137,6 +137,9 @@ namespace virtio {
void reset_host_side();
void free_queues(void);
void register_callback(std::function<void ()> func) {_queues[0]->register_callback(func);};
void enable_callback() {_queues[0]->enable_callback();};
protected:
vring* _queues[max_virtqueues_nr];
u32 _num_queues;
......
......@@ -8,7 +8,11 @@
#include "drivers/virtio-vring.hh"
#include "debug.hh"
#include "sched.hh"
#include "interrupt.hh"
using namespace memory;
using sched::thread;
namespace virtio {
......@@ -39,6 +43,14 @@ namespace virtio {
_avail_added_since_kick = 0;
_avail_count = num;
msix_isr_list* isrs = new msix_isr_list;
void* stk1 = malloc(10000);
thread* isr = new thread([this] { this->interrupt(); } , {stk1, 10000});
isrs->insert(std::make_pair(0, isr));
interrupt_manager::instance()->easy_register(_dev, *isrs);
enable_callback();
_callback = nullptr;
}
vring::~vring()
......@@ -154,13 +166,25 @@ namespace virtio {
void
vring::disable_callback() {
_callback_enabled = false;
}
bool
vring::enable_callback() {
_callback_enabled = true;
return true;
}
void vring::interrupt() {
debug("vring::interrupt for the first time");
while (1) {
thread::wait_until([&] {return _callback_enabled; });
_callback_enabled = false;
debug("vring::interrupt - woke up");
if (_callback) _callback();
}
}
};
#ifndef VIRTIO_VRING_H
#define VIRTIO_VRING_H
#include <functional>
class sglist;
namespace virtio {
......@@ -113,6 +115,8 @@ class virtio_device;
bool kick();
void disable_callback();
bool enable_callback();
void interrupt();
void register_callback(std::function<void ()> func) {_callback = func;};
// The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX
......@@ -148,6 +152,9 @@ class virtio_device;
vring_used *_used;
// cookies to store access to the upper layer pointers
void** _cookie;
//callback function for upper layer virtio queues
std::function<void ()> _callback;
bool _callback_enabled;
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment