e641e781c04c52ef405947a63808530458ff2def
[platform/kernel/u-boot.git] / arch / x86 / cpu / call32.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * (C) Copyright 2015 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6
7 #include <asm/global_data.h>
8 #include <asm/msr-index.h>
9 #include <asm/processor-flags.h>
10
11         /*
12          * rdi - 32-bit code segment selector
13          * rsi - target address
14          * rdx - table address (0 if none)
15          */
16 .code64
17 .globl cpu_call32
18 cpu_call32:
19         cli
20
21         /* Save table pointer */
22         mov     %edx, %ebx
23
24         /*
25          * Debugging option, this outputs characters to the console UART
26          * mov  $0x3f8,%edx
27          * mov  $'a',%al
28          * out  %al,(%dx)
29          */
30
31         pushf
32         push    %rdi    /* 32-bit code segment */
33         lea     compat(%rip), %rax
34         push    %rax
35         retfq
36 .code32
37 compat:
38         /*
39          * We are now in compatibility mode with a default operand size of
40          * 32 bits. First disable paging.
41          */
42         movl    %cr0, %eax
43         andl    $~X86_CR0_PG, %eax
44         movl    %eax, %cr0
45
46         /* Invalidate TLB */
47         xorl    %eax, %eax
48         movl    %eax, %cr3
49
50         /* Disable Long mode in EFER (Extended Feature Enable Register) */
51         movl    $MSR_EFER, %ecx
52         rdmsr
53         btr     $_EFER_LME, %eax
54         wrmsr
55
56         /* Set up table pointer for _x86boot_start */
57         mov     %ebx, %ecx
58
59         /* Jump to the required target */
60         pushl   %edi    /* 32-bit code segment */
61         pushl   %esi    /* 32-bit target address */
62         retfl