^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* ----------------------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2007 rPath, Inc. - All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * ----------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * The actual transition into protected mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/boot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/processor-flags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/segment.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) .code16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * void protected_mode_jump(u32 entrypoint, u32 bootparams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) SYM_FUNC_START_NOALIGN(protected_mode_jump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) movl %edx, %esi # Pointer to boot_params table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) xorl %ebx, %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) movw %cs, %bx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) shll $4, %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) addl %ebx, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) jmp 1f # Short jump to serialize on 386/486
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) movw $__BOOT_DS, %cx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) movw $__BOOT_TSS, %di
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) movl %cr0, %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) orb $X86_CR0_PE, %dl # Protected mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) movl %edx, %cr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) # Transition to 32-bit mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .byte 0x66, 0xea # ljmpl opcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 2: .long .Lin_pm32 # offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .word __BOOT_CS # segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) SYM_FUNC_END(protected_mode_jump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .code32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .section ".text32","ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) SYM_FUNC_START_LOCAL_NOALIGN(.Lin_pm32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) # Set up data segments for flat 32-bit mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) movl %ecx, %ds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) movl %ecx, %es
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) movl %ecx, %fs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) movl %ecx, %gs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) movl %ecx, %ss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) # The 32-bit code sets up its own stack, but this way we do have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) # a valid stack if some debugging hack wants to use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) addl %ebx, %esp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) # Set up TR to make Intel VT happy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ltr %di
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) # Clear registers to allow for future extensions to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) # 32-bit boot protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) xorl %ecx, %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) xorl %edx, %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) xorl %ebx, %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) xorl %ebp, %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) xorl %edi, %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) # Set up LDTR to make Intel VT happy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) lldt %cx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) jmpl *%eax # Jump to the 32-bit entrypoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) SYM_FUNC_END(.Lin_pm32)