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