mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 10:10:41 +00:00
acpi: support fixed power button event in command line
Support injecting an ACPI fixed power button event using "powerbtn" in the command line. BUG=b:199383670 TEST=boot Linux kernel and trigger a power button event Change-Id: I5ed57f533fa3d91043491fd1f0695223a139fc7a Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3350492 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Tomasz Nowicki <tnowicki@google.com>
This commit is contained in:
parent
072c103be6
commit
6ca0323c87
8 changed files with 43 additions and 10 deletions
|
@ -482,6 +482,7 @@ impl arch::LinuxArch for AArch64 {
|
|||
rt_cpus: components.rt_cpus,
|
||||
delay_rt: components.delay_rt,
|
||||
bat_control: None,
|
||||
pm: None,
|
||||
resume_notify_devices: Vec::new(),
|
||||
root_config: pci_root,
|
||||
hotplug_bus: Vec::new(),
|
||||
|
|
|
@ -29,7 +29,7 @@ use remain::sorted;
|
|||
use resources::{MmioType, SystemAllocator};
|
||||
use sync::Mutex;
|
||||
use thiserror::Error;
|
||||
use vm_control::{BatControl, BatteryType};
|
||||
use vm_control::{BatControl, BatteryType, PmResource};
|
||||
use vm_memory::{GuestAddress, GuestMemory, GuestMemoryError};
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", feature = "gdb"))]
|
||||
|
@ -123,6 +123,7 @@ pub struct RunnableLinuxVm<V: VmArch, Vcpu: VcpuArch> {
|
|||
pub bat_control: Option<BatControl>,
|
||||
#[cfg(all(target_arch = "x86_64", feature = "gdb"))]
|
||||
pub gdb: Option<(u32, Tube)>,
|
||||
pub pm: Option<Arc<Mutex<dyn PmResource>>>,
|
||||
/// Devices to be notified before the system resumes from the S3 suspended state.
|
||||
pub resume_notify_devices: Vec<Arc<Mutex<dyn BusResumeDevice>>>,
|
||||
pub root_config: Arc<Mutex<PciRoot>>,
|
||||
|
@ -692,7 +693,7 @@ pub fn add_goldfish_battery(
|
|||
create_monitor,
|
||||
)
|
||||
.map_err(DeviceRegistrationError::RegisterBattery)?;
|
||||
Aml::to_aml_bytes(&goldfish_bat, amls);
|
||||
goldfish_bat.to_aml_bytes(amls);
|
||||
|
||||
match battery_jail.as_ref() {
|
||||
Some(jail) => {
|
||||
|
|
|
@ -1856,6 +1856,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
|||
balloon_host_tube.as_ref(),
|
||||
&mut balloon_stats_id,
|
||||
disk_host_tubes,
|
||||
&mut linux.pm,
|
||||
#[cfg(feature = "usb")]
|
||||
Some(&usb_control_tube),
|
||||
#[cfg(not(feature = "usb"))]
|
||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -2881,6 +2881,17 @@ fn resume_vms(mut args: std::env::Args) -> std::result::Result<(), ()> {
|
|||
vms_request(&VmRequest::Resume, socket_path)
|
||||
}
|
||||
|
||||
fn powerbtn_vms(mut args: std::env::Args) -> std::result::Result<(), ()> {
|
||||
if args.len() == 0 {
|
||||
print_help("crosvm powerbtn", "VM_SOCKET...", &[]);
|
||||
println!("Triggers a power button event in the crosvm instance listening on each `VM_SOCKET` given.");
|
||||
return Err(());
|
||||
}
|
||||
let socket_path = &args.next().unwrap();
|
||||
let socket_path = Path::new(&socket_path);
|
||||
vms_request(&VmRequest::Powerbtn, socket_path)
|
||||
}
|
||||
|
||||
fn balloon_vms(mut args: std::env::Args) -> std::result::Result<(), ()> {
|
||||
if args.len() < 2 {
|
||||
print_help("crosvm balloon", "SIZE VM_SOCKET...", &[]);
|
||||
|
@ -3393,6 +3404,7 @@ fn print_usage() {
|
|||
println!(" run - Start a new crosvm instance.");
|
||||
println!(" stop - Stops crosvm instances via their control sockets.");
|
||||
println!(" suspend - Suspends the crosvm instance.");
|
||||
println!(" powerbtn - Triggers a power button event in the crosvm instance.");
|
||||
println!(" usb - Manage attached virtual USB devices.");
|
||||
println!(" version - Show package version.");
|
||||
println!(" vfio - add/remove host vfio pci device into guest.");
|
||||
|
@ -3448,6 +3460,7 @@ fn crosvm_main() -> std::result::Result<CommandStatus, ()> {
|
|||
"resume" => resume_vms(args),
|
||||
"stop" => stop_vms(args),
|
||||
"suspend" => suspend_vms(args),
|
||||
"powerbtn" => powerbtn_vms(args),
|
||||
"usb" => modify_usb(args),
|
||||
"version" => pkg_version(),
|
||||
"vfio" => modify_vfio(args),
|
||||
|
|
|
@ -883,6 +883,8 @@ impl FsMappingRequest {
|
|||
pub enum VmRequest {
|
||||
/// Break the VM's run loop and exit.
|
||||
Exit,
|
||||
/// Trigger a power button event in the guest.
|
||||
Powerbtn,
|
||||
/// Suspend the VM's VCPUs until resume.
|
||||
Suspend,
|
||||
/// Resume the VM's VCPUs that were previously suspended.
|
||||
|
@ -967,6 +969,7 @@ impl VmRequest {
|
|||
balloon_host_tube: Option<&Tube>,
|
||||
balloon_stats_id: &mut u64,
|
||||
disk_host_tubes: &[Tube],
|
||||
pm: &mut Option<Arc<Mutex<dyn PmResource>>>,
|
||||
usb_control_tube: Option<&Tube>,
|
||||
bat_control: &mut Option<BatControl>,
|
||||
vcpu_handles: &[(JoinHandle<()>, mpsc::Sender<VcpuControl>)],
|
||||
|
@ -976,6 +979,15 @@ impl VmRequest {
|
|||
*run_mode = Some(VmRunMode::Exiting);
|
||||
VmResponse::Ok
|
||||
}
|
||||
VmRequest::Powerbtn => {
|
||||
if pm.is_some() {
|
||||
pm.as_ref().unwrap().lock().pwrbtn_evt();
|
||||
VmResponse::Ok
|
||||
} else {
|
||||
error!("{:#?} not supported", *self);
|
||||
VmResponse::Err(SysError::new(ENOTSUP))
|
||||
}
|
||||
}
|
||||
VmRequest::Suspend => {
|
||||
*run_mode = Some(VmRunMode::Suspending);
|
||||
VmResponse::Ok
|
||||
|
|
|
@ -9,12 +9,15 @@ use acpi_tables::{facs::FACS, rsdp::RSDP, sdt::SDT};
|
|||
use arch::VcpuAffinity;
|
||||
use base::{error, warn};
|
||||
use data_model::DataInit;
|
||||
use devices::{PciAddress, PciInterruptPin};
|
||||
use devices::{ACPIPMResource, PciAddress, PciInterruptPin};
|
||||
use std::sync::Arc;
|
||||
use sync::Mutex;
|
||||
use vm_memory::{GuestAddress, GuestMemory};
|
||||
|
||||
pub struct AcpiDevResource {
|
||||
pub amls: Vec<u8>,
|
||||
pub pm_iobase: u64,
|
||||
pub pm: Arc<Mutex<ACPIPMResource>>,
|
||||
/// Additional system descriptor tables.
|
||||
pub sdts: Vec<SDT>,
|
||||
}
|
||||
|
@ -161,7 +164,7 @@ const MCFG_FIELD_BASE_ADDRESS: usize = 44;
|
|||
const MCFG_FIELD_START_BUS_NUMBER: usize = 54;
|
||||
const MCFG_FIELD_END_BUS_NUMBER: usize = 55;
|
||||
|
||||
fn create_dsdt_table(amls: Vec<u8>) -> SDT {
|
||||
fn create_dsdt_table(amls: &[u8]) -> SDT {
|
||||
let mut dsdt = SDT::new(
|
||||
*b"DSDT",
|
||||
acpi_tables::HEADER_LEN,
|
||||
|
@ -172,7 +175,7 @@ fn create_dsdt_table(amls: Vec<u8>) -> SDT {
|
|||
);
|
||||
|
||||
if !amls.is_empty() {
|
||||
dsdt.append_slice(amls.as_slice());
|
||||
dsdt.append_slice(amls);
|
||||
}
|
||||
|
||||
dsdt
|
||||
|
@ -432,7 +435,7 @@ pub fn create_acpi_tables(
|
|||
sci_irq: u32,
|
||||
reset_port: u32,
|
||||
reset_value: u8,
|
||||
acpi_dev_resource: AcpiDevResource,
|
||||
acpi_dev_resource: &AcpiDevResource,
|
||||
host_cpus: Option<VcpuAffinity>,
|
||||
apic_ids: &mut Vec<usize>,
|
||||
pci_irqs: &[(PciAddress, u32, PciInterruptPin)],
|
||||
|
@ -477,7 +480,7 @@ pub fn create_acpi_tables(
|
|||
Some(dsdt_offset) => dsdt_offset,
|
||||
None => {
|
||||
let dsdt_offset = offset;
|
||||
let dsdt = create_dsdt_table(acpi_dev_resource.amls);
|
||||
let dsdt = create_dsdt_table(&acpi_dev_resource.amls);
|
||||
guest_mem.write_at_addr(dsdt.as_slice(), offset).ok()?;
|
||||
offset = next_offset(offset, dsdt.len() as u64)?;
|
||||
dsdt_offset
|
||||
|
|
|
@ -589,7 +589,7 @@ impl arch::LinuxArch for X8664arch {
|
|||
sci_irq,
|
||||
0xcf9,
|
||||
6, // RST_CPU|SYS_RST
|
||||
acpi_dev_resource,
|
||||
&acpi_dev_resource,
|
||||
host_cpus,
|
||||
kvm_vcpu_ids,
|
||||
&pci_irqs,
|
||||
|
@ -662,6 +662,7 @@ impl arch::LinuxArch for X8664arch {
|
|||
bat_control,
|
||||
#[cfg(all(target_arch = "x86_64", feature = "gdb"))]
|
||||
gdb: components.gdb,
|
||||
pm: Some(acpi_dev_resource.pm),
|
||||
root_config: pci,
|
||||
hotplug_bus: Vec::new(),
|
||||
})
|
||||
|
@ -1361,7 +1362,7 @@ impl X8664arch {
|
|||
devices::acpi::ACPIPM_RESOURCE_LEN as u64,
|
||||
)
|
||||
.unwrap();
|
||||
resume_notify_devices.push(pm);
|
||||
resume_notify_devices.push(pm.clone());
|
||||
|
||||
let bat_control = if let Some(battery_type) = battery.0 {
|
||||
match battery_type {
|
||||
|
@ -1384,6 +1385,7 @@ impl X8664arch {
|
|||
acpi::AcpiDevResource {
|
||||
amls,
|
||||
pm_iobase,
|
||||
pm,
|
||||
sdts,
|
||||
},
|
||||
bat_control,
|
||||
|
|
|
@ -222,7 +222,7 @@ where
|
|||
X86_64_SCI_IRQ,
|
||||
0xcf9,
|
||||
6,
|
||||
acpi_dev_resource.0,
|
||||
&acpi_dev_resource.0,
|
||||
None,
|
||||
&mut apic_ids,
|
||||
&pci_irqs,
|
||||
|
|
Loading…
Reference in a new issue