Hi Bin, On 24 July 2015 at 01:25, Bin Meng <bmeng...@gmail.com> wrote: > Hi Simon, > > On Wed, Jul 22, 2015 at 11:49 PM, Simon Glass <s...@chromium.org> wrote: >> The procedure to drop from 64-bit mode to 32-bit is a bit messy. Add a >> function to take care of it. It requires identity-mapped pages and that >> the calling code is running below 4GB. >> >> Signed-off-by: Simon Glass <s...@chromium.org> >> --- >> >> arch/x86/cpu/Makefile | 6 +++++ >> arch/x86/cpu/call32.S | 65 >> ++++++++++++++++++++++++++++++++++++++++++++++ >> arch/x86/include/asm/cpu.h | 9 +++++++ >> 3 files changed, 80 insertions(+) >> create mode 100644 arch/x86/cpu/call32.S >> >> diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile >> index 9678976..eb993ec 100644 >> --- a/arch/x86/cpu/Makefile >> +++ b/arch/x86/cpu/Makefile >> @@ -12,6 +12,12 @@ extra-y = start.o >> obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o >> obj-y += interrupts.o cpu.o cpu_x86.o call64.o >> >> +AFLAGS_REMOVE_call32.o := -mregparm=3 \ >> + $(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32) >> +AFLAGS_call32.o := -fpic -fshort-wchar >> + >> +extra-y += call32.o >> + >> obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ >> obj-$(CONFIG_SYS_COREBOOT) += coreboot/ >> obj-$(CONFIG_ARCH_EFI) += efi/ >> diff --git a/arch/x86/cpu/call32.S b/arch/x86/cpu/call32.S >> new file mode 100644 >> index 0000000..3fe010e >> --- /dev/null >> +++ b/arch/x86/cpu/call32.S >> @@ -0,0 +1,65 @@ >> +/* >> + * (C) Copyright 2015 Google, Inc >> + * Written by Simon Glass <s...@chromium.org> >> + * >> + * SPDX-License-Identifier: GPL-2.0+ >> + */ >> + >> +#include <asm/global_data.h> >> +#include <asm/msr-index.h> >> +#include <asm/processor-flags.h> >> + >> + /* >> + * rdi - 32-bit code segment selector >> + * rsi - target address >> + * rdx - table address (0 if none) >> + */ >> +.code64 >> +.globl cpu_call32 >> +cpu_call32: >> + cli >> + >> + /* Save table pointer */ >> + mov %edx, %ebx >> + >> + /* >> + * Debugging option, this outputs characters to the console UART >> + * mov $0x3f8,%edx >> + * mov $'a',%al >> + * out %al,(%dx) >> + */ >> + >> + pushf >> + push %rdi /* 32-bit code segment */ >> + lea compat(%rip), %rax >> + push %rax >> + .byte 0x48 > > I think this is a REX prefix. Is there any compiler macro we can use? > We can put some comments here for better understanding. BTW: is this a > must? I believe retf will operate on 64-bit by operand in 64-bit by > default?
I'll add a comment. In fact this problem took me ages to figure out as the documentation seems unclear. But neither qemu nor real hardware seem to work without this prefix. > >> + retf >> +.code32 >> +compat: >> + /* >> + * We are now in compatibility mode with a default operand size of >> + * 32 bits. First disable paging. >> + */ >> + movl %cr0, %eax >> + andl $~X86_CR0_PG, %eax >> + movl %eax, %cr0 >> + >> + /* Invalidate TLB */ >> + xorl %eax, %eax >> + movl %eax, %cr3 >> + >> + /* Disable Long mode in EFER (Extended Feature Enable Register) */ >> + movl $MSR_EFER, %ecx >> + rdmsr >> + btr $_EFER_LME, %eax >> + wrmsr >> + >> + /* Set up table pointer for _x86boot_start */ >> + mov %ebx, %ecx >> + >> + /* Jump to the required target */ >> + pushl %edi /* 32-bit code segment */ >> + pushl %esi /* 32-bit target address */ >> + .byte 0x48 I'll drop this one though. >> + retf >> diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h >> index b96513d..e977045 100644 >> --- a/arch/x86/include/asm/cpu.h >> +++ b/arch/x86/include/asm/cpu.h >> @@ -222,6 +222,15 @@ char *cpu_get_name(char *name); >> void cpu_call64(ulong pgtable, ulong setup_base, ulong target); >> >> /** >> + * cpu_call32() - Jump to a 32-bit entry point >> + * >> + * @code_seg32: 32-bit code segment to use (GDT offset, e.g. 0x20) >> + * @target: Pointer to the start of the 32-bit U-Boot image/entry point >> + * @table: Pointer to start of info table to pass to U-Boot >> + */ >> +void cpu_call32(ulong code_seg32, ulong target, ulong table); >> + >> +/** >> * cpu_jump_to_64bit() - Jump to a 64-bit Linux kernel >> * >> * The kernel is uncompressed and the 64-bit entry point is expected to be >> -- > > Regards, > Bin Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot