30
30
#include <hypervisor.h>
31
31
#include "pci_priv.h"
32
32
33
-
34
- static bool is_cfg_addr (uint16_t addr )
33
+ static void pci_cfg_clear_cache (struct pci_addr_info * pi )
35
34
{
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;
37
38
}
38
39
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 )
40
41
{
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 ;
42
56
}
43
57
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 )
45
59
{
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
+ }
49
68
}
50
69
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 )
52
71
{
53
- uint32_t val = 0xFFFFFFFFU ;
54
72
struct vpci * vpci = & vm -> vpci ;
55
73
struct pci_addr_info * pi = & vpci -> addr_info ;
74
+ uint16_t offset = addr - PCI_CONFIG_DATA ;
75
+ uint32_t val = ~0U ;
56
76
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 );
81
80
}
81
+ pci_cfg_clear_cache (pi );
82
82
}
83
83
84
84
return val ;
85
85
}
86
86
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 )
89
88
{
90
89
struct vpci * vpci = & vm -> vpci ;
91
90
struct pci_addr_info * pi = & vpci -> addr_info ;
91
+ uint16_t offset = addr - PCI_CONFIG_DATA ;
92
92
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 );
113
96
}
97
+ pci_cfg_clear_cache (pi );
114
98
}
115
99
}
116
100
117
101
void vpci_init (struct acrn_vm * vm )
118
102
{
119
103
struct vpci * vpci = & vm -> vpci ;
120
- struct vm_io_range pci_cfg_range = {
104
+
105
+ struct vm_io_range pci_cfgaddr_range = {
121
106
.flags = IO_ATTR_RW ,
122
107
.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
124
115
};
125
116
126
117
vpci -> vm = vm ;
@@ -132,7 +123,12 @@ void vpci_init(struct acrn_vm *vm)
132
123
#endif
133
124
134
125
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
+
136
132
/* This is a tmp solution to avoid sos reboot failure, it need pass-thru IO port CF9 for Reset Control
137
133
* register.
138
134
*/
0 commit comments