Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/xen/hvm.c
Show All 24 Lines | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/linker.h> | |||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/smp.h> | #include <sys/smp.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | ||||
#include <dev/pci/pcivar.h> | #include <dev/pci/pcivar.h> | ||||
#include <machine/_inttypes.h> | #include <machine/_inttypes.h> | ||||
#include <machine/cpufunc.h> | #include <machine/cpufunc.h> | ||||
#include <machine/cpu.h> | #include <machine/cpu.h> | ||||
#include <machine/md_var.h> | #include <machine/md_var.h> | ||||
#include <machine/metadata.h> | |||||
#include <machine/smp.h> | #include <machine/smp.h> | ||||
#include <x86/apicreg.h> | #include <x86/apicreg.h> | ||||
#include <xen/xen-os.h> | #include <xen/xen-os.h> | ||||
#include <xen/error.h> | #include <xen/error.h> | ||||
#include <xen/features.h> | #include <xen/features.h> | ||||
#include <xen/gnttab.h> | #include <xen/gnttab.h> | ||||
▲ Show 20 Lines • Show All 185 Lines • ▼ Show 20 Lines | if (rc != 0) { | ||||
xc_printf("cannot map shared info page: %d\n", rc); | xc_printf("cannot map shared info page: %d\n", rc); | ||||
HYPERVISOR_shared_info = NULL; | HYPERVISOR_shared_info = NULL; | ||||
} else if (HYPERVISOR_shared_info == NULL) | } else if (HYPERVISOR_shared_info == NULL) | ||||
HYPERVISOR_shared_info = &shared_page.shared_info; | HYPERVISOR_shared_info = &shared_page.shared_info; | ||||
return (rc); | return (rc); | ||||
} | } | ||||
static void | |||||
fixup_console(void) | |||||
{ | |||||
struct xen_platform_op op = { | |||||
.cmd = XENPF_get_dom0_console, | |||||
}; | |||||
xenpf_dom0_console_t *console = &op.u.dom0_console; | |||||
union { | |||||
struct efi_fb efi; | |||||
struct vbe_fb vbe; | |||||
} *fb = NULL; | |||||
int size; | |||||
caddr_t kmdp; | |||||
kmdp = preload_search_by_type("elf kernel"); | |||||
if (kmdp == NULL) | |||||
kmdp = preload_search_by_type("elf64 kernel"); | |||||
if (kmdp == NULL) { | |||||
xc_printf("Unable to find kernel metadata\n"); | |||||
return; | |||||
} | |||||
size = HYPERVISOR_platform_op(&op); | |||||
if (size < 0) { | |||||
xc_printf("Failed to get video console info: %d\n", size); | |||||
return; | |||||
} | |||||
switch (console->video_type) { | |||||
case XEN_VGATYPE_VESA_LFB: | |||||
fb = (__typeof__ (fb))preload_search_info(kmdp, | |||||
MODINFO_METADATA | MODINFOMD_VBE_FB); | |||||
if (fb == NULL) { | |||||
xc_printf("No VBE FB in kernel metadata\n"); | |||||
return; | |||||
} | |||||
_Static_assert(offsetof(struct vbe_fb, fb_bpp) == | |||||
offsetof(struct efi_fb, fb_mask_reserved) + | |||||
sizeof(fb->efi.fb_mask_reserved), | |||||
"Bad structure overlay\n"); | |||||
fb->vbe.fb_bpp = console->u.vesa_lfb.bits_per_pixel; | |||||
/* FALLTHROUGH */ | |||||
case XEN_VGATYPE_EFI_LFB: | |||||
if (fb == NULL) { | |||||
fb = (__typeof__ (fb))preload_search_info(kmdp, | |||||
MODINFO_METADATA | MODINFOMD_EFI_FB); | |||||
if (fb == NULL) { | |||||
xc_printf("No EFI FB in kernel metadata\n"); | |||||
return; | |||||
} | |||||
} | |||||
fb->efi.fb_addr = console->u.vesa_lfb.lfb_base; | |||||
if (size > | |||||
offsetof(xenpf_dom0_console_t, u.vesa_lfb.ext_lfb_base)) | |||||
fb->efi.fb_addr |= | |||||
(uint64_t)console->u.vesa_lfb.ext_lfb_base << 32; | |||||
fb->efi.fb_size = console->u.vesa_lfb.lfb_size << 16; | |||||
fb->efi.fb_height = console->u.vesa_lfb.height; | |||||
fb->efi.fb_width = console->u.vesa_lfb.width; | |||||
fb->efi.fb_stride = (console->u.vesa_lfb.bytes_per_line << 3) / | |||||
console->u.vesa_lfb.bits_per_pixel; | |||||
#define FBMASK(c) \ | |||||
((~0u << console->u.vesa_lfb.c ## _pos) & \ | |||||
(~0u >> (32 - console->u.vesa_lfb.c ## _pos - \ | |||||
console->u.vesa_lfb.c ## _size))) | |||||
fb->efi.fb_mask_red = FBMASK(red); | |||||
fb->efi.fb_mask_green = FBMASK(green); | |||||
fb->efi.fb_mask_blue = FBMASK(blue); | |||||
fb->efi.fb_mask_reserved = FBMASK(rsvd); | |||||
#undef FBMASK | |||||
break; | |||||
default: | |||||
xc_printf("Video console type unsupported\n"); | |||||
return; | |||||
} | |||||
} | |||||
/* Early initialization when running as a Xen guest. */ | /* Early initialization when running as a Xen guest. */ | ||||
void | void | ||||
xen_early_init(void) | xen_early_init(void) | ||||
{ | { | ||||
uint32_t regs[4]; | uint32_t regs[4]; | ||||
int rc; | int rc; | ||||
xen_cpuid_base = xen_hvm_cpuid_base(); | xen_cpuid_base = xen_hvm_cpuid_base(); | ||||
Show All 11 Lines | xen_early_init(void) | ||||
wrmsr(regs[1], early_init_vtop(&hypercall_page)); | wrmsr(regs[1], early_init_vtop(&hypercall_page)); | ||||
rc = map_shared_info(); | rc = map_shared_info(); | ||||
if (rc != 0) { | if (rc != 0) { | ||||
vm_guest = VM_GUEST_VM; | vm_guest = VM_GUEST_VM; | ||||
return; | return; | ||||
} | } | ||||
if (xen_initial_domain()) | |||||
/* Fixup video console information in case Xen changed the mode. */ | |||||
fixup_console(); | |||||
} | } | ||||
static void | static void | ||||
xen_hvm_init_shared_info_page(void) | xen_hvm_init_shared_info_page(void) | ||||
{ | { | ||||
struct xen_add_to_physmap xatp; | struct xen_add_to_physmap xatp; | ||||
if (xen_pv_domain()) { | if (xen_pv_domain()) { | ||||
▲ Show 20 Lines • Show All 263 Lines • Show Last 20 Lines |