}
+static uint32_t get_throughable_mask(const struct pt_dev *ptdev,
+ const struct pt_reg_info_tbl *reg,
+ uint32_t valid_mask)
+{
+ uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask);
+
+ return throughable_mask & valid_mask;
+}
+
/* write byte size emulate register */
static int pt_byte_reg_write(struct pt_dev *ptdev,
struct pt_reg_tbl *cfg_entry,
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint8_t writable_mask = 0;
- uint8_t throughable_mask = 0;
+ uint8_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
/* modify emulate register */
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 = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
return 0;
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
/* modify emulate register */
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 = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
return 0;
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
+ uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
/* modify emulate register */
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 = ~reg->emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
return 0;
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint16_t wr_value = *value;
/* modify emulate register */
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;
-
if (*value & PCI_COMMAND_DISABLE_INTx)
{
if (ptdev->msi_trans_en)
PCIDevice *d = (PCIDevice *)&ptdev->dev;
PCIIORegion *r;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
uint32_t bar_emu_mask = 0;
uint32_t bar_ro_mask = 0;
uint32_t new_addr, last_addr;
exit:
/* create value for writing to I/O device register */
- throughable_mask = ~bar_emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value, 0);
/* After BAR reg update, we need to remap BAR*/
reg_grp_entry = pt_find_reg_grp(ptdev, PCI_COMMAND);
PCIDevice *d = (PCIDevice *)&ptdev->dev;
PCIIORegion *r;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
+ uint32_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint32_t r_size = 0;
- uint32_t bar_emu_mask = 0;
uint32_t bar_ro_mask = 0;
r = &d->io_regions[PCI_ROM_SLOT];
PT_GET_EMUL_SIZE(base->bar_flag, r_size);
/* set emulate mask and read-only mask */
- bar_emu_mask = reg->emu_mask;
bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE;
/* modify emulate register */
r->addr = cfg_entry->data;
/* create value for writing to I/O device register */
- throughable_mask = ~bar_emu_mask & valid_mask;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
/* After BAR reg update, we need to remap BAR*/
struct pt_reg_info_tbl *reg = cfg_entry->reg;
PCIDevice *d = &ptdev->dev;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
struct pt_pm_info *pm_state = ptdev->pm_state;
uint16_t read_val = 0;
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;
*value = PT_MERGE_VALUE(*value, dev_value & ~PCI_PM_CTRL_PME_STATUS,
throughable_mask);
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint16_t old_ctrl = cfg_entry->data;
PCIDevice *pd = (PCIDevice *)ptdev;
uint16_t val;
/* modify emulate register */
writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;
/* also emulate MSI_ENABLE bit for MSI-INTx translation */
- if (ptdev->msi_trans_en)
+ if (ptdev->msi_trans_en) {
writable_mask |= PCI_MSI_FLAGS_ENABLE & valid_mask;
+ throughable_mask &= ~PCI_MSI_FLAGS_ENABLE;
+ }
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* update the msi_info too */
ptdev->msi->flags |= cfg_entry->data &
/* create value for writing to I/O device register */
val = *value;
- throughable_mask = ~reg->emu_mask & valid_mask;
- /* don't pass through MSI_ENABLE bit for MSI-INTx translation */
- if (ptdev->msi_trans_en)
- throughable_mask &= ~PCI_MSI_FLAGS_ENABLE;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
/* update MSI */
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
uint32_t old_addr = cfg_entry->data;
/* modify emulate register */
ptdev->msi->addr_lo = cfg_entry->data;
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value, 0);
/* update MSI */
if (cfg_entry->data != old_addr)
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint32_t writable_mask = 0;
- uint32_t throughable_mask = 0;
uint32_t old_addr = cfg_entry->data;
/* check whether the type is 64 bit or not */
ptdev->msi->addr_hi = cfg_entry->data;
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value, 0);
/* update MSI */
if (cfg_entry->data != old_addr)
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
uint16_t old_data = cfg_entry->data;
uint32_t flags = ptdev->msi->flags;
uint32_t offset = reg->offset;
ptdev->msi->data = cfg_entry->data;
/* create value for writing to I/O device register */
- throughable_mask = ~reg->emu_mask & valid_mask;
- *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
+ *value = PT_MERGE_VALUE(*value, dev_value, 0);
/* update MSI */
if (cfg_entry->data != old_data)
{
struct pt_reg_info_tbl *reg = cfg_entry->reg;
uint16_t writable_mask = 0;
- uint16_t throughable_mask = 0;
+ uint16_t throughable_mask = get_throughable_mask(ptdev, reg, valid_mask);
uint16_t old_ctrl = cfg_entry->data;
/* modify emulate register */
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;
*value = PT_MERGE_VALUE(*value, dev_value, throughable_mask);
/* update MSI-X */