Page 4 of 7
Re: Adding 64-bit support to RDOS
Posted: Tue Oct 30, 2012 11:09 am
by Jezze
Perhaps just a simple bug? =)
Re: Adding 64-bit support to RDOS
Posted: Tue Oct 30, 2012 12:10 pm
by rdos
I used the wrong button earlier in the thread (edit instead of quote), but here is the relevant part about support for 32-bit far calls:
I can now confirm that dual-core Intel Atom and AMD Athlon x6 also supports 32-bit far calls from 64-bit mode to 32-bit compability-mode, and that a 32-bit far return will get back to the correct position with the stack in the correct state. I'll probably code the syscalls directly by referring to the actual gate-entry which is stored in kernel. Then 64-bit code needs no patching of syscalls at all.
Re: Adding 64-bit support to RDOS
Posted: Tue Oct 30, 2012 10:22 pm
by Owen
rdos wrote:Owen wrote:Gigasoft wrote:That's because it's the wrong instruction. Remove the 0x48.
0xFF /3 encodes a 32-bit far call.There is no 64-bit far call.
That might have been the reason why AMD generates a GPF with REX.W. I just don't get why nasm adds REX.W when this is not supported!
Intel supports it. This is a really dangerous corner case are of the architecture: For JMP FAR, Intel supports 16/32/64-bit indirect. AMD supports 16/32/32-bit indirect (i.e. the REX.W encoding generates a 32-bit far jump, confusingly)
This may be the case for CALL FAR also (I'm not sure on this)
To force a 32-bit call far, do "call far dword [ptr]". Confusingly, this encodes to a mem16:32 operand. (I can't help but feel that this should be "tword" or similar ["tripleword"])
Owen wrote:Also, how is the 32-bit code returning to 64-bit mode? Obviously you can't just do a simple retf, since the 32-bit code can't do a 64-bit far return.
Seems like the 32-bit far call generates the correct stack frame for the 32-bit retf, which it actually should if the function would be meaningful.[/quote]
I was referring to the case of the 64-bit far call
Re: Adding 64-bit support to RDOS
Posted: Wed Oct 31, 2012 3:37 am
by rdos
Owen wrote:
Intel supports it. This is a really dangerous corner case are of the architecture: For JMP FAR, Intel supports 16/32/64-bit indirect. AMD supports 16/32/32-bit indirect (i.e. the REX.W encoding generates a 32-bit far jump, confusingly)
This may be the case for CALL FAR also (I'm not sure on this)
To force a 32-bit call far, do "call far dword [ptr]". Confusingly, this encodes to a mem16:32 operand. (I can't help but feel that this should be "tword" or similar ["tripleword"])
I've done some further tests on this now. It seems like on AMD, the REX.W prefix generates a 64-bit call-frame, but uses a mem16:32 operand. This seems consistent with the behavior you've found for jmp.
Re: Adding 64-bit support to RDOS
Posted: Wed Oct 31, 2012 3:50 am
by rdos
Owen wrote:rdos wrote:It seems like it's impossible to use multiple orgs, so that doesn't work.
ORG is considered a "convinience feature"; it wraps the builtin section support.
Given that I presume you're using WASM for your other code, I'm surprised you didn't move to JWASM for 64-bit support, since it's a fork enhanced with 64-bit support (among other features)
Watch out for the fact that the AMD64 calling convention is different (Whether you use the simpler Microsoft or better AMD/SystemV ABI)
Actually, I decided yesterday that I can't use NASM for this project, mainly because it cannot handle MASM/WASM-compatible structures, which would become a major pain if I continue with NASM. Thus, I just finished porting the code to JWASM, which has some bugs on it's own, but I managed to solve them with a few fixes. For instance, org doesn't work as expected, and mixing 32-bit and 64-bit code also doesn't work as expected. But at least it can handle my macros and structures correctly.
Re: Adding 64-bit support to RDOS
Posted: Wed Oct 31, 2012 7:40 am
by Antti
rdos wrote:I can't use NASM for this project, mainly because it cannot handle MASM/WASM-compatible structures
I do not know the details but would it be possible to convert your old structures to the format NASM can handle? Perhaps you can make a program that does the conversion? I assume that the structure format is not very complicated.
Re: Adding 64-bit support to RDOS
Posted: Wed Oct 31, 2012 8:15 am
by rdos
Antti wrote:rdos wrote:I can't use NASM for this project, mainly because it cannot handle MASM/WASM-compatible structures
I do not know the details but would it be possible to convert your old structures to the format NASM can handle? Perhaps you can make a program that does the conversion? I assume that the structure format is not very complicated.
The problem is that WASM cannot handle the structures NASM supports, and NASM cannot handle the structures WASM supports, so there is no common ground. That means I'd have to parse all the header-files and produce both WASM and NASM compatible versions, which is a major problem. Additionally, NASM cannot handle constants defined with assignment operator, which also is a problem, but less so because both NASM and WASM supports equ. I also cannot easily move the old source to NASM because of the OFFSET incompability-issue.
Re: Adding 64-bit support to RDOS
Posted: Wed Oct 31, 2012 9:09 am
by rdos
Actually, call fword [some_address] fails when some_address is above 2G, since the address is signed-extended to 64-bits.
Another way to do it is like this:
Code: Select all
push r15
mov r15,osgate_linear + gate_nr SHL 4
call fword ptr [r15]
pop r15
Using R15 in the gate is no problem since 32-bit mode doesn't have access to R15.
Here, call fword ptr [r15] is assembled as: 0x41 0xFF 0x1F.
This works even when osgate_linear is 0xFEFC0000 (no sign extension).
Re: Adding 64-bit support to RDOS
Posted: Wed Oct 31, 2012 9:45 am
by rdos
Another strange issue is how the (AMD) processor interprets 0xCF (iret) in long mode. It seems like this is interpreted as a 32-bit iret (using an 32-bit frame). In order to use a 64-bit frame, I need to add REX.W to form 0x48 0xCF. I wonder what the (standard) MASM notation for this might be??
Status now is that I can issue 32-bit syscalls which switch to compability mode from long mode (tested with GetSelectorBaseSize which returns properties of a selector, which is kind of hard to replicate in long mode). I've also managed to patch the first byte of the syscall instruction from compability-mode in GPF handler, and have restarted the instruction. Next I need to define the interrupt handlers for doing the actual patching operation.
Re: Adding 64-bit support to RDOS
Posted: Wed Oct 31, 2012 9:55 am
by bluemoon
tried IRETQ?
NASM also default IRET to emit IRETD in long mode, and you need to explicitly code IRETQ in 64-bit handlers.
Re: Adding 64-bit support to RDOS
Posted: Wed Oct 31, 2012 10:00 am
by rdos
bluemoon wrote:tried IRETQ?
NASM also default IRET to emit IRETD in long mode, and you need to explicitly code IRETQ in 64-bit handlers.
Yes, that seems to be the name of the instruction. Should have guessed that based on iretd.
Re: Adding 64-bit support to RDOS
Posted: Fri Nov 02, 2012 3:36 am
by rdos
I'm approaching the state where I soon can let the scheduler run 64-bit processes in long mode (in kernel space). I've converted the automatically generated interrupt stubs (including linking several handlers per IRQ) to long mode. It's less safe than the segmented versions, but it works. The 64-bit interrupt stubs consume a lot more space, but then most machines with long mode support have lots of RAM so it is not a problem. After I've linked these new stubs to the APIC/PIC interrupt registration code, I should be able to run tests in long mode with interrupts enabled.
Re: Adding 64-bit support to RDOS
Posted: Wed Nov 07, 2012 8:37 am
by rdos
I've encountered a new problem with mixing 32-bit and 64-bit code. It seems like when 32-bit code uses the general registers, even with saving and restoring them on the stack, the high 32-bits in the 64-bit register will be cleared. The real bad thing is that 32-bit code cannot do anything about this problem since it cannot push 64-bit registers. That's countrary to how this works when using the low 16-bits or 8-bits of the general registers, which will not clear the higher-order bits. This does create additional problems in the scheduler and crash-debugger, which both must be invoked in 64-bit mode first, and saving the general state in 64-bit mode before passing on to 32-bit code, as even the most trivial code needs to modify some general registers.
I really wonder why AMD does such a stupid thing.
In the syscall interface from 64-bit applications, it basically means that the higher order 32-bits of the general registers must be saved and restored in the syscall interface since the interface has no idea which higher order 32-bits are cleared by the service routine.
Re: Adding 64-bit support to RDOS
Posted: Wed Nov 07, 2012 8:42 am
by bluemoon
rdos wrote:I really wonder why AMD does such a stupid thing.
To avoid dependency stall when they reuse the 64-bit circuit to handle 32-bit arithmetic?
Re: Adding 64-bit support to RDOS
Posted: Wed Nov 07, 2012 8:56 am
by rdos
bluemoon wrote:rdos wrote:I really wonder why AMD does such a stupid thing.
To avoid dependency stall when they reuse the 64-bit circuit to handle 32-bit arithmetic?
Possible, but this happens in compability-mode, which never can do 64-bit arithmetics anyway. I wouldn't complain if it happened in long mode, since register saves in long mode always save 64-bit, so it is not an issue there.
And it really isn't an issue of the artithmetics itself. They could very well do 64-bit arithmetics. The problem is that they save the results in the wrong way, clearing high-order bits. It would be easy to save the results in the lower bits only, just like it is done with 16-bit operations.