Not receiving Keyboard IRQs when executing interrupt service routine

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
glolichen
Posts: 17
Joined: Wed Jul 10, 2024 9:23 pm

Not receiving Keyboard IRQs when executing interrupt service routine

Post by glolichen »

I am not able to receive keyboard interrupt requests from the PIC when the CPU is executing another interrupt service routine. The problem arose when implementing the read system call, which I have implemented using the traditional int 80h (instead of syscall or sysenter instructions).

This is run in QEMU - when receiving a keyboard interrupt the following is written to the log by QEMU:

Code: Select all

Servicing hardware INT=0x21
   118: v=21 e=0000 i=0 cpl=0 IP=0008:ffffffff80108813 pc=ffffffff80108813 SP=0010:ffffffff80919ff0 env->regs[R_EAX]=ffffffff82976000
or something similar.

When executing a read system call, the interrupt service routine will block execution until a new line is entered. But when the CPU is executing the system call ISR, I am not receiving any keyboard IRQs from the PIC, so the above message never appears.

Specifically, this is done by loading an ELF program from the file system and executing it. The program will perform a read system call by calling a software interrupt through int 80h.

Interrupts definitely work, as the kernel will handle a division error or any other exception. It's just the keyboard hardware interrupt that doesn't work.

The code for the OS is here: https://github.com/glolichen/lios.

Does this have to do with how the PIC is remapped, by any chance?

Code: Select all

	mov dx, 0x20
	mov al, 0x11
	out dx, al

	mov dx, 0x80
	mov al, 0
	out dx, al

	mov dx, 0xA0
	mov al, 0x11
	out dx, al

	mov dx, 0x80
	mov al, 0
	out dx, al

	mov dx, 0x21
	mov al, 0x20
	out dx, al
 
	mov dx, 0x80
	mov al, 0
	out dx, al

	mov dx, 0xA1
	mov al, 0x28
	out dx, al

	mov dx, 0x80
	mov al, 0
	out dx, al

	mov dx, 0x21
	mov al, 0x04
	out dx, al
	
	mov dx, 0x80
	mov al, 0
	out dx, al

	mov dx, 0xA1
	mov al, 0x02
	out dx, al

	mov dx, 0x80
	mov al, 0
	out dx, al

	mov dx, 0x21
	mov al, 0x01
	out dx, al

	mov dx, 0x80
	mov al, 0
	out dx, al

	mov dx, 0xA1
	mov al, 0x01
	out dx, al

	mov dx, 0x80
	mov al, 0
	out dx, al

	mov dx, 0x21
	mov al, 0xFD
	out dx, al

	mov dx, 0xA1
	mov al, 0xFF
	out dx, al
Any help is greatly appreciated. Thanks.
nullplan
Member
Member
Posts: 1889
Joined: Wed Aug 30, 2017 8:24 am

Re: Not receiving Keyboard IRQs when executing interrupt service routine

Post by nullplan »

Without having looked at your code, I presume you never re-enable interrupts in the system call handler, yet expect them to be enabled, anyway. Just execute an sti instruction after finishing the context switch.
Carpe diem!
Octocontrabass
Member
Member
Posts: 5805
Joined: Mon Mar 25, 2013 7:01 pm

Re: Not receiving Keyboard IRQs when executing interrupt service routine

Post by Octocontrabass »

glolichen wrote: Sat May 10, 2025 3:31 pmI am not able to receive keyboard interrupt requests from the PIC when the CPU is executing another interrupt service routine.
Usually you don't want an interrupt service routine to be interrupted by another interrupt service routine, since your kernel may not have a large enough stack for nested ISRs. If you think you need to interrupt an ISR, you might be doing something wrong.
glolichen wrote: Sat May 10, 2025 3:31 pmusing the traditional int 80h (instead of syscall or sysenter instructions).
All 64-bit x86 CPUs support the SYSCALL instruction. Unlike 32-bit x86, where it makes sense to use INT for backwards compatibility, there is never a good reason to use INT with 64-bit x86.
glolichen wrote: Sat May 10, 2025 3:31 pmWhen executing a read system call, the interrupt service routine will block execution until a new line is entered.
How are you blocking execution? It sounds like the problem might be that you're literally blocking execution instead of marking the current task as blocked and switching to another task.
thewrongchristian
Member
Member
Posts: 449
Joined: Tue Apr 03, 2018 2:44 am

Re: Not receiving Keyboard IRQs when executing interrupt service routine

Post by thewrongchristian »

glolichen wrote: Sat May 10, 2025 3:31 pm I am not able to receive keyboard interrupt requests from the PIC when the CPU is executing another interrupt service routine. The problem arose when implementing the read system call, which I have implemented using the traditional INT 80h (instead of syscall or sysenter instructions).
Check the gate type for your int 0x80.

Interrupt gates, that you should use to handle external interrupts, disable interrupts, then restore the previous interrupt enable state on IRET. The reason for this, as per @Octocontrabass, is to prevent nested hardware interrupts.

If you've defined your INT 80h interrupt handler in the same way as your IRQ interrupt handlers, you may have defined it as an interrupt gate as well. You want to define it as a trap gate.

Looking at your code:

Code: Select all

	// "syscall" (using software interrupt, call with int 128 in assembly)
	// 0xEE = 0b11101110: interrupt, ring 3 permission
	// use IRQ 96 because IRQs are configured to be (interrupt number - 32)
	idt_set_entry(128, (u64) irq96, 0xEE);
I think you want to us 0xEF instead of 0xEE, that will encode the interrupt as a trap gate.
glolichen
Posts: 17
Joined: Wed Jul 10, 2024 9:23 pm

Re: Not receiving Keyboard IRQs when executing interrupt service routine

Post by glolichen »

thewrongchristian wrote: Sun May 11, 2025 5:40 am I think you want to us 0xEF instead of 0xEE, that will encode the interrupt as a trap gate.
Thanks, setting a trap gate fixes the problem.

I'm aware of the advantages of using syscall, I will switch to using that soon. Unfortunately "blocking" is implemented using a dumb while loop, obviously that's not ideal and I will address it when I get to the point of having a working scheduler.
Post Reply