|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [qemu-xen-4.2-testing] xen/pt: consolidate PM capability emu_mask
commit 8c245fa40cd01527dac57292e5497e0fc1515e25
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Jun 10 14:17:54 2015 +0100
Commit: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
CommitDate: Wed Jun 10 14:17:54 2015 +0100
xen/pt: consolidate PM capability emu_mask
There's no point in xen_pt_pmcsr_reg_{read,write}() each ORing
PCI_PM_CTRL_STATE_MASK and PCI_PM_CTRL_NO_SOFT_RESET into a local
emu_mask variable - we can have the same effect by setting the field
descriptor's emu_mask member suitably right away. Note that
xen_pt_pmcsr_reg_write() is being retained in order to allow later
patches to be less intrusive.
This is a preparatory patch for XSA-131.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
hw/pass-through.c | 65 +++++++++++++++++++++++++++-------------------------
1 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/hw/pass-through.c b/hw/pass-through.c
index 81a8de2..98a7df6 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -179,9 +179,6 @@ static int pt_long_reg_read(struct pt_dev *ptdev,
static int pt_bar_reg_read(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
uint32_t *value, uint32_t valid_mask);
-static int pt_pmcsr_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t valid_mask);
static int pt_byte_reg_write(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
uint8_t *value, uint8_t dev_value, uint8_t valid_mask);
@@ -494,7 +491,7 @@ static struct pt_reg_info_tbl pt_emu_reg_pm_tbl[] = {
.u.w.write = pt_word_reg_write,
.u.w.restore = NULL,
},
- /* PCI Power Management Control/Status reg */
+ /* PCI Power Management Control/Status reg (->power_mgmt on) */
{
.offset = PCI_PM_CTRL,
.size = 2,
@@ -502,7 +499,19 @@ static struct pt_reg_info_tbl pt_emu_reg_pm_tbl[] = {
.ro_mask = 0xE1FC,
.emu_mask = 0x8100,
.init = pt_pmcsr_reg_init,
- .u.w.read = pt_pmcsr_reg_read,
+ .u.w.read = pt_word_reg_read,
+ .u.w.write = pt_pmcsr_reg_write,
+ .u.w.restore = pt_pmcsr_reg_restore,
+ },
+ /* PCI Power Management Control/Status reg (->power_mgmt off) */
+ {
+ .offset = PCI_PM_CTRL,
+ .size = 2,
+ .init_val = 0x0008,
+ .ro_mask = 0xE1FC,
+ .emu_mask = 0x810B,
+ .init = pt_pmcsr_reg_init,
+ .u.w.read = pt_word_reg_read,
.u.w.write = pt_pmcsr_reg_write,
.u.w.restore = pt_pmcsr_reg_restore,
},
@@ -2917,6 +2926,7 @@ static uint32_t pt_pmc_reg_init(struct pt_dev *ptdev,
return reg->init_val;
}
+/* this function will be called twice (for ->power_mgmt on and off cases) */
/* initialize PCI Power Management Control/Status register */
static uint32_t pt_pmcsr_reg_init(struct pt_dev *ptdev,
struct pt_reg_info_tbl *reg, uint32_t real_offset)
@@ -2924,8 +2934,23 @@ static uint32_t pt_pmcsr_reg_init(struct pt_dev *ptdev,
PCIDevice *d = &ptdev->dev;
uint16_t cap_ver = 0;
- if (!ptdev->power_mgmt)
- return reg->init_val;
+ switch (reg->emu_mask & (PCI_PM_CTRL_STATE_MASK |
+ PCI_PM_CTRL_NO_SOFT_RESET))
+ {
+ case 0:
+ if (!ptdev->power_mgmt)
+ return PT_INVALID_REG;
+ break;
+ case PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET:
+ if (!ptdev->power_mgmt)
+ return reg->init_val;
+ return PT_INVALID_REG;
+ default:
+ /* exit I/O emulator */
+ PT_LOG("Internal error: Invalid PMCSR emulation mask %04x."
+ " I/O emulator exit.\n", reg->emu_mask);
+ exit(1);
+ }
/* check PCI Power Management support version */
cap_ver = ptdev->pm_state->pmc_field & PCI_PM_CAP_VER_MASK;
@@ -3415,24 +3440,6 @@ static int pt_bar_reg_read(struct pt_dev *ptdev,
}
-/* read Power Management Control/Status register */
-static int pt_pmcsr_reg_read(struct pt_dev *ptdev,
- struct pt_reg_tbl *cfg_entry,
- uint16_t *value, uint16_t valid_mask)
-{
- struct pt_reg_info_tbl *reg = cfg_entry->reg;
- uint16_t valid_emu_mask = reg->emu_mask;
-
- if (!ptdev->power_mgmt)
- valid_emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET;
-
- valid_emu_mask = valid_emu_mask & valid_mask ;
- *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask);
-
- return 0;
-}
-
-
/* write byte size emulate register */
static int pt_byte_reg_write(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
@@ -3766,21 +3773,17 @@ static int pt_pmcsr_reg_write(struct pt_dev *ptdev,
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
PCIDevice *d = &ptdev->dev;
- uint16_t emu_mask = reg->emu_mask;
uint16_t writable_mask = 0;
uint16_t throughable_mask = 0;
struct pt_pm_info *pm_state = ptdev->pm_state;
uint16_t read_val = 0;
- if (!ptdev->power_mgmt)
- emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET;
-
/* modify emulate register */
- writable_mask = emu_mask & ~reg->ro_mask & valid_mask;
+ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* create value for writing to I/O device register */
- throughable_mask = ~emu_mask & valid_mask;
+ throughable_mask = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
if (!ptdev->power_mgmt)
--
generated by git-patchbot for /home/xen/git/qemu-xen-4.2-testing.git
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |