RTL8127网卡导致UEFI 出现Unhandled Exception in EL3

▒▒Unhandled Exception in EL3.
x30            = 0x000000000ff5a384
x0             = 0x0000000000000000
x1             = 0x8000000000000003
x2             = 0x0000000040100000
x3             = 0x000000000000001a
x4             = 0x0000001fb639ef98
x5             = 0x0000000000000000
x6             = 0x0000000000000019
x7             = 0x0000000000000001
x8             = 0x0000000000000000
x9             = 0x000000000000001a
x10            = 0x0000001fb6361f78
x11            = 0x0000000000000000
x12            = 0x0000000000000000
x13            = 0x0000000200000000
x14            = 0x0000000000000000
x15            = 0x0000000200000000
x16            = 0x0000001fb7192630
x17            = 0x0000000000000000
x18            = 0x0000000000000000
x19            = 0x000000000000000a
x20            = 0x0000000040100010
x21            = 0x0000001fb639efa8
x22            = 0x0000000000000000
x23            = 0x0000000000000001
x24            = 0x0000000000000001
x25            = 0x0000000000020000
x26            = 0x0000000000000000
x27            = 0x0000000000000000
x28            = 0x0000000040100000
x29            = 0x0000001fd3ffe1c0
scr_el3        = 0x000000401c07073d
sctlr_el3      = 0x00000000b0cd183f
cptr_el3       = 0x0000000000000100
tcr_el3        = 0x0000000080853510
daif           = 0x00000000000003c0
mair_el3       = 0x00000000004404ff
spsr_el3       = 0x00000000420002cd
elr_el3        = 0x000000000ff5a584
ttbr0_el3      = 0x000000000ff99001
esr_el3        = 0x00000000be000011
far_el3        = 0xfa6dcf59dfaede7c
spsr_el1       = 0x0000000000000000
elr_el1        = 0x0000000000000000
spsr_abt       = 0x0000000000000000
spsr_und       = 0x0000000000000000
spsr_irq       = 0x0000000000000000
spsr_fiq       = 0x0000000000000000
sctlr_el1      = 0x0000000030d00980
actlr_el1      = 0x0000000000000000
cpacr_el1      = 0x0000000000300000
csselr_el1     = 0x0000000000000002
sp_el1         = 0x0000000000000000
esr_el1        = 0x0000000000000000
ttbr0_el1      = 0x0000000000000000
ttbr1_el1      = 0x0000000000000000
mair_el1       = 0x0000000000000000
amair_el1      = 0x0000000000000000
tcr_el1        = 0x0000000000000000
tpidr_el1      = 0x0000000000000000
tpidr_el0      = 0x0000000080000000
tpidrro_el0    = 0x0000000000000000
par_el1        = 0x0000000000000800
mpidr_el1      = 0x0000000081000000
afsr0_el1      = 0x0000000000000000
afsr1_el1      = 0x0000000000000000
contextidr_el1 = 0x0000000000000000
vbar_el1       = 0x0000000000000000
cntp_ctl_el0   = 0x0000000000000005
cntp_cval_el0  = 0x000000021c64f871
cntv_ctl_el0   = 0x0000000000000000
cntv_cval_el0  = 0x0000000000000000
cntkctl_el1    = 0x0000000000000000
sp_el0         = 0x0000001fb72ef100
isr_el1        = 0x0000000000000040
cpuectlr_el1   = 0xc0007403c0543001
gicd_ispendr regs (Offsets 0x200 - 0x278)
 Offset:                        value
0000000000000200:               0x0000000000000000
0000000000000204:               0x0000000000000000
0000000000000208:               0x0000000000000000
000000000000020c:               0x0000000000000008
0000000000000210:               0x0000000010000000
0000000000000214:               0x0000000000000000
0000000000000218:               0x0000000000000000
000000000000021c:               0x0000000000000000
0000000000000220:               0x0000000000000000
0000000000000224:               0x0000000000000000
0000000000000228:               0x0000000000000000
000000000000022c:               0x0000000000000000
0000000000000230:               0x0000000000000000
0000000000000234:               0x0000000000000000
0000000000000238:               0x0000000080000000
000000000000023c:               0x0000000000000000
0000000000000240:               0x0000000000000000
0000000000000244:               0x0000000000000000
0000000000000248:               0x0000000000000000
000000000000024c:               0x0000000000000000
0000000000000250:               0x0000000000001800
0000000000000254:               0x0000000000000000
0000000000000258:               0x0000000000000000
000000000000025c:               0x0000000000000000
0000000000000260:               0x0000000000000000
0000000000000264:               0x0000000000000000
0000000000000268:               0x0000000000000000
000000000000026c:               0x0000000010000000
0000000000000270:               0x0000000000000000
0000000000000274:               0x0000000000000000
0000000000000278:               0x0000000000000000
000000000000027c:               0x0000000000000000

1.使用RTL8127网卡,UEFI固定出现以上报错,导致无法加载启动内核

2.横向对比Mellanox的CX-5,CX-6以及Intel的E810网卡,都是正常启动

3.RTL8127的网卡有做更换测试,目前判断不是单张网卡的硬件问题,而是整个8127系列均会出现的问题

4.继续使用出问题的R8127测试,发现进入UEFI后再插入网卡,也就是说让UEFI先扫描完设备,再插入网卡继续加载内核即可正常识别设备并挂载驱动,而且测试功能是正常的

Question:

以上错误的具体解读与怎么修复?

--- a/Silicon/NVIDIA/Drivers/PcieControllerDxe/PcieControllerDxe.c
+++ b/Silicon/NVIDIA/Drivers/PcieControllerDxe/PcieControllerDxe.c
@@ -86,6 +86,31 @@ NVIDIA_DEVICE_DISCOVERY_CONFIG  gDeviceDiscoverDriverConfig = {
   .ThreadedDeviceStart             = TRUE
 };
 
+STATIC
+BOOLEAN
+IsT264PcieC4DeviceNode (
+  IN CONST NVIDIA_DEVICE_TREE_NODE_PROTOCOL  *DeviceTreeNode
+  )
+{
+  UINT32  PcieDomain;
+
+  if ((DeviceTreeNode == NULL) || (TegraGetChipID () != T264_CHIP_ID)) {
+    return FALSE;
+  }
+
+  if (EFI_ERROR (
+        DeviceTreeGetNodePropertyValue32 (
+          DeviceTreeNode->NodeOffset,
+          "linux,pci-domain",
+          &PcieDomain
+          )))
+  {
+    return FALSE;
+  }
+
+  return PcieDomain == 4;
+}
+
 BOOLEAN  gDelayAfterPERSTRead                                                   = FALSE;
 UINT8    gDelayAfterPERST[TEGRABL_SOC_MAX_SOCKETS][TEGRABL_MAX_PCIE_PER_SOCKET] = { 0 };
 
@@ -2176,6 +2176,14 @@ DeviceDiscoveryNotify (
   PlatformType = TegraGetPlatform ();
   Status       = EFI_SUCCESS;
   PcieFound    = FALSE;
   ChipId       = TegraGetChipID ();
 
+  if (((Phase == DeviceDiscoveryDeviceTreeCompatibility) ||
+       (Phase == DeviceDiscoveryDriverBindingSupported)) &&
+      IsT264PcieC4DeviceNode (DeviceTreeNode))
+  {
+    DEBUG ((DEBUG_INFO, "%a: skip T264 PCIe C4 in UEFI\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+
   if (ChipId == TH500_CHIP_ID) {

测试下来通过拒绝 C4 控制器发现:更早阻止 C4 Root Bridge 和 PCI 总线枚举可以在不破坏 Linux DT 状态的前提下规避 UEFI 阶段的 C4 初始化问题

You need to build out UEFI debug version and use that version to check log again.

Release mode binary won’t print any detail.

However, I think the quick way is just skip PCIe controller enumeration in UEFI.

There are lots of kinds of devices that might lead to unexpected bug in UEFI. Skipping enumeration is a common way to skip those issues.

感谢回复,确实忽略掉UEFI的枚举后功能正常了