The reason I think IRET causes this, is because when a IRQ is received, such as the PIT, my IRQ handler just says to print a message and IRET, and then immediately after the message appears the message for interrupt 0x6 shows up (invalid opcode). Some other ways I tested this was by removing the "while (1);" line (see code below) at the end of my interrupt handler for software interrupts, to stop it from halting. By doing this, it will call IRET next, which, causes the same exception to happen again (invalid opcode).
Here is the output (if I delete "while (1);")
As you can see, "Interrupted 32" shows, which mean that IRQ0 was fired, which is the PIT. The handler for this interrupt calls IRET at the end, and then this causes the invalid opcode interrupt, and this interrupt calls IRET at the end, which again causes the same problem.
Here is the code for the parts that apply:
Code: Select all
#include <stdint.h>
#include "system.h"
struct idt_entry
{
uint16_t basel;
uint16_t selector;
uint8_t zero;
uint8_t attrib;
uint16_t baseh;
}__attribute__((packed));
struct idt_ptr
{
uint16_t limit;
uint32_t base;
}__attribute__((packed));
struct isr_reg {
uint32_t di, si, bp, sp, bx, dx, cx, ax;
uint32_t isr, error;
uint32_t eip, cs, eflags, useresp, ss;
}__attribute__((packed));
const char *exception_names[] =
{
"Division by zero",
"Debug",
"Non maskable interrupt",
"Breakpoint",
"Detected overflow",
"Out of bounds",
"Invalid opcode",
"No coprocessor",
"Double fault",
"Coprocessor segment overrun",
"Bad TSS",
"Segment not present",
"Stack fault",
"General protection fault",
"Page fault",
"Unknown interrupt",
"Coprocessor fault",
"Alignment check",
"Machine check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
static struct idt_entry idt[256];
struct idt_ptr idtp;
extern void eoi();
extern void eoi_slave();
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
extern void isr32();
extern void isr33();
extern void isr34();
extern void isr35();
extern void isr36();
extern void isr37();
extern void isr38();
extern void isr39();
extern void isr40();
extern void isr41();
extern void isr42();
extern void isr43();
extern void isr44();
extern void isr45();
extern void isr46();
extern void isr47();
static void idt_add_gate(struct idt_entry *entry, uint32_t base, uint16_t selector, uint8_t attrib)
{
entry->basel = base & 0x0000ffff;
entry->selector = selector;
entry->zero = 0;
entry->attrib = attrib;
entry->baseh = (base & 0xffff0000) >> 16;
}
void idt_load()
{
memset(&idt[0], 0, sizeof(struct idt_entry) * 256);
idt_add_gate(&idt[0], (unsigned) isr0, 0x08, 0x8e);
idt_add_gate(&idt[1], (unsigned) isr1, 0x08, 0x8e);
idt_add_gate(&idt[2], (unsigned) isr2, 0x08, 0x8e);
idt_add_gate(&idt[3], (unsigned) isr3, 0x08, 0x8e);
idt_add_gate(&idt[4], (unsigned) isr4, 0x08, 0x8e);
idt_add_gate(&idt[5], (unsigned) isr5, 0x08, 0x8e);
idt_add_gate(&idt[6], (unsigned) isr6, 0x08, 0x8e);
idt_add_gate(&idt[7], (unsigned) isr7, 0x08, 0x8e);
idt_add_gate(&idt[8], (unsigned) isr8, 0x08, 0x8e);
idt_add_gate(&idt[9], (unsigned) isr9, 0x08, 0x8e);
idt_add_gate(&idt[10], (unsigned) isr10, 0x08, 0x8e);
idt_add_gate(&idt[11], (unsigned) isr11, 0x08, 0x8e);
idt_add_gate(&idt[12], (unsigned) isr12, 0x08, 0x8e);
idt_add_gate(&idt[13], (unsigned) isr13, 0x08, 0x8e);
idt_add_gate(&idt[14], (unsigned) isr14, 0x08, 0x8e);
idt_add_gate(&idt[15], (unsigned) isr15, 0x08, 0x8e);
idt_add_gate(&idt[16], (unsigned) isr16, 0x08, 0x8e);
idt_add_gate(&idt[17], (unsigned) isr17, 0x08, 0x8e);
idt_add_gate(&idt[18], (unsigned) isr18, 0x08, 0x8e);
idt_add_gate(&idt[19], (unsigned) isr19, 0x08, 0x8e);
idt_add_gate(&idt[20], (unsigned) isr20, 0x08, 0x8e);
idt_add_gate(&idt[21], (unsigned) isr21, 0x08, 0x8e);
idt_add_gate(&idt[22], (unsigned) isr22, 0x08, 0x8e);
idt_add_gate(&idt[23], (unsigned) isr23, 0x08, 0x8e);
idt_add_gate(&idt[24], (unsigned) isr24, 0x08, 0x8e);
idt_add_gate(&idt[25], (unsigned) isr25, 0x08, 0x8e);
idt_add_gate(&idt[26], (unsigned) isr26, 0x08, 0x8e);
idt_add_gate(&idt[27], (unsigned) isr27, 0x08, 0x8e);
idt_add_gate(&idt[28], (unsigned) isr28, 0x08, 0x8e);
idt_add_gate(&idt[29], (unsigned) isr29, 0x08, 0x8e);
idt_add_gate(&idt[30], (unsigned) isr30, 0x08, 0x8e);
idt_add_gate(&idt[31], (unsigned) isr31, 0x08, 0x8e);
idt_add_gate(&idt[32], (unsigned) isr32, 0x08, 0x8e);
idt_add_gate(&idt[33], (unsigned) isr33, 0x08, 0x8e);
idt_add_gate(&idt[34], (unsigned) isr34, 0x08, 0x8e);
idt_add_gate(&idt[35], (unsigned) isr35, 0x08, 0x8e);
idt_add_gate(&idt[36], (unsigned) isr36, 0x08, 0x8e);
idt_add_gate(&idt[37], (unsigned) isr37, 0x08, 0x8e);
idt_add_gate(&idt[38], (unsigned) isr38, 0x08, 0x8e);
idt_add_gate(&idt[39], (unsigned) isr39, 0x08, 0x8e);
idt_add_gate(&idt[40], (unsigned) isr40, 0x08, 0x8e);
idt_add_gate(&idt[41], (unsigned) isr41, 0x08, 0x8e);
idt_add_gate(&idt[42], (unsigned) isr42, 0x08, 0x8e);
idt_add_gate(&idt[43], (unsigned) isr43, 0x08, 0x8e);
idt_add_gate(&idt[44], (unsigned) isr44, 0x08, 0x8e);
idt_add_gate(&idt[45], (unsigned) isr45, 0x08, 0x8e);
idt_add_gate(&idt[46], (unsigned) isr46, 0x08, 0x8e);
idt_add_gate(&idt[47], (unsigned) isr47, 0x08, 0x8e);
idtp.limit = (sizeof(struct idt_entry) * 256) - 1;
idtp.base = (unsigned) &idt;
}
void isrh(struct isr_reg *r)
{
kprint("\nburnsOS encountered a critical exception and needs to reset.\n", YELLOW, BLACK);
kprint("Whoops!\n\n", WHITE, BLACK);
kprint(" Exception: ", GREY, BLACK);
kprint(exception_names[r->isr], WHITE, BLACK);
kprint(" (0x", WHITE, BLACK);
char buffer[10];
itoa(r->isr, buffer, 16);
kprint(buffer, WHITE, BLACK);
kprint(")\n", WHITE, BLACK);
kprint(" Error code: ", GREY, BLACK);
kprint("0x", WHITE, BLACK);
itoa(r->error, buffer, 16);
kprint(buffer, WHITE, BLACK);
kprint("\n\nIt is safe to reset or power down your PC.\n", GREY, BLACK);
while (1);
}
void irqh(struct isr_reg *r)
{
kprint("\nInterrupted: ", GREY, BLACK);
char buffer[10];
itoa(r->isr, buffer, 10);
kprint(buffer, WHITE, BLACK);
kprint("\n", WHITE, BLACK);
if (r->isr >= 40) {
eoi_slave();
} else {
eoi();
}
}
Code: Select all
bits 32
global isr0
global isr1
global isr2
global isr3
global isr4
global isr5
global isr6
global isr7
global isr8
global isr9
global isr10
global isr11
global isr12
global isr13
global isr14
global isr15
global isr16
global isr17
global isr18
global isr19
global isr20
global isr21
global isr22
global isr23
global isr24
global isr25
global isr26
global isr27
global isr28
global isr29
global isr30
global isr31
global isr32
global isr33
global isr34
global isr35
global isr36
global isr37
global isr38
global isr39
global isr40
global isr41
global isr42
global isr43
global isr44
global isr45
global isr46
global isr47
global eoi
global eoi_slave
extern isrh
extern irqh
section .text
align 8
eoi:
mov al, 0x20
out 0x20, al
ret
eoi_slave:
mov al, 0x20
out 0xa0, al
out 0x20, al
ret
isr:
pusha
mov eax, esp
push eax
mov eax, isrh
call eax
pop eax
popa
add esp, 8
iret
irq:
pusha
mov eax, esp
push eax
mov eax, irqh
call eax
pop eax
popa
add esp, 8
iret
isr0: ; Divide by zero
push dword 0
push dword 0
jmp isr
isr1: ; Debug
push dword 0
push dword 1
jmp isr
isr2: ; NMI
push dword 0
push dword 2
jmp isr
isr3: ; Breakpoint
push dword 0
push dword 3
jmp isr
isr4: ; Detected overflow
push dword 0
push dword 4
jmp isr
isr5: ; Out of bounds
push dword 0
push dword 5
jmp isr
isr6: ; Invalid opcode
push dword 0
push dword 6
jmp isr
isr7: ; No coprocessor
push dword 0
push dword 7
jmp isr
isr8: ; Double fault
push dword 8
jmp isr
isr9: ; Coprocessor segment overrun
push dword 0
push dword 9
jmp isr
isr10: ; Bad TSS
push dword 10
jmp isr
isr11: ; Segment not present
push dword 11
jmp isr
isr12: ; Stack fault
push dword 12
jmp isr
isr13: ; General protection fault
push dword 13
jmp isr
isr14: ; Page fault
push dword 0
push dword 14
jmp isr
isr15: ; Unknown interrupt
push dword 0
push dword 15
jmp isr
isr16: ; Coprocessor fault
push dword 0
push dword 16
jmp isr
isr17: ; Alignment check
push dword 0
push dword 17
jmp isr
isr18: ; Machine check
push dword 0
push dword 18
jmp isr
isr19: ; Reserved
push dword 0
push dword 19
jmp isr
isr20: ; Reserved
push dword 0
push dword 20
jmp isr
isr21: ; Reserved
push dword 0
push dword 21
jmp isr
isr22: ; Reserved
push dword 0
push dword 22
jmp isr
isr23: ; Reserved
push dword 0
push dword 23
jmp isr
isr24: ; Reserved
push dword 0
push dword 24
jmp isr
isr25: ; Reserved
push dword 0
push dword 25
jmp isr
isr26: ; Reserved
push dword 0
push dword 26
jmp isr
isr27: ; Reserved
push dword 0
push dword 27
jmp isr
isr28: ; Reserved
push dword 0
push dword 28
jmp isr
isr29: ; Reserved
push dword 0
push dword 29
jmp isr
isr30: ; Reserved
push dword 0
push dword 30
jmp isr
isr31: ; Reserved
push dword 0
push dword 31
jmp isr
isr32:
push dword 0
push dword 32
jmp irq
isr33:
push dword 0
push dword 33
jmp irq
isr34:
push dword 0
push dword 34
jmp irq
isr35:
push dword 0
push dword 35
jmp irq
isr36:
push dword 0
push dword 36
jmp irq
isr37:
push dword 0
push dword 37
jmp irq
isr38:
push dword 0
push dword 38
jmp irq
isr39:
push dword 0
push dword 39
jmp irq
isr40:
push dword 0
push dword 40
jmp irq
isr41:
push dword 0
push dword 41
jmp irq
isr42:
push dword 0
push dword 42
jmp irq
isr43:
push dword 0
push dword 43
jmp irq
isr44:
push dword 0
push dword 44
jmp irq
isr45:
push dword 0
push dword 45
jmp irq
isr46:
push dword 0
push dword 46
jmp irq
isr47:
push dword 0
push dword 47
jmp irq
Please say if you need to know anything else. Also note that I am using qemu, and I have tried bochs too, but with the same result
What could be causing this problem?