x86_64/devices: acpi: Add support for ACPI shutdown & reboot

Add an I/O port "device" to handle requests from the kernel to shutdown
or trigger a reboot, borrowing an I/O used for ACPI on the Q35 platform.
The details of this I/O port are included in the FADT
(SLEEP_STATUS_REG/SLEEP_CONTROL_REG/RESET_REG) with the details of the
value to write in the FADT for reset (RESET_VALUE) and in the DSDT for
shutdown (S5 -> 0x05)

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2019-08-29 14:58:25 +01:00
committed by Samuel Ortiz
parent ae66a44d26
commit 5a187ee2c2
4 changed files with 89 additions and 4 deletions

View File

@@ -608,6 +608,9 @@ struct DeviceManager {
// i8042 device for i8042 reset
i8042: Arc<Mutex<devices::legacy::I8042Device>>,
// ACPI device for reboot/shutdwon
acpi_device: Arc<Mutex<devices::AcpiShutdownDevice>>,
// Shutdown (exit) and reboot (reset) control
exit_evt: EventFd,
reset_evt: EventFd,
@@ -686,6 +689,10 @@ impl DeviceManager {
let i8042 = Arc::new(Mutex::new(devices::legacy::I8042Device::new(
exit_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
)));
let acpi_device = Arc::new(Mutex::new(devices::AcpiShutdownDevice::new(
exit_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
reset_evt.try_clone().map_err(DeviceManagerError::EventFd)?,
)));
let pci_root = PciRoot::new(None);
let mut pci = PciConfigIo::new(pci_root);
@@ -737,6 +744,7 @@ impl DeviceManager {
serial,
console_input: console,
i8042,
acpi_device,
exit_evt,
reset_evt,
ioapic,
@@ -1284,6 +1292,10 @@ impl DeviceManager {
.insert(self.i8042.clone(), 0x61, 0x4)
.map_err(Error::BusError)?;
self.io_bus
.insert(self.acpi_device.clone(), 0x3c0, 0x4)
.map_err(Error::BusError)?;
// Insert the PCI root configuration space.
self.io_bus
.insert(self.pci.clone(), 0xcf8, 0x8)