1 // Copyright 2020 Arm Limited (or its affiliates). All rights reserved. 2 // Copyright © 2020, Oracle and/or its affiliates. 3 // 4 // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 // SPDX-License-Identifier: Apache-2.0 6 7 //! Implements platform specific functionality. 8 //! Supported platforms: x86_64, aarch64. 9 #![allow(clippy::transmute_ptr_to_ptr, clippy::redundant_static_lifetimes)] 10 11 #[macro_use] 12 extern crate log; 13 14 use std::fmt; 15 use std::result; 16 17 type GuestMemoryMmap = vm_memory::GuestMemoryMmap<vm_memory::bitmap::AtomicBitmap>; 18 19 /// Type for returning error code. 20 #[derive(Debug)] 21 pub enum Error { 22 #[cfg(target_arch = "x86_64")] 23 /// X86_64 specific error triggered during system configuration. 24 X86_64Setup(x86_64::Error), 25 #[cfg(target_arch = "aarch64")] 26 /// AArch64 specific error triggered during system configuration. 27 AArch64Setup(aarch64::Error), 28 /// The zero page extends past the end of guest_mem. 29 ZeroPagePastRamEnd, 30 /// Error writing the zero page of guest memory. 31 ZeroPageSetup(vm_memory::GuestMemoryError), 32 /// The memory map table extends past the end of guest memory. 33 MemmapTablePastRamEnd, 34 /// Error writing memory map table to guest memory. 35 MemmapTableSetup, 36 /// The hvm_start_info structure extends past the end of guest memory. 37 StartInfoPastRamEnd, 38 /// Error writing hvm_start_info to guest memory. 39 StartInfoSetup, 40 /// Failed to compute initramfs address. 41 InitramfsAddress, 42 /// Error writing module entry to guest memory. 43 ModlistSetup(vm_memory::GuestMemoryError), 44 /// RSDP Beyond Guest Memory 45 RsdpPastRamEnd, 46 } 47 48 /// Type for returning public functions outcome. 49 pub type Result<T> = result::Result<T, Error>; 50 51 /// Type for memory region types. 52 #[derive(PartialEq, Debug)] 53 pub enum RegionType { 54 /// RAM type 55 Ram, 56 57 /// SubRegion memory region. 58 /// A SubRegion is a memory region sub-region, allowing for a region 59 /// to be split into sub regions managed separately. 60 /// For example, the x86 32-bit memory hole is a SubRegion. 61 SubRegion, 62 63 /// Reserved type. 64 /// A Reserved memory region is one that should not be used for memory 65 /// allocation. This type can be used to prevent the VMM from allocating 66 /// memory ranges in a specific address range. 67 Reserved, 68 } 69 70 /// Module for aarch64 related functionality. 71 #[cfg(target_arch = "aarch64")] 72 pub mod aarch64; 73 74 #[cfg(target_arch = "aarch64")] 75 pub use aarch64::{ 76 arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFdt, 77 get_host_cpu_phys_bits, get_kernel_start, get_uefi_start, initramfs_load_addr, layout, 78 layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, uefi, EntryPoint, 79 }; 80 81 #[cfg(target_arch = "x86_64")] 82 pub mod x86_64; 83 84 #[cfg(target_arch = "x86_64")] 85 pub use x86_64::{ 86 arch_memory_regions, configure_system, configure_vcpu, generate_common_cpuid, 87 get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, 88 layout::CMDLINE_START, regs, EntryPoint, 89 }; 90 91 /// Safe wrapper for `sysconf(_SC_PAGESIZE)`. 92 #[cfg(target_arch = "x86_64")] 93 #[inline(always)] 94 fn pagesize() -> usize { 95 // Trivially safe 96 unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } 97 } 98 99 /// Type for passing information about the initramfs in the guest memory. 100 pub struct InitramfsConfig { 101 /// Load address of initramfs in guest memory 102 pub address: vm_memory::GuestAddress, 103 /// Size of initramfs in guest memory 104 pub size: usize, 105 } 106 107 /// Types of devices that can get attached to this platform. 108 #[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)] 109 pub enum DeviceType { 110 /// Device Type: Virtio. 111 Virtio(u32), 112 /// Device Type: Serial. 113 #[cfg(target_arch = "aarch64")] 114 Serial, 115 /// Device Type: RTC. 116 #[cfg(target_arch = "aarch64")] 117 Rtc, 118 /// Device Type: GPIO. 119 #[cfg(target_arch = "aarch64")] 120 Gpio, 121 } 122 123 /// Default (smallest) memory page size for the supported architectures. 124 pub const PAGE_SIZE: usize = 4096; 125 126 impl fmt::Display for DeviceType { 127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 128 write!(f, "{:?}", self) 129 } 130 } 131 132 /// Structure to describe MMIO device information 133 #[derive(Clone, Debug)] 134 #[cfg(target_arch = "aarch64")] 135 pub struct MmioDeviceInfo { 136 pub addr: u64, 137 pub irq: u32, 138 } 139 140 #[cfg(target_arch = "aarch64")] 141 impl DeviceInfoForFdt for MmioDeviceInfo { 142 fn addr(&self) -> u64 { 143 self.addr 144 } 145 fn irq(&self) -> u32 { 146 self.irq 147 } 148 fn length(&self) -> u64 { 149 4096 150 } 151 } 152