TEMU  4.4
The Terma Emulator
PCI.h
Go to the documentation of this file.
1 //===------------------------------------------------------------*- C++ -*-===//
2 //
3 // TEMU: The Terma Emulator
4 // (c) Terma 2019
5 // Authors: Mattias Holm <maho (at) terma.com>
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef TEMU_BUS_PCI_H
10 #define TEMU_BUS_PCI_H
11 #include <assert.h>
12 #include <stdint.h>
13 #include <stdlib.h>
14 
15 #include "temu-c/Bus/PCIDefines.h"
16 #include "temu-c/Memory/Memory.h"
17 #include "temu-c/Support/Logging.h"
18 #include "temu-c/Support/Objsys.h"
19 
20 //===----------------------------------------------------------------------===//
21 //
22 // NOTE: PCI interfaces is an experimental and unstable API
23 // It is subject to change until it is deemed stable enough.
24 //
25 //===----------------------------------------------------------------------===//
26 
27 typedef struct {
34 } temu_PCIDeviceVTable;
35 
36 #define TEMU_PCI_CONFIG_BYTES 256
37 #define TEMU_PCIE_CONFIG_BYTES 4096
38 #define TEMU_PCI_CONFIG_WORDS 64
39 #define TEMU_PCIE_CONFIG_WORDS 1024
40 
41 typedef struct {
42  size_t Size; // In bytes
43  uint32_t
44  *Data; // Configuration space data must be aligned at 4 byte boundaries
45 } temu_PCIConfig;
46 
47 typedef struct {
48  void (*mapPciIo)(temu_Object *Obj, unsigned Device, unsigned Bar,
49  uint64_t Addr, uint64_t Len);
50  void (*unmapPciIo)(temu_Object *Obj, unsigned Device);
51  void (*mapPciMem)(temu_Object *Obj, unsigned Device, unsigned Bar,
52  uint64_t Addr, uint64_t Len);
53  void (*unmapPciMem)(temu_Object *Obj, unsigned Device);
54 } temu_PCIBusIface;
55 TEMU_IFACE_REFERENCE_TYPE(temu_PCIBus)
56 #define TEMU_PCI_BUS_IFACE_TYPE "temu::PCIBusIface"
57 
58 typedef struct {
59  void (*raiseReset)(temu_Object *);
60  void (*lowerReset)(temu_Object *);
63 } temu_PCIBridgeIface;
64 TEMU_IFACE_REFERENCE_TYPE(temu_PCIBridge)
65 #define TEMU_PCI_BRIDGE_IFACE_TYPE "temu::PCIBridgeIface"
66 
67 typedef struct {
68  void (*startSelfTest)(
69  temu_Object *); // Optional, called when BIST bit 6 is set
70  temu_PCIConfig (*getPciConfig)(temu_Object *);
71  // Writes to config space forwarded here
72  void (*writeConfig)(temu_Object *, uint32_t offset, uint32_t value);
73  uint32_t (*readConfig)(temu_Object *Obj, uint32_t offset);
74  uint64_t (*getPciBarSize)(temu_Object *, unsigned bar);
75  uint64_t (*getPciExpansionROMSize)(temu_Object *);
77  uint8_t type);
78 } temu_PCIDeviceIface;
79 TEMU_IFACE_REFERENCE_TYPE(temu_PCIDevice)
80 #define TEMU_PCI_DEVICE_IFACE_TYPE "temu::PCIDeviceIface"
81 
82 typedef struct {
84  temu_PCIConfig Conf;
85 } temu_PCIDevice;
86 
87 #ifdef __cplusplus
88 extern "C" {
89 #endif
90 
93 TEMU_API uint32_t temu_pciGetConfig(temu_PCIConfig config, uint32_t offset,
94  uint32_t size);
95 
96 #ifdef __cplusplus
97 }
98 #endif
99 
100 static inline void
101 temu_pciDeviceRegister(temu_Class *C)
102 {
103  /*
104  temu_addProperty(C, "pciConfigDeviceVendorID",
105  offsetof(temu_PCIDevice, Conf.DeviceVendorID), teTY_U32,
106  1, // Number of elements (1 = scalar)
107  NULL, NULL, "PCI Device and Vendor ID");
108 
109  temu_addProperty(C, "pciConfigStatusCommand",
110  offsetof(temu_PCIDevice, Conf.StatusCommand), teTY_U32,
111  1, // Number of elements (1 = scalar)
112  NULL, NULL, "PCI Status and Command Register");
113 
114  temu_addProperty(C, "pciConfigClassCodeRevID",
115  offsetof(temu_PCIDevice, Conf.ClassCodeRevID), teTY_U32,
116  1, // Number of elements (1 = scalar)
117  NULL, NULL, "PCI Class Code and Revision ID");
118 
119  temu_addProperty(
120  C, "pciConfigBistHeaderLatencyCacheLineAndSize",
121  offsetof(temu_PCIDevice, Conf.BISTHeaderTypeLatencyTimerCacheLineSize),
122  teTY_U32,
123  1, // Number of elements (1 = scalar)
124  NULL, NULL, "PCI BIST, Header Type, Latency and cache line size");
125 
126  temu_addProperty(C, "pciConfigBAR", offsetof(temu_PCIDevice, Conf.BAR),
127  teTY_U32,
128  6, // Number of elements (1 = scalar)
129  NULL, NULL, "PCI Base Address Registers");
130 
131  temu_addProperty(C, "pciConfigCardbusCISPointer",
132  offsetof(temu_PCIDevice, Conf.CardbusCISPointer), teTY_U32,
133  1, // Number of elements (1 = scalar)
134  NULL, NULL, "PCI Cardbus CIS Pointer");
135 
136  temu_addProperty(C, "pciConfigSubsystemVendorID",
137  offsetof(temu_PCIDevice, Conf.SubsystemVendorID), teTY_U32,
138  1, // Number of elements (1 = scalar)
139  NULL, NULL, "PCI Subsystem and Subsystem Vendor ID");
140 
141  temu_addProperty(C, "pciConfigExpansionROMBaseAddress",
142  offsetof(temu_PCIDevice, Conf.ExpansionROMBaseAddress),
143  teTY_U32,
144  1, // Number of elements (1 = scalar)
145  NULL, NULL, "PCI Expansion ROM base address");
146 
147  temu_addProperty(C, "pciConfigCapabilityPointer",
148  offsetof(temu_PCIDevice, Conf.CapPointer), teTY_U32,
149  1, // Number of elements (1 = scalar)
150  NULL, NULL, "PCI Capability list pointer");
151 
152  temu_addProperty(
153  C, "pciConfigMaxLatMinGntIntPinLine",
154  offsetof(temu_PCIDevice, Conf.MaxLatMinGntIntPinLine), teTY_U32,
155  1, // Number of elements (1 = scalar)
156  NULL, NULL, "PCI Max latency, min gnt, int pin and int line");
157 */
158 }
159 
160 static inline void
161 temu_pciSetDeviceId(temu_PCIConfig C, uint16_t Val)
162 {
163  temu_pciSetConfig(C, TEMU_PCI_CONFIG_DEVICE_ID_OFFSET,
164  TEMU_PCI_CONFIG_DEVICE_ID_SIZE, Val);
165 }
166 
167 static inline void
168 temu_pciSetVendorId(temu_PCIConfig C, uint16_t Val)
169 {
170  temu_pciSetConfig(C, TEMU_PCI_CONFIG_VENDOR_ID_OFFSET,
171  TEMU_PCI_CONFIG_VENDOR_ID_SIZE, Val);
172 }
173 
174 static inline void
175 temu_pciSetStatus(temu_PCIConfig C, uint16_t Val)
176 {
177  temu_pciSetConfig(C, TEMU_PCI_CONFIG_STATUS_OFFSET,
178  TEMU_PCI_CONFIG_STATUS_SIZE, Val);
179 }
180 
181 static inline void
182 temu_pciSetClassCode(temu_PCIConfig C, uint32_t Val)
183 {
184  temu_pciSetConfig(C, TEMU_PCI_CONFIG_CLASS_CODE_OFFSET,
185  TEMU_PCI_CONFIG_CLASS_CODE_SIZE, Val);
186 }
187 
188 static inline void
189 temu_pciSetRevId(temu_PCIConfig C, uint8_t Val)
190 {
191  temu_pciSetConfig(C, TEMU_PCI_CONFIG_REVISION_ID_OFFSET,
192  TEMU_PCI_CONFIG_REVISION_ID_SIZE, Val);
193 }
194 
195 static inline void
196 temu_pciSetBist(temu_PCIConfig C, uint8_t Val)
197 {
198  temu_pciSetConfig(C, TEMU_PCI_CONFIG_BIST_OFFSET, TEMU_PCI_CONFIG_BIST_SIZE,
199  Val);
200 }
201 
202 static inline void
203 temu_pciSetHeaderType(temu_PCIConfig C, uint8_t Val)
204 {
205  temu_pciSetConfig(C, TEMU_PCI_CONFIG_HEADER_TYPE_OFFSET,
206  TEMU_PCI_CONFIG_HEADER_TYPE_SIZE, Val);
207 }
208 
209 static inline void
210 temu_pciSetLatencyTimer(temu_PCIConfig C, uint8_t Val)
211 {
212  temu_pciSetConfig(C, TEMU_PCI_CONFIG_LATENCY_TIMER_OFFSET,
213  TEMU_PCI_CONFIG_LATENCY_TIMER_SIZE, Val);
214 }
215 
216 static inline void
217 temu_pciSetCacheLineSize(temu_PCIConfig C, uint8_t Val)
218 {
219  temu_pciSetConfig(C, TEMU_PCI_CONFIG_CACHELINE_SIZE_OFFSET,
220  TEMU_PCI_CONFIG_CACHELINE_SIZE_SIZE, Val);
221 }
222 
223 static inline void
224 temu_pciSetInterruptPin(temu_PCIConfig C, uint8_t Val)
225 {
226  assert(Val < 0x05);
227  temu_pciSetConfig(C, TEMU_PCI_TYPE_00_INTERRUPT_PIN_OFFSET,
228  TEMU_PCI_TYPE_00_INTERRUPT_PIN_SIZE, Val);
229 }
230 
231 static inline void
232 temu_pciSetSubsystemId(temu_PCIConfig C, uint16_t Val)
233 {
234  assert(temu_pciGetConfig(C, TEMU_PCI_CONFIG_HEADER_TYPE_OFFSET,
235  TEMU_PCI_CONFIG_HEADER_TYPE_SIZE) == 0);
236  temu_pciSetConfig(C, TEMU_PCI_TYPE_00_SUBSYSTEM_ID_OFFSET,
237  TEMU_PCI_TYPE_00_SUBSYSTEM_ID_SIZE, Val);
238 }
239 
240 static inline void
241 temu_pciSetSubsystemVendorId(temu_PCIConfig C, uint16_t Val)
242 {
243  assert(temu_pciGetConfig(C, TEMU_PCI_CONFIG_HEADER_TYPE_OFFSET,
244  TEMU_PCI_CONFIG_HEADER_TYPE_SIZE) == 0);
245  temu_pciSetConfig(C, TEMU_PCI_TYPE_00_SUBSYSTEM_VENDOR_ID_OFFSET,
246  TEMU_PCI_TYPE_00_SUBSYSTEM_VENDOR_ID_SIZE, Val);
247 }
248 
249 #endif // !TEMU_BUS_PCI_H
temu_PCIDeviceVTable::ConfigBlock
temu_MemoryIface ConfigBlock
Definition: PCI.h:31
temu_PCIDeviceVTable::IoAccess
temu_MemAccessIface IoAccess
Definition: PCI.h:29
temu_PCIDeviceVTable::IoBlock
temu_MemoryIface IoBlock
Definition: PCI.h:32
temu_pciSetConfig
TEMU_API void temu_pciSetConfig(temu_PCIConfig config, uint32_t offset, uint32_t size, uint32_t value)
temu_PCIBusIface::unmapPciIo
void(* unmapPciIo)(temu_Object *Obj, unsigned Device)
Definition: PCI.h:50
temu_PCIDevice::Super
temu_Object Super
Definition: PCI.h:83
temu_PCIBridgeIface::connect
void(* connect)(temu_Object *, temu_Object *)
Definition: PCI.h:61
temu_PCIDeviceIface::writeConfig
void(* writeConfig)(temu_Object *, uint32_t offset, uint32_t value)
Definition: PCI.h:72
temu_PCIDeviceIface::startSelfTest
void(* startSelfTest)(temu_Object *)
Definition: PCI.h:68
temu_PCIBusIface::mapPciMem
void(* mapPciMem)(temu_Object *Obj, unsigned Device, unsigned Bar, uint64_t Addr, uint64_t Len)
Definition: PCI.h:51
temu_PCIDeviceVTable::MemBlock
temu_MemoryIface MemBlock
Definition: PCI.h:33
temu_PCIDeviceVTable::ConfigAccess
temu_MemAccessIface ConfigAccess
Definition: PCI.h:28
temu_PCIConfig::Data
uint32_t * Data
Definition: PCI.h:44
temu_PCIBusIface::mapPciIo
void(* mapPciIo)(temu_Object *Obj, unsigned Device, unsigned Bar, uint64_t Addr, uint64_t Len)
Definition: PCI.h:48
temu_PCIBridgeIface::lowerReset
void(* lowerReset)(temu_Object *)
Definition: PCI.h:60
temu_PCIConfig::Size
size_t Size
Definition: PCI.h:42
temu_PCIDevice::Conf
temu_PCIConfig Conf
Definition: PCI.h:84
temu_PCIDeviceVTable::MemAccess
temu_MemAccessIface MemAccess
Definition: PCI.h:30
temu_PCIBridgeIface::raiseReset
void(* raiseReset)(temu_Object *)
Definition: PCI.h:59
temu_PCIDeviceIface::getPciBarIface
temu_MemAccessIface *(* getPciBarIface)(temu_Object *, unsigned BarId, uint8_t type)
Definition: PCI.h:76
temu_PCIBusIface::unmapPciMem
void(* unmapPciMem)(temu_Object *Obj, unsigned Device)
Definition: PCI.h:53
temu_PCIBridgeIface::disconnect
void(* disconnect)(temu_Object *, temu_Object *)
Definition: PCI.h:62