Beispiel #1
0
/*
 * Print out the contents of a buffer, if debug is enabled. Skip registers
 * other than FIFO, unless debug_level_ is 2.
 */
static void trace_dump(const char *prefix, uint32_t reg,
		       size_t bytes, const uint8_t *buffer,
		       int force)
{
	static char prev_prefix CAR_GLOBAL;
	static unsigned prev_reg CAR_GLOBAL;
	static int current_char CAR_GLOBAL;
	const int BYTES_PER_LINE = 32;
	int *current_char_ptr = car_get_var_ptr(&current_char);

	if (!force) {
		if (!debug_level_)
			return;

		if ((debug_level_ < 2) && (reg != TPM_DATA_FIFO_REG))
			return;
	}

	/*
	 * Do not print register address again if the last dump print was for
	 * that register.
	 */
	if ((car_get_var(prev_prefix) != *prefix) ||
		(car_get_var(prev_reg) != reg)) {
		car_set_var(prev_prefix, *prefix);
		car_set_var(prev_reg, reg);
		printk(BIOS_DEBUG, "\n%s %2.2x:", prefix, reg);
		*current_char_ptr = 0;
	}

	if ((reg != TPM_DATA_FIFO_REG) && (bytes == 4)) {
		/*
		 * This must be a regular register address, print the 32 bit
		 * value.
		 */
		printk(BIOS_DEBUG, " %8.8x", *(const uint32_t *)buffer);
	} else {
		int i;

		/*
		 * Data read from or written to FIFO or not in 4 byte
		 * quantiites is printed byte at a time.
		 */
		for (i = 0; i < bytes; i++) {
			if (*current_char_ptr &&
				!(*current_char_ptr % BYTES_PER_LINE)) {
				printk(BIOS_DEBUG, "\n     ");
				*current_char_ptr = 0;
			}
			(*current_char_ptr)++;
			printk(BIOS_DEBUG, " %2.2x", buffer[i]);
		}
	}
}
Beispiel #2
0
int tis_open(void)
{
	if (car_get_var(tpm_is_open)) {
		printk(BIOS_ERR, "tis_open() called twice.\n");
		return -1;
	}
	return 0;
}
Beispiel #3
0
static inline int get_log_level(void)
{
	if (car_get_var(console_inited) == 0)
		return -1;
	if (CONSOLE_LEVEL_CONST)
		return get_console_loglevel();

	return console_loglevel;
}
const struct spi_flash *boot_device_spi_flash(void)
{
	boot_device_rw_init();

	if (car_get_var(sfg_init_done) != true)
		return NULL;

	return car_get_var_ptr(&sfg);
}
const struct region_device *boot_device_rw(void)
{
	/* Probe for the SPI flash device if not already done. */
	boot_device_rw_init();

	if (car_get_var(sfg) == NULL)
		return NULL;

	return &spi_rw;
}
Beispiel #6
0
__weak int tis_plat_irq_status(void)
{
	static int warning_displayed CAR_GLOBAL;

	if (!car_get_var(warning_displayed)) {
		printk(BIOS_WARNING, "WARNING: tis_plat_irq_status() not implemented, wasting 10ms to wait on Cr50!\n");
		car_set_var(warning_displayed, 1);
	}
	mdelay(10);

	return 1;
}
static ssize_t spi_eraseat(const struct region_device *rd,
				size_t offset, size_t size)
{
	struct spi_flash *sf = car_get_var(sfg);

	if (sf == NULL)
		return -1;

	if (spi_flash_erase(sf, offset, size))
		return -1;

	return size;
}
static void boot_device_rw_init(void)
{
	const int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS;
	const int cs = 0;

	if (car_get_var(sfg) != NULL)
		return;

	/* Ensure any necessary setup is performed by the drivers. */
	spi_init();

	car_set_var(sfg, spi_flash_probe(bus, cs));
}
Beispiel #9
0
int tis_close(void)
{
	if (car_get_var(tpm_is_open)) {

		/*
		 * Do we need to do something here, like waiting for a
		 * transaction to stop?
		 */
		car_set_var(tpm_is_open, 0);
	}

	return 0;
}
static ssize_t spi_writeat(const struct region_device *rd, const void *b,
				size_t offset, size_t size)
{
	struct spi_flash *sf = car_get_var(sfg);

	if (sf == NULL)
		return -1;

	if (spi_flash_write(sf, offset, size, b))
		return -1;

	return size;
}
static void boot_device_rw_init(void)
{
	const int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS;
	const int cs = 0;

	if (car_get_var(sfg_init_done) == true)
		return;

	/* Ensure any necessary setup is performed by the drivers. */
	spi_init();

	if (!spi_flash_probe(bus, cs, car_get_var_ptr(&sfg)))
		car_set_var(sfg_init_done, true);
}
Beispiel #12
0
static int vboot_logic_executed(void)
{
    /* If this stage is supposed to run the vboot logic ensure it has been
     * executed. */
    if (verification_should_run() && car_get_var(vboot_executed))
        return 1;

    /* If this stage is supposed to load verstage and verstage is returning
     * back to the calling stage check that it has been executed. */
    if (verstage_should_load() && IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE))
        if (car_get_var(vboot_executed))
            return 1;

    /* Handle all other stages post vboot execution. */
    if (!ENV_BOOTBLOCK) {
        if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
            return 1;
        if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE) &&
                !ENV_ROMSTAGE)
            return 1;
    }

    return 0;
}
Beispiel #13
0
int vb2_logic_executed(void)
{
	/* If we are in a stage that would load the verstage or execute the
	   vboot logic directly, we store the answer in a global. */
	if (verstage_should_load() || verification_should_run())
		return car_get_var(vboot_executed);

	if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK)) {
		/* All other stages are "after the bootblock" */
		return !ENV_BOOTBLOCK;
	} else if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)) {
		/* Post-RAM stages are "after the romstage" */
#ifdef __PRE_RAM__
		return 0;
#else
		return 1;
#endif
	} else {
		die("impossible!");
	}
}
Beispiel #14
0
int tpm_marshal_command(TPM_CC command, void *tpm_command_body, struct obuf *ob)
{
	struct obuf ob_hdr;
	const size_t hdr_sz = sizeof(uint16_t) + 2 * sizeof(uint32_t);
	int rc = 0;

	car_set_var(tpm_tag, TPM_ST_NO_SESSIONS);

	if (obuf_splice_current(ob, &ob_hdr, hdr_sz) < 0)
		return -1;

	/* Write TPM command header with placeholder field values. */
	rc |= obuf_write_be16(ob, 0);
	rc |= obuf_write_be32(ob, 0);
	rc |= obuf_write_be32(ob, command);

	if (rc != 0)
		return rc;

	switch (command) {
	case TPM2_Startup:
		rc |= marshal_startup(ob, tpm_command_body);
		break;

	case TPM2_Shutdown:
		rc |= marshal_shutdown(ob, tpm_command_body);
		break;

	case TPM2_GetCapability:
		rc |= marshal_get_capability(ob, tpm_command_body);
		break;

	case TPM2_NV_Read:
		rc |= marshal_nv_read(ob, tpm_command_body);
		break;

	case TPM2_NV_DefineSpace:
		rc |= marshal_nv_define_space(ob, tpm_command_body);
		break;

	case TPM2_NV_Write:
		rc |= marshal_nv_write(ob, tpm_command_body);
		break;

	case TPM2_NV_WriteLock:
		rc |= marshal_nv_write_lock(ob, tpm_command_body);
		break;

	case TPM2_SelfTest:
		rc |= marshal_selftest(ob, tpm_command_body);
		break;

	case TPM2_Hierarchy_Control:
		rc |= marshal_hierarchy_control(ob, tpm_command_body);
		break;

	case TPM2_Clear:
		rc |= marshal_clear(ob);
		break;

	case TPM2_PCR_Extend:
		rc |= marshal_pcr_extend(ob, tpm_command_body);
		break;

	case TPM2_CR50_VENDOR_COMMAND:
		rc |= marshal_cr50_vendor_command(ob, tpm_command_body);
		break;

	default:
		printk(BIOS_INFO, "%s:%d:Request to marshal unsupported command %#x\n",
		       __FILE__, __LINE__, command);
		rc = -1;
	}

	if (rc != 0)
		return rc;

	/* Fix up the command header with known values. */
	rc |= obuf_write_be16(&ob_hdr, car_get_var(tpm_tag));
	rc |= obuf_write_be32(&ob_hdr, obuf_nr_written(ob));

	return rc;
}
Beispiel #15
0
void init_timer(void)
{
	if (!car_get_var(clocks_per_usec))
		car_set_var(clocks_per_usec, calibrate_tsc());
}
Beispiel #16
0
static int oxpcie_uart_active(void)
{
	return (car_get_var(oxpcie_present));
}
Beispiel #17
0
static inline u32 get_timer_fsb(void)
{
	return car_get_var(g_timer_fsb);
}
Beispiel #18
0
static inline unsigned long get_clocks_per_usec(void)
{
	init_timer();
	return car_get_var(clocks_per_usec);
}
Beispiel #19
0
void tpm2_get_info(struct tpm2_info *info)
{
	*info = car_get_var(g_tpm_info);
}
Beispiel #20
0
/*
 * Each TPM2 SPI transaction starts the same: CS is asserted, the 4 byte
 * header is sent to the TPM, the master waits til TPM is ready to continue.
 *
 * Returns 1 on success, 0 on failure (TPM SPI flow control timeout.)
 */
static int start_transaction(int read_write, size_t bytes, unsigned addr)
{
	spi_frame_header header;
	uint8_t byte;
	int i;
	struct stopwatch sw;
	static int tpm_sync_needed CAR_GLOBAL;
	static struct stopwatch wake_up_sw CAR_GLOBAL;
	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
	/*
	 * First Cr50 access in each coreboot stage where TPM is used will be
	 * prepended by a wake up pulse on the CS line.
	 */
	int wakeup_needed = 1;

	/* Wait for TPM to finish previous transaction if needed */
	if (car_get_var(tpm_sync_needed)) {
		tpm_sync();
		/*
		 * During the first invocation of this function on each stage
		 * this if () clause code does not run (as tpm_sync_needed
		 * value is zero), during all following invocations the
		 * stopwatch below is guaranteed to be started.
		 */
		if (!stopwatch_expired(car_get_var_ptr(&wake_up_sw)))
			wakeup_needed = 0;
	} else {
		car_set_var(tpm_sync_needed, 1);
	}

	if (wakeup_needed) {
		/* Just in case Cr50 is asleep. */
		spi_claim_bus(spi_slave);
		udelay(1);
		spi_release_bus(spi_slave);
		udelay(100);
	}

	/*
	 * The Cr50 on H1 does not go to sleep for 1 second after any
	 * SPI slave activity, let's be conservative and limit the
	 * window to 900 ms.
	 */
	stopwatch_init_msecs_expire(car_get_var_ptr(&wake_up_sw), 900);

	/*
	 * The first byte of the frame header encodes the transaction type
	 * (read or write) and transfer size (set to lentgh - 1), limited to
	 * 64 bytes.
	 */
	header.body[0] = (read_write ? 0x80 : 0) | 0x40 | (bytes - 1);

	/* The rest of the frame header is the TPM register address. */
	for (i = 0; i < 3; i++)
		header.body[i + 1] = (addr >> (8 * (2 - i))) & 0xff;

	/* CS assert wakes up the slave. */
	spi_claim_bus(spi_slave);

	/*
	 * The TCG TPM over SPI specification introduces the notion of SPI
	 * flow control (Section "6.4.5 Flow Control").
	 *
	 * Again, the slave (TPM device) expects each transaction to start
	 * with a 4 byte header trasmitted by master. The header indicates if
	 * the master needs to read or write a register, and the register
	 * address.
	 *
	 * If the slave needs to stall the transaction (for instance it is not
	 * ready to send the register value to the master), it sets the MOSI
	 * line to 0 during the last clock of the 4 byte header. In this case
	 * the master is supposed to start polling the SPI bus, one byte at
	 * time, until the last bit in the received byte (transferred during
	 * the last clock of the byte) is set to 1.
	 *
	 * Due to some SPI controllers' shortcomings (Rockchip comes to
	 * mind...) we trasmit the 4 byte header without checking the byte
	 * transmitted by the TPM during the transaction's last byte.
	 *
	 * We know that cr50 is guaranteed to set the flow control bit to 0
	 * during the header transfer, but real TPM2 might be fast enough not
	 * to require to stall the master, this would present an issue.
	 * crosbug.com/p/52132 has been opened to track this.
	 */
	spi_xfer(spi_slave, header.body, sizeof(header.body), NULL, 0);

	/*
	 * Now poll the bus until TPM removes the stall bit. Give it up to 100
	 * ms to sort it out - it could be saving stuff in nvram at some
	 * point.
	 */
	stopwatch_init_msecs_expire(&sw, 100);
	do {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "TPM flow control failure\n");
			spi_release_bus(spi_slave);
			return 0;
		}
		spi_xfer(spi_slave, NULL, 0, &byte, 1);
	} while (!(byte & 1));
	return 1;
}
Beispiel #21
0
asmlinkage void car_stage_entry(void)
{
	struct postcar_frame pcf;
	uintptr_t top_of_ram;
	bool s3wake;
	struct chipset_power_state *ps = car_get_var_ptr(&power_state);
	void *smm_base;
	size_t smm_size, var_size;
	const void *new_var_data;
	uintptr_t tseg_base;

	timestamp_add_now(TS_START_ROMSTAGE);

	soc_early_romstage_init();
	disable_watchdog();

	console_init();

	s3wake = fill_power_state(ps) == ACPI_S3;
	fsp_memory_init(s3wake);

	if (punit_init())
		set_max_freq();
	else
		printk(BIOS_DEBUG, "Punit failed to initialize properly\n");

	/* Stash variable MRC data and let cache system update it later */
	new_var_data = fsp_find_extension_hob_by_guid(hob_variable_guid,
							&var_size);
	if (new_var_data)
		mrc_cache_stash_vardata(new_var_data, var_size,
					car_get_var(fsp_version));
	else
		printk(BIOS_ERR, "Failed to determine variable data\n");

	if (postcar_frame_init(&pcf, 1*KiB))
		die("Unable to initialize postcar frame.\n");

	mainboard_save_dimm_info();

	/*
	 * We need to make sure ramstage will be run cached. At this point exact
	 * location of ramstage in cbmem is not known. Instruct postcar to cache
	 * 16 megs under cbmem top which is a safe bet to cover ramstage.
	 */
	top_of_ram = (uintptr_t) cbmem_top();
	/* cbmem_top() needs to be at least 16 MiB aligned */
	assert(ALIGN_DOWN(top_of_ram, 16*MiB) == top_of_ram);
	postcar_frame_add_mtrr(&pcf, top_of_ram - 16*MiB, 16*MiB, MTRR_TYPE_WRBACK);

	/* Cache the memory-mapped boot media. */
	if (IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED))
		postcar_frame_add_mtrr(&pcf, -CONFIG_ROM_SIZE, CONFIG_ROM_SIZE,
					MTRR_TYPE_WRPROT);

	/*
	* Cache the TSEG region at the top of ram. This region is
	* not restricted to SMM mode until SMM has been relocated.
	* By setting the region to cacheable it provides faster access
	* when relocating the SMM handler as well as using the TSEG
	* region for other purposes.
	*/
	smm_region(&smm_base, &smm_size);
	tseg_base = (uintptr_t)smm_base;
	postcar_frame_add_mtrr(&pcf, tseg_base, smm_size, MTRR_TYPE_WRBACK);

	run_postcar_phase(&pcf);
}
const struct spi_flash *boot_device_spi_flash(void)
{
	boot_device_rw_init();
	return car_get_var(sfg);
}
Beispiel #23
0
void qemu_debugcon_tx_byte(unsigned char data)
{
	if (car_get_var(qemu_debugcon_detected) != 0)
		outb(data, CONFIG_CONSOLE_QEMU_DEBUGCON_PORT);
}