blob: e641e781c04c52ef405947a63808530458ff2def [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Simon Glass6f92ed82015-08-04 12:33:55 -06002/*
3 * (C) Copyright 2015 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glass6f92ed82015-08-04 12:33:55 -06005 */
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
18cpu_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
Andy Shevchenko94018592020-07-28 12:56:26 +030035 retfq
Simon Glass6f92ed82015-08-04 12:33:55 -060036.code32
37compat:
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 */
Andy Shevchenko94018592020-07-28 12:56:26 +030062 retfl