TEMU  4.4
The Terma Emulator
PCIExpress.h
Go to the documentation of this file.
1 //===------------------------------------------------------------*- C++ -*-===//
2 //
3 // TEMU: The Terma Emulator
4 // (c) Terma 2021
5 // Authors: Daria Vorotnikova <davo (at) terma.com>
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef TEMU_BUS_PCIe_H
10 #define TEMU_BUS_PCIe_H
11 #include <assert.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 #include "temu-c/Bus/PCI.h"
16 #include "temu-c/Bus/PCIDefines.h"
17 #include "temu-c/Memory/Memory.h"
18 #include "temu-c/Support/Logging.h"
19 #include "temu-c/Support/Objsys.h"
20 
21 //===----------------------------------------------------------------------===//
22 //
23 // NOTE: PCIe interfaces is an experimental and unstable API
24 // It is subject to change until it is deemed stable enough.
25 //
26 //===----------------------------------------------------------------------===//
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 /**
32  * temu_PCIeMessageTypes:
33  * PCI Express Messages
34  * name = code
35  */
36 typedef enum {
63 } temu_PCIeMessageTypes;
64 
65 typedef struct {
66  void (*mapPciIo)(temu_Object *Obj, unsigned Device, unsigned Bar,
67  uint64_t Addr, uint64_t Len);
68  void (*unmapPciIo)(temu_Object *Obj, unsigned Device);
69  void (*mapPciMem)(temu_Object *Obj, unsigned Device, unsigned Bar,
70  uint64_t Addr, uint64_t Len);
71  void (*unmapPciMem)(temu_Object *Obj, unsigned Device);
72 } temu_PCIExpressBusIface;
73 TEMU_IFACE_REFERENCE_TYPE(temu_PCIExpressBus)
74 #define TEMU_PCIe_BUS_IFACE_TYPE "temu::PCIExpressBusIface"
75 
76 typedef struct {
77  void (*raiseReset)(temu_Object *);
78  void (*lowerReset)(temu_Object *);
81  void (*sendMessage)(void *, temu_PCIeMessageTypes msgType, uint8_t *payload);
83 } temu_PCIExpressBridgeIface;
84 TEMU_IFACE_REFERENCE_TYPE(temu_PCIExpressBridge)
85 #define TEMU_PCIe_BRIDGE_IFACE_TYPE "temu::PCIExpressBridgeIface"
86 
87 typedef struct temu_PCIExpressBus temu_PCIExpressBus;
88 typedef struct temu_PCIExpressBridge temu_PCIExpressBridge;
89 
90 typedef struct {
92  temu_PCIExpressBus *PrimaryBus;
93 } temu_PCIExpressDevice;
94 
97  uint8_t BusId;
98 
99  temu_PCIExpressBridge *ParentDev;
101 };
102 
104  temu_PCIExpressDevice Super;
105  temu_PCIExpressBus *SecondaryBus;
106  uint8_t PrimBusId;
107  uint8_t SecBusId;
108  uint8_t SubBusId;
109 };
110 
111 static inline temu_PCIExpressBus *
112 temu_pciGetRootBus(temu_PCIExpressDevice *device)
113 {
114  temu_PCIExpressBus *bus = device->PrimaryBus;
115 
116  while (bus->ParentDev != NULL) {
117  device = &bus->ParentDev->Super;
118  bus = device->PrimaryBus;
119  }
120  return bus;
121 }
122 
123 static inline void
124 temu_pcieSetPrimaryBusId(temu_PCIExpressBridge *C, uint8_t Val)
125 {
126  C->PrimBusId = Val;
127 }
128 static inline void
129 temu_pcieSetSecondaryBusId(temu_PCIExpressBridge *C, uint8_t Val)
130 {
131  C->SecBusId = Val;
132 }
133 static inline void
134 temu_pcieSetSubordinaryBusId(temu_PCIExpressBridge *C, uint8_t Val)
135 {
136  C->SubBusId = Val;
137 }
138 
139 static inline void
140 temu_pcieSetBusId(temu_PCIExpressBus *C, uint8_t Val)
141 {
142  C->BusId = Val;
143 }
144 static inline void
145 temu_pcieSetDeviceId(temu_PCIConfig config, uint16_t Val)
146 {
147  temu_pciSetConfig(config, TEMU_PCI_CONFIG_DEVICE_ID_OFFSET,
148  TEMU_PCI_CONFIG_DEVICE_ID_SIZE, Val);
149 }
150 
151 static inline void
152 temu_pcieSetVendorId(temu_PCIConfig config, uint16_t Val)
153 {
154  temu_pciSetConfig(config, TEMU_PCI_CONFIG_VENDOR_ID_OFFSET,
155  TEMU_PCI_CONFIG_VENDOR_ID_SIZE, Val);
156 }
157 
158 static inline void
159 temu_pcieSetStatus(temu_PCIConfig config, uint16_t Val)
160 {
161  temu_pciSetConfig(config, TEMU_PCI_CONFIG_STATUS_OFFSET,
162  TEMU_PCI_CONFIG_STATUS_SIZE, Val);
163 }
164 static inline uint16_t
165 temu_pcieReadStatus(temu_PCIConfig config)
166 {
167  return temu_pciGetConfig(config, TEMU_PCI_CONFIG_STATUS_OFFSET,
168  TEMU_PCI_CONFIG_STATUS_SIZE);
169 }
170 
171 static inline void
172 temu_pcieSetClassCode(temu_PCIConfig config, uint32_t Val)
173 {
174  temu_pciSetConfig(config, TEMU_PCI_CONFIG_CLASS_CODE_OFFSET,
175  TEMU_PCI_CONFIG_CLASS_CODE_SIZE, Val);
176 }
177 
178 static inline void
179 temu_pcieSetRevId(temu_PCIConfig config, uint8_t Val)
180 {
181  temu_pciSetConfig(config, TEMU_PCI_CONFIG_REVISION_ID_OFFSET,
182  TEMU_PCI_CONFIG_REVISION_ID_SIZE, Val);
183 }
184 
185 static inline void
186 temu_pcieSetBist(temu_PCIConfig config, uint8_t Val)
187 {
188  temu_pciSetConfig(config, TEMU_PCI_CONFIG_BIST_OFFSET,
189  TEMU_PCI_CONFIG_BIST_SIZE, Val);
190 }
191 
192 static inline void
193 temu_pcieSetHeaderType(temu_PCIConfig config, uint8_t Val)
194 {
195  temu_pciSetConfig(config, TEMU_PCI_CONFIG_HEADER_TYPE_OFFSET,
196  TEMU_PCI_CONFIG_HEADER_TYPE_SIZE, Val);
197 }
198 
199 static inline void
200 temu_pcieSetLatencyTimer(temu_PCIConfig config, uint8_t Val)
201 {
202  temu_pciSetConfig(config, TEMU_PCI_CONFIG_LATENCY_TIMER_OFFSET,
203  TEMU_PCI_CONFIG_LATENCY_TIMER_SIZE, Val);
204 }
205 
206 static inline void
207 temu_pcieSetCacheLineSize(temu_PCIConfig config, uint8_t Val)
208 {
209  temu_pciSetConfig(config, TEMU_PCI_CONFIG_CACHELINE_SIZE_OFFSET,
210  TEMU_PCI_CONFIG_CACHELINE_SIZE_SIZE, Val);
211 }
212 
213 static inline void
214 temu_pcieSetInterruptPin0(temu_PCIConfig config, uint8_t Val)
215 {
216  assert(Val < 0x05);
217  temu_pciSetConfig(config, TEMU_PCI_TYPE_00_INTERRUPT_PIN_OFFSET,
218  TEMU_PCI_TYPE_00_INTERRUPT_PIN_SIZE, Val);
219 }
220 
221 static inline void
222 temu_pcieSetSubsystemId(temu_PCIConfig config, uint16_t Val)
223 {
224  assert(temu_pciGetConfig(config, TEMU_PCI_CONFIG_HEADER_TYPE_OFFSET,
225  TEMU_PCI_CONFIG_HEADER_TYPE_SIZE) == 0);
226  temu_pciSetConfig(config, TEMU_PCI_TYPE_00_SUBSYSTEM_ID_OFFSET,
227  TEMU_PCI_TYPE_00_SUBSYSTEM_ID_SIZE, Val);
228 }
229 
230 static inline void
231 temu_pcieSetSubsystemVendorId(temu_PCIConfig config, uint16_t Val)
232 {
233  assert(temu_pciGetConfig(config, TEMU_PCI_CONFIG_HEADER_TYPE_OFFSET,
234  TEMU_PCI_CONFIG_HEADER_TYPE_SIZE) == 0);
235  temu_pciSetConfig(config, TEMU_PCI_TYPE_00_SUBSYSTEM_VENDOR_ID_OFFSET,
236  TEMU_PCI_TYPE_00_SUBSYSTEM_VENDOR_ID_SIZE, Val);
237 }
238 static inline void
239 temu_pcieSetPrimaryBusNumber(temu_PCIConfig config, uint8_t Val)
240 {
241  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_PRIMARY_BUS_NUMBER_OFFSET,
242  TEMU_PCI_TYPE_01_PRIMARY_BUS_NUMBER_SIZE, Val);
243 }
244 static inline void
245 temu_pcieSetSecondaryBusNumber(temu_PCIConfig config, uint8_t Val)
246 {
247  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_SECONDARY_BUS_NUMBER_OFFSET,
248  TEMU_PCI_TYPE_01_SECONDARY_BUS_NUMBER_SIZE, Val);
249 }
250 static inline void
251 temu_pcieSetSubordinateBusNumber(temu_PCIConfig config, uint8_t Val)
252 {
253  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_SUBORDINATE_BUS_NUMBER_OFFSET,
254  TEMU_PCI_TYPE_01_SUBORDINATE_BUS_NUMBER_SIZE, Val);
255 }
256 static inline void
257 temu_pcieSetIOBase(temu_PCIConfig config, uint8_t Val)
258 {
259  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_IO_BASE_OFFSET,
260  TEMU_PCI_TYPE_01_IO_BASE_SIZE, Val);
261 }
262 static inline void
263 temu_pcieSetIOLimit(temu_PCIConfig config, uint8_t Val)
264 {
265  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_IO_LIMIT_OFFSET,
266  TEMU_PCI_TYPE_01_IO_LIMIT_SIZE, Val);
267 }
268 static inline void
269 temu_pcieSetSecondaryStatus(temu_PCIConfig config, uint16_t Val)
270 {
271  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_SECONDARY_STATUS_OFFSET,
272  TEMU_PCI_TYPE_01_SECONDARY_STATUS_SIZE, Val);
273 }
274 static inline void
275 temu_pcieSetMemoryBase(temu_PCIConfig config, uint16_t Val)
276 {
277  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_MEMORY_BASE_OFFSET,
278  TEMU_PCI_TYPE_01_MEMORY_BASE_SIZE, Val);
279 }
280 static inline void
281 temu_pcieSetMemoryLimit(temu_PCIConfig config, uint16_t Val)
282 {
283  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_MEMORY_LIMIT_OFFSET,
284  TEMU_PCI_TYPE_01_MEMORY_LIMIT_SIZE, Val);
285 }
286 static inline void
287 temu_pcieSetPrefetchableMemoryBase(temu_PCIConfig config, uint16_t Val)
288 {
289  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_PREFETCHABLE_MEMORY_BASE_OFFSET,
290  TEMU_PCI_TYPE_01_PREFETCHABLE_MEMORY_BASE_SIZE, Val);
291 }
292 static inline void
293 temu_pcieSetPrefetchableMemoryLimit(temu_PCIConfig config, uint16_t Val)
294 {
295  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_PREFETCHABLE_MEMORY_LIMIT_OFFSET,
296  TEMU_PCI_TYPE_01_PREFETCHABLE_MEMORY_LIMIT_SIZE, Val);
297 }
298 static inline void
299 temu_pcieSetInterruptLine(temu_PCIConfig config, uint8_t Val)
300 {
301  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_INTERRUPT_LINE_OFFSET,
302  TEMU_PCI_TYPE_01_INTERRUPT_LINE_SIZE, Val);
303 }
304 static inline void
305 temu_pcieSetInterruptPin1(temu_PCIConfig config, uint8_t Val)
306 {
307  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_INTERRUPT_PIN_OFFSET,
308  TEMU_PCI_TYPE_01_INTERRUPT_PIN_SIZE, Val);
309 }
310 static inline void
311 temu_pcieSetBridgeControl(temu_PCIConfig config, uint16_t Val)
312 {
313  temu_pciSetConfig(config, TEMU_PCI_TYPE_01_BRIDGE_CONTROL_OFFSET,
314  TEMU_PCI_TYPE_01_BRIDGE_CONTROL_SIZE, Val);
315 }
316 
317 static inline uint16_t
318 temu_pcieReadBridgeControl(temu_PCIConfig config)
319 {
320  return temu_pciGetConfig(config, TEMU_PCI_TYPE_01_BRIDGE_CONTROL_OFFSET,
321  TEMU_PCI_TYPE_01_BRIDGE_CONTROL_SIZE);
322 }
323 
324 #ifdef __cplusplus
325 }
326 #endif
327 #endif // !TEMU_BUS_PCIe_H
temu_PCIExpressBusIface::unmapPciMem
void(* unmapPciMem)(temu_Object *Obj, unsigned Device)
Definition: PCIExpress.h:71
temu_PCIExpressBridgeIface::disconnect
void(* disconnect)(temu_Object *, temu_Object *)
Definition: PCIExpress.h:80
temu_PCIExpressBridge::SecBusId
uint8_t SecBusId
Definition: PCIExpress.h:107
temu_PCIExpressBridgeIface::raiseReset
void(* raiseReset)(temu_Object *)
Definition: PCIExpress.h:77
temu_PCIExpressBusIface::mapPciMem
void(* mapPciMem)(temu_Object *Obj, unsigned Device, unsigned Bar, uint64_t Addr, uint64_t Len)
Definition: PCIExpress.h:69
tePMT_PowerIndicatorOn
@ tePMT_PowerIndicatorOn
Definition: PCIExpress.h:59
tePMT_DeassertIntA
@ tePMT_DeassertIntA
Definition: PCIExpress.h:41
temu_PCIExpressBusIface::mapPciIo
void(* mapPciIo)(temu_Object *Obj, unsigned Device, unsigned Bar, uint64_t Addr, uint64_t Len)
Definition: PCIExpress.h:66
temu_PCIExpressBridge::PrimBusId
uint8_t PrimBusId
Definition: PCIExpress.h:106
temu_PCIExpressDevice::Super
temu_PCIDevice Super
Definition: PCIExpress.h:91
tePMT_DeassertIntB
@ tePMT_DeassertIntB
Definition: PCIExpress.h:42
tePMT_VendorDefinedType1
@ tePMT_VendorDefinedType1
Definition: PCIExpress.h:55
temu_PCIExpressDevice::PrimaryBus
temu_PCIExpressBus * PrimaryBus
Definition: PCIExpress.h:92
temu_PCIExpressBridgeIface::lowerReset
void(* lowerReset)(temu_Object *)
Definition: PCIExpress.h:78
temu_PCIExpressBusIface::unmapPciIo
void(* unmapPciIo)(temu_Object *Obj, unsigned Device)
Definition: PCIExpress.h:68
temu_PCIExpressBridge::Super
temu_PCIExpressDevice Super
Definition: PCIExpress.h:104
tePMT_PmPme
@ tePMT_PmPme
Definition: PCIExpress.h:46
tePMT_AttentionButtonPressed
@ tePMT_AttentionButtonPressed
Definition: PCIExpress.h:62
tePMT_DeassertIntC
@ tePMT_DeassertIntC
Definition: PCIExpress.h:43
tePMT_PmActiveStateNak
@ tePMT_PmActiveStateNak
Definition: PCIExpress.h:45
tePMT_PowerIndicatorOff
@ tePMT_PowerIndicatorOff
Definition: PCIExpress.h:61
tePMT_PmeTurnOff
@ tePMT_PmeTurnOff
Definition: PCIExpress.h:47
tePMT_VendorDefinedType0
@ tePMT_VendorDefinedType0
Definition: PCIExpress.h:54
tePMT_AssertIntC
@ tePMT_AssertIntC
Definition: PCIExpress.h:39
temu_PCIExpressBridgeIface::setUpstreamBridge
void(* setUpstreamBridge)(temu_Object *)
Definition: PCIExpress.h:82
tePMT_AssertIntB
@ tePMT_AssertIntB
Definition: PCIExpress.h:38
temu_PCIExpressBus::Super
temu_Object Super
Definition: PCIExpress.h:96
tePMT_AssertIntA
@ tePMT_AssertIntA
Definition: PCIExpress.h:37
tePMT_AttentionIndicatorOn
@ tePMT_AttentionIndicatorOn
Definition: PCIExpress.h:56
tePMT_AttentionIndicatorBlink
@ tePMT_AttentionIndicatorBlink
Definition: PCIExpress.h:57
temu_PCIExpressBridge::SecondaryBus
temu_PCIExpressBus * SecondaryBus
Definition: PCIExpress.h:105
temu_PCIExpressBus::ParentDev
temu_PCIExpressBridge * ParentDev
Definition: PCIExpress.h:99
tePMT_AssertIntD
@ tePMT_AssertIntD
Definition: PCIExpress.h:40
tePMT_ErrFatal
@ tePMT_ErrFatal
Definition: PCIExpress.h:51
temu_PCIExpressBridgeIface::sendMessage
void(* sendMessage)(void *, temu_PCIeMessageTypes msgType, uint8_t *payload)
Definition: PCIExpress.h:81
temu_PCIExpressBridge::SubBusId
uint8_t SubBusId
Definition: PCIExpress.h:108
temu_PCIExpressBus::ChildrenDevs
temu_PCIDeviceIfaceRefArray ChildrenDevs
Definition: PCIExpress.h:100
temu_PCIExpressBridgeIface::connect
void(* connect)(temu_Object *, temu_Object *)
Definition: PCIExpress.h:79
temu_PCIExpressBridge
struct temu_PCIExpressBridge temu_PCIExpressBridge
Definition: PCIExpress.h:88
temu_PCIExpressBus
struct temu_PCIExpressBus temu_PCIExpressBus
Definition: PCIExpress.h:87
tePMT_PmToAck
@ tePMT_PmToAck
Definition: PCIExpress.h:48
tePMT_AttentionIndicatorOff
@ tePMT_AttentionIndicatorOff
Definition: PCIExpress.h:58
tePMT_ErrCor
@ tePMT_ErrCor
Definition: PCIExpress.h:49
tePMT_SetSlotPowerLimit
@ tePMT_SetSlotPowerLimit
Definition: PCIExpress.h:53
tePMT_PowerIndicatorBlink
@ tePMT_PowerIndicatorBlink
Definition: PCIExpress.h:60
temu_PCIExpressBus::BusId
uint8_t BusId
Definition: PCIExpress.h:97
tePMT_Unlock
@ tePMT_Unlock
Definition: PCIExpress.h:52
tePMT_ErrNonFatal
@ tePMT_ErrNonFatal
Definition: PCIExpress.h:50
tePMT_DeassertIntD
@ tePMT_DeassertIntD
Definition: PCIExpress.h:44