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