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/msr-index.h> 8#include <asm/processor-flags.h> 9 10 /* 11 * rdi - 32-bit code segment selector 12 * rsi - target address 13 * rdx - table address (0 if none) 14 */ 15.code64 16.globl cpu_call32 17cpu_call32: 18 cli 19 20 /* Save table pointer */ 21 mov %edx, %ebx 22 23 /* 24 * Debugging option, this outputs characters to the console UART 25 * mov $0x3f8,%edx 26 * mov $'a',%al 27 * out %al,(%dx) 28 */ 29 30 pushf 31 push %rdi /* 32-bit code segment */ 32 lea compat(%rip), %rax 33 push %rax 34 retfq 35.code32 36compat: 37 /* 38 * We are now in compatibility mode with a default operand size of 39 * 32 bits. First disable paging. 40 */ 41 movl %cr0, %eax 42 andl $~X86_CR0_PG, %eax 43 movl %eax, %cr0 44 45 /* Invalidate TLB */ 46 xorl %eax, %eax 47 movl %eax, %cr3 48 49 /* Disable Long mode in EFER (Extended Feature Enable Register) */ 50 movl $MSR_EFER, %ecx 51 rdmsr 52 btr $_EFER_LME, %eax 53 wrmsr 54 55 /* Set up table pointer for _x86boot_start */ 56 mov %ebx, %ecx 57 58 /* Jump to the required target */ 59 pushl %edi /* 32-bit code segment */ 60 pushl %esi /* 32-bit target address */ 61 retfl 62