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