xref: /onnv-gate/usr/src/uts/i86pc/ml/fb_swtch_src.s (revision 8151:138e28c74dae)
17656SSherry.Moore@Sun.COM/*
27656SSherry.Moore@Sun.COM * CDDL HEADER START
37656SSherry.Moore@Sun.COM *
47656SSherry.Moore@Sun.COM * The contents of this file are subject to the terms of the
57656SSherry.Moore@Sun.COM * Common Development and Distribution License (the "License").
67656SSherry.Moore@Sun.COM * You may not use this file except in compliance with the License.
77656SSherry.Moore@Sun.COM *
87656SSherry.Moore@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97656SSherry.Moore@Sun.COM * or http://www.opensolaris.org/os/licensing.
107656SSherry.Moore@Sun.COM * See the License for the specific language governing permissions
117656SSherry.Moore@Sun.COM * and limitations under the License.
127656SSherry.Moore@Sun.COM *
137656SSherry.Moore@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147656SSherry.Moore@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157656SSherry.Moore@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167656SSherry.Moore@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177656SSherry.Moore@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187656SSherry.Moore@Sun.COM *
197656SSherry.Moore@Sun.COM * CDDL HEADER END
207656SSherry.Moore@Sun.COM */
217656SSherry.Moore@Sun.COM
227656SSherry.Moore@Sun.COM/*
237656SSherry.Moore@Sun.COM * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247656SSherry.Moore@Sun.COM * Use is subject to license terms.
257656SSherry.Moore@Sun.COM */
267656SSherry.Moore@Sun.COM
277656SSherry.Moore@Sun.COM
287656SSherry.Moore@Sun.COM#if defined(__lint)
297656SSherry.Moore@Sun.COM
307656SSherry.Moore@Sun.COMint fb_swtch_silence_lint = 0;
317656SSherry.Moore@Sun.COM
327656SSherry.Moore@Sun.COM#else
337656SSherry.Moore@Sun.COM
347656SSherry.Moore@Sun.COM#include <sys/asm_linkage.h>
357656SSherry.Moore@Sun.COM#include <sys/segments.h>
367656SSherry.Moore@Sun.COM#include <sys/controlregs.h>
377656SSherry.Moore@Sun.COM#include <sys/machparam.h>
387656SSherry.Moore@Sun.COM#include <sys/multiboot.h>
397656SSherry.Moore@Sun.COM#include <sys/fastboot.h>
407656SSherry.Moore@Sun.COM#include "assym.h"
417656SSherry.Moore@Sun.COM
427656SSherry.Moore@Sun.COM/*
437656SSherry.Moore@Sun.COM * This code is to switch from 64-bit or 32-bit to protected mode.
447656SSherry.Moore@Sun.COM */
457656SSherry.Moore@Sun.COM
467656SSherry.Moore@Sun.COM/*
477656SSherry.Moore@Sun.COM * For debugging with LEDs
487656SSherry.Moore@Sun.COM */
497656SSherry.Moore@Sun.COM#define	FB_OUTB_ASM(val)	\
507656SSherry.Moore@Sun.COM    movb	val, %al;	\
517656SSherry.Moore@Sun.COM    outb	$0x80;
527656SSherry.Moore@Sun.COM
537656SSherry.Moore@Sun.COM
547656SSherry.Moore@Sun.COM#define	DISABLE_PAGING							\
557656SSherry.Moore@Sun.COM	movl	%cr0, %eax						;\
567656SSherry.Moore@Sun.COM	btrl	$31, %eax	/* clear PG bit */			;\
577656SSherry.Moore@Sun.COM	movl	%eax, %cr0
587656SSherry.Moore@Sun.COM
59*8151SKonstantin.Ananyev@Sun.COM/*
60*8151SKonstantin.Ananyev@Sun.COM * This macro contains common code for 64/32-bit versions of copy_sections().
61*8151SKonstantin.Ananyev@Sun.COM * On entry:
62*8151SKonstantin.Ananyev@Sun.COM *	fbf points to the fboot_file_t
63*8151SKonstantin.Ananyev@Sun.COM *	snum contains the number of sections
64*8151SKonstantin.Ananyev@Sun.COM * Registers that would be clobbered:
65*8151SKonstantin.Ananyev@Sun.COM *	fbs, snum, %eax, %ecx, %edi, %esi.
66*8151SKonstantin.Ananyev@Sun.COM * NOTE: fb_dest_pa is supposed to be in the first 1GB,
67*8151SKonstantin.Ananyev@Sun.COM * therefore it is safe to use 32-bit register to hold it's value
68*8151SKonstantin.Ananyev@Sun.COM * even for 64-bit code.
69*8151SKonstantin.Ananyev@Sun.COM */
70*8151SKonstantin.Ananyev@Sun.COM
71*8151SKonstantin.Ananyev@Sun.COM#define	COPY_SECT(fbf, fbs, snum)		\
72*8151SKonstantin.Ananyev@Sun.COM	lea	FB_SECTIONS(fbf), fbs;		\
73*8151SKonstantin.Ananyev@Sun.COM	xorl	%eax, %eax;			\
74*8151SKonstantin.Ananyev@Sun.COM1:	movl	FB_DEST_PA(fbf), %esi;		\
75*8151SKonstantin.Ananyev@Sun.COM	addl	FB_SEC_OFFSET(fbs), %esi;	\
76*8151SKonstantin.Ananyev@Sun.COM	movl	FB_SEC_PADDR(fbs), %edi;	\
77*8151SKonstantin.Ananyev@Sun.COM	movl	FB_SEC_SIZE(fbs), %ecx;		\
78*8151SKonstantin.Ananyev@Sun.COM	rep					\
79*8151SKonstantin.Ananyev@Sun.COM	  movsb;				\
80*8151SKonstantin.Ananyev@Sun.COM	/* Zero BSS */				\
81*8151SKonstantin.Ananyev@Sun.COM	movl	FB_SEC_BSS_SIZE(fbs), %ecx;	\
82*8151SKonstantin.Ananyev@Sun.COM	rep					\
83*8151SKonstantin.Ananyev@Sun.COM	  stosb;				\
84*8151SKonstantin.Ananyev@Sun.COM	add	$FB_SECTIONS_INCR, fbs;		\
85*8151SKonstantin.Ananyev@Sun.COM	dec	snum;				\
86*8151SKonstantin.Ananyev@Sun.COM	jnz	1b
87*8151SKonstantin.Ananyev@Sun.COM
887656SSherry.Moore@Sun.COM
897656SSherry.Moore@Sun.COM	.globl	_start
907656SSherry.Moore@Sun.COM_start:
917656SSherry.Moore@Sun.COM
927656SSherry.Moore@Sun.COM	/* Disable interrupts */
937656SSherry.Moore@Sun.COM	cli
947656SSherry.Moore@Sun.COM
957656SSherry.Moore@Sun.COM#if defined(__amd64)
967656SSherry.Moore@Sun.COM	/* Switch to a low memory stack */
977656SSherry.Moore@Sun.COM	movq	$_start, %rsp
987656SSherry.Moore@Sun.COM	addq	$FASTBOOT_STACK_OFFSET, %rsp
997656SSherry.Moore@Sun.COM
1007656SSherry.Moore@Sun.COM	/*
1017656SSherry.Moore@Sun.COM	 * Copy from old stack to new stack
1027656SSherry.Moore@Sun.COM	 * If the content before fi_valid gets bigger than 0x200 bytes,
1037656SSherry.Moore@Sun.COM	 * the reserved stack size above will need to be changed.
1047656SSherry.Moore@Sun.COM	 */
1057656SSherry.Moore@Sun.COM	movq	%rdi, %rsi	/* source from old stack */
1067656SSherry.Moore@Sun.COM	movq	%rsp, %rdi	/* destination on the new stack */
1077656SSherry.Moore@Sun.COM	movq	$FI_VALID, %rcx	/* size to copy */
1087656SSherry.Moore@Sun.COM	rep
1097656SSherry.Moore@Sun.COM	  smovb
1107656SSherry.Moore@Sun.COM
1117656SSherry.Moore@Sun.COM#elif defined(__i386)
1127656SSherry.Moore@Sun.COM	movl	0x4(%esp), %esi	/* address of fastboot info struct */
1137656SSherry.Moore@Sun.COM
1147656SSherry.Moore@Sun.COM	/* Switch to a low memory stack */
1157656SSherry.Moore@Sun.COM	movl	$_start, %esp
1167656SSherry.Moore@Sun.COM	addl	$FASTBOOT_STACK_OFFSET, %esp
1177656SSherry.Moore@Sun.COM
1187656SSherry.Moore@Sun.COM	/* Copy struct to stack */
1197656SSherry.Moore@Sun.COM	movl	%esp, %edi	/* destination on the new stack */
1207656SSherry.Moore@Sun.COM	movl	$FI_VALID, %ecx	/* size to copy */
1217656SSherry.Moore@Sun.COM	rep
1227656SSherry.Moore@Sun.COM	  smovb
1237656SSherry.Moore@Sun.COM
1247656SSherry.Moore@Sun.COM#endif
1257656SSherry.Moore@Sun.COM
1267656SSherry.Moore@Sun.COM#if defined(__amd64)
1277656SSherry.Moore@Sun.COM
1287656SSherry.Moore@Sun.COM	xorl	%eax, %eax
1297656SSherry.Moore@Sun.COM	xorl	%edx, %edx
1307656SSherry.Moore@Sun.COM
1317656SSherry.Moore@Sun.COM	movl	$MSR_AMD_FSBASE, %ecx
1327656SSherry.Moore@Sun.COM	wrmsr
1337656SSherry.Moore@Sun.COM
1347656SSherry.Moore@Sun.COM	movl	$MSR_AMD_GSBASE, %ecx
1357656SSherry.Moore@Sun.COM	wrmsr
1367656SSherry.Moore@Sun.COM
1377656SSherry.Moore@Sun.COM	movl	$MSR_AMD_KGSBASE, %ecx
1387656SSherry.Moore@Sun.COM	wrmsr
1397656SSherry.Moore@Sun.COM
1407656SSherry.Moore@Sun.COM#endif
1417656SSherry.Moore@Sun.COM	/*
1427656SSherry.Moore@Sun.COM	 * zero out all the registers to make sure they're 16 bit clean
1437656SSherry.Moore@Sun.COM	 */
1447656SSherry.Moore@Sun.COM#if defined(__amd64)
1457656SSherry.Moore@Sun.COM	xorq	%r8, %r8
1467656SSherry.Moore@Sun.COM	xorq	%r9, %r9
1477656SSherry.Moore@Sun.COM	xorq	%r10, %r10
1487656SSherry.Moore@Sun.COM	xorq	%r11, %r11
1497656SSherry.Moore@Sun.COM	xorq	%r12, %r12
1507656SSherry.Moore@Sun.COM	xorq	%r13, %r13
1517656SSherry.Moore@Sun.COM	xorq	%r14, %r14
1527656SSherry.Moore@Sun.COM	xorq	%r15, %r15
1537656SSherry.Moore@Sun.COM#endif
1547656SSherry.Moore@Sun.COM	xorl	%eax, %eax
1557656SSherry.Moore@Sun.COM	xorl	%ebx, %ebx
1567656SSherry.Moore@Sun.COM	xorl	%ecx, %ecx
1577656SSherry.Moore@Sun.COM	xorl	%edx, %edx
1587656SSherry.Moore@Sun.COM	xorl	%ebp, %ebp
1597656SSherry.Moore@Sun.COM
1607656SSherry.Moore@Sun.COM#if defined(__amd64)
1617656SSherry.Moore@Sun.COM	/*
1627656SSherry.Moore@Sun.COM	 * Load our own GDT
1637656SSherry.Moore@Sun.COM	 */
1647656SSherry.Moore@Sun.COM	lgdt	gdt_info
1657656SSherry.Moore@Sun.COM#endif
1667656SSherry.Moore@Sun.COM	/*
1677656SSherry.Moore@Sun.COM	 * Load our own IDT
1687656SSherry.Moore@Sun.COM	 */
1697656SSherry.Moore@Sun.COM	lidt	idt_info
1707656SSherry.Moore@Sun.COM
1717656SSherry.Moore@Sun.COM#if defined(__amd64)
1727656SSherry.Moore@Sun.COM	/*
173*8151SKonstantin.Ananyev@Sun.COM	 * Invalidate all TLB entries.
174*8151SKonstantin.Ananyev@Sun.COM	 * Load temporary pagetables to copy kernel and boot-archive
175*8151SKonstantin.Ananyev@Sun.COM	 */
176*8151SKonstantin.Ananyev@Sun.COM	movq	%cr4, %rax
177*8151SKonstantin.Ananyev@Sun.COM	andq	$_BITNOT(CR4_PGE), %rax
178*8151SKonstantin.Ananyev@Sun.COM	movq	%rax, %cr4
179*8151SKonstantin.Ananyev@Sun.COM	movq	FI_PAGETABLE_PA(%rsp), %rax
180*8151SKonstantin.Ananyev@Sun.COM	movq	%rax, %cr3
181*8151SKonstantin.Ananyev@Sun.COM
182*8151SKonstantin.Ananyev@Sun.COM	leaq	FI_FILES(%rsp), %rbx	/* offset to the files */
183*8151SKonstantin.Ananyev@Sun.COM
184*8151SKonstantin.Ananyev@Sun.COM	/* copy unix to final destination */
185*8151SKonstantin.Ananyev@Sun.COM	movq	FI_LAST_TABLE_PA(%rsp), %rsi	/* page table PA */
186*8151SKonstantin.Ananyev@Sun.COM	leaq	_MUL(FASTBOOT_UNIX, FI_FILES_INCR)(%rbx), %rdi
187*8151SKonstantin.Ananyev@Sun.COM	call	map_copy
188*8151SKonstantin.Ananyev@Sun.COM
189*8151SKonstantin.Ananyev@Sun.COM	/* copy boot archive to final destination */
190*8151SKonstantin.Ananyev@Sun.COM	movq	FI_LAST_TABLE_PA(%rsp), %rsi	/* page table PA */
191*8151SKonstantin.Ananyev@Sun.COM	leaq	_MUL(FASTBOOT_BOOTARCHIVE, FI_FILES_INCR)(%rbx), %rdi
192*8151SKonstantin.Ananyev@Sun.COM	call	map_copy
193*8151SKonstantin.Ananyev@Sun.COM
194*8151SKonstantin.Ananyev@Sun.COM	/* Copy sections if there are any */
195*8151SKonstantin.Ananyev@Sun.COM	leaq	_MUL(FASTBOOT_UNIX, FI_FILES_INCR)(%rbx), %rdi
196*8151SKonstantin.Ananyev@Sun.COM	movl	FB_SECTCNT(%rdi), %esi
197*8151SKonstantin.Ananyev@Sun.COM	cmpl	$0, %esi
198*8151SKonstantin.Ananyev@Sun.COM	je	1f
199*8151SKonstantin.Ananyev@Sun.COM	call	copy_sections
200*8151SKonstantin.Ananyev@Sun.COM1:
201*8151SKonstantin.Ananyev@Sun.COM	/*
2027656SSherry.Moore@Sun.COM	 * Shut down 64 bit mode. First get into compatiblity mode.
2037656SSherry.Moore@Sun.COM	 */
2047656SSherry.Moore@Sun.COM	movq	%rsp, %rax
2057656SSherry.Moore@Sun.COM	pushq	$B32DATA_SEL
2067656SSherry.Moore@Sun.COM	pushq	%rax
2077656SSherry.Moore@Sun.COM	pushf
2087656SSherry.Moore@Sun.COM	pushq	$B32CODE_SEL
2097656SSherry.Moore@Sun.COM	pushq	$1f
2107656SSherry.Moore@Sun.COM	iretq
2117656SSherry.Moore@Sun.COM
2127656SSherry.Moore@Sun.COM	.code32
2137656SSherry.Moore@Sun.COM1:
2147656SSherry.Moore@Sun.COM	movl	$B32DATA_SEL, %eax
2157656SSherry.Moore@Sun.COM	movw	%ax, %ss
2167656SSherry.Moore@Sun.COM	movw	%ax, %ds
2177656SSherry.Moore@Sun.COM	movw	%ax, %es
2187656SSherry.Moore@Sun.COM	movw	%ax, %fs
2197656SSherry.Moore@Sun.COM	movw	%ax, %gs
2207656SSherry.Moore@Sun.COM
2217656SSherry.Moore@Sun.COM	/*
2227656SSherry.Moore@Sun.COM	 * Disable long mode by:
2237656SSherry.Moore@Sun.COM	 * - shutting down paging (bit 31 of cr0).  This will flush the
2247656SSherry.Moore@Sun.COM	 *   TLBs.
225*8151SKonstantin.Ananyev@Sun.COM	 * - disabling LME (long mode enable) in EFER (extended feature reg)
2267656SSherry.Moore@Sun.COM	 */
2277656SSherry.Moore@Sun.COM#endif
2287656SSherry.Moore@Sun.COM	DISABLE_PAGING		/* clobbers %eax */
2297656SSherry.Moore@Sun.COM
2307656SSherry.Moore@Sun.COM#if defined(__amd64)
2317656SSherry.Moore@Sun.COM	ljmp	$B32CODE_SEL, $1f
2327656SSherry.Moore@Sun.COM1:
2337656SSherry.Moore@Sun.COM#endif
2347656SSherry.Moore@Sun.COM
2357656SSherry.Moore@Sun.COM	/*
2367656SSherry.Moore@Sun.COM	 * Clear PGE, PAE and PSE flags as dboot expects them to be
2377656SSherry.Moore@Sun.COM	 * cleared.
2387656SSherry.Moore@Sun.COM	 */
2397656SSherry.Moore@Sun.COM	movl	%cr4, %eax
2407656SSherry.Moore@Sun.COM	andl	$_BITNOT(CR4_PGE | CR4_PAE | CR4_PSE), %eax
2417656SSherry.Moore@Sun.COM	movl	%eax, %cr4
2427656SSherry.Moore@Sun.COM
2437656SSherry.Moore@Sun.COM#if defined(__amd64)
2447656SSherry.Moore@Sun.COM	movl	$MSR_AMD_EFER, %ecx	/* Extended Feature Enable */
2457656SSherry.Moore@Sun.COM	rdmsr
2467656SSherry.Moore@Sun.COM	btcl	$8, %eax		/* bit 8 Long Mode Enable bit */
2477656SSherry.Moore@Sun.COM	wrmsr
2487656SSherry.Moore@Sun.COM
249*8151SKonstantin.Ananyev@Sun.COM#elif defined(__i386)
2507656SSherry.Moore@Sun.COM	/*
2517656SSherry.Moore@Sun.COM	 * If fi_has_pae is set, re-enable paging with PAE.
2527656SSherry.Moore@Sun.COM	 */
2537656SSherry.Moore@Sun.COM	leal	FI_FILES(%esp), %ebx	/* offset to the files */
2547656SSherry.Moore@Sun.COM	movl	FI_HAS_PAE(%esp), %edi	/* need to enable paging or not */
2557656SSherry.Moore@Sun.COM	cmpl	$0, %edi
2567656SSherry.Moore@Sun.COM	je	paging_on		/* no need to enable paging */
2577656SSherry.Moore@Sun.COM
2587656SSherry.Moore@Sun.COM	movl	FI_LAST_TABLE_PA(%esp), %esi	/* page table PA */
2597656SSherry.Moore@Sun.COM
2607656SSherry.Moore@Sun.COM	/*
2617656SSherry.Moore@Sun.COM	 * Turn on PAE
2627656SSherry.Moore@Sun.COM	 */
2637656SSherry.Moore@Sun.COM	movl	%cr4, %eax
2647656SSherry.Moore@Sun.COM	orl	$CR4_PAE, %eax
2657656SSherry.Moore@Sun.COM	movl	%eax, %cr4
2667656SSherry.Moore@Sun.COM
2677656SSherry.Moore@Sun.COM	/*
2687656SSherry.Moore@Sun.COM	 * Load top pagetable base address into cr3
2697656SSherry.Moore@Sun.COM	 */
2707656SSherry.Moore@Sun.COM	movl	FI_PAGETABLE_PA(%esp), %eax
2717656SSherry.Moore@Sun.COM	movl	%eax, %cr3
2727656SSherry.Moore@Sun.COM
2737656SSherry.Moore@Sun.COM	movl	%cr0, %eax
2747656SSherry.Moore@Sun.COM	orl	$_CONST(CR0_PG | CR0_WP | CR0_AM), %eax
2757656SSherry.Moore@Sun.COM	andl	$_BITNOT(CR0_NW | CR0_CD), %eax
2767656SSherry.Moore@Sun.COM	movl	%eax, %cr0
2777656SSherry.Moore@Sun.COM	jmp	paging_on
2787656SSherry.Moore@Sun.COMpaging_on:
2797656SSherry.Moore@Sun.COM
2807656SSherry.Moore@Sun.COM	/* copy unix to final destination */
2817656SSherry.Moore@Sun.COM	leal	_MUL(FASTBOOT_UNIX, FI_FILES_INCR)(%ebx), %edx
2827656SSherry.Moore@Sun.COM	call	map_copy
2837656SSherry.Moore@Sun.COM
2847656SSherry.Moore@Sun.COM	/* copy boot archive to final destination */
2857656SSherry.Moore@Sun.COM	leal	_MUL(FASTBOOT_BOOTARCHIVE, FI_FILES_INCR)(%ebx), %edx
2867656SSherry.Moore@Sun.COM	call	map_copy
2877656SSherry.Moore@Sun.COM
2887656SSherry.Moore@Sun.COM	/* Disable paging one more time */
2897656SSherry.Moore@Sun.COM	DISABLE_PAGING
2907656SSherry.Moore@Sun.COM
2917656SSherry.Moore@Sun.COM	/* Copy sections if there are any */
2927656SSherry.Moore@Sun.COM	leal	_MUL(FASTBOOT_UNIX, FI_FILES_INCR)(%ebx), %edx
2937656SSherry.Moore@Sun.COM	movl	FB_SECTCNT(%edx), %eax
2947656SSherry.Moore@Sun.COM	cmpl	$0, %eax
2957656SSherry.Moore@Sun.COM	je	1f
2967656SSherry.Moore@Sun.COM	call	copy_sections
2977656SSherry.Moore@Sun.COM1:
2987656SSherry.Moore@Sun.COM
2997656SSherry.Moore@Sun.COM	/* Whatever flags we turn on we need to turn off */
3007656SSherry.Moore@Sun.COM	movl	%cr4, %eax
3017656SSherry.Moore@Sun.COM	andl	$_BITNOT(CR4_PAE), %eax
3027656SSherry.Moore@Sun.COM	movl	%eax, %cr4
303*8151SKonstantin.Ananyev@Sun.COM#endif	/* __i386 */
3047656SSherry.Moore@Sun.COM
3057656SSherry.Moore@Sun.COMdboot_jump:
3067656SSherry.Moore@Sun.COM	/* Jump to dboot */
3077656SSherry.Moore@Sun.COM	movl	$DBOOT_ENTRY_ADDRESS, %edi
3087656SSherry.Moore@Sun.COM	movl	FI_NEW_MBI_PA(%esp), %ebx
3097656SSherry.Moore@Sun.COM	movl	$MB_BOOTLOADER_MAGIC, %eax
3107656SSherry.Moore@Sun.COM	jmp	*%edi
3117656SSherry.Moore@Sun.COM
312*8151SKonstantin.Ananyev@Sun.COM#if defined(__amd64)
313*8151SKonstantin.Ananyev@Sun.COM
314*8151SKonstantin.Ananyev@Sun.COM	.code64
315*8151SKonstantin.Ananyev@Sun.COM	ENTRY_NP(copy_sections)
316*8151SKonstantin.Ananyev@Sun.COM	/*
317*8151SKonstantin.Ananyev@Sun.COM	 * On entry
318*8151SKonstantin.Ananyev@Sun.COM	 *	%rdi points to the fboot_file_t
319*8151SKonstantin.Ananyev@Sun.COM	 *	%rsi contains number of sections
320*8151SKonstantin.Ananyev@Sun.COM	 */
321*8151SKonstantin.Ananyev@Sun.COM	movq	%rdi, %rdx
322*8151SKonstantin.Ananyev@Sun.COM	movq	%rsi, %r9
323*8151SKonstantin.Ananyev@Sun.COM
324*8151SKonstantin.Ananyev@Sun.COM	COPY_SECT(%rdx, %r8, %r9)
325*8151SKonstantin.Ananyev@Sun.COM	ret
326*8151SKonstantin.Ananyev@Sun.COM	SET_SIZE(copy_sections)
327*8151SKonstantin.Ananyev@Sun.COM
328*8151SKonstantin.Ananyev@Sun.COM	ENTRY_NP(map_copy)
329*8151SKonstantin.Ananyev@Sun.COM	/*
330*8151SKonstantin.Ananyev@Sun.COM	 * On entry
331*8151SKonstantin.Ananyev@Sun.COM	 *	%rdi points to the fboot_file_t
332*8151SKonstantin.Ananyev@Sun.COM	 *	%rsi has FI_LAST_TABLE_PA(%rsp)
333*8151SKonstantin.Ananyev@Sun.COM	 */
334*8151SKonstantin.Ananyev@Sun.COM
335*8151SKonstantin.Ananyev@Sun.COM	movq	%rdi, %rdx
336*8151SKonstantin.Ananyev@Sun.COM	movq	%rsi, %r8
337*8151SKonstantin.Ananyev@Sun.COM	movq	FB_PTE_LIST_PA(%rdx), %rax	/* PA list of the source */
338*8151SKonstantin.Ananyev@Sun.COM	movq	FB_DEST_PA(%rdx), %rdi		/* PA of the destination */
339*8151SKonstantin.Ananyev@Sun.COM
340*8151SKonstantin.Ananyev@Sun.COM2:
341*8151SKonstantin.Ananyev@Sun.COM	movq	(%rax), %rcx			/* Are we done? */
342*8151SKonstantin.Ananyev@Sun.COM	cmpl	$FASTBOOT_TERMINATE, %ecx
343*8151SKonstantin.Ananyev@Sun.COM	je	1f
344*8151SKonstantin.Ananyev@Sun.COM
345*8151SKonstantin.Ananyev@Sun.COM	movq	%rcx, (%r8)
346*8151SKonstantin.Ananyev@Sun.COM	movq	%cr3, %rsi		/* Reload cr3 */
347*8151SKonstantin.Ananyev@Sun.COM	movq	%rsi, %cr3
348*8151SKonstantin.Ananyev@Sun.COM	movq	FB_VA(%rdx), %rsi	/* Load from VA */
349*8151SKonstantin.Ananyev@Sun.COM	movq	$PAGESIZE, %rcx
350*8151SKonstantin.Ananyev@Sun.COM	shrq	$3, %rcx		/* 8-byte at a time */
351*8151SKonstantin.Ananyev@Sun.COM	rep
352*8151SKonstantin.Ananyev@Sun.COM	  smovq
353*8151SKonstantin.Ananyev@Sun.COM	addq	$8, %rax 		/* Go to next PTE */
354*8151SKonstantin.Ananyev@Sun.COM	jmp	2b
355*8151SKonstantin.Ananyev@Sun.COM1:
356*8151SKonstantin.Ananyev@Sun.COM	ret
357*8151SKonstantin.Ananyev@Sun.COM	SET_SIZE(map_copy)
358*8151SKonstantin.Ananyev@Sun.COM
359*8151SKonstantin.Ananyev@Sun.COM#elif defined(__i386)
360*8151SKonstantin.Ananyev@Sun.COM
3617656SSherry.Moore@Sun.COM	ENTRY_NP(copy_sections)
3627656SSherry.Moore@Sun.COM	/*
3637656SSherry.Moore@Sun.COM	 * On entry
3647656SSherry.Moore@Sun.COM	 *	%edx points to the fboot_file_t
3657656SSherry.Moore@Sun.COM	 *	%eax contains the number of sections
3667656SSherry.Moore@Sun.COM	 */
3677656SSherry.Moore@Sun.COM	pushl	%ebp
3687656SSherry.Moore@Sun.COM	pushl	%ebx
3697656SSherry.Moore@Sun.COM	pushl	%esi
3707656SSherry.Moore@Sun.COM	pushl	%edi
3717656SSherry.Moore@Sun.COM
3727656SSherry.Moore@Sun.COM	movl	%eax, %ebp
3737656SSherry.Moore@Sun.COM
374*8151SKonstantin.Ananyev@Sun.COM	COPY_SECT(%edx, %ebx, %ebp)
375*8151SKonstantin.Ananyev@Sun.COM
3767656SSherry.Moore@Sun.COM	popl	%edi
3777656SSherry.Moore@Sun.COM	popl	%esi
3787656SSherry.Moore@Sun.COM	popl	%ebx
3797656SSherry.Moore@Sun.COM	popl	%ebp
3807656SSherry.Moore@Sun.COM	ret
3817656SSherry.Moore@Sun.COM	SET_SIZE(copy_sections)
3827656SSherry.Moore@Sun.COM
3837656SSherry.Moore@Sun.COM	ENTRY_NP(map_copy)
3847656SSherry.Moore@Sun.COM	/*
3857656SSherry.Moore@Sun.COM	 * On entry
3867656SSherry.Moore@Sun.COM	 *	%edx points to the fboot_file_t
3877656SSherry.Moore@Sun.COM	 *	%edi has FB_HAS_PAE(%esp)
3887656SSherry.Moore@Sun.COM	 *	%esi has FI_LAST_TABLE_PA(%esp)
3897656SSherry.Moore@Sun.COM	 */
3907656SSherry.Moore@Sun.COM	pushl	%eax
3917656SSherry.Moore@Sun.COM	pushl	%ebx
3927656SSherry.Moore@Sun.COM	pushl	%ecx
3937656SSherry.Moore@Sun.COM	pushl	%edx
3947656SSherry.Moore@Sun.COM	pushl	%ebp
3957656SSherry.Moore@Sun.COM	pushl	%esi
3967656SSherry.Moore@Sun.COM	pushl	%edi
3977656SSherry.Moore@Sun.COM	movl	%esi, %ebp	/* Save page table PA in %ebp */
3987656SSherry.Moore@Sun.COM
3997656SSherry.Moore@Sun.COM	movl	FB_PTE_LIST_PA(%edx), %eax	/* PA list of the source */
4007656SSherry.Moore@Sun.COM	movl	FB_DEST_PA(%edx), %ebx		/* PA of the destination */
4017656SSherry.Moore@Sun.COM
4027656SSherry.Moore@Sun.COMloop:
4037656SSherry.Moore@Sun.COM	movl	(%eax), %esi			/* Are we done? */
4047656SSherry.Moore@Sun.COM	cmpl	$FASTBOOT_TERMINATE, %esi
4057656SSherry.Moore@Sun.COM	je	done
4067656SSherry.Moore@Sun.COM
4077656SSherry.Moore@Sun.COM	cmpl	$1, (%esp)			/* Is paging on? */
4087656SSherry.Moore@Sun.COM	jne	no_paging			/* Nope */
4097656SSherry.Moore@Sun.COM
4107656SSherry.Moore@Sun.COM	movl	%ebp, %edi			/* Page table PA */
4117656SSherry.Moore@Sun.COM	movl	%esi, (%edi)			/* Program low 32-bit */
4127656SSherry.Moore@Sun.COM	movl	4(%eax), %esi			/* high bits of the table */
4137656SSherry.Moore@Sun.COM	movl	%esi, 4(%edi)			/* Program high 32-bit */
4147656SSherry.Moore@Sun.COM	movl	%cr3, %esi			/* Reload cr3 */
4157656SSherry.Moore@Sun.COM	movl	%esi, %cr3
4167656SSherry.Moore@Sun.COM	movl	FB_VA(%edx), %esi		/* Load from VA */
4177656SSherry.Moore@Sun.COM	jmp	do_copy
4187656SSherry.Moore@Sun.COMno_paging:
4197656SSherry.Moore@Sun.COM	andl	$_BITNOT(MMU_PAGEOFFSET), %esi	/* clear lower 12-bit */
4207656SSherry.Moore@Sun.COMdo_copy:
4217656SSherry.Moore@Sun.COM	movl	%ebx, %edi
4227656SSherry.Moore@Sun.COM	movl	$PAGESIZE, %ecx
4237656SSherry.Moore@Sun.COM	shrl	$2, %ecx	/* 4-byte at a time */
4247656SSherry.Moore@Sun.COM	rep
4257656SSherry.Moore@Sun.COM	  smovl
4267656SSherry.Moore@Sun.COM	addl	$8, %eax /* We built the PTEs as 8-byte entries */
4277656SSherry.Moore@Sun.COM	addl	$PAGESIZE, %ebx
4287656SSherry.Moore@Sun.COM	jmp	loop
4297656SSherry.Moore@Sun.COMdone:
4307656SSherry.Moore@Sun.COM	popl	%edi
4317656SSherry.Moore@Sun.COM	popl	%esi
4327656SSherry.Moore@Sun.COM	popl	%ebp
4337656SSherry.Moore@Sun.COM	popl	%edx
4347656SSherry.Moore@Sun.COM	popl	%ecx
4357656SSherry.Moore@Sun.COM	popl	%ebx
4367656SSherry.Moore@Sun.COM	popl	%eax
4377656SSherry.Moore@Sun.COM	ret
4387656SSherry.Moore@Sun.COM	SET_SIZE(map_copy)
439*8151SKonstantin.Ananyev@Sun.COM#endif	/* __i386 */
4407656SSherry.Moore@Sun.COM
4417656SSherry.Moore@Sun.COM
4427656SSherry.Moore@Sun.COMidt_info:
4437656SSherry.Moore@Sun.COM	.value	0x3ff
4447656SSherry.Moore@Sun.COM	.quad	0
4457656SSherry.Moore@Sun.COM
4467656SSherry.Moore@Sun.COM/*
4477656SSherry.Moore@Sun.COM * We need to trampoline thru a gdt we have in low memory.
4487656SSherry.Moore@Sun.COM */
4497656SSherry.Moore@Sun.COM#include "../boot/boot_gdt.s"
4507656SSherry.Moore@Sun.COM#endif /* __lint */
451