VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

How does software detect if it needs to pop an error code(used in some exceptions) from the stack(vs normal INT instruction)>

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 14, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

How does software detect if it needs to pop an error code(used in some exceptions) from the stack(vs normal INT instruction)>

Why do you need to worry about this, do you have some example situation where this is necessary?

Because otherwise the software writer knows what the software currently running should be doing. If you want to handle some exception, you would not call it with INT, and thus you know when it is called then it is an exception and there is an error code to pop.

Reply 2 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

Well, in UniPCemu all those exceptions are currently handled the same(Except task gates): the Interrupt, Nested Task flags are cleared when used for the interrupt descriptor and the handler is started, then the error code is pushed on the stack(having no other side effects for the code to detect, except for (E)SP's value).

Also #GP(0) in real mode uses the same vector as an IRQ handler? How does the code handle IRQ vs memory address overflow?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 4 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

But what about the offset overflow (being >0xFFFF) in real mode? In that case it could either be an #GP with 16-bit value stored on the stack or an plain INT instruction or hardware interrupt with nothing stored on the stack. The stack can't be reliably used, since it could contain "FLAGS, CS, IP, ERRORCODE" or "FLAGS, CS, IP". So there isn't any way for software to detect whether or not the error code is pushed on the stack, nor can it know it's caller's location to check, since that's on the stack as well (it could read IP or ERRORCODE from the bottom of the stack, and there isn't any way to check which one it is, since no other indications exist?)

So there's no way to differentiate between an >0xFFFF #GP fault(with error code) and a plain IRQ5/INT Dh instruction. Since the stack can't be reliable used to find the error location, as it could be any data on the stack, without any way to differentiate between what is used on the stack(it's only data, with no indication whatsoever of whether or not the error code is there, or if it's actually the IP value at that location, which is needed to find errors)?

Btw, documentation on the actual fault interrupt handlers are confusing:
http://www.geek.com/chips/difference-between- … ed-mode-574665/ says it's interrupt 13h, but osdev says interrupt 0Dh(which is interrupt 13 decimal)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 14, by crazyc

User metadata
Rank Member
Rank
Member

That's why they shouldn't do that. By keeping the interrupt gate DPL less than CPL for the interrupts that could also be faults the OS can make sure INT 00h-0Eh will cause a #GP fault rather than a software interrupt. Then just set the PIC to relocate the IRQs and do fix the DPL for them too. And yes, #GP is 13 decimal not hex.

Reply 6 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

But there's still the problem of #GP and #SP in real mode. How can the software interrupt differentiate between a normal INT and a hardware interrupt/exception using an error code pushed on the stack in real mode? The stack values can be either with or without error code. So there's no way to differentiate between an IRQ with error code, an INT without error code and an exception(#GP for a segment with offset >0xFFFF), since the CS and IP on the stack can be any value, as well as the error code pushed on the stack. It also cannot be known by the SP pointer, since the SP before the INT(if any) isn't known(only in protected mode when loaded through the TSS).

So how can the software have an IRQ handler(with error code for IRQ, without error code for INT) and #GP handler at the same place? #GP because of a limit break(e.g. MOV 16-bit to address 0xFFFF) cannot be masked, so it's impossible to keep compatible with 808X software?

Edit: I've modified the real mode interrupt handling to not push the error code to the stack anymore(thus, 808X-compatible). It now also checks the IVT against the IDT limit and produces an INT 8(Instead of double fault as well) or triple fault(if the INT 8 fails as well).

Thus the 80286 interrupt problem is solved(using information on the table mentioned earlier). So the (un)real mode has almost no protection. Only the limit checks of segments and IDT(Used as 8086 IVT with base and limit in the IDTR used) still exists(With exceptions 08h(IVT limit) and 0Dh(Segment limit) being used only). There's also exception 09h, which is a ESC segment limit (instead of 0Dh), but since my emulation doesn't have a coprocessor(80287), this shouldn't need to be handled?

Is this correct?

Last edited by superfury on 2016-10-23, 21:57. Edited 1 time in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 7 of 14, by crazyc

User metadata
Rank Member
Rank
Member

#GP and #SP faults in real mode were not a concern of the 80286 designers. If a #GP fault arrives and the IRQ 5 handler that can't deal with the error code is invoked there's nothing that can be done about it. I'm sure Intel did lots of PC/XT software compatibility testing before releasing the 286.

Reply 8 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

Well, that simple thing(#GP on accessing word at 0xFFFF) would break quite some 808X software, if it pushes an 16-bit error code on the stack, since software executing an IRET or reading/modifying an return address would read the error code as CS, CS as IP and IP as the flags. So it's not 808X-compatible in any way?

Stack on 8086 during normal IRQ5:
FLAGS
IP
CS <- SP

Stack on a 80286+ after #GP because of an limit 0xFFFF word access:
FLAGS
IP
CS
ERRORCODE <- SP

That's in REAL MODE, which is supposed to be 8086-compatible! In what way is that '8086-compatible'? Any 8086 application trying to hook(808X-style hook) or call the IRQ through INT would crash the system(corrupting the stack or crashing)?

Or is no error code pushed onto the stack in real mode?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 14, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

Well in the 286 reference manual, there is a whole appendix on 8088/8086 compatibility, so they did think of these 30+ years ago. In fact the chips are not that compatible in extreme corner cases, but general purpose, well made, bug free 8088/8086 real mode software usually runs just fine on AT, as they should not generate exceptions anyway, so when these vectors do happen they are standard hardware IRQs just like on XT machine. So if your 8088 program wanted to access word at offset 0xFFFF then it is either a bug or otherwise very specially crafted 808x only code and it would not run on a 286. So yes, if there were programs like this, they had to be modified a bit to run on both XT and AT.

Also, the de facto operating system was DOS, it was running in real mode just like on XT, which also meant real mode DOS programs were running on real mode just like on XT. Other OS and Windows and whatever did use 286 protected mode handled it by itself, so the OS and the drivers etc handled all this and normal programs never had to touch any hardware specific stuff.

Reply 10 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

Looking at the manual, page 3-15, table 9 doesn't mention the error codes. So the exceptions are more limited? Only IDT limit(INT 8 ), coprocessor segment limit(INT 9 ) and word reference at segment limit(INT 13/D ) are handled in real mode(no error code is pushed on the stack)? Does INT 13/D also apply with other segment limits than 0xFFFF? So if you enter unreal mode on a 386, will setting the limit not equal to 0xFFFF change the behaviour of the INT 8h/13d/Dh exception?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 11 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've modified the interrupt handling as follows:
- Real mode IVT accesses that break the IDT limit call exception 08h(IVT limit broken).
- Double fault exception in real mode is ignored, but counted towards triple fault.
- Real mode Double fault during IVT accesses are redirected to INT 08 when during an IDT limit fault.
- Double fault to triple fault during IVT in Real mode execute a triple fault(reset).
- Segment limit breaking causes an INT Dh in real mode, by a more limited version of protected mode limit checking(limit check with or without reversal depending on expand down/up only).
- Real mode interrupts don't push the error code(ignored if supplied).

Is this correct?

So the current path can be:
0D exception -> exception handler
Interrupt -> Exception handler
Interrupt(IDT limit fault) -> INT 08h ( -> Double fault INT 08h -> Triple fault)

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 12 of 14, by crazyc

User metadata
Rank Member
Rank
Member

Most faults probably behave the same in real mode as protected mode except they're vectored though the IVT rather than the IDT but I could be wrong. Since these are minimally documented edge cases you'd have to actually test them on a real machine to know for sure.

Reply 13 of 14, by superfury

User metadata
Rank l33t++
Rank
l33t++

But the double fault exception in real mode doesn't exist and becomes a triple fault? Is that correct?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 14 of 14, by crazyc

User metadata
Rank Member
Rank
Member

I see no reason to think that double faults don't exist in real mode, after all you'd have to jump though hoops to even get one. As I said though, there's no docs one way or another and I'm fairly sure no one has actually tested it so you if you really want to know, you'll have to try it.