Commit ab6e724a authored by Yuval Peress's avatar Yuval Peress Committed by Anas Nashif
Browse files

emul: espi: Add ACPI Shared Memory functions



Add the bare minimum to set and access the ACPI shared memory via the
eSPI emulator.

Signed-off-by: default avatarYuval Peress <peress@chromium.org>
parent e17e0c7b
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -87,6 +87,49 @@ static bool espi_emul_get_channel_status(const struct device *dev, enum espi_cha
	return (data->cfg.channel_caps & ch);
}

static int espi_emul_read_lpc_request(const struct device *dev,
				      enum lpc_peripheral_opcode op,
				      uint32_t *data)
{
	const struct emul_espi_device_api *api;
	struct espi_emul *emul;
	struct espi_emul_data *emul_data = dev->data;

	if (!(emul_data->cfg.channel_caps & ESPI_CHANNEL_VWIRE)) {
		LOG_ERR("bad channel vwire");
		return -EINVAL;
	}

	emul = espi_emul_find(dev, EMUL_ESPI_HOST_CHIPSEL);
	if (!emul) {
		LOG_ERR("espi_emul not found");
		return -ENOTSUP;
	}

	__ASSERT_NO_MSG(emul->api);
	api = emul->api;

	switch (op) {
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
	case EACPI_GET_SHARED_MEMORY:
		__ASSERT_NO_MSG(api->get_acpi_shm);
		*data = (uint32_t)api->get_acpi_shm(emul);
		break;
#endif
	default:
		return -EINVAL;
	}
	return 0;
}

static int espi_emul_write_lpc_request(const struct device *dev, enum lpc_peripheral_opcode op,
				       uint32_t *data)
{
	ARG_UNUSED(dev);

	return -EINVAL;
}

static int espi_emul_send_vwire(const struct device *dev, enum espi_vwire_signal vw, uint8_t level)
{
	const struct emul_espi_device_api *api;
@@ -172,6 +215,8 @@ static struct emul_espi_driver_api emul_espi_driver_api = {
	.espi_api = {
		.config = espi_emul_config,
		.get_channel_status = espi_emul_get_channel_status,
		.read_lpc_request = espi_emul_read_lpc_request,
		.write_lpc_request = espi_emul_write_lpc_request,
		.send_vwire = espi_emul_send_vwire,
		.receive_vwire = espi_emul_receive_vwire,
		.manage_callback = espi_emul_manage_callback
+26 −1
Original line number Diff line number Diff line
@@ -61,6 +61,17 @@ typedef int (*emul_espi_api_get_vw)(struct espi_emul *emul,
				    enum espi_vwire_signal vw,
				    uint8_t *level);

#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
/**
 * Get the ACPI shared memory address owned by the emulator.
 *
 * @param emul Emulator instance.
 *
 * @retval The address of the memory.
 */
typedef uintptr_t (*emul_espi_api_get_acpi_shm)(struct espi_emul *emul);
#endif

/**
 * Find an emulator present on a eSPI bus
 *
@@ -88,11 +99,13 @@ typedef struct espi_emul *(*emul_find_emul)(const struct device *dev,
typedef int (*emul_trigger_event)(const struct device *dev,
				  struct espi_event *evt);


/** Definition of the eSPI device emulator API */
struct emul_espi_device_api {
	emul_espi_api_set_vw set_vw;
	emul_espi_api_get_vw get_vw;
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
	emul_espi_api_get_acpi_shm get_acpi_shm;
#endif
};

/** Node in a linked list of emulators for eSPI devices */
@@ -152,6 +165,18 @@ int emul_espi_host_send_vw(const struct device *espi_dev,
 */
int emul_espi_host_port80_write(const struct device *espi_dev, uint32_t data);

#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
/**
 * Get the host device's ACPI shared memory start address. The size of the region is
 * CONFIG_EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE.
 *
 * @param espi_dev eSPI emulation controller device.
 * @return Address of the start of the ACPI shared memory.
 */
uintptr_t emul_espi_host_get_acpi_shm(const struct device *espi_dev);
#endif


#ifdef __cplusplus
}
#endif
+12 −0
Original line number Diff line number Diff line
@@ -9,3 +9,15 @@ config EMUL_ESPI_HOST
	  This is an emulator of the generic eSPI host. The emulator supports
	  basic host operations - virtual wires and writing to port 80. It can be
	  extended.

if EMUL_ESPI_HOST

config EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE
	int "Host I/O peripheral port size for shared memory in emulator"
	depends on ESPI_PERIPHERAL_ACPI_SHM_REGION
	default 256
	help
	  This is the port size used to mimic the Host and EC communication
	  over the shared memory region which returns the ACPI response data.

endif # EMUL_ESPI_HOST
+25 −0
Original line number Diff line number Diff line
@@ -73,6 +73,10 @@ struct espi_host_emul_data {
	/** Virtual Wires states, for one slave only.
	 *  With multi-slaves config, the states should be saved per slave */
	struct vw_data vw_state[NUMBER_OF_VWIRES];
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
	/** ACPI Shared memory. */
	uint8_t shm_acpi_mmap[CONFIG_EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE];
#endif
};

/** Static configuration for the emulator */
@@ -217,10 +221,31 @@ int emul_espi_host_port80_write(const struct device *espi_dev, uint32_t data)
	return 0;
}

#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
static uintptr_t emul_espi_dev_get_acpi_shm(struct espi_emul *emul)
{
	struct espi_host_emul_data *data =
		CONTAINER_OF(emul, struct espi_host_emul_data, emul);

	return (uintptr_t)data->shm_acpi_mmap;
}

uintptr_t emul_espi_host_get_acpi_shm(const struct device *espi_dev)
{
	uint32_t shm;
	int rc = espi_read_lpc_request(espi_dev, EACPI_GET_SHARED_MEMORY, &shm);

	__ASSERT_NO_MSG(rc == 0);

	return (uintptr_t) shm;
}
#endif

/* Device instantiation */
static struct emul_espi_device_api ap_emul_api = {
	.set_vw = emul_host_set_vw,
	.get_vw = emul_host_get_vw,
	.get_acpi_shm = emul_espi_dev_get_acpi_shm,
};

/**
+10 −0
Original line number Diff line number Diff line
# Copyright 2021 Google LLC
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13.1)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(espi)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
Loading