PcieAddressing
Addressing of Transactions
Three TLP routing types (see spec. p. 56):
- Address based (32 or 64 bit addressed)
- ID based (bus, device, function number)
- Implicit (Message Requests routed with r[2:0] sub-field of Type field, see spec. p. 70)
GreenBus routing with MAddr matches address based routing. Other routing mechanisms cannot be mapped to MAddr field routing because all 64 bit are needed by address based routing.
To keep the router fast, two boolean quarks are used to identify the other two routing mechanisms:
| Address based routing | ID based routing | Implicit routing | |
| mIsIDbasedRouting | false | true | false |
| mIsImplicitRouting | false | false | true |
Address based routing
- Uses Transaction Container quark
mAddr. -
mIsIDbasedRouting==mIsImplicitRouting== false
By address routed TLPs are allowed to be routed to any device. The root complex reads out the needed address range of each device at the initialization (amount of writable registers) and assigns the memory space.
Wie funktioniert address based routing?
Type 0 Configuration Space Header (für Devices) (PCI 3.0 spec.) haben Base Address Registers: 6 x 32 Bit. Dadurch sind _mehrere_ Memory Ranges pro Device möglich (beginnend bei 10h)! Bit 0 gibt an, ob es sich um den Memory Space (64bit oder 32 bit) oder den I/O Space (32bit) handelt. Anzahl der Address Ranges pro Device (Function): bei 32-bit address space: 6 address ranges (1 DWORD per range); bei 64-bit address space: 3 address ranges (2 DWORDs per range). Frage: Wie werden diese verschiedenen address ranges addressiert, wenn die upper bits doch nicht interpretiert werden? Vielleicht werden sie doch interpretiert (die Software schreibt die gewünschte base address in das Register), lediglich beim Auslesen durch die Software werden für die oberen Bits '0'en zurückgegeben, obwohl sie nicht '0' sind (damit die benötigte Größe von der SW ausgelesen werden kann).
Die System Software kann beim Booten herausfinden, wie viel Speicherplatz ein Device (für eine bestimmte base address) benötigt, indem es '1'en in alle Bits der base address schreibt und anschließend das Register wieder ausliest. Alle lower Bits, die das Device ignoriert, sind dann auf '0' gesetzt. Die upper Bits, die '1' sind, geben die benötigte Speichergröße (mit natürlichen Grenzen) an (Achtung: die unteren nicht frei verfügbaren bits mitzählen!). Damit sind z.B. für 32-bit Memory 16 bytes bis 2 GB möglich. (16 bytes weil die oberen 4 bit nicht mit einer base address versehen werden können, weil sie fest zugeteilt sind.) (siehe PCI spec. p. 225f.) Das Bit 0 gibt an, ob die Address Range in den Memory Space oder I/O Space gehört.
Genauso funktioniert das Expansion ROM Base Address Register.
Ein Device interpretiert nur die unteren Bits der Adresse, wenn eine Transaktion ausgeliefert wird. (Nein? Ein Device interpretiert alle Bits, um die betreffende address range zuordnen zu können!)
Welchem Device welche Transaction ausgeliefert wird, muss im Switch entschieden und konfiguriert werden!! WIE??
Ablauf (erdacht):
- Power-up software (SW) fragt per configuration (ID based routing) alle base address register aller devices und functions nach ihrer Größe ab.
- SW berechnet base addresses für alle functions
- SW schreibt alle base addresses
- Frage: wie und wann registrieren die Switches die address ranges?
- : Ist das vielleicht vendor specific und ist unsere freie Entscheinung?
ID based routing
Alternatives:
- Use quark
mAddrwith additional boolean quarkmIsIDbasedRouting. Create addresses with ECAM scheme (see spec. p. 416). - (!) Use extra quarks,
mBusNo,mDeviceNo,mFuncNo,mRegisterNo(for Configuration Requests)
The second alternative is faster to be interpreted by a router.
Bus Number and Device Number are generated just by their hardware position. A function has to capture the numbers each time a Type 0 Configuration Write Request arrives. Afterwards it is able to send Completions with the correct Completer ID (see spec. p. 81).
Implementation:
This is about how to assign Bus Number and Device Number to a specific Bus and Device.
- Device Numbers in PCIe most times fixed to 0 because each Downstream Port of a Switch is a lagical PCI-to-PCI Bridge which has its own Bus Number and only one Device connected to it (a Device or another Switch).
Advantages:
No problem with generic peripherals which do not know anything about numbers.
User needs not to care about numbers.
- Bus numbers
- The Bus Numbers are assigned by the Switches: Each switch has one internal Bus Number which is the logical PCI Bus that connects the logical PCI-to-PCI Bridges.
- Each Downstream Port has its own additional Bus Number - the port position forms in increasing order the Bus Numbers. Each Downstream Port is a logical PCI-to-PCI Bridge.
- The Bus Numbers are assigned in the PCIeAddressMap during end_of_elaboration or user initiated after all connections at the Downstream multi Port are done. The Bus Numbers are coordinated with a static member variable (
m_max_bus_no).
Implicit routing
- Use boolean quark
mIsImplicitRoutingand existingmMessageType. Only forPCIeTypeMsg and MsgWithData.
The quark mMessageType contains the information how (where) the transaction shall be routed (to).
The Message Type specifies the different routing types:
| RoutedToRootComplex, | 000 | Route to Root Complex |
| RoutedByAddress, | 001 | Never used (mIsIDbasedRouting=mIsImplicitRouting=false!) |
| RoutedByID, | 010 | Route normally by ID (set mIsIDbasedRouting=true instead of mIsImplicitRouting!) |
| BroadcastFromRootComplex, | 011 | Broadcast from Root Complex to all devices |
| LocalTerminateAtReceiver, | 100 | Local - Not forwarded at the next switch |
| GatheredAndRoutedToRootComplex | 101 | see PME_TO_Ack Message Code (spec. sec. 5.3.3.2.1, p. 310): Collect Acks from Downstream Ports and send one to Upstream Port |
<!> The broadcasted Message is the only case where one TLP is duplicated and forwarded to more than one port. This transaction is not copied.
Posted January 8th, 2008 by MarkBurton