Skip to content

Commit ab6e724

Browse files
Yuval Peressnashif
authored andcommitted
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: Yuval Peress <[email protected]>
1 parent e17e0c7 commit ab6e724

File tree

9 files changed

+192
-1
lines changed

9 files changed

+192
-1
lines changed

drivers/espi/espi_emul.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,49 @@ static bool espi_emul_get_channel_status(const struct device *dev, enum espi_cha
8787
return (data->cfg.channel_caps & ch);
8888
}
8989

90+
static int espi_emul_read_lpc_request(const struct device *dev,
91+
enum lpc_peripheral_opcode op,
92+
uint32_t *data)
93+
{
94+
const struct emul_espi_device_api *api;
95+
struct espi_emul *emul;
96+
struct espi_emul_data *emul_data = dev->data;
97+
98+
if (!(emul_data->cfg.channel_caps & ESPI_CHANNEL_VWIRE)) {
99+
LOG_ERR("bad channel vwire");
100+
return -EINVAL;
101+
}
102+
103+
emul = espi_emul_find(dev, EMUL_ESPI_HOST_CHIPSEL);
104+
if (!emul) {
105+
LOG_ERR("espi_emul not found");
106+
return -ENOTSUP;
107+
}
108+
109+
__ASSERT_NO_MSG(emul->api);
110+
api = emul->api;
111+
112+
switch (op) {
113+
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
114+
case EACPI_GET_SHARED_MEMORY:
115+
__ASSERT_NO_MSG(api->get_acpi_shm);
116+
*data = (uint32_t)api->get_acpi_shm(emul);
117+
break;
118+
#endif
119+
default:
120+
return -EINVAL;
121+
}
122+
return 0;
123+
}
124+
125+
static int espi_emul_write_lpc_request(const struct device *dev, enum lpc_peripheral_opcode op,
126+
uint32_t *data)
127+
{
128+
ARG_UNUSED(dev);
129+
130+
return -EINVAL;
131+
}
132+
90133
static int espi_emul_send_vwire(const struct device *dev, enum espi_vwire_signal vw, uint8_t level)
91134
{
92135
const struct emul_espi_device_api *api;
@@ -172,6 +215,8 @@ static struct emul_espi_driver_api emul_espi_driver_api = {
172215
.espi_api = {
173216
.config = espi_emul_config,
174217
.get_channel_status = espi_emul_get_channel_status,
218+
.read_lpc_request = espi_emul_read_lpc_request,
219+
.write_lpc_request = espi_emul_write_lpc_request,
175220
.send_vwire = espi_emul_send_vwire,
176221
.receive_vwire = espi_emul_receive_vwire,
177222
.manage_callback = espi_emul_manage_callback

include/drivers/espi_emul.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ typedef int (*emul_espi_api_get_vw)(struct espi_emul *emul,
6161
enum espi_vwire_signal vw,
6262
uint8_t *level);
6363

64+
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
65+
/**
66+
* Get the ACPI shared memory address owned by the emulator.
67+
*
68+
* @param emul Emulator instance.
69+
*
70+
* @retval The address of the memory.
71+
*/
72+
typedef uintptr_t (*emul_espi_api_get_acpi_shm)(struct espi_emul *emul);
73+
#endif
74+
6475
/**
6576
* Find an emulator present on a eSPI bus
6677
*
@@ -88,11 +99,13 @@ typedef struct espi_emul *(*emul_find_emul)(const struct device *dev,
8899
typedef int (*emul_trigger_event)(const struct device *dev,
89100
struct espi_event *evt);
90101

91-
92102
/** Definition of the eSPI device emulator API */
93103
struct emul_espi_device_api {
94104
emul_espi_api_set_vw set_vw;
95105
emul_espi_api_get_vw get_vw;
106+
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
107+
emul_espi_api_get_acpi_shm get_acpi_shm;
108+
#endif
96109
};
97110

98111
/** 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,
152165
*/
153166
int emul_espi_host_port80_write(const struct device *espi_dev, uint32_t data);
154167

168+
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
169+
/**
170+
* Get the host device's ACPI shared memory start address. The size of the region is
171+
* CONFIG_EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE.
172+
*
173+
* @param espi_dev eSPI emulation controller device.
174+
* @return Address of the start of the ACPI shared memory.
175+
*/
176+
uintptr_t emul_espi_host_get_acpi_shm(const struct device *espi_dev);
177+
#endif
178+
179+
155180
#ifdef __cplusplus
156181
}
157182
#endif

subsys/emul/espi/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,15 @@ config EMUL_ESPI_HOST
99
This is an emulator of the generic eSPI host. The emulator supports
1010
basic host operations - virtual wires and writing to port 80. It can be
1111
extended.
12+
13+
if EMUL_ESPI_HOST
14+
15+
config EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE
16+
int "Host I/O peripheral port size for shared memory in emulator"
17+
depends on ESPI_PERIPHERAL_ACPI_SHM_REGION
18+
default 256
19+
help
20+
This is the port size used to mimic the Host and EC communication
21+
over the shared memory region which returns the ACPI response data.
22+
23+
endif # EMUL_ESPI_HOST

subsys/emul/espi/emul_espi_host.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ struct espi_host_emul_data {
7373
/** Virtual Wires states, for one slave only.
7474
* With multi-slaves config, the states should be saved per slave */
7575
struct vw_data vw_state[NUMBER_OF_VWIRES];
76+
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
77+
/** ACPI Shared memory. */
78+
uint8_t shm_acpi_mmap[CONFIG_EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE];
79+
#endif
7680
};
7781

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

224+
#ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
225+
static uintptr_t emul_espi_dev_get_acpi_shm(struct espi_emul *emul)
226+
{
227+
struct espi_host_emul_data *data =
228+
CONTAINER_OF(emul, struct espi_host_emul_data, emul);
229+
230+
return (uintptr_t)data->shm_acpi_mmap;
231+
}
232+
233+
uintptr_t emul_espi_host_get_acpi_shm(const struct device *espi_dev)
234+
{
235+
uint32_t shm;
236+
int rc = espi_read_lpc_request(espi_dev, EACPI_GET_SHARED_MEMORY, &shm);
237+
238+
__ASSERT_NO_MSG(rc == 0);
239+
240+
return (uintptr_t) shm;
241+
}
242+
#endif
243+
220244
/* Device instantiation */
221245
static struct emul_espi_device_api ap_emul_api = {
222246
.set_vw = emul_host_set_vw,
223247
.get_vw = emul_host_get_vw,
248+
.get_acpi_shm = emul_espi_dev_get_acpi_shm,
224249
};
225250

226251
/**

tests/drivers/espi/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright 2021 Google LLC
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
cmake_minimum_required(VERSION 3.13.1)
5+
6+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
7+
project(espi)
8+
9+
FILE(GLOB app_sources src/*.c)
10+
target_sources(app PRIVATE ${app_sources})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
&espi0 {
8+
espi_host: espi-host@0 {
9+
status = "okay";
10+
compatible = "zephyr,espi-emul-espi-host";
11+
reg = <0x0>;
12+
label = "ESPI_HOST";
13+
};
14+
};

tests/drivers/espi/prj.conf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright 2021 Google LLC
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
CONFIG_ZTEST=y
5+
CONFIG_ESPI=y
6+
CONFIG_EMUL=y
7+
CONFIG_ESPI_EMUL=y
8+
CONFIG_EMUL_ESPI_HOST=y
9+
10+
CONFIG_ESPI_PERIPHERAL_CHANNEL=y
11+
CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION=y

tests/drivers/espi/src/test_acpi.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <device.h>
7+
#include <drivers/espi.h>
8+
#include <drivers/espi_emul.h>
9+
#include <ztest.h>
10+
11+
static void test_acpi_shared_memory(void)
12+
{
13+
const struct device *espi_dev = device_get_binding(DT_LABEL(DT_NODELABEL(espi0)));
14+
struct espi_cfg cfg = {
15+
.channel_caps = ESPI_CHANNEL_VWIRE | ESPI_CHANNEL_PERIPHERAL,
16+
};
17+
uintptr_t host_shm, peripheral_shm;
18+
19+
zassert_not_null(espi_dev, NULL);
20+
21+
zassert_ok(espi_config(espi_dev, &cfg), NULL);
22+
23+
host_shm = emul_espi_host_get_acpi_shm(espi_dev);
24+
zassert_not_equal(host_shm, 0, NULL);
25+
26+
zassert_ok(espi_read_lpc_request(espi_dev, EACPI_GET_SHARED_MEMORY,
27+
(uint32_t *)&peripheral_shm),
28+
NULL);
29+
30+
zassert_equal(host_shm, peripheral_shm, NULL);
31+
}
32+
33+
ztest_test_suite(acpi, ztest_unit_test(test_acpi_shared_memory));
34+
35+
void test_main(void)
36+
{
37+
ztest_run_test_suite(acpi);
38+
}

tests/drivers/espi/testcase.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright 2021 Google LLC
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
tests:
5+
drivers.espi.acpi:
6+
tags: drivers espi
7+
filter: dt_compat_enabled("zephyr,espi-emul-controller")
8+
harness: ztest
9+
platform_allow: native_posix
10+
integration_platforms:
11+
- native_posix

0 commit comments

Comments
 (0)