hv: emulate ACPI reset register for Service OS guest

Handle the PIO reset register that is defined in host ACPI:

Parse host FADT table to get the host reset register info, and emulate
it for Service OS:

- return all '1' for guest reads because the read behavior is not defined
  in ACPI.
- ignore guest writes with the reset value to stop it from resetting host;
  if guest writes other values, passthru it to hardware in case the reset
  register supports other functionalities.

Tracked-On: #2700
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Zide Chen
2019-05-08 22:43:10 -07:00
committed by wenlingz
parent 26f08680eb
commit 865ee2956e
7 changed files with 93 additions and 1 deletions

View File

@@ -35,6 +35,7 @@
#include <logmsg.h>
#include <host_pm.h>
#include <acrn_common.h>
#include <vm_reset.h>
/* Per ACPI spec:
* There are two fundamental types of ACPI tables:
@@ -56,6 +57,8 @@
/* FACP field offsets */
#define OFFSET_FACS_ADDR 36U
#define OFFSET_RESET_REGISTER 116U
#define OFFSET_RESET_VALUE 128U
#define OFFSET_FACS_X_ADDR 132U
#define OFFSET_PM1A_EVT 148U
#define OFFSET_PM1A_CNT 172U
@@ -154,5 +157,14 @@ void acpi_fixup(void)
sx_data->wake_vector_32 = (uint32_t *)(facs_addr + OFFSET_WAKE_VECTOR_32);
sx_data->wake_vector_64 = (uint64_t *)(facs_addr + OFFSET_WAKE_VECTOR_64);
}
const struct acpi_table_header *table = (const struct acpi_table_header *)facp_addr;
if (table->revision >= 2U) {
struct acpi_reset_reg *rr_data = get_host_reset_reg_data();
get_acpi_dt_gas(facp_addr, OFFSET_RESET_REGISTER, &(rr_data->reg));
rr_data->val = *(facp_addr + OFFSET_RESET_VALUE);
}
}
}