| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 1 | /* ----------------------------------------------------------------------- * | 
|  | 2 | * | 
|  | 3 | *   Copyright (C) 1991, 1992 Linus Torvalds | 
|  | 4 | *   Copyright 2007 rPath, Inc. - All Rights Reserved | 
|  | 5 | * | 
|  | 6 | *   This file is part of the Linux kernel, and is made available under | 
|  | 7 | *   the terms of the GNU General Public License version 2. | 
|  | 8 | * | 
|  | 9 | * ----------------------------------------------------------------------- */ | 
|  | 10 |  | 
|  | 11 | /* | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 12 | * The actual transition into protected mode | 
|  | 13 | */ | 
|  | 14 |  | 
|  | 15 | #include <asm/boot.h> | 
| H. Peter Anvin | 02a7b42 | 2008-01-30 13:33:02 +0100 | [diff] [blame] | 16 | #include <asm/processor-flags.h> | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 17 | #include <asm/segment.h> | 
| Cyrill Gorcunov | 324bda9 | 2009-02-14 00:50:21 +0300 | [diff] [blame] | 18 | #include <linux/linkage.h> | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 19 |  | 
|  | 20 | .text | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 21 | .code16 | 
|  | 22 |  | 
|  | 23 | /* | 
|  | 24 | * void protected_mode_jump(u32 entrypoint, u32 bootparams); | 
|  | 25 | */ | 
| Cyrill Gorcunov | 324bda9 | 2009-02-14 00:50:21 +0300 | [diff] [blame] | 26 | GLOBAL(protected_mode_jump) | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 27 | movl	%edx, %esi		# Pointer to boot_params table | 
| H. Peter Anvin | c4d9ba6 | 2008-01-30 13:33:01 +0100 | [diff] [blame] | 28 |  | 
|  | 29 | xorl	%ebx, %ebx | 
|  | 30 | movw	%cs, %bx | 
|  | 31 | shll	$4, %ebx | 
|  | 32 | addl	%ebx, 2f | 
| H. Peter Anvin | 2ee2394 | 2008-06-30 15:42:47 -0700 | [diff] [blame] | 33 | jmp	1f			# Short jump to serialize on 386/486 | 
|  | 34 | 1: | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 35 |  | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 36 | movw	$__BOOT_DS, %cx | 
| H. Peter Anvin | 8808951 | 2008-01-30 13:33:02 +0100 | [diff] [blame] | 37 | movw	$__BOOT_TSS, %di | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 38 |  | 
|  | 39 | movl	%cr0, %edx | 
| H. Peter Anvin | 02a7b42 | 2008-01-30 13:33:02 +0100 | [diff] [blame] | 40 | orb	$X86_CR0_PE, %dl	# Protected mode | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 41 | movl	%edx, %cr0 | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 42 |  | 
| H. Peter Anvin | c4d9ba6 | 2008-01-30 13:33:01 +0100 | [diff] [blame] | 43 | # Transition to 32-bit mode | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 44 | .byte	0x66, 0xea		# ljmpl opcode | 
| H. Peter Anvin | c4d9ba6 | 2008-01-30 13:33:01 +0100 | [diff] [blame] | 45 | 2:	.long	in_pm32			# offset | 
| H. Peter Anvin | 7052fdd | 2007-07-11 12:18:53 -0700 | [diff] [blame] | 46 | .word	__BOOT_CS		# segment | 
| Cyrill Gorcunov | 324bda9 | 2009-02-14 00:50:21 +0300 | [diff] [blame] | 47 | ENDPROC(protected_mode_jump) | 
| H. Peter Anvin | c4d9ba6 | 2008-01-30 13:33:01 +0100 | [diff] [blame] | 48 |  | 
|  | 49 | .code32 | 
| H. Peter Anvin | be72169 | 2009-03-17 15:26:06 -0700 | [diff] [blame] | 50 | .section ".text32","ax" | 
| Cyrill Gorcunov | 324bda9 | 2009-02-14 00:50:21 +0300 | [diff] [blame] | 51 | GLOBAL(in_pm32) | 
| H. Peter Anvin | c4d9ba6 | 2008-01-30 13:33:01 +0100 | [diff] [blame] | 52 | # Set up data segments for flat 32-bit mode | 
|  | 53 | movl	%ecx, %ds | 
|  | 54 | movl	%ecx, %es | 
|  | 55 | movl	%ecx, %fs | 
|  | 56 | movl	%ecx, %gs | 
|  | 57 | movl	%ecx, %ss | 
|  | 58 | # The 32-bit code sets up its own stack, but this way we do have | 
|  | 59 | # a valid stack if some debugging hack wants to use it. | 
|  | 60 | addl	%ebx, %esp | 
|  | 61 |  | 
| H. Peter Anvin | 8808951 | 2008-01-30 13:33:02 +0100 | [diff] [blame] | 62 | # Set up TR to make Intel VT happy | 
|  | 63 | ltr	%di | 
|  | 64 |  | 
| H. Peter Anvin | c4d9ba6 | 2008-01-30 13:33:01 +0100 | [diff] [blame] | 65 | # Clear registers to allow for future extensions to the | 
|  | 66 | # 32-bit boot protocol | 
|  | 67 | xorl	%ecx, %ecx | 
|  | 68 | xorl	%edx, %edx | 
|  | 69 | xorl	%ebx, %ebx | 
|  | 70 | xorl	%ebp, %ebp | 
|  | 71 | xorl	%edi, %edi | 
|  | 72 |  | 
| H. Peter Anvin | 8808951 | 2008-01-30 13:33:02 +0100 | [diff] [blame] | 73 | # Set up LDTR to make Intel VT happy | 
|  | 74 | lldt	%cx | 
|  | 75 |  | 
| H. Peter Anvin | c4d9ba6 | 2008-01-30 13:33:01 +0100 | [diff] [blame] | 76 | jmpl	*%eax			# Jump to the 32-bit entrypoint | 
| Cyrill Gorcunov | 324bda9 | 2009-02-14 00:50:21 +0300 | [diff] [blame] | 77 | ENDPROC(in_pm32) |