VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

How is RPL in the TR and LDTR register handled?
What happens when they're non-zero? Or non-zero in the Task Gate? What is loaded into the TR register's visible side (RPL and table bits, ie the lower 3 bits)?

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

Reply 1 of 3, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

LLDT and LTR are privileged instructions - you need to be in CPL 0 to execute them. So they don't do any privilege checks on the selectors or descriptors that they load. Similarly, no privilege level tests are performed on the TR load or LDTR load that happen during a task switch - the privilege check is just on the task gate itself. There are some other tests that are performed (Is it a non-null selector? Does it point into the GDT?) just not privilege level. I'm not sure if the TI and RPL bits of TR and LDTR physically exist on the chip (they might just have been omitted since they aren't used) but if the RPL bits do exist the microcode just passes them along unchanged.

Reply 2 of 3, by superfury

User metadata
Rank l33t++
Rank
l33t++

Ok. So basically just when a TSS is loaded into CS it has it's privilege level checked (either on the gate descriptor or not gated). And a LDT doesn't ever check for privilege?

Also, what happens when a task switch is executed while TR is in the reset state (Access Rights byte 82h, although my emulator loads 0x8B on 386+ and 0x83 on the 80286)? Does it just blindly store the old task state at linear address 0 where TR is pointing to?
Since AR 82h means 'present LDT' that'd be invalid for task switches, but does the CPU check for that condition on the outgoing task?

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

Reply 3 of 3, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

CS is never loaded with a TSS segment (TSS holds register values, CS holds code). Correct, loading LDTR doesn't check for privilege.

You can only do a jump or call into a TSS (a task switch) if it's available (AR byte 0x81 for 286 or 0x89 for 386). You can't switch to a busy (0x83/0x8b) TSS or an LDT (0x82). You also can't load TR with a busy TSS (you get a #GP if you try).