1*cb5172cdSderaadt/* $OpenBSD: locore.S,v 1.87 2017/07/06 06:17:04 deraadt Exp $ */ 2b5b9857bSart/* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ 3f5df1827Smickey 4f5df1827Smickey/* 5f5df1827Smickey * Copyright-o-rama! 6f5df1827Smickey */ 7f5df1827Smickey 8f5df1827Smickey/* 9f5df1827Smickey * Copyright (c) 2001 Wasabi Systems, Inc. 10f5df1827Smickey * All rights reserved. 11f5df1827Smickey * 12f5df1827Smickey * Written by Frank van der Linden for Wasabi Systems, Inc. 13f5df1827Smickey * 14f5df1827Smickey * Redistribution and use in source and binary forms, with or without 15f5df1827Smickey * modification, are permitted provided that the following conditions 16f5df1827Smickey * are met: 17f5df1827Smickey * 1. Redistributions of source code must retain the above copyright 18f5df1827Smickey * notice, this list of conditions and the following disclaimer. 19f5df1827Smickey * 2. Redistributions in binary form must reproduce the above copyright 20f5df1827Smickey * notice, this list of conditions and the following disclaimer in the 21f5df1827Smickey * documentation and/or other materials provided with the distribution. 22f5df1827Smickey * 3. All advertising materials mentioning features or use of this software 23f5df1827Smickey * must display the following acknowledgement: 24f5df1827Smickey * This product includes software developed for the NetBSD Project by 25f5df1827Smickey * Wasabi Systems, Inc. 26f5df1827Smickey * 4. The name of Wasabi Systems, Inc. may not be used to endorse 27f5df1827Smickey * or promote products derived from this software without specific prior 28f5df1827Smickey * written permission. 29f5df1827Smickey * 30f5df1827Smickey * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 31f5df1827Smickey * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 32f5df1827Smickey * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 33f5df1827Smickey * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 34f5df1827Smickey * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 35f5df1827Smickey * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 36f5df1827Smickey * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 37f5df1827Smickey * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 38f5df1827Smickey * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39f5df1827Smickey * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 40f5df1827Smickey * POSSIBILITY OF SUCH DAMAGE. 41f5df1827Smickey */ 42f5df1827Smickey 43f5df1827Smickey 44f5df1827Smickey/*- 45f5df1827Smickey * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. 46f5df1827Smickey * All rights reserved. 47f5df1827Smickey * 48f5df1827Smickey * This code is derived from software contributed to The NetBSD Foundation 49f5df1827Smickey * by Charles M. Hannum. 50f5df1827Smickey * 51f5df1827Smickey * Redistribution and use in source and binary forms, with or without 52f5df1827Smickey * modification, are permitted provided that the following conditions 53f5df1827Smickey * are met: 54f5df1827Smickey * 1. Redistributions of source code must retain the above copyright 55f5df1827Smickey * notice, this list of conditions and the following disclaimer. 56f5df1827Smickey * 2. Redistributions in binary form must reproduce the above copyright 57f5df1827Smickey * notice, this list of conditions and the following disclaimer in the 58f5df1827Smickey * documentation and/or other materials provided with the distribution. 59f5df1827Smickey * 60f5df1827Smickey * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 61f5df1827Smickey * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 62f5df1827Smickey * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 63f5df1827Smickey * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 64f5df1827Smickey * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 65f5df1827Smickey * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 66f5df1827Smickey * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 67f5df1827Smickey * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 68f5df1827Smickey * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 69f5df1827Smickey * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 70f5df1827Smickey * POSSIBILITY OF SUCH DAMAGE. 71f5df1827Smickey */ 72f5df1827Smickey 73f5df1827Smickey/*- 74f5df1827Smickey * Copyright (c) 1990 The Regents of the University of California. 75f5df1827Smickey * All rights reserved. 76f5df1827Smickey * 77f5df1827Smickey * This code is derived from software contributed to Berkeley by 78f5df1827Smickey * William Jolitz. 79f5df1827Smickey * 80f5df1827Smickey * Redistribution and use in source and binary forms, with or without 81f5df1827Smickey * modification, are permitted provided that the following conditions 82f5df1827Smickey * are met: 83f5df1827Smickey * 1. Redistributions of source code must retain the above copyright 84f5df1827Smickey * notice, this list of conditions and the following disclaimer. 85f5df1827Smickey * 2. Redistributions in binary form must reproduce the above copyright 86f5df1827Smickey * notice, this list of conditions and the following disclaimer in the 87f5df1827Smickey * documentation and/or other materials provided with the distribution. 88b5b9857bSart * 3. Neither the name of the University nor the names of its contributors 89f5df1827Smickey * may be used to endorse or promote products derived from this software 90f5df1827Smickey * without specific prior written permission. 91f5df1827Smickey * 92f5df1827Smickey * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 93f5df1827Smickey * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94f5df1827Smickey * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 95f5df1827Smickey * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 96f5df1827Smickey * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 97f5df1827Smickey * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 98f5df1827Smickey * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 99f5df1827Smickey * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 100f5df1827Smickey * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 101f5df1827Smickey * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 102f5df1827Smickey * SUCH DAMAGE. 103f5df1827Smickey * 104f5df1827Smickey * @(#)locore.s 7.3 (Berkeley) 5/13/91 105f5df1827Smickey */ 106f5df1827Smickey 107f5df1827Smickey#include "assym.h" 108f5df1827Smickey#include "lapic.h" 109f5df1827Smickey#include "ksyms.h" 110d8213a49Smikeb#include "xen.h" 111218ead0bSmikeb#include "hyperv.h" 112f5df1827Smickey 113f5df1827Smickey#include <sys/syscall.h> 114f5df1827Smickey 115f5df1827Smickey#include <machine/param.h> 116f5df1827Smickey#include <machine/segments.h> 117f5df1827Smickey#include <machine/specialreg.h> 118f5df1827Smickey#include <machine/trap.h> 119f5df1827Smickey#include <machine/frameasm.h> 120f5df1827Smickey 121f5df1827Smickey#if NLAPIC > 0 122f5df1827Smickey#include <machine/i82489reg.h> 123f5df1827Smickey#endif 124f5df1827Smickey 125f5df1827Smickey/* 126f5df1827Smickey * override user-land alignment before including asm.h 127f5df1827Smickey */ 128*cb5172cdSderaadt#define ALIGN_DATA .align 8,0xcc 129f5df1827Smickey#define ALIGN_TEXT .align 16,0x90 130f5df1827Smickey#define _ALIGN_TEXT ALIGN_TEXT 131f5df1827Smickey 132f5df1827Smickey#include <machine/asm.h> 133f5df1827Smickey 134fbe53cacSkrw#define SET_CURPROC(proc,cpu) \ 135fbe53cacSkrw movq CPUVAR(SELF),cpu ; \ 136fbe53cacSkrw movq proc,CPUVAR(CURPROC) ; \ 137fbe53cacSkrw movq cpu,P_CPU(proc) 138fbe53cacSkrw 139fbe53cacSkrw#define GET_CURPCB(reg) movq CPUVAR(CURPCB),reg 140fbe53cacSkrw#define SET_CURPCB(reg) movq reg,CPUVAR(CURPCB) 141fbe53cacSkrw 142fbe53cacSkrw 143f5df1827Smickey/* 144f5df1827Smickey * Initialization 145f5df1827Smickey */ 146f5df1827Smickey .data 147f5df1827Smickey 148f5df1827Smickey#if NLAPIC > 0 1490175496dSderaadt .align NBPG, 0xcc 150f5df1827Smickey .globl _C_LABEL(local_apic), _C_LABEL(lapic_id), _C_LABEL(lapic_tpr) 151f5df1827Smickey_C_LABEL(local_apic): 152f5df1827Smickey .space LAPIC_ID 153f5df1827Smickey_C_LABEL(lapic_id): 154f5df1827Smickey .long 0x00000000 155f5df1827Smickey .space LAPIC_TPRI-(LAPIC_ID+4) 156f5df1827Smickey_C_LABEL(lapic_tpr): 157f5df1827Smickey .space LAPIC_PPRI-LAPIC_TPRI 158f5df1827Smickey_C_LABEL(lapic_ppr): 159f5df1827Smickey .space LAPIC_ISR-LAPIC_PPRI 160f5df1827Smickey_C_LABEL(lapic_isr): 161f5df1827Smickey .space NBPG-LAPIC_ISR 162f5df1827Smickey#endif 163f5df1827Smickey 164576d2332Smlarkin .globl _C_LABEL(cpu_id),_C_LABEL(cpu_vendor) 165f5df1827Smickey .globl _C_LABEL(cpuid_level),_C_LABEL(cpu_feature) 1667196220cSmlarkin .globl _C_LABEL(cpu_ebxfeature) 1676995b18fShaesbaert .globl _C_LABEL(cpu_ecxfeature),_C_LABEL(ecpu_ecxfeature) 16807166672Smglocker .globl _C_LABEL(cpu_perf_eax) 16907166672Smglocker .globl _C_LABEL(cpu_perf_ebx) 17007166672Smglocker .globl _C_LABEL(cpu_perf_edx) 17107166672Smglocker .globl _C_LABEL(cpu_apmi_edx) 172886c356bSmlarkin .globl _C_LABEL(ssym),_C_LABEL(esym),_C_LABEL(boothowto) 173886c356bSmlarkin .globl _C_LABEL(bootdev) 1746483bf47Sderaadt .globl _C_LABEL(bootinfo), _C_LABEL(bootinfo_size), _C_LABEL(atdevbase) 175f5df1827Smickey .globl _C_LABEL(proc0paddr),_C_LABEL(PTDpaddr) 176f5df1827Smickey .globl _C_LABEL(biosbasemem),_C_LABEL(biosextmem) 1776483bf47Sderaadt .globl _C_LABEL(bootapiver) 17836414dbbSmlarkin .globl _C_LABEL(pg_nx) 179f5df1827Smickey_C_LABEL(cpu_id): .long 0 # saved from `cpuid' instruction 180f5df1827Smickey_C_LABEL(cpu_feature): .long 0 # feature flags from 'cpuid' 181f5df1827Smickey # instruction 1827196220cSmlarkin_C_LABEL(cpu_ebxfeature):.long 0 # ext. ebx feature flags from 'cpuid' 1837196220cSmlarkin_C_LABEL(cpu_ecxfeature):.long 0 # ext. ecx feature flags from 'cpuid' 1846995b18fShaesbaert_C_LABEL(ecpu_ecxfeature):.long 0 # extended ecx feature flags 18507166672Smglocker_C_LABEL(cpu_perf_eax): .long 0 # arch. perf. mon. flags from 'cpuid' 18607166672Smglocker_C_LABEL(cpu_perf_ebx): .long 0 # arch. perf. mon. flags from 'cpuid' 18707166672Smglocker_C_LABEL(cpu_perf_edx): .long 0 # arch. perf. mon. flags from 'cpuid' 18807166672Smglocker_C_LABEL(cpu_apmi_edx): .long 0 # adv. power mgmt. info. from 'cpuid' 189f5df1827Smickey_C_LABEL(cpuid_level): .long -1 # max. level accepted by 'cpuid' 190f5df1827Smickey # instruction 191f5df1827Smickey_C_LABEL(cpu_vendor): .space 16 # vendor string returned by `cpuid' 192f5df1827Smickey # instruction 193c7636a68Smlarkin_C_LABEL(ssym): .quad 0 # ptr to start of syms 194f5df1827Smickey_C_LABEL(esym): .quad 0 # ptr to end of syms 195f5df1827Smickey_C_LABEL(atdevbase): .quad 0 # location of start of iomem in virtual 196e9dacf7aStom_C_LABEL(bootapiver): .long 0 # /boot API version 197f431e893Smillert_C_LABEL(bootdev): .long 0 # device we booted from 198f5df1827Smickey_C_LABEL(proc0paddr): .quad 0 199f5df1827Smickey_C_LABEL(PTDpaddr): .quad 0 # paddr of PTD, for libkvm 200f5df1827Smickey#ifndef REALBASEMEM 201f5df1827Smickey_C_LABEL(biosbasemem): .long 0 # base memory reported by BIOS 202f5df1827Smickey#else 203f5df1827Smickey_C_LABEL(biosbasemem): .long REALBASEMEM 204f5df1827Smickey#endif 205f5df1827Smickey#ifndef REALEXTMEM 206f5df1827Smickey_C_LABEL(biosextmem): .long 0 # extended memory reported by BIOS 207f5df1827Smickey#else 208f5df1827Smickey_C_LABEL(biosextmem): .long REALEXTMEM 209f5df1827Smickey#endif 21036414dbbSmlarkin_C_LABEL(pg_nx): .quad 0 # NX PTE bit (if CPU supports) 211f5df1827Smickey 212f5df1827Smickey#define _RELOC(x) ((x) - KERNBASE) 213f5df1827Smickey#define RELOC(x) _RELOC(_C_LABEL(x)) 214f5df1827Smickey 215f5df1827Smickey .globl gdt64 216f5df1827Smickey 217f5df1827Smickeygdt64: 218029cc5b9Smikeb .word gdt64_end-gdt64_start-1 219f5df1827Smickey .quad _RELOC(gdt64_start) 2200175496dSderaadt.align 64, 0xcc 221f5df1827Smickey 222f5df1827Smickeygdt64_start: 223f5df1827Smickey .quad 0x0000000000000000 /* always empty */ 224f5df1827Smickey .quad 0x00af9a000000ffff /* kernel CS */ 225f5df1827Smickey .quad 0x00cf92000000ffff /* kernel DS */ 226f5df1827Smickeygdt64_end: 227f5df1827Smickey 228f5df1827Smickey/* 229f5df1827Smickey * Some hackage to deal with 64bit symbols in 32 bit mode. 230e9dacf7aStom * This may not be needed if things are cleaned up a little. 231f5df1827Smickey */ 232f5df1827Smickey 233f5df1827Smickey/*****************************************************************************/ 234f5df1827Smickey 235f5df1827Smickey/* 236f5df1827Smickey * Signal trampoline; copied to top of user stack. 237aa7a0a27Sguenther * gdb's backtrace logic matches against the instructions in this. 238f5df1827Smickey */ 239b983598cSderaadt .section .rodata 240b983598cSderaadt .globl _C_LABEL(sigcode) 241b983598cSderaadt_C_LABEL(sigcode): 242f5df1827Smickey call *%rax 243f5df1827Smickey 244f5df1827Smickey movq %rsp,%rdi 245f5df1827Smickey pushq %rdi /* fake return address */ 246f5df1827Smickey movq $SYS_sigreturn,%rax 2471396572dSguenther syscall 2487730d1d9Sderaadt .globl _C_LABEL(sigcoderet) 2497730d1d9Sderaadt_C_LABEL(sigcoderet): 250f5df1827Smickey movq $SYS_exit,%rax 251f5df1827Smickey syscall 252f5df1827Smickey .globl _C_LABEL(esigcode) 253f5df1827Smickey_C_LABEL(esigcode): 254f5df1827Smickey 255b983598cSderaadt .globl _C_LABEL(sigfill) 256b983598cSderaadt_C_LABEL(sigfill): 257b983598cSderaadt int3 258b983598cSderaadt_C_LABEL(esigfill): 259b983598cSderaadt .globl _C_LABEL(sigfillsiz) 260b983598cSderaadt_C_LABEL(sigfillsiz): 261b983598cSderaadt .long _C_LABEL(esigfill) - _C_LABEL(sigfill) 262b983598cSderaadt 263b983598cSderaadt .text 264f5df1827Smickey/* 265f5df1827Smickey * void lgdt(struct region_descriptor *rdp); 266f5df1827Smickey * Change the global descriptor table. 267f5df1827Smickey */ 268f5df1827SmickeyNENTRY(lgdt) 269f5df1827Smickey /* Reload the descriptor table. */ 270f5df1827Smickey movq %rdi,%rax 271f5df1827Smickey lgdt (%rax) 272f5df1827Smickey /* Flush the prefetch q. */ 273f5df1827Smickey jmp 1f 274f5df1827Smickey nop 275f5df1827Smickey1: /* Reload "stale" selectors. */ 276f5df1827Smickey movl $GSEL(GDATA_SEL, SEL_KPL),%eax 277f5df1827Smickey movl %eax,%ds 278f5df1827Smickey movl %eax,%es 279f5df1827Smickey movl %eax,%ss 280f5df1827Smickey /* Reload code selector by doing intersegment return. */ 281f5df1827Smickey popq %rax 282f5df1827Smickey pushq $GSEL(GCODE_SEL, SEL_KPL) 283f5df1827Smickey pushq %rax 284f5df1827Smickey lretq 285f5df1827Smickey 286f5df1827SmickeyENTRY(setjmp) 287f5df1827Smickey /* 288f5df1827Smickey * Only save registers that must be preserved across function 289f5df1827Smickey * calls according to the ABI (%rbx, %rsp, %rbp, %r12-%r15) 290f5df1827Smickey * and %rip. 291f5df1827Smickey */ 292f5df1827Smickey movq %rdi,%rax 293f5df1827Smickey movq %rbx,(%rax) 294f5df1827Smickey movq %rsp,8(%rax) 295f5df1827Smickey movq %rbp,16(%rax) 296f5df1827Smickey movq %r12,24(%rax) 297f5df1827Smickey movq %r13,32(%rax) 298f5df1827Smickey movq %r14,40(%rax) 299f5df1827Smickey movq %r15,48(%rax) 300f5df1827Smickey movq (%rsp),%rdx 301f5df1827Smickey movq %rdx,56(%rax) 302f5df1827Smickey xorl %eax,%eax 303f5df1827Smickey ret 304f5df1827Smickey 305f5df1827SmickeyENTRY(longjmp) 306f5df1827Smickey movq %rdi,%rax 307f5df1827Smickey movq (%rax),%rbx 308f5df1827Smickey movq 8(%rax),%rsp 309f5df1827Smickey movq 16(%rax),%rbp 310f5df1827Smickey movq 24(%rax),%r12 311f5df1827Smickey movq 32(%rax),%r13 312f5df1827Smickey movq 40(%rax),%r14 313f5df1827Smickey movq 48(%rax),%r15 314f5df1827Smickey movq 56(%rax),%rdx 315f5df1827Smickey movq %rdx,(%rsp) 316f5df1827Smickey xorl %eax,%eax 317f5df1827Smickey incl %eax 318f5df1827Smickey ret 319f5df1827Smickey 320f5df1827Smickey/*****************************************************************************/ 321f5df1827Smickey 322f5df1827Smickey/* 32345053f4aSart * int cpu_switchto(struct proc *old, struct proc *new) 32445053f4aSart * Switch from "old" proc to "new". 325f5df1827Smickey */ 32645053f4aSartENTRY(cpu_switchto) 327f5df1827Smickey pushq %rbx 328f5df1827Smickey pushq %rbp 329f5df1827Smickey pushq %r12 330f5df1827Smickey pushq %r13 331f5df1827Smickey pushq %r14 332f5df1827Smickey pushq %r15 333f5df1827Smickey 334fbe53cacSkrw movq %rdi, %r13 335fbe53cacSkrw movq %rsi, %r12 336fbe53cacSkrw 33760854cb9Sguenther /* Record new proc. */ 338fbe53cacSkrw movb $SONPROC,P_STAT(%r12) # p->p_stat = SONPROC 339fbe53cacSkrw SET_CURPROC(%r12,%rcx) 34060854cb9Sguenther 341fd94711fSguenther movl CPUVAR(CPUID),%edi 342fd94711fSguenther 343fbe53cacSkrw /* If old proc exited, don't bother. */ 344fbe53cacSkrw testq %r13,%r13 345f5df1827Smickey jz switch_exited 346f5df1827Smickey 347fbe53cacSkrw /* 348fbe53cacSkrw * Save old context. 349fbe53cacSkrw * 350fbe53cacSkrw * Registers: 351fbe53cacSkrw * %rax, %rcx - scratch 352fbe53cacSkrw * %r13 - old proc, then old pcb 353fbe53cacSkrw * %r12 - new proc 354fd94711fSguenther * %edi - cpuid 355fbe53cacSkrw */ 356fbe53cacSkrw 357fbe53cacSkrw movq P_ADDR(%r13),%r13 358fbe53cacSkrw 359fd94711fSguenther /* clear the old pmap's bit for the cpu */ 360fd94711fSguenther movq PCB_PMAP(%r13),%rcx 361fd94711fSguenther lock 362f5e1db71Sguenther btrq %rdi,PM_CPUS(%rcx) 363fd94711fSguenther 364f5df1827Smickey /* Save stack pointers. */ 365f5df1827Smickey movq %rsp,PCB_RSP(%r13) 366f5df1827Smickey movq %rbp,PCB_RBP(%r13) 367fbe53cacSkrw 368f5df1827Smickeyswitch_exited: 369b13138f2Sguenther /* did old proc run in userspace? then reset the segment regs */ 370b13138f2Sguenther btrl $CPUF_USERSEGS_BIT, CPUVAR(FLAGS) 371b13138f2Sguenther jnc restore_saved 372b13138f2Sguenther 373b13138f2Sguenther /* set %ds, %es, and %fs to expected value to prevent info leak */ 374b13138f2Sguenther movw $(GSEL(GUDATA_SEL, SEL_UPL)),%ax 375b13138f2Sguenther movw %ax,%ds 376b13138f2Sguenther movw %ax,%es 377b13138f2Sguenther movw %ax,%fs 378b13138f2Sguenther 379b13138f2Sguentherrestore_saved: 380f5df1827Smickey /* 38145053f4aSart * Restore saved context. 382f5df1827Smickey * 383f5df1827Smickey * Registers: 384f5df1827Smickey * %rax, %rcx, %rdx - scratch 385f5df1827Smickey * %r13 - new pcb 386fbe53cacSkrw * %r12 - new process 387f5df1827Smickey */ 388f5df1827Smickey 389fbe53cacSkrw /* No interrupts while loading new state. */ 390fbe53cacSkrw cli 391fbe53cacSkrw movq P_ADDR(%r12),%r13 392fbe53cacSkrw 393f5df1827Smickey /* Restore stack pointers. */ 394f5df1827Smickey movq PCB_RSP(%r13),%rsp 395f5df1827Smickey movq PCB_RBP(%r13),%rbp 396f5df1827Smickey 397fd94711fSguenther movq CPUVAR(TSS),%rcx 398fd94711fSguenther movq PCB_KSTACK(%r13),%rdx 399fd94711fSguenther movq %rdx,TSS_RSP0(%rcx) 400fd94711fSguenther 401fd94711fSguenther movq PCB_CR3(%r13),%rax 402fd94711fSguenther movq %rax,%cr3 403fd94711fSguenther 404fbe53cacSkrw /* Don't bother with the rest if switching to a system process. */ 405fbe53cacSkrw testl $P_SYSTEM,P_FLAG(%r12) 406fbe53cacSkrw jnz switch_restored 407fd94711fSguenther 408fd94711fSguenther /* set the new pmap's bit for the cpu */ 409fd94711fSguenther movl CPUVAR(CPUID),%edi 410fd94711fSguenther movq PCB_PMAP(%r13),%rcx 411fd94711fSguenther lock 412f5e1db71Sguenther btsq %rdi,PM_CPUS(%rcx) 413fd94711fSguenther#ifdef DIAGNOSTIC 414fd94711fSguenther jc _C_LABEL(switch_pmcpu_set) 415fbe53cacSkrw#endif 416f5df1827Smickey 417fbe53cacSkrwswitch_restored: 418f5df1827Smickey /* Restore cr0 (including FPU state). */ 419f5df1827Smickey movl PCB_CR0(%r13),%ecx 420f5df1827Smickey#ifdef MULTIPROCESSOR 421f5df1827Smickey movq PCB_FPCPU(%r13),%r8 422f5df1827Smickey cmpq CPUVAR(SELF),%r8 423f5df1827Smickey jz 1f 424f5df1827Smickey orl $CR0_TS,%ecx 425f5df1827Smickey1: 426f5df1827Smickey#endif 427f5df1827Smickey movq %rcx,%cr0 428f5df1827Smickey 429fbe53cacSkrw SET_CURPCB(%r13) 430fbe53cacSkrw 431f5df1827Smickey /* Interrupts are okay again. */ 432f5df1827Smickey sti 433f5df1827Smickey 434fbe53cacSkrwswitch_return: 435fbe53cacSkrw 436f5df1827Smickey popq %r15 437f5df1827Smickey popq %r14 438f5df1827Smickey popq %r13 439f5df1827Smickey popq %r12 440f5df1827Smickey popq %rbp 441f5df1827Smickey popq %rbx 442f5df1827Smickey ret 443f5df1827Smickey 44445053f4aSartENTRY(cpu_idle_enter) 4452692ace4Sjordan movq _C_LABEL(cpu_idle_enter_fcn),%rax 4462692ace4Sjordan cmpq $0,%rax 4472692ace4Sjordan je 1f 4482692ace4Sjordan jmpq *%rax 4492692ace4Sjordan1: 45045053f4aSart ret 451f5df1827Smickey 45245053f4aSartENTRY(cpu_idle_cycle) 4532692ace4Sjordan movq _C_LABEL(cpu_idle_cycle_fcn),%rax 4542692ace4Sjordan cmpq $0,%rax 4552692ace4Sjordan je 1f 4562692ace4Sjordan call *%rax 4572692ace4Sjordan ret 4582692ace4Sjordan1: 4592692ace4Sjordan sti 46045053f4aSart hlt 46145053f4aSart ret 462f5df1827Smickey 46345053f4aSartENTRY(cpu_idle_leave) 4642692ace4Sjordan movq _C_LABEL(cpu_idle_leave_fcn),%rax 4652692ace4Sjordan cmpq $0,%rax 4662692ace4Sjordan je 1f 4672692ace4Sjordan jmpq *%rax 4682692ace4Sjordan1: 46945053f4aSart ret 470f5df1827Smickey 471da4ea94cSart .globl _C_LABEL(panic) 472da4ea94cSart 473da4ea94cSart#ifdef DIAGNOSTIC 474fd94711fSguentherNENTRY(switch_pmcpu_set) 47532d5845fSderaadt movabsq $switch_active,%rdi 476fd94711fSguenther call _C_LABEL(panic) 477fd94711fSguenther /* NOTREACHED */ 478f5df1827Smickey 47932d5845fSderaadt .section .rodata 48032d5845fSderaadtswitch_active: 48132d5845fSderaadt .asciz "activate already active pmap" 48232d5845fSderaadt .text 48332d5845fSderaadt#endif /* DIAGNOSTIC */ 484f5df1827Smickey/* 485f5df1827Smickey * savectx(struct pcb *pcb); 486f5df1827Smickey * Update pcb, saving current processor state. 487f5df1827Smickey */ 488f5df1827SmickeyENTRY(savectx) 489f5df1827Smickey /* Save stack pointers. */ 490f5df1827Smickey movq %rsp,PCB_RSP(%rdi) 491f5df1827Smickey movq %rbp,PCB_RBP(%rdi) 492f5df1827Smickey 493f5df1827Smickey ret 494f5df1827Smickey 495f5df1827SmickeyIDTVEC(syscall32) 496f5df1827Smickey sysret /* go away please */ 497f5df1827Smickey 498f5df1827Smickey/* 499f5df1827Smickey * syscall insn entry. This currently isn't much faster, but 500f5df1827Smickey * it can be made faster in the future. 501f5df1827Smickey */ 502f5df1827SmickeyIDTVEC(syscall) 50374ebaa6aSguenther /* 50474ebaa6aSguenther * Enter here with interrupts blocked; %rcx contains the caller's 50574ebaa6aSguenther * %rip and the original rflags has been copied to %r11. %cs and 50674ebaa6aSguenther * %ss have been updated to the kernel segments, but %rsp is still 50774ebaa6aSguenther * the user-space value. 50874ebaa6aSguenther * First order of business is to swap to the kernel gs.base so that 50974ebaa6aSguenther * we can access our struct cpu_info and use the scratch space there 51074ebaa6aSguenther * to switch to our kernel stack. Once that's in place we can 51174ebaa6aSguenther * unblock interrupts and save the rest of the syscall frame. 51274ebaa6aSguenther */ 513f5df1827Smickey swapgs 514f5df1827Smickey movq %r15,CPUVAR(SCRATCH) 515f5df1827Smickey movq CPUVAR(CURPCB),%r15 516fd94711fSguenther movq PCB_KSTACK(%r15),%r15 517f5df1827Smickey xchgq %r15,%rsp 518f5df1827Smickey sti 519f5df1827Smickey 520f5df1827Smickey /* 521f5df1827Smickey * XXX don't need this whole frame, split of the 522f5df1827Smickey * syscall frame and trapframe is needed. 523f5df1827Smickey * First, leave some room for the trapno, error, 524f5df1827Smickey * ss:rsp, etc, so that all GP registers can be 525f5df1827Smickey * saved. Then, fill in the rest. 526f5df1827Smickey */ 5271f7e6433Sguenther pushq $(GSEL(GUDATA_SEL, SEL_UPL)) 528f5df1827Smickey pushq %r15 529f5df1827Smickey subq $(TF_RSP-TF_TRAPNO),%rsp 530f5df1827Smickey movq CPUVAR(SCRATCH),%r15 531f5df1827Smickey subq $32,%rsp 532f5df1827Smickey INTR_SAVE_GPRS 533f5df1827Smickey movq %r11, TF_RFLAGS(%rsp) /* old rflags from syscall insn */ 5341f7e6433Sguenther movq $(GSEL(GUCODE_SEL, SEL_UPL)), TF_CS(%rsp) 535f5df1827Smickey movq %rcx,TF_RIP(%rsp) 5366620a6fbSguenther movq $2,TF_ERR(%rsp) /* ignored */ 537f5df1827Smickey 538f5df1827Smickey movq CPUVAR(CURPROC),%r14 539f5df1827Smickey movq %rsp,P_MD_REGS(%r14) # save pointer to frame 540f5df1827Smickey andl $~MDP_IRET,P_MD_FLAGS(%r14) 541b5b9857bSart movq %rsp,%rdi 5424e1a77ceSsturm call _C_LABEL(syscall) 543c9ad316fSguenther 544c9ad316fSguenther.Lsyscall_check_asts: 545c9ad316fSguenther /* Check for ASTs on exit to user mode. */ 546f5df1827Smickey cli 547f5df1827Smickey CHECK_ASTPENDING(%r11) 548f5df1827Smickey je 2f 549f5df1827Smickey CLEAR_ASTPENDING(%r11) 550f5df1827Smickey sti 551b5b9857bSart movq %rsp,%rdi 552c9ad316fSguenther call _C_LABEL(ast) 553c9ad316fSguenther jmp .Lsyscall_check_asts 554c9ad316fSguenther 555f5df1827Smickey2: 556f5df1827Smickey#ifdef DIAGNOSTIC 557b5b9857bSart cmpl $IPL_NONE,CPUVAR(ILEVEL) 558c9ad316fSguenther jne .Lsyscall_spl_not_lowered 5591396572dSguenther#endif /* DIAGNOSTIC */ 5601396572dSguenther 561c9ad316fSguenther /* Could registers have been changed that require an iretq? */ 562c9ad316fSguenther testl $MDP_IRET, P_MD_FLAGS(%r14) 563c9ad316fSguenther jne intr_fast_exit 564c9ad316fSguenther 5651396572dSguenther movq TF_RDI(%rsp),%rdi 5661396572dSguenther movq TF_RSI(%rsp),%rsi 5671396572dSguenther movq TF_R8(%rsp),%r8 5681396572dSguenther movq TF_R9(%rsp),%r9 5691396572dSguenther movq TF_R10(%rsp),%r10 5701396572dSguenther movq TF_R12(%rsp),%r12 5711396572dSguenther movq TF_R13(%rsp),%r13 5721396572dSguenther movq TF_R14(%rsp),%r14 5731396572dSguenther movq TF_R15(%rsp),%r15 5741396572dSguenther movq TF_RBP(%rsp),%rbp 5751396572dSguenther movq TF_RBX(%rsp),%rbx 5761396572dSguenther 577f1665d79Sguenther INTR_RESTORE_SELECTORS 5781396572dSguenther 5791396572dSguenther movq TF_RDX(%rsp),%rdx 5801396572dSguenther movq TF_RAX(%rsp),%rax 5811396572dSguenther 5821396572dSguenther movq TF_RIP(%rsp),%rcx 5831396572dSguenther movq TF_RFLAGS(%rsp),%r11 5841396572dSguenther movq TF_RSP(%rsp),%rsp 585f5df1827Smickey sysretq 586f5df1827Smickey 587f5df1827Smickey#ifdef DIAGNOSTIC 588c9ad316fSguenther.Lsyscall_spl_not_lowered: 58932d5845fSderaadt movabsq $spl_lowered, %rdi 590f5df1827Smickey movl TF_RAX(%rsp),%esi 591f5df1827Smickey movl TF_RDI(%rsp),%edx 592f5df1827Smickey movl %ebx,%ecx 593b5b9857bSart movl CPUVAR(ILEVEL),%r8d 594f5df1827Smickey xorq %rax,%rax 595f5df1827Smickey call _C_LABEL(printf) 596f5df1827Smickey#ifdef DDB 597f5df1827Smickey int $3 598f5df1827Smickey#endif /* DDB */ 599f5df1827Smickey movl $IPL_NONE,CPUVAR(ILEVEL) 600c9ad316fSguenther jmp .Lsyscall_check_asts 601f5df1827Smickey 60232d5845fSderaadt .section .rodata 60332d5845fSderaadtspl_lowered: 60432d5845fSderaadt .asciz "WARNING: SPL NOT LOWERED ON SYSCALL %d %d EXIT %x %x\n" 60532d5845fSderaadt .text 60632d5845fSderaadt#endif 607f5df1827Smickey 608f5df1827SmickeyNENTRY(proc_trampoline) 609f5df1827Smickey#ifdef MULTIPROCESSOR 610f5df1827Smickey call _C_LABEL(proc_trampoline_mp) 611f5df1827Smickey#endif 612f5df1827Smickey movl $IPL_NONE,CPUVAR(ILEVEL) 613f5df1827Smickey movq %r13,%rdi 614f5df1827Smickey call *%r12 615c9ad316fSguenther movq CPUVAR(CURPROC),%r14 616c9ad316fSguenther jmp .Lsyscall_check_asts 617f5df1827Smickey 618f5df1827Smickey 619f5df1827Smickey/* 6201396572dSguenther * Return via iretq, for real interrupts and signal returns 6211396572dSguenther */ 622c9ad316fSguentherNENTRY(intr_fast_exit) 6231396572dSguenther movq TF_RDI(%rsp),%rdi 6241396572dSguenther movq TF_RSI(%rsp),%rsi 6251396572dSguenther movq TF_R8(%rsp),%r8 6261396572dSguenther movq TF_R9(%rsp),%r9 6271396572dSguenther movq TF_R10(%rsp),%r10 6281396572dSguenther movq TF_R12(%rsp),%r12 6291396572dSguenther movq TF_R13(%rsp),%r13 6301396572dSguenther movq TF_R14(%rsp),%r14 6311396572dSguenther movq TF_R15(%rsp),%r15 6321396572dSguenther movq TF_RBP(%rsp),%rbp 6331396572dSguenther movq TF_RBX(%rsp),%rbx 6341396572dSguenther 63592f33f2bSguenther testq $SEL_RPL,TF_CS(%rsp) 636c6853312Sguenther je 5f 6371396572dSguenther 638f1665d79Sguenther INTR_RESTORE_SELECTORS 6391396572dSguenther 6401396572dSguenther5: movq TF_RDX(%rsp),%rdx 6411396572dSguenther movq TF_RCX(%rsp),%rcx 6421396572dSguenther movq TF_R11(%rsp),%r11 6431396572dSguenther movq TF_RAX(%rsp),%rax 6446950c8e2Smpi 6456950c8e2Smpi#if !defined(GPROF) && defined(DDBPROF) 6466950c8e2Smpi /* 6476950c8e2Smpi * If we are returning from a probe trap we need to fix the 6486950c8e2Smpi * stack layout and emulate the patched instruction. 6496950c8e2Smpi * 6506950c8e2Smpi * The code below does that by trashing %rax, so it MUST be 6516950c8e2Smpi * restored afterward. 6526950c8e2Smpi */ 6536950c8e2Smpi cmpl $INTR_FAKE_TRAP, TF_ERR(%rsp) 6546950c8e2Smpi je .Lprobe_fixup 6556950c8e2Smpi#endif /* !defined(GPROF) && defined(DDBPROF) */ 6566950c8e2Smpi 6571396572dSguenther addq $TF_RIP,%rsp 6581396572dSguenther 659c6853312Sguenther .globl _C_LABEL(doreti_iret) 660c6853312Sguenther_C_LABEL(doreti_iret): 661c6853312Sguenther iretq 662c6853312Sguenther 6633a36161cSart 6646950c8e2Smpi#if !defined(GPROF) && defined(DDBPROF) 6656950c8e2Smpi.Lprobe_fixup: 6666950c8e2Smpi /* Reserve enough room to emulate "pushq %rbp". */ 6676950c8e2Smpi subq $16, %rsp 6686950c8e2Smpi 6696950c8e2Smpi /* Shift hardware-saved registers. */ 6706950c8e2Smpi movq (TF_RIP + 16)(%rsp), %rax 6716950c8e2Smpi movq %rax, TF_RIP(%rsp) 6726950c8e2Smpi movq (TF_CS + 16)(%rsp), %rax 6736950c8e2Smpi movq %rax, TF_CS(%rsp) 6746950c8e2Smpi movq (TF_RFLAGS + 16)(%rsp), %rax 6756950c8e2Smpi movq %rax, TF_RFLAGS(%rsp) 6766950c8e2Smpi movq (TF_RSP + 16)(%rsp), %rax 6776950c8e2Smpi movq %rax, TF_RSP(%rsp) 6786950c8e2Smpi movq (TF_SS + 16)(%rsp), %rax 6796950c8e2Smpi movq %rax, TF_SS(%rsp) 6806950c8e2Smpi 6812f2c18a3Smpi /* Pull 8 bytes off the stack and store %rbp in the expected location.*/ 6826950c8e2Smpi movq TF_RSP(%rsp), %rax 6836950c8e2Smpi subq $8, %rax 6846950c8e2Smpi movq %rax, TF_RSP(%rsp) 6856950c8e2Smpi movq %rbp, (%rax) 6866950c8e2Smpi 6876950c8e2Smpi /* Write back overwritten %rax */ 6886950c8e2Smpi movq (TF_RAX + 16)(%rsp),%rax 6896950c8e2Smpi 6906950c8e2Smpi addq $TF_RIP,%rsp 6916950c8e2Smpi iretq 6926950c8e2Smpi#endif /* !defined(GPROF) && defined(DDBPROF) */ 6936950c8e2Smpi 6943a36161cSartENTRY(pagezero) 6953a36161cSart movq $-PAGE_SIZE,%rdx 6963a36161cSart subq %rdx,%rdi 6973a36161cSart xorq %rax,%rax 6983a36161cSart1: 6993a36161cSart movnti %rax,(%rdi,%rdx) 7003a36161cSart movnti %rax,8(%rdi,%rdx) 7013a36161cSart movnti %rax,16(%rdi,%rdx) 7023a36161cSart movnti %rax,24(%rdi,%rdx) 7033a36161cSart addq $32,%rdx 7043a36161cSart jne 1b 7053a36161cSart sfence 7063a36161cSart ret 7073c8478a6Sgwk 708d8213a49Smikeb#if NXEN > 0 709d8213a49Smikeb /* Hypercall page needs to be page aligned */ 710d8213a49Smikeb .text 7110175496dSderaadt .align NBPG, 0xcc 712d8213a49Smikeb .globl _C_LABEL(xen_hypercall_page) 713d8213a49Smikeb_C_LABEL(xen_hypercall_page): 7140175496dSderaadt .skip 0x1000, 0xcc 715d8213a49Smikeb#endif /* NXEN > 0 */ 716218ead0bSmikeb 717218ead0bSmikeb#if NHYPERV > 0 718218ead0bSmikeb /* Hypercall page needs to be page aligned */ 719218ead0bSmikeb .text 720218ead0bSmikeb .align NBPG, 0xcc 721218ead0bSmikeb .globl _C_LABEL(hv_hypercall_page) 722218ead0bSmikeb_C_LABEL(hv_hypercall_page): 723218ead0bSmikeb .skip 0x1000, 0xcc 724218ead0bSmikeb#endif /* NXEN > 0 */ 725