3 Copyright (C) 2007-2009 Jörg Pfähler
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <kernel/log.hpp>
20 #include <kernel/event_manager.hpp>
21 #include <kernel/x86_shared/interrupt_controller.hpp>
23 using namespace kernel
;
25 SINGLETON_INSTANCE(kernel::event_manager
);
28 kernel::event_manager::event_manager()
33 kernel::event_manager::~event_manager()
37 size_t event_manager::register_irq(libkernel::port_id_t port
,
41 // TODO: We should check whether this irq/params combination is really supposed to be used by this process
43 uint8_t bus
= param1
& 0xFF;
44 uint8_t irq
= (param1
>> 8) & 0xFF;
45 uint8_t busnr
= param2
& 0xFF;
46 uint8_t dev
= (param2
>> 8) & 0xFF;
47 uint8_t intn
= (param1
>> 16) & 0xFF;
48 uint8_t priority
= (param2
>> 24) & 0xFF;
51 interrupt_controller
&InterruptController
= interrupt_controller::instance();
52 if (bus
== BUS_ID_ISA
)
53 vector
= InterruptController
.register_isa_irq(irq
, priority
);
54 else if (bus
== BUS_ID_PCI
)
55 vector
= InterruptController
.register_pci_irq(irq
, intn
, busnr
, dev
, priority
);
61 mIRQEvents
.push_back(pair
<libkernel::port_id_t
, size_t>(port
, vector
));
69 void event_manager::acknoledge_irq(libkernel::port_id_t port
,
74 auto end
= mIRQEvents
.end();
75 for (auto i
= mIRQEvents
.begin();i
!= end
;i
++)
76 if ((*i
).first
== port
&&
77 (*i
).second
== irq_id
)
79 interrupt_controller
&InterruptController
= interrupt_controller::instance();
80 InterruptController
.acknoledge_irq(irq_id
);
88 void event_manager::unregister_irq(libkernel::port_id_t port
,
93 auto end
= mIRQEvents
.end();
94 for (auto i
= mIRQEvents
.begin();i
!= end
;i
++)
95 if ((*i
).first
== port
&&
96 (*i
).second
== irq_id
)
98 interrupt_controller
&InterruptController
= interrupt_controller::instance();
99 InterruptController
.unregister_irq((*i
).second
);
108 void event_manager::handle_irq(uint8_t vector
)
112 auto end
= mIRQEvents
.end();
113 for (auto i
= mIRQEvents
.begin();i
!= end
;i
++)
114 if ((*i
).second
== vector
)
116 libkernel::message_t
msg((*i
).first
, libkernel::message::event
, libkernel::event::irq
, vector
, 0);
117 port_manager
&PortManager
= port_manager::instance();
118 PortManager
.send(libkernel::message_port::kernel
, msg
);
124 void event_manager::register_timer(libkernel::port_id_t port
,
125 uint64_t microseconds
,
132 event
.remaining
= microseconds
* 1000;
133 event
.microseconds
= microseconds
* 1000;
134 event
.periodic
= periodic
;
135 mTimerEvents
.push_back(event
);
140 void event_manager::unregister_timer(libkernel::port_id_t port
)
144 std::vector
<timer_event
>::iterator end
= mTimerEvents
.end();
145 for (std::vector
<timer_event
>::iterator i
= mTimerEvents
.begin();i
!= end
;i
++)
146 if ((*i
).port
== port
)
148 mTimerEvents
.erase(i
);
156 void event_manager::tick(uint64_t microseconds
)
160 mTicks
+= microseconds
;
162 for (size_t i
= 0;i
< mTimerEvents
.size();)
164 if (mTimerEvents
[i
].remaining
< microseconds
)
167 libkernel::message_t
msg(mTimerEvents
[i
].port
,
168 libkernel::message::event
,
169 libkernel::event::timer
,
172 port_manager
&PortManager
= port_manager::instance();
173 PortManager
.send(libkernel::message_port::kernel
, msg
);
176 if (mTimerEvents
[i
].periodic
== true)
178 mTimerEvents
[i
].remaining
= mTimerEvents
[i
].microseconds
;
182 mTimerEvents
.erase(mTimerEvents
.begin() + i
);
186 mTimerEvents
[i
].remaining
-= microseconds
;
194 size_t event_manager::get_ticks()
198 size_t result
= mTicks
/ 1000;