Example #1
0
int get_recovery_mode_switch(void)
{
	uint32_t ec_events;

	ec_events = google_chromeec_get_events_b();

	/* Enter recovery mode either on keyboard recovery / fastboot event. */
	return !!((ec_events &
		   EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY)) ||
		  (ec_events &
		   EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_FASTBOOT)));
}
Example #2
0
void google_chromeec_log_events(uint64_t mask)
{
	u8 event;
	uint64_t wake_mask;
	bool restore_wake_mask = false;

	if (!IS_ENABLED(CONFIG_ELOG))
		return;

	/*
	 * If the EC supports unified wake masks, then there is no need to set
	 * wake mask before reading out the host events.
	 */
	if (google_chromeec_check_feature(EC_FEATURE_UNIFIED_WAKE_MASKS) != 1) {
		wake_mask = google_chromeec_get_wake_mask();
		google_chromeec_set_wake_mask(mask);
		restore_wake_mask = true;
	}

	while ((event = google_chromeec_get_event()) != 0) {
		if (EC_HOST_EVENT_MASK(event) & mask)
			elog_add_event_byte(ELOG_TYPE_EC_EVENT, event);
	}

	if (restore_wake_mask)
		google_chromeec_set_wake_mask(wake_mask);
}
Example #3
0
int clear_recovery_mode_switch(void)
{
	const uint32_t kb_rec_mask =
		EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY);

	/* Unconditionally clear the EC recovery request. */
	return google_chromeec_clear_events_b(kb_rec_mask);
}
Example #4
0
int get_recovery_mode_switch(void)
{
	uint32_t ec_events;

	ec_events = google_chromeec_get_events_b();
	return !!(ec_events &
		  EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
}
Example #5
0
static void google_chromeec_elog_add_recovery_event(void *unused)
{
	uint64_t *events = cbmem_find(CBMEM_ID_EC_HOSTEVENT);
	uint8_t event_byte = EC_EVENT_KEYBOARD_RECOVERY;

	if (!events)
		return;

	if (!(*events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY)))
		return;

	if (*events &
	    EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY_HW_REINIT))
		event_byte = EC_EVENT_KEYBOARD_RECOVERY_HWREINIT;

	elog_add_event_byte(ELOG_TYPE_EC_EVENT, event_byte);
}
Example #6
0
int clear_recovery_mode_switch(void)
{
	if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC))
		/* Clear keyboard recovery event. */
		return google_chromeec_clear_events_b(
			EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));

	return 0;
}
Example #7
0
int get_recovery_mode_switch(void)
{
	/* Check for dedicated recovery switch first. */
	if (google_chromeec_get_switches() & EC_SWITCH_DEDICATED_RECOVERY)
		return 1;

	/* Otherwise check if the EC has posted the keyboard recovery event. */
	return !!(google_chromeec_get_events_b() &
		  EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
}
Example #8
0
/*
 * In AP S0 -> S3 & S0ix transitions,
 * the chipset_suspend is called.
 *
 * The chipset_in_state(CHIPSET_STATE_STANDBY | CHIPSET_STATE_ON)
 * is used to detect the S0ix transiton.
 *
 * During S0ix entry, the wake mask for lid open is enabled.
 *
 */
void lpc_enable_wake_mask_for_lid_open(void)
{
	if ((chipset_in_state(CHIPSET_STATE_STANDBY | CHIPSET_STATE_ON)) ||
				chipset_in_state(CHIPSET_STATE_STANDBY)) {
		uint32_t mask = 0;

		mask = ((lpc_get_host_event_mask(LPC_HOST_EVENT_WAKE)) |
			EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN));

		lpc_set_host_event_mask(LPC_HOST_EVENT_WAKE, mask);
}	}
Example #9
0
int clear_recovery_mode_switch(void)
{
#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
	const uint32_t kb_rec_mask =
		EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY);
	/* Unconditionally clear the EC recovery request. */
	return google_chromeec_clear_events_b(kb_rec_mask);
#else
	return 0;
#endif
}
Example #10
0
int get_recovery_mode_switch(void)
{
	uint32_t ec_events;

	/* The GPIO is active low. */
	if (!gpio_get(GPIO_RECOVERY))
		return 1;

	ec_events = google_chromeec_get_events_b();
	return !!(ec_events &
		  EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
}
Example #11
0
int cros_ec_get_lid_shutdown_mask(struct udevice *dev)
{
	u32 mask;
	int ret;

	ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK,
				     &mask);
	if (ret < 0)
		return ret;

	return !!(mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED));
}
Example #12
0
int get_recovery_mode_switch(void)
{
#if CONFIG_EC_GOOGLE_CHROMEEC
	uint32_t ec_events;

	ec_events = google_chromeec_get_events_b();
	return !!(ec_events &
		  EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
#else
	return 0;
#endif
}
Example #13
0
/* There are actually two recovery switches. One is the magic keyboard chord,
 * the other is driven by Servo. */
int get_recovery_mode_switch(void)
{
	u8 ec_switches = inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES);
	u32 ec_events;

	/* If a switch is set, we don't need to look at events. */
	if (ec_switches & (EC_SWITCH_KEYBOARD_RECOVERY |
			   EC_SWITCH_DEDICATED_RECOVERY))
		return 1;

	/* Else check if the EC has posted the keyboard recovery event. */
	ec_events = google_chromeec_get_events_b();

	return !!(ec_events &
		  EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
}
Example #14
0
int cros_ec_get_host_events(struct cros_ec_dev *dev, uint32_t *events_ptr)
{
	struct ec_response_host_event_mask *resp;

	/*
	 * Use the B copy of the event flags, because the main copy is already
	 * used by ACPI/SMI.
	 */
	if (ec_command_inptr(dev, EC_CMD_HOST_EVENT_GET_B, 0, NULL, 0,
		       (uint8_t **)&resp, sizeof(*resp)) < (int)sizeof(*resp))
		return -1;

	if (resp->mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_INVALID))
		return -1;

	*events_ptr = resp->mask;
	return 0;
}
Example #15
0
void google_chromeec_log_events(u32 mask)
{
#if CONFIG_ELOG
	u8 event;
	u32 wake_mask;

	/* Set wake mask so events will be read from ACPI interface */
	wake_mask = google_chromeec_get_wake_mask();
	google_chromeec_set_wake_mask(mask);

	while ((event = google_chromeec_get_event()) != 0) {
		if (EC_HOST_EVENT_MASK(event) & mask)
			elog_add_event_byte(ELOG_TYPE_EC_EVENT, event);
	}

	google_chromeec_set_wake_mask(wake_mask);
#endif
}
Example #16
0
static int cros_ec_rtc_event(struct notifier_block *nb,
			     unsigned long queued_during_suspend,
			     void *_notify)
{
	struct cros_ec_rtc *cros_ec_rtc;
	struct rtc_device *rtc;
	struct cros_ec_device *cros_ec;
	u32 host_event;

	cros_ec_rtc = container_of(nb, struct cros_ec_rtc, notifier);
	rtc = cros_ec_rtc->rtc;
	cros_ec = cros_ec_rtc->cros_ec;

	host_event = cros_ec_get_host_event(cros_ec);
	if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC)) {
		rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
		return NOTIFY_OK;
	} else {
		return NOTIFY_DONE;
	}
}
Example #17
0
int get_recovery_mode_switch(void)
{
#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
    u8 ec_switches;
    u32 ec_events;
    mec_io_bytes(0, EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES, 1,
                 &ec_switches, NULL);

    /* If a switch is set, we don't need to look at events. */
    if (ec_switches & (EC_SWITCH_DEDICATED_RECOVERY))
        return 1;

    /* Else check if the EC has posted the keyboard recovery event. */
    ec_events = google_chromeec_get_events_b();

    return !!(ec_events &
              EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
#else
    return 0;
#endif
}
Example #18
0
int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable)
{
	u32 mask;
	int ret;

	ret = cros_ec_get_event_mask(dev, EC_CMD_HOST_EVENT_GET_SMI_MASK,
				     &mask);
	if (ret < 0)
		return ret;

	/* Set lid close event state in the EC SMI event mask */
	if (enable)
		mask |= EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED);
	else
		mask &= ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED);

	ret = cros_ec_set_event_mask(dev, EC_CMD_HOST_EVENT_SET_SMI_MASK, mask);
	if (ret < 0)
		return ret;

	printf("EC: %sabled lid close event\n", enable ? "en" : "dis");
	return 0;
}
Example #19
0
File: ec.c Project: jpl888/coreboot
/* Find the last port80 code from the previous boot */
static u16 google_chromeec_get_port80_last_boot(void)
{
	struct ec_response_port80_last_boot rsp;
	struct chromeec_command cmd = {
		.cmd_code = EC_CMD_PORT80_LAST_BOOT,
		.cmd_data_out = &rsp,
		.cmd_size_out = sizeof(rsp),
	};

	/* Get last port80 code */
	if (google_chromeec_command(&cmd) == 0)
		return rsp.code;

	return 0;
}
#endif

void google_chromeec_log_events(u32 mask)
{
#if CONFIG_ELOG
	u8 event;
	u16 code;

	/* Find the last port80 code */
	code = google_chromeec_get_port80_last_boot();

	/* Log the last post code only if it is abornmal */
	if (code > 0 && code != POST_OS_BOOT && code != POST_OS_RESUME)
		printk(BIOS_DEBUG, "Chrome EC: Last POST code was 0x%02x\n",
		       code);

	while ((event = google_chromeec_get_event()) != 0) {
		if (EC_HOST_EVENT_MASK(event) & mask)
			elog_add_event_byte(ELOG_TYPE_EC_EVENT, event);
	}
#endif
}
Example #20
0
/**
 * Process an emulated EC command
 *
 * @param ec		Current emulated EC state
 * @param req_hdr	Pointer to request header
 * @param req_data	Pointer to body of request
 * @param resp_hdr	Pointer to place to put response header
 * @param resp_data	Pointer to place to put response data, if any
 * @return length of response data, or 0 for no response data, or -1 on error
 */
static int process_cmd(struct ec_state *ec,
		       struct ec_host_request *req_hdr, const void *req_data,
		       struct ec_host_response *resp_hdr, void *resp_data)
{
	int len;

	/* TODO([email protected]): Check checksums */
	debug("EC command %#0x\n", req_hdr->command);

	switch (req_hdr->command) {
	case EC_CMD_HELLO: {
		const struct ec_params_hello *req = req_data;
		struct ec_response_hello *resp = resp_data;

		resp->out_data = req->in_data + 0x01020304;
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_GET_VERSION: {
		struct ec_response_get_version *resp = resp_data;

		strcpy(resp->version_string_ro, "sandbox_ro");
		strcpy(resp->version_string_rw, "sandbox_rw");
		resp->current_image = ec->current_image;
		debug("Current image %d\n", resp->current_image);
		len = sizeof(*resp);
		break;
	}
	case EC_CMD_VBNV_CONTEXT: {
		const struct ec_params_vbnvcontext *req = req_data;
		struct ec_response_vbnvcontext *resp = resp_data;

		switch (req->op) {
		case EC_VBNV_CONTEXT_OP_READ:
			memcpy(resp->block, ec->vbnv_context,
			       sizeof(resp->block));
			len = sizeof(*resp);
			break;
		case EC_VBNV_CONTEXT_OP_WRITE:
			memcpy(ec->vbnv_context, resp->block,
			       sizeof(resp->block));
			len = 0;
			break;
		default:
			printf("   ** Unknown vbnv_context command %#02x\n",
			       req->op);
			return -1;
		}
		break;
	}
	case EC_CMD_REBOOT_EC: {
		const struct ec_params_reboot_ec *req = req_data;

		printf("Request reboot type %d\n", req->cmd);
		switch (req->cmd) {
		case EC_REBOOT_DISABLE_JUMP:
			len = 0;
			break;
		case EC_REBOOT_JUMP_RW:
			ec->current_image = EC_IMAGE_RW;
			len = 0;
			break;
		default:
			puts("   ** Unknown type");
			return -1;
		}
		break;
	}
	case EC_CMD_HOST_EVENT_GET_B: {
		struct ec_response_host_event_mask *resp = resp_data;

		resp->mask = 0;
		if (ec->recovery_req) {
			resp->mask |= EC_HOST_EVENT_MASK(
					EC_HOST_EVENT_KEYBOARD_RECOVERY);
		}

		len = sizeof(*resp);
		break;
	}
	case EC_CMD_VBOOT_HASH: {
		const struct ec_params_vboot_hash *req = req_data;
		struct ec_response_vboot_hash *resp = resp_data;
		struct fmap_entry *entry;
		int ret, size;

		entry = &ec->ec_config.region[EC_FLASH_REGION_RW];

		switch (req->cmd) {
		case EC_VBOOT_HASH_RECALC:
		case EC_VBOOT_HASH_GET:
			size = SHA256_SUM_LEN;
			len = get_image_used(ec, entry);
			ret = hash_block("sha256",
					 ec->flash_data + entry->offset,
					 len, resp->hash_digest, &size);
			if (ret) {
				printf("   ** hash_block() failed\n");
				return -1;
			}
			resp->status = EC_VBOOT_HASH_STATUS_DONE;
			resp->hash_type = EC_VBOOT_HASH_TYPE_SHA256;
			resp->digest_size = size;
			resp->reserved0 = 0;
			resp->offset = entry->offset;
			resp->size = len;
			len = sizeof(*resp);
			break;
		default:
			printf("   ** EC_CMD_VBOOT_HASH: Unknown command %d\n",
			       req->cmd);
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_PROTECT: {
		const struct ec_params_flash_protect *req = req_data;
		struct ec_response_flash_protect *resp = resp_data;
		uint32_t expect = EC_FLASH_PROTECT_ALL_NOW |
				EC_FLASH_PROTECT_ALL_AT_BOOT;

		printf("mask=%#x, flags=%#x\n", req->mask, req->flags);
		if (req->flags == expect || req->flags == 0) {
			resp->flags = req->flags ? EC_FLASH_PROTECT_ALL_NOW :
								0;
			resp->valid_flags = EC_FLASH_PROTECT_ALL_NOW;
			resp->writable_flags = 0;
			len = sizeof(*resp);
		} else {
			puts("   ** unexpected flash protect request\n");
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_REGION_INFO: {
		const struct ec_params_flash_region_info *req = req_data;
		struct ec_response_flash_region_info *resp = resp_data;
		struct fmap_entry *entry;

		switch (req->region) {
		case EC_FLASH_REGION_RO:
		case EC_FLASH_REGION_RW:
		case EC_FLASH_REGION_WP_RO:
			entry = &ec->ec_config.region[req->region];
			resp->offset = entry->offset;
			resp->size = entry->length;
			len = sizeof(*resp);
			printf("EC flash region %d: offset=%#x, size=%#x\n",
			       req->region, resp->offset, resp->size);
			break;
		default:
			printf("** Unknown flash region %d\n", req->region);
			return -1;
		}
		break;
	}
	case EC_CMD_FLASH_ERASE: {
		const struct ec_params_flash_erase *req = req_data;

		memset(ec->flash_data + req->offset,
		       ec->ec_config.flash_erase_value,
		       req->size);
		len = 0;
		break;
	}
	case EC_CMD_FLASH_WRITE: {
		const struct ec_params_flash_write *req = req_data;

		memcpy(ec->flash_data + req->offset, req + 1, req->size);
		len = 0;
		break;
	}
	case EC_CMD_MKBP_STATE:
		len = cros_ec_keyscan(ec, resp_data);
		break;
	case EC_CMD_ENTERING_MODE:
		len = 0;
		break;
	default:
		printf("   ** Unknown EC command %#02x\n", req_hdr->command);
		return -1;
	}

	return len;
}
/* Host Event helpers */
static int ev_is_set(int event)
{
	return host_get_events() & EC_HOST_EVENT_MASK(event);
}
Example #22
0
int get_recovery_mode_switch(void)
{
	/* Check if the EC has posted the keyboard recovery event. */
	return !!(google_chromeec_get_events_b() &
		  EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
}
static VbError_t
twostop_init_vboot_library(firmware_storage_t *file, void *gbb,
			   uint32_t gbb_offset, size_t gbb_size,
			   crossystem_data_t *cdata, VbCommonParams *cparams)
{
	VbError_t err;
	VbInitParams iparams;
	int virtual_dev_switch =
		cros_fdtdec_config_has_prop(gd->fdt_blob,
					    "virtual-dev-switch");
#ifdef CONFIG_MKBP
	struct mkbp_dev *mdev = board_get_mkbp_dev();
#endif

	memset(&iparams, 0, sizeof(iparams));
	iparams.flags = check_ro_normal_support();

#ifdef CONFIG_MKBP
	if (mdev) {
		uint32_t ec_events = 0;
		const uint32_t kb_rec_mask =
			EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY);

		/* Read keyboard recovery flag from EC, then clear it */
		if (mkbp_get_host_events(mdev, &ec_events)) {
			/*
			 * TODO: what can we do if that fails?  Request
			 * recovery?  We don't simply want to fail, because
			 * that'll prevent us from going into recovery mode.
			 * We don't want to go into recovery mode
			 * automatically, because that'll break snow.
			 */
			VBDEBUG("VbInit: unable to read EC events\n");
			ec_events = 0;
		}
		if (ec_events & kb_rec_mask) {
			iparams.flags |= VB_INIT_FLAG_REC_BUTTON_PRESSED;
			if (mkbp_clear_host_events(mdev, kb_rec_mask))
				VBDEBUG("VbInit: unable to clear "
					"EC KB recovery event\n");
		}
	}
#endif

	if (cdata->boot_write_protect_switch)
		iparams.flags |= VB_INIT_FLAG_WP_ENABLED;
	if (cdata->boot_recovery_switch)
		iparams.flags |= VB_INIT_FLAG_REC_BUTTON_PRESSED;
	if (cdata->boot_developer_switch)
		iparams.flags |= VB_INIT_FLAG_DEV_SWITCH_ON;
	if (cdata->boot_oprom_loaded)
		iparams.flags |= VB_INIT_FLAG_OPROM_LOADED;
	if (cdata->oprom_matters)
		iparams.flags |= VB_INIT_FLAG_OPROM_MATTERS;
	if (virtual_dev_switch)
		iparams.flags |= VB_INIT_FLAG_VIRTUAL_DEV_SWITCH;
	if (cros_fdtdec_config_has_prop(gd->fdt_blob, "ec-software-sync"))
		iparams.flags |= VB_INIT_FLAG_EC_SOFTWARE_SYNC;
	if (cros_fdtdec_config_has_prop(gd->fdt_blob, "ec-slow-update"))
		iparams.flags |= VB_INIT_FLAG_EC_SLOW_UPDATE;
	if (flash_sw_wp_is_enabled(file))
		iparams.flags |= VB_INIT_FLAG_SW_WP_ENABLED;
	VBDEBUG("iparams.flags: %08x\n", iparams.flags);

	if ((err = VbInit(cparams, &iparams))) {
		VBDEBUG("VbInit: %u\n", err);

		/*
		 * If vboot wants EC to reboot to RO, make request now,
		 * because there isn't a clear path to pass this request
		 * through to do_vboot_twostop().
		 */
		if (err == VBERROR_EC_REBOOT_TO_RO_REQUIRED)
			request_ec_reboot_to_ro();

		return err;
	}

#ifdef CONFIG_VIDEO_TEGRA
	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
#endif
#ifdef CONFIG_EXYNOS_DISPLAYPORT
	exynos_lcd_check_next_stage(gd->fdt_blob, 0);
#endif
	VBDEBUG("iparams.out_flags: %08x\n", iparams.out_flags);

	if (virtual_dev_switch) {
		cdata->boot_developer_switch =
			(iparams.out_flags & VB_INIT_OUT_ENABLE_DEVELOPER) ?
			1 : 0;
		VBDEBUG("cdata->boot_developer_switch=%d\n",
				cdata->boot_developer_switch);
	}

	if (iparams.out_flags & VB_INIT_OUT_CLEAR_RAM)
		wipe_unused_memory(cdata, cparams);

	/* Load required information of GBB */
	if (iparams.out_flags & VB_INIT_OUT_ENABLE_DISPLAY) {
		if (gbb_read_bmp_block(gbb, file, gbb_offset, gbb_size))
			return VBERROR_INVALID_GBB;
		have_read_gbb_bmp_block = 1;
	}
	if (cdata->boot_developer_switch ||
			iparams.out_flags & VB_INIT_OUT_ENABLE_RECOVERY) {
		if (gbb_read_recovery_key(gbb, file, gbb_offset, gbb_size))
			return VBERROR_INVALID_GBB;
	}

	return VBERROR_SUCCESS;
}
static void ev_clear(int event)
{
	host_clear_events(EC_HOST_EVENT_MASK(event));
}
Example #25
0
int clear_recovery_mode_switch(void)
{
	/* Clear keyboard recovery event. */
	return google_chromeec_clear_events_b(
		EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
}