1 // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 // 4 // Portions Copyright 2017 The Chromium OS Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style license that can be 6 // found in the LICENSE-BSD-3-Clause file. 7 8 //! Emulates virtual and hardware devices. 9 10 #[macro_use] 11 extern crate bitflags; 12 #[macro_use] 13 extern crate event_monitor; 14 #[macro_use] 15 extern crate log; 16 17 pub mod acpi; 18 #[cfg(target_arch = "riscv64")] 19 pub mod aia; 20 #[cfg(target_arch = "x86_64")] 21 pub mod debug_console; 22 #[cfg(target_arch = "aarch64")] 23 pub mod gic; 24 pub mod interrupt_controller; 25 #[cfg(target_arch = "x86_64")] 26 pub mod ioapic; 27 pub mod legacy; 28 #[cfg(feature = "pvmemcontrol")] 29 pub mod pvmemcontrol; 30 pub mod pvpanic; 31 // TODO: TPM is not yet supported 32 #[cfg(not(target_arch = "riscv64"))] 33 pub mod tpm; 34 35 pub use self::acpi::{AcpiGedDevice, AcpiPmTimerDevice, AcpiShutdownDevice}; 36 pub use self::pvpanic::{PvPanicDevice, PVPANIC_DEVICE_MMIO_SIZE}; 37 38 bitflags! { 39 pub struct AcpiNotificationFlags: u8 { 40 const NO_DEVICES_CHANGED = 0; 41 const CPU_DEVICES_CHANGED = 0b1; 42 const MEMORY_DEVICES_CHANGED = 0b10; 43 const PCI_DEVICES_CHANGED = 0b100; 44 const POWER_BUTTON_CHANGED = 0b1000; 45 } 46 } 47 48 #[cfg(target_arch = "aarch64")] 49 macro_rules! generate_read_fn { 50 ($fn_name: ident, $data_type: ty, $byte_type: ty, $type_size: expr, $endian_type: ident) => { 51 pub fn $fn_name(input: &[$byte_type]) -> $data_type { 52 assert!($type_size == std::mem::size_of::<$data_type>()); 53 let mut array = [0u8; $type_size]; 54 for (byte, read) in array.iter_mut().zip(input.iter().cloned()) { 55 *byte = read as u8; 56 } 57 <$data_type>::$endian_type(array) 58 } 59 }; 60 } 61 62 #[cfg(target_arch = "aarch64")] 63 macro_rules! generate_write_fn { 64 ($fn_name: ident, $data_type: ty, $byte_type: ty, $endian_type: ident) => { 65 pub fn $fn_name(buf: &mut [$byte_type], n: $data_type) { 66 for (byte, read) in buf 67 .iter_mut() 68 .zip(<$data_type>::$endian_type(n).iter().cloned()) 69 { 70 *byte = read as $byte_type; 71 } 72 } 73 }; 74 } 75 76 #[cfg(target_arch = "aarch64")] 77 generate_read_fn!(read_le_u16, u16, u8, 2, from_le_bytes); 78 #[cfg(target_arch = "aarch64")] 79 generate_read_fn!(read_le_u32, u32, u8, 4, from_le_bytes); 80 #[cfg(target_arch = "aarch64")] 81 generate_read_fn!(read_le_u64, u64, u8, 8, from_le_bytes); 82 #[cfg(target_arch = "aarch64")] 83 generate_read_fn!(read_le_i32, i32, i8, 4, from_le_bytes); 84 85 #[cfg(target_arch = "aarch64")] 86 generate_read_fn!(read_be_u16, u16, u8, 2, from_be_bytes); 87 #[cfg(target_arch = "aarch64")] 88 generate_read_fn!(read_be_u32, u32, u8, 4, from_be_bytes); 89 90 #[cfg(target_arch = "aarch64")] 91 generate_write_fn!(write_le_u16, u16, u8, to_le_bytes); 92 #[cfg(target_arch = "aarch64")] 93 generate_write_fn!(write_le_u32, u32, u8, to_le_bytes); 94 #[cfg(target_arch = "aarch64")] 95 generate_write_fn!(write_le_u64, u64, u8, to_le_bytes); 96 #[cfg(target_arch = "aarch64")] 97 generate_write_fn!(write_le_i32, i32, i8, to_le_bytes); 98 99 #[cfg(target_arch = "aarch64")] 100 generate_write_fn!(write_be_u16, u16, u8, to_be_bytes); 101 #[cfg(target_arch = "aarch64")] 102 generate_write_fn!(write_be_u32, u32, u8, to_be_bytes); 103