unreal mode

Programming, for all ages and all languages.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: unreal mode

Post by bluemoon »

It's perfectly OK without a GPF handler, as long as you do not generate such fault.
However, when such fault triggered and you do not have a valid handler, the CPU generate double fault; if that is also invalid the CPU tripple fault and reset.
dileep
Posts: 13
Joined: Tue Feb 28, 2012 11:31 pm

Re: unreal mode

Post by dileep »

In some system i am able to access 32 bit offset and not in other systems.
So i have to use GPF handler to handle the fault by switching into the unreal mode.

Is there anyway to check whether the system is in unreal mode or not?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: unreal mode

Post by bluemoon »

dileep wrote:In some system i am able to access 32 bit offset and not in other systems.
So i have to use GPF handler to handle the fault by switching into the unreal mode.
Why do you access to some offset you don't know what's there?
If you're working on pre-boot environment, use the memory map, or firmware function, etc...to allocate runtime memory.
Especially for mmio you need to know what is (or is not) there.

dileep wrote:Is there anyway to check whether the system is in unreal mode or not?
No official way. In fact unreal mode is not official thought every 386+ supported it.
dileep
Posts: 13
Joined: Tue Feb 28, 2012 11:31 pm

Re: unreal mode

Post by dileep »

bluemoon wrote: Why do you access to some offset you don't know what's there?
I trying to access known offset from PCI BAR2 address. some machines are left in unreal mode , so i can access this 32 bit offset without changing the mode. Some other machines (Dell R710, etc) are in Real mode, so i have to change to unreal mode.
So i am trying to fix this issue for my driver to work in all servers.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: unreal mode

Post by bluemoon »

I recommend to have your code run inside a barebone protected mode environment. So, instead of:

Code: Select all

// unreal mode
pushf
cli
switch_to_pmode();
set_flat_selectors();
switch_to_rmode();
access_to_BAR();
more_work();
popf
You should do:

Code: Select all

pushf
cli
switch_to_pmode();
set_flat_selectors();
access_to_BAR();
switch_to_rmode();
more_work();
popf
This way you do not need to assume a unreal mode environment, just require a real mode environment for caller.
dileep
Posts: 13
Joined: Tue Feb 28, 2012 11:31 pm

Re: unreal mode

Post by dileep »

this doesn't make sense to me .
What is in the case of systems which are left in unreal mode by the bios.?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: unreal mode

Post by Solar »

Is there even such a thing?
bluemoon wrote:
dileep wrote:
dileep wrote:Is there anyway to check whether the system is in unreal mode or not?
No official way. In fact unreal mode is not official thought every 386+ supported it.
Every good solution is obvious once you've found it.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: unreal mode

Post by turdus »

bluemoon wrote:
dileep wrote:Is there anyway to check whether the system is in unreal mode or not?
No official way. In fact unreal mode is not official thought every 386+ supported it.
As a matter of fact, there are more ways. Here's two:
1. examine data segment in gdt (use sgdt to get base address)
2. set ds to an unused 64k+1 memory. Put a non-zero byte at offset [ds:0], and a zero at [ds+4096:0]. Read from offset [ds:65536]. If you got non-zero byte, you are in real mode, if not, you are in unreal.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: unreal mode

Post by Combuster »

Read from offset [ds:65536]. If you got non-zero byte, you are in real mode, if not, you are in unreal.
Nonsense. It means continue if ds.limit >= 65536 and lock up otherwise (caused by an infinite #GPF/IRET loop).
examine data segment in gdt
Which might be changed or otherwise overwritten since, making it another bad idea.

The only way to check is to install a #GP handler in real mode and testing 4G-1 addresses for each desired selector. if the handler is called, the segment register has a smaller register size. Note that unreal simply means changing the limit to something over 64K for at least one segment register. Typical setups might only set ES, DS+ES, or one of FS/GS. Some typical beginner errors set the limit to 1M instead of 4G.

Which brings us to the bottom line: don't test for unreal mode, just set it if needed.

As far as unreal mode being unofficial - it's essentially nothing but a name coined by its inventor for a programmer construction using a now documented feature:
AMD64 manual wrote:On FAR transfers, CS (code segment) selector is updated to the new value, and the CS segment base is
set to selector * 16. The CS segment limit and attributes are unchanged, but are usually 64K and
read/write, respectively.
Last edited by Combuster on Wed Apr 04, 2012 12:12 pm, edited 2 times in total.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: unreal mode

Post by bluemoon »

examine data segment in gdt (use sgdt to get base address)
Using sgdt in real mode probably give you random byte or zero on fresh boot,
or leftover from previous unreal mode switch, which the memory pointed by it probably got trashed.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: unreal mode

Post by turdus »

@bluemoon: that's the point. If it's valid, you're in unreal mode. You're right the shadow registers may contain different value, so you can tell only being in unreal for sure, if it fails, it does mean anything.

@Combuster: if GPF happens, it's even easier to detect:

Code: Select all

gpfhandler:
inc ah
iret

xor ax, ax
mov ds, ax
mov word [13*4], gpfhandler
mov word [13*4+2], cs
mov ebx, 10000h
mov al, byte [ebx]
or ah, ah
jnz .realmode
;unreal mode
Now this is a 100% accurate method.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: unreal mode

Post by Combuster »

turdus wrote:Now this is a 100% accurate method.
Again wrong because:
Combuster wrote:It means continue if ds.limit >= 65536 and lock up otherwise (caused by an infinite #GPF/IRET loop).
You definitely did not fix that.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: unreal mode

Post by bluemoon »

turdus wrote:@bluemoon: that's the point. If it's valid, you're in unreal mode. You're right the shadow registers may contain different value, so you can tell only being in unreal for sure, if it fails, it does mean anything.
Case study One.
A firmware switched to protected, loaded GDT at slightly higher than 1MiB, finished it job and return to real mode. SGDT will give you a pointer to ~1MiB. In the Unreal Detection function it cannot access that location without itself switched to unreal mode. Detection Failed.

Case study Two.
A firmware switched to protected, loaded GDT at any location, finished it job and return to real mode. SGDT will give you a pointer to some high address. In the Unreal Detection function it cannot tell if that address is just garbage. Detection Failed.

Case study Three.
The system previously goes into unreal mode, SGDT give you a proper pointer, you walk into the descriptor structure and they look valid. The function report unreal mode environment is found. However, the segment registers has already been reloaded by interrupt services. False detection.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: unreal mode

Post by turdus »

@bluemoon: why are you struggling after I stated my 1st solution is not good, and moved on with 2nd?
Combuster wrote:You definitely did not fix that.
You are so narrow-minded. That's the homework part for you. Hint: place "dec ebx" where appropriate. I was programming in head in ancient assembly dialect, no wonder it's not 100%. Not the small details, but the big picture what's important.

The point is, IT IS POSSIBLE to detect unreal mode. Period.

(Before you began to jiggle on post only good code, that's me. I can solve very complex equation systems with several variables mostly in head, and at the end reckon x=5*5=10 without hesitation (that actually happened with me once). I'm afraid you have to deal with it. I'm too old to change.)
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: unreal mode

Post by bluemoon »

turdus wrote:@bluemoon: why are you struggling after I stated my 1st solution is not good, and moved on with 2nd?
Sorry but I did not see you abandon the 1st solution. I was about to say objection to the claim "so you can tell only being in unreal for sure" by putting up a false detection scenario.
The point is, IT IS POSSIBLE to detect unreal mode. Period.
Seems plausible but not practical. In fact that is the official way to detect CPU fault. However, I consider unreal mode itself, and the way to detect it, is still unofficial.
Intel Manual wrote: In section 9.9.2 Switching Back to Real-Address Mode
A procedure that re- enters real-address mode should perform the following steps:
3. Transfer program control to a readable segment that has a limit of 64 KBytes (FFFFH)
4. Load segment registers SS, DS, ES, FS, and GS with a selector for a descriptor containing the following values, which are appropriate for real-address mode:
— Limit = 64 KBytes (0FFFFH)
Unreal mode is activated by not following the manual(at least for IA processors), thus unofficial.


By the way the counter method has overflow bug in some situation but it can be changed to alter the return address to skip the fault instruction. But instead of doing all the troubles, I prefer:
Combuster wrote:Which brings us to the bottom line: don't test for unreal mode, just set it if needed.
Post Reply