problem with irq

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
asdfgh
Member
Member
Posts: 42
Joined: Fri Apr 18, 2008 9:14 pm

problem with irq

Post by asdfgh »

i have remapped the pic.

but when i press a keyboard button nothing happens..

i have written a function for interrupt 33 which is for keyboard

???

Code: Select all

#define ICW1 0x11
#define PICC1 0x20
#define PICC2 0xA0
#define PICD1 0x21
#define PICD2 0xA1

void idt_install()//install the idt and enable interrupts
{
   kprint("Installing IDT                ");
/*Here is where we set all of our idt entries*/
idt_set_gate(0,cast_uint(isr0),0x08,0x8E);
idt_set_gate(1,cast_uint(isr1),0x08,0x8E);
idt_set_gate(2,cast_uint(isr2),0x08,0x8E);
idt_set_gate(3,cast_uint(isr3),0x08,0x8E);
idt_set_gate(4,cast_uint(isr4),0x08,0x8E);
idt_set_gate(5,cast_uint(isr5),0x08,0x8E);
idt_set_gate(6,cast_uint(isr6),0x08,0x8E);
idt_set_gate(7,cast_uint(isr7),0x08,0x8E);
idt_set_gate(8,cast_uint(isr8),0x08,0x8E);
idt_set_gate(9,cast_uint(isr9),0x08,0x8E);
idt_set_gate(10,cast_uint(isr10),0x08,0x8E);
idt_set_gate(11,cast_uint(isr11),0x08,0x8E);
idt_set_gate(12,cast_uint(isr12),0x08,0x8E);
idt_set_gate(13,cast_uint(isr13),0x08,0x8E);
idt_set_gate(14,cast_uint(isr14),0x08,0x8E);
idt_set_gate(15,cast_uint(isr15),0x08,0x8E);
idt_set_gate(16,cast_uint(isr16),0x08,0x8E);
 
/*********************************************/
     remap_pic();
   idt_set_gate(32,cast_uint(isr32),0x08,0x8E);
   idt_set_gate(33,cast_uint(isr33),0x08,0x8E);
 idt_p.limit = sizeof(struct idt_entry) * 256 -1;
   idt_p.base  = cast_uint(&idt_entries);
   idt_flush();//load the idtr with the idt pointer
   kprint("DONE\n");
}

void remap_pic()//for more info check out brokenthorn tuts
{
outb(PICC1,ICW1);//init pic 1
outb(PICC2,ICW1);//init pic 2
outb(PICD1,0x20);//remap irq0-7 to 0x20-0x27
outb(PICD2,0x28);//remap irq8+ to 0x28+
outb(PICD1,0x4);//ICW3
outb(PICD2,0x2);//ICW3 to second pic
outb(PICD1,0x1);//ICW4
outb(PICD2,0x1);//^
outb(PICD1,0);//null out the register values
outb(PICD2,0);
}
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Did you enable interrupts? (sti)
C8H10N4O2 | #446691 | Trust the nodes.
asdfgh
Member
Member
Posts: 42
Joined: Fri Apr 18, 2008 9:14 pm

Post by asdfgh »

ya... all other interrupts from 0 to 31 are working fine...
but only these irq's are not workking..
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

The "interrupts" from 0 to 31 are actually called exceptions, and do not need STI. Please check carefully that your STI command really did run -- that truly is the most likely reason that you are not getting IRQs. Are you running in an emulator? If so, check the EFLAGS IF bit.

If you are running this on real hardware, then there is the possibility that you have a machine with APIC enabled. If APIC is enabled, then remapping the PIC does not work the same way, exactly.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

The other thing that I can think of is that you're silently handling IRQs (for instance, a PIT timer IRQ on IRQ0) but not ACKing them correctly.

Until you ACK an IRQ, you will not recieve another.
asdfgh
Member
Member
Posts: 42
Joined: Fri Apr 18, 2008 9:14 pm

Post by asdfgh »

when i enable sti the timer keeps on executing..... and prints numbers...
when i press keyboard i gives an interrupt only for the first press after which nothing happens

Code: Select all

void timer_isr()
{
	ticks++;
	print_int(ticks);
	outb(0x20, 0x20);
}

void keyboard_isr()
{
kprint("keypressed\n");
outb(0x20, 0x20);
}

User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

asdfgh wrote:when i enable sti the timer keeps on executing..... and prints numbers...
when i press keyboard i gives an interrupt only for the first press after which nothing happens

Code: Select all

void timer_isr()
{
	ticks++;
	print_int(ticks);
	outb(0x20, 0x20);
}

void keyboard_isr()
{
kprint("keypressed\n");
outb(0x20, 0x20);
}

Hi,

This behaviour is correct. The keyboard will only interrupt while its buffer is not full. If its buffer is full and a key is pressed, an interrupt will not occur. You must read port --0x64-- EDIT no, it's 0x60 to empty the buffer.

Cheers,

James
Last edited by JamesM on Mon May 12, 2008 3:40 am, edited 1 time in total.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Post by egos »

asdfgh, try this.

1)

Code: Select all

void keyboard_isr()
{
char c = inb(0x60);
kprint("keypressed\n");
outb(0x20, 0x20);
}
2) send command 0xAE or clean bit 4 of command byte.
User avatar
CmpXchg
Member
Member
Posts: 61
Joined: Mon Apr 28, 2008 12:14 pm
Location: Petrozavodsk, Russia during school months, Vänersborg Sweden in the summertime

Post by CmpXchg »

What is more, a keyboard ISR should set the 7-th bit in the port 61h, and then return it to its previous value. Like this:

Code: Select all

in al,61h
push ax
or al,80h
out 61h,al
pop ax
out 61h,al
Unless it's done, the keyboard won't send any more IRQ's.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

CmpXchg wrote:What is more, a keyboard ISR should set the 7-th bit in the port 61h, and then return it to its previous value. Like this:

Code: Select all

in al,61h
push ax
or al,80h
out 61h,al
pop ax
out 61h,al
Unless it's done, the keyboard won't send any more IRQ's.
That's incorrect. Port 61h does not need to be touched for IRQs to fire.
User avatar
CmpXchg
Member
Member
Posts: 61
Joined: Mon Apr 28, 2008 12:14 pm
Location: Petrozavodsk, Russia during school months, Vänersborg Sweden in the summertime

Post by CmpXchg »

JamesM wrote:Port 61h does not need to be touched for IRQs to fire.
But James, haven't you written that
JamesM wrote:Until you ACK an IRQ, you will not recieve another.
Port 61h seems to be that missing ACK, besides sending 20h to port 20h.

Of course, I'm not entirely sure it is really so, it's from a book on x86 assembly programming. I will try it out under DOS.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

I believe that the ACK mentioned in your second quote was referring to writing an EOI port 0x20.

Reading from port 0x60 is enough for the KBC - you do not need to separately send an ACK to port 0x61.

Cheers,
Adam
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

AJ wrote:I believe that the ACK mentioned in your second quote was referring to writing an EOI port 0x20.
Quite so, sorry for the ambiguity.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

CmpXchg wrote:What is more, a keyboard ISR should set the 7-th bit in the port 61h, and then return it to its previous value. Like this:

Code: Select all

in al,61h
push ax
or al,80h
out 61h,al
pop ax
out 61h,al
Unless it's done, the keyboard won't send any more IRQ's.
This is mostly for very old machines.
More accurately, if several scancodes come from the keyboard before the IRQ gets serviced, you are supposed to toggle that "keyboard disable" bit in order to get the next scancode in the buffer. Otherwise, the old keyboard controller chip would keep giving you the same scancode over and over again.
But it is not necessary on anything built after 1995, or something.
User avatar
CmpXchg
Member
Member
Posts: 61
Joined: Mon Apr 28, 2008 12:14 pm
Location: Petrozavodsk, Russia during school months, Vänersborg Sweden in the summertime

Post by CmpXchg »

bewing wrote:Otherwise, the old keyboard controller chip would keep giving you the same scancode over and over again.
Exactly.

So why not to add the following code:

Code: Select all

in al,61h
or al,80h
out 61h,al
Post Reply