vmm: cpu & acpi: Query CPU manager for CPU status

Rather than hardcode the CPU status for all the CPUs instead query from
the CPU manager via the I/O port that is is on via the ACPI tables.

Each CPU device has a _STA method that calls into the CSTA method which
reads and writes the I/O ports via the PRST field which exposes the I/O
port through and OpRegion.

As we only support boot CPUS report that all the CPUs are enabled for
now.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2019-11-20 14:06:37 +00:00
committed by Sebastien Boeuf
parent 5faf8b756c
commit 07cdb37dda
2 changed files with 127 additions and 16 deletions

View File

@@ -342,12 +342,43 @@ pub struct CpuManager {
vcpus_pause_signalled: Arc<AtomicBool>,
reset_evt: EventFd,
threads: Vec<thread::JoinHandle<()>>,
selected_cpu: u8,
}
impl BusDevice for CpuManager {
fn read(&mut self, _base: u64, _offset: u64, data: &mut [u8]) {}
const CPU_ENABLE_FLAG: usize = 0;
fn write(&mut self, _base: u64, _offset: u64, data: &[u8]) {}
const CPU_STATUS_OFFSET: u64 = 4;
const CPU_SELECTION_OFFSET: u64 = 0;
impl BusDevice for CpuManager {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
match offset {
CPU_STATUS_OFFSET => {
// All CPUs are currently enabled
data[0] |= 1 << CPU_ENABLE_FLAG;
}
_ => {
warn!(
"Unexpected offset for accessing CPU manager device: {:#}",
offset
);
}
}
}
fn write(&mut self, _base: u64, offset: u64, data: &[u8]) {
match offset {
CPU_SELECTION_OFFSET => {
self.selected_cpu = data[0];
}
_ => {
warn!(
"Unexpected offset for accessing CPU manager device: {:#}",
offset
);
}
}
}
}
impl CpuManager {
@@ -371,6 +402,7 @@ impl CpuManager {
vcpus_pause_signalled: Arc::new(AtomicBool::new(false)),
threads: Vec::with_capacity(boot_vcpus as usize),
reset_evt,
selected_cpu: 0,
}));
cpu_manager