mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-11-12 12:07:04 +00:00
bigmac: support more registers.
This commit is contained in:
parent
9db3076a48
commit
5f48a3ab5b
@ -30,6 +30,13 @@ BigMac::BigMac(uint8_t id) {
|
||||
supports_types(HWCompType::MMIO_DEV | HWCompType::ETHER_MAC);
|
||||
|
||||
this->chip_id = id;
|
||||
this->chip_reset();
|
||||
}
|
||||
|
||||
void BigMac::chip_reset() {
|
||||
this->event_mask = 0xFFFFU; // disable HW events causing on-chip interrupts
|
||||
this->stat = 0;
|
||||
|
||||
this->phy_reset();
|
||||
this->mii_reset();
|
||||
this->srom_reset();
|
||||
@ -37,12 +44,38 @@ BigMac::BigMac(uint8_t id) {
|
||||
|
||||
uint16_t BigMac::read(uint16_t reg_offset) {
|
||||
switch (reg_offset) {
|
||||
case BigMacReg::XIFC:
|
||||
return this->tx_if_ctrl;
|
||||
case BigMacReg::CHIP_ID:
|
||||
return this->chip_id;
|
||||
case BigMacReg::MIF_CSR:
|
||||
return (this->mif_csr_old & ~Mif_Data_In) | (this->mii_in_bit << 3);
|
||||
case BigMacReg::GLOB_STAT: {
|
||||
uint16_t old_stat = this->stat;
|
||||
this->stat = 0; // clear-on-read
|
||||
return old_stat;
|
||||
}
|
||||
case BigMacReg::EVENT_MASK:
|
||||
return this->event_mask;
|
||||
case BigMacReg::SROM_CSR:
|
||||
return (this->srom_csr_old & ~Srom_Data_In) | (this->srom_in_bit << 2);
|
||||
case BigMacReg::TX_SW_RST:
|
||||
return this->tx_reset;
|
||||
case BigMacReg::TX_CONFIG:
|
||||
return this->tx_config;
|
||||
case BigMacReg::PEAK_ATT: {
|
||||
uint8_t old_val = this->peak_attempts;
|
||||
this->peak_attempts = 0; // clear-on-read
|
||||
return old_val;
|
||||
}
|
||||
case BigMacReg::NC_CNT:
|
||||
return this->norm_coll_cnt;
|
||||
case BigMacReg::EX_CNT:
|
||||
return this->excs_coll_cnt;
|
||||
case BigMacReg::LT_CNT:
|
||||
return this->late_coll_cnt;
|
||||
case BigMacReg::RX_CONFIG:
|
||||
return this->rx_config;
|
||||
default:
|
||||
LOG_F(WARNING, "%s: unimplemented register at 0x%X", this->name.c_str(),
|
||||
reg_offset);
|
||||
@ -53,6 +86,20 @@ uint16_t BigMac::read(uint16_t reg_offset) {
|
||||
|
||||
void BigMac::write(uint16_t reg_offset, uint16_t value) {
|
||||
switch (reg_offset) {
|
||||
case BigMacReg::XIFC:
|
||||
this->tx_if_ctrl = value;
|
||||
break;
|
||||
case BigMacReg::TX_FIFO_CSR:
|
||||
this->tx_fifo_enable = !!(value & 1);
|
||||
this->tx_fifo_size = (((value >> 1) & 0xFF) + 1) << 7;
|
||||
break;
|
||||
case BigMacReg::TX_FIFO_TH:
|
||||
this->tx_fifo_tresh = value;
|
||||
break;
|
||||
case BigMacReg::RX_FIFO_CSR:
|
||||
this->rx_fifo_enable = !!(value & 1);
|
||||
this->rx_fifo_size = (((value >> 1) & 0xFF) + 1) << 7;
|
||||
break;
|
||||
case BigMacReg::MIF_CSR:
|
||||
if (value & Mif_Data_Out_En) {
|
||||
// send bits one by one on each low-to-high transition of Mif_Clock
|
||||
@ -64,6 +111,9 @@ void BigMac::write(uint16_t reg_offset, uint16_t value) {
|
||||
}
|
||||
this->mif_csr_old = value;
|
||||
break;
|
||||
case BigMacReg::EVENT_MASK:
|
||||
this->event_mask = value;
|
||||
break;
|
||||
case BigMacReg::SROM_CSR:
|
||||
if (value & Srom_Chip_Select) {
|
||||
// exchange data on each low-to-high transition of Srom_Clock
|
||||
@ -80,11 +130,58 @@ void BigMac::write(uint16_t reg_offset, uint16_t value) {
|
||||
this->tx_reset = 0; // acknowledge SW reset
|
||||
}
|
||||
break;
|
||||
case BigMacReg::TX_CONFIG:
|
||||
this->tx_config = value;
|
||||
break;
|
||||
case BigMacReg::NC_CNT:
|
||||
this->norm_coll_cnt = value;
|
||||
break;
|
||||
case BigMacReg::NT_CNT:
|
||||
this->net_coll_cnt = value;
|
||||
break;
|
||||
case BigMacReg::EX_CNT:
|
||||
this->excs_coll_cnt = value;
|
||||
break;
|
||||
case BigMacReg::LT_CNT:
|
||||
this->late_coll_cnt = value;
|
||||
break;
|
||||
case BigMacReg::RNG_SEED:
|
||||
this->rng_seed = value;
|
||||
break;
|
||||
case BigMacReg::RX_SW_RST:
|
||||
if (!value) {
|
||||
LOG_F(INFO, "%s: receiver soft reset asserted", this->name.c_str());
|
||||
}
|
||||
break;
|
||||
case BigMacReg::RX_CONFIG:
|
||||
this->rx_config = value;
|
||||
break;
|
||||
case BigMacReg::MAC_ADDR_0:
|
||||
case BigMacReg::MAC_ADDR_1:
|
||||
case BigMacReg::MAC_ADDR_2:
|
||||
this->mac_addr_flt[8 - ((reg_offset >> 4) & 0xF)] = value;
|
||||
break;
|
||||
case BigMacReg::RX_FRM_CNT:
|
||||
this->rcv_frame_cnt = value;
|
||||
break;
|
||||
case BigMacReg::RX_LE_CNT:
|
||||
this->len_err_cnt = value;
|
||||
break;
|
||||
case BigMacReg::RX_AE_CNT:
|
||||
this->align_err_cnt = value;
|
||||
break;
|
||||
case BigMacReg::RX_FE_CNT:
|
||||
this->fcs_err_cnt = value;
|
||||
break;
|
||||
case BigMacReg::RX_CVE_CNT:
|
||||
this->cv_err_cnt = value;
|
||||
break;
|
||||
case BigMacReg::HASH_TAB_0:
|
||||
case BigMacReg::HASH_TAB_1:
|
||||
case BigMacReg::HASH_TAB_2:
|
||||
case BigMacReg::HASH_TAB_3:
|
||||
this->hash_table[(reg_offset >> 4) & 3] = value;
|
||||
break;
|
||||
default:
|
||||
LOG_F(WARNING, "%s: unimplemented register at 0x%X is written with 0x%X",
|
||||
this->name.c_str(), reg_offset, value);
|
||||
|
@ -37,11 +37,37 @@ enum EthernetCellId : uint8_t {
|
||||
|
||||
/* 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. */
|
||||
@ -107,6 +133,9 @@ public:
|
||||
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();
|
||||
@ -127,7 +156,32 @@ private:
|
||||
uint8_t chip_id; // BigMac Chip ID
|
||||
|
||||
// BigMac state
|
||||
uint16_t tx_reset = 0;
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user