summaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/pmjump.S
blob: d48e1983f13bafd3405af93d7760d0e603212c4d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/* ----------------------------------------------------------------------- *
 *
 *   Copyright (C) 1991, 1992 Linus Torvalds
 *   Copyright 2007 rPath, Inc. - All Rights Reserved
 *
 *   This file is part of the Linux kernel, and is made available under
 *   the terms of the GNU General Public License version 2.
 *
 * ----------------------------------------------------------------------- */

/**
 * @file
 * @brief The actual transition into protected mode
 *
 * Note: This function is running in flat and real mode. Due to some
 * other restrictions it must running from an address space below 0x10000
 */

/**
 * @fn void protected_mode_jump(void)
 * @brief Switches the first time from real mode to flat mode
 */
#ifndef DOXYGEN_SHOULD_SKIP_THIS

#include <asm/modes.h>
#include "boot.h"

	.file "pmjump.S"
	.code16
	.section .boot.text.protected_mode_jump, "ax"

	.globl	protected_mode_jump
	.type	protected_mode_jump, @function

protected_mode_jump:
	jmp 1f			/* Short jump to serialize on 386/486 */
1:

	movw $__BOOT_DS, %cx
	movw $__BOOT_TSS, %di

	movl %cr0, %edx
	orb $X86_CR0_PE, %dl	/* enable protected mode */
	movl %edx, %cr0

	/* Transition to 32-bit flat mode */
	data32  ljmp $__BOOT_CS, $in_pm32

/* ------------------------------------------------------------------------ */

	.section ".text.in_pm32","ax"
	.code32

	.extern uboot_entry
	.extern __bss_end

	.type	in_pm32, @function
in_pm32:
	# Set up data segments for flat 32-bit mode
	movl %ecx, %ds
	movl %ecx, %es
	movl %ecx, %fs
	movl %ecx, %gs
	movl %ecx, %ss
/*
 * Our flat mode code uses its own stack area behind the bss. With this we
 * are still able to return to real mode temporarely
 */
	movl $__bss_end + 32768, %esp

	# Set up TR to make Intel VT happy
	ltr %di

	# Clear registers to allow for future extensions to the
	# 32-bit boot protocol
	xorl %ecx, %ecx
	xorl %edx, %edx
	xorl %ebx, %ebx
	xorl %ebp, %ebp
	xorl %edi, %edi

	# Set up LDTR to make Intel VT happy
	lldt %cx

	jmp uboot_entry

	.size protected_mode_jump, .-protected_mode_jump

#endif