2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * CDDL HEADER START
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * The contents of this file are subject to the terms of the
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Common Development and Distribution License (the "License").
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * You may not use this file except in compliance with the License.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * or http://www.opensolaris.org/os/licensing.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * See the License for the specific language governing permissions
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * and limitations under the License.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * When distributing Covered Code, include this CDDL HEADER in each
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * If applicable, add the following below this CDDL HEADER, with the
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * fields enclosed by brackets "[]" replaced with your own identifying
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * information: Portions Copyright [yyyy] [name of copyright owner]
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * CDDL HEADER END
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
7417cfdecea1902cef03c0d61a72df97d945925dKuriakose Kuruvilla * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#include <sys/asm_linkage.h>
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#include <sys/asm_misc.h>
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#include <sys/regset.h>
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#include <sys/privregs.h>
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#include <sys/x86_archext.h>
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#include <sys/cpr_wakecode.h>
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if !defined(__lint)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#include <sys/segments.h>
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#include "assym.h"
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#ifdef DEBUG
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define LED 1
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define SERIAL 1
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif /* DEBUG */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#ifdef DEBUG
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define COM1 0x3f8
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define COM2 0x2f8
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define WC_COM COM2 /* either COM1 or COM2 */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define WC_LED 0x80 /* diagnostic led port ON motherboard */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan/*
1b1c71b2a16b821c15117fe73e4c435706a6272bjan * defined as offsets from the data register
1b1c71b2a16b821c15117fe73e4c435706a6272bjan */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define DLL 0 /* divisor latch (lsb) */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define DLH 1 /* divisor latch (msb) */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define LCR 3 /* line control register */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define MCR 4 /* modem control register */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define DLAB 0x80 /* divisor latch access bit */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define B9600L 0X0c /* lsb bit pattern for 9600 baud */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define B9600H 0X0 /* hsb bit pattern for 9600 baud */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define DTR 0x01 /* Data Terminal Ready */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define RTS 0x02 /* Request To Send */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define STOP1 0x00 /* 1 stop bit */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#define BITS8 0x03 /* 8 bits per char */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif /* DEBUG */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * This file contains the low level routines involved in getting
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * into and out of ACPI S3, including those needed for restarting
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * the non-boot cpus.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Our assumptions:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Our actions:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if defined(lint) || defined(__lint)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*ARGSUSED*/
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfint
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfwc_save_context(wc_cpu_t *pcpu)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf{ return 0; }
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#else /* lint */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if defined(__amd64)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ENTRY_NP(wc_save_context)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq (%rsp), %rdx / return address
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, WC_RETADDR(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf pushq %rbp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rsp,%rbp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdi, WC_VIRTADDR(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdi, WC_RDI(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, WC_RDX(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ stash everything else we need
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf sgdt WC_GDT(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf sidt WC_IDT(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf sldt WC_LDT(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf str WC_TR(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %cr0, %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, WC_CR0(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %cr3, %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, WC_CR3(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %cr4, %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, WC_CR4(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %cr8, %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, WC_CR8(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %r8, WC_R8(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %r9, WC_R9(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %r10, WC_R10(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %r11, WC_R11(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %r12, WC_R12(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %r13, WC_R13(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %r14, WC_R14(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %r15, WC_R15(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rax, WC_RAX(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rbp, WC_RBP(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rbx, WC_RBX(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rcx, WC_RCX(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rsi, WC_RSI(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rsp, WC_RSP(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ss, WC_SS(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %cs, WC_CS(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ds, WC_DS(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %es, WC_ES(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq $0, %rcx / save %fs register
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %fs, %cx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rcx, WC_FS(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl $MSR_AMD_FSBASE, %ecx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf rdmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, WC_FSBASE(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edx, WC_FSBASE+4(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq $0, %rcx / save %gs register
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %gs, %cx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rcx, WC_GS(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl $MSR_AMD_GSBASE, %ecx / save gsbase msr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf rdmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, WC_GSBASE(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edx, WC_GSBASE+4(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl $MSR_AMD_KGSBASE, %ecx / save kgsbase msr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf rdmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, WC_KGSBASE(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edx, WC_KGSBASE+4(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movq %gs:CPU_ID, %rax / save current cpu id
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movq %rax, WC_CPU_ID(%rdi)
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf pushfq
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf popq WC_EFLAGS(%rdi)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf wbinvd / flush the cache
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend mfence
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq $1, %rax / at suspend return 1
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf leave
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf SET_SIZE(wc_save_context)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#elif defined(__i386)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ENTRY_NP(wc_save_context)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl 4(%esp), %eax / wc_cpu_t *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, WC_VIRTADDR(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl (%esp), %edx / return address
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edx, WC_RETADDR(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf str WC_TR(%eax) / stash everything else we need
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf sgdt WC_GDT(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf sldt WC_LDT(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf sidt WC_IDT(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %cr0, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edx, WC_CR0(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %cr3, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edx, WC_CR3(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %cr4, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edx, WC_CR4(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %ebx, WC_EBX(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edi, WC_EDI(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %esi, WC_ESI(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %ebp, WC_EBP(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %esp, WC_ESP(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ss, WC_SS(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %cs, WC_CS(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ds, WC_DS(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %es, WC_ES(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %fs, WC_FS(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %gs, WC_GS(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf pushfl
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf popl WC_EFLAGS(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend pushl %gs:CPU_ID / save current cpu id
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend popl WC_CPU_ID(%eax)
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf wbinvd / flush the cache
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend mfence
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl $1, %eax / at suspend return 1
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf SET_SIZE(wc_save_context)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif /* __amd64 */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif /* lint */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Our assumptions:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * - We are running in real mode.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * - Interrupts are disabled.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Our actions:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * - We start using our GDT by loading correct values in the
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * selector registers (cs=KCS_SEL, ds=es=ss=KDS_SEL, fs=KFS_SEL,
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * gs=KGS_SEL).
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * - We change over to using our IDT.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * - We load the default LDT into the hardware LDT register.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * - We load the default TSS into the hardware task register.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * - We restore registers
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * - We return to original caller (a la setjmp)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if defined(lint) || defined(__lint)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfvoid
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfwc_rm_start(void)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf{}
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfvoid
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfwc_rm_end(void)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf{}
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#else /* lint */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if defined(__amd64)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ENTRY_NP(wc_rm_start)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe * For the Sun Studio 10 assembler we needed to do a .code32 and
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe * mentally invert the meaning of the addr16 and data16 prefixes to
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe * get 32-bit access when generating code to be executed in 16-bit
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe * mode (sigh...)
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe *
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe * This code, despite always being built with GNU as, has inherited
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe * the conceptual damage.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .code32
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf cli
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %cs, %ax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ax, %ds / establish ds ...
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ax, %ss / ... and ss:esp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movl $WC_STKSTART, %esp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ using the following value blows up machines! - DO NOT USE
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ D16 movl 0xffc, %esp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd1, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x61, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 call cominit
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Enable protected-mode, write protect, and alignment mask
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * %cr0 has already been initialsed to zero
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %cr0, %eax
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 orl $_CONST(CR0_PE|CR0_WP|CR0_AM), %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, %cr0
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Do a jmp immediately after writing to cr0 when enabling protected
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * mode to clear the real mode prefetch queue (per Intel's docs)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf jmp pestart
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfpestart:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd2, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x62, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * 16-bit protected mode is now active, so prepare to turn on long
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * mode
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd3, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x63, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Add any initial cr4 bits
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %cr4, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf A16 D16 orl CR4OFF, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Enable PAE mode (CR4.PAE)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 orl $CR4_PAE, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, %cr4
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd4, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x64, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Point cr3 to the 64-bit long mode page tables.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Note that these MUST exist in 32-bit space, as we don't have
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * a way to load %cr3 with a 64-bit base address for the page tables
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * until the CPU is actually executing in 64-bit long mode.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf A16 D16 movl CR3OFF, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, %cr3
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Set long mode enable in EFER (EFER.LME = 1)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movl $MSR_AMD_EFER, %ecx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf rdmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 orl $AMD_EFER_LME, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf wrmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd5, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x65, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Finally, turn on paging (CR0.PG = 1) to activate long mode.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %cr0, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 orl $CR0_PG, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, %cr0
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * The instruction after enabling paging in CR0 MUST be a branch.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf jmp long_mode_active
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyflong_mode_active:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd6, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x66, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Long mode is now active but since we're still running with the
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * original 16-bit CS we're actually in 16-bit compatability mode.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * We have to load an intermediate GDT and IDT here that we know are
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * in 32-bit space before we can use the kernel's GDT and IDT, which
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * may be in the 64-bit address space, and since we're in compatability
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * mode, we only have access to 16 and 32-bit instructions at the
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * moment.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf A16 D16 lgdt TEMPGDTOFF /* load temporary GDT */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf A16 D16 lidt TEMPIDTOFF /* load temporary IDT */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Do a far transfer to 64-bit mode. Set the CS selector to a 64-bit
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * long mode selector (CS.L=1) in the temporary 32-bit GDT and jump
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * to the real mode platter address of wc_long_mode_64 as until the
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * 64-bit CS is in place we don't have access to 64-bit instructions
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * and thus can't reference a 64-bit %rip.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd7, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x67, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 pushl $TEMP_CS64_SEL
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf A16 D16 pushl LM64OFF
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 lret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Support routine to re-initialize VGA subsystem
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfvgainit:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Support routine to re-initialize keyboard (which is USB - help!)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfkbdinit:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Support routine to re-initialize COM ports to something sane
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfcominit:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf / init COM1 & COM2
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if DEBUG
1b1c71b2a16b821c15117fe73e4c435706a6272bjan/*
1b1c71b2a16b821c15117fe73e4c435706a6272bjan * on debug kernels we need to initialize COM1 & COM2 here, so that
1b1c71b2a16b821c15117fe73e4c435706a6272bjan * we can get debug output before the asy driver has resumed
1b1c71b2a16b821c15117fe73e4c435706a6272bjan */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan/ select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+LCR), %edx
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $DLAB, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+DLL), %edx / divisor latch lsb
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $B9600L, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+DLH), %edx / divisor latch hsb
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $B9600H, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+LCR), %edx / select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movb $_CONST(STOP1|BITS8), %al / 1 stop bit, 8bit word len
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+MCR), %edx / select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movb $_CONST(RTS|DTR), %al / data term ready & req to send
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan/ select COM2
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+LCR), %edx
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $DLAB, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+DLL), %edx / divisor latch lsb
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $B9600L, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+DLH), %edx / divisor latch hsb
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $B9600H, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+LCR), %edx / select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movb $_CONST(STOP1|BITS8), %al / 1 stop bit, 8bit word len
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+MCR), %edx / select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movb $_CONST(RTS|DTR), %al / data term ready & req to send
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif /* DEBUG */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .code64
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .globl wc_long_mode_64
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfwc_long_mode_64:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xd8, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0x68, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * We are now running in long mode with a 64-bit CS (EFER.LMA=1,
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * CS.L=1) so we now have access to 64-bit instructions.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf *
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * First, set the 64-bit GDT base.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .globl rm_platter_pa
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl rm_platter_pa, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf lgdtq GDTROFF(%rax) /* load 64-bit GDT */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Save the CPU number in %r11; get the value here since it's saved in
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * the real mode platter.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ JAN
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ the following is wrong! need to figure out MP systems
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ movl CPUNOFF(%rax), %r11d
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Add rm_platter_pa to %rsp to point it to the same location as seen
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * from 64-bit mode.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf addq %rax, %rsp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Now do an lretq to load CS with the appropriate selector for the
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * kernel's 64-bit GDT and to start executing 64-bit setup code at the
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * virtual address where boot originally loaded this code rather than
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * the copy in the real mode platter's rm_code array as we've been
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * doing so far.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xd9, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ JAN this should produce 'i' but we get 'g' instead ???
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0x69, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf pushq $KCS_SEL
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf pushq $kernel_wc_code
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf lretq
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .globl kernel_wc_code
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfkernel_wc_code:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xda, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ JAN this should produce 'j' but we get 'g' instead ???
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0x6a, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Complete the balance of the setup we need to before executing
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * 64-bit kernel code (namely init rsp, TSS, LGDT, FS and GS).
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .globl rm_platter_va
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq rm_platter_va, %rbx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf addq $WC_CPU, %rbx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xdb, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw $0x6b, %ax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * restore the rest of the registers
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf lidtq WC_IDT(%rbx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xdc, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw $0x6c, %ax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * restore the rest of the registers
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw $KDS_SEL, %ax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ax, %ds
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ax, %es
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ax, %ss
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Before proceeding, enable usage of the page table NX bit if
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * that's how the page tables are set up.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
dfea898ab532c75e4d1426e0ff2cc5e0d67aa72fKuriakose Kuruvilla bt $X86FSET_NX, x86_featureset(%rip)
7417cfdecea1902cef03c0d61a72df97d945925dKuriakose Kuruvilla jnc 1f
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl $MSR_AMD_EFER, %ecx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf rdmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf orl $AMD_EFER_NXE, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf wrmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf1:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_CR4(%rbx), %rax / restore full cr4 (with Global Enable)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rax, %cr4
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf lldt WC_LDT(%rbx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movzwq WC_TR(%rbx), %rax / clear TSS busy bit
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf addq WC_GDT+2(%rbx), %rax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf andl $0xfffffdff, 4(%rax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq 4(%rax), %rcx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ltr WC_TR(%rbx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xdd, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw $0x6d, %ax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ restore %fsbase %gsbase %kgbase registers using wrmsr instruction
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_FS(%rbx), %rcx / restore fs register
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %cx, %fs
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl $MSR_AMD_FSBASE, %ecx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_FSBASE(%rbx), %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_FSBASE+4(%rbx), %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf wrmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_GS(%rbx), %rcx / restore gs register
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %cx, %gs
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl $MSR_AMD_GSBASE, %ecx / restore gsbase msr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_GSBASE(%rbx), %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_GSBASE+4(%rbx), %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf wrmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl $MSR_AMD_KGSBASE, %ecx / restore kgsbase msr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_KGSBASE(%rbx), %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_KGSBASE+4(%rbx), %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf wrmsr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_CR0(%rbx), %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, %cr0
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_CR3(%rbx), %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, %cr3
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_CR8(%rbx), %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rdx, %cr8
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xde, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0x6e, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend /*
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend * if we are not running on the boot CPU restore stack contents by
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend * calling i_cpr_restore_stack(curthread, save_stack);
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend */
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movq %rsp, %rbp
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend call i_cpr_bootcpuid
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend cmpl %eax, WC_CPU_ID(%rbx)
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend je 2f
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movq %gs:CPU_THREAD, %rdi
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movq WC_SAVED_STACK(%rbx), %rsi
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend call i_cpr_restore_stack
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend2:
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movq WC_RSP(%rbx), %rsp / restore stack pointer
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
bc4466305498eebc620bcefaac080629452b3156Guoli Shu * APIC initialization
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movq %rsp, %rbp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan /*
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan * skip iff function pointer is NULL
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan */
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan cmpq $0, ap_mlsetup
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend je 3f
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan call *ap_mlsetup
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend3:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf call *cpr_start_cpu_func
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ restore %rbx to the value it ahd before we called the functions above
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq rm_platter_va, %rbx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf addq $WC_CPU, %rbx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_R8(%rbx), %r8
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_R9(%rbx), %r9
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_R10(%rbx), %r10
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_R11(%rbx), %r11
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_R12(%rbx), %r12
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_R13(%rbx), %r13
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_R14(%rbx), %r14
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_R15(%rbx), %r15
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ movq WC_RAX(%rbx), %rax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RBP(%rbx), %rbp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RCX(%rbx), %rcx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ movq WC_RDX(%rbx), %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RDI(%rbx), %rdi
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RSI(%rbx), %rsi
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ assume that %cs does not need to be restored
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ %ds, %es & %ss are ignored in 64bit mode
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw WC_SS(%rbx), %ss
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw WC_DS(%rbx), %ds
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw WC_ES(%rbx), %es
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xdf, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0x6f, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RBP(%rbx), %rbp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RSP(%rbx), %rsp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xe0, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0x70, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RCX(%rbx), %rcx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf pushq WC_EFLAGS(%rbx) / restore flags
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf popfq
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_LED, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xe1, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan movw $WC_COM, %dx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0x71, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * can not use outb after this point, because doing so would mean using
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * %dx which would modify %rdx which is restored here
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rbx, %rax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RDX(%rax), %rdx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RBX(%rax), %rbx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf leave
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq WC_RETADDR(%rax), %rax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movq %rax, (%rsp) / return to caller of wc_save_context
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf xorl %eax, %eax / at wakeup return 0
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf SET_SIZE(wc_rm_start)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ENTRY_NP(asmspin)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %edi, %ecx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfA1:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf loop A1
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf SET_SIZE(asmspin)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .globl wc_rm_end
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfwc_rm_end:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf nop
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#elif defined(__i386)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ENTRY_NP(wc_rm_start)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/entry: jmp entry / stop here for HDT
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf cli
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %cs, %ax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ax, %ds / establish ds ...
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %ax, %ss / ... and ss:esp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movl $WC_STKSTART, %esp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd1, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x61, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 call vgainit
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 call kbdinit
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 call cominit
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_LED, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd2, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x62, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 A16 movl $WC_CPU, %ebx / base add of wc_cpu_t
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd3, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#if SERIAL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movl $WC_COM, %edx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0x63, %al
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf outb (%dx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 A16 movl %cs:WC_DS(%ebx), %edx / %ds post prot/paging transit
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd4, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 A16 lgdt %cs:WC_GDT(%ebx) / restore gdt and idtr
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 A16 lidt %cs:WC_IDT(%ebx)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd5, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 A16 movl %cs:WC_CR4(%ebx), %eax / restore cr4
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 andl $_BITNOT(CR4_PGE), %eax / don't set Global Enable yet
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, %cr4
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd6, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 A16 movl %cs:WC_CR3(%ebx), %eax / set PDPT
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, %cr3
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd7, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 A16 movl %cs:WC_CR0(%ebx), %eax / enable prot/paging, etc.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, %cr0
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd8, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 A16 movl %cs:WC_VIRTADDR(%ebx), %ebx / virtaddr of wc_cpu_t
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xd9, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xda, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf jmp flush / flush prefetch queue
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfflush:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 pushl $KCS_SEL
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 pushl $kernel_wc_code
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 lret / re-appear at kernel_wc_code
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Support routine to re-initialize VGA subsystem
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfvgainit:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Support routine to re-initialize keyboard (which is USB - help!)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfkbdinit:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/*
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf * Support routine to re-initialize COM ports to something sane for debug output
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfcominit:
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if DEBUG
1b1c71b2a16b821c15117fe73e4c435706a6272bjan/*
1b1c71b2a16b821c15117fe73e4c435706a6272bjan * on debug kernels we need to initialize COM1 & COM2 here, so that
1b1c71b2a16b821c15117fe73e4c435706a6272bjan * we can get debug output before the asy driver has resumed
1b1c71b2a16b821c15117fe73e4c435706a6272bjan */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan/ select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+LCR), %edx
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $DLAB, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+DLL), %edx / divisor latch lsb
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $B9600L, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+DLH), %edx / divisor latch hsb
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $B9600H, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+LCR), %edx / select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movb $_CONST(STOP1|BITS8), %al / 1 stop bit, 8bit word len
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM1+MCR), %edx / select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movb $_CONST(RTS|DTR), %al / 1 stop bit, 8bit word len
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan/ select COM2
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+LCR), %edx
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $DLAB, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+DLL), %edx / divisor latch lsb
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $B9600L, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+DLH), %edx / divisor latch hsb
1b1c71b2a16b821c15117fe73e4c435706a6272bjan D16 movb $B9600H, %al / divisor latch
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+LCR), %edx / select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movb $_CONST(STOP1|BITS8), %al / 1 stop bit, 8bit word len
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movl $_CONST(COM2+MCR), %edx / select COM1
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe D16 movb $_CONST(RTS|DTR), %al / 1 stop bit, 8bit word len
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb (%dx)
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif /* DEBUG */
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .globl wc_rm_end
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfwc_rm_end:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf nop
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf .globl kernel_wc_code
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyfkernel_wc_code:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf / At this point we are with kernel's cs and proper eip.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf / We will be executing not from the copy in real mode platter,
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf / but from the original code where boot loaded us.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf / By this time GDT and IDT are loaded as is cr0, cr3 and cr4.
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf / %ebx is wc_cpu
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf / %dx is our ds
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf D16 movb $0xdb, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/ got here OK
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movw %dx, %ds / $KDS_SEL
1b1c71b2a16b821c15117fe73e4c435706a6272bjan
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#if LED
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movb $0xdc, %al
1b1c71b2a16b821c15117fe73e4c435706a6272bjan outb $WC_LED
1b1c71b2a16b821c15117fe73e4c435706a6272bjan#endif
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan /*
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan * Before proceeding, enable usage of the page table NX bit if
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan * that's how the page tables are set up.
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan */
7417cfdecea1902cef03c0d61a72df97d945925dKuriakose Kuruvilla bt $X86FSET_NX, x86_featureset
7417cfdecea1902cef03c0d61a72df97d945925dKuriakose Kuruvilla jnc 1f
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan movl $MSR_AMD_EFER, %ecx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf rdmsr
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan orl $AMD_EFER_NXE, %eax
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf wrmsr
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan1:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_CR4(%ebx), %eax / restore full cr4 (with Global Enable)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, %cr4
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf lldt WC_LDT(%ebx) / $LDT_SEL
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movzwl WC_TR(%ebx), %eax / clear TSS busy bit
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf addl WC_GDT+2(%ebx), %eax
dad255286ee5ada77255c1f9f132ceee0bc314aaRichard Lowe andl $_BITNOT(0x200), 4(%eax)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ltr WC_TR(%ebx) / $UTSS_SEL
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movw WC_SS(%ebx), %ss / restore segment registers
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movw WC_ES(%ebx), %es
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movw WC_FS(%ebx), %fs
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movw WC_GS(%ebx), %gs
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend /*
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend * set the stack pointer to point into the identity mapped page
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend * temporarily, so we can make function calls
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend */
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend .globl rm_platter_va
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movl rm_platter_va, %eax
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movl $WC_STKSTART, %esp
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend addl %eax, %esp
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movl %esp, %ebp
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend /*
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend * if we are not running on the boot CPU restore stack contents by
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend * calling i_cpr_restore_stack(curthread, save_stack);
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend */
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend call i_cpr_bootcpuid
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend cmpl %eax, WC_CPU_ID(%ebx)
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend je 2f
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend pushl WC_SAVED_STACK(%ebx)
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend pushl %gs:CPU_THREAD
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend call i_cpr_restore_stack
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend addl $0x10, %esp
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend2:
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movl WC_ESP(%ebx), %esp
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend movl %esp, %ebp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_RETADDR(%ebx), %eax / return to caller of wc_save_context
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl %eax, (%esp)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf /*
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan * APIC initialization, skip iff function pointer is NULL
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf */
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan cmpl $0, ap_mlsetup
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend je 3f
4716fd887b81cd876928e6c03a0c6d0dcf362c90jan call *ap_mlsetup
3d995820f4ce8cd712d97f05aae6d30d9952d298Joseph A Townsend3:
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf call *cpr_start_cpu_func
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf pushl WC_EFLAGS(%ebx) / restore flags
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf popfl
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_EDI(%ebx), %edi / restore general registers
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_ESI(%ebx), %esi
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_EBP(%ebx), %ebp
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf movl WC_EBX(%ebx), %ebx
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf/exit: jmp exit / stop here for HDT
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf xorl %eax, %eax / at wakeup return 0
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf ret
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf SET_SIZE(wc_rm_start)
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif /* defined(__amd64) */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf#endif /* lint */
2df1fe9ca32bb227b9158c67f5c00b54c20b10fdrandyf