[haiku-development] Re: Virtual 8086 mode support

Am Samstag, 19. April 2008 schrieb Axel Dörfler:
> > Nice! I wonder, why this is a syscall, though. If the intended use is
> > for the
> > VESA driver, it won't really help. Or do I miss something?

Even though it may sound strange it was (for the first step) the easiest way 
to implement it.

> The VESA driver also has an accelerant. I dunno if one need this
> functionality in userland, but you'd need a syscall anyway to offload
> that functionality to the driver (just an ioctl(), of course).
> Since you want to access low memory (and would need a dedicated kernel
> thread to do so in the kernel, otherwise it's mapped by some app), it
> might even only be possible to do that in userland ATM.

That's pretty much the explanation for why I did it as syscall. First of all I 
see no way on how to do it from a kernel thread. The kernel teams address 
space starts from 0x80000000 but in vm86 mode the thread will run in the 1st 
Mb of the address space. So it must be done in the context of a user mode 
thread unless I overlooked something.

I also thought about to provide a kernel vm86() function but did not do it in 
the first step. I did not came up with a clean solution yet.

Currently I manipulate the iframe from the vm86() syscall to go to vm86 mode 
when the syscall trap handler is left. As soon as a signal is delivered or a 
#GP exception happens I restore the vm86() syscall iframe and the application 
will "return" from the vm86() syscall.

Using vm86 mode directly from the kernel space is a little bit more 
complicated. Basically the driver needs also a vm86() function to 
say "execute this piece in vm86 mode". But in the end the kernel vm86() 
function has to do a "iret" because it's the only way on the x86 to switch to 
vm86 mode. But this leaves the ioctl() syscall iframe on the ring 0 stack -> 
therefore we would have to switch to an alternate ring 0 stack or the task 
would overwrite the old ioctl() iframe when it returns from vm86 mode. Not 
very nice...

BTW, Linux does sth. like that and it took me two or three day to understand 
it... :-/

On the other hand the current user mode solution also has a drawback. When the 
BIOS tries to execute a IN/OUT instruction the CPU will assert a #GP 
exception (because it's a privileged insn) and the user mode part has to 
examine what happened (IN/OUT executed). Then the user mode task will have to 
do the IN/OUT itself and resume execution of the BIOS. But the user mode 
thread is also not allowed to do it. So eighther the kernel mode driver 
provides a ioctl() to do IN/OUT's or we provide a new facility to give a 
thread the rights to execute IN/OUT instructions itself, that is to raise 
it's IOPL to 3.

/Jan

Other related posts: