[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] Re: [PATCH] ioemu: Cleanup the code of PCI passthrough.
On Thu, 19 Feb 2009 17:13:42 +0000 Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> wrote: > Yuji Shimada writes ("[PATCH] ioemu: Cleanup the code of PCI passthrough."): > > This patch cleanups the code of PCI passthrough. > > Thanks but this doesn't apply to the current qemu-xen-unstable head > (commit 200a4ece52fa37d6b884b52c47e3d56b9c1c7563) > > Some of these changes, for example this one: > > - Use LIST_FOREACH(). Don't use lh_first, le_next directly. > seem to have been applied already for example in > 8c771eb6294afc5b3754a9e3de51568d4e5986c2 > > Can you refresh and resend the patch, please ? My patch was created for commit 200a4ece52fa37d6b884b52c47e3d56b9c1c7563. But I found the patch has a trailing whitespace. This might prevent the patch from applying. I removed a trailing whitespace from the patch and attach it to this mail. If the patch doesn't apply to the current qemu-xen-unstable head, Could you send error messages? The patch cleanups the code of PCI passthrough. - Use LIST_FOREACH(). Don't use lh_first, le_next directly. - Use pci_{read, write}_block instead of "switch(len) case [124] pci_{read, write}_{byte, word, long}();". - Eliminate duplicate codes using PT_MEARGE_VALUE macro. - Define PCI_ERR_* macro in pass-through.h if libpci is old. - Remove the unreasonable loop from pt_aer_reg_{save,restore}. - Enable pt_aer_reg_{save,restore}, even if libpci is old. - Fix ro_mask and remove unnecessary pt_xxx_reg_write functions. - Add "Error:" or "Warning:" to messages. - Remove verbose messages. Thanks, -- Yuji Shimada. Signed-off-by: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxx> diff --git a/hw/pass-through.c b/hw/pass-through.c index c2a6ec1..1de0162 100644 --- a/hw/pass-through.c +++ b/hw/pass-through.c @@ -126,18 +126,6 @@ static int pt_exp_rom_bar_reg_write(struct pt_dev *ptdev, static int pt_pmcsr_reg_write(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint16_t *value, uint16_t dev_value, uint16_t valid_mask); -static int pt_devctrl_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t dev_value, uint16_t valid_mask); -static int pt_linkctrl_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t dev_value, uint16_t valid_mask); -static int pt_devctrl2_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t dev_value, uint16_t valid_mask); -static int pt_linkctrl2_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t dev_value, uint16_t valid_mask); static int pt_msgctrl_reg_write(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, uint16_t *value, uint16_t dev_value, uint16_t valid_mask); @@ -413,7 +401,7 @@ static struct pt_reg_info_tbl pt_emu_reg_pm_tbl[] = { .offset = PCI_PM_CTRL, .size = 2, .init_val = 0x0008, - .ro_mask = 0x60FC, + .ro_mask = 0xE1FC, .emu_mask = 0x8100, .init = pt_pmcsr_reg_init, .u.w.read = pt_word_reg_read, @@ -494,11 +482,11 @@ static struct pt_reg_info_tbl pt_emu_reg_pcie_tbl[] = { .offset = PCI_EXP_DEVCTL, .size = 2, .init_val = 0x2810, - .ro_mask = 0x0000, + .ro_mask = 0x8400, .emu_mask = 0xFFFF, .init = pt_common_reg_init, .u.w.read = pt_word_reg_read, - .u.w.write = pt_devctrl_reg_write, + .u.w.write = pt_word_reg_write, .u.w.restore = pt_word_reg_restore, }, /* Link Control reg */ @@ -506,11 +494,11 @@ static struct pt_reg_info_tbl pt_emu_reg_pcie_tbl[] = { .offset = PCI_EXP_LNKCTL, .size = 2, .init_val = 0x0000, - .ro_mask = 0x0000, + .ro_mask = 0xFC34, .emu_mask = 0xFFFF, .init = pt_linkctrl_reg_init, .u.w.read = pt_word_reg_read, - .u.w.write = pt_linkctrl_reg_write, + .u.w.write = pt_word_reg_write, .u.w.restore = pt_word_reg_restore, }, /* Device Control 2 reg */ @@ -518,11 +506,11 @@ static struct pt_reg_info_tbl pt_emu_reg_pcie_tbl[] = { .offset = 0x28, .size = 2, .init_val = 0x0000, - .ro_mask = 0x0000, + .ro_mask = 0xFFE0, .emu_mask = 0xFFFF, .init = pt_devctrl2_reg_init, .u.w.read = pt_word_reg_read, - .u.w.write = pt_devctrl2_reg_write, + .u.w.write = pt_word_reg_write, .u.w.restore = pt_word_reg_restore, }, /* Link Control 2 reg */ @@ -530,11 +518,11 @@ static struct pt_reg_info_tbl pt_emu_reg_pcie_tbl[] = { .offset = 0x30, .size = 2, .init_val = 0x0000, - .ro_mask = 0x0000, + .ro_mask = 0xE040, .emu_mask = 0xFFFF, .init = pt_linkctrl2_reg_init, .u.w.read = pt_word_reg_read, - .u.w.write = pt_linkctrl2_reg_write, + .u.w.write = pt_word_reg_write, .u.w.restore = pt_word_reg_restore, }, { @@ -1051,8 +1039,7 @@ struct pt_reg_grp_tbl* pt_find_reg_grp( struct pt_reg_grp_tbl* reg_grp_entry = NULL; /* find register group entry */ - for (reg_grp_entry = ptdev->reg_grp_tbl_head.lh_first; reg_grp_entry; - reg_grp_entry = reg_grp_entry->entries.le_next) + LIST_FOREACH(reg_grp_entry, &ptdev->reg_grp_tbl_head, entries) { /* check address */ if ((reg_grp_entry->base_offset <= address) && @@ -1075,8 +1062,7 @@ struct pt_reg_tbl* pt_find_reg( uint32_t real_offset = 0; /* find register entry */ - for (reg_entry = reg_grp->reg_tbl_head.lh_first; reg_entry; - reg_entry = reg_entry->entries.le_next) + LIST_FOREACH(reg_entry, ®_grp->reg_tbl_head, entries) { reg = reg_entry->reg; real_offset = (reg_grp->base_offset + reg->offset); @@ -1140,7 +1126,7 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, /* check offset range */ if (address >= 0xFF) { - PT_LOG("Failed to write register with offset exceeding FFh. " + PT_LOG("Error: Failed to write register with offset exceeding FFh. " "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), address, len); @@ -1150,7 +1136,7 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, /* check write size */ if ((len != 1) && (len != 2) && (len != 4)) { - PT_LOG("Failed to write register with invalid access length. " + PT_LOG("Error: Failed to write register with invalid access length. " "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), address, len); @@ -1160,8 +1146,8 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, /* check offset alignment */ if (address & (len-1)) { - PT_LOG("Failed to write register with invalid access size alignment. " - "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", + PT_LOG("Error: Failed to write register with invalid access size " + "alignment. [%02x:%02x.%x][Offset:%02xh][Length:%d]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), address, len); goto exit; @@ -1172,8 +1158,8 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, if ((index >= 0) && (val > 0 && val < PT_BAR_ALLF) && (assigned_device->bases[index].bar_flag == PT_BAR_FLAG_UNUSED)) { - PT_LOG("Guest attempt to set address to unused Base Address Register. " - "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", + PT_LOG("Warning: Guest attempt to set address to unused Base Address " + "Register. [%02x:%02x.%x][Offset:%02xh][Length:%d]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), address, len); } @@ -1194,7 +1180,7 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, if (reg_grp->grp_type == GRP_TYPE_HARDWIRED) { /* ignore silently */ - PT_LOG("Access to 0 Hardwired register. " + PT_LOG("Warning: Access to 0 Hardwired register. " "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), address, len); @@ -1203,28 +1189,14 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, } /* read I/O device register value */ - switch (len) { - case 1: - read_val = pci_read_byte(pci_dev, address); - break; - case 2: - read_val = pci_read_word(pci_dev, address); - break; - case 4: - read_val = pci_read_long(pci_dev, address); - break; - } + ret = pci_read_block(pci_dev, address, (uint8_t *)&read_val, len); - /* check libpci result */ - valid_mask = (0xFFFFFFFF >> ((4 - len) << 3)); - if ((read_val & valid_mask) == valid_mask) + if (!ret) { - PT_LOG("Warning: Return ALL F from libpci read. " - "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", - pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), - address, len); + PT_LOG("Error: pci_read_block failed. return value[%d].\n", ret); + memset((uint8_t *)&read_val, 0xff, len); } - + /* pass directly to libpci for passthrough type register group */ if (reg_grp_entry == NULL) goto out; @@ -1303,17 +1277,10 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val, val >>= ((address & 3) << 3); out: - switch (len){ - case 1: - pci_write_byte(pci_dev, address, val); - break; - case 2: - pci_write_word(pci_dev, address, val); - break; - case 4: - pci_write_long(pci_dev, address, val); - break; - } + ret = pci_write_block(pci_dev, address, (uint8_t *)&val, len); + + if (!ret) + PT_LOG("Error: pci_write_block failed. return value[%d].\n", ret); if (pm_state->flags & PT_FLAG_TRANSITING) /* set QEMUTimer */ @@ -1329,7 +1298,7 @@ static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t address, int len) struct pt_dev *assigned_device = (struct pt_dev *)d; struct pci_dev *pci_dev = assigned_device->pci_dev; struct pt_pm_info *pm_state = assigned_device->pm_state; - uint32_t val = 0xFFFFFFFF; + uint32_t val = 0; struct pt_reg_grp_tbl *reg_grp_entry = NULL; struct pt_reg_grp_info_tbl *reg_grp = NULL; struct pt_reg_tbl *reg_entry = NULL; @@ -1344,7 +1313,7 @@ static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t address, int len) /* check offset range */ if (address >= 0xFF) { - PT_LOG("Failed to read register with offset exceeding FFh. " + PT_LOG("Error: Failed to read register with offset exceeding FFh. " "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), address, len); @@ -1354,7 +1323,7 @@ static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t address, int len) /* check read size */ if ((len != 1) && (len != 2) && (len != 4)) { - PT_LOG("Failed to read register with invalid access length. " + PT_LOG("Error: Failed to read register with invalid access length. " "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), address, len); @@ -1364,8 +1333,8 @@ static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t address, int len) /* check offset alignment */ if (address & (len-1)) { - PT_LOG("Failed to read register with invalid access size alignment. " - "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", + PT_LOG("Error: Failed to read register with invalid access size " + "alignment. [%02x:%02x.%x][Offset:%02xh][Length:%d]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), address, len); goto exit; @@ -1393,26 +1362,12 @@ static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t address, int len) } /* read I/O device register value */ - switch (len) { - case 1: - val = pci_read_byte(pci_dev, address); - break; - case 2: - val = pci_read_word(pci_dev, address); - break; - case 4: - val = pci_read_long(pci_dev, address); - break; - } + ret = pci_read_block(pci_dev, address, (uint8_t *)&val, len); - /* check libpci result */ - valid_mask = (0xFFFFFFFF >> ((4 - len) << 3)); - if ((val & valid_mask) == valid_mask) + if (!ret) { - PT_LOG("Warning: Return ALL F from libpci read. " - "[%02x:%02x.%x][Offset:%02xh][Length:%d]\n", - pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), - address, len); + PT_LOG("Error: pci_read_block failed. return value[%d].\n", ret); + memset((uint8_t *)&val, 0xff, len); } /* just return the I/O device register value for @@ -1514,7 +1471,7 @@ static void pt_libpci_fixup(struct pci_dev *dev) fp = fopen(path, "r"); if ( !fp ) { - PT_LOG("Can't open %s: %s\n", path, strerror(errno)); + PT_LOG("Error: Can't open %s: %s\n", path, strerror(errno)); return; } @@ -1522,7 +1479,7 @@ static void pt_libpci_fixup(struct pci_dev *dev) { if ( fscanf(fp, "%llx %llx %llx", &start, &end, &flags) != 3 ) { - PT_LOG("Syntax error in %s\n", path); + PT_LOG("Error: Syntax error in %s\n", path); break; } @@ -1800,8 +1757,8 @@ static void pt_bar_mapping(struct pt_dev *ptdev, int io_enable, int mem_enable) /* check overlapped address */ ret = pt_chk_bar_overlap(dev->bus, dev->devfn, r_addr, r_size); if (ret > 0) - PT_LOG("ptdev[%02x:%02x.%x][Region:%d][Address:%08xh][Size:%08xh] " - "is overlapped.\n", pci_bus_num(dev->bus), + PT_LOG("Warning: ptdev[%02x:%02x.%x][Region:%d][Address:%08xh]" + "[Size:%08xh] is overlapped.\n", pci_bus_num(dev->bus), (dev->devfn >> 3) & 0x1F, (dev->devfn & 0x7), i, r_addr, r_size); @@ -1841,68 +1798,51 @@ int check_power_state(struct pt_dev *ptdev) return 0; } -/* save AER register */ -static void pt_aer_reg_save(struct pt_dev *ptdev) +/* save AER one register */ +static void aer_save_one_register(struct pt_dev *ptdev, int offset) { PCIDevice *d = &ptdev->dev; uint32_t aer_base = ptdev->pm_state->aer_base; - int i = 0; - /* Root Port and Root Complex Event Collector need size expansion */ - int aer_size = 0x2c; -#ifdef PCI_ERR_UNCOR_MASK - for (i=0; i < aer_size; i+=4) - { - switch (i) { - /* after reset, following register values should be restored. - * So, save them. - */ - case PCI_ERR_UNCOR_MASK: - case PCI_ERR_UNCOR_SEVER: - case PCI_ERR_COR_MASK: - case PCI_ERR_CAP: - *(uint32_t*)(d->config + (aer_base + i)) - = pci_read_long(ptdev->pci_dev, (aer_base + i)); - break; - default: - break; - } - } -#endif + *(uint32_t*)(d->config + (aer_base + offset)) + = pci_read_long(ptdev->pci_dev, (aer_base + offset)); } -/* restore AER register */ -static void pt_aer_reg_restore(struct pt_dev *ptdev) +/* save AER registers */ +static void pt_aer_reg_save(struct pt_dev *ptdev) +{ + /* after reset, following register values should be restored. + * So, save them. + */ + aer_save_one_register(ptdev, PCI_ERR_UNCOR_MASK); + aer_save_one_register(ptdev, PCI_ERR_UNCOR_SEVER); + aer_save_one_register(ptdev, PCI_ERR_COR_MASK); + aer_save_one_register(ptdev, PCI_ERR_CAP); +} + +/* restore AER one register */ +static void aer_restore_one_register(struct pt_dev *ptdev, int offset) { PCIDevice *d = &ptdev->dev; uint32_t aer_base = ptdev->pm_state->aer_base; - int i = 0; uint32_t config = 0; - /* Root Port and Root Complex Event Collector need size expansion */ - int aer_size = 0x2c; -#ifdef PCI_ERR_UNCOR_MASK - for (i=0; i < aer_size; i+=4) - { - switch (i) { - /* the following registers should be reconfigured to correct values - * after reset. restore them. - */ - case PCI_ERR_UNCOR_MASK: - case PCI_ERR_UNCOR_SEVER: - case PCI_ERR_COR_MASK: - case PCI_ERR_CAP: - config = *(uint32_t*)(d->config + (aer_base + i)); - pci_write_long(ptdev->pci_dev, (aer_base + i), config); - break; - /* other registers should not be reconfigured after reset - * if there is no reason - */ - default: - break; - } - } -#endif + config = *(uint32_t*)(d->config + (aer_base + offset)); + pci_write_long(ptdev->pci_dev, (aer_base + offset), config); +} + +/* restore AER registers */ +static void pt_aer_reg_restore(struct pt_dev *ptdev) +{ + /* the following registers should be reconfigured to correct values + * after reset. restore them. + * other registers should not be reconfigured after reset + * if there is no reason + */ + aer_restore_one_register(ptdev, PCI_ERR_UNCOR_MASK); + aer_restore_one_register(ptdev, PCI_ERR_UNCOR_SEVER); + aer_restore_one_register(ptdev, PCI_ERR_COR_MASK); + aer_restore_one_register(ptdev, PCI_ERR_CAP); } /* reset Interrupt and I/O resource */ @@ -2115,7 +2055,7 @@ static int pt_config_reg_init(struct pt_dev *ptdev, reg_entry = qemu_mallocz(sizeof(struct pt_reg_tbl)); if (reg_entry == NULL) { - PT_LOG("Failed to allocate memory.\n"); + PT_LOG("Error: Failed to allocate memory.\n"); err = -1; goto out; } @@ -2171,7 +2111,7 @@ static int pt_config_init(struct pt_dev *ptdev) reg_grp_entry = qemu_mallocz(sizeof(struct pt_reg_grp_tbl)); if (reg_grp_entry == NULL) { - PT_LOG("Failed to allocate memory.\n"); + PT_LOG("Error: Failed to allocate memory.\n"); err = -1; goto out; } @@ -2239,10 +2179,10 @@ static void pt_config_delete(struct pt_dev *ptdev) } /* free all register group entry */ - while ((reg_grp_entry = ptdev->reg_grp_tbl_head.lh_first) != NULL) + while((reg_grp_entry = LIST_FIRST(&ptdev->reg_grp_tbl_head)) != NULL) { /* free all register entry */ - while ((reg_entry = reg_grp_entry->reg_tbl_head.lh_first) != NULL) + while((reg_entry = LIST_FIRST(®_grp_entry->reg_tbl_head)) != NULL) { LIST_REMOVE(reg_entry, entries); qemu_free(reg_entry); @@ -2624,7 +2564,7 @@ static uint8_t pt_msi_size_init(struct pt_dev *ptdev, if ( !ptdev->msi ) { /* exit I/O emulator */ - PT_LOG("error allocation pt_msi_info. I/O emulator exit.\n"); + PT_LOG("Error: Allocating pt_msi_info failed. I/O emulator exit.\n"); exit(1); } memset(ptdev->msi, 0, sizeof(struct pt_msi_info)); @@ -2754,8 +2694,7 @@ static int pt_byte_reg_read(struct pt_dev *ptdev, /* emulate byte register */ valid_emu_mask = reg->emu_mask & valid_mask; - *value = ((*value & ~valid_emu_mask) | - (cfg_entry->data & valid_emu_mask)); + *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); return 0; } @@ -2770,8 +2709,7 @@ static int pt_word_reg_read(struct pt_dev *ptdev, /* emulate word register */ valid_emu_mask = reg->emu_mask & valid_mask; - *value = ((*value & ~valid_emu_mask) | - (cfg_entry->data & valid_emu_mask)); + *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); return 0; } @@ -2786,8 +2724,7 @@ static int pt_long_reg_read(struct pt_dev *ptdev, /* emulate long register */ valid_emu_mask = reg->emu_mask & valid_mask; - *value = ((*value & ~valid_emu_mask) | - (cfg_entry->data & valid_emu_mask)); + *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); return 0; } @@ -2833,8 +2770,7 @@ static int pt_bar_reg_read(struct pt_dev *ptdev, /* emulate BAR */ valid_emu_mask = bar_emu_mask & valid_mask; - *value = ((*value & ~valid_emu_mask) | - (cfg_entry->data & valid_emu_mask)); + *value = PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); return 0; } @@ -2850,13 +2786,11 @@ static int pt_byte_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_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 = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; } @@ -2872,13 +2806,11 @@ static int pt_word_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_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 = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; } @@ -2894,13 +2826,11 @@ static int pt_long_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_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 = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; } @@ -2917,12 +2847,11 @@ static int pt_cmd_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_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 = ((*value & throughable_mask) | (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* mapping BAR */ pt_bar_mapping(ptdev, wr_value & PCI_COMMAND_IO, @@ -2988,8 +2917,7 @@ static int pt_bar_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); + cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* check whether we need to update the virtual region address or not */ switch (ptdev->bases[index].bar_flag) @@ -3007,7 +2935,8 @@ static int pt_bar_reg_write(struct pt_dev *ptdev, if ((last_addr >= 0x10000) && (cfg_entry->data != (PT_BAR_ALLF & ~bar_ro_mask))) { - PT_LOG("Guest attempt to set Base Address over the 64KB. " + PT_LOG("Warning: Guest attempt to set Base Address " + "over the 64KB. " "[%02x:%02x.%x][Offset:%02xh][Address:%08xh][Size:%08xh]\n", pci_bus_num(d->bus), ((d->devfn >> 3) & 0x1F), (d->devfn & 0x7), @@ -3023,7 +2952,7 @@ static int pt_bar_reg_write(struct pt_dev *ptdev, { if (cfg_entry->data != (PT_BAR_ALLF & ~bar_ro_mask)) { - PT_LOG("Guest attempt to set high MMIO Base Address. " + PT_LOG("Warning: Guest attempt to set high MMIO Base Address. " "Ignore mapping. " "[%02x:%02x.%x][Offset:%02xh][High Address:%08xh]\n", pci_bus_num(d->bus), @@ -3066,8 +2995,7 @@ static int pt_bar_reg_write(struct pt_dev *ptdev, exit: /* create value for writing to I/O device register */ throughable_mask = ~bar_emu_mask & valid_mask; - *value = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; } @@ -3099,16 +3027,14 @@ static int pt_exp_rom_bar_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = bar_emu_mask & ~bar_ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); + cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* update the corresponding virtual region address */ r->addr = cfg_entry->data; /* create value for writing to I/O device register */ throughable_mask = ~bar_emu_mask & valid_mask; - *value = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); return 0; } @@ -3122,22 +3048,16 @@ static int pt_pmcsr_reg_write(struct pt_dev *ptdev, PCIDevice *d = &ptdev->dev; uint16_t writable_mask = 0; uint16_t throughable_mask = 0; - uint16_t pmcsr_mask = (PCI_PM_CTRL_PME_ENABLE | - PCI_PM_CTRL_DATA_SEL_MASK | - PCI_PM_CTRL_PME_STATUS); struct pt_pm_info *pm_state = ptdev->pm_state; uint16_t read_val = 0; /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & ~pmcsr_mask; - - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_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 = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* set I/O device power state */ pm_state->cur_state = (dev_value & PCI_PM_CTRL_STATE_MASK); @@ -3236,101 +3156,6 @@ static int pt_pmcsr_reg_write(struct pt_dev *ptdev, return 0; } -/* write Device Control register */ -static int pt_devctrl_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t dev_value, uint16_t valid_mask) -{ - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; - uint16_t devctrl_mask = (PCI_EXP_DEVCTL_AUX_PME | 0x8000); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & ~devctrl_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); - - /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); - - return 0; -} - -/* write Link Control register */ -static int pt_linkctrl_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t dev_value, uint16_t valid_mask) -{ - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; - uint16_t linkctrl_mask = (0x04 | PCI_EXP_LNKCTL_DISABLE | - PCI_EXP_LNKCTL_RETRAIN | - 0x0400 | 0x0800 | 0xF000); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & ~linkctrl_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); - - /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); - - return 0; -} - -/* write Device Control2 register */ -static int pt_devctrl2_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t dev_value, uint16_t valid_mask) -{ - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; - uint16_t devctrl2_mask = 0xFFE0; - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & ~devctrl2_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); - - /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); - - return 0; -} - -/* write Link Control2 register */ -static int pt_linkctrl2_reg_write(struct pt_dev *ptdev, - struct pt_reg_tbl *cfg_entry, - uint16_t *value, uint16_t dev_value, uint16_t valid_mask) -{ - struct pt_reg_info_tbl *reg = cfg_entry->reg; - uint16_t writable_mask = 0; - uint16_t throughable_mask = 0; - uint16_t linkctrl2_mask = (0x0040 | 0xE000); - - /* modify emulate register */ - writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask & - ~linkctrl2_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); - - /* create value for writing to I/O device register */ - throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | - (dev_value & ~throughable_mask)); - - return 0; -} - /* write Message Control register */ static int pt_msgctrl_reg_write(struct pt_dev *ptdev, struct pt_reg_tbl *cfg_entry, @@ -3346,22 +3171,19 @@ static int pt_msgctrl_reg_write(struct pt_dev *ptdev, /* Currently no support for multi-vector */ if ((*value & PCI_MSI_FLAGS_QSIZE) != 0x0) - PT_LOG("try to set more than 1 vector ctrl %x\n", *value); + PT_LOG("Warning: try to set more than 1 vector ctrl %x\n", *value); /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); + cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* update the msi_info too */ ptdev->msi->flags |= cfg_entry->data & ~(MSI_FLAG_UNINIT | PT_MSI_MAPPED | PCI_MSI_FLAGS_ENABLE); - PT_LOG("old_ctrl:%04xh new_ctrl:%04xh\n", old_ctrl, cfg_entry->data); - /* create value for writing to I/O device register */ val = *value; throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI */ if (val & PCI_MSI_FLAGS_ENABLE) @@ -3420,16 +3242,13 @@ static int pt_msgaddr32_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); + cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* update the msi_info too */ ptdev->msi->addr_lo = cfg_entry->data; - PT_LOG("old_addr_lo:%08xh new_addr_lo:%08xh\n", old_addr, cfg_entry->data); - /* create value for writing to I/O device register */ throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI */ if (cfg_entry->data != old_addr) @@ -3455,22 +3274,19 @@ static int pt_msgaddr64_reg_write(struct pt_dev *ptdev, if (!(ptdev->msi->flags & PCI_MSI_FLAGS_64BIT)) { /* exit I/O emulator */ - PT_LOG("why comes to Upper Address without 64 bit support??\n"); + PT_LOG("Error: why comes to Upper Address without 64 bit support??\n"); return -1; } /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); + cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* update the msi_info too */ ptdev->msi->addr_hi = cfg_entry->data; - PT_LOG("old_addr_hi:%08xh new_addr_hi:%08xh\n", old_addr, cfg_entry->data); - /* create value for writing to I/O device register */ throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI */ if (cfg_entry->data != old_addr) @@ -3506,16 +3322,13 @@ static int pt_msgdata_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); + cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); /* update the msi_info too */ ptdev->msi->data = cfg_entry->data; - PT_LOG("old_data:%04xh new_data:%04xh\n", old_data, cfg_entry->data); - /* create value for writing to I/O device register */ throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI */ if (cfg_entry->data != old_data) @@ -3539,14 +3352,11 @@ static int pt_msixctrl_reg_write(struct pt_dev *ptdev, /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; - cfg_entry->data = ((*value & writable_mask) | - (cfg_entry->data & ~writable_mask)); + cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask); - PT_LOG("old_ctrl:%04xh new_ctrl:%04xh\n", old_ctrl, cfg_entry->data); - /* create value for writing to I/O device register */ throughable_mask = ~reg->emu_mask & valid_mask; - *value = ((*value & throughable_mask) | (dev_value & ~throughable_mask)); + *value = PT_MERGE_VALUE(*value, dev_value, throughable_mask); /* update MSI-X */ if ((*value & PCI_MSIX_ENABLE) && !(*value & PCI_MSIX_MASK)) @@ -3979,7 +3789,7 @@ int pt_init(PCIBus *e_bus, const char *direct_pci) pci_access = pci_alloc(); if ( pci_access == NULL ) { - PT_LOG("pci_access is NULL\n"); + PT_LOG("Error: pci_access is NULL\n"); return -1; } pci_init(pci_access); diff --git a/hw/pass-through.h b/hw/pass-through.h index b44b9d7..2b2dbd2 100644 --- a/hw/pass-through.h +++ b/hw/pass-through.h @@ -86,6 +86,26 @@ #define PCI_EXP_TYPE_ROOT_EC 0xa #endif +#ifndef PCI_ERR_UNCOR_MASK +/* Uncorrectable Error Mask */ +#define PCI_ERR_UNCOR_MASK 8 +#endif + +#ifndef PCI_ERR_UNCOR_SEVER +/* Uncorrectable Error Severity */ +#define PCI_ERR_UNCOR_SEVER 12 +#endif + +#ifndef PCI_ERR_COR_MASK +/* Correctable Error Mask */ +#define PCI_ERR_COR_MASK 20 +#endif + +#ifndef PCI_ERR_CAP +/* Advanced Error Capabilities */ +#define PCI_ERR_CAP 24 +#endif + #ifndef PCI_EXT_CAP_ID /* Extended Capabilities (PCI-X 2.0 and PCI Express) */ #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) diff --git a/hw/pt-msi.c b/hw/pt-msi.c index bdd1b38..6b0aaa1 100644 --- a/hw/pt-msi.c +++ b/hw/pt-msi.c @@ -68,7 +68,7 @@ int pt_msi_setup(struct pt_dev *dev) if ( !(dev->msi->flags & MSI_FLAG_UNINIT) ) { - PT_LOG("setup physical after initialized?? \n"); + PT_LOG("Error: setup physical after initialized?? \n"); return -1; } @@ -76,13 +76,13 @@ int pt_msi_setup(struct pt_dev *dev) dev->pci_dev->dev << 3 | dev->pci_dev->func, dev->pci_dev->bus, 0, 0) ) { - PT_LOG("error map msi\n"); + PT_LOG("Error: Mapping of MSI failed.\n"); return -1; } if ( pirq < 0 ) { - PT_LOG("invalid pirq number\n"); + PT_LOG("Error: Invalid pirq number\n"); return -1; } @@ -125,7 +125,7 @@ int pt_msi_update(struct pt_dev *d) addr = (uint64_t)d->msi->addr_hi << 32 | d->msi->addr_lo; gflags = __get_msi_gflags(d->msi->data, addr); - PT_LOG("now update msi with pirq %x gvec %x\n", d->msi->pirq, gvec); + PT_LOG("Update msi with pirq %x gvec %x\n", d->msi->pirq, gvec); return xc_domain_update_msi_irq(xc_handle, domid, gvec, d->msi->pirq, gflags); } @@ -295,19 +295,19 @@ static int pt_msix_update_one(struct pt_dev *dev, int entry_nr) dev->msix->table_base); if ( ret ) { - PT_LOG("error map msix entry %x\n", entry_nr); + PT_LOG("Error: Mapping msix entry %x\n", entry_nr); return ret; } entry->pirq = pirq; } - PT_LOG("now update msix entry %x with pirq %x gvec %x\n", + PT_LOG("Update msix entry %x with pirq %x gvec %x\n", entry_nr, pirq, gvec); ret = xc_domain_update_msi_irq(xc_handle, domid, gvec, pirq, gflags); if ( ret ) { - PT_LOG("error update msix irq info for entry %d\n", entry_nr); + PT_LOG("Error: Updating msix irq info for entry %d\n", entry_nr); return ret; } @@ -378,7 +378,7 @@ void pt_msix_disable(struct pt_dev *dev) static void pci_msix_invalid_write(void *opaque, target_phys_addr_t addr, uint32_t val) { - PT_LOG("invalid write to MSI-X table, \ + PT_LOG("Error: Invalid write to MSI-X table, \ only dword access is allowed.\n"); } @@ -391,8 +391,8 @@ static void pci_msix_writel(void *opaque, target_phys_addr_t addr, uint32_t val) if ( addr % 4 ) { - PT_LOG("unaligned dword access to MSI-X table, addr %016"PRIx64"\n", - addr); + PT_LOG("Error: Unaligned dword access to MSI-X table, \ + addr %016"PRIx64"\n", addr); return; } @@ -402,8 +402,8 @@ static void pci_msix_writel(void *opaque, target_phys_addr_t addr, uint32_t val) if ( offset != 3 && msix->enabled && !(entry->io_mem[3] & 0x1) ) { - PT_LOG("can not update msix entry %d since MSI-X is already \ - function now.\n", entry_nr); + PT_LOG("Error: Can't update msix entry %d since MSI-X is already \ + function.\n", entry_nr); return; } @@ -427,7 +427,7 @@ static CPUWriteMemoryFunc *pci_msix_write[] = { static uint32_t pci_msix_invalid_read(void *opaque, target_phys_addr_t addr) { - PT_LOG("invalid read to MSI-X table, \ + PT_LOG("Error: Invalid read to MSI-X table, \ only dword access is allowed.\n"); return 0; } @@ -440,8 +440,8 @@ static uint32_t pci_msix_readl(void *opaque, target_phys_addr_t addr) if ( addr % 4 ) { - PT_LOG("unaligned dword access to MSI-X table, addr %016"PRIx64"\n", - addr); + PT_LOG("Error: Unaligned dword access to MSI-X table, \ + addr %016"PRIx64"\n", addr); return 0; } @@ -504,7 +504,7 @@ int pt_msix_init(struct pt_dev *dev, int pos) if ( id != PCI_CAP_ID_MSIX ) { - PT_LOG("error id %x pos %x\n", id, pos); + PT_LOG("Error: Invalid id %x pos %x\n", id, pos); return -1; } @@ -516,7 +516,7 @@ int pt_msix_init(struct pt_dev *dev, int pos) + total_entries*sizeof(struct msix_entry_info)); if ( !dev->msix ) { - PT_LOG("error allocation pt_msix_info\n"); + PT_LOG("Error: Allocating pt_msix_info failed.\n"); return -1; } memset(dev->msix, 0, sizeof(struct pt_msix_info) @@ -538,7 +538,7 @@ int pt_msix_init(struct pt_dev *dev, int pos) fd = open("/dev/mem", O_RDWR); if ( fd == -1 ) { - PT_LOG("Can't open /dev/mem: %s\n", strerror(errno)); + PT_LOG("Error: Can't open /dev/mem: %s\n", strerror(errno)); goto error_out; } dev->msix->phys_iomem_base = mmap(0, total_entries * 16, @@ -546,7 +546,7 @@ int pt_msix_init(struct pt_dev *dev, int pos) fd, dev->msix->table_base + table_off); if ( dev->msix->phys_iomem_base == MAP_FAILED ) { - PT_LOG("Can't map physical MSI-X table: %s\n", strerror(errno)); + PT_LOG("Error: Can't map physical MSI-X table: %s\n", strerror(errno)); close(fd); goto error_out; } _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |