On 04/07/21 02:44, James Bottomley wrote: > On Wed, 2021-04-07 at 00:21 +0000, Xu, Min M wrote: >> Hi, Laszlo >> >> For Intel TDX supported guest, all processors start in 32-bit >> protected >> mode, while for Non-Td guest, it starts in 16-bit real mode. To make >> the >> ResetVector work on both Td-guest and Non-Td guest, ResetVector are >> updated as below: >> ------------------------------------------------------------------ >> ALIGN 16 >> resetVector: >> ; >> ; Reset Vector >> ; >> ; This is where the processor will begin execution >> ; >> nop >> nop >> smsw ax >> test al, 1 >> jnz EarlyBspPmEntry >> jmp EarlyBspInitReal16 > > Well, then use the rel8 jump like the compiler would in this situation: > > smsw ax > test al, 1 > jz 1f > jmp EarlyBspPmEntry > 1: > jmp EarlyBspInitReal16 > > So now both entries can be 32k away.
The problem is that we need NASM to generate such *shared* entry code that behaves correctly when executed in either 16-bit or 32-bit mode. The rel8 near jumps ("short jumps") are like that -- for example, the "74 cb" opcode decodes to the same "JZ rel8" in both modes. But the rel16 ("non-short") near jumps turn into rel32 near jumps when decoded in 32-bit mode. For example, "E9 cw" decodes to "JMP rel16" in 16-bit mode, but it gets parsed as "E9 cd" (= "JMP rel32") in 32-bit mode. So the idea is to add more BITS directives, for covering the non-short near jumps themselves: > ; instructions up to and including the rel8 JZ decode identically > ; between BITS 16 and BITS 32 > BITS 16 > smsw ax > test al, 1 > jz Real > > ; the unconditional near jumps are mode-specific > BITS 32 > jmp near EarlyBspPmEntry > BITS 16 > Real: > jmp near EarlyBspInitReal16 > > ; -------------------- > > BITS 16 > EarlyBspInitReal16: > nop > > BITS 32 > EarlyBspPmEntry: > nop $ nasm -f bin jz.nasmb Decoded (executed) in 16-bit mode: $ ndisasm -b 16 -k 7,5 -k 0x10,1 jz 00000000 0F01E0 smsw ax 00000003 A801 test al,0x1 00000005 7405 jz 0xc ; taken 00000007 skipping 0x5 bytes 0000000C E90000 jmp word 0xf 0000000F 90 nop 00000010 skipping 0x1 bytes Decoded (executed) in 32-bit mode: $ ndisasm -b 32 -k 0xc,4 jz 00000000 0F01E0 smsw eax 00000003 A801 test al,0x1 00000005 7405 jz 0xc ; not taken 00000007 E904000000 jmp dword 0x10 0000000C skipping 0x4 bytes 00000010 90 nop With the garbage *not* hidden: $ ndisasm -b 16 -s 0xc jz 00000000 0F01E0 smsw ax 00000003 A801 test al,0x1 00000005 7405 jz 0xc ; taken 00000007 E90400 jmp word 0xe ; garbage 0000000A 0000 add [bx+si],al ; garbage 0000000C E90000 jmp word 0xf 0000000F 90 nop 00000010 90 nop ; garbage $ ndisasm -b 32 -s 0x10 jz 00000000 0F01E0 smsw eax 00000003 A801 test al,0x1 00000005 7405 jz 0xc ; not taken 00000007 E904000000 jmp dword 0x10 0000000C E9 db 0xe9 ; garbage 0000000D 0000 add [eax],al ; garbage 0000000F 90 nop ; garbage 00000010 90 nop Thanks Laszlo -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#73785): https://edk2.groups.io/g/devel/message/73785 Mute This Topic: https://groups.io/mt/81584577/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-