Skip to content

Commit 2f3587f

Browse files
committed
init
1 parent bdf9f9d commit 2f3587f

File tree

8 files changed

+720
-1
lines changed

8 files changed

+720
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.vscode
2+
*.exe
3+
*.tlscan

README.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,35 @@
11
# PCIeConfigSpace
2-
Read a .TLScan file containing the PCIe Configuration Space and Generate a Write Mask
2+
3+
This utility interprets PCIe configuration space data extracted by [TeleScan PE Software](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software). It serves two main functions:
4+
5+
1. Analyzing the configuration space
6+
2. Generating a corresponding write mask
7+
8+
The tool produces two output files compatible with pcileech-fpga:
9+
10+
1. A shadow configuration space
11+
2. A write mask
12+
13+
These files can be used to enhance the legitimacy of your DMA card's appearance when utilizing [pcileech-fpga](https://github.com/ufrisk/pcileech-fpga).
14+
15+
## Usage
16+
17+
```shell
18+
PS C:\Tools\PCIeConfigSpace> .\TLScan.exe -h
19+
Usage of C:\Tools\PCIeConfigSpace\TLScan.exe:
20+
-i string
21+
The .tlscan scan file of your donor card (default "donor.tlscan")
22+
-overwrite
23+
Automatically overwrite existing file
24+
-so string
25+
The output .coe file containing your formatted config space (default "pcileech_cfgspace_extracted.coe")
26+
-wo string
27+
The output .coe file containing your formatted config space writemask (default "pcileech_cfgspace_writemask_extracted.coe")
28+
```
29+
30+
### Resources
31+
32+
- PCI Local Bus Specification (Revision 2.2)
33+
- PCI Code and ID Assignment Specification (Revision 1.11)
34+
- PCI Express® Base Specification (Revision 3.0)
35+
- [Writemask.it by Simonrak](https://github.com/Simonrak/writemask.it)

capabilitiesData.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
)
7+
8+
func GetCapabilityWriteMask(capabilityID uint8) []byte {
9+
capInfo := CAPABILITIES[capabilityID]
10+
return Uint32SliceToBytes(capInfo.WriteMask)
11+
}
12+
13+
func GetCapabilityID(capabilityBase []byte) byte {
14+
return capabilityBase[0]
15+
}
16+
17+
func GetCapabilityNextPointer(capabilityBase []byte) byte {
18+
return capabilityBase[1]
19+
}
20+
21+
func GetCapabilityName(capabilityID uint8) string {
22+
capInfo := CAPABILITIES[capabilityID]
23+
return capInfo.Name
24+
}
25+
26+
func GetCapabilitySize(capabilityBase []byte) int {
27+
capabilityID := GetCapabilityID(capabilityBase)
28+
capInfo := CAPABILITIES[capabilityID]
29+
30+
if capInfo.Size == -1 { //MSI 14bytes or 24 bytes
31+
var messageControl uint16
32+
err := binary.Read(bytes.NewReader(capabilityBase[2:]), binary.LittleEndian, &messageControl)
33+
if err != nil {
34+
return -1
35+
}
36+
bitArray := Uint16ToBitArray(messageControl)
37+
if !bitArray[8] { // If 64 bit disabled
38+
return 1
39+
} else if bitArray[8] && bitArray[7] { // If 64 bit enabled and pre-vector masking is true
40+
return 6
41+
} else {
42+
return 4
43+
}
44+
45+
} else if capInfo.Size == -2 { //MSI-X - get TableSize
46+
var messageControl uint16
47+
err := binary.Read(bytes.NewReader(capabilityBase[2:]), binary.LittleEndian, &messageControl)
48+
if err != nil {
49+
return -1
50+
}
51+
bitArray := Uint16ToBitArray(messageControl)
52+
bitArrayTableSize := bitArray[6:]
53+
tableSize := BinaryArrayToDecimal(bitArrayTableSize) + 1
54+
return tableSize / 2
55+
56+
} else {
57+
return capInfo.Size
58+
}
59+
}

pcieData.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
"fmt"
7+
"unsafe"
8+
)
9+
10+
func ReadPCIeHeader(data []byte, offset int) (PCIeHeader, error) {
11+
var header PCIeHeader
12+
size := int(unsafe.Sizeof(header))
13+
14+
if len(data) < offset+size {
15+
return header, fmt.Errorf("not enough data to read PCIeHeader at offset %d", offset)
16+
}
17+
18+
err := binary.Read(bytes.NewReader(data[offset:offset+size]), binary.LittleEndian, &header)
19+
if err != nil {
20+
return header, fmt.Errorf("failed to read PCIeHeader: %v", err)
21+
}
22+
23+
err = Format3BytesLittleEndian(&header.Reserved1, &header.ClassCode)
24+
if err != nil {
25+
return header, fmt.Errorf("failed to format three byte array: %v", err)
26+
}
27+
28+
return header, nil
29+
}

structs.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package main
2+
3+
import "encoding/xml"
4+
5+
type Devices struct {
6+
XMLName xml.Name `xml:"devices"`
7+
Devices []Device `xml:"device"`
8+
}
9+
10+
type Device struct {
11+
DeviceID string `xml:"device,attr"`
12+
Type string `xml:"type,attr"`
13+
Function string `xml:"function,attr"`
14+
Bus string `xml:"bus,attr"`
15+
Config Config `xml:"config_space"`
16+
}
17+
18+
type Config struct {
19+
Bytes string `xml:"bytes"`
20+
}
21+
22+
type PCIeHeader struct {
23+
VendorID uint16
24+
DeviceID uint16
25+
Command uint16
26+
Status uint16
27+
RevisionID uint8
28+
ClassCode [3]byte
29+
CacheLineSize uint8
30+
LatencyTimer uint8
31+
HeaderType uint8
32+
BuiltInSelfTest uint8
33+
BaseRegister0 uint32
34+
BaseRegister1 uint32
35+
BaseRegister2 uint32
36+
BaseRegister3 uint32
37+
BaseRegister4 uint32
38+
BaseRegister5 uint32
39+
CardbusCISPointer uint32
40+
SubsystemVendorID uint16
41+
SubsystemID uint16
42+
ExpansionROMBaseAddress uint32
43+
CapabilitiesPointer uint8
44+
Reserved1 [3]byte
45+
Reserved2 uint32
46+
InterruptLine uint8
47+
InterruptPin uint8
48+
MinGrant uint8
49+
MaxLatency uint8
50+
}
51+
52+
type CapabilitiesInfo struct {
53+
Name string
54+
Size int
55+
WriteMask []uint32
56+
}
57+
58+
// PCI Code and ID Assignment Specification Revision 1.11
59+
var CAPABILITIES map[uint8]CapabilitiesInfo = map[uint8]CapabilitiesInfo{
60+
0x00: {"NULL", 0, nil},
61+
0x01: {"PCI Power Management Interface ", len(Write_protected_bits_PM), Write_protected_bits_PM},
62+
0x02: {"Accelerated Graphics Port (DEPRECATED)", 0, nil},
63+
0x03: {"Vital Product Data", len(Write_protected_bits_VPD), Write_protected_bits_VPD},
64+
0x04: {"Slot Identification", 8, nil},
65+
0x05: {"Message Signaled Interrupts", -1, nil},
66+
0x06: {"CompactPCI Hot Swap", 8, nil},
67+
0x07: {"PCI-X", 0, nil},
68+
0x08: {"HyperTransport ", 0, nil},
69+
0x09: {"Vendor Specific", len(Write_protected_bits_VSC), Write_protected_bits_VSC},
70+
0x0A: {"Debug port", 16, nil},
71+
0x0B: {"CompactPCI central resource control ", 0, nil},
72+
0x0C: {"PCI Hot-Plug", 8, nil},
73+
0x0D: {"PCI Bridge Subsystem Vendor ID", 8, nil},
74+
0x0E: {"AGP 8x", 0, nil},
75+
0x0F: {"Secure Device", 0, nil},
76+
0x10: {"PCI Express", len(Write_protected_bits_PCIE), Write_protected_bits_PCIE},
77+
0x11: {"MSI-X", -2, nil},
78+
0x12: {"Serial ATA Data/Index Configuration", 8, nil},
79+
0x13: {"Advanced Features", 0, nil},
80+
0x14: {"Enhanced Allocation", 0, nil},
81+
0x15: {"Flattening Portal Bridge", 0, nil},
82+
}
83+
84+
// PCI Code and ID Assignment Specification Revision 1.11
85+
var EXTENDED_CAPABILITIES map[int]CapabilitiesInfo = map[int]CapabilitiesInfo{
86+
0x0001: {"advanced error reporting", len(Write_protected_bits_AER), Write_protected_bits_AER},
87+
0x0002: {"virtual channel", 0, nil},
88+
0x0003: {"device serial number", len(Write_protected_bits_DSN), Write_protected_bits_DSN},
89+
0x0004: {"power budgeting", 2, nil},
90+
0x0005: {"root complex link declaration", 0, nil},
91+
0x0006: {"root complex internal link control", 3, nil},
92+
0x0007: {"root complex event collector endpoint association", 3, nil},
93+
0x0008: {"multi-function virtual channel", 0, nil},
94+
0x0009: {"virtual channel", 0, nil},
95+
0x000A: {"root complex register block", len(Write_protected_bits_VSEC), Write_protected_bits_VSEC},
96+
0x000B: {"vendor specific", len(Write_protected_bits_PTM), Write_protected_bits_PTM},
97+
0x000C: {"configuration access correlation", 3, nil},
98+
0x000D: {"access control services", 0, nil},
99+
0x000E: {"alternative routing-ID interpretation", 2, nil},
100+
0x000F: {"address translation services", 0, nil},
101+
0x0010: {"single root IO virtualization", 0, nil},
102+
0x0011: {"multi-root IO virtualization", 0, nil},
103+
0x0012: {"multicast", 0, nil},
104+
0x0013: {"page request interface", 2, nil},
105+
0x0014: {"AMD reserved", 0, nil},
106+
0x0015: {"resizable BAR", 0, nil},
107+
0x0016: {"dynamic power allocation", 4, nil},
108+
0x0017: {"TPH requester", len(Write_protected_bits_TPH), Write_protected_bits_TPH},
109+
0x0018: {"latency tolerance reporting", 2, nil},
110+
0x0019: {"secondary PCI express", 0, nil},
111+
0x001A: {"protocol multiplexing", 3, nil},
112+
0x001B: {"process address space ID", 2, nil},
113+
0x001C: {"LN requester", 2, nil},
114+
0x001D: {"downstream port containment", 2, nil},
115+
0x001E: {"L1 PM substates", len(Write_protected_bits_L1PM), Write_protected_bits_L1PM},
116+
0x001F: {"precision time measurement", 2, nil},
117+
0x0020: {"M-PCIe", 0, nil},
118+
0x0021: {"FRS queueing", 3, nil},
119+
0x0022: {"Readiness time reporting", 2, nil},
120+
0x0023: {"designated vendor specific", 0, nil},
121+
0x0024: {"VF resizable BAR", 0, nil},
122+
0x0025: {"data link feature", 3, nil},
123+
0x0026: {"physical layer 16.0 GT/s", 4, nil},
124+
0x0027: {"receiver lane margining", 0, nil},
125+
0x0028: {"hierarchy ID", 2, nil},
126+
0x0029: {"native PCIe enclosure management", 0, nil},
127+
0x002A: {"physical layer 32.0 GT/s", 3, nil},
128+
0x002B: {"alternate protocol", 0, nil},
129+
0x002C: {"system firmware intermediary", 0, nil},
130+
}
131+
132+
var PCIeHeaderReadWriteMask [16]uint32 = [16]uint32{
133+
0x00000000, 0x470500f9, 0x00000000, 0xffff0040,
134+
0xf0ffffff, 0xffffffff, 0xf0ffffff, 0xffffffff,
135+
0xf0ffffff, 0xf0ffffff, 0x00000000, 0x00000000,
136+
0x01f8ffff, 0x00000000, 0x00000000, 0xff000000}

0 commit comments

Comments
 (0)