Hello,
I got a irq0 handler , I am using gcc cross compiler 7 version , i tried with attribute (naked & interrupt) to get rid of prologue and epilogue but these attributes are ignored by compiler. The handler producing general protection fault @ iretd
void irq () {
__asm__ __volatile__ (
"pushal;");
_pit_ticks++;
interruptdone(0);
__asm__ __volatile__(" popal;"
"iretl;");
}
00000000 <_irq >:
0: 83 ec 18 sub $0x18,%esp
3: 60 pusha
4: a1 04 00 00 00 mov 0x4,%eax
9: 6a 00 push $0x0
b: 83 c0 01 add $0x1,%eax
e: a3 04 00 00 00 mov %eax,0x4
13: e8 fc ff ff ff call 14 <_irq+0x14>
18: 61 popa
19: cf iret
1a: 83 c4 1c add $0x1c,%esp
1d: c3 ret
1e: 66 90 xchg %ax,%ax
Irq0 firing general protection fault when executing iretd
Re: Irq0 firing general protection fault when executing iret
It is not a very good idea to write your irq handler in C, as you can see in the assembly code it produces (the esp is not the same when you enter and leave "_irq").
It is better to write your irq handler in assembly and then call some common c code which looks at the irq number and executes the code for that irq number.
It is better to write your irq handler in assembly and then call some common c code which looks at the irq number and executes the code for that irq number.
osdev project, goal is to run wasm as userspace: https://github.com/kwast-os/kwast
Re: Irq0 firing general protection fault when executing iret
If you want to use the "interrupt" attribute it is mandatory that your function takes a single parameter, a pointer to a struct interrupt_frame.
I find that I have better control by calling a C function (or functions) inside a wrapper written in assembler.
(PS the above applies to interrupt handlers. Exception handlers that push an error code require a second uword_t parameter.)
I find that I have better control by calling a C function (or functions) inside a wrapper written in assembler.
(PS the above applies to interrupt handlers. Exception handlers that push an error code require a second uword_t parameter.)
Re: Irq0 firing general protection fault when executing iret
Thank you guys writing it in assembler works
Re: Irq0 firing general protection fault when executing iret
You can try my code. It was inspired by Linux.yerri07 wrote:Hello,
I got a irq0 handler , I am using gcc cross compiler 7 version , i tried with attribute (naked & interrupt) to get rid of prologue and epilogue but these attributes are ignored by compiler. The handler producing general protection fault @ iretd
void irq () {
__asm__ __volatile__ (
"pushal;");
_pit_ticks++;
interruptdone(0);
__asm__ __volatile__(" popal;"
"iretl;");
}
00000000 <_irq >:
0: 83 ec 18 sub $0x18,%esp
3: 60 pusha
4: a1 04 00 00 00 mov 0x4,%eax
9: 6a 00 push $0x0
b: 83 c0 01 add $0x1,%eax
e: a3 04 00 00 00 mov %eax,0x4
13: e8 fc ff ff ff call 14 <_irq+0x14>
18: 61 popa
19: cf iret
1a: 83 c4 1c add $0x1c,%esp
1d: c3 ret
1e: 66 90 xchg %ax,%ax
Code: Select all
typedef struct Registers {
unsigned long edi;
unsigned long esi;
unsigned long ebp;
unsigned long esp;
unsigned long ebx;
unsigned long edx;
unsigned long ecx;
unsigned long eax;
unsigned short gs,_gs;
unsigned short fs,_fs;
unsigned short es,_es;
unsigned short ds,_ds;
unsigned long code;
unsigned long eip;
unsigned short cs,_cs;
unsigned long eflags;
} __attribute__((packed)) Registers;
/* Macros for manipulating registers
* */
#define SAVE_REGISTERS() \
__asm__("push ds"); \
__asm__("push es"); \
__asm__("push fs"); \
__asm__("push gs"); \
__asm__("pusha");
#define RESTORE_REGISTERS() \
__asm__("popa"); \
__asm__("pop gs"); \
__asm__("pop fs"); \
__asm__("pop es"); \
__asm__("pop ds");
/* This macro will create interrupt entry point function irq_X_interrupt
* that can be registered with set_idt_gate
* */
#define CREATE_IRQ_HANDLER(nr,handler) \
void irq_##nr##_interrupt(); \
asm("irq_"#nr"_interrupt:"); \
asm("pushd 0"); \
SAVE_REGISTERS() \
asm("pushd "#nr); \
asm("call "#handler); \
asm("add esp,4"); \
RESTORE_REGISTERS(); \
asm("add esp,4"); \
asm("iretd");
///////////////////////
long tick = 0;
void pit_irq(uint nr, Registers regs){
tick++;
}
CREATE_IRQ_HANDLER(0,pit_irq);