ns_gige.cc revision 897
1/* 2 * Copyright (c) 2003 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* @file 30 * Device module for modelling the National Semiconductor 31 * DP83820 ethernet controller. Does not support priority queueing 32 */ 33#include <cstdio> 34#include <deque> 35#include <string> 36 37#include "base/inet.hh" 38#include "cpu/exec_context.hh" 39#include "cpu/intr_control.hh" 40#include "dev/dma.hh" 41#include "dev/ns_gige.hh" 42#include "dev/etherlink.hh" 43#include "mem/bus/bus.hh" 44#include "mem/bus/dma_interface.hh" 45#include "mem/bus/pio_interface.hh" 46#include "mem/bus/pio_interface_impl.hh" 47#include "mem/functional_mem/memory_control.hh" 48#include "mem/functional_mem/physical_memory.hh" 49#include "sim/builder.hh" 50#include "sim/host.hh" 51#include "sim/sim_stats.hh" 52#include "targetarch/vtophys.hh" 53#include "dev/pciconfigall.hh" 54#include "dev/tsunami_cchip.hh" 55 56const char *NsRxStateStrings[] = 57{ 58 "rxIdle", 59 "rxDescRefr", 60 "rxDescRead", 61 "rxFifoBlock", 62 "rxFragWrite", 63 "rxDescWrite", 64 "rxAdvance" 65}; 66 67const char *NsTxStateStrings[] = 68{ 69 "txIdle", 70 "txDescRefr", 71 "txDescRead", 72 "txFifoBlock", 73 "txFragRead", 74 "txDescWrite", 75 "txAdvance" 76}; 77 78const char *NsDmaState[] = 79{ 80 "dmaIdle", 81 "dmaReading", 82 "dmaWriting", 83 "dmaReadWaiting", 84 "dmaWriteWaiting" 85}; 86 87using namespace std; 88 89/////////////////////////////////////////////////////////////////////// 90// 91// NSGigE PCI Device 92// 93NSGigE::NSGigE(const std::string &name, IntrControl *i, Tick intr_delay, 94 PhysicalMemory *pmem, Tick tx_delay, Tick rx_delay, 95 MemoryController *mmu, HierParams *hier, Bus *header_bus, 96 Bus *payload_bus, Tick pio_latency, bool dma_desc_free, 97 bool dma_data_free, Tick dma_read_delay, Tick dma_write_delay, 98 Tick dma_read_factor, Tick dma_write_factor, PciConfigAll *cf, 99 PciConfigData *cd, Tsunami *t, uint32_t bus, uint32_t dev, 100 uint32_t func, bool rx_filter, const int eaddr[6]) 101 : PciDev(name, mmu, cf, cd, bus, dev, func), tsunami(t), 102 txPacketBufPtr(NULL), rxPacketBufPtr(NULL), 103 txXferLen(0), rxXferLen(0), txPktXmitted(0), txState(txIdle), CTDD(false), 104 txFifoCnt(0), txFifoAvail(MAX_TX_FIFO_SIZE), txHalt(false), 105 txFragPtr(0), txDescCnt(0), txDmaState(dmaIdle), rxState(rxIdle), 106 CRDD(false), rxPktBytes(0), rxFifoCnt(0), rxHalt(false), 107 rxFragPtr(0), rxDescCnt(0), rxDmaState(dmaIdle), extstsEnable(false), 108 rxDmaReadEvent(this), rxDmaWriteEvent(this), 109 txDmaReadEvent(this), txDmaWriteEvent(this), 110 dmaDescFree(dma_desc_free), dmaDataFree(dma_data_free), 111 txDelay(tx_delay), rxDelay(rx_delay), rxKickTick(0), txKickTick(0), 112 txEvent(this), rxFilterEnable(rx_filter), acceptBroadcast(false), 113 acceptMulticast(false), acceptUnicast(false), 114 acceptPerfect(false), acceptArp(false), 115 physmem(pmem), intctrl(i), intrTick(0), 116 cpuPendingIntr(false), intrEvent(0), interface(0), pioLatency(pio_latency) 117{ 118 tsunami->ethernet = this; 119 120 if (header_bus) { 121 pioInterface = newPioInterface(name, hier, header_bus, this, 122 &NSGigE::cacheAccess); 123 124 if (payload_bus) 125 dmaInterface = new DMAInterface<Bus>(name + ".dma", 126 header_bus, payload_bus, 1); 127 else 128 dmaInterface = new DMAInterface<Bus>(name + ".dma", 129 header_bus, header_bus, 1); 130 } else if (payload_bus) { 131 pioInterface = newPioInterface(name, hier, payload_bus, this, 132 &NSGigE::cacheAccess); 133 134 dmaInterface = new DMAInterface<Bus>(name + ".dma", 135 payload_bus, payload_bus, 1); 136 137 } 138 139 140 intrDelay = US2Ticks(intr_delay); 141 dmaReadDelay = dma_read_delay; 142 dmaWriteDelay = dma_write_delay; 143 dmaReadFactor = dma_read_factor; 144 dmaWriteFactor = dma_write_factor; 145 146 memset(®s, 0, sizeof(regs)); 147 regsReset(); 148 rom.perfectMatch[0] = eaddr[0]; 149 rom.perfectMatch[1] = eaddr[1]; 150 rom.perfectMatch[2] = eaddr[2]; 151 rom.perfectMatch[3] = eaddr[3]; 152 rom.perfectMatch[4] = eaddr[4]; 153 rom.perfectMatch[5] = eaddr[5]; 154} 155 156NSGigE::~NSGigE() 157{} 158 159void 160NSGigE::regStats() 161{ 162 txBytes 163 .name(name() + ".txBytes") 164 .desc("Bytes Transmitted") 165 .prereq(txBytes) 166 ; 167 168 rxBytes 169 .name(name() + ".rxBytes") 170 .desc("Bytes Received") 171 .prereq(rxBytes) 172 ; 173 174 txPackets 175 .name(name() + ".txPackets") 176 .desc("Number of Packets Transmitted") 177 .prereq(txBytes) 178 ; 179 180 rxPackets 181 .name(name() + ".rxPackets") 182 .desc("Number of Packets Received") 183 .prereq(rxBytes) 184 ; 185 186 txBandwidth 187 .name(name() + ".txBandwidth") 188 .desc("Transmit Bandwidth (bits/s)") 189 .precision(0) 190 .prereq(txBytes) 191 ; 192 193 rxBandwidth 194 .name(name() + ".rxBandwidth") 195 .desc("Receive Bandwidth (bits/s)") 196 .precision(0) 197 .prereq(rxBytes) 198 ; 199 200 txPacketRate 201 .name(name() + ".txPPS") 202 .desc("Packet Tranmission Rate (packets/s)") 203 .precision(0) 204 .prereq(txBytes) 205 ; 206 207 rxPacketRate 208 .name(name() + ".rxPPS") 209 .desc("Packet Reception Rate (packets/s)") 210 .precision(0) 211 .prereq(rxBytes) 212 ; 213 214 txBandwidth = txBytes * Stats::constant(8) / simSeconds; 215 rxBandwidth = rxBytes * Stats::constant(8) / simSeconds; 216 txPacketRate = txPackets / simSeconds; 217 rxPacketRate = rxPackets / simSeconds; 218} 219 220/** 221 * This is to read the PCI general configuration registers 222 */ 223void 224NSGigE::ReadConfig(int offset, int size, uint8_t *data) 225{ 226 if (offset < PCI_DEVICE_SPECIFIC) 227 PciDev::ReadConfig(offset, size, data); 228 else 229 panic("Device specific PCI config space not implemented!\n"); 230} 231 232/** 233 * This is to write to the PCI general configuration registers 234 */ 235void 236NSGigE::WriteConfig(int offset, int size, uint32_t data) 237{ 238 if (offset < PCI_DEVICE_SPECIFIC) 239 PciDev::WriteConfig(offset, size, data); 240 else 241 panic("Device specific PCI config space not implemented!\n"); 242 243 // Need to catch writes to BARs to update the PIO interface 244 switch (offset) { 245 case PCI0_BASE_ADDR0: 246 if (BARAddrs[0] != 0) { 247 addr = BARAddrs[0]; 248 249 if (pioInterface) 250 pioInterface->addAddrRange(addr, addr + size - 1); 251 252 addr &= PA_UNCACHED_MASK; 253 } 254 break; 255 } 256} 257 258/** 259 * This reads the device registers, which are detailed in the NS83820 260 * spec sheet 261 */ 262Fault 263NSGigE::read(MemReqPtr &req, uint8_t *data) 264{ 265 //The mask is to give you only the offset into the device register file 266 Addr daddr = req->paddr & 0xfff; 267 DPRINTF(EthernetPIO, "read da=%#x pa=%#x va=%#x size=%d\n", 268 daddr, req->paddr, req->vaddr, req->size); 269 270 271 //there are some reserved registers, you can see ns_gige_reg.h and 272 //the spec sheet for details 273 if (daddr > LAST && daddr <= RESERVED) { 274 panic("Accessing reserved register"); 275 } else if (daddr > RESERVED && daddr <= 0x3FC) { 276 ReadConfig(daddr & 0xff, req->size, data); 277 return No_Fault; 278 } else if (daddr >= MIB_START && daddr <= MIB_END) { 279 // don't implement all the MIB's. hopefully the kernel 280 // doesn't actually DEPEND upon their values 281 // MIB are just hardware stats keepers 282 uint32_t ® = *(uint32_t *) data; 283 reg = 0; 284 return No_Fault; 285 } else if (daddr > 0x3FC) 286 panic("Something is messed up!\n"); 287 288 switch (req->size) { 289 case sizeof(uint32_t): 290 { 291 uint32_t ® = *(uint32_t *)data; 292 293 switch (daddr) { 294 case CR: 295 reg = regs.command; 296 //these are supposed to be cleared on a read 297 reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); 298 break; 299 300 case CFG: 301 reg = regs.config; 302 break; 303 304 case MEAR: 305 reg = regs.mear; 306 break; 307 308 case PTSCR: 309 reg = regs.ptscr; 310 break; 311 312 case ISR: 313 reg = regs.isr; 314 devIntrClear(ISR_ALL); 315 break; 316 317 case IMR: 318 reg = regs.imr; 319 break; 320 321 case IER: 322 reg = regs.ier; 323 break; 324 325 case IHR: 326 reg = regs.ihr; 327 break; 328 329 case TXDP: 330 reg = regs.txdp; 331 break; 332 333 case TXDP_HI: 334 reg = regs.txdp_hi; 335 break; 336 337 case TXCFG: 338 reg = regs.txcfg; 339 break; 340 341 case GPIOR: 342 reg = regs.gpior; 343 break; 344 345 case RXDP: 346 reg = regs.rxdp; 347 break; 348 349 case RXDP_HI: 350 reg = regs.rxdp_hi; 351 break; 352 353 case RXCFG: 354 reg = regs.rxcfg; 355 break; 356 357 case PQCR: 358 reg = regs.pqcr; 359 break; 360 361 case WCSR: 362 reg = regs.wcsr; 363 break; 364 365 case PCR: 366 reg = regs.pcr; 367 break; 368 369 //see the spec sheet for how RFCR and RFDR work 370 //basically, you write to RFCR to tell the machine what you want to do next 371 //then you act upon RFDR, and the device will be prepared b/c 372 //of what you wrote to RFCR 373 case RFCR: 374 reg = regs.rfcr; 375 break; 376 377 case RFDR: 378 switch (regs.rfcr & RFCR_RFADDR) { 379 case 0x000: 380 reg = rom.perfectMatch[1]; 381 reg = reg << 8; 382 reg += rom.perfectMatch[0]; 383 break; 384 case 0x002: 385 reg = rom.perfectMatch[3] << 8; 386 reg += rom.perfectMatch[2]; 387 break; 388 case 0x004: 389 reg = rom.perfectMatch[5] << 8; 390 reg += rom.perfectMatch[4]; 391 break; 392 default: 393 panic("reading from RFDR for something for other than PMATCH!\n"); 394 //didn't implement other RFDR functionality b/c driver didn't use 395 } 396 break; 397 398 case SRR: 399 reg = regs.srr; 400 break; 401 402 case MIBC: 403 reg = regs.mibc; 404 reg &= ~(MIBC_MIBS | MIBC_ACLR); 405 break; 406 407 case VRCR: 408 reg = regs.vrcr; 409 break; 410 411 case VTCR: 412 reg = regs.vtcr; 413 break; 414 415 case VDR: 416 reg = regs.vdr; 417 break; 418 419 case CCSR: 420 reg = regs.ccsr; 421 break; 422 423 case TBICR: 424 reg = regs.tbicr; 425 break; 426 427 case TBISR: 428 reg = regs.tbisr; 429 break; 430 431 case TANAR: 432 reg = regs.tanar; 433 break; 434 435 case TANLPAR: 436 reg = regs.tanlpar; 437 break; 438 439 case TANER: 440 reg = regs.taner; 441 break; 442 443 case TESR: 444 reg = regs.tesr; 445 break; 446 447 default: 448 panic("reading unimplemented register: addr = %#x", daddr); 449 } 450 451 DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", 452 daddr, reg, reg); 453 } 454 break; 455 456 default: 457 panic("accessing register with invalid size: addr=%#x, size=%d", 458 daddr, req->size); 459 } 460 461 return No_Fault; 462} 463 464Fault 465NSGigE::write(MemReqPtr &req, const uint8_t *data) 466{ 467 Addr daddr = req->paddr & 0xfff; 468 DPRINTF(EthernetPIO, "write da=%#x pa=%#x va=%#x size=%d\n", 469 daddr, req->paddr, req->vaddr, req->size); 470 471 if (daddr > LAST && daddr <= RESERVED) { 472 panic("Accessing reserved register"); 473 } else if (daddr > RESERVED && daddr <= 0x3FC) { 474 WriteConfig(daddr & 0xff, req->size, *(uint32_t *)data); 475 return No_Fault; 476 } else if (daddr > 0x3FC) 477 panic("Something is messed up!\n"); 478 479 if (req->size == sizeof(uint32_t)) { 480 uint32_t reg = *(uint32_t *)data; 481 DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg); 482 483 switch (daddr) { 484 case CR: 485 regs.command = reg; 486 if ((reg & (CR_TXE | CR_TXD)) == (CR_TXE | CR_TXD)) { 487 txHalt = true; 488 } else if (reg & CR_TXE) { 489 //the kernel is enabling the transmit machine 490 if (txState == txIdle) 491 txKick(); 492 } else if (reg & CR_TXD) { 493 txHalt = true; 494 } 495 496 if ((reg & (CR_RXE | CR_RXD)) == (CR_RXE | CR_RXD)) { 497 rxHalt = true; 498 } else if (reg & CR_RXE) { 499 if (rxState == rxIdle) { 500 rxKick(); 501 } 502 } else if (reg & CR_RXD) { 503 rxHalt = true; 504 } 505 506 if (reg & CR_TXR) 507 txReset(); 508 509 if (reg & CR_RXR) 510 rxReset(); 511 512 if (reg & CR_SWI) 513 devIntrPost(ISR_SWI); 514 515 if (reg & CR_RST) { 516 txReset(); 517 rxReset(); 518 519 regsReset(); 520 } 521 break; 522 523 case CFG: 524 if (reg & CFG_LNKSTS || reg & CFG_SPDSTS || reg & CFG_DUPSTS 525 || reg & CFG_RESERVED || reg & CFG_T64ADDR 526 || reg & CFG_PCI64_DET) 527 panic("writing to read-only or reserved CFG bits!\n"); 528 529 regs.config |= reg & ~(CFG_LNKSTS | CFG_SPDSTS | CFG_DUPSTS | CFG_RESERVED | 530 CFG_T64ADDR | CFG_PCI64_DET); 531 532// all these #if 0's are because i don't THINK the kernel needs to have these implemented 533// if there is a problem relating to one of these, you may need to add functionality in 534#if 0 535 if (reg & CFG_TBI_EN) ; 536 if (reg & CFG_MODE_1000) ; 537#endif 538 539 if (reg & CFG_AUTO_1000) 540 panic("CFG_AUTO_1000 not implemented!\n"); 541 542#if 0 543 if (reg & CFG_PINT_DUPSTS || reg & CFG_PINT_LNKSTS || reg & CFG_PINT_SPDSTS) ; 544 if (reg & CFG_TMRTEST) ; 545 if (reg & CFG_MRM_DIS) ; 546 if (reg & CFG_MWI_DIS) ; 547 548 if (reg & CFG_T64ADDR) 549 panic("CFG_T64ADDR is read only register!\n"); 550 551 if (reg & CFG_PCI64_DET) 552 panic("CFG_PCI64_DET is read only register!\n"); 553 554 if (reg & CFG_DATA64_EN) ; 555 if (reg & CFG_M64ADDR) ; 556 if (reg & CFG_PHY_RST) ; 557 if (reg & CFG_PHY_DIS) ; 558#endif 559 560 if (reg & CFG_EXTSTS_EN) 561 extstsEnable = true; 562 else 563 extstsEnable = false; 564 565#if 0 566 if (reg & CFG_REQALG) ; 567 if (reg & CFG_SB) ; 568 if (reg & CFG_POW) ; 569 if (reg & CFG_EXD) ; 570 if (reg & CFG_PESEL) ; 571 if (reg & CFG_BROM_DIS) ; 572 if (reg & CFG_EXT_125) ; 573 if (reg & CFG_BEM) ; 574#endif 575 break; 576 577 case MEAR: 578 regs.mear = reg; 579 /* since phy is completely faked, MEAR_MD* don't matter 580 and since the driver never uses MEAR_EE*, they don't matter */ 581#if 0 582 if (reg & MEAR_EEDI) ; 583 if (reg & MEAR_EEDO) ; //this one is read only 584 if (reg & MEAR_EECLK) ; 585 if (reg & MEAR_EESEL) ; 586 if (reg & MEAR_MDIO) ; 587 if (reg & MEAR_MDDIR) ; 588 if (reg & MEAR_MDC) ; 589#endif 590 break; 591 592 case PTSCR: 593 regs.ptscr = reg & ~(PTSCR_RBIST_RDONLY); 594 /* these control BISTs for various parts of chip - we don't care or do 595 just fake that the BIST is done */ 596 if (reg & PTSCR_RBIST_EN) 597 regs.ptscr |= PTSCR_RBIST_DONE; 598 if (reg & PTSCR_EEBIST_EN) 599 regs.ptscr &= ~PTSCR_EEBIST_EN; 600 if (reg & PTSCR_EELOAD_EN) 601 regs.ptscr &= ~PTSCR_EELOAD_EN; 602 break; 603 604 case ISR: /* writing to the ISR has no effect */ 605 panic("ISR is a read only register!\n"); 606 607 case IMR: 608 regs.imr = reg; 609 devIntrChangeMask(); 610 break; 611 612 case IER: 613 regs.ier = reg; 614 break; 615 616 case IHR: 617 regs.ihr = reg; 618 /* not going to implement real interrupt holdoff */ 619 break; 620 621 case TXDP: 622 regs.txdp = (reg & 0xFFFFFFFC); 623 assert(txState == txIdle); 624 CTDD = false; 625 break; 626 627 case TXDP_HI: 628 regs.txdp_hi = reg; 629 break; 630 631 case TXCFG: 632 regs.txcfg = reg; 633#if 0 634 if (reg & TXCFG_CSI) ; 635 if (reg & TXCFG_HBI) ; 636 if (reg & TXCFG_MLB) ; 637 if (reg & TXCFG_ATP) ; 638 if (reg & TXCFG_ECRETRY) ; /* this could easily be implemented, but 639 considering the network is just a fake 640 pipe, wouldn't make sense to do this */ 641 642 if (reg & TXCFG_BRST_DIS) ; 643#endif 644 645 646 /* we handle our own DMA, ignore the kernel's exhortations */ 647 if (reg & TXCFG_MXDMA) ; 648 649 break; 650 651 case GPIOR: 652 regs.gpior = reg; 653 /* these just control general purpose i/o pins, don't matter */ 654 break; 655 656 case RXDP: 657 regs.rxdp = reg; 658 break; 659 660 case RXDP_HI: 661 regs.rxdp_hi = reg; 662 break; 663 664 case RXCFG: 665 regs.rxcfg = reg; 666#if 0 667 if (reg & RXCFG_AEP) ; 668 if (reg & RXCFG_ARP) ; 669 if (reg & RXCFG_STRIPCRC) ; 670 if (reg & RXCFG_RX_RD) ; 671 if (reg & RXCFG_ALP) ; 672 if (reg & RXCFG_AIRL) ; 673#endif 674 675 /* we handle our own DMA, ignore what kernel says about it */ 676 if (reg & RXCFG_MXDMA) ; 677 678#if 0 679 if (reg & (RXCFG_DRTH | RXCFG_DRTH0)) ; 680#endif 681 break; 682 683 case PQCR: 684 /* there is no priority queueing used in the linux 2.6 driver */ 685 regs.pqcr = reg; 686 break; 687 688 case WCSR: 689 /* not going to implement wake on LAN */ 690 regs.wcsr = reg; 691 break; 692 693 case PCR: 694 /* not going to implement pause control */ 695 regs.pcr = reg; 696 break; 697 698 case RFCR: 699 regs.rfcr = reg; 700 701 rxFilterEnable = (reg & RFCR_RFEN) ? true : false; 702 703 acceptBroadcast = (reg & RFCR_AAB) ? true : false; 704 705 acceptMulticast = (reg & RFCR_AAM) ? true : false; 706 707 acceptUnicast = (reg & RFCR_AAU) ? true : false; 708 709 acceptPerfect = (reg & RFCR_APM) ? true : false; 710 711 acceptArp = (reg & RFCR_AARP) ? true : false; 712 713 if (reg & RFCR_APAT) ; 714// panic("RFCR_APAT not implemented!\n"); 715 716 if (reg & RFCR_MHEN || reg & RFCR_UHEN) 717 panic("hash filtering not implemented!\n"); 718 719 if (reg & RFCR_ULM) 720 panic("RFCR_ULM not implemented!\n"); 721 722 break; 723 724 case RFDR: 725 panic("the driver never writes to RFDR, something is wrong!\n"); 726 727 case BRAR: 728 panic("the driver never uses BRAR, something is wrong!\n"); 729 730 case BRDR: 731 panic("the driver never uses BRDR, something is wrong!\n"); 732 733 case SRR: 734 panic("SRR is read only register!\n"); 735 736 case MIBC: 737 panic("the driver never uses MIBC, something is wrong!\n"); 738 739 case VRCR: 740 regs.vrcr = reg; 741 break; 742 743 case VTCR: 744 regs.vtcr = reg; 745 break; 746 747 case VDR: 748 panic("the driver never uses VDR, something is wrong!\n"); 749 break; 750 751 case CCSR: 752 /* not going to implement clockrun stuff */ 753 regs.ccsr = reg; 754 break; 755 756 case TBICR: 757 regs.tbicr = reg; 758 if (reg & TBICR_MR_LOOPBACK) 759 panic("TBICR_MR_LOOPBACK never used, something wrong!\n"); 760 761 if (reg & TBICR_MR_AN_ENABLE) { 762 regs.tanlpar = regs.tanar; 763 regs.tbisr |= (TBISR_MR_AN_COMPLETE | TBISR_MR_LINK_STATUS); 764 } 765 766#if 0 767 if (reg & TBICR_MR_RESTART_AN) ; 768#endif 769 770 break; 771 772 case TBISR: 773 panic("TBISR is read only register!\n"); 774 775 case TANAR: 776 regs.tanar = reg; 777 if (reg & TANAR_PS2) 778 panic("this isn't used in driver, something wrong!\n"); 779 780 if (reg & TANAR_PS1) 781 panic("this isn't used in driver, something wrong!\n"); 782 break; 783 784 case TANLPAR: 785 panic("this should only be written to by the fake phy!\n"); 786 787 case TANER: 788 panic("TANER is read only register!\n"); 789 790 case TESR: 791 regs.tesr = reg; 792 break; 793 794 default: 795 panic("thought i covered all the register, what is this? addr=%#x", 796 daddr); 797 } 798 } else 799 panic("Invalid Request Size"); 800 801 return No_Fault; 802} 803 804void 805NSGigE::devIntrPost(uint32_t interrupts) 806{ 807 bool delay = false; 808 809 if (interrupts & ISR_RESERVE) 810 panic("Cannot set a reserved interrupt"); 811 812 if (interrupts & ISR_TXRCMP) 813 regs.isr |= ISR_TXRCMP; 814 815 if (interrupts & ISR_RXRCMP) 816 regs.isr |= ISR_RXRCMP; 817 818//ISR_DPERR not implemented 819//ISR_SSERR not implemented 820//ISR_RMABT not implemented 821//ISR_RXSOVR not implemented 822//ISR_HIBINT not implemented 823//ISR_PHY not implemented 824//ISR_PME not implemented 825 826 if (interrupts & ISR_SWI) 827 regs.isr |= ISR_SWI; 828 829//ISR_MIB not implemented 830//ISR_TXURN not implemented 831 832 if (interrupts & ISR_TXIDLE) 833 regs.isr |= ISR_TXIDLE; 834 835 if (interrupts & ISR_TXERR) 836 regs.isr |= ISR_TXERR; 837 838 if (interrupts & ISR_TXDESC) 839 regs.isr |= ISR_TXDESC; 840 841 if (interrupts & ISR_TXOK) { 842 regs.isr |= ISR_TXOK; 843 delay = true; 844 } 845 846 if (interrupts & ISR_RXORN) 847 regs.isr |= ISR_RXORN; 848 849 if (interrupts & ISR_RXIDLE) 850 regs.isr |= ISR_RXIDLE; 851 852//ISR_RXEARLY not implemented 853 854 if (interrupts & ISR_RXERR) 855 regs.isr |= ISR_RXERR; 856 857 if (interrupts & ISR_RXDESC) 858 regs.isr |= ISR_RXDESC; 859 860 if (interrupts & ISR_RXOK) { 861 delay = true; 862 regs.isr |= ISR_RXOK; 863 } 864 865 if ((regs.isr & regs.imr)) { 866 Tick when = curTick; 867 if (delay) 868 when += intrDelay; 869 cpuIntrPost(when); 870 } 871 872 DPRINTF(Ethernet, "interrupt posted intr=%#x isr=%#x imr=%#x\n", 873 interrupts, regs.isr, regs.imr); 874} 875 876void 877NSGigE::devIntrClear(uint32_t interrupts) 878{ 879 if (interrupts & ISR_RESERVE) 880 panic("Cannot clear a reserved interrupt"); 881 882 if (interrupts & ISR_TXRCMP) 883 regs.isr &= ~ISR_TXRCMP; 884 885 if (interrupts & ISR_RXRCMP) 886 regs.isr &= ~ISR_RXRCMP; 887 888//ISR_DPERR not implemented 889//ISR_SSERR not implemented 890//ISR_RMABT not implemented 891//ISR_RXSOVR not implemented 892//ISR_HIBINT not implemented 893//ISR_PHY not implemented 894//ISR_PME not implemented 895 896 if (interrupts & ISR_SWI) 897 regs.isr &= ~ISR_SWI; 898 899//ISR_MIB not implemented 900//ISR_TXURN not implemented 901 902 if (interrupts & ISR_TXIDLE) 903 regs.isr &= ~ISR_TXIDLE; 904 905 if (interrupts & ISR_TXERR) 906 regs.isr &= ~ISR_TXERR; 907 908 if (interrupts & ISR_TXDESC) 909 regs.isr &= ~ISR_TXDESC; 910 911 if (interrupts & ISR_TXOK) 912 regs.isr &= ~ISR_TXOK; 913 914 if (interrupts & ISR_RXORN) 915 regs.isr &= ~ISR_RXORN; 916 917 if (interrupts & ISR_RXIDLE) 918 regs.isr &= ~ISR_RXIDLE; 919 920//ISR_RXEARLY not implemented 921 922 if (interrupts & ISR_RXERR) 923 regs.isr &= ~ISR_RXERR; 924 925 if (interrupts & ISR_RXDESC) 926 regs.isr &= ~ISR_RXDESC; 927 928 if (interrupts & ISR_RXOK) 929 regs.isr &= ~ISR_RXOK; 930 931 if (!(regs.isr & regs.imr)) 932 cpuIntrClear(); 933 934 DPRINTF(Ethernet, "interrupt cleared intr=%x isr=%x imr=%x\n", 935 interrupts, regs.isr, regs.imr); 936} 937 938void 939NSGigE::devIntrChangeMask() 940{ 941 DPRINTF(Ethernet, "interrupt mask changed\n"); 942 943 if (regs.isr & regs.imr) 944 cpuIntrPost(curTick); 945 else 946 cpuIntrClear(); 947} 948 949void 950NSGigE::cpuIntrPost(Tick when) 951{ 952 if (when > intrTick && intrTick != 0) 953 return; 954 955 intrTick = when; 956 957 if (intrEvent) { 958 intrEvent->squash(); 959 intrEvent = 0; 960 } 961 962 if (when < curTick) { 963 cpuInterrupt(); 964 } else { 965 intrEvent = new IntrEvent(this, true); 966 intrEvent->schedule(intrTick); 967 } 968} 969 970void 971NSGigE::cpuInterrupt() 972{ 973 // Don't send an interrupt if there's already one 974 if (cpuPendingIntr) 975 return; 976 977 // Don't send an interrupt if it's supposed to be delayed 978 if (intrTick > curTick) 979 return; 980 981 // Whether or not there's a pending interrupt, we don't care about 982 // it anymore 983 intrEvent = 0; 984 intrTick = 0; 985 986 // Send interrupt 987 cpuPendingIntr = true; 988 /** @todo rework the intctrl to be tsunami ok */ 989 //intctrl->post(TheISA::INTLEVEL_IRQ1, TheISA::INTINDEX_ETHERNET); 990 tsunami->cchip->postDRIR(configData->config.hdr.pci0.interruptLine); 991} 992 993void 994NSGigE::cpuIntrClear() 995{ 996 if (cpuPendingIntr) { 997 cpuPendingIntr = false; 998 /** @todo rework the intctrl to be tsunami ok */ 999 //intctrl->clear(TheISA::INTLEVEL_IRQ1, TheISA::INTINDEX_ETHERNET); 1000 tsunami->cchip->clearDRIR(configData->config.hdr.pci0.interruptLine); 1001 } 1002} 1003 1004bool 1005NSGigE::cpuIntrPending() const 1006{ return cpuPendingIntr; } 1007 1008void 1009NSGigE::txReset() 1010{ 1011 1012 DPRINTF(Ethernet, "transmit reset\n"); 1013 1014 CTDD = false; 1015 txFifoCnt = 0; 1016 txFifoAvail = MAX_TX_FIFO_SIZE; 1017 txHalt = false; 1018 txFragPtr = 0; 1019 assert(txDescCnt == 0); 1020 txFifo.clear(); 1021 regs.command &= ~CR_TXE; 1022 txState = txIdle; 1023 assert(txDmaState == dmaIdle); 1024} 1025 1026void 1027NSGigE::rxReset() 1028{ 1029 DPRINTF(Ethernet, "receive reset\n"); 1030 1031 CRDD = false; 1032 assert(rxPktBytes == 0); 1033 rxFifoCnt = 0; 1034 rxHalt = false; 1035 rxFragPtr = 0; 1036 assert(rxDescCnt == 0); 1037 assert(rxDmaState == dmaIdle); 1038 rxFifo.clear(); 1039 regs.command &= ~CR_RXE; 1040 rxState = rxIdle; 1041} 1042 1043void 1044NSGigE::rxDmaReadCopy() 1045{ 1046 assert(rxDmaState == dmaReading); 1047 1048 memcpy(rxDmaData, physmem->dma_addr(rxDmaAddr, rxDmaLen), rxDmaLen); 1049 rxDmaState = dmaIdle; 1050 1051 DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n", 1052 rxDmaAddr, rxDmaLen); 1053 DDUMP(EthernetDMA, rxDmaData, rxDmaLen); 1054} 1055 1056bool 1057NSGigE::doRxDmaRead() 1058{ 1059 assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting); 1060 rxDmaState = dmaReading; 1061 1062 if (dmaInterface && !rxDmaFree) { 1063 if (dmaInterface->busy()) 1064 rxDmaState = dmaReadWaiting; 1065 else 1066 dmaInterface->doDMA(Read, rxDmaAddr, rxDmaLen, curTick, 1067 &rxDmaReadEvent); 1068 return true; 1069 } 1070 1071 if (dmaReadDelay == 0 && dmaReadFactor == 0) { 1072 rxDmaReadCopy(); 1073 return false; 1074 } 1075 1076 Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; 1077 Tick start = curTick + dmaReadDelay + factor; 1078 rxDmaReadEvent.schedule(start); 1079 return true; 1080} 1081 1082void 1083NSGigE::rxDmaReadDone() 1084{ 1085 assert(rxDmaState == dmaReading); 1086 rxDmaReadCopy(); 1087 1088 // If the transmit state machine has a pending DMA, let it go first 1089 if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) 1090 txKick(); 1091 1092 rxKick(); 1093} 1094 1095void 1096NSGigE::rxDmaWriteCopy() 1097{ 1098 assert(rxDmaState == dmaWriting); 1099 1100 memcpy(physmem->dma_addr(rxDmaAddr, rxDmaLen), rxDmaData, rxDmaLen); 1101 rxDmaState = dmaIdle; 1102 1103 DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", 1104 rxDmaAddr, rxDmaLen); 1105 DDUMP(EthernetDMA, rxDmaData, rxDmaLen); 1106} 1107 1108bool 1109NSGigE::doRxDmaWrite() 1110{ 1111 assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting); 1112 rxDmaState = dmaWriting; 1113 1114 if (dmaInterface && !rxDmaFree) { 1115 if (dmaInterface->busy()) 1116 rxDmaState = dmaWriteWaiting; 1117 else 1118 dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen, curTick, 1119 &rxDmaWriteEvent); 1120 return true; 1121 } 1122 1123 if (dmaWriteDelay == 0 && dmaWriteFactor == 0) { 1124 rxDmaWriteCopy(); 1125 return false; 1126 } 1127 1128 Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; 1129 Tick start = curTick + dmaWriteDelay + factor; 1130 rxDmaWriteEvent.schedule(start); 1131 return true; 1132} 1133 1134void 1135NSGigE::rxDmaWriteDone() 1136{ 1137 assert(rxDmaState == dmaWriting); 1138 rxDmaWriteCopy(); 1139 1140 // If the transmit state machine has a pending DMA, let it go first 1141 if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) 1142 txKick(); 1143 1144 rxKick(); 1145} 1146 1147void 1148NSGigE::rxKick() 1149{ 1150 DPRINTF(Ethernet, "receive kick state=%s (rxBuf.size=%d)\n", 1151 NsRxStateStrings[rxState], rxFifo.size()); 1152 1153 if (rxKickTick > curTick) { 1154 DPRINTF(Ethernet, "receive kick exiting, can't run till %d\n", 1155 rxKickTick); 1156 return; 1157 } 1158 1159 next: 1160 switch(rxDmaState) { 1161 case dmaReadWaiting: 1162 if (doRxDmaRead()) 1163 goto exit; 1164 break; 1165 case dmaWriteWaiting: 1166 if (doRxDmaWrite()) 1167 goto exit; 1168 break; 1169 default: 1170 break; 1171 } 1172 1173 // see state machine from spec for details 1174 // the way this works is, if you finish work on one state and can go directly to 1175 // another, you do that through jumping to the label "next". however, if you have 1176 // intermediate work, like DMA so that you can't go to the next state yet, you go to 1177 // exit and exit the loop. however, when the DMA is done it will trigger an 1178 // event and come back to this loop. 1179 switch (rxState) { 1180 case rxIdle: 1181 if (!regs.command & CR_RXE) { 1182 DPRINTF(Ethernet, "Receive Disabled! Nothing to do.\n"); 1183 goto exit; 1184 } 1185 1186 if (CRDD) { 1187 rxState = rxDescRefr; 1188 1189 rxDmaAddr = regs.rxdp & 0x3fffffff; 1190 rxDmaData = &rxDescCache + offsetof(ns_desc, link); 1191 rxDmaLen = sizeof(rxDescCache.link); 1192 rxDmaFree = dmaDescFree; 1193 1194 if (doRxDmaRead()) 1195 goto exit; 1196 } else { 1197 rxState = rxDescRead; 1198 1199 rxDmaAddr = regs.rxdp & 0x3fffffff; 1200 rxDmaData = &rxDescCache; 1201 rxDmaLen = sizeof(ns_desc); 1202 rxDmaFree = dmaDescFree; 1203 1204 if (doRxDmaRead()) 1205 goto exit; 1206 } 1207 break; 1208 1209 case rxDescRefr: 1210 if (rxDmaState != dmaIdle) 1211 goto exit; 1212 1213 rxState = rxAdvance; 1214 break; 1215 1216 case rxDescRead: 1217 if (rxDmaState != dmaIdle) 1218 goto exit; 1219 1220 DPRINTF(Ethernet, 1221 "rxDescCache:\n\tlink=%#x\n\tbufptr=%#x\n\tcmdsts=%#x\n\textsts=%#x\n" 1222 ,rxDescCache.link, rxDescCache.bufptr, rxDescCache.cmdsts, 1223 rxDescCache.extsts); 1224 1225 if (rxDescCache.cmdsts & CMDSTS_OWN) { 1226 rxState = rxIdle; 1227 } else { 1228 rxState = rxFifoBlock; 1229 rxFragPtr = rxDescCache.bufptr; 1230 rxDescCnt = rxDescCache.cmdsts & CMDSTS_LEN_MASK; 1231 } 1232 break; 1233 1234 case rxFifoBlock: 1235 if (!rxPacket) { 1236 /** 1237 * @todo in reality, we should be able to start processing 1238 * the packet as it arrives, and not have to wait for the 1239 * full packet ot be in the receive fifo. 1240 */ 1241 if (rxFifo.empty()) 1242 goto exit; 1243 1244 // If we don't have a packet, grab a new one from the fifo. 1245 rxPacket = rxFifo.front(); 1246 rxPktBytes = rxPacket->length; 1247 rxPacketBufPtr = rxPacket->data; 1248 1249 // sanity check - i think the driver behaves like this 1250 assert(rxDescCnt >= rxPktBytes); 1251 1252 // Must clear the value before popping to decrement the 1253 // reference count 1254 rxFifo.front() = NULL; 1255 rxFifo.pop_front(); 1256 } 1257 1258 1259 // dont' need the && rxDescCnt > 0 if driver sanity check above holds 1260 if (rxPktBytes > 0) { 1261 rxState = rxFragWrite; 1262 // don't need min<>(rxPktBytes,rxDescCnt) if above sanity check holds 1263 rxXferLen = rxPktBytes; 1264 1265 rxDmaAddr = rxFragPtr & 0x3fffffff; 1266 rxDmaData = rxPacketBufPtr; 1267 rxDmaLen = rxXferLen; 1268 rxDmaFree = dmaDataFree; 1269 1270 if (doRxDmaWrite()) 1271 goto exit; 1272 1273 } else { 1274 rxState = rxDescWrite; 1275 1276 //if (rxPktBytes == 0) { /* packet is done */ 1277 assert(rxPktBytes == 0); 1278 1279 rxDescCache.cmdsts |= CMDSTS_OWN; 1280 rxDescCache.cmdsts &= ~CMDSTS_MORE; 1281 rxDescCache.cmdsts |= CMDSTS_OK; 1282 rxDescCache.cmdsts &= 0xffff0000; 1283 rxDescCache.cmdsts += rxPacket->length; //i.e. set CMDSTS_SIZE 1284 1285#if 0 1286 /* all the driver uses these are for its own stats keeping 1287 which we don't care about, aren't necessary for functionality 1288 and doing this would just slow us down. if they end up using 1289 this in a later version for functional purposes, just undef 1290 */ 1291 if (rxFilterEnable) { 1292 rxDescCache.cmdsts &= ~CMDSTS_DEST_MASK; 1293 if (rxFifo.front()->IsUnicast()) 1294 rxDescCache.cmdsts |= CMDSTS_DEST_SELF; 1295 if (rxFifo.front()->IsMulticast()) 1296 rxDescCache.cmdsts |= CMDSTS_DEST_MULTI; 1297 if (rxFifo.front()->IsBroadcast()) 1298 rxDescCache.cmdsts |= CMDSTS_DEST_MASK; 1299 } 1300#endif 1301 1302 eth_header *eth = (eth_header *) rxPacket->data; 1303 // eth->type 0x800 indicated that it's an ip packet. 1304 if (eth->type == 0x800 && extstsEnable) { 1305 rxDescCache.extsts |= EXTSTS_IPPKT; 1306 if (!ipChecksum(rxPacket, false)) 1307 rxDescCache.extsts |= EXTSTS_IPERR; 1308 ip_header *ip = rxFifo.front()->getIpHdr(); 1309 1310 if (ip->protocol == 6) { 1311 rxDescCache.extsts |= EXTSTS_TCPPKT; 1312 if (!tcpChecksum(rxPacket, false)) 1313 rxDescCache.extsts |= EXTSTS_TCPERR; 1314 } else if (ip->protocol == 17) { 1315 rxDescCache.extsts |= EXTSTS_UDPPKT; 1316 if (!udpChecksum(rxPacket, false)) 1317 rxDescCache.extsts |= EXTSTS_UDPERR; 1318 } 1319 } 1320 1321 rxFifoCnt -= rxPacket->length; 1322 rxPacket = 0; 1323 1324 /* the driver seems to always receive into desc buffers 1325 of size 1514, so you never have a pkt that is split 1326 into multiple descriptors on the receive side, so 1327 i don't implement that case, hence the assert above. 1328 */ 1329 1330 DPRINTF(Ethernet, "rxDesc writeback:\n\tcmdsts=%#x\n\textsts=%#x\n", 1331 rxDescCache.cmdsts, rxDescCache.extsts); 1332 1333 rxDmaAddr = (regs.rxdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff; 1334 rxDmaData = &(rxDescCache.cmdsts); 1335 rxDmaLen = sizeof(rxDescCache.cmdsts) + sizeof(rxDescCache.extsts); 1336 rxDmaFree = dmaDescFree; 1337 1338 if (doRxDmaWrite()) 1339 goto exit; 1340 } 1341 break; 1342 1343 case rxFragWrite: 1344 if (rxDmaState != dmaIdle) 1345 goto exit; 1346 1347 rxPacketBufPtr += rxXferLen; 1348 rxFragPtr += rxXferLen; 1349 rxPktBytes -= rxXferLen; 1350 1351 rxState = rxFifoBlock; 1352 break; 1353 1354 case rxDescWrite: 1355 if (rxDmaState != dmaIdle) 1356 goto exit; 1357 1358 assert(rxDescCache.cmdsts & CMDSTS_OWN); 1359 1360 assert(rxPacket == 0); 1361 devIntrPost(ISR_RXOK); 1362 1363 if (rxDescCache.cmdsts & CMDSTS_INTR) 1364 devIntrPost(ISR_RXDESC); 1365 1366 if (rxHalt) { 1367 rxState = rxIdle; 1368 rxHalt = false; 1369 } else 1370 rxState = rxAdvance; 1371 break; 1372 1373 case rxAdvance: 1374 if (rxDescCache.link == 0) { 1375 rxState = rxIdle; 1376 return; 1377 } else { 1378 rxState = rxDescRead; 1379 regs.rxdp = rxDescCache.link; 1380 CRDD = false; 1381 1382 rxDmaAddr = regs.rxdp & 0x3fffffff; 1383 rxDmaData = &rxDescCache; 1384 rxDmaLen = sizeof(ns_desc); 1385 rxDmaFree = dmaDescFree; 1386 1387 if (doRxDmaRead()) 1388 goto exit; 1389 } 1390 break; 1391 1392 default: 1393 panic("Invalid rxState!"); 1394 } 1395 1396 1397 DPRINTF(Ethernet, "entering next rx state = %s\n", 1398 NsRxStateStrings[rxState]); 1399 1400 if (rxState == rxIdle) { 1401 regs.command &= ~CR_RXE; 1402 devIntrPost(ISR_RXIDLE); 1403 return; 1404 } 1405 1406 goto next; 1407 1408 exit: 1409 /** 1410 * @todo do we want to schedule a future kick? 1411 */ 1412 DPRINTF(Ethernet, "rx state machine exited state=%s\n", 1413 NsRxStateStrings[rxState]); 1414} 1415 1416void 1417NSGigE::transmit() 1418{ 1419 if (txFifo.empty()) { 1420 DPRINTF(Ethernet, "nothing to transmit\n"); 1421 return; 1422 } 1423 1424 if (interface->sendPacket(txFifo.front())) { 1425 DPRINTF(Ethernet, "transmit packet\n"); 1426 DDUMP(Ethernet, txFifo.front()->data, txFifo.front()->length); 1427 txBytes += txFifo.front()->length; 1428 txPackets++; 1429 1430 txFifoCnt -= (txFifo.front()->length - txPktXmitted); 1431 txPktXmitted = 0; 1432 txFifo.front() = NULL; 1433 txFifo.pop_front(); 1434 1435 /* normally do a writeback of the descriptor here, and ONLY after that is 1436 done, send this interrupt. but since our stuff never actually fails, 1437 just do this interrupt here, otherwise the code has to stray from this 1438 nice format. besides, it's functionally the same. 1439 */ 1440 devIntrPost(ISR_TXOK); 1441 } 1442 1443 if (!txFifo.empty() && !txEvent.scheduled()) { 1444 DPRINTF(Ethernet, "reschedule transmit\n"); 1445 txEvent.schedule(curTick + 1000); 1446 } 1447} 1448 1449void 1450NSGigE::txDmaReadCopy() 1451{ 1452 assert(txDmaState == dmaReading); 1453 1454 memcpy(txDmaData, physmem->dma_addr(txDmaAddr, txDmaLen), txDmaLen); 1455 txDmaState = dmaIdle; 1456 1457 DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", 1458 txDmaAddr, txDmaLen); 1459 DDUMP(EthernetDMA, txDmaData, txDmaLen); 1460} 1461 1462bool 1463NSGigE::doTxDmaRead() 1464{ 1465 assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting); 1466 txDmaState = dmaReading; 1467 1468 if (dmaInterface && !txDmaFree) { 1469 if (dmaInterface->busy()) 1470 txDmaState = dmaReadWaiting; 1471 else 1472 dmaInterface->doDMA(Read, txDmaAddr, txDmaLen, curTick, 1473 &txDmaReadEvent); 1474 return true; 1475 } 1476 1477 if (dmaReadDelay == 0 && dmaReadFactor == 0.0) { 1478 txDmaReadCopy(); 1479 return false; 1480 } 1481 1482 Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; 1483 Tick start = curTick + dmaReadDelay + factor; 1484 txDmaReadEvent.schedule(start); 1485 return true; 1486} 1487 1488void 1489NSGigE::txDmaReadDone() 1490{ 1491 assert(txDmaState == dmaReading); 1492 txDmaReadCopy(); 1493 1494 // If the receive state machine has a pending DMA, let it go first 1495 if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) 1496 rxKick(); 1497 1498 txKick(); 1499} 1500 1501void 1502NSGigE::txDmaWriteCopy() 1503{ 1504 assert(txDmaState == dmaWriting); 1505 1506 memcpy(physmem->dma_addr(txDmaAddr, txDmaLen), txDmaData, txDmaLen); 1507 txDmaState = dmaIdle; 1508 1509 DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n", 1510 txDmaAddr, txDmaLen); 1511 DDUMP(EthernetDMA, txDmaData, txDmaLen); 1512} 1513 1514bool 1515NSGigE::doTxDmaWrite() 1516{ 1517 assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting); 1518 txDmaState = dmaWriting; 1519 1520 if (dmaInterface && !txDmaFree) { 1521 if (dmaInterface->busy()) 1522 txDmaState = dmaWriteWaiting; 1523 else 1524 dmaInterface->doDMA(WriteInvalidate, txDmaAddr, txDmaLen, curTick, 1525 &txDmaWriteEvent); 1526 return true; 1527 } 1528 1529 if (dmaWriteDelay == 0 && dmaWriteFactor == 0.0) { 1530 txDmaWriteCopy(); 1531 return false; 1532 } 1533 1534 Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; 1535 Tick start = curTick + dmaWriteDelay + factor; 1536 txDmaWriteEvent.schedule(start); 1537 return true; 1538} 1539 1540void 1541NSGigE::txDmaWriteDone() 1542{ 1543 assert(txDmaState == dmaWriting); 1544 txDmaWriteCopy(); 1545 1546 // If the receive state machine has a pending DMA, let it go first 1547 if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) 1548 rxKick(); 1549 1550 txKick(); 1551} 1552 1553void 1554NSGigE::txKick() 1555{ 1556 DPRINTF(Ethernet, "transmit kick state=%s\n", NsTxStateStrings[txState]); 1557 1558 if (rxKickTick > curTick) { 1559 DPRINTF(Ethernet, "receive kick exiting, can't run till %d\n", 1560 rxKickTick); 1561 1562 return; 1563 } 1564 1565 next: 1566 switch(txDmaState) { 1567 case dmaReadWaiting: 1568 if (doTxDmaRead()) 1569 goto exit; 1570 break; 1571 case dmaWriteWaiting: 1572 if (doTxDmaWrite()) 1573 goto exit; 1574 break; 1575 default: 1576 break; 1577 } 1578 1579 switch (txState) { 1580 case txIdle: 1581 if (!regs.command & CR_TXE) { 1582 DPRINTF(Ethernet, "Transmit disabled. Nothing to do.\n"); 1583 goto exit; 1584 } 1585 1586 if (CTDD) { 1587 txState = txDescRefr; 1588 1589 txDmaAddr = regs.txdp & 0x3fffffff; 1590 txDmaData = &txDescCache + offsetof(ns_desc, link); 1591 txDmaLen = sizeof(txDescCache.link); 1592 txDmaFree = dmaDescFree; 1593 1594 if (doTxDmaRead()) 1595 goto exit; 1596 1597 } else { 1598 txState = txDescRead; 1599 1600 txDmaAddr = regs.txdp & 0x3fffffff; 1601 txDmaData = &txDescCache; 1602 txDmaLen = sizeof(ns_desc); 1603 txDmaFree = dmaDescFree; 1604 1605 if (doTxDmaRead()) 1606 goto exit; 1607 } 1608 break; 1609 1610 case txDescRefr: 1611 if (txDmaState != dmaIdle) 1612 goto exit; 1613 1614 txState = txAdvance; 1615 break; 1616 1617 case txDescRead: 1618 if (txDmaState != dmaIdle) 1619 goto exit; 1620 1621 DPRINTF(Ethernet, 1622 "txDescCache data:\n\tlink=%#x\n\tbufptr=%#x\n\tcmdsts=%#x\n\textsts=%#x\n" 1623 ,txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts, 1624 txDescCache.extsts); 1625 1626 if (txDescCache.cmdsts & CMDSTS_OWN) { 1627 txState = txFifoBlock; 1628 txFragPtr = txDescCache.bufptr; 1629 txDescCnt = txDescCache.cmdsts & CMDSTS_LEN_MASK; 1630 } else { 1631 txState = txIdle; 1632 } 1633 break; 1634 1635 case txFifoBlock: 1636 if (!txPacket) { 1637 DPRINTF(Ethernet, "starting the tx of a new packet\n"); 1638 txPacket = new EtherPacket; 1639 txPacket->data = new uint8_t[16384]; 1640 txPacketBufPtr = txPacket->data; 1641 } 1642 1643 if (txDescCnt == 0) { 1644 DPRINTF(Ethernet, "the txDescCnt == 0, done with descriptor\n"); 1645 if (txDescCache.cmdsts & CMDSTS_MORE) { 1646 DPRINTF(Ethernet, "there are more descriptors to come\n"); 1647 txState = txDescWrite; 1648 1649 txDescCache.cmdsts &= ~CMDSTS_OWN; 1650 1651 txDmaAddr = (regs.txdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff; 1652 txDmaData = &(txDescCache.cmdsts); 1653 txDmaLen = sizeof(txDescCache.cmdsts); 1654 txDmaFree = dmaDescFree; 1655 1656 if (doTxDmaWrite()) 1657 goto exit; 1658 1659 } else { /* this packet is totally done */ 1660 DPRINTF(Ethernet, "This packet is done, let's wrap it up\n"); 1661 /* deal with the the packet that just finished */ 1662 if ((regs.vtcr & VTCR_PPCHK) && extstsEnable) { 1663 if (txDescCache.extsts & EXTSTS_UDPPKT) { 1664 udpChecksum(txPacket, true); 1665 } else if (txDescCache.extsts & EXTSTS_TCPPKT) { 1666 tcpChecksum(txPacket, true); 1667 } else if (txDescCache.extsts & EXTSTS_IPPKT) { 1668 ipChecksum(txPacket, true); 1669 } 1670 } 1671 1672 txPacket->length = txPacketBufPtr - txPacket->data; 1673 /* this is just because the receive can't handle a packet bigger 1674 want to make sure */ 1675 assert(txPacket->length <= 1514); 1676 txFifo.push_back(txPacket); 1677 1678 1679 /* this following section is not to spec, but functionally shouldn't 1680 be any different. normally, the chip will wait til the transmit has 1681 occurred before writing back the descriptor because it has to wait 1682 to see that it was successfully transmitted to decide whether to set 1683 CMDSTS_OK or not. however, in the simulator since it is always 1684 successfully transmitted, and writing it exactly to spec would 1685 complicate the code, we just do it here 1686 */ 1687 txDescCache.cmdsts &= ~CMDSTS_OWN; 1688 txDescCache.cmdsts |= CMDSTS_OK; 1689 1690 DPRINTF(Ethernet, 1691 "txDesc writeback:\n\tcmdsts=%#x\n\textsts=%#x\n", 1692 txDescCache.cmdsts, txDescCache.extsts); 1693 1694 txDmaAddr = (regs.txdp + offsetof(ns_desc, cmdsts)) & 0x3fffffff; 1695 txDmaData = &(txDescCache.cmdsts); 1696 txDmaLen = sizeof(txDescCache.cmdsts) + sizeof(txDescCache.extsts); 1697 txDmaFree = dmaDescFree; 1698 1699 if (doTxDmaWrite()) 1700 goto exit; 1701 1702 txPacket = 0; 1703 transmit(); 1704 1705 if (txHalt) { 1706 txState = txIdle; 1707 txHalt = false; 1708 } else 1709 txState = txAdvance; 1710 } 1711 } else { 1712 DPRINTF(Ethernet, "this descriptor isn't done yet\n"); 1713 /* the fill thresh is in units of 32 bytes, shift right by 8 to get the 1714 value, shift left by 5 to get the real number of bytes */ 1715 if (txFifoAvail < ((regs.txcfg & TXCFG_FLTH_MASK) >> 3)) { 1716 DPRINTF(Ethernet, "txFifoAvail=%d, regs.txcfg & TXCFG_FLTH_MASK = %#x\n", 1717 txFifoAvail, regs.txcfg & TXCFG_FLTH_MASK); 1718 goto exit; 1719 } 1720 1721 txState = txFragRead; 1722 1723 /* The number of bytes transferred is either whatever is left 1724 in the descriptor (txDescCnt), or if there is not enough 1725 room in the fifo, just whatever room is left in the fifo 1726 */ 1727 txXferLen = min<uint32_t>(txDescCnt, txFifoAvail); 1728 1729 txDmaAddr = txFragPtr & 0x3fffffff; 1730 txDmaData = txPacketBufPtr; 1731 txDmaLen = txXferLen; 1732 txDmaFree = dmaDataFree; 1733 1734 if (doTxDmaRead()) 1735 goto exit; 1736 } 1737 break; 1738 1739 case txFragRead: 1740 if (txDmaState != dmaIdle) 1741 goto exit; 1742 1743 txPacketBufPtr += txXferLen; 1744 txFragPtr += txXferLen; 1745 txFifoCnt += txXferLen; 1746 txDescCnt -= txXferLen; 1747 1748 txState = txFifoBlock; 1749 break; 1750 1751 case txDescWrite: 1752 if (txDmaState != dmaIdle) 1753 goto exit; 1754 1755 if (txFifoCnt >= ((regs.txcfg & TXCFG_DRTH_MASK) << 5)) { 1756 if (txFifo.empty()) { 1757 uint32_t xmitted = (uint32_t) (txPacketBufPtr - txPacket->data - txPktXmitted); 1758 txFifoCnt -= xmitted; 1759 txPktXmitted += xmitted; 1760 } else { 1761 transmit(); 1762 } 1763 } 1764 1765 if (txDescCache.cmdsts & CMDSTS_INTR) { 1766 devIntrPost(ISR_TXDESC); 1767 } 1768 1769 txState = txAdvance; 1770 break; 1771 1772 case txAdvance: 1773 if (txDescCache.link == 0) { 1774 txState = txIdle; 1775 } else { 1776 txState = txDescRead; 1777 regs.txdp = txDescCache.link; 1778 CTDD = false; 1779 1780 txDmaAddr = txDescCache.link & 0x3fffffff; 1781 txDmaData = &txDescCache; 1782 txDmaLen = sizeof(ns_desc); 1783 txDmaFree = dmaDescFree; 1784 1785 if (doTxDmaRead()) 1786 goto exit; 1787 } 1788 break; 1789 1790 default: 1791 panic("invalid state"); 1792 } 1793 1794 DPRINTF(Ethernet, "entering next tx state=%s\n", 1795 NsTxStateStrings[txState]); 1796 1797 if (txState == txIdle) { 1798 regs.command &= ~CR_TXE; 1799 devIntrPost(ISR_TXIDLE); 1800 return; 1801 } 1802 1803 goto next; 1804 1805 exit: 1806 /** 1807 * @todo do we want to schedule a future kick? 1808 */ 1809 DPRINTF(Ethernet, "tx state machine exited state=%s\n", 1810 NsTxStateStrings[txState]); 1811} 1812 1813void 1814NSGigE::transferDone() 1815{ 1816 if (txFifo.empty()) 1817 return; 1818 1819 DPRINTF(Ethernet, "schedule transmit\n"); 1820 1821 if (txEvent.scheduled()) 1822 txEvent.reschedule(curTick + 1); 1823 else 1824 txEvent.schedule(curTick + 1); 1825} 1826 1827bool 1828NSGigE::rxFilter(PacketPtr packet) 1829{ 1830 bool drop = true; 1831 string type; 1832 1833 if (packet->IsUnicast()) { 1834 type = "unicast"; 1835 1836 // If we're accepting all unicast addresses 1837 if (acceptUnicast) 1838 drop = false; 1839 1840 // If we make a perfect match 1841 if ((acceptPerfect) 1842 && (memcmp(rom.perfectMatch, packet->data, sizeof(rom.perfectMatch)) == 0)) 1843 drop = false; 1844 1845 eth_header *eth = (eth_header *) packet->data; 1846 if ((acceptArp) && (eth->type == 0x806)) 1847 drop = false; 1848 1849 } else if (packet->IsBroadcast()) { 1850 type = "broadcast"; 1851 1852 // if we're accepting broadcasts 1853 if (acceptBroadcast) 1854 drop = false; 1855 1856 } else if (packet->IsMulticast()) { 1857 type = "multicast"; 1858 1859 // if we're accepting all multicasts 1860 if (acceptMulticast) 1861 drop = false; 1862 1863 } else { 1864 type = "unknown"; 1865 1866 // oh well, punt on this one 1867 } 1868 1869 if (drop) { 1870 DPRINTF(Ethernet, "rxFilter drop\n"); 1871 DDUMP(EthernetData, packet->data, packet->length); 1872 } 1873 1874 return drop; 1875} 1876 1877bool 1878NSGigE::recvPacket(PacketPtr packet) 1879{ 1880 rxBytes += packet->length; 1881 rxPackets++; 1882 1883 if (rxState == rxIdle) { 1884 DPRINTF(Ethernet, "receive disabled...packet dropped\n"); 1885 interface->recvDone(); 1886 return true; 1887 } 1888 1889 if (rxFilterEnable && rxFilter(packet)) { 1890 DPRINTF(Ethernet, "packet filtered...dropped\n"); 1891 interface->recvDone(); 1892 return true; 1893 } 1894 1895 if (rxFifoCnt + packet->length >= MAX_RX_FIFO_SIZE) { 1896 DPRINTF(Ethernet, 1897 "packet will not fit in receive buffer...packet dropped\n"); 1898 devIntrPost(ISR_RXORN); 1899 return false; 1900 } 1901 1902 rxFifo.push_back(packet); 1903 rxFifoCnt += packet->length; 1904 interface->recvDone(); 1905 1906 rxKick(); 1907 return true; 1908} 1909 1910/** 1911 * does a udp checksum. if gen is true, then it generates it and puts it in the right place 1912 * else, it just checks what it calculates against the value in the header in packet 1913 */ 1914bool 1915NSGigE::udpChecksum(PacketPtr packet, bool gen) 1916{ 1917 udp_header *hdr = (udp_header *) packet->getTransportHdr(); 1918 1919 ip_header *ip = packet->getIpHdr(); 1920 1921 pseudo_header *pseudo = new pseudo_header; 1922 1923 pseudo->src_ip_addr = ip->src_ip_addr; 1924 pseudo->dest_ip_addr = ip->dest_ip_addr; 1925 pseudo->protocol = ip->protocol; 1926 pseudo->len = hdr->len; 1927 1928 uint16_t cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr, 1929 (uint32_t) hdr->len); 1930 1931 delete pseudo; 1932 if (gen) 1933 hdr->chksum = cksum; 1934 else 1935 if (cksum != 0) 1936 return false; 1937 1938 return true; 1939} 1940 1941bool 1942NSGigE::tcpChecksum(PacketPtr packet, bool gen) 1943{ 1944 tcp_header *hdr = (tcp_header *) packet->getTransportHdr(); 1945 1946 ip_header *ip = packet->getIpHdr(); 1947 1948 pseudo_header *pseudo = new pseudo_header; 1949 1950 pseudo->src_ip_addr = ip->src_ip_addr; 1951 pseudo->dest_ip_addr = ip->dest_ip_addr; 1952 pseudo->protocol = ip->protocol; 1953 pseudo->len = ip->dgram_len - (ip->vers_len & 0xf); 1954 1955 uint16_t cksum = checksumCalc((uint16_t *) pseudo, (uint16_t *) hdr, 1956 (uint32_t) pseudo->len); 1957 1958 delete pseudo; 1959 if (gen) 1960 hdr->chksum = cksum; 1961 else 1962 if (cksum != 0) 1963 return false; 1964 1965 return true; 1966} 1967 1968bool 1969NSGigE::ipChecksum(PacketPtr packet, bool gen) 1970{ 1971 ip_header *hdr = packet->getIpHdr(); 1972 1973 uint16_t cksum = checksumCalc(NULL, (uint16_t *) hdr, (hdr->vers_len & 0xf)); 1974 1975 if (gen) 1976 hdr->hdr_chksum = cksum; 1977 else 1978 if (cksum != 0) 1979 return false; 1980 1981 return true; 1982} 1983 1984uint16_t 1985NSGigE::checksumCalc(uint16_t *pseudo, uint16_t *buf, uint32_t len) 1986{ 1987 uint32_t sum = 0; 1988 1989 uint16_t last_pad = 0; 1990 if (len & 1) { 1991 last_pad = buf[len/2] & 0xff; 1992 len--; 1993 sum += last_pad; 1994 } 1995 1996 if (pseudo) { 1997 sum = pseudo[0] + pseudo[1] + pseudo[2] + 1998 pseudo[3] + pseudo[4] + pseudo[5]; 1999 } 2000 2001 for (int i=0; i < (len/2); ++i) { 2002 sum += buf[i]; 2003 } 2004 2005 while (sum >> 16) 2006 sum = (sum >> 16) + (sum & 0xffff); 2007 2008 return ~sum; 2009} 2010 2011//===================================================================== 2012// 2013// 2014void 2015NSGigE::serialize(ostream &os) 2016{ 2017 // Serialize the PciDev base class 2018 PciDev::serialize(os); 2019 2020 /* 2021 * Finalize any DMA events now. 2022 */ 2023 if (rxDmaReadEvent.scheduled()) 2024 rxDmaReadCopy(); 2025 if (rxDmaWriteEvent.scheduled()) 2026 rxDmaWriteCopy(); 2027 if (txDmaReadEvent.scheduled()) 2028 txDmaReadCopy(); 2029 if (txDmaWriteEvent.scheduled()) 2030 txDmaWriteCopy(); 2031 2032 /* 2033 * Serialize the device registers 2034 */ 2035 SERIALIZE_SCALAR(regs.command); 2036 SERIALIZE_SCALAR(regs.config); 2037 SERIALIZE_SCALAR(regs.mear); 2038 SERIALIZE_SCALAR(regs.ptscr); 2039 SERIALIZE_SCALAR(regs.isr); 2040 SERIALIZE_SCALAR(regs.imr); 2041 SERIALIZE_SCALAR(regs.ier); 2042 SERIALIZE_SCALAR(regs.ihr); 2043 SERIALIZE_SCALAR(regs.txdp); 2044 SERIALIZE_SCALAR(regs.txdp_hi); 2045 SERIALIZE_SCALAR(regs.txcfg); 2046 SERIALIZE_SCALAR(regs.gpior); 2047 SERIALIZE_SCALAR(regs.rxdp); 2048 SERIALIZE_SCALAR(regs.rxdp_hi); 2049 SERIALIZE_SCALAR(regs.rxcfg); 2050 SERIALIZE_SCALAR(regs.pqcr); 2051 SERIALIZE_SCALAR(regs.wcsr); 2052 SERIALIZE_SCALAR(regs.pcr); 2053 SERIALIZE_SCALAR(regs.rfcr); 2054 SERIALIZE_SCALAR(regs.rfdr); 2055 SERIALIZE_SCALAR(regs.srr); 2056 SERIALIZE_SCALAR(regs.mibc); 2057 SERIALIZE_SCALAR(regs.vrcr); 2058 SERIALIZE_SCALAR(regs.vtcr); 2059 SERIALIZE_SCALAR(regs.vdr); 2060 SERIALIZE_SCALAR(regs.ccsr); 2061 SERIALIZE_SCALAR(regs.tbicr); 2062 SERIALIZE_SCALAR(regs.tbisr); 2063 SERIALIZE_SCALAR(regs.tanar); 2064 SERIALIZE_SCALAR(regs.tanlpar); 2065 SERIALIZE_SCALAR(regs.taner); 2066 SERIALIZE_SCALAR(regs.tesr); 2067 2068 SERIALIZE_ARRAY(rom.perfectMatch, EADDR_LEN); 2069 2070 /* 2071 * Serialize the various helper variables 2072 */ 2073 uint32_t txPktBufPtr = (uint32_t) txPacketBufPtr; 2074 SERIALIZE_SCALAR(txPktBufPtr); 2075 uint32_t rxPktBufPtr = (uint32_t) rxPktBufPtr; 2076 SERIALIZE_SCALAR(rxPktBufPtr); 2077 SERIALIZE_SCALAR(txXferLen); 2078 SERIALIZE_SCALAR(rxXferLen); 2079 SERIALIZE_SCALAR(txPktXmitted); 2080 2081 bool txPacketExists = txPacket; 2082 SERIALIZE_SCALAR(txPacketExists); 2083 bool rxPacketExists = rxPacket; 2084 SERIALIZE_SCALAR(rxPacketExists); 2085 2086 /* 2087 * Serialize DescCaches 2088 */ 2089 SERIALIZE_SCALAR(txDescCache.link); 2090 SERIALIZE_SCALAR(txDescCache.bufptr); 2091 SERIALIZE_SCALAR(txDescCache.cmdsts); 2092 SERIALIZE_SCALAR(txDescCache.extsts); 2093 SERIALIZE_SCALAR(rxDescCache.link); 2094 SERIALIZE_SCALAR(rxDescCache.bufptr); 2095 SERIALIZE_SCALAR(rxDescCache.cmdsts); 2096 SERIALIZE_SCALAR(rxDescCache.extsts); 2097 2098 /* 2099 * Serialize tx state machine 2100 */ 2101 int txNumPkts = txFifo.size(); 2102 SERIALIZE_SCALAR(txNumPkts); 2103 int txState = this->txState; 2104 SERIALIZE_SCALAR(txState); 2105 SERIALIZE_SCALAR(CTDD); 2106 SERIALIZE_SCALAR(txFifoCnt); 2107 SERIALIZE_SCALAR(txFifoAvail); 2108 SERIALIZE_SCALAR(txHalt); 2109 SERIALIZE_SCALAR(txFragPtr); 2110 SERIALIZE_SCALAR(txDescCnt); 2111 int txDmaState = this->txDmaState; 2112 SERIALIZE_SCALAR(txDmaState); 2113 2114 /* 2115 * Serialize rx state machine 2116 */ 2117 int rxNumPkts = rxFifo.size(); 2118 SERIALIZE_SCALAR(rxNumPkts); 2119 int rxState = this->rxState; 2120 SERIALIZE_SCALAR(rxState); 2121 SERIALIZE_SCALAR(CRDD); 2122 SERIALIZE_SCALAR(rxPktBytes); 2123 SERIALIZE_SCALAR(rxFifoCnt); 2124 SERIALIZE_SCALAR(rxHalt); 2125 SERIALIZE_SCALAR(rxDescCnt); 2126 int rxDmaState = this->rxDmaState; 2127 SERIALIZE_SCALAR(rxDmaState); 2128 2129 SERIALIZE_SCALAR(extstsEnable); 2130 2131 /* 2132 * If there's a pending transmit, store the time so we can 2133 * reschedule it later 2134 */ 2135 Tick transmitTick = txEvent.scheduled() ? txEvent.when() - curTick : 0; 2136 SERIALIZE_SCALAR(transmitTick); 2137 2138 /* 2139 * Keep track of pending interrupt status. 2140 */ 2141 SERIALIZE_SCALAR(intrTick); 2142 SERIALIZE_SCALAR(cpuPendingIntr); 2143 Tick intrEventTick = 0; 2144 if (intrEvent) 2145 intrEventTick = intrEvent->when(); 2146 SERIALIZE_SCALAR(intrEventTick); 2147 2148 int i = 0; 2149 for (pktiter_t p = rxFifo.begin(); p != rxFifo.end(); ++p) { 2150 nameOut(os, csprintf("%s.rxFifo%d", name(), i++)); 2151 (*p)->serialize(os); 2152 } 2153 if (rxPacketExists) { 2154 nameOut(os, csprintf("%s.rxPacket", name())); 2155 rxPacket->serialize(os); 2156 } 2157 i = 0; 2158 for (pktiter_t p = txFifo.begin(); p != txFifo.end(); ++p) { 2159 nameOut(os, csprintf("%s.txFifo%d", name(), i++)); 2160 (*p)->serialize(os); 2161 } 2162 if (txPacketExists) { 2163 nameOut(os, csprintf("%s.txPacket", name())); 2164 txPacket->serialize(os); 2165 } 2166} 2167 2168void 2169NSGigE::unserialize(Checkpoint *cp, const std::string §ion) 2170{ 2171 // Unserialize the PciDev base class 2172 PciDev::unserialize(cp, section); 2173 2174 UNSERIALIZE_SCALAR(regs.command); 2175 UNSERIALIZE_SCALAR(regs.config); 2176 UNSERIALIZE_SCALAR(regs.mear); 2177 UNSERIALIZE_SCALAR(regs.ptscr); 2178 UNSERIALIZE_SCALAR(regs.isr); 2179 UNSERIALIZE_SCALAR(regs.imr); 2180 UNSERIALIZE_SCALAR(regs.ier); 2181 UNSERIALIZE_SCALAR(regs.ihr); 2182 UNSERIALIZE_SCALAR(regs.txdp); 2183 UNSERIALIZE_SCALAR(regs.txdp_hi); 2184 UNSERIALIZE_SCALAR(regs.txcfg); 2185 UNSERIALIZE_SCALAR(regs.gpior); 2186 UNSERIALIZE_SCALAR(regs.rxdp); 2187 UNSERIALIZE_SCALAR(regs.rxdp_hi); 2188 UNSERIALIZE_SCALAR(regs.rxcfg); 2189 UNSERIALIZE_SCALAR(regs.pqcr); 2190 UNSERIALIZE_SCALAR(regs.wcsr); 2191 UNSERIALIZE_SCALAR(regs.pcr); 2192 UNSERIALIZE_SCALAR(regs.rfcr); 2193 UNSERIALIZE_SCALAR(regs.rfdr); 2194 UNSERIALIZE_SCALAR(regs.srr); 2195 UNSERIALIZE_SCALAR(regs.mibc); 2196 UNSERIALIZE_SCALAR(regs.vrcr); 2197 UNSERIALIZE_SCALAR(regs.vtcr); 2198 UNSERIALIZE_SCALAR(regs.vdr); 2199 UNSERIALIZE_SCALAR(regs.ccsr); 2200 UNSERIALIZE_SCALAR(regs.tbicr); 2201 UNSERIALIZE_SCALAR(regs.tbisr); 2202 UNSERIALIZE_SCALAR(regs.tanar); 2203 UNSERIALIZE_SCALAR(regs.tanlpar); 2204 UNSERIALIZE_SCALAR(regs.taner); 2205 UNSERIALIZE_SCALAR(regs.tesr); 2206 2207 UNSERIALIZE_ARRAY(rom.perfectMatch, EADDR_LEN); 2208 2209 /* 2210 * unserialize the various helper variables 2211 */ 2212 uint32_t txPktBufPtr; 2213 UNSERIALIZE_SCALAR(txPktBufPtr); 2214 txPacketBufPtr = (uint8_t *) txPktBufPtr; 2215 uint32_t rxPktBufPtr; 2216 UNSERIALIZE_SCALAR(rxPktBufPtr); 2217 rxPacketBufPtr = (uint8_t *) rxPktBufPtr; 2218 UNSERIALIZE_SCALAR(txXferLen); 2219 UNSERIALIZE_SCALAR(rxXferLen); 2220 UNSERIALIZE_SCALAR(txPktXmitted); 2221 2222 bool txPacketExists; 2223 UNSERIALIZE_SCALAR(txPacketExists); 2224 bool rxPacketExists; 2225 UNSERIALIZE_SCALAR(rxPacketExists); 2226 2227 /* 2228 * Unserialize DescCaches 2229 */ 2230 UNSERIALIZE_SCALAR(txDescCache.link); 2231 UNSERIALIZE_SCALAR(txDescCache.bufptr); 2232 UNSERIALIZE_SCALAR(txDescCache.cmdsts); 2233 UNSERIALIZE_SCALAR(txDescCache.extsts); 2234 UNSERIALIZE_SCALAR(rxDescCache.link); 2235 UNSERIALIZE_SCALAR(rxDescCache.bufptr); 2236 UNSERIALIZE_SCALAR(rxDescCache.cmdsts); 2237 UNSERIALIZE_SCALAR(rxDescCache.extsts); 2238 2239 /* 2240 * unserialize tx state machine 2241 */ 2242 int txNumPkts; 2243 UNSERIALIZE_SCALAR(txNumPkts); 2244 int txState; 2245 UNSERIALIZE_SCALAR(txState); 2246 this->txState = (TxState) txState; 2247 UNSERIALIZE_SCALAR(CTDD); 2248 UNSERIALIZE_SCALAR(txFifoCnt); 2249 UNSERIALIZE_SCALAR(txFifoAvail); 2250 UNSERIALIZE_SCALAR(txHalt); 2251 UNSERIALIZE_SCALAR(txFragPtr); 2252 UNSERIALIZE_SCALAR(txDescCnt); 2253 int txDmaState; 2254 UNSERIALIZE_SCALAR(txDmaState); 2255 this->txDmaState = (DmaState) txDmaState; 2256 2257 /* 2258 * unserialize rx state machine 2259 */ 2260 int rxNumPkts; 2261 UNSERIALIZE_SCALAR(rxNumPkts); 2262 int rxState; 2263 UNSERIALIZE_SCALAR(rxState); 2264 this->rxState = (RxState) rxState; 2265 UNSERIALIZE_SCALAR(CRDD); 2266 UNSERIALIZE_SCALAR(rxPktBytes); 2267 UNSERIALIZE_SCALAR(rxFifoCnt); 2268 UNSERIALIZE_SCALAR(rxHalt); 2269 UNSERIALIZE_SCALAR(rxDescCnt); 2270 int rxDmaState; 2271 UNSERIALIZE_SCALAR(rxDmaState); 2272 this->rxDmaState = (DmaState) rxDmaState; 2273 2274 UNSERIALIZE_SCALAR(extstsEnable); 2275 2276 /* 2277 * If there's a pending transmit, store the time so we can 2278 * reschedule it later 2279 */ 2280 Tick transmitTick; 2281 UNSERIALIZE_SCALAR(transmitTick); 2282 if (transmitTick) 2283 txEvent.schedule(curTick + transmitTick); 2284 2285 /* 2286 * Keep track of pending interrupt status. 2287 */ 2288 UNSERIALIZE_SCALAR(intrTick); 2289 UNSERIALIZE_SCALAR(cpuPendingIntr); 2290 Tick intrEventTick; 2291 UNSERIALIZE_SCALAR(intrEventTick); 2292 if (intrEventTick) { 2293 intrEvent = new IntrEvent(this, true); 2294 intrEvent->schedule(intrEventTick); 2295 } 2296 2297 for (int i = 0; i < rxNumPkts; ++i) { 2298 PacketPtr p = new EtherPacket; 2299 p->unserialize(cp, csprintf("%s.rxFifo%d", section, i)); 2300 rxFifo.push_back(p); 2301 } 2302 rxPacket = NULL; 2303 if (rxPacketExists) { 2304 rxPacket = new EtherPacket; 2305 rxPacket->unserialize(cp, csprintf("%s.rxPacket", section)); 2306 } 2307 for (int i = 0; i < txNumPkts; ++i) { 2308 PacketPtr p = new EtherPacket; 2309 p->unserialize(cp, csprintf("%s.rxFifo%d", section, i)); 2310 txFifo.push_back(p); 2311 } 2312 if (txPacketExists) { 2313 txPacket = new EtherPacket; 2314 txPacket->unserialize(cp, csprintf("%s.txPacket", section)); 2315 } 2316} 2317 2318 2319Tick 2320NSGigE::cacheAccess(MemReqPtr &req) 2321{ 2322 DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", 2323 req->paddr, req->paddr - addr); 2324 return curTick + pioLatency; 2325} 2326//===================================================================== 2327 2328 2329BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt) 2330 2331 SimObjectParam<EtherInt *> peer; 2332 SimObjectParam<NSGigE *> device; 2333 2334END_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt) 2335 2336BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigEInt) 2337 2338 INIT_PARAM_DFLT(peer, "peer interface", NULL), 2339 INIT_PARAM(device, "Ethernet device of this interface") 2340 2341END_INIT_SIM_OBJECT_PARAMS(NSGigEInt) 2342 2343CREATE_SIM_OBJECT(NSGigEInt) 2344{ 2345 NSGigEInt *dev_int = new NSGigEInt(getInstanceName(), device); 2346 2347 EtherInt *p = (EtherInt *)peer; 2348 if (p) { 2349 dev_int->setPeer(p); 2350 p->setPeer(dev_int); 2351 } 2352 2353 return dev_int; 2354} 2355 2356REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt) 2357 2358 2359BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) 2360 2361 Param<Tick> tx_delay; 2362 Param<Tick> rx_delay; 2363 SimObjectParam<IntrControl *> intr_ctrl; 2364 Param<Tick> intr_delay; 2365 SimObjectParam<MemoryController *> mmu; 2366 SimObjectParam<PhysicalMemory *> physmem; 2367 Param<bool> rx_filter; 2368 Param<string> hardware_address; 2369 SimObjectParam<Bus*> header_bus; 2370 SimObjectParam<Bus*> payload_bus; 2371 SimObjectParam<HierParams *> hier; 2372 Param<Tick> pio_latency; 2373 Param<bool> dma_desc_free; 2374 Param<bool> dma_data_free; 2375 Param<Tick> dma_read_delay; 2376 Param<Tick> dma_write_delay; 2377 Param<Tick> dma_read_factor; 2378 Param<Tick> dma_write_factor; 2379 SimObjectParam<PciConfigAll *> configspace; 2380 SimObjectParam<PciConfigData *> configdata; 2381 SimObjectParam<Tsunami *> tsunami; 2382 Param<uint32_t> pci_bus; 2383 Param<uint32_t> pci_dev; 2384 Param<uint32_t> pci_func; 2385 2386END_DECLARE_SIM_OBJECT_PARAMS(NSGigE) 2387 2388BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) 2389 2390 INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000), 2391 INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000), 2392 INIT_PARAM(intr_ctrl, "Interrupt Controller"), 2393 INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0), 2394 INIT_PARAM(mmu, "Memory Controller"), 2395 INIT_PARAM(physmem, "Physical Memory"), 2396 INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true), 2397 INIT_PARAM_DFLT(hardware_address, "Ethernet Hardware Address", 2398 "00:99:00:00:00:01"), 2399 INIT_PARAM_DFLT(header_bus, "The IO Bus to attach to for headers", NULL), 2400 INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL), 2401 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), 2402 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), 2403 INIT_PARAM_DFLT(dma_desc_free, "DMA of Descriptors is free", false), 2404 INIT_PARAM_DFLT(dma_data_free, "DMA of Data is free", false), 2405 INIT_PARAM_DFLT(dma_read_delay, "fixed delay for dma reads", 0), 2406 INIT_PARAM_DFLT(dma_write_delay, "fixed delay for dma writes", 0), 2407 INIT_PARAM_DFLT(dma_read_factor, "multiplier for dma reads", 0), 2408 INIT_PARAM_DFLT(dma_write_factor, "multiplier for dma writes", 0), 2409 INIT_PARAM(configspace, "PCI Configspace"), 2410 INIT_PARAM(configdata, "PCI Config data"), 2411 INIT_PARAM(tsunami, "Tsunami"), 2412 INIT_PARAM(pci_bus, "PCI bus"), 2413 INIT_PARAM(pci_dev, "PCI device number"), 2414 INIT_PARAM(pci_func, "PCI function code") 2415 2416END_INIT_SIM_OBJECT_PARAMS(NSGigE) 2417 2418 2419CREATE_SIM_OBJECT(NSGigE) 2420{ 2421 int eaddr[6]; 2422 sscanf(((string)hardware_address).c_str(), "%x:%x:%x:%x:%x:%x", 2423 &eaddr[0], &eaddr[1], &eaddr[2], &eaddr[3], &eaddr[4], &eaddr[5]); 2424 2425 return new NSGigE(getInstanceName(), intr_ctrl, intr_delay, 2426 physmem, tx_delay, rx_delay, mmu, hier, header_bus, 2427 payload_bus, pio_latency, dma_desc_free, dma_data_free, 2428 dma_read_delay, dma_write_delay, dma_read_factor, 2429 dma_write_factor, configspace, configdata, 2430 tsunami, pci_bus, pci_dev, pci_func, rx_filter, eaddr); 2431} 2432 2433REGISTER_SIM_OBJECT("NSGigE", NSGigE) 2434