From 7179dbddf4941a5246a57173e24ed3184ff36aa0 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 24 Mar 2009 13:30:10 +0000 Subject: [PATCH] ioemu: emulate No_Soft_Reset in PMCSR When pci_power_mgmt=0, the No_Soft_Reset field in power management control/status register of a PCI device needs to be emulated and fixed to 1. This bit indicates that devices transitioning from D3 to D0 because of PowerState commands do not perform an internal reset. Signed-off-by: Kouya Shimura --- hw/pass-through.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/hw/pass-through.c b/hw/pass-through.c index 0e3d80b9..f23bdbb3 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -2868,7 +2868,7 @@ static int pt_pmcsr_reg_read(struct pt_dev *ptdev, uint16_t valid_emu_mask = reg->emu_mask; if (!ptdev->power_mgmt) - valid_emu_mask |= PCI_PM_CTRL_STATE_MASK; + 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); @@ -3152,37 +3152,26 @@ 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) { - uint16_t emu_mask = - PCI_PM_CTRL_PME_STATUS | PCI_PM_CTRL_DATA_SCALE_MASK | - PCI_PM_CTRL_PME_ENABLE | - PCI_PM_CTRL_DATA_SEL_MASK | PCI_PM_CTRL_STATE_MASK; - uint16_t ro_mask = PCI_PM_CTRL_DATA_SCALE_MASK; - - /* modify emulate register */ - writable_mask = emu_mask & ~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; - *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); - - return 0; - } + if (!ptdev->power_mgmt) + emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; + writable_mask = 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 = ~reg->emu_mask & valid_mask; + throughable_mask = ~emu_mask & valid_mask; *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); + if (!ptdev->power_mgmt) + return 0; + /* set I/O device power state */ pm_state->cur_state = (dev_value & PCI_PM_CTRL_STATE_MASK); -- 2.39.5