1 /*
2  * Copyright 2020 Google LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_
9 
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/emul.h>
12 #include <zephyr/drivers/espi.h>
13 #include <zephyr/sys/slist.h>
14 #include <zephyr/types.h>
15 
16 /**
17  * @file
18  *
19  * @brief Public APIs for the eSPI emulation drivers.
20  */
21 
22 /**
23  * @brief eSPI Emulation Interface
24  * @defgroup espi_emul_interface eSPI Emulation Interface
25  * @ingroup io_emulators
26  * @{
27  */
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 #define EMUL_ESPI_HOST_CHIPSEL 0
34 
35 struct espi_emul;
36 
37 /**
38  * Passes eSPI virtual wires set request (virtual wire packet) to the emulator.
39  * The emulator updates the state (level) of its virtual wire.
40  *
41  * @param target The device Emulator instance
42  * @param vw The signal to be set.
43  * @param level The level of signal requested LOW(0) or HIGH(1).
44  *
45  * @retval 0 If successful.
46  * @retval -EIO General input / output error.
47  */
48 typedef int (*emul_espi_api_set_vw)(const struct emul *target, enum espi_vwire_signal vw,
49 				    uint8_t level);
50 
51 /**
52  * Passes eSPI virtual wires get request (virtual wire packet) to the emulator.
53  * The emulator returns the state (level) of its virtual wire.
54  *
55  * @param target The device Emulator instance
56  * @param vw The signal to be get.
57  * @param level The level of the signal to be get.
58  *
59  * @retval 0 If successful.
60  * @retval -EIO General input / output error.
61  */
62 typedef int (*emul_espi_api_get_vw)(const struct emul *target, enum espi_vwire_signal vw,
63 				    uint8_t *level);
64 
65 #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
66 /**
67  * Get the ACPI shared memory address owned by the emulator.
68  *
69  * @param target The device Emulator instance
70  *
71  * @retval The address of the memory.
72  */
73 typedef uintptr_t (*emul_espi_api_get_acpi_shm)(const struct emul *target);
74 #endif
75 
76 /**
77  * Find an emulator present on a eSPI bus
78  *
79  * At present the function is used only to find an emulator of the host
80  * device. It may be useful in systems with the SPI flash chips.
81  *
82  * @param dev eSPI emulation controller device
83  * @param chipsel Chip-select value
84  * @return espi_emul to use
85  * @return NULL if not found
86  */
87 typedef struct espi_emul *(*emul_find_emul)(const struct device *dev, unsigned int chipsel);
88 
89 /**
90  * Triggers an event on the emulator of eSPI controller side which causes
91  * calling specific callbacks.
92  *
93  * @param dev Device instance of emulated eSPI controller
94  * @param evt Event to be triggered
95  *
96  * @retval 0 If successful.
97  * @retval -EIO General input / output error.
98  */
99 typedef int (*emul_trigger_event)(const struct device *dev, struct espi_event *evt);
100 
101 /** Definition of the eSPI device emulator API */
102 struct emul_espi_device_api {
103 	emul_espi_api_set_vw set_vw;
104 	emul_espi_api_get_vw get_vw;
105 #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
106 	emul_espi_api_get_acpi_shm get_acpi_shm;
107 #endif
108 };
109 
110 /** Node in a linked list of emulators for eSPI devices */
111 struct espi_emul {
112 	sys_snode_t node;
113 	/** Target emulator - REQUIRED for all emulated bus nodes of any type */
114 	const struct emul *target;
115 	/** API provided for this device */
116 	const struct emul_espi_device_api *api;
117 	/** eSPI chip-select of the emulated device */
118 	uint16_t chipsel;
119 };
120 
121 /** Definition of the eSPI controller emulator API */
122 struct emul_espi_driver_api {
123 	/* The struct espi_driver_api has to be first in
124 	 * struct emul_espi_driver_api to make pointer casting working
125 	 */
126 	struct espi_driver_api espi_api;
127 	/* The rest, emulator specific functions */
128 	emul_trigger_event trigger_event;
129 	emul_find_emul find_emul;
130 };
131 
132 /**
133  * Register an emulated device on the controller
134  *
135  * @param dev Device that will use the emulator
136  * @param emul eSPI emulator to use
137  * @return 0 indicating success (always)
138  */
139 int espi_emul_register(const struct device *dev, struct espi_emul *emul);
140 
141 /**
142  * Sets the eSPI virtual wire on the host side, which will
143  * trigger a proper event(and callbacks) on the emulated eSPI controller
144  *
145  * @param espi_dev eSPI emulation controller device
146  * @param vw The signal to be set.
147  * @param level The level of the signal to be set.
148  *
149  * @retval 0 If successful.
150  * @retval -EIO General input / output error.
151  */
152 int emul_espi_host_send_vw(const struct device *espi_dev, enum espi_vwire_signal vw, uint8_t level);
153 
154 /**
155  * Perform port80 write on the emulated host side, which will
156  * trigger a proper event(and callbacks) on the emulated eSPI controller
157  *
158  * @param espi_dev eSPI emulation controller device
159  * @param data The date to be written.
160  *
161  * @retval 0 If successful.
162  * @retval -EIO General input / output error.
163  */
164 int emul_espi_host_port80_write(const struct device *espi_dev, uint32_t data);
165 
166 #ifdef CONFIG_ESPI_PERIPHERAL_ACPI_SHM_REGION
167 /**
168  * Get the host device's ACPI shared memory start address. The size of the region is
169  * CONFIG_EMUL_ESPI_HOST_ACPI_SHM_REGION_SIZE.
170  *
171  * @param espi_dev eSPI emulation controller device.
172  * @return Address of the start of the ACPI shared memory.
173  */
174 uintptr_t emul_espi_host_get_acpi_shm(const struct device *espi_dev);
175 #endif
176 
177 #ifdef __cplusplus
178 }
179 #endif
180 
181 /**
182  * @}
183  */
184 
185 #endif /* ZEPHYR_INCLUDE_DRIVERS_ESPI_SPI_EMUL_H_ */
186