- Timestamp:
- Aug 26, 2021 9:23:46 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Security/DevTpm.cpp
r90587 r90903 64 64 #define TPM_FIFO_LOCALITY_REG_ACCESS 0x00 65 65 /** Indicates whether a dynamic OS has been established on this platform before.. */ 66 # define TPM_FIFO_LOCALITY_REG_ ESTABLISHMENTRT_BIT(0)66 # define TPM_FIFO_LOCALITY_REG_ACCESS_ESTABLISHMENT RT_BIT(0) 67 67 /** On reads indicates whether the locality requests use of the TPM (1) or not or is already active locality (0), 68 68 * writing a 1 requests the locality to be granted getting the active locality.. */ 69 # define TPM_FIFO_LOCALITY_REG_ REQUEST_USERT_BIT(1)69 # define TPM_FIFO_LOCALITY_REG_ACCESS_REQUEST_USE RT_BIT(1) 70 70 /** Indicates whether another locality is requesting usage of the TPM. */ 71 # define TPM_FIFO_LOCALITY_REG_ PENDING_REQUESTRT_BIT(2)71 # define TPM_FIFO_LOCALITY_REG_ACCESS_PENDING_REQUEST RT_BIT(2) 72 72 /** Writing a 1 forces the TPM to give control to the locality if it has a higher priority. */ 73 73 # define TPM_FIFO_LOCALITY_REG_ACCESS_SEIZE RT_BIT(3) … … 183 183 /** Indicates whether the Expect and data available bits are valid. */ 184 184 # define TPM_FIFO_LOCALITY_REG_STS_VALID RT_BIT_32(7) 185 /** Sets the burst count. */ 185 186 # define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_MASK UINT32_C(0xffff00) 186 # define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SHIFT 8187 # define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SHIFT UINT32_C(8) 187 188 # define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SET(a) ((a) << TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SHIFT) 189 /** Cancels the active command. */ 190 # define TPM_FIFO_LOCALITY_REG_STS_CMD_CANCEL RT_BIT_32(24) 191 /** Reset establishment bit. */ 192 # define TPM_FIFO_LOCALITY_REG_STS_RST_ESTABLISHMENT RT_BIT_32(25) 193 /** Sets the TPM family. */ 194 # define TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_MASK UINT32_C(0x0c000000) 195 # define TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_SHIFT UINT32_C(26) 196 # define TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_SET(a) ((a) << TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_SHIFT) 197 # define TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_1_2 UINT32_C(0) 198 # define TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_2_0 UINT32_C(1) 199 188 200 189 201 /** TPM end of HASH operation signal register for locality 4. */ … … 438 450 /** The current state of the TPM. */ 439 451 DEVTPMSTATE enmState; 440 452 /** The TPM version being emulated. */ 453 TPMVERSION enmTpmVers; 454 455 /** Offset into the Command/Response buffer. */ 456 uint32_t offCmdResp; 441 457 /** Command/Response buffer. */ 442 458 uint8_t abCmdResp[TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE]; … … 522 538 PDMBOTHCBDECL(void) tpmLocIrqUpdate(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc) 523 539 { 524 if ( (pLoc->uRegIntEn & TPM_CRB_LOCALITY_REG_INT_GLOBAL_ENABLE) 540 if ( (pLoc->uRegIntEn & TPM_CRB_LOCALITY_REG_INT_GLOBAL_ENABLE) /* Aliases with TPM_FIFO_LOCALITY_REG_INT_ENABLE_GLOBAL */ 525 541 && (pLoc->uRegIntEn & pLoc->uRegIntSts)) 526 542 tpmIrqReq(pDevIns, pThis, 1); … … 597 613 * @param uReg The register offset being accessed. 598 614 * @param pu64 Where to store the read data. 615 * @param cb Number of bytes to read. 599 616 */ 600 617 static VBOXSTRICTRC tpmMmioFifoRead(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc, 601 uint8_t bLoc, uint32_t uReg, uint64_t *pu64 )602 { 603 RT_NOREF(pDevIns , pThis, pLoc, bLoc, uReg, pu64);618 uint8_t bLoc, uint32_t uReg, uint64_t *pu64, size_t cb) 619 { 620 RT_NOREF(pDevIns); 604 621 VBOXSTRICTRC rc = VINF_SUCCESS; 605 622 606 #if 0 623 /* Special path for the data buffer. */ 624 if ( ( ( uReg >= TPM_FIFO_LOCALITY_REG_DATA_FIFO 625 && uReg < TPM_FIFO_LOCALITY_REG_DATA_FIFO + sizeof(uint32_t)) 626 || ( uReg >= TPM_FIFO_LOCALITY_REG_XDATA_FIFO 627 && uReg < TPM_FIFO_LOCALITY_REG_XDATA_FIFO + sizeof(uint32_t))) 628 && bLoc == pThis->bLoc 629 && pThis->enmState == DEVTPMSTATE_CMD_COMPLETION) 630 { 631 if (pThis->offCmdResp <= sizeof(pThis->abCmdResp) - cb) 632 { 633 memcpy(pu64, &pThis->abCmdResp[pThis->offCmdResp], cb); 634 pThis->offCmdResp += cb; 635 } 636 else 637 memset(pu64, 0xff, cb); 638 return VINF_SUCCESS; 639 } 640 607 641 uint64_t u64; 608 642 switch (uReg) 609 643 { 610 644 case TPM_FIFO_LOCALITY_REG_ACCESS: 611 u64 = 0; 645 u64 = TPM_FIFO_LOCALITY_REG_ACCESS_VALID; 646 if (pThis->bLoc == bLoc) 647 u64 |= TPM_FIFO_LOCALITY_REG_ACCESS_ACTIVE; 648 if (pThis->bmLocSeizedAcc & RT_BIT_32(bLoc)) 649 u64 |= TPM_FIFO_LOCALITY_REG_ACCESS_BEEN_SEIZED; 650 if (pThis->bmLocReqAcc & ~RT_BIT_32(bLoc)) 651 u64 |= TPM_FIFO_LOCALITY_REG_ACCESS_PENDING_REQUEST; 652 if ( pThis->bLoc != bLoc 653 && pThis->bmLocReqAcc & RT_BIT_32(bLoc)) 654 u64 |= TPM_FIFO_LOCALITY_REG_ACCESS_REQUEST_USE; 655 /** @todo Establishment bit. */ 612 656 break; 613 657 case TPM_FIFO_LOCALITY_REG_INT_ENABLE: … … 635 679 break; 636 680 } 637 /** @todo */ 638 break; 639 case TPM_FIFO_LOCALITY_REG_DATA_FIFO: 640 //case TPM_FIFO_LOCALITY_REG_DATA_XFIFO: 641 /** @todo */ 681 682 u64 = TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_SET( pThis->enmTpmVers == TPMVERSION_1_2 683 ? TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_1_2 684 : TPM_FIFO_LOCALITY_REG_STS_TPM_FAMILY_2_0) 685 | TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SET(_1K) 686 | TPM_FIFO_LOCALITY_REG_STS_VALID; 687 if (pThis->enmState == DEVTPMSTATE_READY) 688 u64 |= TPM_FIFO_LOCALITY_REG_STS_CMD_RDY; 689 else if (pThis->enmState == DEVTPMSTATE_CMD_RECEPTION) /* When in the command reception state check whether all of the command data has been received. */ 690 { 691 if ( pThis->offCmdResp < sizeof(TPMREQHDR) 692 || pThis->offCmdResp < RTTpmReqGetSz((PCTPMREQHDR)&pThis->abCmdResp[0])) 693 u64 |= TPM_FIFO_LOCALITY_REG_STS_EXPECT; 694 } 695 else if (pThis->enmState == DEVTPMSTATE_CMD_COMPLETION) /* Check whether there is more response data available. */ 696 { 697 if (pThis->offCmdResp < RTTpmRespGetSz((PCTPMRESPHDR)&pThis->abCmdResp[0])) 698 u64 |= TPM_FIFO_LOCALITY_REG_STS_DATA_AVAIL; 699 } 642 700 break; 643 701 case TPM_FIFO_LOCALITY_REG_DID_VID: … … 653 711 654 712 *pu64 = u64; 655 #endif656 713 657 714 return rc; … … 669 726 * @param uReg The register offset being accessed. 670 727 * @param u64 The value to write. 728 * @param cb Number of bytes to write. 671 729 */ 672 730 static VBOXSTRICTRC tpmMmioFifoWrite(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc, 673 uint8_t bLoc, uint32_t uReg, uint64_t u64) 674 { 675 RT_NOREF(pDevIns, pThis, pLoc, bLoc, uReg, u64); 731 uint8_t bLoc, uint32_t uReg, uint64_t u64, size_t cb) 732 { 733 RT_NOREF(pDevIns); 734 735 /* Special path for the data buffer. */ 736 if ( ( ( uReg >= TPM_FIFO_LOCALITY_REG_DATA_FIFO 737 && uReg < TPM_FIFO_LOCALITY_REG_DATA_FIFO + sizeof(uint32_t)) 738 || ( uReg >= TPM_FIFO_LOCALITY_REG_XDATA_FIFO 739 && uReg < TPM_FIFO_LOCALITY_REG_XDATA_FIFO + sizeof(uint32_t))) 740 && bLoc == pThis->bLoc 741 && ( pThis->enmState == DEVTPMSTATE_READY 742 || pThis->enmState == DEVTPMSTATE_CMD_RECEPTION)) 743 { 744 pThis->enmState = DEVTPMSTATE_CMD_RECEPTION; 745 if (pThis->offCmdResp <= sizeof(pThis->abCmdResp) - cb) 746 { 747 memcpy(&pThis->abCmdResp[pThis->offCmdResp], &u64, cb); 748 pThis->offCmdResp += cb; 749 } 750 return VINF_SUCCESS; 751 } 676 752 677 753 VBOXSTRICTRC rc = VINF_SUCCESS; 678 #if 0679 754 uint32_t u32 = (uint32_t)u64; 680 755 … … 690 765 if (!RT_IS_POWER_OF_TWO(u32)) 691 766 break; 692 /** @todo */ 767 768 /* Seize access only if this locality has a higher priority than the currently selected one. */ 769 if ( (u32 & TPM_FIFO_LOCALITY_REG_ACCESS_SEIZE) 770 && pThis->bLoc != TPM_NO_LOCALITY_SELECTED 771 && bLoc > pThis->bLoc) 772 { 773 pThis->bmLocSeizedAcc |= RT_BIT_32(pThis->bLoc); 774 /** @todo Abort command. */ 775 pThis->bLoc = bLoc; 776 } 777 778 if ( (u64 & TPM_FIFO_LOCALITY_REG_ACCESS_REQUEST_USE) 779 && !(pThis->bmLocReqAcc & RT_BIT_32(bLoc))) 780 { 781 pThis->bmLocReqAcc |= RT_BIT_32(bLoc); 782 if (pThis->bLoc == TPM_NO_LOCALITY_SELECTED) 783 { 784 pThis->bLoc = bLoc; /* Doesn't fire an interrupt. */ 785 pThis->bmLocSeizedAcc &= ~RT_BIT_32(bLoc); 786 } 787 } 788 789 if ( (u64 & TPM_FIFO_LOCALITY_REG_ACCESS_ACTIVE) 790 && (pThis->bmLocReqAcc & RT_BIT_32(bLoc))) 791 { 792 pThis->bmLocReqAcc &= ~RT_BIT_32(bLoc); 793 if (pThis->bLoc == bLoc) 794 { 795 pThis->bLoc = TPM_NO_LOCALITY_SELECTED; 796 if (pThis->bmLocReqAcc) 797 tpmLocSelectNext(pDevIns, pThis); /* Select the next locality. */ 798 } 799 } 693 800 break; 694 801 case TPM_FIFO_LOCALITY_REG_INT_ENABLE: … … 700 807 if (bLoc != pThis->bLoc) 701 808 break; 702 pLoc->uReg Sts &= ~(u32 & TPM_FIFO_LOCALITY_REG_INT_STS_WR_MASK);809 pLoc->uRegIntSts &= ~(u32 & TPM_FIFO_LOCALITY_REG_INT_STS_WR_MASK); 703 810 tpmLocIrqUpdate(pDevIns, pThis, pLoc); 704 811 break; … … 712 819 || !RT_IS_POWER_OF_TWO(u64)) 713 820 break; 714 /** @todo */ 715 break; 716 case TPM_FIFO_LOCALITY_REG_DATA_FIFO: 717 case TPM_FIFO_LOCALITY_REG_DATA_XFIFO: 718 if (bLoc != pThis->bLoc) 719 break; 720 /** @todo */ 821 822 if ( (u64 & TPM_FIFO_LOCALITY_REG_STS_CMD_RDY) 823 && ( pThis->enmState == DEVTPMSTATE_IDLE 824 || pThis->enmState == DEVTPMSTATE_CMD_COMPLETION)) 825 { 826 pThis->enmState = DEVTPMSTATE_READY; 827 pThis->offCmdResp = 0; 828 tpmLocSetIntSts(pDevIns, pThis, pLoc, TPM_FIFO_LOCALITY_REG_INT_STS_CMD_RDY); 829 } 830 831 if ( (u64 & TPM_FIFO_LOCALITY_REG_STS_TPM_GO) 832 && pThis->enmState == DEVTPMSTATE_CMD_RECEPTION) 833 { 834 pThis->enmState = DEVTPMSTATE_CMD_EXEC; 835 rc = PDMDevHlpTaskTrigger(pDevIns, pThis->hTpmCmdTask); 836 } 837 /** @todo Cancel and reset establishment. */ 721 838 break; 722 839 case TPM_FIFO_LOCALITY_REG_INT_VEC: … … 727 844 break; 728 845 } 729 #endif 846 730 847 return rc; 731 848 } … … 951 1068 /* Invalidate the command/response buffer. */ 952 1069 RT_ZERO(pThis->abCmdResp); 953 pThis->enmState = DEVTPMSTATE_IDLE; 1070 pThis->offCmdResp = 0; 1071 pThis->enmState = DEVTPMSTATE_IDLE; 954 1072 } 955 1073 break; … … 960 1078 && u32 == 0x1) 961 1079 { 962 pThis->enmState = =DEVTPMSTATE_CMD_CANCEL;1080 pThis->enmState = DEVTPMSTATE_CMD_CANCEL; 963 1081 /** @todo Cancel. */ 964 pThis->enmState = =DEVTPMSTATE_CMD_COMPLETION;1082 pThis->enmState = DEVTPMSTATE_CMD_COMPLETION; 965 1083 tpmLocSetIntSts(pDevIns, pThis, pLoc, TPM_CRB_LOCALITY_REG_INT_STS_START); 966 1084 } … … 1022 1140 rc = tpmMmioCrbRead(pDevIns, pThis, pLoc, bLoc, uReg, &u64, cb); 1023 1141 else 1024 rc = tpmMmioFifoRead(pDevIns, pThis, pLoc, bLoc, uReg, &u64 );1142 rc = tpmMmioFifoRead(pDevIns, pThis, pLoc, bLoc, uReg, &u64, cb); 1025 1143 1026 1144 LogFlowFunc((": %RGp %#x %#llx\n", off, cb, u64)); … … 1072 1190 rc = tpmMmioCrbWrite(pDevIns, pThis, pLoc, bLoc, uReg, u64, cb); 1073 1191 else 1074 rc = tpmMmioFifoWrite(pDevIns, pThis, pLoc, bLoc, uReg, u64 );1192 rc = tpmMmioFifoWrite(pDevIns, pThis, pLoc, bLoc, uReg, u64, cb); 1075 1193 1076 1194 return rc; … … 1100 1218 if (RT_SUCCESS(rc)) 1101 1219 { 1102 pThis->enmState = DEVTPMSTATE_CMD_COMPLETION; 1103 tpmLocSetIntSts(pThisCC->pDevIns, pThis, &pThis->aLoc[pThis->bLoc], TPM_CRB_LOCALITY_REG_INT_STS_START); 1220 pThis->enmState = DEVTPMSTATE_CMD_COMPLETION; 1221 pThis->offCmdResp = 0; 1222 if (pThis->fCrb) 1223 tpmLocSetIntSts(pThisCC->pDevIns, pThis, &pThis->aLoc[pThis->bLoc], TPM_CRB_LOCALITY_REG_INT_STS_START); 1224 else 1225 tpmLocSetIntSts(pThisCC->pDevIns, pThis, &pThis->aLoc[pThis->bLoc], TPM_FIFO_LOCALITY_REG_INT_STS_DATA_AVAIL | TPM_FIFO_LOCALITY_REG_INT_STS_STS_VALID); 1104 1226 } 1105 1227 else … … 1215 1337 PDEVTPM pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPM); 1216 1338 1217 pThis->enmState = DEVTPMSTATE_IDLE; 1218 pThis->bLoc = TPM_NO_LOCALITY_SELECTED; 1339 pThis->enmState = DEVTPMSTATE_IDLE; 1340 pThis->bLoc = TPM_NO_LOCALITY_SELECTED; 1341 pThis->offCmdResp = 0; 1219 1342 RT_ZERO(pThis->abCmdResp); 1220 1343 … … 1320 1443 if (RT_FAILURE(rc)) 1321 1444 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to startup the TPM")); 1445 1446 pThis->enmTpmVers = pThisCC->pDrvTpm->pfnGetVersion(pThisCC->pDrvTpm); 1447 if (pThis->enmTpmVers == TPMVERSION_UNKNOWN) 1448 return PDMDEV_SET_ERROR(pDevIns, VERR_NOT_SUPPORTED, N_("The emulated TPM version is not supported")); 1322 1449 } 1323 1450 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) … … 1355 1482 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); 1356 1483 PDEVTPM pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPM); 1357 PDEVTPMCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVTPMCC);1358 1484 1359 1485 int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, tpmMmioWrite, tpmMmioRead, NULL /*pvUser*/);
Note:
See TracChangeset
for help on using the changeset viewer.