1*c7c5d3e3SMark Johnston /*- 2*c7c5d3e3SMark Johnston * SPDX-License-Identifier: BSD-2-Clause 3*c7c5d3e3SMark Johnston * 4*c7c5d3e3SMark Johnston * Copyright (c) 2012 NetApp, Inc. 5*c7c5d3e3SMark Johnston * All rights reserved. 6*c7c5d3e3SMark Johnston * 7*c7c5d3e3SMark Johnston * Redistribution and use in source and binary forms, with or without 8*c7c5d3e3SMark Johnston * modification, are permitted provided that the following conditions 9*c7c5d3e3SMark Johnston * are met: 10*c7c5d3e3SMark Johnston * 1. Redistributions of source code must retain the above copyright 11*c7c5d3e3SMark Johnston * notice, this list of conditions and the following disclaimer. 12*c7c5d3e3SMark Johnston * 2. Redistributions in binary form must reproduce the above copyright 13*c7c5d3e3SMark Johnston * notice, this list of conditions and the following disclaimer in the 14*c7c5d3e3SMark Johnston * documentation and/or other materials provided with the distribution. 15*c7c5d3e3SMark Johnston * 16*c7c5d3e3SMark Johnston * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 17*c7c5d3e3SMark Johnston * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*c7c5d3e3SMark Johnston * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*c7c5d3e3SMark Johnston * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 20*c7c5d3e3SMark Johnston * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*c7c5d3e3SMark Johnston * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*c7c5d3e3SMark Johnston * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*c7c5d3e3SMark Johnston * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*c7c5d3e3SMark Johnston * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*c7c5d3e3SMark Johnston * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*c7c5d3e3SMark Johnston * SUCH DAMAGE. 27*c7c5d3e3SMark Johnston */ 28*c7c5d3e3SMark Johnston 29*c7c5d3e3SMark Johnston #include <sys/cdefs.h> 30*c7c5d3e3SMark Johnston #include <sys/param.h> 31*c7c5d3e3SMark Johnston #include <sys/types.h> 32*c7c5d3e3SMark Johnston 33*c7c5d3e3SMark Johnston #include <machine/vmm.h> 34*c7c5d3e3SMark Johnston #include <vmmapi.h> 35*c7c5d3e3SMark Johnston 36*c7c5d3e3SMark Johnston #include <stdio.h> 37*c7c5d3e3SMark Johnston #include <stdlib.h> 38*c7c5d3e3SMark Johnston #include <assert.h> 39*c7c5d3e3SMark Johnston 40*c7c5d3e3SMark Johnston #include "bhyverun.h" 41*c7c5d3e3SMark Johnston #include "spinup_ap.h" 42*c7c5d3e3SMark Johnston 43*c7c5d3e3SMark Johnston static void 44*c7c5d3e3SMark Johnston spinup_ap_realmode(struct vcpu *newcpu, uint64_t rip) 45*c7c5d3e3SMark Johnston { 46*c7c5d3e3SMark Johnston int vector, error; 47*c7c5d3e3SMark Johnston uint16_t cs; 48*c7c5d3e3SMark Johnston uint64_t desc_base; 49*c7c5d3e3SMark Johnston uint32_t desc_limit, desc_access; 50*c7c5d3e3SMark Johnston 51*c7c5d3e3SMark Johnston vector = rip >> PAGE_SHIFT; 52*c7c5d3e3SMark Johnston 53*c7c5d3e3SMark Johnston /* 54*c7c5d3e3SMark Johnston * Update the %cs and %rip of the guest so that it starts 55*c7c5d3e3SMark Johnston * executing real mode code at at 'vector << 12'. 56*c7c5d3e3SMark Johnston */ 57*c7c5d3e3SMark Johnston error = vm_set_register(newcpu, VM_REG_GUEST_RIP, 0); 58*c7c5d3e3SMark Johnston assert(error == 0); 59*c7c5d3e3SMark Johnston 60*c7c5d3e3SMark Johnston error = vm_get_desc(newcpu, VM_REG_GUEST_CS, &desc_base, 61*c7c5d3e3SMark Johnston &desc_limit, &desc_access); 62*c7c5d3e3SMark Johnston assert(error == 0); 63*c7c5d3e3SMark Johnston 64*c7c5d3e3SMark Johnston desc_base = vector << PAGE_SHIFT; 65*c7c5d3e3SMark Johnston error = vm_set_desc(newcpu, VM_REG_GUEST_CS, 66*c7c5d3e3SMark Johnston desc_base, desc_limit, desc_access); 67*c7c5d3e3SMark Johnston assert(error == 0); 68*c7c5d3e3SMark Johnston 69*c7c5d3e3SMark Johnston cs = (vector << PAGE_SHIFT) >> 4; 70*c7c5d3e3SMark Johnston error = vm_set_register(newcpu, VM_REG_GUEST_CS, cs); 71*c7c5d3e3SMark Johnston assert(error == 0); 72*c7c5d3e3SMark Johnston } 73*c7c5d3e3SMark Johnston 74*c7c5d3e3SMark Johnston void 75*c7c5d3e3SMark Johnston spinup_ap(struct vcpu *newcpu, uint64_t rip) 76*c7c5d3e3SMark Johnston { 77*c7c5d3e3SMark Johnston int error; 78*c7c5d3e3SMark Johnston 79*c7c5d3e3SMark Johnston error = vcpu_reset(newcpu); 80*c7c5d3e3SMark Johnston assert(error == 0); 81*c7c5d3e3SMark Johnston 82*c7c5d3e3SMark Johnston spinup_ap_realmode(newcpu, rip); 83*c7c5d3e3SMark Johnston 84*c7c5d3e3SMark Johnston vm_resume_cpu(newcpu); 85*c7c5d3e3SMark Johnston } 86