+/* SPDX-License-Identifier: GPL-2.0 */
/*
* From coreboot x86_asm.S, cleaned up substantially
*
* Copyright (C) 2009-2010 coresystems GmbH
- *
- * SPDX-License-Identifier: GPL-2.0
*/
#include <asm/processor.h>
push %fs
push %gs
+ /* Save real mode SS */
+ movw %ss, %cs:__realmode_ss
+
/* Clear DF to not break ABI assumptions */
cld
enter_protected_mode
+ /*
+ * Now we are in protected mode. We need compute the right ESP based
+ * on saved real mode SS otherwise interrupt_handler() won't get
+ * correct parameters from the stack.
+ */
+ movzwl %cs:__realmode_ss, %ecx
+ shll $4, %ecx
+ addl %ecx, %esp
+
/* Call the C interrupt handler */
movl $interrupt_handler, %eax
call *%eax
+ /* Restore real mode ESP based on saved SS */
+ movzwl %cs:__realmode_ss, %ecx
+ shll $4, %ecx
+ subl %ecx, %esp
+
enter_real_mode
+ /* Restore real mode SS */
+ movw %cs:__realmode_ss, %ss
+
/*
* Restore all registers, including those manipulated by the C
* handler
popal
iret
+__realmode_ss = PTR_TO_REAL_MODE(.)
+ .word 0
+
.globl asm_realmode_code_size
asm_realmode_code_size:
.long . - asm_realmode_code