From: Simon Glass Date: Mon, 16 Jan 2017 14:04:19 +0000 (-0700) Subject: x86: Move call64 to the i386 directory X-Git-Tag: v2017.03-rc2~61 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=8cfc966c777ae0effaeea40a96d62034b2f86b91;p=oweals%2Fu-boot.git x86: Move call64 to the i386 directory This code is only used in 32-bit mode. Move it so that it does not get built with 64-bit U-Boot. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 6889df34c4..2fda32d29f 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -15,7 +15,7 @@ extra-y = start.o endif extra-$(CONFIG_$(SPL_)X86_16BIT_INIT) += resetvec.o start16.o ifndef CONFIG_$(SPL_)X86_64 -obj-y += call64.o setjmp.o +obj-y += setjmp.o endif obj-y += cpu.o cpu_x86.o diff --git a/arch/x86/cpu/call64.S b/arch/x86/cpu/call64.S deleted file mode 100644 index 970c461508..0000000000 --- a/arch/x86/cpu/call64.S +++ /dev/null @@ -1,96 +0,0 @@ -/* - * (C) Copyright 2014 Google, Inc - * Copyright (C) 1991, 1992, 1993 Linus Torvalds - * - * Parts of this copied from Linux arch/x86/boot/compressed/head_64.S - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include - -.code32 -.globl cpu_call64 -cpu_call64: - /* - * cpu_call64(ulong pgtable, ulong setup_base, ulong target) - * - * eax - pgtable - * edx - setup_base - * ecx - target - */ - cli - push %ecx /* arg2 = target */ - push %edx /* arg1 = setup_base */ - mov %eax, %ebx - - /* Load new GDT with the 64bit segments using 32bit descriptor */ - leal gdt, %eax - movl %eax, gdt+2 - lgdt gdt - - /* Enable PAE mode */ - movl $(X86_CR4_PAE), %eax - movl %eax, %cr4 - - /* Enable the boot page tables */ - leal (%ebx), %eax - movl %eax, %cr3 - - /* Enable Long mode in EFER (Extended Feature Enable Register) */ - movl $MSR_EFER, %ecx - rdmsr - btsl $_EFER_LME, %eax - wrmsr - - /* After gdt is loaded */ - xorl %eax, %eax - lldt %ax - movl $0x20, %eax - ltr %ax - - /* - * Setup for the jump to 64bit mode - * - * When the jump is performed we will be in long mode but - * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1 - * (and in turn EFER.LMA = 1). To jump into 64bit mode we use - * the new gdt/idt that has __KERNEL_CS with CS.L = 1. - * We place all of the values on our mini stack so lret can - * used to perform that far jump. See the gdt below. - */ - pop %esi /* setup_base */ - - pushl $0x10 - leal lret_target, %eax - pushl %eax - - /* Enter paged protected Mode, activating Long Mode */ - movl $(X86_CR0_PG | X86_CR0_PE), %eax - movl %eax, %cr0 - - /* Jump from 32bit compatibility mode into 64bit mode. */ - lret - -code64: -lret_target: - pop %eax /* target */ - mov %eax, %eax /* Clear bits 63:32 */ - jmp *%eax /* Jump to the 64-bit target */ - - .data - .align 16 - .globl gdt64 -gdt64: -gdt: - .word gdt_end - gdt - 1 - .long gdt /* Fixed up by code above */ - .word 0 - .quad 0x0000000000000000 /* NULL descriptor */ - .quad 0x00af9a000000ffff /* __KERNEL_CS */ - .quad 0x00cf92000000ffff /* __KERNEL_DS */ - .quad 0x0080890000000000 /* TS descriptor */ - .quad 0x0000000000000000 /* TS continued */ -gdt_end: diff --git a/arch/x86/cpu/i386/Makefile b/arch/x86/cpu/i386/Makefile index d3364955d8..2547bbaa63 100644 --- a/arch/x86/cpu/i386/Makefile +++ b/arch/x86/cpu/i386/Makefile @@ -3,5 +3,6 @@ # Written by Simon Glass # +obj-y += call64.o obj-y += cpu.o obj-y += interrupt.o diff --git a/arch/x86/cpu/i386/call64.S b/arch/x86/cpu/i386/call64.S new file mode 100644 index 0000000000..970c461508 --- /dev/null +++ b/arch/x86/cpu/i386/call64.S @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2014 Google, Inc + * Copyright (C) 1991, 1992, 1993 Linus Torvalds + * + * Parts of this copied from Linux arch/x86/boot/compressed/head_64.S + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +.code32 +.globl cpu_call64 +cpu_call64: + /* + * cpu_call64(ulong pgtable, ulong setup_base, ulong target) + * + * eax - pgtable + * edx - setup_base + * ecx - target + */ + cli + push %ecx /* arg2 = target */ + push %edx /* arg1 = setup_base */ + mov %eax, %ebx + + /* Load new GDT with the 64bit segments using 32bit descriptor */ + leal gdt, %eax + movl %eax, gdt+2 + lgdt gdt + + /* Enable PAE mode */ + movl $(X86_CR4_PAE), %eax + movl %eax, %cr4 + + /* Enable the boot page tables */ + leal (%ebx), %eax + movl %eax, %cr3 + + /* Enable Long mode in EFER (Extended Feature Enable Register) */ + movl $MSR_EFER, %ecx + rdmsr + btsl $_EFER_LME, %eax + wrmsr + + /* After gdt is loaded */ + xorl %eax, %eax + lldt %ax + movl $0x20, %eax + ltr %ax + + /* + * Setup for the jump to 64bit mode + * + * When the jump is performed we will be in long mode but + * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1 + * (and in turn EFER.LMA = 1). To jump into 64bit mode we use + * the new gdt/idt that has __KERNEL_CS with CS.L = 1. + * We place all of the values on our mini stack so lret can + * used to perform that far jump. See the gdt below. + */ + pop %esi /* setup_base */ + + pushl $0x10 + leal lret_target, %eax + pushl %eax + + /* Enter paged protected Mode, activating Long Mode */ + movl $(X86_CR0_PG | X86_CR0_PE), %eax + movl %eax, %cr0 + + /* Jump from 32bit compatibility mode into 64bit mode. */ + lret + +code64: +lret_target: + pop %eax /* target */ + mov %eax, %eax /* Clear bits 63:32 */ + jmp *%eax /* Jump to the 64-bit target */ + + .data + .align 16 + .globl gdt64 +gdt64: +gdt: + .word gdt_end - gdt - 1 + .long gdt /* Fixed up by code above */ + .word 0 + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ + .quad 0x0080890000000000 /* TS descriptor */ + .quad 0x0000000000000000 /* TS continued */ +gdt_end: