[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [qemu-xen-4.4-testing] xen/pt: consolidate PM capability emu_mask



commit cdad723c1e4bd517c1898825b9eb35509a6d0393
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Jun 10 14:12:16 2015 +0100
Commit:     Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
CommitDate: Wed Jun 10 14:12:16 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 8c63b8a..d73a137 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.4-testing.git

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.