xref: /openbmc/u-boot/arch/x86/cpu/call32.S (revision e8f80a5a)
1*83d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0+ */
26f92ed8fSSimon Glass/*
36f92ed8fSSimon Glass * (C) Copyright 2015 Google, Inc
46f92ed8fSSimon Glass * Written by Simon Glass <sjg@chromium.org>
56f92ed8fSSimon Glass */
66f92ed8fSSimon Glass
76f92ed8fSSimon Glass#include <asm/global_data.h>
86f92ed8fSSimon Glass#include <asm/msr-index.h>
96f92ed8fSSimon Glass#include <asm/processor-flags.h>
106f92ed8fSSimon Glass
116f92ed8fSSimon Glass	/*
126f92ed8fSSimon Glass	 * rdi - 32-bit code segment selector
136f92ed8fSSimon Glass	 * rsi - target address
146f92ed8fSSimon Glass	 * rdx - table address (0 if none)
156f92ed8fSSimon Glass	 */
166f92ed8fSSimon Glass.code64
176f92ed8fSSimon Glass.globl cpu_call32
186f92ed8fSSimon Glasscpu_call32:
196f92ed8fSSimon Glass	cli
206f92ed8fSSimon Glass
216f92ed8fSSimon Glass	/* Save table pointer */
226f92ed8fSSimon Glass	mov	%edx, %ebx
236f92ed8fSSimon Glass
246f92ed8fSSimon Glass	/*
256f92ed8fSSimon Glass	 * Debugging option, this outputs characters to the console UART
266f92ed8fSSimon Glass	 * mov	$0x3f8,%edx
276f92ed8fSSimon Glass	 * mov	$'a',%al
286f92ed8fSSimon Glass	 * out	%al,(%dx)
296f92ed8fSSimon Glass	 */
306f92ed8fSSimon Glass
316f92ed8fSSimon Glass	pushf
326f92ed8fSSimon Glass	push	%rdi	/* 32-bit code segment */
336f92ed8fSSimon Glass	lea	compat(%rip), %rax
346f92ed8fSSimon Glass	push	%rax
356f92ed8fSSimon Glass	.byte	0x48	/* REX prefix to force 64-bit far return */
366f92ed8fSSimon Glass	retf
376f92ed8fSSimon Glass.code32
386f92ed8fSSimon Glasscompat:
396f92ed8fSSimon Glass	/*
406f92ed8fSSimon Glass	 * We are now in compatibility mode with a default operand size of
416f92ed8fSSimon Glass	 * 32 bits. First disable paging.
426f92ed8fSSimon Glass	 */
436f92ed8fSSimon Glass	movl	%cr0, %eax
446f92ed8fSSimon Glass	andl	$~X86_CR0_PG, %eax
456f92ed8fSSimon Glass	movl	%eax, %cr0
466f92ed8fSSimon Glass
476f92ed8fSSimon Glass	/* Invalidate TLB */
486f92ed8fSSimon Glass	xorl	%eax, %eax
496f92ed8fSSimon Glass	movl	%eax, %cr3
506f92ed8fSSimon Glass
516f92ed8fSSimon Glass	/* Disable Long mode in EFER (Extended Feature Enable Register) */
526f92ed8fSSimon Glass	movl	$MSR_EFER, %ecx
536f92ed8fSSimon Glass	rdmsr
546f92ed8fSSimon Glass	btr	$_EFER_LME, %eax
556f92ed8fSSimon Glass	wrmsr
566f92ed8fSSimon Glass
576f92ed8fSSimon Glass	/* Set up table pointer for _x86boot_start */
586f92ed8fSSimon Glass	mov	%ebx, %ecx
596f92ed8fSSimon Glass
606f92ed8fSSimon Glass	/* Jump to the required target */
616f92ed8fSSimon Glass	pushl	%edi	/* 32-bit code segment */
626f92ed8fSSimon Glass	pushl	%esi	/* 32-bit target address */
636f92ed8fSSimon Glass	retf
64