dev_sgi_mec.cc Source File
Back to the index.
Go to the documentation of this file.
78 #define MEC_TICK_SHIFT 14
80 #define MAX_TX_PACKET_LEN 1700
81 #define N_RX_ADDRESSES 16
111 memset(d->
reg, 0,
sizeof(d->
reg));
122 debug(
"[ sgi_mec: CORE RESET ]\n");
134 unsigned char data[8];
135 int i, res, retval = 0;
139 fatal(
"[ mec_try_rx(): WARNING! lowest bits of base are "
140 "non-zero (0x%3x). TODO ]\n", (
int)(base & 0xfff));
141 base &= 0xfffff000ULL;
154 if (
data[0] & 0x80) {
156 goto skip_and_advance;
169 for (i=0; i<
sizeof(
data); i++) {
172 printf(
"%02x",
data[i]);
187 printf(
"RX: %i bytes, index %i, base = 0x%x\n",
226 uint64_t base,
addr, dma_base;
227 int tx_ring_ptr, ringread, ringwrite, res, i, j;
228 unsigned char data[32];
229 int len, start_offset, dma_ptr_nr, dma_len;
243 if (ringread == ringwrite)
250 addr = base + tx_ring_ptr*128;
257 if (
data[0] & 0x80) {
258 fatal(
"[ mec_try_tx: tx_ring_ptr = %i, already"
259 " transmitted? ]\n", tx_ring_ptr);
264 start_offset =
data[5] & 0x7f;
274 printf(
"{ mec: txdesc %i: ", tx_ring_ptr);
275 for (i=0; i<
sizeof(
data); i++) {
278 printf(
"%02x",
data[i]);
288 for (i=start_offset; i<start_offset+len; i++) {
291 if ((i & 0x7f) == 0x00)
300 fatal(
"[ mec_try_tx: packet too large? ]\n");
312 if (!(
data[4] & (0x01 << dma_ptr_nr)))
314 dma_base = (
data[dma_ptr_nr * 8 + 4] << 24)
315 + (
data[dma_ptr_nr * 8 + 5] << 16)
316 + (
data[dma_ptr_nr * 8 + 6] << 8)
317 + (
data[dma_ptr_nr * 8 + 7]);
318 dma_base &= 0xfffffff8ULL;
319 dma_len = (
data[dma_ptr_nr * 8 + 2] << 8)
320 + (
data[dma_ptr_nr * 8 + 3]) + 1;
325 while (dma_len > 0) {
333 fatal(
"[ mec_try_tx: packet too large?"
344 fatal(
"[ mec_try_tx: not enough data? ]\n");
350 if (
data[4] & 0x01) {
370 ringread = (ringread >> 16) + 1;
393 while (mec_try_tx(
cpu, d))
396 while (mec_try_rx(
cpu, d) && n < 16)
414 uint64_t idata = 0, odata = 0;
423 regnr = relative_addr /
sizeof(uint64_t);
429 if (len ==
sizeof(uint64_t)) {
431 d->
reg[regnr] = idata;
433 odata = d->
reg[regnr];
434 }
else if (len ==
sizeof(uint32_t)) {
436 if (relative_addr & 4)
437 d->
reg[regnr] = (d->
reg[regnr] & ~0xffffffffULL) | (uint32_t)idata;
439 d->
reg[regnr] = (d->
reg[regnr] & 0xffffffffULL) | ((uint64_t)idata << 32ULL);
441 odata = d->
reg[regnr];
442 if (relative_addr & 4)
443 odata = (int32_t)odata;
445 odata = (odata >> 32ULL);
447 }
else if (len ==
sizeof(uint16_t)) {
449 fatal(
"[ sgi_mec: unimplemented %s len %i (addr 0x%x) ]\n",
450 writeflag ?
"write" :
"read", len, (
long long)relative_addr);
451 }
else if ((relative_addr & 7) == 4) {
452 odata = d->
reg[regnr];
453 odata = (uint16_t)(odata >> 16);
454 }
else if ((relative_addr & 7) == 6) {
455 odata = d->
reg[regnr];
456 odata = (uint16_t)odata;
458 fatal(
"[ sgi_mec: unimplemented %s len %i (addr 0x%x) ]\n",
459 writeflag ?
"write" :
"read", len, (
long long)relative_addr);
462 fatal(
"[ sgi_mec: unimplemented %s len %i (addr 0x%x) ]\n",
463 writeflag ?
"write" :
"read", len, (
long long)relative_addr);
468 fatal(
"[ sgi_mec: write to address"
469 " 0x%llx, len %i, data=0x%016llx ]\n",
470 (
long long)relative_addr, len, (
long long)idata);
474 switch (relative_addr & ~7) {
477 mec_control_write(
cpu, d, idata);
492 debug(
"[ sgi_mec: write to MEC_INT_STATUS: "
493 "0x%016llx ]\n", (
long long)idata);
498 debug(
"[ sgi_mec: write to MEC_DMA_CONTROL: "
499 "0x%016llx ]\n", (
long long)idata);
510 debug(
"[ sgi_mec: write to MEC_TX_ALIAS: "
511 "0x%016llx ]\n", (
long long)idata);
513 debug(
"[ sgi_mec: read from MEC_TX_ALIAS: "
514 "0x%016llx ]\n", (
long long)idata);
520 debug(
"[ sgi_mec: write to MEC_RX_ALIAS: "
521 "0x%016llx ]\n", (
long long)idata);
529 debug(
"[ sgi_mec: write to MEC_TX_RING_PTR: "
530 "0x%016llx ]\n", (
long long)idata);
539 debug(
"[ sgi_mec: write to MEC_PHY_DATA (dev %i, reg %i): "
541 dev,
reg, (
long long)idata);
569 fatal(
"[ sgi_mec: unimplemented %s PHY register %i ]\n",
570 writeflag ?
"write to" :
"read from",
reg);
575 debug(
"[ sgi_mec: read from MEC_PHY_DATA (dev %i, reg %i): "
577 dev,
reg, (
long long)odata);
583 debug(
"[ sgi_mec: write to MEC_PHY_ADDRESS: "
584 "0x%016llx ]\n", (
long long)idata);
588 debug(
"[ sgi_mec: write to MEC_PHY_READ_INITIATE: "
589 "0x%016llx ]\n", (
long long)idata);
593 debug(
"[ sgi_mec: setting the MAC address to "
594 "%02x:%02x:%02x:%02x:%02x:%02x ]\n",
595 (idata >> 40) & 255, (idata >> 32) & 255,
596 (idata >> 24) & 255, (idata >> 16) & 255,
597 (idata >> 8) & 255, (idata >> 0) & 255);
599 fatal(
"[ sgi_mec: reading the MAC address as "
600 "%02x:%02x:%02x:%02x:%02x:%02x ]\n",
601 (odata >> 40) & 255, (odata >> 32) & 255,
602 (odata >> 24) & 255, (odata >> 16) & 255,
603 (odata >> 8) & 255, (odata >> 0) & 255);
607 debug(
"[ sgi_mec: setting the ALTERNATIVE MAC address"
608 " to %02x:%02x:%02x:%02x:%02x:%02x ]\n",
609 (idata >> 40) & 255, (idata >> 32) & 255,
610 (idata >> 24) & 255, (idata >> 16) & 255,
611 (idata >> 8) & 255, (idata >> 0) & 255);
613 debug(
"[ sgi_mec: reading the ALTERNATIVE MAC address"
614 " as %02x:%02x:%02x:%02x:%02x:%02x ]\n",
615 (odata >> 40) & 255, (odata >> 32) & 255,
616 (odata >> 24) & 255, (odata >> 16) & 255,
617 (odata >> 8) & 255, (odata >> 0) & 255);
621 debug(
"[ sgi_mec: write to MEC_MULTICAST: "
622 "0x%016llx ]\n", (
long long)idata);
626 debug(
"[ sgi_mec: write to MEC_TX_RING_BASE: "
627 "0x%016llx ]\n", (
long long)idata);
631 debug(
"[ sgi_mec: write to MEC_MCL_RX_FIFO: 0x"
632 "%016llx ]\n", (
long long)idata);
640 fatal(
"[ sgi_mec: unimplemented write to address"
641 " 0x%llx, data=0x%016llx ]\n",
642 (
long long)relative_addr, (
long long)idata);
644 fatal(
"[ sgi_mec: unimplemented read from address"
645 " 0x%llx ]\n", (
long long)relative_addr);
653 fatal(
"[ sgi_mec: read from address"
654 " 0x%llx, len %i, data=0x%llx ]\n", (
long long)relative_addr,
655 len, (
long long)odata);
658 dev_sgi_mec_tick(
cpu, extra);
668 uint64_t baseaddr,
char *irq_path,
unsigned char *
macaddr)
682 snprintf(name2, nlen,
"mec [%02x:%02x:%02x:%02x:%02x:%02x]",
#define MEC_INT_RX_THRESHOLD
#define MEC_INT_STATUS_MASK
#define INTERRUPT_CONNECT(name, istruct)
#define MEC_INT_TX_RING_BUFFER_ALIAS
#define INTERRUPT_ASSERT(istruct)
uint64_t rx_addr[N_RX_ADDRESSES]
#define DEV_SGI_MEC_LENGTH
#define MEC_TX_RING_READ_PTR
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
int net_ethernet_rx(struct net *net, void *extra, unsigned char **packetp, int *lenp)
unsigned char cur_tx_packet[MAX_TX_PACKET_LEN]
#define MEC_PHY_ADDR_DEVICE
void machine_add_tickfunction(struct machine *machine, void(*func)(struct cpu *, void *), void *extra, int clockshift)
#define MEC_PHY_ADDR_DEVSHIFT
#define MEC_PHY_ADDR_REGISTER
void fatal(const char *fmt,...)
#define MAX_TX_PACKET_LEN
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
uint64_t reg[DEV_SGI_MEC_LENGTH/sizeof(uint64_t)]
int cur_rx_addr_index_write
void net_ethernet_tx(struct net *net, void *extra, unsigned char *packet, int len)
#define MEC_TX_RING_PTR_ALIAS
#define MEC_DMA_TX_INT_ENABLE
unsigned char * cur_rx_packet
void net_add_nic(struct net *net, void *extra, unsigned char *macaddr)
#define MEC_TX_RING_WRITE_PTR
int dev_sgi_mec_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
int net_ethernet_rx_avail(struct net *net, void *extra)
#define MEC_INT_TX_PACKET_SENT
#define MEC_INT_RX_MCL_FIFO_ALIAS
#define INTERRUPT_DEASSERT(istruct)
void dev_sgi_mec_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, char *irq_path, unsigned char *macaddr)
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
#define MEC_MAC_REVISION_SHIFT
#define MEC_MAC_CORE_RESET
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
#define MEC_PHY_READ_INITIATE
#define CHECK_ALLOCATION(ptr)
Generated on Tue Aug 25 2020 19:25:06 for GXemul by
1.8.18