mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-27 00:29:18 +00:00
218 lines
6.3 KiB
C++
218 lines
6.3 KiB
C++
/*
|
|
DingusPPC - The Experimental PowerPC Macintosh emulator
|
|
Copyright (C) 2018-23 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/>.
|
|
*/
|
|
|
|
/** @file BigMac Ethernet controller definitions. */
|
|
|
|
#ifndef BIG_MAC_H
|
|
#define BIG_MAC_H
|
|
|
|
#include <devices/common/hwcomponent.h>
|
|
|
|
#include <cinttypes>
|
|
#include <memory>
|
|
|
|
/* Ethernet cell IDs for various MacIO ASICs. */
|
|
enum EthernetCellId : uint8_t {
|
|
Heathrow = 0xB1,
|
|
Paddington = 0xC7,
|
|
};
|
|
|
|
/* BigMac HW registers. */
|
|
enum BigMacReg : uint16_t {
|
|
XIFC = 0x000, // transceiver interface control
|
|
TX_FIFO_CSR = 0x100,
|
|
TX_FIFO_TH = 0x110,
|
|
RX_FIFO_CSR = 0x120,
|
|
CHIP_ID = 0x170,
|
|
MIF_CSR = 0x180,
|
|
GLOB_STAT = 0x200, // Apple: kSTAT, Sun: Global Status Register
|
|
EVENT_MASK = 0x210, // ambiguously called INT_DISABLE in the Apple source
|
|
SROM_CSR = 0x190,
|
|
TX_SW_RST = 0x420,
|
|
TX_CONFIG = 0x430,
|
|
PEAK_ATT = 0x4E0, // Apple: kPAREG, Sun: PeakAttempts Register
|
|
NC_CNT = 0x500, // Normal Collision Counter
|
|
NT_CNT = 0x510, // Apple: Network Collision Counter
|
|
EX_CNT = 0x520, // Excessive Collision Counter
|
|
LT_CNT = 0x530, // Late Collision Counter
|
|
RNG_SEED = 0x540,
|
|
RX_SW_RST = 0x620,
|
|
RX_CONFIG = 0x630,
|
|
MAC_ADDR_2 = 0x660,
|
|
MAC_ADDR_1 = 0x670,
|
|
MAC_ADDR_0 = 0x680,
|
|
RX_FRM_CNT = 0x690, // Receive Frame Counter
|
|
RX_LE_CNT = 0x6A0, // Length Error Counter
|
|
RX_AE_CNT = 0x6B0, // Alignment Error Counter
|
|
RX_FE_CNT = 0x6C0, // FCS Error Counter
|
|
RX_CVE_CNT = 0x6E0, // Code Violation Error Counter
|
|
HASH_TAB_3 = 0x700,
|
|
HASH_TAB_2 = 0x710,
|
|
HASH_TAB_1 = 0x720,
|
|
HASH_TAB_0 = 0x730,
|
|
};
|
|
|
|
/* MIF_CSR bit definitions. */
|
|
enum {
|
|
Mif_Clock = 1 << 0,
|
|
Mif_Data_Out = 1 << 1,
|
|
Mif_Data_Out_En = 1 << 2,
|
|
Mif_Data_In = 1 << 3
|
|
};
|
|
|
|
/* SROM_CSR bit definitions. */
|
|
enum {
|
|
Srom_Chip_Select = 1 << 0,
|
|
Srom_Clock = 1 << 1,
|
|
Srom_Data_In = 1 << 2,
|
|
Srom_Data_Out = 1 << 3,
|
|
};
|
|
|
|
/* Serial EEPROM states (see ST93C46 datasheet). */
|
|
enum {
|
|
Srom_Start,
|
|
Srom_Opcode,
|
|
Srom_Address,
|
|
Srom_Read_Data,
|
|
};
|
|
|
|
/* MII frame states. */
|
|
enum MII_FRAME_SM {
|
|
Preamble,
|
|
Start,
|
|
Opcode,
|
|
Phy_Address,
|
|
Reg_Address,
|
|
Turnaround,
|
|
Read_Data,
|
|
Write_Data,
|
|
Stop
|
|
};
|
|
|
|
/* PHY control/status registers. */
|
|
enum {
|
|
PHY_BMCR = 0,
|
|
PHY_BMSR = 1,
|
|
PHY_ID1 = 2,
|
|
PHY_ID2 = 3,
|
|
PHY_ANAR = 4,
|
|
};
|
|
|
|
class BigMac : public HWComponent {
|
|
public:
|
|
BigMac(uint8_t id);
|
|
~BigMac() = default;
|
|
|
|
static std::unique_ptr<HWComponent> create_for_heathrow() {
|
|
return std::unique_ptr<BigMac>(new BigMac(EthernetCellId::Heathrow));
|
|
}
|
|
|
|
static std::unique_ptr<HWComponent> create_for_paddington() {
|
|
return std::unique_ptr<BigMac>(new BigMac(EthernetCellId::Paddington));
|
|
}
|
|
|
|
// BigMac register accessors
|
|
uint16_t read(uint16_t reg_offset);
|
|
void write(uint16_t reg_offset, uint16_t value);
|
|
|
|
protected:
|
|
void chip_reset();
|
|
|
|
// MII methods
|
|
bool mii_rcv_value(uint16_t& var, uint8_t num_bits, uint8_t next_bit);
|
|
void mii_rcv_bit();
|
|
void mii_xmit_bit(const uint8_t bit_val);
|
|
void mii_reset();
|
|
|
|
// PHY control/status methods
|
|
void phy_reset();
|
|
uint16_t phy_reg_read(uint8_t reg_num);
|
|
void phy_reg_write(uint8_t reg_num, uint16_t value);
|
|
|
|
// MAC Serial EEPROM methods
|
|
void srom_reset();
|
|
bool srom_rcv_value(uint16_t& var, uint8_t num_bits, uint8_t next_bit);
|
|
void srom_xmit_bit(const uint8_t bit_val);
|
|
|
|
private:
|
|
uint8_t chip_id; // BigMac Chip ID
|
|
|
|
// BigMac state
|
|
uint16_t tx_reset = 0; // self-clearing one-bit register
|
|
uint16_t tx_if_ctrl = 0;
|
|
uint16_t rng_seed;
|
|
uint16_t norm_coll_cnt = 0;
|
|
uint16_t net_coll_cnt = 0;
|
|
uint16_t excs_coll_cnt = 0;
|
|
uint16_t late_coll_cnt = 0;
|
|
uint16_t rcv_frame_cnt = 0;
|
|
uint8_t len_err_cnt = 0;
|
|
uint8_t align_err_cnt = 0;
|
|
uint8_t fcs_err_cnt = 0;
|
|
uint8_t cv_err_cnt = 0;
|
|
uint8_t peak_attempts = 0;
|
|
uint8_t tx_fifo_tresh = 0;
|
|
bool tx_fifo_enable = false;
|
|
bool rx_fifo_enable = false;
|
|
uint16_t tx_fifo_size = 0;
|
|
uint16_t rx_fifo_size = 0;
|
|
uint16_t hash_table[4] = {};
|
|
uint16_t mac_addr_flt[3] = {};
|
|
uint16_t tx_config = 0;
|
|
uint16_t rx_config = 0;
|
|
|
|
// Interrupt state
|
|
uint16_t event_mask = 0xFFFFU; // inverted mask: 0 - enabled, 1 - disabled
|
|
uint16_t stat = 0;
|
|
|
|
// MII state
|
|
uint8_t mif_csr_old = 0;
|
|
uint8_t mii_bit_counter = 0;
|
|
uint16_t mii_start = 0;
|
|
uint16_t mii_stop = 0;
|
|
uint16_t mii_opcode = 0;
|
|
uint16_t mii_phy_address = 0;
|
|
uint16_t mii_reg_address = 0;
|
|
uint16_t mii_turnaround = 0;
|
|
uint16_t mii_data = 0;
|
|
uint8_t mii_in_bit = 1;
|
|
MII_FRAME_SM mii_state = MII_FRAME_SM::Preamble;
|
|
|
|
// PHY state
|
|
uint32_t phy_oui;
|
|
uint8_t phy_model;
|
|
uint8_t phy_rev;
|
|
uint16_t phy_bmcr;
|
|
uint16_t phy_anar;
|
|
|
|
// MAC SROM state
|
|
uint8_t srom_csr_old = 0;
|
|
uint8_t srom_bit_counter = 0;
|
|
uint16_t srom_opcode = 0;
|
|
uint16_t srom_address = 0;
|
|
uint8_t srom_in_bit = 0;
|
|
uint8_t srom_state = Srom_Start;
|
|
uint16_t srom_data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0xDEAD, 0xBEEF, 0xBABE}; // bogus MAC!!!
|
|
};
|
|
|
|
#endif // BIG_MAC_H
|