mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-11 04:29:37 +00:00
Interrupt refactor in progress
This commit is contained in:
parent
7fbbde0750
commit
3db6d07060
|
@ -61,7 +61,8 @@ AMIC::AMIC()
|
|||
}
|
||||
|
||||
bool AMIC::supports_type(HWCompType type) {
|
||||
if (type == HWCompType::MMIO_DEV) {
|
||||
if ((type == HWCompType::MMIO_DEV)
|
||||
|| (type == HWCompType::INT_CTRL)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -28,6 +28,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
#include <devices/common/scsi/ncr53c94.h>
|
||||
#include <devices/common/viacuda.h>
|
||||
#include <devices/ethernet/mace.h>
|
||||
#include <devices/ioctrl/interruptctrl.h>
|
||||
#include <devices/serial/escc.h>
|
||||
#include <devices/sound/awacs.h>
|
||||
|
||||
|
@ -121,7 +122,7 @@ enum AMICReg : uint32_t {
|
|||
};
|
||||
|
||||
/** Apple Memory-mapped I/O controller device. */
|
||||
class AMIC : public MMIODevice {
|
||||
class AMIC : public MMIODevice, public InterruptCtrl {
|
||||
public:
|
||||
AMIC();
|
||||
~AMIC() = default;
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-21 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HEATHINTCTRL_H
|
||||
#define HEATHINTCTRL_H
|
||||
|
||||
#include <cinttypes>
|
||||
#include <devices/ioctrl/interruptctrl.h>
|
||||
#include <memory>
|
||||
|
||||
enum AMIC_Int {
|
||||
};
|
||||
|
||||
class AMICIntCtrl : public InterruptCtrl {
|
||||
};
|
||||
|
||||
#endif /* HEATHINTCTRL_H */
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-21 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HEATHINTCTRL_H
|
||||
#define HEATHINTCTRL_H
|
||||
|
||||
#include <devices/ioctrl/interruptctrl.h>
|
||||
#include <cinttypes>
|
||||
#include <memory>
|
||||
|
||||
enum Heathrow_Int1 {
|
||||
SCSI_DMA = (1 << 0),
|
||||
Swim3_DMA = (1 << 1),
|
||||
IDE0_DMA = (1 << 2),
|
||||
IDE1_DMA = (1 << 3),
|
||||
SCC_A_DMA_OUT = (1 << 4),
|
||||
SCC_A_DMA_IN = (1 << 5),
|
||||
SCC_B_DMA_OUT = (1 << 6),
|
||||
SCC_B_DMA_IN = (1 << 7),
|
||||
DAVBUS_DMA_OUT = (1 << 8),
|
||||
DAVBUS_DMA_IN = (1 << 9),
|
||||
SCSI0 = (1 << 12),
|
||||
IDE0 = (1 << 13),
|
||||
IDE1 = (1 << 14),
|
||||
SCC_A = (1 << 15),
|
||||
SCC_B = (1 << 16),
|
||||
DAVBUS = (1 << 17),
|
||||
VIA_CUDA = (1 << 18),
|
||||
SWIM3 = (1 << 19),
|
||||
NMI = (1 << 20),
|
||||
PERCH_DMA = (1 << 21),
|
||||
PERCH = (1 << 26),
|
||||
};
|
||||
|
||||
enum Heathrow_Int2 {
|
||||
BMAC_DMA_OUT = (1 << 32),
|
||||
BMAC_DMA_IN = (1 << 33),
|
||||
BMAC = (1 << 42),
|
||||
};
|
||||
|
||||
class HeathIntCtrl : public InterruptCtrl {
|
||||
public:
|
||||
HeathIntCtrl(){};
|
||||
~HeathIntCtrl() = default;
|
||||
|
||||
void update_mask2_flags(uint32_t bit_setting) {
|
||||
int_mask2 = bit_setting;
|
||||
}
|
||||
|
||||
void update_events2_flags(uint32_t bit_setting) {
|
||||
int_events2 = bit_setting;
|
||||
}
|
||||
|
||||
void update_levels2_flags(uint32_t bit_setting) {
|
||||
int_levels2 = bit_setting;
|
||||
}
|
||||
|
||||
void update_clear2_flags(uint32_t bit_setting) {
|
||||
int_clear2 = bit_setting;
|
||||
int_events2 &= ~int_clear2;
|
||||
}
|
||||
|
||||
uint32_t retrieve_mask2_flags() {
|
||||
return int_mask2;
|
||||
}
|
||||
|
||||
uint32_t retrieve_events2_flags() {
|
||||
return int_events2;
|
||||
}
|
||||
|
||||
uint32_t retrieve_levels2_flags() {
|
||||
return int_levels2;
|
||||
}
|
||||
|
||||
uint32_t retrieve_clear2_flags() {
|
||||
return int_clear2;
|
||||
}
|
||||
|
||||
uint32_t ack_interrupt(uint32_t device_bits, bool is_int2) {
|
||||
bool confirm_interrupt = false;
|
||||
|
||||
if (is_int2) {
|
||||
int_events2 |= device_bits;
|
||||
uint32_t mask2_check = retrieve_mask2_flags();
|
||||
if (mask2_check && int_events2)
|
||||
confirm_interrupt = true;
|
||||
} else {
|
||||
//slightly nasty workaround
|
||||
uint32_t mask1_check = retrieve_mask_flags() + device_bits;
|
||||
update_mask_flags(mask1_check + device_bits);
|
||||
uint32_t events1_check = retrieve_events_flags();
|
||||
if (mask1_check && events1_check)
|
||||
confirm_interrupt = true;
|
||||
}
|
||||
|
||||
if (confirm_interrupt)
|
||||
call_ppc_handler();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t int_events2 = 0;
|
||||
uint32_t int_mask2 = 0;
|
||||
uint32_t int_clear2 = 0;
|
||||
uint32_t int_levels2 = 0;
|
||||
};
|
||||
|
||||
#endif /* HEATHINTCTRL_H */
|
|
@ -23,7 +23,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
#include <devices/common/dbdma.h>
|
||||
#include <devices/common/viacuda.h>
|
||||
#include <devices/ioctrl/macio.h>
|
||||
#include <devices/ioctrl/heathintctrl.h>
|
||||
#include <devices/ioctrl/interruptctrl.h>
|
||||
#include <devices/serial/escc.h>
|
||||
#include <devices/sound/awacs.h>
|
||||
#include <endianswap.h>
|
||||
|
@ -59,9 +59,38 @@ HeathrowIC::HeathrowIC() : PCIDevice("mac-io/heathrow") {
|
|||
|
||||
this->mesh = std::unique_ptr<MESHController> (new MESHController(HeathrowMESHID));
|
||||
this->escc = std::unique_ptr<EsccController>(new EsccController());
|
||||
this->int_ctrl = std::unique_ptr<HeathIntCtrl>(new HeathIntCtrl());
|
||||
}
|
||||
|
||||
uint32_t HeathrowIC::register_device(DEV_ID dev_id){
|
||||
return (1 << dev_id);
|
||||
};
|
||||
|
||||
void HeathrowIC::process_interrupt(uint32_t cookie) {
|
||||
bool confirm_interrupt = false;
|
||||
uint32_t bit_field = 0;
|
||||
|
||||
switch (cookie) {
|
||||
case DEV_ID::DAVBUS_DMA_OUT:
|
||||
bit_field = (1 << DEV_ID::DAVBUS_DMA_OUT);
|
||||
break;
|
||||
case DEV_ID::SCSI0:
|
||||
bit_field = (1 << DEV_ID::SCSI0);
|
||||
break;
|
||||
case DEV_ID::VIA_CUDA:
|
||||
bit_field = (1 << DEV_ID::VIA_CUDA);
|
||||
break;
|
||||
case DEV_ID::SWIM3:
|
||||
bit_field = (1 << DEV_ID::SWIM3);
|
||||
break;
|
||||
case DEV_ID::DAVBUS:
|
||||
bit_field = (1 << DEV_ID::DAVBUS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (confirm_interrupt)
|
||||
ack_interrupt(bit_field);
|
||||
};
|
||||
|
||||
uint32_t HeathrowIC::pci_cfg_read(uint32_t reg_offs, uint32_t size) {
|
||||
return this->pci_cfg_hdr[reg_offs & 0xFF];
|
||||
}
|
||||
|
@ -95,7 +124,7 @@ uint32_t HeathrowIC::dma_read(uint32_t offset, int size) {
|
|||
switch (offset >> 8) {
|
||||
case 8:
|
||||
res = this->snd_out_dma->reg_read(offset & 0xFF, size);
|
||||
this->int_ctrl->ack_interrupt(Heathrow_Int1::DAVBUS_DMA_OUT, 0);
|
||||
this->ack_interrupt(DEV_ID::DAVBUS_DMA_OUT);
|
||||
break;
|
||||
default:
|
||||
LOG_F(WARNING, "Unsupported DMA channel read, offset=0x%X", offset);
|
||||
|
@ -178,7 +207,7 @@ void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int
|
|||
break;
|
||||
case 0x10:
|
||||
this->mesh->write((offset >> 4) & 0xF, value);
|
||||
this->int_ctrl->ack_interrupt(Heathrow_Int1::SCSI0, 0);
|
||||
this->process_interrupt(DEV_ID::SCSI0);
|
||||
break;
|
||||
case 0x11: // BMAC
|
||||
LOG_F(WARNING, "Attempted to write to BMAC: %x \n", (offset - 0x11000));
|
||||
|
@ -191,7 +220,7 @@ void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int
|
|||
break;
|
||||
case 0x14:
|
||||
this->screamer->snd_ctrl_write(offset - 0x14000, value, size);
|
||||
this->int_ctrl->ack_interrupt(Heathrow_Int1::DAVBUS, 0);
|
||||
this->process_interrupt(DEV_ID::DAVBUS);
|
||||
break;
|
||||
case 0x15: // SWIM 3
|
||||
LOG_F(WARNING, "Attempted to write to SWIM 3: %x \n", (offset - 0x15000));
|
||||
|
@ -199,7 +228,7 @@ void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int
|
|||
case 0x16:
|
||||
case 0x17:
|
||||
this->viacuda->write((offset - 0x16000) >> 9, value);
|
||||
this->int_ctrl->ack_interrupt(Heathrow_Int1::VIA_CUDA, 0);
|
||||
this->process_interrupt(DEV_ID::VIA_CUDA);
|
||||
break;
|
||||
case 0x20: // IDE
|
||||
case 0x21:
|
||||
|
@ -220,35 +249,35 @@ uint32_t HeathrowIC::mio_ctrl_read(uint32_t offset, int size) {
|
|||
switch (offset & 0xFC) {
|
||||
case 0x10:
|
||||
LOG_F(0, "read from MIO:Int_Events2 register \n");
|
||||
res = this->int_ctrl->retrieve_events2_flags();
|
||||
res = this->retrieve_reg(REG_ID::events2);
|
||||
break;
|
||||
case 0x14:
|
||||
LOG_F(0, "read from MIO:Int_Mask2 register \n");
|
||||
res = this->int_ctrl->retrieve_mask2_flags();
|
||||
res = this->retrieve_reg(REG_ID::mask2);
|
||||
break;
|
||||
case 0x18:
|
||||
LOG_F(0, "read from MIO:Int_Clear2 register \n");
|
||||
res = this->int_ctrl->retrieve_clear2_flags();
|
||||
res = this->retrieve_reg(REG_ID::clear2);
|
||||
break;
|
||||
case 0x1C:
|
||||
LOG_F(0, "read from MIO:Int_Levels2 register \n");
|
||||
res = this->int_ctrl->retrieve_levels2_flags();
|
||||
res = this->retrieve_reg(REG_ID::levels2);
|
||||
break;
|
||||
case 0x20:
|
||||
LOG_F(0, "read from MIO:Int_Events1 register \n");
|
||||
res = this->int_ctrl->retrieve_events_flags();
|
||||
res = this->retrieve_reg(REG_ID::events1);
|
||||
break;
|
||||
case 0x24:
|
||||
LOG_F(0, "read from MIO:Int_Mask1 register \n");
|
||||
res = this->int_ctrl->retrieve_mask_flags();
|
||||
res = this->retrieve_reg(REG_ID::mask1);
|
||||
break;
|
||||
case 0x28:
|
||||
LOG_F(0, "read from MIO:Int_Clear1 register \n");
|
||||
res = this->int_ctrl->retrieve_clear_flags();
|
||||
res = this->retrieve_reg(REG_ID::clear1);
|
||||
break;
|
||||
case 0x2C:
|
||||
LOG_F(0, "read from MIO:Int_Levels1 register \n");
|
||||
res = this->int_ctrl->retrieve_levels_flags();
|
||||
res = this->retrieve_reg(REG_ID::levels1);
|
||||
break;
|
||||
case 0x34: /* heathrowIDs / HEATHROW_MBCR (Linux): media bay config reg? */
|
||||
LOG_F(9, "read from MIO:ID register at Address %x \n", ppc_state.pc);
|
||||
|
@ -270,35 +299,35 @@ void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) {
|
|||
switch (offset & 0xFC) {
|
||||
case 0x10:
|
||||
LOG_F(0, "write %x to MIO:Int_Events2 register \n", value);
|
||||
this->int_ctrl->update_events2_flags(value);
|
||||
this->update_reg(REG_ID::events2, value);
|
||||
break;
|
||||
case 0x14:
|
||||
LOG_F(0, "write %x to MIO:Int_Mask2 register \n", value);
|
||||
this->int_ctrl->update_mask2_flags(value);
|
||||
this->update_reg(REG_ID::mask2, value);
|
||||
break;
|
||||
case 0x18:
|
||||
LOG_F(0, "write %x to MIO:Int_Clear2 register \n", value);
|
||||
this->int_ctrl->update_clear2_flags(value);
|
||||
this->update_reg(REG_ID::clear2, value);
|
||||
break;
|
||||
case 0x1C:
|
||||
LOG_F(0, "write %x to MIO:Int_Levels2 register \n", value);
|
||||
this->int_ctrl->update_levels2_flags(value);
|
||||
this->update_reg(REG_ID::levels2, value);
|
||||
break;
|
||||
case 0x20:
|
||||
LOG_F(0, "write %x to MIO:Int_Events1 register \n", value);
|
||||
this->int_ctrl->update_events_flags(value);
|
||||
this->update_reg(REG_ID::events1, value);
|
||||
break;
|
||||
case 0x24:
|
||||
LOG_F(0, "write %x to MIO:Int_Mask1 register \n", value);
|
||||
this->int_ctrl->update_mask_flags(value);
|
||||
this->update_reg(REG_ID::mask1, value);
|
||||
break;
|
||||
case 0x28:
|
||||
LOG_F(0, "write %x to MIO:Int_Clear1 register \n", value);
|
||||
this->int_ctrl->update_clear_flags(value);
|
||||
this->update_reg(REG_ID::clear1, value);
|
||||
break;
|
||||
case 0x2C:
|
||||
LOG_F(0, "write %x to MIO:Int_Levels1 register \n", value);
|
||||
this->int_ctrl->update_levels_flags(value);
|
||||
this->update_reg(REG_ID::levels1, value);
|
||||
break;
|
||||
case 0x34:
|
||||
LOG_F(WARNING, "Attempted to write %x to MIO:ID at %x; Address : %x \n", value, offset, ppc_state.pc);
|
||||
|
|
|
@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
*/
|
||||
|
||||
#include <cpu/ppc/ppcemu.h>
|
||||
#include "interruptctrl.h"
|
||||
#include <devices/ioctrl/interruptctrl.h>
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
#include <loguru.hpp>
|
||||
|
@ -30,40 +30,67 @@ using namespace std;
|
|||
InterruptCtrl::InterruptCtrl() {
|
||||
}
|
||||
|
||||
void InterruptCtrl::update_mask_flags(uint32_t bit_setting) {
|
||||
int_mask1 = bit_setting;
|
||||
void InterruptCtrl::update_reg(REG_ID retrieve_reg, uint32_t bit_setting) {
|
||||
switch (retrieve_reg) {
|
||||
case mask1:
|
||||
int_mask1 = bit_setting;
|
||||
break;
|
||||
case clear1:
|
||||
int_clear1 = bit_setting;
|
||||
int_events1 &= ~int_clear1;
|
||||
break;
|
||||
case events1:
|
||||
int_events1 = bit_setting;
|
||||
break;
|
||||
case levels1:
|
||||
int_levels1 = bit_setting;
|
||||
break;
|
||||
case mask2:
|
||||
int_mask2 = bit_setting;
|
||||
break;
|
||||
case clear2:
|
||||
int_clear2 = bit_setting;
|
||||
int_events2 &= ~int_clear2;
|
||||
break;
|
||||
case events2:
|
||||
int_events2 = bit_setting;
|
||||
break;
|
||||
case levels2:
|
||||
int_levels2 = bit_setting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InterruptCtrl::update_events_flags(uint32_t bit_setting) {
|
||||
int_events1 = bit_setting;
|
||||
uint32_t InterruptCtrl::retrieve_reg(REG_ID retrieve_reg) {
|
||||
switch (retrieve_reg) {
|
||||
case mask1:
|
||||
return int_mask1;
|
||||
break;
|
||||
case clear1:
|
||||
return int_clear1;
|
||||
break;
|
||||
case events1:
|
||||
return int_events1;
|
||||
break;
|
||||
case levels1:
|
||||
return int_levels1;
|
||||
break;
|
||||
case mask2:
|
||||
return int_mask2;
|
||||
break;
|
||||
case clear2:
|
||||
return int_clear2;
|
||||
break;
|
||||
case events2:
|
||||
return int_events2;
|
||||
break;
|
||||
case levels2:
|
||||
return int_levels2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InterruptCtrl::update_levels_flags(uint32_t bit_setting) {
|
||||
int_levels1 = bit_setting;
|
||||
}
|
||||
|
||||
void InterruptCtrl::update_clear_flags(uint32_t bit_setting) {
|
||||
int_clear1 = bit_setting;
|
||||
int_events1 &= ~int_clear1;
|
||||
}
|
||||
|
||||
uint32_t InterruptCtrl::retrieve_mask_flags() {
|
||||
return int_mask1;
|
||||
}
|
||||
|
||||
uint32_t InterruptCtrl::retrieve_events_flags() {
|
||||
return int_events1;
|
||||
}
|
||||
|
||||
uint32_t InterruptCtrl::retrieve_levels_flags() {
|
||||
return int_levels1;
|
||||
}
|
||||
|
||||
uint32_t InterruptCtrl::retrieve_clear_flags() {
|
||||
return int_clear1;
|
||||
}
|
||||
|
||||
uint32_t InterruptCtrl::ack_interrupt(uint32_t device_bits){
|
||||
uint32_t InterruptCtrl::ack_interrupt(uint32_t device_bits) {
|
||||
bool confirm_interrupt = false;
|
||||
|
||||
int_events1 |= device_bits;
|
||||
|
@ -71,11 +98,11 @@ uint32_t InterruptCtrl::ack_interrupt(uint32_t device_bits){
|
|||
confirm_interrupt = true;
|
||||
|
||||
if (confirm_interrupt)
|
||||
call_ppc_handler();
|
||||
ack_cpu_interrupt();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InterruptCtrl::call_ppc_handler() {
|
||||
void InterruptCtrl::ack_cpu_interrupt() {
|
||||
ppc_exception_handler(Except_Type::EXC_EXT_INT, 0x0);
|
||||
}
|
|
@ -26,36 +26,71 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
#include <cinttypes>
|
||||
#include <memory>
|
||||
|
||||
class InterruptCtrl : public HWComponent {
|
||||
enum DEV_ID {
|
||||
SCSI_DMA = 0,
|
||||
Swim3_DMA = 1,
|
||||
IDE0_DMA = 2,
|
||||
IDE1_DMA = 3,
|
||||
SCC_A_DMA_OUT = 4,
|
||||
SCC_A_DMA_IN = 5,
|
||||
SCC_B_DMA_OUT = 6,
|
||||
SCC_B_DMA_IN = 7,
|
||||
DAVBUS_DMA_OUT = 8,
|
||||
DAVBUS_DMA_IN = 9,
|
||||
VIDEO_OUT = 10,
|
||||
VIDEO_IN = 11,
|
||||
SCSI0 = 12,
|
||||
IDE0 = 13,
|
||||
IDE1 = 14,
|
||||
SCC_A = 15,
|
||||
SCC_B = 16,
|
||||
DAVBUS = 17,
|
||||
VIA_CUDA = 18,
|
||||
SWIM3 = 19,
|
||||
NMI = 20,
|
||||
PERCH_DMA = 21,
|
||||
PERCH = 22,
|
||||
BMAC_DMA_OUT = 0,
|
||||
BMAC_DMA_IN = 1,
|
||||
BMAC = 10,
|
||||
};
|
||||
|
||||
enum REG_ID {
|
||||
mask1 = 0,
|
||||
clear1 = 1,
|
||||
events1 = 2,
|
||||
levels1 = 3,
|
||||
mask2 = 4,
|
||||
clear2 = 5,
|
||||
events2 = 6,
|
||||
levels2 = 7,
|
||||
};
|
||||
|
||||
class InterruptCtrl {
|
||||
public:
|
||||
InterruptCtrl();
|
||||
~InterruptCtrl() = default;
|
||||
|
||||
bool supports_type(HWCompType type) {
|
||||
return (type == HWCompType::INT_CTRL);
|
||||
};
|
||||
|
||||
uint32_t ack_interrupt(uint32_t device_bits);
|
||||
|
||||
//for all (Old World) PCI-based Macs (is_int is only for Heathrow)
|
||||
void update_mask_flags(uint32_t bit_setting);
|
||||
void update_events_flags(uint32_t bit_setting);
|
||||
void update_levels_flags(uint32_t bit_setting);
|
||||
void update_clear_flags(uint32_t bit_setting);
|
||||
uint32_t retrieve_mask_flags();
|
||||
uint32_t retrieve_events_flags();
|
||||
uint32_t retrieve_levels_flags();
|
||||
uint32_t retrieve_clear_flags();
|
||||
virtual uint32_t register_device(DEV_ID dev_id){
|
||||
return 0;
|
||||
};
|
||||
|
||||
//for Heathrow
|
||||
void update_reg(REG_ID retrieve_reg, uint32_t bit_setting);
|
||||
uint32_t retrieve_reg(REG_ID retrieve_reg);
|
||||
|
||||
void call_ppc_handler();
|
||||
void ack_cpu_interrupt();
|
||||
|
||||
private:
|
||||
protected:
|
||||
uint32_t int_events1 = 0;
|
||||
uint32_t int_mask1 = 0;
|
||||
uint32_t int_clear1 = 0;
|
||||
uint32_t int_levels1 = 0;
|
||||
uint32_t int_events2 = 0;
|
||||
uint32_t int_mask2 = 0;
|
||||
uint32_t int_clear2 = 0;
|
||||
uint32_t int_levels2 = 0;
|
||||
};
|
||||
|
||||
#endif /* HWINTERRUPT_H */
|
|
@ -59,7 +59,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
#include <devices/common/pci/pcihost.h>
|
||||
#include <devices/common/scsi/mesh.h>
|
||||
#include <devices/common/viacuda.h>
|
||||
#include <devices/ioctrl/heathintctrl.h>
|
||||
#include <devices/ioctrl/interruptctrl.h>
|
||||
#include <devices/memctrl/memctrlbase.h>
|
||||
#include <devices/serial/escc.h>
|
||||
#include <devices/sound/awacs.h>
|
||||
|
@ -93,13 +93,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||
VIA-CUDA register space: 0x00016000, size: 0x00002000
|
||||
*/
|
||||
|
||||
class HeathrowIC : public PCIDevice {
|
||||
class HeathrowIC : public PCIDevice,
|
||||
public InterruptCtrl {
|
||||
|
||||
public:
|
||||
HeathrowIC();
|
||||
~HeathrowIC() = default;
|
||||
|
||||
bool supports_type(HWCompType type) {
|
||||
return type == HWCompType::MMIO_DEV;
|
||||
return (type == HWCompType::MMIO_DEV) || (type == HWCompType::INT_CTRL);
|
||||
};
|
||||
|
||||
/* PCI device methods */
|
||||
|
@ -114,6 +116,9 @@ public:
|
|||
uint32_t read(uint32_t reg_start, uint32_t offset, int size);
|
||||
void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size);
|
||||
|
||||
uint32_t register_device(DEV_ID dev_id);
|
||||
void process_interrupt(uint32_t cookie);
|
||||
|
||||
protected:
|
||||
uint32_t dma_read(uint32_t offset, int size);
|
||||
void dma_write(uint32_t offset, uint32_t value, int size);
|
||||
|
@ -154,7 +159,6 @@ private:
|
|||
std::unique_ptr<AwacsScreamer> screamer; // Screamer audio codec instance
|
||||
std::unique_ptr<MESHController> mesh; // MESH SCSI cell instance
|
||||
std::unique_ptr<EsccController> escc; // ESCC serial controller
|
||||
std::unique_ptr<HeathIntCtrl> int_ctrl; // Interrupt controller
|
||||
|
||||
std::unique_ptr<DMAChannel> snd_out_dma;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user