]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/irq_msi.cpp
update
[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 int
61 Irq_chip_msi::set_mode(Mword, Mode)
62 { return 0; }
63
64 PUBLIC bool
65 Irq_chip_msi::is_edge_triggered(Mword) const
66 { return true; }
67
68 PUBLIC void
69 Irq_chip_msi::set_cpu(Mword, Cpu_number)
70 {}
71
72 PUBLIC void
73 Irq_chip_msi::mask(Mword)
74 {}
75
76 PUBLIC void
77 Irq_chip_msi::ack(Mword)
78 { ::Apic::irq_ack(); }
79
80 PUBLIC void
81 Irq_chip_msi::mask_and_ack(Mword)
82 { ::Apic::irq_ack(); }
83
84 PUBLIC void
85 Irq_chip_msi::unmask(Mword)
86 {}
87
88
89 PUBLIC inline explicit
90 Irq_mgr_msi::Irq_mgr_msi(Irq_mgr *o) : _orig(o) {}
91
92 PUBLIC Irq_mgr::Irq
93 Irq_mgr_msi::chip(Mword irq) const
94 {
95   if (irq & 0x80000000)
96     return Irq(&_chip, irq & ~0x80000000);
97   else
98     return _orig->chip(irq);
99 }
100
101 PUBLIC
102 unsigned
103 Irq_mgr_msi::nr_irqs() const
104 { return _orig->nr_irqs(); }
105
106 PUBLIC
107 unsigned
108 Irq_mgr_msi::nr_msis() const
109 { return _chip.nr_irqs(); }
110
111 PUBLIC
112 Mword
113 Irq_mgr_msi::msg(Mword irq) const
114 {
115   if (irq & 0x80000000)
116     return _chip.msg(irq & ~0x80000000);
117   else
118     return 0;
119 }
120
121 PUBLIC unsigned
122 Irq_mgr_msi::legacy_override(Mword irq)
123 {
124   if (irq & 0x80000000)
125     return irq;
126   else
127     return _orig->legacy_override(irq);
128 }
129
130
131 PUBLIC static FIASCO_INIT
132 void
133 Irq_mgr_msi::init()
134 {
135   Irq_mgr_msi *m;
136   Irq_mgr::mgr = m =  new Boot_object<Irq_mgr_msi>(Irq_mgr::mgr);
137   printf("Enable MSI support: chained IRQ mgr @ %p\n", m->_orig);
138 }
139
140 STATIC_INITIALIZE(Irq_mgr_msi);
141