OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 7:06 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Irq0 firing general protection fault when executing iretd
PostPosted: Tue Jun 13, 2017 4:05 am 
Offline
Member
Member

Joined: Sat Apr 29, 2017 6:56 am
Posts: 26
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


Top
 Profile  
 
 Post subject: Re: Irq0 firing general protection fault when executing iret
PostPosted: Tue Jun 13, 2017 4:38 am 
Offline
Member
Member
User avatar

Joined: Sun Apr 05, 2015 3:15 pm
Posts: 31
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.

_________________
osdev project, goal is to run wasm as userspace: https://github.com/kwast-os/kwast


Top
 Profile  
 
 Post subject: Re: Irq0 firing general protection fault when executing iret
PostPosted: Tue Jun 13, 2017 4:52 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
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.)


Top
 Profile  
 
 Post subject: Re: Irq0 firing general protection fault when executing iret
PostPosted: Tue Jun 13, 2017 10:22 am 
Offline
Member
Member

Joined: Sat Apr 29, 2017 6:56 am
Posts: 26
Thank you guys writing it in assembler works


Top
 Profile  
 
 Post subject: Re: Irq0 firing general protection fault when executing iret
PostPosted: Tue Jun 13, 2017 11:03 am 
Offline
Member
Member

Joined: Mon Sep 19, 2016 5:34 am
Posts: 27
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

You can try my code. It was inspired by Linux.
Code:
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);

Don't forget to register irq_0_interrupt in your idt. You can also define other naming pattern by modify CREATE_IRQ_HANDLER's macro.

_________________
https://github.com/irvanherz/jaura/


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 75 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group