Page 1 of 1
I don't know why IRQ1 handler doesn't work
Posted: Tue Jun 15, 2004 4:32 pm
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
Re: I don't know why IRQ1 handler doesn't work
Posted: Tue Jun 15, 2004 4:46 pm
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 ...
Re: I don't know why IRQ1 handler doesn't work
Posted: Wed Jun 16, 2004 8:27 pm
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
Re: I don't know why IRQ1 handler doesn't work
Posted: Thu Jun 17, 2004 2:01 am
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.
Re: I don't know why IRQ1 handler doesn't work
Posted: Wed Jul 14, 2004 2:33 pm
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 ..
Re: I don't know why IRQ1 handler doesn't work
Posted: Wed Jul 14, 2004 2:56 pm
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.
Re: I don't know why IRQ1 handler doesn't work
Posted: Thu Jul 15, 2004 8:03 am
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 .
Re: I don't know why IRQ1 handler doesn't work
Posted: Thu Jul 15, 2004 8:13 am
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 ?
Re: I don't know why IRQ1 handler doesn't work
Posted: Thu Jul 15, 2004 1:53 pm
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 .
Re: I don't know why IRQ1 handler doesn't work
Posted: Thu Jul 15, 2004 3:04 pm
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
Re: I don't know why IRQ1 handler doesn't work
Posted: Fri Jul 16, 2004 12:57 am
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
Re: I don't know why IRQ1 handler doesn't work
Posted: Fri Jul 16, 2004 1:51 pm
by firas981
Both solutions succeeded .
thank you very much