/* prepare aborting current command */ static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty) { TPMTISEmuState *tis = &s->s.tis; uint8_t busy_locty; tis->aborting_locty = locty; tis->next_locty = newlocty; /* locality after successful abort */ /* * only abort a command using an interrupt if currently executing * a command AND if there's a valid connection to the vTPM. */ for (busy_locty = 0; busy_locty < TPM_TIS_NUM_LOCALITIES; busy_locty++) { if (tis->loc[busy_locty].state == TPM_TIS_STATE_EXECUTION) { /* * request the backend to cancel. Some backends may not * support it */ tpm_backend_cancel_cmd(s->be_driver); return; } } tpm_tis_abort(s, locty); }
static void tpm_tis_receive_bh(void *opaque) { TPMState *s = opaque; TPMTISEmuState *tis = &s->s.tis; uint8_t locty = s->locty_number; tis->loc[locty].sts = TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE; tis->loc[locty].state = TPM_TIS_STATE_COMPLETION; tis->loc[locty].r_offset = 0; tis->loc[locty].w_offset = 0; if (TPM_TIS_IS_VALID_LOCTY(tis->next_locty)) { tpm_tis_abort(s, locty); } #ifndef RAISE_STS_IRQ tpm_tis_raise_irq(s, locty, TPM_TIS_INT_DATA_AVAILABLE); #else tpm_tis_raise_irq(s, locty, TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID); #endif }