CPU exception interrupts in real mode

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
Erukaron
Posts: 13
Joined: Sat Feb 22, 2020 3:24 am
Libera.chat IRC: Erukaron
Location: Germany

CPU exception interrupts in real mode

Post by Erukaron »

Hi,

i have a question regarding interrupts in real mode. I understand that the first 20 interrupts in real mode are cpu exception interrupts. I tried to redirect them to my own error handling interrupt, so that i can inform the user that a double fault or divide by zero or something like that occurred and then restart the system.

If i do this for e.g. interrupt 0 (divide by zero) this works fine. Upon an illegal division the system informs me and halts, or if no illegal division is executed, operates normal.
However, if i try to do this for the interrupt 8 (double fault), i am getting double fault errors consistently the fourth time i try to read the floppy.
Here is some of the code i use:

Overwriting the ivt:

Code: Select all

; Double Fault
mov [ds:0x20], word _critical_double_fault
mov ax, cs
mov [ds:0x20 + 2], ax
Interrupt handler for double fault:

Code: Select all

_critical_double_fault:
	pusha
	push ds
	mov ax, cs
	mov ds, ax
	
	; This is a macro calling a software interrupt, printing the message with error code 8 and then halting the system, effectifely making everything below this macro useless
	critical_println .error_msg, 8
	pop ds

	end_of_interrupt

	popa 
	iret

	.error_msg db 'Double fault!', 0
Reading the floppy:
The error occurs on ch=0, cl=5, dh=1, dl=0, es:bx=0x03400

Code: Select all

	mov ah, 0x02 ; Read device es:bx
	mov al, 0x01 ; Number of sectors to read
	mov ch, byte [__lba_chs_absolute_track] ; track
	mov cl, byte [__lba_chs_absolute_sector] ; sector
	mov dh, byte [__lba_chs_absolute_head] ; head
	mov dl, byte [bsDriveNumber]
	int 0x13
	jnc .done ; test if succeeded
The jnc statement is never reached the fourth time this code is executed.

If i do not alter the ivt for interrupt 8, there is no problem in reading the floppy disk, neither is the interrupt being called. I set a breakpoint on the start of the interrupt handler (0xffea5) to verify this.

Has somebody had a similar problem or knows why the double fault interrupt is called only if i change the ivt? Is it okay to overwrite the cpu exception interrupts?
Octocontrabass
Member
Member
Posts: 5575
Joined: Mon Mar 25, 2013 7:01 pm

Re: CPU exception interrupts in real mode

Post by Octocontrabass »

Those aren't double faults, those are IRQ0. The interrupt controller is programmed to use interrupt vectors 8 through 15 for IRQs 0 through 7. You can thank backwards compatibility: the IBM PC 5150 does it that way, so everyone else does too.

I'm not sure if there's any way to work around this limitation while using BIOS code. As far as I know, the BIOS is free to reprogram the interrupt controller and reload the IDTR at any time, so it's not possible to redirect interrupts through a shadow IVT.

If you're not using BIOS code, then you can reprogram the interrupt controller to use more convenient interrupt vectors.
Erukaron
Posts: 13
Joined: Sat Feb 22, 2020 3:24 am
Libera.chat IRC: Erukaron
Location: Germany

Re: CPU exception interrupts in real mode

Post by Erukaron »

Thank you for your answer.

I realized i made a mistake in my initial post:
If i do not alter the ivt for interrupt 8, there is no problem in reading the floppy disk, neither is the interrupt being called. I set a breakpoint on the start of the interrupt handler (0xffea5) to verify this.
I don't know what i did wrong last time, but i tried it again today and the interrupt is called, even if i do not alter the IVT, so this makes it more clear to me, that interrupt 8 is invoked by IRQ0 for timing purpose.
Those aren't double faults, those are IRQ0. The interrupt controller is programmed to use interrupt vectors 8 through 15 for IRQs 0 through 7.
How to tell which interrupt vector is assigned to the PIC and which is used for processor exceptions? When i look up resources for the PIC, i find that interrupt vectors 8 trough 15 are reserved for the PIC. https://wiki.osdev.org/PIC#Programming_the_PIC_chips

But if i search for cpu exception interrupts or the default IVT, i find that interrupt 8 is assigned to double faults.
https://wiki.osdev.org/IVT
80386 reference: http://beefchunk.com/documentation/hard ... html#9.8.8

This is very confusing to me. Can somebody explain to me in which case the interrupts are invoked by the PIC and in which case the IVT refers to processor exceptions?
Octocontrabass
Member
Member
Posts: 5575
Joined: Mon Mar 25, 2013 7:01 pm

Re: CPU exception interrupts in real mode

Post by Octocontrabass »

The interrupt vectors are assigned to both at the same time. In real mode, there's no way for you to tell whether interrupt 8 was caused by IRQ0 or a double fault.

You can reconfigure the PIC to use different vectors, but then the BIOS won't work properly. Without the BIOS, you may as well use protected mode (or long mode) to take full advantage of the CPU's capabilities.
Erukaron
Posts: 13
Joined: Sat Feb 22, 2020 3:24 am
Libera.chat IRC: Erukaron
Location: Germany

Re: CPU exception interrupts in real mode

Post by Erukaron »

Oh okay, what a pity there is no reliable way in using the BIOS and reconfiguring the PIC. Thanks for the explanation.
Without the BIOS, you may as well use protected mode (or long mode) to take full advantage of the CPU's capabilities.
Thank you, i know, but i explicitly want to program in 16-bit mode.
mallard
Member
Member
Posts: 280
Joined: Tue May 13, 2014 3:02 am
Location: Private, UK

Re: CPU exception interrupts in real mode

Post by mallard »

Octocontrabass wrote:In real mode, there's no way for you to tell whether interrupt 8 was caused by IRQ0 or a double fault.
Well, you can read the PIC status to determine whether IRQ0 is in-service or not. Of course, if you're unlucky enough to get a double-fault while trying to handle IRQ0 you won't be able to distinguish them, but in the common case you should be able to.
Image
Post Reply