unreal mode
Re: unreal mode
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.
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.
Re: unreal mode
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?
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?
Re: unreal mode
Why do you access to some offset you don't know what's there?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.
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.
No official way. In fact unreal mode is not official thought every 386+ supported it.dileep wrote:Is there anyway to check whether the system is in unreal mode or not?
Re: unreal mode
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.bluemoon wrote: Why do you access to some offset you don't know what's there?
So i am trying to fix this issue for my driver to work in all servers.
Re: unreal mode
I recommend to have your code run inside a barebone protected mode environment. So, instead of:
You should do:
This way you do not need to assume a unreal mode environment, just require a real mode environment for caller.
Code: Select all
// unreal mode
pushf
cli
switch_to_pmode();
set_flat_selectors();
switch_to_rmode();
access_to_BAR();
more_work();
popf
Code: Select all
pushf
cli
switch_to_pmode();
set_flat_selectors();
access_to_BAR();
switch_to_rmode();
more_work();
popf
Re: unreal mode
this doesn't make sense to me .
What is in the case of systems which are left in unreal mode by the bios.?
What is in the case of systems which are left in unreal mode by the bios.?
Re: unreal mode
Is there even such a thing?
bluemoon wrote:dileep wrote:No official way. In fact unreal mode is not official thought every 386+ supported it.dileep wrote:Is there anyway to check whether the system is in unreal mode or not?
Every good solution is obvious once you've found it.
Re: unreal mode
As a matter of fact, there are more ways. Here's two:bluemoon wrote:No official way. In fact unreal mode is not official thought every 386+ supported it.dileep wrote:Is there anyway to check whether the system is in unreal mode or not?
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.
- Combuster
- 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
Nonsense. It means continue if ds.limit >= 65536 and lock up otherwise (caused by an infinite #GPF/IRET loop).Read from offset [ds:65536]. If you got non-zero byte, you are in real mode, if not, you are in unreal.
Which might be changed or otherwise overwritten since, making it another bad idea.examine data segment in gdt
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.
Re: unreal mode
Using sgdt in real mode probably give you random byte or zero on fresh boot,examine data segment in gdt (use sgdt to get base address)
or leftover from previous unreal mode switch, which the memory pointed by it probably got trashed.
Re: unreal mode
@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:
Now this is a 100% accurate method.
@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
- Combuster
- 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
Again wrong because:turdus wrote:Now this is a 100% accurate method.
You definitely did not fix that.Combuster wrote:It means continue if ds.limit >= 65536 and lock up otherwise (caused by an infinite #GPF/IRET loop).
Re: unreal mode
Case study One.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.
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.
Re: unreal mode
@bluemoon: why are you struggling after I stated my 1st solution is not good, and moved on with 2nd?
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.)
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.Combuster wrote:You definitely did not fix that.
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.)
Re: unreal mode
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.turdus wrote:@bluemoon: why are you struggling after I stated my 1st solution is not good, and moved on with 2nd?
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.The point is, IT IS POSSIBLE to detect unreal mode. Period.
Unreal mode is activated by not following the manual(at least for IA processors), thus 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)
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.