- Timestamp:
- Feb 5, 2013 2:43:08 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevE1000.cpp
r44542 r44546 612 612 } E1kRegIndex; 613 613 614 #define E1K_NUM_OF_32BIT_REGS MTA_IDX 614 #define E1K_NUM_OF_32BIT_REGS MTA_IDX 615 /** The number of registers with strictly increasing offset. */ 616 #define E1K_NUM_OF_BINARY_SEARCHABLE (WUPL_IDX + 1) 615 617 616 618 … … 1223 1225 STAMCOUNTER StatTxPathRegular; 1224 1226 STAMCOUNTER StatPHYAccesses; 1225 1227 STAMCOUNTER aStatRegWrites[E1K_NUM_OF_REGS]; 1228 STAMCOUNTER aStatRegReads[E1K_NUM_OF_REGS]; 1226 1229 #endif /* VBOX_WITH_STATISTICS */ 1227 1230 … … 1314 1317 * Register map table. 1315 1318 * 1316 * Override fn_read and fn_write to get register-specific behavior.1317 */ 1318 const staticstruct E1kRegMap_st1319 * Override pfnRead and pfnWrite to get register-specific behavior. 1320 */ 1321 static const struct E1kRegMap_st 1319 1322 { 1320 1323 /** Register offset in the register space. */ … … 1334 1337 /** Full name. */ 1335 1338 const char *name; 1336 } s_e1kRegMap[E1K_NUM_OF_REGS] =1339 } g_aE1kRegMap[E1K_NUM_OF_REGS] = 1337 1340 { 1338 1341 /* offset size read mask write mask read callback write callback abbrev full name */ … … 1469 1472 { 0x09800, 0x003fc, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FFVT" , "Flexible Filter Value Table" }, 1470 1473 { 0x10000, 0x10000, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "PBM" , "Packet Buffer Memory (n)" }, 1471 { 0x00040, 0x00080, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadRA , e1kRegWriteRA , "RA ", "Receive Address (64-bit) (n) (82542)" },1472 { 0x00200, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadMTA , e1kRegWriteMTA , "MTA ", "Multicast Table Array (n) (82542)" },1473 { 0x00600, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadVFTA , e1kRegWriteVFTA , "VFTA ", "VLAN Filter Table Array (n) (82542)" }1474 { 0x00040, 0x00080, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadRA , e1kRegWriteRA , "RA82542" , "Receive Address (64-bit) (n) (82542)" }, 1475 { 0x00200, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadMTA , e1kRegWriteMTA , "MTA82542", "Multicast Table Array (n) (82542)" }, 1476 { 0x00600, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadVFTA , e1kRegWriteVFTA , "VFTA82542", "VLAN Filter Table Array (n) (82542)" } 1474 1477 }; 1475 1478 … … 2844 2847 { 2845 2848 E1K_INC_ISTAT_CNT(pThis->uStatIntICS); 2846 return e1kRaiseInterrupt(pThis, VINF_IOM_R3_MMIO_WRITE, value & s_e1kRegMap[ICS_IDX].writable);2849 return e1kRaiseInterrupt(pThis, VINF_IOM_R3_MMIO_WRITE, value & g_aE1kRegMap[ICS_IDX].writable); 2847 2850 } 2848 2851 … … 5298 5301 static int e1kRegWriteMTA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t value) 5299 5302 { 5300 AssertReturn(offset - s_e1kRegMap[index].offset < sizeof(pThis->auMTA), VERR_DEV_IO_ERROR);5301 pThis->auMTA[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->auMTA[0])] = value;5303 AssertReturn(offset - g_aE1kRegMap[index].offset < sizeof(pThis->auMTA), VERR_DEV_IO_ERROR); 5304 pThis->auMTA[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->auMTA[0])] = value; 5302 5305 5303 5306 return VINF_SUCCESS; … … 5316 5319 static int e1kRegReadMTA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t *pu32Value) 5317 5320 { 5318 AssertReturn(offset - s_e1kRegMap[index].offset< sizeof(pThis->auMTA), VERR_DEV_IO_ERROR);5319 *pu32Value = pThis->auMTA[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->auMTA[0])];5321 AssertReturn(offset - g_aE1kRegMap[index].offset< sizeof(pThis->auMTA), VERR_DEV_IO_ERROR); 5322 *pu32Value = pThis->auMTA[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->auMTA[0])]; 5320 5323 5321 5324 return VINF_SUCCESS; … … 5333 5336 static int e1kRegWriteRA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t value) 5334 5337 { 5335 AssertReturn(offset - s_e1kRegMap[index].offset < sizeof(pThis->aRecAddr.au32), VERR_DEV_IO_ERROR);5336 pThis->aRecAddr.au32[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->aRecAddr.au32[0])] = value;5338 AssertReturn(offset - g_aE1kRegMap[index].offset < sizeof(pThis->aRecAddr.au32), VERR_DEV_IO_ERROR); 5339 pThis->aRecAddr.au32[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->aRecAddr.au32[0])] = value; 5337 5340 5338 5341 return VINF_SUCCESS; … … 5351 5354 static int e1kRegReadRA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t *pu32Value) 5352 5355 { 5353 AssertReturn(offset - s_e1kRegMap[index].offset< sizeof(pThis->aRecAddr.au32), VERR_DEV_IO_ERROR);5354 *pu32Value = pThis->aRecAddr.au32[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->aRecAddr.au32[0])];5356 AssertReturn(offset - g_aE1kRegMap[index].offset< sizeof(pThis->aRecAddr.au32), VERR_DEV_IO_ERROR); 5357 *pu32Value = pThis->aRecAddr.au32[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->aRecAddr.au32[0])]; 5355 5358 5356 5359 return VINF_SUCCESS; … … 5368 5371 static int e1kRegWriteVFTA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t value) 5369 5372 { 5370 AssertReturn(offset - s_e1kRegMap[index].offset < sizeof(pThis->auVFTA), VINF_SUCCESS);5371 pThis->auVFTA[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->auVFTA[0])] = value;5373 AssertReturn(offset - g_aE1kRegMap[index].offset < sizeof(pThis->auVFTA), VINF_SUCCESS); 5374 pThis->auVFTA[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->auVFTA[0])] = value; 5372 5375 5373 5376 return VINF_SUCCESS; … … 5386 5389 static int e1kRegReadVFTA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t *pu32Value) 5387 5390 { 5388 AssertReturn(offset - s_e1kRegMap[index].offset< sizeof(pThis->auVFTA), VERR_DEV_IO_ERROR);5389 *pu32Value = pThis->auVFTA[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->auVFTA[0])];5391 AssertReturn(offset - g_aE1kRegMap[index].offset< sizeof(pThis->auVFTA), VERR_DEV_IO_ERROR); 5392 *pu32Value = pThis->auVFTA[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->auVFTA[0])]; 5390 5393 5391 5394 return VINF_SUCCESS; … … 5407 5410 { 5408 5411 E1kLog(("%s At %08X read (00000000) attempt from unimplemented register %s (%s)\n", 5409 pThis->szPrf, offset, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));5412 pThis->szPrf, offset, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name)); 5410 5413 *pu32Value = 0; 5411 5414 … … 5457 5460 { 5458 5461 AssertReturn(index < E1K_NUM_OF_32BIT_REGS, VERR_DEV_IO_ERROR); 5459 *pu32Value = pThis->auRegs[index] & s_e1kRegMap[index].readable;5462 *pu32Value = pThis->auRegs[index] & g_aE1kRegMap[index].readable; 5460 5463 5461 5464 return VINF_SUCCESS; … … 5477 5480 { 5478 5481 E1kLog(("%s At %08X write attempt (%08X) to unimplemented register %s (%s)\n", 5479 pThis->szPrf, offset, value, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));5482 pThis->szPrf, offset, value, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name)); 5480 5483 5481 5484 return VINF_SUCCESS; … … 5501 5504 { 5502 5505 AssertReturn(index < E1K_NUM_OF_32BIT_REGS, VERR_DEV_IO_ERROR); 5503 pThis->auRegs[index] = (value & s_e1kRegMap[index].writable) |5504 (pThis->auRegs[index] & ~s_e1kRegMap[index].writable);5506 pThis->auRegs[index] = (value & g_aE1kRegMap[index].writable) 5507 | (pThis->auRegs[index] & ~g_aE1kRegMap[index].writable); 5505 5508 5506 5509 return VINF_SUCCESS; … … 5518 5521 static int e1kRegLookup(PE1KSTATE pThis, uint32_t offReg) 5519 5522 { 5523 #if 0 5520 5524 int index; 5521 5525 5522 5526 for (index = 0; index < E1K_NUM_OF_REGS; index++) 5523 5527 { 5524 if ( s_e1kRegMap[index].offset <= offReg && offReg < s_e1kRegMap[index].offset + s_e1kRegMap[index].size)5528 if (g_aE1kRegMap[index].offset <= offReg && offReg < g_aE1kRegMap[index].offset + g_aE1kRegMap[index].size) 5525 5529 { 5526 5530 return index; 5527 5531 } 5528 5532 } 5533 #else 5534 int iStart = 0; 5535 int iEnd = E1K_NUM_OF_BINARY_SEARCHABLE; 5536 for (;;) 5537 { 5538 int i = (iEnd - iStart) / 2 + iStart; 5539 uint32_t offCur = g_aE1kRegMap[i].offset; 5540 if (offReg < offCur) 5541 { 5542 if (i == iStart) 5543 break; 5544 iEnd = i; 5545 } 5546 else if (offReg >= offCur + g_aE1kRegMap[i].size) 5547 { 5548 i++; 5549 if (i == iEnd) 5550 break; 5551 iStart = i; 5552 } 5553 else 5554 return i; 5555 Assert(iEnd > iStart); 5556 } 5557 5558 for (unsigned i = E1K_NUM_OF_BINARY_SEARCHABLE; i < RT_ELEMENTS(g_aE1kRegMap); i++) 5559 if (offReg - g_aE1kRegMap[i].offset < g_aE1kRegMap[i].size) 5560 return i; 5561 5562 # ifdef VBOX_STRICT 5563 for (unsigned i = 0; i < RT_ELEMENTS(g_aE1kRegMap); i++) 5564 Assert(offReg - g_aE1kRegMap[i].offset >= g_aE1kRegMap[i].size); 5565 # endif 5566 5567 #endif 5529 5568 5530 5569 return -1; … … 5579 5618 if (index != -1) 5580 5619 { 5581 if ( s_e1kRegMap[index].readable)5620 if (g_aE1kRegMap[index].readable) 5582 5621 { 5583 5622 /* Make the mask correspond to the bits we are about to read. */ 5584 shift = (offReg - s_e1kRegMap[index].offset) % sizeof(uint32_t) * 8;5623 shift = (offReg - g_aE1kRegMap[index].offset) % sizeof(uint32_t) * 8; 5585 5624 mask <<= shift; 5586 5625 if (!mask) … … 5598 5637 //pThis->iStatIntLost += pThis->iStatIntLostOne; 5599 5638 //pThis->iStatIntLostOne = 0; 5600 rc = s_e1kRegMap[index].pfnRead(pThis, offReg & 0xFFFFFFFC, index, &u32);5639 rc = g_aE1kRegMap[index].pfnRead(pThis, offReg & 0xFFFFFFFC, index, &u32); 5601 5640 u32 &= mask; 5602 5641 //e1kCsLeave(pThis); 5603 5642 E1kLog2(("%s At %08X read %s from %s (%s)\n", 5604 pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf), s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));5643 pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf), g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name)); 5605 5644 /* Shift back the result. */ 5606 5645 u32 >>= shift; 5607 5646 } 5608 5647 else 5609 {5610 5648 E1kLog(("%s At %08X read (%s) attempt from write-only register %s (%s)\n", 5611 pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf), s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name)); 5612 } 5649 pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf), g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name)); 5650 if (IOM_SUCCESS(rc)) 5651 STAM_COUNTER_INC(&pThis->aStatRegReads[index]); 5613 5652 } 5614 5653 else 5615 {5616 5654 E1kLog(("%s At %08X read (%s) attempt from non-existing register\n", 5617 5655 pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf))); 5618 }5619 5656 5620 5657 memcpy(pv, &u32, cb); … … 5639 5676 int rc = VINF_SUCCESS; 5640 5677 int index = e1kRegLookup(pThis, offReg); 5641 uint32_t u32;5642 5678 5643 5679 /* … … 5659 5695 return VINF_SUCCESS; 5660 5696 } 5661 u32 = *(uint32_t*)pv; 5697 5698 uint32_t u32 = *(uint32_t const *)pv; 5662 5699 if (index != -1) 5663 5700 { 5664 if ( s_e1kRegMap[index].writable)5701 if (g_aE1kRegMap[index].writable) 5665 5702 { 5666 5703 /* … … 5669 5706 */ 5670 5707 E1kLog2(("%s At %08X write %08X to %s (%s)\n", 5671 pThis->szPrf, offReg, u32, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));5708 pThis->szPrf, offReg, u32, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name)); 5672 5709 //rc = e1kCsEnter(pThis, VERR_SEM_BUSY, RT_SRC_POS); 5673 5710 if (RT_UNLIKELY(rc != VINF_SUCCESS)) … … 5676 5713 //pThis->iStatIntLost += pThis->iStatIntLostOne; 5677 5714 //pThis->iStatIntLostOne = 0; 5678 rc = s_e1kRegMap[index].pfnWrite(pThis, offReg, index, u32);5715 rc = g_aE1kRegMap[index].pfnWrite(pThis, offReg, index, u32); 5679 5716 //e1kCsLeave(pThis); 5680 5717 } 5681 5718 else 5682 {5683 5719 E1kLog(("%s At %08X write attempt (%08X) to read-only register %s (%s)\n", 5684 pThis->szPrf, offReg, u32, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name)); 5685 } 5720 pThis->szPrf, offReg, u32, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name)); 5721 if (IOM_SUCCESS(rc)) 5722 STAM_COUNTER_INC(&pThis->aStatRegWrites[index]); 5686 5723 } 5687 5724 else 5688 {5689 5725 E1kLog(("%s At %08X write attempt (%08X) to non-existing register\n", 5690 5726 pThis->szPrf, offReg, u32)); 5691 }5692 5727 return rc; 5693 5728 } … … 5869 5904 { 5870 5905 E1kLog2(("%s %8.8s = %08x\n", pThis->szPrf, 5871 s_e1kRegMap[i].abbrev, pThis->auRegs[i]));5906 g_aE1kRegMap[i].abbrev, pThis->auRegs[i])); 5872 5907 } 5873 5908 # ifdef E1K_INT_STATS … … 6869 6904 6870 6905 for (i = 0; i < E1K_NUM_OF_32BIT_REGS; ++i) 6871 pHlp->pfnPrintf(pHlp, "%8.8s = %08x\n", s_e1kRegMap[i].abbrev, pThis->auRegs[i]);6906 pHlp->pfnPrintf(pHlp, "%8.8s = %08x\n", g_aE1kRegMap[i].abbrev, pThis->auRegs[i]); 6872 6907 6873 6908 for (i = 0; i < RT_ELEMENTS(pThis->aRecAddr.array); i++) … … 7327 7362 7328 7363 /* 7364 * Internal validations. 7365 */ 7366 for (uint32_t iReg = 1; iReg < E1K_NUM_OF_BINARY_SEARCHABLE; iReg++) 7367 AssertLogRelMsgReturn( g_aE1kRegMap[iReg].offset > g_aE1kRegMap[iReg - 1].offset 7368 && g_aE1kRegMap[iReg].offset + g_aE1kRegMap[iReg].size 7369 >= g_aE1kRegMap[iReg - 1].offset + g_aE1kRegMap[iReg - 1].size, 7370 ("%s@%#xLB%#x vs %s@%#xLB%#x\n", 7371 g_aE1kRegMap[iReg].abbrev, g_aE1kRegMap[iReg].offset, g_aE1kRegMap[iReg].size, 7372 g_aE1kRegMap[iReg - 1].abbrev, g_aE1kRegMap[iReg - 1].offset, g_aE1kRegMap[iReg - 1].size), 7373 VERR_INTERNAL_ERROR_4); 7374 7375 /* 7329 7376 * Validate configuration. 7330 7377 */ … … 7624 7671 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatTxPathRegular, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Regular descriptor path", "/Devices/E1k%d/TxPath/Normal", iInstance); 7625 7672 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatPHYAccesses, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of PHY accesses", "/Devices/E1k%d/PHYAccesses", iInstance); 7673 for (unsigned iReg = 0; iReg < E1K_NUM_OF_REGS; iReg++) 7674 { 7675 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStatRegReads[iReg], STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 7676 g_aE1kRegMap[iReg].name, "/Devices/E1k%d/Regs/%s-Reads", iInstance, g_aE1kRegMap[iReg].abbrev); 7677 PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStatRegWrites[iReg], STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, 7678 g_aE1kRegMap[iReg].name, "/Devices/E1k%d/Regs/%s-Writes", iInstance, g_aE1kRegMap[iReg].abbrev); 7679 } 7626 7680 #endif /* VBOX_WITH_STATISTICS */ 7627 7681
Note:
See TracChangeset
for help on using the changeset viewer.