Skip to content
Snippets Groups Projects
interrupt.hh 2.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef INTERRUPT_HH_
    #define INTERRUPT_HH_
    
    #include <functional>
    
    #include <map>
    #include <list>
    
    #include "sched.hh"
    #include "drivers/pci.hh"
    #include "drivers/pci-function.hh"
    
    // 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);
    
    
        std::function<void ()> _handler;
    
        // 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;