3 #include "dirq_pic_pin.h"
6 class Dirq_io_apic : public Dirq_pic_pin
9 class Chip : public Dirq_pic_pin::Chip
12 bool alloc(Irq_base *irq, unsigned irqnum);
13 void setup(Irq_base *irq, unsigned irqnum);
14 unsigned legacy_override(unsigned irq);
15 unsigned nr_irqs() const;
16 void disable_irq(unsigned irqnum);
32 Default_mode = Irq::Trigger_edge | Irq::Polarity_high,
33 //Default_mode = Irq::Trigger_level | Irq::Polarity_high,
39 Dirq_io_apic::Chip::legacy_override(unsigned irq)
41 return Io_apic::legacy_override(irq);
48 Dirq_io_apic::Chip::nr_irqs() const
49 { return Io_apic::nr_irqs(); }
54 Dirq_io_apic::Chip::setup(Irq_base *irq, unsigned irqnum)
56 //irq->pin()->set_mode(Default_mode);
57 if (irq->pin()->get_mode() & Irq::Trigger_level)
58 irq->pin()->replace<Pin_io_apic_level>(irqnum);
60 irq->pin()->replace<Pin_io_apic_edge>(irqnum);
65 Dirq_io_apic::Chip::alloc(Irq_base *irq, unsigned irqnum)
67 if (!Dirq_pic_pin::Chip::alloc(irq, irqnum))
70 Io_apic_entry e = Io_apic::apic()->read_entry(irqnum);
71 e.vector(vector(irqnum));
72 Io_apic::apic()->write_entry(irqnum, e);
78 Dirq_io_apic::Chip::disable_irq(unsigned vector)
80 extern char entry_int_apic_ignore[];
81 Idt::set_entry(vector, Address(&entry_int_apic_ignore), false);
85 Mword to_io_apic_trigger(unsigned mode)
87 return (mode & Irq::Trigger_level)
88 ? Io_apic_entry::Level
89 : Io_apic_entry::Edge;
93 Mword to_io_apic_polarity(unsigned mode)
95 return (mode & Irq::Polarity_low)
96 ? Io_apic_entry::Low_active
97 : Io_apic_entry::High_active;
100 class Pin_io_apic_level : public Dirq_pic_pin
103 explicit Pin_io_apic_level(unsigned irq) : Dirq_pic_pin(irq) {}
106 class Pin_io_apic_edge : public Pin_io_apic_level
109 explicit Pin_io_apic_edge(unsigned irq) : Pin_io_apic_level(irq) {}
116 Pin_io_apic_level::disable()
118 extern char entry_int_apic_ignore[];
119 unsigned vector = this->vector();
120 Idt::set_entry(vector, Address(&entry_int_apic_ignore), false);
125 Pin_io_apic_edge::do_mask_and_ack()
127 assert (cpu_lock.test());
133 Pin_io_apic_edge::do_set_mode(unsigned mode)
135 Io_apic_entry e = Io_apic::apic()->read_entry(irq());
136 e.polarity(to_io_apic_polarity(mode));
137 e.trigger(to_io_apic_trigger(mode));
138 Io_apic::apic()->write_entry(irq(), e);
139 if (mode & Irq::Trigger_level)
140 new (this) Pin_io_apic_level(irq());
145 Pin_io_apic_level::do_mask()
147 assert (cpu_lock.test());
148 Io_apic::mask(irq());
155 Pin_io_apic_level::ack()
157 assert (cpu_lock.test());
164 Pin_io_apic_level::do_mask_and_ack()
166 assert (cpu_lock.test());
168 Io_apic::mask(irq());
175 Pin_io_apic_level::do_unmask()
177 assert (cpu_lock.test());
178 Io_apic::unmask(irq());
182 Pin_io_apic_level::set_cpu(unsigned cpu)
184 Io_apic::set_dest(irq(), Cpu::cpus.cpu(cpu).phys_id());
189 Pin_io_apic_level::do_set_mode(unsigned mode)
191 Io_apic_entry e = Io_apic::apic()->read_entry(irq());
192 e.polarity(to_io_apic_polarity(mode));
193 e.trigger(to_io_apic_trigger(mode));
194 Io_apic::apic()->write_entry(irq(), e);
195 if (!(mode & Irq::Trigger_level))
196 new (this) Pin_io_apic_edge(irq());
200 PUBLIC static FIASCO_INIT
205 Irq_chip::hw_chip = &_ia;
208 // --------------------------------------------------------------------------
209 IMPLEMENTATION [debug]:
213 Pin_io_apic_level::pin_type() const
214 { return "HW IRQ (IOAPIC level)"; }
218 Pin_io_apic_edge::pin_type() const
219 { return "HW IRQ (IOAPIC edge)"; }