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