1240912Sneel/*- 2240912Sneel * Copyright (c) 2012 NetApp, Inc. 3240912Sneel * All rights reserved. 4240912Sneel * 5240912Sneel * Redistribution and use in source and binary forms, with or without 6240912Sneel * modification, are permitted provided that the following conditions 7240912Sneel * are met: 8240912Sneel * 1. Redistributions of source code must retain the above copyright 9240912Sneel * notice, this list of conditions and the following disclaimer. 10240912Sneel * 2. Redistributions in binary form must reproduce the above copyright 11240912Sneel * notice, this list of conditions and the following disclaimer in the 12240912Sneel * documentation and/or other materials provided with the distribution. 13240912Sneel * 14240912Sneel * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15240912Sneel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16240912Sneel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17240912Sneel * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18240912Sneel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19240912Sneel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20240912Sneel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21240912Sneel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22240912Sneel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23240912Sneel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24240912Sneel * SUCH DAMAGE. 25240912Sneel * 26240912Sneel * $FreeBSD: releng/11.0/usr.sbin/bhyve/spinup_ap.c 263432 2014-03-20 18:15:37Z neel $ 27240912Sneel */ 28240912Sneel 29240912Sneel#include <sys/cdefs.h> 30240912Sneel__FBSDID("$FreeBSD: releng/11.0/usr.sbin/bhyve/spinup_ap.c 263432 2014-03-20 18:15:37Z neel $"); 31240912Sneel 32240912Sneel#include <sys/param.h> 33240912Sneel#include <sys/types.h> 34240912Sneel 35240912Sneel#include <machine/vmm.h> 36240912Sneel#include <vmmapi.h> 37240912Sneel 38240912Sneel#include <stdio.h> 39240912Sneel#include <stdlib.h> 40240912Sneel#include <assert.h> 41240912Sneel 42244167Sgrehan#include "bhyverun.h" 43240912Sneel#include "spinup_ap.h" 44240912Sneel 45240912Sneelstatic void 46240912Sneelspinup_ap_realmode(struct vmctx *ctx, int newcpu, uint64_t *rip) 47240912Sneel{ 48240912Sneel int vector, error; 49240912Sneel uint16_t cs; 50240912Sneel uint64_t desc_base; 51240912Sneel uint32_t desc_limit, desc_access; 52240912Sneel 53240912Sneel vector = *rip >> PAGE_SHIFT; 54240912Sneel *rip = 0; 55240912Sneel 56240912Sneel /* 57240912Sneel * Update the %cs and %rip of the guest so that it starts 58240912Sneel * executing real mode code at at 'vector << 12'. 59240912Sneel */ 60240912Sneel error = vm_set_register(ctx, newcpu, VM_REG_GUEST_RIP, *rip); 61240912Sneel assert(error == 0); 62240912Sneel 63240912Sneel error = vm_get_desc(ctx, newcpu, VM_REG_GUEST_CS, &desc_base, 64240912Sneel &desc_limit, &desc_access); 65240912Sneel assert(error == 0); 66240912Sneel 67240912Sneel desc_base = vector << PAGE_SHIFT; 68240912Sneel error = vm_set_desc(ctx, newcpu, VM_REG_GUEST_CS, 69240912Sneel desc_base, desc_limit, desc_access); 70240912Sneel assert(error == 0); 71240912Sneel 72240912Sneel cs = (vector << PAGE_SHIFT) >> 4; 73240912Sneel error = vm_set_register(ctx, newcpu, VM_REG_GUEST_CS, cs); 74240912Sneel assert(error == 0); 75240912Sneel} 76240912Sneel 77240912Sneelint 78240912Sneelspinup_ap(struct vmctx *ctx, int vcpu, int newcpu, uint64_t rip) 79240912Sneel{ 80240912Sneel int error; 81240912Sneel 82240912Sneel assert(newcpu != 0); 83240912Sneel assert(newcpu < guest_ncpus); 84240912Sneel 85240912Sneel error = vcpu_reset(ctx, newcpu); 86240912Sneel assert(error == 0); 87240912Sneel 88256645Sneel fbsdrun_set_capabilities(ctx, newcpu); 89240912Sneel 90240912Sneel /* 91245020Sneel * Enable the 'unrestricted guest' mode for 'newcpu'. 92245020Sneel * 93245020Sneel * Set up the processor state in power-on 16-bit mode, with the CS:IP 94245020Sneel * init'd to the specified low-mem 4K page. 95240912Sneel */ 96240912Sneel error = vm_set_capability(ctx, newcpu, VM_CAP_UNRESTRICTED_GUEST, 1); 97245020Sneel assert(error == 0); 98240912Sneel 99245020Sneel spinup_ap_realmode(ctx, newcpu, &rip); 100245020Sneel 101263432Sneel fbsdrun_addcpu(ctx, vcpu, newcpu, rip); 102240912Sneel 103240912Sneel return (newcpu); 104240912Sneel} 105