TEMU  4.2
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 
14 #include "temu-c/Bus/PCIDefines.h"
15 #include "temu-c/Memory/Memory.h"
16 #include "temu-c/Support/Logging.h"
17 #include "temu-c/Support/Objsys.h"
18 
19 //===----------------------------------------------------------------------===//
20 //
21 // NOTE: PCI interfaces is an experimental and unstable API
22 // It is subject to change until it is deemed stable enough.
23 //
24 //===----------------------------------------------------------------------===//
25 
26 typedef struct {
33 } temu_PCIDeviceVTable;
34 
35 typedef struct {
36  uint32_t DeviceVendorID;
37  uint32_t StatusCommand;
38  uint32_t ClassCodeRevID;
40  uint32_t BAR[6];
44  uint32_t CapPointer;
46 } temu_PCIConfig;
47 
48 typedef struct {
49  void (*mapPciIo)(temu_Object *Obj, unsigned Device, unsigned Bar,
50  uint64_t Addr, uint64_t Len);
51  void (*unmapPciIo)(temu_Object *Obj, unsigned Device);
52  void (*mapPciMem)(temu_Object *Obj, unsigned Device, unsigned Bar,
53  uint64_t Addr, uint64_t Len);
54  void (*unmapPciMem)(temu_Object *Obj, unsigned Device);
55 } temu_PCIBusIface;
56 TEMU_IFACE_REFERENCE_TYPE(temu_PCIBus)
57 #define TEMU_PCI_BUS_IFACE_TYPE "temu::PCIBusIface"
58 
59 typedef struct {
60  void (*raiseReset)(temu_Object *);
61  void (*lowerReset)(temu_Object *);
64 } temu_PCIBridgeIface;
65 TEMU_IFACE_REFERENCE_TYPE(temu_PCIBridge)
66 #define TEMU_PCI_BRIDGE_IFACE_TYPE "temu::PCIBridgeIface"
67 
68 typedef struct {
69  void (*startSelfTest)(
70  temu_Object *); // Optional, called when BIST bit 6 is set
71  temu_PCIConfig *(*getPciConfig)(temu_Object *);
72  // Writes to config space forwarded here
73  void (*writeConfig)(temu_Object *, uint32_t offset, uint32_t value);
74  uint32_t (*readConfig)(temu_Object *Obj, uint32_t offset);
75  uint64_t (*getPciBarSize)(temu_Object *, unsigned bar);
76  uint64_t (*getPciExpansionROMSize)(temu_Object *);
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 static inline void
88 temu_pciDeviceRegister(temu_Class *C)
89 {
90  temu_addProperty(C, "pciConfigDeviceVendorID",
91  offsetof(temu_PCIDevice, Conf.DeviceVendorID), teTY_U32,
92  1, // Number of elements (1 = scalar)
93  NULL, NULL, "PCI Device and Vendor ID");
94 
95  temu_addProperty(C, "pciConfigStatusCommand",
96  offsetof(temu_PCIDevice, Conf.StatusCommand), teTY_U32,
97  1, // Number of elements (1 = scalar)
98  NULL, NULL, "PCI Status and Command Register");
99 
100  temu_addProperty(C, "pciConfigClassCodeRevID",
101  offsetof(temu_PCIDevice, Conf.ClassCodeRevID), teTY_U32,
102  1, // Number of elements (1 = scalar)
103  NULL, NULL, "PCI Class Code and Revision ID");
104 
105  temu_addProperty(
106  C, "pciConfigBistHeaderLatencyCacheLineAndSize",
107  offsetof(temu_PCIDevice, Conf.BISTHeaderTypeLatencyTimerCacheLineSize),
108  teTY_U32,
109  1, // Number of elements (1 = scalar)
110  NULL, NULL, "PCI BIST, Header Type, Latency and cache line size");
111 
112  temu_addProperty(C, "pciConfigBAR", offsetof(temu_PCIDevice, Conf.BAR),
113  teTY_U32,
114  6, // Number of elements (1 = scalar)
115  NULL, NULL, "PCI Base Address Registers");
116 
117  temu_addProperty(C, "pciConfigCardbusCISPointer",
118  offsetof(temu_PCIDevice, Conf.CardbusCISPointer), teTY_U32,
119  1, // Number of elements (1 = scalar)
120  NULL, NULL, "PCI Cardbus CIS Pointer");
121 
122  temu_addProperty(C, "pciConfigSubsystemVendorID",
123  offsetof(temu_PCIDevice, Conf.SubsystemVendorID), teTY_U32,
124  1, // Number of elements (1 = scalar)
125  NULL, NULL, "PCI Subsystem and Subsystem Vendor ID");
126 
127  temu_addProperty(C, "pciConfigExpansionROMBaseAddress",
128  offsetof(temu_PCIDevice, Conf.ExpansionROMBaseAddress),
129  teTY_U32,
130  1, // Number of elements (1 = scalar)
131  NULL, NULL, "PCI Expansion ROM base address");
132 
133  temu_addProperty(C, "pciConfigCapabilityPointer",
134  offsetof(temu_PCIDevice, Conf.CapPointer), teTY_U32,
135  1, // Number of elements (1 = scalar)
136  NULL, NULL, "PCI Capability list pointer");
137 
138  temu_addProperty(
139  C, "pciConfigMaxLatMinGntIntPinLine",
140  offsetof(temu_PCIDevice, Conf.MaxLatMinGntIntPinLine), teTY_U32,
141  1, // Number of elements (1 = scalar)
142  NULL, NULL, "PCI Max latency, min gnt, int pin and int line");
143 }
144 
145 static inline void
146 temu_pciSetDeviceId(temu_PCIConfig *C, uint16_t Val)
147 {
148  C->DeviceVendorID = ((uint32_t)Val << 16) | (C->DeviceVendorID & 0xffff);
149 }
150 
151 static inline void
152 temu_pciSetVendorId(temu_PCIConfig *C, uint16_t Val)
153 {
154  C->DeviceVendorID = (uint32_t)Val | (C->DeviceVendorID & 0xffff0000);
155 }
156 
157 static inline void
158 temu_pciSetStatus(temu_PCIConfig *C, uint16_t Val)
159 {
160  C->StatusCommand = ((uint32_t)Val << 16) | (C->StatusCommand & 0xffff);
161 }
162 
163 static inline void
164 temu_pciSetClassCode(temu_PCIConfig *C, uint32_t Val)
165 {
166  C->ClassCodeRevID &= 0x000000ff;
167  C->ClassCodeRevID |= Val << 8;
168 }
169 
170 static inline void
171 temu_pciSetRevId(temu_PCIConfig *C, uint8_t Val)
172 {
173  C->ClassCodeRevID &= 0xffffff00;
174  C->ClassCodeRevID |= Val;
175 }
176 
177 static inline void
178 temu_pciSetBist(temu_PCIConfig *C, uint8_t Val)
179 {
181  ((uint32_t)Val << 24) |
183 }
184 
185 static inline void
186 temu_pciSetHeaderType(temu_PCIConfig *C, uint8_t Val)
187 {
189  ((uint32_t)Val << 16) |
191 }
192 
193 static inline void
194 temu_pciSetLatencyTimer(temu_PCIConfig *C, uint8_t Val)
195 {
197  ((uint32_t)Val << 8) |
199 }
200 
201 static inline void
202 temu_pciSetCacheLineSize(temu_PCIConfig *C, uint8_t Val)
203 {
205  ((uint32_t)Val << 0) |
207 }
208 
209 static inline void
210 temu_pciSetInterruptPin(temu_PCIConfig *C, uint8_t Val)
211 {
212  assert(Val < 0x05);
214  ((uint32_t)Val << 8) | (C->MaxLatMinGntIntPinLine & 0xffff00ff);
215 }
216 
217 static inline void
218 temu_pciSetSubsystemId(temu_PCIConfig *C, uint16_t Val)
219 {
221  (uint32_t)Val << 16 | (C->SubsystemVendorID & 0x0000ffff);
222 }
223 
224 static inline void
225 temu_pciSetSubsystemVendorId(temu_PCIConfig *C, uint16_t Val)
226 {
228  (uint32_t)Val << 0 | (C->SubsystemVendorID & 0xffff0000);
229 }
230 
231 #endif // !TEMU_BUS_PCI_H
temu_PCIConfig::CapPointer
uint32_t CapPointer
Definition: PCI.h:44
temu_PCIDeviceVTable::ConfigBlock
temu_MemoryIface ConfigBlock
Definition: PCI.h:30
temu_PCIConfig::StatusCommand
uint32_t StatusCommand
Definition: PCI.h:37
temu_PCIDeviceVTable::IoAccess
temu_MemAccessIface IoAccess
Definition: PCI.h:28
temu_PCIConfig::DeviceVendorID
uint32_t DeviceVendorID
Definition: PCI.h:36
temu_PCIDeviceVTable::IoBlock
temu_MemoryIface IoBlock
Definition: PCI.h:31
temu_PCIConfig::BISTHeaderTypeLatencyTimerCacheLineSize
uint32_t BISTHeaderTypeLatencyTimerCacheLineSize
Definition: PCI.h:39
temu_PCIBusIface::unmapPciIo
void(* unmapPciIo)(temu_Object *Obj, unsigned Device)
Definition: PCI.h:51
temu_PCIConfig::ExpansionROMBaseAddress
uint32_t ExpansionROMBaseAddress
Definition: PCI.h:43
temu_PCIDevice::Super
temu_Object Super
Definition: PCI.h:83
temu_PCIBridgeIface::connect
void(* connect)(temu_Object *, temu_Object *)
Definition: PCI.h:62
temu_PCIDeviceIface::writeConfig
void(* writeConfig)(temu_Object *, uint32_t offset, uint32_t value)
Definition: PCI.h:73
temu_PCIDeviceIface::startSelfTest
void(* startSelfTest)(temu_Object *)
Definition: PCI.h:69
temu_PCIConfig::CardbusCISPointer
uint32_t CardbusCISPointer
Definition: PCI.h:41
temu_PCIBusIface::mapPciMem
void(* mapPciMem)(temu_Object *Obj, unsigned Device, unsigned Bar, uint64_t Addr, uint64_t Len)
Definition: PCI.h:52
temu_PCIConfig::ClassCodeRevID
uint32_t ClassCodeRevID
Definition: PCI.h:38
temu_PCIDeviceVTable::MemBlock
temu_MemoryIface MemBlock
Definition: PCI.h:32
temu_PCIDeviceVTable::ConfigAccess
temu_MemAccessIface ConfigAccess
Definition: PCI.h:27
temu_PCIBusIface::mapPciIo
void(* mapPciIo)(temu_Object *Obj, unsigned Device, unsigned Bar, uint64_t Addr, uint64_t Len)
Definition: PCI.h:49
temu_PCIConfig::SubsystemVendorID
uint32_t SubsystemVendorID
Definition: PCI.h:42
temu_PCIBridgeIface::lowerReset
void(* lowerReset)(temu_Object *)
Definition: PCI.h:61
temu_PCIConfig::BAR
uint32_t BAR[6]
Definition: PCI.h:40
temu_PCIDevice::Conf
temu_PCIConfig Conf
Definition: PCI.h:84
temu_PCIDeviceVTable::MemAccess
temu_MemAccessIface MemAccess
Definition: PCI.h:29
temu_PCIBridgeIface::raiseReset
void(* raiseReset)(temu_Object *)
Definition: PCI.h:60
temu_PCIDeviceIface::getPciBarIface
temu_MemAccessIface *(* getPciBarIface)(temu_Object *, unsigned BarId, uint8_t type)
Definition: PCI.h:77
temu_PCIBusIface::unmapPciMem
void(* unmapPciMem)(temu_Object *Obj, unsigned Device)
Definition: PCI.h:54
temu_PCIConfig::MaxLatMinGntIntPinLine
uint32_t MaxLatMinGntIntPinLine
Definition: PCI.h:45
temu_PCIBridgeIface::disconnect
void(* disconnect)(temu_Object *, temu_Object *)
Definition: PCI.h:63