xref: /freebsd/usr.sbin/bhyve/amd64/spinup_ap.c (revision c7c5d3e3888aa9018297794285dcd884e6182bd5)
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