I don't know why IRQ1 handler doesn't work

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
firas981

I don't know why IRQ1 handler doesn't work

Post by firas981 »

I wrote the kb driver , and wrote kb handler ( IRQ1 handler ) and registered it in IDT at 0x21 , of course I've qualified PICs before .
I also followed the advice mentioned in FAQs about writing a wrapper in assembly for the handler.
I put a message to be displayed in the handler , but nothing occured whatever the key I press .
i.e. the handler is not called !!
   
thanks
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re: I don't know why IRQ1 handler doesn't work

Post by Pype.Clicker »

did you make sure the irq1 was not masked (either at the PIC or at the cpu with IF ?)

do you have exception handlers ? could it be that you believe the handler is not called because it entered endless exceptions just before it should have printed the message ?

For the keyboard, if your handler can get called once, but no more, also make sure you acknowledge the interrupt properly and read the byte out of the controller or the hardware will be unable to deliver further interrupts ...
firas981

Re: I don't know why IRQ1 handler doesn't work

Post by firas981 »

after debugging I found that the instruction
   " sti " which is called as inline assembly instruction from inside the c kernel file caused
   bochs to report exception as :
   Event type: PANIC
   Device: [CPU ]
   Message: exception(): 3rd (13) exception with no resolution .
   
   this is the case even if i stop execution after "sti" .

   okay , I went to the intel reference and found that "sti" causes GP exception
    If the CPL is greater (has less privilege) than the IOPL of the current
   program or procedure.
   
   however the cpl is 0 ( the kernel ) , so regardless of iopl , the exception should not occur , should it ?!!!!

   thanks
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re: I don't know why IRQ1 handler doesn't work

Post by Pype.Clicker »

the most likely is that your STI did work and immediately enabled interrupts that were blocked for so long.
Probably you have some trouble with your IDT table, however (for example wrong content loaded into IDTR), and thus once the CPU tries to handle the interrupt, it gets a fault but as the IDT is wrong, the exception cannot be handled either, which ultimately leads to a tripple fault.

Make sure you read I can't get interrupts working from the FAQ.
firas981

Re: I don't know why IRQ1 handler doesn't work

Post by firas981 »

I 've read the mega-tokyo FAQs several times , and as I think I followed all advices mentioned there ....
surely , I mistaked somewhere , but I don't know where , although I tried very hardly to solve the problem .
I 'll present the problem in more detail by excerpts :

//------------------------- ----- interrupts_wrappers.asm -------------------------------

GLOBAL KB_IRQ1_Handler_Wrapper
EXTERN KB_IRQ1_Handler

ALIGN 4

KB_IRQ1_Handler_Wrapper :

pushad
call KB_IRQ1_Handler
popad

iret

//--------------------------------------------- kb.c ------------------------------------

void KB_IRQ1_Handler ( )
{

if ( current_top < top_max ) buffer[ current_top] = KB_Read_From_OutputRegister () ;
current_top++ ;

PIC_Set_EOI ( 1 ) ;

}

extern Dword KB_IRQ1_Handler_Wrapper ;

void KB_Register_IRQ1_Handler ()
{
   Byte dpl = 0 ;
   IDTAddInterruptGateEntry ( 0x21 ,( void * ) KB_IRQ1_Handler_Wrapper , dpl ) ;
}

//---------------------------------------------- idt.h ---------------------------------
typedef struct
{
Word limit;    
Dword base;      

} __attribute__ ((packed)) IDTR ;

typedef struct {

Word offset0_15;
Word selector ;
unsigned reserved:5;
unsigned zeros:3;   
unsigned type:5;
unsigned dpl:2;
unsigned present:1;
Word offset16_31;

} __attribute__ ((packed)) InterruptGate ;

typedef union
{
TaskGate    taskGate ;
InterruptGate interruptGate ;
TrapGate    trapGate ;
//I've mentioned & used the second field only .

} IDTDescriptor;

IDTDescriptor IDT[256] ;

#define System_32Bit_InterruptGate         0x0E

#define HIGH_WORD_OF_DWORD(x) (Word)( (x) >> 16 )   
#define LOW_WORD_OF_DWORD(x) (Word)( (x) & 0x0000FFFF )

//---------------------------------------------- idt.c ---------------------------------

void IDTLoadIDTR()
{
   
   IDTR idtr ;
   
   idtr.limit = 256 * 8 -1 ;                              
   
   idtr.base = (Dword) IDT;      

   IDTR *IDTRptr = &idtr ;
   
   asm volatile("LIDT (%0) ": :"p" (IDTRptr));
   
}

void IDTAddInterruptGateEntry (Byte vector , void (*handler)(), Byte dpl)
{   
   Dword offset = (Dword)handler;
   asm volatile("movw %%cs,%0" :"=g"(selector));

   IDT[vector].interruptGate.offset0_15    = LOW_WORD_OF_DWORD(offset);
   IDT[vector].interruptGate.selector    = selector;
   IDT[vector].interruptGate.type      = System_32Bit_InterruptGate ;
   IDT[vector].interruptGate.dpl         = dpl & 3 ;
   IDT[vector].interruptGate.offset16_31    = HIGH_WORD_OF_DWORD(offset);

}

//-------------------------------------- kernel.c -----------------------------------------

int main()

{

//the following function remap pics , then disable all IRQs from pic side :
//OutPortByte ( PIC_Master_1 , 0xFF ) ;
//OutPortByte ( PIC_Slave_1 , 0xFF ) ;

PIC_Initialize (0x20 ,0x28 ) ;

asm volatile("cli");

IDTLoadIDTR();   

KB_Register_IRQ1_Handler() ;

PIC_UnMask_IRQ ( 1 ) ;

asm volatile("sti");   

while (1) ;

return 0 ;
}

//---------------------------------- notes --------------------------------------------------
1 )I am using nasm & gcc
2 )elf format is the output format of the compilation
binary format is the output format of the link .
3 )when running my ill os on bochs , it boots and loads the kernel successfully , but when press
any-key , bochs reports this message :
   " [CPU ] exception(): 3rd (13) exception with no resolution "
Thanks a lot ..
Dreamsmith

Re: I don't know why IRQ1 handler doesn't work

Post by Dreamsmith »

firas981 wrote:void IDTAddInterruptGateEntry (Byte vector , void (*handler)(), Byte dpl)
{
Dword offset = (Dword)handler;
asm volatile("movw %%cs,%0" :"=g"(selector));

IDT[vector].interruptGate.offset0_15 = LOW_WORD_OF_DWORD(offset);
IDT[vector].interruptGate.selector = selector;
IDT[vector].interruptGate.type = System_32Bit_InterruptGate ;
IDT[vector].interruptGate.dpl = dpl & 3 ;
IDT[vector].interruptGate.offset16_31 = HIGH_WORD_OF_DWORD(offset);

}
Err, you're forgetting to set a bunch of values in the IDT, it looks like. The "present" bit, for one, is hugely important to be set correctly. You also should make sure the reserved bits are zero.
firas981

Re: I don't know why IRQ1 handler doesn't work

Post by firas981 »

thanks very much , I have to pay more attention to such things .
Ok ,That was an error and I corrected it , but there is another error :

my code will not work unless i put 0x7b50 ( which is the physical address of the interrupt handler )
instead of KB_IRQ1_Handler_Wrapper when invoking the call of IDTAddInterruptGateEntry :
IDTAddInterruptGateEntry ( 0x21 ,( void * ) 0x7b50 , dpl ) ;

I really see that this is not reasonable !!

thanks .
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re: I don't know why IRQ1 handler doesn't work

Post by Pype.Clicker »

could you be loading IDT descriptor's selector field with a wrong segment (not having the proper base ?)
Or could you be missing some TLB invalidation after you changed some page table/directory entries ?
firas981

Re: I don't know why IRQ1 handler doesn't work

Post by firas981 »

The selector got its value from cs as demonstrated by the code .

The code segment descriptor is :
Base = 0h , Limit = 16 MgB , 32 bit segment , present , ring 0
type is code , Non-Conforming , ex/re , not-accessed

The kernel is loaded to 0x7400 physical , and there is no paging at all .

thanks .
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re: I don't know why IRQ1 handler doesn't work

Post by Pype.Clicker »

imho, your error is in declaring the wrapper as a "dword". (void*) Wrapper will return the 32-bits value at the Wrapper (thus bytes for push, call, etc) and then convert them in a pointer... not good.
try

Code: Select all

void KB_IRQ1_Handler_Wrapper();

void KB_Register_IRQ1_Handler ()
{
   Byte dpl = 0 ;
   IDTAddInterruptGateEntry ( 0x21 ,( void * ) KB_IRQ1_Handler_Wrapper , dpl ) ;
}
instead :p
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: I don't know why IRQ1 handler doesn't work

Post by Candy »

Code: Select all

void KB_IRQ1_Handler_Wrapper();

typedef void (*IRQHandler)();

void KB_Register_IRQ1_Handler ()
{
   Byte dpl = 0 ;
   IDTAddInterruptGateEntry ( 0x21 ,(IRQHandler) &KB_IRQ1_Handler_Wrapper , dpl ) ;
}
instead might work even better ;)
firas981

Re: I don't know why IRQ1 handler doesn't work

Post by firas981 »

Both solutions succeeded .
thank you very much
Post Reply