Rename data conversion helpers for PCI config.

Reword some descriptions for better understanding.
This commit is contained in:
Maxim Poliakovski 2023-02-02 02:21:23 +01:00
parent 36dee46e9b
commit e64aab1577
4 changed files with 23 additions and 15 deletions

View File

@ -166,7 +166,7 @@ uint32_t BanditHost::read(uint32_t rgn_start, uint32_t offset, int size)
details.flags = PCI_CONFIG_TYPE_0 | PCI_CONFIG_READ; details.flags = PCI_CONFIG_TYPE_0 | PCI_CONFIG_READ;
result = this->dev_map[idsel]->pci_cfg_read(REG_NUM(), details); result = this->dev_map[idsel]->pci_cfg_read(REG_NUM(), details);
return pci_cfg_rev_read(result, details); return pci_conv_rd_data(result, details);
} else { } else {
LOG_F( LOG_F(
ERROR, "%s err: read attempt from non-existing PCI device ??:%02x.%x @%02x", ERROR, "%s err: read attempt from non-existing PCI device ??:%02x.%x @%02x",
@ -225,7 +225,7 @@ void BanditHost::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int
this->dev_map[idsel]->pci_cfg_write(REG_NUM(), BYTESWAP_32(value), details); this->dev_map[idsel]->pci_cfg_write(REG_NUM(), BYTESWAP_32(value), details);
} else { // otherwise perform necessary data transformations -> slow path } else { // otherwise perform necessary data transformations -> slow path
uint32_t old_val = this->dev_map[idsel]->pci_cfg_read(REG_NUM(), details); uint32_t old_val = this->dev_map[idsel]->pci_cfg_read(REG_NUM(), details);
uint32_t new_val = pci_cfg_rev_write(old_val, value, details); uint32_t new_val = pci_conv_wr_data(old_val, value, details);
this->dev_map[idsel]->pci_cfg_write(REG_NUM(), new_val, details); this->dev_map[idsel]->pci_cfg_write(REG_NUM(), new_val, details);
} }
} else { } else {

View File

@ -116,12 +116,12 @@ protected:
// PCI configuration space state // PCI configuration space state
uint16_t vendor_id; uint16_t vendor_id;
uint16_t device_id; uint16_t device_id;
uint32_t class_rev; // class code and revision id uint32_t class_rev; // class code and revision id
uint16_t status = 0; uint16_t status = 0;
uint16_t command = 0; uint16_t command = 0;
uint8_t hdr_type = 0; // header type uint8_t hdr_type = 0; // header type
uint8_t lat_timer = 0; // latency timer uint8_t lat_timer = 0; // latency timer
uint8_t cache_ln_sz = 0; // cache line size uint8_t cache_ln_sz = 0; // cache line size
uint16_t subsys_id = 0; uint16_t subsys_id = 0;
uint16_t subsys_vndr = 0; uint16_t subsys_vndr = 0;
uint8_t cap_ptr = 0; uint8_t cap_ptr = 0;

View File

@ -72,9 +72,14 @@ protected:
std::vector<PCIDevice*> io_space_devs; std::vector<PCIDevice*> io_space_devs;
}; };
/* value is dword from PCI config. MSB..LSB of value is stored in PCI config as 0:LSB..3:MSB. // Helpers for data conversion in the PCI Configuration space.
result is part of value at byte offset from LSB with size bytes (with wrap around) and flipped as required for pci_cfg_read result. */
inline uint32_t pci_cfg_rev_read(uint32_t value, AccessDetails &details) { /**
Perform size dependent endian swapping for value that is dword from PCI config.
Unaligned data is handled properly by wrapping around if needed.
*/
inline uint32_t pci_conv_rd_data(uint32_t value, AccessDetails &details) {
switch (details.size << 2 | details.offset) { switch (details.size << 2 | details.offset) {
// Bytes // Bytes
case 0x04: case 0x04:
@ -110,10 +115,13 @@ inline uint32_t pci_cfg_rev_read(uint32_t value, AccessDetails &details) {
} }
} }
/* value is dword from PCI config. MSB..LSB of value (3.2.1.0) is stored in PCI config as 0:LSB..3:MSB. /**
newvalue is flipped bytes (d0.d1.d2.d3, as passed to pci_cfg_write) to be merged into value. Perform size dependent endian swapping for v2, then merge v2 with v1 under
result is part of value at byte offset from LSB with size bytes (with wrap around) modified by newvalue. */ control of a mask generated according with the size parameter.
inline uint32_t pci_cfg_rev_write(uint32_t v1, uint32_t v2, AccessDetails &details)
Unaligned data is handled properly by wrapping around if needed.
*/
inline uint32_t pci_conv_wr_data(uint32_t v1, uint32_t v2, AccessDetails &details)
{ {
switch (details.size << 2 | details.offset) { switch (details.size << 2 | details.offset) {
// Bytes // Bytes

View File

@ -136,7 +136,7 @@ uint32_t MPC106::pci_read(uint32_t offset, uint32_t size) {
details.size = size; details.size = size;
details.flags = PCI_CONFIG_TYPE_0 | PCI_CONFIG_READ; details.flags = PCI_CONFIG_TYPE_0 | PCI_CONFIG_READ;
uint32_t result = this->dev_map[dev_num]->pci_cfg_read(reg_offs, details); uint32_t result = this->dev_map[dev_num]->pci_cfg_read(reg_offs, details);
return pci_cfg_rev_read(result, details); return pci_conv_rd_data(result, details);
} else { } else {
LOG_F(ERROR, "%s: read attempt from non-existing PCI device ??:%02x.%x @%02x", LOG_F(ERROR, "%s: read attempt from non-existing PCI device ??:%02x.%x @%02x",
this->name.c_str(), dev_num, fun_num, offset); this->name.c_str(), dev_num, fun_num, offset);
@ -167,7 +167,7 @@ void MPC106::pci_write(uint32_t offset, uint32_t value, uint32_t size) {
this->dev_map[dev_num]->pci_cfg_write(reg_offs, BYTESWAP_32(value), details); this->dev_map[dev_num]->pci_cfg_write(reg_offs, BYTESWAP_32(value), details);
} else { // otherwise perform necessary data transformations -> slow path } else { // otherwise perform necessary data transformations -> slow path
uint32_t old_val = this->dev_map[dev_num]->pci_cfg_read(reg_offs, details); uint32_t old_val = this->dev_map[dev_num]->pci_cfg_read(reg_offs, details);
uint32_t new_val = pci_cfg_rev_write(old_val, value, details); uint32_t new_val = pci_conv_wr_data(old_val, value, details);
this->dev_map[dev_num]->pci_cfg_write(reg_offs, new_val, details); this->dev_map[dev_num]->pci_cfg_write(reg_offs, new_val, details);
} }
} else { } else {