xref: /titanic_51/usr/src/uts/i86pc/ml/fb_swtch_src.s (revision 877400d375b54199aef7c18828cb32f991339ff7)
119397407SSherry Moore/*
219397407SSherry Moore * CDDL HEADER START
319397407SSherry Moore *
419397407SSherry Moore * The contents of this file are subject to the terms of the
519397407SSherry Moore * Common Development and Distribution License (the "License").
619397407SSherry Moore * You may not use this file except in compliance with the License.
719397407SSherry Moore *
819397407SSherry Moore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
919397407SSherry Moore * or http://www.opensolaris.org/os/licensing.
1019397407SSherry Moore * See the License for the specific language governing permissions
1119397407SSherry Moore * and limitations under the License.
1219397407SSherry Moore *
1319397407SSherry Moore * When distributing Covered Code, include this CDDL HEADER in each
1419397407SSherry Moore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1519397407SSherry Moore * If applicable, add the following below this CDDL HEADER, with the
1619397407SSherry Moore * fields enclosed by brackets "[]" replaced with your own identifying
1719397407SSherry Moore * information: Portions Copyright [yyyy] [name of copyright owner]
1819397407SSherry Moore *
1919397407SSherry Moore * CDDL HEADER END
2019397407SSherry Moore */
2119397407SSherry Moore
2219397407SSherry Moore/*
2319397407SSherry Moore * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2419397407SSherry Moore * Use is subject to license terms.
2519397407SSherry Moore */
2619397407SSherry Moore
2719397407SSherry Moore
2819397407SSherry Moore#if defined(__lint)
2919397407SSherry Moore
3019397407SSherry Mooreint fb_swtch_silence_lint = 0;
3119397407SSherry Moore
3219397407SSherry Moore#else
3319397407SSherry Moore
3419397407SSherry Moore#include <sys/asm_linkage.h>
3519397407SSherry Moore#include <sys/segments.h>
3619397407SSherry Moore#include <sys/controlregs.h>
3719397407SSherry Moore#include <sys/machparam.h>
3819397407SSherry Moore#include <sys/multiboot.h>
3919397407SSherry Moore#include <sys/fastboot.h>
4019397407SSherry Moore#include "assym.h"
4119397407SSherry Moore
4219397407SSherry Moore/*
4319397407SSherry Moore * This code is to switch from 64-bit or 32-bit to protected mode.
4419397407SSherry Moore */
4519397407SSherry Moore
4619397407SSherry Moore/*
4719397407SSherry Moore * For debugging with LEDs
4819397407SSherry Moore */
4919397407SSherry Moore#define	FB_OUTB_ASM(val)	\
5019397407SSherry Moore    movb	val, %al;	\
5119397407SSherry Moore    outb	$0x80;
5219397407SSherry Moore
5319397407SSherry Moore
5419397407SSherry Moore#define	DISABLE_PAGING							\
5519397407SSherry Moore	movl	%cr0, %eax						;\
5619397407SSherry Moore	btrl	$31, %eax	/* clear PG bit */			;\
5719397407SSherry Moore	movl	%eax, %cr0
5819397407SSherry Moore
59*877400d3SKonstantin Ananyev/*
60*877400d3SKonstantin Ananyev * This macro contains common code for 64/32-bit versions of copy_sections().
61*877400d3SKonstantin Ananyev * On entry:
62*877400d3SKonstantin Ananyev *	fbf points to the fboot_file_t
63*877400d3SKonstantin Ananyev *	snum contains the number of sections
64*877400d3SKonstantin Ananyev * Registers that would be clobbered:
65*877400d3SKonstantin Ananyev *	fbs, snum, %eax, %ecx, %edi, %esi.
66*877400d3SKonstantin Ananyev * NOTE: fb_dest_pa is supposed to be in the first 1GB,
67*877400d3SKonstantin Ananyev * therefore it is safe to use 32-bit register to hold it's value
68*877400d3SKonstantin Ananyev * even for 64-bit code.
69*877400d3SKonstantin Ananyev */
70*877400d3SKonstantin Ananyev
71*877400d3SKonstantin Ananyev#define	COPY_SECT(fbf, fbs, snum)		\
72*877400d3SKonstantin Ananyev	lea	FB_SECTIONS(fbf), fbs;		\
73*877400d3SKonstantin Ananyev	xorl	%eax, %eax;			\
74*877400d3SKonstantin Ananyev1:	movl	FB_DEST_PA(fbf), %esi;		\
75*877400d3SKonstantin Ananyev	addl	FB_SEC_OFFSET(fbs), %esi;	\
76*877400d3SKonstantin Ananyev	movl	FB_SEC_PADDR(fbs), %edi;	\
77*877400d3SKonstantin Ananyev	movl	FB_SEC_SIZE(fbs), %ecx;		\
78*877400d3SKonstantin Ananyev	rep					\
79*877400d3SKonstantin Ananyev	  movsb;				\
80*877400d3SKonstantin Ananyev	/* Zero BSS */				\
81*877400d3SKonstantin Ananyev	movl	FB_SEC_BSS_SIZE(fbs), %ecx;	\
82*877400d3SKonstantin Ananyev	rep					\
83*877400d3SKonstantin Ananyev	  stosb;				\
84*877400d3SKonstantin Ananyev	add	$FB_SECTIONS_INCR, fbs;		\
85*877400d3SKonstantin Ananyev	dec	snum;				\
86*877400d3SKonstantin Ananyev	jnz	1b
87*877400d3SKonstantin Ananyev
8819397407SSherry Moore
8919397407SSherry Moore	.globl	_start
9019397407SSherry Moore_start:
9119397407SSherry Moore
9219397407SSherry Moore	/* Disable interrupts */
9319397407SSherry Moore	cli
9419397407SSherry Moore
9519397407SSherry Moore#if defined(__amd64)
9619397407SSherry Moore	/* Switch to a low memory stack */
9719397407SSherry Moore	movq	$_start, %rsp
9819397407SSherry Moore	addq	$FASTBOOT_STACK_OFFSET, %rsp
9919397407SSherry Moore
10019397407SSherry Moore	/*
10119397407SSherry Moore	 * Copy from old stack to new stack
10219397407SSherry Moore	 * If the content before fi_valid gets bigger than 0x200 bytes,
10319397407SSherry Moore	 * the reserved stack size above will need to be changed.
10419397407SSherry Moore	 */
10519397407SSherry Moore	movq	%rdi, %rsi	/* source from old stack */
10619397407SSherry Moore	movq	%rsp, %rdi	/* destination on the new stack */
10719397407SSherry Moore	movq	$FI_VALID, %rcx	/* size to copy */
10819397407SSherry Moore	rep
10919397407SSherry Moore	  smovb
11019397407SSherry Moore
11119397407SSherry Moore#elif defined(__i386)
11219397407SSherry Moore	movl	0x4(%esp), %esi	/* address of fastboot info struct */
11319397407SSherry Moore
11419397407SSherry Moore	/* Switch to a low memory stack */
11519397407SSherry Moore	movl	$_start, %esp
11619397407SSherry Moore	addl	$FASTBOOT_STACK_OFFSET, %esp
11719397407SSherry Moore
11819397407SSherry Moore	/* Copy struct to stack */
11919397407SSherry Moore	movl	%esp, %edi	/* destination on the new stack */
12019397407SSherry Moore	movl	$FI_VALID, %ecx	/* size to copy */
12119397407SSherry Moore	rep
12219397407SSherry Moore	  smovb
12319397407SSherry Moore
12419397407SSherry Moore#endif
12519397407SSherry Moore
12619397407SSherry Moore#if defined(__amd64)
12719397407SSherry Moore
12819397407SSherry Moore	xorl	%eax, %eax
12919397407SSherry Moore	xorl	%edx, %edx
13019397407SSherry Moore
13119397407SSherry Moore	movl	$MSR_AMD_FSBASE, %ecx
13219397407SSherry Moore	wrmsr
13319397407SSherry Moore
13419397407SSherry Moore	movl	$MSR_AMD_GSBASE, %ecx
13519397407SSherry Moore	wrmsr
13619397407SSherry Moore
13719397407SSherry Moore	movl	$MSR_AMD_KGSBASE, %ecx
13819397407SSherry Moore	wrmsr
13919397407SSherry Moore
14019397407SSherry Moore#endif
14119397407SSherry Moore	/*
14219397407SSherry Moore	 * zero out all the registers to make sure they're 16 bit clean
14319397407SSherry Moore	 */
14419397407SSherry Moore#if defined(__amd64)
14519397407SSherry Moore	xorq	%r8, %r8
14619397407SSherry Moore	xorq	%r9, %r9
14719397407SSherry Moore	xorq	%r10, %r10
14819397407SSherry Moore	xorq	%r11, %r11
14919397407SSherry Moore	xorq	%r12, %r12
15019397407SSherry Moore	xorq	%r13, %r13
15119397407SSherry Moore	xorq	%r14, %r14
15219397407SSherry Moore	xorq	%r15, %r15
15319397407SSherry Moore#endif
15419397407SSherry Moore	xorl	%eax, %eax
15519397407SSherry Moore	xorl	%ebx, %ebx
15619397407SSherry Moore	xorl	%ecx, %ecx
15719397407SSherry Moore	xorl	%edx, %edx
15819397407SSherry Moore	xorl	%ebp, %ebp
15919397407SSherry Moore
16019397407SSherry Moore#if defined(__amd64)
16119397407SSherry Moore	/*
16219397407SSherry Moore	 * Load our own GDT
16319397407SSherry Moore	 */
16419397407SSherry Moore	lgdt	gdt_info
16519397407SSherry Moore#endif
16619397407SSherry Moore	/*
16719397407SSherry Moore	 * Load our own IDT
16819397407SSherry Moore	 */
16919397407SSherry Moore	lidt	idt_info
17019397407SSherry Moore
17119397407SSherry Moore#if defined(__amd64)
17219397407SSherry Moore	/*
173*877400d3SKonstantin Ananyev	 * Invalidate all TLB entries.
174*877400d3SKonstantin Ananyev	 * Load temporary pagetables to copy kernel and boot-archive
175*877400d3SKonstantin Ananyev	 */
176*877400d3SKonstantin Ananyev	movq	%cr4, %rax
177*877400d3SKonstantin Ananyev	andq	$_BITNOT(CR4_PGE), %rax
178*877400d3SKonstantin Ananyev	movq	%rax, %cr4
179*877400d3SKonstantin Ananyev	movq	FI_PAGETABLE_PA(%rsp), %rax
180*877400d3SKonstantin Ananyev	movq	%rax, %cr3
181*877400d3SKonstantin Ananyev
182*877400d3SKonstantin Ananyev	leaq	FI_FILES(%rsp), %rbx	/* offset to the files */
183*877400d3SKonstantin Ananyev
184*877400d3SKonstantin Ananyev	/* copy unix to final destination */
185*877400d3SKonstantin Ananyev	movq	FI_LAST_TABLE_PA(%rsp), %rsi	/* page table PA */
186*877400d3SKonstantin Ananyev	leaq	_MUL(FASTBOOT_UNIX, FI_FILES_INCR)(%rbx), %rdi
187*877400d3SKonstantin Ananyev	call	map_copy
188*877400d3SKonstantin Ananyev
189*877400d3SKonstantin Ananyev	/* copy boot archive to final destination */
190*877400d3SKonstantin Ananyev	movq	FI_LAST_TABLE_PA(%rsp), %rsi	/* page table PA */
191*877400d3SKonstantin Ananyev	leaq	_MUL(FASTBOOT_BOOTARCHIVE, FI_FILES_INCR)(%rbx), %rdi
192*877400d3SKonstantin Ananyev	call	map_copy
193*877400d3SKonstantin Ananyev
194*877400d3SKonstantin Ananyev	/* Copy sections if there are any */
195*877400d3SKonstantin Ananyev	leaq	_MUL(FASTBOOT_UNIX, FI_FILES_INCR)(%rbx), %rdi
196*877400d3SKonstantin Ananyev	movl	FB_SECTCNT(%rdi), %esi
197*877400d3SKonstantin Ananyev	cmpl	$0, %esi
198*877400d3SKonstantin Ananyev	je	1f
199*877400d3SKonstantin Ananyev	call	copy_sections
200*877400d3SKonstantin Ananyev1:
201*877400d3SKonstantin Ananyev	/*
20219397407SSherry Moore	 * Shut down 64 bit mode. First get into compatiblity mode.
20319397407SSherry Moore	 */
20419397407SSherry Moore	movq	%rsp, %rax
20519397407SSherry Moore	pushq	$B32DATA_SEL
20619397407SSherry Moore	pushq	%rax
20719397407SSherry Moore	pushf
20819397407SSherry Moore	pushq	$B32CODE_SEL
20919397407SSherry Moore	pushq	$1f
21019397407SSherry Moore	iretq
21119397407SSherry Moore
21219397407SSherry Moore	.code32
21319397407SSherry Moore1:
21419397407SSherry Moore	movl	$B32DATA_SEL, %eax
21519397407SSherry Moore	movw	%ax, %ss
21619397407SSherry Moore	movw	%ax, %ds
21719397407SSherry Moore	movw	%ax, %es
21819397407SSherry Moore	movw	%ax, %fs
21919397407SSherry Moore	movw	%ax, %gs
22019397407SSherry Moore
22119397407SSherry Moore	/*
22219397407SSherry Moore	 * Disable long mode by:
22319397407SSherry Moore	 * - shutting down paging (bit 31 of cr0).  This will flush the
22419397407SSherry Moore	 *   TLBs.
225*877400d3SKonstantin Ananyev	 * - disabling LME (long mode enable) in EFER (extended feature reg)
22619397407SSherry Moore	 */
22719397407SSherry Moore#endif
22819397407SSherry Moore	DISABLE_PAGING		/* clobbers %eax */
22919397407SSherry Moore
23019397407SSherry Moore#if defined(__amd64)
23119397407SSherry Moore	ljmp	$B32CODE_SEL, $1f
23219397407SSherry Moore1:
23319397407SSherry Moore#endif
23419397407SSherry Moore
23519397407SSherry Moore	/*
23619397407SSherry Moore	 * Clear PGE, PAE and PSE flags as dboot expects them to be
23719397407SSherry Moore	 * cleared.
23819397407SSherry Moore	 */
23919397407SSherry Moore	movl	%cr4, %eax
24019397407SSherry Moore	andl	$_BITNOT(CR4_PGE | CR4_PAE | CR4_PSE), %eax
24119397407SSherry Moore	movl	%eax, %cr4
24219397407SSherry Moore
24319397407SSherry Moore#if defined(__amd64)
24419397407SSherry Moore	movl	$MSR_AMD_EFER, %ecx	/* Extended Feature Enable */
24519397407SSherry Moore	rdmsr
24619397407SSherry Moore	btcl	$8, %eax		/* bit 8 Long Mode Enable bit */
24719397407SSherry Moore	wrmsr
24819397407SSherry Moore
249*877400d3SKonstantin Ananyev#elif defined(__i386)
25019397407SSherry Moore	/*
25119397407SSherry Moore	 * If fi_has_pae is set, re-enable paging with PAE.
25219397407SSherry Moore	 */
25319397407SSherry Moore	leal	FI_FILES(%esp), %ebx	/* offset to the files */
25419397407SSherry Moore	movl	FI_HAS_PAE(%esp), %edi	/* need to enable paging or not */
25519397407SSherry Moore	cmpl	$0, %edi
25619397407SSherry Moore	je	paging_on		/* no need to enable paging */
25719397407SSherry Moore
25819397407SSherry Moore	movl	FI_LAST_TABLE_PA(%esp), %esi	/* page table PA */
25919397407SSherry Moore
26019397407SSherry Moore	/*
26119397407SSherry Moore	 * Turn on PAE
26219397407SSherry Moore	 */
26319397407SSherry Moore	movl	%cr4, %eax
26419397407SSherry Moore	orl	$CR4_PAE, %eax
26519397407SSherry Moore	movl	%eax, %cr4
26619397407SSherry Moore
26719397407SSherry Moore	/*
26819397407SSherry Moore	 * Load top pagetable base address into cr3
26919397407SSherry Moore	 */
27019397407SSherry Moore	movl	FI_PAGETABLE_PA(%esp), %eax
27119397407SSherry Moore	movl	%eax, %cr3
27219397407SSherry Moore
27319397407SSherry Moore	movl	%cr0, %eax
27419397407SSherry Moore	orl	$_CONST(CR0_PG | CR0_WP | CR0_AM), %eax
27519397407SSherry Moore	andl	$_BITNOT(CR0_NW | CR0_CD), %eax
27619397407SSherry Moore	movl	%eax, %cr0
27719397407SSherry Moore	jmp	paging_on
27819397407SSherry Moorepaging_on:
27919397407SSherry Moore
28019397407SSherry Moore	/* copy unix to final destination */
28119397407SSherry Moore	leal	_MUL(FASTBOOT_UNIX, FI_FILES_INCR)(%ebx), %edx
28219397407SSherry Moore	call	map_copy
28319397407SSherry Moore
28419397407SSherry Moore	/* copy boot archive to final destination */
28519397407SSherry Moore	leal	_MUL(FASTBOOT_BOOTARCHIVE, FI_FILES_INCR)(%ebx), %edx
28619397407SSherry Moore	call	map_copy
28719397407SSherry Moore
28819397407SSherry Moore	/* Disable paging one more time */
28919397407SSherry Moore	DISABLE_PAGING
29019397407SSherry Moore
29119397407SSherry Moore	/* Copy sections if there are any */
29219397407SSherry Moore	leal	_MUL(FASTBOOT_UNIX, FI_FILES_INCR)(%ebx), %edx
29319397407SSherry Moore	movl	FB_SECTCNT(%edx), %eax
29419397407SSherry Moore	cmpl	$0, %eax
29519397407SSherry Moore	je	1f
29619397407SSherry Moore	call	copy_sections
29719397407SSherry Moore1:
29819397407SSherry Moore
29919397407SSherry Moore	/* Whatever flags we turn on we need to turn off */
30019397407SSherry Moore	movl	%cr4, %eax
30119397407SSherry Moore	andl	$_BITNOT(CR4_PAE), %eax
30219397407SSherry Moore	movl	%eax, %cr4
303*877400d3SKonstantin Ananyev#endif	/* __i386 */
30419397407SSherry Moore
30519397407SSherry Mooredboot_jump:
30619397407SSherry Moore	/* Jump to dboot */
30719397407SSherry Moore	movl	$DBOOT_ENTRY_ADDRESS, %edi
30819397407SSherry Moore	movl	FI_NEW_MBI_PA(%esp), %ebx
30919397407SSherry Moore	movl	$MB_BOOTLOADER_MAGIC, %eax
31019397407SSherry Moore	jmp	*%edi
31119397407SSherry Moore
312*877400d3SKonstantin Ananyev#if defined(__amd64)
313*877400d3SKonstantin Ananyev
314*877400d3SKonstantin Ananyev	.code64
315*877400d3SKonstantin Ananyev	ENTRY_NP(copy_sections)
316*877400d3SKonstantin Ananyev	/*
317*877400d3SKonstantin Ananyev	 * On entry
318*877400d3SKonstantin Ananyev	 *	%rdi points to the fboot_file_t
319*877400d3SKonstantin Ananyev	 *	%rsi contains number of sections
320*877400d3SKonstantin Ananyev	 */
321*877400d3SKonstantin Ananyev	movq	%rdi, %rdx
322*877400d3SKonstantin Ananyev	movq	%rsi, %r9
323*877400d3SKonstantin Ananyev
324*877400d3SKonstantin Ananyev	COPY_SECT(%rdx, %r8, %r9)
325*877400d3SKonstantin Ananyev	ret
326*877400d3SKonstantin Ananyev	SET_SIZE(copy_sections)
327*877400d3SKonstantin Ananyev
328*877400d3SKonstantin Ananyev	ENTRY_NP(map_copy)
329*877400d3SKonstantin Ananyev	/*
330*877400d3SKonstantin Ananyev	 * On entry
331*877400d3SKonstantin Ananyev	 *	%rdi points to the fboot_file_t
332*877400d3SKonstantin Ananyev	 *	%rsi has FI_LAST_TABLE_PA(%rsp)
333*877400d3SKonstantin Ananyev	 */
334*877400d3SKonstantin Ananyev
335*877400d3SKonstantin Ananyev	movq	%rdi, %rdx
336*877400d3SKonstantin Ananyev	movq	%rsi, %r8
337*877400d3SKonstantin Ananyev	movq	FB_PTE_LIST_PA(%rdx), %rax	/* PA list of the source */
338*877400d3SKonstantin Ananyev	movq	FB_DEST_PA(%rdx), %rdi		/* PA of the destination */
339*877400d3SKonstantin Ananyev
340*877400d3SKonstantin Ananyev2:
341*877400d3SKonstantin Ananyev	movq	(%rax), %rcx			/* Are we done? */
342*877400d3SKonstantin Ananyev	cmpl	$FASTBOOT_TERMINATE, %ecx
343*877400d3SKonstantin Ananyev	je	1f
344*877400d3SKonstantin Ananyev
345*877400d3SKonstantin Ananyev	movq	%rcx, (%r8)
346*877400d3SKonstantin Ananyev	movq	%cr3, %rsi		/* Reload cr3 */
347*877400d3SKonstantin Ananyev	movq	%rsi, %cr3
348*877400d3SKonstantin Ananyev	movq	FB_VA(%rdx), %rsi	/* Load from VA */
349*877400d3SKonstantin Ananyev	movq	$PAGESIZE, %rcx
350*877400d3SKonstantin Ananyev	shrq	$3, %rcx		/* 8-byte at a time */
351*877400d3SKonstantin Ananyev	rep
352*877400d3SKonstantin Ananyev	  smovq
353*877400d3SKonstantin Ananyev	addq	$8, %rax 		/* Go to next PTE */
354*877400d3SKonstantin Ananyev	jmp	2b
355*877400d3SKonstantin Ananyev1:
356*877400d3SKonstantin Ananyev	ret
357*877400d3SKonstantin Ananyev	SET_SIZE(map_copy)
358*877400d3SKonstantin Ananyev
359*877400d3SKonstantin Ananyev#elif defined(__i386)
360*877400d3SKonstantin Ananyev
36119397407SSherry Moore	ENTRY_NP(copy_sections)
36219397407SSherry Moore	/*
36319397407SSherry Moore	 * On entry
36419397407SSherry Moore	 *	%edx points to the fboot_file_t
36519397407SSherry Moore	 *	%eax contains the number of sections
36619397407SSherry Moore	 */
36719397407SSherry Moore	pushl	%ebp
36819397407SSherry Moore	pushl	%ebx
36919397407SSherry Moore	pushl	%esi
37019397407SSherry Moore	pushl	%edi
37119397407SSherry Moore
37219397407SSherry Moore	movl	%eax, %ebp
37319397407SSherry Moore
374*877400d3SKonstantin Ananyev	COPY_SECT(%edx, %ebx, %ebp)
375*877400d3SKonstantin Ananyev
37619397407SSherry Moore	popl	%edi
37719397407SSherry Moore	popl	%esi
37819397407SSherry Moore	popl	%ebx
37919397407SSherry Moore	popl	%ebp
38019397407SSherry Moore	ret
38119397407SSherry Moore	SET_SIZE(copy_sections)
38219397407SSherry Moore
38319397407SSherry Moore	ENTRY_NP(map_copy)
38419397407SSherry Moore	/*
38519397407SSherry Moore	 * On entry
38619397407SSherry Moore	 *	%edx points to the fboot_file_t
38719397407SSherry Moore	 *	%edi has FB_HAS_PAE(%esp)
38819397407SSherry Moore	 *	%esi has FI_LAST_TABLE_PA(%esp)
38919397407SSherry Moore	 */
39019397407SSherry Moore	pushl	%eax
39119397407SSherry Moore	pushl	%ebx
39219397407SSherry Moore	pushl	%ecx
39319397407SSherry Moore	pushl	%edx
39419397407SSherry Moore	pushl	%ebp
39519397407SSherry Moore	pushl	%esi
39619397407SSherry Moore	pushl	%edi
39719397407SSherry Moore	movl	%esi, %ebp	/* Save page table PA in %ebp */
39819397407SSherry Moore
39919397407SSherry Moore	movl	FB_PTE_LIST_PA(%edx), %eax	/* PA list of the source */
40019397407SSherry Moore	movl	FB_DEST_PA(%edx), %ebx		/* PA of the destination */
40119397407SSherry Moore
40219397407SSherry Mooreloop:
40319397407SSherry Moore	movl	(%eax), %esi			/* Are we done? */
40419397407SSherry Moore	cmpl	$FASTBOOT_TERMINATE, %esi
40519397407SSherry Moore	je	done
40619397407SSherry Moore
40719397407SSherry Moore	cmpl	$1, (%esp)			/* Is paging on? */
40819397407SSherry Moore	jne	no_paging			/* Nope */
40919397407SSherry Moore
41019397407SSherry Moore	movl	%ebp, %edi			/* Page table PA */
41119397407SSherry Moore	movl	%esi, (%edi)			/* Program low 32-bit */
41219397407SSherry Moore	movl	4(%eax), %esi			/* high bits of the table */
41319397407SSherry Moore	movl	%esi, 4(%edi)			/* Program high 32-bit */
41419397407SSherry Moore	movl	%cr3, %esi			/* Reload cr3 */
41519397407SSherry Moore	movl	%esi, %cr3
41619397407SSherry Moore	movl	FB_VA(%edx), %esi		/* Load from VA */
41719397407SSherry Moore	jmp	do_copy
41819397407SSherry Mooreno_paging:
41919397407SSherry Moore	andl	$_BITNOT(MMU_PAGEOFFSET), %esi	/* clear lower 12-bit */
42019397407SSherry Mooredo_copy:
42119397407SSherry Moore	movl	%ebx, %edi
42219397407SSherry Moore	movl	$PAGESIZE, %ecx
42319397407SSherry Moore	shrl	$2, %ecx	/* 4-byte at a time */
42419397407SSherry Moore	rep
42519397407SSherry Moore	  smovl
42619397407SSherry Moore	addl	$8, %eax /* We built the PTEs as 8-byte entries */
42719397407SSherry Moore	addl	$PAGESIZE, %ebx
42819397407SSherry Moore	jmp	loop
42919397407SSherry Mooredone:
43019397407SSherry Moore	popl	%edi
43119397407SSherry Moore	popl	%esi
43219397407SSherry Moore	popl	%ebp
43319397407SSherry Moore	popl	%edx
43419397407SSherry Moore	popl	%ecx
43519397407SSherry Moore	popl	%ebx
43619397407SSherry Moore	popl	%eax
43719397407SSherry Moore	ret
43819397407SSherry Moore	SET_SIZE(map_copy)
439*877400d3SKonstantin Ananyev#endif	/* __i386 */
44019397407SSherry Moore
44119397407SSherry Moore
44219397407SSherry Mooreidt_info:
44319397407SSherry Moore	.value	0x3ff
44419397407SSherry Moore	.quad	0
44519397407SSherry Moore
44619397407SSherry Moore/*
44719397407SSherry Moore * We need to trampoline thru a gdt we have in low memory.
44819397407SSherry Moore */
44919397407SSherry Moore#include "../boot/boot_gdt.s"
45019397407SSherry Moore#endif /* __lint */
451