arch/x86/realmode/rm/trampoline_64.S

Source file repositories/reference/linux-study-clean/arch/x86/realmode/rm/trampoline_64.S

File Facts

System
Linux kernel
Corpus path
arch/x86/realmode/rm/trampoline_64.S
Extension
.S
Size
7338 bytes
Lines
295
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: arch/x86
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/linkage.h>
#include <asm/pgtable_types.h>
#include <asm/page_types.h>
#include <asm/msr.h>
#include <asm/segment.h>
#include <asm/processor-flags.h>
#include <asm/realmode.h>
#include "realmode.h"

	.text
	.code16

.macro LOCK_AND_LOAD_REALMODE_ESP lock_pa=0 lock_rip=0
	/*
	 * Make sure only one CPU fiddles with the realmode stack
	 */
.Llock_rm\@:
	.if \lock_pa
        lock btsl       $0, pa_tr_lock
	.elseif \lock_rip
        lock btsl       $0, tr_lock(%rip)
	.else
        lock btsl       $0, tr_lock
	.endif
        jnc             2f
        pause
        jmp             .Llock_rm\@
2:
	# Setup stack
	movl	$rm_stack_end, %esp
.endm

	.balign	PAGE_SIZE
SYM_CODE_START(trampoline_start)
	cli			# We should be safe anyway
	wbinvd

	LJMPW_RM(1f)
1:
	mov	%cs, %ax	# Code and data in the same place
	mov	%ax, %ds
	mov	%ax, %es
	mov	%ax, %ss

	LOCK_AND_LOAD_REALMODE_ESP

	call	verify_cpu		# Verify the cpu supports long mode
	testl   %eax, %eax		# Check for return code
	jnz	no_longmode

.Lswitch_to_protected:
	/*
	 * GDT tables in non default location kernel can be beyond 16MB and
	 * lgdt will not be able to load the address as in real mode default
	 * operand size is 16bit. Use lgdtl instead to force operand size
	 * to 32 bit.
	 */

	lidtl	tr_idt	# load idt with 0, 0
	lgdtl	tr_gdt	# load gdt with whatever is appropriate

	movw	$__KERNEL_DS, %dx	# Data segment descriptor

	# Enable protected mode
	movl	$(CR0_STATE & ~X86_CR0_PG), %eax
	movl	%eax, %cr0		# into protected mode

	# flush prefetch and jump to startup_32
	ljmpl	$__KERNEL32_CS, $pa_startup_32

Annotation

Implementation Notes