]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/irq_msi.cpp
b9cc8a99036571d89e1726d92074875d0dd05d10
[l4.git] / kernel / fiasco / src / kern / ia32 / irq_msi.cpp
1 IMPLEMENTATION:
2
3 #include "idt.h"
4 #include "irq_chip.h"
5 #include "irq_mgr.h"
6 #include "irq_chip_ia32.h"
7
8 #include "apic.h"
9 #include "static_init.h"
10 #include "boot_alloc.h"
11
12 class Irq_chip_msi : public Irq_chip_ia32
13 {
14 public:
15   // this is somehow arbitrary
16   enum { Max_msis = 0x40 };
17   Irq_chip_msi() : Irq_chip_ia32(Max_msis) {}
18 };
19
20 class Irq_mgr_msi : public Irq_mgr
21 {
22 private:
23   mutable Irq_chip_msi _chip;
24   Irq_mgr *_orig;
25 };
26
27 PUBLIC inline
28 char const *
29 Irq_chip_msi::chip_type() const
30 { return "MSI"; }
31
32 PUBLIC
33 bool
34 Irq_chip_msi::alloc(Irq_base *irq, Mword pin)
35 {
36   return valloc(irq, pin, 0);
37 }
38
39 PUBLIC
40 void
41 Irq_chip_msi::unbind(Irq_base *irq)
42 {
43   extern char entry_int_apic_ignore[];
44   //Mword n = irq->pin();
45   // hm: no way to mask an MSI: mask(n);
46   vfree(irq, &entry_int_apic_ignore);
47   Irq_chip_icu::unbind(irq);
48 }
49
50 PUBLIC
51 Mword
52 Irq_chip_msi::msg(Mword pin)
53 {
54   if (pin < _irqs)
55     return _entry[pin].vector();
56
57   return 0;
58 }
59
60 PUBLIC unsigned
61 Irq_chip_msi::set_mode(Mword, unsigned)
62 { return Irq_base::Trigger_edge | Irq_base::Polarity_low; }
63
64 PUBLIC void
65 Irq_chip_msi::set_cpu(Mword, unsigned)
66 {}
67
68 PUBLIC void
69 Irq_chip_msi::mask(Mword)
70 {}
71
72 PUBLIC void
73 Irq_chip_msi::ack(Mword)
74 { ::Apic::irq_ack(); }
75
76 PUBLIC void
77 Irq_chip_msi::mask_and_ack(Mword)
78 { ::Apic::irq_ack(); }
79
80 PUBLIC void
81 Irq_chip_msi::unmask(Mword)
82 {}
83
84
85 PUBLIC inline explicit
86 Irq_mgr_msi::Irq_mgr_msi(Irq_mgr *o) : _orig(o) {}
87
88 PUBLIC Irq_mgr::Irq
89 Irq_mgr_msi::chip(Mword irq) const
90 {
91   if (irq & 0x80000000)
92     return Irq(&_chip, irq & ~0x80000000);
93   else
94     return _orig->chip(irq);
95 }
96
97 PUBLIC
98 unsigned
99 Irq_mgr_msi::nr_irqs() const
100 { return _orig->nr_irqs(); }
101
102 PUBLIC
103 unsigned
104 Irq_mgr_msi::nr_msis() const
105 { return _chip.nr_irqs(); }
106
107 PUBLIC
108 Mword
109 Irq_mgr_msi::msg(Mword irq) const
110 {
111   if (irq & 0x80000000)
112     return _chip.msg(irq & ~0x80000000);
113   else
114     return 0;
115 }
116
117 PUBLIC unsigned
118 Irq_mgr_msi::legacy_override(Mword irq)
119 {
120   if (irq & 0x80000000)
121     return irq;
122   else
123     return _orig->legacy_override(irq);
124 }
125
126
127 PUBLIC static FIASCO_INIT
128 void
129 Irq_mgr_msi::init()
130 {
131   Irq_mgr_msi *m;
132   Irq_mgr::mgr = m =  new Boot_object<Irq_mgr_msi>(Irq_mgr::mgr);
133   printf("Enable MSI support: chained IRQ mgr @ %p\n", m->_orig);
134 }
135
136 STATIC_INITIALIZE(Irq_mgr_msi);
137