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