Skip to content

Commit c4939e7

Browse files
authored
Merge pull request #816 from fwsGonzo/dev
Mask off PIT interrupt in IOAPIC when unused
2 parents 8dfa8b6 + 1dbb993 commit c4939e7

4 files changed

Lines changed: 22 additions & 5 deletions

File tree

api/kernel/irq_manager.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class IRQ_manager {
7575
* @param irq: the IRQ to enable
7676
*/
7777
void enable_irq(uint8_t irq);
78+
void disable_irq(uint8_t irq);
7879

7980
/**
8081
* Directly set an IRQ handler in IDT

src/hw/apic.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ namespace hw {
4848
static const uintptr_t IA32_APIC_BASE_MSR = 0x1B;
4949
static const uintptr_t IA32_APIC_BASE_MSR_ENABLE = 0x800;
5050
static const uintptr_t BOOTLOADER_LOCATION = 0x80000;
51+
static const uint8_t SPURIOUS_INTR = IRQ_manager::INTR_LINES-1;
5152

5253
// every CPU has a local APIC
5354
apic lapic;
@@ -123,7 +124,6 @@ namespace hw {
123124

124125
// start receiving interrupts (0x100), set spurious vector
125126
// note: spurious IRQ must have 4 last bits set (0x?F)
126-
const uint8_t SPURIOUS_INTR = IRQ_manager::INTR_LINES-1;
127127
lapic.enable_intr(SPURIOUS_INTR);
128128

129129
// acknowledge any outstanding interrupts
@@ -213,14 +213,14 @@ namespace hw {
213213
for (uint8_t i = 0; i < 8; i++)
214214
if (lapic.regs->isr[i].reg)
215215
return 32 * i + __builtin_ffs(lapic.regs->isr[i].reg) - 1;
216-
return 0;
216+
return 255;
217217
}
218218
uint8_t APIC::get_irr()
219219
{
220220
for (uint8_t i = 0; i < 8; i++)
221221
if (lapic.regs->irr[i].reg)
222222
return 32 * i + __builtin_ffs(lapic.regs->irr[i].reg) - 1;
223-
return 0;
223+
return 255;
224224
}
225225

226226
void APIC::eoi()
@@ -282,6 +282,16 @@ namespace hw {
282282
}
283283
void APIC::disable_irq(uint8_t irq)
284284
{
285+
auto& overrides = ACPI::get_overrides();
286+
for (auto& redir : overrides)
287+
{
288+
// NOTE: @bus_source is the IOAPIC number
289+
if (redir.irq_source == irq)
290+
{
291+
IOAPIC::disable(redir.global_intr);
292+
return;
293+
}
294+
}
285295
IOAPIC::disable(irq);
286296
}
287297
void APIC::setup_subs()

src/hw/pit.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ namespace hw {
6262
void PIT::disable_regular_interrupts()
6363
{
6464
oneshot(1);
65+
IRQ_manager::get().disable_irq(0);
6566
}
6667

6768
PIT::PIT() {}
@@ -105,8 +106,10 @@ namespace hw {
105106
PIT::Timer_iterator PIT::start_timer(Timer t, std::chrono::milliseconds in_msecs){
106107
if (in_msecs < 1ms) panic("Can't wait less than 1 ms. ");
107108

108-
if (current_mode_ != RATE_GEN)
109+
if (current_mode_ != RATE_GEN) {
109110
set_mode(RATE_GEN);
111+
IRQ_manager::get().enable_irq(0);
112+
}
110113

111114
if (current_freq_divider_ != millisec_interval)
112115
set_freq_divider(millisec_interval);
@@ -267,7 +270,7 @@ namespace hw {
267270

268271
if (timers_.empty()) {
269272
debug("No more timers. Entering one-shot mode\n");
270-
oneshot(1);
273+
disable_regular_interrupts();
271274
}
272275

273276

src/kernel/irq_manager.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ void IRQ_manager::enable_irq(uint8_t irq) {
156156
// program IOAPIC to redirect this irq to BSP LAPIC
157157
hw::APIC::enable_irq(irq);
158158
}
159+
void IRQ_manager::disable_irq(uint8_t irq) {
160+
hw::APIC::disable_irq(irq);
161+
}
159162

160163
void IRQ_manager::subscribe(uint8_t irq, irq_delegate del) {
161164
if (irq >= IRQ_LINES)

0 commit comments

Comments
 (0)