Also, this is my first time here!
I've been trying to solve this for over a week now, I've checked my code several times and it seems ok.
The first time i tryied to solve the PIT ticked one time, but now it doesn't even do it
The strange is, if i put like this:
Code: Select all
while(0==0) __asm__ __volatile__("sti");
Please help me, I'm just so dumb that i can't even pass the IRQ's!
idt.c
Code: Select all
#include "idt.h"
idt_entry_t idt_entries[256];
idt_ptr_t idt_ptr;
static void idt_set_gate(uint8 num, uint32 base, uint16 sel, uint8 flags)
{
idt_entries[num].base_lo = base & 0xFFFF;
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
idt_entries[num].sel = sel;
idt_entries[num].always0 = 0;
// We must uncomment the OR below when we get to using user-mode.
// It sets the interrupt gate's privilege level to 3.
idt_entries[num].flags = flags /* | 0x60 */;
}
static void irq_init(){
idt_set_gate(32, (uint32)irq0 , 0x08, 0x8E);
idt_set_gate(33, (uint32)irq1 , 0x08, 0x8E);
idt_set_gate(34, (uint32)irq2 , 0x08, 0x8E);
idt_set_gate(35, (uint32)irq3 , 0x08, 0x8E);
idt_set_gate(36, (uint32)irq4 , 0x08, 0x8E);
idt_set_gate(37, (uint32)irq5 , 0x08, 0x8E);
idt_set_gate(38, (uint32)irq6 , 0x08, 0x8E);
idt_set_gate(39, (uint32)irq7 , 0x08, 0x8E);
idt_set_gate(40, (uint32)irq8 , 0x08, 0x8E);
idt_set_gate(41, (uint32)irq9 , 0x08, 0x8E);
idt_set_gate(42, (uint32)irq10 , 0x08, 0x8E);
idt_set_gate(43, (uint32)irq11 , 0x08, 0x8E);
idt_set_gate(44, (uint32)irq12 , 0x08, 0x8E);
idt_set_gate(45, (uint32)irq13 , 0x08, 0x8E);
idt_set_gate(46, (uint32)irq14 , 0x08, 0x8E);
idt_set_gate(47, (uint32)irq15 , 0x08, 0x8E);
// Remap the irq table.
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, 0x20);
outb(0xA1, 0x28);
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, 0x0);
outb(0xA1, 0x0);
k_log(1, "IRQ", "IRQ Setup complete!");
}
void init_idt()
{
idt_ptr.limit = sizeof(idt_entry_t) * 256 -1;
idt_ptr.base = (uint32)&idt_entries;
memset(&idt_entries, 0, sizeof(idt_entry_t)*256);
idt_set_gate(0, (uint32)isr0 , 0x08, 0x8E);
idt_set_gate(1, (uint32)isr1 , 0x08, 0x8E);
idt_set_gate(2, (uint32)isr2 , 0x08, 0x8E);
idt_set_gate(3, (uint32)isr3 , 0x08, 0x8E);
idt_set_gate(4, (uint32)isr4 , 0x08, 0x8E);
idt_set_gate(5, (uint32)isr5 , 0x08, 0x8E);
idt_set_gate(6, (uint32)isr6 , 0x08, 0x8E);
idt_set_gate(7, (uint32)isr7 , 0x08, 0x8E);
idt_set_gate(8, (uint32)isr8 , 0x08, 0x8E);
idt_set_gate(9, (uint32)isr9 , 0x08, 0x8E);
idt_set_gate(10, (uint32)isr10 , 0x08, 0x8E);
idt_set_gate(11, (uint32)isr11 , 0x08, 0x8E);
idt_set_gate(12, (uint32)isr12 , 0x08, 0x8E);
idt_set_gate(13, (uint32)isr13 , 0x08, 0x8E);
idt_set_gate(14, (uint32)isr14 , 0x08, 0x8E);
idt_set_gate(15, (uint32)isr15 , 0x08, 0x8E);
idt_set_gate(16, (uint32)isr16 , 0x08, 0x8E);
idt_set_gate(17, (uint32)isr17 , 0x08, 0x8E);
idt_set_gate(18, (uint32)isr18 , 0x08, 0x8E);
idt_set_gate(19, (uint32)isr19 , 0x08, 0x8E);
idt_set_gate(20, (uint32)isr20 , 0x08, 0x8E);
idt_set_gate(21, (uint32)isr21 , 0x08, 0x8E);
idt_set_gate(22, (uint32)isr22 , 0x08, 0x8E);
idt_set_gate(23, (uint32)isr23 , 0x08, 0x8E);
idt_set_gate(24, (uint32)isr24 , 0x08, 0x8E);
idt_set_gate(25, (uint32)isr25 , 0x08, 0x8E);
idt_set_gate(26, (uint32)isr26 , 0x08, 0x8E);
idt_set_gate(27, (uint32)isr27 , 0x08, 0x8E);
idt_set_gate(28, (uint32)isr28 , 0x08, 0x8E);
idt_set_gate(29, (uint32)isr29 , 0x08, 0x8E);
idt_set_gate(30, (uint32)isr30 , 0x08, 0x8E);
idt_set_gate(31, (uint32)isr31 , 0x08, 0x8E);
k_log(1, "IDT/ISR", "IDT/ISR Setup complete!");
irq_init();
idt_flush((uint32)&idt_ptr);
asm volatile ("sti");
}
Code: Select all
.intel_syntax noprefix
.text
# In isr.c
.extern isr_handler
# This is our common ISR stub. It saves the processor state, sets
# up for kernel mode segments, calls the C-level fault handler,
# and finally restores the stack frame.
isr_common_stub:
pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds # Lower 16-bits of eax = ds.
push eax # save the data segment descriptor
mov ax, 0x10 # load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call isr_handler
pop eax # reload the original data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
popa # Pops edi,esi,ebp...
add esp, 8 # Cleans up the pushed error code and pushed ISR number
sti
iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
.extern irq_handler
irq_common_stub:
pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds # Lower 16-bits of eax = ds.
push eax # save the data segment descriptor
mov ax, 0x10 # load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call irq_handler
pop ebx # reload the original data segment descriptor
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa # Pops edi,esi,ebp...
add esp, 8 # Cleans up the pushed error code and pushed ISR number
sti
iretd # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
.macro ISR_NOERROR ARG1
.global isr\ARG1
isr\ARG1:
cli # Disable interrupts
push 0 # Push a dummy error code (if ISR0 doesn't push it's own error code)
push \ARG1 # Push the interrupt number (0)
jmp isr_common_stub # Go to our common handler.
.endm
.macro IRQ ARG1, ARG2
.global irq\ARG1
irq\ARG1:
cli
push 0
push \ARG2
jmp irq_common_stub
.endm
# ISR Macro 0 - 31
ISR_NOERROR 0
ISR_NOERROR 1
ISR_NOERROR 2
ISR_NOERROR 3
ISR_NOERROR 4
ISR_NOERROR 5
ISR_NOERROR 6
ISR_NOERROR 7
ISR_NOERROR 8
ISR_NOERROR 9
ISR_NOERROR 10
ISR_NOERROR 11
ISR_NOERROR 12
ISR_NOERROR 13
ISR_NOERROR 14
ISR_NOERROR 15
ISR_NOERROR 16
ISR_NOERROR 17
ISR_NOERROR 18
ISR_NOERROR 19
ISR_NOERROR 20
ISR_NOERROR 21
ISR_NOERROR 22
ISR_NOERROR 23
ISR_NOERROR 24
ISR_NOERROR 25
ISR_NOERROR 26
ISR_NOERROR 27
ISR_NOERROR 28
ISR_NOERROR 29
ISR_NOERROR 30
ISR_NOERROR 31
# IRQ Macro 0 - 15 (32 - 47)
IRQ 0 , 32
IRQ 1 , 33
IRQ 2 , 34
IRQ 3 , 35
IRQ 4 , 36
IRQ 5 , 37
IRQ 6 , 38
IRQ 7 , 39
IRQ 8 , 40
IRQ 9 , 41
IRQ 10, 42
IRQ 11, 43
IRQ 12, 44
IRQ 13, 45
IRQ 14, 46
IRQ 15, 47
Code: Select all
#include "isr.h"
isr_t interrupt_handlers[256];
void isr_handler(registers_t regs)
{
ee_printf("\nReceived Interrupt: 0x%X", regs.int_no);
}
void irq_handler(registers_t regs)
{
if(regs.int_no >= 40)
{
outb(0xA0, 0x20);
}
outb(0x20, 0x20);
vga_writestring("\nIRQ!");
if(interrupt_handlers[regs.int_no] != 0){
isr_t handler = interrupt_handlers[regs.int_no];
handler(regs);
}
}
void register_interrupt_handler(uint8 n, isr_t handler){
interrupt_handlers[n] = handler;
}
Code: Select all
#include "pit.h"
uint32 tick = 0;
static void pit_tick_handler(registers_t regs)
{
++tick;
ee_printf("\nTick: %d", tick);
}
void pit_init(uint32 freq)
{
register_interrupt_handler(IRQ0, &pit_tick_handler);
uint32 divisor = INPUT_CLOCK / freq;
// Send command byte
outb(0x43, 0x34);
uint8 low = (divisor & 0xFF);
uint8 hight = ((divisor >> 8) & 0xFF);
// Send the divisor
outb(0x40, low);
outb(0x40, hight);
}