]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/irq_mgr.cpp
a39742318a887541d6d98ea7be7f80cd33c568b0
[l4.git] / kernel / fiasco / src / kern / irq_mgr.cpp
1 INTERFACE:
2
3 #include "types.h"
4 #include "irq_chip.h"
5 #include <type_traits>
6
7 /**
8  * Interface used to manage harware IRQs on a platform.
9  *
10  * The main purpose of this interface is to allow an
11  * abstract mapping of global IRQ numbers to a chip
12  * and pin number pair. The interface provides also
13  * some global information about IRQs.
14  */
15 class Irq_mgr
16 {
17 public:
18   /**
19    * Chip and pin for an IRQ pin.
20    */
21   struct Irq
22   {
23     // allow uninitialized instances
24     enum Init { Bss };
25     Irq(Init) {}
26
27     /// Invalid IRQ.
28     Irq() : chip(0) {}
29
30     /// Create a chip-pin pair.
31     Irq(Irq_chip_icu *chip, Mword pin) : chip(chip), pin(pin) {}
32
33     /// The chip.
34     Irq_chip_icu *chip;
35
36     /// The pin number local to \a chip.
37     Mword pin;
38   };
39
40   /// Map legacy (IA32) IRQ numbers to valid IRQ numbers.
41   virtual unsigned legacy_override(Mword irqnum) { return irqnum; }
42
43   /// Get the chip-pin pair for the given global IRQ number.
44   virtual Irq chip(Mword irqnum) const = 0;
45
46   /// Get the highest available global IRQ number plus 1.
47   virtual unsigned nr_irqs() const = 0;
48
49   /// Get the number of available entry points for MSIs.
50   virtual unsigned nr_msis() const = 0;
51
52   /** Get the message to use for a given MSI.
53    * \pre The IRQ pin needs to be already allocated before using this function.
54    */
55   virtual Mword msg(Mword irqnum) const { (void)irqnum; return 0; }
56
57   virtual void set_cpu(Mword irqnum, unsigned cpu) const;
58
59   /// The pointer to the single global instance of the actual IRQ manager.
60   static Irq_mgr *mgr;
61
62   /// Prevent generation of a real virtual delete function
63   virtual ~Irq_mgr() = 0;
64 };
65
66 template< typename CHIP >
67 class Irq_mgr_single_chip : public Irq_mgr
68 {
69 public:
70   Irq_mgr_single_chip() {}
71
72   template< typename... A >
73   explicit Irq_mgr_single_chip(A&&... args) : c(cxx::forward<A>(args)...) {}
74
75   Irq chip(Mword irqnum) const { return Irq(&c, irqnum); }
76   unsigned nr_irqs() const { return c.nr_irqs(); }
77   unsigned nr_msis() const { return 0; }
78   mutable CHIP c;
79 };
80
81 //--------------------------------------------------------------------------
82 IMPLEMENTATION:
83
84 #include "warn.h"
85
86 Irq_mgr *Irq_mgr::mgr;
87
88 IMPLEMENT inline Irq_mgr::~Irq_mgr() {}
89
90 PUBLIC inline
91 bool
92 Irq_mgr::alloc(Irq_base *irq, Mword pin)
93 {
94   Irq i = chip(pin);
95   if (!i.chip)
96     return false;
97
98   return i.chip->alloc(irq, i.pin);
99 }
100
101 PUBLIC inline
102 bool
103 Irq_mgr::reserve(Mword irqnum)
104 {
105   Irq i = chip(irqnum);
106   if (!i.chip)
107     return false;
108
109   return i.chip->reserve(i.pin);
110 }
111
112 PUBLIC inline
113 Irq_base *
114 Irq_mgr::irq(Mword irqnum) const
115 {
116   Irq i = chip(irqnum);
117   if (!i.chip)
118     return 0;
119
120   return i.chip->irq(i.pin);
121 }
122
123 IMPLEMENT
124 void
125 Irq_mgr::set_cpu(Mword irqnum, unsigned cpu) const
126 {
127   WARNX(Warning, "IRQ%ld: ignoring CPU setting (%d).\n", irqnum, cpu);
128 }