ROMED4ID-2T — Merging Paired SlimSAS x8 Ports into a True x16 GPU Slot: **Resolved**

*Follow-up to: [Niche: ROMED4ID-2T PCIe ports usecase](Niche' ROMED4ID-2T PCIE Ports usecase)*

*Previous revision of these notes ended with open questions. This revision reports a working result.*

**
—**

## 1. Result

**Two merged SlimSAS 8i ports train a full PCIe 4.0 x16 link on this board, using an ordinary passive adapter.** An RTX 3090 on `SLIM5`+`SLIM6`, set to `x16` in BIOS and fed by two SlimSAS cables into a plain SlimSAS-to-PCIe-slot adapter — no retimer, no redriver, no active silicon of any kind — negotiates 16GT/s at x16 with equalization complete.

**No ASRock RDV riser or retimer card is required.** The x8 ceiling reported in the original thread is neither a platform limitation nor evidence that active components are needed.

```

# Root port (SLIM6/SLIM5 pair, BIOS Link Width = x16)

80:03.1 LnkCap: Port #0, Speed 16GT/s, Width x16, ASPM L1

     LnkSta:  Speed 16GT/s, Width x16

     LnkSta2: EqualizationComplete+ EqualizationPhase1+

     SltSta:  PresDet+

# Endpoint

83:00.0 NVIDIA GA102 [GeForce RTX 3090] [10de:2204]

     LnkCap:  Speed 16GT/s, Width x16

     LnkSta:  Speed 16GT/s, Width x16

```

No bandwidth warning is logged, and `dmesg` carries no AER or link-training errors. The link stays at x16 after `vfio-pci` binds the card and a guest takes it.

### Test system

| | |

|—|—|

| Board | ASRock Rack ROMED4ID-2T |

| BIOS | P3.30, 2022-09-05 |

| CPU | EPYC 7F52 (16C/32T, Rome) |

| RAM | 2× 64 GB DDR4-2666 RDIMM |

| OS | Proxmox VE 9.2.5, kernel 7.0.14-8-pve |

| GPU | ZOTAC RTX 3090 (`19da:1613`) |

| Adapter | Passive SlimSAS 8i ×2 → PCIe x16 slot, no active components; requires its own power feed |

| BIOS setting | `SLIM6/SLIM5 Link Width = x16` |

This settles the question the original thread turned on. The inference that ASRock’s

RDV-suffixed risers must contain retimers, and that a generic adapter therefore cannot

work, does not hold — a passive adapter reaches full width on this board. It is the

earlier x8 result that now needs explaining, not this one. See §7.

—

## 2. What the merge looks like from the OS

Setting a pair to `x16` collapses four x4 root ports into one x16 root port. Before, with `SLIM6/SLIM5` at the `x4x4/x4x4` default:

```

80:03.1 PCI bridge LnkCap Width x4

80:03.2 PCI bridge LnkCap Width x4

80:03.3 PCI bridge LnkCap Width x4

80:03.4 PCI bridge LnkCap Width x4

```

After setting the pair to `x16`, `80:03.2` through `80:03.4` cease to exist:

```

80:03.0 Host bridge (AMD Starship/Matisse PCIe Dummy Host Bridge)

80:03.1 PCI bridge LnkCap Width x16

```

The other two pairs, left at their defaults, keep their four x4 ports each. This is a clean way to confirm the BIOS setting took effect before ever plugging a card in.

—

## 3. Port grouping, confirmed empirically


The block diagram’s pairing — `1+4`, `2+3`, `5+6`, not sequential — is independently confirmed by walking PCI topology on a running system. Each pair sits on its own root complex:

| Connectors | Root complex | Root ports | Block-diagram controller |

|—|—|—|—|

| `SLIM2` + `SLIM3` | `0000:00` | `00:03.1`–`00:03.4` | PCIE G2 |

| `SLIM1` + `SLIM4` | `0000:40` | `40:01.1`–`40:01.4` | PCIE G3 |

| `SLIM5` + `SLIM6` | `0000:80` | `80:03.1`–`80:03.4` | PCIE G1 |

| `PCIE7` | `0000:40` | `40:03.x` | PCIE P0 (separate controller) |

| `M2_1` | `0000:c0` | `c0:03.1` | PCIE P3 |

| on-board X550 | `0000:c0` | `c0:03.3` | — |

Derived from `dmidecode -t slot` bus addresses cross-referenced against which root port lit up as devices were moved between connectors. Two useful consequences:

- **`PCIE7` shares root complex `0000:40` with `SLIM1`/`SLIM4`** but is a separate controller, matching the diagram.

- **Nothing hangs off root complex `0000:c0` except `M2_1` and the on-board NIC.** For multi-GPU work this matters: peer-to-peer traffic between cards on different root complexes crosses Infinity Fabric, so a tensor-parallel group is best kept within one pair.

### PCIE7 bifurcates further than documented

The earlier notes recorded `PCIE7 Link Width [x16]` as the only option. On this BIOS it splits further — observed while running a x1 Wi-Fi card in it:

```

40:03.1 LnkCap Width x4 ← card here

40:03.2 LnkCap Width x4

40:03.3 LnkCap Width x8

```

So `PCIE7` offers at least `x4x4x8`. Worth checking on other boards before assuming the slot is all-or-nothing.

—

## 4. How to verify a link without guessing

Most of the time lost in this investigation went to misreading an empty port. Two artifacts to know:

**An empty root port lies about both speed and width.**

```

80:03.1 LnkCap: Speed 2.5GT/s, Width x16 ← looks like a Gen1 cap

     LnkSta: Speed 2.5GT/s, Width x16 (overdriven)

```

`Width x16 (overdriven)` is what `lspci` prints when no link exists, and the `2.5GT/s` in `LnkCap` is not a real Gen1 restriction. The same port reported `Speed 16GT/s, Width x16` in both registers the moment a GPU was fitted. Do not chase a BIOS link-speed setting on the strength of that reading.

**`Port #247` in `LnkCap` means “nothing attached.”** It becomes a real port number once a device links.

The three registers that actually tell you where you are:

| Reading | Meaning |

|—|—|

| `SltSta: PresDet-` | Nothing electrically present — cable unseated, or adapter unpowered |

| `PresDet+`, `LnkSta … (overdriven)`, `EqualizationPhase1-` | Card present, link never trained — far end electrically silent |

| `PresDet+`, `EqualizationComplete+`, real width | Working |

```bash

for d in 00:03.1 00:03.2 00:03.3 00:03.4 40:01.1 40:01.2 40:01.3 40:01.4 \

80:03.1 80:03.2 80:03.3 80:03.4; do

o=$(lspci -vv -s $d 2>/dev/null)

printf “%-8s %-9s %s\n” “$d” \

"$(echo "$o" | grep 'SltSta:' | grep -o 'PresDet\[+-\]')" \\

“$(echo “$o” | grep -o ‘LnkSta:.*’)”

done

```

### Retrain does not renegotiate width

Worth knowing before concluding a card is bad. Setting Retrain Link (`LNKCTL` bit 5) only drives the LTSSM to **Recovery**, which does not re-run lane detection — a link stuck at x1 stays at x1:

```bash

cur=$(setpci -s 0000:00:03.3 CAP_EXP+10.w)

setpci -s 0000:00:03.3 CAP_EXP+10.w=(printf "%04x" ((0x$cur | 0x20)))

```

Toggling Link Disable (bit 4) forces a full return to **Detect**, where lanes are detected:

```bash

echo 1 > /sys/bus/pci/devices/0000:03:00.0/remove

cur=$(setpci -s 0000:00:03.3 CAP_EXP+10.w)

setpci -s 0000:00:03.3 CAP_EXP+10.w=(printf "%04x" ((0x$cur | 0x10))) # disable

sleep 2

setpci -s 0000:00:03.3 CAP_EXP+10.w=(printf "%04x" ((0x$cur & ~0x10))) # enable

sleep 3

echo 1 > /sys/bus/pci/rescan

```

If width is still short after that, the missing lanes are not being detected at all — an open circuit rather than marginal signalling. Clean `CESta` counters (`RxErr-`, `BadTLP-`, `BadDLLP-`) alongside a narrow link point the same way: dead lanes, not noisy ones.

—

## 5. Failure modes hit along the way

Every one of these presented as “the merge doesn’t work” before being pinned down.

**The adapter needs its own power.** A SlimSAS-to-PCIe-slot adapter has to source the slot’s 12 V and 3.3 V itself; the cables carry signal only. Unpowered, the whole chain reads `PresDet-` and looks identical to a cable that isn’t plugged in. This alone cost several boot cycles.

**Not every card works in the cable chain.** A Realtek RTL8922AE Wi-Fi card in the same adapter never trained — presence detect flapped at roughly 1 Hz, with `pciehp` logging `Card present` / `No link` in a continuous loop, and the raw `SLTSTA` PresDet bit toggling between samples. The same adapter, cables and connector ran the RTX 3090 at full x16. Moved into `PCIE7`, the Wi-Fi card worked normally. Match the card to the position rather than assuming a slot that works for one works for all.

**A ~1 Hz `Card present` / `No link` loop is mechanical.** Read the raw bit rather than trusting the driver log, which retries on its own cadence:

```bash

raw=(setpci -s 0000:80:03.1 CAP_EXP+1a.w); echo (( (0x$raw >> 6) & 1 ))

```

**Adding or moving any device reshuffles UEFI boot order.** This stranded the host at “no bootable device” twice, needing IPMI console access to re-select the boot drive. Budget for it after every hardware change.

**IOMMU groups renumber, breaking hypervisor passthrough configs.** Proxmox pins `path=`, `id=` and `iommugroup=` in `/etc/pve/mapping/pci.cfg`. Over this investigation the GPU’s group moved 57 → 59 → 54 → 32 as devices came and went, and moving the GPU put a different card at its old address:

```

PCI device mapping invalid (hardware probably changed):

‘id’ does not match for ‘gpu-rtx3090’ (10ec:8922 != 10de:2204)

```

Re-derive both values from the card’s *current* address after any change. A trap worth naming: the Wi-Fi card landed in group 57 — the number the stale mapping still held — so checking against the old address appeared to match.

**One x4 lane group in a cable/adapter/carrier chain had dead lanes.** Separately from the GPU work, two NVMe drives behind a two-cable adapter and an M.2 carrier gave one drive at x4 and the other stuck at x1 (`8GT/s`, speed negotiated fine, width short, error counters clean). Swapping the drives left the x1 on the position, clearing both drives; moving the whole assembly to a different connector on a different root complex carried the x1 with it, clearing the board. The fault is in the cable, the adapter, or the carrier’s first slot. Relevant here as a caution: with two cables feeding one slot, a single bad lane group degrades width without any error being logged.

—

## 6. Practical notes for multi-GPU builds on this board

**Seven GPU positions exist**: `PCIE7` at x16 plus six SlimSAS at x8, or fewer at wider widths if pairs are merged. Lanes are not the constraint — 16 + 48 + 4 (M.2) + 4 (X550) is 72 of the 7F52’s 128.

**MMIO is not a constraint either.** With Above 4G Decoding enabled each root complex exposes roughly 8 TiB of 64-bit MMIO, so large and resizable BARs have room. Note this BIOS has **no Re-Size BAR option at all** — `Advanced → PCI Subsystem Settings` offers only `Above 4G Decoding` and `SR-IOV Support`. Forcing a resize from the OS before guest start is the workaround.

**Legacy I/O port space is already exhausted.** The 64 KB x86 range is fixed, each bridge wants a 4 KB granule, and `0x1000`–`0xd000` are allocated with no expansion cards fitted — several root ports log `can’t assign; no space` at every boot. GPUs do claim an I/O BAR (the 3090 takes 128 bytes), but a failed assignment costs only legacy VGA; compute and passthrough are unaffected.

**ACS is enabled, so peer-to-peer is redirected.** Every root port reports `ReqRedir+ CmpltRedir+ UpstreamFwd+`, meaning GPU-to-GPU traffic routes up to the root complex and through the IOMMU rather than directly. That is what gives clean per-device IOMMU groups — the 3090’s two functions sit alone in group 32, no ACS override needed — but it is also why tensor parallelism over PCIe will be communication-bound here. The trade is direct: ACS on for passthrough isolation, ACS off for real P2P. With no NVLink bridging possible across cable-mounted cards, pipeline parallelism is the better fit; if TP is required, keep the group within one SlimSAS pair.

**NUMA is not a factor.** The BIOS is at NPS1, so the whole socket presents as one NUMA node and every PCI device reports `numa_node: -1`. No CPU or memory affinity work is needed — though PCIe traffic between root complexes still crosses the fabric.

—

## 7. Still open

1. **Why did the earlier c-payne test stop at x8?** A passive adapter works here, so the

difference lies somewhere else: cable length or pair matching, cable revision, BIOS

version, board revision, or cable ordering across the two connectors. Anyone who hit

the x8 ceiling is now looking for a specific variable rather than a missing chip.

2. **Cable length and skew.** The most likely remaining candidate. Two cables feeding

one x16 link have to stay within the lane-to-lane skew budget, and that is the one

thing a passive adapter cannot fix. Reported lengths from both working and failing

setups would settle it quickly.

3. **Does the same merge train at x16 on the other two pairs?** Only `SLIM5`+`SLIM6` has

been tested at x16 on this system. The block diagram says the three pairs are

equivalent, but that is untested here.

4. **Are the ASRock RDV risers actually retimer cards?** Still unconfirmed, and now

less interesting — whatever they contain, they are not a prerequisite.

—

## 8. References

- Original thread: Niche' ROMED4ID-2T PCIE Ports usecase

- ROMED4ID-2T full manual (block diagram, BIOS options): https://download.asrock.com/Manual/ROMED4ID-2T.pdf

- ROMED4ID-2T QIG: https://download.asrock.com/Manual/QIG/ROMED4ID-2T.pdf

- 1U2N2G-ROME/2T QIG (cable list, wiring): https://download.asrock.com/Manual/QIG/1U2N2G-ROME2T.pdf

- 1U4G-ROME product page: https://www.asrockrack.com/general/productdetail.tw.asp?Model=1U4G-ROME#Manual

- 1U4G-ROME QIG: https://download.asrock.com/Manual/QIG/1U4G-ROME.pdf