mirror of
https://github.com/StrikerX3/StrikeBox.git
synced 2024-06-21 13:52:36 -04:00
Refactored I/O and MMIO mapping
The mapping is now performed by a separate object which allows I/O devices to be registered to specified I/O and/or MMIO ranges. It also prevents overlapping ranges. All I/O methods have been standardized to the same convention.
This commit is contained in:
parent
f6d6dfbbfb
commit
131b7f9c80
|
@ -27,11 +27,12 @@ void i8254::Reset() {
|
|||
m_running = false;
|
||||
}
|
||||
|
||||
void i8254::IORead(uint32_t addr, uint32_t *value, uint16_t size) {
|
||||
bool i8254::IORead(uint32_t port, uint32_t *value, uint8_t size) {
|
||||
*value = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void i8254::IOWrite(uint32_t addr, uint32_t value, uint16_t size) {
|
||||
bool i8254::IOWrite(uint32_t port, uint32_t value, uint8_t size) {
|
||||
// HACK: The Xbox always inits the PIT to the same value:
|
||||
// Timer 0, Mode 2, 1ms interrupt interval.
|
||||
// Rather than fully implement the PIC, we just wait for the command to
|
||||
|
@ -40,6 +41,7 @@ void i8254::IOWrite(uint32_t addr, uint32_t value, uint16_t size) {
|
|||
m_running = true;
|
||||
Thread_Create("[HW] i8254", i8254ThreadFunc, this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void i8254::Run() {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cstdint>
|
||||
|
||||
#include "i8259.h"
|
||||
#include "openxbox/io.h"
|
||||
|
||||
namespace openxbox {
|
||||
|
||||
|
@ -11,16 +12,15 @@ namespace openxbox {
|
|||
#define PORT_PIT_DATA_2 0x42
|
||||
#define PORT_PIT_COMMAND 0x43
|
||||
|
||||
class i8254
|
||||
{
|
||||
class i8254 : public IODevice {
|
||||
public:
|
||||
i8254(i8259 *pic, float tickRate = 1000.0f);
|
||||
void Reset();
|
||||
|
||||
void Run();
|
||||
|
||||
void IORead(uint32_t addr, uint32_t *value, uint16_t size);
|
||||
void IOWrite(uint32_t addr, uint32_t value, uint16_t size);
|
||||
bool IORead(uint32_t port, uint32_t *value, uint8_t size) override;
|
||||
bool IOWrite(uint32_t port, uint32_t value, uint8_t size) override;
|
||||
private:
|
||||
i8259 *m_pic;
|
||||
float m_tickRate;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "i8259.h"
|
||||
|
||||
#include "openxbox/log.h"
|
||||
#include "openxbox/io.h"
|
||||
|
||||
namespace openxbox {
|
||||
|
||||
|
@ -121,54 +122,56 @@ void i8259::SetIRQ(int pic, int index, bool asserted) {
|
|||
UpdateIRQ(pic);
|
||||
}
|
||||
|
||||
void i8259::IORead(uint32_t addr, uint32_t *value, uint16_t size) {
|
||||
switch (addr) {
|
||||
bool i8259::IORead(uint32_t port, uint32_t *value, uint8_t size) {
|
||||
switch (port) {
|
||||
case PORT_PIC_MASTER_COMMAND:
|
||||
*value = CommandRead(PIC_MASTER);
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_SLAVE_COMMAND:
|
||||
*value = CommandRead(PIC_SLAVE);
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_MASTER_DATA:
|
||||
*value = DataRead(PIC_MASTER);
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_SLAVE_DATA:
|
||||
*value = DataRead(PIC_SLAVE);
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_MASTER_ELCR:
|
||||
*value = m_ELCR[PIC_MASTER];
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_SLAVE_ELCR:
|
||||
*value = m_ELCR[PIC_SLAVE];
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
log_warning("i8295::IORead: Invalid address 0x%x\n", addr);
|
||||
log_warning("i8259::IORead: Invalid address 0x%x\n", port);
|
||||
return false;
|
||||
}
|
||||
|
||||
void i8259::IOWrite(uint32_t addr, uint32_t value, uint16_t size) {
|
||||
switch (addr) {
|
||||
bool i8259::IOWrite(uint32_t port, uint32_t value, uint8_t size) {
|
||||
switch (port) {
|
||||
case PORT_PIC_MASTER_COMMAND:
|
||||
CommandWrite(PIC_MASTER, value);
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_SLAVE_COMMAND:
|
||||
CommandWrite(PIC_SLAVE, value);
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_MASTER_DATA:
|
||||
DataWrite(PIC_MASTER, value);
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_SLAVE_DATA:
|
||||
DataWrite(PIC_SLAVE, value);
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_MASTER_ELCR:
|
||||
m_ELCR[PIC_MASTER] = value & m_ELCRMask[PIC_MASTER];
|
||||
return;
|
||||
return true;
|
||||
case PORT_PIC_SLAVE_ELCR:
|
||||
m_ELCR[PIC_SLAVE] = value & m_ELCRMask[PIC_SLAVE];
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
log_warning("i8295::IOWrite: Invalid address 0x%x\n", addr);
|
||||
log_warning("i8259::IOWrite: Invalid address 0x%x\n", port);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t i8259::CommandRead(int pic) {
|
||||
|
|
|
@ -16,13 +16,13 @@ namespace openxbox {
|
|||
#define PIC_MASTER 0
|
||||
#define PIC_SLAVE 1
|
||||
|
||||
class i8259 {
|
||||
class i8259 : public IODevice {
|
||||
public:
|
||||
i8259(Cpu *cpu);
|
||||
void Reset();
|
||||
|
||||
void IORead(uint32_t addr, uint32_t *value, uint16_t size);
|
||||
void IOWrite(uint32_t addr, uint32_t value, uint16_t size);
|
||||
bool IORead(uint32_t port, uint32_t *value, uint8_t size) override;
|
||||
bool IOWrite(uint32_t port, uint32_t value, uint8_t size) override;
|
||||
|
||||
void RaiseIRQ(int index);
|
||||
void LowerIRQ(int index);
|
||||
|
|
|
@ -85,20 +85,20 @@ void PCIBus::IOWriteConfigData(uint32_t pData, uint8_t size, uint8_t regOffset)
|
|||
);
|
||||
}
|
||||
|
||||
bool PCIBus::IORead(uint32_t addr, uint32_t* data, unsigned size) {
|
||||
switch (addr) {
|
||||
bool PCIBus::IORead(uint32_t port, uint32_t *value, uint8_t size) {
|
||||
switch (port) {
|
||||
case PORT_PCI_CONFIG_DATA: // 0xCFC
|
||||
case PORT_PCI_CONFIG_DATA + 1: // 0xCFD
|
||||
case PORT_PCI_CONFIG_DATA + 2: // 0xCFE
|
||||
case PORT_PCI_CONFIG_DATA + 3: // 0xCFF
|
||||
*data = IOReadConfigData(size, addr - PORT_PCI_CONFIG_DATA);
|
||||
*value = IOReadConfigData(size, port - PORT_PCI_CONFIG_DATA);
|
||||
return true;
|
||||
default:
|
||||
for (auto it = m_Devices.begin(); it != m_Devices.end(); ++it) {
|
||||
uint8_t barIndex;
|
||||
uint32_t baseAddress;
|
||||
if (it->second->GetIOBar(addr, &barIndex, &baseAddress)) {
|
||||
*data = it->second->IORead(barIndex, addr - (baseAddress << 2), size);
|
||||
if (it->second->GetIOBar(port, &barIndex, &baseAddress)) {
|
||||
it->second->PCIIORead(barIndex, port - (baseAddress << 2), value, size);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -107,15 +107,15 @@ bool PCIBus::IORead(uint32_t addr, uint32_t* data, unsigned size) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool PCIBus::IOWrite(uint32_t addr, uint32_t value, unsigned size) {
|
||||
switch (addr) {
|
||||
bool PCIBus::IOWrite(uint32_t port, uint32_t value, uint8_t size) {
|
||||
switch (port) {
|
||||
case PORT_PCI_CONFIG_ADDRESS: // 0xCF8
|
||||
if (size == sizeof(uint32_t)) {
|
||||
IOWriteConfigAddress(value);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
log_warning("PCIBus:IOWrite: Writing %d-bit PCI config address, address 0x%x, value 0x%x\n", size << 3, addr, value);
|
||||
log_warning("PCIBus:IOWrite: Writing %d-bit PCI config address, address 0x%x, value 0x%x\n", size << 3, port, value);
|
||||
IOWriteConfigAddress(value);
|
||||
return true;
|
||||
}
|
||||
|
@ -124,14 +124,14 @@ bool PCIBus::IOWrite(uint32_t addr, uint32_t value, unsigned size) {
|
|||
case PORT_PCI_CONFIG_DATA + 1: // 0xCFD
|
||||
case PORT_PCI_CONFIG_DATA + 2: // 0xCFE
|
||||
case PORT_PCI_CONFIG_DATA + 3: // 0xCFF
|
||||
IOWriteConfigData(value, size, addr - PORT_PCI_CONFIG_DATA);
|
||||
IOWriteConfigData(value, size, port - PORT_PCI_CONFIG_DATA);
|
||||
return true; // TODO : Should IOWriteConfigData() success/failure be returned?
|
||||
default:
|
||||
for (auto it = m_Devices.begin(); it != m_Devices.end(); ++it) {
|
||||
uint8_t barIndex;
|
||||
uint32_t baseAddress;
|
||||
if (it->second->GetIOBar(addr, &barIndex, &baseAddress)) {
|
||||
it->second->IOWrite(barIndex, addr - (baseAddress << 2), value, size);
|
||||
if (it->second->GetIOBar(port, &barIndex, &baseAddress)) {
|
||||
it->second->PCIIOWrite(barIndex, port - (baseAddress << 2), value, size);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -140,12 +140,12 @@ bool PCIBus::IOWrite(uint32_t addr, uint32_t value, unsigned size) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool PCIBus::MMIORead(uint32_t addr, uint32_t* data, unsigned size) {
|
||||
bool PCIBus::MMIORead(uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
for (auto it = m_Devices.begin(); it != m_Devices.end(); ++it) {
|
||||
uint8_t barIndex;
|
||||
uint32_t baseAddress;
|
||||
if (it->second->GetMMIOBar(addr, &barIndex, &baseAddress)) {
|
||||
*data = it->second->MMIORead(barIndex, addr - (baseAddress << 4), size);
|
||||
it->second->PCIMMIORead(barIndex, addr - (baseAddress << 4), value, size);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -153,13 +153,13 @@ bool PCIBus::MMIORead(uint32_t addr, uint32_t* data, unsigned size) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool PCIBus::MMIOWrite(uint32_t addr, uint32_t value, unsigned size) {
|
||||
bool PCIBus::MMIOWrite(uint32_t addr, uint32_t value, uint8_t size) {
|
||||
for (auto it = m_Devices.begin(); it != m_Devices.end(); ++it) {
|
||||
PCIDevice *dev = it->second;
|
||||
uint8_t barIndex;
|
||||
uint32_t baseAddress;
|
||||
if (dev->GetMMIOBar(addr, &barIndex, &baseAddress)) {
|
||||
dev->MMIOWrite(barIndex, addr - (baseAddress << 4), value, size);
|
||||
dev->PCIMMIOWrite(barIndex, addr - (baseAddress << 4), value, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../pci/pci.h"
|
||||
#include "openxbox/io.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
@ -28,15 +29,15 @@ typedef struct {
|
|||
uint8_t enable : 1;
|
||||
} PCIConfigAddressRegister;
|
||||
|
||||
class PCIBus {
|
||||
class PCIBus : public IODevice {
|
||||
public:
|
||||
void ConnectDevice(uint32_t deviceId, PCIDevice *pDevice);
|
||||
|
||||
bool IORead(uint32_t addr, uint32_t* value, unsigned size);
|
||||
bool IOWrite(uint32_t addr, uint32_t value, unsigned size);
|
||||
bool IORead(uint32_t port, uint32_t *value, uint8_t size) override;
|
||||
bool IOWrite(uint32_t port, uint32_t value, uint8_t size) override;
|
||||
|
||||
bool MMIORead(uint32_t addr, uint32_t * data, unsigned size);
|
||||
bool MMIOWrite(uint32_t addr, uint32_t value, unsigned size);
|
||||
bool MMIORead(uint32_t addr, uint32_t *value, uint8_t size) override;
|
||||
bool MMIOWrite(uint32_t addr, uint32_t value, uint8_t size) override;
|
||||
|
||||
void Reset();
|
||||
private:
|
||||
|
|
|
@ -95,65 +95,63 @@ void SMBus::ExecuteTransaction() {
|
|||
m_Status |= GS_HCYC_STS;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SMBus::IORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
void SMBus::PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size) {
|
||||
if (barIndex != 1) {
|
||||
log_debug("SMBus::IORead: unimplemented access to bar %d: address = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
return 0;
|
||||
log_debug("SMBus::PCIIORead: unimplemented access to bar %d: port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
*value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (size != 1) {
|
||||
log_debug("SMBus::IORead: unexpected size %d bar = %d, address = 0x%x\n", size, barIndex, addr);
|
||||
log_debug("SMBus::PCIIORead: unexpected size %d bar = %d, port = 0x%x\n", size, barIndex, port);
|
||||
}
|
||||
|
||||
uint32_t value;
|
||||
addr &= 0x3f;
|
||||
port &= 0x3f;
|
||||
|
||||
switch (addr) {
|
||||
switch (port) {
|
||||
case SMB_GLOBAL_STATUS:
|
||||
value = m_Status;
|
||||
*value = m_Status;
|
||||
break;
|
||||
case SMB_GLOBAL_ENABLE:
|
||||
value = m_Control & 0x1f;
|
||||
*value = m_Control & 0x1f;
|
||||
break;
|
||||
case SMB_HOST_COMMAND:
|
||||
value = m_Command;
|
||||
*value = m_Command;
|
||||
break;
|
||||
case SMB_HOST_ADDRESS:
|
||||
value = m_Address;
|
||||
*value = m_Address;
|
||||
break;
|
||||
case SMB_HOST_DATA:
|
||||
value = m_Data0;
|
||||
*value = m_Data0;
|
||||
break;
|
||||
case SMB_HOST_DATA + 1:
|
||||
value = m_Data1;
|
||||
*value = m_Data1;
|
||||
break;
|
||||
case SMB_HOST_BLOCK_DATA:
|
||||
value = m_Data[m_Index++];
|
||||
*value = m_Data[m_Index++];
|
||||
if (m_Index > 31) {
|
||||
m_Index = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
value = 0;
|
||||
log_debug("SMBus::PCIIOWrite: Unhandled read! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
*value = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void SMBus::IOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
void SMBus::PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size) {
|
||||
if (barIndex != 1) {
|
||||
log_debug("SMBus::IOWrite: unimplemented access to bar %d: address = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
log_debug("SMBus::PCIIOWrite: unimplemented access to bar %d: port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size != 1) {
|
||||
log_debug("SMBus::IOWrite: unexpected size %d bar = %d, address = 0x%x, value = 0x%x\n", size, barIndex, addr, value);
|
||||
log_debug("SMBus::PCIIOWrite: unexpected size %d bar = %d, port = 0x%x, value = 0x%x\n", size, barIndex, port, value);
|
||||
}
|
||||
|
||||
addr &= 0x3f;
|
||||
switch (addr) {
|
||||
port &= 0x3f;
|
||||
switch (port) {
|
||||
case SMB_GLOBAL_STATUS:
|
||||
// If a new status is being set and interrupts are enabled, trigger an interrupt
|
||||
if ((m_Control & GE_HCYC_EN) && ((value & GS_CLEAR_STS) & (~(m_Status & GS_CLEAR_STS)))) {
|
||||
|
@ -211,16 +209,9 @@ void SMBus::IOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
log_debug("SMBus::PCIIOWrite: Unhandled write! bar = %d, port = 0x%x, value = 0x%x, size = %d\n", barIndex, port, value, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t SMBus::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SMBus::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,11 +56,8 @@ public:
|
|||
void Init();
|
||||
void Reset();
|
||||
|
||||
uint32_t IORead(int barIndex, uint32_t addr, unsigned size = sizeof(uint8_t));
|
||||
void IOWrite(int barIndex, uint32_t addr, uint32_t data, unsigned size = sizeof(uint8_t));
|
||||
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
void PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size) override;
|
||||
void PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size) override;
|
||||
|
||||
// Misc
|
||||
void ConnectDevice(uint8_t addr, SMDevice *device);
|
||||
|
|
|
@ -20,36 +20,4 @@ void AC97Device::Init() {
|
|||
void AC97Device::Reset() {
|
||||
}
|
||||
|
||||
uint32_t AC97Device::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
//log_spew("AC97Device::IORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
// TODO
|
||||
log_warning("AC97Device::IORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AC97Device::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
//log_spew("AC97Device::IOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("AC97Device::IOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
uint32_t AC97Device::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
//log_spew("AC97Device::MMIORead: bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
// TODO
|
||||
log_warning("AC97Device::MMIORead: Unimplemented! bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AC97Device::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
//log_spew("AC97Device::MMIOWrite: bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("AC97Device::MMIOWrite: Unimplemented! bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,10 +16,7 @@ public:
|
|||
void Init();
|
||||
void Reset();
|
||||
|
||||
uint32_t IORead(int barIndex, uint32_t port, unsigned size);
|
||||
void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
// TODO: implement I/O
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -21,36 +21,4 @@ void HostBridgeDevice::Init() {
|
|||
void HostBridgeDevice::Reset() {
|
||||
}
|
||||
|
||||
uint32_t HostBridgeDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
//log_spew("HostBridgeDevice::IORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
// TODO
|
||||
log_warning("HostBridgeDevice::IORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HostBridgeDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
//log_spew("HostBridgeDevice::IOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("HostBridgeDevice::IOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
uint32_t HostBridgeDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
//log_spew("HostBridgeDevice::MMIORead: bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
// TODO
|
||||
log_warning("HostBridgeDevice::MMIORead: Unimplemented! bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HostBridgeDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
//log_spew("HostBridgeDevice::MMIOWrite: bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("HostBridgeDevice::MMIOWrite: Unimplemented! bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,11 +15,6 @@ public:
|
|||
// PCI Device functions
|
||||
void Init();
|
||||
void Reset();
|
||||
|
||||
uint32_t IORead(int barIndex, uint32_t port, unsigned size);
|
||||
void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -18,36 +18,4 @@ void IDEDevice::Init() {
|
|||
void IDEDevice::Reset() {
|
||||
}
|
||||
|
||||
uint32_t IDEDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
//log_spew("IDEDevice::IORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
// TODO
|
||||
log_warning("IDEDevice::IORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IDEDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
//log_spew("IDEDevice::IOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("IDEDevice::IOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
uint32_t IDEDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
//log_spew("IDEDevice::MMIORead: bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
// TODO
|
||||
log_warning("IDEDevice::MMIORead: Unimplemented! bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IDEDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
//log_spew("IDEDevice::MMIOWrite: bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("IDEDevice::MMIOWrite: Unimplemented! bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,10 +16,7 @@ public:
|
|||
void Init();
|
||||
void Reset();
|
||||
|
||||
uint32_t IORead(int barIndex, uint32_t port, unsigned size);
|
||||
void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
// TODO: implement I/O
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ void LPCDevice::Init() {
|
|||
void LPCDevice::Reset() {
|
||||
}
|
||||
|
||||
uint32_t LPCDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
log_spew("LPCDevice::IORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
void LPCDevice::PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size) {
|
||||
log_spew("LPCDevice::PCIIORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
if (barIndex != 0) {
|
||||
return 0;
|
||||
log_spew("LPCDevice::PCIIORead: Unhandled BAR access: %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
*value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
@ -32,7 +34,8 @@ uint32_t LPCDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
|||
if (size == sizeof(uint32_t)) {
|
||||
// This timer counts at 3375000 Hz
|
||||
auto t = std::chrono::high_resolution_clock::now();
|
||||
return static_cast<uint32_t>(t.time_since_epoch().count() * 0.003375000);
|
||||
*value = static_cast<uint32_t>(t.time_since_epoch().count() * 0.003375000);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -40,37 +43,21 @@ uint32_t LPCDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
|||
if (size == sizeof(uint8_t)) {
|
||||
// field pin from tv encoder?
|
||||
m_field_pin = (m_field_pin + 1) & 1;
|
||||
return m_field_pin << 5;
|
||||
*value = m_field_pin << 5;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
log_warning("LPCDevice::IORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
return 0;
|
||||
log_warning("LPCDevice::PCIIORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
}
|
||||
|
||||
void LPCDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
//log_spew("LPCDevice::IOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
void LPCDevice::PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size) {
|
||||
//log_spew("LPCDevice::PCIIOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("LPCDevice::IOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
uint32_t LPCDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
//log_spew("LPCDevice::MMIORead: bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
// TODO
|
||||
log_warning("LPCDevice::MMIORead: Unimplemented! bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LPCDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
//log_spew("LPCDevice::MMIOWrite: bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("LPCDevice::MMIOWrite: Unimplemented! bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
log_warning("LPCDevice::PCIIOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,10 +16,8 @@ public:
|
|||
void Init();
|
||||
void Reset();
|
||||
|
||||
uint32_t IORead(int barIndex, uint32_t port, unsigned size);
|
||||
void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
void PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size) override;
|
||||
void PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size) override;
|
||||
|
||||
private:
|
||||
int m_field_pin = 0;
|
||||
|
|
|
@ -18,36 +18,4 @@ void MCPXRAMDevice::Init() {
|
|||
void MCPXRAMDevice::Reset() {
|
||||
}
|
||||
|
||||
uint32_t MCPXRAMDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
//log_spew("MCPXRAMDevice::IORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
// TODO
|
||||
log_warning("MCPXRAMDevice::IORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MCPXRAMDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
//log_spew("MCPXRAMDevice::IOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("MCPXRAMDevice::IOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
uint32_t MCPXRAMDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
//log_spew("MCPXRAMDevice::MMIORead: bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
// TODO
|
||||
log_warning("MCPXRAMDevice::MMIORead: Unimplemented! bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MCPXRAMDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
//log_spew("MCPXRAMDevice::MMIOWrite: bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("MCPXRAMDevice::MMIOWrite: Unimplemented! bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,11 +16,6 @@ public:
|
|||
// PCI Device functions
|
||||
void Init();
|
||||
void Reset();
|
||||
|
||||
uint32_t IORead(int barIndex, uint32_t port, unsigned size);
|
||||
void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
private:
|
||||
MCPXRevision m_revision;
|
||||
};
|
||||
|
|
|
@ -18,36 +18,4 @@ void NVAPUDevice::Init() {
|
|||
void NVAPUDevice::Reset() {
|
||||
}
|
||||
|
||||
uint32_t NVAPUDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
//log_spew("NVAPUDevice::IORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
// TODO
|
||||
log_warning("NVAPUDevice::IORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NVAPUDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
//log_spew("NVAPUDevice::IOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("NVAPUDevice::IOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
uint32_t NVAPUDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
//log_spew("NVAPUDevice::MMIORead: bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
// TODO
|
||||
log_warning("NVAPUDevice::MMIORead: Unimplemented! bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NVAPUDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
//log_spew("NVAPUDevice::MMIOWrite: bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("NVAPUDevice::MMIOWrite: Unimplemented! bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,10 +16,7 @@ public:
|
|||
void Init();
|
||||
void Reset();
|
||||
|
||||
uint32_t IORead(int barIndex, uint32_t port, unsigned size);
|
||||
void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
// TODO: implement I/O
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -470,31 +470,44 @@ void NVNetDevice::Init() {
|
|||
void NVNetDevice::Reset() {
|
||||
}
|
||||
|
||||
uint32_t NVNetDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
if (barIndex != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NVNetDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
void NVNetDevice::PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size) {
|
||||
//log_spew("NVNetDevice::PCIIORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
if (barIndex != 1) {
|
||||
log_spew("NVNetDevice::PCIIORead: Unhandled BAR access: %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
*value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*value = 0;
|
||||
log_warning("NVNetDevice::PCIIORead: Unimplemented read! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
}
|
||||
|
||||
uint32_t NVNetDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
if (barIndex != 0) {
|
||||
return 0;
|
||||
void NVNetDevice::PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size) {
|
||||
//log_spew("NVNetDevice::PCIIOWrite: bar = %d, port = 0x%x, value = 0x%x, size = %d\n", barIndex, port, value, size);
|
||||
if (barIndex != 1) {
|
||||
log_spew("NVNetDevice::PCIIOWrite: Unhandled BAR access: %d, port = 0x%x, value = 0x%x, size = %d\n", barIndex, port, value, size);
|
||||
return;
|
||||
}
|
||||
|
||||
return EmuNVNet_Read(addr, size * 8); // For now, forward
|
||||
log_warning("NVNetDevice::PCIIOWrite: Unimplemented write! bar = %d, port = 0x%x, value = 0x%x, size = %d\n", barIndex, port, value, size);
|
||||
}
|
||||
|
||||
void NVNetDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
void NVNetDevice::PCIMMIORead(int barIndex, uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
//log_spew("NVNetDevice::PCIMMIORead: bar = %d, address = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
if (barIndex != 0) {
|
||||
log_spew("NVNetDevice::PCIMMIORead: Unhandled BAR access: %d, address = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
*value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*value = EmuNVNet_Read(addr, size * 8); // For now, forward
|
||||
return;
|
||||
}
|
||||
|
||||
void NVNetDevice::PCIMMIOWrite(int barIndex, uint32_t addr, uint32_t value, uint8_t size) {
|
||||
//log_spew("NVNetDevice::PCIMMIOWrite: bar = %d, address = 0x%x, value = 0x%x, size = %d\n", barIndex, addr, value, size);
|
||||
if (barIndex != 0) {
|
||||
log_spew("NVNetDevice::PCIMMIOWrite: Unhandled BAR access: %d, address = 0x%x, value = 0x%x, size = %d\n", barIndex, addr, value, size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,11 @@ public:
|
|||
// PCI Device functions
|
||||
void Init();
|
||||
void Reset();
|
||||
uint32_t IORead(int barIndex, uint32_t port, unsigned size);
|
||||
void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
|
||||
void PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size) override;
|
||||
void PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size) override;
|
||||
void PCIMMIORead(int barIndex, uint32_t addr, uint32_t *value, uint8_t size) override;
|
||||
void PCIMMIOWrite(int barIndex, uint32_t addr, uint32_t value, uint8_t size) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -253,4 +253,22 @@ void PCIDevice::WriteConfig(uint32_t reg, uint32_t value, uint8_t size) {
|
|||
// TODO: handle Message Signalled Interrupts
|
||||
}
|
||||
|
||||
void PCIDevice::PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size) {
|
||||
log_spew("PCIDevice::PCIIORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
*value = 0;
|
||||
}
|
||||
|
||||
void PCIDevice::PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size) {
|
||||
log_spew("PCIDevice::PCIIOWrite: bar = %d, port = 0x%x, value = 0x%x, size = %d\n", barIndex, port, value, size);
|
||||
}
|
||||
|
||||
void PCIDevice::PCIMMIORead(int barIndex, uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
log_spew("PCIDevice::PCIMMIORead: bar = %d, address = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
*value = 0;
|
||||
}
|
||||
|
||||
void PCIDevice::PCIMMIOWrite(int barIndex, uint32_t addr, uint32_t value, uint8_t size) {
|
||||
log_spew("PCIDevice::PCIMMIOWrite: bar = %d, address = 0x%x, value = 0x%x, size = %d\n", barIndex, addr, value, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cstdint>
|
||||
|
||||
#include "pci_regs.h"
|
||||
#include "openxbox/io.h"
|
||||
|
||||
namespace openxbox {
|
||||
|
||||
|
@ -49,20 +50,22 @@ class PCIDevice {
|
|||
public:
|
||||
virtual void Init() = 0;
|
||||
virtual void Reset() = 0;
|
||||
virtual uint32_t IORead(int barIndex, uint32_t port, unsigned size) = 0;
|
||||
virtual void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) = 0;
|
||||
virtual uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size) = 0;
|
||||
virtual void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) = 0;
|
||||
|
||||
virtual void PCIIORead(int barIndex, uint32_t port, uint32_t *value, uint8_t size);
|
||||
virtual void PCIIOWrite(int barIndex, uint32_t port, uint32_t value, uint8_t size);
|
||||
virtual void PCIMMIORead(int barIndex, uint32_t addr, uint32_t *value, uint8_t size);
|
||||
virtual void PCIMMIOWrite(int barIndex, uint32_t addr, uint32_t value, uint8_t size);
|
||||
|
||||
// PCI Device Implementation
|
||||
public:
|
||||
PCIDevice(uint8_t type, uint16_t vendorID, uint16_t deviceID,
|
||||
uint8_t revisionID, uint8_t classID, uint8_t subclass, uint8_t progIF,
|
||||
uint16_t subsystemVendorID = 0x00, uint16_t subsystemID = 0x00);
|
||||
|
||||
bool GetIOBar(uint32_t port, uint8_t* barIndex, uint32_t *baseAddress);
|
||||
bool GetMMIOBar(uint32_t addr, uint8_t* barIndex, uint32_t *baseAddress);
|
||||
bool RegisterBAR(int index, uint32_t size, uint32_t type);
|
||||
|
||||
|
||||
void ReadConfig(uint32_t reg, uint8_t *value, uint8_t size);
|
||||
virtual void WriteConfig(uint32_t reg, uint32_t value, uint8_t size);
|
||||
protected:
|
||||
|
|
|
@ -64,36 +64,4 @@ void PCIBridgeDevice::WriteConfig(uint32_t reg, uint32_t value, uint8_t size) {
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t PCIBridgeDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
//log_spew("PCIBridgeDevice::IORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
// TODO
|
||||
log_warning("PCIBridgeDevice::IORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PCIBridgeDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
//log_spew("PCIBridgeDevice::IOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("PCIBridgeDevice::IOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
uint32_t PCIBridgeDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
//log_spew("PCIBridgeDevice::MMIORead: bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
// TODO
|
||||
log_warning("PCIBridgeDevice::MMIORead: Unimplemented! bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PCIBridgeDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
//log_spew("PCIBridgeDevice::MMIOWrite: bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("PCIBridgeDevice::MMIOWrite: Unimplemented! bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,11 +16,6 @@ public:
|
|||
virtual void Init() override;
|
||||
virtual void Reset() override;
|
||||
|
||||
virtual uint32_t IORead(int barIndex, uint32_t port, unsigned size) override;
|
||||
virtual void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) override;
|
||||
virtual uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size) override;
|
||||
virtual void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) override;
|
||||
|
||||
void WriteConfig(uint32_t reg, uint32_t value, uint8_t size) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,36 +18,4 @@ void USBPCIDevice::Init() {
|
|||
void USBPCIDevice::Reset() {
|
||||
}
|
||||
|
||||
uint32_t USBPCIDevice::IORead(int barIndex, uint32_t port, unsigned size) {
|
||||
//log_spew("USBPCIDevice::IORead: bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
// TODO
|
||||
log_warning("USBPCIDevice::IORead: Unimplemented! bar = %d, port = 0x%x, size = %d\n", barIndex, port, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USBPCIDevice::IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size) {
|
||||
//log_spew("USBPCIDevice::IOWrite: bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("USBPCIDevice::IOWrite: Unimplemented! bar = %d, port = 0x%x, size = %d, value = 0x%x\n", barIndex, port, size, value);
|
||||
}
|
||||
|
||||
uint32_t USBPCIDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) {
|
||||
//log_spew("USBPCIDevice::MMIORead: bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
// TODO
|
||||
log_warning("USBPCIDevice::MMIORead: Unimplemented! bar = %d, addr = 0x%x, size = %d\n", barIndex, addr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USBPCIDevice::MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size) {
|
||||
//log_spew("USBPCIDevice::MMIOWrite: bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
|
||||
// TODO
|
||||
log_warning("USBPCIDevice::MMIOWrite: Unimplemented! bar = %d, addr = 0x%x, size = %d, value = 0x%x\n", barIndex, addr, size, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,10 +16,7 @@ public:
|
|||
void Init();
|
||||
void Reset();
|
||||
|
||||
uint32_t IORead(int barIndex, uint32_t port, unsigned size);
|
||||
void IOWrite(int barIndex, uint32_t port, uint32_t value, unsigned size);
|
||||
uint32_t MMIORead(int barIndex, uint32_t addr, unsigned size);
|
||||
void MMIOWrite(int barIndex, uint32_t addr, uint32_t value, unsigned size);
|
||||
// TODO: implement I/O
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ int Xbox::Initialize(OpenXBOXSettings *settings)
|
|||
log_fatal("CPU instantiation failed\n");
|
||||
return -1;
|
||||
}
|
||||
m_cpu->Initialize(this);
|
||||
m_cpu->Initialize(&m_ioMapper);
|
||||
|
||||
// Allow CPU to update memory map based on device allocation, etc
|
||||
m_cpu->MemMap(m_memRegion);
|
||||
|
@ -223,6 +223,19 @@ int Xbox::Initialize(OpenXBOXSettings *settings)
|
|||
m_PCIBus->ConnectDevice(PCI_DEVID(0, PCI_DEVFN(30, 0)), m_AGPBridge);
|
||||
m_PCIBus->ConnectDevice(PCI_DEVID(1, PCI_DEVFN(0, 0)), m_NV2A);
|
||||
|
||||
// Map I/O ports and MMIO addresses
|
||||
m_ioMapper.MapIODevice(PORT_PIC_MASTER_COMMAND, 2, m_i8259);
|
||||
m_ioMapper.MapIODevice(PORT_PIC_SLAVE_COMMAND, 2, m_i8259);
|
||||
m_ioMapper.MapIODevice(PORT_PIC_MASTER_ELCR, 2, m_i8259);
|
||||
|
||||
m_ioMapper.MapIODevice(PORT_PIT_DATA_0, 4, m_i8254);
|
||||
|
||||
m_ioMapper.MapIODevice(PORT_PCI_CONFIG_ADDRESS, 1, m_PCIBus);
|
||||
m_ioMapper.MapIODevice(PORT_PCI_CONFIG_DATA, 4, m_PCIBus);
|
||||
|
||||
// Add the PCI bus as a dynamic I/O mapper
|
||||
m_ioMapper.AddDevice(m_PCIBus);
|
||||
|
||||
// TODO: Handle other SMBUS Addresses, like PIC_ADDRESS, XCALIBUR_ADDRESS
|
||||
// Resources:
|
||||
// http://pablot.com/misc/fancontroller.cpp
|
||||
|
@ -344,109 +357,6 @@ void Xbox::Stop() {
|
|||
m_should_run = false;
|
||||
}
|
||||
|
||||
void Xbox::IORead(uint32_t addr, uint32_t *value, uint16_t size) {
|
||||
log_spew("Xbox::IORead address = 0x%x, size = %d\n", addr, size);
|
||||
|
||||
// TODO: proper I/O port mapping
|
||||
|
||||
switch (addr) {
|
||||
case PORT_PIC_MASTER_COMMAND:
|
||||
case PORT_PIC_MASTER_DATA:
|
||||
case PORT_PIC_SLAVE_COMMAND:
|
||||
case PORT_PIC_SLAVE_DATA:
|
||||
case PORT_PIC_MASTER_ELCR:
|
||||
case PORT_PIC_SLAVE_ELCR:
|
||||
m_i8259->IORead(addr, value, size);
|
||||
break;
|
||||
case PORT_PIT_DATA_0:
|
||||
case PORT_PIT_DATA_1:
|
||||
case PORT_PIT_DATA_2:
|
||||
case PORT_PIT_COMMAND: {
|
||||
m_i8254->IORead(addr, value, size);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
// Pass the IO Read to the PCI Bus.
|
||||
// This will handle devices with BARs set to IO addresses
|
||||
if (m_PCIBus->IORead(addr, value, size)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
log_warning("Unhandled I/O! address = 0x%x, size = %d, read\n", addr, size);
|
||||
*value = 0;
|
||||
}
|
||||
|
||||
void Xbox::IOWrite(uint32_t addr, uint32_t value, uint16_t size) {
|
||||
log_spew("Xbox::IOWrite address = 0x%x, size = %d, value = 0x%x\n", addr, size, value);
|
||||
|
||||
// TODO: proper I/O port mapping
|
||||
|
||||
switch (addr) {
|
||||
case PORT_PIC_MASTER_COMMAND:
|
||||
case PORT_PIC_MASTER_DATA:
|
||||
case PORT_PIC_MASTER_ELCR:
|
||||
case PORT_PIC_SLAVE_COMMAND:
|
||||
case PORT_PIC_SLAVE_DATA:
|
||||
case PORT_PIC_SLAVE_ELCR:
|
||||
m_i8259->IOWrite(addr, value, size);
|
||||
return;
|
||||
case PORT_PIT_DATA_0:
|
||||
case PORT_PIT_DATA_1:
|
||||
case PORT_PIT_DATA_2:
|
||||
case PORT_PIT_COMMAND:
|
||||
m_i8254->IOWrite(addr, value, size);
|
||||
return;
|
||||
default:
|
||||
// Pass the IO Write to the PCI Bus.
|
||||
// This will handle devices with BARs set to IO addresses
|
||||
if (m_PCIBus->IOWrite(addr, value, size)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
log_warning("Unhandled I/O! address = 0x%x, size = %d, write 0x%x\n", addr, size, value);
|
||||
}
|
||||
|
||||
void Xbox::MMIORead(uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
log_spew("Xbox::MMIORead address = 0x%x, size = %d\n", addr, size);
|
||||
|
||||
if ((addr & (size - 1)) != 0) {
|
||||
log_warning("Unaligned MMIO read! address = 0x%x, size = %d\n", addr, size);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass the read to the PCI Bus.
|
||||
// This will handle devices with BARs set to MMIO addresses
|
||||
if (m_PCIBus->MMIORead(addr, value, size)) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_warning("Unhandled MMIO! address = 0x%x, size = %d, read\n", addr, size);
|
||||
*value = 0;
|
||||
}
|
||||
|
||||
void Xbox::MMIOWrite(uint32_t addr, uint32_t value, uint8_t size) {
|
||||
log_spew("Xbox::MMIOWrite address = 0x%x, size = %d, value = 0x%x\n", addr, size, value);
|
||||
|
||||
if ((addr & (size - 1)) != 0) {
|
||||
log_warning("Unaligned MMIO write! address = 0x%x, size = %d, value = 0x%x\n", addr, size, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass the write to the PCI Bus.
|
||||
// This will handle devices with BARs set to MMIO addresses
|
||||
if (m_PCIBus->MMIOWrite(addr, value, size)) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_warning("Unhandled MMIO! address = 0x%x, size = %d, write 0x%x\n", addr, size, value);
|
||||
}
|
||||
|
||||
|
||||
void Xbox::Cleanup() {
|
||||
if (LOG_LEVEL >= LOG_LEVEL_DEBUG) {
|
||||
log_debug("CPU state at the end of execution:\n");
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace openxbox {
|
|||
* This class is the top-level class, will perform initialization and high-level
|
||||
* management of the overall emulation flow.
|
||||
*/
|
||||
class Xbox : Emulator, IOMapper {
|
||||
class Xbox : Emulator {
|
||||
protected:
|
||||
// ----- Modules ----------------------------------------------------------
|
||||
IOpenXBOXCPUModule * m_cpuModule;
|
||||
|
@ -62,6 +62,7 @@ protected:
|
|||
char *m_ram;
|
||||
char *m_rom;
|
||||
MemoryRegion *m_memRegion;
|
||||
IOMapper m_ioMapper;
|
||||
|
||||
i8254 *m_i8254;
|
||||
i8259 *m_i8259;
|
||||
|
@ -105,13 +106,6 @@ public:
|
|||
int Run();
|
||||
int RunCpu();
|
||||
void Stop();
|
||||
|
||||
// IOMapper implementation
|
||||
void IORead(uint32_t addr, uint32_t *value, uint16_t size);
|
||||
void IOWrite(uint32_t addr, uint32_t value, uint16_t size);
|
||||
|
||||
void MMIORead(uint32_t addr, uint32_t *value, uint8_t size);
|
||||
void MMIOWrite(uint32_t addr, uint32_t value, uint8_t size);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "openxbox/memregion.h"
|
||||
#include "openxbox/gdt.h"
|
||||
#include "openxbox/idt.h"
|
||||
#include "openxbox/iomapper.h"
|
||||
#include "openxbox/io.h"
|
||||
|
||||
namespace openxbox {
|
||||
|
||||
|
|
188
src/cpu-module/openxbox/io.cpp
Normal file
188
src/cpu-module/openxbox/io.cpp
Normal file
|
@ -0,0 +1,188 @@
|
|||
#include "io.h"
|
||||
#include "openxbox/log.h"
|
||||
|
||||
namespace openxbox {
|
||||
|
||||
// ----- Default I/O device implementation ------------------------------------
|
||||
|
||||
bool IODevice::IORead(uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
*value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IODevice::IOWrite(uint32_t addr, uint32_t value, uint8_t size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IODevice::MMIORead(uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
*value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IODevice::MMIOWrite(uint32_t addr, uint32_t value, uint8_t size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----- I/O mapper -----------------------------------------------------------
|
||||
|
||||
bool IOMapper::MapIODevice(uint32_t basePort, uint32_t numPorts, IODevice *device) {
|
||||
return MapDevice(m_mappedIODevices, basePort, numPorts, device);
|
||||
}
|
||||
|
||||
bool IOMapper::MapMMIODevice(uint32_t baseAddress, uint32_t numAddresses, IODevice *device) {
|
||||
return MapDevice(m_mappedMMIODevices, baseAddress, numAddresses, device);
|
||||
}
|
||||
|
||||
bool IOMapper::MapDevice(std::map<uint32_t, MappedDevice>& iomap, uint32_t base, uint32_t size, IODevice *device) {
|
||||
uint32_t last = base + size - 1;
|
||||
|
||||
// Ensure there are no overlapping ranges
|
||||
auto pu = iomap.upper_bound(base);
|
||||
if (pu != iomap.end()) {
|
||||
if ((base >= pu->first && base <= pu->second.lastAddress) || (last >= pu->first && last <= pu->second.lastAddress)) {
|
||||
log_warning("IOMapper::MapDevice: Attempted to map a device to %s range 0x%x..0x%x, but another device is already mapped to range 0x%x..0x%x\n",
|
||||
(&iomap == &m_mappedIODevices) ? "I/O" : "MMIO",
|
||||
base, last,
|
||||
pu->first, pu->second.lastAddress);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto pl = iomap.lower_bound(last);
|
||||
if (pl != iomap.begin()) pl--;
|
||||
if (pl != iomap.begin()) {
|
||||
if ((base >= pl->first && base <= pl->second.lastAddress) || (last >= pl->first && last <= pl->second.lastAddress)) {
|
||||
log_warning("IOMapper::MapDevice: Attempted to map a device to %s range 0x%x..0x%x, but another device is already mapped to range 0x%x..0x%x\n",
|
||||
(&iomap == &m_mappedIODevices) ? "I/O" : "MMIO",
|
||||
base, last,
|
||||
pu->first, pu->second.lastAddress);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Map the device to the specified I/O or MMIO range
|
||||
iomap[base] = MappedDevice{ base, last, device };
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IOMapper::AddDevice(IODevice *device) {
|
||||
return m_dynamicDevices.emplace(device).second;
|
||||
}
|
||||
|
||||
bool IOMapper::LookupDevice(std::map<uint32_t, MappedDevice>& iomap, uint32_t addr, IODevice **device) {
|
||||
auto p = iomap.upper_bound(addr);
|
||||
|
||||
// p->first > addr
|
||||
if (p == iomap.begin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// p->first <= addr
|
||||
--p;
|
||||
|
||||
if (addr >= p->first && addr <= p->second.lastAddress) {
|
||||
*device = p->second.device;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IOMapper::IORead(uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
log_spew("IOMapper::IORead: address = 0x%x, size = %d\n", addr, size);
|
||||
|
||||
// Try looking up a device mapped to the specified port first
|
||||
IODevice *dev;
|
||||
if (LookupDevice(m_mappedIODevices, addr, &dev)) {
|
||||
return dev->IORead(addr, value, size);
|
||||
}
|
||||
|
||||
// Otherwise search for one of the dynamically mapped devices
|
||||
for (auto it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); it++) {
|
||||
auto dev = *it;
|
||||
if (dev->IORead(addr, value, size)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
log_warning("IOMapper::IORead: Unhandled I/O! address = 0x%x, size = %d, read\n", addr, size);
|
||||
*value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IOMapper::IOWrite(uint32_t addr, uint32_t value, uint8_t size) {
|
||||
log_spew("IOMapper::IOWrite: address = 0x%x, size = %d, value = 0x%x\n", addr, size, value);
|
||||
|
||||
// Try looking up a device mapped to the specified port first
|
||||
IODevice *dev;
|
||||
if (LookupDevice(m_mappedIODevices, addr, &dev)) {
|
||||
return dev->IOWrite(addr, value, size);
|
||||
}
|
||||
|
||||
// Otherwise search for one of the dynamically mapped devices
|
||||
for (auto it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); it++) {
|
||||
auto dev = *it;
|
||||
if (dev->IOWrite(addr, value, size)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
log_warning("IOMapper::IOWrite: Unhandled I/O! address = 0x%x, size = %d, write 0x%x\n", addr, size, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IOMapper::MMIORead(uint32_t addr, uint32_t *value, uint8_t size) {
|
||||
log_spew("IOMapper::MMIORead: address = 0x%x, size = %d\n", addr, size);
|
||||
|
||||
if ((addr & (size - 1)) != 0) {
|
||||
log_warning("IOMapper::MMIORead: Unaligned MMIO read! address = 0x%x, size = %d\n", addr, size);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try looking up a device mapped to the specified port first
|
||||
IODevice *dev;
|
||||
if (LookupDevice(m_mappedMMIODevices, addr, &dev)) {
|
||||
return dev->MMIORead(addr, value, size);
|
||||
}
|
||||
|
||||
// Otherwise search for one of the dynamically mapped devices
|
||||
for (auto it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); it++) {
|
||||
auto dev = *it;
|
||||
if (dev->MMIORead(addr, value, size)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
log_warning("IOMapper::MMIORead: Unhandled MMIO! address = 0x%x, size = %d, read\n", addr, size);
|
||||
*value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IOMapper::MMIOWrite(uint32_t addr, uint32_t value, uint8_t size) {
|
||||
log_spew("IOMapper::MMIOWrite: address = 0x%x, size = %d, value = 0x%x\n", addr, size, value);
|
||||
|
||||
if ((addr & (size - 1)) != 0) {
|
||||
log_warning("IOMapper::MMIOWrite: Unaligned MMIO write! address = 0x%x, size = %d, value = 0x%x\n", addr, size, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try looking up a device mapped to the specified port first
|
||||
IODevice *dev;
|
||||
if (LookupDevice(m_mappedMMIODevices, addr, &dev)) {
|
||||
return dev->MMIOWrite(addr, value, size);
|
||||
}
|
||||
|
||||
// Otherwise search for one of the dynamically mapped devices
|
||||
for (auto it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); it++) {
|
||||
auto dev = *it;
|
||||
if (dev->MMIOWrite(addr, value, size)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
log_warning("IOMapper::MMIOWrite: Unhandled MMIO! address = 0x%x, size = %d, write 0x%x\n", addr, size, value);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
83
src/cpu-module/openxbox/io.h
Normal file
83
src/cpu-module/openxbox/io.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace openxbox {
|
||||
|
||||
/*!
|
||||
* Abstract base class that represents devices that respond to port-mapped
|
||||
* and/or memory-mapped I/O.
|
||||
*
|
||||
* I/O functions return true if the I/O operation was handled by the device.
|
||||
*
|
||||
* The default implementations read the value 0 and don't handle I/O.
|
||||
*/
|
||||
class IODevice {
|
||||
public:
|
||||
virtual bool IORead(uint32_t port, uint32_t *value, uint8_t size);
|
||||
virtual bool IOWrite(uint32_t port, uint32_t value, uint8_t size);
|
||||
|
||||
virtual bool MMIORead(uint32_t addr, uint32_t *value, uint8_t size);
|
||||
virtual bool MMIOWrite(uint32_t addr, uint32_t value, uint8_t size);
|
||||
};
|
||||
|
||||
/*!
|
||||
* A mapped I/O device with specified I/O or MMIO ranges.
|
||||
*/
|
||||
struct MappedDevice {
|
||||
// I/O or MMIO addresses
|
||||
uint32_t baseAddress;
|
||||
uint32_t lastAddress;
|
||||
|
||||
// The device itself
|
||||
IODevice *device;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Maps I/O and MMIO reads and writes to the corresponding devices.
|
||||
*/
|
||||
class IOMapper {
|
||||
public:
|
||||
/*!
|
||||
* Maps a device to the specified range of ports.
|
||||
*/
|
||||
bool MapIODevice(uint32_t basePort, uint32_t numPorts, IODevice *device);
|
||||
|
||||
/*!
|
||||
* Maps a device to the specified MMIO range.
|
||||
*/
|
||||
bool MapMMIODevice(uint32_t baseAddress, uint32_t numAddresses, IODevice *device);
|
||||
|
||||
/*!
|
||||
* Adds a device with dynamic I/O address mapping.
|
||||
*/
|
||||
bool AddDevice(IODevice *device);
|
||||
|
||||
bool IORead(uint32_t addr, uint32_t *value, uint8_t size);
|
||||
bool IOWrite(uint32_t addr, uint32_t value, uint8_t size);
|
||||
|
||||
bool MMIORead(uint32_t addr, uint32_t *value, uint8_t size);
|
||||
bool MMIOWrite(uint32_t addr, uint32_t value, uint8_t size);
|
||||
|
||||
private:
|
||||
/*!
|
||||
* Looks up the I/O device mapped to the specified I/O or MMIO address,
|
||||
* depending on the map used.
|
||||
*
|
||||
* Returns true if found.
|
||||
*/
|
||||
bool LookupDevice(std::map<uint32_t, MappedDevice>& iomap, uint32_t addr, IODevice **device);
|
||||
|
||||
/*!
|
||||
* Maps a device to the specified address range.
|
||||
*/
|
||||
bool MapDevice(std::map<uint32_t, MappedDevice>& iomap, uint32_t base, uint32_t size, IODevice *device);
|
||||
|
||||
std::map<uint32_t, MappedDevice> m_mappedIODevices;
|
||||
std::map<uint32_t, MappedDevice> m_mappedMMIODevices;
|
||||
std::set<IODevice *> m_dynamicDevices;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace openxbox {
|
||||
|
||||
/*!
|
||||
* Maps I/O and MMIO reads and writes to the corresponding devices.
|
||||
*/
|
||||
class IOMapper {
|
||||
public:
|
||||
virtual void IORead(uint32_t addr, uint32_t *value, uint16_t size) = 0;
|
||||
virtual void IOWrite(uint32_t addr, uint32_t value, uint16_t size) = 0;
|
||||
|
||||
virtual void MMIORead(uint32_t addr, uint32_t *value, uint8_t size) = 0;
|
||||
virtual void MMIOWrite(uint32_t addr, uint32_t value, uint8_t size) = 0;
|
||||
};
|
||||
|
||||
|
||||
}
|
Loading…
Reference in a new issue