dboot_grub.s revision ae115bc77f6fcde83175c75b4206dc2e50747966
ae115bc77f6fcde83175c75b4206dc2e50747966mrj/*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * CDDL HEADER START
ae115bc77f6fcde83175c75b4206dc2e50747966mrj *
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * The contents of this file are subject to the terms of the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Common Development and Distribution License (the "License").
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * You may not use this file except in compliance with the License.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj *
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * or http://www.opensolaris.org/os/licensing.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * See the License for the specific language governing permissions
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * and limitations under the License.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj *
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * When distributing Covered Code, include this CDDL HEADER in each
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * If applicable, add the following below this CDDL HEADER, with the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * fields enclosed by brackets "[]" replaced with your own identifying
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * information: Portions Copyright [yyyy] [name of copyright owner]
ae115bc77f6fcde83175c75b4206dc2e50747966mrj *
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * CDDL HEADER END
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj/*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Use is subject to license terms.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#pragma ident "%Z%%M% %I% %E% SMI"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#if defined(__lint)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrjint silence_lint_warnings = 0;
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#else /* __lint */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#include <sys/multiboot.h>
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#include <sys/asm_linkage.h>
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#include <sys/segments.h>
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#include <sys/controlregs.h>
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#include "dboot_xboot.h"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .text
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .globl _start
ae115bc77f6fcde83175c75b4206dc2e50747966mrj_start:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj jmp code_start
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * The multiboot header has to be at the start of the file
ae115bc77f6fcde83175c75b4206dc2e50747966mrj *
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * The 32 bit kernel is ELF32, so the MB header is mostly ignored.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj *
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * The 64 bit kernel is ELF64, so we get grub to load the entire
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * ELF file into memory and trick it into jumping into this code.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * The trick is done by a binary utility run after unix is linked,
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * that rewrites the mb_header.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .align 4
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .globl mb_header
ae115bc77f6fcde83175c75b4206dc2e50747966mrjmb_header:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long MB_HEADER_MAGIC /* magic number */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long MB_HEADER_FLAGS /* flags */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long MB_HEADER_CHECKSUM /* checksum */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0x11111111 /* header_addr: patched by elfpatch */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0x100000 /* load_addr: patched by elfpatch */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0 /* load_end_addr - 0 means entire file */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0 /* bss_end_addr */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0x2222222 /* entry_addr: patched by elfpatch */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0 /* video mode.. */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0 /* width 0 == don't care */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0 /* height 0 == don't care */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .long 0 /* depth 0 == don't care */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * At entry we are in protected mode, 32 bit execution, paging and
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * interrupts are disabled.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj *
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * EAX == 0x2BADB002
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * EBX points to multiboot information
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * segment registers all have segments with base 0, limit == 0xffffffff
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrjcode_start:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %ebx, mb_info
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl $stack_space, %esp /* load my stack pointer */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj addl $STACK_SIZE, %esp
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushl $0x0 /* push a dead-end frame */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushl $0x0
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %esp, %ebp
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushl $0x0 /* clear all processor flags */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj popf
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * setup a global descriptor table with known contents
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj lgdt gdt_info
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movw $B32DATA_SEL, %ax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movw %ax, %ds
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movw %ax, %es
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movw %ax, %fs
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movw %ax, %gs
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movw %ax, %ss
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ljmp $B32CODE_SEL, $newgdt
ae115bc77f6fcde83175c75b4206dc2e50747966mrjnewgdt:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj nop
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * go off and determine memory config, build page tables, etc.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj call startup_kernel
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * On amd64 we'll want the stack pointer to be 16 byte aligned.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj andl $0xfffffff0, %esp
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Enable PGE, PAE and large pages
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %cr4, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj testl $1, pge_support
ae115bc77f6fcde83175c75b4206dc2e50747966mrj jz 1f
ae115bc77f6fcde83175c75b4206dc2e50747966mrj orl $CR4_PGE, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj1:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj testl $1, pae_support
ae115bc77f6fcde83175c75b4206dc2e50747966mrj jz 1f
ae115bc77f6fcde83175c75b4206dc2e50747966mrj orl $CR4_PAE, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj1:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj testl $1, largepage_support
ae115bc77f6fcde83175c75b4206dc2e50747966mrj jz 1f
ae115bc77f6fcde83175c75b4206dc2e50747966mrj orl $CR4_PSE, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj1:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %eax, %cr4
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * enable NX protection if processor supports it
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj testl $1, NX_support
ae115bc77f6fcde83175c75b4206dc2e50747966mrj jz 1f
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl $MSR_AMD_EFER, %ecx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj rdmsr
ae115bc77f6fcde83175c75b4206dc2e50747966mrj orl $AMD_EFER_NXE, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj wrmsr
ae115bc77f6fcde83175c75b4206dc2e50747966mrj1:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * load the pagetable base address into cr3
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl top_page_table, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %eax, %cr3
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#if defined(_BOOT_TARGET_amd64)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * enable long mode
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl $MSR_AMD_EFER, %ecx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj rdmsr
ae115bc77f6fcde83175c75b4206dc2e50747966mrj orl $AMD_EFER_LME, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj wrmsr
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#endif
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * enable paging
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %cr0, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj orl $CR0_PG, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %eax, %cr0
ae115bc77f6fcde83175c75b4206dc2e50747966mrj jmp paging_on
ae115bc77f6fcde83175c75b4206dc2e50747966mrjpaging_on:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * The xboot_info ptr gets passed to the kernel as its argument
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl bi, %edi
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl entry_addr_low, %esi
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#if defined(_BOOT_TARGET_i386)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushl %edi
ae115bc77f6fcde83175c75b4206dc2e50747966mrj call *%esi
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#elif defined(_BOOT_TARGET_amd64)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * We're still in compatibility mode with 32 bit execution.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Switch to 64 bit mode now by switching to a 64 bit code segment.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * then set up and do a lret to get into 64 bit execution.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushl $B64CODE_SEL
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushl $longmode
ae115bc77f6fcde83175c75b4206dc2e50747966mrj lret
ae115bc77f6fcde83175c75b4206dc2e50747966mrjlongmode:
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .code64
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movq $0xffffffff00000000,%rdx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj orq %rdx, %rsi /* set upper bits of entry addr */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj notq %rdx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj andq %rdx, %rdi /* clean %rdi for passing arg */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj call *%rsi
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#else
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#error "undefined target"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#endif
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj .code32
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * uint8_t inb(int port)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ENTRY_NP(inb)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl 4(%esp), %edx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj inb (%dx)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj andl $0xff, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ret
ae115bc77f6fcde83175c75b4206dc2e50747966mrj SET_SIZE(inb)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * void outb(int port, uint8_t value)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ENTRY_NP(outb)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl 4(%esp), %edx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl 8(%esp), %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj outb (%dx)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ret
ae115bc77f6fcde83175c75b4206dc2e50747966mrj SET_SIZE(outb)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * if reset fails halt the system
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ENTRY_NP(dboot_halt)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj hlt
ae115bc77f6fcde83175c75b4206dc2e50747966mrj SET_SIZE(dboot_halt)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * flush the TLB
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ENTRY_NP(reload_cr3)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %cr3, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %eax, %cr3
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ret
ae115bc77f6fcde83175c75b4206dc2e50747966mrj SET_SIZE(reload_cr3)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * do a cpuid instruction, returning the eax/edx values
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ENTRY_NP(get_cpuid_edx)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl 4(%esp), %ecx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl (%ecx), %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushl %ebx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj cpuid
ae115bc77f6fcde83175c75b4206dc2e50747966mrj popl %ebx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl 4(%esp), %ecx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %eax, (%ecx)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %edx, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ret
ae115bc77f6fcde83175c75b4206dc2e50747966mrj SET_SIZE(get_cpuid_edx)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj /*
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Detect if we can do cpuid, see if we can change bit 21 of eflags.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Note we don't do the bizarre tests for Cyrix CPUs in ml/locore.s.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * If you're on such a CPU, you're stuck with non-PAE 32 bit kernels.
ae115bc77f6fcde83175c75b4206dc2e50747966mrj */
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ENTRY_NP(have_cpuid)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushf
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushf
ae115bc77f6fcde83175c75b4206dc2e50747966mrj xorl %eax, %eax
ae115bc77f6fcde83175c75b4206dc2e50747966mrj popl %ecx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj movl %ecx, %edx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj xorl $0x200000, %ecx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushl %ecx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj popf
ae115bc77f6fcde83175c75b4206dc2e50747966mrj pushf
ae115bc77f6fcde83175c75b4206dc2e50747966mrj popl %ecx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj cmpl %ecx, %edx
ae115bc77f6fcde83175c75b4206dc2e50747966mrj setne %al
ae115bc77f6fcde83175c75b4206dc2e50747966mrj popf
ae115bc77f6fcde83175c75b4206dc2e50747966mrj ret
ae115bc77f6fcde83175c75b4206dc2e50747966mrj SET_SIZE(have_cpuid)
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#include "../boot/boot_gdt.s"
ae115bc77f6fcde83175c75b4206dc2e50747966mrj
ae115bc77f6fcde83175c75b4206dc2e50747966mrj#endif /* __lint */