Newer
Older
#ifndef INTERRUPT_HH_
#define INTERRUPT_HH_
#include <functional>
#include <map>
#include <list>
#include "sched.hh"
#include "drivers/pci.hh"
#include "drivers/pci-function.hh"
#include "types.hh"
using namespace pci;
// max vectors per request
const int max_vectors = 256;
class msix_vector {
msix_vector(pci_function* dev);
virtual ~msix_vector();
pci_function* get_pci_function(void);
unsigned get_vector(void);
void msix_unmask_entries(void);
void msix_mask_entries(void);
void add_entryid(unsigned entry_id);
void interrupt(void);
void set_handler(std::function<void ()> handler);
// Handler to invoke...
std::function<void ()> _handler;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// The device that owns this vector
pci_function * _dev;
// Entry ids used by this vector
std::list<unsigned> _entryids;
unsigned _vector;
unsigned _num_entries;
};
// Used to communicate assigned vectors back to driver
class assigned_vectors {
public:
assigned_vectors() : _num(0) {
for (int i=0; i<max_vectors; i++) {
_vectors[i] = 0;
}
}
unsigned _vectors[max_vectors];
unsigned _num;
};
// entry -> thread to wake
typedef std::map<unsigned, sched::thread *> msix_isr_list;
class interrupt_manager {
public:
interrupt_manager();
virtual ~interrupt_manager();
static interrupt_manager * instance() {
if (_instance == nullptr) {
_instance = new interrupt_manager();
}
return (_instance);
}
////////////////////
// Easy Interface //
////////////////////
// 1. Enabled MSI-x For device
// 2. Allocate vectors and assign ISRs
// 3. Setup entries
// 4. Unmask interrupts
bool easy_register(pci_function* dev, msix_isr_list& isrs);
void easy_unregister(pci_function* dev);
/////////////////////
// Multi Interface //
/////////////////////
assigned_vectors request_vectors(pci_function* dev, unsigned num_vectors);
void free_vectors(const assigned_vectors& vectors);
bool assign_isr(unsigned vector, std::function<void ()> handler);
// Multiple entry can be assigned the same vector
bool setup_entry(unsigned entry_id, unsigned vector);
// unmasks all interrupts
bool unmask_interrupts(const assigned_vectors& vectors);
private:
static interrupt_manager* _instance;
msix_vector* _vectors[max_vectors];
// Used by the easy interface
std::map<pci_function *, assigned_vectors> _easy_dev2vectors;
};
#endif /* INTERRUPT_HH_ */