x64 16-bit CM

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
kerravon
Member
Member
Posts: 289
Joined: Fri Nov 17, 2006 5:26 am

x64 16-bit CM

Post by kerravon »

Hi.

I have code here:

https://sourceforge.net/p/pdos/gitcode/ ... ric/bios.c

/* I am guessing that this sets 0xffff as the maximum offset */
gdt[cm16_ss / sizeof (*gdt)].limit[0] = 0xff;
gdt[cm16_ss / sizeof (*gdt)].limit[1] = 0xff;
/* I am hoping this sets it to 16-bit stack */
/* I need ERW set and also S and also P */
gdt[cm16_ss / sizeof (*gdt)].access_byte = 0x96;
gdt[cm16_ss / sizeof (*gdt)].limit_flags = 0;


and here:

https://sourceforge.net/p/pdos/gitcode/ ... imcm32.asm

# This requires the test16 to be in the same 64k
# segment. We need another routine after the test16
# and use that instead, if this one is not suitable

# Note that this creates a gap of 4 bytes on the stack
# that will need to be compensated for by test16
# Note that this is to keep the stack 8-byte aligned
# which I think is a requirement

.global call_cm16
call_cm16:
push rbp
push r9
mov ax, ss
mov r9, ax
mov rbp, rsp
mov ax, dx
mov ss, ax
mov rsp, 0xfff0
sub rsp, 8
mov rax, cs
mov [rsp+6], ax
lea rax, call_cm16_end[rip]
mov [rsp+4], ax
push rcx
push r8
retfq
call_cm16_end:
mov rax, r9
mov ss, ax
mov rsp, rbp
pop r9
pop rbp
ret



Currently it is hanging when trying to go into/out of the 16-bit code.

Can someone confirm I need a 16-bit stack to be able to return from 16-bit CM to long mode?

Can anyone spot something wrong with what I am doing?

Thanks. Paul.
Octocontrabass
Member
Member
Posts: 5754
Joined: Mon Mar 25, 2013 7:01 pm

Re: x64 16-bit CM

Post by Octocontrabass »

kerravon wrote: Tue Apr 15, 2025 12:00 amgdt[cm16_ss / sizeof (*gdt)].access_byte = 0x96;
Stack segments are ordinary data segments. If you're not using the "expand down" function for this data segment, you should set this byte to 0x93 as you would for any other ring 0 data segment (or 0x92 if you need to see when the CPU sets the "accessed" bit).
kerravon wrote: Tue Apr 15, 2025 12:00 am mov ss, ax
mov rsp, 0xfff0
The SS descriptor is ignored while the CPU is in 64-bit mode. You're clobbering memory.
kerravon wrote: Tue Apr 15, 2025 12:00 am lea rax, call_cm16_end[rip]
mov [rsp+4], ax
You're truncating the call_cm16_end address to 16 bits. Even if you weren't clobbering memory, this might cause problems.
kerravon wrote: Tue Apr 15, 2025 12:00 amCan someone confirm I need a 16-bit stack to be able to return from 16-bit CM to long mode?
Only if the instruction you're using in 16-bit mode to return to 64-bit mode requires a stack. JMP doesn't require a stack. RETF does require a stack. INT may or may not require a stack depending on how you've configured your IDT.
kerravon
Member
Member
Posts: 289
Joined: Fri Nov 17, 2006 5:26 am

Re: x64 16-bit CM

Post by kerravon »

Thanks for that info. I have committed a fix provided from my contact in Slovakia.

Edit: fix isn't working for me though.

Edit: now working with both cc64 and Visual C
rdos
Member
Member
Posts: 3351
Joined: Wed Oct 01, 2008 1:55 pm

Re: x64 16-bit CM

Post by rdos »

Octocontrabass wrote: Tue Apr 15, 2025 11:13 am
kerravon wrote: Tue Apr 15, 2025 12:00 am mov ss, ax
mov rsp, 0xfff0
The SS descriptor is ignored while the CPU is in 64-bit mode. You're clobbering memory.
SS descriptor can be loaded in long mode, but the attributes are ignored until the processor gets into CM. So, yes, this is indeed faulty code.
Post Reply