xref: /cloud-hypervisor/arch/src/lib.rs (revision f7f2f25a574b1b2dba22c094fc8226d404157d15)
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, CpuidFeatureEntry, 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