]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/irq_msi.cpp
d2cd3209d94621af4626dddd695e3651ad95ce4a
[l4.git] / kernel / fiasco / src / kern / ia32 / irq_msi.cpp
1 IMPLEMENTATION:
2
3 #include "idt.h"
4 #include "irq_pin.h"
5 #include "irq_chip.h"
6 #include "irq.h"
7
8 #include "dirq_pic_pin.h"
9 #include "apic.h"
10 #include "static_init.h"
11
12 class Irq_pin_msi : public Irq_pin
13 {
14 public:
15   enum
16   {
17     Vector_offs = 0x50,
18   };
19
20   explicit Irq_pin_msi(unsigned vect) { payload()[0] = vect; }
21   unsigned vector() const { return payload()[0]; }
22 };
23
24
25 class Irq_chip_msi : public Dirq_pic_pin::Chip
26 {
27 public:
28   void disable_irq(unsigned irqnum);
29 };
30
31 PUBLIC
32 unsigned
33 Irq_chip_msi::nr_irqs() const
34 { return APIC_IRQ_BASE - 0x10 - Irq_pin_msi::Vector_offs; }
35
36 PUBLIC
37 Mword
38 Irq_chip_msi::msg(unsigned irqn)
39 { return irqn + Irq_pin_msi::Vector_offs; }
40
41 PUBLIC
42 void
43 Irq_chip_msi::setup(Irq_base *irq, unsigned irqnum)
44 {
45   unsigned v = irqnum + Irq_pin_msi::Vector_offs;
46   if (v >= APIC_IRQ_BASE - 0x10)
47     return;
48
49   irq->pin()->replace<Irq_pin_msi>(v);
50 }
51
52 PUBLIC
53 Irq_base *
54 Irq_chip_msi::irq(unsigned irqnum)
55 {
56   unsigned v = irqnum + Irq_pin_msi::Vector_offs;
57   if (v >= APIC_IRQ_BASE - 0x10)
58     return 0;
59
60   return virq(v);
61 }
62
63 IMPLEMENT
64 void
65 Irq_chip_msi::disable_irq(unsigned vector)
66 {
67   extern char entry_int_apic_ignore[];
68   Idt::set_entry(vector, Address(&entry_int_apic_ignore), false);
69 }
70
71 PUBLIC
72 bool
73 Irq_chip_msi::alloc(Irq_base *irq, unsigned irqnum)
74 {
75   unsigned v = irqnum + Irq_pin_msi::Vector_offs;
76   if (!valloc(irq, v))
77     return false;
78
79   setup(irq, irqnum);
80   return true;
81 }
82
83 PUBLIC
84 bool
85 Irq_chip_msi::free(Irq_base *irq, unsigned irqnum)
86 {
87   return vfree(irq, irqnum + Irq_pin_msi::Vector_offs);
88 }
89
90
91 PUBLIC static FIASCO_INIT
92 void
93 Irq_chip_msi::init()
94 {
95   static Irq_chip_msi _ia;
96   Irq_chip::hw_chip_msi = &_ia;
97   for (unsigned i = 0; i < _ia.nr_irqs(); ++i)
98     _ia.disable_irq(i + Irq_pin_msi::Vector_offs);
99 }
100
101 STATIC_INITIALIZE(Irq_chip_msi);
102
103
104 PUBLIC
105 void
106 Irq_pin_msi::do_mask()
107 {}
108
109 PUBLIC
110 void
111 Irq_pin_msi::do_unmask()
112 {}
113
114 PUBLIC
115 void
116 Irq_pin_msi::do_mask_and_ack()
117 {
118   Apic::irq_ack();
119 }
120
121 PUBLIC
122 void
123 Irq_pin_msi::do_set_mode(unsigned)
124 {}
125
126 PUBLIC
127 void
128 Irq_pin_msi::ack()
129 {
130   Apic::irq_ack();
131 }
132
133 PUBLIC
134 void
135 Irq_pin_msi::set_cpu(unsigned)
136 {}
137
138 PUBLIC
139 void
140 Irq_pin_msi::unbind_irq()
141 {
142   Irq_chip::hw_chip_msi->free(Irq::self(this), vector() - Vector_offs);
143   replace<Sw_irq_pin>();
144 }
145
146 //--------------------------------------------------------------------------
147 IMPLEMENTATION [debug]:
148
149 PUBLIC
150 char const *
151 Irq_pin_msi::pin_type() const
152 { return "HW IRQ (MSI)"; }
153
154