Skip to content

Commit fe9a340

Browse files
ZideChen0lijinxia
authored andcommitted
hv: separate the PCI CONFIG_ADDR and CONFIG_DATA I/O port handlers
Register separate I/O emulation handlers for I/O port CF8 and CFC. This makes the code simpler, and offers some flexibilities to be able to handle CF8 and CFC ports differently. Tracked-On: #1815 Signed-off-by: Zide Chen <zide.chen@intel.com> Reviewed-by: Li, Fei1 <fei1.li@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent 8b4f395 commit fe9a340

File tree

2 files changed

+59
-62
lines changed

2 files changed

+59
-62
lines changed

hypervisor/dm/vpci/vpci.c

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -30,97 +30,88 @@
3030
#include <hypervisor.h>
3131
#include "pci_priv.h"
3232

33-
34-
static bool is_cfg_addr(uint16_t addr)
33+
static void pci_cfg_clear_cache(struct pci_addr_info *pi)
3534
{
36-
return (addr >= PCI_CONFIG_ADDR) && (addr < (PCI_CONFIG_ADDR + 4U));
35+
pi->cached_bdf.value = 0xFFFFU;
36+
pi->cached_reg = 0U;
37+
pi->cached_enable = false;
3738
}
3839

39-
static bool is_cfg_data(uint16_t addr)
40+
static uint32_t pci_cfgaddr_io_read(struct acrn_vm *vm, uint16_t addr, size_t bytes)
4041
{
41-
return (addr >= PCI_CONFIG_DATA) && (addr < (PCI_CONFIG_DATA + 4U));
42+
uint32_t val = ~0U;
43+
struct vpci *vpci = &vm->vpci;
44+
struct pci_addr_info *pi = &vpci->addr_info;
45+
46+
if ((addr == (uint16_t)PCI_CONFIG_ADDR) && (bytes == 4U)) {
47+
val = (uint32_t)pi->cached_bdf.value;
48+
val <<= 8U;
49+
val |= pi->cached_reg;
50+
if (pi->cached_enable) {
51+
val |= PCI_CFG_ENABLE;
52+
}
53+
}
54+
55+
return val;
4256
}
4357

44-
static void pci_cfg_clear_cache(struct pci_addr_info *pi)
58+
static void pci_cfgaddr_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes, uint32_t val)
4559
{
46-
pi->cached_bdf.value = 0xFFFFU;
47-
pi->cached_reg = 0U;
48-
pi->cached_enable = false;
60+
struct vpci *vpci = &vm->vpci;
61+
struct pci_addr_info *pi = &vpci->addr_info;
62+
63+
if ((addr == (uint16_t)PCI_CONFIG_ADDR) && (bytes == 4U)) {
64+
pi->cached_bdf.value = (uint16_t)(val >> 8U);
65+
pi->cached_reg = val & PCI_REGMAX;
66+
pi->cached_enable = ((val & PCI_CFG_ENABLE) == PCI_CFG_ENABLE);
67+
}
4968
}
5069

51-
static uint32_t pci_cfg_io_read(struct acrn_vm *vm, uint16_t addr, size_t bytes)
70+
static uint32_t pci_cfgdata_io_read(struct acrn_vm *vm, uint16_t addr, size_t bytes)
5271
{
53-
uint32_t val = 0xFFFFFFFFU;
5472
struct vpci *vpci = &vm->vpci;
5573
struct pci_addr_info *pi = &vpci->addr_info;
74+
uint16_t offset = addr - PCI_CONFIG_DATA;
75+
uint32_t val = ~0U;
5676

57-
if (is_cfg_addr(addr)) {
58-
/* TODO: handling the non 4 bytes access */
59-
if (bytes == 4U) {
60-
val = (uint32_t)pi->cached_bdf.value;
61-
val <<= 8U;
62-
val |= pi->cached_reg;
63-
if (pi->cached_enable) {
64-
val |= PCI_CFG_ENABLE;
65-
}
66-
}
67-
} else {
68-
if (is_cfg_data(addr)) {
69-
if (pi->cached_enable) {
70-
uint16_t offset = addr - PCI_CONFIG_DATA;
71-
72-
if ((vpci->ops != NULL) && (vpci->ops->cfgread != NULL)) {
73-
vpci->ops->cfgread(vpci, pi->cached_bdf,
74-
pi->cached_reg + offset, bytes, &val);
75-
}
76-
77-
pci_cfg_clear_cache(pi);
78-
}
79-
} else {
80-
val = 0xFFFFFFFFU;
77+
if (pi->cached_enable) {
78+
if ((vpci->ops != NULL) && (vpci->ops->cfgread != NULL)) {
79+
vpci->ops->cfgread(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, &val);
8180
}
81+
pci_cfg_clear_cache(pi);
8282
}
8383

8484
return val;
8585
}
8686

87-
static void pci_cfg_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes,
88-
uint32_t val)
87+
static void pci_cfgdata_io_write(struct acrn_vm *vm, uint16_t addr, size_t bytes, uint32_t val)
8988
{
9089
struct vpci *vpci = &vm->vpci;
9190
struct pci_addr_info *pi = &vpci->addr_info;
91+
uint16_t offset = addr - PCI_CONFIG_DATA;
9292

93-
if (is_cfg_addr(addr)) {
94-
/* TODO: handling the non 4 bytes access */
95-
if (bytes == 4U) {
96-
pi->cached_bdf.value = (uint16_t)(val >> 8U);
97-
pi->cached_reg = val & PCI_REGMAX;
98-
pi->cached_enable = ((val & PCI_CFG_ENABLE) == PCI_CFG_ENABLE);
99-
}
100-
} else {
101-
if (is_cfg_data(addr)) {
102-
if (pi->cached_enable) {
103-
uint16_t offset = addr - PCI_CONFIG_DATA;
104-
105-
if ((vpci->ops != NULL) && (vpci->ops->cfgwrite != NULL)) {
106-
vpci->ops->cfgwrite(vpci, pi->cached_bdf,
107-
pi->cached_reg + offset, bytes, val);
108-
}
109-
pci_cfg_clear_cache(pi);
110-
}
111-
} else {
112-
pr_err("Not PCI cfg data/addr port access!");
93+
if (pi->cached_enable) {
94+
if ((vpci->ops != NULL) && (vpci->ops->cfgwrite != NULL)) {
95+
vpci->ops->cfgwrite(vpci, pi->cached_bdf, pi->cached_reg + offset, bytes, val);
11396
}
97+
pci_cfg_clear_cache(pi);
11498
}
11599
}
116100

117101
void vpci_init(struct acrn_vm *vm)
118102
{
119103
struct vpci *vpci = &vm->vpci;
120-
struct vm_io_range pci_cfg_range = {
104+
105+
struct vm_io_range pci_cfgaddr_range = {
121106
.flags = IO_ATTR_RW,
122107
.base = PCI_CONFIG_ADDR,
123-
.len = 8U
108+
.len = 4U
109+
};
110+
111+
struct vm_io_range pci_cfgdata_range = {
112+
.flags = IO_ATTR_RW,
113+
.base = PCI_CONFIG_DATA,
114+
.len = 4U
124115
};
125116

126117
vpci->vm = vm;
@@ -132,7 +123,12 @@ void vpci_init(struct acrn_vm *vm)
132123
#endif
133124

134125
if ((vpci->ops->init != NULL) && (vpci->ops->init(vm) == 0)) {
135-
register_io_emulation_handler(vm, PCI_PIO_IDX, &pci_cfg_range, pci_cfg_io_read, pci_cfg_io_write);
126+
register_io_emulation_handler(vm, PCI_CFGADDR_PIO_IDX, &pci_cfgaddr_range,
127+
pci_cfgaddr_io_read, pci_cfgaddr_io_write);
128+
129+
register_io_emulation_handler(vm, PCI_CFGDATA_PIO_IDX, &pci_cfgdata_range,
130+
pci_cfgdata_io_read, pci_cfgdata_io_write);
131+
136132
/* This is a tmp solution to avoid sos reboot failure, it need pass-thru IO port CF9 for Reset Control
137133
* register.
138134
*/

hypervisor/include/arch/x86/io.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
#define PIC_MASTER_PIO_IDX 0U
1414
#define PIC_SLAVE_PIO_IDX (PIC_MASTER_PIO_IDX + 1U)
1515
#define PIC_ELC_PIO_IDX (PIC_SLAVE_PIO_IDX + 1U)
16-
#define PCI_PIO_IDX (PIC_ELC_PIO_IDX + 1U)
17-
#define UART_PIO_IDX (PCI_PIO_IDX + 1U)
16+
#define PCI_CFGADDR_PIO_IDX (PIC_ELC_PIO_IDX + 1U)
17+
#define PCI_CFGDATA_PIO_IDX (PCI_CFGADDR_PIO_IDX + 1U)
18+
#define UART_PIO_IDX (PCI_CFGDATA_PIO_IDX + 1U)
1819
#define PM1A_EVT_PIO_IDX (UART_PIO_IDX + 1U)
1920
#define PM1A_CNT_PIO_IDX (PM1A_EVT_PIO_IDX + 1U)
2021
#define PM1B_EVT_PIO_IDX (PM1A_CNT_PIO_IDX + 1U)

0 commit comments

Comments
 (0)