mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-10 13:29:38 +00:00
pci: Change pci_conv_rd_data unaligned.
pci_conv_rd_data can be used to handle unaligned or 64-bit accesses in mmio regions if it's modified to include the next 32-bit value. For pci config accesses, grackle repeats the 32-bit value. bandit uses a seemingly random number for the next 32-bit value, but we'll make it work like grackle.
This commit is contained in:
parent
6d23e18c11
commit
54bda0ea95
@ -147,7 +147,10 @@ uint32_t BanditHost::read(uint32_t rgn_start, uint32_t offset, int size)
|
||||
cfg_setup(offset, size, bus_num, dev_num, fun_num, reg_offs, details, device);
|
||||
details.flags |= PCI_CONFIG_READ;
|
||||
if (device) {
|
||||
return pci_conv_rd_data(device->pci_cfg_read(reg_offs, details), details);
|
||||
uint32_t value = device->pci_cfg_read(reg_offs, details);
|
||||
// bytes 4 to 7 are random on bandit but
|
||||
// we choose to repeat bytes 0 to 3 like grackle
|
||||
return pci_conv_rd_data(value, value, details);
|
||||
}
|
||||
LOG_READ_NON_EXISTENT_PCI_DEVICE();
|
||||
return 0xFFFFFFFFUL; // PCI spec §6.1
|
||||
|
@ -93,11 +93,11 @@ protected:
|
||||
// Helpers for data conversion in the PCI Configuration space.
|
||||
|
||||
/**
|
||||
Perform size dependent endian swapping for value that is dword from PCI config.
|
||||
Perform size dependent endian swapping for value that is dword from PCI config or any other dword little endian register.
|
||||
|
||||
Unaligned data is handled properly by wrapping around if needed.
|
||||
Unaligned data is handled properly by using bytes from the next dword.
|
||||
*/
|
||||
inline uint32_t pci_conv_rd_data(uint32_t value, AccessDetails &details) {
|
||||
inline uint32_t pci_conv_rd_data(uint32_t value, uint32_t value2, AccessDetails &details) {
|
||||
switch (details.size << 2 | details.offset) {
|
||||
// Bytes
|
||||
case 0x04:
|
||||
@ -117,17 +117,20 @@ inline uint32_t pci_conv_rd_data(uint32_t value, AccessDetails &details) {
|
||||
case 0x0A:
|
||||
return BYTESWAP_16((value >> 16) & 0xFFFFU); // 2 3
|
||||
case 0x0B:
|
||||
return ((value >> 16) & 0xFF00) | (value & 0xFF); // 3 0
|
||||
return ((value >> 16) & 0xFF00) | (value2 & 0xFF); // 3 4
|
||||
|
||||
// Dwords
|
||||
case 0x10:
|
||||
return BYTESWAP_32(value); // 0 1 2 3
|
||||
return BYTESWAP_32(value); // 0 1 2 3
|
||||
case 0x11:
|
||||
return ROTL_32(BYTESWAP_32(value), 8); // 1 2 3 0
|
||||
value = (uint32_t)((((uint64_t)value2 << 32) | value) >> 8);
|
||||
return BYTESWAP_32(value); // 1 2 3 4
|
||||
case 0x12:
|
||||
return ROTL_32(BYTESWAP_32(value), 16); // 2 3 0 1
|
||||
value = (uint32_t)((((uint64_t)value2 << 32) | value) >> 16);
|
||||
return BYTESWAP_32(value); // 2 3 4 5
|
||||
case 0x13:
|
||||
return ROTR_32(BYTESWAP_32(value), 8); // 3 0 1 2
|
||||
value = (uint32_t)((((uint64_t)value2 << 32) | value) >> 24);
|
||||
return BYTESWAP_32(value); // 3 4 5 6
|
||||
default:
|
||||
return 0xFFFFFFFFUL;
|
||||
}
|
||||
|
@ -86,7 +86,9 @@ uint32_t MPC106::read(uint32_t rgn_start, uint32_t offset, int size) {
|
||||
cfg_setup(offset, size, bus_num, dev_num, fun_num, reg_offs, details, device);
|
||||
details.flags |= PCI_CONFIG_READ;
|
||||
if (device) {
|
||||
return pci_conv_rd_data(device->pci_cfg_read(reg_offs, details), details);
|
||||
uint32_t value = device->pci_cfg_read(reg_offs, details);
|
||||
// bytes 0 to 3 repeat
|
||||
return pci_conv_rd_data(value, value, details);
|
||||
}
|
||||
LOG_READ_NON_EXISTENT_PCI_DEVICE();
|
||||
return 0xFFFFFFFFUL; // PCI spec §6.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user