Add ATA drive support #27
@ -22,6 +22,9 @@ namespace CPU
|
||||
void disable_interrupts();
|
||||
void wait_for_interrupt();
|
||||
|
||||
bool save_interrupts();
|
||||
void restore_interrupts(bool saved);
|
||||
|
||||
void get_stack_trace(void (*callback)(u64, void*), void* arg);
|
||||
void print_stack_trace();
|
||||
void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg);
|
||||
@ -30,6 +33,7 @@ namespace CPU
|
||||
u16 get_processor_id();
|
||||
|
||||
bool register_interrupt(u8 interrupt, void (*handler)(Registers*, void*), void* context);
|
||||
void sync_interrupts();
|
||||
|
||||
void pause();
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ extern "C" void enable_nx();
|
||||
|
||||
extern void setup_gdt();
|
||||
extern void remap_pic();
|
||||
extern void change_pic_masks(u8 pic1_mask, u8 pic2_mask);
|
||||
extern void pic_eoi(unsigned char irq);
|
||||
extern void pic_eoi(Registers* regs);
|
||||
extern void setup_idt();
|
||||
@ -268,6 +269,8 @@ namespace CPU
|
||||
.expect_value("Could not create the IO background thread!");
|
||||
|
||||
remap_pic();
|
||||
|
||||
sync_interrupts();
|
||||
}
|
||||
|
||||
void enable_interrupts()
|
||||
@ -280,6 +283,20 @@ namespace CPU
|
||||
asm volatile("cli");
|
||||
}
|
||||
|
||||
bool save_interrupts()
|
||||
{
|
||||
u64 flags;
|
||||
asm volatile("pushfq; pop %0" : "=r"(flags));
|
||||
return flags & 0x200;
|
||||
}
|
||||
|
||||
void restore_interrupts(bool saved)
|
||||
{
|
||||
if (saved) enable_interrupts();
|
||||
else
|
||||
disable_interrupts();
|
||||
}
|
||||
|
||||
void wait_for_interrupt()
|
||||
{
|
||||
asm volatile("hlt");
|
||||
@ -387,8 +404,28 @@ namespace CPU
|
||||
|
||||
irq_handlers[interrupt] = { handler, context };
|
||||
|
||||
sync_interrupts();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void sync_interrupts()
|
||||
{
|
||||
u8 pic1_mask, pic2_mask;
|
||||
pic1_mask = pic2_mask = 0b11111111;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (irq_handlers[i].function) pic1_mask &= (u8)(~(1 << i));
|
||||
if (irq_handlers[i + 8].function) pic2_mask &= (u8)(~(1 << i));
|
||||
}
|
||||
|
||||
if (pic2_mask != 0b11111111) pic1_mask &= 0b11111011;
|
||||
|
||||
auto val = CPU::save_interrupts();
|
||||
CPU::disable_interrupts();
|
||||
change_pic_masks(pic1_mask, pic2_mask);
|
||||
CPU::restore_interrupts(val);
|
||||
}
|
||||
}
|
||||
|
||||
// called by kernel_yield
|
||||
|
@ -84,6 +84,20 @@ INT(20);
|
||||
INT(21);
|
||||
INT(32);
|
||||
INT(33);
|
||||
INT(34);
|
||||
INT(35);
|
||||
INT(36);
|
||||
INT(37);
|
||||
INT(38);
|
||||
INT(39);
|
||||
INT(40);
|
||||
INT(41);
|
||||
INT(42);
|
||||
INT(43);
|
||||
INT(44);
|
||||
INT(45);
|
||||
INT(46);
|
||||
INT(47);
|
||||
INT(66);
|
||||
|
||||
void setup_idt()
|
||||
@ -112,6 +126,20 @@ void setup_idt()
|
||||
TRAP(21);
|
||||
IRQ(32);
|
||||
IRQ(33);
|
||||
IRQ(34);
|
||||
IRQ(35);
|
||||
IRQ(36);
|
||||
IRQ(37);
|
||||
IRQ(38);
|
||||
IRQ(39);
|
||||
IRQ(40);
|
||||
IRQ(41);
|
||||
IRQ(42);
|
||||
IRQ(43);
|
||||
IRQ(44);
|
||||
IRQ(45);
|
||||
IRQ(46);
|
||||
IRQ(47);
|
||||
SYS(66);
|
||||
|
||||
static IDTR idtr;
|
||||
|
@ -36,9 +36,18 @@ void remap_pic()
|
||||
IO::outb(PIC2_DATA, ICW4_8086);
|
||||
io_delay();
|
||||
|
||||
IO::outb(PIC1_DATA, 0b11111100);
|
||||
IO::outb(PIC1_DATA, 0b11111111);
|
||||
io_delay();
|
||||
IO::outb(PIC2_DATA, 0b11111111);
|
||||
io_delay();
|
||||
}
|
||||
|
||||
void change_pic_masks(u8 pic1_mask, u8 pic2_mask)
|
||||
{
|
||||
IO::outb(PIC1_DATA, pic1_mask);
|
||||
io_delay();
|
||||
IO::outb(PIC2_DATA, pic2_mask);
|
||||
io_delay();
|
||||
}
|
||||
|
||||
void pic_eoi(unsigned char irq)
|
||||
|
Loading…
Reference in New Issue
Block a user