mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-22 15:29:58 +00:00
Improve MACE stub.
This commit is contained in:
parent
bda85a66df
commit
211f8adc0e
@ -1,6 +1,6 @@
|
||||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-22 divingkatae and maximum
|
||||
Copyright (C) 2018-24 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
@ -32,11 +32,24 @@ using namespace MaceEnet;
|
||||
uint8_t MaceController::read(uint8_t reg_offset)
|
||||
{
|
||||
switch(reg_offset) {
|
||||
case MaceReg::Interrupt:
|
||||
LOG_F(INFO, "MACE: all interrupt flags cleared");
|
||||
return 0;
|
||||
case MaceReg::Rcv_Frame_Ctrl:
|
||||
return this->rcv_fc;
|
||||
case MaceReg::Interrupt: {
|
||||
uint8_t ret_val = this->int_stat;
|
||||
this->int_stat = 0;
|
||||
LOG_F(9, "%s: all interrupt flags cleared", this->name.c_str());
|
||||
return ret_val;
|
||||
}
|
||||
case MaceReg::Interrupt_Mask:
|
||||
return this->int_mask;
|
||||
case MaceReg::BIU_Config_Ctrl:
|
||||
return this->biu_ctrl;
|
||||
case MaceReg::Chip_ID_Lo:
|
||||
return this->chip_id & 0xFFU;
|
||||
case MaceReg::Chip_ID_Hi:
|
||||
return (this->chip_id >> 8) & 0xFFU;
|
||||
default:
|
||||
LOG_F(INFO, "Reading MACE register %d", reg_offset);
|
||||
LOG_F(INFO, "%s: reading from register %d", this->name.c_str(), reg_offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -45,15 +58,57 @@ uint8_t MaceController::read(uint8_t reg_offset)
|
||||
void MaceController::write(uint8_t reg_offset, uint8_t value)
|
||||
{
|
||||
switch(reg_offset) {
|
||||
case MaceReg::Rcv_Frame_Ctrl:
|
||||
this->rcv_fc = value;
|
||||
break;
|
||||
case MaceReg::Interrupt_Mask:
|
||||
this->int_mask = value;
|
||||
break;
|
||||
case MaceReg::MAC_Config_Ctrl:
|
||||
this->mac_cfg = value;
|
||||
break;
|
||||
case MaceReg::BIU_Config_Ctrl:
|
||||
if (value & 1) {
|
||||
LOG_F(INFO, "MACE Reset issued");
|
||||
} else {
|
||||
LOG_F(INFO, "MACE BIU Config set to 0x%X", value);
|
||||
if (value & BIU_SWRST) {
|
||||
LOG_F(INFO, "%s: soft reset asserted", this->name.c_str());
|
||||
value &= ~BIU_SWRST; // acknowledge soft reset
|
||||
}
|
||||
this->biu_ctrl = value;
|
||||
break;
|
||||
case MaceReg::PLS_Config_Ctrl:
|
||||
if (value != 7)
|
||||
LOG_F(WARNING, "%s: unsupported transceiver interface 0x%X in PLSCC",
|
||||
this->name.c_str(), value);
|
||||
break;
|
||||
case MaceReg::Int_Addr_Config:
|
||||
if ((value & IAC_LOGADDR) && (value & IAC_PHYADDR))
|
||||
value &= ~IAC_PHYADDR;
|
||||
if (value & (IAC_LOGADDR | IAC_PHYADDR))
|
||||
this->addr_ptr = 0;
|
||||
this->addr_cfg = value;
|
||||
break;
|
||||
case MaceReg::Log_Addr_Flt:
|
||||
if (this->addr_cfg & IAC_LOGADDR) {
|
||||
uint64_t mask = ~(0xFFULL << (this->addr_ptr * 8));
|
||||
this->log_addr = (this->log_addr & mask) | ((uint64_t)value << (this->addr_ptr * 8));
|
||||
if (++this->addr_ptr >= 8) {
|
||||
this->addr_cfg &= ~IAC_LOGADDR;
|
||||
this->addr_ptr = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MaceReg::Phys_Addr:
|
||||
if (this->addr_cfg & IAC_PHYADDR) {
|
||||
uint64_t mask = ~(0xFFULL << (this->addr_ptr * 8));
|
||||
this->phys_addr = (this->phys_addr & mask) | ((uint64_t)value << (this->addr_ptr * 8));
|
||||
if (++this->addr_ptr >= 6) {
|
||||
this->addr_cfg &= ~IAC_PHYADDR;
|
||||
this->addr_ptr = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_F(INFO, "Writing 0x%X to MACE register %d", value, reg_offset);
|
||||
LOG_F(INFO, "%s: writing 0x%X to register %d", this->name.c_str(),
|
||||
value, reg_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-22 divingkatae and maximum
|
||||
Copyright (C) 2018-24 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
@ -24,58 +24,74 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#ifndef MACE_H
|
||||
#define MACE_H
|
||||
|
||||
#include <devices/common/dmacore.h>
|
||||
#include <devices/common/hwcomponent.h>
|
||||
|
||||
#include <cinttypes>
|
||||
#include <memory>
|
||||
|
||||
// MACE Chip ID from AMD datasheet
|
||||
// TODO: compare with real HW
|
||||
#define MACE_ID 0x3940
|
||||
/** Known MACE chip IDs. */
|
||||
#define MACE_ID_REV_B0 0x0940 // Darwin-0.3 source
|
||||
#define MACE_ID_REV_A2 0x0941 // Darwin-0.3 source & Curio datasheet
|
||||
|
||||
// MACE registers offsets
|
||||
/** MACE registers offsets. */
|
||||
// Refer to the Am79C940 datasheet for details
|
||||
namespace MaceEnet {
|
||||
enum MaceReg : uint8_t {
|
||||
Rcv_FIFO = 0,
|
||||
Xmit_FIFO = 1,
|
||||
Xmit_Frame_Ctrl = 2,
|
||||
Xmit_Frame_Stat = 3,
|
||||
Xmit_Retry_Cnt = 4,
|
||||
Rcv_Frame_Ctrl = 5,
|
||||
Rcv_Frame_Stat = 6,
|
||||
FIFO_Frame_Cnt = 7,
|
||||
Interrupt = 8,
|
||||
Interrupt_Mask = 9,
|
||||
Poll = 10,
|
||||
BIU_Config_Ctrl = 11,
|
||||
FIFO_Config = 12,
|
||||
MAC_Config_Ctrl = 13,
|
||||
PLS_Config_Ctrl = 14,
|
||||
PHY_Config_Ctrl = 15,
|
||||
Chip_ID_Lo = 16,
|
||||
Chip_ID_Hi = 17,
|
||||
Int_Addr_Config = 18,
|
||||
Log_Addr_Flt = 20,
|
||||
Phys_Addr = 21,
|
||||
Missed_Pkt_Cnt = 24,
|
||||
Runt_Pkt_Cnt = 26, // not used in Macintosh?
|
||||
Rcv_Collis_Cnt = 27, // not used in Macintosh?
|
||||
User_Test = 29,
|
||||
Rsrvd_Test_1 = 30, // not used in Macintosh?
|
||||
Rsrvd_Test_2 = 31, // not used in Macintosh?
|
||||
};
|
||||
|
||||
enum MaceReg : uint8_t {
|
||||
Rcv_FIFO = 0,
|
||||
Xmit_FIFO = 1,
|
||||
Xmit_Frame_Ctrl = 2,
|
||||
Xmit_Frame_Stat = 3,
|
||||
Xmit_Retry_Cnt = 4,
|
||||
Rcv_Frame_Ctrl = 5,
|
||||
Rcv_Frame_Stat = 6,
|
||||
FIFO_Frame_Cnt = 7,
|
||||
Interrupt = 8,
|
||||
Interrupt_Mask = 9,
|
||||
Poll = 0x0A,
|
||||
BIU_Config_Ctrl = 0x0B,
|
||||
FIFO_Config = 0x0C,
|
||||
MAC_Config_Ctrl = 0x0D,
|
||||
PLS_Config_Ctrl = 0x0E,
|
||||
PHY_Config_Ctrl = 0x0F,
|
||||
Chip_ID_Lo = 0x10,
|
||||
Chip_ID_Hi = 0x11,
|
||||
Addr_Config = 0x12,
|
||||
Log_Addr_Flt = 0x14,
|
||||
Phys_Addr = 0x15,
|
||||
Missed_Pkt_Cnt = 0x18,
|
||||
Runt_Pkt_Cnt = 0x1A, // not used in Macintosh?
|
||||
Rcv_Collis_Cnt = 0x1B, // not used in Macintosh?
|
||||
User_Test = 0x1D,
|
||||
Rsrvd_Test_1 = 0x1E, // not used in Macintosh?
|
||||
Rsrvd_Test_2 = 0x1F, // not used in Macintosh?
|
||||
};
|
||||
/** Bit definitions for BIU_Config_Ctrl register. */
|
||||
enum {
|
||||
BIU_SWRST = 1 << 0,
|
||||
};
|
||||
|
||||
/** Bit definitions for the internal configuration register. */
|
||||
enum {
|
||||
IAC_LOGADDR = 1 << 1,
|
||||
IAC_PHYADDR = 1 << 2,
|
||||
IAC_ADDRCHG = 1 << 7
|
||||
};
|
||||
|
||||
}; // namespace MaceEnet
|
||||
|
||||
class MaceController : public HWComponent {
|
||||
class MaceController : public DmaDevice, public HWComponent {
|
||||
public:
|
||||
MaceController(uint16_t id) { this->chip_id = id; };
|
||||
MaceController(uint16_t id) {
|
||||
this->chip_id = id;
|
||||
this->set_name("MACE");
|
||||
this->supports_types(HWCompType::MMIO_DEV | HWCompType::ETHER_MAC);
|
||||
};
|
||||
~MaceController() = default;
|
||||
|
||||
static std::unique_ptr<HWComponent> create() {
|
||||
return std::unique_ptr<MaceController>(new MaceController(MACE_ID));
|
||||
return std::unique_ptr<MaceController>(new MaceController(MACE_ID_REV_A2));
|
||||
}
|
||||
|
||||
// MACE registers access
|
||||
@ -84,6 +100,17 @@ public:
|
||||
|
||||
private:
|
||||
uint16_t chip_id; // per-instance MACE Chip ID
|
||||
uint8_t addr_cfg = 0;
|
||||
uint8_t addr_ptr = 0;
|
||||
uint8_t rcv_fc = 1;
|
||||
uint8_t biu_ctrl = 0;
|
||||
uint8_t mac_cfg = 0;
|
||||
uint64_t phys_addr = 0;
|
||||
uint64_t log_addr = 0;
|
||||
|
||||
// interrupt stuff
|
||||
uint8_t int_stat = 0;
|
||||
uint8_t int_mask = 0;
|
||||
};
|
||||
|
||||
#endif // MACE_H
|
||||
|
@ -129,6 +129,13 @@ GrandCentral::GrandCentral() : PCIDevice("mac-io/grandcentral"), InterruptCtrl()
|
||||
|
||||
// connect Ethernet HW
|
||||
this->mace = dynamic_cast<MaceController*>(gMachineObj->get_comp_by_name("Mace"));
|
||||
this->enet_tx_dma = std::unique_ptr<DMAChannel> (new DMAChannel("mace_enet_tx"));
|
||||
this->enet_tx_dma->register_dma_int(this, this->register_dma_int(IntSrc::DMA_ETHERNET_Tx));
|
||||
this->enet_rx_dma = std::unique_ptr<DMAChannel> (new DMAChannel("mace_enet_rx"));
|
||||
this->enet_rx_dma->register_dma_int(this, this->register_dma_int(IntSrc::DMA_ETHERNET_Rx));
|
||||
this->enet_tx_dma->connect(this->mace);
|
||||
this->enet_rx_dma->connect(this->mace);
|
||||
this->mace->connect(this->enet_rx_dma.get());
|
||||
|
||||
// connect floppy disk HW
|
||||
this->swim3 = dynamic_cast<Swim3::Swim3Ctrl*>(gMachineObj->get_comp_by_name("Swim3"));
|
||||
@ -221,6 +228,10 @@ uint32_t GrandCentral::read(uint32_t rgn_start, uint32_t offset, int size)
|
||||
return this->curio_dma->reg_read(offset & 0xFF, size);
|
||||
case MIO_GC_DMA_FLOPPY:
|
||||
return this->floppy_dma->reg_read(offset & 0xFF, size);
|
||||
case MIO_GC_DMA_ETH_XMIT:
|
||||
return this->enet_tx_dma->reg_read(offset & 0xFF, size);
|
||||
case MIO_GC_DMA_ETH_RCV:
|
||||
return this->enet_rx_dma->reg_read(offset & 0xFF, size);
|
||||
case MIO_GC_DMA_ESCC_A_XMIT:
|
||||
return this->escc_a_tx_dma->reg_read(offset & 0xFF, size);
|
||||
case MIO_GC_DMA_ESCC_A_RCV:
|
||||
@ -337,6 +348,12 @@ void GrandCentral::write(uint32_t rgn_start, uint32_t offset, uint32_t value, in
|
||||
case MIO_GC_DMA_FLOPPY:
|
||||
this->floppy_dma->reg_write(offset & 0xFF, value, size);
|
||||
break;
|
||||
case MIO_GC_DMA_ETH_XMIT:
|
||||
this->enet_tx_dma->reg_write(offset & 0xFF, value, size);
|
||||
break;
|
||||
case MIO_GC_DMA_ETH_RCV:
|
||||
this->enet_rx_dma->reg_write(offset & 0xFF, value, size);
|
||||
break;
|
||||
case MIO_GC_DMA_ESCC_A_XMIT:
|
||||
this->escc_a_tx_dma->reg_write(offset & 0xFF, value, size);
|
||||
break;
|
||||
|
@ -175,9 +175,9 @@ private:
|
||||
std::unique_ptr<AwacsScreamer> awacs; // AWACS audio codec instance
|
||||
std::unique_ptr<MeshStub> mesh_stub = nullptr;
|
||||
|
||||
MaceController* mace;
|
||||
MaceController* mace; // Ethernet cell within Curio
|
||||
ViaCuda* viacuda; // VIA cell with Cuda MCU attached to it
|
||||
EsccController* escc; // ESCC serial controller
|
||||
EsccController* escc; // ESCC serial controller cell within Curio
|
||||
MeshBase* mesh; // internal SCSI (fast)
|
||||
Sc53C94* curio; // external SCSI (slow)
|
||||
Swim3::Swim3Ctrl* swim3; // floppy disk controller
|
||||
@ -187,6 +187,8 @@ private:
|
||||
std::unique_ptr<DMAChannel> snd_out_dma;
|
||||
std::unique_ptr<DMAChannel> snd_in_dma;
|
||||
std::unique_ptr<DMAChannel> floppy_dma;
|
||||
std::unique_ptr<DMAChannel> enet_tx_dma;
|
||||
std::unique_ptr<DMAChannel> enet_rx_dma;
|
||||
std::unique_ptr<DMAChannel> escc_a_tx_dma;
|
||||
std::unique_ptr<DMAChannel> escc_a_rx_dma;
|
||||
std::unique_ptr<DMAChannel> escc_b_tx_dma;
|
||||
|
Loading…
Reference in New Issue
Block a user