VirtualBox

Changeset 90903 in vbox for trunk


Ignore:
Timestamp:
Aug 26, 2021 9:23:46 AM (3 years ago)
Author:
vboxsync
Message:

Devices/Security/DevTpm: Implement FIFO/TIS interface, bugref:10075

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Security/DevTpm.cpp

    r90587 r90903  
    6464#define TPM_FIFO_LOCALITY_REG_ACCESS                         0x00
    6565/** Indicates whether a dynamic OS has been established on this platform before.. */
    66 # define TPM_FIFO_LOCALITY_REG_ESTABLISHMENT                 RT_BIT(0)
     66# define TPM_FIFO_LOCALITY_REG_ACCESS_ESTABLISHMENT          RT_BIT(0)
    6767/** On reads indicates whether the locality requests use of the TPM (1) or not or is already active locality (0),
    6868 * writing a 1 requests the locality to be granted getting the active locality.. */
    69 # define TPM_FIFO_LOCALITY_REG_REQUEST_USE                   RT_BIT(1)
     69# define TPM_FIFO_LOCALITY_REG_ACCESS_REQUEST_USE            RT_BIT(1)
    7070/** Indicates whether another locality is requesting usage of the TPM. */
    71 # define TPM_FIFO_LOCALITY_REG_PENDING_REQUEST               RT_BIT(2)
     71# define TPM_FIFO_LOCALITY_REG_ACCESS_PENDING_REQUEST        RT_BIT(2)
    7272/** Writing a 1 forces the TPM to give control to the locality if it has a higher priority. */
    7373# define TPM_FIFO_LOCALITY_REG_ACCESS_SEIZE                  RT_BIT(3)
     
    183183/** Indicates whether the Expect and data available bits are valid. */
    184184# define TPM_FIFO_LOCALITY_REG_STS_VALID                     RT_BIT_32(7)
     185/** Sets the burst count. */
    185186# define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_MASK            UINT32_C(0xffff00)
    186 # define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SHIFT           8
     187# define TPM_FIFO_LOCALITY_REG_STS_BURST_CNT_SHIFT           UINT32_C(8)
    187188# 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
    188200
    189201/** TPM end of HASH operation signal register for locality 4. */
     
    438450    /** The current state of the TPM. */
    439451    DEVTPMSTATE                     enmState;
    440 
     452    /** The TPM version being emulated. */
     453    TPMVERSION                      enmTpmVers;
     454
     455    /** Offset into the Command/Response buffer. */
     456    uint32_t                        offCmdResp;
    441457    /** Command/Response buffer. */
    442458    uint8_t                         abCmdResp[TPM_CRB_LOCALITY_REG_DATA_BUFFER_SIZE];
     
    522538PDMBOTHCBDECL(void) tpmLocIrqUpdate(PPDMDEVINS pDevIns, PDEVTPM pThis, PDEVTPMLOCALITY pLoc)
    523539{
    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 */
    525541        && (pLoc->uRegIntEn & pLoc->uRegIntSts))
    526542        tpmIrqReq(pDevIns, pThis, 1);
     
    597613 * @param   uReg                The register offset being accessed.
    598614 * @param   pu64                Where to store the read data.
     615 * @param   cb                  Number of bytes to read.
    599616 */
    600617static 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);
    604621    VBOXSTRICTRC rc = VINF_SUCCESS;
    605622
    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
    607641    uint64_t u64;
    608642    switch (uReg)
    609643    {
    610644        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. */
    612656            break;
    613657        case TPM_FIFO_LOCALITY_REG_INT_ENABLE:
     
    635679                break;
    636680            }
    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            }
    642700            break;
    643701        case TPM_FIFO_LOCALITY_REG_DID_VID:
     
    653711
    654712    *pu64 = u64;
    655 #endif
    656713
    657714    return rc;
     
    669726 * @param   uReg                The register offset being accessed.
    670727 * @param   u64                 The value to write.
     728 * @param   cb                  Number of bytes to write.
    671729 */
    672730static 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    }
    676752
    677753    VBOXSTRICTRC rc = VINF_SUCCESS;
    678 #if 0
    679754    uint32_t u32 = (uint32_t)u64;
    680755
     
    690765            if (!RT_IS_POWER_OF_TWO(u32))
    691766                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            }
    693800            break;
    694801        case TPM_FIFO_LOCALITY_REG_INT_ENABLE:
     
    700807            if (bLoc != pThis->bLoc)
    701808                break;
    702             pLoc->uRegSts &= ~(u32 & TPM_FIFO_LOCALITY_REG_INT_STS_WR_MASK);
     809            pLoc->uRegIntSts &= ~(u32 & TPM_FIFO_LOCALITY_REG_INT_STS_WR_MASK);
    703810            tpmLocIrqUpdate(pDevIns, pThis, pLoc);
    704811            break;
     
    712819                || !RT_IS_POWER_OF_TWO(u64))
    713820                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. */
    721838            break;
    722839        case TPM_FIFO_LOCALITY_REG_INT_VEC:
     
    727844            break;
    728845    }
    729 #endif
     846
    730847    return rc;
    731848}
     
    9511068                /* Invalidate the command/response buffer. */
    9521069                RT_ZERO(pThis->abCmdResp);
    953                 pThis->enmState = DEVTPMSTATE_IDLE;
     1070                pThis->offCmdResp = 0;
     1071                pThis->enmState   = DEVTPMSTATE_IDLE;
    9541072            }
    9551073            break;
     
    9601078                && u32 == 0x1)
    9611079            {
    962                 pThis->enmState == DEVTPMSTATE_CMD_CANCEL;
     1080                pThis->enmState = DEVTPMSTATE_CMD_CANCEL;
    9631081                /** @todo Cancel. */
    964                 pThis->enmState == DEVTPMSTATE_CMD_COMPLETION;
     1082                pThis->enmState = DEVTPMSTATE_CMD_COMPLETION;
    9651083                tpmLocSetIntSts(pDevIns, pThis, pLoc, TPM_CRB_LOCALITY_REG_INT_STS_START);
    9661084            }
     
    10221140        rc = tpmMmioCrbRead(pDevIns, pThis, pLoc, bLoc, uReg, &u64, cb);
    10231141    else
    1024         rc = tpmMmioFifoRead(pDevIns, pThis, pLoc, bLoc, uReg, &u64);
     1142        rc = tpmMmioFifoRead(pDevIns, pThis, pLoc, bLoc, uReg, &u64, cb);
    10251143
    10261144    LogFlowFunc((": %RGp %#x %#llx\n", off, cb, u64));
     
    10721190        rc = tpmMmioCrbWrite(pDevIns, pThis, pLoc, bLoc, uReg, u64, cb);
    10731191    else
    1074         rc = tpmMmioFifoWrite(pDevIns, pThis, pLoc, bLoc, uReg, u64);
     1192        rc = tpmMmioFifoWrite(pDevIns, pThis, pLoc, bLoc, uReg, u64, cb);
    10751193
    10761194    return rc;
     
    11001218        if (RT_SUCCESS(rc))
    11011219        {
    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);
    11041226        }
    11051227        else
     
    12151337    PDEVTPM pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
    12161338
    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;
    12191342    RT_ZERO(pThis->abCmdResp);
    12201343
     
    13201443        if (RT_FAILURE(rc))
    13211444            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"));
    13221449    }
    13231450    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
     
    13551482    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
    13561483    PDEVTPM   pThis   = PDMDEVINS_2_DATA(pDevIns, PDEVTPM);
    1357     PDEVTPMCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVTPMCC);
    13581484
    13591485    int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, tpmMmioWrite, tpmMmioRead, NULL /*pvUser*/);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette