Devices that use IRQ should use the IRQHandler base type instead of the i8259

This commit is contained in:
StrikerX3 2018-12-03 20:37:19 -02:00
parent 2b59883eae
commit 60d3db0cde
12 changed files with 43 additions and 34 deletions

View file

@ -18,12 +18,12 @@ namespace openxbox {
namespace hw {
namespace ata {
ATA::ATA(i8259 *pic) {
m_states[0].m_pic = pic;
ATA::ATA(IRQHandler *irqHandler) {
m_states[0].m_irqHandler = irqHandler;
m_states[0].m_irqNum = kPrimaryIRQ;
m_states[0].m_channel = ChanPrimary;
m_states[1].m_pic = pic;
m_states[1].m_irqHandler = irqHandler;
m_states[1].m_irqNum = kSecondaryIRQ;
m_states[1].m_channel = ChanSecondary;
}

View file

@ -14,7 +14,7 @@
#include <cstdint>
#include "openxbox/cpu.h"
#include "../basic/i8259.h"
#include "../basic/irq.h"
#include "../ata/defs.h"
#include "ata_channel.h"
@ -24,7 +24,7 @@ namespace ata {
class ATA : public IODevice {
public:
ATA(i8259 *pic);
ATA(IRQHandler *irqHandler);
virtual ~ATA();
void Reset();

View file

@ -112,7 +112,7 @@ void ATAChannel::ReadStatus(uint8_t *value) {
*value = StReady;
// [7.15.4]: "Reading this register when an interrupt is pending causes the interrupt to be cleared"
m_pendingInterrupt = false;
HandleInterrupt(false);
}
void ATAChannel::WriteData(uint16_t value) {
@ -123,6 +123,11 @@ void ATAChannel::WriteCommand(uint8_t value) {
log_warning("ATAChannel::WriteCommand: Unimplemented! (channel = %d value = 0x%02x)\n", m_channel, value);
}
void ATAChannel::HandleInterrupt(bool asserted) {
m_interrupt = asserted;
m_irqHandler->HandleIRQ(m_irqNum, asserted);
}
}
}
}

View file

@ -14,7 +14,7 @@
#include <cstdint>
#include "openxbox/cpu.h"
#include "../basic/i8259.h"
#include "../basic/irq.h"
#include "../ata/defs.h"
namespace openxbox {
@ -32,7 +32,7 @@ struct ATAChannel {
// ----- IRQ handling -----------------------------------------------------
i8259 *m_pic;
IRQHandler *m_irqHandler;
uint8_t m_irqNum;
// ----- Registers --------------------------------------------------------
@ -47,7 +47,7 @@ struct ATAChannel {
// ----- State ------------------------------------------------------------
bool m_pendingInterrupt = false; // [5.2.9] INTRQ (Device Interrupt)
bool m_interrupt = false; // [5.2.9] INTRQ (Device Interrupt)
// ----- Basic I/O --------------------------------------------------------
@ -65,6 +65,10 @@ struct ATAChannel {
void WriteData(uint16_t value);
void WriteCommand(uint8_t value);
// ----- Interrupt handling -----------------------------------------------
void HandleInterrupt(bool asserted);
// ----- Utility functions ------------------------------------------------
// Retrieves the index of the currently selected device from bit 4
@ -78,7 +82,7 @@ struct ATAChannel {
inline bool IsPIOMode() const { return m_operationMode >= PIO0 && m_operationMode <= PIO4; }
inline bool IsUltraDMAMode() const { return m_operationMode >= UltraDMA0 && m_operationMode <= UltraDMA2; }
inline void SetIRQ(bool level) const { m_pic->HandleIRQ(m_irqNum, level); }
inline void SetIRQ(bool level) const { m_irqHandler->HandleIRQ(m_irqNum, level); }
};
}

View file

@ -44,8 +44,8 @@ static uint32_t i8254ThreadFunc(void *data) {
return 0;
}
i8254::i8254(i8259 *pic, float tickRate)
: m_pic(pic)
i8254::i8254(IRQHandler *irqHandler, float tickRate)
: m_irqHandler(irqHandler)
, m_tickRate(tickRate)
, m_running(false)
{
@ -92,12 +92,12 @@ void i8254::Run() {
m_running = true;
while (m_running) {
m_pic->HandleIRQ(0, 1);
m_irqHandler->HandleIRQ(0, 1);
nextStop += interval;
std::this_thread::sleep_until(nextStop);
m_pic->HandleIRQ(0, 0);
m_irqHandler->HandleIRQ(0, 0);
}
}

View file

@ -3,7 +3,7 @@
#include <cstdint>
#include <thread>
#include "i8259.h"
#include "irq.h"
#include "openxbox/io.h"
namespace openxbox {
@ -18,7 +18,7 @@ namespace openxbox {
class i8254 : public IODevice {
public:
i8254(i8259 *pic, float tickRate = 1000.0f);
i8254(IRQHandler *irqHandler, float tickRate = 1000.0f);
virtual ~i8254();
void Reset();
@ -29,7 +29,7 @@ public:
void Run();
private:
i8259 *m_pic;
IRQHandler *m_irqHandler;
float m_tickRate;
bool m_running;

View file

@ -124,8 +124,8 @@ void Serial::FifoTimeoutInterruptCB(void *userData) {
((Serial *)userData)->FifoTimeoutInterrupt();
}
Serial::Serial(i8259 *pic, uint32_t ioBase)
: m_pic(pic)
Serial::Serial(IRQHandler *irqHandler, uint32_t ioBase)
: m_irqHandler(irqHandler)
, m_ioBase(ioBase)
{
m_recvFifo = new Fifo<uint8_t>(UART_FIFO_LENGTH);
@ -621,10 +621,10 @@ void Serial::UpdateIRQ() {
m_iir = tmp_iir | (m_iir & 0xF0);
if (tmp_iir != UART_IIR_NO_INT) {
m_pic->HandleIRQ(m_irq, 1);
m_irqHandler->HandleIRQ(m_irq, 1);
}
else {
m_pic->HandleIRQ(m_irq, 0);
m_irqHandler->HandleIRQ(m_irq, 0);
}
}

View file

@ -6,7 +6,7 @@
#include "openxbox/util/fifo.h"
#include "openxbox/util/invoke_later.h"
#include "char.h"
#include "../basic/i8259.h"
#include "../basic/irq.h"
#include <chrono>
@ -22,7 +22,7 @@ namespace openxbox {
class Serial : public IODevice {
public:
Serial(i8259 *pic, uint32_t ioBase);
Serial(IRQHandler *irqHandler, uint32_t ioBase);
virtual ~Serial();
bool Init(CharDriver *chr);
@ -61,7 +61,7 @@ private:
static void UpdateMSLCB(void *userData);
static void FifoTimeoutInterruptCB(void *userData);
i8259 *m_pic;
IRQHandler *m_irqHandler;
uint32_t m_ioBase;
uint16_t m_divider = 0;

View file

@ -32,7 +32,7 @@ const static uint32_t kSerialPortIOBases[] = {
PORT_SERIAL_BASE_2
};
SuperIO::SuperIO(i8259 *pic, CharDriver *chrs[SUPERIO_SERIAL_PORT_COUNT]) {
SuperIO::SuperIO(IRQHandler *irqHandler, CharDriver *chrs[SUPERIO_SERIAL_PORT_COUNT]) {
memset(m_configRegs, 0, sizeof(m_configRegs));
memset(m_deviceRegs, 0, sizeof(m_deviceRegs));
@ -44,7 +44,7 @@ SuperIO::SuperIO(i8259 *pic, CharDriver *chrs[SUPERIO_SERIAL_PORT_COUNT]) {
// Initialize serial ports
for (int i = 0; i < SUPERIO_SERIAL_PORT_COUNT; i++) {
m_serialPorts[i] = new Serial(pic, kSerialPortIOBases[i]);
m_serialPorts[i] = new Serial(irqHandler, kSerialPortIOBases[i]);
m_serialPorts[i]->Init(chrs[i]);
m_serialPorts[i]->SetBaudBase(115200);
}

View file

@ -43,7 +43,7 @@ namespace openxbox {
class SuperIO : public IODevice {
public:
SuperIO(i8259 *pic, CharDriver *chrs[SUPERIO_SERIAL_PORT_COUNT]);
SuperIO(IRQHandler *irqHandler, CharDriver *chrs[SUPERIO_SERIAL_PORT_COUNT]);
virtual ~SuperIO();
void Init();

View file

@ -61,12 +61,12 @@ static inline uint32_t ldl_le_p(const void *p) {
NV2ADevice::NV2ADevice(uint16_t vendorID, uint16_t deviceID, uint8_t revisionID,
uint8_t *pSystemRAM, uint32_t systemRAMSize,
i8259 *pic)
IRQHandler *irqHandler)
: PCIDevice(PCI_HEADER_TYPE_NORMAL, vendorID, deviceID, revisionID,
0x03, 0x00, 0x00) // VGA-compatible controller
, m_pSystemRAM(pSystemRAM)
, m_systemRAMSize(systemRAMSize)
, m_pic(pic)
, m_irqHandler(irqHandler)
{
}
@ -2438,10 +2438,10 @@ void NV2ADevice::UpdateIRQ() {
uint8_t irq = Read8(m_configSpace, PCI_INTERRUPT_PIN);
if (m_PMC.pendingInterrupts && m_PMC.enabledInterrupts) {
m_pic->HandleIRQ(irq, 1);
m_irqHandler->HandleIRQ(irq, 1);
}
else {
m_pic->HandleIRQ(irq, 0);
m_irqHandler->HandleIRQ(irq, 0);
}
}

View file

@ -6,7 +6,7 @@
#include "pci.h"
#include "../nv2a/defs.h"
#include "../nv2a/vga.h"
#include "../basic/i8259.h"
#include "../basic/irq.h"
namespace openxbox {
@ -14,7 +14,7 @@ class NV2ADevice : public PCIDevice {
public:
NV2ADevice(uint16_t vendorID, uint16_t deviceID, uint8_t revisionID,
uint8_t *pSystemRAM, uint32_t systemRAMSize,
i8259 *pic);
IRQHandler *irqHandler);
virtual ~NV2ADevice();
@ -122,7 +122,7 @@ private:
uint8_t *m_pSystemRAM;
uint32_t m_systemRAMSize;
i8259 *m_pic;
IRQHandler *m_irqHandler;
uint8_t* m_pRAMIN = nullptr;
uint8_t* m_VRAM = nullptr;