crosvm/devices/src/bat.rs

413 lines
13 KiB
Rust
Raw Normal View History

// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::BusDevice;
use acpi_tables::{aml, aml::Aml};
use base::{error, warn, AsRawDescriptor, Descriptor, Event, PollContext, PollToken};
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
use msg_socket::{MsgReceiver, MsgSender};
use std::fmt::{self, Display};
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
use std::os::unix::io::RawFd;
use std::sync::Arc;
use std::thread;
use sync::Mutex;
use vm_control::{BatControlCommand, BatControlResponseSocket, BatControlResult};
/// Errors for battery devices.
#[derive(Debug)]
pub enum BatteryError {
Non32BitMmioAddress,
}
impl Display for BatteryError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::BatteryError::*;
match self {
Non32BitMmioAddress => write!(f, "Non 32-bit mmio address space"),
}
}
}
type Result<T> = std::result::Result<T, BatteryError>;
/// the GoldFish Battery MMIO length.
pub const GOLDFISHBAT_MMIO_LEN: u64 = 0x1000;
struct GoldfishBatteryState {
// interrupt state
int_status: u32,
int_enable: u32,
// AC state
ac_online: u32,
// Battery state
status: u32,
health: u32,
present: u32,
capacity: u32,
}
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
macro_rules! create_battery_func {
// $property: the battery property which is going to be modified.
// $int: the interrupt status which is going to be set to notify the guest.
($fn:ident, $property:ident, $int:ident) => {
fn $fn(&mut self, value: u32) -> bool {
let old = std::mem::replace(&mut self.$property, value);
old != self.$property && self.set_int_status($int)
}
};
}
impl GoldfishBatteryState {
fn set_int_status(&mut self, mask: u32) -> bool {
if ((self.int_enable & mask) != 0) && ((self.int_status & mask) == 0) {
self.int_status |= mask;
return true;
}
false
}
fn int_status(&self) -> u32 {
self.int_status
}
create_battery_func!(set_ac_online, ac_online, AC_STATUS_CHANGED);
create_battery_func!(set_status, status, BATTERY_STATUS_CHANGED);
create_battery_func!(set_health, health, BATTERY_STATUS_CHANGED);
create_battery_func!(set_present, present, BATTERY_STATUS_CHANGED);
create_battery_func!(set_capacity, capacity, BATTERY_STATUS_CHANGED);
}
/// GoldFish Battery state
pub struct GoldfishBattery {
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
state: Arc<Mutex<GoldfishBatteryState>>,
mmio_base: u32,
irq_num: u32,
irq_evt: Event,
irq_resample_evt: Event,
activated: bool,
monitor_thread: Option<thread::JoinHandle<()>>,
kill_evt: Option<Event>,
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
socket: Option<BatControlResponseSocket>,
}
/// Goldfish Battery MMIO offset
const BATTERY_INT_STATUS: u32 = 0;
const BATTERY_INT_ENABLE: u32 = 0x4;
const BATTERY_AC_ONLINE: u32 = 0x8;
const BATTERY_STATUS: u32 = 0xC;
const BATTERY_HEALTH: u32 = 0x10;
const BATTERY_PRESENT: u32 = 0x14;
const BATTERY_CAPACITY: u32 = 0x18;
const BATTERY_VOLTAGE: u32 = 0x1C;
const BATTERY_TEMP: u32 = 0x20;
const BATTERY_CHARGE_COUNTER: u32 = 0x24;
const BATTERY_VOLTAGE_MAX: u32 = 0x28;
const BATTERY_CURRENT_MAX: u32 = 0x2C;
const BATTERY_CURRENT_NOW: u32 = 0x30;
const BATTERY_CURRENT_AVG: u32 = 0x34;
const BATTERY_CHARGE_FULL_UAH: u32 = 0x38;
const BATTERY_CYCLE_COUNT: u32 = 0x40;
/// Goldfish Battery interrupt bits
const BATTERY_STATUS_CHANGED: u32 = 1 << 0;
const AC_STATUS_CHANGED: u32 = 1 << 1;
const BATTERY_INT_MASK: u32 = BATTERY_STATUS_CHANGED | AC_STATUS_CHANGED;
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
fn command_monitor(
socket: BatControlResponseSocket,
irq_evt: Event,
irq_resample_evt: Event,
kill_evt: Event,
state: Arc<Mutex<GoldfishBatteryState>>,
) {
#[derive(PollToken)]
enum Token {
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
Commands,
Resample,
Kill,
}
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
let poll_ctx: PollContext<Token> = match PollContext::build_with(&[
(&Descriptor(socket.as_raw_descriptor()), Token::Commands),
(
&Descriptor(irq_resample_evt.as_raw_descriptor()),
Token::Resample,
),
(&Descriptor(kill_evt.as_raw_descriptor()), Token::Kill),
]) {
Ok(pc) => pc,
Err(e) => {
error!("failed to build PollContext: {}", e);
return;
}
};
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
'poll: loop {
let events = match poll_ctx.wait() {
Ok(v) => v,
Err(e) => {
error!("error while polling for events: {}", e);
break;
}
};
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
for event in events.iter_readable() {
match event.token() {
Token::Commands => {
let req = match socket.recv() {
Ok(req) => req,
Err(e) => {
error!("failed to receive request: {}", e);
continue;
}
};
let mut bat_state = state.lock();
let inject_irq = match req {
BatControlCommand::SetStatus(status) => bat_state.set_status(status.into()),
BatControlCommand::SetHealth(health) => bat_state.set_health(health.into()),
BatControlCommand::SetPresent(present) => {
let v = if present != 0 { 1 } else { 0 };
bat_state.set_present(v)
}
BatControlCommand::SetCapacity(capacity) => {
let v = std::cmp::min(capacity, 100);
bat_state.set_capacity(v)
}
BatControlCommand::SetACOnline(ac_online) => {
let v = if ac_online != 0 { 1 } else { 0 };
bat_state.set_ac_online(v)
}
};
if inject_irq {
let _ = irq_evt.write(1);
}
if let Err(e) = socket.send(&BatControlResult::Ok) {
error!("failed to send response: {}", e);
}
}
Token::Resample => {
let _ = irq_resample_evt.read();
if state.lock().int_status() != 0 {
let _ = irq_evt.write(1);
}
}
Token::Kill => break 'poll,
}
}
}
}
impl GoldfishBattery {
/// Create GoldfishBattery device model
///
/// * `mmio_base` - The 32-bit mmio base address.
/// * `irq_num` - The corresponding interrupt number of the irq_evt
/// which will be put into the ACPI DSDT.
/// * `irq_evt` - The interrupt event used to notify driver about
/// the battery properties changing.
/// * `irq_resample_evt` - Resample interrupt event notified at EOI.
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
/// * `socket` - Battery control socket
pub fn new(
mmio_base: u64,
irq_num: u32,
irq_evt: Event,
irq_resample_evt: Event,
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
socket: BatControlResponseSocket,
) -> Result<Self> {
if mmio_base + GOLDFISHBAT_MMIO_LEN - 1 > u32::MAX as u64 {
return Err(BatteryError::Non32BitMmioAddress);
}
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
let state = Arc::new(Mutex::new(GoldfishBatteryState {
capacity: 50,
health: 1,
present: 1,
status: 1,
ac_online: 1,
int_enable: 0,
int_status: 0,
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
}));
Ok(GoldfishBattery {
state,
mmio_base: mmio_base as u32,
irq_num,
irq_evt,
irq_resample_evt,
activated: false,
monitor_thread: None,
kill_evt: None,
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
socket: Some(socket),
})
}
/// return the fds used by this device
pub fn keep_fds(&self) -> Vec<RawFd> {
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
let mut fds = vec![
self.irq_evt.as_raw_descriptor(),
self.irq_resample_evt.as_raw_descriptor(),
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
];
if let Some(socket) = &self.socket {
fds.push(socket.as_raw_descriptor());
}
fds
}
/// start a monitor thread to monitor the events from host
fn start_monitor(&mut self) {
if self.activated {
return;
}
let (self_kill_evt, kill_evt) = match Event::new().and_then(|e| Ok((e.try_clone()?, e))) {
Ok(v) => v,
Err(e) => {
error!(
"{}: failed to create kill EventFd pair: {}",
self.debug_label(),
e
);
return;
}
};
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
if let Some(socket) = self.socket.take() {
let irq_evt = self.irq_evt.try_clone().unwrap();
let irq_resample_evt = self.irq_resample_evt.try_clone().unwrap();
let bat_state = self.state.clone();
let monitor_result = thread::Builder::new()
.name(self.debug_label())
.spawn(move || {
command_monitor(socket, irq_evt, irq_resample_evt, kill_evt, bat_state);
});
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
self.monitor_thread = match monitor_result {
Err(e) => {
error!(
"{}: failed to spawn PowerIO monitor: {}",
self.debug_label(),
e
);
return;
}
Ok(join_handle) => Some(join_handle),
};
self.kill_evt = Some(self_kill_evt);
self.activated = true;
}
}
}
impl Drop for GoldfishBattery {
fn drop(&mut self) {
if let Some(kill_evt) = self.kill_evt.take() {
// Ignore the result because there is nothing we can do with a failure.
let _ = kill_evt.write(1);
}
if let Some(thread) = self.monitor_thread.take() {
let _ = thread.join();
}
}
}
impl BusDevice for GoldfishBattery {
fn debug_label(&self) -> String {
"GoldfishBattery".to_owned()
}
fn read(&mut self, offset: u64, data: &mut [u8]) {
if data.len() != std::mem::size_of::<u32>() {
warn!(
"{}: unsupported read length {}, only support 4bytes read",
self.debug_label(),
data.len()
);
return;
}
let val = match offset as u32 {
BATTERY_INT_STATUS => {
// read to clear the interrupt status
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
std::mem::replace(&mut self.state.lock().int_status, 0)
}
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
BATTERY_INT_ENABLE => self.state.lock().int_enable,
BATTERY_AC_ONLINE => self.state.lock().ac_online,
BATTERY_STATUS => self.state.lock().status,
BATTERY_HEALTH => self.state.lock().health,
BATTERY_PRESENT => self.state.lock().present,
BATTERY_CAPACITY => self.state.lock().capacity,
BATTERY_VOLTAGE => 0,
BATTERY_TEMP => 0,
BATTERY_CHARGE_COUNTER => 0,
BATTERY_VOLTAGE_MAX => 0,
BATTERY_CURRENT_MAX => 0,
BATTERY_CURRENT_NOW => 0,
BATTERY_CURRENT_AVG => 0,
BATTERY_CHARGE_FULL_UAH => 0,
BATTERY_CYCLE_COUNT => 0,
_ => {
warn!("{}: unsupported read offset {}", self.debug_label(), offset);
return;
}
};
let val_arr = val.to_ne_bytes();
data.copy_from_slice(&val_arr);
}
fn write(&mut self, offset: u64, data: &[u8]) {
if data.len() != std::mem::size_of::<u32>() {
warn!(
"{}: unsupported write length {}, only support 4bytes write",
self.debug_label(),
data.len()
);
return;
}
let mut val_arr = u32::to_ne_bytes(0 as u32);
val_arr.copy_from_slice(data);
let val = u32::from_ne_bytes(val_arr);
match offset as u32 {
BATTERY_INT_ENABLE => {
Goldfish battery: add external command interface to set the state Add a new command "battery" which is used to modify the virtual battery/ac status. When there is goldfish battery device model created, the command is able to sent to the goldfish battery monitoring thread. If no, the command won't be sent. The supported commands are: 1. crosvm battery goldfish status <status string> crosvm.sock 2. crosvm battery goldfish health <health string> crosvm.sock 3. crosvm battery goldfish present <number> crosvm.sock 4. crosvm battery goldfish capacity <number> crosvm.sock 5. crosvm battery goldfish aconline <number> crosvm.sock "goldfish" is the battery identifier to specify which virtual battery is going to be modified by this command in case there are multiple virtual batteries in the guest in future. Right now only one goldfish battery is supported. BUG=chromium:1050432 BUG=b:137890633 TEST=create VM with parameter "--battery" or "--battery=type=goldfish" and boot linux guest with goldfish_battery driver enabled. From host side, execute command "#crosvm battery goldfish status discharging crosvm.sock" can make the guest receive an interrupt, and the status sysfs is changed to "Discharging". Also tested the other commands as well. TEST=modified values are visible in ARCVM and interrupts are triggered Change-Id: I82177811a6f2b1960f7895522760ff3b8143163f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2119574 Tested-by: Alex Lau <alexlau@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Alex Lau <alexlau@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
2020-04-27 08:39:33 +00:00
self.state.lock().int_enable = val;
if (val & BATTERY_INT_MASK) != 0 && !self.activated {
self.start_monitor();
}
}
_ => {
warn!("{}: Bad write to offset {}", self.debug_label(), offset);
}
};
}
}
impl Aml for GoldfishBattery {
fn to_aml_bytes(&self, bytes: &mut Vec<u8>) {
aml::Device::new(
"GFBY".into(),
vec![
&aml::Name::new("_HID".into(), &"GFSH0001"),
&aml::Name::new(
"_CRS".into(),
&aml::ResourceTemplate::new(vec![
&aml::Memory32Fixed::new(true, self.mmio_base, GOLDFISHBAT_MMIO_LEN as u32),
&aml::Interrupt::new(true, false, false, true, self.irq_num),
]),
),
],
)
.to_aml_bytes(bytes);
}
}