VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

When I look at the faults a 80386 can throw when switching tasks, is the fault that's raised for each of them a normal fault(#GP/#SS/#NP etc.) or #TSS(desc)?

In other words, are the faults thrown when loading segmebts and checking the descriptors(mentioned in the task switching part of the 80386 documentation) normal faults, or are they all #TS faults with the error code pointing to the loaded segment(CS,SS,DS,ES,FS,GS)?

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

Reply 1 of 4, by crazyc

User metadata
Rank Member
Rank
Member

The fault type raised for each check is noted in the manual. BTW, the 80386 manual has an incorrect order and fault types for TSS checks that will cause some programs to break. The IA32 manual is correct.

Reply 2 of 4, by superfury

User metadata
Rank l33t++
Rank
l33t++

So, looking at https://www.cs.umd.edu/~hollings/cs412/s02/proj1/ia32ch7.pdf , it looks like instead of generating #GP/#SS faults it instead throws #TS faults(#GP/#SS fault being conditions where it's loaded during normal program execution, e.g. MOV and JMP). So I just modify the #GP and #SS faults to throw #TS faults instead when task switching loads the segment(except TR register loads)?

So within getsegment_seg, replace all THROWDESCGP with it's #TS variant(using another bonus bit(bit 17) in isJMPorCALL to differentiate between normal loads and task switching(of course not using the gate descriptor handling for those)?

Current protection base code(minus task switching specifics, containing segment loads(segmentWritten calling getsegment_seg): https://bitbucket.org/superfury/unipcemu/src/ … ion.c?at=master

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

Reply 3 of 4, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've changed the TSS-bases task switching to throw #TS instead of #GP, as well as disable usage of gate descriptors(now counting them as invalid when loaded through a TSS). Also fixed a slight security(non-existant mask on the table field in the error code) error in the #TS fault raising.
I've also combined the two variants of #GP/#TS faults during segment loading into two by simple goto statements(for easier debugging and patching). Now there's one for the original(loaded) selector and one for the gated one(the value the gate points to). Or is it supposed to be the original one(the value passed to getsegment_seg, originalval in the code) in all cases?

https://bitbucket.org/superfury/unipcemu/src/ … ion.c?at=master

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

Reply 4 of 4, by superfury

User metadata
Rank l33t++
Rank
l33t++

Some odd thing is in the Intel documentation: #NP is checked last for all checks? If you'd do that, you'll end up faulting using #GP/#TS on non-present descriptor bits that might not even be there? So let's say you have a non-present descriptor (P-bit being zeroed) containing a data segment, which is loaded into a task's CS selector. Thus you'll end up with a #TS(CS) instead of the expected #NP(CS)? Or is that documentation incorrect?

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