コード例 #1
0
ファイル: chromeos.c プロジェクト: RafaelRMachado/Coreboot
int get_lid_switch(void)
{
#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
	u8 ec_switches;

	mec_io_bytes(0, EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SWITCHES, 1,
		     &ec_switches, NULL);
	return !!(ec_switches & EC_SWITCH_LID_OPEN);
#else
	/* Default to force open. */
	return 1;
#endif
}
コード例 #2
0
ファイル: ec_lpc.c プロジェクト: AdriDlu/coreboot
/*
 * Write bytes to a given LPC-mapped address.
 *
 * @port: Base write address
 * @length: Number of bytes to write
 * @msg: Write data buffer
 * @csum: Optional parameter, sums data written
 */
static void write_bytes(u16 port, unsigned int length, u8 *msg, u8 *csum)
{
	int i;

#if CONFIG_EC_GOOGLE_CHROMEEC_MEC
	/* Access desired range though EMI interface */
	if (port >= MEC_EMI_RANGE_START && port <= MEC_EMI_RANGE_END) {
		mec_io_bytes(1, port, length, msg, csum);
		return;
	}
#endif

	for (i = 0; i < length; ++i) {
		outb(msg[i], port + i);
		if (csum)
			*csum += msg[i];
	}
}
コード例 #3
0
ファイル: ec_lpc.c プロジェクト: AdriDlu/coreboot
/*
 * Read bytes from a given LPC-mapped address.
 *
 * @port: Base read address
 * @length: Number of bytes to read
 * @dest: Destination buffer
 * @csum: Optional parameter, sums data read
 */
static void read_bytes(u16 port, unsigned int length, u8 *dest, u8 *csum)
{
	int i;

#if CONFIG_EC_GOOGLE_CHROMEEC_MEC
	/* Access desired range though EMI interface */
	if (port >= MEC_EMI_RANGE_START && port <= MEC_EMI_RANGE_END) {
		mec_io_bytes(0, port, length, dest, csum);
		return;
	}
#endif

	for (i = 0; i < length; ++i) {
		dest[i] = inb(port + i);
		if (csum)
			*csum += dest[i];
	}
}
コード例 #4
0
ファイル: chromeos.c プロジェクト: RafaelRMachado/Coreboot
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
}
コード例 #5
0
static int wilco_ec_transfer(struct wilco_ec_message *msg)
{
	struct wilco_ec_request rq;
	struct wilco_ec_response rs;
	uint8_t checksum;
	size_t skip_size;

	/* Prepare request packet */
	wilco_ec_prepare(msg, &rq);

	/* Write request header */
	mec_io_bytes(MEC_IO_WRITE, CONFIG_EC_BASE_PACKET, 0, &rq, sizeof(rq));

	/* Write request data */
	mec_io_bytes(MEC_IO_WRITE, CONFIG_EC_BASE_PACKET, sizeof(rq),
		     msg->data, msg->request_size);

	/* Start the command */
	outb(EC_MAILBOX_START_COMMAND, CONFIG_EC_BASE_HOST_COMMAND);

	/* Wait for it to complete */
	if (wilco_ec_response_timed_out()) {
		printk(BIOS_ERR, "%s: response timed out\n", __func__);
		return -1;
	}

	/* Some commands will put the EC into a state where it cannot respond */
	if (msg->type == WILCO_EC_MSG_NO_RESPONSE) {
		printk(BIOS_DEBUG, "%s: EC does not respond to this command\n",
		       __func__);
		return 0;
	}

	/* Check result */
	msg->result = inb(CONFIG_EC_BASE_HOST_DATA);
	if (msg->result != 0) {
		printk(BIOS_ERR, "%s: bad response: 0x%02x\n",
		       __func__, msg->result);
		return -1;
	}

	/* Read back response */
	checksum = mec_io_bytes(MEC_IO_READ, CONFIG_EC_BASE_PACKET, 0,
				&rs, sizeof(rs));
	if (checksum) {
		printk(BIOS_ERR, "%s: bad checksum %02x\n", __func__, checksum);
		return -1;
	}
	msg->result = rs.result;

	/* EC always returns EC_MAILBOX_DATA_SIZE bytes */
	if (rs.data_size > EC_MAILBOX_DATA_SIZE) {
		printk(BIOS_ERR, "%s: packet too long (%d bytes, expected %d)",
		       __func__, rs.data_size, EC_MAILBOX_DATA_SIZE);
		return -1;
	}

	/* Skip response data bytes as requested */
	skip_size = (msg->type == WILCO_EC_MSG_DEFAULT) ? 1 : 0;

	if (msg->response_size > rs.data_size - skip_size) {
		printk(BIOS_ERR, "%s: data too short (%lu bytes, expected %zu)",
		       __func__, rs.data_size - skip_size, msg->response_size);
		return -1;
	}

	memcpy(msg->data, rs.data + skip_size, msg->response_size);

	/* Return actual amount of data received */
	return msg->response_size;
}