Exemplo n.º 1
0
static int tpm2_claim_locality(void)
{
	uint8_t access;
	struct stopwatch sw;

	/*
	 * Locality is released by TPM reset.
	 *
	 * If locality is taken at this point, this could be due to the fact
	 * that the TPM is performing a long operation and has not processed
	 * reset request yet. We'll wait up to CR50_TIMEOUT_INIT_MS and see if
	 * it releases locality when reset is processed.
	 */
	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_INIT_MS);
	do {
		access = tpm2_read_access_reg();
		if (access & TPM_ACCESS_ACTIVE_LOCALITY) {
			/*
			 * Don't bombard the chip with traffic, let it keep
			 * processing the command.
			 */
			mdelay(2);
			continue;
		}

		/*
		 * Ok, the locality is free, TPM must be reset, let's claim
		 * it.
		 */

		tpm2_write_access_reg(TPM_ACCESS_REQUEST_USE);
		access = tpm2_read_access_reg();
		if (access != (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
			break;
		}

		printk(BIOS_INFO, "TPM ready after %ld ms\n",
		       stopwatch_duration_msecs(&sw));

		return 1;
	} while (!stopwatch_expired(&sw));

	printk(BIOS_ERR,
	       "Failed to claim locality 0 after %ld ms, status: %#x\n",
	       stopwatch_duration_msecs(&sw), access);

	return 0;
}
Exemplo n.º 2
0
void reset_prepare(void)
{
	struct stopwatch sw;

	/*
	 * If CSE state is something else than 'normal', it is probably in some
	 * recovery state. In this case there is no point in  waiting for it to
	 * get ready so we cross fingers and reset.
	 */
	if (!heci_cse_normal()) {
		printk(BIOS_DEBUG, "CSE is not in normal state, resetting\n");
		return;
	}

	/* Reset if CSE is ready */
	if (heci_cse_done())
		return;

	printk(BIOS_SPEW, "CSE is not yet ready, waiting\n");
	stopwatch_init_msecs_expire(&sw, CSE_WAIT_MAX_MS);
	while (!heci_cse_done()) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_SPEW, "CSE timed out. Resetting\n");
			return;
		}
		mdelay(1);
	}
	printk(BIOS_SPEW, "CSE took %lu ms\n", stopwatch_duration_msecs(&sw));
}
Exemplo n.º 3
0
/*
 * Cr50 processes reset requests asynchronously and consceivably could be busy
 * executing a long command and not reacting to the reset pulse for a while.
 *
 * This function will make sure that the AP does not proceed with boot until
 * TPM finished reset processing.
 */
static int process_reset(struct tpm_chip *chip)
{
	struct stopwatch sw;
	int rv = 0;
	uint8_t access;

	/*
	 * Locality is released by TPM reset.
	 *
	 * If locality is taken at this point, this could be due to the fact
	 * that the TPM is performing a long operation and has not processed
	 * reset request yet. We'll wait up to CR50_TIMEOUT_INIT_MS and see if
	 * it releases locality when reset is processed.
	 */
	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_INIT_MS);
	do {
		const uint8_t mask =
			TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY;

		rv = cr50_i2c_read(chip, TPM_ACCESS(0),
				   &access, sizeof(access));
		if (rv || ((access & mask) == mask)) {
			/*
			 * Don't bombard the chip with traffic, let it keep
			 * processing the command.
			 */
			mdelay(2);
			continue;
		}

		printk(BIOS_INFO, "TPM ready after %ld ms\n",
		       stopwatch_duration_msecs(&sw));

		return 0;
	} while (!stopwatch_expired(&sw));

	if (rv)
		printk(BIOS_ERR, "Failed to read TPM\n");
	else
		printk(BIOS_ERR,
			"TPM failed to reset after %ld ms, status: %#x\n",
			stopwatch_duration_msecs(&sw), access);

	return -1;
}
Exemplo n.º 4
0
/**
 * Wait for DisplayPort to be ready
 *
 * @param timeout Wait aborts after <timeout> ms.
 * @return 1: Success or 0: Timeout.
 */
int google_chromeec_wait_for_displayport(long timeout)
{
	struct stopwatch sw;

	printk(BIOS_INFO, "Waiting for DisplayPort\n");
	stopwatch_init_msecs_expire(&sw, timeout);
	while (google_chromeec_pd_get_amode(USB_SID_DISPLAYPORT) != 1) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_WARNING,
			       "DisplayPort not ready after %ldms. Abort.\n",
			       timeout);
			return 0;
		}
		mdelay(200);
	}
	printk(BIOS_INFO, "DisplayPort ready after %lu ms\n",
	       stopwatch_duration_msecs(&sw));

	return 1;
}