blob: e185b9a42b034cedeefa0376d44e4e4d1b2b69d6 [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
35 .byte 0x48 /* REX prefix to force 64-bit far return */
36 retf
37.code32
38compat:
39 /*
40 * We are now in compatibility mode with a default operand size of
41 * 32 bits. First disable paging.
42 */
43 movl %cr0, %eax
44 andl $~X86_CR0_PG, %eax
45 movl %eax, %cr0
46
47 /* Invalidate TLB */
48 xorl %eax, %eax
49 movl %eax, %cr3
50
51 /* Disable Long mode in EFER (Extended Feature Enable Register) */
52 movl $MSR_EFER, %ecx
53 rdmsr
54 btr $_EFER_LME, %eax
55 wrmsr
56
57 /* Set up table pointer for _x86boot_start */
58 mov %ebx, %ecx
59
60 /* Jump to the required target */
61 pushl %edi /* 32-bit code segment */
62 pushl %esi /* 32-bit target address */
63 retf