From 7f05fa00f73038b425002566d3afe6c3ade2ccdb Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 22 Dec 2016 15:55:38 +0800 Subject: MdeModulePkg: Move to new location Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.c | 225 -- MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.h | 147 - MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c | 2106 ----------- MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h | 248 -- MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.c | 258 -- MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.h | 75 - MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf | 90 - MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.uni | Bin 3940 -> 0 bytes MdeModulePkg/Bus/Pci/EhciDxe/EhciDxeExtra.uni | Bin 1348 -> 0 bytes MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c | 658 ---- MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h | 363 -- MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c | 1052 ------ MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.h | 180 - MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c | 657 ---- MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h | 336 -- MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c | 566 --- MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h | 157 - MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.c | 1275 ------- MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.h | 224 -- MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf | 70 - MdeModulePkg/Bus/Pci/EhciPei/EhciPei.uni | Bin 2216 -> 0 bytes MdeModulePkg/Bus/Pci/EhciPei/EhciPeiExtra.uni | Bin 1362 -> 0 bytes MdeModulePkg/Bus/Pci/EhciPei/EhciReg.h | 310 -- MdeModulePkg/Bus/Pci/EhciPei/EhciSched.c | 461 --- MdeModulePkg/Bus/Pci/EhciPei/EhciSched.h | 100 - MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.c | 610 ---- MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.h | 331 -- MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.c | 493 --- MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.h | 77 - MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.c | 2501 ------------- MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.h | 789 ---- MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.inf | 69 - MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.uni | Bin 2572 -> 0 bytes MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPeiExtra.uni | Bin 1372 -> 0 bytes .../IncompatiblePciDeviceSupport.c | 387 -- .../IncompatiblePciDeviceSupport.uni | Bin 1992 -> 0 bytes .../IncompatiblePciDeviceSupportDxe.inf | 53 - .../IncompatiblePciDeviceSupportExtra.uni | Bin 1414 -> 0 bytes MdeModulePkg/Bus/Pci/NvmExpressDxe/ComponentName.c | 233 -- MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c | 1138 ------ MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h | 610 ---- .../Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.c | 883 ----- .../Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.h | 269 -- .../Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.c | 162 - .../Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.h | 129 - .../Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf | 79 - .../Bus/Pci/NvmExpressDxe/NvmExpressDxe.uni | Bin 1942 -> 0 bytes .../Bus/Pci/NvmExpressDxe/NvmExpressDxeExtra.uni | Bin 1330 -> 0 bytes MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c | 981 ----- MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.h | 809 ----- .../Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c | 907 ----- MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.c | 176 - MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.h | 152 - MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c | 409 --- MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 404 --- MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | 112 - MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.uni | Bin 2042 -> 0 bytes MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxeExtra.uni | Bin 1328 -> 0 bytes MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c | 260 -- MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.h | 238 -- MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c | 1155 ------ MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h | 289 -- MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c | 143 - MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h | 86 - MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c | 2251 ------------ MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h | 519 --- .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 2717 -------------- .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.h | 476 --- MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c | 394 -- MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h | 190 - MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c | 2043 ----------- MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.h | 687 ---- MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c | 1649 --------- MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.h | 165 - .../Bus/Pci/PciBusDxe/PciOptionRomSupport.c | 783 ---- .../Bus/Pci/PciBusDxe/PciOptionRomSupport.h | 142 - .../Bus/Pci/PciBusDxe/PciPowerManagement.c | 88 - .../Bus/Pci/PciBusDxe/PciPowerManagement.h | 34 - .../Bus/Pci/PciBusDxe/PciResourceSupport.c | 2291 ------------ .../Bus/Pci/PciBusDxe/PciResourceSupport.h | 463 --- MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c | 126 - MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h | 55 - .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c | 1471 -------- .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.h | 252 -- .../Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | 56 - .../Bus/Pci/PciHostBridgeDxe/PciHostResource.h | 47 - .../Bus/Pci/PciHostBridgeDxe/PciRootBridge.h | 578 --- .../Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c | 1594 -------- .../Bus/Pci/PciSioSerialDxe/ComponentName.c | 288 -- .../Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf | 81 - .../Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.uni | Bin 1936 -> 0 bytes .../Pci/PciSioSerialDxe/PciSioSerialDxeExtra.uni | Bin 1372 -> 0 bytes MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.c | 1248 ------- MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.h | 789 ---- MdeModulePkg/Bus/Pci/PciSioSerialDxe/SerialIo.c | 1320 ------- MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c | 225 -- MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c | 818 ----- MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h | 511 --- MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf | 56 - MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni | Bin 1980 -> 0 bytes .../Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni | Bin 1336 -> 0 bytes MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.c | 152 - MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.h | 62 - MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.inf | 56 - MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.uni | Bin 2076 -> 0 bytes .../Bus/Pci/UfsPciHcPei/UfsPciHcPeiExtra.uni | Bin 1372 -> 0 bytes MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.c | 231 -- MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.h | 145 - MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c | 1889 ---------- MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h | 221 -- MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.c | 77 - MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.h | 47 - MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf | 86 - MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.uni | Bin 2260 -> 0 bytes MdeModulePkg/Bus/Pci/UhciDxe/UhciDxeExtra.uni | Bin 1326 -> 0 bytes MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.c | 707 ---- MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.h | 272 -- MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.c | 281 -- MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.h | 248 -- MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c | 1045 ------ MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.h | 271 -- MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c | 564 --- MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.h | 161 - MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.c | 3219 ---------------- MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.h | 1333 ------- MdeModulePkg/Bus/Pci/UhciPei/UhciPei.inf | 64 - MdeModulePkg/Bus/Pci/UhciPei/UhciPei.uni | Bin 2246 -> 0 bytes MdeModulePkg/Bus/Pci/UhciPei/UhciPeiExtra.uni | Bin 1362 -> 0 bytes MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c | 224 -- MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h | 146 - MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c | 758 ---- MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h | 213 -- MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c | 2250 ------------ MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h | 727 ---- MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf | 76 - MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.uni | Bin 2358 -> 0 bytes MdeModulePkg/Bus/Pci/XhciDxe/XhciDxeExtra.uni | Bin 1326 -> 0 bytes MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c | 743 ---- MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h | 583 --- MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 3838 -------------------- MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h | 1461 -------- MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c | 662 ---- MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h | 142 - MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c | 1534 -------- MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h | 239 -- MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf | 64 - MdeModulePkg/Bus/Pci/XhciPei/XhciPei.uni | Bin 2238 -> 0 bytes MdeModulePkg/Bus/Pci/XhciPei/XhciPeiExtra.uni | Bin 1338 -> 0 bytes MdeModulePkg/Bus/Pci/XhciPei/XhciReg.h | 471 --- MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c | 2963 --------------- MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h | 1307 ------- 151 files changed, 78431 deletions(-) delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.uni delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciDxeExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhciPei.uni delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhciPeiExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhciReg.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhciSched.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhciSched.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.h delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.c delete mode 100644 MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.h delete mode 100644 MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.c delete mode 100644 MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.h delete mode 100644 MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.inf delete mode 100644 MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.uni delete mode 100644 MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPeiExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c delete mode 100644 MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.uni delete mode 100644 MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.c delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.h delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.c delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.h delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.uni delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxeExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.h delete mode 100644 MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.uni delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxeExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c delete mode 100644 MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h delete mode 100644 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c delete mode 100644 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h delete mode 100644 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostResource.h delete mode 100644 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h delete mode 100644 MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c delete mode 100644 MdeModulePkg/Bus/Pci/PciSioSerialDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.uni delete mode 100644 MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxeExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.c delete mode 100644 MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.h delete mode 100644 MdeModulePkg/Bus/Pci/PciSioSerialDxe/SerialIo.c delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.c delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.h delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.inf delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.uni delete mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPeiExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.h delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.c delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.h delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.uni delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciDxeExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.c delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.h delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.c delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.h delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.h delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c delete mode 100644 MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.h delete mode 100644 MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.c delete mode 100644 MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.h delete mode 100644 MdeModulePkg/Bus/Pci/UhciPei/UhciPei.inf delete mode 100644 MdeModulePkg/Bus/Pci/UhciPei/UhciPei.uni delete mode 100644 MdeModulePkg/Bus/Pci/UhciPei/UhciPeiExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.uni delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/XhciDxeExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c delete mode 100644 MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/XhciPei.uni delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/XhciPeiExtra.uni delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/XhciReg.h delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c delete mode 100644 MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h (limited to 'MdeModulePkg/Bus/Pci') diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.c deleted file mode 100644 index 3181b9da5b..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.c +++ /dev/null @@ -1,225 +0,0 @@ -/** @file - UEFI Component Name(2) protocol implementation for EHCI driver. - -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ehci.h" - - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEhciComponentName = { - EhciComponentNameGetDriverName, - EhciComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEhciComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EhciComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EhciComponentNameGetControllerName, - "en" -}; - - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mEhciDriverNameTable[] = { - { "eng;en", L"Usb Ehci Driver" }, - { NULL , NULL } -}; - - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -EhciComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mEhciDriverNameTable, - DriverName, - (BOOLEAN)(This == &gEhciComponentName) - ); -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -EhciComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - USB2_HC_DEV *EhciDev; - EFI_USB2_HC_PROTOCOL *Usb2Hc; - - // - // This is a device driver, so ChildHandle must be NULL. - // - if (ChildHandle != NULL) { - return EFI_UNSUPPORTED; - } - // - // Make sure this driver is currently managing ControllerHandle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gEhciDriverBinding.DriverBindingHandle, - &gEfiPciIoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Get the device context - // - Status = gBS->OpenProtocol ( - ControllerHandle, - &gEfiUsb2HcProtocolGuid, - (VOID **) &Usb2Hc, - gEhciDriverBinding.DriverBindingHandle, - ControllerHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - EhciDev = EHC_FROM_THIS (Usb2Hc); - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - EhciDev->ControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gEhciComponentName) - ); - -} diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.h b/MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.h deleted file mode 100644 index 1a17d0bb49..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/ComponentName.h +++ /dev/null @@ -1,147 +0,0 @@ -/** @file - - This file contains the delarations for componet name routines. - -Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _COMPONENT_NAME_H_ -#define _COMPONENT_NAME_H_ - - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -EhciComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -EhciComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -#endif - diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c deleted file mode 100644 index 4e9e05f0e4..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c +++ /dev/null @@ -1,2106 +0,0 @@ -/** @file - The Ehci controller driver. - - EhciDxe driver is responsible for managing the behavior of EHCI controller. - It implements the interfaces of monitoring the status of all ports and transferring - Control, Bulk, Interrupt and Isochronous requests to Usb2.0 device. - - Note that EhciDxe driver is enhanced to guarantee that the EHCI controller get attached - to the EHCI controller before a UHCI or OHCI driver attaches to the companion UHCI or - OHCI controller. This way avoids the control transfer on a shared port between EHCI - and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a - USB 2.0 device inserts. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "Ehci.h" - -// -// Two arrays used to translate the EHCI port state (change) -// to the UEFI protocol's port state (change). -// -USB_PORT_STATE_MAP mUsbPortStateMap[] = { - {PORTSC_CONN, USB_PORT_STAT_CONNECTION}, - {PORTSC_ENABLED, USB_PORT_STAT_ENABLE}, - {PORTSC_SUSPEND, USB_PORT_STAT_SUSPEND}, - {PORTSC_OVERCUR, USB_PORT_STAT_OVERCURRENT}, - {PORTSC_RESET, USB_PORT_STAT_RESET}, - {PORTSC_POWER, USB_PORT_STAT_POWER}, - {PORTSC_OWNER, USB_PORT_STAT_OWNER} -}; - -USB_PORT_STATE_MAP mUsbPortChangeMap[] = { - {PORTSC_CONN_CHANGE, USB_PORT_STAT_C_CONNECTION}, - {PORTSC_ENABLE_CHANGE, USB_PORT_STAT_C_ENABLE}, - {PORTSC_OVERCUR_CHANGE, USB_PORT_STAT_C_OVERCURRENT} -}; - -EFI_DRIVER_BINDING_PROTOCOL -gEhciDriverBinding = { - EhcDriverBindingSupported, - EhcDriverBindingStart, - EhcDriverBindingStop, - 0x30, - NULL, - NULL -}; - -/** - Retrieves the capability of root hub ports. - - @param This This EFI_USB_HC_PROTOCOL instance. - @param MaxSpeed Max speed supported by the controller. - @param PortNumber Number of the root hub ports. - @param Is64BitCapable Whether the controller supports 64-bit memory - addressing. - - @retval EFI_SUCCESS Host controller capability were retrieved successfully. - @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL. - -**/ -EFI_STATUS -EFIAPI -EhcGetCapability ( - IN EFI_USB2_HC_PROTOCOL *This, - OUT UINT8 *MaxSpeed, - OUT UINT8 *PortNumber, - OUT UINT8 *Is64BitCapable - ) -{ - USB2_HC_DEV *Ehc; - EFI_TPL OldTpl; - - if ((MaxSpeed == NULL) || (PortNumber == NULL) || (Is64BitCapable == NULL)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - - *MaxSpeed = EFI_USB_SPEED_HIGH; - *PortNumber = (UINT8) (Ehc->HcStructParams & HCSP_NPORTS); - *Is64BitCapable = (UINT8) (Ehc->HcCapParams & HCCP_64BIT); - - DEBUG ((EFI_D_INFO, "EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable)); - - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; -} - - -/** - Provides software reset for the USB host controller. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param Attributes A bit mask of the reset operation to perform. - - @retval EFI_SUCCESS The reset operation succeeded. - @retval EFI_INVALID_PARAMETER Attributes is not valid. - @retval EFI_UNSUPPOURTED The type of reset specified by Attributes is - not currently supported by the host controller. - @retval EFI_DEVICE_ERROR Host controller isn't halted to reset. - -**/ -EFI_STATUS -EFIAPI -EhcReset ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT16 Attributes - ) -{ - USB2_HC_DEV *Ehc; - EFI_TPL OldTpl; - EFI_STATUS Status; - UINT32 DbgCtrlStatus; - - Ehc = EHC_FROM_THIS (This); - - if (Ehc->DevicePath != NULL) { - // - // Report Status Code to indicate reset happens - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_USB | EFI_IOB_PC_RESET), - Ehc->DevicePath - ); - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - - switch (Attributes) { - case EFI_USB_HC_RESET_GLOBAL: - // - // Flow through, same behavior as Host Controller Reset - // - case EFI_USB_HC_RESET_HOST_CONTROLLER: - // - // Host Controller must be Halt when Reset it - // - if (Ehc->DebugPortNum != 0) { - DbgCtrlStatus = EhcReadDbgRegister(Ehc, 0); - if ((DbgCtrlStatus & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) == (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) { - Status = EFI_SUCCESS; - goto ON_EXIT; - } - } - - if (!EhcIsHalt (Ehc)) { - Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto ON_EXIT; - } - } - - // - // Clean up the asynchronous transfers, currently only - // interrupt supports asynchronous operation. - // - EhciDelAllAsyncIntTransfers (Ehc); - EhcAckAllInterrupt (Ehc); - EhcFreeSched (Ehc); - - Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT); - - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - Status = EhcInitHC (Ehc); - break; - - case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG: - case EFI_USB_HC_RESET_HOST_WITH_DEBUG: - Status = EFI_UNSUPPORTED; - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - -ON_EXIT: - DEBUG ((EFI_D_INFO, "EhcReset: exit status %r\n", Status)); - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Retrieve the current state of the USB host controller. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param State Variable to return the current host controller - state. - - @retval EFI_SUCCESS Host controller state was returned in State. - @retval EFI_INVALID_PARAMETER State is NULL. - @retval EFI_DEVICE_ERROR An error was encountered while attempting to - retrieve the host controller's current state. - -**/ -EFI_STATUS -EFIAPI -EhcGetState ( - IN EFI_USB2_HC_PROTOCOL *This, - OUT EFI_USB_HC_STATE *State - ) -{ - EFI_TPL OldTpl; - USB2_HC_DEV *Ehc; - - if (State == NULL) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - - if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) { - *State = EfiUsbHcStateHalt; - } else { - *State = EfiUsbHcStateOperational; - } - - gBS->RestoreTPL (OldTpl); - - DEBUG ((EFI_D_INFO, "EhcGetState: current state %d\n", *State)); - return EFI_SUCCESS; -} - - -/** - Sets the USB host controller to a specific state. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param State The state of the host controller that will be set. - - @retval EFI_SUCCESS The USB host controller was successfully placed - in the state specified by State. - @retval EFI_INVALID_PARAMETER State is invalid. - @retval EFI_DEVICE_ERROR Failed to set the state due to device error. - -**/ -EFI_STATUS -EFIAPI -EhcSetState ( - IN EFI_USB2_HC_PROTOCOL *This, - IN EFI_USB_HC_STATE State - ) -{ - USB2_HC_DEV *Ehc; - EFI_TPL OldTpl; - EFI_STATUS Status; - EFI_USB_HC_STATE CurState; - - Status = EhcGetState (This, &CurState); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - if (CurState == State) { - return EFI_SUCCESS; - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - - switch (State) { - case EfiUsbHcStateHalt: - Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); - break; - - case EfiUsbHcStateOperational: - if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR)) { - Status = EFI_DEVICE_ERROR; - break; - } - - // - // Software must not write a one to this field unless the host controller - // is in the Halted state. Doing so will yield undefined results. - // refers to Spec[EHCI1.0-2.3.1] - // - if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) { - Status = EFI_DEVICE_ERROR; - break; - } - - Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT); - break; - - case EfiUsbHcStateSuspend: - Status = EFI_UNSUPPORTED; - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - - DEBUG ((EFI_D_INFO, "EhcSetState: exit status %r\n", Status)); - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Retrieves the current status of a USB root hub port. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param PortNumber The root hub port to retrieve the state from. - This value is zero-based. - @param PortStatus Variable to receive the port state. - - @retval EFI_SUCCESS The status of the USB root hub port specified. - by PortNumber was returned in PortStatus. - @retval EFI_INVALID_PARAMETER PortNumber is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -EhcGetRootHubPortStatus ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - OUT EFI_USB_PORT_STATUS *PortStatus - ) -{ - USB2_HC_DEV *Ehc; - EFI_TPL OldTpl; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - UINTN Index; - UINTN MapSize; - EFI_STATUS Status; - UINT32 DbgCtrlStatus; - - if (PortStatus == NULL) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - - Ehc = EHC_FROM_THIS (This); - Status = EFI_SUCCESS; - - TotalPort = (Ehc->HcStructParams & HCSP_NPORTS); - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber)); - PortStatus->PortStatus = 0; - PortStatus->PortChangeStatus = 0; - - if ((Ehc->DebugPortNum != 0) && (PortNumber == (Ehc->DebugPortNum - 1))) { - DbgCtrlStatus = EhcReadDbgRegister(Ehc, 0); - if ((DbgCtrlStatus & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) == (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) { - goto ON_EXIT; - } - } - - State = EhcReadOpReg (Ehc, Offset); - - // - // Identify device speed. If in K state, it is low speed. - // If the port is enabled after reset, the device is of - // high speed. The USB bus driver should retrieve the actual - // port speed after reset. - // - if (EHC_BIT_IS_SET (State, PORTSC_LINESTATE_K)) { - PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED; - - } else if (EHC_BIT_IS_SET (State, PORTSC_ENABLED)) { - PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED; - } - - // - // Convert the EHCI port/port change state to UEFI status - // - MapSize = sizeof (mUsbPortStateMap) / sizeof (USB_PORT_STATE_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (EHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) { - PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState); - } - } - - MapSize = sizeof (mUsbPortChangeMap) / sizeof (USB_PORT_STATE_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (EHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) { - PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState); - } - } - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Sets a feature for the specified root hub port. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param PortNumber Root hub port to set. - @param PortFeature Feature to set. - - @retval EFI_SUCCESS The feature specified by PortFeature was set. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -EhcSetRootHubPortFeature ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - USB2_HC_DEV *Ehc; - EFI_TPL OldTpl; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - EFI_STATUS Status; - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - Status = EFI_SUCCESS; - - TotalPort = (Ehc->HcStructParams & HCSP_NPORTS); - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber)); - State = EhcReadOpReg (Ehc, Offset); - - // - // Mask off the port status change bits, these bits are - // write clean bit - // - State &= ~PORTSC_CHANGE_MASK; - - switch (PortFeature) { - case EfiUsbPortEnable: - // - // Sofeware can't set this bit, Port can only be enable by - // EHCI as a part of the reset and enable - // - State |= PORTSC_ENABLED; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortSuspend: - State |= PORTSC_SUSPEND; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortReset: - // - // Make sure Host Controller not halt before reset it - // - if (EhcIsHalt (Ehc)) { - Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature :failed to start HC - %r\n", Status)); - break; - } - } - - // - // Set one to PortReset bit must also set zero to PortEnable bit - // - State |= PORTSC_RESET; - State &= ~PORTSC_ENABLED; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortPower: - // - // Set port power bit when PPC is 1 - // - if ((Ehc->HcCapParams & HCSP_PPC) == HCSP_PPC) { - State |= PORTSC_POWER; - EhcWriteOpReg (Ehc, Offset, State); - } - break; - - case EfiUsbPortOwner: - State |= PORTSC_OWNER; - EhcWriteOpReg (Ehc, Offset, State); - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - -ON_EXIT: - DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature: exit status %r\n", Status)); - - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Clears a feature for the specified root hub port. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param PortNumber Specifies the root hub port whose feature is - requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. - - @retval EFI_SUCCESS The feature specified by PortFeature was cleared - for the USB root hub port specified by PortNumber. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -EhcClearRootHubPortFeature ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - USB2_HC_DEV *Ehc; - EFI_TPL OldTpl; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - EFI_STATUS Status; - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - Status = EFI_SUCCESS; - - TotalPort = (Ehc->HcStructParams & HCSP_NPORTS); - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = EHC_PORT_STAT_OFFSET + (4 * PortNumber); - State = EhcReadOpReg (Ehc, Offset); - State &= ~PORTSC_CHANGE_MASK; - - switch (PortFeature) { - case EfiUsbPortEnable: - // - // Clear PORT_ENABLE feature means disable port. - // - State &= ~PORTSC_ENABLED; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortSuspend: - // - // A write of zero to this bit is ignored by the host - // controller. The host controller will unconditionally - // set this bit to a zero when: - // 1. software sets the Forct Port Resume bit to a zero from a one. - // 2. software sets the Port Reset bit to a one frome a zero. - // - State &= ~PORSTSC_RESUME; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortReset: - // - // Clear PORT_RESET means clear the reset signal. - // - State &= ~PORTSC_RESET; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortOwner: - // - // Clear port owner means this port owned by EHC - // - State &= ~PORTSC_OWNER; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortConnectChange: - // - // Clear connect status change - // - State |= PORTSC_CONN_CHANGE; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortEnableChange: - // - // Clear enable status change - // - State |= PORTSC_ENABLE_CHANGE; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortOverCurrentChange: - // - // Clear PortOverCurrent change - // - State |= PORTSC_OVERCUR_CHANGE; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortPower: - // - // Clear port power bit when PPC is 1 - // - if ((Ehc->HcCapParams & HCSP_PPC) == HCSP_PPC) { - State &= ~PORTSC_POWER; - EhcWriteOpReg (Ehc, Offset, State); - } - break; - case EfiUsbPortSuspendChange: - case EfiUsbPortResetChange: - // - // Not supported or not related operation - // - break; - - default: - Status = EFI_INVALID_PARAMETER; - break; - } - -ON_EXIT: - DEBUG ((EFI_D_INFO, "EhcClearRootHubPortFeature: exit status %r\n", Status)); - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Submits control transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress The target device address. - @param DeviceSpeed Target device speed. - @param MaximumPacketLength Maximum packet size the default control transfer - endpoint is capable of sending or receiving. - @param Request USB device request to send. - @param TransferDirection Specifies the data direction for the data stage - @param Data Data buffer to be transmitted or received from USB - device. - @param DataLength The size (in bytes) of the data buffer. - @param TimeOut Indicates the maximum timeout, in millisecond. - @param Translator Transaction translator to be used by this device. - @param TransferResult Return the result of this control transfer. - - @retval EFI_SUCCESS Transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT Transfer failed due to timeout. - @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -EhcControlTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN EFI_USB_DEVICE_REQUEST *Request, - IN EFI_USB_DATA_DIRECTION TransferDirection, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - USB2_HC_DEV *Ehc; - URB *Urb; - EFI_TPL OldTpl; - UINT8 Endpoint; - EFI_STATUS Status; - - // - // Validate parameters - // - if ((Request == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbDataIn) && - (TransferDirection != EfiUsbDataOut) && - (TransferDirection != EfiUsbNoData)) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection == EfiUsbNoData) && - ((Data != NULL) || (*DataLength != 0))) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbNoData) && - ((Data == NULL) || (*DataLength == 0))) { - return EFI_INVALID_PARAMETER; - } - - if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) && - (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - - Status = EFI_DEVICE_ERROR; - *TransferResult = EFI_USB_ERR_SYSTEM; - - if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - DEBUG ((EFI_D_ERROR, "EhcControlTransfer: HC halted at entrance\n")); - - EhcAckAllInterrupt (Ehc); - goto ON_EXIT; - } - - EhcAckAllInterrupt (Ehc); - - // - // Create a new URB, insert it into the asynchronous - // schedule list, then poll the execution status. - // - // - // Encode the direction in address, although default control - // endpoint is bidirectional. EhcCreateUrb expects this - // combination of Ep addr and its direction. - // - Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0)); - Urb = EhcCreateUrb ( - Ehc, - DeviceAddress, - Endpoint, - DeviceSpeed, - 0, - MaximumPacketLength, - Translator, - EHC_CTRL_TRANSFER, - Request, - Data, - *DataLength, - NULL, - NULL, - 1 - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "EhcControlTransfer: failed to create URB")); - - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - EhcLinkQhToAsync (Ehc, Urb->Qh); - Status = EhcExecTransfer (Ehc, Urb, TimeOut); - EhcUnlinkQhFromAsync (Ehc, Urb->Qh); - - // - // Get the status from URB. The result is updated in EhcCheckUrbResult - // which is called by EhcExecTransfer - // - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } - - EhcAckAllInterrupt (Ehc); - EhcFreeUrb (Ehc, Urb); - -ON_EXIT: - Ehc->PciIo->Flush (Ehc->PciIo); - gBS->RestoreTPL (OldTpl); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); - } - - return Status; -} - - -/** - Submits bulk transfer to a bulk endpoint of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction in bit 7. - @param DeviceSpeed Device speed, Low speed device doesn't support bulk - transfer. - @param MaximumPacketLength Maximum packet size the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data to transmit - from or receive into. - @param DataLength The lenght of the data buffer. - @param DataToggle On input, the initial data toggle for the transfer; - On output, it is updated to to next data toggle to - use of the subsequent bulk transfer. - @param TimeOut Indicates the maximum time, in millisecond, which - the transfer is allowed to complete. - @param Translator A pointr to the transaction translator data. - @param TransferResult A pointer to the detailed result information of the - bulk transfer. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -EhcBulkTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - USB2_HC_DEV *Ehc; - URB *Urb; - EFI_TPL OldTpl; - EFI_STATUS Status; - - // - // Validate the parameters - // - if ((DataLength == NULL) || (*DataLength == 0) || - (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 0) && (*DataToggle != 1)) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_LOW) || - ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) || - ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512))) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_DEVICE_ERROR; - - if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: HC is halted\n")); - - EhcAckAllInterrupt (Ehc); - goto ON_EXIT; - } - - EhcAckAllInterrupt (Ehc); - - // - // Create a new URB, insert it into the asynchronous - // schedule list, then poll the execution status. - // - Urb = EhcCreateUrb ( - Ehc, - DeviceAddress, - EndPointAddress, - DeviceSpeed, - *DataToggle, - MaximumPacketLength, - Translator, - EHC_BULK_TRANSFER, - NULL, - Data[0], - *DataLength, - NULL, - NULL, - 1 - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: failed to create URB\n")); - - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - EhcLinkQhToAsync (Ehc, Urb->Qh); - Status = EhcExecTransfer (Ehc, Urb, TimeOut); - EhcUnlinkQhFromAsync (Ehc, Urb->Qh); - - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - *DataToggle = Urb->DataToggle; - - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } - - EhcAckAllInterrupt (Ehc); - EhcFreeUrb (Ehc, Urb); - -ON_EXIT: - Ehc->PciIo->Flush (Ehc->PciIo); - gBS->RestoreTPL (OldTpl); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); - } - - return Status; -} - - -/** - Submits an asynchronous interrupt transfer to an - interrupt endpoint of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction encoded in bit 7 - @param DeviceSpeed Indicates device speed. - @param MaximumPacketLength Maximum packet size the target endpoint is capable - @param IsNewTransfer If TRUE, to submit an new asynchronous interrupt - transfer If FALSE, to remove the specified - asynchronous interrupt. - @param DataToggle On input, the initial data toggle to use; on output, - it is updated to indicate the next data toggle. - @param PollingInterval The he interval, in milliseconds, that the transfer - is polled. - @param DataLength The length of data to receive at the rate specified - by PollingInterval. - @param Translator Transaction translator to use. - @param CallBackFunction Function to call at the rate specified by - PollingInterval. - @param Context Context to CallBackFunction. - - @retval EFI_SUCCESS The request has been successfully submitted or canceled. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The request failed due to a lack of resources. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -EhcAsyncInterruptTransfer ( - IN EFI_USB2_HC_PROTOCOL * This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN BOOLEAN IsNewTransfer, - IN OUT UINT8 *DataToggle, - IN UINTN PollingInterval, - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction, - IN VOID *Context OPTIONAL - ) -{ - USB2_HC_DEV *Ehc; - URB *Urb; - EFI_TPL OldTpl; - EFI_STATUS Status; - UINT8 *Data; - - // - // Validate parameters - // - if (!EHCI_IS_DATAIN (EndPointAddress)) { - return EFI_INVALID_PARAMETER; - } - - if (IsNewTransfer) { - if (DataLength == 0) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 1) && (*DataToggle != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((PollingInterval > 255) || (PollingInterval < 1)) { - return EFI_INVALID_PARAMETER; - } - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - - // - // Delete Async interrupt transfer request. DataToggle will return - // the next data toggle to use. - // - if (!IsNewTransfer) { - Status = EhciDelAsyncIntTransfer (Ehc, DeviceAddress, EndPointAddress, DataToggle); - - DEBUG ((EFI_D_INFO, "EhcAsyncInterruptTransfer: remove old transfer - %r\n", Status)); - goto ON_EXIT; - } - - Status = EFI_SUCCESS; - - if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: HC is halt\n")); - EhcAckAllInterrupt (Ehc); - - Status = EFI_DEVICE_ERROR; - goto ON_EXIT; - } - - EhcAckAllInterrupt (Ehc); - - Data = AllocatePool (DataLength); - - if (Data == NULL) { - DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to allocate buffer\n")); - - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Urb = EhcCreateUrb ( - Ehc, - DeviceAddress, - EndPointAddress, - DeviceSpeed, - *DataToggle, - MaximumPacketLength, - Translator, - EHC_INT_TRANSFER_ASYNC, - NULL, - Data, - DataLength, - CallBackFunction, - Context, - PollingInterval - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to create URB\n")); - - gBS->FreePool (Data); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - // - // New asynchronous transfer must inserted to the head. - // Check the comments in EhcMoniteAsyncRequests - // - EhcLinkQhToPeriod (Ehc, Urb->Qh); - InsertHeadList (&Ehc->AsyncIntTransfers, &Urb->UrbList); - -ON_EXIT: - Ehc->PciIo->Flush (Ehc->PciIo); - gBS->RestoreTPL (OldTpl); - - return Status; -} - - -/** - Submits synchronous interrupt transfer to an interrupt endpoint - of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction encoded in bit 7 - @param DeviceSpeed Indicates device speed. - @param MaximumPacketLength Maximum packet size the target endpoint is capable - of sending or receiving. - @param Data Buffer of data that will be transmitted to USB - device or received from USB device. - @param DataLength On input, the size, in bytes, of the data buffer; On - output, the number of bytes transferred. - @param DataToggle On input, the initial data toggle to use; on output, - it is updated to indicate the next data toggle. - @param TimeOut Maximum time, in second, to complete. - @param Translator Transaction translator to use. - @param TransferResult Variable to receive the transfer result. - - @return EFI_SUCCESS The transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @return EFI_INVALID_PARAMETER Some parameters are invalid. - @return EFI_TIMEOUT The transfer failed due to timeout. - @return EFI_DEVICE_ERROR The failed due to host controller or device error - -**/ -EFI_STATUS -EFIAPI -EhcSyncInterruptTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - USB2_HC_DEV *Ehc; - EFI_TPL OldTpl; - URB *Urb; - EFI_STATUS Status; - - // - // Validates parameters - // - if ((DataLength == NULL) || (*DataLength == 0) || - (Data == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 1) && (*DataToggle != 0)) { - return EFI_INVALID_PARAMETER; - } - - if (((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) || - ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) || - ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072))) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = EHC_FROM_THIS (This); - - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_DEVICE_ERROR; - - if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: HC is halt\n")); - - EhcAckAllInterrupt (Ehc); - goto ON_EXIT; - } - - EhcAckAllInterrupt (Ehc); - - Urb = EhcCreateUrb ( - Ehc, - DeviceAddress, - EndPointAddress, - DeviceSpeed, - *DataToggle, - MaximumPacketLength, - Translator, - EHC_INT_TRANSFER_SYNC, - NULL, - Data, - *DataLength, - NULL, - NULL, - 1 - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: failed to create URB\n")); - - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - EhcLinkQhToPeriod (Ehc, Urb->Qh); - Status = EhcExecTransfer (Ehc, Urb, TimeOut); - EhcUnlinkQhFromPeriod (Ehc, Urb->Qh); - - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - *DataToggle = Urb->DataToggle; - - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } - -ON_EXIT: - Ehc->PciIo->Flush (Ehc->PciIo); - gBS->RestoreTPL (OldTpl); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); - } - - return Status; -} - - -/** - Submits isochronous transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress End point address with its direction. - @param DeviceSpeed Device speed, Low speed device doesn't support this - type. - @param MaximumPacketLength Maximum packet size that the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data that will - be transmitted to USB device or received from USB - device. - @param DataLength The size, in bytes, of the data buffer. - @param Translator Transaction translator to use. - @param TransferResult Variable to receive the transfer result. - - @return EFI_UNSUPPORTED Isochronous transfer is unsupported. - -**/ -EFI_STATUS -EFIAPI -EhcIsochronousTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - return EFI_UNSUPPORTED; -} - - -/** - Submits Async isochronous transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress End point address with its direction. - @param DeviceSpeed Device speed, Low speed device doesn't support this - type. - @param MaximumPacketLength Maximum packet size that the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data that will - be transmitted to USB device or received from USB - device. - @param DataLength The size, in bytes, of the data buffer. - @param Translator Transaction translator to use. - @param IsochronousCallBack Function to be called when the transfer complete. - @param Context Context passed to the call back function as - parameter. - - @return EFI_UNSUPPORTED Isochronous transfer isn't supported. - -**/ -EFI_STATUS -EFIAPI -EhcAsyncIsochronousTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, - IN VOID *Context - ) -{ - return EFI_UNSUPPORTED; -} - -/** - Entry point for EFI drivers. - - @param ImageHandle EFI_HANDLE. - @param SystemTable EFI_SYSTEM_TABLE. - - @return EFI_SUCCESS Success. - EFI_DEVICE_ERROR Fail. - -**/ -EFI_STATUS -EFIAPI -EhcDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gEhciDriverBinding, - ImageHandle, - &gEhciComponentName, - &gEhciComponentName2 - ); -} - - -/** - Test to see if this driver supports ControllerHandle. Any - ControllerHandle that has Usb2HcProtocol installed will - be supported. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS This driver supports this device. - @return EFI_UNSUPPORTED This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -EhcDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - USB_CLASSC UsbClassCReg; - - // - // Test whether there is PCI IO Protocol attached on the controller handle. - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_CLASSCODE_OFFSET, - sizeof (USB_CLASSC) / sizeof (UINT8), - &UsbClassCReg - ); - - if (EFI_ERROR (Status)) { - Status = EFI_UNSUPPORTED; - goto ON_EXIT; - } - - // - // Test whether the controller belongs to Ehci type - // - if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) - || ((UsbClassCReg.ProgInterface != PCI_IF_EHCI) && (UsbClassCReg.ProgInterface != PCI_IF_UHCI) && (UsbClassCReg.ProgInterface != PCI_IF_OHCI))) { - - Status = EFI_UNSUPPORTED; - } - -ON_EXIT: - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; -} - -/** - Get the usb debug port related information. - - @param Ehc The EHCI device. - - @retval RETURN_SUCCESS Get debug port number, bar and offset successfully. - @retval Others The usb host controller does not supported usb debug port capability. - -**/ -EFI_STATUS -EhcGetUsbDebugPortInfo ( - IN USB2_HC_DEV *Ehc - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT16 PciStatus; - UINT8 CapabilityPtr; - UINT8 CapabilityId; - UINT16 DebugPort; - EFI_STATUS Status; - - ASSERT (Ehc->PciIo != NULL); - PciIo = Ehc->PciIo; - - // - // Detect if the EHCI host controller support Capaility Pointer. - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_PRIMARY_STATUS_OFFSET, - sizeof (UINT16), - &PciStatus - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - if ((PciStatus & EFI_PCI_STATUS_CAPABILITY) == 0) { - // - // The Pci Device Doesn't Support Capability Pointer. - // - return EFI_UNSUPPORTED; - } - - // - // Get Pointer To Capability List - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_CAPBILITY_POINTER_OFFSET, - 1, - &CapabilityPtr - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Find Capability ID 0xA, Which Is For Debug Port - // - while (CapabilityPtr != 0) { - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - CapabilityPtr, - 1, - &CapabilityId - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - if (CapabilityId == EHC_DEBUG_PORT_CAP_ID) { - break; - } - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - CapabilityPtr + 1, - 1, - &CapabilityPtr - ); - - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // No Debug Port Capability Found - // - if (CapabilityPtr == 0) { - return EFI_UNSUPPORTED; - } - - // - // Get The Base Address Of Debug Port Register In Debug Port Capability Register - // - Status = PciIo->Pci.Read ( - Ehc->PciIo, - EfiPciIoWidthUint8, - CapabilityPtr + 2, - sizeof (UINT16), - &DebugPort - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Ehc->DebugPortOffset = DebugPort & 0x1FFF; - Ehc->DebugPortBarNum = (UINT8)((DebugPort >> 13) - 1); - Ehc->DebugPortNum = (UINT8)((Ehc->HcStructParams & 0x00F00000) >> 20); - - return EFI_SUCCESS; -} - - -/** - Create and initialize a USB2_HC_DEV. - - @param PciIo The PciIo on this device. - @param DevicePath The device path of host controller. - @param OriginalPciAttributes Original PCI attributes. - - @return The allocated and initialized USB2_HC_DEV structure if created, - otherwise NULL. - -**/ -USB2_HC_DEV * -EhcCreateUsb2Hc ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN UINT64 OriginalPciAttributes - ) -{ - USB2_HC_DEV *Ehc; - EFI_STATUS Status; - - Ehc = AllocateZeroPool (sizeof (USB2_HC_DEV)); - - if (Ehc == NULL) { - return NULL; - } - - // - // Init EFI_USB2_HC_PROTOCOL interface and private data structure - // - Ehc->Signature = USB2_HC_DEV_SIGNATURE; - - Ehc->Usb2Hc.GetCapability = EhcGetCapability; - Ehc->Usb2Hc.Reset = EhcReset; - Ehc->Usb2Hc.GetState = EhcGetState; - Ehc->Usb2Hc.SetState = EhcSetState; - Ehc->Usb2Hc.ControlTransfer = EhcControlTransfer; - Ehc->Usb2Hc.BulkTransfer = EhcBulkTransfer; - Ehc->Usb2Hc.AsyncInterruptTransfer = EhcAsyncInterruptTransfer; - Ehc->Usb2Hc.SyncInterruptTransfer = EhcSyncInterruptTransfer; - Ehc->Usb2Hc.IsochronousTransfer = EhcIsochronousTransfer; - Ehc->Usb2Hc.AsyncIsochronousTransfer = EhcAsyncIsochronousTransfer; - Ehc->Usb2Hc.GetRootHubPortStatus = EhcGetRootHubPortStatus; - Ehc->Usb2Hc.SetRootHubPortFeature = EhcSetRootHubPortFeature; - Ehc->Usb2Hc.ClearRootHubPortFeature = EhcClearRootHubPortFeature; - Ehc->Usb2Hc.MajorRevision = 0x2; - Ehc->Usb2Hc.MinorRevision = 0x0; - - Ehc->PciIo = PciIo; - Ehc->DevicePath = DevicePath; - Ehc->OriginalPciAttributes = OriginalPciAttributes; - - InitializeListHead (&Ehc->AsyncIntTransfers); - - Ehc->HcStructParams = EhcReadCapRegister (Ehc, EHC_HCSPARAMS_OFFSET); - Ehc->HcCapParams = EhcReadCapRegister (Ehc, EHC_HCCPARAMS_OFFSET); - Ehc->CapLen = EhcReadCapRegister (Ehc, EHC_CAPLENGTH_OFFSET) & 0x0FF; - - DEBUG ((EFI_D_INFO, "EhcCreateUsb2Hc: capability length %d\n", Ehc->CapLen)); - - // - // EHCI Controllers with a CapLen of 0 are ignored. - // - if (Ehc->CapLen == 0) { - gBS->FreePool (Ehc); - return NULL; - } - - EhcGetUsbDebugPortInfo (Ehc); - - // - // Create AsyncRequest Polling Timer - // - Status = gBS->CreateEvent ( - EVT_TIMER | EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - EhcMonitorAsyncRequests, - Ehc, - &Ehc->PollTimer - ); - - if (EFI_ERROR (Status)) { - gBS->FreePool (Ehc); - return NULL; - } - - return Ehc; -} - -/** - One notified function to stop the Host Controller when gBS->ExitBootServices() called. - - @param Event Pointer to this event - @param Context Event handler private data - -**/ -VOID -EFIAPI -EhcExitBootService ( - EFI_EVENT Event, - VOID *Context - ) - -{ - USB2_HC_DEV *Ehc; - - Ehc = (USB2_HC_DEV *) Context; - - // - // Reset the Host Controller - // - EhcResetHC (Ehc, EHC_RESET_TIMEOUT); -} - - -/** - Starting the Usb EHCI Driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS supports this device. - @return EFI_UNSUPPORTED do not support this device. - @return EFI_DEVICE_ERROR cannot be started due to device Error. - @return EFI_OUT_OF_RESOURCES cannot allocate resources. - -**/ -EFI_STATUS -EFIAPI -EhcDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - USB2_HC_DEV *Ehc; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_PCI_IO_PROTOCOL *Instance; - UINT64 Supports; - UINT64 OriginalPciAttributes; - BOOLEAN PciAttributesSaved; - USB_CLASSC UsbClassCReg; - EFI_HANDLE *HandleBuffer; - UINTN NumberOfHandles; - UINTN Index; - UINTN CompanionSegmentNumber; - UINTN CompanionBusNumber; - UINTN CompanionDeviceNumber; - UINTN CompanionFunctionNumber; - UINTN EhciSegmentNumber; - UINTN EhciBusNumber; - UINTN EhciDeviceNumber; - UINTN EhciFunctionNumber; - UINT32 State; - EFI_DEVICE_PATH_PROTOCOL *HcDevicePath; - - // - // Open the PciIo Protocol, then enable the USB host controller - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Open Device Path Protocol for on USB host controller - // - HcDevicePath = NULL; - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &HcDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - PciAttributesSaved = FALSE; - // - // Save original PCI attributes - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationGet, - 0, - &OriginalPciAttributes - ); - - if (EFI_ERROR (Status)) { - goto CLOSE_PCIIO; - } - PciAttributesSaved = TRUE; - - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to enable controller\n")); - goto CLOSE_PCIIO; - } - - // - // Get the Pci device class code. - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_CLASSCODE_OFFSET, - sizeof (USB_CLASSC) / sizeof (UINT8), - &UsbClassCReg - ); - - if (EFI_ERROR (Status)) { - Status = EFI_UNSUPPORTED; - goto CLOSE_PCIIO; - } - // - // Determine if the device is UHCI or OHCI host controller or not. If yes, then find out the - // companion usb ehci host controller and force EHCI driver get attached to it before - // UHCI or OHCI driver attaches to UHCI or OHCI host controller. - // - if ((UsbClassCReg.ProgInterface == PCI_IF_UHCI || UsbClassCReg.ProgInterface == PCI_IF_OHCI) && - (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) && - (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB)) { - Status = PciIo->GetLocation ( - PciIo, - &CompanionSegmentNumber, - &CompanionBusNumber, - &CompanionDeviceNumber, - &CompanionFunctionNumber - ); - if (EFI_ERROR (Status)) { - goto CLOSE_PCIIO; - } - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &NumberOfHandles, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - goto CLOSE_PCIIO; - } - - for (Index = 0; Index < NumberOfHandles; Index++) { - // - // Get the device path on this handle - // - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **)&Instance - ); - ASSERT_EFI_ERROR (Status); - - Status = Instance->Pci.Read ( - Instance, - EfiPciIoWidthUint8, - PCI_CLASSCODE_OFFSET, - sizeof (USB_CLASSC) / sizeof (UINT8), - &UsbClassCReg - ); - - if (EFI_ERROR (Status)) { - Status = EFI_UNSUPPORTED; - goto CLOSE_PCIIO; - } - - if ((UsbClassCReg.ProgInterface == PCI_IF_EHCI) && - (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) && - (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB)) { - Status = Instance->GetLocation ( - Instance, - &EhciSegmentNumber, - &EhciBusNumber, - &EhciDeviceNumber, - &EhciFunctionNumber - ); - if (EFI_ERROR (Status)) { - goto CLOSE_PCIIO; - } - // - // Currently, the judgment on the companion usb host controller is through the - // same bus number, which may vary on different platform. - // - if (EhciBusNumber == CompanionBusNumber) { - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - EhcDriverBindingStart(This, HandleBuffer[Index], NULL); - } - } - } - Status = EFI_NOT_FOUND; - goto CLOSE_PCIIO; - } - - // - // Create then install USB2_HC_PROTOCOL - // - Ehc = EhcCreateUsb2Hc (PciIo, HcDevicePath, OriginalPciAttributes); - - if (Ehc == NULL) { - DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to create USB2_HC\n")); - - Status = EFI_OUT_OF_RESOURCES; - goto CLOSE_PCIIO; - } - - Status = gBS->InstallProtocolInterface ( - &Controller, - &gEfiUsb2HcProtocolGuid, - EFI_NATIVE_INTERFACE, - &Ehc->Usb2Hc - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to install USB2_HC Protocol\n")); - goto FREE_POOL; - } - - // - // Robustnesss improvement such as for Duet platform - // Default is not required. - // - if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) { - EhcClearLegacySupport (Ehc); - } - - if (Ehc->DebugPortNum != 0) { - State = EhcReadDbgRegister(Ehc, 0); - if ((State & (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) != (USB_DEBUG_PORT_IN_USE | USB_DEBUG_PORT_OWNER)) { - EhcResetHC (Ehc, EHC_RESET_TIMEOUT); - } - } - - Status = EhcInitHC (Ehc); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to init host controller\n")); - goto UNINSTALL_USBHC; - } - - // - // Start the asynchronous interrupt monitor - // - Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_INTERVAL); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to start async interrupt monitor\n")); - - EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); - goto UNINSTALL_USBHC; - } - - // - // Create event to stop the HC when exit boot service. - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - EhcExitBootService, - Ehc, - &gEfiEventExitBootServicesGuid, - &Ehc->ExitBootServiceEvent - ); - if (EFI_ERROR (Status)) { - goto UNINSTALL_USBHC; - } - - // - // Install the component name protocol, don't fail the start - // because of something for display. - // - AddUnicodeString2 ( - "eng", - gEhciComponentName.SupportedLanguages, - &Ehc->ControllerNameTable, - L"Enhanced Host Controller (USB 2.0)", - TRUE - ); - AddUnicodeString2 ( - "en", - gEhciComponentName2.SupportedLanguages, - &Ehc->ControllerNameTable, - L"Enhanced Host Controller (USB 2.0)", - FALSE - ); - - - DEBUG ((EFI_D_INFO, "EhcDriverBindingStart: EHCI started for controller @ %p\n", Controller)); - return EFI_SUCCESS; - -UNINSTALL_USBHC: - gBS->UninstallProtocolInterface ( - Controller, - &gEfiUsb2HcProtocolGuid, - &Ehc->Usb2Hc - ); - -FREE_POOL: - EhcFreeSched (Ehc); - gBS->CloseEvent (Ehc->PollTimer); - gBS->FreePool (Ehc); - -CLOSE_PCIIO: - if (PciAttributesSaved) { - // - // Restore original PCI attributes - // - PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSet, - OriginalPciAttributes, - NULL - ); - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; -} - - -/** - Stop this driver on ControllerHandle. Support stoping any child handles - created by this driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on. - @param NumberOfChildren Number of Children in the ChildHandleBuffer. - @param ChildHandleBuffer List of handles for the children we need to stop. - - @return EFI_SUCCESS Success. - @return EFI_DEVICE_ERROR Fail. - -**/ -EFI_STATUS -EFIAPI -EhcDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_STATUS Status; - EFI_USB2_HC_PROTOCOL *Usb2Hc; - EFI_PCI_IO_PROTOCOL *PciIo; - USB2_HC_DEV *Ehc; - - // - // Test whether the Controller handler passed in is a valid - // Usb controller handle that should be supported, if not, - // return the error status directly - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiUsb2HcProtocolGuid, - (VOID **) &Usb2Hc, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Ehc = EHC_FROM_THIS (Usb2Hc); - PciIo = Ehc->PciIo; - - Status = gBS->UninstallProtocolInterface ( - Controller, - &gEfiUsb2HcProtocolGuid, - Usb2Hc - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Stop AsyncRequest Polling timer then stop the EHCI driver - // and uninstall the EHCI protocl. - // - gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL); - EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT); - - if (Ehc->PollTimer != NULL) { - gBS->CloseEvent (Ehc->PollTimer); - } - - if (Ehc->ExitBootServiceEvent != NULL) { - gBS->CloseEvent (Ehc->ExitBootServiceEvent); - } - - EhcFreeSched (Ehc); - - if (Ehc->ControllerNameTable != NULL) { - FreeUnicodeStringTable (Ehc->ControllerNameTable); - } - - // - // Disable routing of all ports to EHCI controller, so all ports are - // routed back to the UHCI or OHCI controller. - // - EhcClearOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC); - - // - // Restore original PCI attributes - // - PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSet, - Ehc->OriginalPciAttributes, - NULL - ); - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - FreePool (Ehc); - - return EFI_SUCCESS; -} - diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h deleted file mode 100644 index 7177658092..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h +++ /dev/null @@ -1,248 +0,0 @@ -/** @file - - Provides some data struct used by EHCI controller driver. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_H_ -#define _EFI_EHCI_H_ - - -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef struct _USB2_HC_DEV USB2_HC_DEV; - -#include "UsbHcMem.h" -#include "EhciReg.h" -#include "EhciUrb.h" -#include "EhciSched.h" -#include "EhciDebug.h" -#include "ComponentName.h" - -// -// EHC timeout experience values -// - -#define EHC_1_MICROSECOND 1 -#define EHC_1_MILLISECOND (1000 * EHC_1_MICROSECOND) -#define EHC_1_SECOND (1000 * EHC_1_MILLISECOND) - -// -// EHCI register operation timeout, set by experience -// -#define EHC_RESET_TIMEOUT (1 * EHC_1_SECOND) -#define EHC_GENERIC_TIMEOUT (10 * EHC_1_MILLISECOND) - -// -// Wait for roothub port power stable, refers to Spec[EHCI1.0-2.3.9] -// -#define EHC_ROOT_PORT_RECOVERY_STALL (20 * EHC_1_MILLISECOND) - -// -// Sync and Async transfer polling interval, set by experience, -// and the unit of Async is 100us, means 1ms as interval. -// -#define EHC_SYNC_POLL_INTERVAL (1 * EHC_1_MILLISECOND) -#define EHC_ASYNC_POLL_INTERVAL EFI_TIMER_PERIOD_MILLISECONDS(1) - -// -// EHCI debug port control status register bit definition -// -#define USB_DEBUG_PORT_IN_USE BIT10 -#define USB_DEBUG_PORT_ENABLE BIT28 -#define USB_DEBUG_PORT_OWNER BIT30 - -// -// EHC raises TPL to TPL_NOTIFY to serialize all its operations -// to protect shared data structures. -// -#define EHC_TPL TPL_NOTIFY - -// -//Iterate through the doule linked list. NOT delete safe -// -#define EFI_LIST_FOR_EACH(Entry, ListHead) \ - for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink) - -// -//Iterate through the doule linked list. This is delete-safe. -//Don't touch NextEntry -// -#define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \ - for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\ - Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLink) - -#define EFI_LIST_CONTAINER(Entry, Type, Field) BASE_CR(Entry, Type, Field) - - -#define EHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0XFFFFFFFF)) -#define EHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF)) -#define EHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit))) - -#define EHC_REG_BIT_IS_SET(Ehc, Offset, Bit) \ - (EHC_BIT_IS_SET(EhcReadOpReg ((Ehc), (Offset)), (Bit))) - -#define USB2_HC_DEV_SIGNATURE SIGNATURE_32 ('e', 'h', 'c', 'i') -#define EHC_FROM_THIS(a) CR(a, USB2_HC_DEV, Usb2Hc, USB2_HC_DEV_SIGNATURE) - -struct _USB2_HC_DEV { - UINTN Signature; - EFI_USB2_HC_PROTOCOL Usb2Hc; - - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UINT64 OriginalPciAttributes; - USBHC_MEM_POOL *MemPool; - - // - // Schedule data shared between asynchronous and periodic - // transfers: - // ShortReadStop, as its name indicates, is used to terminate - // the short read except the control transfer. EHCI follows - // the alternative next QTD point when a short read happens. - // For control transfer, even the short read happens, try the - // status stage. - // - EHC_QTD *ShortReadStop; - EFI_EVENT PollTimer; - - // - // ExitBootServicesEvent is used to stop the EHC DMA operation - // after exit boot service. - // - EFI_EVENT ExitBootServiceEvent; - - // - // Asynchronous(bulk and control) transfer schedule data: - // ReclaimHead is used as the head of the asynchronous transfer - // list. It acts as the reclamation header. - // - EHC_QH *ReclaimHead; - - // - // Peroidic (interrupt) transfer schedule data: - // - VOID *PeriodFrame; // the buffer pointed by this pointer is used to store pci bus address of the QH descriptor. - VOID *PeriodFrameHost; // the buffer pointed by this pointer is used to store host memory address of the QH descriptor. - VOID *PeriodFrameMap; - - EHC_QH *PeriodOne; - LIST_ENTRY AsyncIntTransfers; - - // - // EHCI configuration data - // - UINT32 HcStructParams; // Cache of HC structure parameter, EHC_HCSPARAMS_OFFSET - UINT32 HcCapParams; // Cache of HC capability parameter, HCCPARAMS - UINT32 CapLen; // Capability length - - // - // Misc - // - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - - // - // EHCI debug port info - // - UINT16 DebugPortOffset; // The offset of debug port mmio register - UINT8 DebugPortBarNum; // The bar number of debug port mmio register - UINT8 DebugPortNum; // The port number of usb debug port -}; - - -extern EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gEhciComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gEhciComponentName2; - -/** - Test to see if this driver supports ControllerHandle. Any - ControllerHandle that has Usb2HcProtocol installed will - be supported. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS This driver supports this device. - @return EFI_UNSUPPORTED This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -EhcDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Starting the Usb EHCI Driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS supports this device. - @return EFI_UNSUPPORTED do not support this device. - @return EFI_DEVICE_ERROR cannot be started due to device Error. - @return EFI_OUT_OF_RESOURCES cannot allocate resources. - -**/ -EFI_STATUS -EFIAPI -EhcDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stop this driver on ControllerHandle. Support stoping any child handles - created by this driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on. - @param NumberOfChildren Number of Children in the ChildHandleBuffer. - @param ChildHandleBuffer List of handles for the children we need to stop. - - @return EFI_SUCCESS Success. - @return EFI_DEVICE_ERROR Fail. - -**/ -EFI_STATUS -EFIAPI -EhcDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -#endif - diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.c deleted file mode 100644 index 76368b4748..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.c +++ /dev/null @@ -1,258 +0,0 @@ -/** @file - - This file provides the information dump support for EHCI when in debug mode. - -Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "Ehci.h" - -/** - Dump the status byte in QTD/QH to a more friendly format. - - @param State The state in the QTD/QH. - -**/ -VOID -EhcDumpStatus ( - IN UINT32 State - ) -{ - if (EHC_BIT_IS_SET (State, QTD_STAT_DO_PING)) { - DEBUG ((EFI_D_VERBOSE, " Do_Ping")); - } else { - DEBUG ((EFI_D_VERBOSE, " Do_Out")); - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_DO_CS)) { - DEBUG ((EFI_D_VERBOSE, " Do_CS")); - } else { - DEBUG ((EFI_D_VERBOSE, " Do_SS")); - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_TRANS_ERR)) { - DEBUG ((EFI_D_VERBOSE, " Transfer_Error")); - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_BABBLE_ERR)) { - DEBUG ((EFI_D_VERBOSE, " Babble_Error")); - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_BUFF_ERR)) { - DEBUG ((EFI_D_VERBOSE, " Buffer_Error")); - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_HALTED)) { - DEBUG ((EFI_D_VERBOSE, " Halted")); - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_ACTIVE)) { - DEBUG ((EFI_D_VERBOSE, " Active")); - } - - DEBUG ((EFI_D_VERBOSE, "\n")); -} - - -/** - Dump the fields of a QTD. - - @param Qtd The QTD to dump. - @param Msg The message to print before the dump. - -**/ -VOID -EhcDumpQtd ( - IN EHC_QTD *Qtd, - IN CHAR8 *Msg - ) -{ - QTD_HW *QtdHw; - UINTN Index; - - if (Msg != NULL) { - DEBUG ((EFI_D_VERBOSE, Msg)); - } - - DEBUG ((EFI_D_VERBOSE, "Queue TD @ 0x%p, data length %d\n", Qtd, (UINT32)Qtd->DataLen)); - - QtdHw = &Qtd->QtdHw; - - DEBUG ((EFI_D_VERBOSE, "Next QTD : %x\n", QtdHw->NextQtd)); - DEBUG ((EFI_D_VERBOSE, "AltNext QTD : %x\n", QtdHw->AltNext)); - DEBUG ((EFI_D_VERBOSE, "Status : %x\n", QtdHw->Status)); - EhcDumpStatus (QtdHw->Status); - - if (QtdHw->Pid == QTD_PID_SETUP) { - DEBUG ((EFI_D_VERBOSE, "PID : Setup\n")); - - } else if (QtdHw->Pid == QTD_PID_INPUT) { - DEBUG ((EFI_D_VERBOSE, "PID : IN\n")); - - } else if (QtdHw->Pid == QTD_PID_OUTPUT) { - DEBUG ((EFI_D_VERBOSE, "PID : OUT\n")); - - } - - DEBUG ((EFI_D_VERBOSE, "Error Count : %d\n", QtdHw->ErrCnt)); - DEBUG ((EFI_D_VERBOSE, "Current Page : %d\n", QtdHw->CurPage)); - DEBUG ((EFI_D_VERBOSE, "IOC : %d\n", QtdHw->Ioc)); - DEBUG ((EFI_D_VERBOSE, "Total Bytes : %d\n", QtdHw->TotalBytes)); - DEBUG ((EFI_D_VERBOSE, "Data Toggle : %d\n", QtdHw->DataToggle)); - - for (Index = 0; Index < 5; Index++) { - DEBUG ((EFI_D_VERBOSE, "Page[%d] : 0x%x\n", (UINT32)Index, QtdHw->Page[Index])); - } -} - - -/** - Dump the queue head. - - @param Qh The queue head to dump. - @param Msg The message to print before the dump. - @param DumpBuf Whether to dump the memory buffer of the associated QTD. - -**/ -VOID -EhcDumpQh ( - IN EHC_QH *Qh, - IN CHAR8 *Msg, - IN BOOLEAN DumpBuf - ) -{ - EHC_QTD *Qtd; - QH_HW *QhHw; - LIST_ENTRY *Entry; - UINTN Index; - - if (Msg != NULL) { - DEBUG ((EFI_D_VERBOSE, Msg)); - } - - DEBUG ((EFI_D_VERBOSE, "Queue head @ 0x%p, interval %ld, next qh %p\n", - Qh, (UINT64)Qh->Interval, Qh->NextQh)); - - QhHw = &Qh->QhHw; - - DEBUG ((EFI_D_VERBOSE, "Hoziontal link: %x\n", QhHw->HorizonLink)); - DEBUG ((EFI_D_VERBOSE, "Device address: %d\n", QhHw->DeviceAddr)); - DEBUG ((EFI_D_VERBOSE, "Inactive : %d\n", QhHw->Inactive)); - DEBUG ((EFI_D_VERBOSE, "EP number : %d\n", QhHw->EpNum)); - DEBUG ((EFI_D_VERBOSE, "EP speed : %d\n", QhHw->EpSpeed)); - DEBUG ((EFI_D_VERBOSE, "DT control : %d\n", QhHw->DtCtrl)); - DEBUG ((EFI_D_VERBOSE, "Reclaim head : %d\n", QhHw->ReclaimHead)); - DEBUG ((EFI_D_VERBOSE, "Max packet len: %d\n", QhHw->MaxPacketLen)); - DEBUG ((EFI_D_VERBOSE, "Ctrl EP : %d\n", QhHw->CtrlEp)); - DEBUG ((EFI_D_VERBOSE, "Nak reload : %d\n", QhHw->NakReload)); - - DEBUG ((EFI_D_VERBOSE, "SMask : %x\n", QhHw->SMask)); - DEBUG ((EFI_D_VERBOSE, "CMask : %x\n", QhHw->CMask)); - DEBUG ((EFI_D_VERBOSE, "Hub address : %d\n", QhHw->HubAddr)); - DEBUG ((EFI_D_VERBOSE, "Hub port : %d\n", QhHw->PortNum)); - DEBUG ((EFI_D_VERBOSE, "Multiplier : %d\n", QhHw->Multiplier)); - - DEBUG ((EFI_D_VERBOSE, "Cur QTD : %x\n", QhHw->CurQtd)); - - DEBUG ((EFI_D_VERBOSE, "Next QTD : %x\n", QhHw->NextQtd)); - DEBUG ((EFI_D_VERBOSE, "AltNext QTD : %x\n", QhHw->AltQtd)); - DEBUG ((EFI_D_VERBOSE, "Status : %x\n", QhHw->Status)); - - EhcDumpStatus (QhHw->Status); - - if (QhHw->Pid == QTD_PID_SETUP) { - DEBUG ((EFI_D_VERBOSE, "PID : Setup\n")); - - } else if (QhHw->Pid == QTD_PID_INPUT) { - DEBUG ((EFI_D_VERBOSE, "PID : IN\n")); - - } else if (QhHw->Pid == QTD_PID_OUTPUT) { - DEBUG ((EFI_D_VERBOSE, "PID : OUT\n")); - } - - DEBUG ((EFI_D_VERBOSE, "Error Count : %d\n", QhHw->ErrCnt)); - DEBUG ((EFI_D_VERBOSE, "Current Page : %d\n", QhHw->CurPage)); - DEBUG ((EFI_D_VERBOSE, "IOC : %d\n", QhHw->Ioc)); - DEBUG ((EFI_D_VERBOSE, "Total Bytes : %d\n", QhHw->TotalBytes)); - DEBUG ((EFI_D_VERBOSE, "Data Toggle : %d\n", QhHw->DataToggle)); - - for (Index = 0; Index < 5; Index++) { - DEBUG ((EFI_D_VERBOSE, "Page[%d] : 0x%x\n", Index, QhHw->Page[Index])); - } - - DEBUG ((EFI_D_VERBOSE, "\n")); - - EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) { - Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList); - EhcDumpQtd (Qtd, NULL); - - if (DumpBuf && (Qtd->DataLen != 0)) { - EhcDumpBuf (Qtd->Data, Qtd->DataLen); - } - } -} - - -/** - Dump the buffer in the form of hex. - - @param Buf The buffer to dump. - @param Len The length of buffer. - -**/ -VOID -EhcDumpBuf ( - IN UINT8 *Buf, - IN UINTN Len - ) -{ - UINTN Index; - - for (Index = 0; Index < Len; Index++) { - if (Index % 16 == 0) { - DEBUG ((EFI_D_VERBOSE,"\n")); - } - - DEBUG ((EFI_D_VERBOSE, "%02x ", Buf[Index])); - } - - DEBUG ((EFI_D_VERBOSE, "\n")); -} - -/** - Dump the EHCI status registers. - - @param Ehc USB EHCI Host Controller instance - -**/ -VOID -EhcDumpRegs ( - IN USB2_HC_DEV *Ehc - ) -{ - UINT8 Index; - - DEBUG ((EFI_D_VERBOSE, " EHC_CAPLENGTH_OFFSET = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_CAPLENGTH_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_HCSPARAMS_OFFSET = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_HCSPARAMS_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_HCCPARAMS_OFFSET = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_HCCPARAMS_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_USBCMD_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBCMD_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_USBSTS_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBSTS_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_USBINTR_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBINTR_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_FRINDEX_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_FRINDEX_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_CTRLDSSEG_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_CTRLDSSEG_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_FRAME_BASE_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_FRAME_BASE_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_ASYNC_HEAD_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET))); - DEBUG ((EFI_D_VERBOSE, " EHC_CONFIG_FLAG_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_CONFIG_FLAG_OFFSET))); - for (Index = 0; Index < (UINT8) (Ehc->HcStructParams & HCSP_NPORTS); Index++) { - DEBUG ((EFI_D_VERBOSE, " EHC_PORT_STAT_OFFSET(%d) = 0x%08x\n", Index, EhcReadOpReg (Ehc, EHC_PORT_STAT_OFFSET + (4 * Index)))); - } -} diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.h b/MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.h deleted file mode 100644 index bc84bb7864..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.h +++ /dev/null @@ -1,75 +0,0 @@ -/** @file - - This file contains the definination for host controller debug support routines. - -Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_DEBUG_H_ -#define _EFI_EHCI_DEBUG_H_ - - -/** - Dump the fields of a QTD. - - @param Qtd The QTD to dump. - @param Msg The message to print before the dump. - -**/ -VOID -EhcDumpQtd ( - IN EHC_QTD *Qtd, - IN CHAR8 *Msg - ); - - -/** - Dump the queue head. - - @param Qh The queue head to dump. - @param Msg The message to print before the dump. - @param DumpBuf Whether to dump the memory buffer of the associated QTD. - -**/ -VOID -EhcDumpQh ( - IN EHC_QH *Qh, - IN CHAR8 *Msg, - IN BOOLEAN DumpBuf - ); - - -/** - Dump the buffer in the form of hex. - - @param Buf The buffer to dump. - @param Len The length of buffer. - -**/ -VOID -EhcDumpBuf ( - IN UINT8 *Buf, - IN UINTN Len - ); - - -/** - Dump the EHCI status registers. - - @param Ehc USB EHCI Host Controller instance - -**/ -VOID -EhcDumpRegs ( - IN USB2_HC_DEV *Ehc - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf b/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf deleted file mode 100644 index 238923e828..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf +++ /dev/null @@ -1,90 +0,0 @@ -## @file -# The EhciDxe driver is responsible for managing the behavior of EHCI controller. -# It implements the interfaces of monitoring the status of all ports and transferring -# Control, Bulk, Interrupt and Isochronous requests to Usb2.0 device. -# -# Note that EhciDxe driver is enhanced to guarantee that the EHCI controller get attached -# to the EHCI controller before the UHCI driver attaches to the companion UHCI controller. -# This way avoids the control transfer on a shared port between EHCI and companion host -# controller when UHCI gets attached earlier than EHCI and a USB 2.0 device inserts. -# -# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = EhciDxe - MODULE_UNI_FILE = EhciDxe.uni - FILE_GUID = BDFE430E-8F2A-4db0-9991-6F856594777E - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = EhcDriverEntryPoint - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64 -# -# DRIVER_BINDING = gEhciDriverBinding -# COMPONENT_NAME = gEhciComponentName -# COMPONENT_NAME2 = gEhciComponentName2 -# - -[Sources] - UsbHcMem.h - EhciUrb.c - EhciReg.h - UsbHcMem.c - EhciSched.c - EhciDebug.c - EhciReg.c - EhciDebug.h - ComponentName.c - ComponentName.h - EhciUrb.h - Ehci.h - EhciSched.h - Ehci.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport ## CONSUMES - -[LibraryClasses] - MemoryAllocationLib - BaseLib - UefiLib - UefiBootServicesTableLib - UefiDriverEntryPoint - BaseMemoryLib - DebugLib - PcdLib - ReportStatusCodeLib - -[Guids] - gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event - -[Protocols] - gEfiPciIoProtocolGuid ## TO_START - gEfiUsb2HcProtocolGuid ## BY_START - -# [Event] -# EVENT_TYPE_PERIODIC_TIMER ## CONSUMES -# - -[UserExtensions.TianoCore."ExtraFiles"] - EhciDxeExtra.uni diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.uni b/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.uni deleted file mode 100644 index 0ddb7ab705..0000000000 Binary files a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxeExtra.uni b/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxeExtra.uni deleted file mode 100644 index 0039424c15..0000000000 Binary files a/MdeModulePkg/Bus/Pci/EhciDxe/EhciDxeExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c deleted file mode 100644 index 88a66aee71..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c +++ /dev/null @@ -1,658 +0,0 @@ -/** @file - - The EHCI register operation routines. - -Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "Ehci.h" - - -/** - Read EHCI capability register. - - @param Ehc The EHCI device. - @param Offset Capability register address. - - @return The register content read. - @retval If err, return 0xffff. - -**/ -UINT32 -EhcReadCapRegister ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset - ) -{ - UINT32 Data; - EFI_STATUS Status; - - Status = Ehc->PciIo->Mem.Read ( - Ehc->PciIo, - EfiPciIoWidthUint32, - EHC_BAR_INDEX, - (UINT64) Offset, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcReadCapRegister: Pci Io read error - %r at %d\n", Status, Offset)); - Data = 0xFFFF; - } - - return Data; -} - -/** - Read EHCI debug port register. - - @param Ehc The EHCI device. - @param Offset Debug port register offset. - - @return The register content read. - @retval If err, return 0xffff. - -**/ -UINT32 -EhcReadDbgRegister ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset - ) -{ - UINT32 Data; - EFI_STATUS Status; - - Status = Ehc->PciIo->Mem.Read ( - Ehc->PciIo, - EfiPciIoWidthUint32, - Ehc->DebugPortBarNum, - (UINT64) (Ehc->DebugPortOffset + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcReadDbgRegister: Pci Io read error - %r at %d\n", Status, Offset)); - Data = 0xFFFF; - } - - return Data; -} - - -/** - Read EHCI Operation register. - - @param Ehc The EHCI device. - @param Offset The operation register offset. - - @return The register content read. - @retval If err, return 0xffff. - -**/ -UINT32 -EhcReadOpReg ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset - ) -{ - UINT32 Data; - EFI_STATUS Status; - - ASSERT (Ehc->CapLen != 0); - - Status = Ehc->PciIo->Mem.Read ( - Ehc->PciIo, - EfiPciIoWidthUint32, - EHC_BAR_INDEX, - (UINT64) (Ehc->CapLen + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset)); - Data = 0xFFFF; - } - - return Data; -} - - -/** - Write the data to the EHCI operation register. - - @param Ehc The EHCI device. - @param Offset EHCI operation register offset. - @param Data The data to write. - -**/ -VOID -EhcWriteOpReg ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - EFI_STATUS Status; - - ASSERT (Ehc->CapLen != 0); - - Status = Ehc->PciIo->Mem.Write ( - Ehc->PciIo, - EfiPciIoWidthUint32, - EHC_BAR_INDEX, - (UINT64) (Ehc->CapLen + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset)); - } -} - - -/** - Set one bit of the operational register while keeping other bits. - - @param Ehc The EHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to set. - -**/ -VOID -EhcSetOpRegBit ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = EhcReadOpReg (Ehc, Offset); - Data |= Bit; - EhcWriteOpReg (Ehc, Offset, Data); -} - - -/** - Clear one bit of the operational register while keeping other bits. - - @param Ehc The EHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to clear. - -**/ -VOID -EhcClearOpRegBit ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = EhcReadOpReg (Ehc, Offset); - Data &= ~Bit; - EhcWriteOpReg (Ehc, Offset, Data); -} - - -/** - Wait the operation register's bit as specified by Bit - to become set (or clear). - - @param Ehc The EHCI device. - @param Offset The offset of the operation register. - @param Bit The bit of the register to wait for. - @param WaitToSet Wait the bit to set or clear. - @param Timeout The time to wait before abort (in millisecond). - - @retval EFI_SUCCESS The bit successfully changed by host controller. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -EhcWaitOpRegBit ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Bit, - IN BOOLEAN WaitToSet, - IN UINT32 Timeout - ) -{ - UINT32 Index; - - for (Index = 0; Index < Timeout / EHC_SYNC_POLL_INTERVAL + 1; Index++) { - if (EHC_REG_BIT_IS_SET (Ehc, Offset, Bit) == WaitToSet) { - return EFI_SUCCESS; - } - - gBS->Stall (EHC_SYNC_POLL_INTERVAL); - } - - return EFI_TIMEOUT; -} - - -/** - Add support for UEFI Over Legacy (UoL) feature, stop - the legacy USB SMI support. - - @param Ehc The EHCI device. - -**/ -VOID -EhcClearLegacySupport ( - IN USB2_HC_DEV *Ehc - ) -{ - UINT32 ExtendCap; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT32 Value; - UINT32 TimeOut; - - DEBUG ((EFI_D_INFO, "EhcClearLegacySupport: called to clear legacy support\n")); - - PciIo = Ehc->PciIo; - ExtendCap = (Ehc->HcCapParams >> 8) & 0xFF; - - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value); - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value); - - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value); - Value |= (0x1 << 24); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value); - - TimeOut = 40; - while (TimeOut-- != 0) { - gBS->Stall (500); - - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value); - - if ((Value & 0x01010000) == 0x01000000) { - break; - } - } - - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value); - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value); -} - - - -/** - Set door bell and wait it to be ACKed by host controller. - This function is used to synchronize with the hardware. - - @param Ehc The EHCI device. - @param Timeout The time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS Synchronized with the hardware. - @retval EFI_TIMEOUT Time out happened while waiting door bell to set. - -**/ -EFI_STATUS -EhcSetAndWaitDoorBell ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - UINT32 Data; - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_IAAD); - - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_IAA, TRUE, Timeout); - - // - // ACK the IAA bit in USBSTS register. Make sure other - // interrupt bits are not ACKed. These bits are WC (Write Clean). - // - Data = EhcReadOpReg (Ehc, EHC_USBSTS_OFFSET); - Data &= ~USBSTS_INTACK_MASK; - Data |= USBSTS_IAA; - - EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, Data); - - return Status; -} - - -/** - Clear all the interrutp status bits, these bits - are Write-Clean. - - @param Ehc The EHCI device. - -**/ -VOID -EhcAckAllInterrupt ( - IN USB2_HC_DEV *Ehc - ) -{ - EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, USBSTS_INTACK_MASK); -} - - -/** - Enable the periodic schedule then wait EHC to - actually enable it. - - @param Ehc The EHCI device. - @param Timeout The time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS The periodical schedule is enabled. - @retval EFI_TIMEOUT Time out happened while enabling periodic schedule. - -**/ -EFI_STATUS -EhcEnablePeriodSchd ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_PERIOD); - - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_PERIOD_ENABLED, TRUE, Timeout); - return Status; -} - - -/** - Disable periodic schedule. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS Periodic schedule is disabled. - @retval EFI_DEVICE_ERROR Fail to disable periodic schedule. - -**/ -EFI_STATUS -EhcDisablePeriodSchd ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_PERIOD); - - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_PERIOD_ENABLED, FALSE, Timeout); - return Status; -} - - - -/** - Enable asynchrounous schedule. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_SUCCESS The EHCI asynchronous schedule is enabled. - @return Others Failed to enable the asynchronous scheudle. - -**/ -EFI_STATUS -EhcEnableAsyncSchd ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_ASYNC); - - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_ASYNC_ENABLED, TRUE, Timeout); - return Status; -} - - - -/** - Disable asynchrounous schedule. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS The asynchronous schedule is disabled. - @return Others Failed to disable the asynchronous schedule. - -**/ -EFI_STATUS -EhcDisableAsyncSchd ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_ASYNC); - - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_ASYNC_ENABLED, FALSE, Timeout); - return Status; -} - - - -/** - Whether Ehc is halted. - - @param Ehc The EHCI device. - - @retval TRUE The controller is halted. - @retval FALSE It isn't halted. - -**/ -BOOLEAN -EhcIsHalt ( - IN USB2_HC_DEV *Ehc - ) -{ - return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT); -} - - -/** - Whether system error occurred. - - @param Ehc The EHCI device. - - @return TRUE System error happened. - @return FALSE No system error. - -**/ -BOOLEAN -EhcIsSysError ( - IN USB2_HC_DEV *Ehc - ) -{ - return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR); -} - - -/** - Reset the host controller. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS The host controller is reset. - @return Others Failed to reset the host. - -**/ -EFI_STATUS -EhcResetHC ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - // - // Host can only be reset when it is halt. If not so, halt it - // - if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) { - Status = EhcHaltHC (Ehc, Timeout); - - if (EFI_ERROR (Status)) { - return Status; - } - } - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET); - Status = EhcWaitOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET, FALSE, Timeout); - return Status; -} - - -/** - Halt the host controller. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_SUCCESS The EHCI is halt. - @retval EFI_TIMEOUT Failed to halt the controller before Timeout. - -**/ -EFI_STATUS -EhcHaltHC ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN); - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, TRUE, Timeout); - return Status; -} - - -/** - Set the EHCI to run. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_SUCCESS The EHCI is running. - @return Others Failed to set the EHCI to run. - -**/ -EFI_STATUS -EhcRunHC ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN); - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, FALSE, Timeout); - return Status; -} - - -/** - Initialize the HC hardware. - EHCI spec lists the five things to do to initialize the hardware: - 1. Program CTRLDSSEGMENT - 2. Set USBINTR to enable interrupts - 3. Set periodic list base - 4. Set USBCMD, interrupt threshold, frame list size etc - 5. Write 1 to CONFIGFLAG to route all ports to EHCI - - @param Ehc The EHCI device. - - @return EFI_SUCCESS The EHCI has come out of halt state. - @return EFI_TIMEOUT Time out happened. - -**/ -EFI_STATUS -EhcInitHC ( - IN USB2_HC_DEV *Ehc - ) -{ - EFI_STATUS Status; - UINT32 Index; - - // This ASSERT crashes the BeagleBoard. There is some issue in the USB stack. - // This ASSERT needs to be removed so the BeagleBoard will boot. When we fix - // the USB stack we can put this ASSERT back in - // ASSERT (EhcIsHalt (Ehc)); - - // - // Allocate the periodic frame and associated memeory - // management facilities if not already done. - // - if (Ehc->PeriodFrame != NULL) { - EhcFreeSched (Ehc); - } - - Status = EhcInitSched (Ehc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // 1. Clear USBINTR to disable all the interrupt. UEFI works by polling - // - EhcWriteOpReg (Ehc, EHC_USBINTR_OFFSET, 0); - - // - // 2. Start the Host Controller - // - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN); - - // - // 3. Power up all ports if EHCI has Port Power Control (PPC) support - // - if (Ehc->HcStructParams & HCSP_PPC) { - for (Index = 0; Index < (UINT8) (Ehc->HcStructParams & HCSP_NPORTS); Index++) { - EhcSetOpRegBit (Ehc, (UINT32) (EHC_PORT_STAT_OFFSET + (4 * Index)), PORTSC_POWER); - } - } - - // - // Wait roothub port power stable - // - gBS->Stall (EHC_ROOT_PORT_RECOVERY_STALL); - - // - // 4. Set all ports routing to EHC - // - EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC); - - Status = EhcEnablePeriodSchd (Ehc, EHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcInitHC: failed to enable period schedule\n")); - return Status; - } - - Status = EhcEnableAsyncSchd (Ehc, EHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcInitHC: failed to enable async schedule\n")); - return Status; - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h deleted file mode 100644 index 2347ee125f..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h +++ /dev/null @@ -1,363 +0,0 @@ -/** @file - - This file contains the definination for host controller register operation routines. - -Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_REG_H_ -#define _EFI_EHCI_REG_H_ - -// -// EHCI register offset -// - - -// -// Capability register offset -// -#define EHC_CAPLENGTH_OFFSET 0 // Capability register length offset -#define EHC_HCSPARAMS_OFFSET 0x04 // Structural Parameters 04-07h -#define EHC_HCCPARAMS_OFFSET 0x08 // Capability parameters offset - -// -// Capability register bit definition -// -#define HCSP_NPORTS 0x0F // Number of root hub port -#define HCSP_PPC 0x10 // Port Power Control -#define HCCP_64BIT 0x01 // 64-bit addressing capability - -// -// Operational register offset -// -#define EHC_USBCMD_OFFSET 0x0 // USB command register offset -#define EHC_USBSTS_OFFSET 0x04 // Statue register offset -#define EHC_USBINTR_OFFSET 0x08 // USB interrutp offset -#define EHC_FRINDEX_OFFSET 0x0C // Frame index offset -#define EHC_CTRLDSSEG_OFFSET 0x10 // Control data structure segment offset -#define EHC_FRAME_BASE_OFFSET 0x14 // Frame list base address offset -#define EHC_ASYNC_HEAD_OFFSET 0x18 // Next asynchronous list address offset -#define EHC_CONFIG_FLAG_OFFSET 0x40 // Configure flag register offset -#define EHC_PORT_STAT_OFFSET 0x44 // Port status/control offset - -#define EHC_FRAME_LEN 1024 - -// -// Register bit definition -// -#define CONFIGFLAG_ROUTE_EHC 0x01 // Route port to EHC - -#define USBCMD_RUN 0x01 // Run/stop -#define USBCMD_RESET 0x02 // Start the host controller reset -#define USBCMD_ENABLE_PERIOD 0x10 // Enable periodic schedule -#define USBCMD_ENABLE_ASYNC 0x20 // Enable asynchronous schedule -#define USBCMD_IAAD 0x40 // Interrupt on async advance doorbell - -#define USBSTS_IAA 0x20 // Interrupt on async advance -#define USBSTS_PERIOD_ENABLED 0x4000 // Periodic schedule status -#define USBSTS_ASYNC_ENABLED 0x8000 // Asynchronous schedule status -#define USBSTS_HALT 0x1000 // Host controller halted -#define USBSTS_SYS_ERROR 0x10 // Host system error -#define USBSTS_INTACK_MASK 0x003F // Mask for the interrupt ACK, the WC - // (write clean) bits in USBSTS register - -#define PORTSC_CONN 0x01 // Current Connect Status -#define PORTSC_CONN_CHANGE 0x02 // Connect Status Change -#define PORTSC_ENABLED 0x04 // Port Enable / Disable -#define PORTSC_ENABLE_CHANGE 0x08 // Port Enable / Disable Change -#define PORTSC_OVERCUR 0x10 // Over current Active -#define PORTSC_OVERCUR_CHANGE 0x20 // Over current Change -#define PORSTSC_RESUME 0x40 // Force Port Resume -#define PORTSC_SUSPEND 0x80 // Port Suspend State -#define PORTSC_RESET 0x100 // Port Reset -#define PORTSC_LINESTATE_K 0x400 // Line Status K-state -#define PORTSC_LINESTATE_J 0x800 // Line Status J-state -#define PORTSC_POWER 0x1000 // Port Power -#define PORTSC_OWNER 0x2000 // Port Owner -#define PORTSC_CHANGE_MASK 0x2A // Mask of the port change bits, - // they are WC (write clean) -// -// PCI Configuration Registers -// -#define EHC_BAR_INDEX 0 // how many bytes away from USB_BASE to 0x10 - -// -// Debug port capability id -// -#define EHC_DEBUG_PORT_CAP_ID 0x0A - -#define EHC_LINK_TERMINATED(Link) (((Link) & 0x01) != 0) - -#define EHC_ADDR(High, QhHw32) \ - ((VOID *) (UINTN) (LShiftU64 ((High), 32) | ((QhHw32) & 0xFFFFFFF0))) - -#define EHCI_IS_DATAIN(EndpointAddr) EHC_BIT_IS_SET((EndpointAddr), 0x80) - -// -// Structure to map the hardware port states to the -// UEFI's port states. -// -typedef struct { - UINT16 HwState; - UINT16 UefiState; -} USB_PORT_STATE_MAP; - -// -// Ehci Data and Ctrl Structures -// -#pragma pack(1) -typedef struct { - UINT8 ProgInterface; - UINT8 SubClassCode; - UINT8 BaseCode; -} USB_CLASSC; -#pragma pack() - -/** - Read EHCI capability register. - - @param Ehc The EHCI device. - @param Offset Capability register address. - - @return The register content. - -**/ -UINT32 -EhcReadCapRegister ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset - ); - -/** - Read EHCI debug port register. - - @param Ehc The EHCI device. - @param Offset Debug port register address. - - @return The register content read. - @retval If err, return 0xffff. - -**/ -UINT32 -EhcReadDbgRegister ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset - ); - -/** - Read EHCI Operation register. - - @param Ehc The EHCI device. - @param Offset The operation register offset. - - @return The register content. - -**/ -UINT32 -EhcReadOpReg ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset - ); - - -/** - Write the data to the EHCI operation register. - - @param Ehc The EHCI device. - @param Offset EHCI operation register offset. - @param Data The data to write. - -**/ -VOID -EhcWriteOpReg ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Data - ); - -/** - Set one bit of the operational register while keeping other bits. - - @param Ehc The EHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to set. - -**/ -VOID -EhcSetOpRegBit ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Clear one bit of the operational register while keeping other bits. - - @param Ehc The EHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to clear. - -**/ -VOID -EhcClearOpRegBit ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Add support for UEFI Over Legacy (UoL) feature, stop - the legacy USB SMI support. - - @param Ehc The EHCI device. - -**/ -VOID -EhcClearLegacySupport ( - IN USB2_HC_DEV *Ehc - ); - - - -/** - Set door bell and wait it to be ACKed by host controller. - This function is used to synchronize with the hardware. - - @param Ehc The EHCI device. - @param Timeout The time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS Synchronized with the hardware. - @retval EFI_TIMEOUT Time out happened while waiting door bell to set. - -**/ -EFI_STATUS -EhcSetAndWaitDoorBell ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ); - - -/** - Clear all the interrutp status bits, these bits are Write-Clean. - - @param Ehc The EHCI device. - -**/ -VOID -EhcAckAllInterrupt ( - IN USB2_HC_DEV *Ehc - ); - - - -/** - Whether Ehc is halted. - - @param Ehc The EHCI device. - - @retval TRUE The controller is halted. - @retval FALSE It isn't halted. - -**/ -BOOLEAN -EhcIsHalt ( - IN USB2_HC_DEV *Ehc - ); - - -/** - Whether system error occurred. - - @param Ehc The EHCI device. - - @retval TRUE System error happened. - @retval FALSE No system error. - -**/ -BOOLEAN -EhcIsSysError ( - IN USB2_HC_DEV *Ehc - ); - - -/** - Reset the host controller. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS The host controller is reset. - @return Others Failed to reset the host. - -**/ -EFI_STATUS -EhcResetHC ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ); - - -/** - Halt the host controller. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @return EFI_SUCCESS The EHCI is halt. - @return EFI_TIMEOUT Failed to halt the controller before Timeout. - -**/ -EFI_STATUS -EhcHaltHC ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ); - - -/** - Set the EHCI to run. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @return EFI_SUCCESS The EHCI is running. - @return Others Failed to set the EHCI to run. - -**/ -EFI_STATUS -EhcRunHC ( - IN USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ); - - - -/** - Initialize the HC hardware. - EHCI spec lists the five things to do to initialize the hardware: - 1. Program CTRLDSSEGMENT - 2. Set USBINTR to enable interrupts - 3. Set periodic list base - 4. Set USBCMD, interrupt threshold, frame list size etc - 5. Write 1 to CONFIGFLAG to route all ports to EHCI - - @param Ehc The EHCI device. - - @return EFI_SUCCESS The EHCI has come out of halt state. - @return EFI_TIMEOUT Time out happened. - -**/ -EFI_STATUS -EhcInitHC ( - IN USB2_HC_DEV *Ehc - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c deleted file mode 100644 index 5594e6699e..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c +++ /dev/null @@ -1,1052 +0,0 @@ -/** @file - - EHCI transfer scheduling routines. - -Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ehci.h" - - -/** - Create helper QTD/QH for the EHCI device. - - @param Ehc The EHCI device. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for helper QTD/QH. - @retval EFI_SUCCESS Helper QH/QTD are created. - -**/ -EFI_STATUS -EhcCreateHelpQ ( - IN USB2_HC_DEV *Ehc - ) -{ - USB_ENDPOINT Ep; - EHC_QH *Qh; - QH_HW *QhHw; - EHC_QTD *Qtd; - EFI_PHYSICAL_ADDRESS PciAddr; - - // - // Create an inactive Qtd to terminate the short packet read. - // - Qtd = EhcCreateQtd (Ehc, NULL, NULL, 0, QTD_PID_INPUT, 0, 64); - - if (Qtd == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Qtd->QtdHw.Status = QTD_STAT_HALTED; - Ehc->ShortReadStop = Qtd; - - // - // Create a QH to act as the EHC reclamation header. - // Set the header to loopback to itself. - // - Ep.DevAddr = 0; - Ep.EpAddr = 1; - Ep.Direction = EfiUsbDataIn; - Ep.DevSpeed = EFI_USB_SPEED_HIGH; - Ep.MaxPacket = 64; - Ep.HubAddr = 0; - Ep.HubPort = 0; - Ep.Toggle = 0; - Ep.Type = EHC_BULK_TRANSFER; - Ep.PollRate = 1; - - Qh = EhcCreateQh (Ehc, &Ep); - - if (Qh == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH)); - QhHw = &Qh->QhHw; - QhHw->HorizonLink = QH_LINK (PciAddr + OFFSET_OF(EHC_QH, QhHw), EHC_TYPE_QH, FALSE); - QhHw->Status = QTD_STAT_HALTED; - QhHw->ReclaimHead = 1; - Qh->NextQh = Qh; - Ehc->ReclaimHead = Qh; - - // - // Create a dummy QH to act as the terminator for periodical schedule - // - Ep.EpAddr = 2; - Ep.Type = EHC_INT_TRANSFER_SYNC; - - Qh = EhcCreateQh (Ehc, &Ep); - - if (Qh == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Qh->QhHw.Status = QTD_STAT_HALTED; - Ehc->PeriodOne = Qh; - - return EFI_SUCCESS; -} - - -/** - Initialize the schedule data structure such as frame list. - - @param Ehc The EHCI device to init schedule data. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to init schedule data. - @retval EFI_SUCCESS The schedule data is initialized. - -**/ -EFI_STATUS -EhcInitSched ( - IN USB2_HC_DEV *Ehc - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - VOID *Buf; - EFI_PHYSICAL_ADDRESS PhyAddr; - VOID *Map; - UINTN Pages; - UINTN Bytes; - UINTN Index; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS PciAddr; - - // - // First initialize the periodical schedule data: - // 1. Allocate and map the memory for the frame list - // 2. Create the help QTD/QH - // 3. Initialize the frame entries - // 4. Set the frame list register - // - PciIo = Ehc->PciIo; - - Bytes = 4096; - Pages = EFI_SIZE_TO_PAGES (Bytes); - - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - Pages, - &Buf, - 0 - ); - - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - Buf, - &Bytes, - &PhyAddr, - &Map - ); - - if (EFI_ERROR (Status) || (Bytes != 4096)) { - PciIo->FreeBuffer (PciIo, Pages, Buf); - return EFI_OUT_OF_RESOURCES; - } - - Ehc->PeriodFrame = Buf; - Ehc->PeriodFrameMap = Map; - - // - // Program the FRAMELISTBASE register with the low 32 bit addr - // - EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (PhyAddr)); - // - // Program the CTRLDSSEGMENT register with the high 32 bit addr - // - EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, EHC_HIGH_32BIT (PhyAddr)); - - // - // Init memory pool management then create the helper - // QTD/QH. If failed, previously allocated resources - // will be freed by EhcFreeSched - // - Ehc->MemPool = UsbHcInitMemPool ( - PciIo, - EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT), - EHC_HIGH_32BIT (PhyAddr) - ); - - if (Ehc->MemPool == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit1; - } - - Status = EhcCreateHelpQ (Ehc); - - if (EFI_ERROR (Status)) { - goto ErrorExit; - } - - // - // Initialize the frame list entries then set the registers - // - Ehc->PeriodFrameHost = AllocateZeroPool (EHC_FRAME_LEN * sizeof (UINTN)); - if (Ehc->PeriodFrameHost == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ErrorExit; - } - - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH)); - - for (Index = 0; Index < EHC_FRAME_LEN; Index++) { - // - // Store the pci bus address of the QH in period frame list which will be accessed by pci bus master. - // - ((UINT32 *)(Ehc->PeriodFrame))[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); - // - // Store the host address of the QH in period frame list which will be accessed by host. - // - ((UINTN *)(Ehc->PeriodFrameHost))[Index] = (UINTN)Ehc->PeriodOne; - } - - // - // Second initialize the asynchronous schedule: - // Only need to set the AsynListAddr register to - // the reclamation header - // - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH)); - EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (PciAddr)); - return EFI_SUCCESS; - -ErrorExit: - if (Ehc->PeriodOne != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH)); - Ehc->PeriodOne = NULL; - } - - if (Ehc->ReclaimHead != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH)); - Ehc->ReclaimHead = NULL; - } - - if (Ehc->ShortReadStop != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD)); - Ehc->ShortReadStop = NULL; - } - -ErrorExit1: - PciIo->FreeBuffer (PciIo, Pages, Buf); - PciIo->Unmap (PciIo, Map); - - return Status; -} - - -/** - Free the schedule data. It may be partially initialized. - - @param Ehc The EHCI device. - -**/ -VOID -EhcFreeSched ( - IN USB2_HC_DEV *Ehc - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, 0); - EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, 0); - - if (Ehc->PeriodOne != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH)); - Ehc->PeriodOne = NULL; - } - - if (Ehc->ReclaimHead != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH)); - Ehc->ReclaimHead = NULL; - } - - if (Ehc->ShortReadStop != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD)); - Ehc->ShortReadStop = NULL; - } - - if (Ehc->MemPool != NULL) { - UsbHcFreeMemPool (Ehc->MemPool); - Ehc->MemPool = NULL; - } - - if (Ehc->PeriodFrame != NULL) { - PciIo = Ehc->PciIo; - ASSERT (PciIo != NULL); - - PciIo->Unmap (PciIo, Ehc->PeriodFrameMap); - - PciIo->FreeBuffer ( - PciIo, - EFI_SIZE_TO_PAGES (EFI_PAGE_SIZE), - Ehc->PeriodFrame - ); - - Ehc->PeriodFrame = NULL; - } - - if (Ehc->PeriodFrameHost != NULL) { - FreePool (Ehc->PeriodFrameHost); - Ehc->PeriodFrameHost = NULL; - } -} - - -/** - Link the queue head to the asynchronous schedule list. - UEFI only supports one CTRL/BULK transfer at a time - due to its interfaces. This simplifies the AsynList - management: A reclamation header is always linked to - the AsyncListAddr, the only active QH is appended to it. - - @param Ehc The EHCI device. - @param Qh The queue head to link. - -**/ -VOID -EhcLinkQhToAsync ( - IN USB2_HC_DEV *Ehc, - IN EHC_QH *Qh - ) -{ - EHC_QH *Head; - EFI_PHYSICAL_ADDRESS PciAddr; - - // - // Append the queue head after the reclaim header, then - // fix the hardware visiable parts (EHCI R1.0 page 72). - // ReclaimHead is always linked to the EHCI's AsynListAddr. - // - Head = Ehc->ReclaimHead; - - Qh->NextQh = Head->NextQh; - Head->NextQh = Qh; - - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh->NextQh, sizeof (EHC_QH)); - Qh->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head->NextQh, sizeof (EHC_QH)); - Head->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); -} - - -/** - Unlink a queue head from the asynchronous schedule list. - Need to synchronize with hardware. - - @param Ehc The EHCI device. - @param Qh The queue head to unlink. - -**/ -VOID -EhcUnlinkQhFromAsync ( - IN USB2_HC_DEV *Ehc, - IN EHC_QH *Qh - ) -{ - EHC_QH *Head; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS PciAddr; - - ASSERT (Ehc->ReclaimHead->NextQh == Qh); - - // - // Remove the QH from reclamation head, then update the hardware - // visiable part: Only need to loopback the ReclaimHead. The Qh - // is pointing to ReclaimHead (which is staill in the list). - // - Head = Ehc->ReclaimHead; - - Head->NextQh = Qh->NextQh; - Qh->NextQh = NULL; - - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head->NextQh, sizeof (EHC_QH)); - Head->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); - - // - // Set and wait the door bell to synchronize with the hardware - // - Status = EhcSetAndWaitDoorBell (Ehc, EHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcUnlinkQhFromAsync: Failed to synchronize with doorbell\n")); - } -} - - -/** - Link a queue head for interrupt transfer to the periodic - schedule frame list. This code is very much the same as - that in UHCI. - - @param Ehc The EHCI device. - @param Qh The queue head to link. - -**/ -VOID -EhcLinkQhToPeriod ( - IN USB2_HC_DEV *Ehc, - IN EHC_QH *Qh - ) -{ - UINTN Index; - EHC_QH *Prev; - EHC_QH *Next; - EFI_PHYSICAL_ADDRESS PciAddr; - - for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) { - // - // First QH can't be NULL because we always keep PeriodOne - // heads on the frame list - // - ASSERT (!EHC_LINK_TERMINATED (((UINT32*)Ehc->PeriodFrame)[Index])); - Next = (EHC_QH*)((UINTN*)Ehc->PeriodFrameHost)[Index]; - Prev = NULL; - - // - // Now, insert the queue head (Qh) into this frame: - // 1. Find a queue head with the same poll interval, just insert - // Qh after this queue head, then we are done. - // - // 2. Find the position to insert the queue head into: - // Previous head's interval is bigger than Qh's - // Next head's interval is less than Qh's - // Then, insert the Qh between then - // - while (Next->Interval > Qh->Interval) { - Prev = Next; - Next = Next->NextQh; - } - - ASSERT (Next != NULL); - - // - // The entry may have been linked into the frame by early insertation. - // For example: if insert a Qh with Qh.Interval == 4, and there is a Qh - // with Qh.Interval == 8 on the frame. If so, we are done with this frame. - // It isn't necessary to compare all the QH with the same interval to - // Qh. This is because if there is other QH with the same interval, Qh - // should has been inserted after that at Frames[0] and at Frames[0] it is - // impossible for (Next == Qh) - // - if (Next == Qh) { - continue; - } - - if (Next->Interval == Qh->Interval) { - // - // If there is a QH with the same interval, it locates at - // Frames[0], and we can simply insert it after this QH. We - // are all done. - // - ASSERT ((Index == 0) && (Qh->NextQh == NULL)); - - Prev = Next; - Next = Next->NextQh; - - Qh->NextQh = Next; - Prev->NextQh = Qh; - - Qh->QhHw.HorizonLink = Prev->QhHw.HorizonLink; - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH)); - Prev->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); - break; - } - - // - // OK, find the right position, insert it in. If Qh's next - // link has already been set, it is in position. This is - // guarranted by 2^n polling interval. - // - if (Qh->NextQh == NULL) { - Qh->NextQh = Next; - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Next, sizeof (EHC_QH)); - Qh->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); - } - - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH)); - - if (Prev == NULL) { - ((UINT32*)Ehc->PeriodFrame)[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); - ((UINTN*)Ehc->PeriodFrameHost)[Index] = (UINTN)Qh; - } else { - Prev->NextQh = Qh; - Prev->QhHw.HorizonLink = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE); - } - } -} - - -/** - Unlink an interrupt queue head from the periodic - schedule frame list. - - @param Ehc The EHCI device. - @param Qh The queue head to unlink. - -**/ -VOID -EhcUnlinkQhFromPeriod ( - IN USB2_HC_DEV *Ehc, - IN EHC_QH *Qh - ) -{ - UINTN Index; - EHC_QH *Prev; - EHC_QH *This; - - for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) { - // - // Frame link can't be NULL because we always keep PeroidOne - // on the frame list - // - ASSERT (!EHC_LINK_TERMINATED (((UINT32*)Ehc->PeriodFrame)[Index])); - This = (EHC_QH*)((UINTN*)Ehc->PeriodFrameHost)[Index]; - Prev = NULL; - - // - // Walk through the frame's QH list to find the - // queue head to remove - // - while ((This != NULL) && (This != Qh)) { - Prev = This; - This = This->NextQh; - } - - // - // Qh may have already been unlinked from this frame - // by early action. See the comments in EhcLinkQhToPeriod. - // - if (This == NULL) { - continue; - } - - if (Prev == NULL) { - // - // Qh is the first entry in the frame - // - ((UINT32*)Ehc->PeriodFrame)[Index] = Qh->QhHw.HorizonLink; - ((UINTN*)Ehc->PeriodFrameHost)[Index] = (UINTN)Qh->NextQh; - } else { - Prev->NextQh = Qh->NextQh; - Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink; - } - } -} - - -/** - Check the URB's execution result and update the URB's - result accordingly. - - @param Ehc The EHCI device. - @param Urb The URB to check result. - - @return Whether the result of URB transfer is finialized. - -**/ -BOOLEAN -EhcCheckUrbResult ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb - ) -{ - LIST_ENTRY *Entry; - EHC_QTD *Qtd; - QTD_HW *QtdHw; - UINT8 State; - BOOLEAN Finished; - EFI_PHYSICAL_ADDRESS PciAddr; - - ASSERT ((Ehc != NULL) && (Urb != NULL) && (Urb->Qh != NULL)); - - Finished = TRUE; - Urb->Completed = 0; - - Urb->Result = EFI_USB_NOERROR; - - if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - Urb->Result |= EFI_USB_ERR_SYSTEM; - goto ON_EXIT; - } - - EFI_LIST_FOR_EACH (Entry, &Urb->Qh->Qtds) { - Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList); - QtdHw = &Qtd->QtdHw; - State = (UINT8) QtdHw->Status; - - if (EHC_BIT_IS_SET (State, QTD_STAT_HALTED)) { - // - // EHCI will halt the queue head when met some error. - // If it is halted, the result of URB is finialized. - // - if ((State & QTD_STAT_ERR_MASK) == 0) { - Urb->Result |= EFI_USB_ERR_STALL; - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_BABBLE_ERR)) { - Urb->Result |= EFI_USB_ERR_BABBLE; - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_BUFF_ERR)) { - Urb->Result |= EFI_USB_ERR_BUFFER; - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_TRANS_ERR) && (QtdHw->ErrCnt == 0)) { - Urb->Result |= EFI_USB_ERR_TIMEOUT; - } - - Finished = TRUE; - goto ON_EXIT; - - } else if (EHC_BIT_IS_SET (State, QTD_STAT_ACTIVE)) { - // - // The QTD is still active, no need to check furthur. - // - Urb->Result |= EFI_USB_ERR_NOTEXECUTE; - - Finished = FALSE; - goto ON_EXIT; - - } else { - // - // This QTD is finished OK or met short packet read. Update the - // transfer length if it isn't a setup. - // - if (QtdHw->Pid != QTD_PID_SETUP) { - Urb->Completed += Qtd->DataLen - QtdHw->TotalBytes; - } - - if ((QtdHw->TotalBytes != 0) && (QtdHw->Pid == QTD_PID_INPUT)) { - EhcDumpQh (Urb->Qh, "Short packet read", FALSE); - - // - // Short packet read condition. If it isn't a setup transfer, - // no need to check furthur: the queue head will halt at the - // ShortReadStop. If it is a setup transfer, need to check the - // Status Stage of the setup transfer to get the finial result - // - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD)); - if (QtdHw->AltNext == QTD_LINK (PciAddr, FALSE)) { - DEBUG ((EFI_D_VERBOSE, "EhcCheckUrbResult: Short packet read, break\n")); - - Finished = TRUE; - goto ON_EXIT; - } - - DEBUG ((EFI_D_VERBOSE, "EhcCheckUrbResult: Short packet read, continue\n")); - } - } - } - -ON_EXIT: - // - // Return the data toggle set by EHCI hardware, bulk and interrupt - // transfer will use this to initialize the next transaction. For - // Control transfer, it always start a new data toggle sequence for - // new transfer. - // - // NOTICE: don't move DT update before the loop, otherwise there is - // a race condition that DT is wrong. - // - Urb->DataToggle = (UINT8) Urb->Qh->QhHw.DataToggle; - - return Finished; -} - - -/** - Execute the transfer by polling the URB. This is a synchronous operation. - - @param Ehc The EHCI device. - @param Urb The URB to execute. - @param TimeOut The time to wait before abort, in millisecond. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -EhcExecTransfer ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb, - IN UINTN TimeOut - ) -{ - EFI_STATUS Status; - UINTN Index; - UINTN Loop; - BOOLEAN Finished; - BOOLEAN InfiniteLoop; - - Status = EFI_SUCCESS; - Loop = TimeOut * EHC_1_MILLISECOND; - Finished = FALSE; - InfiniteLoop = FALSE; - - // - // According to UEFI spec section 16.2.4, If Timeout is 0, then the caller - // must wait for the function to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR - // is returned. - // - if (TimeOut == 0) { - InfiniteLoop = TRUE; - } - - for (Index = 0; InfiniteLoop || (Index < Loop); Index++) { - Finished = EhcCheckUrbResult (Ehc, Urb); - - if (Finished) { - break; - } - - gBS->Stall (EHC_1_MICROSECOND); - } - - if (!Finished) { - DEBUG ((EFI_D_ERROR, "EhcExecTransfer: transfer not finished in %dms\n", (UINT32)TimeOut)); - EhcDumpQh (Urb->Qh, NULL, FALSE); - - Status = EFI_TIMEOUT; - - } else if (Urb->Result != EFI_USB_NOERROR) { - DEBUG ((EFI_D_ERROR, "EhcExecTransfer: transfer failed with %x\n", Urb->Result)); - EhcDumpQh (Urb->Qh, NULL, FALSE); - - Status = EFI_DEVICE_ERROR; - } - - return Status; -} - - -/** - Delete a single asynchronous interrupt transfer for - the device and endpoint. - - @param Ehc The EHCI device. - @param DevAddr The address of the target device. - @param EpNum The endpoint of the target. - @param DataToggle Return the next data toggle to use. - - @retval EFI_SUCCESS An asynchronous transfer is removed. - @retval EFI_NOT_FOUND No transfer for the device is found. - -**/ -EFI_STATUS -EhciDelAsyncIntTransfer ( - IN USB2_HC_DEV *Ehc, - IN UINT8 DevAddr, - IN UINT8 EpNum, - OUT UINT8 *DataToggle - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - URB *Urb; - EFI_USB_DATA_DIRECTION Direction; - - Direction = (((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut); - EpNum &= 0x0F; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Ehc->AsyncIntTransfers) { - Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList); - - if ((Urb->Ep.DevAddr == DevAddr) && (Urb->Ep.EpAddr == EpNum) && - (Urb->Ep.Direction == Direction)) { - // - // Check the URB status to retrieve the next data toggle - // from the associated queue head. - // - EhcCheckUrbResult (Ehc, Urb); - *DataToggle = Urb->DataToggle; - - EhcUnlinkQhFromPeriod (Ehc, Urb->Qh); - RemoveEntryList (&Urb->UrbList); - - gBS->FreePool (Urb->Data); - EhcFreeUrb (Ehc, Urb); - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - - -/** - Remove all the asynchronous interrutp transfers. - - @param Ehc The EHCI device. - -**/ -VOID -EhciDelAllAsyncIntTransfers ( - IN USB2_HC_DEV *Ehc - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - URB *Urb; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Ehc->AsyncIntTransfers) { - Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList); - - EhcUnlinkQhFromPeriod (Ehc, Urb->Qh); - RemoveEntryList (&Urb->UrbList); - - gBS->FreePool (Urb->Data); - EhcFreeUrb (Ehc, Urb); - } -} - - -/** - Flush data from PCI controller specific address to mapped system - memory address. - - @param Ehc The EHCI device. - @param Urb The URB to unmap. - - @retval EFI_SUCCESS Success to flush data to mapped system memory. - @retval EFI_DEVICE_ERROR Fail to flush data to mapped system memory. - -**/ -EFI_STATUS -EhcFlushAsyncIntMap ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS PhyAddr; - EFI_PCI_IO_PROTOCOL_OPERATION MapOp; - EFI_PCI_IO_PROTOCOL *PciIo; - UINTN Len; - VOID *Map; - - PciIo = Ehc->PciIo; - Len = Urb->DataLen; - - if (Urb->Ep.Direction == EfiUsbDataIn) { - MapOp = EfiPciIoOperationBusMasterWrite; - } else { - MapOp = EfiPciIoOperationBusMasterRead; - } - - Status = PciIo->Unmap (PciIo, Urb->DataMap); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Urb->DataMap = NULL; - - Status = PciIo->Map (PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map); - if (EFI_ERROR (Status) || (Len != Urb->DataLen)) { - goto ON_ERROR; - } - - Urb->DataPhy = (VOID *) ((UINTN) PhyAddr); - Urb->DataMap = Map; - return EFI_SUCCESS; - -ON_ERROR: - return EFI_DEVICE_ERROR; -} - - -/** - Update the queue head for next round of asynchronous transfer. - - @param Ehc The EHCI device. - @param Urb The URB to update. - -**/ -VOID -EhcUpdateAsyncRequest ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb - ) -{ - LIST_ENTRY *Entry; - EHC_QTD *FirstQtd; - QH_HW *QhHw; - EHC_QTD *Qtd; - QTD_HW *QtdHw; - UINTN Index; - EFI_PHYSICAL_ADDRESS PciAddr; - - Qtd = NULL; - - if (Urb->Result == EFI_USB_NOERROR) { - FirstQtd = NULL; - - EFI_LIST_FOR_EACH (Entry, &Urb->Qh->Qtds) { - Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList); - - if (FirstQtd == NULL) { - FirstQtd = Qtd; - } - - // - // Update the QTD for next round of transfer. Host control - // may change dt/Total Bytes to Transfer/C_Page/Cerr/Status/ - // Current Offset. These fields need to be updated. DT isn't - // used by interrupt transfer. It uses DT in queue head. - // Current Offset is in Page[0], only need to reset Page[0] - // to initial data buffer. - // - QtdHw = &Qtd->QtdHw; - QtdHw->Status = QTD_STAT_ACTIVE; - QtdHw->ErrCnt = QTD_MAX_ERR; - QtdHw->CurPage = 0; - QtdHw->TotalBytes = (UINT32) Qtd->DataLen; - // - // calculate physical address by offset. - // - PciAddr = (UINTN)Urb->DataPhy + ((UINTN)Qtd->Data - (UINTN)Urb->Data); - QtdHw->Page[0] = EHC_LOW_32BIT (PciAddr); - QtdHw->PageHigh[0]= EHC_HIGH_32BIT (PciAddr); - } - - // - // Update QH for next round of transfer. Host control only - // touch the fields in transfer overlay area. Only need to - // zero out the overlay area and set NextQtd to the first - // QTD. DateToggle bit is left untouched. - // - QhHw = &Urb->Qh->QhHw; - QhHw->CurQtd = QTD_LINK (0, TRUE); - QhHw->AltQtd = 0; - - QhHw->Status = 0; - QhHw->Pid = 0; - QhHw->ErrCnt = 0; - QhHw->CurPage = 0; - QhHw->Ioc = 0; - QhHw->TotalBytes = 0; - - for (Index = 0; Index < 5; Index++) { - QhHw->Page[Index] = 0; - QhHw->PageHigh[Index] = 0; - } - - PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, FirstQtd, sizeof (EHC_QTD)); - QhHw->NextQtd = QTD_LINK (PciAddr, FALSE); - } - - return ; -} - - -/** - Interrupt transfer periodic check handler. - - @param Event Interrupt event. - @param Context Pointer to USB2_HC_DEV. - -**/ -VOID -EFIAPI -EhcMonitorAsyncRequests ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - USB2_HC_DEV *Ehc; - EFI_TPL OldTpl; - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - BOOLEAN Finished; - UINT8 *ProcBuf; - URB *Urb; - EFI_STATUS Status; - - OldTpl = gBS->RaiseTPL (EHC_TPL); - Ehc = (USB2_HC_DEV *) Context; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Ehc->AsyncIntTransfers) { - Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList); - - // - // Check the result of URB execution. If it is still - // active, check the next one. - // - Finished = EhcCheckUrbResult (Ehc, Urb); - - if (!Finished) { - continue; - } - - // - // Flush any PCI posted write transactions from a PCI host - // bridge to system memory. - // - Status = EhcFlushAsyncIntMap (Ehc, Urb); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "EhcMonitorAsyncRequests: Fail to Flush AsyncInt Mapped Memeory\n")); - } - - // - // Allocate a buffer then copy the transferred data for user. - // If failed to allocate the buffer, update the URB for next - // round of transfer. Ignore the data of this round. - // - ProcBuf = NULL; - - if (Urb->Result == EFI_USB_NOERROR) { - ASSERT (Urb->Completed <= Urb->DataLen); - - ProcBuf = AllocatePool (Urb->Completed); - - if (ProcBuf == NULL) { - EhcUpdateAsyncRequest (Ehc, Urb); - continue; - } - - CopyMem (ProcBuf, Urb->Data, Urb->Completed); - } - - EhcUpdateAsyncRequest (Ehc, Urb); - - // - // Leave error recovery to its related device driver. A - // common case of the error recovery is to re-submit the - // interrupt transfer which is linked to the head of the - // list. This function scans from head to tail. So the - // re-submitted interrupt transfer's callback function - // will not be called again in this round. Don't touch this - // URB after the callback, it may have been removed by the - // callback. - // - if (Urb->Callback != NULL) { - // - // Restore the old TPL, USB bus maybe connect device in - // his callback. Some drivers may has a lower TPL restriction. - // - gBS->RestoreTPL (OldTpl); - (Urb->Callback) (ProcBuf, Urb->Completed, Urb->Context, Urb->Result); - OldTpl = gBS->RaiseTPL (EHC_TPL); - } - - if (ProcBuf != NULL) { - FreePool (ProcBuf); - } - } - - gBS->RestoreTPL (OldTpl); -} diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.h b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.h deleted file mode 100644 index c03bd619d7..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.h +++ /dev/null @@ -1,180 +0,0 @@ -/** @file - - This file contains the definination for host controller schedule routines. - -Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_SCHED_H_ -#define _EFI_EHCI_SCHED_H_ - - -/** - Initialize the schedule data structure such as frame list. - - @param Ehc The EHCI device to init schedule data for. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to init schedule data. - @retval EFI_SUCCESS The schedule data is initialized. - -**/ -EFI_STATUS -EhcInitSched ( - IN USB2_HC_DEV *Ehc - ); - - -/** - Free the schedule data. It may be partially initialized. - - @param Ehc The EHCI device. - -**/ -VOID -EhcFreeSched ( - IN USB2_HC_DEV *Ehc - ); - - -/** - Link the queue head to the asynchronous schedule list. - UEFI only supports one CTRL/BULK transfer at a time - due to its interfaces. This simplifies the AsynList - management: A reclamation header is always linked to - the AsyncListAddr, the only active QH is appended to it. - - @param Ehc The EHCI device. - @param Qh The queue head to link. - -**/ -VOID -EhcLinkQhToAsync ( - IN USB2_HC_DEV *Ehc, - IN EHC_QH *Qh - ); - - -/** - Unlink a queue head from the asynchronous schedule list. - Need to synchronize with hardware. - - @param Ehc The EHCI device. - @param Qh The queue head to unlink. - -**/ -VOID -EhcUnlinkQhFromAsync ( - IN USB2_HC_DEV *Ehc, - IN EHC_QH *Qh - ); - - -/** - Link a queue head for interrupt transfer to the periodic - schedule frame list. This code is very much the same as - that in UHCI. - - @param Ehc The EHCI device. - @param Qh The queue head to link. - -**/ -VOID -EhcLinkQhToPeriod ( - IN USB2_HC_DEV *Ehc, - IN EHC_QH *Qh - ); - - -/** - Unlink an interrupt queue head from the periodic - schedule frame list. - - @param Ehc The EHCI device. - @param Qh The queue head to unlink. - -**/ -VOID -EhcUnlinkQhFromPeriod ( - IN USB2_HC_DEV *Ehc, - IN EHC_QH *Qh - ); - - - -/** - Execute the transfer by polling the URB. This is a synchronous operation. - - @param Ehc The EHCI device. - @param Urb The URB to execute. - @param TimeOut The time to wait before abort, in millisecond. - - @retval EFI_DEVICE_ERROR The transfer failed due to transfer error. - @retval EFI_TIMEOUT The transfer failed due to time out. - @retval EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -EhcExecTransfer ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb, - IN UINTN TimeOut - ); - - -/** - Delete a single asynchronous interrupt transfer for - the device and endpoint. - - @param Ehc The EHCI device. - @param DevAddr The address of the target device. - @param EpNum The endpoint of the target. - @param DataToggle Return the next data toggle to use. - - @retval EFI_SUCCESS An asynchronous transfer is removed. - @retval EFI_NOT_FOUND No transfer for the device is found. - -**/ -EFI_STATUS -EhciDelAsyncIntTransfer ( - IN USB2_HC_DEV *Ehc, - IN UINT8 DevAddr, - IN UINT8 EpNum, - OUT UINT8 *DataToggle - ); - - -/** - Remove all the asynchronous interrutp transfers. - - @param Ehc The EHCI device. - -**/ -VOID -EhciDelAllAsyncIntTransfers ( - IN USB2_HC_DEV *Ehc - ); - - -/** - Interrupt transfer periodic check handler. - - @param Event Interrupt event. - @param Context Pointer to USB2_HC_DEV. - -**/ -VOID -EFIAPI -EhcMonitorAsyncRequests ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c deleted file mode 100644 index 6afb327df1..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c +++ /dev/null @@ -1,657 +0,0 @@ -/** @file - - This file contains URB request, each request is warpped in a - URB (Usb Request Block). - -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ehci.h" - - -/** - Create a single QTD to hold the data. - - @param Ehc The EHCI device. - @param Data The cpu memory address of current data not associated with a QTD. - @param DataPhy The pci bus address of current data not associated with a QTD. - @param DataLen The length of the data. - @param PktId Packet ID to use in the QTD. - @param Toggle Data toggle to use in the QTD. - @param MaxPacket Maximu packet length of the endpoint. - - @return Created QTD or NULL if failed to create one. - -**/ -EHC_QTD * -EhcCreateQtd ( - IN USB2_HC_DEV *Ehc, - IN UINT8 *Data, - IN UINT8 *DataPhy, - IN UINTN DataLen, - IN UINT8 PktId, - IN UINT8 Toggle, - IN UINTN MaxPacket - ) -{ - EHC_QTD *Qtd; - QTD_HW *QtdHw; - UINTN Index; - UINTN Len; - UINTN ThisBufLen; - - ASSERT (Ehc != NULL); - - Qtd = UsbHcAllocateMem (Ehc->MemPool, sizeof (EHC_QTD)); - - if (Qtd == NULL) { - return NULL; - } - - Qtd->Signature = EHC_QTD_SIG; - Qtd->Data = Data; - Qtd->DataLen = 0; - - InitializeListHead (&Qtd->QtdList); - - QtdHw = &Qtd->QtdHw; - QtdHw->NextQtd = QTD_LINK (NULL, TRUE); - QtdHw->AltNext = QTD_LINK (NULL, TRUE); - QtdHw->Status = QTD_STAT_ACTIVE; - QtdHw->Pid = PktId; - QtdHw->ErrCnt = QTD_MAX_ERR; - QtdHw->Ioc = 0; - QtdHw->TotalBytes = 0; - QtdHw->DataToggle = Toggle; - - // - // Fill in the buffer points - // - if (Data != NULL) { - Len = 0; - - for (Index = 0; Index <= QTD_MAX_BUFFER; Index++) { - // - // Set the buffer point (Check page 41 EHCI Spec 1.0). No need to - // compute the offset and clear Reserved fields. This is already - // done in the data point. - // - QtdHw->Page[Index] = EHC_LOW_32BIT (DataPhy); - QtdHw->PageHigh[Index] = EHC_HIGH_32BIT (DataPhy); - - ThisBufLen = QTD_BUF_LEN - (EHC_LOW_32BIT (DataPhy) & QTD_BUF_MASK); - - if (Len + ThisBufLen >= DataLen) { - Len = DataLen; - break; - } - - Len += ThisBufLen; - Data += ThisBufLen; - DataPhy += ThisBufLen; - } - - // - // Need to fix the last pointer if the Qtd can't hold all the - // user's data to make sure that the length is in the unit of - // max packets. If it can hold all the data, there is no such - // need. - // - if (Len < DataLen) { - Len = Len - Len % MaxPacket; - } - - QtdHw->TotalBytes = (UINT32) Len; - Qtd->DataLen = Len; - } - - return Qtd; -} - - - -/** - Initialize the queue head for interrupt transfer, - that is, initialize the following three fields: - 1. SplitXState in the Status field - 2. Microframe S-mask - 3. Microframe C-mask - - @param Ep The queue head's related endpoint. - @param QhHw The queue head to initialize. - -**/ -VOID -EhcInitIntQh ( - IN USB_ENDPOINT *Ep, - IN QH_HW *QhHw - ) -{ - // - // Because UEFI interface can't utilitize an endpoint with - // poll rate faster than 1ms, only need to set one bit in - // the queue head. simple. But it may be changed later. If - // sub-1ms interrupt is supported, need to update the S-Mask - // here - // - if (Ep->DevSpeed == EFI_USB_SPEED_HIGH) { - QhHw->SMask = QH_MICROFRAME_0; - return ; - } - - // - // For low/full speed device, the transfer must go through - // the split transaction. Need to update three fields - // 1. SplitXState in the status - // 2. Microframe S-Mask - // 3. Microframe C-Mask - // UEFI USB doesn't exercise admission control. It simplely - // schedule the high speed transactions in microframe 0, and - // full/low speed transactions at microframe 1. This also - // avoid the use of FSTN. - // - QhHw->SMask = QH_MICROFRAME_1; - QhHw->CMask = QH_MICROFRAME_3 | QH_MICROFRAME_4 | QH_MICROFRAME_5; -} - - - -/** - Allocate and initialize a EHCI queue head. - - @param Ehci The EHCI device. - @param Ep The endpoint to create queue head for. - - @return Created queue head or NULL if failed to create one. - -**/ -EHC_QH * -EhcCreateQh ( - IN USB2_HC_DEV *Ehci, - IN USB_ENDPOINT *Ep - ) -{ - EHC_QH *Qh; - QH_HW *QhHw; - - Qh = UsbHcAllocateMem (Ehci->MemPool, sizeof (EHC_QH)); - - if (Qh == NULL) { - return NULL; - } - - Qh->Signature = EHC_QH_SIG; - Qh->NextQh = NULL; - Qh->Interval = Ep->PollRate; - - InitializeListHead (&Qh->Qtds); - - QhHw = &Qh->QhHw; - QhHw->HorizonLink = QH_LINK (NULL, 0, TRUE); - QhHw->DeviceAddr = Ep->DevAddr; - QhHw->Inactive = 0; - QhHw->EpNum = Ep->EpAddr; - QhHw->EpSpeed = Ep->DevSpeed; - QhHw->DtCtrl = 0; - QhHw->ReclaimHead = 0; - QhHw->MaxPacketLen = (UINT32) Ep->MaxPacket; - QhHw->CtrlEp = 0; - QhHw->NakReload = QH_NAK_RELOAD; - QhHw->HubAddr = Ep->HubAddr; - QhHw->PortNum = Ep->HubPort; - QhHw->Multiplier = 1; - QhHw->DataToggle = Ep->Toggle; - - if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) { - QhHw->Status |= QTD_STAT_DO_SS; - } - - switch (Ep->Type) { - case EHC_CTRL_TRANSFER: - // - // Special initialization for the control transfer: - // 1. Control transfer initialize data toggle from each QTD - // 2. Set the Control Endpoint Flag (C) for low/full speed endpoint. - // - QhHw->DtCtrl = 1; - - if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) { - QhHw->CtrlEp = 1; - } - break; - - case EHC_INT_TRANSFER_ASYNC: - case EHC_INT_TRANSFER_SYNC: - // - // Special initialization for the interrupt transfer - // to set the S-Mask and C-Mask - // - QhHw->NakReload = 0; - EhcInitIntQh (Ep, QhHw); - break; - - case EHC_BULK_TRANSFER: - if ((Ep->DevSpeed == EFI_USB_SPEED_HIGH) && (Ep->Direction == EfiUsbDataOut)) { - QhHw->Status |= QTD_STAT_DO_PING; - } - - break; - } - - return Qh; -} - - -/** - Convert the poll interval from application to that - be used by EHCI interface data structure. Only need - to get the max 2^n that is less than interval. UEFI - can't support high speed endpoint with a interval less - than 8 microframe because interval is specified in - the unit of ms (millisecond). - - @param Interval The interval to convert. - - @return The converted interval. - -**/ -UINTN -EhcConvertPollRate ( - IN UINTN Interval - ) -{ - UINTN BitCount; - - if (Interval == 0) { - return 1; - } - - // - // Find the index (1 based) of the highest non-zero bit - // - BitCount = 0; - - while (Interval != 0) { - Interval >>= 1; - BitCount++; - } - - return (UINTN)1 << (BitCount - 1); -} - - -/** - Free a list of QTDs. - - @param Ehc The EHCI device. - @param Qtds The list head of the QTD. - -**/ -VOID -EhcFreeQtds ( - IN USB2_HC_DEV *Ehc, - IN LIST_ENTRY *Qtds - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - EHC_QTD *Qtd; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, Qtds) { - Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList); - - RemoveEntryList (&Qtd->QtdList); - UsbHcFreeMem (Ehc->MemPool, Qtd, sizeof (EHC_QTD)); - } -} - - -/** - Free an allocated URB. It is possible for it to be partially inited. - - @param Ehc The EHCI device. - @param Urb The URB to free. - -**/ -VOID -EhcFreeUrb ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - PciIo = Ehc->PciIo; - - if (Urb->RequestPhy != NULL) { - PciIo->Unmap (PciIo, Urb->RequestMap); - } - - if (Urb->DataMap != NULL) { - PciIo->Unmap (PciIo, Urb->DataMap); - } - - if (Urb->Qh != NULL) { - // - // Ensure that this queue head has been unlinked from the - // schedule data structures. Free all the associated QTDs - // - EhcFreeQtds (Ehc, &Urb->Qh->Qtds); - UsbHcFreeMem (Ehc->MemPool, Urb->Qh, sizeof (EHC_QH)); - } - - gBS->FreePool (Urb); -} - - -/** - Create a list of QTDs for the URB. - - @param Ehc The EHCI device. - @param Urb The URB to create QTDs for. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for QTD. - @retval EFI_SUCCESS The QTDs are allocated for the URB. - -**/ -EFI_STATUS -EhcCreateQtds ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb - ) -{ - USB_ENDPOINT *Ep; - EHC_QH *Qh; - EHC_QTD *Qtd; - EHC_QTD *StatusQtd; - EHC_QTD *NextQtd; - LIST_ENTRY *Entry; - UINT32 AlterNext; - UINT8 Toggle; - UINTN Len; - UINT8 Pid; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT ((Urb != NULL) && (Urb->Qh != NULL)); - - // - // EHCI follows the alternet next QTD pointer if it meets - // a short read and the AlterNext pointer is valid. UEFI - // EHCI driver should terminate the transfer except the - // control transfer. - // - Toggle = 0; - Qh = Urb->Qh; - Ep = &Urb->Ep; - StatusQtd = NULL; - AlterNext = QTD_LINK (NULL, TRUE); - - PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD)); - if (Ep->Direction == EfiUsbDataIn) { - AlterNext = QTD_LINK (PhyAddr, FALSE); - } - - // - // Build the Setup and status packets for control transfer - // - if (Urb->Ep.Type == EHC_CTRL_TRANSFER) { - Len = sizeof (EFI_USB_DEVICE_REQUEST); - Qtd = EhcCreateQtd (Ehc, (UINT8 *)Urb->Request, (UINT8 *)Urb->RequestPhy, Len, QTD_PID_SETUP, 0, Ep->MaxPacket); - - if (Qtd == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - InsertTailList (&Qh->Qtds, &Qtd->QtdList); - - // - // Create the status packet now. Set the AlterNext to it. So, when - // EHCI meets a short control read, it can resume at the status stage. - // Use the opposite direction of the data stage, or IN if there is - // no data stage. - // - if (Ep->Direction == EfiUsbDataIn) { - Pid = QTD_PID_OUTPUT; - } else { - Pid = QTD_PID_INPUT; - } - - StatusQtd = EhcCreateQtd (Ehc, NULL, NULL, 0, Pid, 1, Ep->MaxPacket); - - if (StatusQtd == NULL) { - goto ON_ERROR; - } - - if (Ep->Direction == EfiUsbDataIn) { - PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, StatusQtd, sizeof (EHC_QTD)); - AlterNext = QTD_LINK (PhyAddr, FALSE); - } - - Toggle = 1; - } - - // - // Build the data packets for all the transfers - // - if (Ep->Direction == EfiUsbDataIn) { - Pid = QTD_PID_INPUT; - } else { - Pid = QTD_PID_OUTPUT; - } - - Qtd = NULL; - Len = 0; - - while (Len < Urb->DataLen) { - Qtd = EhcCreateQtd ( - Ehc, - (UINT8 *) Urb->Data + Len, - (UINT8 *) Urb->DataPhy + Len, - Urb->DataLen - Len, - Pid, - Toggle, - Ep->MaxPacket - ); - - if (Qtd == NULL) { - goto ON_ERROR; - } - - Qtd->QtdHw.AltNext = AlterNext; - InsertTailList (&Qh->Qtds, &Qtd->QtdList); - - // - // Switch the Toggle bit if odd number of packets are included in the QTD. - // - if (((Qtd->DataLen + Ep->MaxPacket - 1) / Ep->MaxPacket) % 2) { - Toggle = (UINT8) (1 - Toggle); - } - - Len += Qtd->DataLen; - } - - // - // Insert the status packet for control transfer - // - if (Ep->Type == EHC_CTRL_TRANSFER) { - InsertTailList (&Qh->Qtds, &StatusQtd->QtdList); - } - - // - // OK, all the QTDs needed are created. Now, fix the NextQtd point - // - EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) { - Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList); - - // - // break if it is the last entry on the list - // - if (Entry->ForwardLink == &Qh->Qtds) { - break; - } - - NextQtd = EFI_LIST_CONTAINER (Entry->ForwardLink, EHC_QTD, QtdList); - PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD)); - Qtd->QtdHw.NextQtd = QTD_LINK (PhyAddr, FALSE); - } - - // - // Link the QTDs to the queue head - // - NextQtd = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, EHC_QTD, QtdList); - PhyAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD)); - Qh->QhHw.NextQtd = QTD_LINK (PhyAddr, FALSE); - return EFI_SUCCESS; - -ON_ERROR: - EhcFreeQtds (Ehc, &Qh->Qtds); - return EFI_OUT_OF_RESOURCES; -} - - -/** - Create a new URB and its associated QTD. - - @param Ehc The EHCI device. - @param DevAddr The device address. - @param EpAddr Endpoint addrress & its direction. - @param DevSpeed The device speed. - @param Toggle Initial data toggle to use. - @param MaxPacket The max packet length of the endpoint. - @param Hub The transaction translator to use. - @param Type The transaction type. - @param Request The standard USB request for control transfer. - @param Data The user data to transfer. - @param DataLen The length of data buffer. - @param Callback The function to call when data is transferred. - @param Context The context to the callback. - @param Interval The interval for interrupt transfer. - - @return Created URB or NULL. - -**/ -URB * -EhcCreateUrb ( - IN USB2_HC_DEV *Ehc, - IN UINT8 DevAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINT8 Toggle, - IN UINTN MaxPacket, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context, - IN UINTN Interval - ) -{ - USB_ENDPOINT *Ep; - EFI_PHYSICAL_ADDRESS PhyAddr; - EFI_PCI_IO_PROTOCOL_OPERATION MapOp; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINTN Len; - URB *Urb; - VOID *Map; - - Urb = AllocateZeroPool (sizeof (URB)); - - if (Urb == NULL) { - return NULL; - } - - Urb->Signature = EHC_URB_SIG; - InitializeListHead (&Urb->UrbList); - - Ep = &Urb->Ep; - Ep->DevAddr = DevAddr; - Ep->EpAddr = (UINT8) (EpAddr & 0x0F); - Ep->Direction = (((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut); - Ep->DevSpeed = DevSpeed; - Ep->MaxPacket = MaxPacket; - - Ep->HubAddr = 0; - Ep->HubPort = 0; - - if (DevSpeed != EFI_USB_SPEED_HIGH) { - ASSERT (Hub != NULL); - - Ep->HubAddr = Hub->TranslatorHubAddress; - Ep->HubPort = Hub->TranslatorPortNumber; - } - - Ep->Toggle = Toggle; - Ep->Type = Type; - Ep->PollRate = EhcConvertPollRate (Interval); - - Urb->Request = Request; - Urb->Data = Data; - Urb->DataLen = DataLen; - Urb->Callback = Callback; - Urb->Context = Context; - - PciIo = Ehc->PciIo; - Urb->Qh = EhcCreateQh (Ehc, &Urb->Ep); - - if (Urb->Qh == NULL) { - goto ON_ERROR; - } - - // - // Map the request and user data - // - if (Request != NULL) { - Len = sizeof (EFI_USB_DEVICE_REQUEST); - MapOp = EfiPciIoOperationBusMasterRead; - Status = PciIo->Map (PciIo, MapOp, Request, &Len, &PhyAddr, &Map); - - if (EFI_ERROR (Status) || (Len != sizeof (EFI_USB_DEVICE_REQUEST))) { - goto ON_ERROR; - } - - Urb->RequestPhy = (VOID *) ((UINTN) PhyAddr); - Urb->RequestMap = Map; - } - - if (Data != NULL) { - Len = DataLen; - - if (Ep->Direction == EfiUsbDataIn) { - MapOp = EfiPciIoOperationBusMasterWrite; - } else { - MapOp = EfiPciIoOperationBusMasterRead; - } - - Status = PciIo->Map (PciIo, MapOp, Data, &Len, &PhyAddr, &Map); - - if (EFI_ERROR (Status) || (Len != DataLen)) { - goto ON_ERROR; - } - - Urb->DataPhy = (VOID *) ((UINTN) PhyAddr); - Urb->DataMap = Map; - } - - Status = EhcCreateQtds (Ehc, Urb); - - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - return Urb; - -ON_ERROR: - EhcFreeUrb (Ehc, Urb); - return NULL; -} diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h deleted file mode 100644 index 02e9af81be..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h +++ /dev/null @@ -1,336 +0,0 @@ -/** @file - - This file contains URB request, each request is warpped in a - URB (Usb Request Block). - -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_URB_H_ -#define _EFI_EHCI_URB_H_ - - -typedef struct _EHC_QTD EHC_QTD; -typedef struct _EHC_QH EHC_QH; -typedef struct _URB URB; - -// -// Transfer types, used in URB to identify the transfer type -// -#define EHC_CTRL_TRANSFER 0x01 -#define EHC_BULK_TRANSFER 0x02 -#define EHC_INT_TRANSFER_SYNC 0x04 -#define EHC_INT_TRANSFER_ASYNC 0x08 - -#define EHC_QTD_SIG SIGNATURE_32 ('U', 'S', 'B', 'T') -#define EHC_QH_SIG SIGNATURE_32 ('U', 'S', 'B', 'H') -#define EHC_URB_SIG SIGNATURE_32 ('U', 'S', 'B', 'R') - -// -// Hardware related bit definitions -// -#define EHC_TYPE_ITD 0x00 -#define EHC_TYPE_QH 0x02 -#define EHC_TYPE_SITD 0x04 -#define EHC_TYPE_FSTN 0x06 - -#define QH_NAK_RELOAD 3 -#define QH_HSHBW_MULTI 1 - -#define QTD_MAX_ERR 3 -#define QTD_PID_OUTPUT 0x00 -#define QTD_PID_INPUT 0x01 -#define QTD_PID_SETUP 0x02 - -#define QTD_STAT_DO_OUT 0 -#define QTD_STAT_DO_SS 0 -#define QTD_STAT_DO_PING 0x01 -#define QTD_STAT_DO_CS 0x02 -#define QTD_STAT_TRANS_ERR 0x08 -#define QTD_STAT_BABBLE_ERR 0x10 -#define QTD_STAT_BUFF_ERR 0x20 -#define QTD_STAT_HALTED 0x40 -#define QTD_STAT_ACTIVE 0x80 -#define QTD_STAT_ERR_MASK (QTD_STAT_TRANS_ERR | QTD_STAT_BABBLE_ERR | QTD_STAT_BUFF_ERR) - -#define QTD_MAX_BUFFER 4 -#define QTD_BUF_LEN 4096 -#define QTD_BUF_MASK 0x0FFF - -#define QH_MICROFRAME_0 0x01 -#define QH_MICROFRAME_1 0x02 -#define QH_MICROFRAME_2 0x04 -#define QH_MICROFRAME_3 0x08 -#define QH_MICROFRAME_4 0x10 -#define QH_MICROFRAME_5 0x20 -#define QH_MICROFRAME_6 0x40 -#define QH_MICROFRAME_7 0x80 - -#define USB_ERR_SHORT_PACKET 0x200 - -// -// Fill in the hardware link point: pass in a EHC_QH/QH_HW -// pointer to QH_LINK; A EHC_QTD/QTD_HW pointer to QTD_LINK -// -#define QH_LINK(Addr, Type, Term) \ - ((UINT32) ((EHC_LOW_32BIT (Addr) & 0xFFFFFFE0) | (Type) | ((Term) ? 1 : 0))) - -#define QTD_LINK(Addr, Term) QH_LINK((Addr), 0, (Term)) - -// -// The defination of EHCI hardware used data structure for -// little endian architecture. The QTD and QH structures -// are required to be 32 bytes aligned. Don't add members -// to the head of the associated software strucuture. -// -#pragma pack(1) -typedef struct { - UINT32 NextQtd; - UINT32 AltNext; - - UINT32 Status : 8; - UINT32 Pid : 2; - UINT32 ErrCnt : 2; - UINT32 CurPage : 3; - UINT32 Ioc : 1; - UINT32 TotalBytes : 15; - UINT32 DataToggle : 1; - - UINT32 Page[5]; - UINT32 PageHigh[5]; -} QTD_HW; - -typedef struct { - UINT32 HorizonLink; - // - // Endpoint capabilities/Characteristics DWord 1 and DWord 2 - // - UINT32 DeviceAddr : 7; - UINT32 Inactive : 1; - UINT32 EpNum : 4; - UINT32 EpSpeed : 2; - UINT32 DtCtrl : 1; - UINT32 ReclaimHead : 1; - UINT32 MaxPacketLen : 11; - UINT32 CtrlEp : 1; - UINT32 NakReload : 4; - - UINT32 SMask : 8; - UINT32 CMask : 8; - UINT32 HubAddr : 7; - UINT32 PortNum : 7; - UINT32 Multiplier : 2; - - // - // Transaction execution overlay area - // - UINT32 CurQtd; - UINT32 NextQtd; - UINT32 AltQtd; - - UINT32 Status : 8; - UINT32 Pid : 2; - UINT32 ErrCnt : 2; - UINT32 CurPage : 3; - UINT32 Ioc : 1; - UINT32 TotalBytes : 15; - UINT32 DataToggle : 1; - - UINT32 Page[5]; - UINT32 PageHigh[5]; -} QH_HW; -#pragma pack() - - -// -// Endpoint address and its capabilities -// -typedef struct _USB_ENDPOINT { - UINT8 DevAddr; - UINT8 EpAddr; // Endpoint address, no direction encoded in - EFI_USB_DATA_DIRECTION Direction; - UINT8 DevSpeed; - UINTN MaxPacket; - UINT8 HubAddr; - UINT8 HubPort; - UINT8 Toggle; // Data toggle, not used for control transfer - UINTN Type; - UINTN PollRate; // Polling interval used by EHCI -} USB_ENDPOINT; - -// -// Software QTD strcture, this is used to manage all the -// QTD generated from a URB. Don't add fields before QtdHw. -// -struct _EHC_QTD { - QTD_HW QtdHw; - UINT32 Signature; - LIST_ENTRY QtdList; // The list of QTDs to one end point - UINT8 *Data; // Buffer of the original data - UINTN DataLen; // Original amount of data in this QTD -}; - -// -// Software QH structure. All three different transaction types -// supported by UEFI USB, that is the control/bulk/interrupt -// transfers use the queue head and queue token strcuture. -// -// Interrupt QHs are linked to periodic frame list in the reversed -// 2^N tree. Each interrupt QH is linked to the list starting at -// frame 0. There is a dummy interrupt QH linked to each frame as -// a sentinental whose polling interval is 1. Synchronous interrupt -// transfer is linked after this dummy QH. -// -// For control/bulk transfer, only synchronous (in the sense of UEFI) -// transfer is supported. A dummy QH is linked to EHCI AsyncListAddr -// as the reclamation header. New transfer is inserted after this QH. -// -struct _EHC_QH { - QH_HW QhHw; - UINT32 Signature; - EHC_QH *NextQh; // The queue head pointed to by horizontal link - LIST_ENTRY Qtds; // The list of QTDs to this queue head - UINTN Interval; -}; - -// -// URB (Usb Request Block) contains information for all kinds of -// usb requests. -// -struct _URB { - UINT32 Signature; - LIST_ENTRY UrbList; - - // - // Transaction information - // - USB_ENDPOINT Ep; - EFI_USB_DEVICE_REQUEST *Request; // Control transfer only - VOID *RequestPhy; // Address of the mapped request - VOID *RequestMap; - VOID *Data; - UINTN DataLen; - VOID *DataPhy; // Address of the mapped user data - VOID *DataMap; - EFI_ASYNC_USB_TRANSFER_CALLBACK Callback; - VOID *Context; - - // - // Schedule data - // - EHC_QH *Qh; - - // - // Transaction result - // - UINT32 Result; - UINTN Completed; // completed data length - UINT8 DataToggle; -}; - - - -/** - Create a single QTD to hold the data. - - @param Ehc The EHCI device. - @param Data The cpu memory address of current data not associated with a QTD. - @param DataPhy The pci bus address of current data not associated with a QTD. - @param DataLen The length of the data. - @param PktId Packet ID to use in the QTD. - @param Toggle Data toggle to use in the QTD. - @param MaxPacket Maximu packet length of the endpoint. - - @return Created QTD or NULL if failed to create one. - -**/ -EHC_QTD * -EhcCreateQtd ( - IN USB2_HC_DEV *Ehc, - IN UINT8 *Data, - IN UINT8 *DataPhy, - IN UINTN DataLen, - IN UINT8 PktId, - IN UINT8 Toggle, - IN UINTN MaxPacket - ); - - - -/** - Allocate and initialize a EHCI queue head. - - @param Ehci The EHCI device. - @param Ep The endpoint to create queue head for. - - @return Created queue head or NULL if failed to create one. - -**/ -EHC_QH * -EhcCreateQh ( - IN USB2_HC_DEV *Ehci, - IN USB_ENDPOINT *Ep - ); - - -/** - Free an allocated URB. It is possible for it to be partially inited. - - @param Ehc The EHCI device. - @param Urb The URB to free. - -**/ -VOID -EhcFreeUrb ( - IN USB2_HC_DEV *Ehc, - IN URB *Urb - ); - - -/** - Create a new URB and its associated QTD. - - @param Ehc The EHCI device. - @param DevAddr The device address. - @param EpAddr Endpoint addrress & its direction. - @param DevSpeed The device speed. - @param Toggle Initial data toggle to use. - @param MaxPacket The max packet length of the endpoint. - @param Hub The transaction translator to use. - @param Type The transaction type. - @param Request The standard USB request for control transfer. - @param Data The user data to transfer. - @param DataLen The length of data buffer. - @param Callback The function to call when data is transferred. - @param Context The context to the callback. - @param Interval The interval for interrupt transfer. - - @return Created URB or NULL. - -**/ -URB * -EhcCreateUrb ( - IN USB2_HC_DEV *Ehc, - IN UINT8 DevAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINT8 Toggle, - IN UINTN MaxPacket, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context, - IN UINTN Interval - ); -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c deleted file mode 100644 index 28be3803f1..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c +++ /dev/null @@ -1,566 +0,0 @@ -/** @file - - Routine procedures for memory allocate/free. - -Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "Ehci.h" - - -/** - Allocate a block of memory to be used by the buffer pool. - - @param Pool The buffer pool to allocate memory for. - @param Pages How many pages to allocate. - - @return The allocated memory block or NULL if failed. - -**/ -USBHC_MEM_BLOCK * -UsbHcAllocMemBlock ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Pages - ) -{ - USBHC_MEM_BLOCK *Block; - EFI_PCI_IO_PROTOCOL *PciIo; - VOID *BufHost; - VOID *Mapping; - EFI_PHYSICAL_ADDRESS MappedAddr; - UINTN Bytes; - EFI_STATUS Status; - - PciIo = Pool->PciIo; - - Block = AllocateZeroPool (sizeof (USBHC_MEM_BLOCK)); - if (Block == NULL) { - return NULL; - } - - // - // each bit in the bit array represents USBHC_MEM_UNIT - // bytes of memory in the memory block. - // - ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE); - - Block->BufLen = EFI_PAGES_TO_SIZE (Pages); - Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8); - Block->Bits = AllocateZeroPool (Block->BitsLen); - - if (Block->Bits == NULL) { - gBS->FreePool (Block); - return NULL; - } - - // - // Allocate the number of Pages of memory, then map it for - // bus master read and write. - // - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - Pages, - &BufHost, - 0 - ); - - if (EFI_ERROR (Status)) { - goto FREE_BITARRAY; - } - - Bytes = EFI_PAGES_TO_SIZE (Pages); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - BufHost, - &Bytes, - &MappedAddr, - &Mapping - ); - - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) { - goto FREE_BUFFER; - } - - // - // Check whether the data structure used by the host controller - // should be restricted into the same 4G - // - if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) { - PciIo->Unmap (PciIo, Mapping); - goto FREE_BUFFER; - } - - Block->BufHost = BufHost; - Block->Buf = (UINT8 *) ((UINTN) MappedAddr); - Block->Mapping = Mapping; - - return Block; - -FREE_BUFFER: - PciIo->FreeBuffer (PciIo, Pages, BufHost); - -FREE_BITARRAY: - gBS->FreePool (Block->Bits); - gBS->FreePool (Block); - return NULL; -} - - -/** - Free the memory block from the memory pool. - - @param Pool The memory pool to free the block from. - @param Block The memory block to free. - -**/ -VOID -UsbHcFreeMemBlock ( - IN USBHC_MEM_POOL *Pool, - IN USBHC_MEM_BLOCK *Block - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - ASSERT ((Pool != NULL) && (Block != NULL)); - - PciIo = Pool->PciIo; - - // - // Unmap the common buffer then free the structures - // - PciIo->Unmap (PciIo, Block->Mapping); - PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost); - - gBS->FreePool (Block->Bits); - gBS->FreePool (Block); -} - - -/** - Alloc some memory from the block. - - @param Block The memory block to allocate memory from. - @param Units Number of memory units to allocate. - - @return The pointer to the allocated memory. If couldn't allocate the needed memory, - the return value is NULL. - -**/ -VOID * -UsbHcAllocMemFromBlock ( - IN USBHC_MEM_BLOCK *Block, - IN UINTN Units - ) -{ - UINTN Byte; - UINT8 Bit; - UINTN StartByte; - UINT8 StartBit; - UINTN Available; - UINTN Count; - - ASSERT ((Block != 0) && (Units != 0)); - - StartByte = 0; - StartBit = 0; - Available = 0; - - for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) { - // - // If current bit is zero, the corresponding memory unit is - // available, otherwise we need to restart our searching. - // Available counts the consective number of zero bit. - // - if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) { - Available++; - - if (Available >= Units) { - break; - } - - NEXT_BIT (Byte, Bit); - - } else { - NEXT_BIT (Byte, Bit); - - Available = 0; - StartByte = Byte; - StartBit = Bit; - } - } - - if (Available < Units) { - return NULL; - } - - // - // Mark the memory as allocated - // - Byte = StartByte; - Bit = StartBit; - - for (Count = 0; Count < Units; Count++) { - ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT; -} - -/** - Calculate the corresponding pci bus address according to the Mem parameter. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to host memory. - @param Size The size of the memory region. - - @return the pci memory address -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetPciAddressForHostMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINTN AllocSize; - EFI_PHYSICAL_ADDRESS PhyAddr; - UINTN Offset; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - - if (Mem == NULL) { - return 0; - } - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the allocated memory. - // - if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) { - break; - } - } - - ASSERT ((Block != NULL)); - // - // calculate the pci memory address for host memory address. - // - Offset = (UINT8 *)Mem - Block->BufHost; - PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset); - return PhyAddr; -} - - -/** - Insert the memory block to the pool's list of the blocks. - - @param Head The head of the memory pool's block list. - @param Block The memory block to insert. - -**/ -VOID -UsbHcInsertMemBlockToPool ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *Block - ) -{ - ASSERT ((Head != NULL) && (Block != NULL)); - Block->Next = Head->Next; - Head->Next = Block; -} - - -/** - Is the memory block empty? - - @param Block The memory block to check. - - @retval TRUE The memory block is empty. - @retval FALSE The memory block isn't empty. - -**/ -BOOLEAN -UsbHcIsMemBlockEmpty ( - IN USBHC_MEM_BLOCK *Block - ) -{ - UINTN Index; - - for (Index = 0; Index < Block->BitsLen; Index++) { - if (Block->Bits[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - - -/** - Unlink the memory block from the pool's list. - - @param Head The block list head of the memory's pool. - @param BlockToUnlink The memory block to unlink. - -**/ -VOID -UsbHcUnlinkMemBlock ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *BlockToUnlink - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT ((Head != NULL) && (BlockToUnlink != NULL)); - - for (Block = Head; Block != NULL; Block = Block->Next) { - if (Block->Next == BlockToUnlink) { - Block->Next = BlockToUnlink->Next; - BlockToUnlink->Next = NULL; - break; - } - } -} - - -/** - Initialize the memory management pool for the host controller. - - @param PciIo The PciIo that can be used to access the host controller. - @param Check4G Whether the host controller requires allocated memory - from one 4G address space. - @param Which4G The 4G memory area each memory allocated should be from. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN BOOLEAN Check4G, - IN UINT32 Which4G - ) -{ - USBHC_MEM_POOL *Pool; - - Pool = AllocatePool (sizeof (USBHC_MEM_POOL)); - - if (Pool == NULL) { - return Pool; - } - - Pool->PciIo = PciIo; - Pool->Check4G = Check4G; - Pool->Which4G = Which4G; - Pool->Head = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES); - - if (Pool->Head == NULL) { - gBS->FreePool (Pool); - Pool = NULL; - } - - return Pool; -} - - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - - @retval EFI_SUCCESS The memory pool is freed. - @retval EFI_DEVICE_ERROR Failed to free the memory pool. - -**/ -EFI_STATUS -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT (Pool->Head != NULL); - - // - // Unlink all the memory blocks from the pool, then free them. - // UsbHcUnlinkMemBlock can't be used to unlink and free the - // first block. - // - for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) { - UsbHcUnlinkMemBlock (Pool->Head, Block); - UsbHcFreeMemBlock (Pool, Block); - } - - UsbHcFreeMemBlock (Pool, Pool->Head); - gBS->FreePool (Pool); - return EFI_SUCCESS; -} - - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - USBHC_MEM_BLOCK *NewBlock; - VOID *Mem; - UINTN AllocSize; - UINTN Pages; - - Mem = NULL; - AllocSize = USBHC_MEM_ROUND (Size); - Head = Pool->Head; - ASSERT (Head != NULL); - - // - // First check whether current memory blocks can satisfy the allocation. - // - for (Block = Head; Block != NULL; Block = Block->Next) { - Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - break; - } - } - - if (Mem != NULL) { - return Mem; - } - - // - // Create a new memory block if there is not enough memory - // in the pool. If the allocation size is larger than the - // default page number, just allocate a large enough memory - // block. Otherwise allocate default pages. - // - if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) { - Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1; - } else { - Pages = USBHC_MEM_DEFAULT_PAGES; - } - - NewBlock = UsbHcAllocMemBlock (Pool, Pages); - - if (NewBlock == NULL) { - DEBUG ((EFI_D_ERROR, "UsbHcAllocateMem: failed to allocate block\n")); - return NULL; - } - - // - // Add the new memory block to the pool, then allocate memory from it - // - UsbHcInsertMemBlockToPool (Head, NewBlock); - Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - } - - return Mem; -} - - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINT8 *ToFree; - UINTN AllocSize; - UINTN Byte; - UINTN Bit; - UINTN Count; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - ToFree = (UINT8 *) Mem; - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the memory to free. - // - if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) { - // - // compute the start byte and bit in the bit array - // - Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8; - Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8; - - // - // reset associated bits in bit arry - // - for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) { - ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - break; - } - } - - // - // If Block == NULL, it means that the current memory isn't - // in the host controller's pool. This is critical because - // the caller has passed in a wrong memory point - // - ASSERT (Block != NULL); - - // - // Release the current memory block if it is empty and not the head - // - if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) { - UsbHcUnlinkMemBlock (Head, Block); - UsbHcFreeMemBlock (Pool, Block); - } - - return ; -} diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h deleted file mode 100644 index 84ced8d580..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h +++ /dev/null @@ -1,157 +0,0 @@ -/** @file - - This file contains the definination for host controller memory management routines. - -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_MEM_H_ -#define _EFI_EHCI_MEM_H_ - -#define USB_HC_BIT(a) ((UINTN)(1 << (a))) - -#define USB_HC_BIT_IS_SET(Data, Bit) \ - ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit))) - -#define USB_HC_HIGH_32BIT(Addr64) \ - ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF)) - -typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK; -struct _USBHC_MEM_BLOCK { - UINT8 *Bits; // Bit array to record which unit is allocated - UINTN BitsLen; - UINT8 *Buf; - UINT8 *BufHost; - UINTN BufLen; // Memory size in bytes - VOID *Mapping; - USBHC_MEM_BLOCK *Next; -}; - -// -// USBHC_MEM_POOL is used to manage the memory used by USB -// host controller. EHCI requires the control memory and transfer -// data to be on the same 4G memory. -// -typedef struct _USBHC_MEM_POOL { - EFI_PCI_IO_PROTOCOL *PciIo; - BOOLEAN Check4G; - UINT32 Which4G; - USBHC_MEM_BLOCK *Head; -} USBHC_MEM_POOL; - -// -// Memory allocation unit, must be 2^n, n>4 -// -#define USBHC_MEM_UNIT 64 - -#define USBHC_MEM_UNIT_MASK (USBHC_MEM_UNIT - 1) -#define USBHC_MEM_DEFAULT_PAGES 16 - -#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK)) - -// -// Advance the byte and bit to the next bit, adjust byte accordingly. -// -#define NEXT_BIT(Byte, Bit) \ - do { \ - (Bit)++; \ - if ((Bit) > 7) { \ - (Byte)++; \ - (Bit) = 0; \ - } \ - } while (0) - - - -/** - Initialize the memory management pool for the host controller. - - @param PciIo The PciIo that can be used to access the host controller. - @param Check4G Whether the host controller requires allocated memory - from one 4G address space. - @param Which4G The 4G memory area each memory allocated should be from. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN BOOLEAN Check4G, - IN UINT32 Which4G - ); - - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - - @retval EFI_SUCCESS The memory pool is freed. - @retval EFI_DEVICE_ERROR Failed to free the memory pool. - -**/ -EFI_STATUS -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ); - - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ); - - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -/** - Calculate the corresponding pci bus address according to the Mem parameter. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to host memory. - @param Size The size of the memory region. - - @return the pci memory address -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetPciAddressForHostMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.c b/MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.c deleted file mode 100644 index 09769eaf24..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.c +++ /dev/null @@ -1,1275 +0,0 @@ -/** @file -PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -which is used to enable recovery function from USB Drivers. - -Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EhcPeim.h" - -// -// Two arrays used to translate the EHCI port state (change) -// to the UEFI protocol's port state (change). -// -USB_PORT_STATE_MAP mUsbPortStateMap[] = { - {PORTSC_CONN, USB_PORT_STAT_CONNECTION}, - {PORTSC_ENABLED, USB_PORT_STAT_ENABLE}, - {PORTSC_SUSPEND, USB_PORT_STAT_SUSPEND}, - {PORTSC_OVERCUR, USB_PORT_STAT_OVERCURRENT}, - {PORTSC_RESET, USB_PORT_STAT_RESET}, - {PORTSC_POWER, USB_PORT_STAT_POWER}, - {PORTSC_OWNER, USB_PORT_STAT_OWNER} -}; - -USB_PORT_STATE_MAP mUsbPortChangeMap[] = { - {PORTSC_CONN_CHANGE, USB_PORT_STAT_C_CONNECTION}, - {PORTSC_ENABLE_CHANGE, USB_PORT_STAT_C_ENABLE}, - {PORTSC_OVERCUR_CHANGE, USB_PORT_STAT_C_OVERCURRENT} -}; - -/** - Read Ehc Operation register. - - @param Ehc The EHCI device. - @param Offset The operation register offset. - - @retval the register content read. - -**/ -UINT32 -EhcReadOpReg ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset - ) -{ - UINT32 Data; - - ASSERT (Ehc->CapLen != 0); - - Data = MmioRead32 (Ehc->UsbHostControllerBaseAddress + Ehc->CapLen + Offset); - - return Data; -} - -/** - Write the data to the EHCI operation register. - - @param Ehc The EHCI device. - @param Offset EHCI operation register offset. - @param Data The data to write. - -**/ -VOID -EhcWriteOpReg ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - - ASSERT (Ehc->CapLen != 0); - - MmioWrite32(Ehc->UsbHostControllerBaseAddress + Ehc->CapLen + Offset, Data); - -} - -/** - Set one bit of the operational register while keeping other bits. - - @param Ehc The EHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to set. - -**/ -VOID -EhcSetOpRegBit ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = EhcReadOpReg (Ehc, Offset); - Data |= Bit; - EhcWriteOpReg (Ehc, Offset, Data); -} - -/** - Clear one bit of the operational register while keeping other bits. - - @param Ehc The EHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to clear. - -**/ -VOID -EhcClearOpRegBit ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = EhcReadOpReg (Ehc, Offset); - Data &= ~Bit; - EhcWriteOpReg (Ehc, Offset, Data); -} - -/** - Wait the operation register's bit as specified by Bit - to become set (or clear). - - @param Ehc The EHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to wait for. - @param WaitToSet Wait the bit to set or clear. - @param Timeout The time to wait before abort (in millisecond). - - @retval EFI_SUCCESS The bit successfully changed by host controller. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -EhcWaitOpRegBit ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Bit, - IN BOOLEAN WaitToSet, - IN UINT32 Timeout - ) -{ - UINT32 Index; - - for (Index = 0; Index < Timeout / EHC_SYNC_POLL_INTERVAL + 1; Index++) { - if (EHC_REG_BIT_IS_SET (Ehc, Offset, Bit) == WaitToSet) { - return EFI_SUCCESS; - } - - MicroSecondDelay (EHC_SYNC_POLL_INTERVAL); - } - - return EFI_TIMEOUT; -} - -/** - Read EHCI capability register. - - @param Ehc The EHCI device. - @param Offset Capability register address. - - @retval the register content read. - -**/ -UINT32 -EhcReadCapRegister ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset - ) -{ - UINT32 Data; - - Data = MmioRead32(Ehc->UsbHostControllerBaseAddress + Offset); - - return Data; -} - -/** - Set door bell and wait it to be ACKed by host controller. - This function is used to synchronize with the hardware. - - @param Ehc The EHCI device. - @param Timeout The time to wait before abort (in millisecond, ms). - - @retval EFI_TIMEOUT Time out happened while waiting door bell to set. - @retval EFI_SUCCESS Synchronized with the hardware. - -**/ -EFI_STATUS -EhcSetAndWaitDoorBell ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - UINT32 Data; - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_IAAD); - - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_IAA, TRUE, Timeout); - - // - // ACK the IAA bit in USBSTS register. Make sure other - // interrupt bits are not ACKed. These bits are WC (Write Clean). - // - Data = EhcReadOpReg (Ehc, EHC_USBSTS_OFFSET); - Data &= ~USBSTS_INTACK_MASK; - Data |= USBSTS_IAA; - - EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, Data); - - return Status; -} - -/** - Clear all the interrutp status bits, these bits - are Write-Clean. - - @param Ehc The EHCI device. - -**/ -VOID -EhcAckAllInterrupt ( - IN PEI_USB2_HC_DEV *Ehc - ) -{ - EhcWriteOpReg (Ehc, EHC_USBSTS_OFFSET, USBSTS_INTACK_MASK); -} - -/** - Enable the periodic schedule then wait EHC to - actually enable it. - - @param Ehc The EHCI device. - @param Timeout The time to wait before abort (in millisecond, ms). - - @retval EFI_TIMEOUT Time out happened while enabling periodic schedule. - @retval EFI_SUCCESS The periodical schedule is enabled. - -**/ -EFI_STATUS -EhcEnablePeriodSchd ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_PERIOD); - - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_PERIOD_ENABLED, TRUE, Timeout); - return Status; -} - -/** - Enable asynchrounous schedule. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_SUCCESS The EHCI asynchronous schedule is enabled. - @retval Others Failed to enable the asynchronous scheudle. - -**/ -EFI_STATUS -EhcEnableAsyncSchd ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_ENABLE_ASYNC); - - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_ASYNC_ENABLED, TRUE, Timeout); - return Status; -} - -/** - Check whether Ehc is halted. - - @param Ehc The EHCI device. - - @retval TRUE The controller is halted. - @retval FALSE The controller isn't halted. - -**/ -BOOLEAN -EhcIsHalt ( - IN PEI_USB2_HC_DEV *Ehc - ) -{ - return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT); -} - -/** - Check whether system error occurred. - - @param Ehc The EHCI device. - - @retval TRUE System error happened. - @retval FALSE No system error. - -**/ -BOOLEAN -EhcIsSysError ( - IN PEI_USB2_HC_DEV *Ehc - ) -{ - return EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR); -} - -/** - Reset the host controller. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_TIMEOUT The transfer failed due to time out. - @retval Others Failed to reset the host. - -**/ -EFI_STATUS -EhcResetHC ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - // - // Host can only be reset when it is halt. If not so, halt it - // - if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) { - Status = EhcHaltHC (Ehc, Timeout); - - if (EFI_ERROR (Status)) { - return Status; - } - } - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET); - Status = EhcWaitOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RESET, FALSE, Timeout); - return Status; -} - -/** - Halt the host controller. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_TIMEOUT Failed to halt the controller before Timeout. - @retval EFI_SUCCESS The EHCI is halt. - -**/ -EFI_STATUS -EhcHaltHC ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcClearOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN); - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, TRUE, Timeout); - return Status; -} - -/** - Set the EHCI to run. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_SUCCESS The EHCI is running. - @retval Others Failed to set the EHCI to run. - -**/ -EFI_STATUS -EhcRunHC ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN); - Status = EhcWaitOpRegBit (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT, FALSE, Timeout); - return Status; -} - -/** - Power On All EHCI Ports. - - @param Ehc The EHCI device. - -**/ -VOID -EhcPowerOnAllPorts ( - IN PEI_USB2_HC_DEV *Ehc - ) -{ - UINT8 PortNumber; - UINT8 Index; - - PortNumber = (UINT8)(Ehc->HcStructParams & HCSP_NPORTS); - for (Index = 0; Index < PortNumber; Index++) { - EhcSetOpRegBit (Ehc, EHC_PORT_STAT_OFFSET + 4 * Index, PORTSC_POWER); - } -} - -/** - Initialize the HC hardware. - EHCI spec lists the five things to do to initialize the hardware. - 1. Program CTRLDSSEGMENT. - 2. Set USBINTR to enable interrupts. - 3. Set periodic list base. - 4. Set USBCMD, interrupt threshold, frame list size etc. - 5. Write 1 to CONFIGFLAG to route all ports to EHCI. - - @param Ehc The EHCI device. - - @retval EFI_SUCCESS The EHCI has come out of halt state. - @retval EFI_TIMEOUT Time out happened. - -**/ -EFI_STATUS -EhcInitHC ( - IN PEI_USB2_HC_DEV *Ehc - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS TempPtr; - UINTN PageNumber; - - ASSERT (EhcIsHalt (Ehc)); - - // - // Allocate the periodic frame and associated memeory - // management facilities if not already done. - // - if (Ehc->PeriodFrame != NULL) { - EhcFreeSched (Ehc); - } - PageNumber = sizeof(PEI_URB)/PAGESIZE +1; - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - PageNumber, - &TempPtr - ); - Ehc->Urb = (PEI_URB *) ((UINTN) TempPtr); - if (Ehc->Urb == NULL) { - return Status; - } - - EhcPowerOnAllPorts (Ehc); - MicroSecondDelay (EHC_ROOT_PORT_RECOVERY_STALL); - - Status = EhcInitSched (Ehc); - - if (EFI_ERROR (Status)) { - return Status; - } - // - // 1. Program the CTRLDSSEGMENT register with the high 32 bit addr - // - EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, Ehc->High32bitAddr); - - // - // 2. Clear USBINTR to disable all the interrupt. UEFI works by polling - // - EhcWriteOpReg (Ehc, EHC_USBINTR_OFFSET, 0); - - // - // 3. Program periodic frame list, already done in EhcInitSched - // 4. Start the Host Controller - // - EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN); - - // - // 5. Set all ports routing to EHC - // - EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC); - - // - // Wait roothub port power stable - // - MicroSecondDelay (EHC_ROOT_PORT_RECOVERY_STALL); - - Status = EhcEnablePeriodSchd (Ehc, EHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EhcEnableAsyncSchd (Ehc, EHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_SUCCESS; -} - -/** - Submits bulk transfer to a bulk endpoint of a USB device. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction in bit 7. - @param DeviceSpeed Device speed, Low speed device doesn't support - bulk transfer. - @param MaximumPacketLength Maximum packet size the endpoint is capable of - sending or receiving. - @param Data Array of pointers to the buffers of data to transmit - from or receive into. - @param DataLength The lenght of the data buffer. - @param DataToggle On input, the initial data toggle for the transfer; - On output, it is updated to to next data toggle to use of - the subsequent bulk transfer. - @param TimeOut Indicates the maximum time, in millisecond, which the - transfer is allowed to complete. - If Timeout is 0, then the caller must wait for the function - to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - @param Translator A pointr to the transaction translator data. - @param TransferResult A pointer to the detailed result information of the - bulk transfer. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @retval EFI_INVALID_PARAMETER Parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -EhcBulkTransfer ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - PEI_USB2_HC_DEV *Ehc; - PEI_URB *Urb; - EFI_STATUS Status; - - // - // Validate the parameters - // - if ((DataLength == NULL) || (*DataLength == 0) || - (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 0) && (*DataToggle != 1)) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_LOW) || - ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) || - ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512))) { - return EFI_INVALID_PARAMETER; - } - - Ehc =PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS(This); - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_DEVICE_ERROR; - - if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - EhcAckAllInterrupt (Ehc); - goto ON_EXIT; - } - - EhcAckAllInterrupt (Ehc); - - // - // Create a new URB, insert it into the asynchronous - // schedule list, then poll the execution status. - // - Urb = EhcCreateUrb ( - Ehc, - DeviceAddress, - EndPointAddress, - DeviceSpeed, - *DataToggle, - MaximumPacketLength, - Translator, - EHC_BULK_TRANSFER, - NULL, - Data[0], - *DataLength, - NULL, - NULL, - 1 - ); - - if (Urb == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - EhcLinkQhToAsync (Ehc, Urb->Qh); - Status = EhcExecTransfer (Ehc, Urb, TimeOut); - EhcUnlinkQhFromAsync (Ehc, Urb->Qh); - - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - *DataToggle = Urb->DataToggle; - - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } - - EhcAckAllInterrupt (Ehc); - EhcFreeUrb (Ehc, Urb); - -ON_EXIT: - return Status; -} - -/** - Retrieves the number of root hub ports. - - @param[in] PeiServices The pointer to the PEI Services Table. - @param[in] This The pointer to this instance of the - PEI_USB2_HOST_CONTROLLER_PPI. - @param[out] PortNumber The pointer to the number of the root hub ports. - - @retval EFI_SUCCESS The port number was retrieved successfully. - @retval EFI_INVALID_PARAMETER PortNumber is NULL. - -**/ -EFI_STATUS -EFIAPI -EhcGetRootHubPortNumber ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - OUT UINT8 *PortNumber - ) -{ - - PEI_USB2_HC_DEV *EhcDev; - EhcDev = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This); - - if (PortNumber == NULL) { - return EFI_INVALID_PARAMETER; - } - - *PortNumber = (UINT8)(EhcDev->HcStructParams & HCSP_NPORTS); - return EFI_SUCCESS; - -} - -/** - Clears a feature for the specified root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI. - @param PortNumber Specifies the root hub port whose feature - is requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. - - @retval EFI_SUCCESS The feature specified by PortFeature was cleared - for the USB root hub port specified by PortNumber. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - -**/ -EFI_STATUS -EFIAPI -EhcClearRootHubPortFeature ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - PEI_USB2_HC_DEV *Ehc; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - EFI_STATUS Status; - - Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This); - Status = EFI_SUCCESS; - - TotalPort = (Ehc->HcStructParams & HCSP_NPORTS); - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = EHC_PORT_STAT_OFFSET + (4 * PortNumber); - State = EhcReadOpReg (Ehc, Offset); - State &= ~PORTSC_CHANGE_MASK; - - switch (PortFeature) { - case EfiUsbPortEnable: - // - // Clear PORT_ENABLE feature means disable port. - // - State &= ~PORTSC_ENABLED; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortSuspend: - // - // A write of zero to this bit is ignored by the host - // controller. The host controller will unconditionally - // set this bit to a zero when: - // 1. software sets the Forct Port Resume bit to a zero from a one. - // 2. software sets the Port Reset bit to a one frome a zero. - // - State &= ~PORSTSC_RESUME; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortReset: - // - // Clear PORT_RESET means clear the reset signal. - // - State &= ~PORTSC_RESET; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortOwner: - // - // Clear port owner means this port owned by EHC - // - State &= ~PORTSC_OWNER; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortConnectChange: - // - // Clear connect status change - // - State |= PORTSC_CONN_CHANGE; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortEnableChange: - // - // Clear enable status change - // - State |= PORTSC_ENABLE_CHANGE; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortOverCurrentChange: - // - // Clear PortOverCurrent change - // - State |= PORTSC_OVERCUR_CHANGE; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortPower: - case EfiUsbPortSuspendChange: - case EfiUsbPortResetChange: - // - // Not supported or not related operation - // - break; - - default: - Status = EFI_INVALID_PARAMETER; - break; - } - -ON_EXIT: - return Status; -} - -/** - Sets a feature for the specified root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI - @param PortNumber Root hub port to set. - @param PortFeature Feature to set. - - @retval EFI_SUCCESS The feature specified by PortFeature was set. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -EFIAPI -EhcSetRootHubPortFeature ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - PEI_USB2_HC_DEV *Ehc; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - EFI_STATUS Status; - - Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This); - Status = EFI_SUCCESS; - - TotalPort = (Ehc->HcStructParams & HCSP_NPORTS); - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber)); - State = EhcReadOpReg (Ehc, Offset); - - // - // Mask off the port status change bits, these bits are - // write clean bit - // - State &= ~PORTSC_CHANGE_MASK; - - switch (PortFeature) { - case EfiUsbPortEnable: - // - // Sofeware can't set this bit, Port can only be enable by - // EHCI as a part of the reset and enable - // - State |= PORTSC_ENABLED; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortSuspend: - State |= PORTSC_SUSPEND; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortReset: - // - // Make sure Host Controller not halt before reset it - // - if (EhcIsHalt (Ehc)) { - Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - break; - } - } - - // - // Set one to PortReset bit must also set zero to PortEnable bit - // - State |= PORTSC_RESET; - State &= ~PORTSC_ENABLED; - EhcWriteOpReg (Ehc, Offset, State); - break; - - case EfiUsbPortPower: - // - // Not supported, ignore the operation - // - Status = EFI_SUCCESS; - break; - - case EfiUsbPortOwner: - State |= PORTSC_OWNER; - EhcWriteOpReg (Ehc, Offset, State); - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - -ON_EXIT: - return Status; -} - -/** - Retrieves the current status of a USB root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI. - @param PortNumber The root hub port to retrieve the state from. - @param PortStatus Variable to receive the port state. - - @retval EFI_SUCCESS The status of the USB root hub port specified. - by PortNumber was returned in PortStatus. - @retval EFI_INVALID_PARAMETER PortNumber is invalid. - -**/ -EFI_STATUS -EFIAPI -EhcGetRootHubPortStatus ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - OUT EFI_USB_PORT_STATUS *PortStatus - ) -{ - PEI_USB2_HC_DEV *Ehc; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - UINTN Index; - UINTN MapSize; - EFI_STATUS Status; - - if (PortStatus == NULL) { - return EFI_INVALID_PARAMETER; - } - - Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS(This); - Status = EFI_SUCCESS; - - TotalPort = (Ehc->HcStructParams & HCSP_NPORTS); - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber)); - PortStatus->PortStatus = 0; - PortStatus->PortChangeStatus = 0; - - State = EhcReadOpReg (Ehc, Offset); - - // - // Identify device speed. If in K state, it is low speed. - // If the port is enabled after reset, the device is of - // high speed. The USB bus driver should retrieve the actual - // port speed after reset. - // - if (EHC_BIT_IS_SET (State, PORTSC_LINESTATE_K)) { - PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED; - - } else if (EHC_BIT_IS_SET (State, PORTSC_ENABLED)) { - PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED; - } - - // - // Convert the EHCI port/port change state to UEFI status - // - MapSize = sizeof (mUsbPortStateMap) / sizeof (USB_PORT_STATE_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (EHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) { - PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState); - } - } - - MapSize = sizeof (mUsbPortChangeMap) / sizeof (USB_PORT_STATE_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (EHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) { - PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState); - } - } - -ON_EXIT: - return Status; -} - -/** - Submits control transfer to a target USB device. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI. - @param DeviceAddress The target device address. - @param DeviceSpeed Target device speed. - @param MaximumPacketLength Maximum packet size the default control transfer - endpoint is capable of sending or receiving. - @param Request USB device request to send. - @param TransferDirection Specifies the data direction for the data stage. - @param Data Data buffer to be transmitted or received from USB device. - @param DataLength The size (in bytes) of the data buffer. - @param TimeOut Indicates the maximum timeout, in millisecond. - If Timeout is 0, then the caller must wait for the function - to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - @param Translator Transaction translator to be used by this device. - @param TransferResult Return the result of this control transfer. - - @retval EFI_SUCCESS Transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT Transfer failed due to timeout. - @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -EhcControlTransfer ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 DeviceAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN EFI_USB_DEVICE_REQUEST *Request, - IN EFI_USB_DATA_DIRECTION TransferDirection, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - PEI_USB2_HC_DEV *Ehc; - PEI_URB *Urb; - UINT8 Endpoint; - EFI_STATUS Status; - - // - // Validate parameters - // - if ((Request == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbDataIn) && - (TransferDirection != EfiUsbDataOut) && - (TransferDirection != EfiUsbNoData)) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection == EfiUsbNoData) && - ((Data != NULL) || (*DataLength != 0))) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbNoData) && - ((Data == NULL) || (*DataLength == 0))) { - return EFI_INVALID_PARAMETER; - } - - if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) && - (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) { - return EFI_INVALID_PARAMETER; - } - - - if ((DeviceSpeed == EFI_USB_SPEED_LOW) || - ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) || - ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512))) { - return EFI_INVALID_PARAMETER; - } - - Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This); - - Status = EFI_DEVICE_ERROR; - *TransferResult = EFI_USB_ERR_SYSTEM; - - if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - EhcAckAllInterrupt (Ehc); - goto ON_EXIT; - } - - EhcAckAllInterrupt (Ehc); - - // - // Create a new URB, insert it into the asynchronous - // schedule list, then poll the execution status. - // - // - // Encode the direction in address, although default control - // endpoint is bidirectional. EhcCreateUrb expects this - // combination of Ep addr and its direction. - // - Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0)); - Urb = EhcCreateUrb ( - Ehc, - DeviceAddress, - Endpoint, - DeviceSpeed, - 0, - MaximumPacketLength, - Translator, - EHC_CTRL_TRANSFER, - Request, - Data, - *DataLength, - NULL, - NULL, - 1 - ); - - if (Urb == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - EhcLinkQhToAsync (Ehc, Urb->Qh); - Status = EhcExecTransfer (Ehc, Urb, TimeOut); - EhcUnlinkQhFromAsync (Ehc, Urb->Qh); - - // - // Get the status from URB. The result is updated in EhcCheckUrbResult - // which is called by EhcExecTransfer - // - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } - - EhcAckAllInterrupt (Ehc); - EhcFreeUrb (Ehc, Urb); - -ON_EXIT: - return Status; -} - -/** - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCCESS PPI successfully installed. - -**/ -EFI_STATUS -EFIAPI -EhcPeimEntry ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - PEI_USB_CONTROLLER_PPI *ChipSetUsbControllerPpi; - EFI_STATUS Status; - UINT8 Index; - UINTN ControllerType; - UINTN BaseAddress; - UINTN MemPages; - PEI_USB2_HC_DEV *EhcDev; - EFI_PHYSICAL_ADDRESS TempPtr; - - // - // Shadow this PEIM to run from memory - // - if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { - return EFI_SUCCESS; - } - - Status = PeiServicesLocatePpi ( - &gPeiUsbControllerPpiGuid, - 0, - NULL, - (VOID **) &ChipSetUsbControllerPpi - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Index = 0; - while (TRUE) { - Status = ChipSetUsbControllerPpi->GetUsbController ( - (EFI_PEI_SERVICES **) PeiServices, - ChipSetUsbControllerPpi, - Index, - &ControllerType, - &BaseAddress - ); - // - // When status is error, meant no controller is found - // - if (EFI_ERROR (Status)) { - break; - } - - // - // This PEIM is for UHC type controller. - // - if (ControllerType != PEI_EHCI_CONTROLLER) { - Index++; - continue; - } - - MemPages = sizeof (PEI_USB2_HC_DEV) / PAGESIZE + 1; - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - MemPages, - &TempPtr - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem((VOID *)(UINTN)TempPtr, MemPages*PAGESIZE); - EhcDev = (PEI_USB2_HC_DEV *) ((UINTN) TempPtr); - - EhcDev->Signature = USB2_HC_DEV_SIGNATURE; - - EhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress; - - - EhcDev->HcStructParams = EhcReadCapRegister (EhcDev, EHC_HCSPARAMS_OFFSET); - EhcDev->HcCapParams = EhcReadCapRegister (EhcDev, EHC_HCCPARAMS_OFFSET); - EhcDev->CapLen = EhcReadCapRegister (EhcDev, EHC_CAPLENGTH_OFFSET) & 0x0FF; - // - // Initialize Uhc's hardware - // - Status = InitializeUsbHC (EhcDev); - if (EFI_ERROR (Status)) { - return Status; - } - - EhcDev->Usb2HostControllerPpi.ControlTransfer = EhcControlTransfer; - EhcDev->Usb2HostControllerPpi.BulkTransfer = EhcBulkTransfer; - EhcDev->Usb2HostControllerPpi.GetRootHubPortNumber = EhcGetRootHubPortNumber; - EhcDev->Usb2HostControllerPpi.GetRootHubPortStatus = EhcGetRootHubPortStatus; - EhcDev->Usb2HostControllerPpi.SetRootHubPortFeature = EhcSetRootHubPortFeature; - EhcDev->Usb2HostControllerPpi.ClearRootHubPortFeature = EhcClearRootHubPortFeature; - - EhcDev->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); - EhcDev->PpiDescriptor.Guid = &gPeiUsb2HostControllerPpiGuid; - EhcDev->PpiDescriptor.Ppi = &EhcDev->Usb2HostControllerPpi; - - Status = PeiServicesInstallPpi (&EhcDev->PpiDescriptor); - if (EFI_ERROR (Status)) { - Index++; - continue; - } - - Index++; - } - - return EFI_SUCCESS; -} - -/** - @param EhcDev EHCI Device. - - @retval EFI_SUCCESS EHCI successfully initialized. - @retval EFI_ABORTED EHCI was failed to be initialized. - -**/ -EFI_STATUS -InitializeUsbHC ( - IN PEI_USB2_HC_DEV *EhcDev - ) -{ - EFI_STATUS Status; - - - EhcResetHC (EhcDev, EHC_RESET_TIMEOUT); - - Status = EhcInitHC (EhcDev); - - if (EFI_ERROR (Status)) { - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.h b/MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.h deleted file mode 100644 index 74037769a4..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/EhcPeim.h +++ /dev/null @@ -1,224 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _RECOVERY_EHC_H_ -#define _RECOVERY_EHC_H_ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -typedef struct _PEI_USB2_HC_DEV PEI_USB2_HC_DEV; - -#define EFI_LIST_ENTRY LIST_ENTRY - -#include "UsbHcMem.h" -#include "EhciReg.h" -#include "EhciUrb.h" -#include "EhciSched.h" - -#define EFI_USB_SPEED_FULL 0x0000 -#define EFI_USB_SPEED_LOW 0x0001 -#define EFI_USB_SPEED_HIGH 0x0002 - -#define PAGESIZE 4096 - -#define EHC_1_MICROSECOND 1 -#define EHC_1_MILLISECOND (1000 * EHC_1_MICROSECOND) -#define EHC_1_SECOND (1000 * EHC_1_MILLISECOND) - -// -// EHCI register operation timeout, set by experience -// -#define EHC_RESET_TIMEOUT (1 * EHC_1_SECOND) -#define EHC_GENERIC_TIMEOUT (10 * EHC_1_MILLISECOND) - - -// -// Wait for roothub port power stable, refers to Spec[EHCI1.0-2.3.9] -// -#define EHC_ROOT_PORT_RECOVERY_STALL (20 * EHC_1_MILLISECOND) - -// -// Sync transfer polling interval, set by experience. -// -#define EHC_SYNC_POLL_INTERVAL (6 * EHC_1_MILLISECOND) - -// -//Iterate through the doule linked list. NOT delete safe -// -#define EFI_LIST_FOR_EACH(Entry, ListHead) \ - for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink) - -// -//Iterate through the doule linked list. This is delete-safe. -//Don't touch NextEntry -// -#define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \ - for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\ - Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLink) - -#define EFI_LIST_CONTAINER(Entry, Type, Field) BASE_CR(Entry, Type, Field) - - -#define EHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0XFFFFFFFF)) -#define EHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF)) -#define EHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit))) - -#define EHC_REG_BIT_IS_SET(Ehc, Offset, Bit) \ - (EHC_BIT_IS_SET(EhcReadOpReg ((Ehc), (Offset)), (Bit))) - -#define USB2_HC_DEV_SIGNATURE SIGNATURE_32 ('e', 'h', 'c', 'i') - -struct _PEI_USB2_HC_DEV { - UINTN Signature; - PEI_USB2_HOST_CONTROLLER_PPI Usb2HostControllerPpi; - EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; - UINT32 UsbHostControllerBaseAddress; - PEI_URB *Urb; - USBHC_MEM_POOL *MemPool; - - // - // Schedule data shared between asynchronous and periodic - // transfers: - // ShortReadStop, as its name indicates, is used to terminate - // the short read except the control transfer. EHCI follows - // the alternative next QTD point when a short read happens. - // For control transfer, even the short read happens, try the - // status stage. - // - PEI_EHC_QTD *ShortReadStop; - EFI_EVENT PollTimer; - - // - // Asynchronous(bulk and control) transfer schedule data: - // ReclaimHead is used as the head of the asynchronous transfer - // list. It acts as the reclamation header. - // - PEI_EHC_QH *ReclaimHead; - - // - // Peroidic (interrupt) transfer schedule data: - // - VOID *PeriodFrame; // Mapped as common buffer - VOID *PeriodFrameHost; - VOID *PeriodFrameMap; - - PEI_EHC_QH *PeriodOne; - EFI_LIST_ENTRY AsyncIntTransfers; - - // - // EHCI configuration data - // - UINT32 HcStructParams; // Cache of HC structure parameter, EHC_HCSPARAMS_OFFSET - UINT32 HcCapParams; // Cache of HC capability parameter, HCCPARAMS - UINT32 CapLen; // Capability length - UINT32 High32bitAddr; -}; - -#define PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS(a) CR (a, PEI_USB2_HC_DEV, Usb2HostControllerPpi, USB2_HC_DEV_SIGNATURE) - -/** - @param EhcDev EHCI Device. - - @retval EFI_SUCCESS EHCI successfully initialized. - @retval EFI_ABORTED EHCI was failed to be initialized. - -**/ -EFI_STATUS -InitializeUsbHC ( - IN PEI_USB2_HC_DEV *EhcDev - ); - -/** - Initialize the memory management pool for the host controller. - - @param Ehc The EHCI device. - @param Check4G Whether the host controller requires allocated memory - from one 4G address space. - @param Which4G The 4G memory area each memory allocated should be from. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - IN PEI_USB2_HC_DEV *Ehc, - IN BOOLEAN Check4G, - IN UINT32 Which4G - ) -; - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - - @retval EFI_DEVICE_ERROR Fail to free the memory pool. - @retval EFI_SUCCESS The memory pool is freed. - -**/ -EFI_STATUS -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ) -; - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Ehc The EHCI device. - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN PEI_USB2_HC_DEV *Ehc, - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ) -; - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -; - -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf b/MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf deleted file mode 100644 index 7083f86681..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf +++ /dev/null @@ -1,70 +0,0 @@ -## @file -# The EhcPeim driver is responsible for managing EHCI host controller at PEI phase. -# -# It produces gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -# which is used to enable recovery function from USB Drivers. -# -# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions -# of the BSD License which accompanies this distribution. The -# full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = EhciPei - MODULE_UNI_FILE = EhciPei.uni - FILE_GUID = BAB4F20F-0981-4b5f-A047-6EF83BEEAB3C - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - - ENTRY_POINT = EhcPeimEntry - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - EhcPeim.c - EhcPeim.h - EhciUrb.c - EhciSched.c - UsbHcMem.c - EhciReg.h - EhciSched.h - EhciUrb.h - UsbHcMem.h - - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - - -[LibraryClasses] - IoLib - TimerLib - BaseMemoryLib - PeimEntryPoint - PeiServicesLib - - -[Ppis] - gPeiUsb2HostControllerPpiGuid ## PRODUCES - gPeiUsbControllerPpiGuid ## CONSUMES - - -[Depex] - gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid - -[UserExtensions.TianoCore."ExtraFiles"] - EhciPeiExtra.uni diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhciPei.uni b/MdeModulePkg/Bus/Pci/EhciPei/EhciPei.uni deleted file mode 100644 index c0f6890275..0000000000 Binary files a/MdeModulePkg/Bus/Pci/EhciPei/EhciPei.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhciPeiExtra.uni b/MdeModulePkg/Bus/Pci/EhciPei/EhciPeiExtra.uni deleted file mode 100644 index 3f5163896d..0000000000 Binary files a/MdeModulePkg/Bus/Pci/EhciPei/EhciPeiExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhciReg.h b/MdeModulePkg/Bus/Pci/EhciPei/EhciReg.h deleted file mode 100644 index 34c61d8a94..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/EhciReg.h +++ /dev/null @@ -1,310 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2010, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_REG_H_ -#define _EFI_EHCI_REG_H_ - - - -// -// Capability register offset -// -#define EHC_CAPLENGTH_OFFSET 0 // Capability register length offset -#define EHC_HCSPARAMS_OFFSET 0x04 // Structural Parameters 04-07h -#define EHC_HCCPARAMS_OFFSET 0x08 // Capability parameters offset - -// -// Capability register bit definition -// -#define HCSP_NPORTS 0x0F // Number of root hub port -#define HCCP_64BIT 0x01 // 64-bit addressing capability - -// -// Operational register offset -// -#define EHC_USBCMD_OFFSET 0x0 // USB command register offset -#define EHC_USBSTS_OFFSET 0x04 // Statue register offset -#define EHC_USBINTR_OFFSET 0x08 // USB interrutp offset -#define EHC_FRINDEX_OFFSET 0x0C // Frame index offset -#define EHC_CTRLDSSEG_OFFSET 0x10 // Control data structure segment offset -#define EHC_FRAME_BASE_OFFSET 0x14 // Frame list base address offset -#define EHC_ASYNC_HEAD_OFFSET 0x18 // Next asynchronous list address offset -#define EHC_CONFIG_FLAG_OFFSET 0x40 // Configure flag register offset -#define EHC_PORT_STAT_OFFSET 0x44 // Port status/control offset - -#define EHC_FRAME_LEN 1024 - -// -// Register bit definition -// -#define CONFIGFLAG_ROUTE_EHC 0x01 // Route port to EHC - -#define USBCMD_RUN 0x01 // Run/stop -#define USBCMD_RESET 0x02 // Start the host controller reset -#define USBCMD_ENABLE_PERIOD 0x10 // Enable periodic schedule -#define USBCMD_ENABLE_ASYNC 0x20 // Enable asynchronous schedule -#define USBCMD_IAAD 0x40 // Interrupt on async advance doorbell - -#define USBSTS_IAA 0x20 // Interrupt on async advance -#define USBSTS_PERIOD_ENABLED 0x4000 // Periodic schedule status -#define USBSTS_ASYNC_ENABLED 0x8000 // Asynchronous schedule status -#define USBSTS_HALT 0x1000 // Host controller halted -#define USBSTS_SYS_ERROR 0x10 // Host system error -#define USBSTS_INTACK_MASK 0x003F // Mask for the interrupt ACK, the WC - // (write clean) bits in USBSTS register - -#define PORTSC_CONN 0x01 // Current Connect Status -#define PORTSC_CONN_CHANGE 0x02 // Connect Status Change -#define PORTSC_ENABLED 0x04 // Port Enable / Disable -#define PORTSC_ENABLE_CHANGE 0x08 // Port Enable / Disable Change -#define PORTSC_OVERCUR 0x10 // Over current Active -#define PORTSC_OVERCUR_CHANGE 0x20 // Over current Change -#define PORSTSC_RESUME 0x40 // Force Port Resume -#define PORTSC_SUSPEND 0x80 // Port Suspend State -#define PORTSC_RESET 0x100 // Port Reset -#define PORTSC_LINESTATE_K 0x400 // Line Status K-state -#define PORTSC_LINESTATE_J 0x800 // Line Status J-state -#define PORTSC_POWER 0x1000 // Port Power -#define PORTSC_OWNER 0x2000 // Port Owner -#define PORTSC_CHANGE_MASK 0x2A // Mask of the port change bits, - // they are WC (write clean) -// -// PCI Configuration Registers -// -#define EHC_BAR_INDEX 0 // how many bytes away from USB_BASE to 0x10 - -#define EHC_LINK_TERMINATED(Link) (((Link) & 0x01) != 0) - -#define EHC_ADDR(High, QhHw32) \ - ((VOID *) (UINTN) (LShiftU64 ((High), 32) | ((QhHw32) & 0xFFFFFFF0))) - -#define EHCI_IS_DATAIN(EndpointAddr) EHC_BIT_IS_SET((EndpointAddr), 0x80) - -// -// Structure to map the hardware port states to the -// UEFI's port states. -// -typedef struct { - UINT16 HwState; - UINT16 UefiState; -} USB_PORT_STATE_MAP; - -// -// Ehci Data and Ctrl Structures -// -#pragma pack(1) -typedef struct { - UINT8 Pi; - UINT8 SubClassCode; - UINT8 BaseCode; -} USB_CLASSC; -#pragma pack() - - -/** - Read EHCI capability register. - - @param Ehc The EHCI device. - @param Offset Capability register address. - - @retval the register content read. - -**/ -UINT32 -EhcReadCapRegister ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset - ) -; - -/** - Read Ehc Operation register. - - @param Ehc The EHCI device. - @param Offset The operation register offset. - - @retval the register content read. - -**/ -UINT32 -EhcReadOpReg ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset - ) -; - -/** - Write the data to the EHCI operation register. - - @param Ehc The EHCI device. - @param Offset EHCI operation register offset. - @param Data The data to write. - -**/ -VOID -EhcWriteOpReg ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Offset, - IN UINT32 Data - ) -; - -/** - Stop the legacy USB SMI support. - - @param Ehc The EHCI device. - -**/ -VOID -EhcClearLegacySupport ( - IN PEI_USB2_HC_DEV *Ehc - ) -; - -/** - Set door bell and wait it to be ACKed by host controller. - This function is used to synchronize with the hardware. - - @param Ehc The EHCI device. - @param Timeout The time to wait before abort (in millisecond, ms). - - @retval EFI_TIMEOUT Time out happened while waiting door bell to set. - @retval EFI_SUCCESS Synchronized with the hardware. - -**/ -EFI_STATUS -EhcSetAndWaitDoorBell ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -; - -/** - Clear all the interrutp status bits, these bits - are Write-Clean. - - @param Ehc The EHCI device. - -**/ -VOID -EhcAckAllInterrupt ( - IN PEI_USB2_HC_DEV *Ehc - ) -; - -/** - Check whether Ehc is halted. - - @param Ehc The EHCI device. - - @retval TRUE The controller is halted. - @retval FALSE The controller isn't halted. - -**/ -BOOLEAN -EhcIsHalt ( - IN PEI_USB2_HC_DEV *Ehc - ) -; - -/** - Check whether system error occurred. - - @param Ehc The EHCI device. - - @retval TRUE System error happened. - @retval FALSE No system error. - -**/ -BOOLEAN -EhcIsSysError ( - IN PEI_USB2_HC_DEV *Ehc - ) -; - -/** - Reset the host controller. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_TIMEOUT The transfer failed due to time out. - @retval Others Failed to reset the host. - -**/ -EFI_STATUS -EhcResetHC ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -; - -/** - Halt the host controller. - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_TIMEOUT Failed to halt the controller before Timeout. - @retval EFI_SUCCESS The EHCI is halt. - -**/ -EFI_STATUS -EhcHaltHC ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -; - -/** - Set the EHCI to run - - @param Ehc The EHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_SUCCESS The EHCI is running. - @retval Others Failed to set the EHCI to run. - -**/ -EFI_STATUS -EhcRunHC ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT32 Timeout - ) -; - -/** - Initialize the HC hardware. - EHCI spec lists the five things to do to initialize the hardware. - 1. Program CTRLDSSEGMENT. - 2. Set USBINTR to enable interrupts. - 3. Set periodic list base. - 4. Set USBCMD, interrupt threshold, frame list size etc. - 5. Write 1 to CONFIGFLAG to route all ports to EHCI. - - @param Ehc The EHCI device. - - @retval EFI_SUCCESS The EHCI has come out of halt state. - @retval EFI_TIMEOUT Time out happened. - -**/ -EFI_STATUS -EhcInitHC ( - IN PEI_USB2_HC_DEV *Ehc - ) -; - -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhciSched.c b/MdeModulePkg/Bus/Pci/EhciPei/EhciSched.c deleted file mode 100644 index e992d4f287..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/EhciSched.c +++ /dev/null @@ -1,461 +0,0 @@ -/** @file -PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -which is used to enable recovery function from USB Drivers. - -Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EhcPeim.h" - -/** - Create helper QTD/QH for the EHCI device. - - @param Ehc The EHCI device. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for helper QTD/QH. - @retval EFI_SUCCESS Helper QH/QTD are created. - -**/ -EFI_STATUS -EhcCreateHelpQ ( - IN PEI_USB2_HC_DEV *Ehc - ) -{ - USB_ENDPOINT Ep; - PEI_EHC_QH *Qh; - QH_HW *QhHw; - PEI_EHC_QTD *Qtd; - - // - // Create an inactive Qtd to terminate the short packet read. - // - Qtd = EhcCreateQtd (Ehc, NULL, 0, QTD_PID_INPUT, 0, 64); - - if (Qtd == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Qtd->QtdHw.Status = QTD_STAT_HALTED; - Ehc->ShortReadStop = Qtd; - - // - // Create a QH to act as the EHC reclamation header. - // Set the header to loopback to itself. - // - Ep.DevAddr = 0; - Ep.EpAddr = 1; - Ep.Direction = EfiUsbDataIn; - Ep.DevSpeed = EFI_USB_SPEED_HIGH; - Ep.MaxPacket = 64; - Ep.HubAddr = 0; - Ep.HubPort = 0; - Ep.Toggle = 0; - Ep.Type = EHC_BULK_TRANSFER; - Ep.PollRate = 1; - - Qh = EhcCreateQh (Ehc, &Ep); - - if (Qh == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - QhHw = &Qh->QhHw; - QhHw->HorizonLink = QH_LINK (QhHw, EHC_TYPE_QH, FALSE); - QhHw->Status = QTD_STAT_HALTED; - QhHw->ReclaimHead = 1; - Ehc->ReclaimHead = Qh; - - // - // Create a dummy QH to act as the terminator for periodical schedule - // - Ep.EpAddr = 2; - Ep.Type = EHC_INT_TRANSFER_SYNC; - - Qh = EhcCreateQh (Ehc, &Ep); - - if (Qh == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Qh->QhHw.Status = QTD_STAT_HALTED; - Ehc->PeriodOne = Qh; - - return EFI_SUCCESS; -} - -/** - Initialize the schedule data structure such as frame list. - - @param Ehc The EHCI device to init schedule data for. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to init schedule data. - @retval EFI_SUCCESS The schedule data is initialized. - -**/ -EFI_STATUS -EhcInitSched ( - IN PEI_USB2_HC_DEV *Ehc - ) -{ - EFI_PHYSICAL_ADDRESS PhyAddr; - VOID *Map; - UINTN Index; - UINT32 *Desc; - EFI_STATUS Status; - - // - // First initialize the periodical schedule data: - // 1. Allocate and map the memory for the frame list - // 2. Create the help QTD/QH - // 3. Initialize the frame entries - // 4. Set the frame list register - // - // - // The Frame List ocupies 4K bytes, - // and must be aligned on 4-Kbyte boundaries. - // - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - 1, - &PhyAddr - ); - - Map = NULL; - Ehc->PeriodFrameHost = (VOID *)(UINTN)PhyAddr; - Ehc->PeriodFrame = (VOID *)(UINTN)PhyAddr; - Ehc->PeriodFrameMap = Map; - Ehc->High32bitAddr = EHC_HIGH_32BIT (PhyAddr); - - // - // Init memory pool management then create the helper - // QTD/QH. If failed, previously allocated resources - // will be freed by EhcFreeSched - // - Ehc->MemPool = UsbHcInitMemPool ( - Ehc, - EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT), - Ehc->High32bitAddr - ); - - if (Ehc->MemPool == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = EhcCreateHelpQ (Ehc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Initialize the frame list entries then set the registers - // - Desc = (UINT32 *) Ehc->PeriodFrame; - - for (Index = 0; Index < EHC_FRAME_LEN; Index++) { - Desc[Index] = QH_LINK (Ehc->PeriodOne, EHC_TYPE_QH, FALSE); - } - - EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (Ehc->PeriodFrame)); - - // - // Second initialize the asynchronous schedule: - // Only need to set the AsynListAddr register to - // the reclamation header - // - EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (Ehc->ReclaimHead)); - return EFI_SUCCESS; -} - -/** - Free the schedule data. It may be partially initialized. - - @param Ehc The EHCI device. - -**/ -VOID -EhcFreeSched ( - IN PEI_USB2_HC_DEV *Ehc - ) -{ - EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, 0); - EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, 0); - - if (Ehc->PeriodOne != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (PEI_EHC_QH)); - Ehc->PeriodOne = NULL; - } - - if (Ehc->ReclaimHead != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (PEI_EHC_QH)); - Ehc->ReclaimHead = NULL; - } - - if (Ehc->ShortReadStop != NULL) { - UsbHcFreeMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (PEI_EHC_QTD)); - Ehc->ShortReadStop = NULL; - } - - if (Ehc->MemPool != NULL) { - UsbHcFreeMemPool (Ehc->MemPool); - Ehc->MemPool = NULL; - } - - if (Ehc->PeriodFrame != NULL) { - Ehc->PeriodFrame = NULL; - } -} - -/** - Link the queue head to the asynchronous schedule list. - UEFI only supports one CTRL/BULK transfer at a time - due to its interfaces. This simplifies the AsynList - management: A reclamation header is always linked to - the AsyncListAddr, the only active QH is appended to it. - - @param Ehc The EHCI device. - @param Qh The queue head to link. - -**/ -VOID -EhcLinkQhToAsync ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_EHC_QH *Qh - ) -{ - PEI_EHC_QH *Head; - - // - // Append the queue head after the reclaim header, then - // fix the hardware visiable parts (EHCI R1.0 page 72). - // ReclaimHead is always linked to the EHCI's AsynListAddr. - // - Head = Ehc->ReclaimHead; - - Qh->NextQh = Head->NextQh; - Head->NextQh = Qh; - - Qh->QhHw.HorizonLink = QH_LINK (Head, EHC_TYPE_QH, FALSE);; - Head->QhHw.HorizonLink = QH_LINK (Qh, EHC_TYPE_QH, FALSE); -} - -/** - Unlink a queue head from the asynchronous schedule list. - Need to synchronize with hardware. - - @param Ehc The EHCI device. - @param Qh The queue head to unlink. - -**/ -VOID -EhcUnlinkQhFromAsync ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_EHC_QH *Qh - ) -{ - PEI_EHC_QH *Head; - - ASSERT (Ehc->ReclaimHead->NextQh == Qh); - - // - // Remove the QH from reclamation head, then update the hardware - // visiable part: Only need to loopback the ReclaimHead. The Qh - // is pointing to ReclaimHead (which is staill in the list). - // - Head = Ehc->ReclaimHead; - - Head->NextQh = Qh->NextQh; - Qh->NextQh = NULL; - - Head->QhHw.HorizonLink = QH_LINK (Head, EHC_TYPE_QH, FALSE); - - // - // Set and wait the door bell to synchronize with the hardware - // - EhcSetAndWaitDoorBell (Ehc, EHC_GENERIC_TIMEOUT); - - return; -} - -/** - Check the URB's execution result and update the URB's - result accordingly. - - @param Ehc The EHCI device. - @param Urb The URB to check result. - - @retval TRUE URB transfer is finialized. - @retval FALSE URB transfer is not finialized. - -**/ -BOOLEAN -EhcCheckUrbResult ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_URB *Urb - ) -{ - EFI_LIST_ENTRY *Entry; - PEI_EHC_QTD *Qtd; - QTD_HW *QtdHw; - UINT8 State; - BOOLEAN Finished; - - ASSERT ((Ehc != NULL) && (Urb != NULL) && (Urb->Qh != NULL)); - - Finished = TRUE; - Urb->Completed = 0; - - Urb->Result = EFI_USB_NOERROR; - - if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) { - Urb->Result |= EFI_USB_ERR_SYSTEM; - goto ON_EXIT; - } - - EFI_LIST_FOR_EACH (Entry, &Urb->Qh->Qtds) { - Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList); - QtdHw = &Qtd->QtdHw; - State = (UINT8) QtdHw->Status; - - if (EHC_BIT_IS_SET (State, QTD_STAT_HALTED)) { - // - // EHCI will halt the queue head when met some error. - // If it is halted, the result of URB is finialized. - // - if ((State & QTD_STAT_ERR_MASK) == 0) { - Urb->Result |= EFI_USB_ERR_STALL; - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_BABBLE_ERR)) { - Urb->Result |= EFI_USB_ERR_BABBLE; - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_BUFF_ERR)) { - Urb->Result |= EFI_USB_ERR_BUFFER; - } - - if (EHC_BIT_IS_SET (State, QTD_STAT_TRANS_ERR) && (QtdHw->ErrCnt == 0)) { - Urb->Result |= EFI_USB_ERR_TIMEOUT; - } - - Finished = TRUE; - goto ON_EXIT; - - } else if (EHC_BIT_IS_SET (State, QTD_STAT_ACTIVE)) { - // - // The QTD is still active, no need to check furthur. - // - Urb->Result |= EFI_USB_ERR_NOTEXECUTE; - - Finished = FALSE; - goto ON_EXIT; - - } else { - // - // This QTD is finished OK or met short packet read. Update the - // transfer length if it isn't a setup. - // - if (QtdHw->Pid != QTD_PID_SETUP) { - Urb->Completed += Qtd->DataLen - QtdHw->TotalBytes; - } - - if ((QtdHw->TotalBytes != 0) && (QtdHw->Pid == QTD_PID_INPUT)) { - //EHC_DUMP_QH ((Urb->Qh, "Short packet read", FALSE)); - - // - // Short packet read condition. If it isn't a setup transfer, - // no need to check furthur: the queue head will halt at the - // ShortReadStop. If it is a setup transfer, need to check the - // Status Stage of the setup transfer to get the finial result - // - if (QtdHw->AltNext == QTD_LINK (Ehc->ShortReadStop, FALSE)) { - - Finished = TRUE; - goto ON_EXIT; - } - } - } - } - -ON_EXIT: - // - // Return the data toggle set by EHCI hardware, bulk and interrupt - // transfer will use this to initialize the next transaction. For - // Control transfer, it always start a new data toggle sequence for - // new transfer. - // - // NOTICE: don't move DT update before the loop, otherwise there is - // a race condition that DT is wrong. - // - Urb->DataToggle = (UINT8) Urb->Qh->QhHw.DataToggle; - - return Finished; -} - -/** - Execute the transfer by polling the URB. This is a synchronous operation. - - @param Ehc The EHCI device. - @param Urb The URB to execute. - @param TimeOut The time to wait before abort, in millisecond. - - @retval EFI_DEVICE_ERROR The transfer failed due to transfer error. - @retval EFI_TIMEOUT The transfer failed due to time out. - @retval EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -EhcExecTransfer ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_URB *Urb, - IN UINTN TimeOut - ) -{ - EFI_STATUS Status; - UINTN Index; - UINTN Loop; - BOOLEAN Finished; - BOOLEAN InfiniteLoop; - - Status = EFI_SUCCESS; - Loop = TimeOut * EHC_1_MILLISECOND; - Finished = FALSE; - InfiniteLoop = FALSE; - - // - // If Timeout is 0, then the caller must wait for the function to be completed - // until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - // - if (TimeOut == 0) { - InfiniteLoop = TRUE; - } - - for (Index = 0; InfiniteLoop || (Index < Loop); Index++) { - Finished = EhcCheckUrbResult (Ehc, Urb); - - if (Finished) { - break; - } - - MicroSecondDelay (EHC_1_MICROSECOND); - } - - if (!Finished) { - Status = EFI_TIMEOUT; - } else if (Urb->Result != EFI_USB_NOERROR) { - Status = EFI_DEVICE_ERROR; - } - - return Status; -} - diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhciSched.h b/MdeModulePkg/Bus/Pci/EhciPei/EhciSched.h deleted file mode 100644 index 6cc52f8d0a..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/EhciSched.h +++ /dev/null @@ -1,100 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_SCHED_H_ -#define _EFI_EHCI_SCHED_H_ - -/** - Initialize the schedule data structure such as frame list. - - @param Ehc The EHCI device to init schedule data for. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to init schedule data. - @retval EFI_SUCCESS The schedule data is initialized. - -**/ -EFI_STATUS -EhcInitSched ( - IN PEI_USB2_HC_DEV *Ehc - ) -; - -/** - Free the schedule data. It may be partially initialized. - - @param Ehc The EHCI device. - -**/ -VOID -EhcFreeSched ( - IN PEI_USB2_HC_DEV *Ehc - ) -; - -/** - Link the queue head to the asynchronous schedule list. - UEFI only supports one CTRL/BULK transfer at a time - due to its interfaces. This simplifies the AsynList - management: A reclamation header is always linked to - the AsyncListAddr, the only active QH is appended to it. - - @param Ehc The EHCI device. - @param Qh The queue head to link. - -**/ -VOID -EhcLinkQhToAsync ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_EHC_QH *Qh - ) -; - -/** - Unlink a queue head from the asynchronous schedule list. - Need to synchronize with hardware. - - @param Ehc The EHCI device. - @param Qh The queue head to unlink. - -**/ -VOID -EhcUnlinkQhFromAsync ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_EHC_QH *Qh - ) -; - -/** - Execute the transfer by polling the URB. This is a synchronous operation. - - @param Ehc The EHCI device. - @param Urb The URB to execute. - @param TimeOut The time to wait before abort, in millisecond. - - @retval EFI_DEVICE_ERROR The transfer failed due to transfer error. - @retval EFI_TIMEOUT The transfer failed due to time out. - @retval EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -EhcExecTransfer ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_URB *Urb, - IN UINTN TimeOut - ) -; - -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.c b/MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.c deleted file mode 100644 index 597a4947f5..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.c +++ /dev/null @@ -1,610 +0,0 @@ -/** @file -PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -which is used to enable recovery function from USB Drivers. - -Copyright (c) 2010, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EhcPeim.h" - -/** - Delete a single asynchronous interrupt transfer for - the device and endpoint. - - @param Ehc The EHCI device. - @param Data Current data not associated with a QTD. - @param DataLen The length of the data. - @param PktId Packet ID to use in the QTD. - @param Toggle Data toggle to use in the QTD. - @param MaxPacket Maximu packet length of the endpoint. - - @retval the pointer to the created QTD or NULL if failed to create one. - -**/ -PEI_EHC_QTD * -EhcCreateQtd ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT8 *Data, - IN UINTN DataLen, - IN UINT8 PktId, - IN UINT8 Toggle, - IN UINTN MaxPacket - ) -{ - PEI_EHC_QTD *Qtd; - QTD_HW *QtdHw; - UINTN Index; - UINTN Len; - UINTN ThisBufLen; - - ASSERT (Ehc != NULL); - - Qtd = UsbHcAllocateMem (Ehc, Ehc->MemPool, sizeof (PEI_EHC_QTD)); - - if (Qtd == NULL) { - return NULL; - } - - Qtd->Signature = EHC_QTD_SIG; - Qtd->Data = Data; - Qtd->DataLen = 0; - - InitializeListHead (&Qtd->QtdList); - - QtdHw = &Qtd->QtdHw; - QtdHw->NextQtd = QTD_LINK (NULL, TRUE); - QtdHw->AltNext = QTD_LINK (NULL, TRUE); - QtdHw->Status = QTD_STAT_ACTIVE; - QtdHw->Pid = PktId; - QtdHw->ErrCnt = QTD_MAX_ERR; - QtdHw->Ioc = 0; - QtdHw->TotalBytes = 0; - QtdHw->DataToggle = Toggle; - - // - // Fill in the buffer points - // - if (Data != NULL) { - Len = 0; - - for (Index = 0; Index <= QTD_MAX_BUFFER; Index++) { - // - // Set the buffer point (Check page 41 EHCI Spec 1.0). No need to - // compute the offset and clear Reserved fields. This is already - // done in the data point. - // - QtdHw->Page[Index] = EHC_LOW_32BIT (Data); - QtdHw->PageHigh[Index] = EHC_HIGH_32BIT (Data); - - ThisBufLen = QTD_BUF_LEN - (EHC_LOW_32BIT (Data) & QTD_BUF_MASK); - - if (Len + ThisBufLen >= DataLen) { - Len = DataLen; - break; - } - - Len += ThisBufLen; - Data += ThisBufLen; - } - - // - // Need to fix the last pointer if the Qtd can't hold all the - // user's data to make sure that the length is in the unit of - // max packets. If it can hold all the data, there is no such - // need. - // - if (Len < DataLen) { - Len = Len - Len % MaxPacket; - } - - QtdHw->TotalBytes = (UINT32) Len; - Qtd->DataLen = Len; - } - - return Qtd; -} - -/** - Initialize the queue head for interrupt transfer, - that is, initialize the following three fields: - 1. SplitXState in the Status field. - 2. Microframe S-mask. - 3. Microframe C-mask. - - @param Ep The queue head's related endpoint. - @param QhHw The queue head to initialize. - -**/ -VOID -EhcInitIntQh ( - IN USB_ENDPOINT *Ep, - IN QH_HW *QhHw - ) -{ - // - // Because UEFI interface can't utilitize an endpoint with - // poll rate faster than 1ms, only need to set one bit in - // the queue head. simple. But it may be changed later. If - // sub-1ms interrupt is supported, need to update the S-Mask - // here - // - if (Ep->DevSpeed == EFI_USB_SPEED_HIGH) { - QhHw->SMask = QH_MICROFRAME_0; - return ; - } - - // - // For low/full speed device, the transfer must go through - // the split transaction. Need to update three fields - // 1. SplitXState in the status - // 2. Microframe S-Mask - // 3. Microframe C-Mask - // UEFI USB doesn't exercise admission control. It simplely - // schedule the high speed transactions in microframe 0, and - // full/low speed transactions at microframe 1. This also - // avoid the use of FSTN. - // - QhHw->SMask = QH_MICROFRAME_1; - QhHw->CMask = QH_MICROFRAME_3 | QH_MICROFRAME_4 | QH_MICROFRAME_5; -} - -/** - Allocate and initialize a EHCI queue head. - - @param Ehci The EHCI device. - @param Ep The endpoint to create queue head for. - - @retval the pointer to the created queue head or NULL if failed to create one. - -**/ -PEI_EHC_QH * -EhcCreateQh ( - IN PEI_USB2_HC_DEV *Ehci, - IN USB_ENDPOINT *Ep - ) -{ - PEI_EHC_QH *Qh; - QH_HW *QhHw; - - Qh = UsbHcAllocateMem (Ehci, Ehci->MemPool, sizeof (PEI_EHC_QH)); - - if (Qh == NULL) { - return NULL; - } - - Qh->Signature = EHC_QH_SIG; - Qh->NextQh = NULL; - Qh->Interval = Ep->PollRate; - - InitializeListHead (&Qh->Qtds); - - QhHw = &Qh->QhHw; - QhHw->HorizonLink = QH_LINK (NULL, 0, TRUE); - QhHw->DeviceAddr = Ep->DevAddr; - QhHw->Inactive = 0; - QhHw->EpNum = Ep->EpAddr; - QhHw->EpSpeed = Ep->DevSpeed; - QhHw->DtCtrl = 0; - QhHw->ReclaimHead = 0; - QhHw->MaxPacketLen = (UINT32) Ep->MaxPacket; - QhHw->CtrlEp = 0; - QhHw->NakReload = QH_NAK_RELOAD; - QhHw->HubAddr = Ep->HubAddr; - QhHw->PortNum = Ep->HubPort; - QhHw->Multiplier = 1; - QhHw->DataToggle = Ep->Toggle; - - if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) { - QhHw->Status |= QTD_STAT_DO_SS; - } - - switch (Ep->Type) { - case EHC_CTRL_TRANSFER: - // - // Special initialization for the control transfer: - // 1. Control transfer initialize data toggle from each QTD - // 2. Set the Control Endpoint Flag (C) for low/full speed endpoint. - // - QhHw->DtCtrl = 1; - - if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) { - QhHw->CtrlEp = 1; - } - break; - - case EHC_INT_TRANSFER_ASYNC: - case EHC_INT_TRANSFER_SYNC: - // - // Special initialization for the interrupt transfer - // to set the S-Mask and C-Mask - // - QhHw->NakReload = 0; - EhcInitIntQh (Ep, QhHw); - break; - - case EHC_BULK_TRANSFER: - if ((Ep->DevSpeed == EFI_USB_SPEED_HIGH) && (Ep->Direction == EfiUsbDataOut)) { - QhHw->Status |= QTD_STAT_DO_PING; - } - - break; - } - - return Qh; -} - -/** - Convert the poll interval from application to that - be used by EHCI interface data structure. Only need - to get the max 2^n that is less than interval. UEFI - can't support high speed endpoint with a interval less - than 8 microframe because interval is specified in - the unit of ms (millisecond). - - @param Interval The interval to convert. - - @retval The converted interval. - -**/ -UINTN -EhcConvertPollRate ( - IN UINTN Interval - ) -{ - UINTN BitCount; - - if (Interval == 0) { - return 1; - } - - // - // Find the index (1 based) of the highest non-zero bit - // - BitCount = 0; - - while (Interval != 0) { - Interval >>= 1; - BitCount++; - } - - return (UINTN)1 << (BitCount - 1); -} - -/** - Free a list of QTDs. - - @param Ehc The EHCI device. - @param Qtds The list head of the QTD. - -**/ -VOID -EhcFreeQtds ( - IN PEI_USB2_HC_DEV *Ehc, - IN EFI_LIST_ENTRY *Qtds - ) -{ - EFI_LIST_ENTRY *Entry; - EFI_LIST_ENTRY *Next; - PEI_EHC_QTD *Qtd; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, Qtds) { - Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList); - - RemoveEntryList (&Qtd->QtdList); - UsbHcFreeMem (Ehc->MemPool, Qtd, sizeof (PEI_EHC_QTD)); - } -} - -/** - Free an allocated URB. It is possible for it to be partially inited. - - @param Ehc The EHCI device. - @param Urb The URB to free. - -**/ -VOID -EhcFreeUrb ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_URB *Urb - ) -{ - if (Urb->Qh != NULL) { - // - // Ensure that this queue head has been unlinked from the - // schedule data structures. Free all the associated QTDs - // - EhcFreeQtds (Ehc, &Urb->Qh->Qtds); - UsbHcFreeMem (Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH)); - } -} - -/** - Create a list of QTDs for the URB. - - @param Ehc The EHCI device. - @param Urb The URB to create QTDs for. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for QTD. - @retval EFI_SUCCESS The QTDs are allocated for the URB. - -**/ -EFI_STATUS -EhcCreateQtds ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_URB *Urb - ) -{ - USB_ENDPOINT *Ep; - PEI_EHC_QH *Qh; - PEI_EHC_QTD *Qtd; - PEI_EHC_QTD *StatusQtd; - PEI_EHC_QTD *NextQtd; - EFI_LIST_ENTRY *Entry; - UINT32 AlterNext; - UINT8 Toggle; - UINTN Len; - UINT8 Pid; - - ASSERT ((Urb != NULL) && (Urb->Qh != NULL)); - - // - // EHCI follows the alternet next QTD pointer if it meets - // a short read and the AlterNext pointer is valid. UEFI - // EHCI driver should terminate the transfer except the - // control transfer. - // - Toggle = 0; - Qh = Urb->Qh; - Ep = &Urb->Ep; - StatusQtd = NULL; - AlterNext = QTD_LINK (NULL, TRUE); - - if (Ep->Direction == EfiUsbDataIn) { - AlterNext = QTD_LINK (Ehc->ShortReadStop, FALSE); - } - - // - // Build the Setup and status packets for control transfer - // - if (Urb->Ep.Type == EHC_CTRL_TRANSFER) { - Len = sizeof (EFI_USB_DEVICE_REQUEST); - Qtd = EhcCreateQtd (Ehc, Urb->RequestPhy, Len, QTD_PID_SETUP, 0, Ep->MaxPacket); - - if (Qtd == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - InsertTailList (&Qh->Qtds, &Qtd->QtdList); - - // - // Create the status packet now. Set the AlterNext to it. So, when - // EHCI meets a short control read, it can resume at the status stage. - // Use the opposite direction of the data stage, or IN if there is - // no data stage. - // - if (Ep->Direction == EfiUsbDataIn) { - Pid = QTD_PID_OUTPUT; - } else { - Pid = QTD_PID_INPUT; - } - - StatusQtd = EhcCreateQtd (Ehc, NULL, 0, Pid, 1, Ep->MaxPacket); - - if (StatusQtd == NULL) { - goto ON_ERROR; - } - - if (Ep->Direction == EfiUsbDataIn) { - AlterNext = QTD_LINK (StatusQtd, FALSE); - } - - Toggle = 1; - } - - // - // Build the data packets for all the transfers - // - if (Ep->Direction == EfiUsbDataIn) { - Pid = QTD_PID_INPUT; - } else { - Pid = QTD_PID_OUTPUT; - } - - Qtd = NULL; - Len = 0; - - while (Len < Urb->DataLen) { - Qtd = EhcCreateQtd ( - Ehc, - (UINT8 *) Urb->DataPhy + Len, - Urb->DataLen - Len, - Pid, - Toggle, - Ep->MaxPacket - ); - - if (Qtd == NULL) { - goto ON_ERROR; - } - - Qtd->QtdHw.AltNext = AlterNext; - InsertTailList (&Qh->Qtds, &Qtd->QtdList); - - // - // Switch the Toggle bit if odd number of packets are included in the QTD. - // - if (((Qtd->DataLen + Ep->MaxPacket - 1) / Ep->MaxPacket) % 2) { - Toggle = (UINT8) (1 - Toggle); - } - - Len += Qtd->DataLen; - } - - // - // Insert the status packet for control transfer - // - if (Ep->Type == EHC_CTRL_TRANSFER) { - InsertTailList (&Qh->Qtds, &StatusQtd->QtdList); - } - - // - // OK, all the QTDs needed are created. Now, fix the NextQtd point - // - EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) { - Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList); - - // - // break if it is the last entry on the list - // - if (Entry->ForwardLink == &Qh->Qtds) { - break; - } - - NextQtd = EFI_LIST_CONTAINER (Entry->ForwardLink, PEI_EHC_QTD, QtdList); - Qtd->QtdHw.NextQtd = QTD_LINK (NextQtd, FALSE); - } - - // - // Link the QTDs to the queue head - // - NextQtd = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, PEI_EHC_QTD, QtdList); - Qh->QhHw.NextQtd = QTD_LINK (NextQtd, FALSE); - return EFI_SUCCESS; - -ON_ERROR: - EhcFreeQtds (Ehc, &Qh->Qtds); - return EFI_OUT_OF_RESOURCES; -} - -/** - Create a new URB and its associated QTD. - - @param Ehc The EHCI device. - @param DevAddr The device address. - @param EpAddr Endpoint addrress & its direction. - @param DevSpeed The device speed. - @param Toggle Initial data toggle to use. - @param MaxPacket The max packet length of the endpoint. - @param Hub The transaction translator to use. - @param Type The transaction type. - @param Request The standard USB request for control transfer. - @param Data The user data to transfer. - @param DataLen The length of data buffer. - @param Callback The function to call when data is transferred. - @param Context The context to the callback. - @param Interval The interval for interrupt transfer. - - @retval the pointer to the created URB or NULL. - -**/ -PEI_URB * -EhcCreateUrb ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT8 DevAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINT8 Toggle, - IN UINTN MaxPacket, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context, - IN UINTN Interval - ) -{ - USB_ENDPOINT *Ep; - EFI_PHYSICAL_ADDRESS PhyAddr; - EFI_STATUS Status; - UINTN Len; - PEI_URB *Urb; - VOID *Map; - - - Map = NULL; - - Urb = Ehc->Urb; - Urb->Signature = EHC_URB_SIG; - InitializeListHead (&Urb->UrbList); - - Ep = &Urb->Ep; - Ep->DevAddr = DevAddr; - Ep->EpAddr = (UINT8) (EpAddr & 0x0F); - Ep->Direction = (((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut); - Ep->DevSpeed = DevSpeed; - Ep->MaxPacket = MaxPacket; - - Ep->HubAddr = 0; - Ep->HubPort = 0; - - if (DevSpeed != EFI_USB_SPEED_HIGH) { - ASSERT (Hub != NULL); - - Ep->HubAddr = Hub->TranslatorHubAddress; - Ep->HubPort = Hub->TranslatorPortNumber; - } - - Ep->Toggle = Toggle; - Ep->Type = Type; - Ep->PollRate = EhcConvertPollRate (Interval); - - Urb->Request = Request; - Urb->Data = Data; - Urb->DataLen = DataLen; - Urb->Callback = Callback; - Urb->Context = Context; - Urb->Qh = EhcCreateQh (Ehc, &Urb->Ep); - - if (Urb->Qh == NULL) { - goto ON_ERROR; - } - - // - // Map the request and user data - // - if (Request != NULL) { - Len = sizeof (EFI_USB_DEVICE_REQUEST); - PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) Request ; - if ( (Len != sizeof (EFI_USB_DEVICE_REQUEST))) { - goto ON_ERROR; - } - - Urb->RequestPhy = (VOID *) ((UINTN) PhyAddr); - Urb->RequestMap = Map; - } - - if (Data != NULL) { - Len = DataLen; - PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) Data ; - if ( (Len != DataLen)) { - goto ON_ERROR; - } - - Urb->DataPhy = (VOID *) ((UINTN) PhyAddr); - Urb->DataMap = Map; - } - - Status = EhcCreateQtds (Ehc, Urb); - - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - return Urb; - -ON_ERROR: - EhcFreeUrb (Ehc, Urb); - return NULL; -} diff --git a/MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.h b/MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.h deleted file mode 100644 index 3fe93fb294..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.h +++ /dev/null @@ -1,331 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2010, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_URB_H_ -#define _EFI_EHCI_URB_H_ - -typedef struct _PEI_EHC_QTD PEI_EHC_QTD; -typedef struct _PEI_EHC_QH PEI_EHC_QH; -typedef struct _PEI_URB PEI_URB; - -#define EHC_CTRL_TRANSFER 0x01 -#define EHC_BULK_TRANSFER 0x02 -#define EHC_INT_TRANSFER_SYNC 0x04 -#define EHC_INT_TRANSFER_ASYNC 0x08 - -#define EHC_QTD_SIG SIGNATURE_32 ('U', 'S', 'B', 'T') -#define EHC_QH_SIG SIGNATURE_32 ('U', 'S', 'B', 'H') -#define EHC_URB_SIG SIGNATURE_32 ('U', 'S', 'B', 'R') - -// -// Hardware related bit definitions -// -#define EHC_TYPE_ITD 0x00 -#define EHC_TYPE_QH 0x02 -#define EHC_TYPE_SITD 0x04 -#define EHC_TYPE_FSTN 0x06 - -#define QH_NAK_RELOAD 3 -#define QH_HSHBW_MULTI 1 - -#define QTD_MAX_ERR 3 -#define QTD_PID_OUTPUT 0x00 -#define QTD_PID_INPUT 0x01 -#define QTD_PID_SETUP 0x02 - -#define QTD_STAT_DO_OUT 0 -#define QTD_STAT_DO_SS 0 -#define QTD_STAT_DO_PING 0x01 -#define QTD_STAT_DO_CS 0x02 -#define QTD_STAT_TRANS_ERR 0x08 -#define QTD_STAT_BABBLE_ERR 0x10 -#define QTD_STAT_BUFF_ERR 0x20 -#define QTD_STAT_HALTED 0x40 -#define QTD_STAT_ACTIVE 0x80 -#define QTD_STAT_ERR_MASK (QTD_STAT_TRANS_ERR | QTD_STAT_BABBLE_ERR | QTD_STAT_BUFF_ERR) - -#define QTD_MAX_BUFFER 4 -#define QTD_BUF_LEN 4096 -#define QTD_BUF_MASK 0x0FFF - -#define QH_MICROFRAME_0 0x01 -#define QH_MICROFRAME_1 0x02 -#define QH_MICROFRAME_2 0x04 -#define QH_MICROFRAME_3 0x08 -#define QH_MICROFRAME_4 0x10 -#define QH_MICROFRAME_5 0x20 -#define QH_MICROFRAME_6 0x40 -#define QH_MICROFRAME_7 0x80 - -#define USB_ERR_SHORT_PACKET 0x200 - -// -// Fill in the hardware link point: pass in a EHC_QH/QH_HW -// pointer to QH_LINK; A EHC_QTD/QTD_HW pointer to QTD_LINK -// -#define QH_LINK(Addr, Type, Term) \ - ((UINT32) ((EHC_LOW_32BIT (Addr) & 0xFFFFFFE0) | (Type) | ((Term) ? 1 : 0))) - -#define QTD_LINK(Addr, Term) QH_LINK((Addr), 0, (Term)) - -// -// The defination of EHCI hardware used data structure for -// little endian architecture. The QTD and QH structures -// are required to be 32 bytes aligned. Don't add members -// to the head of the associated software strucuture. -// -#pragma pack(1) -typedef struct { - UINT32 NextQtd; - UINT32 AltNext; - - UINT32 Status : 8; - UINT32 Pid : 2; - UINT32 ErrCnt : 2; - UINT32 CurPage : 3; - UINT32 Ioc : 1; - UINT32 TotalBytes : 15; - UINT32 DataToggle : 1; - - UINT32 Page[5]; - UINT32 PageHigh[5]; -} QTD_HW; - -typedef struct { - UINT32 HorizonLink; - // - // Endpoint capabilities/Characteristics DWord 1 and DWord 2 - // - UINT32 DeviceAddr : 7; - UINT32 Inactive : 1; - UINT32 EpNum : 4; - UINT32 EpSpeed : 2; - UINT32 DtCtrl : 1; - UINT32 ReclaimHead : 1; - UINT32 MaxPacketLen : 11; - UINT32 CtrlEp : 1; - UINT32 NakReload : 4; - - UINT32 SMask : 8; - UINT32 CMask : 8; - UINT32 HubAddr : 7; - UINT32 PortNum : 7; - UINT32 Multiplier : 2; - - // - // Transaction execution overlay area - // - UINT32 CurQtd; - UINT32 NextQtd; - UINT32 AltQtd; - - UINT32 Status : 8; - UINT32 Pid : 2; - UINT32 ErrCnt : 2; - UINT32 CurPage : 3; - UINT32 Ioc : 1; - UINT32 TotalBytes : 15; - UINT32 DataToggle : 1; - - UINT32 Page[5]; - UINT32 PageHigh[5]; -} QH_HW; -#pragma pack() - - -// -// Endpoint address and its capabilities -// -typedef struct _USB_ENDPOINT { - UINT8 DevAddr; - UINT8 EpAddr; // Endpoint address, no direction encoded in - EFI_USB_DATA_DIRECTION Direction; - UINT8 DevSpeed; - UINTN MaxPacket; - UINT8 HubAddr; - UINT8 HubPort; - UINT8 Toggle; // Data toggle, not used for control transfer - UINTN Type; - UINTN PollRate; // Polling interval used by EHCI -} USB_ENDPOINT; - -// -// Software QTD strcture, this is used to manage all the -// QTD generated from a URB. Don't add fields before QtdHw. -// -struct _PEI_EHC_QTD { - QTD_HW QtdHw; - UINT32 Signature; - EFI_LIST_ENTRY QtdList; // The list of QTDs to one end point - UINT8 *Data; // Buffer of the original data - UINTN DataLen; // Original amount of data in this QTD -}; - - - -// -// Software QH structure. All three different transaction types -// supported by UEFI USB, that is the control/bulk/interrupt -// transfers use the queue head and queue token strcuture. -// -// Interrupt QHs are linked to periodic frame list in the reversed -// 2^N tree. Each interrupt QH is linked to the list starting at -// frame 0. There is a dummy interrupt QH linked to each frame as -// a sentinental whose polling interval is 1. Synchronous interrupt -// transfer is linked after this dummy QH. -// -// For control/bulk transfer, only synchronous (in the sense of UEFI) -// transfer is supported. A dummy QH is linked to EHCI AsyncListAddr -// as the reclamation header. New transfer is inserted after this QH. -// -struct _PEI_EHC_QH { - QH_HW QhHw; - UINT32 Signature; - PEI_EHC_QH *NextQh; // The queue head pointed to by horizontal link - EFI_LIST_ENTRY Qtds; // The list of QTDs to this queue head - UINTN Interval; -}; - -// -// URB (Usb Request Block) contains information for all kinds of -// usb requests. -// -struct _PEI_URB { - UINT32 Signature; - EFI_LIST_ENTRY UrbList; - - // - // Transaction information - // - USB_ENDPOINT Ep; - EFI_USB_DEVICE_REQUEST *Request; // Control transfer only - VOID *RequestPhy; // Address of the mapped request - VOID *RequestMap; - VOID *Data; - UINTN DataLen; - VOID *DataPhy; // Address of the mapped user data - VOID *DataMap; - EFI_ASYNC_USB_TRANSFER_CALLBACK Callback; - VOID *Context; - - // - // Schedule data - // - PEI_EHC_QH *Qh; - - // - // Transaction result - // - UINT32 Result; - UINTN Completed; // completed data length - UINT8 DataToggle; -}; - -/** - Delete a single asynchronous interrupt transfer for - the device and endpoint. - - @param Ehc The EHCI device. - @param Data Current data not associated with a QTD. - @param DataLen The length of the data. - @param PktId Packet ID to use in the QTD. - @param Toggle Data toggle to use in the QTD. - @param MaxPacket Maximu packet length of the endpoint. - - @retval the pointer to the created QTD or NULL if failed to create one. - -**/ -PEI_EHC_QTD * -EhcCreateQtd ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT8 *Data, - IN UINTN DataLen, - IN UINT8 PktId, - IN UINT8 Toggle, - IN UINTN MaxPacket - ) -; - -/** - Allocate and initialize a EHCI queue head. - - @param Ehci The EHCI device. - @param Ep The endpoint to create queue head for. - - @retval the pointer to the created queue head or NULL if failed to create one. - -**/ -PEI_EHC_QH * -EhcCreateQh ( - IN PEI_USB2_HC_DEV *Ehci, - IN USB_ENDPOINT *Ep - ) -; - -/** - Free an allocated URB. It is possible for it to be partially inited. - - @param Ehc The EHCI device. - @param Urb The URB to free. - -**/ -VOID -EhcFreeUrb ( - IN PEI_USB2_HC_DEV *Ehc, - IN PEI_URB *Urb - ) -; - -/** - Create a new URB and its associated QTD. - - @param Ehc The EHCI device. - @param DevAddr The device address. - @param EpAddr Endpoint addrress & its direction. - @param DevSpeed The device speed. - @param Toggle Initial data toggle to use. - @param MaxPacket The max packet length of the endpoint. - @param Hub The transaction translator to use. - @param Type The transaction type. - @param Request The standard USB request for control transfer. - @param Data The user data to transfer. - @param DataLen The length of data buffer. - @param Callback The function to call when data is transferred. - @param Context The context to the callback. - @param Interval The interval for interrupt transfer. - - @retval the pointer to the created URB or NULL. - -**/ -PEI_URB * -EhcCreateUrb ( - IN PEI_USB2_HC_DEV *Ehc, - IN UINT8 DevAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINT8 Toggle, - IN UINTN MaxPacket, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context, - IN UINTN Interval - ) -; -#endif diff --git a/MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.c b/MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.c deleted file mode 100644 index 6b3755852b..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.c +++ /dev/null @@ -1,493 +0,0 @@ -/** @file -PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -which is used to enable recovery function from USB Drivers. - -Copyright (c) 2010, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "EhcPeim.h" - -/** - Allocate a block of memory to be used by the buffer pool. - - @param Ehc The EHCI device. - @param Pool The buffer pool to allocate memory for. - @param Pages How many pages to allocate. - - @return The allocated memory block or NULL if failed. - -**/ -USBHC_MEM_BLOCK * -UsbHcAllocMemBlock ( - IN PEI_USB2_HC_DEV *Ehc, - IN USBHC_MEM_POOL *Pool, - IN UINTN Pages - ) -{ - USBHC_MEM_BLOCK *Block; - VOID *BufHost; - VOID *Mapping; - EFI_PHYSICAL_ADDRESS MappedAddr; - EFI_STATUS Status; - UINTN PageNumber; - EFI_PHYSICAL_ADDRESS TempPtr; - - Mapping = NULL; - PageNumber = sizeof(USBHC_MEM_BLOCK)/PAGESIZE +1; - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - PageNumber, - &TempPtr - ); - - if (EFI_ERROR (Status)) { - return NULL; - } - ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE); - - // - // each bit in the bit array represents USBHC_MEM_UNIT - // bytes of memory in the memory block. - // - ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE); - - Block = (USBHC_MEM_BLOCK*)(UINTN)TempPtr; - Block->BufLen = EFI_PAGES_TO_SIZE (Pages); - Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8); - - PageNumber = (Block->BitsLen)/PAGESIZE +1; - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - PageNumber, - &TempPtr - ); - - if (EFI_ERROR (Status)) { - return NULL; - } - ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE); - - Block->Bits = (UINT8 *)(UINTN)TempPtr; - - - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - Pages, - &TempPtr - ); - ZeroMem ((VOID *)(UINTN)TempPtr, Pages*EFI_PAGE_SIZE); - - BufHost = (VOID *)(UINTN)TempPtr; - MappedAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) BufHost; - // - // Check whether the data structure used by the host controller - // should be restricted into the same 4G - // - if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) { - return NULL; - } - - Block->BufHost = BufHost; - Block->Buf = (UINT8 *) ((UINTN) MappedAddr); - Block->Mapping = Mapping; - Block->Next = NULL; - - return Block; - -} - -/** - Free the memory block from the memory pool. - - @param Pool The memory pool to free the block from. - @param Block The memory block to free. - -**/ -VOID -UsbHcFreeMemBlock ( - IN USBHC_MEM_POOL *Pool, - IN USBHC_MEM_BLOCK *Block - ) -{ - ASSERT ((Pool != NULL) && (Block != NULL)); -} - -/** - Alloc some memory from the block. - - @param Block The memory block to allocate memory from. - @param Units Number of memory units to allocate. - - @return The pointer to the allocated memory. If couldn't allocate the needed memory, - the return value is NULL. - -**/ -VOID * -UsbHcAllocMemFromBlock ( - IN USBHC_MEM_BLOCK *Block, - IN UINTN Units - ) -{ - UINTN Byte; - UINT8 Bit; - UINTN StartByte; - UINT8 StartBit; - UINTN Available; - UINTN Count; - - ASSERT ((Block != 0) && (Units != 0)); - - StartByte = 0; - StartBit = 0; - Available = 0; - - for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) { - // - // If current bit is zero, the corresponding memory unit is - // available, otherwise we need to restart our searching. - // Available counts the consective number of zero bit. - // - if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) { - Available++; - - if (Available >= Units) { - break; - } - - NEXT_BIT (Byte, Bit); - - } else { - NEXT_BIT (Byte, Bit); - - Available = 0; - StartByte = Byte; - StartBit = Bit; - } - } - - if (Available < Units) { - return NULL; - } - - // - // Mark the memory as allocated - // - Byte = StartByte; - Bit = StartBit; - - for (Count = 0; Count < Units; Count++) { - ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT; -} - -/** - Insert the memory block to the pool's list of the blocks. - - @param Head The head of the memory pool's block list. - @param Block The memory block to insert. - -**/ -VOID -UsbHcInsertMemBlockToPool ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *Block - ) -{ - ASSERT ((Head != NULL) && (Block != NULL)); - Block->Next = Head->Next; - Head->Next = Block; -} - -/** - Is the memory block empty? - - @param Block The memory block to check. - - @retval TRUE The memory block is empty. - @retval FALSE The memory block isn't empty. - -**/ -BOOLEAN -UsbHcIsMemBlockEmpty ( - IN USBHC_MEM_BLOCK *Block - ) -{ - UINTN Index; - - - for (Index = 0; Index < Block->BitsLen; Index++) { - if (Block->Bits[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - -/** - Unlink the memory block from the pool's list. - - @param Head The block list head of the memory's pool. - @param BlockToUnlink The memory block to unlink. - -**/ -VOID -UsbHcUnlinkMemBlock ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *BlockToUnlink - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT ((Head != NULL) && (BlockToUnlink != NULL)); - - for (Block = Head; Block != NULL; Block = Block->Next) { - if (Block->Next == BlockToUnlink) { - Block->Next = BlockToUnlink->Next; - BlockToUnlink->Next = NULL; - break; - } - } -} - -/** - Initialize the memory management pool for the host controller. - - @param Ehc The EHCI device. - @param Check4G Whether the host controller requires allocated memory. - from one 4G address space. - @param Which4G The 4G memory area each memory allocated should be from. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - IN PEI_USB2_HC_DEV *Ehc, - IN BOOLEAN Check4G, - IN UINT32 Which4G - ) -{ - USBHC_MEM_POOL *Pool; - UINTN PageNumber; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS TempPtr; - - PageNumber = sizeof(USBHC_MEM_POOL)/PAGESIZE +1; - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - PageNumber, - &TempPtr - ); - - if (EFI_ERROR (Status)) { - return NULL; - } - ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE); - - Pool = (USBHC_MEM_POOL *) ((UINTN) TempPtr); - - Pool->Check4G = Check4G; - Pool->Which4G = Which4G; - Pool->Head = UsbHcAllocMemBlock (Ehc, Pool, USBHC_MEM_DEFAULT_PAGES); - - if (Pool->Head == NULL) { - Pool = NULL; - } - - return Pool; -} - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - - @retval EFI_DEVICE_ERROR Fail to free the memory pool. - @retval EFI_SUCCESS The memory pool is freed. - -**/ -EFI_STATUS -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT (Pool->Head != NULL); - - // - // Unlink all the memory blocks from the pool, then free them. - // UsbHcUnlinkMemBlock can't be used to unlink and free the - // first block. - // - for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) { - UsbHcFreeMemBlock (Pool, Block); - } - - UsbHcFreeMemBlock (Pool, Pool->Head); - - return EFI_SUCCESS; -} - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Ehc The EHCI device. - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN PEI_USB2_HC_DEV *Ehc, - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - USBHC_MEM_BLOCK *NewBlock; - VOID *Mem; - UINTN AllocSize; - UINTN Pages; - - Mem = NULL; - AllocSize = USBHC_MEM_ROUND (Size); - Head = Pool->Head; - ASSERT (Head != NULL); - - // - // First check whether current memory blocks can satisfy the allocation. - // - for (Block = Head; Block != NULL; Block = Block->Next) { - Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - break; - } - } - - if (Mem != NULL) { - return Mem; - } - - // - // Create a new memory block if there is not enough memory - // in the pool. If the allocation size is larger than the - // default page number, just allocate a large enough memory - // block. Otherwise allocate default pages. - // - if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) { - Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1; - } else { - Pages = USBHC_MEM_DEFAULT_PAGES; - } - NewBlock = UsbHcAllocMemBlock (Ehc,Pool, Pages); - - if (NewBlock == NULL) { - return NULL; - } - - // - // Add the new memory block to the pool, then allocate memory from it - // - UsbHcInsertMemBlockToPool (Head, NewBlock); - Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - } - - return Mem; -} - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINT8 *ToFree; - UINTN AllocSize; - UINTN Byte; - UINTN Bit; - UINTN Count; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - ToFree = (UINT8 *) Mem; - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the memory to free. - // - if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) { - // - // compute the start byte and bit in the bit array - // - Byte = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) / 8; - Bit = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) % 8; - - // - // reset associated bits in bit arry - // - for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) { - ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - break; - } - } - - // - // If Block == NULL, it means that the current memory isn't - // in the host controller's pool. This is critical because - // the caller has passed in a wrong memory point - // - ASSERT (Block != NULL); - - // - // Release the current memory block if it is empty and not the head - // - if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) { - UsbHcFreeMemBlock (Pool, Block); - } - - return ; -} diff --git a/MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.h b/MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.h deleted file mode 100644 index 586d12af96..0000000000 --- a/MdeModulePkg/Bus/Pci/EhciPei/UsbHcMem.h +++ /dev/null @@ -1,77 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2010, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_MEM_H_ -#define _EFI_EHCI_MEM_H_ - -#include -#include - -#define USB_HC_BIT(a) ((UINTN)(1 << (a))) - -#define USB_HC_BIT_IS_SET(Data, Bit) \ - ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit))) - -#define USB_HC_HIGH_32BIT(Addr64) \ - ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF)) - -typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK; - -struct _USBHC_MEM_BLOCK { - UINT8 *Bits; // Bit array to record which unit is allocated - UINTN BitsLen; - UINT8 *Buf; - UINT8 *BufHost; - UINTN BufLen; // Memory size in bytes - VOID *Mapping; - USBHC_MEM_BLOCK *Next; -}; - -// -// USBHC_MEM_POOL is used to manage the memory used by USB -// host controller. EHCI requires the control memory and transfer -// data to be on the same 4G memory. -// -typedef struct _USBHC_MEM_POOL { - BOOLEAN Check4G; - UINT32 Which4G; - USBHC_MEM_BLOCK *Head; -} USBHC_MEM_POOL; - -// -// Memory allocation unit, must be 2^n, n>4 -// -#define USBHC_MEM_UNIT 64 - -#define USBHC_MEM_UNIT_MASK (USBHC_MEM_UNIT - 1) -#define USBHC_MEM_DEFAULT_PAGES 16 - -#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK)) - -// -// Advance the byte and bit to the next bit, adjust byte accordingly. -// -#define NEXT_BIT(Byte, Bit) \ - do { \ - (Bit)++; \ - if ((Bit) > 7) { \ - (Byte)++; \ - (Bit) = 0; \ - } \ - } while (0) - - -#endif diff --git a/MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.c b/MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.c deleted file mode 100644 index be1b829200..0000000000 --- a/MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.c +++ /dev/null @@ -1,2501 +0,0 @@ -/** @file -PEIM to produce gEfiPeiVirtualBlockIoPpiGuid & gEfiPeiVirtualBlockIo2PpiGuid PPI for -ATA controllers in the platform. - -This PPI can be consumed by PEIM which produce gEfiPeiDeviceRecoveryModulePpiGuid -for Atapi CD ROM device. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "AtapiPeim.h" - -/** - Initializes the Atapi Block Io PPI. - - @param[in] FileHandle Handle of the file being invoked. - @param[in] PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCCESS Operation performed successfully. - @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate. - -**/ -EFI_STATUS -EFIAPI -AtapiPeimEntry ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - PEI_ATA_CONTROLLER_PPI *AtaControllerPpi; - EFI_STATUS Status; - ATAPI_BLK_IO_DEV *AtapiBlkIoDev; - - Status = PeiServicesRegisterForShadow (FileHandle); - if (!EFI_ERROR (Status)) { - return Status; - } - - Status = PeiServicesLocatePpi ( - &gPeiAtaControllerPpiGuid, - 0, - NULL, - (VOID **) &AtaControllerPpi - ); - ASSERT_EFI_ERROR (Status); - - AtapiBlkIoDev = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*AtapiBlkIoDev))); - if (AtapiBlkIoDev == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - AtapiBlkIoDev->Signature = ATAPI_BLK_IO_DEV_SIGNATURE; - AtapiBlkIoDev->AtaControllerPpi = AtaControllerPpi; - - // - // atapi device enumeration and build private data - // - AtapiEnumerateDevices (AtapiBlkIoDev); - - AtapiBlkIoDev->AtapiBlkIo.GetNumberOfBlockDevices = AtapiGetNumberOfBlockDevices; - AtapiBlkIoDev->AtapiBlkIo.GetBlockDeviceMediaInfo = AtapiGetBlockDeviceMediaInfo; - AtapiBlkIoDev->AtapiBlkIo.ReadBlocks = AtapiReadBlocks; - AtapiBlkIoDev->AtapiBlkIo2.Revision = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION; - AtapiBlkIoDev->AtapiBlkIo2.GetNumberOfBlockDevices = AtapiGetNumberOfBlockDevices2; - AtapiBlkIoDev->AtapiBlkIo2.GetBlockDeviceMediaInfo = AtapiGetBlockDeviceMediaInfo2; - AtapiBlkIoDev->AtapiBlkIo2.ReadBlocks = AtapiReadBlocks2; - - AtapiBlkIoDev->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI; - AtapiBlkIoDev->PpiDescriptor.Guid = &gEfiPeiVirtualBlockIoPpiGuid; - AtapiBlkIoDev->PpiDescriptor.Ppi = &AtapiBlkIoDev->AtapiBlkIo; - - AtapiBlkIoDev->PpiDescriptor2.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); - AtapiBlkIoDev->PpiDescriptor2.Guid = &gEfiPeiVirtualBlockIo2PpiGuid; - AtapiBlkIoDev->PpiDescriptor2.Ppi = &AtapiBlkIoDev->AtapiBlkIo2; - - DEBUG ((EFI_D_INFO, "Atatpi Device Count is %d\n", AtapiBlkIoDev->DeviceCount)); - if (AtapiBlkIoDev->DeviceCount != 0) { - Status = PeiServicesInstallPpi (&AtapiBlkIoDev->PpiDescriptor); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - } - - return EFI_SUCCESS; -} - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS Operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -AtapiGetNumberOfBlockDevices ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - OUT UINTN *NumberBlockDevices - ) -{ - ATAPI_BLK_IO_DEV *AtapiBlkIoDev; - - AtapiBlkIoDev = NULL; - - AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This); - - *NumberBlockDevices = AtapiBlkIoDev->DeviceCount; - - return EFI_SUCCESS; -} - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - @retval Others Other failure occurs. - -**/ -EFI_STATUS -EFIAPI -AtapiGetBlockDeviceMediaInfo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo - ) -{ - UINTN DeviceCount; - ATAPI_BLK_IO_DEV *AtapiBlkIoDev; - EFI_STATUS Status; - UINTN Index; - - AtapiBlkIoDev = NULL; - - if (This == NULL || MediaInfo == NULL) { - return EFI_INVALID_PARAMETER; - } - - AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This); - - DeviceCount = AtapiBlkIoDev->DeviceCount; - - // - // DeviceIndex is a value from 1 to NumberBlockDevices. - // - if ((DeviceIndex < 1) || (DeviceIndex > DeviceCount) || (DeviceIndex > MAX_IDE_DEVICES)) { - return EFI_INVALID_PARAMETER; - } - - Index = DeviceIndex - 1; - - // - // probe media and retrieve latest media information - // - DEBUG ((EFI_D_INFO, "Atatpi GetInfo DevicePosition is %d\n", AtapiBlkIoDev->DeviceInfo[Index].DevicePosition)); - DEBUG ((EFI_D_INFO, "Atatpi GetInfo DeviceType is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.DeviceType)); - DEBUG ((EFI_D_INFO, "Atatpi GetInfo MediaPresent is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.MediaPresent)); - DEBUG ((EFI_D_INFO, "Atatpi GetInfo BlockSize is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.BlockSize)); - DEBUG ((EFI_D_INFO, "Atatpi GetInfo LastBlock is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.LastBlock)); - - Status = DetectMedia ( - AtapiBlkIoDev, - AtapiBlkIoDev->DeviceInfo[Index].DevicePosition, - &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo, - &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo2 - ); - if (Status != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - - DEBUG ((EFI_D_INFO, "Atatpi GetInfo DevicePosition is %d\n", AtapiBlkIoDev->DeviceInfo[Index].DevicePosition)); - DEBUG ((EFI_D_INFO, "Atatpi GetInfo DeviceType is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.DeviceType)); - DEBUG ((EFI_D_INFO, "Atatpi GetInfo MediaPresent is %d\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.MediaPresent)); - DEBUG ((EFI_D_INFO, "Atatpi GetInfo BlockSize is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.BlockSize)); - DEBUG ((EFI_D_INFO, "Atatpi GetInfo LastBlock is 0x%x\n", AtapiBlkIoDev->DeviceInfo[Index].MediaInfo.LastBlock)); - - // - // Get media info from AtapiBlkIoDev - // - CopyMem (MediaInfo, &AtapiBlkIoDev->DeviceInfo[Index].MediaInfo, sizeof(EFI_PEI_BLOCK_IO_MEDIA)); - - return EFI_SUCCESS; -} - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -AtapiReadBlocks ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - - EFI_PEI_BLOCK_IO_MEDIA MediaInfo; - EFI_STATUS Status; - UINTN NumberOfBlocks; - UINTN BlockSize; - ATAPI_BLK_IO_DEV *AtapiBlkIoDev; - - AtapiBlkIoDev = NULL; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS (This); - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - Status = AtapiGetBlockDeviceMediaInfo ( - PeiServices, - This, - DeviceIndex, - &MediaInfo - ); - if (Status != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - - if (!MediaInfo.MediaPresent) { - return EFI_NO_MEDIA; - } - - BlockSize = MediaInfo.BlockSize; - - if (BufferSize % BlockSize != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - - if ((StartLBA + NumberOfBlocks - 1) > AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].MediaInfo2.LastBlock) { - return EFI_INVALID_PARAMETER; - } - - Status = ReadSectors ( - AtapiBlkIoDev, - AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].DevicePosition, - Buffer, - StartLBA, - NumberOfBlocks, - BlockSize - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS Operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -AtapiGetNumberOfBlockDevices2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - OUT UINTN *NumberBlockDevices - ) -{ - EFI_STATUS Status; - ATAPI_BLK_IO_DEV *AtapiBlkIoDev; - - AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This); - - Status = AtapiGetNumberOfBlockDevices ( - PeiServices, - &AtapiBlkIoDev->AtapiBlkIo, - NumberBlockDevices - ); - - return Status; -} - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - @retval Others Other failure occurs. - -**/ -EFI_STATUS -EFIAPI -AtapiGetBlockDeviceMediaInfo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo - ) -{ - ATAPI_BLK_IO_DEV *AtapiBlkIoDev; - EFI_STATUS Status; - EFI_PEI_BLOCK_IO_MEDIA Media; - - AtapiBlkIoDev = NULL; - - if (This == NULL || MediaInfo == NULL) { - return EFI_INVALID_PARAMETER; - } - - AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This); - - Status = AtapiGetBlockDeviceMediaInfo ( - PeiServices, - &AtapiBlkIoDev->AtapiBlkIo, - DeviceIndex, - &Media - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Get media info from AtapiBlkIoDev - // - CopyMem (MediaInfo, &AtapiBlkIoDev->DeviceInfo[DeviceIndex - 1].MediaInfo2, sizeof(EFI_PEI_BLOCK_IO2_MEDIA)); - - return EFI_SUCCESS; -} - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -AtapiReadBlocks2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - ATAPI_BLK_IO_DEV *AtapiBlkIoDev; - - AtapiBlkIoDev = NULL; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - AtapiBlkIoDev = PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS (This); - - Status = AtapiReadBlocks ( - PeiServices, - &AtapiBlkIoDev->AtapiBlkIo, - DeviceIndex, - StartLBA, - BufferSize, - Buffer - ); - - return Status; -} - - -/** - Enumerate Atapi devices. - - This function is used to enumerate Atatpi device in Ide channel. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device - -**/ -VOID -AtapiEnumerateDevices ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev - ) -{ - UINT8 Index1; - UINT8 Index2; - UINTN DevicePosition; - EFI_PEI_BLOCK_IO_MEDIA MediaInfo; - EFI_PEI_BLOCK_IO2_MEDIA MediaInfo2; - EFI_STATUS Status; - UINTN DeviceCount; - UINT16 CommandBlockBaseAddr; - UINT16 ControlBlockBaseAddr; - UINT32 IdeEnabledNumber; - IDE_REGS_BASE_ADDR IdeRegsBaseAddr[MAX_IDE_CHANNELS]; - - DeviceCount = 0; - DevicePosition = 0; - - // - // Scan IDE bus for ATAPI devices - // - - // - // Enable Sata and IDE controller. - // - AtapiBlkIoDev->AtaControllerPpi->EnableAtaChannel ( - (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(), - AtapiBlkIoDev->AtaControllerPpi, - PEI_ICH_IDE_PRIMARY | PEI_ICH_IDE_SECONDARY - ); - - // - // Allow SATA Devices to spin-up. This is needed if - // SEC and PEI phase is too short, for example Release Build. - // - DEBUG ((EFI_D_INFO, "Delay for %d seconds for SATA devices to spin-up\n", PcdGet16 (PcdSataSpinUpDelayInSecForRecoveryPath))); - MicroSecondDelay (PcdGet16 (PcdSataSpinUpDelayInSecForRecoveryPath) * 1000 * 1000); // - - // - // Get four channels (primary or secondary Pata, Sata Channel) Command and Control Regs Base address. - // - IdeEnabledNumber = AtapiBlkIoDev->AtaControllerPpi->GetIdeRegsBaseAddr ( - (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(), - AtapiBlkIoDev->AtaControllerPpi, - IdeRegsBaseAddr - ); - - // - // Using Command and Control Regs Base Address to fill other registers. - // - for (Index1 = 0; Index1 < IdeEnabledNumber; Index1 ++) { - CommandBlockBaseAddr = IdeRegsBaseAddr[Index1].CommandBlockBaseAddr; - AtapiBlkIoDev->IdeIoPortReg[Index1].Data = CommandBlockBaseAddr; - AtapiBlkIoDev->IdeIoPortReg[Index1].Reg1.Feature = (UINT16) (CommandBlockBaseAddr + 0x1); - AtapiBlkIoDev->IdeIoPortReg[Index1].SectorCount = (UINT16) (CommandBlockBaseAddr + 0x2); - AtapiBlkIoDev->IdeIoPortReg[Index1].SectorNumber = (UINT16) (CommandBlockBaseAddr + 0x3); - AtapiBlkIoDev->IdeIoPortReg[Index1].CylinderLsb = (UINT16) (CommandBlockBaseAddr + 0x4); - AtapiBlkIoDev->IdeIoPortReg[Index1].CylinderMsb = (UINT16) (CommandBlockBaseAddr + 0x5); - AtapiBlkIoDev->IdeIoPortReg[Index1].Head = (UINT16) (CommandBlockBaseAddr + 0x6); - AtapiBlkIoDev->IdeIoPortReg[Index1].Reg.Command = (UINT16) (CommandBlockBaseAddr + 0x7); - - ControlBlockBaseAddr = IdeRegsBaseAddr[Index1].ControlBlockBaseAddr; - AtapiBlkIoDev->IdeIoPortReg[Index1].Alt.DeviceControl = ControlBlockBaseAddr; - AtapiBlkIoDev->IdeIoPortReg[Index1].DriveAddress = (UINT16) (ControlBlockBaseAddr + 0x1); - - // - // Scan IDE bus for ATAPI devices IDE or Sata device - // - for (Index2 = IdeMaster; Index2 < IdeMaxDevice; Index2++) { - // - // Pata & Sata, Primary & Secondary channel, Master & Slave device - // - DevicePosition = (UINTN) (Index1 * 2 + Index2); - - if (DiscoverAtapiDevice (AtapiBlkIoDev, DevicePosition, &MediaInfo, &MediaInfo2)) { - // - // ATAPI Device at DevicePosition is found. - // - AtapiBlkIoDev->DeviceInfo[DeviceCount].DevicePosition = DevicePosition; - // - // Retrieve Media Info - // - Status = DetectMedia (AtapiBlkIoDev, DevicePosition, &MediaInfo, &MediaInfo2); - CopyMem (&(AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo), &MediaInfo, sizeof (MediaInfo)); - CopyMem (&(AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2), &MediaInfo2, sizeof (MediaInfo2)); - - DEBUG ((EFI_D_INFO, "Atatpi Device Position is %d\n", DevicePosition)); - DEBUG ((EFI_D_INFO, "Atatpi DeviceType is %d\n", MediaInfo.DeviceType)); - DEBUG ((EFI_D_INFO, "Atatpi MediaPresent is %d\n", MediaInfo.MediaPresent)); - DEBUG ((EFI_D_INFO, "Atatpi BlockSize is 0x%x\n", MediaInfo.BlockSize)); - - if (EFI_ERROR (Status)) { - AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo.MediaPresent = FALSE; - AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo.LastBlock = 0; - AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2.MediaPresent = FALSE; - AtapiBlkIoDev->DeviceInfo[DeviceCount].MediaInfo2.LastBlock = 0; - } - DeviceCount += 1; - } - } - } - - AtapiBlkIoDev->DeviceCount = DeviceCount; -} - -/** - Detect Atapi devices. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[out] MediaInfo The media information of the specified block media. - @param[out] MediaInfo2 The media information 2 of the specified block media. - - @retval TRUE Atapi device exists in specified position. - @retval FALSE Atapi device does not exist in specified position. - -**/ -BOOLEAN -DiscoverAtapiDevice ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 - ) -{ - EFI_STATUS Status; - - if (!DetectIDEController (AtapiBlkIoDev, DevicePosition)) { - return FALSE; - } - // - // test if it is an ATAPI device (only supported device) - // - if (ATAPIIdentify (AtapiBlkIoDev, DevicePosition) == EFI_SUCCESS) { - - Status = Inquiry (AtapiBlkIoDev, DevicePosition, MediaInfo, MediaInfo2); - if (!EFI_ERROR (Status)) { - return TRUE; - } - } - - return FALSE; -} - -/** - Check power mode of Atapi devices. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] AtaCommand The Ata Command passed in. - - @retval EFI_SUCCESS The Atapi device support power mode. - @retval EFI_NOT_FOUND The Atapi device not found. - @retval EFI_TIMEOUT Atapi command transaction is time out. - @retval EFI_ABORTED Atapi command abort. - -**/ -EFI_STATUS -CheckPowerMode ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN UINT8 AtaCommand - ) -{ - UINT8 Channel; - UINT8 Device; - UINT16 StatusRegister; - UINT16 HeadRegister; - UINT16 CommandRegister; - UINT16 ErrorRegister; - UINT16 SectorCountRegister; - EFI_STATUS Status; - UINT8 StatusValue; - UINT8 ErrorValue; - UINT8 SectorCountValue; - - Channel = (UINT8) (DevicePosition / 2); - Device = (UINT8) (DevicePosition % 2); - - ASSERT (Channel < MAX_IDE_CHANNELS); - - StatusRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status; - HeadRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Head; - CommandRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command; - ErrorRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg1.Error; - SectorCountRegister = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorCount; - - // - // select device - // - IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0)); - - // - // refresh the SectorCount register - // - SectorCountValue = 0x55; - IoWrite8 (SectorCountRegister, SectorCountValue); - - // - // select device - // - IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0)); - - Status = DRDYReady (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 100); - - // - // select device - // - IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0)); - // - // send 'check power' commandd via Command Register - // - IoWrite8 (CommandRegister, AtaCommand); - - Status = WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 3000); - if (EFI_ERROR (Status)) { - return EFI_TIMEOUT; - } - - StatusValue = IoRead8 (StatusRegister); - - // - // command returned status is DRDY, indicating device supports the command, - // so device is present. - // - if ((StatusValue & ATA_STSREG_DRDY) == ATA_STSREG_DRDY) { - return EFI_SUCCESS; - } - - SectorCountValue = IoRead8 (SectorCountRegister); - - // - // command returned status is ERR & ABRT_ERR, indicating device does not support - // the command, so device is present. - // - if ((StatusValue & ATA_STSREG_ERR) == ATA_STSREG_ERR) { - ErrorValue = IoRead8 (ErrorRegister); - if ((ErrorValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } else { - // - // According to spec, no other error code is valid - // - return EFI_NOT_FOUND; - } - } - - if ((SectorCountValue == 0x00) || (SectorCountValue == 0x80) || (SectorCountValue == 0xff)) { - // - // Write SectorCount 0x55 but return valid state value. Maybe no device - // exists or some slow kind of ATAPI device exists. - // - IoWrite8 (HeadRegister, (UINT8) ((Device << 4) | 0xe0)); - - // - // write 0x55 and 0xaa to SectorCounter register, - // if the data could be written into the register, - // indicating the device is present, otherwise the device is not present. - // - SectorCountValue = 0x55; - IoWrite8 (SectorCountRegister, SectorCountValue); - MicroSecondDelay (10000); - - SectorCountValue = IoRead8 (SectorCountRegister); - if (SectorCountValue != 0x55) { - return EFI_NOT_FOUND; - } - // - // Send a "ATAPI TEST UNIT READY" command ... slow but accurate - // - Status = TestUnitReady (AtapiBlkIoDev, DevicePosition); - return Status; - } - - return EFI_NOT_FOUND; -} - -/** - Detect if an IDE controller exists in specified position. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - - @retval TRUE The Atapi device exists. - @retval FALSE The Atapi device does not present. - -**/ -BOOLEAN -DetectIDEController ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition - ) -{ - UINT8 Channel; - EFI_STATUS Status; - UINT8 AtaCommand; - - Channel = (UINT8) (DevicePosition / 2); - - ASSERT (Channel < MAX_IDE_CHANNELS); - // - // Wait 31 seconds for BSY clear - // - Status = WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000); - if (EFI_ERROR (Status)) { - return FALSE; - } - // - // Send 'check power' command for IDE device - // - AtaCommand = 0xE5; - Status = CheckPowerMode (AtapiBlkIoDev, DevicePosition, AtaCommand); - if ((Status == EFI_ABORTED) || (Status == EFI_SUCCESS)) { - return TRUE; - } - - return FALSE; -} - -/** - Wait specified time interval to poll for BSY bit clear in the Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS BSY bit is cleared in the specified time interval. - @retval EFI_TIMEOUT BSY bit is not cleared in the specified time interval. - -**/ -EFI_STATUS -WaitForBSYClear ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ) -{ - UINTN Delay; - UINT16 StatusRegister; - UINT8 StatusValue; - - StatusValue = 0; - - StatusRegister = IdeIoRegisters->Reg.Status; - - Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; - do { - StatusValue = IoRead8 (StatusRegister); - if ((StatusValue & ATA_STSREG_BSY) == 0x00) { - break; - } - MicroSecondDelay (250); - - Delay--; - - } while (Delay != 0); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - Wait specified time interval to poll for DRDY bit set in the Status register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRDY bit is set in the specified time interval. - @retval EFI_TIMEOUT DRDY bit is not set in the specified time interval. - -**/ -EFI_STATUS -DRDYReady ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ) -{ - UINTN Delay; - UINT16 StatusRegister; - UINT8 StatusValue; - UINT8 ErrValue; - - StatusValue = 0; - - StatusRegister = IdeIoRegisters->Reg.Status; - - Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; - do { - StatusValue = IoRead8 (StatusRegister); - // - // BSY == 0 , DRDY == 1 - // - if ((StatusValue & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) { - break; - } - - if ((StatusValue & (ATA_STSREG_ERR | ATA_STSREG_BSY)) == ATA_STSREG_ERR) { - ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); - if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - MicroSecondDelay (250); - - Delay--; - - } while (Delay != 0); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - Wait specified time interval to poll for DRQ bit clear in the Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRQ bit is cleared in the specified time interval. - @retval EFI_TIMEOUT DRQ bit is not cleared in the specified time interval. - -**/ -EFI_STATUS -DRQClear ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ) -{ - UINTN Delay; - UINT16 StatusRegister; - UINT8 StatusValue; - UINT8 ErrValue; - - StatusValue = 0; - - StatusRegister = IdeIoRegisters->Reg.Status; - - Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; - do { - - StatusValue = IoRead8 (StatusRegister); - - // - // wait for BSY == 0 and DRQ == 0 - // - if ((StatusValue & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) { - break; - } - - if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); - if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - MicroSecondDelay (250); - - Delay--; - } while (Delay != 0); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - Wait specified time interval to poll for DRQ bit clear in the Alternate Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRQ bit is cleared in the specified time interval. - @retval EFI_TIMEOUT DRQ bit is not cleared in the specified time interval. - -**/ -EFI_STATUS -DRQClear2 ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ) -{ - UINTN Delay; - UINT16 AltStatusRegister; - UINT8 AltStatusValue; - UINT8 ErrValue; - - AltStatusValue = 0; - - AltStatusRegister = IdeIoRegisters->Alt.AltStatus; - - Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; - do { - - AltStatusValue = IoRead8 (AltStatusRegister); - - // - // wait for BSY == 0 and DRQ == 0 - // - if ((AltStatusValue & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) { - break; - } - - if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); - if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - - MicroSecondDelay (250); - - Delay--; - } while (Delay != 0); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - Wait specified time interval to poll for DRQ bit set in the Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRQ bit is set in the specified time interval. - @retval EFI_TIMEOUT DRQ bit is not set in the specified time interval. - @retval EFI_ABORTED Operation Aborted. - -**/ -EFI_STATUS -DRQReady ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ) -{ - UINTN Delay; - UINT16 StatusRegister; - UINT8 StatusValue; - UINT8 ErrValue; - - StatusValue = 0; - ErrValue = 0; - - StatusRegister = IdeIoRegisters->Reg.Status; - - Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; - do { - // - // read Status Register will clear interrupt - // - StatusValue = IoRead8 (StatusRegister); - - // - // BSY==0,DRQ==1 - // - if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { - break; - } - - if ((StatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - - ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); - if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - MicroSecondDelay (250); - - Delay--; - } while (Delay != 0); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - Wait specified time interval to poll for DRQ bit set in the Alternate Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRQ bit is set in the specified time interval. - @retval EFI_TIMEOUT DRQ bit is not set in the specified time interval. - @retval EFI_ABORTED Operation Aborted. - -**/ -EFI_STATUS -DRQReady2 ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ) -{ - UINTN Delay; - UINT16 AltStatusRegister; - UINT8 AltStatusValue; - UINT8 ErrValue; - - AltStatusValue = 0; - - AltStatusRegister = IdeIoRegisters->Alt.AltStatus; - - Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1; - do { - - AltStatusValue = IoRead8 (AltStatusRegister); - - // - // BSY==0,DRQ==1 - // - if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { - break; - } - - if ((AltStatusValue & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) { - - ErrValue = IoRead8 (IdeIoRegisters->Reg1.Error); - if ((ErrValue & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) { - return EFI_ABORTED; - } - } - MicroSecondDelay (250); - - Delay--; - } while (Delay != 0); - - if (Delay == 0) { - return EFI_TIMEOUT; - } - - return EFI_SUCCESS; -} - -/** - Check if there is an error in Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] StatusReg The address to IDE IO registers. - - @retval EFI_SUCCESS Operation success. - @retval EFI_DEVICE_ERROR Device error. - -**/ -EFI_STATUS -CheckErrorStatus ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINT16 StatusReg - ) -{ - UINT8 StatusValue; - - StatusValue = IoRead8 (StatusReg); - - if ((StatusValue & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) { - - return EFI_SUCCESS; - } - - return EFI_DEVICE_ERROR; - -} - -/** - Idendify Atapi devices. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - - @retval EFI_SUCCESS Identify successfully. - @retval EFI_DEVICE_ERROR Device cannot be identified successfully. - -**/ -EFI_STATUS -ATAPIIdentify ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition - ) -{ - ATAPI_IDENTIFY_DATA AtapiIdentifyData; - UINT8 Channel; - UINT8 Device; - UINT16 StatusReg; - UINT16 HeadReg; - UINT16 CommandReg; - UINT16 DataReg; - UINT16 SectorCountReg; - UINT16 SectorNumberReg; - UINT16 CylinderLsbReg; - UINT16 CylinderMsbReg; - - UINT32 WordCount; - UINT32 Increment; - UINT32 Index; - UINT32 ByteCount; - UINT16 *Buffer16; - - EFI_STATUS Status; - - ByteCount = sizeof (AtapiIdentifyData); - Buffer16 = (UINT16 *) &AtapiIdentifyData; - - Channel = (UINT8) (DevicePosition / 2); - Device = (UINT8) (DevicePosition % 2); - - ASSERT (Channel < MAX_IDE_CHANNELS); - - StatusReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status; - HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head; - CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command; - DataReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Data; - SectorCountReg = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorCount; - SectorNumberReg = AtapiBlkIoDev->IdeIoPortReg[Channel].SectorNumber; - CylinderLsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderLsb; - CylinderMsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderMsb; - - // - // Send ATAPI Identify Command to get IDENTIFY data. - // - if (WaitForBSYClear ( - AtapiBlkIoDev, - &(AtapiBlkIoDev->IdeIoPortReg[Channel]), - ATATIMEOUT - ) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - // - // select device via Head/Device register. - // Before write Head/Device register, BSY and DRQ must be 0. - // - if (DRQClear2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), ATATIMEOUT) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - // - // e0:1110,0000-- bit7 and bit5 are reserved bits. - // bit6 set means LBA mode - // - IoWrite8 (HeadReg, (UINT8) ((Device << 4) | 0xe0)); - - // - // set all the command parameters - // Before write to all the following registers, BSY and DRQ must be 0. - // - if (DRQClear2 ( - AtapiBlkIoDev, - &(AtapiBlkIoDev->IdeIoPortReg[Channel]), - ATATIMEOUT - ) != EFI_SUCCESS) { - - return EFI_DEVICE_ERROR; - } - - IoWrite8 (SectorCountReg, 0); - IoWrite8 (SectorNumberReg, 0); - IoWrite8 (CylinderLsbReg, 0); - IoWrite8 (CylinderMsbReg, 0); - - // - // send command via Command Register - // - IoWrite8 (CommandReg, ATA_CMD_IDENTIFY_DEVICE); - - // - // According to PIO data in protocol, host can perform a series of reads to the - // data register after each time device set DRQ ready; - // The data size of "a series of read" is command specific. - // For most ATA command, data size received from device will not exceed 1 sector, - // hense the data size for "a series of read" can be the whole data size of one command request. - // For ATA command such as Read Sector command, whole data size of one ATA command request is often larger - // than 1 sector, according to the Read Sector command, the data size of "a series of read" is exactly - // 1 sector. - // Here for simplification reason, we specify the data size for "a series of read" to - // 1 sector (256 words) if whole data size of one ATA commmand request is larger than 256 words. - // - Increment = 256; - // - // 256 words - // - WordCount = 0; - // - // WordCount is used to record bytes of currently transfered data - // - while (WordCount < ByteCount / 2) { - // - // Poll DRQ bit set, data transfer can be performed only when DRQ is ready. - // - Status = DRQReady2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), ATATIMEOUT); - if (Status != EFI_SUCCESS) { - return Status; - } - - if (CheckErrorStatus (AtapiBlkIoDev, StatusReg) != EFI_SUCCESS) { - - return EFI_DEVICE_ERROR; - } - // - // Get the byte count for one series of read - // - if ((WordCount + Increment) > ByteCount / 2) { - Increment = ByteCount / 2 - WordCount; - } - // - // perform a series of read without check DRQ ready - // - for (Index = 0; Index < Increment; Index++) { - *Buffer16++ = IoRead16 (DataReg); - } - - WordCount += Increment; - - } - // - // while - // - if (DRQClear ( - AtapiBlkIoDev, - &(AtapiBlkIoDev->IdeIoPortReg[Channel]), - ATATIMEOUT - ) != EFI_SUCCESS) { - return CheckErrorStatus (AtapiBlkIoDev, StatusReg); - } - - return EFI_SUCCESS; - -} - -/** - Sends out ATAPI Test Unit Ready Packet Command to the specified device - to find out whether device is accessible. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - - @retval EFI_SUCCESS TestUnit command executed successfully. - @retval EFI_DEVICE_ERROR Device cannot be executed TestUnit command successfully. - -**/ -EFI_STATUS -TestUnitReady ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition - ) -{ - ATAPI_PACKET_COMMAND Packet; - EFI_STATUS Status; - - // - // fill command packet - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY; - - // - // send command packet - // - Status = AtapiPacketCommandIn (AtapiBlkIoDev, DevicePosition, &Packet, NULL, 0, ATAPITIMEOUT); - return Status; -} - -/** - Send out ATAPI commands conforms to the Packet Command with PIO Data In Protocol. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] Packet A pointer to ATAPI command packet. - @param[in] Buffer Buffer to contain requested transfer data from device. - @param[in] ByteCount Requested transfer data length. - @param[in] TimeoutInMilliSeconds Time out value, in unit of milliseconds. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Device cannot be executed command successfully. - -**/ -EFI_STATUS -AtapiPacketCommandIn ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN ATAPI_PACKET_COMMAND *Packet, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN UINTN TimeoutInMilliSeconds - ) -{ - UINT8 Channel; - UINT8 Device; - UINT16 StatusReg; - UINT16 HeadReg; - UINT16 CommandReg; - UINT16 FeatureReg; - UINT16 CylinderLsbReg; - UINT16 CylinderMsbReg; - UINT16 DeviceControlReg; - UINT16 DataReg; - EFI_STATUS Status; - UINT32 Count; - UINT16 *CommandIndex; - UINT16 *PtrBuffer; - UINT32 Index; - UINT8 StatusValue; - UINT32 WordCount; - - // - // required transfer data in word unit. - // - UINT32 RequiredWordCount; - - // - // actual transfer data in word unit. - // - UINT32 ActualWordCount; - - Channel = (UINT8) (DevicePosition / 2); - Device = (UINT8) (DevicePosition % 2); - - ASSERT (Channel < MAX_IDE_CHANNELS); - - StatusReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Status; - HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head; - CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command; - FeatureReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg1.Feature; - CylinderLsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderLsb; - CylinderMsbReg = AtapiBlkIoDev->IdeIoPortReg[Channel].CylinderMsb; - DeviceControlReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Alt.DeviceControl; - DataReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Data; - - // - // Set all the command parameters by fill related registers. - // Before write to all the following registers, BSY and DRQ must be 0. - // - if (DRQClear2 ( - AtapiBlkIoDev, - &(AtapiBlkIoDev->IdeIoPortReg[Channel]), - ATATIMEOUT - ) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - // - // Select device via Device/Head Register. - // DEFAULT_CMD: 0xa0 (1010,0000) - // - IoWrite8 (HeadReg, (UINT8) ((Device << 4) | ATA_DEFAULT_CMD)); - - // - // No OVL; No DMA - // - IoWrite8 (FeatureReg, 0x00); - - // - // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device - // determine how many data should be transfered. - // - IoWrite8 (CylinderLsbReg, (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)); - IoWrite8 (CylinderMsbReg, (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)); - - // - // DEFAULT_CTL:0x0a (0000,1010) - // Disable interrupt - // - IoWrite8 (DeviceControlReg, ATA_DEFAULT_CTL); - - // - // Send Packet command to inform device - // that the following data bytes are command packet. - // - IoWrite8 (CommandReg, ATA_CMD_PACKET); - - Status = DRQReady (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), TimeoutInMilliSeconds); - if (Status != EFI_SUCCESS) { - return Status; - } - // - // Send out command packet - // - CommandIndex = Packet->Data16; - for (Count = 0; Count < 6; Count++, CommandIndex++) { - IoWrite16 (DataReg, *CommandIndex); - MicroSecondDelay (10); - } - - StatusValue = IoRead8 (StatusReg); - if ((StatusValue & ATA_STSREG_ERR) == ATA_STSREG_ERR) { - // - // Trouble! Something's wrong here... Wait some time and return. 3 second is - // supposed to be long enough for a device reset latency or error recovery - // - MicroSecondDelay (3000000); - return EFI_DEVICE_ERROR; - } - - if (Buffer == NULL || ByteCount == 0) { - return EFI_SUCCESS; - } - // - // call PioReadWriteData() function to get - // requested transfer data form device. - // - PtrBuffer = Buffer; - RequiredWordCount = ByteCount / 2; - // - // ActuralWordCount means the word count of data really transfered. - // - ActualWordCount = 0; - - Status = EFI_SUCCESS; - while ((Status == EFI_SUCCESS) && (ActualWordCount < RequiredWordCount)) { - // - // before each data transfer stream, the host should poll DRQ bit ready, - // which informs device is ready to transfer data. - // - if (DRQReady2 ( - AtapiBlkIoDev, - &(AtapiBlkIoDev->IdeIoPortReg[Channel]), - TimeoutInMilliSeconds - ) != EFI_SUCCESS) { - return CheckErrorStatus (AtapiBlkIoDev, StatusReg); - } - // - // read Status Register will clear interrupt - // - StatusValue = IoRead8 (StatusReg); - - // - // get current data transfer size from Cylinder Registers. - // - WordCount = IoRead8 (CylinderMsbReg) << 8; - WordCount = WordCount | IoRead8 (CylinderLsbReg); - WordCount = WordCount & 0xffff; - WordCount /= 2; - - // - // perform a series data In/Out. - // - for (Index = 0; (Index < WordCount) && (ActualWordCount < RequiredWordCount); Index++, ActualWordCount++) { - - *PtrBuffer = IoRead16 (DataReg); - - PtrBuffer++; - - } - - if (((ATAPI_REQUEST_SENSE_CMD *) Packet)->opcode == ATA_CMD_REQUEST_SENSE && ActualWordCount >= 4) { - RequiredWordCount = MIN ( - RequiredWordCount, - (UINT32) (4 + (((ATAPI_REQUEST_SENSE_DATA *) Buffer)->addnl_sense_length / 2)) - ); - } - - } - // - // After data transfer is completed, normally, DRQ bit should clear. - // - Status = DRQClear2 (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), TimeoutInMilliSeconds); - if (Status != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - // - // read status register to check whether error happens. - // - Status = CheckErrorStatus (AtapiBlkIoDev, StatusReg); - return Status; -} - -/** - Sends out ATAPI Inquiry Packet Command to the specified device. - This command will return INQUIRY data of the device. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[out] MediaInfo The media information of the specified block media. - @param[out] MediaInfo2 The media information 2 of the specified block media. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Device cannot be executed command successfully. - @retval EFI_UNSUPPORTED Unsupported device type. - -**/ -EFI_STATUS -Inquiry ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 - ) -{ - ATAPI_PACKET_COMMAND Packet; - EFI_STATUS Status; - ATAPI_INQUIRY_DATA Idata; - - // - // prepare command packet for the ATAPI Inquiry Packet Command. - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - ZeroMem (&Idata, sizeof (ATAPI_INQUIRY_DATA)); - - Packet.Inquiry.opcode = ATA_CMD_INQUIRY; - Packet.Inquiry.page_code = 0; - Packet.Inquiry.allocation_length = (UINT8) sizeof (ATAPI_INQUIRY_DATA); - - // - // Send command packet and get requested Inquiry data. - // - Status = AtapiPacketCommandIn ( - AtapiBlkIoDev, - DevicePosition, - &Packet, - (UINT16 *) (&Idata), - sizeof (ATAPI_INQUIRY_DATA), - ATAPITIMEOUT - //50 - ); - - if (Status != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - // - // Identify device type via INQUIRY data. - // - switch (Idata.peripheral_type & 0x1f) { - case 0x00: - // - // Magnetic Disk - // - MediaInfo->DeviceType = IdeLS120; - MediaInfo->MediaPresent = FALSE; - MediaInfo->LastBlock = 0; - MediaInfo->BlockSize = 0x200; - MediaInfo2->InterfaceType = MSG_ATAPI_DP; - MediaInfo2->RemovableMedia = TRUE; - MediaInfo2->MediaPresent = FALSE; - MediaInfo2->ReadOnly = FALSE; - MediaInfo2->BlockSize = 0x200; - MediaInfo2->LastBlock = 0; - break; - - case 0x05: - // - // CD-ROM - // - MediaInfo->DeviceType = IdeCDROM; - MediaInfo->MediaPresent = FALSE; - MediaInfo->LastBlock = 0; - MediaInfo->BlockSize = 0x800; - MediaInfo2->InterfaceType = MSG_ATAPI_DP; - MediaInfo2->RemovableMedia = TRUE; - MediaInfo2->MediaPresent = FALSE; - MediaInfo2->ReadOnly = TRUE; - MediaInfo2->BlockSize = 0x200; - MediaInfo2->LastBlock = 0; - break; - - default: - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -/** - Used before read/write blocks from/to ATAPI device media. - Since ATAPI device media is removable, it is necessary to detect - whether media is present and get current present media's information. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in, out] MediaInfo The media information of the specified block media. - @param[in, out] MediaInfo2 The media information 2 of the specified block media. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - @retval EFI_OUT_OF_RESOURCES Can not allocate required resources. - -**/ -EFI_STATUS -DetectMedia ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, - IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 - ) -{ - - UINTN Index; - UINTN RetryNum; - UINTN MaxRetryNum; - ATAPI_REQUEST_SENSE_DATA *SenseBuffers; - BOOLEAN NeedReadCapacity; - BOOLEAN NeedRetry; - EFI_STATUS Status; - UINT8 SenseCounts; - - SenseBuffers = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*SenseBuffers))); - if (SenseBuffers == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Test Unit Ready command is used to detect whether device is accessible, - // the device will produce corresponding Sense data. - // - for (Index = 0; Index < 2; Index++) { - - Status = TestUnitReady (AtapiBlkIoDev, DevicePosition); - if (Status != EFI_SUCCESS) { - Status = ResetDevice (AtapiBlkIoDev, DevicePosition, FALSE); - - if (Status != EFI_SUCCESS) { - ResetDevice (AtapiBlkIoDev, DevicePosition, TRUE); - } - - } else { - break; - } - } - - SenseCounts = MAX_SENSE_KEY_COUNT; - Status = EFI_SUCCESS; - NeedReadCapacity = TRUE; - - for (Index = 0; Index < 5; Index++) { - SenseCounts = MAX_SENSE_KEY_COUNT; - Status = RequestSense ( - AtapiBlkIoDev, - DevicePosition, - SenseBuffers, - &SenseCounts - ); - DEBUG ((EFI_D_INFO, "Atapi Request Sense Count is %d\n", SenseCounts)); - if (IsDeviceStateUnclear (SenseBuffers, SenseCounts) || IsNoMedia (SenseBuffers, SenseCounts)) { - // - // We are not sure whether the media is present or not, try again - // - TestUnitReady (AtapiBlkIoDev, DevicePosition); - } else { - break; - } - } - - if (Status == EFI_SUCCESS) { - - if (IsNoMedia (SenseBuffers, SenseCounts)) { - - NeedReadCapacity = FALSE; - MediaInfo->MediaPresent = FALSE; - MediaInfo->LastBlock = 0; - MediaInfo2->MediaPresent = FALSE; - MediaInfo2->LastBlock = 0; - } - - if (IsMediaError (SenseBuffers, SenseCounts)) { - return EFI_DEVICE_ERROR; - } - } - - if (NeedReadCapacity) { - // - // at most retry 5 times - // - MaxRetryNum = 5; - RetryNum = 1; - // - // initial retry once - // - for (Index = 0; (Index < RetryNum) && (Index < MaxRetryNum); Index++) { - - Status = ReadCapacity (AtapiBlkIoDev, DevicePosition, MediaInfo, MediaInfo2); - MicroSecondDelay (200000); - SenseCounts = MAX_SENSE_KEY_COUNT; - - if (Status != EFI_SUCCESS) { - - Status = RequestSense (AtapiBlkIoDev, DevicePosition, SenseBuffers, &SenseCounts); - // - // If Request Sense data failed, reset the device and retry. - // - if (Status != EFI_SUCCESS) { - - Status = ResetDevice (AtapiBlkIoDev, DevicePosition, FALSE); - // - // if ATAPI soft reset fail, - // use stronger reset mechanism -- ATA soft reset. - // - if (Status != EFI_SUCCESS) { - ResetDevice (AtapiBlkIoDev, DevicePosition, TRUE); - } - - RetryNum++; - // - // retry once more - // - continue; - } - // - // No Media - // - if (IsNoMedia (SenseBuffers, SenseCounts)) { - - MediaInfo->MediaPresent = FALSE; - MediaInfo->LastBlock = 0; - MediaInfo2->MediaPresent = FALSE; - MediaInfo2->LastBlock = 0; - break; - } - - if (IsMediaError (SenseBuffers, SenseCounts)) { - return EFI_DEVICE_ERROR; - } - - if (!IsDriveReady (SenseBuffers, SenseCounts, &NeedRetry)) { - // - // Drive not ready: if NeedRetry, then retry once more; - // else return error - // - if (NeedRetry) { - RetryNum++; - continue; - } else { - return EFI_DEVICE_ERROR; - } - } - // - // if read capacity fail not for above reasons, retry once more - // - RetryNum++; - - } - - } - - } - - return EFI_SUCCESS; -} - -/** - Reset specified Atapi device. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] Extensive If TRUE, use ATA soft reset, otherwise use Atapi soft reset. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - -**/ -EFI_STATUS -ResetDevice ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN BOOLEAN Extensive - ) -{ - UINT8 DevControl; - UINT8 Command; - UINT8 DeviceSelect; - UINT16 DeviceControlReg; - UINT16 CommandReg; - UINT16 HeadReg; - UINT8 Channel; - UINT8 Device; - - Channel = (UINT8) (DevicePosition / 2); - Device = (UINT8) (DevicePosition % 2); - - ASSERT (Channel < MAX_IDE_CHANNELS); - - DeviceControlReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Alt.DeviceControl; - CommandReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Reg.Command; - HeadReg = AtapiBlkIoDev->IdeIoPortReg[Channel].Head; - - if (Extensive) { - - DevControl = 0; - DevControl |= ATA_CTLREG_SRST; - // - // set SRST bit to initiate soft reset - // - DevControl |= BIT1; - // - // disable Interrupt - // - IoWrite8 (DeviceControlReg, DevControl); - - // - // Wait 10us - // - MicroSecondDelay (10); - - // - // Clear SRST bit - // - DevControl &= 0xfb; - // - // 0xfb:1111,1011 - // - IoWrite8 (DeviceControlReg, DevControl); - - // - // slave device needs at most 31s to clear BSY - // - if (WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000) == EFI_TIMEOUT) { - return EFI_DEVICE_ERROR; - } - - } else { - // - // for ATAPI device, no need to wait DRDY ready after device selecting. - // bit7 and bit5 are both set to 1 for backward compatibility - // - DeviceSelect = (UINT8) (((BIT7 | BIT5) | (Device << 4))); - IoWrite8 (HeadReg, DeviceSelect); - - Command = ATA_CMD_SOFT_RESET; - IoWrite8 (CommandReg, Command); - - // - // BSY cleared is the only status return to the host by the device when reset is completed - // slave device needs at most 31s to clear BSY - // - if (WaitForBSYClear (AtapiBlkIoDev, &(AtapiBlkIoDev->IdeIoPortReg[Channel]), 31000) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - // - // stall 5 seconds to make the device status stable - // - MicroSecondDelay (STALL_1_SECONDS * 5); - } - - return EFI_SUCCESS; - -} - -/** - Sends out ATAPI Request Sense Packet Command to the specified device. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] SenseBuffers Pointer to sense buffer. - @param[in, out] SenseCounts Length of sense buffer. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - -**/ -EFI_STATUS -RequestSense ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN ATAPI_REQUEST_SENSE_DATA *SenseBuffers, - IN OUT UINT8 *SenseCounts - ) -{ - EFI_STATUS Status; - ATAPI_REQUEST_SENSE_DATA *Sense; - UINT16 *Ptr; - BOOLEAN SenseReq; - ATAPI_PACKET_COMMAND Packet; - - ZeroMem (SenseBuffers, sizeof (ATAPI_REQUEST_SENSE_DATA) * (*SenseCounts)); - // - // fill command packet for Request Sense Packet Command - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE; - Packet.RequestSence.allocation_length = (UINT8) sizeof (ATAPI_REQUEST_SENSE_DATA); - - Ptr = (UINT16 *) SenseBuffers; - // - // initialize pointer - // - *SenseCounts = 0; - // - // request sense data from device continiously until no sense data exists in the device. - // - for (SenseReq = TRUE; SenseReq;) { - - Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr; - - // - // send out Request Sense Packet Command and get one Sense data form device - // - Status = AtapiPacketCommandIn ( - AtapiBlkIoDev, - DevicePosition, - &Packet, - Ptr, - sizeof (ATAPI_REQUEST_SENSE_DATA), - ATAPITIMEOUT - ); - // - // failed to get Sense data - // - if (Status != EFI_SUCCESS) { - if (*SenseCounts == 0) { - return EFI_DEVICE_ERROR; - } else { - return EFI_SUCCESS; - } - } - - (*SenseCounts)++; - - if (*SenseCounts > MAX_SENSE_KEY_COUNT) { - return EFI_SUCCESS; - } - // - // We limit MAX sense data count to 20 in order to avoid dead loop. Some - // incompatible ATAPI devices don't retrive NO_SENSE when there is no media. - // In this case, dead loop occurs if we don't have a gatekeeper. 20 is - // supposed to be large enough for any ATAPI device. - // - if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) { - - Ptr += sizeof (ATAPI_REQUEST_SENSE_DATA) / 2; - // - // Ptr is word based pointer - // - } else { - // - // when no sense key, skip out the loop - // - SenseReq = FALSE; - } - } - - return EFI_SUCCESS; -} - -/** - Sends out ATAPI Read Capacity Packet Command to the specified device. - This command will return the information regarding the capacity of the - media in the device. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in, out] MediaInfo The media information of the specified block media. - @param[in, out] MediaInfo2 The media information 2 of the specified block media. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - -**/ -EFI_STATUS -ReadCapacity ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, - IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 - ) -{ - EFI_STATUS Status; - ATAPI_PACKET_COMMAND Packet; - - // - // used for capacity data returned from ATAPI device - // - ATAPI_READ_CAPACITY_DATA Data; - ATAPI_READ_FORMAT_CAPACITY_DATA FormatData; - - ZeroMem (&Data, sizeof (Data)); - ZeroMem (&FormatData, sizeof (FormatData)); - - if (MediaInfo->DeviceType == IdeCDROM) { - - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY; - Status = AtapiPacketCommandIn ( - AtapiBlkIoDev, - DevicePosition, - &Packet, - (UINT16 *) (&Data), - sizeof (ATAPI_READ_CAPACITY_DATA), - ATAPITIMEOUT - ); - - } else { - // - // DeviceType == IdeLS120 - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY; - Packet.ReadFormatCapacity.allocation_length_lo = 12; - Status = AtapiPacketCommandIn ( - AtapiBlkIoDev, - DevicePosition, - &Packet, - (UINT16 *) (&FormatData), - sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA), - ATAPITIMEOUT*10 - ); - } - - if (Status == EFI_SUCCESS) { - - if (MediaInfo->DeviceType == IdeCDROM) { - - MediaInfo->LastBlock = (Data.LastLba3 << 24) | (Data.LastLba2 << 16) | (Data.LastLba1 << 8) | Data.LastLba0; - MediaInfo->MediaPresent = TRUE; - // - // Because the user data portion in the sector of the Data CD supported - // is always 800h - // - MediaInfo->BlockSize = 0x800; - - MediaInfo2->LastBlock = MediaInfo->LastBlock; - MediaInfo2->MediaPresent = MediaInfo->MediaPresent; - MediaInfo2->BlockSize = (UINT32)MediaInfo->BlockSize; - } - - if (MediaInfo->DeviceType == IdeLS120) { - - if (FormatData.DesCode == 3) { - MediaInfo->MediaPresent = FALSE; - MediaInfo->LastBlock = 0; - MediaInfo2->MediaPresent = FALSE; - MediaInfo2->LastBlock = 0; - } else { - MediaInfo->LastBlock = (FormatData.LastLba3 << 24) | - (FormatData.LastLba2 << 16) | - (FormatData.LastLba1 << 8) | - FormatData.LastLba0; - MediaInfo->LastBlock--; - - MediaInfo->MediaPresent = TRUE; - - MediaInfo->BlockSize = 0x200; - - MediaInfo2->LastBlock = MediaInfo->LastBlock; - MediaInfo2->MediaPresent = MediaInfo->MediaPresent; - MediaInfo2->BlockSize = (UINT32)MediaInfo->BlockSize; - - } - } - - return EFI_SUCCESS; - - } else { - return EFI_DEVICE_ERROR; - } -} - -/** - Perform read from disk in block unit. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] Buffer Buffer to contain read data. - @param[in] StartLba Starting LBA address. - @param[in] NumberOfBlocks Number of blocks to read. - @param[in] BlockSize Size of each block. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - -**/ -EFI_STATUS -ReadSectors ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN VOID *Buffer, - IN EFI_PEI_LBA StartLba, - IN UINTN NumberOfBlocks, - IN UINTN BlockSize - ) -{ - - ATAPI_PACKET_COMMAND Packet; - ATAPI_READ10_CMD *Read10Packet; - EFI_STATUS Status; - UINTN BlocksRemaining; - UINT32 Lba32; - UINT32 ByteCount; - UINT16 SectorCount; - VOID *PtrBuffer; - UINT16 MaxBlock; - - // - // fill command packet for Read(10) command - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Read10Packet = &Packet.Read10; - Lba32 = (UINT32) StartLba; - PtrBuffer = Buffer; - - // - // limit the data bytes that can be transfered by one Read(10) Command - // - MaxBlock = (UINT16) (0x10000 / BlockSize); - // - // (64k bytes) - // - BlocksRemaining = NumberOfBlocks; - - Status = EFI_SUCCESS; - while (BlocksRemaining > 0) { - - if (BlocksRemaining <= MaxBlock) { - SectorCount = (UINT16) BlocksRemaining; - } else { - SectorCount = MaxBlock; - } - // - // fill the Packet data sturcture - // - Read10Packet->opcode = ATA_CMD_READ_10; - - // - // Lba0 ~ Lba3 specify the start logical block address of the data transfer. - // Lba0 is MSB, Lba3 is LSB - // - Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff); - Read10Packet->Lba2 = (UINT8) (Lba32 >> 8); - Read10Packet->Lba1 = (UINT8) (Lba32 >> 16); - Read10Packet->Lba0 = (UINT8) (Lba32 >> 24); - - // - // TranLen0 ~ TranLen1 specify the transfer length in block unit. - // TranLen0 is MSB, TranLen is LSB - // - Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff); - Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8); - - ByteCount = (UINT32) (SectorCount * BlockSize); - - Status = AtapiPacketCommandIn ( - AtapiBlkIoDev, - DevicePosition, - &Packet, - (UINT16 *) PtrBuffer, - ByteCount, - ATAPILONGTIMEOUT - ); - if (Status != EFI_SUCCESS) { - return Status; - } - - Lba32 += SectorCount; - PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize; - BlocksRemaining -= SectorCount; - } - - return Status; -} - -/** - Check if there is media according to sense data. - - @param[in] SenseData Pointer to sense data. - @param[in] SenseCounts Count of sense data. - - @retval TRUE No media - @retval FALSE Media exists - -**/ -BOOLEAN -IsNoMedia ( - IN ATAPI_REQUEST_SENSE_DATA *SenseData, - IN UINTN SenseCounts - ) -{ - ATAPI_REQUEST_SENSE_DATA *SensePtr; - UINTN Index; - BOOLEAN IsNoMedia; - - IsNoMedia = FALSE; - - SensePtr = SenseData; - - for (Index = 0; Index < SenseCounts; Index++) { - - if ((SensePtr->sense_key == ATA_SK_NOT_READY) && (SensePtr->addnl_sense_code == ATA_ASC_NO_MEDIA)) { - IsNoMedia = TRUE; - } - - SensePtr++; - } - - return IsNoMedia; -} - -/** - Check if device state is unclear according to sense data. - - @param[in] SenseData Pointer to sense data. - @param[in] SenseCounts Count of sense data. - - @retval TRUE Device state is unclear - @retval FALSE Device state is clear - -**/ -BOOLEAN -IsDeviceStateUnclear ( - IN ATAPI_REQUEST_SENSE_DATA *SenseData, - IN UINTN SenseCounts - ) -{ - ATAPI_REQUEST_SENSE_DATA *SensePtr; - UINTN Index; - BOOLEAN Unclear; - - Unclear = FALSE; - - SensePtr = SenseData; - - for (Index = 0; Index < SenseCounts; Index++) { - - if (SensePtr->sense_key == 0x06) { - // - // Sense key is 0x06 means the device is just be reset or media just - // changed. The current state of the device is unclear. - // - Unclear = TRUE; - break; - } - - SensePtr++; - } - - return Unclear; -} - -/** - Check if there is media error according to sense data. - - @param[in] SenseData Pointer to sense data. - @param[in] SenseCounts Count of sense data. - - @retval TRUE Media error - @retval FALSE No media error - -**/ -BOOLEAN -IsMediaError ( - IN ATAPI_REQUEST_SENSE_DATA *SenseData, - IN UINTN SenseCounts - ) -{ - ATAPI_REQUEST_SENSE_DATA *SensePtr; - UINTN Index; - BOOLEAN IsError; - - IsError = FALSE; - - SensePtr = SenseData; - - for (Index = 0; Index < SenseCounts; Index++) { - - switch (SensePtr->sense_key) { - - case ATA_SK_MEDIUM_ERROR: - switch (SensePtr->addnl_sense_code) { - case ATA_ASC_MEDIA_ERR1: - // - // fall through - // - case ATA_ASC_MEDIA_ERR2: - // - // fall through - // - case ATA_ASC_MEDIA_ERR3: - // - // fall through - // - case ATA_ASC_MEDIA_ERR4: - IsError = TRUE; - break; - - default: - break; - } - - break; - - case ATA_SK_NOT_READY: - switch (SensePtr->addnl_sense_code) { - case ATA_ASC_MEDIA_UPSIDE_DOWN: - IsError = TRUE; - break; - - default: - break; - } - break; - - default: - break; - } - - SensePtr++; - } - - return IsError; -} - -/** - Check if drive is ready according to sense data. - - @param[in] SenseData Pointer to sense data. - @param[in] SenseCounts Count of sense data. - @param[out] NeedRetry Indicate if retry is needed. - - @retval TRUE Drive ready - @retval FALSE Drive not ready - -**/ -BOOLEAN -IsDriveReady ( - IN ATAPI_REQUEST_SENSE_DATA *SenseData, - IN UINTN SenseCounts, - OUT BOOLEAN *NeedRetry - ) -{ - ATAPI_REQUEST_SENSE_DATA *SensePtr; - UINTN Index; - BOOLEAN IsReady; - - IsReady = TRUE; - *NeedRetry = FALSE; - - SensePtr = SenseData; - - for (Index = 0; Index < SenseCounts; Index++) { - - switch (SensePtr->sense_key) { - - case ATA_SK_NOT_READY: - switch (SensePtr->addnl_sense_code) { - case ATA_ASC_NOT_READY: - switch (SensePtr->addnl_sense_code_qualifier) { - case ATA_ASCQ_IN_PROGRESS: - IsReady = FALSE; - *NeedRetry = TRUE; - break; - - default: - IsReady = FALSE; - *NeedRetry = FALSE; - break; - } - break; - - default: - break; - } - break; - - default: - break; - } - - SensePtr++; - } - - return IsReady; -} diff --git a/MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.h b/MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.h deleted file mode 100644 index 20b35c4afd..0000000000 --- a/MdeModulePkg/Bus/Pci/IdeBusPei/AtapiPeim.h +++ /dev/null @@ -1,789 +0,0 @@ -/** @file -Private Include file for IdeBus PEIM. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _RECOVERY_ATAPI_H_ -#define _RECOVERY_ATAPI_H_ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include - -#define MAX_SENSE_KEY_COUNT 6 -#define MAX_IDE_CHANNELS 4 // Ide and Sata Primary, Secondary Channel. -#define MAX_IDE_DEVICES 8 // Ide, Sata Primary, Secondary and Master, Slave device. - -typedef enum { - IdePrimary = 0, - IdeSecondary = 1, - IdeMaxChannel = 2 -} EFI_IDE_CHANNEL; - -typedef enum { - IdeMaster = 0, - IdeSlave = 1, - IdeMaxDevice = 2 -} EFI_IDE_DEVICE; - -// -// IDE Registers -// -typedef union { - UINT16 Command; /* when write */ - UINT16 Status; /* when read */ -} IDE_CMD_OR_STATUS; - -typedef union { - UINT16 Error; /* when read */ - UINT16 Feature; /* when write */ -} IDE_ERROR_OR_FEATURE; - -typedef union { - UINT16 AltStatus; /* when read */ - UINT16 DeviceControl; /* when write */ -} IDE_ALTSTATUS_OR_DEVICECONTROL; - -// -// IDE registers set -// -typedef struct { - UINT16 Data; - IDE_ERROR_OR_FEATURE Reg1; - UINT16 SectorCount; - UINT16 SectorNumber; - UINT16 CylinderLsb; - UINT16 CylinderMsb; - UINT16 Head; - IDE_CMD_OR_STATUS Reg; - - IDE_ALTSTATUS_OR_DEVICECONTROL Alt; - UINT16 DriveAddress; -} IDE_BASE_REGISTERS; - -typedef struct { - - UINTN DevicePosition; - EFI_PEI_BLOCK_IO_MEDIA MediaInfo; - EFI_PEI_BLOCK_IO2_MEDIA MediaInfo2; - -} PEI_ATAPI_DEVICE_INFO; - -#define ATAPI_BLK_IO_DEV_SIGNATURE SIGNATURE_32 ('a', 'b', 'i', 'o') -typedef struct { - UINTN Signature; - - EFI_PEI_RECOVERY_BLOCK_IO_PPI AtapiBlkIo; - EFI_PEI_RECOVERY_BLOCK_IO2_PPI AtapiBlkIo2; - EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; - EFI_PEI_PPI_DESCRIPTOR PpiDescriptor2; - PEI_ATA_CONTROLLER_PPI *AtaControllerPpi; - - UINTN DeviceCount; - PEI_ATAPI_DEVICE_INFO DeviceInfo[MAX_IDE_DEVICES]; //for max 8 device - IDE_BASE_REGISTERS IdeIoPortReg[MAX_IDE_CHANNELS]; //for max 4 channel. -} ATAPI_BLK_IO_DEV; - -#define PEI_RECOVERY_ATAPI_FROM_BLKIO_THIS(a) CR (a, ATAPI_BLK_IO_DEV, AtapiBlkIo, ATAPI_BLK_IO_DEV_SIGNATURE) -#define PEI_RECOVERY_ATAPI_FROM_BLKIO2_THIS(a) CR (a, ATAPI_BLK_IO_DEV, AtapiBlkIo2, ATAPI_BLK_IO_DEV_SIGNATURE) - - -#define STALL_1_MILLI_SECOND 1000 // stall 1 ms -#define STALL_1_SECONDS 1000 * STALL_1_MILLI_SECOND - -// -// Time Out Value For IDE Device Polling -// -// ATATIMEOUT is used for waiting time out for ATA device -// -#define ATATIMEOUT 1000 // 1 second -// ATAPITIMEOUT is used for waiting operation -// except read and write time out for ATAPI device -// -#define ATAPITIMEOUT 1000 // 1 second -// ATAPILONGTIMEOUT is used for waiting read and -// write operation timeout for ATAPI device -// -#define CDROMLONGTIMEOUT 2000 // 2 seconds -#define ATAPILONGTIMEOUT 5000 // 5 seconds - -// -// PEI Recovery Block I/O PPI -// - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS Operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -AtapiGetNumberOfBlockDevices ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - OUT UINTN *NumberBlockDevices - ); - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - @retval Others Other failure occurs. - -**/ -EFI_STATUS -EFIAPI -AtapiGetBlockDeviceMediaInfo ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo - ); - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -AtapiReadBlocks ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Gets the count of block I/O devices that one specific block driver detects. - - This function is used for getting the count of block I/O devices that one - specific block driver detects. To the PEI ATAPI driver, it returns the number - of all the detected ATAPI devices it detects during the enumeration process. - To the PEI legacy floppy driver, it returns the number of all the legacy - devices it finds during its enumeration process. If no device is detected, - then the function will return zero. - - @param[in] PeiServices General-purpose services that are available - to every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI - instance. - @param[out] NumberBlockDevices The number of block I/O devices discovered. - - @retval EFI_SUCCESS Operation performed successfully. - -**/ -EFI_STATUS -EFIAPI -AtapiGetNumberOfBlockDevices2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - OUT UINTN *NumberBlockDevices - ); - -/** - Gets a block device's media information. - - This function will provide the caller with the specified block device's media - information. If the media changes, calling this function will update the media - information accordingly. - - @param[in] PeiServices General-purpose services that are available to every - PEIM - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the - device index that was assigned during the enumeration - process. This index is a number from one to - NumberBlockDevices. - @param[out] MediaInfo The media information of the specified block media. - The caller is responsible for the ownership of this - data structure. - - @retval EFI_SUCCESS Media information about the specified block device - was obtained successfully. - @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware - error. - @retval Others Other failure occurs. - -**/ -EFI_STATUS -EFIAPI -AtapiGetBlockDeviceMediaInfo2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo - ); - -/** - Reads the requested number of blocks from the specified block device. - - The function reads the requested number of blocks from the device. All the - blocks are read, or an error is returned. If there is no media in the device, - the function returns EFI_NO_MEDIA. - - @param[in] PeiServices General-purpose services that are available to - every PEIM. - @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance. - @param[in] DeviceIndex Specifies the block device to which the function wants - to talk. Because the driver that implements Block I/O - PPIs will manage multiple block devices, the PPIs that - want to talk to a single device must specify the device - index that was assigned during the enumeration process. - This index is a number from one to NumberBlockDevices. - @param[in] StartLBA The starting logical block address (LBA) to read from - on the device - @param[in] BufferSize The size of the Buffer in bytes. This number must be - a multiple of the intrinsic block size of the device. - @param[out] Buffer A pointer to the destination buffer for the data. - The caller is responsible for the ownership of the - buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while attempting - to perform the read operation. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not - valid, or the buffer is not properly aligned. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of - the intrinsic block size of the device. - -**/ -EFI_STATUS -EFIAPI -AtapiReadBlocks2 ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, - IN UINTN DeviceIndex, - IN EFI_PEI_LBA StartLBA, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -// -// Internal functions -// - -/** - Enumerate Atapi devices. - - This function is used to enumerate Atatpi device in Ide channel. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device - -**/ -VOID -AtapiEnumerateDevices ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev - ); - -/** - Detect Atapi devices. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[out] MediaInfo The media information of the specified block media. - @param[out] MediaInfo2 The media information 2 of the specified block media. - - @retval TRUE Atapi device exists in specified position. - @retval FALSE Atapi device does not exist in specified position. - -**/ -BOOLEAN -DiscoverAtapiDevice ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 - ); - -/** - Detect if an IDE controller exists in specified position. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - - @retval TRUE The Atapi device exists. - @retval FALSE The Atapi device does not present. - -**/ -BOOLEAN -DetectIDEController ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition - ); - -/** - Wait specified time interval to poll for BSY bit clear in the Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS BSY bit is cleared in the specified time interval. - @retval EFI_TIMEOUT BSY bit is not cleared in the specified time interval. - -**/ -EFI_STATUS -WaitForBSYClear ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ); - -/** - Wait specified time interval to poll for DRDY bit set in the Status register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRDY bit is set in the specified time interval. - @retval EFI_TIMEOUT DRDY bit is not set in the specified time interval. - -**/ -EFI_STATUS -DRDYReady ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ); - -/** - Wait specified time interval to poll for DRQ bit clear in the Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRQ bit is cleared in the specified time interval. - @retval EFI_TIMEOUT DRQ bit is not cleared in the specified time interval. - -**/ -EFI_STATUS -DRQClear ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ); - -/** - Wait specified time interval to poll for DRQ bit clear in the Alternate Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRQ bit is cleared in the specified time interval. - @retval EFI_TIMEOUT DRQ bit is not cleared in the specified time interval. - -**/ -EFI_STATUS -DRQClear2 ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ); - -/** - Wait specified time interval to poll for DRQ bit set in the Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRQ bit is set in the specified time interval. - @retval EFI_TIMEOUT DRQ bit is not set in the specified time interval. - @retval EFI_ABORTED Operation Aborted. - -**/ -EFI_STATUS -DRQReady ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ); - -/** - Wait specified time interval to poll for DRQ bit set in the Alternate Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] IdeIoRegisters A pointer to IDE IO registers. - @param[in] TimeoutInMilliSeconds Time specified in milliseconds. - - @retval EFI_SUCCESS DRQ bit is set in the specified time interval. - @retval EFI_TIMEOUT DRQ bit is not set in the specified time interval. - @retval EFI_ABORTED Operation Aborted. - -**/ -EFI_STATUS -DRQReady2 ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN IDE_BASE_REGISTERS *IdeIoRegisters, - IN UINTN TimeoutInMilliSeconds - ); - -/** - Check if there is an error in Status Register. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] StatusReg The address to IDE IO registers. - - @retval EFI_SUCCESS Operation success. - @retval EFI_DEVICE_ERROR Device error. - -**/ -EFI_STATUS -CheckErrorStatus ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINT16 StatusReg - ); - -/** - Idendify Atapi devices. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - - @retval EFI_SUCCESS Identify successfully. - @retval EFI_DEVICE_ERROR Device cannot be identified successfully. - -**/ -EFI_STATUS -ATAPIIdentify ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition - ); - -/** - Sends out ATAPI Test Unit Ready Packet Command to the specified device - to find out whether device is accessible. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - - @retval EFI_SUCCESS TestUnit command executed successfully. - @retval EFI_DEVICE_ERROR Device cannot be executed TestUnit command successfully. - -**/ -EFI_STATUS -TestUnitReady ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition - ) ; - -/** - Send out ATAPI commands conforms to the Packet Command with PIO Data In Protocol. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] Packet A pointer to ATAPI command packet. - @param[in] Buffer Buffer to contain requested transfer data from device. - @param[in] ByteCount Requested transfer data length. - @param[in] TimeoutInMilliSeconds Time out value, in unit of milliseconds. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Device cannot be executed command successfully. - -**/ -EFI_STATUS -AtapiPacketCommandIn ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN ATAPI_PACKET_COMMAND *Packet, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN UINTN TimeoutInMilliSeconds - ); - -/** - Sends out ATAPI Inquiry Packet Command to the specified device. - This command will return INQUIRY data of the device. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[out] MediaInfo The media information of the specified block media. - @param[out] MediaInfo2 The media information 2 of the specified block media. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Device cannot be executed command successfully. - @retval EFI_UNSUPPORTED Unsupported device type. - -**/ -EFI_STATUS -Inquiry ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, - OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 - ); - -/** - Used before read/write blocks from/to ATAPI device media. - Since ATAPI device media is removable, it is necessary to detect - whether media is present and get current present media's information. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in, out] MediaInfo The media information of the specified block media. - @param[in, out] MediaInfo2 The media information 2 of the specified block media. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - @retval EFI_OUT_OF_RESOURCES Can not allocate required resources. - -**/ -EFI_STATUS -DetectMedia ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, - IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 - ); - -/** - Reset specified Atapi device. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] Extensive If TRUE, use ATA soft reset, otherwise use Atapi soft reset. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - -**/ -EFI_STATUS -ResetDevice ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN BOOLEAN Extensive - ); - -/** - Sends out ATAPI Request Sense Packet Command to the specified device. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] SenseBuffers Pointer to sense buffer. - @param[in, out] SenseCounts Length of sense buffer. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - -**/ -EFI_STATUS -RequestSense ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN ATAPI_REQUEST_SENSE_DATA *SenseBuffers, - IN OUT UINT8 *SenseCounts - ); - -/** - Sends out ATAPI Read Capacity Packet Command to the specified device. - This command will return the information regarding the capacity of the - media in the device. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in, out] MediaInfo The media information of the specified block media. - @param[in, out] MediaInfo2 The media information 2 of the specified block media. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - -**/ -EFI_STATUS -ReadCapacity ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo, - IN OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo2 - ); - -/** - Perform read from disk in block unit. - - @param[in] AtapiBlkIoDev A pointer to atapi block IO device. - @param[in] DevicePosition An integer to signify device position. - @param[in] Buffer Buffer to contain read data. - @param[in] StartLba Starting LBA address. - @param[in] NumberOfBlocks Number of blocks to read. - @param[in] BlockSize Size of each block. - - @retval EFI_SUCCESS Command executed successfully. - @retval EFI_DEVICE_ERROR Some device errors happen. - -**/ -EFI_STATUS -ReadSectors ( - IN ATAPI_BLK_IO_DEV *AtapiBlkIoDev, - IN UINTN DevicePosition, - IN VOID *Buffer, - IN EFI_PEI_LBA StartLba, - IN UINTN NumberOfBlocks, - IN UINTN BlockSize - ); - -/** - Check if there is media according to sense data. - - @param[in] SenseData Pointer to sense data. - @param[in] SenseCounts Count of sense data. - - @retval TRUE No media - @retval FALSE Media exists - -**/ -BOOLEAN -IsNoMedia ( - IN ATAPI_REQUEST_SENSE_DATA *SenseData, - IN UINTN SenseCounts - ); - -/** - Check if device state is unclear according to sense data. - - @param[in] SenseData Pointer to sense data. - @param[in] SenseCounts Count of sense data. - - @retval TRUE Device state is unclear - @retval FALSE Device state is clear - -**/ -BOOLEAN -IsDeviceStateUnclear ( - IN ATAPI_REQUEST_SENSE_DATA *SenseData, - IN UINTN SenseCounts - ); - -/** - Check if there is media error according to sense data. - - @param[in] SenseData Pointer to sense data. - @param[in] SenseCounts Count of sense data. - - @retval TRUE Media error - @retval FALSE No media error - -**/ -BOOLEAN -IsMediaError ( - IN ATAPI_REQUEST_SENSE_DATA *SenseData, - IN UINTN SenseCounts - ); - -/** - Check if drive is ready according to sense data. - - @param[in] SenseData Pointer to sense data. - @param[in] SenseCounts Count of sense data. - @param[out] NeedRetry Indicate if retry is needed. - - @retval TRUE Drive ready - @retval FALSE Drive not ready - -**/ -BOOLEAN -IsDriveReady ( - IN ATAPI_REQUEST_SENSE_DATA *SenseData, - IN UINTN SenseCounts, - OUT BOOLEAN *NeedRetry - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.inf b/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.inf deleted file mode 100644 index 8bcef7bc6a..0000000000 --- a/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.inf +++ /dev/null @@ -1,69 +0,0 @@ -## @file -# PEIM to produce gEfiPeiVirtualBlockIoPpiGuid PPI for ATA controllers in the platform. -# This PPI can be consumed by PEIM which produce gEfiPeiDeviceRecoveryModulePpiGuid -# for Atapi CD ROM device. -# -# This module discovers CDROM devices in Legacy and native mode and installs block IO ppis for them. -# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions -# of the BSD License which accompanies this distribution. The -# full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = IdeBusPei - MODULE_UNI_FILE = IdeBusPei.uni - FILE_GUID = B7A5041A-78BA-49e3-B73B-54C757811FB6 - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - - ENTRY_POINT = AtapiPeimEntry - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - AtapiPeim.h - AtapiPeim.c - - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - - -[LibraryClasses] - IoLib - BaseMemoryLib - PeiServicesLib - PeimEntryPoint - DebugLib - TimerLib - PeiServicesTablePointerLib - MemoryAllocationLib - PcdLib - -[Ppis] - gPeiAtaControllerPpiGuid ## CONSUMES - gEfiPeiVirtualBlockIoPpiGuid ## PRODUCES - gEfiPeiVirtualBlockIo2PpiGuid ## PRODUCES - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdSataSpinUpDelayInSecForRecoveryPath ## CONSUMES - -[Depex] - gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid AND gPeiAtaControllerPpiGuid - -[UserExtensions.TianoCore."ExtraFiles"] - IdeBusPeiExtra.uni diff --git a/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.uni b/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.uni deleted file mode 100644 index 75ab58e15d..0000000000 Binary files a/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPei.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPeiExtra.uni b/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPeiExtra.uni deleted file mode 100644 index ec4663cf91..0000000000 Binary files a/MdeModulePkg/Bus/Pci/IdeBusPei/IdeBusPeiExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c b/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c deleted file mode 100644 index 3d581b69fd..0000000000 --- a/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c +++ /dev/null @@ -1,387 +0,0 @@ -/** @file - This module is one template module for Incompatible PCI Device Support protocol. - It includes one incompatile pci devices list template. - - Incompatible PCI Device Support protocol allows the PCI bus driver to support - resource allocation for some PCI devices that do not comply with the PCI Specification. - -Copyright (c) 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include - -#include -#include -#include - -#include -#include - -typedef struct { - UINT64 VendorId; - UINT64 DeviceId; - UINT64 RevisionId; - UINT64 SubsystemVendorId; - UINT64 SubsystemDeviceId; -} EFI_PCI_DEVICE_HEADER_INFO; - -typedef struct { - UINT64 ResType; - UINT64 GenFlag; - UINT64 SpecificFlag; - UINT64 AddrSpaceGranularity; - UINT64 AddrRangeMin; - UINT64 AddrRangeMax; - UINT64 AddrTranslationOffset; - UINT64 AddrLen; -} EFI_PCI_RESOUCE_DESCRIPTOR; - -#define PCI_DEVICE_ID(VendorId, DeviceId, Revision, SubVendorId, SubDeviceId) \ - VendorId, DeviceId, Revision, SubVendorId, SubDeviceId - -#define PCI_BAR_TYPE_IO ACPI_ADDRESS_SPACE_TYPE_IO -#define PCI_BAR_TYPE_MEM ACPI_ADDRESS_SPACE_TYPE_MEM - -#define DEVICE_INF_TAG 0xFFF2 -#define DEVICE_RES_TAG 0xFFF1 -#define LIST_END_TAG 0x0000 - - -/** - Returns a list of ACPI resource descriptors that detail the special - resource configuration requirements for an incompatible PCI device. - - @param This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance. - @param VendorId A unique ID to identify the manufacturer of the PCI device. - @param DeviceId A unique ID to identify the particular PCI device. - @param RevisionId A PCI device-specific revision identifier. - @param SubsystemVendorId Specifies the subsystem vendor ID. - @param SubsystemDeviceId Specifies the subsystem device ID. - @param Configuration A list of ACPI resource descriptors returned that detail - the configuration requirement. - - @retval EFI_SUCCESS Successfully got ACPI resource for specified PCI device. - @retval EFI_INVALID_PARAMETER Configuration is NULL. - @retval EFI_OUT_OF_RESOURCES No memory available. - @retval EFI_UNSUPPORTED The specified PCI device wasn't supported. - -**/ -EFI_STATUS -EFIAPI -PCheckDevice ( - IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This, - IN UINTN VendorId, - IN UINTN DeviceId, - IN UINTN RevisionId, - IN UINTN SubsystemVendorId, - IN UINTN SubsystemDeviceId, - OUT VOID **Configuration - ); - -// -// Handle onto which the Incompatible PCI Device List is installed -// -EFI_HANDLE mIncompatiblePciDeviceSupportHandle = NULL; - -// -// The Incompatible PCI Device Support Protocol instance produced by this driver -// -EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL mIncompatiblePciDeviceSupport = { - PCheckDevice -}; - -// -// The incompatible PCI devices list template -// -GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mIncompatiblePciDeviceList[] = { - // - // DEVICE_INF_TAG, - // PCI_DEVICE_ID (VendorID, DeviceID, Revision, SubVendorId, SubDeviceId), - // DEVICE_RES_TAG, - // ResType, GFlag , SFlag, Granularity, RangeMin, - // RangeMax, Offset, AddrLen - // - // - // Device Adaptec 9004 - // - DEVICE_INF_TAG, - PCI_DEVICE_ID(0x9004, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), - DEVICE_RES_TAG, - PCI_BAR_TYPE_IO, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_BAR_EVEN_ALIGN, - PCI_BAR_ALL, - PCI_BAR_NOCHANGE, - // - // Device Adaptec 9005 - // - DEVICE_INF_TAG, - PCI_DEVICE_ID(0x9005, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), - DEVICE_RES_TAG, - PCI_BAR_TYPE_IO, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_BAR_EVEN_ALIGN, - PCI_BAR_ALL, - PCI_BAR_NOCHANGE, - // - // Device QLogic 1007 - // - DEVICE_INF_TAG, - PCI_DEVICE_ID(0x1077, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), - DEVICE_RES_TAG, - PCI_BAR_TYPE_IO, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_BAR_EVEN_ALIGN, - PCI_BAR_ALL, - PCI_BAR_NOCHANGE, - // - // Device Agilent 103C - // - DEVICE_INF_TAG, - PCI_DEVICE_ID(0x103C, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), - DEVICE_RES_TAG, - PCI_BAR_TYPE_IO, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_BAR_EVEN_ALIGN, - PCI_BAR_ALL, - PCI_BAR_NOCHANGE, - // - // Device Agilent 15BC - // - DEVICE_INF_TAG, - PCI_DEVICE_ID(0x15BC, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE, DEVICE_ID_NOCARE), - DEVICE_RES_TAG, - PCI_BAR_TYPE_IO, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_ACPI_UNUSED, - PCI_BAR_EVEN_ALIGN, - PCI_BAR_ALL, - PCI_BAR_NOCHANGE, - // - // The end of the list - // - LIST_END_TAG -}; - - -/** - Entry point of the incompatible pci device support code. Setup an incompatible device list template - and install EFI Incompatible PCI Device Support protocol. - - @param ImageHandle A handle for the image that is initializing this driver. - @param SystemTable A pointer to the EFI system table. - - @retval EFI_SUCCESS Installed EFI Incompatible PCI Device Support Protocol successfully. - @retval others Failed to install protocol. - -**/ -EFI_STATUS -EFIAPI -IncompatiblePciDeviceSupportEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - // - // Install EFI Incompatible PCI Device Support Protocol on a new handle - // - Status = gBS->InstallProtocolInterface ( - &mIncompatiblePciDeviceSupportHandle, - &gEfiIncompatiblePciDeviceSupportProtocolGuid, - EFI_NATIVE_INTERFACE, - &mIncompatiblePciDeviceSupport - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} - -/** - Returns a list of ACPI resource descriptors that detail the special - resource configuration requirements for an incompatible PCI device. - - @param This Pointer to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL instance. - @param VendorId A unique ID to identify the manufacturer of the PCI device. - @param DeviceId A unique ID to identify the particular PCI device. - @param RevisionId A PCI device-specific revision identifier. - @param SubsystemVendorId Specifies the subsystem vendor ID. - @param SubsystemDeviceId Specifies the subsystem device ID. - @param Configuration A list of ACPI resource descriptors returned that detail - the configuration requirement. - - @retval EFI_SUCCESS Successfully got ACPI resource for specified PCI device. - @retval EFI_INVALID_PARAMETER Configuration is NULL. - @retval EFI_OUT_OF_RESOURCES No memory available. - @retval EFI_UNSUPPORTED The specified PCI device wasn't supported. - -**/ -EFI_STATUS -EFIAPI -PCheckDevice ( - IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This, - IN UINTN VendorId, - IN UINTN DeviceId, - IN UINTN RevisionId, - IN UINTN SubsystemVendorId, - IN UINTN SubsystemDeviceId, - OUT VOID **Configuration - ) -{ - UINT64 Tag; - UINT64 *ListPtr; - UINT64 *TempListPtr; - EFI_PCI_DEVICE_HEADER_INFO *Header; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AcpiPtr; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *OldAcpiPtr; - EFI_PCI_RESOUCE_DESCRIPTOR *Dsc; - EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd; - UINTN Index; - - // - // Validate the parameters - // - if (Configuration == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Initialize the return value to NULL - // - * (VOID **) Configuration = NULL; - - ListPtr = mIncompatiblePciDeviceList; - while (*ListPtr != LIST_END_TAG) { - - Tag = *ListPtr; - - switch (Tag) { - case DEVICE_INF_TAG: - Header = (EFI_PCI_DEVICE_HEADER_INFO *) (ListPtr + 1); - ListPtr = ListPtr + 1 + sizeof (EFI_PCI_DEVICE_HEADER_INFO) / sizeof (UINT64); - // - // See if the Header matches the parameters passed in - // - if (Header->VendorId != DEVICE_ID_NOCARE) { - if (Header->VendorId != VendorId) { - continue; - } - } - - if (Header->DeviceId != DEVICE_ID_NOCARE) { - if (DeviceId != Header->DeviceId) { - continue; - } - } - - if (Header->RevisionId != DEVICE_ID_NOCARE) { - if (RevisionId != Header->RevisionId) { - continue; - } - } - - if (Header->SubsystemVendorId != DEVICE_ID_NOCARE) { - if (SubsystemVendorId != Header->SubsystemVendorId) { - continue; - } - } - - if (Header->SubsystemDeviceId != DEVICE_ID_NOCARE) { - if (SubsystemDeviceId != Header->SubsystemDeviceId) { - continue; - } - } - // - // Matched an item, so construct the ACPI descriptor for the resource. - // - // - // Count the resource items so that to allocate space - // - for (Index = 0, TempListPtr = ListPtr; *TempListPtr == DEVICE_RES_TAG; Index++) { - TempListPtr = TempListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64)); - } - // - // If there is at least one type of resource request, - // allocate an acpi resource node - // - if (Index == 0) { - return EFI_UNSUPPORTED; - } - - AcpiPtr = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Index + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (AcpiPtr == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - OldAcpiPtr = AcpiPtr; - // - // Fill the EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR structure - // according to the EFI_PCI_RESOUCE_DESCRIPTOR structure - // - for (; *ListPtr == DEVICE_RES_TAG;) { - - Dsc = (EFI_PCI_RESOUCE_DESCRIPTOR *) (ListPtr + 1); - - AcpiPtr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - AcpiPtr->Len = (UINT16) sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); - AcpiPtr->ResType = (UINT8) Dsc->ResType; - AcpiPtr->GenFlag = (UINT8) Dsc->GenFlag; - AcpiPtr->SpecificFlag = (UINT8) Dsc->SpecificFlag; - AcpiPtr->AddrSpaceGranularity = Dsc->AddrSpaceGranularity;; - AcpiPtr->AddrRangeMin = Dsc->AddrRangeMin; - AcpiPtr->AddrRangeMax = Dsc->AddrRangeMax; - AcpiPtr->AddrTranslationOffset = Dsc->AddrTranslationOffset; - AcpiPtr->AddrLen = Dsc->AddrLen; - - ListPtr = ListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64)); - AcpiPtr++; - } - // - // Put the checksum - // - PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (AcpiPtr); - PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; - PtrEnd->Checksum = 0; - - *(VOID **) Configuration = OldAcpiPtr; - - return EFI_SUCCESS; - - case DEVICE_RES_TAG: - // - // Adjust the pointer to the next PCI resource descriptor item - // - ListPtr = ListPtr + 1 + ((sizeof (EFI_PCI_RESOUCE_DESCRIPTOR)) / sizeof (UINT64)); - break; - - default: - return EFI_UNSUPPORTED; - } - } - - return EFI_UNSUPPORTED; -} - diff --git a/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.uni b/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.uni deleted file mode 100644 index 46732f797a..0000000000 Binary files a/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf b/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf deleted file mode 100644 index a83edaec7b..0000000000 --- a/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportDxe.inf +++ /dev/null @@ -1,53 +0,0 @@ -## @file -# PCI Incompatible device support module template. -# -# Installs EFI PCI Incompatible Device Support protocol and includes one incompatile -# pci devices list template. -# -# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = IncompatiblePciDeviceSupport - MODULE_UNI_FILE = IncompatiblePciDeviceSupport.uni - FILE_GUID = AD70855E-0CC5-4abf-8979-BE762A949EA3 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = IncompatiblePciDeviceSupportEntryPoint - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - IncompatiblePciDeviceSupport.c - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - UefiBootServicesTableLib - MemoryAllocationLib - DebugLib - -[Protocols] - gEfiIncompatiblePciDeviceSupportProtocolGuid ## PRODUCES - -[Depex] - TRUE - -[UserExtensions.TianoCore."ExtraFiles"] - IncompatiblePciDeviceSupportExtra.uni diff --git a/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportExtra.uni b/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportExtra.uni deleted file mode 100644 index 0a3aaac3da..0000000000 Binary files a/MdeModulePkg/Bus/Pci/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupportExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/ComponentName.c deleted file mode 100644 index 60849aea03..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/ComponentName.c +++ /dev/null @@ -1,233 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "NvmExpress.h" - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gNvmExpressComponentName = { - NvmExpressComponentNameGetDriverName, - NvmExpressComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gNvmExpressComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) NvmExpressComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) NvmExpressComponentNameGetControllerName, - "en" -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mNvmExpressDriverNameTable[] = { - { "eng;en", L"NVM Express Driver" }, - { NULL, NULL } -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mNvmExpressControllerNameTable[] = { - { "eng;en", L"NVM Express Controller" }, - { NULL, NULL } -}; - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -NvmExpressComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mNvmExpressDriverNameTable, - DriverName, - (BOOLEAN)(This == &gNvmExpressComponentName) - ); -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -NvmExpressComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - - // - // Make sure this driver is currently managing ControllHandle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gNvmExpressDriverBinding.DriverBindingHandle, - &gEfiPciIoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - ControllerNameTable = mNvmExpressControllerNameTable; - if (ChildHandle != NULL) { - Status = EfiTestChildHandle ( - ControllerHandle, - ChildHandle, - &gEfiPciIoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Get the child context - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo, - gNvmExpressDriverBinding.DriverBindingHandle, - ChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (BlockIo); - ControllerNameTable = Device->ControllerNameTable; - } - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - ControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gNvmExpressComponentName) - ); - -} diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c deleted file mode 100644 index 9938bf4541..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c +++ /dev/null @@ -1,1138 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "NvmExpress.h" - -// -// NVM Express Driver Binding Protocol Instance -// -EFI_DRIVER_BINDING_PROTOCOL gNvmExpressDriverBinding = { - NvmExpressDriverBindingSupported, - NvmExpressDriverBindingStart, - NvmExpressDriverBindingStop, - 0x10, - NULL, - NULL -}; - -// -// NVM Express EFI Driver Supported EFI Version Protocol Instance -// -EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiVersion = { - sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL), // Size of Protocol structure. - 0 // Version number to be filled at start up. -}; - -// -// Template for NVM Express Pass Thru Mode data structure. -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_NVM_EXPRESS_PASS_THRU_MODE gEfiNvmExpressPassThruMode = { - EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_LOGICAL | EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVM, - sizeof (UINTN), - 0x10100 -}; - -/** - Check if the specified Nvm Express device namespace is active, and create child handles - for them with BlockIo and DiskInfo protocol instances. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - - @retval EFI_SUCCESS All the namespaces in the device are successfully enumerated. - @return Others Some error occurs when enumerating the namespaces. - -**/ -EFI_STATUS -EnumerateNvmeDevNamespace ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - UINT32 NamespaceId - ) -{ - NVME_ADMIN_NAMESPACE_DATA *NamespaceData; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_HANDLE DeviceHandle; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - UINT32 Lbads; - UINT32 Flbas; - UINT32 LbaFmtIdx; - - NewDevicePathNode = NULL; - DevicePath = NULL; - Device = NULL; - - // - // Allocate a buffer for Identify Namespace data - // - NamespaceData = AllocateZeroPool(sizeof (NVME_ADMIN_NAMESPACE_DATA)); - if(NamespaceData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - ParentDevicePath = Private->ParentDevicePath; - // - // Identify Namespace - // - Status = NvmeIdentifyNamespace ( - Private, - NamespaceId, - (VOID *)NamespaceData - ); - if (EFI_ERROR(Status)) { - goto Exit; - } - // - // Validate Namespace - // - if (NamespaceData->Ncap == 0) { - Status = EFI_DEVICE_ERROR; - } else { - // - // allocate device private data for each discovered namespace - // - Device = AllocateZeroPool(sizeof(NVME_DEVICE_PRIVATE_DATA)); - if (Device == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - // - // Initialize SSD namespace instance data - // - Device->Signature = NVME_DEVICE_PRIVATE_DATA_SIGNATURE; - Device->NamespaceId = NamespaceId; - Device->NamespaceUuid = NamespaceData->Eui64; - - Device->ControllerHandle = Private->ControllerHandle; - Device->DriverBindingHandle = Private->DriverBindingHandle; - Device->Controller = Private; - - // - // Build BlockIo media structure - // - Device->Media.MediaId = 0; - Device->Media.RemovableMedia = FALSE; - Device->Media.MediaPresent = TRUE; - Device->Media.LogicalPartition = FALSE; - Device->Media.ReadOnly = FALSE; - Device->Media.WriteCaching = FALSE; - - Flbas = NamespaceData->Flbas; - LbaFmtIdx = Flbas & 0xF; - Lbads = NamespaceData->LbaFormat[LbaFmtIdx].Lbads; - Device->Media.BlockSize = (UINT32)1 << Lbads; - - Device->Media.LastBlock = NamespaceData->Nsze - 1; - Device->Media.LogicalBlocksPerPhysicalBlock = 1; - Device->Media.LowestAlignedLba = 1; - - // - // Create BlockIo Protocol instance - // - Device->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2; - Device->BlockIo.Media = &Device->Media; - Device->BlockIo.Reset = NvmeBlockIoReset; - Device->BlockIo.ReadBlocks = NvmeBlockIoReadBlocks; - Device->BlockIo.WriteBlocks = NvmeBlockIoWriteBlocks; - Device->BlockIo.FlushBlocks = NvmeBlockIoFlushBlocks; - - // - // Create StorageSecurityProtocol Instance - // - Device->StorageSecurity.ReceiveData = NvmeStorageSecurityReceiveData; - Device->StorageSecurity.SendData = NvmeStorageSecuritySendData; - - // - // Create DiskInfo Protocol instance - // - InitializeDiskInfo (Device); - - // - // Create a Nvm Express Namespace Device Path Node - // - Status = Private->Passthru.BuildDevicePath ( - &Private->Passthru, - Device->NamespaceId, - &NewDevicePathNode - ); - - if (EFI_ERROR(Status)) { - goto Exit; - } - - // - // Append the SSD node to the controller's device path - // - DevicePath = AppendDevicePathNode (ParentDevicePath, NewDevicePathNode); - if (DevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - DeviceHandle = NULL; - RemainingDevicePath = DevicePath; - Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle); - if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) { - Status = EFI_ALREADY_STARTED; - FreePool (DevicePath); - goto Exit; - } - - Device->DevicePath = DevicePath; - - // - // Make sure the handle is NULL so we create a new handle - // - Device->DeviceHandle = NULL; - - Status = gBS->InstallMultipleProtocolInterfaces ( - &Device->DeviceHandle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - &gEfiDiskInfoProtocolGuid, - &Device->DiskInfo, - NULL - ); - - if(EFI_ERROR(Status)) { - goto Exit; - } - - // - // Check if the NVMe controller supports the Security Send and Security Receive commands - // - if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) != 0) { - Status = gBS->InstallProtocolInterface ( - &Device->DeviceHandle, - &gEfiStorageSecurityCommandProtocolGuid, - EFI_NATIVE_INTERFACE, - &Device->StorageSecurity - ); - if(EFI_ERROR(Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - &Device->DeviceHandle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - &gEfiDiskInfoProtocolGuid, - &Device->DiskInfo, - NULL - ); - goto Exit; - } - } - - gBS->OpenProtocol ( - Private->ControllerHandle, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **) &Private->Passthru, - Private->DriverBindingHandle, - Device->DeviceHandle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - - // - // Dump NvmExpress Identify Namespace Data - // - DEBUG ((EFI_D_INFO, " == NVME IDENTIFY NAMESPACE [%d] DATA ==\n", NamespaceId)); - DEBUG ((EFI_D_INFO, " NSZE : 0x%x\n", NamespaceData->Nsze)); - DEBUG ((EFI_D_INFO, " NCAP : 0x%x\n", NamespaceData->Ncap)); - DEBUG ((EFI_D_INFO, " NUSE : 0x%x\n", NamespaceData->Nuse)); - DEBUG ((EFI_D_INFO, " LBAF0.LBADS : 0x%x\n", (NamespaceData->LbaFormat[0].Lbads))); - - // - // Build controller name for Component Name (2) protocol. - // - UnicodeSPrintAsciiFormat (Device->ModelName, sizeof (Device->ModelName), "%a-%a-%x", Private->ControllerData->Sn, Private->ControllerData->Mn, NamespaceData->Eui64); - - AddUnicodeString2 ( - "eng", - gNvmExpressComponentName.SupportedLanguages, - &Device->ControllerNameTable, - Device->ModelName, - TRUE - ); - - AddUnicodeString2 ( - "en", - gNvmExpressComponentName2.SupportedLanguages, - &Device->ControllerNameTable, - Device->ModelName, - FALSE - ); - } - -Exit: - if(NamespaceData != NULL) { - FreePool (NamespaceData); - } - - if (NewDevicePathNode != NULL) { - FreePool (NewDevicePathNode); - } - - if(EFI_ERROR(Status) && (Device != NULL) && (Device->DevicePath != NULL)) { - FreePool (Device->DevicePath); - } - if(EFI_ERROR(Status) && (Device != NULL)) { - FreePool (Device); - } - return Status; -} - -/** - Discover all Nvm Express device namespaces, and create child handles for them with BlockIo - and DiskInfo protocol instances. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS All the namespaces in the device are successfully enumerated. - @return Others Some error occurs when enumerating the namespaces. - -**/ -EFI_STATUS -DiscoverAllNamespaces ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_STATUS Status; - UINT32 NamespaceId; - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *Passthru; - - NamespaceId = 0xFFFFFFFF; - Passthru = &Private->Passthru; - - while (TRUE) { - Status = Passthru->GetNextNamespace ( - Passthru, - (UINT32 *)&NamespaceId - ); - - if (EFI_ERROR (Status)) { - break; - } - - Status = EnumerateNvmeDevNamespace ( - Private, - NamespaceId - ); - - if (EFI_ERROR(Status)) { - continue; - } - } - - return EFI_SUCCESS; -} - -/** - Unregisters a Nvm Express device namespace. - - This function removes the protocols installed on the controller handle and - frees the resources allocated for the namespace. - - @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance. - @param Controller The controller handle of the namespace. - @param Handle The child handle. - - @retval EFI_SUCCESS The namespace is successfully unregistered. - @return Others Some error occurs when unregistering the namespace. - -**/ -EFI_STATUS -UnregisterNvmeNamespace ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_HANDLE Handle - ) -{ - EFI_STATUS Status; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - NVME_DEVICE_PRIVATE_DATA *Device; - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurity; - - BlockIo = NULL; - - Status = gBS->OpenProtocol ( - Handle, - &gEfiBlockIoProtocolGuid, - (VOID **) &BlockIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (BlockIo); - Private = Device->Controller; - - // - // Close the child handle - // - gBS->CloseProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - This->DriverBindingHandle, - Handle - ); - - // - // The Nvm Express driver installs the BlockIo and DiskInfo in the DriverBindingStart(). - // Here should uninstall both of them. - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiDevicePathProtocolGuid, - Device->DevicePath, - &gEfiBlockIoProtocolGuid, - &Device->BlockIo, - &gEfiDiskInfoProtocolGuid, - &Device->DiskInfo, - NULL - ); - - if (EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **) &Private->Passthru, - This->DriverBindingHandle, - Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - return Status; - } - - // - // If Storage Security Command Protocol is installed, then uninstall this protocol. - // - Status = gBS->OpenProtocol ( - Handle, - &gEfiStorageSecurityCommandProtocolGuid, - (VOID **) &StorageSecurity, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (!EFI_ERROR (Status)) { - Status = gBS->UninstallProtocolInterface ( - Handle, - &gEfiStorageSecurityCommandProtocolGuid, - &Device->StorageSecurity - ); - if (EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **) &Private->Passthru, - This->DriverBindingHandle, - Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - return Status; - } - } - - if(Device->DevicePath != NULL) { - FreePool (Device->DevicePath); - } - - if (Device->ControllerNameTable != NULL) { - FreeUnicodeStringTable (Device->ControllerNameTable); - } - - FreePool (Device); - - return EFI_SUCCESS; -} - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_DEV_PATH_PTR DevicePathNode; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 ClassCode[3]; - - // - // Check whether device path is valid - // - if (RemainingDevicePath != NULL) { - // - // Check if RemainingDevicePath is the End of Device Path Node, - // if yes, go on checking other conditions - // - if (!IsDevicePathEnd (RemainingDevicePath)) { - // - // If RemainingDevicePath isn't the End of Device Path Node, - // check its validation - // - DevicePathNode.DevPath = RemainingDevicePath; - - if ((DevicePathNode.DevPath->Type != MESSAGING_DEVICE_PATH) || - (DevicePathNode.DevPath->SubType != MSG_NVME_NAMESPACE_DP) || - (DevicePathNodeLength(DevicePathNode.DevPath) != sizeof(NVME_NAMESPACE_DEVICE_PATH))) { - return EFI_UNSUPPORTED; - } - } - } - - // - // Open the EFI Device Path protocol needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Close protocol, don't use device path protocol in the Support() function - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - // - // Attempt to Open PCI I/O Protocol - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Now further check the PCI header: Base class (offset 0x0B) and Sub Class (offset 0x0A). - // This controller should be a Nvm Express controller. - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_CLASSCODE_OFFSET, - sizeof (ClassCode), - ClassCode - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Examine Nvm Express controller PCI Configuration table fields - // - if ((ClassCode[0] != PCI_IF_NVMHCI) || (ClassCode[1] != PCI_CLASS_MASS_STORAGE_NVM) || (ClassCode[2] != PCI_CLASS_MASS_STORAGE)) { - Status = EFI_UNSUPPORTED; - } - -Done: - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; -} - - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - UINT32 NamespaceId; - EFI_PHYSICAL_ADDRESS MappedAddr; - UINTN Bytes; - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *Passthru; - - DEBUG ((EFI_D_INFO, "NvmExpressDriverBindingStart: start\n")); - - Private = NULL; - Passthru = NULL; - ParentDevicePath = NULL; - - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) { - return Status; - } - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { - return Status; - } - - // - // Check EFI_ALREADY_STARTED to reuse the original NVME_CONTROLLER_PRIVATE_DATA. - // - if (Status != EFI_ALREADY_STARTED) { - Private = AllocateZeroPool (sizeof (NVME_CONTROLLER_PRIVATE_DATA)); - - if (Private == NULL) { - DEBUG ((EFI_D_ERROR, "NvmExpressDriverBindingStart: allocating pool for Nvme Private Data failed!\n")); - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - // - // 4 x 4kB aligned buffers will be carved out of this buffer. - // 1st 4kB boundary is the start of the admin submission queue. - // 2nd 4kB boundary is the start of the admin completion queue. - // 3rd 4kB boundary is the start of I/O submission queue #1. - // 4th 4kB boundary is the start of I/O completion queue #1. - // - // Allocate 4 pages of memory, then map it for bus master read and write. - // - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - 4, - (VOID**)&Private->Buffer, - 0 - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Bytes = EFI_PAGES_TO_SIZE (4); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - Private->Buffer, - &Bytes, - &MappedAddr, - &Private->Mapping - ); - - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (4))) { - goto Exit; - } - - Private->BufferPciAddr = (UINT8 *)(UINTN)MappedAddr; - ZeroMem (Private->Buffer, EFI_PAGES_TO_SIZE (4)); - - Private->Signature = NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE; - Private->ControllerHandle = Controller; - Private->ImageHandle = This->DriverBindingHandle; - Private->DriverBindingHandle = This->DriverBindingHandle; - Private->PciIo = PciIo; - Private->ParentDevicePath = ParentDevicePath; - Private->Passthru.Mode = &Private->PassThruMode; - Private->Passthru.PassThru = NvmExpressPassThru; - Private->Passthru.GetNextNamespace = NvmExpressGetNextNamespace; - Private->Passthru.BuildDevicePath = NvmExpressBuildDevicePath; - Private->Passthru.GetNamespace = NvmExpressGetNamespace; - CopyMem (&Private->PassThruMode, &gEfiNvmExpressPassThruMode, sizeof (EFI_NVM_EXPRESS_PASS_THRU_MODE)); - - Status = NvmeControllerInit (Private); - if (EFI_ERROR(Status)) { - goto Exit; - } - - Status = gBS->InstallMultipleProtocolInterfaces ( - &Controller, - &gEfiNvmExpressPassThruProtocolGuid, - &Private->Passthru, - NULL - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - } else { - Status = gBS->OpenProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **) &Passthru, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (Passthru); - } - - if (RemainingDevicePath == NULL) { - // - // Enumerate all NVME namespaces in the controller - // - Status = DiscoverAllNamespaces ( - Private - ); - - } else if (!IsDevicePathEnd (RemainingDevicePath)) { - // - // Enumerate the specified NVME namespace - // - Status = Private->Passthru.GetNamespace ( - &Private->Passthru, - RemainingDevicePath, - &NamespaceId - ); - - if (!EFI_ERROR (Status)) { - Status = EnumerateNvmeDevNamespace ( - Private, - NamespaceId - ); - } - } - - DEBUG ((EFI_D_INFO, "NvmExpressDriverBindingStart: end successfully\n")); - return EFI_SUCCESS; - -Exit: - if ((Private != NULL) && (Private->Mapping != NULL)) { - PciIo->Unmap (PciIo, Private->Mapping); - } - - if ((Private != NULL) && (Private->Buffer != NULL)) { - PciIo->FreeBuffer (PciIo, 4, Private->Buffer); - } - - if (Private != NULL) { - FreePool (Private); - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - DEBUG ((EFI_D_INFO, "NvmExpressDriverBindingStart: end with %r\n", Status)); - - return Status; -} - - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_STATUS Status; - BOOLEAN AllChildrenStopped; - UINTN Index; - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *PassThru; - - if (NumberOfChildren == 0) { - Status = gBS->OpenProtocol ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - (VOID **) &PassThru, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (!EFI_ERROR (Status)) { - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (PassThru); - gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiNvmExpressPassThruProtocolGuid, - PassThru, - NULL - ); - - if (Private->Mapping != NULL) { - Private->PciIo->Unmap (Private->PciIo, Private->Mapping); - } - - if (Private->Buffer != NULL) { - Private->PciIo->FreeBuffer (Private->PciIo, 4, Private->Buffer); - } - - FreePool (Private->ControllerData); - FreePool (Private); - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - return EFI_SUCCESS; - } - - AllChildrenStopped = TRUE; - - for (Index = 0; Index < NumberOfChildren; Index++) { - Status = UnregisterNvmeNamespace (This, Controller, ChildHandleBuffer[Index]); - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - } - } - - if (!AllChildrenStopped) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - This is the unload handle for the NVM Express driver. - - Disconnect the driver specified by ImageHandle from the NVMe device in the handle database. - Uninstall all the protocols installed in the driver. - - @param[in] ImageHandle The drivers' driver image. - - @retval EFI_SUCCESS The image is unloaded. - @retval Others Failed to unload the image. - -**/ -EFI_STATUS -EFIAPI -NvmExpressUnload ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_STATUS Status; - EFI_HANDLE *DeviceHandleBuffer; - UINTN DeviceHandleCount; - UINTN Index; - EFI_COMPONENT_NAME_PROTOCOL *ComponentName; - EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2; - - // - // Get the list of the device handles managed by this driver. - // If there is an error getting the list, then means the driver - // doesn't manage any device. At this way, we would only close - // those protocols installed at image handle. - // - DeviceHandleBuffer = NULL; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiNvmExpressPassThruProtocolGuid, - NULL, - &DeviceHandleCount, - &DeviceHandleBuffer - ); - - if (!EFI_ERROR (Status)) { - // - // Disconnect the driver specified by ImageHandle from all - // the devices in the handle database. - // - for (Index = 0; Index < DeviceHandleCount; Index++) { - Status = gBS->DisconnectController ( - DeviceHandleBuffer[Index], - ImageHandle, - NULL - ); - if (EFI_ERROR (Status)) { - goto EXIT; - } - } - } - - // - // Uninstall all the protocols installed in the driver entry point - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - ImageHandle, - &gEfiDriverBindingProtocolGuid, - &gNvmExpressDriverBinding, - &gEfiDriverSupportedEfiVersionProtocolGuid, - &gNvmExpressDriverSupportedEfiVersion, - NULL - ); - - if (EFI_ERROR (Status)) { - goto EXIT; - } - - // - // Note we have to one by one uninstall the following protocols. - // It's because some of them are optionally installed based on - // the following PCD settings. - // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable - // gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable - // gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable - // gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable - // - Status = gBS->HandleProtocol ( - ImageHandle, - &gEfiComponentNameProtocolGuid, - (VOID **) &ComponentName - ); - if (!EFI_ERROR (Status)) { - gBS->UninstallProtocolInterface ( - ImageHandle, - &gEfiComponentNameProtocolGuid, - ComponentName - ); - } - - Status = gBS->HandleProtocol ( - ImageHandle, - &gEfiComponentName2ProtocolGuid, - (VOID **) &ComponentName2 - ); - if (!EFI_ERROR (Status)) { - gBS->UninstallProtocolInterface ( - ImageHandle, - &gEfiComponentName2ProtocolGuid, - ComponentName2 - ); - } - - Status = EFI_SUCCESS; - -EXIT: - // - // Free the buffer containing the list of handles from the handle database - // - if (DeviceHandleBuffer != NULL) { - gBS->FreePool (DeviceHandleBuffer); - } - return Status; -} - -/** - The entry point for Nvm Express driver, used to install Nvm Express driver on the ImageHandle. - - @param ImageHandle The firmware allocated handle for this driver image. - @param SystemTable Pointer to the EFI system table. - - @retval EFI_SUCCESS Driver loaded. - @retval other Driver not loaded. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverEntry ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gNvmExpressDriverBinding, - ImageHandle, - &gNvmExpressComponentName, - &gNvmExpressComponentName2 - ); - ASSERT_EFI_ERROR (Status); - - // - // Install EFI Driver Supported EFI Version Protocol required for - // EFI drivers that are on PCI and other plug in cards. - // - gNvmExpressDriverSupportedEfiVersion.FirmwareVersion = 0x00020028; - Status = gBS->InstallMultipleProtocolInterfaces ( - &ImageHandle, - &gEfiDriverSupportedEfiVersionProtocolGuid, - &gNvmExpressDriverSupportedEfiVersion, - NULL - ); - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h deleted file mode 100644 index 21c6255caa..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h +++ /dev/null @@ -1,610 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_NVM_EXPRESS_H_ -#define _EFI_NVM_EXPRESS_H_ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct _NVME_CONTROLLER_PRIVATE_DATA NVME_CONTROLLER_PRIVATE_DATA; -typedef struct _NVME_DEVICE_PRIVATE_DATA NVME_DEVICE_PRIVATE_DATA; - -#include "NvmExpressBlockIo.h" -#include "NvmExpressDiskInfo.h" -#include "NvmExpressHci.h" - -extern EFI_DRIVER_BINDING_PROTOCOL gNvmExpressDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gNvmExpressComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gNvmExpressComponentName2; -extern EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL gNvmExpressDriverSupportedEfiVersion; - -#define PCI_CLASS_MASS_STORAGE_NVM 0x08 // mass storage sub-class non-volatile memory. -#define PCI_IF_NVMHCI 0x02 // mass storage programming interface NVMHCI. - -#define NVME_ASQ_SIZE 1 // Number of admin submission queue entries, which is 0-based -#define NVME_ACQ_SIZE 1 // Number of admin completion queue entries, which is 0-based - -#define NVME_CSQ_SIZE 1 // Number of I/O submission queue entries, which is 0-based -#define NVME_CCQ_SIZE 1 // Number of I/O completion queue entries, which is 0-based - -#define NVME_MAX_QUEUES 2 // Number of queues supported by the driver - -#define NVME_CONTROLLER_ID 0 - -// -// Time out value for Nvme transaction execution -// -#define NVME_GENERIC_TIMEOUT EFI_TIMER_PERIOD_SECONDS (5) - -// -// Unique signature for private data structure. -// -#define NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('N','V','M','E') - -// -// Nvme private data structure. -// -struct _NVME_CONTROLLER_PRIVATE_DATA { - UINT32 Signature; - - EFI_HANDLE ControllerHandle; - EFI_HANDLE ImageHandle; - EFI_HANDLE DriverBindingHandle; - - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 PciAttributes; - - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - - EFI_NVM_EXPRESS_PASS_THRU_MODE PassThruMode; - EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL Passthru; - - // - // pointer to identify controller data - // - NVME_ADMIN_CONTROLLER_DATA *ControllerData; - - // - // 6 x 4kB aligned buffers will be carved out of this buffer. - // 1st 4kB boundary is the start of the admin submission queue. - // 2nd 4kB boundary is the start of the I/O submission queue #1. - // 3rd 4kB boundary is the start of the admin completion queue. - // 4th 4kB boundary is the start of the I/O completion queue #1. - // 5th 4kB boundary is the start of the first PRP list page. - // 6th 4kB boundary is the start of the second PRP list page. - // - UINT8 *Buffer; - UINT8 *BufferPciAddr; - - // - // Pointers to 4kB aligned submission & completion queues. - // - NVME_SQ *SqBuffer[NVME_MAX_QUEUES]; - NVME_CQ *CqBuffer[NVME_MAX_QUEUES]; - NVME_SQ *SqBufferPciAddr[NVME_MAX_QUEUES]; - NVME_CQ *CqBufferPciAddr[NVME_MAX_QUEUES]; - - // - // Submission and completion queue indices. - // - NVME_SQTDBL SqTdbl[NVME_MAX_QUEUES]; - NVME_CQHDBL CqHdbl[NVME_MAX_QUEUES]; - - UINT8 Pt[NVME_MAX_QUEUES]; - UINT16 Cid[NVME_MAX_QUEUES]; - - // - // Nvme controller capabilities - // - NVME_CAP Cap; - - VOID *Mapping; -}; - -#define NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU(a) \ - CR (a, \ - NVME_CONTROLLER_PRIVATE_DATA, \ - Passthru, \ - NVME_CONTROLLER_PRIVATE_DATA_SIGNATURE \ - ) - -// -// Unique signature for private data structure. -// -#define NVME_DEVICE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('X','S','S','D') - -// -// Nvme device private data structure -// -struct _NVME_DEVICE_PRIVATE_DATA { - UINT32 Signature; - - EFI_HANDLE DeviceHandle; - EFI_HANDLE ControllerHandle; - EFI_HANDLE DriverBindingHandle; - - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - - UINT32 NamespaceId; - UINT64 NamespaceUuid; - - EFI_BLOCK_IO_MEDIA Media; - EFI_BLOCK_IO_PROTOCOL BlockIo; - EFI_DISK_INFO_PROTOCOL DiskInfo; - EFI_STORAGE_SECURITY_COMMAND_PROTOCOL StorageSecurity; - - EFI_LBA NumBlocks; - - CHAR16 ModelName[80]; - NVME_ADMIN_NAMESPACE_DATA NamespaceData; - - NVME_CONTROLLER_PRIVATE_DATA *Controller; - -}; - -// -// Statments to retrieve the private data from produced protocols. -// -#define NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO(a) \ - CR (a, \ - NVME_DEVICE_PRIVATE_DATA, \ - BlockIo, \ - NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ - ) - -#define NVME_DEVICE_PRIVATE_DATA_FROM_DISK_INFO(a) \ - CR (a, \ - NVME_DEVICE_PRIVATE_DATA, \ - DiskInfo, \ - NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ - ) - -#define NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY(a)\ - CR (a, \ - NVME_DEVICE_PRIVATE_DATA, \ - StorageSecurity, \ - NVME_DEVICE_PRIVATE_DATA_SIGNATURE \ - ) - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -NvmExpressComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -NvmExpressComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -/** - Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function supports - both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the nonblocking - I/O functionality is optional. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] NamespaceId Is a 32 bit Namespace ID to which the Express HCI command packet will be sent. - A value of 0 denotes the NVM Express controller, a value of all 0FFh in the namespace - ID specifies that the command packet should be sent to all valid namespaces. - @param[in,out] Packet A pointer to the NVM Express HCI Command Packet to send to the NVMe namespace specified - by NamespaceId. - @param[in] Event If nonblocking I/O is not supported then Event is ignored, and blocking I/O is performed. - If Event is NULL, then blocking I/O is performed. If Event is not NULL and non blocking I/O - is supported, then nonblocking I/O is performed, and Event will be signaled when the NVM - Express Command Packet completes. - - @retval EFI_SUCCESS The NVM Express Command Packet was sent by the host. TransferLength bytes were transferred - to, or from DataBuffer. - @retval EFI_BAD_BUFFER_SIZE The NVM Express Command Packet was not executed. The number of bytes that could be transferred - is returned in TransferLength. - @retval EFI_NOT_READY The NVM Express Command Packet could not be sent because the controller is not ready. The caller - may retry again later. - @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the NVM Express Command Packet. - @retval EFI_INVALID_PARAMETER Namespace, or the contents of EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM - Express Command Packet was not sent, so no additional status information is available. - @retval EFI_UNSUPPORTED The command described by the NVM Express Command Packet is not supported by the host adapter. - The NVM Express Command Packet was not sent, so no additional status information is available. - @retval EFI_TIMEOUT A timeout occurred while waiting for the NVM Express Command Packet to execute. - -**/ -EFI_STATUS -EFIAPI -NvmExpressPassThru ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet, - IN EFI_EVENT Event OPTIONAL - ); - -/** - Used to retrieve the next namespace ID for this NVM Express controller. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNextNamespace() function retrieves the next valid - namespace ID on this NVM Express controller. - - If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the first valid namespace - ID defined on the NVM Express controller is returned in the location pointed to by NamespaceId - and a status of EFI_SUCCESS is returned. - - If on input the value pointed to by NamespaceId is an invalid namespace ID other than 0xFFFFFFFF, - then EFI_INVALID_PARAMETER is returned. - - If on input the value pointed to by NamespaceId is a valid namespace ID, then the next valid - namespace ID on the NVM Express controller is returned in the location pointed to by NamespaceId, - and EFI_SUCCESS is returned. - - If the value pointed to by NamespaceId is the namespace ID of the last namespace on the NVM - Express controller, then EFI_NOT_FOUND is returned. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in,out] NamespaceId On input, a pointer to a legal NamespaceId for an NVM Express - namespace present on the NVM Express controller. On output, a - pointer to the next NamespaceId of an NVM Express namespace on - an NVM Express controller. An input value of 0xFFFFFFFF retrieves - the first NamespaceId for an NVM Express namespace present on an - NVM Express controller. - - @retval EFI_SUCCESS The Namespace ID of the next Namespace was returned. - @retval EFI_NOT_FOUND There are no more namespaces defined on this controller. - @retval EFI_INVALID_PARAMETER NamespaceId is an invalid value other than 0xFFFFFFFF. - -**/ -EFI_STATUS -EFIAPI -NvmExpressGetNextNamespace ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN OUT UINT32 *NamespaceId - ); - -/** - Used to translate a device path node to a namespace ID. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNamespace() function determines the namespace ID associated with the - namespace described by DevicePath. - - If DevicePath is a device path node type that the NVM Express Pass Thru driver supports, then the NVM Express - Pass Thru driver will attempt to translate the contents DevicePath into a namespace ID. - - If this translation is successful, then that namespace ID is returned in NamespaceId, and EFI_SUCCESS is returned - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] DevicePath A pointer to the device path node that describes an NVM Express namespace on - the NVM Express controller. - @param[out] NamespaceId The NVM Express namespace ID contained in the device path node. - - @retval EFI_SUCCESS DevicePath was successfully translated to NamespaceId. - @retval EFI_INVALID_PARAMETER If DevicePath or NamespaceId are NULL, then EFI_INVALID_PARAMETER is returned. - @retval EFI_UNSUPPORTED If DevicePath is not a device path node type that the NVM Express Pass Thru driver - supports, then EFI_UNSUPPORTED is returned. - @retval EFI_NOT_FOUND If DevicePath is a device path node type that the NVM Express Pass Thru driver - supports, but there is not a valid translation from DevicePath to a namespace ID, - then EFI_NOT_FOUND is returned. -**/ -EFI_STATUS -EFIAPI -NvmExpressGetNamespace ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT UINT32 *NamespaceId - ); - -/** - Used to allocate and build a device path node for an NVM Express namespace on an NVM Express controller. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.BuildDevicePath() function allocates and builds a single device - path node for the NVM Express namespace specified by NamespaceId. - - If the NamespaceId is not valid, then EFI_NOT_FOUND is returned. - - If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned. - - If there are not enough resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned. - - Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of DevicePath are - initialized to describe the NVM Express namespace specified by NamespaceId, and EFI_SUCCESS is returned. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - @param[in,out] DevicePath A pointer to a single device path node that describes the NVM Express - namespace specified by NamespaceId. This function is responsible for - allocating the buffer DevicePath with the boot service AllocatePool(). - It is the caller's responsibility to free DevicePath when the caller - is finished with DevicePath. - @retval EFI_SUCCESS The device path node that describes the NVM Express namespace specified - by NamespaceId was allocated and returned in DevicePath. - @retval EFI_NOT_FOUND The NamespaceId is not valid. - @retval EFI_INVALID_PARAMETER DevicePath is NULL. - @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the DevicePath node. - -**/ -EFI_STATUS -EFIAPI -NvmExpressBuildDevicePath ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.c deleted file mode 100644 index 6cb2f92e8d..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.c +++ /dev/null @@ -1,883 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "NvmExpress.h" - -/** - Read some sectors from the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - @param Buffer The buffer used to store the data read from the device. - @param Lba The start block number. - @param Blocks Total block number to be read. - - @retval EFI_SUCCESS Datum are read from the device. - @retval Others Fail to read all the datum. - -**/ -EFI_STATUS -ReadSectors ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN UINT64 Buffer, - IN UINT64 Lba, - IN UINT32 Blocks - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - UINT32 Bytes; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - UINT32 BlockSize; - - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - Bytes = Blocks * BlockSize; - - ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_READ_OPC; - CommandPacket.NvmeCmd->Nsid = Device->NamespaceId; - CommandPacket.TransferBuffer = (VOID *)(UINTN)Buffer; - - CommandPacket.TransferLength = Bytes; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_IO_QUEUE; - - CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba; - CommandPacket.NvmeCmd->Cdw11 = (UINT32)(Lba >> 32); - CommandPacket.NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF; - - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - Device->NamespaceId, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Write some sectors to the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - @param Buffer The buffer to be written into the device. - @param Lba The start block number. - @param Blocks Total block number to be written. - - @retval EFI_SUCCESS Datum are written into the buffer. - @retval Others Fail to write all the datum. - -**/ -EFI_STATUS -WriteSectors ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN UINT64 Buffer, - IN UINT64 Lba, - IN UINT32 Blocks - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - UINT32 Bytes; - UINT32 BlockSize; - - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - Bytes = Blocks * BlockSize; - - ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_WRITE_OPC; - CommandPacket.NvmeCmd->Nsid = Device->NamespaceId; - CommandPacket.TransferBuffer = (VOID *)(UINTN)Buffer; - - CommandPacket.TransferLength = Bytes; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_IO_QUEUE; - - CommandPacket.NvmeCmd->Cdw10 = (UINT32)Lba; - CommandPacket.NvmeCmd->Cdw11 = (UINT32)(Lba >> 32); - CommandPacket.NvmeCmd->Cdw12 = (Blocks - 1) & 0xFFFF; - - CommandPacket.MetadataBuffer = NULL; - CommandPacket.MetadataLength = 0; - - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID | CDW12_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - Device->NamespaceId, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Read some blocks from the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - @param Buffer The buffer used to store the data read from the device. - @param Lba The start block number. - @param Blocks Total block number to be read. - - @retval EFI_SUCCESS Datum are read from the device. - @retval Others Fail to read all the datum. - -**/ -EFI_STATUS -NvmeRead ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - OUT VOID *Buffer, - IN UINT64 Lba, - IN UINTN Blocks - ) -{ - EFI_STATUS Status; - UINT32 BlockSize; - NVME_CONTROLLER_PRIVATE_DATA *Private; - UINT32 MaxTransferBlocks; - UINTN OrginalBlocks; - - Status = EFI_SUCCESS; - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - OrginalBlocks = Blocks; - - if (Private->ControllerData->Mdts != 0) { - MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize; - } else { - MaxTransferBlocks = 1024; - } - - while (Blocks > 0) { - if (Blocks > MaxTransferBlocks) { - Status = ReadSectors (Device, (UINT64)(UINTN)Buffer, Lba, MaxTransferBlocks); - - Blocks -= MaxTransferBlocks; - Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize); - Lba += MaxTransferBlocks; - } else { - Status = ReadSectors (Device, (UINT64)(UINTN)Buffer, Lba, (UINT32)Blocks); - Blocks = 0; - } - - if (EFI_ERROR(Status)) { - break; - } - } - - DEBUG ((EFI_D_INFO, "NvmeRead() Lba = 0x%08x, Original = 0x%08x, Remaining = 0x%08x, BlockSize = 0x%x Status = %r\n", Lba, OrginalBlocks, Blocks, BlockSize, Status)); - - return Status; -} - -/** - Write some blocks to the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - @param Buffer The buffer to be written into the device. - @param Lba The start block number. - @param Blocks Total block number to be written. - - @retval EFI_SUCCESS Datum are written into the buffer. - @retval Others Fail to write all the datum. - -**/ -EFI_STATUS -NvmeWrite ( - IN NVME_DEVICE_PRIVATE_DATA *Device, - IN VOID *Buffer, - IN UINT64 Lba, - IN UINTN Blocks - ) -{ - EFI_STATUS Status; - UINT32 BlockSize; - NVME_CONTROLLER_PRIVATE_DATA *Private; - UINT32 MaxTransferBlocks; - UINTN OrginalBlocks; - - Status = EFI_SUCCESS; - Private = Device->Controller; - BlockSize = Device->Media.BlockSize; - OrginalBlocks = Blocks; - - if (Private->ControllerData->Mdts != 0) { - MaxTransferBlocks = (1 << (Private->ControllerData->Mdts)) * (1 << (Private->Cap.Mpsmin + 12)) / BlockSize; - } else { - MaxTransferBlocks = 1024; - } - - while (Blocks > 0) { - if (Blocks > MaxTransferBlocks) { - Status = WriteSectors (Device, (UINT64)(UINTN)Buffer, Lba, MaxTransferBlocks); - - Blocks -= MaxTransferBlocks; - Buffer = (VOID *)(UINTN)((UINT64)(UINTN)Buffer + MaxTransferBlocks * BlockSize); - Lba += MaxTransferBlocks; - } else { - Status = WriteSectors (Device, (UINT64)(UINTN)Buffer, Lba, (UINT32)Blocks); - Blocks = 0; - } - - if (EFI_ERROR(Status)) { - break; - } - } - - DEBUG ((EFI_D_INFO, "NvmeWrite() Lba = 0x%08x, Original = 0x%08x, Remaining = 0x%08x, BlockSize = 0x%x Status = %r\n", Lba, OrginalBlocks, Blocks, BlockSize, Status)); - - return Status; -} - -/** - Flushes all modified data to the device. - - @param Device The pointer to the NVME_DEVICE_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS Datum are written into the buffer. - @retval Others Fail to write all the datum. - -**/ -EFI_STATUS -NvmeFlush ( - IN NVME_DEVICE_PRIVATE_DATA *Device - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - - Private = Device->Controller; - - ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - CommandPacket.NvmeCmd->Cdw0.Opcode = NVME_IO_FLUSH_OPC; - CommandPacket.NvmeCmd->Nsid = Device->NamespaceId; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_IO_QUEUE; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - Device->NamespaceId, - &CommandPacket, - NULL - ); - - return Status; -} - - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - EFI_TPL OldTpl; - NVME_CONTROLLER_PRIVATE_DATA *Private; - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // For Nvm Express subsystem, reset block device means reset controller. - // - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - Private = Device->Controller; - - Status = NvmeControllerInit (Private); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if (IoAlign > 0 && (((UINTN) Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - Status = NvmeRead (Device, Buffer, Lba, NumberOfBlocks); - - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_BLOCK_IO_MEDIA *Media; - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN IoAlign; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Media = This->Media; - - if (MediaId != Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (BufferSize == 0) { - return EFI_SUCCESS; - } - - BlockSize = Media->BlockSize; - if ((BufferSize % BlockSize) != 0) { - return EFI_BAD_BUFFER_SIZE; - } - - NumberOfBlocks = BufferSize / BlockSize; - if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { - return EFI_INVALID_PARAMETER; - } - - IoAlign = Media->IoAlign; - if (IoAlign > 0 && (((UINTN) Buffer & (IoAlign - 1)) != 0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - Status = NvmeWrite (Device, Buffer, Lba, NumberOfBlocks); - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device. - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data. - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -{ - NVME_DEVICE_PRIVATE_DATA *Device; - EFI_STATUS Status; - EFI_TPL OldTpl; - - // - // Check parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_BLOCK_IO (This); - - Status = NvmeFlush (Device); - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Trust transfer data from/to NVMe device. - - This function performs one NVMe transaction to do a trust transfer from/to NVMe device. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Buffer The pointer to the current transaction buffer. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param TransferLength The block number or sector count of the transfer. - @param IsTrustSend Indicates whether it is a trust send operation or not. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param TransferLengthOut A pointer to a buffer to store the size in bytes of the data - written to the buffer. Ignore it when IsTrustSend is TRUE. - - @retval EFI_SUCCESS The data transfer is complete successfully. - @return others Some error occurs when transferring data. - -**/ -EFI_STATUS -TrustTransferNvmeDevice ( - IN OUT NVME_CONTROLLER_PRIVATE_DATA *Private, - IN OUT VOID *Buffer, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN TransferLength, - IN BOOLEAN IsTrustSend, - IN UINT64 Timeout, - OUT UINTN *TransferLengthOut - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - UINT16 SpecificData; - - ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof (EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - // - // Change Endianness of SecurityProtocolSpecificData - // - SpecificData = (((SecurityProtocolSpecificData << 8) & 0xFF00) | (SecurityProtocolSpecificData >> 8)); - - if (IsTrustSend) { - Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_SEND_CMD; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = (UINT32)TransferLength; - CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8)); - CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength; - } else { - Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_RECEIVE_CMD; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = (UINT32)TransferLength; - CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8)); - CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength; - } - - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID; - CommandPacket.NvmeCmd->Nsid = NVME_CONTROLLER_ID; - CommandPacket.CommandTimeout = Timeout; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - NVME_CONTROLLER_ID, - &CommandPacket, - NULL - ); - - if (!IsTrustSend) { - if (EFI_ERROR (Status)) { - *TransferLengthOut = 0; - } else { - *TransferLengthOut = (UINTN) TransferLength; - } - } - - return Status; -} - -/** - Send a security protocol command to a device that receives data and/or the result - of one or more commands sent by SendData. - - The ReceiveData function sends a security protocol command to the given MediaId. - The security protocol command sent is defined by SecurityProtocolId and contains - the security protocol specific data SecurityProtocolSpecificData. The function - returns the data from the security protocol command in PayloadBuffer. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL IN command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. - - If the PayloadBufferSize is zero, the security protocol command is sent using the - Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBufferSize is too small to store the available data from the security - protocol command, the function shall copy PayloadBufferSize bytes into the - PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. - - If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, - the function shall return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function shall - return EFI_UNSUPPORTED. If there is no media in the device, the function returns - EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, - the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall - return EFI_SUCCESS. If the security protocol command completes with an error, the - function shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the - data written to the payload data buffer. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available - data from the device. The PayloadBuffer contains the truncated data. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and - PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -NvmeStorageSecurityReceiveData ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - OUT UINTN *PayloadTransferSize - ) -{ - EFI_STATUS Status; - NVME_DEVICE_PRIVATE_DATA *Device; - - Status = EFI_SUCCESS; - - if ((PayloadBuffer == NULL) || (PayloadTransferSize == NULL) || (PayloadBufferSize == 0)) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY (This); - - if (MediaId != Device->BlockIo.Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (!Device->BlockIo.Media->MediaPresent) { - return EFI_NO_MEDIA; - } - - Status = TrustTransferNvmeDevice ( - Device->Controller, - PayloadBuffer, - SecurityProtocolId, - SecurityProtocolSpecificData, - PayloadBufferSize, - FALSE, - Timeout, - PayloadTransferSize - ); - - return Status; -} - -/** - Send a security protocol command to a device. - - The SendData function sends a security protocol command containing the payload - PayloadBuffer to the given MediaId. The security protocol command sent is - defined by SecurityProtocolId and contains the security protocol specific data - SecurityProtocolSpecificData. If the underlying protocol command requires a - specific padding for the command payload, the SendData function shall add padding - bytes to the command payload to satisfy the padding requirements. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL OUT command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. If the PayloadBufferSize is zero, the security protocol command is - sent using the Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall - return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function - shall return EFI_UNSUPPORTED. If there is no media in the device, the function - returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the - device, the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall return - EFI_SUCCESS. If the security protocol command completes with an error, the function - shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the send data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -NvmeStorageSecuritySendData ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - IN VOID *PayloadBuffer - ) -{ - EFI_STATUS Status; - NVME_DEVICE_PRIVATE_DATA *Device; - - Status = EFI_SUCCESS; - - if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) { - return EFI_INVALID_PARAMETER; - } - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY (This); - - if (MediaId != Device->BlockIo.Media->MediaId) { - return EFI_MEDIA_CHANGED; - } - - if (!Device->BlockIo.Media->MediaPresent) { - return EFI_NO_MEDIA; - } - - Status = TrustTransferNvmeDevice ( - Device->Controller, - PayloadBuffer, - SecurityProtocolId, - SecurityProtocolSpecificData, - PayloadBufferSize, - TRUE, - Timeout, - NULL - ); - - return Status; -} - - - - diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.h deleted file mode 100644 index 1c71a81ec5..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressBlockIo.h +++ /dev/null @@ -1,269 +0,0 @@ -/** @file - Header file for EFI_BLOCK_IO_PROTOCOL interface. - -Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_NVME_BLOCKIO_H_ -#define _EFI_NVME_BLOCKIO_H_ - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoReadBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoWriteBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writing back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -NvmeBlockIoFlushBlocks ( - IN EFI_BLOCK_IO_PROTOCOL *This - ); - -/** - Send a security protocol command to a device that receives data and/or the result - of one or more commands sent by SendData. - - The ReceiveData function sends a security protocol command to the given MediaId. - The security protocol command sent is defined by SecurityProtocolId and contains - the security protocol specific data SecurityProtocolSpecificData. The function - returns the data from the security protocol command in PayloadBuffer. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL IN command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. - - If the PayloadBufferSize is zero, the security protocol command is sent using the - Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBufferSize is too small to store the available data from the security - protocol command, the function shall copy PayloadBufferSize bytes into the - PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL. - - If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero, - the function shall return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function shall - return EFI_UNSUPPORTED. If there is no media in the device, the function returns - EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device, - the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall - return EFI_SUCCESS. If the security protocol command completes with an error, the - function shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. The caller is responsible for having - either implicit or explicit ownership of the buffer. - @param PayloadTransferSize A pointer to a buffer to store the size in bytes of the - data written to the payload data buffer. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available - data from the device. The PayloadBuffer contains the truncated data. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and - PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -NvmeStorageSecurityReceiveData ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - OUT VOID *PayloadBuffer, - OUT UINTN *PayloadTransferSize - ); - -/** - Send a security protocol command to a device. - - The SendData function sends a security protocol command containing the payload - PayloadBuffer to the given MediaId. The security protocol command sent is - defined by SecurityProtocolId and contains the security protocol specific data - SecurityProtocolSpecificData. If the underlying protocol command requires a - specific padding for the command payload, the SendData function shall add padding - bytes to the command payload to satisfy the padding requirements. - - For devices supporting the SCSI command set, the security protocol command is sent - using the SECURITY PROTOCOL OUT command defined in SPC-4. - - For devices supporting the ATA command set, the security protocol command is sent - using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize - is non-zero. If the PayloadBufferSize is zero, the security protocol command is - sent using the Trusted Non-Data command defined in ATA8-ACS. - - If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall - return EFI_INVALID_PARAMETER. - - If the given MediaId does not support security protocol commands, the function - shall return EFI_UNSUPPORTED. If there is no media in the device, the function - returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the - device, the function returns EFI_MEDIA_CHANGED. - - If the security protocol fails to complete within the Timeout period, the function - shall return EFI_TIMEOUT. - - If the security protocol command completes without an error, the function shall return - EFI_SUCCESS. If the security protocol command completes with an error, the function - shall return EFI_DEVICE_ERROR. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to receive data from. - @param Timeout The timeout, in 100ns units, to use for the execution - of the security protocol command. A Timeout value of 0 - means that this function will wait indefinitely for the - security protocol command to execute. If Timeout is greater - than zero, then this function will return EFI_TIMEOUT - if the time required to execute the receive data command - is greater than Timeout. - @param SecurityProtocolId The value of the "Security Protocol" parameter of - the security protocol command to be sent. - @param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter - of the security protocol command to be sent. - @param PayloadBufferSize Size in bytes of the payload data buffer. - @param PayloadBuffer A pointer to a destination buffer to store the security - protocol command specific payload data for the security - protocol command. - - @retval EFI_SUCCESS The security protocol command completed successfully. - @retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands. - @retval EFI_DEVICE_ERROR The security protocol command completed with an error. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. - @retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero. - @retval EFI_TIMEOUT A timeout occurred while waiting for the security - protocol command to execute. - -**/ -EFI_STATUS -EFIAPI -NvmeStorageSecuritySendData ( - IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Timeout, - IN UINT8 SecurityProtocolId, - IN UINT16 SecurityProtocolSpecificData, - IN UINTN PayloadBufferSize, - IN VOID *PayloadBuffer - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.c deleted file mode 100644 index ea108a851d..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.c +++ /dev/null @@ -1,162 +0,0 @@ -/** @file - This file is used to implement the EFI_DISK_INFO_PROTOCOL interface.. - - Copyright (c) 2013, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "NvmExpress.h" - -EFI_DISK_INFO_PROTOCOL gNvmExpressDiskInfoProtocolTemplate = { - EFI_DISK_INFO_NVME_INTERFACE_GUID, - NvmExpressDiskInfoInquiry, - NvmExpressDiskInfoIdentify, - NvmExpressDiskInfoSenseData, - NvmExpressDiskInfoWhichIde -}; - -/** - Initialize the installation of DiskInfo protocol. - - This function prepares for the installation of DiskInfo protocol on the child handle. - By default, it installs DiskInfo protocol with NVME interface GUID. - - @param[in] Device The pointer of NVME_DEVICE_PRIVATE_DATA. - -**/ -VOID -InitializeDiskInfo ( - IN NVME_DEVICE_PRIVATE_DATA *Device - ) -{ - CopyMem (&Device->DiskInfo, &gNvmExpressDiskInfoProtocolTemplate, sizeof (EFI_DISK_INFO_PROTOCOL)); -} - - -/** - Provides inquiry information for the controller type. - - This function is used to get inquiry data. Data format - of Identify data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[in, out] InquiryData Pointer to a buffer for the inquiry data. - @param[in, out] InquiryDataSize Pointer to the value for the inquiry data size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading InquiryData from device - @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoInquiry ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *InquiryData, - IN OUT UINT32 *InquiryDataSize - ) -{ - return EFI_NOT_FOUND; -} - - -/** - Provides identify information for the controller type. - - This function is used to get identify data. Data format - of Identify data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL - instance. - @param[in, out] IdentifyData Pointer to a buffer for the identify data. - @param[in, out] IdentifyDataSize Pointer to the value for the identify data - size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading IdentifyData from device - @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoIdentify ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *IdentifyData, - IN OUT UINT32 *IdentifyDataSize - ) -{ - EFI_STATUS Status; - NVME_DEVICE_PRIVATE_DATA *Device; - - Device = NVME_DEVICE_PRIVATE_DATA_FROM_DISK_INFO (This); - - Status = EFI_BUFFER_TOO_SMALL; - if (*IdentifyDataSize >= sizeof (Device->NamespaceData)) { - Status = EFI_SUCCESS; - CopyMem (IdentifyData, &Device->NamespaceData, sizeof (Device->NamespaceData)); - } - *IdentifyDataSize = sizeof (Device->NamespaceData); - return Status; -} - -/** - Provides sense data information for the controller type. - - This function is used to get sense data. - Data format of Sense data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[in, out] SenseData Pointer to the SenseData. - @param[in, out] SenseDataSize Size of SenseData in bytes. - @param[out] SenseDataNumber Pointer to the value for the sense data size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class. - @retval EFI_DEVICE_ERROR Error reading SenseData from device. - @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoSenseData ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *SenseData, - IN OUT UINT32 *SenseDataSize, - OUT UINT8 *SenseDataNumber - ) -{ - return EFI_NOT_FOUND; -} - - -/** - This function is used to get controller information. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary. - @param[out] IdeDevice Pointer to the Ide Device number. Master or slave. - - @retval EFI_SUCCESS IdeChannel and IdeDevice are valid. - @retval EFI_UNSUPPORTED This is not an IDE device. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoWhichIde ( - IN EFI_DISK_INFO_PROTOCOL *This, - OUT UINT32 *IdeChannel, - OUT UINT32 *IdeDevice - ) -{ - return EFI_UNSUPPORTED; -} - diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.h deleted file mode 100644 index f07cfe3474..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDiskInfo.h +++ /dev/null @@ -1,129 +0,0 @@ -/** @file - Header file for EFI_DISK_INFO_PROTOCOL interface. - -Copyright (c) 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _NVME_DISKINFO_H_ -#define _NVME_DISKINFO_H_ - -/** - Initialize the installation of DiskInfo protocol. - - This function prepares for the installation of DiskInfo protocol on the child handle. - By default, it installs DiskInfo protocol with NVME interface GUID. - - @param[in] Device The pointer of NVME_DEVICE_PRIVATE_DATA. - -**/ -VOID -InitializeDiskInfo ( - IN NVME_DEVICE_PRIVATE_DATA *Device - ); - - -/** - Provides inquiry information for the controller type. - - This function is used to get inquiry data. Data format - of Identify data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[in, out] InquiryData Pointer to a buffer for the inquiry data. - @param[in, out] InquiryDataSize Pointer to the value for the inquiry data size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading InquiryData from device - @retval EFI_BUFFER_TOO_SMALL InquiryDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoInquiry ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *InquiryData, - IN OUT UINT32 *InquiryDataSize - ); - -/** - Provides identify information for the controller type. - - This function is used to get identify data. Data format - of Identify data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL - instance. - @param[in, out] IdentifyData Pointer to a buffer for the identify data. - @param[in, out] IdentifyDataSize Pointer to the value for the identify data - size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class - @retval EFI_DEVICE_ERROR Error reading IdentifyData from device - @retval EFI_BUFFER_TOO_SMALL IdentifyDataSize not big enough - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoIdentify ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *IdentifyData, - IN OUT UINT32 *IdentifyDataSize - ); - -/** - Provides sense data information for the controller type. - - This function is used to get sense data. - Data format of Sense data is defined by the Interface GUID. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[in, out] SenseData Pointer to the SenseData. - @param[in, out] SenseDataSize Size of SenseData in bytes. - @param[out] SenseDataNumber Pointer to the value for the sense data size. - - @retval EFI_SUCCESS The command was accepted without any errors. - @retval EFI_NOT_FOUND Device does not support this data class. - @retval EFI_DEVICE_ERROR Error reading SenseData from device. - @retval EFI_BUFFER_TOO_SMALL SenseDataSize not big enough. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoSenseData ( - IN EFI_DISK_INFO_PROTOCOL *This, - IN OUT VOID *SenseData, - IN OUT UINT32 *SenseDataSize, - OUT UINT8 *SenseDataNumber - ); - - -/** - This function is used to get controller information. - - @param[in] This Pointer to the EFI_DISK_INFO_PROTOCOL instance. - @param[out] IdeChannel Pointer to the Ide Channel number. Primary or secondary. - @param[out] IdeDevice Pointer to the Ide Device number. Master or slave. - - @retval EFI_SUCCESS IdeChannel and IdeDevice are valid. - @retval EFI_UNSUPPORTED This is not an IDE device. - -**/ -EFI_STATUS -EFIAPI -NvmExpressDiskInfoWhichIde ( - IN EFI_DISK_INFO_PROTOCOL *This, - OUT UINT32 *IdeChannel, - OUT UINT32 *IdeDevice - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf deleted file mode 100644 index 00acf2b5cf..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf +++ /dev/null @@ -1,79 +0,0 @@ -## @file -# NVM Express Host Controller Module. -# -# NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows -# NVM Express specification. -# -# Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = NvmExpressDxe - MODULE_UNI_FILE = NvmExpressDxe.uni - FILE_GUID = 5BE3BDF4-53CF-46a3-A6A9-73C34A6E5EE3 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = NvmExpressDriverEntry - UNLOAD_IMAGE = NvmExpressUnload - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# -# DRIVER_BINDING = gNvmExpressDriverBinding -# COMPONENT_NAME = gNvmExpressComponentName -# COMPONENT_NAME2 = gNvmExpressComponentName2 - -[Sources] - NvmExpressBlockIo.c - NvmExpressBlockIo.h - ComponentName.c - NvmExpress.c - NvmExpress.h - NvmExpressDiskInfo.c - NvmExpressDiskInfo.h - NvmExpressHci.c - NvmExpressHci.h - NvmExpressPassthru.c - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseMemoryLib - BaseLib - DebugLib - DevicePathLib - MemoryAllocationLib - UefiDriverEntryPoint - UefiBootServicesTableLib - UefiLib - PrintLib - -[Protocols] - gEfiPciIoProtocolGuid ## TO_START - ## BY_START - ## TO_START - gEfiDevicePathProtocolGuid - gEfiNvmExpressPassThruProtocolGuid ## BY_START - gEfiBlockIoProtocolGuid ## BY_START - gEfiDiskInfoProtocolGuid ## BY_START - gEfiStorageSecurityCommandProtocolGuid ## BY_START - gEfiDriverSupportedEfiVersionProtocolGuid ## PRODUCES - -# [Event] -# EVENT_TYPE_RELATIVE_TIMER ## SOMETIMES_CONSUMES -# - -[UserExtensions.TianoCore."ExtraFiles"] - NvmExpressDxeExtra.uni \ No newline at end of file diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.uni b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.uni deleted file mode 100644 index 36fbc2acfe..0000000000 Binary files a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxeExtra.uni b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxeExtra.uni deleted file mode 100644 index 2f8bf5922d..0000000000 Binary files a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxeExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c deleted file mode 100644 index f6b6288f65..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.c +++ /dev/null @@ -1,981 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "NvmExpress.h" - -/** - Read Nvm Express controller capability register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Cap The buffer used to store capability register content. - - @return EFI_SUCCESS Successfully read the controller capability register content. - @return EFI_DEVICE_ERROR Fail to read the controller capability register. - -**/ -EFI_STATUS -ReadNvmeControllerCapabilities ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_CAP *Cap - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT64 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CAP_OFFSET, - 2, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - WriteUnaligned64 ((UINT64*)Cap, Data); - return EFI_SUCCESS; -} - -/** - Read Nvm Express controller configuration register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Cc The buffer used to store configuration register content. - - @return EFI_SUCCESS Successfully read the controller configuration register content. - @return EFI_DEVICE_ERROR Fail to read the controller configuration register. - -**/ -EFI_STATUS -ReadNvmeControllerConfiguration ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_CC *Cc - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CC_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - WriteUnaligned32 ((UINT32*)Cc, Data); - return EFI_SUCCESS; -} - -/** - Write Nvm Express controller configuration register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Cc The buffer used to store the content to be written into configuration register. - - @return EFI_SUCCESS Successfully write data into the controller configuration register. - @return EFI_DEVICE_ERROR Fail to write data into the controller configuration register. - -**/ -EFI_STATUS -WriteNvmeControllerConfiguration ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_CC *Cc - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Data = ReadUnaligned32 ((UINT32*)Cc); - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CC_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - DEBUG ((EFI_D_INFO, "Cc.En: %d\n", Cc->En)); - DEBUG ((EFI_D_INFO, "Cc.Css: %d\n", Cc->Css)); - DEBUG ((EFI_D_INFO, "Cc.Mps: %d\n", Cc->Mps)); - DEBUG ((EFI_D_INFO, "Cc.Ams: %d\n", Cc->Ams)); - DEBUG ((EFI_D_INFO, "Cc.Shn: %d\n", Cc->Shn)); - DEBUG ((EFI_D_INFO, "Cc.Iosqes: %d\n", Cc->Iosqes)); - DEBUG ((EFI_D_INFO, "Cc.Iocqes: %d\n", Cc->Iocqes)); - - return EFI_SUCCESS; -} - -/** - Read Nvm Express controller status register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Csts The buffer used to store status register content. - - @return EFI_SUCCESS Successfully read the controller status register content. - @return EFI_DEVICE_ERROR Fail to read the controller status register. - -**/ -EFI_STATUS -ReadNvmeControllerStatus ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_CSTS *Csts - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CSTS_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - WriteUnaligned32 ((UINT32*)Csts, Data); - return EFI_SUCCESS; -} - -/** - Read Nvm Express admin queue attributes register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Aqa The buffer used to store admin queue attributes register content. - - @return EFI_SUCCESS Successfully read the admin queue attributes register content. - @return EFI_DEVICE_ERROR Fail to read the admin queue attributes register. - -**/ -EFI_STATUS -ReadNvmeAdminQueueAttributes ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_AQA *Aqa - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_AQA_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - WriteUnaligned32 ((UINT32*)Aqa, Data); - return EFI_SUCCESS; -} - -/** - Write Nvm Express admin queue attributes register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Aqa The buffer used to store the content to be written into admin queue attributes register. - - @return EFI_SUCCESS Successfully write data into the admin queue attributes register. - @return EFI_DEVICE_ERROR Fail to write data into the admin queue attributes register. - -**/ -EFI_STATUS -WriteNvmeAdminQueueAttributes ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_AQA *Aqa - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 Data; - - PciIo = Private->PciIo; - Data = ReadUnaligned32 ((UINT32*)Aqa); - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_AQA_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - DEBUG ((EFI_D_INFO, "Aqa.Asqs: %d\n", Aqa->Asqs)); - DEBUG ((EFI_D_INFO, "Aqa.Acqs: %d\n", Aqa->Acqs)); - - return EFI_SUCCESS; -} - -/** - Read Nvm Express admin submission queue base address register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Asq The buffer used to store admin submission queue base address register content. - - @return EFI_SUCCESS Successfully read the admin submission queue base address register content. - @return EFI_DEVICE_ERROR Fail to read the admin submission queue base address register. - -**/ -EFI_STATUS -ReadNvmeAdminSubmissionQueueBaseAddress ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_ASQ *Asq - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT64 Data; - - PciIo = Private->PciIo; - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_ASQ_OFFSET, - 2, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - WriteUnaligned64 ((UINT64*)Asq, Data); - return EFI_SUCCESS; -} - -/** - Write Nvm Express admin submission queue base address register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Asq The buffer used to store the content to be written into admin submission queue base address register. - - @return EFI_SUCCESS Successfully write data into the admin submission queue base address register. - @return EFI_DEVICE_ERROR Fail to write data into the admin submission queue base address register. - -**/ -EFI_STATUS -WriteNvmeAdminSubmissionQueueBaseAddress ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_ASQ *Asq - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT64 Data; - - PciIo = Private->PciIo; - Data = ReadUnaligned64 ((UINT64*)Asq); - - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_ASQ_OFFSET, - 2, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - DEBUG ((EFI_D_INFO, "Asq.Asqb: %lx\n", Asq->Asqb)); - - return EFI_SUCCESS; -} - -/** - Read Nvm Express admin completion queue base address register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Acq The buffer used to store admin completion queue base address register content. - - @return EFI_SUCCESS Successfully read the admin completion queue base address register content. - @return EFI_DEVICE_ERROR Fail to read the admin completion queue base address register. - -**/ -EFI_STATUS -ReadNvmeAdminCompletionQueueBaseAddress ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_ACQ *Acq - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT64 Data; - - PciIo = Private->PciIo; - - Status = PciIo->Mem.Read ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_ACQ_OFFSET, - 2, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - WriteUnaligned64 ((UINT64*)Acq, Data); - return EFI_SUCCESS; -} - -/** - Write Nvm Express admin completion queue base address register. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Acq The buffer used to store the content to be written into admin completion queue base address register. - - @return EFI_SUCCESS Successfully write data into the admin completion queue base address register. - @return EFI_DEVICE_ERROR Fail to write data into the admin completion queue base address register. - -**/ -EFI_STATUS -WriteNvmeAdminCompletionQueueBaseAddress ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN NVME_ACQ *Acq - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT64 Data; - - PciIo = Private->PciIo; - Data = ReadUnaligned64 ((UINT64*)Acq); - - Status = PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_ACQ_OFFSET, - 2, - &Data - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - DEBUG ((EFI_D_INFO, "Acq.Acqb: %lxh\n", Acq->Acqb)); - - return EFI_SUCCESS; -} - -/** - Disable the Nvm Express controller. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @return EFI_SUCCESS Successfully disable the controller. - @return EFI_DEVICE_ERROR Fail to disable the controller. - -**/ -EFI_STATUS -NvmeDisableController ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - NVME_CC Cc; - NVME_CSTS Csts; - EFI_STATUS Status; - UINT32 Index; - UINT8 Timeout; - - // - // Read Controller Configuration Register. - // - Status = ReadNvmeControllerConfiguration (Private, &Cc); - if (EFI_ERROR(Status)) { - return Status; - } - - Cc.En = 0; - - // - // Disable the controller. - // - Status = WriteNvmeControllerConfiguration (Private, &Cc); - - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Cap.To specifies max delay time in 500ms increments for Csts.Rdy to transition from 1 to 0 after - // Cc.Enable transition from 1 to 0. Loop produces a 1 millisecond delay per itteration, up to 500 * Cap.To. - // - if (Private->Cap.To == 0) { - Timeout = 1; - } else { - Timeout = Private->Cap.To; - } - - for(Index = (Timeout * 500); Index != 0; --Index) { - gBS->Stall(1000); - - // - // Check if the controller is initialized - // - Status = ReadNvmeControllerStatus (Private, &Csts); - - if (EFI_ERROR(Status)) { - return Status; - } - - if (Csts.Rdy == 0) { - break; - } - } - - if (Index == 0) { - Status = EFI_DEVICE_ERROR; - } - - DEBUG ((EFI_D_INFO, "NVMe controller is disabled with status [%r].\n", Status)); - return Status; -} - -/** - Enable the Nvm Express controller. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @return EFI_SUCCESS Successfully enable the controller. - @return EFI_DEVICE_ERROR Fail to enable the controller. - @return EFI_TIMEOUT Fail to enable the controller in given time slot. - -**/ -EFI_STATUS -NvmeEnableController ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - NVME_CC Cc; - NVME_CSTS Csts; - EFI_STATUS Status; - UINT32 Index; - UINT8 Timeout; - - // - // Enable the controller. - // CC.AMS, CC.MPS and CC.CSS are all set to 0. - // - ZeroMem (&Cc, sizeof (NVME_CC)); - Cc.En = 1; - Cc.Iosqes = 6; - Cc.Iocqes = 4; - - Status = WriteNvmeControllerConfiguration (Private, &Cc); - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Cap.To specifies max delay time in 500ms increments for Csts.Rdy to set after - // Cc.Enable. Loop produces a 1 millisecond delay per itteration, up to 500 * Cap.To. - // - if (Private->Cap.To == 0) { - Timeout = 1; - } else { - Timeout = Private->Cap.To; - } - - for(Index = (Timeout * 500); Index != 0; --Index) { - gBS->Stall(1000); - - // - // Check if the controller is initialized - // - Status = ReadNvmeControllerStatus (Private, &Csts); - - if (EFI_ERROR(Status)) { - return Status; - } - - if (Csts.Rdy) { - break; - } - } - - if (Index == 0) { - Status = EFI_TIMEOUT; - } - - DEBUG ((EFI_D_INFO, "NVMe controller is enabled with status [%r].\n", Status)); - return Status; -} - -/** - Get identify controller data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Buffer The buffer used to store the identify controller data. - - @return EFI_SUCCESS Successfully get the identify controller data. - @return EFI_DEVICE_ERROR Fail to get the identify controller data. - -**/ -EFI_STATUS -NvmeIdentifyController ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN VOID *Buffer - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - - ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION)); - - Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD; - // - // According to Nvm Express 1.1 spec Figure 38, When not used, the field shall be cleared to 0h. - // For the Identify command, the Namespace Identifier is only used for the Namespace data structure. - // - Command.Nsid = 0; - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = sizeof (NVME_ADMIN_CONTROLLER_DATA); - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - // - // Set bit 0 (Cns bit) to 1 to identify a controller - // - Command.Cdw10 = 1; - Command.Flags = CDW10_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - NVME_CONTROLLER_ID, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Get specified identify namespace data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param NamespaceId The specified namespace identifier. - @param Buffer The buffer used to store the identify namespace data. - - @return EFI_SUCCESS Successfully get the identify namespace data. - @return EFI_DEVICE_ERROR Fail to get the identify namespace data. - -**/ -EFI_STATUS -NvmeIdentifyNamespace ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 NamespaceId, - IN VOID *Buffer - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - - ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - Command.Cdw0.Opcode = NVME_ADMIN_IDENTIFY_CMD; - Command.Nsid = NamespaceId; - CommandPacket.TransferBuffer = Buffer; - CommandPacket.TransferLength = sizeof (NVME_ADMIN_NAMESPACE_DATA); - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - // - // Set bit 0 (Cns bit) to 1 to identify a namespace - // - CommandPacket.NvmeCmd->Cdw10 = 0; - CommandPacket.NvmeCmd->Flags = CDW10_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - NamespaceId, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Create io completion queue. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @return EFI_SUCCESS Successfully create io completion queue. - @return EFI_DEVICE_ERROR Fail to create io completion queue. - -**/ -EFI_STATUS -NvmeCreateIoCompletionQueue ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - NVME_ADMIN_CRIOCQ CrIoCq; - - ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION)); - ZeroMem (&CrIoCq, sizeof(NVME_ADMIN_CRIOCQ)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - Command.Cdw0.Opcode = NVME_ADMIN_CRIOCQ_CMD; - CommandPacket.TransferBuffer = Private->CqBufferPciAddr[1]; - CommandPacket.TransferLength = EFI_PAGE_SIZE; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - - CrIoCq.Qid = NVME_IO_QUEUE; - CrIoCq.Qsize = NVME_CCQ_SIZE; - CrIoCq.Pc = 1; - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoCq, sizeof (NVME_ADMIN_CRIOCQ)); - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - 0, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Create io submission queue. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @return EFI_SUCCESS Successfully create io submission queue. - @return EFI_DEVICE_ERROR Fail to create io submission queue. - -**/ -EFI_STATUS -NvmeCreateIoSubmissionQueue ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET CommandPacket; - EFI_NVM_EXPRESS_COMMAND Command; - EFI_NVM_EXPRESS_COMPLETION Completion; - EFI_STATUS Status; - NVME_ADMIN_CRIOSQ CrIoSq; - - ZeroMem (&CommandPacket, sizeof(EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); - ZeroMem (&Command, sizeof(EFI_NVM_EXPRESS_COMMAND)); - ZeroMem (&Completion, sizeof(EFI_NVM_EXPRESS_COMPLETION)); - ZeroMem (&CrIoSq, sizeof(NVME_ADMIN_CRIOSQ)); - - CommandPacket.NvmeCmd = &Command; - CommandPacket.NvmeCompletion = &Completion; - - Command.Cdw0.Opcode = NVME_ADMIN_CRIOSQ_CMD; - CommandPacket.TransferBuffer = Private->SqBufferPciAddr[1]; - CommandPacket.TransferLength = EFI_PAGE_SIZE; - CommandPacket.CommandTimeout = NVME_GENERIC_TIMEOUT; - CommandPacket.QueueType = NVME_ADMIN_QUEUE; - - CrIoSq.Qid = NVME_IO_QUEUE; - CrIoSq.Qsize = NVME_CSQ_SIZE; - CrIoSq.Pc = 1; - CrIoSq.Cqid = NVME_IO_QUEUE; - CrIoSq.Qprio = 0; - CopyMem (&CommandPacket.NvmeCmd->Cdw10, &CrIoSq, sizeof (NVME_ADMIN_CRIOSQ)); - CommandPacket.NvmeCmd->Flags = CDW10_VALID | CDW11_VALID; - - Status = Private->Passthru.PassThru ( - &Private->Passthru, - 0, - &CommandPacket, - NULL - ); - - return Status; -} - -/** - Initialize the Nvm Express controller. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The NVM Express Controller is initialized successfully. - @retval Others A device error occurred while initializing the controller. - -**/ -EFI_STATUS -NvmeControllerInit ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Supports; - NVME_AQA Aqa; - NVME_ASQ Asq; - NVME_ACQ Acq; - - // - // Save original PCI attributes and enable this controller. - // - PciIo = Private->PciIo; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationGet, - 0, - &Private->PciAttributes - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, "NvmeControllerInit: failed to enable controller\n")); - return Status; - } - - // - // Read the Controller Capabilities register and verify that the NVM command set is supported - // - Status = ReadNvmeControllerCapabilities (Private, &Private->Cap); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Private->Cap.Css != 0x01) { - DEBUG ((EFI_D_INFO, "NvmeControllerInit: the controller doesn't support NVMe command set\n")); - return EFI_UNSUPPORTED; - } - - // - // Currently the driver only supports 4k page size. - // - ASSERT ((Private->Cap.Mpsmin + 12) <= EFI_PAGE_SHIFT); - - Private->Cid[0] = 0; - Private->Cid[1] = 0; - - Status = NvmeDisableController (Private); - - if (EFI_ERROR(Status)) { - return Status; - } - - // - // set number of entries admin submission & completion queues. - // - Aqa.Asqs = NVME_ASQ_SIZE; - Aqa.Rsvd1 = 0; - Aqa.Acqs = NVME_ACQ_SIZE; - Aqa.Rsvd2 = 0; - - // - // Address of admin submission queue. - // - Asq.Rsvd1 = 0; - Asq.Asqb = (UINT64)(UINTN)(Private->BufferPciAddr) >> 12; - - // - // Address of admin completion queue. - // - Acq.Rsvd1 = 0; - Acq.Acqb = (UINT64)(UINTN)(Private->BufferPciAddr + EFI_PAGE_SIZE) >> 12; - - // - // Address of I/O submission & completion queue. - // - Private->SqBuffer[0] = (NVME_SQ *)(UINTN)(Private->Buffer); - Private->SqBufferPciAddr[0] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr); - Private->CqBuffer[0] = (NVME_CQ *)(UINTN)(Private->Buffer + 1 * EFI_PAGE_SIZE); - Private->CqBufferPciAddr[0] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + 1 * EFI_PAGE_SIZE); - Private->SqBuffer[1] = (NVME_SQ *)(UINTN)(Private->Buffer + 2 * EFI_PAGE_SIZE); - Private->SqBufferPciAddr[1] = (NVME_SQ *)(UINTN)(Private->BufferPciAddr + 2 * EFI_PAGE_SIZE); - Private->CqBuffer[1] = (NVME_CQ *)(UINTN)(Private->Buffer + 3 * EFI_PAGE_SIZE); - Private->CqBufferPciAddr[1] = (NVME_CQ *)(UINTN)(Private->BufferPciAddr + 3 * EFI_PAGE_SIZE); - - DEBUG ((EFI_D_INFO, "Private->Buffer = [%016X]\n", (UINT64)(UINTN)Private->Buffer)); - DEBUG ((EFI_D_INFO, "Admin Submission Queue size (Aqa.Asqs) = [%08X]\n", Aqa.Asqs)); - DEBUG ((EFI_D_INFO, "Admin Completion Queue size (Aqa.Acqs) = [%08X]\n", Aqa.Acqs)); - DEBUG ((EFI_D_INFO, "Admin Submission Queue (SqBuffer[0]) = [%016X]\n", Private->SqBuffer[0])); - DEBUG ((EFI_D_INFO, "Admin Completion Queue (CqBuffer[0]) = [%016X]\n", Private->CqBuffer[0])); - DEBUG ((EFI_D_INFO, "I/O Submission Queue (SqBuffer[1]) = [%016X]\n", Private->SqBuffer[1])); - DEBUG ((EFI_D_INFO, "I/O Completion Queue (CqBuffer[1]) = [%016X]\n", Private->CqBuffer[1])); - - // - // Program admin queue attributes. - // - Status = WriteNvmeAdminQueueAttributes (Private, &Aqa); - - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Program admin submission queue address. - // - Status = WriteNvmeAdminSubmissionQueueBaseAddress (Private, &Asq); - - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Program admin completion queue address. - // - Status = WriteNvmeAdminCompletionQueueBaseAddress (Private, &Acq); - - if (EFI_ERROR(Status)) { - return Status; - } - - Status = NvmeEnableController (Private); - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Allocate buffer for Identify Controller data - // - Private->ControllerData = (NVME_ADMIN_CONTROLLER_DATA *)AllocateZeroPool (sizeof(NVME_ADMIN_CONTROLLER_DATA)); - - if (Private->ControllerData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Get current Identify Controller Data - // - Status = NvmeIdentifyController (Private, Private->ControllerData); - - if (EFI_ERROR(Status)) { - FreePool(Private->ControllerData); - Private->ControllerData = NULL; - return EFI_NOT_FOUND; - } - - // - // Dump NvmExpress Identify Controller Data - // - Private->ControllerData->Sn[19] = 0; - Private->ControllerData->Mn[39] = 0; - DEBUG ((EFI_D_INFO, " == NVME IDENTIFY CONTROLLER DATA ==\n")); - DEBUG ((EFI_D_INFO, " PCI VID : 0x%x\n", Private->ControllerData->Vid)); - DEBUG ((EFI_D_INFO, " PCI SSVID : 0x%x\n", Private->ControllerData->Ssvid)); - DEBUG ((EFI_D_INFO, " SN : %a\n", (CHAR8 *)(Private->ControllerData->Sn))); - DEBUG ((EFI_D_INFO, " MN : %a\n", (CHAR8 *)(Private->ControllerData->Mn))); - DEBUG ((EFI_D_INFO, " FR : 0x%x\n", *((UINT64*)Private->ControllerData->Fr))); - DEBUG ((EFI_D_INFO, " RAB : 0x%x\n", Private->ControllerData->Rab)); - DEBUG ((EFI_D_INFO, " IEEE : 0x%x\n", *(UINT32*)Private->ControllerData->Ieee_oui)); - DEBUG ((EFI_D_INFO, " AERL : 0x%x\n", Private->ControllerData->Aerl)); - DEBUG ((EFI_D_INFO, " SQES : 0x%x\n", Private->ControllerData->Sqes)); - DEBUG ((EFI_D_INFO, " CQES : 0x%x\n", Private->ControllerData->Cqes)); - DEBUG ((EFI_D_INFO, " NN : 0x%x\n", Private->ControllerData->Nn)); - - // - // Create one I/O completion queue. - // - Status = NvmeCreateIoCompletionQueue (Private); - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Create one I/O Submission queue. - // - Status = NvmeCreateIoSubmissionQueue (Private); - if (EFI_ERROR(Status)) { - return Status; - } - - return Status; -} - diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.h b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.h deleted file mode 100644 index 06c1db7d8e..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressHci.h +++ /dev/null @@ -1,809 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _NVME_HCI_H_ -#define _NVME_HCI_H_ - -#define NVME_BAR 0 - -// -// controller register offsets -// -#define NVME_CAP_OFFSET 0x0000 // Controller Capabilities -#define NVME_VER_OFFSET 0x0008 // Version -#define NVME_INTMS_OFFSET 0x000c // Interrupt Mask Set -#define NVME_INTMC_OFFSET 0x0010 // Interrupt Mask Clear -#define NVME_CC_OFFSET 0x0014 // Controller Configuration -#define NVME_CSTS_OFFSET 0x001c // Controller Status -#define NVME_NSSR_OFFSET 0x0020 // NVM Subsystem Reset -#define NVME_AQA_OFFSET 0x0024 // Admin Queue Attributes -#define NVME_ASQ_OFFSET 0x0028 // Admin Submission Queue Base Address -#define NVME_ACQ_OFFSET 0x0030 // Admin Completion Queue Base Address -#define NVME_SQ0_OFFSET 0x1000 // Submission Queue 0 (admin) Tail Doorbell -#define NVME_CQ0_OFFSET 0x1004 // Completion Queue 0 (admin) Head Doorbell - -// -// These register offsets are defined as 0x1000 + (N * (4 << CAP.DSTRD)) -// Get the doorbell stride bit shift value from the controller capabilities. -// -#define NVME_SQTDBL_OFFSET(QID, DSTRD) 0x1000 + ((2 * (QID)) * (4 << (DSTRD))) // Submission Queue y (NVM) Tail Doorbell -#define NVME_CQHDBL_OFFSET(QID, DSTRD) 0x1000 + (((2 * (QID)) + 1) * (4 << (DSTRD))) // Completion Queue y (NVM) Head Doorbell - - -#pragma pack(1) - -// -// 3.1.1 Offset 00h: CAP - Controller Capabilities -// -typedef struct { - UINT16 Mqes; // Maximum Queue Entries Supported - UINT8 Cqr:1; // Contiguous Queues Required - UINT8 Ams:2; // Arbitration Mechanism Supported - UINT8 Rsvd1:5; - UINT8 To; // Timeout - UINT16 Dstrd:4; - UINT16 Nssrs:1; // NVM Subsystem Reset Supported NSSRS - UINT16 Css:4; // Command Sets Supported - Bit 37 - UINT16 Rsvd3:7; - UINT8 Mpsmin:4; - UINT8 Mpsmax:4; - UINT8 Rsvd4; -} NVME_CAP; - -// -// 3.1.2 Offset 08h: VS - Version -// -typedef struct { - UINT16 Mnr; // Minor version number - UINT16 Mjr; // Major version number -} NVME_VER; - -// -// 3.1.5 Offset 14h: CC - Controller Configuration -// -typedef struct { - UINT16 En:1; // Enable - UINT16 Rsvd1:3; - UINT16 Css:3; // I/O Command Set Selected - UINT16 Mps:4; // Memory Page Size - UINT16 Ams:3; // Arbitration Mechanism Selected - UINT16 Shn:2; // Shutdown Notification - UINT8 Iosqes:4; // I/O Submission Queue Entry Size - UINT8 Iocqes:4; // I/O Completion Queue Entry Size - UINT8 Rsvd2; -} NVME_CC; - -// -// 3.1.6 Offset 1Ch: CSTS - Controller Status -// -typedef struct { - UINT32 Rdy:1; // Ready - UINT32 Cfs:1; // Controller Fatal Status - UINT32 Shst:2; // Shutdown Status - UINT32 Nssro:1; // NVM Subsystem Reset Occurred - UINT32 Rsvd1:27; -} NVME_CSTS; - -// -// 3.1.8 Offset 24h: AQA - Admin Queue Attributes -// -typedef struct { - UINT16 Asqs:12; // Submission Queue Size - UINT16 Rsvd1:4; - UINT16 Acqs:12; // Completion Queue Size - UINT16 Rsvd2:4; -} NVME_AQA; - -// -// 3.1.9 Offset 28h: ASQ - Admin Submission Queue Base Address -// -typedef struct { - UINT64 Rsvd1:12; - UINT64 Asqb:52; // Admin Submission Queue Base Address -} NVME_ASQ; - -// -// 3.1.10 Offset 30h: ACQ - Admin Completion Queue Base Address -// -typedef struct { - UINT64 Rsvd1:12; - UINT64 Acqb:52; // Admin Completion Queue Base Address -} NVME_ACQ; - -// -// 3.1.11 Offset (1000h + ((2y) * (4 << CAP.DSTRD))): SQyTDBL - Submission Queue y Tail Doorbell -// -typedef struct { - UINT16 Sqt; - UINT16 Rsvd1; -} NVME_SQTDBL; - -// -// 3.1.12 Offset (1000h + ((2y + 1) * (4 << CAP.DSTRD))): CQyHDBL - Completion Queue y Head Doorbell -// -typedef struct { - UINT16 Cqh; - UINT16 Rsvd1; -} NVME_CQHDBL; - -// -// NVM command set structures -// -// Read Command -// -typedef struct { - // - // CDW 10, 11 - // - UINT64 Slba; /* Starting Sector Address */ - // - // CDW 12 - // - UINT16 Nlb; /* Number of Sectors */ - UINT16 Rsvd1:10; - UINT16 Prinfo:4; /* Protection Info Check */ - UINT16 Fua:1; /* Force Unit Access */ - UINT16 Lr:1; /* Limited Retry */ - // - // CDW 13 - // - UINT32 Af:4; /* Access Frequency */ - UINT32 Al:2; /* Access Latency */ - UINT32 Sr:1; /* Sequential Request */ - UINT32 In:1; /* Incompressible */ - UINT32 Rsvd2:24; - // - // CDW 14 - // - UINT32 Eilbrt; /* Expected Initial Logical Block Reference Tag */ - // - // CDW 15 - // - UINT16 Elbat; /* Expected Logical Block Application Tag */ - UINT16 Elbatm; /* Expected Logical Block Application Tag Mask */ -} NVME_READ; - -// -// Write Command -// -typedef struct { - // - // CDW 10, 11 - // - UINT64 Slba; /* Starting Sector Address */ - // - // CDW 12 - // - UINT16 Nlb; /* Number of Sectors */ - UINT16 Rsvd1:10; - UINT16 Prinfo:4; /* Protection Info Check */ - UINT16 Fua:1; /* Force Unit Access */ - UINT16 Lr:1; /* Limited Retry */ - // - // CDW 13 - // - UINT32 Af:4; /* Access Frequency */ - UINT32 Al:2; /* Access Latency */ - UINT32 Sr:1; /* Sequential Request */ - UINT32 In:1; /* Incompressible */ - UINT32 Rsvd2:24; - // - // CDW 14 - // - UINT32 Ilbrt; /* Initial Logical Block Reference Tag */ - // - // CDW 15 - // - UINT16 Lbat; /* Logical Block Application Tag */ - UINT16 Lbatm; /* Logical Block Application Tag Mask */ -} NVME_WRITE; - -// -// Flush -// -typedef struct { - // - // CDW 10 - // - UINT32 Flush; /* Flush */ -} NVME_FLUSH; - -// -// Write Uncorrectable command -// -typedef struct { - // - // CDW 10, 11 - // - UINT64 Slba; /* Starting LBA */ - // - // CDW 12 - // - UINT32 Nlb:16; /* Number of Logical Blocks */ - UINT32 Rsvd1:16; -} NVME_WRITE_UNCORRECTABLE; - -// -// Write Zeroes command -// -typedef struct { - // - // CDW 10, 11 - // - UINT64 Slba; /* Starting LBA */ - // - // CDW 12 - // - UINT16 Nlb; /* Number of Logical Blocks */ - UINT16 Rsvd1:10; - UINT16 Prinfo:4; /* Protection Info Check */ - UINT16 Fua:1; /* Force Unit Access */ - UINT16 Lr:1; /* Limited Retry */ - // - // CDW 13 - // - UINT32 Rsvd2; - // - // CDW 14 - // - UINT32 Ilbrt; /* Initial Logical Block Reference Tag */ - // - // CDW 15 - // - UINT16 Lbat; /* Logical Block Application Tag */ - UINT16 Lbatm; /* Logical Block Application Tag Mask */ -} NVME_WRITE_ZEROES; - -// -// Compare command -// -typedef struct { - // - // CDW 10, 11 - // - UINT64 Slba; /* Starting LBA */ - // - // CDW 12 - // - UINT16 Nlb; /* Number of Logical Blocks */ - UINT16 Rsvd1:10; - UINT16 Prinfo:4; /* Protection Info Check */ - UINT16 Fua:1; /* Force Unit Access */ - UINT16 Lr:1; /* Limited Retry */ - // - // CDW 13 - // - UINT32 Rsvd2; - // - // CDW 14 - // - UINT32 Eilbrt; /* Expected Initial Logical Block Reference Tag */ - // - // CDW 15 - // - UINT16 Elbat; /* Expected Logical Block Application Tag */ - UINT16 Elbatm; /* Expected Logical Block Application Tag Mask */ -} NVME_COMPARE; - -typedef union { - NVME_READ Read; - NVME_WRITE Write; - NVME_FLUSH Flush; - NVME_WRITE_UNCORRECTABLE WriteUncorrectable; - NVME_WRITE_ZEROES WriteZeros; - NVME_COMPARE Compare; -} NVME_CMD; - -typedef struct { - UINT16 Mp; /* Maximum Power */ - UINT8 Rsvd1; /* Reserved as of Nvm Express 1.1 Spec */ - UINT8 Mps:1; /* Max Power Scale */ - UINT8 Nops:1; /* Non-Operational State */ - UINT8 Rsvd2:6; /* Reserved as of Nvm Express 1.1 Spec */ - UINT32 Enlat; /* Entry Latency */ - UINT32 Exlat; /* Exit Latency */ - UINT8 Rrt:5; /* Relative Read Throughput */ - UINT8 Rsvd3:3; /* Reserved as of Nvm Express 1.1 Spec */ - UINT8 Rrl:5; /* Relative Read Leatency */ - UINT8 Rsvd4:3; /* Reserved as of Nvm Express 1.1 Spec */ - UINT8 Rwt:5; /* Relative Write Throughput */ - UINT8 Rsvd5:3; /* Reserved as of Nvm Express 1.1 Spec */ - UINT8 Rwl:5; /* Relative Write Leatency */ - UINT8 Rsvd6:3; /* Reserved as of Nvm Express 1.1 Spec */ - UINT8 Rsvd7[16]; /* Reserved as of Nvm Express 1.1 Spec */ -} NVME_PSDESCRIPTOR; - -// -// Identify Controller Data -// -typedef struct { - // - // Controller Capabilities and Features 0-255 - // - UINT16 Vid; /* PCI Vendor ID */ - UINT16 Ssvid; /* PCI sub-system vendor ID */ - UINT8 Sn[20]; /* Product serial number */ - - UINT8 Mn[40]; /* Proeduct model number */ - UINT8 Fr[8]; /* Firmware Revision */ - UINT8 Rab; /* Recommended Arbitration Burst */ - UINT8 Ieee_oui[3]; /* Organization Unique Identifier */ - UINT8 Cmic; /* Multi-interface Capabilities */ - UINT8 Mdts; /* Maximum Data Transfer Size */ - UINT8 Cntlid[2]; /* Controller ID */ - UINT8 Rsvd1[176]; /* Reserved as of Nvm Express 1.1 Spec */ - // - // Admin Command Set Attributes - // - UINT16 Oacs; /* Optional Admin Command Support */ - #define NAMESPACE_MANAGEMENT_SUPPORTED BIT3 - #define FW_DOWNLOAD_ACTIVATE_SUPPORTED BIT2 - #define FORMAT_NVM_SUPPORTED BIT1 - #define SECURITY_SEND_RECEIVE_SUPPORTED BIT0 - UINT8 Acl; /* Abort Command Limit */ - UINT8 Aerl; /* Async Event Request Limit */ - UINT8 Frmw; /* Firmware updates */ - UINT8 Lpa; /* Log Page Attributes */ - UINT8 Elpe; /* Error Log Page Entries */ - UINT8 Npss; /* Number of Power States Support */ - UINT8 Avscc; /* Admin Vendor Specific Command Configuration */ - UINT8 Apsta; /* Autonomous Power State Transition Attributes */ - UINT8 Rsvd2[246]; /* Reserved as of Nvm Express 1.1 Spec */ - // - // NVM Command Set Attributes - // - UINT8 Sqes; /* Submission Queue Entry Size */ - UINT8 Cqes; /* Completion Queue Entry Size */ - UINT16 Rsvd3; /* Reserved as of Nvm Express 1.1 Spec */ - UINT32 Nn; /* Number of Namespaces */ - UINT16 Oncs; /* Optional NVM Command Support */ - UINT16 Fuses; /* Fused Operation Support */ - UINT8 Fna; /* Format NVM Attributes */ - UINT8 Vwc; /* Volatile Write Cache */ - UINT16 Awun; /* Atomic Write Unit Normal */ - UINT16 Awupf; /* Atomic Write Unit Power Fail */ - UINT8 Nvscc; /* NVM Vendor Specific Command Configuration */ - UINT8 Rsvd4; /* Reserved as of Nvm Express 1.1 Spec */ - UINT16 Acwu; /* Atomic Compare & Write Unit */ - UINT16 Rsvd5; /* Reserved as of Nvm Express 1.1 Spec */ - UINT32 Sgls; /* SGL Support */ - UINT8 Rsvd6[164]; /* Reserved as of Nvm Express 1.1 Spec */ - // - // I/O Command set Attributes - // - UINT8 Rsvd7[1344]; /* Reserved as of Nvm Express 1.1 Spec */ - // - // Power State Descriptors - // - NVME_PSDESCRIPTOR PsDescriptor[32]; - - UINT8 VendorData[1024]; /* Vendor specific data */ -} NVME_ADMIN_CONTROLLER_DATA; - -typedef struct { - UINT16 Ms; /* Metadata Size */ - UINT8 Lbads; /* LBA Data Size */ - UINT8 Rp:2; /* Relative Performance */ - #define LBAF_RP_BEST 00b - #define LBAF_RP_BETTER 01b - #define LBAF_RP_GOOD 10b - #define LBAF_RP_DEGRADED 11b - UINT8 Rsvd1:6; /* Reserved as of Nvm Express 1.1 Spec */ -} NVME_LBAFORMAT; - -// -// Identify Namespace Data -// -typedef struct { - // - // NVM Command Set Specific - // - UINT64 Nsze; /* Namespace Size (total number of blocks in formatted namespace) */ - UINT64 Ncap; /* Namespace Capacity (max number of logical blocks) */ - UINT64 Nuse; /* Namespace Utilization */ - UINT8 Nsfeat; /* Namespace Features */ - UINT8 Nlbaf; /* Number of LBA Formats */ - UINT8 Flbas; /* Formatted LBA size */ - UINT8 Mc; /* Metadata Capabilities */ - UINT8 Dpc; /* End-to-end Data Protection capabilities */ - UINT8 Dps; /* End-to-end Data Protection Type Settings */ - UINT8 Nmic; /* Namespace Multi-path I/O and Namespace Sharing Capabilities */ - UINT8 Rescap; /* Reservation Capabilities */ - UINT8 Rsvd1[88]; /* Reserved as of Nvm Express 1.1 Spec */ - UINT64 Eui64; /* IEEE Extended Unique Identifier */ - // - // LBA Format - // - NVME_LBAFORMAT LbaFormat[16]; - - UINT8 Rsvd2[192]; /* Reserved as of Nvm Express 1.1 Spec */ - UINT8 VendorData[3712]; /* Vendor specific data */ -} NVME_ADMIN_NAMESPACE_DATA; - -// -// NvmExpress Admin Identify Cmd -// -typedef struct { - // - // CDW 10 - // - UINT32 Cns:2; - UINT32 Rsvd1:30; -} NVME_ADMIN_IDENTIFY; - -// -// NvmExpress Admin Create I/O Completion Queue -// -typedef struct { - // - // CDW 10 - // - UINT32 Qid:16; /* Queue Identifier */ - UINT32 Qsize:16; /* Queue Size */ - - // - // CDW 11 - // - UINT32 Pc:1; /* Physically Contiguous */ - UINT32 Ien:1; /* Interrupts Enabled */ - UINT32 Rsvd1:14; /* reserved as of Nvm Express 1.1 Spec */ - UINT32 Iv:16; /* Interrupt Vector for MSI-X or MSI*/ -} NVME_ADMIN_CRIOCQ; - -// -// NvmExpress Admin Create I/O Submission Queue -// -typedef struct { - // - // CDW 10 - // - UINT32 Qid:16; /* Queue Identifier */ - UINT32 Qsize:16; /* Queue Size */ - - // - // CDW 11 - // - UINT32 Pc:1; /* Physically Contiguous */ - UINT32 Qprio:2; /* Queue Priority */ - UINT32 Rsvd1:13; /* Reserved as of Nvm Express 1.1 Spec */ - UINT32 Cqid:16; /* Completion Queue ID */ -} NVME_ADMIN_CRIOSQ; - -// -// NvmExpress Admin Delete I/O Completion Queue -// -typedef struct { - // - // CDW 10 - // - UINT16 Qid; - UINT16 Rsvd1; -} NVME_ADMIN_DEIOCQ; - -// -// NvmExpress Admin Delete I/O Submission Queue -// -typedef struct { - // - // CDW 10 - // - UINT16 Qid; - UINT16 Rsvd1; -} NVME_ADMIN_DEIOSQ; - -// -// NvmExpress Admin Abort Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Sqid:16; /* Submission Queue identifier */ - UINT32 Cid:16; /* Command Identifier */ -} NVME_ADMIN_ABORT; - -// -// NvmExpress Admin Firmware Activate Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Fs:3; /* Submission Queue identifier */ - UINT32 Aa:2; /* Command Identifier */ - UINT32 Rsvd1:27; -} NVME_ADMIN_FIRMWARE_ACTIVATE; - -// -// NvmExpress Admin Firmware Image Download Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Numd; /* Number of Dwords */ - // - // CDW 11 - // - UINT32 Ofst; /* Offset */ -} NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD; - -// -// NvmExpress Admin Get Features Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Fid:8; /* Feature Identifier */ - UINT32 Sel:3; /* Select */ - UINT32 Rsvd1:21; -} NVME_ADMIN_GET_FEATURES; - -// -// NvmExpress Admin Get Log Page Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Lid:8; /* Log Page Identifier */ - #define LID_ERROR_INFO 0x1 - #define LID_SMART_INFO 0x2 - #define LID_FW_SLOT_INFO 0x3 - UINT32 Rsvd1:8; - UINT32 Numd:12; /* Number of Dwords */ - UINT32 Rsvd2:4; /* Reserved as of Nvm Express 1.1 Spec */ -} NVME_ADMIN_GET_LOG_PAGE; - -// -// NvmExpress Admin Set Features Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Fid:8; /* Feature Identifier */ - UINT32 Rsvd1:23; - UINT32 Sv:1; /* Save */ -} NVME_ADMIN_SET_FEATURES; - -// -// NvmExpress Admin Format NVM Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Lbaf:4; /* LBA Format */ - UINT32 Ms:1; /* Metadata Settings */ - UINT32 Pi:3; /* Protection Information */ - UINT32 Pil:1; /* Protection Information Location */ - UINT32 Ses:3; /* Secure Erase Settings */ - UINT32 Rsvd1:20; -} NVME_ADMIN_FORMAT_NVM; - -// -// NvmExpress Admin Security Receive Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Rsvd1:8; - UINT32 Spsp:16; /* SP Specific */ - UINT32 Secp:8; /* Security Protocol */ - // - // CDW 11 - // - UINT32 Al; /* Allocation Length */ -} NVME_ADMIN_SECURITY_RECEIVE; - -// -// NvmExpress Admin Security Send Command -// -typedef struct { - // - // CDW 10 - // - UINT32 Rsvd1:8; - UINT32 Spsp:16; /* SP Specific */ - UINT32 Secp:8; /* Security Protocol */ - // - // CDW 11 - // - UINT32 Tl; /* Transfer Length */ -} NVME_ADMIN_SECURITY_SEND; - -typedef union { - NVME_ADMIN_IDENTIFY Identify; - NVME_ADMIN_CRIOCQ CrIoCq; - NVME_ADMIN_CRIOSQ CrIoSq; - NVME_ADMIN_DEIOCQ DeIoCq; - NVME_ADMIN_DEIOSQ DeIoSq; - NVME_ADMIN_ABORT Abort; - NVME_ADMIN_FIRMWARE_ACTIVATE Activate; - NVME_ADMIN_FIRMWARE_IMAGE_DOWNLOAD FirmwareImageDownload; - NVME_ADMIN_GET_FEATURES GetFeatures; - NVME_ADMIN_GET_LOG_PAGE GetLogPage; - NVME_ADMIN_SET_FEATURES SetFeatures; - NVME_ADMIN_FORMAT_NVM FormatNvm; - NVME_ADMIN_SECURITY_RECEIVE SecurityReceive; - NVME_ADMIN_SECURITY_SEND SecuritySend; -} NVME_ADMIN_CMD; - -typedef struct { - UINT32 Cdw10; - UINT32 Cdw11; - UINT32 Cdw12; - UINT32 Cdw13; - UINT32 Cdw14; - UINT32 Cdw15; -} NVME_RAW; - -typedef union { - NVME_ADMIN_CMD Admin; // Union of Admin commands - NVME_CMD Nvm; // Union of Nvm commands - NVME_RAW Raw; -} NVME_PAYLOAD; - -// -// Submission Queue -// -typedef struct { - // - // CDW 0, Common to all comnmands - // - UINT8 Opc; // Opcode - UINT8 Fuse:2; // Fused Operation - UINT8 Rsvd1:5; - UINT8 Psdt:1; // PRP or SGL for Data Transfer - UINT16 Cid; // Command Identifier - - // - // CDW 1 - // - UINT32 Nsid; // Namespace Identifier - - // - // CDW 2,3 - // - UINT64 Rsvd2; - - // - // CDW 4,5 - // - UINT64 Mptr; // Metadata Pointer - - // - // CDW 6-9 - // - UINT64 Prp[2]; // First and second PRP entries - - NVME_PAYLOAD Payload; - -} NVME_SQ; - -// -// Completion Queue -// -typedef struct { - // - // CDW 0 - // - UINT32 Dword0; - // - // CDW 1 - // - UINT32 Rsvd1; - // - // CDW 2 - // - UINT16 Sqhd; // Submission Queue Head Pointer - UINT16 Sqid; // Submission Queue Identifier - // - // CDW 3 - // - UINT16 Cid; // Command Identifier - UINT16 Pt:1; // Phase Tag - UINT16 Sc:8; // Status Code - UINT16 Sct:3; // Status Code Type - UINT16 Rsvd2:2; - UINT16 Mo:1; // More - UINT16 Dnr:1; // Do Not Retry -} NVME_CQ; - -// -// Nvm Express Admin cmd opcodes -// -#define NVME_ADMIN_DEIOSQ_CMD 0x00 -#define NVME_ADMIN_CRIOSQ_CMD 0x01 -#define NVME_ADMIN_GET_LOG_PAGE_CMD 0x02 -#define NVME_ADMIN_DEIOCQ_CMD 0x04 -#define NVME_ADMIN_CRIOCQ_CMD 0x05 -#define NVME_ADMIN_IDENTIFY_CMD 0x06 -#define NVME_ADMIN_ABORT_CMD 0x08 -#define NVME_ADMIN_SET_FEATURES_CMD 0x09 -#define NVME_ADMIN_GET_FEATURES_CMD 0x0A -#define NVME_ADMIN_ASYNC_EVENT_REQUEST_CMD 0x0C -#define NVME_ADMIN_NAMESACE_MANAGEMENT_CMD 0x0D -#define NVME_ADMIN_FW_COMMIT_CMD 0x10 -#define NVME_ADMIN_FW_IAMGE_DOWNLOAD_CMD 0x11 -#define NVME_ADMIN_NAMESACE_ATTACHMENT_CMD 0x15 -#define NVME_ADMIN_FORMAT_NVM_CMD 0x80 -#define NVME_ADMIN_SECURITY_SEND_CMD 0x81 -#define NVME_ADMIN_SECURITY_RECEIVE_CMD 0x82 - -#define NVME_IO_FLUSH_OPC 0 -#define NVME_IO_WRITE_OPC 1 -#define NVME_IO_READ_OPC 2 - -// -// Offset from the beginning of private data queue buffer -// -#define NVME_ASQ_BUF_OFFSET EFI_PAGE_SIZE - -/** - Initialize the Nvm Express controller. - - @param[in] Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - - @retval EFI_SUCCESS The NVM Express Controller is initialized successfully. - @retval Others A device error occurred while initializing the controller. - -**/ -EFI_STATUS -NvmeControllerInit ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private - ); - -/** - Get identify controller data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param Buffer The buffer used to store the identify controller data. - - @return EFI_SUCCESS Successfully get the identify controller data. - @return EFI_DEVICE_ERROR Fail to get the identify controller data. - -**/ -EFI_STATUS -NvmeIdentifyController ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN VOID *Buffer - ); - -/** - Get specified identify namespace data. - - @param Private The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure. - @param NamespaceId The specified namespace identifier. - @param Buffer The buffer used to store the identify namespace data. - - @return EFI_SUCCESS Successfully get the identify namespace data. - @return EFI_DEVICE_ERROR Fail to get the identify namespace data. - -**/ -EFI_STATUS -NvmeIdentifyNamespace ( - IN NVME_CONTROLLER_PRIVATE_DATA *Private, - IN UINT32 NamespaceId, - IN VOID *Buffer - ); - -#pragma pack() - -#endif - diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c deleted file mode 100644 index f9871527dd..0000000000 --- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c +++ /dev/null @@ -1,907 +0,0 @@ -/** @file - NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows - NVM Express specification. - - (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "NvmExpress.h" - -/** - Dump the execution status from a given completion queue entry. - - @param[in] Cq A pointer to the NVME_CQ item. - -**/ -VOID -NvmeDumpStatus ( - IN NVME_CQ *Cq - ) -{ - DEBUG ((EFI_D_VERBOSE, "Dump NVMe Completion Entry Status from [0x%x]:\n", Cq)); - - DEBUG ((EFI_D_VERBOSE, " SQ Identifier : [0x%x], Phase Tag : [%d], Cmd Identifier : [0x%x]\n", Cq->Sqid, Cq->Pt, Cq->Cid)); - - DEBUG ((EFI_D_VERBOSE, " NVMe Cmd Execution Result - ")); - - switch (Cq->Sct) { - case 0x0: - switch (Cq->Sc) { - case 0x0: - DEBUG ((EFI_D_VERBOSE, "Successful Completion\n")); - break; - case 0x1: - DEBUG ((EFI_D_VERBOSE, "Invalid Command Opcode\n")); - break; - case 0x2: - DEBUG ((EFI_D_VERBOSE, "Invalid Field in Command\n")); - break; - case 0x3: - DEBUG ((EFI_D_VERBOSE, "Command ID Conflict\n")); - break; - case 0x4: - DEBUG ((EFI_D_VERBOSE, "Data Transfer Error\n")); - break; - case 0x5: - DEBUG ((EFI_D_VERBOSE, "Commands Aborted due to Power Loss Notification\n")); - break; - case 0x6: - DEBUG ((EFI_D_VERBOSE, "Internal Device Error\n")); - break; - case 0x7: - DEBUG ((EFI_D_VERBOSE, "Command Abort Requested\n")); - break; - case 0x8: - DEBUG ((EFI_D_VERBOSE, "Command Aborted due to SQ Deletion\n")); - break; - case 0x9: - DEBUG ((EFI_D_VERBOSE, "Command Aborted due to Failed Fused Command\n")); - break; - case 0xA: - DEBUG ((EFI_D_VERBOSE, "Command Aborted due to Missing Fused Command\n")); - break; - case 0xB: - DEBUG ((EFI_D_VERBOSE, "Invalid Namespace or Format\n")); - break; - case 0xC: - DEBUG ((EFI_D_VERBOSE, "Command Sequence Error\n")); - break; - case 0xD: - DEBUG ((EFI_D_VERBOSE, "Invalid SGL Last Segment Descriptor\n")); - break; - case 0xE: - DEBUG ((EFI_D_VERBOSE, "Invalid Number of SGL Descriptors\n")); - break; - case 0xF: - DEBUG ((EFI_D_VERBOSE, "Data SGL Length Invalid\n")); - break; - case 0x10: - DEBUG ((EFI_D_VERBOSE, "Metadata SGL Length Invalid\n")); - break; - case 0x11: - DEBUG ((EFI_D_VERBOSE, "SGL Descriptor Type Invalid\n")); - break; - case 0x80: - DEBUG ((EFI_D_VERBOSE, "LBA Out of Range\n")); - break; - case 0x81: - DEBUG ((EFI_D_VERBOSE, "Capacity Exceeded\n")); - break; - case 0x82: - DEBUG ((EFI_D_VERBOSE, "Namespace Not Ready\n")); - break; - case 0x83: - DEBUG ((EFI_D_VERBOSE, "Reservation Conflict\n")); - break; - } - break; - - case 0x1: - switch (Cq->Sc) { - case 0x0: - DEBUG ((EFI_D_VERBOSE, "Completion Queue Invalid\n")); - break; - case 0x1: - DEBUG ((EFI_D_VERBOSE, "Invalid Queue Identifier\n")); - break; - case 0x2: - DEBUG ((EFI_D_VERBOSE, "Maximum Queue Size Exceeded\n")); - break; - case 0x3: - DEBUG ((EFI_D_VERBOSE, "Abort Command Limit Exceeded\n")); - break; - case 0x5: - DEBUG ((EFI_D_VERBOSE, "Asynchronous Event Request Limit Exceeded\n")); - break; - case 0x6: - DEBUG ((EFI_D_VERBOSE, "Invalid Firmware Slot\n")); - break; - case 0x7: - DEBUG ((EFI_D_VERBOSE, "Invalid Firmware Image\n")); - break; - case 0x8: - DEBUG ((EFI_D_VERBOSE, "Invalid Interrupt Vector\n")); - break; - case 0x9: - DEBUG ((EFI_D_VERBOSE, "Invalid Log Page\n")); - break; - case 0xA: - DEBUG ((EFI_D_VERBOSE, "Invalid Format\n")); - break; - case 0xB: - DEBUG ((EFI_D_VERBOSE, "Firmware Application Requires Conventional Reset\n")); - break; - case 0xC: - DEBUG ((EFI_D_VERBOSE, "Invalid Queue Deletion\n")); - break; - case 0xD: - DEBUG ((EFI_D_VERBOSE, "Feature Identifier Not Saveable\n")); - break; - case 0xE: - DEBUG ((EFI_D_VERBOSE, "Feature Not Changeable\n")); - break; - case 0xF: - DEBUG ((EFI_D_VERBOSE, "Feature Not Namespace Specific\n")); - break; - case 0x10: - DEBUG ((EFI_D_VERBOSE, "Firmware Application Requires NVM Subsystem Reset\n")); - break; - case 0x80: - DEBUG ((EFI_D_VERBOSE, "Conflicting Attributes\n")); - break; - case 0x81: - DEBUG ((EFI_D_VERBOSE, "Invalid Protection Information\n")); - break; - case 0x82: - DEBUG ((EFI_D_VERBOSE, "Attempted Write to Read Only Range\n")); - break; - } - break; - - case 0x2: - switch (Cq->Sc) { - case 0x80: - DEBUG ((EFI_D_VERBOSE, "Write Fault\n")); - break; - case 0x81: - DEBUG ((EFI_D_VERBOSE, "Unrecovered Read Error\n")); - break; - case 0x82: - DEBUG ((EFI_D_VERBOSE, "End-to-end Guard Check Error\n")); - break; - case 0x83: - DEBUG ((EFI_D_VERBOSE, "End-to-end Application Tag Check Error\n")); - break; - case 0x84: - DEBUG ((EFI_D_VERBOSE, "End-to-end Reference Tag Check Error\n")); - break; - case 0x85: - DEBUG ((EFI_D_VERBOSE, "Compare Failure\n")); - break; - case 0x86: - DEBUG ((EFI_D_VERBOSE, "Access Denied\n")); - break; - } - break; - - default: - break; - } -} - -/** - Create PRP lists for data transfer which is larger than 2 memory pages. - Note here we calcuate the number of required PRP lists and allocate them at one time. - - @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param[in] PhysicalAddr The physical base address of data buffer. - @param[in] Pages The number of pages to be transfered. - @param[out] PrpListHost The host base address of PRP lists. - @param[in,out] PrpListNo The number of PRP List. - @param[out] Mapping The mapping value returned from PciIo.Map(). - - @retval The pointer to the first PRP List of the PRP lists. - -**/ -VOID* -NvmeCreatePrpList ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_PHYSICAL_ADDRESS PhysicalAddr, - IN UINTN Pages, - OUT VOID **PrpListHost, - IN OUT UINTN *PrpListNo, - OUT VOID **Mapping - ) -{ - UINTN PrpEntryNo; - UINT64 PrpListBase; - UINTN PrpListIndex; - UINTN PrpEntryIndex; - UINT64 Remainder; - EFI_PHYSICAL_ADDRESS PrpListPhyAddr; - UINTN Bytes; - EFI_STATUS Status; - - // - // The number of Prp Entry in a memory page. - // - PrpEntryNo = EFI_PAGE_SIZE / sizeof (UINT64); - - // - // Calculate total PrpList number. - // - *PrpListNo = (UINTN)DivU64x64Remainder ((UINT64)Pages, (UINT64)PrpEntryNo - 1, &Remainder); - if (*PrpListNo == 0) { - *PrpListNo = 1; - } else if ((Remainder != 0) && (Remainder != 1)) { - *PrpListNo += 1; - } else if (Remainder == 1) { - Remainder = PrpEntryNo; - } else if (Remainder == 0) { - Remainder = PrpEntryNo - 1; - } - - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - *PrpListNo, - PrpListHost, - 0 - ); - - if (EFI_ERROR (Status)) { - return NULL; - } - - Bytes = EFI_PAGES_TO_SIZE (*PrpListNo); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - *PrpListHost, - &Bytes, - &PrpListPhyAddr, - Mapping - ); - - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (*PrpListNo))) { - DEBUG ((EFI_D_ERROR, "NvmeCreatePrpList: create PrpList failure!\n")); - goto EXIT; - } - // - // Fill all PRP lists except of last one. - // - ZeroMem (*PrpListHost, Bytes); - for (PrpListIndex = 0; PrpListIndex < *PrpListNo - 1; ++PrpListIndex) { - PrpListBase = *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SIZE; - - for (PrpEntryIndex = 0; PrpEntryIndex < PrpEntryNo; ++PrpEntryIndex) { - if (PrpEntryIndex != PrpEntryNo - 1) { - // - // Fill all PRP entries except of last one. - // - *((UINT64*)(UINTN)PrpListBase + PrpEntryIndex) = PhysicalAddr; - PhysicalAddr += EFI_PAGE_SIZE; - } else { - // - // Fill last PRP entries with next PRP List pointer. - // - *((UINT64*)(UINTN)PrpListBase + PrpEntryIndex) = PrpListPhyAddr + (PrpListIndex + 1) * EFI_PAGE_SIZE; - } - } - } - // - // Fill last PRP list. - // - PrpListBase = *(UINT64*)PrpListHost + PrpListIndex * EFI_PAGE_SIZE; - for (PrpEntryIndex = 0; PrpEntryIndex < Remainder; ++PrpEntryIndex) { - *((UINT64*)(UINTN)PrpListBase + PrpEntryIndex) = PhysicalAddr; - PhysicalAddr += EFI_PAGE_SIZE; - } - - return (VOID*)(UINTN)PrpListPhyAddr; - -EXIT: - PciIo->FreeBuffer (PciIo, *PrpListNo, *PrpListHost); - return NULL; -} - - -/** - Sends an NVM Express Command Packet to an NVM Express controller or namespace. This function supports - both blocking I/O and non-blocking I/O. The blocking I/O functionality is required, and the non-blocking - I/O functionality is optional. - - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] NamespaceId A 32 bit namespace ID as defined in the NVMe specification to which the NVM Express Command - Packet will be sent. A value of 0 denotes the NVM Express controller, a value of all 0xFF's - (all bytes are 0xFF) in the namespace ID specifies that the command packet should be sent to - all valid namespaces. - @param[in,out] Packet A pointer to the NVM Express Command Packet. - @param[in] Event If non-blocking I/O is not supported then Event is ignored, and blocking I/O is performed. - If Event is NULL, then blocking I/O is performed. If Event is not NULL and non-blocking I/O - is supported, then non-blocking I/O is performed, and Event will be signaled when the NVM - Express Command Packet completes. - - @retval EFI_SUCCESS The NVM Express Command Packet was sent by the host. TransferLength bytes were transferred - to, or from DataBuffer. - @retval EFI_BAD_BUFFER_SIZE The NVM Express Command Packet was not executed. The number of bytes that could be transferred - is returned in TransferLength. - @retval EFI_NOT_READY The NVM Express Command Packet could not be sent because the controller is not ready. The caller - may retry again later. - @retval EFI_DEVICE_ERROR A device error occurred while attempting to send the NVM Express Command Packet. - @retval EFI_INVALID_PARAMETER NamespaceId or the contents of EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET are invalid. The NVM - Express Command Packet was not sent, so no additional status information is available. - @retval EFI_UNSUPPORTED The command described by the NVM Express Command Packet is not supported by the NVM Express - controller. The NVM Express Command Packet was not sent so no additional status information - is available. - @retval EFI_TIMEOUT A timeout occurred while waiting for the NVM Express Command Packet to execute. - -**/ -EFI_STATUS -EFIAPI -NvmExpressPassThru ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet, - IN EFI_EVENT Event OPTIONAL - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - NVME_SQ *Sq; - NVME_CQ *Cq; - UINT8 QueueType; - UINT32 Bytes; - UINT16 Offset; - EFI_EVENT TimerEvent; - EFI_PCI_IO_PROTOCOL_OPERATION Flag; - EFI_PHYSICAL_ADDRESS PhyAddr; - VOID *MapData; - VOID *MapMeta; - VOID *MapPrpList; - UINTN MapLength; - UINT64 *Prp; - VOID *PrpListHost; - UINTN PrpListNo; - UINT32 Data; - - // - // check the data fields in Packet parameter. - // - if ((This == NULL) || (Packet == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Packet->NvmeCmd == NULL) || (Packet->NvmeCompletion == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (Packet->QueueType != NVME_ADMIN_QUEUE && Packet->QueueType != NVME_IO_QUEUE) { - return EFI_INVALID_PARAMETER; - } - - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This); - PciIo = Private->PciIo; - MapData = NULL; - MapMeta = NULL; - MapPrpList = NULL; - PrpListHost = NULL; - PrpListNo = 0; - Prp = NULL; - TimerEvent = NULL; - Status = EFI_SUCCESS; - - QueueType = Packet->QueueType; - Sq = Private->SqBuffer[QueueType] + Private->SqTdbl[QueueType].Sqt; - Cq = Private->CqBuffer[QueueType] + Private->CqHdbl[QueueType].Cqh; - - if (Packet->NvmeCmd->Nsid != NamespaceId) { - return EFI_INVALID_PARAMETER; - } - - ZeroMem (Sq, sizeof (NVME_SQ)); - Sq->Opc = (UINT8)Packet->NvmeCmd->Cdw0.Opcode; - Sq->Fuse = (UINT8)Packet->NvmeCmd->Cdw0.FusedOperation; - Sq->Cid = Private->Cid[QueueType]++; - Sq->Nsid = Packet->NvmeCmd->Nsid; - - // - // Currently we only support PRP for data transfer, SGL is NOT supported. - // - ASSERT (Sq->Psdt == 0); - if (Sq->Psdt != 0) { - DEBUG ((EFI_D_ERROR, "NvmExpressPassThru: doesn't support SGL mechanism\n")); - return EFI_UNSUPPORTED; - } - - Sq->Prp[0] = (UINT64)(UINTN)Packet->TransferBuffer; - // - // If the NVMe cmd has data in or out, then mapping the user buffer to the PCI controller specific addresses. - // Note here we don't handle data buffer for CreateIOSubmitionQueue and CreateIOCompletionQueue cmds because - // these two cmds are special which requires their data buffer must support simultaneous access by both the - // processor and a PCI Bus Master. It's caller's responsbility to ensure this. - // - if (((Sq->Opc & (BIT0 | BIT1)) != 0) && (Sq->Opc != NVME_ADMIN_CRIOCQ_CMD) && (Sq->Opc != NVME_ADMIN_CRIOSQ_CMD)) { - if ((Sq->Opc & BIT0) != 0) { - Flag = EfiPciIoOperationBusMasterRead; - } else { - Flag = EfiPciIoOperationBusMasterWrite; - } - - MapLength = Packet->TransferLength; - Status = PciIo->Map ( - PciIo, - Flag, - Packet->TransferBuffer, - &MapLength, - &PhyAddr, - &MapData - ); - if (EFI_ERROR (Status) || (Packet->TransferLength != MapLength)) { - return EFI_OUT_OF_RESOURCES; - } - - Sq->Prp[0] = PhyAddr; - Sq->Prp[1] = 0; - - MapLength = Packet->MetadataLength; - if(Packet->MetadataBuffer != NULL) { - MapLength = Packet->MetadataLength; - Status = PciIo->Map ( - PciIo, - Flag, - Packet->MetadataBuffer, - &MapLength, - &PhyAddr, - &MapMeta - ); - if (EFI_ERROR (Status) || (Packet->MetadataLength != MapLength)) { - PciIo->Unmap ( - PciIo, - MapData - ); - - return EFI_OUT_OF_RESOURCES; - } - Sq->Mptr = PhyAddr; - } - } - // - // If the buffer size spans more than two memory pages (page size as defined in CC.Mps), - // then build a PRP list in the second PRP submission queue entry. - // - Offset = ((UINT16)Sq->Prp[0]) & (EFI_PAGE_SIZE - 1); - Bytes = Packet->TransferLength; - - if ((Offset + Bytes) > (EFI_PAGE_SIZE * 2)) { - // - // Create PrpList for remaining data buffer. - // - PhyAddr = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1); - Prp = NvmeCreatePrpList (PciIo, PhyAddr, EFI_SIZE_TO_PAGES(Offset + Bytes) - 1, &PrpListHost, &PrpListNo, &MapPrpList); - if (Prp == NULL) { - goto EXIT; - } - - Sq->Prp[1] = (UINT64)(UINTN)Prp; - } else if ((Offset + Bytes) > EFI_PAGE_SIZE) { - Sq->Prp[1] = (Sq->Prp[0] + EFI_PAGE_SIZE) & ~(EFI_PAGE_SIZE - 1); - } - - if(Packet->NvmeCmd->Flags & CDW2_VALID) { - Sq->Rsvd2 = (UINT64)Packet->NvmeCmd->Cdw2; - } - if(Packet->NvmeCmd->Flags & CDW3_VALID) { - Sq->Rsvd2 |= LShiftU64 ((UINT64)Packet->NvmeCmd->Cdw3, 32); - } - if(Packet->NvmeCmd->Flags & CDW10_VALID) { - Sq->Payload.Raw.Cdw10 = Packet->NvmeCmd->Cdw10; - } - if(Packet->NvmeCmd->Flags & CDW11_VALID) { - Sq->Payload.Raw.Cdw11 = Packet->NvmeCmd->Cdw11; - } - if(Packet->NvmeCmd->Flags & CDW12_VALID) { - Sq->Payload.Raw.Cdw12 = Packet->NvmeCmd->Cdw12; - } - if(Packet->NvmeCmd->Flags & CDW13_VALID) { - Sq->Payload.Raw.Cdw13 = Packet->NvmeCmd->Cdw13; - } - if(Packet->NvmeCmd->Flags & CDW14_VALID) { - Sq->Payload.Raw.Cdw14 = Packet->NvmeCmd->Cdw14; - } - if(Packet->NvmeCmd->Flags & CDW15_VALID) { - Sq->Payload.Raw.Cdw15 = Packet->NvmeCmd->Cdw15; - } - - // - // Ring the submission queue doorbell. - // - Private->SqTdbl[QueueType].Sqt ^= 1; - Data = ReadUnaligned32 ((UINT32*)&Private->SqTdbl[QueueType]); - PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_SQTDBL_OFFSET(QueueType, Private->Cap.Dstrd), - 1, - &Data - ); - - Status = gBS->CreateEvent ( - EVT_TIMER, - TPL_CALLBACK, - NULL, - NULL, - &TimerEvent - ); - if (EFI_ERROR (Status)) { - goto EXIT; - } - - Status = gBS->SetTimer(TimerEvent, TimerRelative, Packet->CommandTimeout); - - if (EFI_ERROR(Status)) { - goto EXIT; - } - - // - // Wait for completion queue to get filled in. - // - Status = EFI_TIMEOUT; - while (EFI_ERROR (gBS->CheckEvent (TimerEvent))) { - if (Cq->Pt != Private->Pt[QueueType]) { - Status = EFI_SUCCESS; - break; - } - } - - // - // Check the NVMe cmd execution result - // - if (Status != EFI_TIMEOUT) { - if ((Cq->Sct == 0) && (Cq->Sc == 0)) { - Status = EFI_SUCCESS; - } else { - Status = EFI_DEVICE_ERROR; - // - // Copy the Respose Queue entry for this command to the callers response buffer - // - CopyMem(Packet->NvmeCompletion, Cq, sizeof(EFI_NVM_EXPRESS_COMPLETION)); - - // - // Dump every completion entry status for debugging. - // - DEBUG_CODE_BEGIN(); - NvmeDumpStatus(Cq); - DEBUG_CODE_END(); - } - } - - if ((Private->CqHdbl[QueueType].Cqh ^= 1) == 0) { - Private->Pt[QueueType] ^= 1; - } - - Data = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[QueueType]); - PciIo->Mem.Write ( - PciIo, - EfiPciIoWidthUint32, - NVME_BAR, - NVME_CQHDBL_OFFSET(QueueType, Private->Cap.Dstrd), - 1, - &Data - ); - -EXIT: - if (MapData != NULL) { - PciIo->Unmap ( - PciIo, - MapData - ); - } - - if (MapMeta != NULL) { - PciIo->Unmap ( - PciIo, - MapMeta - ); - } - - if (MapPrpList != NULL) { - PciIo->Unmap ( - PciIo, - MapPrpList - ); - } - - if (Prp != NULL) { - PciIo->FreeBuffer (PciIo, PrpListNo, PrpListHost); - } - - if (TimerEvent != NULL) { - gBS->CloseEvent (TimerEvent); - } - return Status; -} - -/** - Used to retrieve the next namespace ID for this NVM Express controller. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNextNamespace() function retrieves the next valid - namespace ID on this NVM Express controller. - - If on input the value pointed to by NamespaceId is 0xFFFFFFFF, then the first valid namespace - ID defined on the NVM Express controller is returned in the location pointed to by NamespaceId - and a status of EFI_SUCCESS is returned. - - If on input the value pointed to by NamespaceId is an invalid namespace ID other than 0xFFFFFFFF, - then EFI_INVALID_PARAMETER is returned. - - If on input the value pointed to by NamespaceId is a valid namespace ID, then the next valid - namespace ID on the NVM Express controller is returned in the location pointed to by NamespaceId, - and EFI_SUCCESS is returned. - - If the value pointed to by NamespaceId is the namespace ID of the last namespace on the NVM - Express controller, then EFI_NOT_FOUND is returned. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in,out] NamespaceId On input, a pointer to a legal NamespaceId for an NVM Express - namespace present on the NVM Express controller. On output, a - pointer to the next NamespaceId of an NVM Express namespace on - an NVM Express controller. An input value of 0xFFFFFFFF retrieves - the first NamespaceId for an NVM Express namespace present on an - NVM Express controller. - - @retval EFI_SUCCESS The Namespace ID of the next Namespace was returned. - @retval EFI_NOT_FOUND There are no more namespaces defined on this controller. - @retval EFI_INVALID_PARAMETER NamespaceId is an invalid value other than 0xFFFFFFFF. - -**/ -EFI_STATUS -EFIAPI -NvmExpressGetNextNamespace ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN OUT UINT32 *NamespaceId - ) -{ - NVME_CONTROLLER_PRIVATE_DATA *Private; - NVME_ADMIN_NAMESPACE_DATA *NamespaceData; - UINT32 NextNamespaceId; - EFI_STATUS Status; - - if ((This == NULL) || (NamespaceId == NULL)) { - return EFI_INVALID_PARAMETER; - } - - NamespaceData = NULL; - Status = EFI_NOT_FOUND; - - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This); - // - // If the NamespaceId input value is 0xFFFFFFFF, then get the first valid namespace ID - // - if (*NamespaceId == 0xFFFFFFFF) { - // - // Start with the first namespace ID - // - NextNamespaceId = 1; - // - // Allocate buffer for Identify Namespace data. - // - NamespaceData = (NVME_ADMIN_NAMESPACE_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); - - if (NamespaceData == NULL) { - return EFI_NOT_FOUND; - } - - Status = NvmeIdentifyNamespace (Private, NextNamespaceId, NamespaceData); - if (EFI_ERROR(Status)) { - goto Done; - } - - *NamespaceId = NextNamespaceId; - } else { - if (*NamespaceId >= Private->ControllerData->Nn) { - return EFI_INVALID_PARAMETER; - } - - NextNamespaceId = *NamespaceId + 1; - // - // Allocate buffer for Identify Namespace data. - // - NamespaceData = (NVME_ADMIN_NAMESPACE_DATA *)AllocateZeroPool (sizeof (NVME_ADMIN_NAMESPACE_DATA)); - if (NamespaceData == NULL) { - return EFI_NOT_FOUND; - } - - Status = NvmeIdentifyNamespace (Private, NextNamespaceId, NamespaceData); - if (EFI_ERROR(Status)) { - goto Done; - } - - *NamespaceId = NextNamespaceId; - } - -Done: - if (NamespaceData != NULL) { - FreePool(NamespaceData); - } - - return Status; -} - -/** - Used to translate a device path node to a namespace ID. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNamespace() function determines the namespace ID associated with the - namespace described by DevicePath. - - If DevicePath is a device path node type that the NVM Express Pass Thru driver supports, then the NVM Express - Pass Thru driver will attempt to translate the contents DevicePath into a namespace ID. - - If this translation is successful, then that namespace ID is returned in NamespaceId, and EFI_SUCCESS is returned - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] DevicePath A pointer to the device path node that describes an NVM Express namespace on - the NVM Express controller. - @param[out] NamespaceId The NVM Express namespace ID contained in the device path node. - - @retval EFI_SUCCESS DevicePath was successfully translated to NamespaceId. - @retval EFI_INVALID_PARAMETER If DevicePath or NamespaceId are NULL, then EFI_INVALID_PARAMETER is returned. - @retval EFI_UNSUPPORTED If DevicePath is not a device path node type that the NVM Express Pass Thru driver - supports, then EFI_UNSUPPORTED is returned. - @retval EFI_NOT_FOUND If DevicePath is a device path node type that the NVM Express Pass Thru driver - supports, but there is not a valid translation from DevicePath to a namespace ID, - then EFI_NOT_FOUND is returned. -**/ -EFI_STATUS -EFIAPI -NvmExpressGetNamespace ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT UINT32 *NamespaceId - ) -{ - NVME_NAMESPACE_DEVICE_PATH *Node; - - if ((This == NULL) || (DevicePath == NULL) || (NamespaceId == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (DevicePath->Type != MESSAGING_DEVICE_PATH) { - return EFI_UNSUPPORTED; - } - - Node = (NVME_NAMESPACE_DEVICE_PATH *)DevicePath; - - if (DevicePath->SubType == MSG_NVME_NAMESPACE_DP) { - if (DevicePathNodeLength(DevicePath) != sizeof(NVME_NAMESPACE_DEVICE_PATH)) { - return EFI_NOT_FOUND; - } - - *NamespaceId = Node->NamespaceId; - - return EFI_SUCCESS; - } else { - return EFI_UNSUPPORTED; - } -} - -/** - Used to allocate and build a device path node for an NVM Express namespace on an NVM Express controller. - - The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.BuildDevicePath() function allocates and builds a single device - path node for the NVM Express namespace specified by NamespaceId. - - If the NamespaceId is not valid, then EFI_NOT_FOUND is returned. - - If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned. - - If there are not enough resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned. - - Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of DevicePath are - initialized to describe the NVM Express namespace specified by NamespaceId, and EFI_SUCCESS is returned. - - @param[in] This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance. - @param[in] NamespaceId The NVM Express namespace ID for which a device path node is to be - allocated and built. Caller must set the NamespaceId to zero if the - device path node will contain a valid UUID. - @param[in,out] DevicePath A pointer to a single device path node that describes the NVM Express - namespace specified by NamespaceId. This function is responsible for - allocating the buffer DevicePath with the boot service AllocatePool(). - It is the caller's responsibility to free DevicePath when the caller - is finished with DevicePath. - @retval EFI_SUCCESS The device path node that describes the NVM Express namespace specified - by NamespaceId was allocated and returned in DevicePath. - @retval EFI_NOT_FOUND The NamespaceId is not valid. - @retval EFI_INVALID_PARAMETER DevicePath is NULL. - @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the DevicePath node. - -**/ -EFI_STATUS -EFIAPI -NvmExpressBuildDevicePath ( - IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This, - IN UINT32 NamespaceId, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath - ) -{ - NVME_NAMESPACE_DEVICE_PATH *Node; - NVME_CONTROLLER_PRIVATE_DATA *Private; - EFI_STATUS Status; - NVME_ADMIN_NAMESPACE_DATA *NamespaceData; - - // - // Validate parameters - // - if ((This == NULL) || (DevicePath == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (NamespaceId == 0) { - return EFI_NOT_FOUND; - } - - Status = EFI_SUCCESS; - Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This); - - Node = (NVME_NAMESPACE_DEVICE_PATH *)AllocateZeroPool (sizeof (NVME_NAMESPACE_DEVICE_PATH)); - if (Node == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Node->Header.Type = MESSAGING_DEVICE_PATH; - Node->Header.SubType = MSG_NVME_NAMESPACE_DP; - SetDevicePathNodeLength (&Node->Header, sizeof (NVME_NAMESPACE_DEVICE_PATH)); - Node->NamespaceId = NamespaceId; - - // - // Allocate a buffer for Identify Namespace data. - // - NamespaceData = NULL; - NamespaceData = AllocateZeroPool(sizeof (NVME_ADMIN_NAMESPACE_DATA)); - if(NamespaceData == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - // - // Get UUID from specified Identify Namespace data. - // - Status = NvmeIdentifyNamespace ( - Private, - NamespaceId, - (VOID *)NamespaceData - ); - - if (EFI_ERROR(Status)) { - goto Exit; - } - - Node->NamespaceUuid = NamespaceData->Eui64; - - *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Node; - -Exit: - if(NamespaceData != NULL) { - FreePool (NamespaceData); - } - - if (EFI_ERROR (Status)) { - FreePool (Node); - } - - return Status; -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.c deleted file mode 100644 index 580e8bcc44..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.c +++ /dev/null @@ -1,176 +0,0 @@ -/** @file - EFI Component Name functions implementation for PCI Bus module. - -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName = { - PciBusComponentNameGetDriverName, - PciBusComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPciBusComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) PciBusComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) PciBusComponentNameGetControllerName, - "en" -}; - - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPciBusDriverNameTable[] = { - { "eng;en", (CHAR16 *) L"PCI Bus Driver" }, - { NULL , NULL } -}; - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -PciBusComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mPciBusDriverNameTable, - DriverName, - (BOOLEAN)(This == &gPciBusComponentName) - ); -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -PciBusComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - return EFI_UNSUPPORTED; -} diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.h b/MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.h deleted file mode 100644 index e74851ed35..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/ComponentName.h +++ /dev/null @@ -1,152 +0,0 @@ -/** @file - EFI Component Name functions declaration for PCI Bus module. - -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#ifndef _EFI_PCI_BUS_COMPONENT_NAME_H_ -#define _EFI_PCI_BUS_COMPONENT_NAME_H_ - -extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gPciBusComponentName2; - -// -// EFI Component Name Functions -// -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -PciBusComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -PciBusComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c deleted file mode 100644 index beecf79a35..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c +++ /dev/null @@ -1,409 +0,0 @@ -/** @file - Driver Binding functions for PCI Bus module. - - Single PCI bus driver instance will manager all PCI Root Bridges in one EFI based firmware, - since all PCI Root Bridges' resources need to be managed together. - Supported() function will try to get PCI Root Bridge IO Protocol. - Start() function will get PCI Host Bridge Resource Allocation Protocol to manage all - PCI Root Bridges. So it means platform needs install PCI Root Bridge IO protocol for each - PCI Root Bus and install PCI Host Bridge Resource Allocation Protocol. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -// -// PCI Bus Driver Global Variables -// -EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = { - PciBusDriverBindingSupported, - PciBusDriverBindingStart, - PciBusDriverBindingStop, - 0xa, - NULL, - NULL -}; - -EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM]; -EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport = NULL; -UINTN gPciHostBridgeNumber = 0; -BOOLEAN gFullEnumeration = TRUE; -UINT64 gAllOne = 0xFFFFFFFFFFFFFFFFULL; -UINT64 gAllZero = 0; - -EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; -EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol; - - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_PCI_HOTPLUG_REQUEST_PROTOCOL mPciHotPlugRequest = { - PciHotPlugRequestNotify -}; - -/** - The Entry Point for PCI Bus module. The user code starts with this function. - - Installs driver module protocols and. Creates virtual device handles for ConIn, - ConOut, and StdErr. Installs Simple Text In protocol, Simple Text In Ex protocol, - Simple Pointer protocol, Absolute Pointer protocol on those virtual handlers. - Installs Graphics Output protocol and/or UGA Draw protocol if needed. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval other Some error occurred when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -PciBusEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - - // - // Initializes PCI devices pool - // - InitializePciDevicePool (); - - // - // Install driver model protocol(s). - // - Status = EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gPciBusDriverBinding, - ImageHandle, - &gPciBusComponentName, - &gPciBusComponentName2 - ); - ASSERT_EFI_ERROR (Status); - - if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - // - // If Hot Plug is supported, install EFI PCI Hot Plug Request protocol. - // - Handle = NULL; - Status = gBS->InstallProtocolInterface ( - &Handle, - &gEfiPciHotPlugRequestProtocolGuid, - EFI_NATIVE_INTERFACE, - &mPciHotPlugRequest - ); - } - - return Status; -} - -/** - Test to see if this driver supports ControllerHandle. Any ControllerHandle - than contains a gEfiPciRootBridgeIoProtocolGuid protocol can be supported. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Optional parameter use to pick a specific child. - device to start. - - @retval EFI_SUCCESS This driver supports this device. - @retval EFI_ALREADY_STARTED This driver is already running on this device. - @retval other This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -PciBusDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - EFI_DEV_PATH_PTR Node; - - // - // Check RemainingDevicePath validation - // - if (RemainingDevicePath != NULL) { - // - // Check if RemainingDevicePath is the End of Device Path Node, - // if yes, go on checking other conditions - // - if (!IsDevicePathEnd (RemainingDevicePath)) { - // - // If RemainingDevicePath isn't the End of Device Path Node, - // check its validation - // - Node.DevPath = RemainingDevicePath; - if (Node.DevPath->Type != HARDWARE_DEVICE_PATH || - Node.DevPath->SubType != HW_PCI_DP || - DevicePathNodeLength(Node.DevPath) != sizeof(PCI_DEVICE_PATH)) { - return EFI_UNSUPPORTED; - } - } - } - - // - // Check if Pci Root Bridge IO protocol is installed by platform - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Close the I/O Abstraction(s) used to perform the supported test - // - gBS->CloseProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - // - // Open the EFI Device Path protocol needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Close protocol, don't use device path protocol in the Support() function - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return EFI_SUCCESS; -} - -/** - Start this driver on ControllerHandle and enumerate Pci bus and start - all device under PCI bus. - - @param This Protocol instance pointer. - @param Controller Handle of device to bind driver to. - @param RemainingDevicePath Optional parameter use to pick a specific child. - device to start. - - @retval EFI_SUCCESS This driver is added to ControllerHandle. - @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle. - @retval other This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -PciBusDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - - // - // Check RemainingDevicePath validation - // - if (RemainingDevicePath != NULL) { - // - // Check if RemainingDevicePath is the End of Device Path Node, - // if yes, return EFI_SUCCESS - // - if (IsDevicePathEnd (RemainingDevicePath)) { - return EFI_SUCCESS; - } - } - - gBS->LocateProtocol ( - &gEfiIncompatiblePciDeviceSupportProtocolGuid, - NULL, - (VOID **) &gEfiIncompatiblePciDeviceSupport - ); - - // - // If PCI Platform protocol is available, get it now. - // If the platform implements this, it must be installed before BDS phase - // - gPciPlatformProtocol = NULL; - gBS->LocateProtocol ( - &gEfiPciPlatformProtocolGuid, - NULL, - (VOID **) &gPciPlatformProtocol - ); - - // - // If PCI Platform protocol doesn't exist, try to Pci Override Protocol. - // - if (gPciPlatformProtocol == NULL) { - gPciOverrideProtocol = NULL; - gBS->LocateProtocol ( - &gEfiPciOverrideProtocolGuid, - NULL, - (VOID **) &gPciOverrideProtocol - ); - } - - if (PcdGetBool (PcdPciDisableBusEnumeration)) { - gFullEnumeration = FALSE; - } else { - gFullEnumeration = (BOOLEAN) ((SearchHostBridgeHandle (Controller) ? FALSE : TRUE)); - } - - // - // Open Device Path Protocol for PCI root bridge - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - - // - // Report Status Code to indicate PCI bus starts - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_PCI | EFI_IOB_PC_INIT), - ParentDevicePath - ); - - // - // Enumerate the entire host bridge - // After enumeration, a database that records all the device information will be created - // - // - Status = PciEnumerator (Controller); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Start all the devices under the entire host bridge. - // - StartPciDevices (Controller); - - return EFI_SUCCESS; -} - -/** - Stop this driver on ControllerHandle. Support stoping any child handles - created by this driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on. - @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of - children is zero stop the entire bus driver. - @param ChildHandleBuffer List of Child Handles to Stop. - - @retval EFI_SUCCESS This driver is removed ControllerHandle. - @retval other This driver was not removed from this device. - -**/ -EFI_STATUS -EFIAPI -PciBusDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_STATUS Status; - UINTN Index; - BOOLEAN AllChildrenStopped; - - if (NumberOfChildren == 0) { - // - // Close the bus driver - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - gBS->CloseProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - DestroyRootBridgeByHandle ( - Controller - ); - - return EFI_SUCCESS; - } - - // - // Stop all the children - // - - AllChildrenStopped = TRUE; - - for (Index = 0; Index < NumberOfChildren; Index++) { - - // - // De register all the pci device - // - Status = DeRegisterPciDevice (Controller, ChildHandleBuffer[Index]); - - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - } - } - - if (!AllChildrenStopped) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h deleted file mode 100644 index b99d3181ac..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h +++ /dev/null @@ -1,404 +0,0 @@ -/** @file - Header files and data structures needed by PCI Bus module. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#ifndef _EFI_PCI_BUS_H_ -#define _EFI_PCI_BUS_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -typedef struct _PCI_IO_DEVICE PCI_IO_DEVICE; -typedef struct _PCI_BAR PCI_BAR; - -#define EFI_PCI_RID(Bus, Device, Function) (((UINT32)Bus << 8) + ((UINT32)Device << 3) + (UINT32)Function) -#define EFI_PCI_BUS_OF_RID(RID) ((UINT32)RID >> 8) - -#define EFI_PCI_IOV_POLICY_ARI 0x0001 -#define EFI_PCI_IOV_POLICY_SRIOV 0x0002 -#define EFI_PCI_IOV_POLICY_MRIOV 0x0004 - -typedef enum { - PciBarTypeUnknown = 0, - PciBarTypeIo16, - PciBarTypeIo32, - PciBarTypeMem32, - PciBarTypePMem32, - PciBarTypeMem64, - PciBarTypePMem64, - PciBarTypeIo, - PciBarTypeMem, - PciBarTypeMaxType -} PCI_BAR_TYPE; - -#include "ComponentName.h" -#include "PciIo.h" -#include "PciCommand.h" -#include "PciDeviceSupport.h" -#include "PciEnumerator.h" -#include "PciEnumeratorSupport.h" -#include "PciDriverOverride.h" -#include "PciRomTable.h" -#include "PciOptionRomSupport.h" -#include "PciPowerManagement.h" -#include "PciHotPlugSupport.h" -#include "PciLib.h" - -#define VGABASE1 0x3B0 -#define VGALIMIT1 0x3BB - -#define VGABASE2 0x3C0 -#define VGALIMIT2 0x3DF - -#define ISABASE 0x100 -#define ISALIMIT 0x3FF - -// -// PCI BAR parameters -// -struct _PCI_BAR { - UINT64 BaseAddress; - UINT64 Length; - UINT64 Alignment; - PCI_BAR_TYPE BarType; - BOOLEAN Prefetchable; - UINT8 MemType; - UINT16 Offset; -}; - -// -// defined in PCI Card Specification, 8.0 -// -#define PCI_CARD_MEMORY_BASE_0 0x1C -#define PCI_CARD_MEMORY_LIMIT_0 0x20 -#define PCI_CARD_MEMORY_BASE_1 0x24 -#define PCI_CARD_MEMORY_LIMIT_1 0x28 -#define PCI_CARD_IO_BASE_0_LOWER 0x2C -#define PCI_CARD_IO_BASE_0_UPPER 0x2E -#define PCI_CARD_IO_LIMIT_0_LOWER 0x30 -#define PCI_CARD_IO_LIMIT_0_UPPER 0x32 -#define PCI_CARD_IO_BASE_1_LOWER 0x34 -#define PCI_CARD_IO_BASE_1_UPPER 0x36 -#define PCI_CARD_IO_LIMIT_1_LOWER 0x38 -#define PCI_CARD_IO_LIMIT_1_UPPER 0x3A -#define PCI_CARD_BRIDGE_CONTROL 0x3E - -#define PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE BIT8 -#define PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE BIT9 - -#define RB_IO_RANGE 1 -#define RB_MEM32_RANGE 2 -#define RB_PMEM32_RANGE 3 -#define RB_MEM64_RANGE 4 -#define RB_PMEM64_RANGE 5 - -#define PPB_BAR_0 0 -#define PPB_BAR_1 1 -#define PPB_IO_RANGE 2 -#define PPB_MEM32_RANGE 3 -#define PPB_PMEM32_RANGE 4 -#define PPB_PMEM64_RANGE 5 -#define PPB_MEM64_RANGE 0xFF - -#define P2C_BAR_0 0 -#define P2C_MEM_1 1 -#define P2C_MEM_2 2 -#define P2C_IO_1 3 -#define P2C_IO_2 4 - -#define EFI_BRIDGE_IO32_DECODE_SUPPORTED 0x0001 -#define EFI_BRIDGE_PMEM32_DECODE_SUPPORTED 0x0002 -#define EFI_BRIDGE_PMEM64_DECODE_SUPPORTED 0x0004 -#define EFI_BRIDGE_IO16_DECODE_SUPPORTED 0x0008 -#define EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED 0x0010 -#define EFI_BRIDGE_MEM64_DECODE_SUPPORTED 0x0020 -#define EFI_BRIDGE_MEM32_DECODE_SUPPORTED 0x0040 - -#define PCI_MAX_HOST_BRIDGE_NUM 0x0010 - -// -// Define option for attribute -// -#define EFI_SET_SUPPORTS 0 -#define EFI_SET_ATTRIBUTES 1 - -#define PCI_IO_DEVICE_SIGNATURE SIGNATURE_32 ('p', 'c', 'i', 'o') - -struct _PCI_IO_DEVICE { - UINT32 Signature; - EFI_HANDLE Handle; - EFI_PCI_IO_PROTOCOL PciIo; - LIST_ENTRY Link; - - EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL PciDriverOverride; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - EFI_LOAD_FILE2_PROTOCOL LoadFile2; - - // - // PCI configuration space header type - // - PCI_TYPE00 Pci; - - // - // Bus number, Device number, Function number - // - UINT8 BusNumber; - UINT8 DeviceNumber; - UINT8 FunctionNumber; - - // - // BAR for this PCI Device - // - PCI_BAR PciBar[PCI_MAX_BAR]; - - // - // The bridge device this pci device is subject to - // - PCI_IO_DEVICE *Parent; - - // - // A linked list for children Pci Device if it is bridge device - // - LIST_ENTRY ChildList; - - // - // TURE if the PCI bus driver creates the handle for this PCI device - // - BOOLEAN Registered; - - // - // TRUE if the PCI bus driver successfully allocates the resource required by - // this PCI device - // - BOOLEAN Allocated; - - // - // The attribute this PCI device currently set - // - UINT64 Attributes; - - // - // The attributes this PCI device actually supports - // - UINT64 Supports; - - // - // The resource decode the bridge supports - // - UINT32 Decodes; - - // - // TRUE if the ROM image is from the PCI Option ROM BAR - // - BOOLEAN EmbeddedRom; - - // - // The OptionRom Size - // - UINT64 RomSize; - - // - // The OptionRom Size - // - UINT64 RomBase; - - // - // TRUE if all OpROM (in device or in platform specific position) have been processed - // - BOOLEAN AllOpRomProcessed; - - // - // TRUE if there is any EFI driver in the OptionRom - // - BOOLEAN BusOverride; - - // - // A list tracking reserved resource on a bridge device - // - LIST_ENTRY ReservedResourceList; - - // - // A list tracking image handle of platform specific overriding driver - // - LIST_ENTRY OptionRomDriverList; - - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ResourcePaddingDescriptors; - EFI_HPC_PADDING_ATTRIBUTES PaddingAttributes; - - // - // Bus number ranges for a PCI Root Bridge device - // - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BusNumberRanges; - - BOOLEAN IsPciExp; - // - // For SR-IOV - // - UINT8 PciExpressCapabilityOffset; - UINT32 AriCapabilityOffset; - UINT32 SrIovCapabilityOffset; - UINT32 MrIovCapabilityOffset; - PCI_BAR VfPciBar[PCI_MAX_BAR]; - UINT32 SystemPageSize; - UINT16 InitialVFs; - UINT16 ReservedBusNum; - // - // Per PCI to PCI Bridge spec, I/O window is 4K aligned, - // but some chipsets support non-stardard I/O window aligments less than 4K. - // This field is used to support this case. - // - UINT16 BridgeIoAlignment; -}; - -#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \ - CR (a, PCI_IO_DEVICE, PciIo, PCI_IO_DEVICE_SIGNATURE) - -#define PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS(a) \ - CR (a, PCI_IO_DEVICE, PciDriverOverride, PCI_IO_DEVICE_SIGNATURE) - -#define PCI_IO_DEVICE_FROM_LINK(a) \ - CR (a, PCI_IO_DEVICE, Link, PCI_IO_DEVICE_SIGNATURE) - -#define PCI_IO_DEVICE_FROM_LOAD_FILE2_THIS(a) \ - CR (a, PCI_IO_DEVICE, LoadFile2, PCI_IO_DEVICE_SIGNATURE) - - - -// -// Global Variables -// -extern EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *gEfiIncompatiblePciDeviceSupport; -extern EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gPciBusComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gPciBusComponentName2; -extern BOOLEAN gFullEnumeration; -extern UINTN gPciHostBridgeNumber; -extern EFI_HANDLE gPciHostBrigeHandles[PCI_MAX_HOST_BRIDGE_NUM]; -extern UINT64 gAllOne; -extern UINT64 gAllZero; -extern EFI_PCI_PLATFORM_PROTOCOL *gPciPlatformProtocol; -extern EFI_PCI_OVERRIDE_PROTOCOL *gPciOverrideProtocol; -extern BOOLEAN mReserveIsaAliases; -extern BOOLEAN mReserveVgaAliases; - -/** - Macro that checks whether device is a GFX device. - - @param _p Specified device. - - @retval TRUE Device is a a GFX device. - @retval FALSE Device is not a a GFX device. - -**/ -#define IS_PCI_GFX(_p) IS_CLASS2 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_OTHER) - -/** - Test to see if this driver supports ControllerHandle. Any ControllerHandle - than contains a gEfiPciRootBridgeIoProtocolGuid protocol can be supported. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Optional parameter use to pick a specific child. - device to start. - - @retval EFI_SUCCESS This driver supports this device. - @retval EFI_ALREADY_STARTED This driver is already running on this device. - @retval other This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -PciBusDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Start this driver on ControllerHandle and enumerate Pci bus and start - all device under PCI bus. - - @param This Protocol instance pointer. - @param Controller Handle of device to bind driver to. - @param RemainingDevicePath Optional parameter use to pick a specific child. - device to start. - - @retval EFI_SUCCESS This driver is added to ControllerHandle. - @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle. - @retval other This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -PciBusDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stop this driver on ControllerHandle. Support stoping any child handles - created by this driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on. - @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of - children is zero stop the entire bus driver. - @param ChildHandleBuffer List of Child Handles to Stop. - - @retval EFI_SUCCESS This driver is removed ControllerHandle. - @retval other This driver was not removed from this device. - -**/ -EFI_STATUS -EFIAPI -PciBusDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf deleted file mode 100644 index 330ccc8cbf..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +++ /dev/null @@ -1,112 +0,0 @@ -## @file -# The PCI bus driver will probe all PCI devices and allocate MMIO and IO space for these devices. -# Please use PCD feature flag PcdPciBusHotplugDeviceSupport to enable hot plug supporting. -# -# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = PciBusDxe - MODULE_UNI_FILE = PciBusDxe.uni - FILE_GUID = 93B80004-9FB3-11d4-9A3A-0090273FC14D - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = PciBusEntryPoint - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64 -# -# DRIVER_BINDING = gPciBusDriverBinding -# COMPONENT_NAME = gPciBusComponentName -# COMPONENT_NAME2 = gPciBusComponentName2 -# - -[Sources] - PciLib.c - PciIo.c - PciBus.c - PciDeviceSupport.c - ComponentName.c - ComponentName.h - PciCommand.c - PciResourceSupport.c - PciEnumeratorSupport.c - PciEnumerator.c - PciOptionRomSupport.c - PciDriverOverride.c - PciPowerManagement.c - PciPowerManagement.h - PciDriverOverride.h - PciRomTable.c - PciHotPlugSupport.c - PciLib.h - PciHotPlugSupport.h - PciRomTable.h - PciOptionRomSupport.h - PciEnumeratorSupport.h - PciEnumerator.h - PciResourceSupport.h - PciDeviceSupport.h - PciCommand.h - PciIo.h - PciBus.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - PcdLib - DevicePathLib - UefiBootServicesTableLib - MemoryAllocationLib - ReportStatusCodeLib - BaseMemoryLib - UefiLib - BaseLib - UefiDriverEntryPoint - DebugLib - PeCoffLib - -[Protocols] - gEfiPciHotPlugRequestProtocolGuid ## SOMETIMES_PRODUCES - gEfiPciIoProtocolGuid ## BY_START - gEfiDevicePathProtocolGuid ## BY_START - gEfiBusSpecificDriverOverrideProtocolGuid ## BY_START - gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES - gEfiDecompressProtocolGuid ## SOMETIMES_CONSUMES - gEfiPciHotPlugInitProtocolGuid ## SOMETIMES_CONSUMES - gEfiPciHostBridgeResourceAllocationProtocolGuid ## TO_START - gEfiPciPlatformProtocolGuid ## SOMETIMES_CONSUMES - gEfiPciOverrideProtocolGuid ## SOMETIMES_CONSUMES - gEfiPciEnumerationCompleteProtocolGuid ## PRODUCES - gEfiPciRootBridgeIoProtocolGuid ## TO_START - gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadFile2ProtocolGuid ## SOMETIMES_PRODUCES - -[FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdPciBusHotplugDeviceSupport ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPciBridgeIoAlignmentProbe ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdUnalignedPciIoEnable ## CONSUMES - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration ## SOMETIMES_CONSUMES - -[UserExtensions.TianoCore."ExtraFiles"] - PciBusDxeExtra.uni diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.uni b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.uni deleted file mode 100644 index 9b34afdc9d..0000000000 Binary files a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxeExtra.uni b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxeExtra.uni deleted file mode 100644 index 63eff41a74..0000000000 Binary files a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxeExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c deleted file mode 100644 index 0bc1fbfeff..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c +++ /dev/null @@ -1,260 +0,0 @@ -/** @file - PCI command register operations supporting functions implementation for PCI Bus module. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -/** - Operate the PCI register via PciIo function interface. - - @param PciIoDevice Pointer to instance of PCI_IO_DEVICE. - @param Command Operator command. - @param Offset The address within the PCI configuration space for the PCI controller. - @param Operation Type of Operation. - @param PtrCommand Return buffer holding old PCI command, if operation is not EFI_SET_REGISTER. - - @return Status of PciIo operation. - -**/ -EFI_STATUS -PciOperateRegister ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 Command, - IN UINT8 Offset, - IN UINT8 Operation, - OUT UINT16 *PtrCommand - ) -{ - UINT16 OldCommand; - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - - OldCommand = 0; - PciIo = &PciIoDevice->PciIo; - - if (Operation != EFI_SET_REGISTER) { - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - Offset, - 1, - &OldCommand - ); - - if (Operation == EFI_GET_REGISTER) { - *PtrCommand = OldCommand; - return Status; - } - } - - if (Operation == EFI_ENABLE_REGISTER) { - OldCommand = (UINT16) (OldCommand | Command); - } else if (Operation == EFI_DISABLE_REGISTER) { - OldCommand = (UINT16) (OldCommand & ~(Command)); - } else { - OldCommand = Command; - } - - return PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - Offset, - 1, - &OldCommand - ); -} - -/** - Check the cpability supporting by given device. - - @param PciIoDevice Pointer to instance of PCI_IO_DEVICE. - - @retval TRUE Cpability supportted. - @retval FALSE Cpability not supportted. - -**/ -BOOLEAN -PciCapabilitySupport ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - if ((PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) != 0) { - return TRUE; - } - - return FALSE; -} - -/** - Locate capability register block per capability ID. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE. - @param CapId The capability ID. - @param Offset A pointer to the offset returned. - @param NextRegBlock A pointer to the next block returned. - - @retval EFI_SUCCESS Successfuly located capability register block. - @retval EFI_UNSUPPORTED Pci device does not support capability. - @retval EFI_NOT_FOUND Pci device support but can not find register block. - -**/ -EFI_STATUS -LocateCapabilityRegBlock ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 CapId, - IN OUT UINT8 *Offset, - OUT UINT8 *NextRegBlock OPTIONAL - ) -{ - UINT8 CapabilityPtr; - UINT16 CapabilityEntry; - UINT8 CapabilityID; - - // - // To check the cpability of this device supports - // - if (!PciCapabilitySupport (PciIoDevice)) { - return EFI_UNSUPPORTED; - } - - if (*Offset != 0) { - CapabilityPtr = *Offset; - } else { - - CapabilityPtr = 0; - if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - - PciIoDevice->PciIo.Pci.Read ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint8, - EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR, - 1, - &CapabilityPtr - ); - } else { - - PciIoDevice->PciIo.Pci.Read ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint8, - PCI_CAPBILITY_POINTER_OFFSET, - 1, - &CapabilityPtr - ); - } - } - - while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) { - PciIoDevice->PciIo.Pci.Read ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint16, - CapabilityPtr, - 1, - &CapabilityEntry - ); - - CapabilityID = (UINT8) CapabilityEntry; - - if (CapabilityID == CapId) { - *Offset = CapabilityPtr; - if (NextRegBlock != NULL) { - *NextRegBlock = (UINT8) (CapabilityEntry >> 8); - } - - return EFI_SUCCESS; - } - - // - // Certain PCI device may incorrectly have capability pointing to itself, - // break to avoid dead loop. - // - if (CapabilityPtr == (UINT8) (CapabilityEntry >> 8)) { - break; - } - - CapabilityPtr = (UINT8) (CapabilityEntry >> 8); - } - - return EFI_NOT_FOUND; -} - -/** - Locate PciExpress capability register block per capability ID. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE. - @param CapId The capability ID. - @param Offset A pointer to the offset returned. - @param NextRegBlock A pointer to the next block returned. - - @retval EFI_SUCCESS Successfuly located capability register block. - @retval EFI_UNSUPPORTED Pci device does not support capability. - @retval EFI_NOT_FOUND Pci device support but can not find register block. - -**/ -EFI_STATUS -LocatePciExpressCapabilityRegBlock ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 CapId, - IN OUT UINT32 *Offset, - OUT UINT32 *NextRegBlock OPTIONAL - ) -{ - EFI_STATUS Status; - UINT32 CapabilityPtr; - UINT32 CapabilityEntry; - UINT16 CapabilityID; - - // - // To check the capability of this device supports - // - if (!PciIoDevice->IsPciExp) { - return EFI_UNSUPPORTED; - } - - if (*Offset != 0) { - CapabilityPtr = *Offset; - } else { - CapabilityPtr = EFI_PCIE_CAPABILITY_BASE_OFFSET; - } - - while (CapabilityPtr != 0) { - // - // Mask it to DWORD alignment per PCI spec - // - CapabilityPtr &= 0xFFC; - Status = PciIoDevice->PciIo.Pci.Read ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint32, - CapabilityPtr, - 1, - &CapabilityEntry - ); - if (EFI_ERROR (Status)) { - break; - } - - CapabilityID = (UINT16) CapabilityEntry; - - if (CapabilityID == CapId) { - *Offset = CapabilityPtr; - if (NextRegBlock != NULL) { - *NextRegBlock = (CapabilityEntry >> 20) & 0xFFF; - } - - return EFI_SUCCESS; - } - - CapabilityPtr = (CapabilityEntry >> 20) & 0xFFF; - } - - return EFI_NOT_FOUND; -} diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.h deleted file mode 100644 index cc942d0d42..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.h +++ /dev/null @@ -1,238 +0,0 @@ -/** @file - PCI command register operations supporting functions declaration for PCI Bus module. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#ifndef _EFI_PCI_COMMAND_H_ -#define _EFI_PCI_COMMAND_H_ - -// -// The PCI Command register bits owned by PCI Bus driver. -// -// They should be cleared at the beginning. The other registers -// are owned by chipset, we should not touch them. -// -#define EFI_PCI_COMMAND_BITS_OWNED ( \ - EFI_PCI_COMMAND_IO_SPACE | \ - EFI_PCI_COMMAND_MEMORY_SPACE | \ - EFI_PCI_COMMAND_BUS_MASTER | \ - EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE | \ - EFI_PCI_COMMAND_VGA_PALETTE_SNOOP | \ - EFI_PCI_COMMAND_FAST_BACK_TO_BACK \ - ) - -// -// The PCI Bridge Control register bits owned by PCI Bus driver. -// -// They should be cleared at the beginning. The other registers -// are owned by chipset, we should not touch them. -// -#define EFI_PCI_BRIDGE_CONTROL_BITS_OWNED ( \ - EFI_PCI_BRIDGE_CONTROL_ISA | \ - EFI_PCI_BRIDGE_CONTROL_VGA | \ - EFI_PCI_BRIDGE_CONTROL_VGA_16 | \ - EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \ - ) - -// -// The PCCard Bridge Control register bits owned by PCI Bus driver. -// -// They should be cleared at the beginning. The other registers -// are owned by chipset, we should not touch them. -// -#define EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED ( \ - EFI_PCI_BRIDGE_CONTROL_ISA | \ - EFI_PCI_BRIDGE_CONTROL_VGA | \ - EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK \ - ) - - -#define EFI_GET_REGISTER 1 -#define EFI_SET_REGISTER 2 -#define EFI_ENABLE_REGISTER 3 -#define EFI_DISABLE_REGISTER 4 - -/** - Operate the PCI register via PciIo function interface. - - @param PciIoDevice Pointer to instance of PCI_IO_DEVICE. - @param Command Operator command. - @param Offset The address within the PCI configuration space for the PCI controller. - @param Operation Type of Operation. - @param PtrCommand Return buffer holding old PCI command, if operation is not EFI_SET_REGISTER. - - @return Status of PciIo operation. - -**/ -EFI_STATUS -PciOperateRegister ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 Command, - IN UINT8 Offset, - IN UINT8 Operation, - OUT UINT16 *PtrCommand - ); - -/** - Check the cpability supporting by given device. - - @param PciIoDevice Pointer to instance of PCI_IO_DEVICE. - - @retval TRUE Cpability supportted. - @retval FALSE Cpability not supportted. - -**/ -BOOLEAN -PciCapabilitySupport ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Locate capability register block per capability ID. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE. - @param CapId The capability ID. - @param Offset A pointer to the offset returned. - @param NextRegBlock A pointer to the next block returned. - - @retval EFI_SUCCESS Successfuly located capability register block. - @retval EFI_UNSUPPORTED Pci device does not support capability. - @retval EFI_NOT_FOUND Pci device support but can not find register block. - -**/ -EFI_STATUS -LocateCapabilityRegBlock ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 CapId, - IN OUT UINT8 *Offset, - OUT UINT8 *NextRegBlock OPTIONAL - ); - -/** - Locate PciExpress capability register block per capability ID. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE. - @param CapId The capability ID. - @param Offset A pointer to the offset returned. - @param NextRegBlock A pointer to the next block returned. - - @retval EFI_SUCCESS Successfuly located capability register block. - @retval EFI_UNSUPPORTED Pci device does not support capability. - @retval EFI_NOT_FOUND Pci device support but can not find register block. - -**/ -EFI_STATUS -LocatePciExpressCapabilityRegBlock ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 CapId, - IN OUT UINT32 *Offset, - OUT UINT32 *NextRegBlock OPTIONAL - ); - -/** - Macro that reads command register. - - @param a[in] Pointer to instance of PCI_IO_DEVICE. - @param b[out] Pointer to the 16-bit value read from command register. - - @return status of PciIo operation - -**/ -#define PCI_READ_COMMAND_REGISTER(a,b) \ - PciOperateRegister (a, 0, PCI_COMMAND_OFFSET, EFI_GET_REGISTER, b) - -/** - Macro that writes command register. - - @param a[in] Pointer to instance of PCI_IO_DEVICE. - @param b[in] The 16-bit value written into command register. - - @return status of PciIo operation - -**/ -#define PCI_SET_COMMAND_REGISTER(a,b) \ - PciOperateRegister (a, b, PCI_COMMAND_OFFSET, EFI_SET_REGISTER, NULL) - -/** - Macro that enables command register. - - @param a[in] Pointer to instance of PCI_IO_DEVICE. - @param b[in] The enabled value written into command register. - - @return status of PciIo operation - -**/ -#define PCI_ENABLE_COMMAND_REGISTER(a,b) \ - PciOperateRegister (a, b, PCI_COMMAND_OFFSET, EFI_ENABLE_REGISTER, NULL) - -/** - Macro that disalbes command register. - - @param a[in] Pointer to instance of PCI_IO_DEVICE. - @param b[in] The disabled value written into command register. - - @return status of PciIo operation - -**/ -#define PCI_DISABLE_COMMAND_REGISTER(a,b) \ - PciOperateRegister (a, b, PCI_COMMAND_OFFSET, EFI_DISABLE_REGISTER, NULL) - -/** - Macro that reads PCI bridge control register. - - @param a[in] Pointer to instance of PCI_IO_DEVICE. - @param b[out] The 16-bit value read from control register. - - @return status of PciIo operation - -**/ -#define PCI_READ_BRIDGE_CONTROL_REGISTER(a,b) \ - PciOperateRegister (a, 0, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_GET_REGISTER, b) - -/** - Macro that writes PCI bridge control register. - - @param a[in] Pointer to instance of PCI_IO_DEVICE. - @param b[in] The 16-bit value written into control register. - - @return status of PciIo operation - -**/ -#define PCI_SET_BRIDGE_CONTROL_REGISTER(a,b) \ - PciOperateRegister (a, b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_SET_REGISTER, NULL) - -/** - Macro that enables PCI bridge control register. - - @param a[in] Pointer to instance of PCI_IO_DEVICE. - @param b[in] The enabled value written into command register. - - @return status of PciIo operation - -**/ -#define PCI_ENABLE_BRIDGE_CONTROL_REGISTER(a,b) \ - PciOperateRegister (a, b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_ENABLE_REGISTER, NULL) - -/** - Macro that disalbes PCI bridge control register. - - @param a[in] Pointer to instance of PCI_IO_DEVICE. - @param b[in] The disabled value written into command register. - - @return status of PciIo operation - -**/ -#define PCI_DISABLE_BRIDGE_CONTROL_REGISTER(a,b) \ - PciOperateRegister (a, b, PCI_BRIDGE_CONTROL_REGISTER_OFFSET, EFI_DISABLE_REGISTER, NULL) - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c deleted file mode 100644 index c0227fa2b6..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.c +++ /dev/null @@ -1,1155 +0,0 @@ -/** @file - Supporting functions implementaion for PCI devices management. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -// -// This device structure is serviced as a header. -// Its next field points to the first root bridge device node. -// -LIST_ENTRY mPciDevicePool; - -/** - Initialize the PCI devices pool. - -**/ -VOID -InitializePciDevicePool ( - VOID - ) -{ - InitializeListHead (&mPciDevicePool); -} - -/** - Insert a root bridge into PCI device pool. - - @param RootBridge A pointer to the PCI_IO_DEVICE. - -**/ -VOID -InsertRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ) -{ - InsertTailList (&mPciDevicePool, &(RootBridge->Link)); -} - -/** - This function is used to insert a PCI device node under - a bridge. - - @param Bridge The PCI bridge. - @param PciDeviceNode The PCI device needs inserting. - -**/ -VOID -InsertPciDevice ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_IO_DEVICE *PciDeviceNode - ) -{ - InsertTailList (&Bridge->ChildList, &(PciDeviceNode->Link)); - PciDeviceNode->Parent = Bridge; -} - -/** - Destroy root bridge and remove it from deivce tree. - - @param RootBridge The bridge want to be removed. - -**/ -VOID -DestroyRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ) -{ - DestroyPciDeviceTree (RootBridge); - - FreePciDevice (RootBridge); -} - -/** - Destroy a pci device node. - - All direct or indirect allocated resource for this node will be freed. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE to be destoried. - -**/ -VOID -FreePciDevice ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - ASSERT (PciIoDevice != NULL); - // - // Assume all children have been removed underneath this device - // - if (PciIoDevice->ResourcePaddingDescriptors != NULL) { - FreePool (PciIoDevice->ResourcePaddingDescriptors); - } - - if (PciIoDevice->DevicePath != NULL) { - FreePool (PciIoDevice->DevicePath); - } - - FreePool (PciIoDevice); -} - -/** - Destroy all the pci device node under the bridge. - Bridge itself is not included. - - @param Bridge A pointer to the PCI_IO_DEVICE. - -**/ -VOID -DestroyPciDeviceTree ( - IN PCI_IO_DEVICE *Bridge - ) -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - while (!IsListEmpty (&Bridge->ChildList)) { - - CurrentLink = Bridge->ChildList.ForwardLink; - - // - // Remove this node from the linked list - // - RemoveEntryList (CurrentLink); - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (!IsListEmpty (&Temp->ChildList)) { - DestroyPciDeviceTree (Temp); - } - - FreePciDevice (Temp); - } -} - -/** - Destroy all device nodes under the root bridge - specified by Controller. - - The root bridge itself is also included. - - @param Controller Root bridge handle. - - @retval EFI_SUCCESS Destory all devcie nodes successfully. - @retval EFI_NOT_FOUND Cannot find any PCI device under specified - root bridge. - -**/ -EFI_STATUS -DestroyRootBridgeByHandle ( - IN EFI_HANDLE Controller - ) -{ - - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - CurrentLink = mPciDevicePool.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &mPciDevicePool) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (Temp->Handle == Controller) { - - RemoveEntryList (CurrentLink); - - DestroyPciDeviceTree (Temp); - - FreePciDevice (Temp); - - return EFI_SUCCESS; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_NOT_FOUND; -} - -/** - This function registers the PCI IO device. - - It creates a handle for this PCI IO device (if the handle does not exist), attaches - appropriate protocols onto the handle, does necessary initialization, and sets up - parent/child relationship with its bus controller. - - @param Controller An EFI handle for the PCI bus controller. - @param PciIoDevice A PCI_IO_DEVICE pointer to the PCI IO device to be registered. - @param Handle A pointer to hold the returned EFI handle for the PCI IO device. - - @retval EFI_SUCCESS The PCI device is successfully registered. - @retval other An error occurred when registering the PCI device. - -**/ -EFI_STATUS -RegisterPciDevice ( - IN EFI_HANDLE Controller, - IN PCI_IO_DEVICE *PciIoDevice, - OUT EFI_HANDLE *Handle OPTIONAL - ) -{ - EFI_STATUS Status; - VOID *PlatformOpRomBuffer; - UINTN PlatformOpRomSize; - UINT8 PciExpressCapRegOffset; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Data8; - BOOLEAN HasEfiImage; - - // - // Install the pciio protocol, device path protocol - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - NULL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Detect if PCI Express Device - // - PciExpressCapRegOffset = 0; - Status = LocateCapabilityRegBlock ( - PciIoDevice, - EFI_PCI_CAPABILITY_ID_PCIEXP, - &PciExpressCapRegOffset, - NULL - ); - if (!EFI_ERROR (Status)) { - PciIoDevice->IsPciExp = TRUE; - } - - // - // Force Interrupt line to "Unknown" or "No Connection" - // - PciIo = &(PciIoDevice->PciIo); - Data8 = PCI_INT_LINE_UNKNOWN; - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Data8); - - // - // Process OpRom - // - if (!PciIoDevice->AllOpRomProcessed) { - - // - // Get the OpRom provided by platform - // - if (gPciPlatformProtocol != NULL) { - Status = gPciPlatformProtocol->GetPciRom ( - gPciPlatformProtocol, - PciIoDevice->Handle, - &PlatformOpRomBuffer, - &PlatformOpRomSize - ); - if (!EFI_ERROR (Status)) { - PciIoDevice->EmbeddedRom = FALSE; - PciIoDevice->RomSize = PlatformOpRomSize; - PciIoDevice->PciIo.RomSize = PlatformOpRomSize; - PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer; - // - // For OpROM read from gPciPlatformProtocol: - // Add the Rom Image to internal database for later PCI light enumeration - // - PciRomAddImageMapping ( - NULL, - PciIoDevice->PciRootBridgeIo->SegmentNumber, - PciIoDevice->BusNumber, - PciIoDevice->DeviceNumber, - PciIoDevice->FunctionNumber, - (UINT64) (UINTN) PciIoDevice->PciIo.RomImage, - PciIoDevice->PciIo.RomSize - ); - } - } else if (gPciOverrideProtocol != NULL) { - Status = gPciOverrideProtocol->GetPciRom ( - gPciOverrideProtocol, - PciIoDevice->Handle, - &PlatformOpRomBuffer, - &PlatformOpRomSize - ); - if (!EFI_ERROR (Status)) { - PciIoDevice->EmbeddedRom = FALSE; - PciIoDevice->RomSize = PlatformOpRomSize; - PciIoDevice->PciIo.RomSize = PlatformOpRomSize; - PciIoDevice->PciIo.RomImage = PlatformOpRomBuffer; - // - // For OpROM read from gPciOverrideProtocol: - // Add the Rom Image to internal database for later PCI light enumeration - // - PciRomAddImageMapping ( - NULL, - PciIoDevice->PciRootBridgeIo->SegmentNumber, - PciIoDevice->BusNumber, - PciIoDevice->DeviceNumber, - PciIoDevice->FunctionNumber, - (UINT64) (UINTN) PciIoDevice->PciIo.RomImage, - PciIoDevice->PciIo.RomSize - ); - } - } - } - - // - // Determine if there are EFI images in the option rom - // - HasEfiImage = ContainEfiImage (PciIoDevice->PciIo.RomImage, PciIoDevice->PciIo.RomSize); - - if (HasEfiImage) { - Status = gBS->InstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiLoadFile2ProtocolGuid, - &PciIoDevice->LoadFile2, - NULL - ); - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - NULL - ); - return Status; - } - } - - - if (!PciIoDevice->AllOpRomProcessed) { - - PciIoDevice->AllOpRomProcessed = TRUE; - - // - // Dispatch the EFI OpRom for the PCI device. - // The OpRom is got from platform in the above code - // or loaded from device in the previous round of bus enumeration - // - if (HasEfiImage) { - ProcessOpRomImage (PciIoDevice); - } - } - - if (PciIoDevice->BusOverride) { - // - // Install Bus Specific Driver Override Protocol - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiBusSpecificDriverOverrideProtocolGuid, - &PciIoDevice->PciDriverOverride, - NULL - ); - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - NULL - ); - if (HasEfiImage) { - gBS->UninstallMultipleProtocolInterfaces ( - &PciIoDevice->Handle, - &gEfiLoadFile2ProtocolGuid, - &PciIoDevice->LoadFile2, - NULL - ); - } - - return Status; - } - } - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &(PciIoDevice->PciRootBridgeIo), - gPciBusDriverBinding.DriverBindingHandle, - PciIoDevice->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Handle != NULL) { - *Handle = PciIoDevice->Handle; - } - - // - // Indicate the pci device is registered - // - PciIoDevice->Registered = TRUE; - - return EFI_SUCCESS; -} - -/** - This function is used to remove the whole PCI devices on the specified bridge from - the root bridge. - - @param RootBridgeHandle The root bridge device handle. - @param Bridge The bridge device to be removed. - -**/ -VOID -RemoveAllPciDeviceOnBridge ( - EFI_HANDLE RootBridgeHandle, - PCI_IO_DEVICE *Bridge - ) -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - while (!IsListEmpty (&Bridge->ChildList)) { - - CurrentLink = Bridge->ChildList.ForwardLink; - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - // - // Check if the current node has been deregistered before - // If it is not, then deregister it - // - if (Temp->Registered) { - DeRegisterPciDevice (RootBridgeHandle, Temp->Handle); - } - - // - // Remove this node from the linked list - // - RemoveEntryList (CurrentLink); - - if (!IsListEmpty (&Temp->ChildList)) { - RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp); - } - - FreePciDevice (Temp); - } -} - -/** - This function is used to de-register the PCI IO device. - - That includes un-installing PciIo protocol from the specified PCI - device handle. - - @param Controller An EFI handle for the PCI bus controller. - @param Handle PCI device handle. - - @retval EFI_SUCCESS The PCI device is successfully de-registered. - @retval other An error occurred when de-registering the PCI device. - -**/ -EFI_STATUS -DeRegisterPciDevice ( - IN EFI_HANDLE Controller, - IN EFI_HANDLE Handle - ) - -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - PCI_IO_DEVICE *Node; - LIST_ENTRY *CurrentLink; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - Status = gBS->OpenProtocol ( - Handle, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo); - - // - // If it is already de-registered - // - if (!PciIoDevice->Registered) { - return EFI_SUCCESS; - } - - // - // If it is PPB, first de-register its children - // - - if (!IsListEmpty (&PciIoDevice->ChildList)) { - - CurrentLink = PciIoDevice->ChildList.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) { - Node = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - Status = DeRegisterPciDevice (Controller, Node->Handle); - - if (EFI_ERROR (Status)) { - return Status; - } - - CurrentLink = CurrentLink->ForwardLink; - } - } - - // - // Close the child handle - // - Status = gBS->CloseProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - gPciBusDriverBinding.DriverBindingHandle, - Handle - ); - - // - // Un-install the Device Path protocol and PCI I/O protocol - // and Bus Specific Driver Override protocol if needed. - // - if (PciIoDevice->BusOverride) { - Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - &gEfiBusSpecificDriverOverrideProtocolGuid, - &PciIoDevice->PciDriverOverride, - NULL - ); - } else { - Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiDevicePathProtocolGuid, - PciIoDevice->DevicePath, - &gEfiPciIoProtocolGuid, - &PciIoDevice->PciIo, - NULL - ); - } - - if (!EFI_ERROR (Status)) { - // - // Try to uninstall LoadFile2 protocol if exists - // - Status = gBS->OpenProtocol ( - Handle, - &gEfiLoadFile2ProtocolGuid, - NULL, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - Status = gBS->UninstallMultipleProtocolInterfaces ( - Handle, - &gEfiLoadFile2ProtocolGuid, - &PciIoDevice->LoadFile2, - NULL - ); - } - // - // Restore Status - // - Status = EFI_SUCCESS; - } - - - if (EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - return Status; - } - - // - // The Device Driver should disable this device after disconnect - // so the Pci Bus driver will not touch this device any more. - // Restore the register field to the original value - // - PciIoDevice->Registered = FALSE; - PciIoDevice->Handle = NULL; - } else { - - // - // Handle may be closed before - // - return EFI_SUCCESS; - } - - return EFI_SUCCESS; -} - -/** - Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge. - - @param Controller The root bridge handle. - @param RootBridge A pointer to the PCI_IO_DEVICE. - @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL. - @param NumberOfChildren Children number. - @param ChildHandleBuffer A pointer to the child handle buffer. - - @retval EFI_NOT_READY Device is not allocated. - @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge. - @retval EFI_NOT_FOUND Can not find the specific device. - @retval EFI_SUCCESS Success to start Pci devices on bridge. - -**/ -EFI_STATUS -StartPciDevicesOnBridge ( - IN EFI_HANDLE Controller, - IN PCI_IO_DEVICE *RootBridge, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - IN OUT UINT8 *NumberOfChildren, - IN OUT EFI_HANDLE *ChildHandleBuffer - ) - -{ - PCI_IO_DEVICE *PciIoDevice; - EFI_DEV_PATH_PTR Node; - EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath; - EFI_STATUS Status; - LIST_ENTRY *CurrentLink; - UINT64 Supports; - - PciIoDevice = NULL; - CurrentLink = RootBridge->ChildList.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) { - - PciIoDevice = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (RemainingDevicePath != NULL) { - - Node.DevPath = RemainingDevicePath; - - if (Node.Pci->Device != PciIoDevice->DeviceNumber || - Node.Pci->Function != PciIoDevice->FunctionNumber) { - CurrentLink = CurrentLink->ForwardLink; - continue; - } - - // - // Check if the device has been assigned with required resource - // - if (!PciIoDevice->Allocated) { - return EFI_NOT_READY; - } - - // - // Check if the current node has been registered before - // If it is not, register it - // - if (!PciIoDevice->Registered) { - Status = RegisterPciDevice ( - Controller, - PciIoDevice, - NULL - ); - - } - - if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && PciIoDevice->Registered) { - ChildHandleBuffer[*NumberOfChildren] = PciIoDevice->Handle; - (*NumberOfChildren)++; - } - - // - // Get the next device path - // - CurrentDevicePath = NextDevicePathNode (RemainingDevicePath); - if (IsDevicePathEnd (CurrentDevicePath)) { - return EFI_SUCCESS; - } - - // - // If it is a PPB - // - if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { - Status = StartPciDevicesOnBridge ( - Controller, - PciIoDevice, - CurrentDevicePath, - NumberOfChildren, - ChildHandleBuffer - ); - - PciIoDevice->PciIo.Attributes ( - &(PciIoDevice->PciIo), - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - PciIoDevice->PciIo.Attributes ( - &(PciIoDevice->PciIo), - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - - return Status; - } else { - - // - // Currently, the PCI bus driver only support PCI-PCI bridge - // - return EFI_UNSUPPORTED; - } - - } else { - - // - // If remaining device path is NULL, - // try to enable all the pci devices under this bridge - // - if (!PciIoDevice->Registered && PciIoDevice->Allocated) { - Status = RegisterPciDevice ( - Controller, - PciIoDevice, - NULL - ); - - } - - if (NumberOfChildren != NULL && ChildHandleBuffer != NULL && PciIoDevice->Registered) { - ChildHandleBuffer[*NumberOfChildren] = PciIoDevice->Handle; - (*NumberOfChildren)++; - } - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { - Status = StartPciDevicesOnBridge ( - Controller, - PciIoDevice, - RemainingDevicePath, - NumberOfChildren, - ChildHandleBuffer - ); - - PciIoDevice->PciIo.Attributes ( - &(PciIoDevice->PciIo), - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - PciIoDevice->PciIo.Attributes ( - &(PciIoDevice->PciIo), - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - - } - - CurrentLink = CurrentLink->ForwardLink; - } - } - - if (PciIoDevice == NULL) { - return EFI_NOT_FOUND; - } else { - return EFI_SUCCESS; - } -} - -/** - Start to manage all the PCI devices it found previously under - the entire host bridge. - - @param Controller The root bridge handle. - - @retval EFI_NOT_READY Device is not allocated. - @retval EFI_SUCCESS Success to start Pci device on host bridge. - -**/ -EFI_STATUS -StartPciDevices ( - IN EFI_HANDLE Controller - ) -{ - PCI_IO_DEVICE *RootBridge; - EFI_HANDLE ThisHostBridge; - LIST_ENTRY *CurrentLink; - - RootBridge = GetRootBridgeByHandle (Controller); - ASSERT (RootBridge != NULL); - ThisHostBridge = RootBridge->PciRootBridgeIo->ParentHandle; - - CurrentLink = mPciDevicePool.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &mPciDevicePool) { - - RootBridge = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - // - // Locate the right root bridge to start - // - if (RootBridge->PciRootBridgeIo->ParentHandle == ThisHostBridge) { - StartPciDevicesOnBridge ( - RootBridge->Handle, - RootBridge, - NULL, - NULL, - NULL - ); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -/** - Create root bridge device. - - @param RootBridgeHandle Specified root bridge hanle. - - @return The crated root bridge device instance, NULL means no - root bridge device instance created. - -**/ -PCI_IO_DEVICE * -CreateRootBridge ( - IN EFI_HANDLE RootBridgeHandle - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *Dev; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - Dev = AllocateZeroPool (sizeof (PCI_IO_DEVICE)); - if (Dev == NULL) { - return NULL; - } - - Dev->Signature = PCI_IO_DEVICE_SIGNATURE; - Dev->Handle = RootBridgeHandle; - InitializeListHead (&Dev->ChildList); - - Status = gBS->OpenProtocol ( - RootBridgeHandle, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - gPciBusDriverBinding.DriverBindingHandle, - RootBridgeHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - FreePool (Dev); - return NULL; - } - - // - // Record the root bridge parent device path - // - Dev->DevicePath = DuplicateDevicePath (ParentDevicePath); - - // - // Get the pci root bridge io protocol - // - Status = gBS->OpenProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - RootBridgeHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - FreePciDevice (Dev); - return NULL; - } - - Dev->PciRootBridgeIo = PciRootBridgeIo; - - // - // Initialize the PCI I/O instance structure - // - InitializePciIoInstance (Dev); - InitializePciDriverOverrideInstance (Dev); - InitializePciLoadFile2 (Dev); - - // - // Initialize reserved resource list and - // option rom driver list - // - InitializeListHead (&Dev->ReservedResourceList); - InitializeListHead (&Dev->OptionRomDriverList); - - return Dev; -} - -/** - Get root bridge device instance by specific root bridge handle. - - @param RootBridgeHandle Given root bridge handle. - - @return The root bridge device instance, NULL means no root bridge - device instance found. - -**/ -PCI_IO_DEVICE * -GetRootBridgeByHandle ( - EFI_HANDLE RootBridgeHandle - ) -{ - PCI_IO_DEVICE *RootBridgeDev; - LIST_ENTRY *CurrentLink; - - CurrentLink = mPciDevicePool.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &mPciDevicePool) { - - RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (RootBridgeDev->Handle == RootBridgeHandle) { - return RootBridgeDev; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return NULL; -} - -/** - Judege whether Pci device existed. - - @param Bridge Parent bridege instance. - @param PciIoDevice Device instance. - - @retval TRUE Pci device existed. - @retval FALSE Pci device did not exist. - -**/ -BOOLEAN -PciDeviceExisted ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (Temp == PciIoDevice) { - return TRUE; - } - - if (!IsListEmpty (&Temp->ChildList)) { - if (PciDeviceExisted (Temp, PciIoDevice)) { - return TRUE; - } - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return FALSE; -} - -/** - Get the active VGA device on the same segment. - - @param VgaDevice PCI IO instance for the VGA device. - - @return The active VGA device on the same segment. - -**/ -PCI_IO_DEVICE * -ActiveVGADeviceOnTheSameSegment ( - IN PCI_IO_DEVICE *VgaDevice - ) -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - CurrentLink = mPciDevicePool.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &mPciDevicePool) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (Temp->PciRootBridgeIo->SegmentNumber == VgaDevice->PciRootBridgeIo->SegmentNumber) { - - Temp = ActiveVGADeviceOnTheRootBridge (Temp); - - if (Temp != NULL) { - return Temp; - } - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return NULL; -} - -/** - Get the active VGA device on the root bridge. - - @param RootBridge PCI IO instance for the root bridge. - - @return The active VGA device. - -**/ -PCI_IO_DEVICE * -ActiveVGADeviceOnTheRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ) -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - CurrentLink = RootBridge->ChildList.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (IS_PCI_VGA(&Temp->Pci) && - (Temp->Attributes & - (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | - EFI_PCI_IO_ATTRIBUTE_VGA_IO | - EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) != 0) { - return Temp; - } - - if (IS_PCI_BRIDGE (&Temp->Pci)) { - - Temp = ActiveVGADeviceOnTheRootBridge (Temp); - - if (Temp != NULL) { - return Temp; - } - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return NULL; -} - - -/** - Get HPC PCI address according to its device path. - - @param RootBridge Root bridege Io instance. - @param RemainingDevicePath Given searching device path. - @param PciAddress Buffer holding searched result. - - @retval EFI_SUCCESS PCI address was stored in PciAddress - @retval EFI_NOT_FOUND Can not find the specific device path. - -**/ -EFI_STATUS -GetHpcPciAddressFromRootBridge ( - IN PCI_IO_DEVICE *RootBridge, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - OUT UINT64 *PciAddress - ) -{ - EFI_DEV_PATH_PTR Node; - PCI_IO_DEVICE *Temp; - EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath; - LIST_ENTRY *CurrentLink; - BOOLEAN MisMatch; - - MisMatch = FALSE; - - CurrentDevicePath = RemainingDevicePath; - Node.DevPath = CurrentDevicePath; - Temp = NULL; - - while (!IsDevicePathEnd (CurrentDevicePath)) { - - CurrentLink = RootBridge->ChildList.ForwardLink; - Node.DevPath = CurrentDevicePath; - - while (CurrentLink != NULL && CurrentLink != &RootBridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (Node.Pci->Device == Temp->DeviceNumber && - Node.Pci->Function == Temp->FunctionNumber) { - RootBridge = Temp; - break; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // Check if we find the bridge - // - if (CurrentLink == &RootBridge->ChildList) { - - MisMatch = TRUE; - break; - - } - - CurrentDevicePath = NextDevicePathNode (CurrentDevicePath); - } - - if (MisMatch) { - - CurrentDevicePath = NextDevicePathNode (CurrentDevicePath); - - if (IsDevicePathEnd (CurrentDevicePath)) { - *PciAddress = EFI_PCI_ADDRESS (RootBridge->BusNumber, Node.Pci->Device, Node.Pci->Function, 0); - return EFI_SUCCESS; - } - - return EFI_NOT_FOUND; - } - - if (Temp != NULL) { - *PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0); - } else { - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; - -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h deleted file mode 100644 index 1a01e72b1e..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDeviceSupport.h +++ /dev/null @@ -1,289 +0,0 @@ -/** @file - Supporting functions declaration for PCI devices management. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_DEVICE_SUPPORT_H_ -#define _EFI_PCI_DEVICE_SUPPORT_H_ - -/** - Initialize the PCI devices pool. - -**/ -VOID -InitializePciDevicePool ( - VOID - ); - -/** - Insert a root bridge into PCI device pool. - - @param RootBridge A pointer to the PCI_IO_DEVICE. - -**/ -VOID -InsertRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ); - -/** - This function is used to insert a PCI device node under - a bridge. - - @param Bridge The PCI bridge. - @param PciDeviceNode The PCI device needs inserting. - -**/ -VOID -InsertPciDevice ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_IO_DEVICE *PciDeviceNode - ); - -/** - Destroy root bridge and remove it from deivce tree. - - @param RootBridge The bridge want to be removed. - -**/ -VOID -DestroyRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ); - -/** - Destroy all the pci device node under the bridge. - Bridge itself is not included. - - @param Bridge A pointer to the PCI_IO_DEVICE. - -**/ -VOID -DestroyPciDeviceTree ( - IN PCI_IO_DEVICE *Bridge - ); - -/** - Destroy all device nodes under the root bridge - specified by Controller. - - The root bridge itself is also included. - - @param Controller Root bridge handle. - - @retval EFI_SUCCESS Destory all devcie nodes successfully. - @retval EFI_NOT_FOUND Cannot find any PCI device under specified - root bridge. - -**/ -EFI_STATUS -DestroyRootBridgeByHandle ( - IN EFI_HANDLE Controller - ); - -/** - This function registers the PCI IO device. - - It creates a handle for this PCI IO device (if the handle does not exist), attaches - appropriate protocols onto the handle, does necessary initialization, and sets up - parent/child relationship with its bus controller. - - @param Controller An EFI handle for the PCI bus controller. - @param PciIoDevice A PCI_IO_DEVICE pointer to the PCI IO device to be registered. - @param Handle A pointer to hold the returned EFI handle for the PCI IO device. - - @retval EFI_SUCCESS The PCI device is successfully registered. - @retval other An error occurred when registering the PCI device. - -**/ -EFI_STATUS -RegisterPciDevice ( - IN EFI_HANDLE Controller, - IN PCI_IO_DEVICE *PciIoDevice, - OUT EFI_HANDLE *Handle OPTIONAL - ); - -/** - This function is used to remove the whole PCI devices on the specified bridge from - the root bridge. - - @param RootBridgeHandle The root bridge device handle. - @param Bridge The bridge device to be removed. - -**/ -VOID -RemoveAllPciDeviceOnBridge ( - EFI_HANDLE RootBridgeHandle, - PCI_IO_DEVICE *Bridge - ); - -/** - This function is used to de-register the PCI IO device. - - That includes un-installing PciIo protocol from the specified PCI - device handle. - - @param Controller An EFI handle for the PCI bus controller. - @param Handle PCI device handle. - - @retval EFI_SUCCESS The PCI device is successfully de-registered. - @retval other An error occurred when de-registering the PCI device. - -**/ -EFI_STATUS -DeRegisterPciDevice ( - IN EFI_HANDLE Controller, - IN EFI_HANDLE Handle - ); - -/** - Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge. - - @param Controller The root bridge handle. - @param RootBridge A pointer to the PCI_IO_DEVICE. - @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL. - @param NumberOfChildren Children number. - @param ChildHandleBuffer A pointer to the child handle buffer. - - @retval EFI_NOT_READY Device is not allocated. - @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge. - @retval EFI_NOT_FOUND Can not find the specific device. - @retval EFI_SUCCESS Success to start Pci devices on bridge. - -**/ -EFI_STATUS -StartPciDevicesOnBridge ( - IN EFI_HANDLE Controller, - IN PCI_IO_DEVICE *RootBridge, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - IN OUT UINT8 *NumberOfChildren, - IN OUT EFI_HANDLE *ChildHandleBuffer - ); - -/** - Start to manage all the PCI devices it found previously under - the entire host bridge. - - @param Controller The root bridge handle. - - @retval EFI_NOT_READY Device is not allocated. - @retval EFI_SUCCESS Success to start Pci device on host bridge. - -**/ -EFI_STATUS -StartPciDevices ( - IN EFI_HANDLE Controller - ); - -/** - Create root bridge device. - - @param RootBridgeHandle Specified root bridge hanle. - - @return The crated root bridge device instance, NULL means no - root bridge device instance created. - -**/ -PCI_IO_DEVICE * -CreateRootBridge ( - IN EFI_HANDLE RootBridgeHandle - ); - -/** - Get root bridge device instance by specific root bridge handle. - - @param RootBridgeHandle Given root bridge handle. - - @return The root bridge device instance, NULL means no root bridge - device instance found. - -**/ -PCI_IO_DEVICE * -GetRootBridgeByHandle ( - EFI_HANDLE RootBridgeHandle - ); - - -/** - Judege whether Pci device existed. - - @param Bridge Parent bridege instance. - @param PciIoDevice Device instance. - - @retval TRUE Pci device existed. - @retval FALSE Pci device did not exist. - -**/ -BOOLEAN -PciDeviceExisted ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Get the active VGA device on the same segment. - - @param VgaDevice PCI IO instance for the VGA device. - - @return The active VGA device on the same segment. - -**/ -PCI_IO_DEVICE * -ActiveVGADeviceOnTheSameSegment ( - IN PCI_IO_DEVICE *VgaDevice - ); - -/** - Get the active VGA device on the root bridge. - - @param RootBridge PCI IO instance for the root bridge. - - @return The active VGA device. - -**/ -PCI_IO_DEVICE * -ActiveVGADeviceOnTheRootBridge ( - IN PCI_IO_DEVICE *RootBridge - ); - -/** - Get HPC PCI address according to its device path. - - @param RootBridge Root bridege Io instance. - @param RemainingDevicePath Given searching device path. - @param PciAddress Buffer holding searched result. - - @retval EFI_SUCCESS PCI address was stored in PciAddress. - @retval EFI_NOT_FOUND Can not find the specific device path. - -**/ -EFI_STATUS -GetHpcPciAddressFromRootBridge ( - IN PCI_IO_DEVICE *RootBridge, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, - OUT UINT64 *PciAddress - ); - -/** - Destroy a pci device node. - - All direct or indirect allocated resource for this node will be freed. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE to be destoried. - -**/ -VOID -FreePciDevice ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c deleted file mode 100644 index 97f45e42d0..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c +++ /dev/null @@ -1,143 +0,0 @@ -/** @file - Functions implementation for Bus Specific Driver Override protoocl. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -/** - Initializes a PCI Driver Override Instance. - - @param PciIoDevice PCI Device instance. - -**/ -VOID -InitializePciDriverOverrideInstance ( - IN OUT PCI_IO_DEVICE *PciIoDevice - ) -{ - PciIoDevice->PciDriverOverride.GetDriver = GetDriver; -} - - -/** - Uses a bus specific algorithm to retrieve a driver image handle for a controller. - - @param This A pointer to the EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL instance. - @param DriverImageHandle On input, a pointer to the previous driver image handle returned - by GetDriver(). On output, a pointer to the next driver - image handle. Passing in a NULL, will return the first driver - image handle. - - @retval EFI_SUCCESS A bus specific override driver is returned in DriverImageHandle. - @retval EFI_NOT_FOUND The end of the list of override drivers was reached. - A bus specific override driver is not returned in DriverImageHandle. - @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a - previous call to GetDriver(). - -**/ -EFI_STATUS -EFIAPI -GetDriver ( - IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, - IN OUT EFI_HANDLE *DriverImageHandle - ) -{ - PCI_IO_DEVICE *PciIoDevice; - LIST_ENTRY *CurrentLink; - PCI_DRIVER_OVERRIDE_LIST *Node; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This); - - CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &PciIoDevice->OptionRomDriverList) { - - Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink); - - if (*DriverImageHandle == NULL) { - - *DriverImageHandle = Node->DriverImageHandle; - return EFI_SUCCESS; - } - - if (*DriverImageHandle == Node->DriverImageHandle) { - - if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList || - CurrentLink->ForwardLink == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get next node - // - Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink); - *DriverImageHandle = Node->DriverImageHandle; - return EFI_SUCCESS; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_INVALID_PARAMETER; -} - -/** - Add an overriding driver image. - - @param PciIoDevice Instance of PciIo device. - @param DriverImageHandle new added driver image. - - @retval EFI_SUCCESS Successfully added driver. - @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance. - @retval other Some error occurred when locating gEfiLoadedImageProtocolGuid. - -**/ -EFI_STATUS -AddDriver ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_HANDLE DriverImageHandle - ) -{ - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - PCI_DRIVER_OVERRIDE_LIST *Node; - - Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage); - if (EFI_ERROR (Status)) { - return Status; - } - - Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST)); - if (Node == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Node->Signature = DRIVER_OVERRIDE_SIGNATURE; - Node->DriverImageHandle = DriverImageHandle; - - InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link)); - - PciIoDevice->BusOverride = TRUE; - - ImageContext.Handle = LoadedImage->ImageBase; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - - // - // Get information about the image - // - PeCoffLoaderGetImageInfo (&ImageContext); - - return EFI_SUCCESS; -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h deleted file mode 100644 index bf8efff8f1..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.h +++ /dev/null @@ -1,86 +0,0 @@ -/** @file - Functions declaration for Bus Specific Driver Override protoocl. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#ifndef _EFI_PCI_DRIVER_OVERRRIDE_H_ -#define _EFI_PCI_DRIVER_OVERRRIDE_H_ - -#define DRIVER_OVERRIDE_SIGNATURE SIGNATURE_32 ('d', 'r', 'o', 'v') - -// -// PCI driver override driver image list -// -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_HANDLE DriverImageHandle; -} PCI_DRIVER_OVERRIDE_LIST; - - -#define DRIVER_OVERRIDE_FROM_LINK(a) \ - CR (a, PCI_DRIVER_OVERRIDE_LIST, Link, DRIVER_OVERRIDE_SIGNATURE) - -/** - Initializes a PCI Driver Override Instance. - - @param PciIoDevice PCI Device instance. - -**/ -VOID -InitializePciDriverOverrideInstance ( - IN OUT PCI_IO_DEVICE *PciIoDevice - ); - -/** - Add an overriding driver image. - - @param PciIoDevice Instance of PciIo device. - @param DriverImageHandle new added driver image. - - @retval EFI_SUCCESS Successfully added driver. - @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance. - @retval other Some error occurred when locating gEfiLoadedImageProtocolGuid. - -**/ -EFI_STATUS -AddDriver ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_HANDLE DriverImageHandle - ); - - -/** - Uses a bus specific algorithm to retrieve a driver image handle for a controller. - - @param This A pointer to the EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL instance. - @param DriverImageHandle On input, a pointer to the previous driver image handle returned - by GetDriver(). On output, a pointer to the next driver - image handle. Passing in a NULL, will return the first driver - image handle. - - @retval EFI_SUCCESS A bus specific override driver is returned in DriverImageHandle. - @retval EFI_NOT_FOUND The end of the list of override drivers was reached. - A bus specific override driver is not returned in DriverImageHandle. - @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a - previous call to GetDriver(). - -**/ -EFI_STATUS -EFIAPI -GetDriver ( - IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This, - IN OUT EFI_HANDLE *DriverImageHandle - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c deleted file mode 100644 index 7329143136..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c +++ /dev/null @@ -1,2251 +0,0 @@ -/** @file - PCI eunmeration implementation on entire PCI bus system for PCI Bus module. - -Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -/** - This routine is used to enumerate entire pci bus system - in a given platform. - - @param Controller Parent controller handle. - - @retval EFI_SUCCESS PCI enumeration finished successfully. - @retval other Some error occurred when enumerating the pci bus system. - -**/ -EFI_STATUS -PciEnumerator ( - IN EFI_HANDLE Controller - ) -{ - EFI_HANDLE HostBridgeHandle; - EFI_STATUS Status; - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - // - // If PCI bus has already done the full enumeration, never do it again - // - if (!gFullEnumeration) { - return PciEnumeratorLight (Controller); - } - - // - // Get the rootbridge Io protocol to find the host bridge handle - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the host bridge handle - // - HostBridgeHandle = PciRootBridgeIo->ParentHandle; - - // - // Get the pci host bridge resource allocation protocol - // - Status = gBS->OpenProtocol ( - HostBridgeHandle, - &gEfiPciHostBridgeResourceAllocationProtocolGuid, - (VOID **) &PciResAlloc, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Notify the pci bus enumeration is about to begin - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginEnumeration); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Start the bus allocation phase - // - Status = PciHostBridgeEnumerator (PciResAlloc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Submit the resource request - // - Status = PciHostBridgeResourceAllocator (PciResAlloc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Notify the pci bus enumeration is about to complete - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeEndEnumeration); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Process P2C - // - Status = PciHostBridgeP2CProcess (PciResAlloc); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Process attributes for devices on this host bridge - // - Status = PciHostBridgeDeviceAttribute (PciResAlloc); - if (EFI_ERROR (Status)) { - return Status; - } - - gFullEnumeration = FALSE; - - Status = gBS->InstallProtocolInterface ( - &HostBridgeHandle, - &gEfiPciEnumerationCompleteProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_SUCCESS; -} - -/** - Enumerate PCI root bridge. - - @param PciResAlloc Pointer to protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - @param RootBridgeDev Instance of root bridge device. - - @retval EFI_SUCCESS Successfully enumerated root bridge. - @retval other Failed to enumerate root bridge. - -**/ -EFI_STATUS -PciRootBridgeEnumerator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - IN PCI_IO_DEVICE *RootBridgeDev - ) -{ - EFI_STATUS Status; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration1; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration2; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration3; - UINT8 SubBusNumber; - UINT8 StartBusNumber; - UINT8 PaddedBusRange; - EFI_HANDLE RootBridgeHandle; - UINT8 Desc; - UINT64 AddrLen; - UINT64 AddrRangeMin; - - SubBusNumber = 0; - StartBusNumber = 0; - PaddedBusRange = 0; - - // - // Get the root bridge handle - // - RootBridgeHandle = RootBridgeDev->Handle; - - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_PCI_BUS_ENUM, - RootBridgeDev->DevicePath - ); - - // - // Get the Bus information - // - Status = PciResAlloc->StartBusEnumeration ( - PciResAlloc, - RootBridgeHandle, - (VOID **) &Configuration - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - if (Configuration == NULL || Configuration->Desc == ACPI_END_TAG_DESCRIPTOR) { - return EFI_INVALID_PARAMETER; - } - RootBridgeDev->BusNumberRanges = Configuration; - - // - // Sort the descriptors in ascending order - // - for (Configuration1 = Configuration; Configuration1->Desc != ACPI_END_TAG_DESCRIPTOR; Configuration1++) { - Configuration2 = Configuration1; - for (Configuration3 = Configuration1 + 1; Configuration3->Desc != ACPI_END_TAG_DESCRIPTOR; Configuration3++) { - if (Configuration2->AddrRangeMin > Configuration3->AddrRangeMin) { - Configuration2 = Configuration3; - } - } - // - // All other fields other than AddrRangeMin and AddrLen are ignored in a descriptor, - // so only need to swap these two fields. - // - if (Configuration2 != Configuration1) { - AddrRangeMin = Configuration1->AddrRangeMin; - Configuration1->AddrRangeMin = Configuration2->AddrRangeMin; - Configuration2->AddrRangeMin = AddrRangeMin; - - AddrLen = Configuration1->AddrLen; - Configuration1->AddrLen = Configuration2->AddrLen; - Configuration2->AddrLen = AddrLen; - } - } - - // - // Get the bus number to start with - // - StartBusNumber = (UINT8) (Configuration->AddrRangeMin); - - // - // Initialize the subordinate bus number - // - SubBusNumber = StartBusNumber; - - // - // Reset all assigned PCI bus number - // - ResetAllPpbBusNumber ( - RootBridgeDev, - StartBusNumber - ); - - // - // Assign bus number - // - Status = PciScanBus ( - RootBridgeDev, - StartBusNumber, - &SubBusNumber, - &PaddedBusRange - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - - // - // Assign max bus number scanned - // - - Status = PciAllocateBusNumber (RootBridgeDev, SubBusNumber, PaddedBusRange, &SubBusNumber); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Find the bus range which contains the higest bus number, then returns the number of buses - // that should be decoded. - // - while (Configuration->AddrRangeMin + Configuration->AddrLen - 1 < SubBusNumber) { - Configuration++; - } - AddrLen = Configuration->AddrLen; - Configuration->AddrLen = SubBusNumber - Configuration->AddrRangeMin + 1; - - // - // Save the Desc field of the next descriptor. Mark the next descriptor as an END descriptor. - // - Configuration++; - Desc = Configuration->Desc; - Configuration->Desc = ACPI_END_TAG_DESCRIPTOR; - - // - // Set bus number - // - Status = PciResAlloc->SetBusNumbers ( - PciResAlloc, - RootBridgeHandle, - RootBridgeDev->BusNumberRanges - ); - - // - // Restore changed fields - // - Configuration->Desc = Desc; - (Configuration - 1)->AddrLen = AddrLen; - - return Status; -} - -/** - This routine is used to process all PCI devices' Option Rom - on a certain root bridge. - - @param Bridge Given parent's root bridge. - @param RomBase Base address of ROM driver loaded from. - @param MaxLength Maximum rom size. - -**/ -VOID -ProcessOptionRom ( - IN PCI_IO_DEVICE *Bridge, - IN UINT64 RomBase, - IN UINT64 MaxLength - ) -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - - // - // Go through bridges to reach all devices - // - CurrentLink = Bridge->ChildList.ForwardLink; - while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (!IsListEmpty (&Temp->ChildList)) { - - // - // Go further to process the option rom under this bridge - // - ProcessOptionRom (Temp, RomBase, MaxLength); - } - - if (Temp->RomSize != 0 && Temp->RomSize <= MaxLength) { - - // - // Load and process the option rom - // - LoadOpRomImage (Temp, RomBase); - } - - CurrentLink = CurrentLink->ForwardLink; - } -} - -/** - This routine is used to assign bus number to the given PCI bus system - - @param Bridge Parent root bridge instance. - @param StartBusNumber Number of beginning. - @param SubBusNumber The number of sub bus. - - @retval EFI_SUCCESS Successfully assigned bus number. - @retval EFI_DEVICE_ERROR Failed to assign bus number. - -**/ -EFI_STATUS -PciAssignBusNumber ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber - ) -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT8 Func; - UINT64 Address; - UINTN SecondBus; - UINT16 Register; - UINT8 Register8; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - - SecondBus = 0; - Register = 0; - - *SubBusNumber = StartBusNumber; - - // - // First check to see whether the parent is ppb - // - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether a pci device is present - // - Status = PciDevicePresent ( - PciRootBridgeIo, - &Pci, - StartBusNumber, - Device, - Func - ); - - if (!EFI_ERROR (Status) && - (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) { - - // - // Reserved one bus for cardbus bridge - // - Status = PciAllocateBusNumber (Bridge, *SubBusNumber, 1, SubBusNumber); - if (EFI_ERROR (Status)) { - return Status; - } - SecondBus = *SubBusNumber; - - Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); - - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); - - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint16, - Address, - 1, - &Register - ); - - // - // Initialize SubBusNumber to SecondBus - // - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint8, - Address, - 1, - SubBusNumber - ); - // - // If it is PPB, resursively search down this bridge - // - if (IS_PCI_BRIDGE (&Pci)) { - - Register8 = 0xFF; - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint8, - Address, - 1, - &Register8 - ); - - Status = PciAssignBusNumber ( - Bridge, - (UINT8) (SecondBus), - SubBusNumber - ); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - } - - // - // Set the current maximum bus number under the PPB - // - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x1A); - - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint8, - Address, - 1, - SubBusNumber - ); - - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - - // - // Skip sub functions, this is not a multi function device - // - Func = PCI_MAX_FUNC; - } - } - } - - return EFI_SUCCESS; -} - -/** - This routine is used to determine the root bridge attribute by interfacing - the host bridge resource allocation protocol. - - @param PciResAlloc Protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL - @param RootBridgeDev Root bridge instance - - @retval EFI_SUCCESS Successfully got root bridge's attribute. - @retval other Failed to get attribute. - -**/ -EFI_STATUS -DetermineRootBridgeAttributes ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - IN PCI_IO_DEVICE *RootBridgeDev - ) -{ - UINT64 Attributes; - EFI_STATUS Status; - EFI_HANDLE RootBridgeHandle; - - Attributes = 0; - RootBridgeHandle = RootBridgeDev->Handle; - - // - // Get root bridge attribute by calling into pci host bridge resource allocation protocol - // - Status = PciResAlloc->GetAllocAttributes ( - PciResAlloc, - RootBridgeHandle, - &Attributes - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Here is the point where PCI bus driver calls HOST bridge allocation protocol - // Currently we hardcoded for ea815 - // - if ((Attributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) { - RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED; - } - - if ((Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) != 0) { - RootBridgeDev->Decodes |= EFI_BRIDGE_MEM64_DECODE_SUPPORTED; - RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED; - } - - RootBridgeDev->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED; - RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; - RootBridgeDev->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED; - - return EFI_SUCCESS; -} - -/** - Get Max Option Rom size on specified bridge. - - @param Bridge Given bridge device instance. - - @return Max size of option rom needed. - -**/ -UINT64 -GetMaxOptionRomSize ( - IN PCI_IO_DEVICE *Bridge - ) -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - UINT64 MaxOptionRomSize; - UINT64 TempOptionRomSize; - - MaxOptionRomSize = 0; - - // - // Go through bridges to reach all devices - // - CurrentLink = Bridge->ChildList.ForwardLink; - while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (!IsListEmpty (&Temp->ChildList)) { - - // - // Get max option rom size under this bridge - // - TempOptionRomSize = GetMaxOptionRomSize (Temp); - - // - // Compare with the option rom size of the bridge - // Get the larger one - // - if (Temp->RomSize > TempOptionRomSize) { - TempOptionRomSize = Temp->RomSize; - } - - } else { - - // - // For devices get the rom size directly - // - TempOptionRomSize = Temp->RomSize; - } - - // - // Get the largest rom size on this bridge - // - if (TempOptionRomSize > MaxOptionRomSize) { - MaxOptionRomSize = TempOptionRomSize; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return MaxOptionRomSize; -} - -/** - Process attributes of devices on this host bridge - - @param PciResAlloc Protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - - @retval EFI_SUCCESS Successfully process attribute. - @retval EFI_NOT_FOUND Can not find the specific root bridge device. - @retval other Failed to determine the root bridge device's attribute. - -**/ -EFI_STATUS -PciHostBridgeDeviceAttribute ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -{ - EFI_HANDLE RootBridgeHandle; - PCI_IO_DEVICE *RootBridgeDev; - EFI_STATUS Status; - - RootBridgeHandle = NULL; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Set the attributes for devcies behind the Root Bridge - // - Status = DetermineDeviceAttribute (RootBridgeDev); - if (EFI_ERROR (Status)) { - return Status; - } - - } - - return EFI_SUCCESS; -} - -/** - Get resource allocation status from the ACPI resource descriptor. - - @param AcpiConfig Point to Acpi configuration table. - @param IoResStatus Return the status of I/O resource. - @param Mem32ResStatus Return the status of 32-bit Memory resource. - @param PMem32ResStatus Return the status of 32-bit Prefetchable Memory resource. - @param Mem64ResStatus Return the status of 64-bit Memory resource. - @param PMem64ResStatus Return the status of 64-bit Prefetchable Memory resource. - -**/ -VOID -GetResourceAllocationStatus ( - VOID *AcpiConfig, - OUT UINT64 *IoResStatus, - OUT UINT64 *Mem32ResStatus, - OUT UINT64 *PMem32ResStatus, - OUT UINT64 *Mem64ResStatus, - OUT UINT64 *PMem64ResStatus - ) -{ - UINT8 *Temp; - UINT64 ResStatus; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ACPIAddressDesc; - - Temp = (UINT8 *) AcpiConfig; - - while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) { - - ACPIAddressDesc = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp; - ResStatus = ACPIAddressDesc->AddrTranslationOffset; - - switch (ACPIAddressDesc->ResType) { - case 0: - if (ACPIAddressDesc->AddrSpaceGranularity == 32) { - if (ACPIAddressDesc->SpecificFlag == 0x06) { - // - // Pmem32 - // - *PMem32ResStatus = ResStatus; - } else { - // - // Mem32 - // - *Mem32ResStatus = ResStatus; - } - } - - if (ACPIAddressDesc->AddrSpaceGranularity == 64) { - if (ACPIAddressDesc->SpecificFlag == 0x06) { - // - // PMem64 - // - *PMem64ResStatus = ResStatus; - } else { - // - // Mem64 - // - *Mem64ResStatus = ResStatus; - } - } - - break; - - case 1: - // - // Io - // - *IoResStatus = ResStatus; - break; - - default: - break; - } - - Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); - } -} - -/** - Remove a PCI device from device pool and mark its bar. - - @param PciDevice Instance of Pci device. - - @retval EFI_SUCCESS Successfully remove the PCI device. - @retval EFI_ABORTED Pci device is a root bridge or a PCI-PCI bridge. - -**/ -EFI_STATUS -RejectPciDevice ( - IN PCI_IO_DEVICE *PciDevice - ) -{ - PCI_IO_DEVICE *Bridge; - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - - // - // Remove the padding resource from a bridge - // - if ( IS_PCI_BRIDGE(&PciDevice->Pci) && - PciDevice->ResourcePaddingDescriptors != NULL ) { - FreePool (PciDevice->ResourcePaddingDescriptors); - PciDevice->ResourcePaddingDescriptors = NULL; - return EFI_SUCCESS; - } - - // - // Skip RB and PPB - // - if (IS_PCI_BRIDGE (&PciDevice->Pci) || (PciDevice->Parent == NULL)) { - return EFI_ABORTED; - } - - if (IS_CARDBUS_BRIDGE (&PciDevice->Pci)) { - // - // Get the root bridge device - // - Bridge = PciDevice; - while (Bridge->Parent != NULL) { - Bridge = Bridge->Parent; - } - - RemoveAllPciDeviceOnBridge (Bridge->Handle, PciDevice); - - // - // Mark its bar - // - InitializeP2C (PciDevice); - } - - // - // Remove the device - // - Bridge = PciDevice->Parent; - CurrentLink = Bridge->ChildList.ForwardLink; - while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (Temp == PciDevice) { - InitializePciDevice (Temp); - RemoveEntryList (CurrentLink); - return EFI_SUCCESS; - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_ABORTED; -} - -/** - Determine whethter a PCI device can be rejected. - - @param PciResNode Pointer to Pci resource node instance. - - @retval TRUE The PCI device can be rejected. - @retval TRUE The PCI device cannot be rejected. - -**/ -BOOLEAN -IsRejectiveDevice ( - IN PCI_RESOURCE_NODE *PciResNode - ) -{ - PCI_IO_DEVICE *Temp; - - Temp = PciResNode->PciDev; - - // - // Ensure the device is present - // - if (Temp == NULL) { - return FALSE; - } - - // - // PPB and RB should go ahead - // - if (IS_PCI_BRIDGE (&Temp->Pci) || (Temp->Parent == NULL)) { - return TRUE; - } - - // - // Skip device on Bus0 - // - if ((Temp->Parent != NULL) && (Temp->BusNumber == 0)) { - return FALSE; - } - - // - // Skip VGA - // - if (IS_PCI_VGA (&Temp->Pci)) { - return FALSE; - } - - return TRUE; -} - -/** - Compare two resource nodes and get the larger resource consumer. - - @param PciResNode1 resource node 1 want to be compared - @param PciResNode2 resource node 2 want to be compared - - @return Larger resource node. - -**/ -PCI_RESOURCE_NODE * -GetLargerConsumerDevice ( - IN PCI_RESOURCE_NODE *PciResNode1, - IN PCI_RESOURCE_NODE *PciResNode2 - ) -{ - if (PciResNode2 == NULL) { - return PciResNode1; - } - - if ((IS_PCI_BRIDGE(&(PciResNode2->PciDev->Pci)) || (PciResNode2->PciDev->Parent == NULL)) \ - && (PciResNode2->ResourceUsage != PciResUsagePadding) ) - { - return PciResNode1; - } - - if (PciResNode1 == NULL) { - return PciResNode2; - } - - if ((PciResNode1->Length) > (PciResNode2->Length)) { - return PciResNode1; - } - - return PciResNode2; -} - - -/** - Get the max resource consumer in the host resource pool. - - @param ResPool Pointer to resource pool node. - - @return The max resource consumer in the host resource pool. - -**/ -PCI_RESOURCE_NODE * -GetMaxResourceConsumerDevice ( - IN PCI_RESOURCE_NODE *ResPool - ) -{ - PCI_RESOURCE_NODE *Temp; - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *PciResNode; - PCI_RESOURCE_NODE *PPBResNode; - - PciResNode = NULL; - - CurrentLink = ResPool->ChildList.ForwardLink; - while (CurrentLink != NULL && CurrentLink != &ResPool->ChildList) { - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (!IsRejectiveDevice (Temp)) { - CurrentLink = CurrentLink->ForwardLink; - continue; - } - - if ((IS_PCI_BRIDGE (&(Temp->PciDev->Pci)) || (Temp->PciDev->Parent == NULL)) \ - && (Temp->ResourceUsage != PciResUsagePadding)) - { - PPBResNode = GetMaxResourceConsumerDevice (Temp); - PciResNode = GetLargerConsumerDevice (PciResNode, PPBResNode); - } else { - PciResNode = GetLargerConsumerDevice (PciResNode, Temp); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return PciResNode; -} - -/** - Adjust host bridge allocation so as to reduce resource requirement - - @param IoPool Pointer to instance of I/O resource Node. - @param Mem32Pool Pointer to instance of 32-bit memory resource Node. - @param PMem32Pool Pointer to instance of 32-bit Prefetchable memory resource node. - @param Mem64Pool Pointer to instance of 64-bit memory resource node. - @param PMem64Pool Pointer to instance of 64-bit Prefetchable memory resource node. - @param IoResStatus Status of I/O resource Node. - @param Mem32ResStatus Status of 32-bit memory resource Node. - @param PMem32ResStatus Status of 32-bit Prefetchable memory resource node. - @param Mem64ResStatus Status of 64-bit memory resource node. - @param PMem64ResStatus Status of 64-bit Prefetchable memory resource node. - - @retval EFI_SUCCESS Successfully adjusted resoruce on host bridge. - @retval EFI_ABORTED Host bridge hasn't this resource type or no resource be adjusted. - -**/ -EFI_STATUS -PciHostBridgeAdjustAllocation ( - IN PCI_RESOURCE_NODE *IoPool, - IN PCI_RESOURCE_NODE *Mem32Pool, - IN PCI_RESOURCE_NODE *PMem32Pool, - IN PCI_RESOURCE_NODE *Mem64Pool, - IN PCI_RESOURCE_NODE *PMem64Pool, - IN UINT64 IoResStatus, - IN UINT64 Mem32ResStatus, - IN UINT64 PMem32ResStatus, - IN UINT64 Mem64ResStatus, - IN UINT64 PMem64ResStatus - ) -{ - BOOLEAN AllocationAjusted; - PCI_RESOURCE_NODE *PciResNode; - PCI_RESOURCE_NODE *ResPool[5]; - PCI_IO_DEVICE *RemovedPciDev[5]; - UINT64 ResStatus[5]; - UINTN RemovedPciDevNum; - UINTN DevIndex; - UINTN ResType; - EFI_STATUS Status; - EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData; - - PciResNode = NULL; - ZeroMem (RemovedPciDev, 5 * sizeof (PCI_IO_DEVICE *)); - RemovedPciDevNum = 0; - - ResPool[0] = IoPool; - ResPool[1] = Mem32Pool; - ResPool[2] = PMem32Pool; - ResPool[3] = Mem64Pool; - ResPool[4] = PMem64Pool; - - ResStatus[0] = IoResStatus; - ResStatus[1] = Mem32ResStatus; - ResStatus[2] = PMem32ResStatus; - ResStatus[3] = Mem64ResStatus; - ResStatus[4] = PMem64ResStatus; - - AllocationAjusted = FALSE; - - for (ResType = 0; ResType < 5; ResType++) { - - if (ResStatus[ResType] == EFI_RESOURCE_SATISFIED) { - continue; - } - - if (ResStatus[ResType] == EFI_RESOURCE_NOT_SATISFIED) { - // - // Host bridge hasn't this resource type - // - return EFI_ABORTED; - } - - // - // Hostbridge hasn't enough resource - // - PciResNode = GetMaxResourceConsumerDevice (ResPool[ResType]); - if (PciResNode == NULL) { - continue; - } - - // - // Check if the device has been removed before - // - for (DevIndex = 0; DevIndex < RemovedPciDevNum; DevIndex++) { - if (PciResNode->PciDev == RemovedPciDev[DevIndex]) { - break; - } - } - - if (DevIndex != RemovedPciDevNum) { - continue; - } - - // - // Remove the device if it isn't in the array - // - Status = RejectPciDevice (PciResNode->PciDev); - if (Status == EFI_SUCCESS) { - DEBUG (( - EFI_D_ERROR, - "PciBus: [%02x|%02x|%02x] was rejected due to resource confliction.\n", - PciResNode->PciDev->BusNumber, PciResNode->PciDev->DeviceNumber, PciResNode->PciDev->FunctionNumber - )); - - // - // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code - // - // - // Have no way to get ReqRes, AllocRes & Bar here - // - ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData)); - AllocFailExtendedData.DevicePathSize = (UINT16) sizeof (EFI_DEVICE_PATH_PROTOCOL); - AllocFailExtendedData.DevicePath = (UINT8 *) PciResNode->PciDev->DevicePath; - AllocFailExtendedData.Bar = PciResNode->Bar; - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT, - (VOID *) &AllocFailExtendedData, - sizeof (AllocFailExtendedData) - ); - - // - // Add it to the array and indicate at least a device has been rejected - // - RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev; - AllocationAjusted = TRUE; - } - } - // - // End for - // - - if (AllocationAjusted) { - return EFI_SUCCESS; - } else { - return EFI_ABORTED; - } -} - -/** - Summary requests for all resource type, and contruct ACPI resource - requestor instance. - - @param Bridge detecting bridge - @param IoNode Pointer to instance of I/O resource Node - @param Mem32Node Pointer to instance of 32-bit memory resource Node - @param PMem32Node Pointer to instance of 32-bit Pmemory resource node - @param Mem64Node Pointer to instance of 64-bit memory resource node - @param PMem64Node Pointer to instance of 64-bit Pmemory resource node - @param Config Output buffer holding new constructed APCI resource requestor - - @retval EFI_SUCCESS Successfully constructed ACPI resource. - @retval EFI_OUT_OF_RESOURCES No memory availabe. - -**/ -EFI_STATUS -ConstructAcpiResourceRequestor ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node, - OUT VOID **Config - ) -{ - UINT8 NumConfig; - UINT8 Aperture; - UINT8 *Configuration; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd; - - NumConfig = 0; - Aperture = 0; - - *Config = NULL; - - // - // if there is io request, add to the io aperture - // - if (ResourceRequestExisted (IoNode)) { - NumConfig++; - Aperture |= 0x01; - } - - // - // if there is mem32 request, add to the mem32 aperture - // - if (ResourceRequestExisted (Mem32Node)) { - NumConfig++; - Aperture |= 0x02; - } - - // - // if there is pmem32 request, add to the pmem32 aperture - // - if (ResourceRequestExisted (PMem32Node)) { - NumConfig++; - Aperture |= 0x04; - } - - // - // if there is mem64 request, add to the mem64 aperture - // - if (ResourceRequestExisted (Mem64Node)) { - NumConfig++; - Aperture |= 0x08; - } - - // - // if there is pmem64 request, add to the pmem64 aperture - // - if (ResourceRequestExisted (PMem64Node)) { - NumConfig++; - Aperture |= 0x10; - } - - if (NumConfig != 0) { - - // - // If there is at least one type of resource request, - // allocate a acpi resource node - // - Configuration = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (Configuration == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; - - // - // Deal with io aperture - // - if ((Aperture & 0x01) != 0) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3); - // - // Io - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; - // - // non ISA range - // - Ptr->SpecificFlag = 1; - Ptr->AddrLen = IoNode->Length; - Ptr->AddrRangeMax = IoNode->Alignment; - - Ptr++; - } - // - // Deal with mem32 aperture - // - if ((Aperture & 0x02) != 0) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3); - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // Nonprefechable - // - Ptr->SpecificFlag = 0; - // - // 32 bit - // - Ptr->AddrSpaceGranularity = 32; - Ptr->AddrLen = Mem32Node->Length; - Ptr->AddrRangeMax = Mem32Node->Alignment; - - Ptr++; - } - - // - // Deal with Pmem32 aperture - // - if ((Aperture & 0x04) != 0) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3); - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // prefechable - // - Ptr->SpecificFlag = 0x6; - // - // 32 bit - // - Ptr->AddrSpaceGranularity = 32; - Ptr->AddrLen = PMem32Node->Length; - Ptr->AddrRangeMax = PMem32Node->Alignment; - - Ptr++; - } - // - // Deal with mem64 aperture - // - if ((Aperture & 0x08) != 0) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3); - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // nonprefechable - // - Ptr->SpecificFlag = 0; - // - // 64 bit - // - Ptr->AddrSpaceGranularity = 64; - Ptr->AddrLen = Mem64Node->Length; - Ptr->AddrRangeMax = Mem64Node->Alignment; - - Ptr++; - } - // - // Deal with Pmem64 aperture - // - if ((Aperture & 0x10) != 0) { - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Ptr->Len = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3); - // - // Mem - // - Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // prefechable - // - Ptr->SpecificFlag = 0x06; - // - // 64 bit - // - Ptr->AddrSpaceGranularity = 64; - Ptr->AddrLen = PMem64Node->Length; - Ptr->AddrRangeMax = PMem64Node->Alignment; - - Ptr++; - } - - // - // put the checksum - // - PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr; - - PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; - PtrEnd->Checksum = 0; - - } else { - - // - // If there is no resource request - // - Configuration = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (Configuration == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration); - Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - - PtrEnd = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Ptr + 1); - PtrEnd->Desc = ACPI_END_TAG_DESCRIPTOR; - PtrEnd->Checksum = 0; - } - - *Config = Configuration; - - return EFI_SUCCESS; -} - -/** - Get resource base from an acpi configuration descriptor. - - @param Config An acpi configuration descriptor. - @param IoBase Output of I/O resource base address. - @param Mem32Base Output of 32-bit memory base address. - @param PMem32Base Output of 32-bit prefetchable memory base address. - @param Mem64Base Output of 64-bit memory base address. - @param PMem64Base Output of 64-bit prefetchable memory base address. - -**/ -VOID -GetResourceBase ( - IN VOID *Config, - OUT UINT64 *IoBase, - OUT UINT64 *Mem32Base, - OUT UINT64 *PMem32Base, - OUT UINT64 *Mem64Base, - OUT UINT64 *PMem64Base - ) -{ - UINT8 *Temp; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - UINT64 ResStatus; - - ASSERT (Config != NULL); - - *IoBase = 0xFFFFFFFFFFFFFFFFULL; - *Mem32Base = 0xFFFFFFFFFFFFFFFFULL; - *PMem32Base = 0xFFFFFFFFFFFFFFFFULL; - *Mem64Base = 0xFFFFFFFFFFFFFFFFULL; - *PMem64Base = 0xFFFFFFFFFFFFFFFFULL; - - Temp = (UINT8 *) Config; - - while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) { - - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp; - ResStatus = Ptr->AddrTranslationOffset; - - if (ResStatus == EFI_RESOURCE_SATISFIED) { - - switch (Ptr->ResType) { - - // - // Memory type aperture - // - case 0: - - // - // Check to see the granularity - // - if (Ptr->AddrSpaceGranularity == 32) { - if ((Ptr->SpecificFlag & 0x06) != 0) { - *PMem32Base = Ptr->AddrRangeMin; - } else { - *Mem32Base = Ptr->AddrRangeMin; - } - } - - if (Ptr->AddrSpaceGranularity == 64) { - if ((Ptr->SpecificFlag & 0x06) != 0) { - *PMem64Base = Ptr->AddrRangeMin; - } else { - *Mem64Base = Ptr->AddrRangeMin; - } - } - break; - - case 1: - - // - // Io type aperture - // - *IoBase = Ptr->AddrRangeMin; - break; - - default: - break; - - } - // - // End switch - // - } - // - // End for - // - Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR); - } -} - -/** - Enumerate pci bridge, allocate resource and determine attribute - for devices on this bridge. - - @param BridgeDev Pointer to instance of bridge device. - - @retval EFI_SUCCESS Successfully enumerated PCI bridge. - @retval other Failed to enumerate. - -**/ -EFI_STATUS -PciBridgeEnumerator ( - IN PCI_IO_DEVICE *BridgeDev - ) -{ - UINT8 SubBusNumber; - UINT8 StartBusNumber; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - - SubBusNumber = 0; - StartBusNumber = 0; - PciIo = &(BridgeDev->PciIo); - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciAssignBusNumber ( - BridgeDev, - StartBusNumber, - &SubBusNumber - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciBridgeResourceAllocator (BridgeDev); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = DetermineDeviceAttribute (BridgeDev); - - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_SUCCESS; - -} - -/** - Allocate all kinds of resource for PCI bridge. - - @param Bridge Pointer to bridge instance. - - @retval EFI_SUCCESS Successfully allocated resource for PCI bridge. - @retval other Failed to allocate resource for bridge. - -**/ -EFI_STATUS -PciBridgeResourceAllocator ( - IN PCI_IO_DEVICE *Bridge - ) -{ - PCI_RESOURCE_NODE *IoBridge; - PCI_RESOURCE_NODE *Mem32Bridge; - PCI_RESOURCE_NODE *PMem32Bridge; - PCI_RESOURCE_NODE *Mem64Bridge; - PCI_RESOURCE_NODE *PMem64Bridge; - UINT64 IoBase; - UINT64 Mem32Base; - UINT64 PMem32Base; - UINT64 Mem64Base; - UINT64 PMem64Base; - EFI_STATUS Status; - - IoBridge = CreateResourceNode ( - Bridge, - 0, - Bridge->BridgeIoAlignment, - 0, - PciBarTypeIo16, - PciResUsageTypical - ); - - Mem32Bridge = CreateResourceNode ( - Bridge, - 0, - 0xFFFFF, - 0, - PciBarTypeMem32, - PciResUsageTypical - ); - - PMem32Bridge = CreateResourceNode ( - Bridge, - 0, - 0xFFFFF, - 0, - PciBarTypePMem32, - PciResUsageTypical - ); - - Mem64Bridge = CreateResourceNode ( - Bridge, - 0, - 0xFFFFF, - 0, - PciBarTypeMem64, - PciResUsageTypical - ); - - PMem64Bridge = CreateResourceNode ( - Bridge, - 0, - 0xFFFFF, - 0, - PciBarTypePMem64, - PciResUsageTypical - ); - - // - // Create resourcemap by going through all the devices subject to this root bridge - // - CreateResourceMap ( - Bridge, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge - ); - - Status = GetResourceBaseFromBridge ( - Bridge, - &IoBase, - &Mem32Base, - &PMem32Base, - &Mem64Base, - &PMem64Base - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Program IO resources - // - ProgramResource ( - IoBase, - IoBridge - ); - - // - // Program Mem32 resources - // - ProgramResource ( - Mem32Base, - Mem32Bridge - ); - - // - // Program PMem32 resources - // - ProgramResource ( - PMem32Base, - PMem32Bridge - ); - - // - // Program Mem64 resources - // - ProgramResource ( - Mem64Base, - Mem64Bridge - ); - - // - // Program PMem64 resources - // - ProgramResource ( - PMem64Base, - PMem64Bridge - ); - - DestroyResourceTree (IoBridge); - DestroyResourceTree (Mem32Bridge); - DestroyResourceTree (PMem32Bridge); - DestroyResourceTree (PMem64Bridge); - DestroyResourceTree (Mem64Bridge); - - gBS->FreePool (IoBridge); - gBS->FreePool (Mem32Bridge); - gBS->FreePool (PMem32Bridge); - gBS->FreePool (PMem64Bridge); - gBS->FreePool (Mem64Bridge); - - return EFI_SUCCESS; -} - -/** - Get resource base address for a pci bridge device. - - @param Bridge Given Pci driver instance. - @param IoBase Output for base address of I/O type resource. - @param Mem32Base Output for base address of 32-bit memory type resource. - @param PMem32Base Ooutput for base address of 32-bit Pmemory type resource. - @param Mem64Base Output for base address of 64-bit memory type resource. - @param PMem64Base Output for base address of 64-bit Pmemory type resource. - - @retval EFI_SUCCESS Successfully got resource base address. - @retval EFI_OUT_OF_RESOURCES PCI bridge is not available. - -**/ -EFI_STATUS -GetResourceBaseFromBridge ( - IN PCI_IO_DEVICE *Bridge, - OUT UINT64 *IoBase, - OUT UINT64 *Mem32Base, - OUT UINT64 *PMem32Base, - OUT UINT64 *Mem64Base, - OUT UINT64 *PMem64Base - ) -{ - if (!Bridge->Allocated) { - return EFI_OUT_OF_RESOURCES; - } - - *IoBase = gAllOne; - *Mem32Base = gAllOne; - *PMem32Base = gAllOne; - *Mem64Base = gAllOne; - *PMem64Base = gAllOne; - - if (IS_PCI_BRIDGE (&Bridge->Pci)) { - - if (Bridge->PciBar[PPB_IO_RANGE].Length > 0) { - *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress; - } - - if (Bridge->PciBar[PPB_MEM32_RANGE].Length > 0) { - *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress; - } - - if (Bridge->PciBar[PPB_PMEM32_RANGE].Length > 0) { - *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress; - } - - if (Bridge->PciBar[PPB_PMEM64_RANGE].Length > 0) { - *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress; - } else { - *PMem64Base = gAllOne; - } - - } - - if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) { - if (Bridge->PciBar[P2C_IO_1].Length > 0) { - *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress; - } else { - if (Bridge->PciBar[P2C_IO_2].Length > 0) { - *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress; - } - } - - if (Bridge->PciBar[P2C_MEM_1].Length > 0) { - if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) { - *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress; - } - - if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) { - *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress; - } - } - - if (Bridge->PciBar[P2C_MEM_2].Length > 0) { - if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) { - *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress; - } - - if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) { - *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress; - } - } - } - - return EFI_SUCCESS; -} - -/** - These are the notifications from the PCI bus driver that it is about to enter a certain - phase of the PCI enumeration process. - - This member function can be used to notify the host bridge driver to perform specific actions, - including any chipset-specific initialization, so that the chipset is ready to enter the next phase. - Eight notification points are defined at this time. See belows: - EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures and internal data - structures. The PCI enumerator should issue this notification - before starting a fresh enumeration process. Enumeration cannot - be restarted after sending any other notification such as - EfiPciHostBridgeBeginBusAllocation. - EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to begin. No specific action is - required here. This notification can be used to perform any - chipset-specific programming. - EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming phase is complete. No - specific action is required here. This notification can be used to - perform any chipset-specific programming. - EfiPciHostBridgeBeginResourceAllocation - The resource allocation phase is about to begin. No specific - action is required here. This notification can be used to perform - any chipset-specific programming. - EfiPciHostBridgeAllocateResources Allocates resources per previously submitted requests for all the PCI - root bridges. These resource settings are returned on the next call to - GetProposedResources(). Before calling NotifyPhase() with a Phase of - EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible - for gathering I/O and memory requests for - all the PCI root bridges and submitting these requests using - SubmitResources(). This function pads the resource amount - to suit the root bridge hardware, takes care of dependencies between - the PCI root bridges, and calls the Global Coherency Domain (GCD) - with the allocation request. In the case of padding, the allocated range - could be bigger than what was requested. - EfiPciHostBridgeSetResources Programs the host bridge hardware to decode previously allocated - resources (proposed resources) for all the PCI root bridges. After the - hardware is programmed, reassigning resources will not be supported. - The bus settings are not affected. - EfiPciHostBridgeFreeResources Deallocates resources that were previously allocated for all the PCI - root bridges and resets the I/O and memory apertures to their initial - state. The bus settings are not affected. If the request to allocate - resources fails, the PCI enumerator can use this notification to - deallocate previous resources, adjust the requests, and retry - allocation. - EfiPciHostBridgeEndResourceAllocation The resource allocation phase is completed. No specific action is - required here. This notification can be used to perform any chipsetspecific - programming. - - @param[in] PciResAlloc The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL - @param[in] Phase The phase during enumeration - - @retval EFI_NOT_READY This phase cannot be entered at this time. For example, this error - is valid for a Phase of EfiPciHostBridgeAllocateResources if - SubmitResources() has not been called for one or more - PCI root bridges before this call - @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. This error is valid - for a Phase of EfiPciHostBridgeSetResources. - @retval EFI_INVALID_PARAMETER Invalid phase parameter - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the - previously submitted resource requests cannot be fulfilled or - were only partially fulfilled. - @retval EFI_SUCCESS The notification was accepted without any errors. - -**/ -EFI_STATUS -NotifyPhase ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase - ) -{ - EFI_HANDLE HostBridgeHandle; - EFI_HANDLE RootBridgeHandle; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - EFI_STATUS Status; - - HostBridgeHandle = NULL; - RootBridgeHandle = NULL; - if (gPciPlatformProtocol != NULL) { - // - // Get Host Bridge Handle. - // - PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle); - - // - // Get the rootbridge Io protocol to find the host bridge handle - // - Status = gBS->HandleProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo - ); - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - HostBridgeHandle = PciRootBridgeIo->ParentHandle; - - // - // Call PlatformPci::PlatformNotify() if the protocol is present. - // - gPciPlatformProtocol->PlatformNotify ( - gPciPlatformProtocol, - HostBridgeHandle, - Phase, - ChipsetEntry - ); - } else if (gPciOverrideProtocol != NULL){ - // - // Get Host Bridge Handle. - // - PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle); - - // - // Get the rootbridge Io protocol to find the host bridge handle - // - Status = gBS->HandleProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo - ); - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - HostBridgeHandle = PciRootBridgeIo->ParentHandle; - - // - // Call PlatformPci::PhaseNotify() if the protocol is present. - // - gPciOverrideProtocol->PlatformNotify ( - gPciOverrideProtocol, - HostBridgeHandle, - Phase, - ChipsetEntry - ); - } - - Status = PciResAlloc->NotifyPhase ( - PciResAlloc, - Phase - ); - - if (gPciPlatformProtocol != NULL) { - // - // Call PlatformPci::PlatformNotify() if the protocol is present. - // - gPciPlatformProtocol->PlatformNotify ( - gPciPlatformProtocol, - HostBridgeHandle, - Phase, - ChipsetExit - ); - - } else if (gPciOverrideProtocol != NULL) { - // - // Call PlatformPci::PhaseNotify() if the protocol is present. - // - gPciOverrideProtocol->PlatformNotify ( - gPciOverrideProtocol, - HostBridgeHandle, - Phase, - ChipsetExit - ); - } - - return Status; -} - -/** - Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various - stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual - PCI controllers before enumeration. - - This function is called during the PCI enumeration process. No specific action is expected from this - member function. It allows the host bridge driver to preinitialize individual PCI controllers before - enumeration. - - @param Bridge Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance. - @param Bus The bus number of the pci device. - @param Device The device number of the pci device. - @param Func The function number of the pci device. - @param Phase The phase of the PCI device enumeration. - - @retval EFI_SUCCESS The requested parameters were returned. - @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle. - @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined in - EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE. - @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. The PCI enumerator should - not enumerate this device, including its child devices if it is a PCI-to-PCI - bridge. - -**/ -EFI_STATUS -PreprocessController ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func, - IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase - ) -{ - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress; - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc; - EFI_HANDLE RootBridgeHandle; - EFI_HANDLE HostBridgeHandle; - EFI_STATUS Status; - - // - // Get the host bridge handle - // - HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle; - - // - // Get the pci host bridge resource allocation protocol - // - Status = gBS->OpenProtocol ( - HostBridgeHandle, - &gEfiPciHostBridgeResourceAllocationProtocolGuid, - (VOID **) &PciResAlloc, - NULL, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Get Root Brige Handle - // - while (Bridge->Parent != NULL) { - Bridge = Bridge->Parent; - } - - RootBridgeHandle = Bridge->Handle; - - RootBridgePciAddress.Register = 0; - RootBridgePciAddress.Function = Func; - RootBridgePciAddress.Device = Device; - RootBridgePciAddress.Bus = Bus; - RootBridgePciAddress.ExtendedRegister = 0; - - if (gPciPlatformProtocol != NULL) { - // - // Call PlatformPci::PrepController() if the protocol is present. - // - gPciPlatformProtocol->PlatformPrepController ( - gPciPlatformProtocol, - HostBridgeHandle, - RootBridgeHandle, - RootBridgePciAddress, - Phase, - ChipsetEntry - ); - } else if (gPciOverrideProtocol != NULL) { - // - // Call PlatformPci::PrepController() if the protocol is present. - // - gPciOverrideProtocol->PlatformPrepController ( - gPciOverrideProtocol, - HostBridgeHandle, - RootBridgeHandle, - RootBridgePciAddress, - Phase, - ChipsetEntry - ); - } - - Status = PciResAlloc->PreprocessController ( - PciResAlloc, - RootBridgeHandle, - RootBridgePciAddress, - Phase - ); - - if (gPciPlatformProtocol != NULL) { - // - // Call PlatformPci::PrepController() if the protocol is present. - // - gPciPlatformProtocol->PlatformPrepController ( - gPciPlatformProtocol, - HostBridgeHandle, - RootBridgeHandle, - RootBridgePciAddress, - Phase, - ChipsetExit - ); - } else if (gPciOverrideProtocol != NULL) { - // - // Call PlatformPci::PrepController() if the protocol is present. - // - gPciOverrideProtocol->PlatformPrepController ( - gPciOverrideProtocol, - HostBridgeHandle, - RootBridgeHandle, - RootBridgePciAddress, - Phase, - ChipsetExit - ); - } - - return EFI_SUCCESS; -} - -/** - This function allows the PCI bus driver to be notified to act as requested when a hot-plug event has - happened on the hot-plug controller. Currently, the operations include add operation and remove operation.. - - @param This A pointer to the hot plug request protocol. - @param Operation The operation the PCI bus driver is requested to make. - @param Controller The handle of the hot-plug controller. - @param RemainingDevicePath The remaining device path for the PCI-like hot-plug device. - @param NumberOfChildren The number of child handles. - For a add operation, it is an output parameter. - For a remove operation, it's an input parameter. - @param ChildHandleBuffer The buffer which contains the child handles. - - @retval EFI_INVALID_PARAMETER Operation is not a legal value. - Controller is NULL or not a valid handle. - NumberOfChildren is NULL. - ChildHandleBuffer is NULL while Operation is add. - @retval EFI_OUT_OF_RESOURCES There are no enough resources to start the devices. - @retval EFI_NOT_FOUND Can not find bridge according to controller handle. - @retval EFI_SUCCESS The handles for the specified device have been created or destroyed - as requested, and for an add operation, the new handles are - returned in ChildHandleBuffer. -**/ -EFI_STATUS -EFIAPI -PciHotPlugRequestNotify ( - IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This, - IN EFI_PCI_HOTPLUG_OPERATION Operation, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL, - IN OUT UINT8 *NumberOfChildren, - IN OUT EFI_HANDLE * ChildHandleBuffer - ) -{ - PCI_IO_DEVICE *Bridge; - PCI_IO_DEVICE *Temp; - EFI_PCI_IO_PROTOCOL *PciIo; - UINTN Index; - EFI_HANDLE RootBridgeHandle; - EFI_STATUS Status; - - // - // Check input parameter validity - // - if ((Controller == NULL) || (NumberOfChildren == NULL)){ - return EFI_INVALID_PARAMETER; - } - - if ((Operation != EfiPciHotPlugRequestAdd) && (Operation != EfiPciHotplugRequestRemove)) { - return EFI_INVALID_PARAMETER; - } - - if (Operation == EfiPciHotPlugRequestAdd){ - if (ChildHandleBuffer == NULL) { - return EFI_INVALID_PARAMETER; - } - } else if ((Operation == EfiPciHotplugRequestRemove) && (*NumberOfChildren != 0)) { - if (ChildHandleBuffer == NULL) { - return EFI_INVALID_PARAMETER; - } - } - - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo); - - // - // Get root bridge handle - // - Temp = Bridge; - while (Temp->Parent != NULL) { - Temp = Temp->Parent; - } - - RootBridgeHandle = Temp->Handle; - - if (Operation == EfiPciHotPlugRequestAdd) { - // - // Report Status Code to indicate hot plug happens - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_PCI | EFI_IOB_PC_HOTPLUG), - Temp->DevicePath - ); - - if (NumberOfChildren != NULL) { - *NumberOfChildren = 0; - } - - if (IsListEmpty (&Bridge->ChildList)) { - - Status = PciBridgeEnumerator (Bridge); - - if (EFI_ERROR (Status)) { - return Status; - } - } - - Status = StartPciDevicesOnBridge ( - RootBridgeHandle, - Bridge, - RemainingDevicePath, - NumberOfChildren, - ChildHandleBuffer - ); - - return Status; - } - - if (Operation == EfiPciHotplugRequestRemove) { - - if (*NumberOfChildren == 0) { - // - // Remove all devices on the bridge - // - RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge); - return EFI_SUCCESS; - - } - - for (Index = 0; Index < *NumberOfChildren; Index++) { - // - // De register all the pci device - // - Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]); - - if (EFI_ERROR (Status)) { - return Status; - } - - } - // - // End for - // - return EFI_SUCCESS; - } - - return EFI_SUCCESS; -} - -/** - Search hostbridge according to given handle - - @param RootBridgeHandle Host bridge handle. - - @retval TRUE Found host bridge handle. - @retval FALSE Not found hot bridge handle. - -**/ -BOOLEAN -SearchHostBridgeHandle ( - IN EFI_HANDLE RootBridgeHandle - ) -{ - EFI_HANDLE HostBridgeHandle; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - UINTN Index; - EFI_STATUS Status; - - // - // Get the rootbridge Io protocol to find the host bridge handle - // - Status = gBS->OpenProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - RootBridgeHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return FALSE; - } - - HostBridgeHandle = PciRootBridgeIo->ParentHandle; - for (Index = 0; Index < gPciHostBridgeNumber; Index++) { - if (HostBridgeHandle == gPciHostBrigeHandles[Index]) { - return TRUE; - } - } - - return FALSE; -} - -/** - Add host bridge handle to global variable for enumerating. - - @param HostBridgeHandle Host bridge handle. - - @retval EFI_SUCCESS Successfully added host bridge. - @retval EFI_ABORTED Host bridge is NULL, or given host bridge - has been in host bridge list. - -**/ -EFI_STATUS -AddHostBridgeEnumerator ( - IN EFI_HANDLE HostBridgeHandle - ) -{ - UINTN Index; - - if (HostBridgeHandle == NULL) { - return EFI_ABORTED; - } - - for (Index = 0; Index < gPciHostBridgeNumber; Index++) { - if (HostBridgeHandle == gPciHostBrigeHandles[Index]) { - return EFI_ABORTED; - } - } - - if (Index < PCI_MAX_HOST_BRIDGE_NUM) { - gPciHostBrigeHandles[Index] = HostBridgeHandle; - gPciHostBridgeNumber++; - } - - return EFI_SUCCESS; -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h deleted file mode 100644 index ff164d1f09..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.h +++ /dev/null @@ -1,519 +0,0 @@ -/** @file - PCI bus enumeration logic function declaration for PCI bus module. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_ENUMERATOR_H_ -#define _EFI_PCI_ENUMERATOR_H_ - -#include "PciResourceSupport.h" - -/** - This routine is used to enumerate entire pci bus system - in a given platform. - - @param Controller Parent controller handle. - - @retval EFI_SUCCESS PCI enumeration finished successfully. - @retval other Some error occurred when enumerating the pci bus system. - -**/ -EFI_STATUS -PciEnumerator ( - IN EFI_HANDLE Controller - ); - -/** - Enumerate PCI root bridge. - - @param PciResAlloc Pointer to protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - @param RootBridgeDev Instance of root bridge device. - - @retval EFI_SUCCESS Successfully enumerated root bridge. - @retval other Failed to enumerate root bridge. - -**/ -EFI_STATUS -PciRootBridgeEnumerator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - IN PCI_IO_DEVICE *RootBridgeDev - ); - -/** - This routine is used to process all PCI devices' Option Rom - on a certain root bridge. - - @param Bridge Given parent's root bridge. - @param RomBase Base address of ROM driver loaded from. - @param MaxLength Maximum rom size. - -**/ -VOID -ProcessOptionRom ( - IN PCI_IO_DEVICE *Bridge, - IN UINT64 RomBase, - IN UINT64 MaxLength - ); - -/** - This routine is used to assign bus number to the given PCI bus system - - @param Bridge Parent root bridge instance. - @param StartBusNumber Number of beginning. - @param SubBusNumber The number of sub bus. - - @retval EFI_SUCCESS Successfully assigned bus number. - @retval EFI_DEVICE_ERROR Failed to assign bus number. - -**/ -EFI_STATUS -PciAssignBusNumber ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber - ); - -/** - This routine is used to determine the root bridge attribute by interfacing - the host bridge resource allocation protocol. - - @param PciResAlloc Protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL - @param RootBridgeDev Root bridge instance - - @retval EFI_SUCCESS Successfully got root bridge's attribute. - @retval other Failed to get attribute. - -**/ -EFI_STATUS -DetermineRootBridgeAttributes ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - IN PCI_IO_DEVICE *RootBridgeDev - ); - -/** - Get Max Option Rom size on specified bridge. - - @param Bridge Given bridge device instance. - - @return Max size of option rom needed. - -**/ -UINT64 -GetMaxOptionRomSize ( - IN PCI_IO_DEVICE *Bridge - ); - -/** - Process attributes of devices on this host bridge - - @param PciResAlloc Protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - - @retval EFI_SUCCESS Successfully process attribute. - @retval EFI_NOT_FOUND Can not find the specific root bridge device. - @retval other Failed to determine the root bridge device's attribute. - -**/ -EFI_STATUS -PciHostBridgeDeviceAttribute ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ); - -/** - Get resource allocation status from the ACPI resource descriptor. - - @param AcpiConfig Point to Acpi configuration table. - @param IoResStatus Return the status of I/O resource. - @param Mem32ResStatus Return the status of 32-bit Memory resource. - @param PMem32ResStatus Return the status of 32-bit Prefetchable Memory resource. - @param Mem64ResStatus Return the status of 64-bit Memory resource. - @param PMem64ResStatus Return the status of 64-bit Prefetchable Memory resource. - -**/ -VOID -GetResourceAllocationStatus ( - VOID *AcpiConfig, - OUT UINT64 *IoResStatus, - OUT UINT64 *Mem32ResStatus, - OUT UINT64 *PMem32ResStatus, - OUT UINT64 *Mem64ResStatus, - OUT UINT64 *PMem64ResStatus - ); - -/** - Remove a PCI device from device pool and mark its bar. - - @param PciDevice Instance of Pci device. - - @retval EFI_SUCCESS Successfully remove the PCI device. - @retval EFI_ABORTED Pci device is a root bridge or a PCI-PCI bridge. - -**/ -EFI_STATUS -RejectPciDevice ( - IN PCI_IO_DEVICE *PciDevice - ); - -/** - Determine whethter a PCI device can be rejected. - - @param PciResNode Pointer to Pci resource node instance. - - @retval TRUE The PCI device can be rejected. - @retval TRUE The PCI device cannot be rejected. - -**/ -BOOLEAN -IsRejectiveDevice ( - IN PCI_RESOURCE_NODE *PciResNode - ); - -/** - Compare two resource nodes and get the larger resource consumer. - - @param PciResNode1 resource node 1 want to be compared - @param PciResNode2 resource node 2 want to be compared - - @return Larger resource node. - -**/ -PCI_RESOURCE_NODE * -GetLargerConsumerDevice ( - IN PCI_RESOURCE_NODE *PciResNode1, - IN PCI_RESOURCE_NODE *PciResNode2 - ); - -/** - Get the max resource consumer in the host resource pool. - - @param ResPool Pointer to resource pool node. - - @return The max resource consumer in the host resource pool. - -**/ -PCI_RESOURCE_NODE * -GetMaxResourceConsumerDevice ( - IN PCI_RESOURCE_NODE *ResPool - ); - -/** - Adjust host bridge allocation so as to reduce resource requirement - - @param IoPool Pointer to instance of I/O resource Node. - @param Mem32Pool Pointer to instance of 32-bit memory resource Node. - @param PMem32Pool Pointer to instance of 32-bit Prefetchable memory resource node. - @param Mem64Pool Pointer to instance of 64-bit memory resource node. - @param PMem64Pool Pointer to instance of 64-bit Prefetchable memory resource node. - @param IoResStatus Status of I/O resource Node. - @param Mem32ResStatus Status of 32-bit memory resource Node. - @param PMem32ResStatus Status of 32-bit Prefetchable memory resource node. - @param Mem64ResStatus Status of 64-bit memory resource node. - @param PMem64ResStatus Status of 64-bit Prefetchable memory resource node. - - @retval EFI_SUCCESS Successfully adjusted resoruce on host bridge. - @retval EFI_ABORTED Host bridge hasn't this resource type or no resource be adjusted. - -**/ -EFI_STATUS -PciHostBridgeAdjustAllocation ( - IN PCI_RESOURCE_NODE *IoPool, - IN PCI_RESOURCE_NODE *Mem32Pool, - IN PCI_RESOURCE_NODE *PMem32Pool, - IN PCI_RESOURCE_NODE *Mem64Pool, - IN PCI_RESOURCE_NODE *PMem64Pool, - IN UINT64 IoResStatus, - IN UINT64 Mem32ResStatus, - IN UINT64 PMem32ResStatus, - IN UINT64 Mem64ResStatus, - IN UINT64 PMem64ResStatus - ); - -/** - Summary requests for all resource type, and contruct ACPI resource - requestor instance. - - @param Bridge detecting bridge - @param IoNode Pointer to instance of I/O resource Node - @param Mem32Node Pointer to instance of 32-bit memory resource Node - @param PMem32Node Pointer to instance of 32-bit Pmemory resource node - @param Mem64Node Pointer to instance of 64-bit memory resource node - @param PMem64Node Pointer to instance of 64-bit Pmemory resource node - @param Config Output buffer holding new constructed APCI resource requestor - - @retval EFI_SUCCESS Successfully constructed ACPI resource. - @retval EFI_OUT_OF_RESOURCES No memory availabe. - -**/ -EFI_STATUS -ConstructAcpiResourceRequestor ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node, - OUT VOID **Config - ); - -/** - Get resource base from an acpi configuration descriptor. - - @param Config An acpi configuration descriptor. - @param IoBase Output of I/O resource base address. - @param Mem32Base Output of 32-bit memory base address. - @param PMem32Base Output of 32-bit prefetchable memory base address. - @param Mem64Base Output of 64-bit memory base address. - @param PMem64Base Output of 64-bit prefetchable memory base address. - -**/ -VOID -GetResourceBase ( - IN VOID *Config, - OUT UINT64 *IoBase, - OUT UINT64 *Mem32Base, - OUT UINT64 *PMem32Base, - OUT UINT64 *Mem64Base, - OUT UINT64 *PMem64Base - ); - -/** - Enumerate pci bridge, allocate resource and determine attribute - for devices on this bridge. - - @param BridgeDev Pointer to instance of bridge device. - - @retval EFI_SUCCESS Successfully enumerated PCI bridge. - @retval other Failed to enumerate. - -**/ -EFI_STATUS -PciBridgeEnumerator ( - IN PCI_IO_DEVICE *BridgeDev - ); - -/** - Allocate all kinds of resource for PCI bridge. - - @param Bridge Pointer to bridge instance. - - @retval EFI_SUCCESS Successfully allocated resource for PCI bridge. - @retval other Failed to allocate resource for bridge. - -**/ -EFI_STATUS -PciBridgeResourceAllocator ( - IN PCI_IO_DEVICE *Bridge - ); - -/** - Get resource base address for a pci bridge device. - - @param Bridge Given Pci driver instance. - @param IoBase Output for base address of I/O type resource. - @param Mem32Base Output for base address of 32-bit memory type resource. - @param PMem32Base Ooutput for base address of 32-bit Pmemory type resource. - @param Mem64Base Output for base address of 64-bit memory type resource. - @param PMem64Base Output for base address of 64-bit Pmemory type resource. - - @retval EFI_SUCCESS Successfully got resource base address. - @retval EFI_OUT_OF_RESOURCES PCI bridge is not available. - -**/ -EFI_STATUS -GetResourceBaseFromBridge ( - IN PCI_IO_DEVICE *Bridge, - OUT UINT64 *IoBase, - OUT UINT64 *Mem32Base, - OUT UINT64 *PMem32Base, - OUT UINT64 *Mem64Base, - OUT UINT64 *PMem64Base - ); - -/** - Process Option Rom on this host bridge - - @param PciResAlloc Pointer to instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - - @retval EFI_NOT_FOUND Can not find the root bridge instance. - @retval EFI_SUCCESS Success process. -**/ -EFI_STATUS -PciHostBridgeP2CProcess ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ); - -/** - These are the notifications from the PCI bus driver that it is about to enter a certain - phase of the PCI enumeration process. - - This member function can be used to notify the host bridge driver to perform specific actions, - including any chipset-specific initialization, so that the chipset is ready to enter the next phase. - Eight notification points are defined at this time. See belows: - EfiPciHostBridgeBeginEnumeration Resets the host bridge PCI apertures and internal data - structures. The PCI enumerator should issue this notification - before starting a fresh enumeration process. Enumeration cannot - be restarted after sending any other notification such as - EfiPciHostBridgeBeginBusAllocation. - EfiPciHostBridgeBeginBusAllocation The bus allocation phase is about to begin. No specific action is - required here. This notification can be used to perform any - chipset-specific programming. - EfiPciHostBridgeEndBusAllocation The bus allocation and bus programming phase is complete. No - specific action is required here. This notification can be used to - perform any chipset-specific programming. - EfiPciHostBridgeBeginResourceAllocation - The resource allocation phase is about to begin. No specific - action is required here. This notification can be used to perform - any chipset-specific programming. - EfiPciHostBridgeAllocateResources Allocates resources per previously submitted requests for all the PCI - root bridges. These resource settings are returned on the next call to - GetProposedResources(). Before calling NotifyPhase() with a Phase of - EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible - for gathering I/O and memory requests for - all the PCI root bridges and submitting these requests using - SubmitResources(). This function pads the resource amount - to suit the root bridge hardware, takes care of dependencies between - the PCI root bridges, and calls the Global Coherency Domain (GCD) - with the allocation request. In the case of padding, the allocated range - could be bigger than what was requested. - EfiPciHostBridgeSetResources Programs the host bridge hardware to decode previously allocated - resources (proposed resources) for all the PCI root bridges. After the - hardware is programmed, reassigning resources will not be supported. - The bus settings are not affected. - EfiPciHostBridgeFreeResources Deallocates resources that were previously allocated for all the PCI - root bridges and resets the I/O and memory apertures to their initial - state. The bus settings are not affected. If the request to allocate - resources fails, the PCI enumerator can use this notification to - deallocate previous resources, adjust the requests, and retry - allocation. - EfiPciHostBridgeEndResourceAllocation The resource allocation phase is completed. No specific action is - required here. This notification can be used to perform any chipsetspecific - programming. - - @param[in] PciResAlloc The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL - @param[in] Phase The phase during enumeration - - @retval EFI_NOT_READY This phase cannot be entered at this time. For example, this error - is valid for a Phase of EfiPciHostBridgeAllocateResources if - SubmitResources() has not been called for one or more - PCI root bridges before this call - @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. This error is valid - for a Phase of EfiPciHostBridgeSetResources. - @retval EFI_INVALID_PARAMETER Invalid phase parameter - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the - previously submitted resource requests cannot be fulfilled or - were only partially fulfilled. - @retval EFI_SUCCESS The notification was accepted without any errors. - -**/ -EFI_STATUS -NotifyPhase ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc, - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase - ); - -/** - Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various - stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual - PCI controllers before enumeration. - - This function is called during the PCI enumeration process. No specific action is expected from this - member function. It allows the host bridge driver to preinitialize individual PCI controllers before - enumeration. - - @param Bridge Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance. - @param Bus The bus number of the pci device. - @param Device The device number of the pci device. - @param Func The function number of the pci device. - @param Phase The phase of the PCI device enumeration. - - @retval EFI_SUCCESS The requested parameters were returned. - @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid root bridge handle. - @retval EFI_INVALID_PARAMETER Phase is not a valid phase that is defined in - EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE. - @retval EFI_DEVICE_ERROR Programming failed due to a hardware error. The PCI enumerator should - not enumerate this device, including its child devices if it is a PCI-to-PCI - bridge. - -**/ -EFI_STATUS -PreprocessController ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func, - IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase - ); - -/** - This function allows the PCI bus driver to be notified to act as requested when a hot-plug event has - happened on the hot-plug controller. Currently, the operations include add operation and remove operation.. - - @param This A pointer to the hot plug request protocol. - @param Operation The operation the PCI bus driver is requested to make. - @param Controller The handle of the hot-plug controller. - @param RemainingDevicePath The remaining device path for the PCI-like hot-plug device. - @param NumberOfChildren The number of child handles. - For a add operation, it is an output parameter. - For a remove operation, it's an input parameter. - @param ChildHandleBuffer The buffer which contains the child handles. - - @retval EFI_INVALID_PARAMETER Operation is not a legal value. - Controller is NULL or not a valid handle. - NumberOfChildren is NULL. - ChildHandleBuffer is NULL while Operation is add. - @retval EFI_OUT_OF_RESOURCES There are no enough resources to start the devices. - @retval EFI_NOT_FOUND Can not find bridge according to controller handle. - @retval EFI_SUCCESS The handles for the specified device have been created or destroyed - as requested, and for an add operation, the new handles are - returned in ChildHandleBuffer. -**/ -EFI_STATUS -EFIAPI -PciHotPlugRequestNotify ( - IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This, - IN EFI_PCI_HOTPLUG_OPERATION Operation, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL, - IN OUT UINT8 *NumberOfChildren, - IN OUT EFI_HANDLE * ChildHandleBuffer - ); - -/** - Search hostbridge according to given handle - - @param RootBridgeHandle Host bridge handle. - - @retval TRUE Found host bridge handle. - @retval FALSE Not found hot bridge handle. - -**/ -BOOLEAN -SearchHostBridgeHandle ( - IN EFI_HANDLE RootBridgeHandle - ); - -/** - Add host bridge handle to global variable for enumerating. - - @param HostBridgeHandle Host bridge handle. - - @retval EFI_SUCCESS Successfully added host bridge. - @retval EFI_ABORTED Host bridge is NULL, or given host bridge - has been in host bridge list. - -**/ -EFI_STATUS -AddHostBridgeEnumerator ( - IN EFI_HANDLE HostBridgeHandle - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c deleted file mode 100644 index b070eb1b5f..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c +++ /dev/null @@ -1,2717 +0,0 @@ -/** @file - PCI emumeration support functions implementation for PCI Bus module. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -extern CHAR16 *mBarTypeStr[]; - -/** - This routine is used to check whether the pci device is present. - - @param PciRootBridgeIo Pointer to instance of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Pci Output buffer for PCI device configuration space. - @param Bus PCI bus NO. - @param Device PCI device NO. - @param Func PCI Func NO. - - @retval EFI_NOT_FOUND PCI device not present. - @retval EFI_SUCCESS PCI device is found. - -**/ -EFI_STATUS -PciDevicePresent ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - OUT PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ) -{ - UINT64 Address; - EFI_STATUS Status; - - // - // Create PCI address map in terms of Bus, Device and Func - // - Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0); - - // - // Read the Vendor ID register - // - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - EfiPciWidthUint32, - Address, - 1, - Pci - ); - - if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) { - // - // Read the entire config header for the device - // - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - EfiPciWidthUint32, - Address, - sizeof (PCI_TYPE00) / sizeof (UINT32), - Pci - ); - - return EFI_SUCCESS; - } - - return EFI_NOT_FOUND; -} - -/** - Collect all the resource information under this root bridge. - - A database that records all the information about pci device subject to this - root bridge will then be created. - - @param Bridge Parent bridge instance. - @param StartBusNumber Bus number of begining. - - @retval EFI_SUCCESS PCI device is found. - @retval other Some error occurred when reading PCI bridge information. - -**/ -EFI_STATUS -PciPciDeviceInfoCollector ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber - ) -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT8 Func; - UINT8 SecBus; - PCI_IO_DEVICE *PciIoDevice; - EFI_PCI_IO_PROTOCOL *PciIo; - - Status = EFI_SUCCESS; - SecBus = 0; - - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether PCI device is present - // - Status = PciDevicePresent ( - Bridge->PciRootBridgeIo, - &Pci, - (UINT8) StartBusNumber, - (UINT8) Device, - (UINT8) Func - ); - if (!EFI_ERROR (Status)) { - - // - // Call back to host bridge function - // - PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection); - - // - // Collect all the information about the PCI device discovered - // - Status = PciSearchDevice ( - Bridge, - &Pci, - (UINT8) StartBusNumber, - Device, - Func, - &PciIoDevice - ); - - // - // Recursively scan PCI busses on the other side of PCI-PCI bridges - // - // - if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) { - - // - // If it is PPB, we need to get the secondary bus to continue the enumeration - // - PciIo = &(PciIoDevice->PciIo); - - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 1, &SecBus); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get resource padding for PPB - // - GetResourcePaddingPpb (PciIoDevice); - - // - // Deep enumerate the next level bus - // - Status = PciPciDeviceInfoCollector ( - PciIoDevice, - (UINT8) (SecBus) - ); - - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - - // - // Skip sub functions, this is not a multi function device - // - Func = PCI_MAX_FUNC; - } - } - - } - } - - return EFI_SUCCESS; -} - -/** - Seach required device and create PCI device instance. - - @param Bridge Parent bridge instance. - @param Pci Input PCI device information block. - @param Bus PCI bus NO. - @param Device PCI device NO. - @param Func PCI func NO. - @param PciDevice Output of searched PCI device instance. - - @retval EFI_SUCCESS Successfully created PCI device instance. - @retval EFI_OUT_OF_RESOURCES Cannot get PCI device information. - -**/ -EFI_STATUS -PciSearchDevice ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func, - OUT PCI_IO_DEVICE **PciDevice - ) -{ - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = NULL; - - DEBUG (( - EFI_D_INFO, - "PciBus: Discovered %s @ [%02x|%02x|%02x]\n", - IS_PCI_BRIDGE (Pci) ? L"PPB" : - IS_CARDBUS_BRIDGE (Pci) ? L"P2C" : - L"PCI", - Bus, Device, Func - )); - - if (!IS_PCI_BRIDGE (Pci)) { - - if (IS_CARDBUS_BRIDGE (Pci)) { - PciIoDevice = GatherP2CInfo ( - Bridge, - Pci, - Bus, - Device, - Func - ); - if ((PciIoDevice != NULL) && gFullEnumeration) { - InitializeP2C (PciIoDevice); - } - } else { - - // - // Create private data for Pci Device - // - PciIoDevice = GatherDeviceInfo ( - Bridge, - Pci, - Bus, - Device, - Func - ); - - } - - } else { - - // - // Create private data for PPB - // - PciIoDevice = GatherPpbInfo ( - Bridge, - Pci, - Bus, - Device, - Func - ); - - // - // Special initialization for PPB including making the PPB quiet - // - if ((PciIoDevice != NULL) && gFullEnumeration) { - InitializePpb (PciIoDevice); - } - } - - if (PciIoDevice == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Update the bar information for this PCI device so as to support some specific device - // - UpdatePciInfo (PciIoDevice); - - if (PciIoDevice->DevicePath == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Detect this function has option rom - // - if (gFullEnumeration) { - - if (!IS_CARDBUS_BRIDGE (Pci)) { - - GetOpRomInfo (PciIoDevice); - - } - - ResetPowerManagementFeature (PciIoDevice); - - } - - // - // Insert it into a global tree for future reference - // - InsertPciDevice (Bridge, PciIoDevice); - - // - // Determine PCI device attributes - // - - if (PciDevice != NULL) { - *PciDevice = PciIoDevice; - } - - return EFI_SUCCESS; -} - -/** - Dump the PPB padding resource information. - - @param PciIoDevice PCI IO instance. - @param ResourceType The desired resource type to dump. - PciBarTypeUnknown means to dump all types of resources. -**/ -VOID -DumpPpbPaddingResource ( - IN PCI_IO_DEVICE *PciIoDevice, - IN PCI_BAR_TYPE ResourceType - ) -{ - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; - PCI_BAR_TYPE Type; - - if (PciIoDevice->ResourcePaddingDescriptors == NULL) { - return; - } - - if (ResourceType == PciBarTypeIo16 || ResourceType == PciBarTypeIo32) { - ResourceType = PciBarTypeIo; - } - - for (Descriptor = PciIoDevice->ResourcePaddingDescriptors; Descriptor->Desc != ACPI_END_TAG_DESCRIPTOR; Descriptor++) { - - Type = PciBarTypeUnknown; - if (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) { - Type = PciBarTypeIo; - } else if (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { - - if (Descriptor->AddrSpaceGranularity == 32) { - // - // prefechable - // - if (Descriptor->SpecificFlag == EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) { - Type = PciBarTypePMem32; - } - - // - // Non-prefechable - // - if (Descriptor->SpecificFlag == 0) { - Type = PciBarTypeMem32; - } - } - - if (Descriptor->AddrSpaceGranularity == 64) { - // - // prefechable - // - if (Descriptor->SpecificFlag == EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) { - Type = PciBarTypePMem64; - } - - // - // Non-prefechable - // - if (Descriptor->SpecificFlag == 0) { - Type = PciBarTypeMem64; - } - } - } - - if ((Type != PciBarTypeUnknown) && ((ResourceType == PciBarTypeUnknown) || (ResourceType == Type))) { - DEBUG (( - EFI_D_INFO, - " Padding: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx\n", - mBarTypeStr[Type], Descriptor->AddrRangeMax, Descriptor->AddrLen - )); - } - } - -} - -/** - Dump the PCI BAR information. - - @param PciIoDevice PCI IO instance. -**/ -VOID -DumpPciBars ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - UINTN Index; - - for (Index = 0; Index < PCI_MAX_BAR; Index++) { - if (PciIoDevice->PciBar[Index].BarType == PciBarTypeUnknown) { - continue; - } - - DEBUG (( - EFI_D_INFO, - " BAR[%d]: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx;\tOffset = 0x%02x\n", - Index, mBarTypeStr[MIN (PciIoDevice->PciBar[Index].BarType, PciBarTypeMaxType)], - PciIoDevice->PciBar[Index].Alignment, PciIoDevice->PciBar[Index].Length, PciIoDevice->PciBar[Index].Offset - )); - } - - for (Index = 0; Index < PCI_MAX_BAR; Index++) { - if ((PciIoDevice->VfPciBar[Index].BarType == PciBarTypeUnknown) && (PciIoDevice->VfPciBar[Index].Length == 0)) { - continue; - } - - DEBUG (( - EFI_D_INFO, - " VFBAR[%d]: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx;\tOffset = 0x%02x\n", - Index, mBarTypeStr[MIN (PciIoDevice->VfPciBar[Index].BarType, PciBarTypeMaxType)], - PciIoDevice->VfPciBar[Index].Alignment, PciIoDevice->VfPciBar[Index].Length, PciIoDevice->VfPciBar[Index].Offset - )); - } - DEBUG ((EFI_D_INFO, "\n")); -} - -/** - Create PCI device instance for PCI device. - - @param Bridge Parent bridge instance. - @param Pci Input PCI device information block. - @param Bus PCI device Bus NO. - @param Device PCI device Device NO. - @param Func PCI device's func NO. - - @return Created PCI device instance. - -**/ -PCI_IO_DEVICE * -GatherDeviceInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ) -{ - UINTN Offset; - UINTN BarIndex; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = CreatePciIoDevice ( - Bridge, - Pci, - Bus, - Device, - Func - ); - - if (PciIoDevice == NULL) { - return NULL; - } - - // - // If it is a full enumeration, disconnect the device in advance - // - if (gFullEnumeration) { - - PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); - - } - - // - // Start to parse the bars - // - for (Offset = 0x10, BarIndex = 0; Offset <= 0x24 && BarIndex < PCI_MAX_BAR; BarIndex++) { - Offset = PciParseBar (PciIoDevice, Offset, BarIndex); - } - - // - // Parse the SR-IOV VF bars - // - if (PcdGetBool (PcdSrIovSupport) && PciIoDevice->SrIovCapabilityOffset != 0) { - for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0; - Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5; - BarIndex++) { - - ASSERT (BarIndex < PCI_MAX_BAR); - Offset = PciIovParseVfBar (PciIoDevice, Offset, BarIndex); - } - } - - DEBUG_CODE (DumpPciBars (PciIoDevice);); - return PciIoDevice; -} - -/** - Create PCI device instance for PCI-PCI bridge. - - @param Bridge Parent bridge instance. - @param Pci Input PCI device information block. - @param Bus PCI device Bus NO. - @param Device PCI device Device NO. - @param Func PCI device's func NO. - - @return Created PCI device instance. - -**/ -PCI_IO_DEVICE * -GatherPpbInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ) -{ - PCI_IO_DEVICE *PciIoDevice; - EFI_STATUS Status; - UINT8 Value; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Temp; - UINT32 PMemBaseLimit; - UINT16 PrefetchableMemoryBase; - UINT16 PrefetchableMemoryLimit; - - PciIoDevice = CreatePciIoDevice ( - Bridge, - Pci, - Bus, - Device, - Func - ); - - if (PciIoDevice == NULL) { - return NULL; - } - - if (gFullEnumeration) { - PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); - - // - // Initalize the bridge control register - // - PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED); - - } - - // - // PPB can have two BARs - // - if (PciParseBar (PciIoDevice, 0x10, PPB_BAR_0) == 0x14) { - // - // Not 64-bit bar - // - PciParseBar (PciIoDevice, 0x14, PPB_BAR_1); - } - - PciIo = &PciIoDevice->PciIo; - - // - // Test whether it support 32 decode or not - // - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne); - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp); - - if (Value != 0) { - if ((Value & 0x01) != 0) { - PciIoDevice->Decodes |= EFI_BRIDGE_IO32_DECODE_SUPPORTED; - } else { - PciIoDevice->Decodes |= EFI_BRIDGE_IO16_DECODE_SUPPORTED; - } - } - - // - // if PcdPciBridgeIoAlignmentProbe is TRUE, PCI bus driver probes - // PCI bridge supporting non-stardard I/O window alignment less than 4K. - // - - PciIoDevice->BridgeIoAlignment = 0xFFF; - if (FeaturePcdGet (PcdPciBridgeIoAlignmentProbe)) { - // - // Check any bits of bit 3-1 of I/O Base Register are writable. - // if so, it is assumed non-stardard I/O window alignment is supported by this bridge. - // Per spec, bit 3-1 of I/O Base Register are reserved bits, so its content can't be assumed. - // - Value = (UINT8)(Temp ^ (BIT3 | BIT2 | BIT1)); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value); - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Value); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &Temp); - Value = (UINT8)((Value ^ Temp) & (BIT3 | BIT2 | BIT1)); - switch (Value) { - case BIT3: - PciIoDevice->BridgeIoAlignment = 0x7FF; - break; - case BIT3 | BIT2: - PciIoDevice->BridgeIoAlignment = 0x3FF; - break; - case BIT3 | BIT2 | BIT1: - PciIoDevice->BridgeIoAlignment = 0x1FF; - break; - } - } - - Status = BarExisted ( - PciIoDevice, - 0x24, - NULL, - &PMemBaseLimit - ); - - // - // Test if it supports 64 memory or not - // - // The bottom 4 bits of both the Prefetchable Memory Base and Prefetchable Memory Limit - // registers: - // 0 - the bridge supports only 32 bit addresses. - // 1 - the bridge supports 64-bit addresses. - // - PrefetchableMemoryBase = (UINT16)(PMemBaseLimit & 0xffff); - PrefetchableMemoryLimit = (UINT16)(PMemBaseLimit >> 16); - if (!EFI_ERROR (Status) && - (PrefetchableMemoryBase & 0x000f) == 0x0001 && - (PrefetchableMemoryLimit & 0x000f) == 0x0001) { - Status = BarExisted ( - PciIoDevice, - 0x28, - NULL, - NULL - ); - - if (!EFI_ERROR (Status)) { - PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; - PciIoDevice->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED; - } else { - PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED; - } - } - - // - // Memory 32 code is required for ppb - // - PciIoDevice->Decodes |= EFI_BRIDGE_MEM32_DECODE_SUPPORTED; - - GetResourcePaddingPpb (PciIoDevice); - - DEBUG_CODE ( - DumpPpbPaddingResource (PciIoDevice, PciBarTypeUnknown); - DumpPciBars (PciIoDevice); - ); - - return PciIoDevice; -} - - -/** - Create PCI device instance for PCI Card bridge device. - - @param Bridge Parent bridge instance. - @param Pci Input PCI device information block. - @param Bus PCI device Bus NO. - @param Device PCI device Device NO. - @param Func PCI device's func NO. - - @return Created PCI device instance. - -**/ -PCI_IO_DEVICE * -GatherP2CInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ) -{ - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = CreatePciIoDevice ( - Bridge, - Pci, - Bus, - Device, - Func - ); - - if (PciIoDevice == NULL) { - return NULL; - } - - if (gFullEnumeration) { - PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED); - - // - // Initalize the bridge control register - // - PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED); - } - - // - // P2C only has one bar that is in 0x10 - // - PciParseBar (PciIoDevice, 0x10, P2C_BAR_0); - - // - // Read PciBar information from the bar register - // - GetBackPcCardBar (PciIoDevice); - PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED | - EFI_BRIDGE_PMEM32_DECODE_SUPPORTED | - EFI_BRIDGE_IO32_DECODE_SUPPORTED; - - DEBUG_CODE (DumpPciBars (PciIoDevice);); - - return PciIoDevice; -} - -/** - Create device path for pci deivce. - - @param ParentDevicePath Parent bridge's path. - @param PciIoDevice Pci device instance. - - @return Device path protocol instance for specific pci device. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -CreatePciDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - - PCI_DEVICE_PATH PciNode; - - // - // Create PCI device path - // - PciNode.Header.Type = HARDWARE_DEVICE_PATH; - PciNode.Header.SubType = HW_PCI_DP; - SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode)); - - PciNode.Device = PciIoDevice->DeviceNumber; - PciNode.Function = PciIoDevice->FunctionNumber; - PciIoDevice->DevicePath = AppendDevicePathNode (ParentDevicePath, &PciNode.Header); - - return PciIoDevice->DevicePath; -} - -/** - Check whether the PCI IOV VF bar is existed or not. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE. - @param Offset The offset. - @param BarLengthValue The bar length value returned. - @param OriginalBarValue The original bar value returned. - - @retval EFI_NOT_FOUND The bar doesn't exist. - @retval EFI_SUCCESS The bar exist. - -**/ -EFI_STATUS -VfBarExisted ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - OUT UINT32 *BarLengthValue, - OUT UINT32 *OriginalBarValue - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT32 OriginalValue; - UINT32 Value; - EFI_TPL OldTpl; - - // - // Ensure it is called properly - // - ASSERT (PciIoDevice->SrIovCapabilityOffset != 0); - if (PciIoDevice->SrIovCapabilityOffset == 0) { - return EFI_NOT_FOUND; - } - - PciIo = &PciIoDevice->PciIo; - - // - // Preserve the original value - // - - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &OriginalValue); - - // - // Raise TPL to high level to disable timer interrupt while the BAR is probed - // - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &gAllOne); - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &Value); - - // - // Write back the original value - // - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT32)Offset, 1, &OriginalValue); - - // - // Restore TPL to its original level - // - gBS->RestoreTPL (OldTpl); - - if (BarLengthValue != NULL) { - *BarLengthValue = Value; - } - - if (OriginalBarValue != NULL) { - *OriginalBarValue = OriginalValue; - } - - if (Value == 0) { - return EFI_NOT_FOUND; - } else { - return EFI_SUCCESS; - } -} - -/** - Check whether the bar is existed or not. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE. - @param Offset The offset. - @param BarLengthValue The bar length value returned. - @param OriginalBarValue The original bar value returned. - - @retval EFI_NOT_FOUND The bar doesn't exist. - @retval EFI_SUCCESS The bar exist. - -**/ -EFI_STATUS -BarExisted ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - OUT UINT32 *BarLengthValue, - OUT UINT32 *OriginalBarValue - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT32 OriginalValue; - UINT32 Value; - EFI_TPL OldTpl; - - PciIo = &PciIoDevice->PciIo; - - // - // Preserve the original value - // - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue); - - // - // Raise TPL to high level to disable timer interrupt while the BAR is probed - // - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne); - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value); - - // - // Write back the original value - // - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue); - - // - // Restore TPL to its original level - // - gBS->RestoreTPL (OldTpl); - - if (BarLengthValue != NULL) { - *BarLengthValue = Value; - } - - if (OriginalBarValue != NULL) { - *OriginalBarValue = OriginalValue; - } - - if (Value == 0) { - return EFI_NOT_FOUND; - } else { - return EFI_SUCCESS; - } -} - -/** - Test whether the device can support given attributes. - - @param PciIoDevice Pci device instance. - @param Command Input command register value, and - returned supported register value. - @param BridgeControl Inout bridge control value for PPB or P2C, and - returned supported bridge control value. - @param OldCommand Returned and stored old command register offset. - @param OldBridgeControl Returned and stored old Bridge control value for PPB or P2C. - -**/ -VOID -PciTestSupportedAttribute ( - IN PCI_IO_DEVICE *PciIoDevice, - IN OUT UINT16 *Command, - IN OUT UINT16 *BridgeControl, - OUT UINT16 *OldCommand, - OUT UINT16 *OldBridgeControl - ) -{ - EFI_TPL OldTpl; - - // - // Preserve the original value - // - PCI_READ_COMMAND_REGISTER (PciIoDevice, OldCommand); - - // - // Raise TPL to high level to disable timer interrupt while the BAR is probed - // - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - PCI_SET_COMMAND_REGISTER (PciIoDevice, *Command); - PCI_READ_COMMAND_REGISTER (PciIoDevice, Command); - - // - // Write back the original value - // - PCI_SET_COMMAND_REGISTER (PciIoDevice, *OldCommand); - - // - // Restore TPL to its original level - // - gBS->RestoreTPL (OldTpl); - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - - // - // Preserve the original value - // - PCI_READ_BRIDGE_CONTROL_REGISTER (PciIoDevice, OldBridgeControl); - - // - // Raise TPL to high level to disable timer interrupt while the BAR is probed - // - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - - PCI_SET_BRIDGE_CONTROL_REGISTER (PciIoDevice, *BridgeControl); - PCI_READ_BRIDGE_CONTROL_REGISTER (PciIoDevice, BridgeControl); - - // - // Write back the original value - // - PCI_SET_BRIDGE_CONTROL_REGISTER (PciIoDevice, *OldBridgeControl); - - // - // Restore TPL to its original level - // - gBS->RestoreTPL (OldTpl); - - } else { - *OldBridgeControl = 0; - *BridgeControl = 0; - } -} - -/** - Set the supported or current attributes of a PCI device. - - @param PciIoDevice Structure pointer for PCI device. - @param Command Command register value. - @param BridgeControl Bridge control value for PPB or P2C. - @param Option Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES. - -**/ -VOID -PciSetDeviceAttribute ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 Command, - IN UINT16 BridgeControl, - IN UINTN Option - ) -{ - UINT64 Attributes; - - Attributes = 0; - - if ((Command & EFI_PCI_COMMAND_IO_SPACE) != 0) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_IO; - } - - if ((Command & EFI_PCI_COMMAND_MEMORY_SPACE) != 0) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY; - } - - if ((Command & EFI_PCI_COMMAND_BUS_MASTER) != 0) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER; - } - - if ((Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) != 0) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; - } - - if ((BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) != 0) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO; - } - - if ((BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) != 0) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO; - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY; - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; - } - - if ((BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16) != 0) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16; - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16; - } - - if (Option == EFI_SET_SUPPORTS) { - - Attributes |= (UINT64) (EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | - EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | - EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE | - EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE | - EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM | - EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE); - - if (IS_PCI_LPC (&PciIoDevice->Pci)) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO; - Attributes |= (mReserveIsaAliases ? (UINT64) EFI_PCI_IO_ATTRIBUTE_ISA_IO : \ - (UINT64) EFI_PCI_IO_ATTRIBUTE_ISA_IO_16); - } - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - // - // For bridge, it should support IDE attributes - // - Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO; - Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO; - - if (mReserveVgaAliases) { - Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | \ - EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16); - } else { - Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_VGA_IO | \ - EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO); - } - } else { - - if (IS_PCI_IDE (&PciIoDevice->Pci)) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO; - Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO; - } - - if (IS_PCI_VGA (&PciIoDevice->Pci)) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY; - Attributes |= (mReserveVgaAliases ? (UINT64) EFI_PCI_IO_ATTRIBUTE_VGA_IO : \ - (UINT64) EFI_PCI_IO_ATTRIBUTE_VGA_IO_16); - } - } - - PciIoDevice->Supports = Attributes; - PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \ - EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \ - EFI_PCI_IO_ATTRIBUTE_BUS_MASTER ); - - } else { - // - // When this attribute is clear, the RomImage and RomSize fields in the PCI IO were - // initialized based on the PCI option ROM found through the ROM BAR of the PCI controller. - // When this attribute is set, the PCI option ROM described by the RomImage and RomSize - // fields is not from the the ROM BAR of the PCI controller. - // - if (!PciIoDevice->EmbeddedRom) { - Attributes |= EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM; - } - PciIoDevice->Attributes = Attributes; - } -} - -/** - Determine if the device can support Fast Back to Back attribute. - - @param PciIoDevice Pci device instance. - @param StatusIndex Status register value. - - @retval EFI_SUCCESS This device support Fast Back to Back attribute. - @retval EFI_UNSUPPORTED This device doesn't support Fast Back to Back attribute. - -**/ -EFI_STATUS -GetFastBackToBackSupport ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 StatusIndex - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT32 StatusRegister; - - // - // Read the status register - // - PciIo = &PciIoDevice->PciIo; - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Check the Fast B2B bit - // - if ((StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) != 0) { - return EFI_SUCCESS; - } else { - return EFI_UNSUPPORTED; - } -} - -/** - Process the option ROM for all the children of the specified parent PCI device. - It can only be used after the first full Option ROM process. - - @param PciIoDevice Pci device instance. - -**/ -VOID -ProcessOptionRomLight ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - - // - // For RootBridge, PPB , P2C, go recursively to traverse all its children - // - CurrentLink = PciIoDevice->ChildList.ForwardLink; - while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (!IsListEmpty (&Temp->ChildList)) { - ProcessOptionRomLight (Temp); - } - - PciRomGetImageMapping (Temp); - - // - // The OpRom has already been processed in the first round - // - Temp->AllOpRomProcessed = TRUE; - - CurrentLink = CurrentLink->ForwardLink; - } -} - -/** - Determine the related attributes of all devices under a Root Bridge. - - @param PciIoDevice PCI device instance. - -**/ -EFI_STATUS -DetermineDeviceAttribute ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - UINT16 Command; - UINT16 BridgeControl; - UINT16 OldCommand; - UINT16 OldBridgeControl; - BOOLEAN FastB2BSupport; - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - EFI_STATUS Status; - - // - // For Root Bridge, just copy it by RootBridgeIo proctocol - // so as to keep consistent with the actual attribute - // - if (PciIoDevice->Parent == NULL) { - Status = PciIoDevice->PciRootBridgeIo->GetAttributes ( - PciIoDevice->PciRootBridgeIo, - &PciIoDevice->Supports, - &PciIoDevice->Attributes - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Assume the PCI Root Bridge supports DAC - // - PciIoDevice->Supports |= (UINT64)(EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE | - EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM | - EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE); - - } else { - - // - // Set the attributes to be checked for common PCI devices and PPB or P2C - // Since some devices only support part of them, it is better to set the - // attribute according to its command or bridge control register - // - Command = EFI_PCI_COMMAND_IO_SPACE | - EFI_PCI_COMMAND_MEMORY_SPACE | - EFI_PCI_COMMAND_BUS_MASTER | - EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; - - BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16; - - // - // Test whether the device can support attributes above - // - PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl); - - // - // Set the supported attributes for specified PCI device - // - PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS); - - // - // Set the current attributes for specified PCI device - // - PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES); - - // - // Enable other supported attributes but not defined in PCI_IO_PROTOCOL - // - PCI_ENABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE); - } - - FastB2BSupport = TRUE; - - // - // P2C can not support FB2B on the secondary side - // - if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - FastB2BSupport = FALSE; - } - - // - // For RootBridge, PPB , P2C, go recursively to traverse all its children - // - CurrentLink = PciIoDevice->ChildList.ForwardLink; - while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - Status = DetermineDeviceAttribute (Temp); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Detect Fast Bact to Bact support for the device under the bridge - // - Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET); - if (FastB2BSupport && EFI_ERROR (Status)) { - FastB2BSupport = FALSE; - } - - CurrentLink = CurrentLink->ForwardLink; - } - // - // Set or clear Fast Back to Back bit for the whole bridge - // - if (!IsListEmpty (&PciIoDevice->ChildList)) { - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { - - Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET); - - if (EFI_ERROR (Status) || (!FastB2BSupport)) { - FastB2BSupport = FALSE; - PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK); - } else { - PCI_ENABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK); - } - } - - CurrentLink = PciIoDevice->ChildList.ForwardLink; - while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - if (FastB2BSupport) { - PCI_ENABLE_COMMAND_REGISTER (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK); - } else { - PCI_DISABLE_COMMAND_REGISTER (Temp, EFI_PCI_COMMAND_FAST_BACK_TO_BACK); - } - - CurrentLink = CurrentLink->ForwardLink; - } - } - // - // End for IsListEmpty - // - return EFI_SUCCESS; -} - -/** - This routine is used to update the bar information for those incompatible PCI device. - - @param PciIoDevice Input Pci device instance. Output Pci device instance with updated - Bar information. - - @retval EFI_SUCCESS Successfully updated bar information. - @retval EFI_UNSUPPORTED Given PCI device doesn't belong to incompatible PCI device list. - -**/ -EFI_STATUS -UpdatePciInfo ( - IN OUT PCI_IO_DEVICE *PciIoDevice - ) -{ - EFI_STATUS Status; - UINTN BarIndex; - UINTN BarEndIndex; - BOOLEAN SetFlag; - VOID *Configuration; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - - Configuration = NULL; - Status = EFI_SUCCESS; - - if (gEfiIncompatiblePciDeviceSupport == NULL) { - // - // It can only be supported after the Incompatible PCI Device - // Support Protocol has been installed - // - Status = gBS->LocateProtocol ( - &gEfiIncompatiblePciDeviceSupportProtocolGuid, - NULL, - (VOID **) &gEfiIncompatiblePciDeviceSupport - ); - } - if (Status == EFI_SUCCESS) { - // - // Check whether the device belongs to incompatible devices from protocol or not - // If it is , then get its special requirement in the ACPI table - // - Status = gEfiIncompatiblePciDeviceSupport->CheckDevice ( - gEfiIncompatiblePciDeviceSupport, - PciIoDevice->Pci.Hdr.VendorId, - PciIoDevice->Pci.Hdr.DeviceId, - PciIoDevice->Pci.Hdr.RevisionID, - PciIoDevice->Pci.Device.SubsystemVendorID, - PciIoDevice->Pci.Device.SubsystemID, - &Configuration - ); - - } - - if (EFI_ERROR (Status) || Configuration == NULL ) { - return EFI_UNSUPPORTED; - } - - // - // Update PCI device information from the ACPI table - // - Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; - - while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) { - - if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) { - // - // The format is not support - // - break; - } - - BarIndex = (UINTN) Ptr->AddrTranslationOffset; - BarEndIndex = BarIndex; - - // - // Update all the bars in the device - // - if (BarIndex == PCI_BAR_ALL) { - BarIndex = 0; - BarEndIndex = PCI_MAX_BAR - 1; - } - - if (BarIndex > PCI_MAX_BAR) { - Ptr++; - continue; - } - - for (; BarIndex <= BarEndIndex; BarIndex++) { - SetFlag = FALSE; - switch (Ptr->ResType) { - case ACPI_ADDRESS_SPACE_TYPE_MEM: - - // - // Make sure the bar is memory type - // - if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) { - SetFlag = TRUE; - } - break; - - case ACPI_ADDRESS_SPACE_TYPE_IO: - - // - // Make sure the bar is IO type - // - if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) { - SetFlag = TRUE; - } - break; - } - - if (SetFlag) { - - // - // Update the new alignment for the device - // - SetNewAlign (&(PciIoDevice->PciBar[BarIndex].Alignment), Ptr->AddrRangeMax); - - // - // Update the new length for the device - // - if (Ptr->AddrLen != PCI_BAR_NOCHANGE) { - PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen; - } - } - } - - Ptr++; - } - - FreePool (Configuration); - - return EFI_SUCCESS; -} - -/** - This routine will update the alignment with the new alignment. - - @param Alignment Input Old alignment. Output updated alignment. - @param NewAlignment New alignment. - -**/ -VOID -SetNewAlign ( - IN OUT UINT64 *Alignment, - IN UINT64 NewAlignment - ) -{ - UINT64 OldAlignment; - UINTN ShiftBit; - - // - // The new alignment is the same as the original, - // so skip it - // - if (NewAlignment == PCI_BAR_OLD_ALIGN) { - return ; - } - // - // Check the validity of the parameter - // - if (NewAlignment != PCI_BAR_EVEN_ALIGN && - NewAlignment != PCI_BAR_SQUAD_ALIGN && - NewAlignment != PCI_BAR_DQUAD_ALIGN ) { - *Alignment = NewAlignment; - return ; - } - - OldAlignment = (*Alignment) + 1; - ShiftBit = 0; - - // - // Get the first non-zero hex value of the length - // - while ((OldAlignment & 0x0F) == 0x00) { - OldAlignment = RShiftU64 (OldAlignment, 4); - ShiftBit += 4; - } - - // - // Adjust the alignment to even, quad or double quad boundary - // - if (NewAlignment == PCI_BAR_EVEN_ALIGN) { - if ((OldAlignment & 0x01) != 0) { - OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01); - } - } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) { - if ((OldAlignment & 0x03) != 0) { - OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03); - } - } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) { - if ((OldAlignment & 0x07) != 0) { - OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07); - } - } - - // - // Update the old value - // - NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1; - *Alignment = NewAlignment; - - return ; -} - -/** - Parse PCI IOV VF bar information and fill them into PCI device instance. - - @param PciIoDevice Pci device instance. - @param Offset Bar offset. - @param BarIndex Bar index. - - @return Next bar offset. - -**/ -UINTN -PciIovParseVfBar ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - IN UINTN BarIndex - ) -{ - UINT32 Value; - UINT32 OriginalValue; - UINT32 Mask; - EFI_STATUS Status; - - // - // Ensure it is called properly - // - ASSERT (PciIoDevice->SrIovCapabilityOffset != 0); - if (PciIoDevice->SrIovCapabilityOffset == 0) { - return 0; - } - - OriginalValue = 0; - Value = 0; - - Status = VfBarExisted ( - PciIoDevice, - Offset, - &Value, - &OriginalValue - ); - - if (EFI_ERROR (Status)) { - PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0; - PciIoDevice->VfPciBar[BarIndex].Length = 0; - PciIoDevice->VfPciBar[BarIndex].Alignment = 0; - - // - // Scan all the BARs anyway - // - PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset; - return Offset + 4; - } - - PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset; - if ((Value & 0x01) != 0) { - // - // Device I/Os. Impossible - // - ASSERT (FALSE); - return Offset + 4; - - } else { - - Mask = 0xfffffff0; - - PciIoDevice->VfPciBar[BarIndex].BaseAddress = OriginalValue & Mask; - - switch (Value & 0x07) { - - // - //memory space; anywhere in 32 bit address space - // - case 0x00: - if ((Value & 0x08) != 0) { - PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32; - } else { - PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32; - } - - PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1; - PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1; - - // - // Adjust Length - // - PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs); - // - // Adjust Alignment - // - if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) { - PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1; - } - - break; - - // - // memory space; anywhere in 64 bit address space - // - case 0x04: - if ((Value & 0x08) != 0) { - PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64; - } else { - PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64; - } - - // - // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar - // is regarded as an extension for the first bar. As a result - // the sizing will be conducted on combined 64 bit value - // Here just store the masked first 32bit value for future size - // calculation - // - PciIoDevice->VfPciBar[BarIndex].Length = Value & Mask; - PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1; - - if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) { - PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1; - } - - // - // Increment the offset to point to next DWORD - // - Offset += 4; - - Status = VfBarExisted ( - PciIoDevice, - Offset, - &Value, - &OriginalValue - ); - - if (EFI_ERROR (Status)) { - return Offset + 4; - } - - // - // Fix the length to support some spefic 64 bit BAR - // - Value |= ((UINT32) -1 << HighBitSet32 (Value)); - - // - // Calculate the size of 64bit bar - // - PciIoDevice->VfPciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32); - - PciIoDevice->VfPciBar[BarIndex].Length = PciIoDevice->VfPciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32); - PciIoDevice->VfPciBar[BarIndex].Length = (~(PciIoDevice->VfPciBar[BarIndex].Length)) + 1; - PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1; - - // - // Adjust Length - // - PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs); - // - // Adjust Alignment - // - if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) { - PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1; - } - - break; - - // - // reserved - // - default: - PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown; - PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1; - PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1; - - if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) { - PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1; - } - - break; - } - } - - // - // Check the length again so as to keep compatible with some special bars - // - if (PciIoDevice->VfPciBar[BarIndex].Length == 0) { - PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown; - PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0; - PciIoDevice->VfPciBar[BarIndex].Alignment = 0; - } - - // - // Increment number of bar - // - return Offset + 4; -} - -/** - Parse PCI bar information and fill them into PCI device instance. - - @param PciIoDevice Pci device instance. - @param Offset Bar offset. - @param BarIndex Bar index. - - @return Next bar offset. - -**/ -UINTN -PciParseBar ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - IN UINTN BarIndex - ) -{ - UINT32 Value; - UINT32 OriginalValue; - UINT32 Mask; - EFI_STATUS Status; - - OriginalValue = 0; - Value = 0; - - Status = BarExisted ( - PciIoDevice, - Offset, - &Value, - &OriginalValue - ); - - if (EFI_ERROR (Status)) { - PciIoDevice->PciBar[BarIndex].BaseAddress = 0; - PciIoDevice->PciBar[BarIndex].Length = 0; - PciIoDevice->PciBar[BarIndex].Alignment = 0; - - // - // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway - // - PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset; - return Offset + 4; - } - - PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset; - if ((Value & 0x01) != 0) { - // - // Device I/Os - // - Mask = 0xfffffffc; - - if ((Value & 0xFFFF0000) != 0) { - // - // It is a IO32 bar - // - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32; - PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1); - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - } else { - // - // It is a IO16 bar - // - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16; - PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1); - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - } - // - // Workaround. Some platforms inplement IO bar with 0 length - // Need to treat it as no-bar - // - if (PciIoDevice->PciBar[BarIndex].Length == 0) { - PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE) 0; - } - - PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE; - PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask; - - } else { - - Mask = 0xfffffff0; - - PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask; - - switch (Value & 0x07) { - - // - //memory space; anywhere in 32 bit address space - // - case 0x00: - if ((Value & 0x08) != 0) { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32; - } else { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32; - } - - PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1; - if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) { - // - // Force minimum 4KByte alignment for Virtualization technology for Directed I/O - // - PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1); - } else { - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - } - break; - - // - // memory space; anywhere in 64 bit address space - // - case 0x04: - if ((Value & 0x08) != 0) { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64; - } else { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64; - } - - // - // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar - // is regarded as an extension for the first bar. As a result - // the sizing will be conducted on combined 64 bit value - // Here just store the masked first 32bit value for future size - // calculation - // - PciIoDevice->PciBar[BarIndex].Length = Value & Mask; - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - - // - // Increment the offset to point to next DWORD - // - Offset += 4; - - Status = BarExisted ( - PciIoDevice, - Offset, - &Value, - &OriginalValue - ); - - if (EFI_ERROR (Status)) { - // - // the high 32 bit does not claim any BAR, we need to re-check the low 32 bit BAR again - // - if (PciIoDevice->PciBar[BarIndex].Length == 0) { - // - // some device implement MMIO bar with 0 length, need to treat it as no-bar - // - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown; - return Offset + 4; - } - } - - // - // Fix the length to support some spefic 64 bit BAR - // - if (Value == 0) { - DEBUG ((EFI_D_INFO, "[PciBus]BAR probing for upper 32bit of MEM64 BAR returns 0, change to 0xFFFFFFFF.\n")); - Value = (UINT32) -1; - } else { - Value |= ((UINT32)(-1) << HighBitSet32 (Value)); - } - - // - // Calculate the size of 64bit bar - // - PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32); - - PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32); - PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1; - if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) { - // - // Force minimum 4KByte alignment for Virtualization technology for Directed I/O - // - PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1); - } else { - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - } - - break; - - // - // reserved - // - default: - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown; - PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1; - if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) { - // - // Force minimum 4KByte alignment for Virtualization technology for Directed I/O - // - PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1); - } else { - PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1; - } - break; - } - } - - // - // Check the length again so as to keep compatible with some special bars - // - if (PciIoDevice->PciBar[BarIndex].Length == 0) { - PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown; - PciIoDevice->PciBar[BarIndex].BaseAddress = 0; - PciIoDevice->PciBar[BarIndex].Alignment = 0; - } - - // - // Increment number of bar - // - return Offset + 4; -} - -/** - This routine is used to initialize the bar of a PCI device. - - @param PciIoDevice Pci device instance. - - @note It can be called typically when a device is going to be rejected. - -**/ -VOID -InitializePciDevice ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Offset; - - PciIo = &(PciIoDevice->PciIo); - - // - // Put all the resource apertures - // Resource base is set to all ones so as to indicate its resource - // has not been alloacted - // - for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) { - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne); - } -} - -/** - This routine is used to initialize the bar of a PCI-PCI Bridge device. - - @param PciIoDevice PCI-PCI bridge device instance. - -**/ -VOID -InitializePpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - PciIo = &(PciIoDevice->PciIo); - - // - // Put all the resource apertures including IO16 - // Io32, pMem32, pMem64 to quiescent state - // Resource base all ones, Resource limit all zeros - // - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1C, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x1D, 1, &gAllZero); - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x20, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x22, 1, &gAllZero); - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x24, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x26, 1, &gAllZero); - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2C, 1, &gAllZero); - - // - // Don't support use io32 as for now - // - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x30, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x32, 1, &gAllZero); - - // - // Force Interrupt line to zero for cards that come up randomly - // - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero); -} - -/** - This routine is used to initialize the bar of a PCI Card Bridge device. - - @param PciIoDevice PCI Card bridge device. - -**/ -VOID -InitializeP2C ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - PciIo = &(PciIoDevice->PciIo); - - // - // Put all the resource apertures including IO16 - // Io32, pMem32, pMem64 to quiescent state( - // Resource base all ones, Resource limit all zeros - // - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1c, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x20, 1, &gAllZero); - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x24, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x28, 1, &gAllZero); - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x2c, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x30, 1, &gAllZero); - - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x34, 1, &gAllOne); - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x38, 1, &gAllZero); - - // - // Force Interrupt line to zero for cards that come up randomly - // - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x3C, 1, &gAllZero); -} - -/** - Create and initiliaze general PCI I/O device instance for - PCI device/bridge device/hotplug bridge device. - - @param PciRootBridgeIo Pointer to instance of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Pci Input Pci information block. - @param Bus Device Bus NO. - @param Device Device device NO. - @param Func Device func NO. - - @return Instance of PCI device. NULL means no instance created. - -**/ -PCI_IO_DEVICE * -CreatePciIoDevice ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ) -{ - PCI_IO_DEVICE *PciIoDevice; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - - PciIoDevice = AllocateZeroPool (sizeof (PCI_IO_DEVICE)); - if (PciIoDevice == NULL) { - return NULL; - } - - PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE; - PciIoDevice->Handle = NULL; - PciIoDevice->PciRootBridgeIo = Bridge->PciRootBridgeIo; - PciIoDevice->DevicePath = NULL; - PciIoDevice->BusNumber = Bus; - PciIoDevice->DeviceNumber = Device; - PciIoDevice->FunctionNumber = Func; - PciIoDevice->Decodes = 0; - - if (gFullEnumeration) { - PciIoDevice->Allocated = FALSE; - } else { - PciIoDevice->Allocated = TRUE; - } - - PciIoDevice->Registered = FALSE; - PciIoDevice->Attributes = 0; - PciIoDevice->Supports = 0; - PciIoDevice->BusOverride = FALSE; - PciIoDevice->AllOpRomProcessed = FALSE; - - PciIoDevice->IsPciExp = FALSE; - - CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01)); - - // - // Initialize the PCI I/O instance structure - // - InitializePciIoInstance (PciIoDevice); - InitializePciDriverOverrideInstance (PciIoDevice); - InitializePciLoadFile2 (PciIoDevice); - PciIo = &PciIoDevice->PciIo; - - // - // Create a device path for this PCI device and store it into its private data - // - CreatePciDevicePath ( - Bridge->DevicePath, - PciIoDevice - ); - - // - // Detect if PCI Express Device - // - PciIoDevice->PciExpressCapabilityOffset = 0; - Status = LocateCapabilityRegBlock ( - PciIoDevice, - EFI_PCI_CAPABILITY_ID_PCIEXP, - &PciIoDevice->PciExpressCapabilityOffset, - NULL - ); - if (!EFI_ERROR (Status)) { - PciIoDevice->IsPciExp = TRUE; - } - - if (PcdGetBool (PcdAriSupport)) { - // - // Check if the device is an ARI device. - // - Status = LocatePciExpressCapabilityRegBlock ( - PciIoDevice, - EFI_PCIE_CAPABILITY_ID_ARI, - &PciIoDevice->AriCapabilityOffset, - NULL - ); - if (!EFI_ERROR (Status)) { - // - // We need to enable ARI feature before calculate BusReservation, - // because FirstVFOffset and VFStride may change after that. - // - EFI_PCI_IO_PROTOCOL *ParentPciIo; - UINT32 Data32; - - // - // Check if its parent supports ARI forwarding. - // - ParentPciIo = &Bridge->PciIo; - ParentPciIo->Pci.Read ( - ParentPciIo, - EfiPciIoWidthUint32, - Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET, - 1, - &Data32 - ); - if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) != 0) { - // - // ARI forward support in bridge, so enable it. - // - ParentPciIo->Pci.Read ( - ParentPciIo, - EfiPciIoWidthUint32, - Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET, - 1, - &Data32 - ); - if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING) == 0) { - Data32 |= EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING; - ParentPciIo->Pci.Write ( - ParentPciIo, - EfiPciIoWidthUint32, - Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET, - 1, - &Data32 - ); - DEBUG (( - EFI_D_INFO, - " ARI: forwarding enabled for PPB[%02x:%02x:%02x]\n", - Bridge->BusNumber, - Bridge->DeviceNumber, - Bridge->FunctionNumber - )); - } - } - - DEBUG ((EFI_D_INFO, " ARI: CapOffset = 0x%x\n", PciIoDevice->AriCapabilityOffset)); - } - } - - // - // Initialization for SR-IOV - // - - if (PcdGetBool (PcdSrIovSupport)) { - Status = LocatePciExpressCapabilityRegBlock ( - PciIoDevice, - EFI_PCIE_CAPABILITY_ID_SRIOV, - &PciIoDevice->SrIovCapabilityOffset, - NULL - ); - if (!EFI_ERROR (Status)) { - UINT32 SupportedPageSize; - UINT16 VFStride; - UINT16 FirstVFOffset; - UINT16 Data16; - UINT32 PFRid; - UINT32 LastVF; - - // - // If the SR-IOV device is an ARI device, then Set ARI Capable Hierarchy for the device. - // - if (PcdGetBool (PcdAriSupport) && PciIoDevice->AriCapabilityOffset != 0) { - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL, - 1, - &Data16 - ); - Data16 |= EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL, - 1, - &Data16 - ); - } - - // - // Calculate SystemPageSize - // - - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint32, - PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE, - 1, - &SupportedPageSize - ); - PciIoDevice->SystemPageSize = (PcdGet32 (PcdSrIovSystemPageSize) & SupportedPageSize); - ASSERT (PciIoDevice->SystemPageSize != 0); - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE, - 1, - &PciIoDevice->SystemPageSize - ); - // - // Adjust SystemPageSize for Alignment usage later - // - PciIoDevice->SystemPageSize <<= 12; - - // - // Calculate BusReservation for PCI IOV - // - - // - // Read First FirstVFOffset, InitialVFs, and VFStride - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF, - 1, - &FirstVFOffset - ); - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS, - 1, - &PciIoDevice->InitialVFs - ); - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE, - 1, - &VFStride - ); - // - // Calculate LastVF - // - PFRid = EFI_PCI_RID(Bus, Device, Func); - LastVF = PFRid + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride; - - // - // Calculate ReservedBusNum for this PF - // - PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1); - - DEBUG (( - EFI_D_INFO, - " SR-IOV: SupportedPageSize = 0x%x; SystemPageSize = 0x%x; FirstVFOffset = 0x%x;\n", - SupportedPageSize, PciIoDevice->SystemPageSize >> 12, FirstVFOffset - )); - DEBUG (( - EFI_D_INFO, - " InitialVFs = 0x%x; ReservedBusNum = 0x%x; CapOffset = 0x%x\n", - PciIoDevice->InitialVFs, PciIoDevice->ReservedBusNum, PciIoDevice->SrIovCapabilityOffset - )); - } - } - - if (PcdGetBool (PcdMrIovSupport)) { - Status = LocatePciExpressCapabilityRegBlock ( - PciIoDevice, - EFI_PCIE_CAPABILITY_ID_MRIOV, - &PciIoDevice->MrIovCapabilityOffset, - NULL - ); - if (!EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, " MR-IOV: CapOffset = 0x%x\n", PciIoDevice->MrIovCapabilityOffset)); - } - } - - // - // Initialize the reserved resource list - // - InitializeListHead (&PciIoDevice->ReservedResourceList); - - // - // Initialize the driver list - // - InitializeListHead (&PciIoDevice->OptionRomDriverList); - - // - // Initialize the child list - // - InitializeListHead (&PciIoDevice->ChildList); - - return PciIoDevice; -} - -/** - This routine is used to enumerate entire pci bus system - in a given platform. - - It is only called on the second start on the same Root Bridge. - - @param Controller Parent bridge handler. - - @retval EFI_SUCCESS PCI enumeration finished successfully. - @retval other Some error occurred when enumerating the pci bus system. - -**/ -EFI_STATUS -PciEnumeratorLight ( - IN EFI_HANDLE Controller - ) -{ - - EFI_STATUS Status; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - PCI_IO_DEVICE *RootBridgeDev; - UINT16 MinBus; - UINT16 MaxBus; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; - - MinBus = 0; - MaxBus = PCI_MAX_BUS; - Descriptors = NULL; - - // - // If this root bridge has been already enumerated, then return successfully - // - if (GetRootBridgeByHandle (Controller) != NULL) { - return EFI_SUCCESS; - } - - // - // Open pci root bridge io protocol - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { - return Status; - } - - Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors); - - if (EFI_ERROR (Status)) { - return Status; - } - - while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) { - - // - // Create a device node for root bridge device with a NULL host bridge controller handle - // - RootBridgeDev = CreateRootBridge (Controller); - - if (RootBridgeDev == NULL) { - Descriptors++; - continue; - } - - // - // Record the root bridgeio protocol - // - RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo; - - Status = PciPciDeviceInfoCollector ( - RootBridgeDev, - (UINT8) MinBus - ); - - if (!EFI_ERROR (Status)) { - - // - // Remove those PCI devices which are rejected when full enumeration - // - RemoveRejectedPciDevices (RootBridgeDev->Handle, RootBridgeDev); - - // - // Process option rom light - // - ProcessOptionRomLight (RootBridgeDev); - - // - // Determine attributes for all devices under this root bridge - // - DetermineDeviceAttribute (RootBridgeDev); - - // - // If successfully, insert the node into device pool - // - InsertRootBridge (RootBridgeDev); - } else { - - // - // If unsuccessly, destroy the entire node - // - DestroyRootBridge (RootBridgeDev); - } - - Descriptors++; - } - - return EFI_SUCCESS; -} - -/** - Get bus range from PCI resource descriptor list. - - @param Descriptors A pointer to the address space descriptor. - @param MinBus The min bus returned. - @param MaxBus The max bus returned. - @param BusRange The bus range returned. - - @retval EFI_SUCCESS Successfully got bus range. - @retval EFI_NOT_FOUND Can not find the specific bus. - -**/ -EFI_STATUS -PciGetBusRange ( - IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, - OUT UINT16 *MinBus, - OUT UINT16 *MaxBus, - OUT UINT16 *BusRange - ) -{ - while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) { - if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) { - if (MinBus != NULL) { - *MinBus = (UINT16) (*Descriptors)->AddrRangeMin; - } - - if (MaxBus != NULL) { - *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax; - } - - if (BusRange != NULL) { - *BusRange = (UINT16) (*Descriptors)->AddrLen; - } - - return EFI_SUCCESS; - } - - (*Descriptors)++; - } - - return EFI_NOT_FOUND; -} - -/** - This routine can be used to start the root bridge. - - @param RootBridgeDev Pci device instance. - - @retval EFI_SUCCESS This device started. - @retval other Failed to get PCI Root Bridge I/O protocol. - -**/ -EFI_STATUS -StartManagingRootBridge ( - IN PCI_IO_DEVICE *RootBridgeDev - ) -{ - EFI_HANDLE RootBridgeHandle; - EFI_STATUS Status; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - // - // Get the root bridge handle - // - RootBridgeHandle = RootBridgeDev->Handle; - PciRootBridgeIo = NULL; - - // - // Get the pci root bridge io protocol - // - Status = gBS->OpenProtocol ( - RootBridgeHandle, - &gEfiPciRootBridgeIoProtocolGuid, - (VOID **) &PciRootBridgeIo, - gPciBusDriverBinding.DriverBindingHandle, - RootBridgeHandle, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { - return Status; - } - - // - // Store the PciRootBridgeIo protocol into root bridge private data - // - RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo; - - return EFI_SUCCESS; - -} - -/** - This routine can be used to check whether a PCI device should be rejected when light enumeration. - - @param PciIoDevice Pci device instance. - - @retval TRUE This device should be rejected. - @retval FALSE This device shouldn't be rejected. - -**/ -BOOLEAN -IsPciDeviceRejected ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - EFI_STATUS Status; - UINT32 TestValue; - UINT32 OldValue; - UINT32 Mask; - UINT8 BarOffset; - - // - // PPB should be skip! - // - if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { - return FALSE; - } - - if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - // - // Only test base registers for P2C - // - for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) { - - Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC; - Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); - if (EFI_ERROR (Status)) { - continue; - } - - TestValue = TestValue & Mask; - if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { - // - // The bar isn't programed, so it should be rejected - // - return TRUE; - } - } - - return FALSE; - } - - for (BarOffset = 0x14; BarOffset <= 0x24; BarOffset += sizeof (UINT32)) { - // - // Test PCI devices - // - Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); - if (EFI_ERROR (Status)) { - continue; - } - - if ((TestValue & 0x01) != 0) { - - // - // IO Bar - // - Mask = 0xFFFFFFFC; - TestValue = TestValue & Mask; - if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { - return TRUE; - } - - } else { - - // - // Mem Bar - // - Mask = 0xFFFFFFF0; - TestValue = TestValue & Mask; - - if ((TestValue & 0x07) == 0x04) { - - // - // Mem64 or PMem64 - // - BarOffset += sizeof (UINT32); - if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { - - // - // Test its high 32-Bit BAR - // - Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue); - if (TestValue == OldValue) { - return TRUE; - } - } - - } else { - - // - // Mem32 or PMem32 - // - if ((TestValue != 0) && (TestValue == (OldValue & Mask))) { - return TRUE; - } - } - } - } - - return FALSE; -} - -/** - Reset all bus number from specific bridge. - - @param Bridge Parent specific bridge. - @param StartBusNumber Start bus number. - -**/ -VOID -ResetAllPpbBusNumber ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber - ) -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT32 Register; - UINT8 Func; - UINT64 Address; - UINT8 SecondaryBus; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether a pci device is present - // - Status = PciDevicePresent ( - PciRootBridgeIo, - &Pci, - StartBusNumber, - Device, - Func - ); - - if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) { - - Register = 0; - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18); - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - EfiPciWidthUint32, - Address, - 1, - &Register - ); - SecondaryBus = (UINT8)(Register >> 8); - - if (SecondaryBus != 0) { - ResetAllPpbBusNumber (Bridge, SecondaryBus); - } - - // - // Reset register 18h, 19h, 1Ah on PCI Bridge - // - Register &= 0xFF000000; - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint32, - Address, - 1, - &Register - ); - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - // - // Skip sub functions, this is not a multi function device - // - Func = PCI_MAX_FUNC; - } - } - } -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h deleted file mode 100644 index 42306e9a47..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h +++ /dev/null @@ -1,476 +0,0 @@ -/** @file - PCI emumeration support functions declaration for PCI Bus module. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_ENUMERATOR_SUPPORT_H_ -#define _EFI_PCI_ENUMERATOR_SUPPORT_H_ - -/** - This routine is used to check whether the pci device is present. - - @param PciRootBridgeIo Pointer to instance of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Pci Output buffer for PCI device configuration space. - @param Bus PCI bus NO. - @param Device PCI device NO. - @param Func PCI Func NO. - - @retval EFI_NOT_FOUND PCI device not present. - @retval EFI_SUCCESS PCI device is found. - -**/ -EFI_STATUS -PciDevicePresent ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, - OUT PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ); - -/** - Collect all the resource information under this root bridge. - - A database that records all the information about pci device subject to this - root bridge will then be created. - - @param Bridge Parent bridge instance. - @param StartBusNumber Bus number of begining. - - @retval EFI_SUCCESS PCI device is found. - @retval other Some error occurred when reading PCI bridge information. - -**/ -EFI_STATUS -PciPciDeviceInfoCollector ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber - ); - -/** - Seach required device and create PCI device instance. - - @param Bridge Parent bridge instance. - @param Pci Input PCI device information block. - @param Bus PCI bus NO. - @param Device PCI device NO. - @param Func PCI func NO. - @param PciDevice Output of searched PCI device instance. - - @retval EFI_SUCCESS Successfully created PCI device instance. - @retval EFI_OUT_OF_RESOURCES Cannot get PCI device information. - -**/ -EFI_STATUS -PciSearchDevice ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func, - OUT PCI_IO_DEVICE **PciDevice - ); - -/** - Create PCI device instance for PCI device. - - @param Bridge Parent bridge instance. - @param Pci Input PCI device information block. - @param Bus PCI device Bus NO. - @param Device PCI device Device NO. - @param Func PCI device's func NO. - - @return Created PCI device instance. - -**/ -PCI_IO_DEVICE * -GatherDeviceInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ); - -/** - Create PCI device instance for PCI-PCI bridge. - - @param Bridge Parent bridge instance. - @param Pci Input PCI device information block. - @param Bus PCI device Bus NO. - @param Device PCI device Device NO. - @param Func PCI device's func NO. - - @return Created PCI device instance. - -**/ -PCI_IO_DEVICE * -GatherPpbInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ); - -/** - Create PCI device instance for PCI Card bridge device. - - @param Bridge Parent bridge instance. - @param Pci Input PCI device information block. - @param Bus PCI device Bus NO. - @param Device PCI device Device NO. - @param Func PCI device's func NO. - - @return Created PCI device instance. - -**/ -PCI_IO_DEVICE * -GatherP2CInfo ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ); - -/** - Create device path for pci deivce. - - @param ParentDevicePath Parent bridge's path. - @param PciIoDevice Pci device instance. - - @return device path protocol instance for specific pci device. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -CreatePciDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Check whether the PCI IOV VF bar is existed or not. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE. - @param Offset The offset. - @param BarLengthValue The bar length value returned. - @param OriginalBarValue The original bar value returned. - - @retval EFI_NOT_FOUND The bar doesn't exist. - @retval EFI_SUCCESS The bar exist. - -**/ -EFI_STATUS -VfBarExisted ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - OUT UINT32 *BarLengthValue, - OUT UINT32 *OriginalBarValue - ); - -/** - Check whether the bar is existed or not. - - @param PciIoDevice A pointer to the PCI_IO_DEVICE. - @param Offset The offset. - @param BarLengthValue The bar length value returned. - @param OriginalBarValue The original bar value returned. - - @retval EFI_NOT_FOUND The bar doesn't exist. - @retval EFI_SUCCESS The bar exist. - -**/ -EFI_STATUS -BarExisted ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - OUT UINT32 *BarLengthValue, - OUT UINT32 *OriginalBarValue - ); - -/** - Test whether the device can support given attributes. - - @param PciIoDevice Pci device instance. - @param Command Input command register value, and - returned supported register value. - @param BridgeControl Inout bridge control value for PPB or P2C, and - returned supported bridge control value. - @param OldCommand Returned and stored old command register offset. - @param OldBridgeControl Returned and stored old Bridge control value for PPB or P2C. - -**/ -VOID -PciTestSupportedAttribute ( - IN PCI_IO_DEVICE *PciIoDevice, - IN OUT UINT16 *Command, - IN OUT UINT16 *BridgeControl, - OUT UINT16 *OldCommand, - OUT UINT16 *OldBridgeControl - ); - -/** - Set the supported or current attributes of a PCI device. - - @param PciIoDevice Structure pointer for PCI device. - @param Command Command register value. - @param BridgeControl Bridge control value for PPB or P2C. - @param Option Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES. - -**/ -VOID -PciSetDeviceAttribute ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT16 Command, - IN UINT16 BridgeControl, - IN UINTN Option - ); - -/** - Determine if the device can support Fast Back to Back attribute. - - @param PciIoDevice Pci device instance. - @param StatusIndex Status register value. - - @retval EFI_SUCCESS This device support Fast Back to Back attribute. - @retval EFI_UNSUPPORTED This device doesn't support Fast Back to Back attribute. - -**/ -EFI_STATUS -GetFastBackToBackSupport ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 StatusIndex - ); - -/** - Determine the related attributes of all devices under a Root Bridge. - - @param PciIoDevice PCI device instance. - -**/ -EFI_STATUS -DetermineDeviceAttribute ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - This routine is used to update the bar information for those incompatible PCI device. - - @param PciIoDevice Input Pci device instance. Output Pci device instance with updated - Bar information. - - @retval EFI_SUCCESS Successfully updated bar information. - @retval EFI_UNSUPPORTED Given PCI device doesn't belong to incompatible PCI device list. - -**/ -EFI_STATUS -UpdatePciInfo ( - IN OUT PCI_IO_DEVICE *PciIoDevice - ); - -/** - This routine will update the alignment with the new alignment. - - @param Alignment Input Old alignment. Output updated alignment. - @param NewAlignment New alignment. - -**/ -VOID -SetNewAlign ( - IN OUT UINT64 *Alignment, - IN UINT64 NewAlignment - ); - -/** - Parse PCI bar information and fill them into PCI device instance. - - @param PciIoDevice Pci device instance. - @param Offset Bar offset. - @param BarIndex Bar index. - - @return Next bar offset. - -**/ -UINTN -PciParseBar ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - IN UINTN BarIndex - ); - -/** - Parse PCI IOV VF bar information and fill them into PCI device instance. - - @param PciIoDevice Pci device instance. - @param Offset Bar offset. - @param BarIndex Bar index. - - @return Next bar offset. - -**/ -UINTN -PciIovParseVfBar ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINTN Offset, - IN UINTN BarIndex - ); - -/** - This routine is used to initialize the bar of a PCI device. - - @param PciIoDevice Pci device instance. - - @note It can be called typically when a device is going to be rejected. - -**/ -VOID -InitializePciDevice ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - This routine is used to initialize the bar of a PCI-PCI Bridge device. - - @param PciIoDevice PCI-PCI bridge device instance. - -**/ -VOID -InitializePpb ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - This routine is used to initialize the bar of a PCI Card Bridge device. - - @param PciIoDevice PCI Card bridge device. - -**/ -VOID -InitializeP2C ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Create and initiliaze general PCI I/O device instance for - PCI device/bridge device/hotplug bridge device. - - @param Bridge Parent bridge instance. - @param Pci Input Pci information block. - @param Bus Device Bus NO. - @param Device Device device NO. - @param Func Device func NO. - - @return Instance of PCI device. NULL means no instance created. - -**/ -PCI_IO_DEVICE * -CreatePciIoDevice ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_TYPE00 *Pci, - IN UINT8 Bus, - IN UINT8 Device, - IN UINT8 Func - ); - -/** - This routine is used to enumerate entire pci bus system - in a given platform. - - It is only called on the second start on the same Root Bridge. - - @param Controller Parent bridge handler. - - @retval EFI_SUCCESS PCI enumeration finished successfully. - @retval other Some error occurred when enumerating the pci bus system. - -**/ -EFI_STATUS -PciEnumeratorLight ( - IN EFI_HANDLE Controller - ); - -/** - Get bus range from PCI resource descriptor list. - - @param Descriptors A pointer to the address space descriptor. - @param MinBus The min bus returned. - @param MaxBus The max bus returned. - @param BusRange The bus range returned. - - @retval EFI_SUCCESS Successfully got bus range. - @retval EFI_NOT_FOUND Can not find the specific bus. - -**/ -EFI_STATUS -PciGetBusRange ( - IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR **Descriptors, - OUT UINT16 *MinBus, - OUT UINT16 *MaxBus, - OUT UINT16 *BusRange - ); - -/** - This routine can be used to start the root bridge. - - @param RootBridgeDev Pci device instance. - - @retval EFI_SUCCESS This device started. - @retval other Failed to get PCI Root Bridge I/O protocol. - -**/ -EFI_STATUS -StartManagingRootBridge ( - IN PCI_IO_DEVICE *RootBridgeDev - ); - -/** - This routine can be used to check whether a PCI device should be rejected when light enumeration. - - @param PciIoDevice Pci device instance. - - @retval TRUE This device should be rejected. - @retval FALSE This device shouldn't be rejected. - -**/ -BOOLEAN -IsPciDeviceRejected ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Reset all bus number from specific bridge. - - @param Bridge Parent specific bridge. - @param StartBusNumber Start bus number. - -**/ -VOID -ResetAllPpbBusNumber ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber - ); - -/** - Dump the PPB padding resource information. - - @param PciIoDevice PCI IO instance. - @param ResourceType The desired resource type to dump. - PciBarTypeUnknown means to dump all types of resources. -**/ -VOID -DumpPpbPaddingResource ( - IN PCI_IO_DEVICE *PciIoDevice, - IN PCI_BAR_TYPE ResourceType - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c deleted file mode 100644 index 257874b8b0..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.c +++ /dev/null @@ -1,394 +0,0 @@ -/** @file - PCI Hot Plug support functions implementation for PCI Bus module.. - -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit = NULL; -EFI_HPC_LOCATION *gPciRootHpcPool = NULL; -UINTN gPciRootHpcCount = 0; -ROOT_HPC_DATA *gPciRootHpcData = NULL; - - -/** - Event notification function to set Hot Plug controller status. - - @param Event The event that invoke this function. - @param Context The calling context, pointer to ROOT_HPC_DATA. - -**/ -VOID -EFIAPI -PciHPCInitialized ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - ROOT_HPC_DATA *HpcData; - - HpcData = (ROOT_HPC_DATA *) Context; - HpcData->Initialized = TRUE; -} - -/** - Compare two device pathes to check if they are exactly same. - - @param DevicePath1 A pointer to the first device path data structure. - @param DevicePath2 A pointer to the second device path data structure. - - @retval TRUE They are same. - @retval FALSE They are not same. - -**/ -BOOLEAN -EfiCompareDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 - ) -{ - UINTN Size1; - UINTN Size2; - - Size1 = GetDevicePathSize (DevicePath1); - Size2 = GetDevicePathSize (DevicePath2); - - if (Size1 != Size2) { - return FALSE; - } - - if (CompareMem (DevicePath1, DevicePath2, Size1) != 0) { - return FALSE; - } - - return TRUE; -} - -/** - Check hot plug support and initialize root hot plug private data. - - If Hot Plug is supported by the platform, call PCI Hot Plug Init protocol - to get PCI Hot Plug controller's information and constructor the root hot plug - private data structure. - - @retval EFI_SUCCESS They are same. - @retval EFI_UNSUPPORTED No PCI Hot Plug controler on the platform. - @retval EFI_OUT_OF_RESOURCES No memory to constructor root hot plug private - data structure. - -**/ -EFI_STATUS -InitializeHotPlugSupport ( - VOID - ) -{ - EFI_STATUS Status; - EFI_HPC_LOCATION *HpcList; - UINTN HpcCount; - - // - // Locate the PciHotPlugInit Protocol - // If it doesn't exist, that means there is no - // hot plug controller supported on the platform - // the PCI Bus driver is running on. HotPlug Support - // is an optional feature, so absence of the protocol - // won't incur the penalty. - // - Status = gBS->LocateProtocol ( - &gEfiPciHotPlugInitProtocolGuid, - NULL, - (VOID **) &gPciHotPlugInit - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = gPciHotPlugInit->GetRootHpcList ( - gPciHotPlugInit, - &HpcCount, - &HpcList - ); - - if (!EFI_ERROR (Status)) { - - gPciRootHpcPool = HpcList; - gPciRootHpcCount = HpcCount; - gPciRootHpcData = AllocateZeroPool (sizeof (ROOT_HPC_DATA) * gPciRootHpcCount); - if (gPciRootHpcData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - return EFI_SUCCESS; -} - -/** - Test whether device path is for root pci hot plug bus. - - @param HpbDevicePath A pointer to device path data structure to be tested. - @param HpIndex If HpIndex is not NULL, return the index of root hot - plug in global array when TRUE is retuned. - - @retval TRUE The device path is for root pci hot plug bus. - @retval FALSE The device path is not for root pci hot plug bus. - -**/ -BOOLEAN -IsRootPciHotPlugBus ( - IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath, - OUT UINTN *HpIndex OPTIONAL - ) -{ - UINTN Index; - - for (Index = 0; Index < gPciRootHpcCount; Index++) { - - if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpbDevicePath, HpbDevicePath)) { - - if (HpIndex != NULL) { - *HpIndex = Index; - } - - return TRUE; - } - } - - return FALSE; -} - -/** - Test whether device path is for root pci hot plug controller. - - @param HpcDevicePath A pointer to device path data structure to be tested. - @param HpIndex If HpIndex is not NULL, return the index of root hot - plug in global array when TRUE is retuned. - - @retval TRUE The device path is for root pci hot plug controller. - @retval FALSE The device path is not for root pci hot plug controller. - -**/ -BOOLEAN -IsRootPciHotPlugController ( - IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, - OUT UINTN *HpIndex - ) -{ - UINTN Index; - - for (Index = 0; Index < gPciRootHpcCount; Index++) { - - if (EfiCompareDevicePath (gPciRootHpcPool[Index].HpcDevicePath, HpcDevicePath)) { - - if (HpIndex != NULL) { - *HpIndex = Index; - } - - return TRUE; - } - } - - return FALSE; -} - -/** - Creating event object for PCI Hot Plug controller. - - @param HpIndex Index of hot plug device in global array. - @param Event The retuned event that invoke this function. - - @return Status of create event invoken. - -**/ -EFI_STATUS -CreateEventForHpc ( - IN UINTN HpIndex, - OUT EFI_EVENT *Event - ) -{ - EFI_STATUS Status; - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - PciHPCInitialized, - gPciRootHpcData + HpIndex, - &((gPciRootHpcData + HpIndex)->Event) - ); - - if (!EFI_ERROR (Status)) { - *Event = (gPciRootHpcData + HpIndex)->Event; - } - - return Status; -} - -/** - Wait for all root PCI Hot Plug controller finished initializing. - - @param TimeoutInMicroSeconds Microseconds to wait for all root HPCs' initialization. - - @retval EFI_SUCCESS All HPCs initialization finished. - @retval EFI_TIMEOUT Not ALL HPCs initialization finished in Microseconds. - -**/ -EFI_STATUS -AllRootHPCInitialized ( - IN UINTN TimeoutInMicroSeconds - ) -{ - UINT32 Delay; - UINTN Index; - - Delay = (UINT32) ((TimeoutInMicroSeconds / 30) + 1); - - do { - for (Index = 0; Index < gPciRootHpcCount; Index++) { - - if (gPciRootHpcData[Index].Found && !gPciRootHpcData[Index].Initialized) { - break; - } - } - - if (Index == gPciRootHpcCount) { - return EFI_SUCCESS; - } - - // - // Stall for 30 microseconds.. - // - gBS->Stall (30); - - Delay--; - - } while (Delay > 0); - - return EFI_TIMEOUT; -} - -/** - Check whether PCI-PCI bridge has PCI Hot Plug capability register block. - - @param PciIoDevice A Pointer to the PCI-PCI bridge. - - @retval TRUE PCI device is HPC. - @retval FALSE PCI device is not HPC. - -**/ -BOOLEAN -IsSHPC ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - - EFI_STATUS Status; - UINT8 Offset; - - if (PciIoDevice == NULL) { - return FALSE; - } - - Offset = 0; - Status = LocateCapabilityRegBlock ( - PciIoDevice, - EFI_PCI_CAPABILITY_ID_HOTPLUG, - &Offset, - NULL - ); - - // - // If the PCI-PCI bridge has the hot plug controller build-in, - // then return TRUE; - // - if (!EFI_ERROR (Status)) { - return TRUE; - } - - return FALSE; -} - -/** - Get resource padding if the specified PCI bridge is a hot plug bus. - - @param PciIoDevice PCI bridge instance. - -**/ -VOID -GetResourcePaddingForHpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - EFI_STATUS Status; - EFI_HPC_STATE State; - UINT64 PciAddress; - EFI_HPC_PADDING_ATTRIBUTES Attributes; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; - - if (IsPciHotPlugBus (PciIoDevice)) { - // - // If PCI-PCI bridge device is PCI Hot Plug bus. - // - PciAddress = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0); - Status = gPciHotPlugInit->GetResourcePadding ( - gPciHotPlugInit, - PciIoDevice->DevicePath, - PciAddress, - &State, - (VOID **) &Descriptors, - &Attributes - ); - - if (EFI_ERROR (Status)) { - return; - } - - if ((State & EFI_HPC_STATE_ENABLED) != 0 && (State & EFI_HPC_STATE_INITIALIZED) != 0) { - PciIoDevice->ResourcePaddingDescriptors = Descriptors; - PciIoDevice->PaddingAttributes = Attributes; - } - - return; - } -} - -/** - Test whether PCI device is hot plug bus. - - @param PciIoDevice PCI device instance. - - @retval TRUE PCI device is a hot plug bus. - @retval FALSE PCI device is not a hot plug bus. - -**/ -BOOLEAN -IsPciHotPlugBus ( - PCI_IO_DEVICE *PciIoDevice - ) -{ - if (IsSHPC (PciIoDevice)) { - // - // If the PPB has the hot plug controller build-in, - // then return TRUE; - // - return TRUE; - } - - // - // Otherwise, see if it is a Root HPC - // - if(IsRootPciHotPlugBus (PciIoDevice->DevicePath, NULL)) { - return TRUE; - } - - return FALSE; -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h deleted file mode 100644 index 1fb9ba9720..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciHotPlugSupport.h +++ /dev/null @@ -1,190 +0,0 @@ -/** @file - PCI Hot Plug support functions declaration for PCI Bus module. - -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_HOT_PLUG_SUPPORT_H_ -#define _EFI_PCI_HOT_PLUG_SUPPORT_H_ - -// -// stall 1 second, its unit is 100ns -// -#define STALL_1_SECOND 1000000 - -// -// PCI Hot Plug controller private data -// -typedef struct { - EFI_EVENT Event; - BOOLEAN Found; - BOOLEAN Initialized; - VOID *Padding; -} ROOT_HPC_DATA; - -// -// Reference of some global variabes -// -extern EFI_PCI_HOT_PLUG_INIT_PROTOCOL *gPciHotPlugInit; -extern EFI_HPC_LOCATION *gPciRootHpcPool; -extern ROOT_HPC_DATA *gPciRootHpcData; - -/** - Event notification function to set Hot Plug controller status. - - @param Event The event that invoke this function. - @param Context The calling context, pointer to ROOT_HPC_DATA. - -**/ -VOID -EFIAPI -PciHPCInitialized ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Compare two device pathes to check if they are exactly same. - - @param DevicePath1 A pointer to the first device path data structure. - @param DevicePath2 A pointer to the second device path data structure. - - @retval TRUE They are same. - @retval FALSE They are not same. - -**/ -BOOLEAN -EfiCompareDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 - ); - -/** - Check hot plug support and initialize root hot plug private data. - - If Hot Plug is supported by the platform, call PCI Hot Plug Init protocol - to get PCI Hot Plug controller's information and constructor the root hot plug - private data structure. - - @retval EFI_SUCCESS They are same. - @retval EFI_UNSUPPORTED No PCI Hot Plug controler on the platform. - @retval EFI_OUT_OF_RESOURCES No memory to constructor root hot plug private - data structure. - -**/ -EFI_STATUS -InitializeHotPlugSupport ( - VOID - ); - -/** - Test whether PCI device is hot plug bus. - - @param PciIoDevice PCI device instance. - - @retval TRUE PCI device is a hot plug bus. - @retval FALSE PCI device is not a hot plug bus. - -**/ -BOOLEAN -IsPciHotPlugBus ( - PCI_IO_DEVICE *PciIoDevice - ); - -/** - Test whether device path is for root pci hot plug bus. - - @param HpbDevicePath A pointer to device path data structure to be tested. - @param HpIndex If HpIndex is not NULL, return the index of root hot - plug in global array when TRUE is retuned. - - @retval TRUE The device path is for root pci hot plug bus. - @retval FALSE The device path is not for root pci hot plug bus. - -**/ -BOOLEAN -IsRootPciHotPlugBus ( - IN EFI_DEVICE_PATH_PROTOCOL *HpbDevicePath, - OUT UINTN *HpIndex OPTIONAL - ); - -/** - Test whether device path is for root pci hot plug controller. - - @param HpcDevicePath A pointer to device path data structure to be tested. - @param HpIndex If HpIndex is not NULL, return the index of root hot - plug in global array when TRUE is retuned. - - @retval TRUE The device path is for root pci hot plug controller. - @retval FALSE The device path is not for root pci hot plug controller. - -**/ -BOOLEAN -IsRootPciHotPlugController ( - IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, - OUT UINTN *HpIndex - ); - -/** - Creating event object for PCI Hot Plug controller. - - @param HpIndex Index of hot plug device in global array. - @param Event The retuned event that invoke this function. - - @return Status of create event invoken. - -**/ -EFI_STATUS -CreateEventForHpc ( - IN UINTN HpIndex, - OUT EFI_EVENT *Event - ); - -/** - Wait for all root PCI Hot Plug controller finished initializing. - - @param TimeoutInMicroSeconds Microseconds to wait for all root HPCs' initialization. - - @retval EFI_SUCCESS All HPCs initialization finished. - @retval EFI_TIMEOUT Not ALL HPCs initialization finished in Microseconds. - -**/ -EFI_STATUS -AllRootHPCInitialized ( - IN UINTN TimeoutInMicroSeconds - ); - -/** - Check whether PCI-PCI bridge has PCI Hot Plug capability register block. - - @param PciIoDevice A Pointer to the PCI-PCI bridge. - - @retval TRUE PCI device is HPC. - @retval FALSE PCI device is not HPC. - -**/ -BOOLEAN -IsSHPC ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Get resource padding if the specified PCI bridge is a hot plug bus. - - @param PciIoDevice PCI bridge instance. - -**/ -VOID -GetResourcePaddingForHpb ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c deleted file mode 100644 index 416063268f..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.c +++ /dev/null @@ -1,2043 +0,0 @@ -/** @file - EFI PCI IO protocol functions implementation for PCI Bus module. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -// -// Pci Io Protocol Interface -// -EFI_PCI_IO_PROTOCOL mPciIoInterface = { - PciIoPollMem, - PciIoPollIo, - { - PciIoMemRead, - PciIoMemWrite - }, - { - PciIoIoRead, - PciIoIoWrite - }, - { - PciIoConfigRead, - PciIoConfigWrite - }, - PciIoCopyMem, - PciIoMap, - PciIoUnmap, - PciIoAllocateBuffer, - PciIoFreeBuffer, - PciIoFlush, - PciIoGetLocation, - PciIoAttributes, - PciIoGetBarAttributes, - PciIoSetBarAttributes, - 0, - NULL -}; - -/** - Initializes a PCI I/O Instance. - - @param PciIoDevice Pci device instance. - -**/ -VOID -InitializePciIoInstance ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - CopyMem (&PciIoDevice->PciIo, &mPciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL)); -} - -/** - Verifies access to a PCI Base Address Register (BAR). - - @param PciIoDevice Pci device instance. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Type Operation type could be memory or I/O. - @param Width Signifies the width of the memory or I/O operations. - @param Count The number of memory or I/O operations to perform. - @param Offset The offset within the PCI configuration space for the PCI controller. - - @retval EFI_INVALID_PARAMETER Invalid Width/BarIndex or Bar type. - @retval EFI_SUCCESS Successfully verified. - -**/ -EFI_STATUS -PciIoVerifyBarAccess ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 BarIndex, - IN PCI_BAR_TYPE Type, - IN IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN IN UINTN Count, - IN UINT64 *Offset - ) -{ - if ((UINT32)Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) { - return EFI_SUCCESS; - } - - // - // BarIndex 0-5 is legal - // - if (BarIndex >= PCI_MAX_BAR) { - return EFI_INVALID_PARAMETER; - } - - if (!CheckBarType (PciIoDevice, BarIndex, Type)) { - return EFI_INVALID_PARAMETER; - } - - // - // If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX - // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX - // - if (Width >= EfiPciIoWidthFifoUint8 && Width <= EfiPciIoWidthFifoUint64) { - Count = 1; - } - - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03); - - if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) { - return EFI_INVALID_PARAMETER; - } - - *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress; - - return EFI_SUCCESS; -} - -/** - Verifies access to a PCI Configuration Header. - - @param PciIoDevice Pci device instance. - @param Width Signifies the width of the memory or I/O operations. - @param Count The number of memory or I/O operations to perform. - @param Offset The offset within the PCI configuration space for the PCI controller. - - @retval EFI_INVALID_PARAMETER Invalid Width - @retval EFI_UNSUPPORTED Offset overflowed. - @retval EFI_SUCCESS Successfully verified. - -**/ -EFI_STATUS -PciIoVerifyConfigAccess ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINTN Count, - IN UINT64 *Offset - ) -{ - UINT64 ExtendOffset; - - if ((UINT32)Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - // - // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX - // - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & 0x03); - - if (PciIoDevice->IsPciExp) { - if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) { - return EFI_UNSUPPORTED; - } - - ExtendOffset = LShiftU64 (*Offset, 32); - *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0); - *Offset = (*Offset) | ExtendOffset; - - } else { - if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) { - return EFI_UNSUPPORTED; - } - - *Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset); - } - - return EFI_SUCCESS; -} - -/** - Reads from the memory space of a PCI controller. Returns either when the polling exit criteria is - satisfied or after a defined duration. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory operation to perform. - @param Offset The offset within the selected BAR to start the memory operation. - @param Mask Mask used for the polling criteria. - @param Value The comparison value used for the polling exit criteria. - @param Delay The number of 100 ns units to poll. - @param Result Pointer to the last value read from the memory location. - - @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED Offset is not valid for the BarIndex of this PCI controller. - @retval EFI_TIMEOUT Delay expired before a match occurred. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoPollMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((UINT32)Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - if (Width > EfiPciIoWidthUint64) { - return EFI_INVALID_PARAMETER; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) { - Status = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result); - if (EFI_ERROR (Status)) { - return Status; - } - if ((*Result & Mask) == Value || Delay == 0) { - return EFI_SUCCESS; - } - do { - // - // Stall 10 us = 100 * 100ns - // - gBS->Stall (10); - - Status = PciIoMemRead (This, Width, BarIndex, Offset, 1, Result); - if (EFI_ERROR (Status)) { - return Status; - } - if ((*Result & Mask) == Value) { - return EFI_SUCCESS; - } - if (Delay <= 100) { - return EFI_TIMEOUT; - } - Delay -= 100; - } while (TRUE); - } - } - - Status = PciIoDevice->PciRootBridgeIo->PollMem ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Mask, - Value, - Delay, - Result - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Reads from the memory space of a PCI controller. Returns either when the polling exit criteria is - satisfied or after a defined duration. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory operation to perform. - @param Offset The offset within the selected BAR to start the memory operation. - @param Mask Mask used for the polling criteria. - @param Value The comparison value used for the polling exit criteria. - @param Delay The number of 100 ns units to poll. - @param Result Pointer to the last value read from the memory location. - - @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED Offset is not valid for the BarIndex of this PCI controller. - @retval EFI_TIMEOUT Delay expired before a match occurred. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoPollIo ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((UINT32)Width > EfiPciIoWidthUint64) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) { - Status = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result); - if (EFI_ERROR (Status)) { - return Status; - } - if ((*Result & Mask) == Value || Delay == 0) { - return EFI_SUCCESS; - } - do { - // - // Stall 10 us = 100 * 100ns - // - gBS->Stall (10); - - Status = PciIoIoRead (This, Width, BarIndex, Offset, 1, Result); - if (EFI_ERROR (Status)) { - return Status; - } - if ((*Result & Mask) == Value) { - return EFI_SUCCESS; - } - if (Delay <= 100) { - return EFI_TIMEOUT; - } - Delay -= 100; - } while (TRUE); - } - } - - Status = PciIoDevice->PciRootBridgeIo->PollIo ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Mask, - Value, - Delay, - Result - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. - @param Count The number of memory or I/O operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoMemRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((UINT32)Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) { - Count *= (UINTN)(1 << (Width & 0x03)); - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03)); - } - } - - - Status = PciIoDevice->PciRootBridgeIo->Mem.Read ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. - @param Count The number of memory or I/O operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoMemWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((UINT32)Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) { - Count *= (UINTN)(1 << (Width & 0x03)); - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03)); - } - } - - Status = PciIoDevice->PciRootBridgeIo->Mem.Write ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. - @param Count The number of memory or I/O operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoIoRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((UINT32)Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) { - Count *= (UINTN)(1 << (Width & 0x03)); - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03)); - } - } - - Status = PciIoDevice->PciRootBridgeIo->Io.Read ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. - @param Count The number of memory or I/O operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoIoWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((UINT32)Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) { - Count *= (UINTN)(1 << (Width & 0x03)); - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03)); - } - } - - Status = PciIoDevice->PciRootBridgeIo->Io.Write ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Offset, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Enable a PCI driver to access PCI controller registers in PCI configuration space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param Offset The offset within the PCI configuration space for the PCI controller. - @param Count The number of PCI configuration operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI configuration header of the PCI controller. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoConfigRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - UINT64 Address; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Address = Offset; - Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) { - Count *= (UINTN)(1 << (Width & 0x03)); - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03)); - } - } - - Status = PciIoDevice->PciRootBridgeIo->Pci.Read ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Address, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Enable a PCI driver to access PCI controller registers in PCI configuration space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param Offset The offset within the PCI configuration space for the PCI controller. - @param Count The number of PCI configuration operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI configuration header of the PCI controller. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoConfigWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - UINT64 Address; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Address = Offset; - Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((Offset & ((1 << (Width & 0x03)) - 1)) != 0) { - Count *= (UINTN)(1 << (Width & 0x03)); - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03)); - } - } - - Status = PciIoDevice->PciRootBridgeIo->Pci.Write ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - Address, - Count, - Buffer - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Enables a PCI driver to copy one region of PCI memory space to another region of PCI - memory space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param DestBarIndex The BAR index in the standard PCI Configuration header to use as the - base address for the memory operation to perform. - @param DestOffset The destination offset within the BAR specified by DestBarIndex to - start the memory writes for the copy operation. - @param SrcBarIndex The BAR index in the standard PCI Configuration header to use as the - base address for the memory operation to perform. - @param SrcOffset The source offset within the BAR specified by SrcBarIndex to start - the memory reads for the copy operation. - @param Count The number of memory operations to perform. Bytes moved is Width - size * Count, starting at DestOffset and SrcOffset. - - @retval EFI_SUCCESS The data was copied from one memory region to another memory region. - @retval EFI_UNSUPPORTED DestBarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED SrcBarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by DestOffset, Width, and Count - is not valid for the PCI BAR specified by DestBarIndex. - @retval EFI_UNSUPPORTED The address range specified by SrcOffset, Width, and Count is - not valid for the PCI BAR specified by SrcBarIndex. - @retval EFI_INVALID_PARAMETER Width is invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -EFIAPI -PciIoCopyMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 DestBarIndex, - IN UINT64 DestOffset, - IN UINT8 SrcBarIndex, - IN UINT64 SrcOffset, - IN UINTN Count - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((UINT32)Width >= EfiPciIoWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (Width == EfiPciIoWidthFifoUint8 || - Width == EfiPciIoWidthFifoUint16 || - Width == EfiPciIoWidthFifoUint32 || - Width == EfiPciIoWidthFifoUint64 || - Width == EfiPciIoWidthFillUint8 || - Width == EfiPciIoWidthFillUint16 || - Width == EfiPciIoWidthFillUint32 || - Width == EfiPciIoWidthFillUint64) { - return EFI_INVALID_PARAMETER; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // If request is not aligned, then convert request to EfiPciIoWithXXXUint8 - // - if (FeaturePcdGet (PcdUnalignedPciIoEnable)) { - if ((SrcOffset & ((1 << (Width & 0x03)) - 1)) != 0 || (DestOffset & ((1 << (Width & 0x03)) - 1)) != 0) { - Count *= (UINTN)(1 << (Width & 0x03)); - Width = (EFI_PCI_IO_PROTOCOL_WIDTH) (Width & (~0x03)); - } - } - - Status = PciIoDevice->PciRootBridgeIo->CopyMem ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, - DestOffset, - SrcOffset, - Count - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Provides the PCI controller-specific addresses needed to access system memory. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Operation Indicates if the bus master is going to read or write to system memory. - @param HostAddress The system memory address to map to the PCI controller. - @param NumberOfBytes On input the number of bytes to map. On output the number of bytes - that were mapped. - @param DeviceAddress The resulting map address for the bus master PCI controller to use to - access the hosts HostAddress. - @param Mapping A resulting value to pass to Unmap(). - - @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. - -**/ -EFI_STATUS -EFIAPI -PciIoMap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((UINT32)Operation >= EfiPciIoOperationMaximum) { - return EFI_INVALID_PARAMETER; - } - - if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) != 0) { - Operation = (EFI_PCI_IO_PROTOCOL_OPERATION) (Operation + EfiPciOperationBusMasterRead64); - } - - Status = PciIoDevice->PciRootBridgeIo->Map ( - PciIoDevice->PciRootBridgeIo, - (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation, - HostAddress, - NumberOfBytes, - DeviceAddress, - Mapping - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Completes the Map() operation and releases any corresponding resources. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Mapping The mapping value returned from Map(). - - @retval EFI_SUCCESS The range was unmapped. - @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. - -**/ -EFI_STATUS -EFIAPI -PciIoUnmap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN VOID *Mapping - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Status = PciIoDevice->PciRootBridgeIo->Unmap ( - PciIoDevice->PciRootBridgeIo, - Mapping - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer - mapping. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Type This parameter is not used and must be ignored. - @param MemoryType The type of memory to allocate, EfiBootServicesData or - EfiRuntimeServicesData. - @param Pages The number of pages to allocate. - @param HostAddress A pointer to store the base system memory address of the - allocated range. - @param Attributes The requested bit mask of attributes for the allocated range. - - @retval EFI_SUCCESS The requested memory pages were allocated. - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are - MEMORY_WRITE_COMBINE and MEMORY_CACHED. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. - -**/ -EFI_STATUS -EFIAPI -PciIoAllocateBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - if ((Attributes & - (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) != 0){ - return EFI_UNSUPPORTED; - } - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if ((PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) != 0) { - Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE; - } - - Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer ( - PciIoDevice->PciRootBridgeIo, - Type, - MemoryType, - Pages, - HostAddress, - Attributes - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Frees memory that was allocated with AllocateBuffer(). - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Pages The number of pages to free. - @param HostAddress The base system memory address of the allocated range. - - @retval EFI_SUCCESS The requested memory pages were freed. - @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages - was not allocated with AllocateBuffer(). - -**/ -EFI_STATUS -EFIAPI -PciIoFreeBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Status = PciIoDevice->PciRootBridgeIo->FreeBuffer ( - PciIoDevice->PciRootBridgeIo, - Pages, - HostAddress - ); - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Flushes all PCI posted write transactions from a PCI host bridge to system memory. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - - @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host - bridge to system memory. - @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI - host bridge due to a hardware error. - -**/ -EFI_STATUS -EFIAPI -PciIoFlush ( - IN EFI_PCI_IO_PROTOCOL *This - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - Status = PciIoDevice->PciRootBridgeIo->Flush ( - PciIoDevice->PciRootBridgeIo - ); - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Retrieves this PCI controller's current PCI bus number, device number, and function number. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param SegmentNumber The PCI controller's current PCI segment number. - @param BusNumber The PCI controller's current PCI bus number. - @param DeviceNumber The PCI controller's current PCI device number. - @param FunctionNumber The PCI controller's current PCI function number. - - @retval EFI_SUCCESS The PCI controller location was returned. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoGetLocation ( - IN EFI_PCI_IO_PROTOCOL *This, - OUT UINTN *Segment, - OUT UINTN *Bus, - OUT UINTN *Device, - OUT UINTN *Function - ) -{ - PCI_IO_DEVICE *PciIoDevice; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber; - *Bus = PciIoDevice->BusNumber; - *Device = PciIoDevice->DeviceNumber; - *Function = PciIoDevice->FunctionNumber; - - return EFI_SUCCESS; -} - -/** - Check BAR type for PCI resource. - - @param PciIoDevice PCI device instance. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param BarType Memory or I/O. - - @retval TRUE Pci device's bar type is same with input BarType. - @retval TRUE Pci device's bar type is not same with input BarType. - -**/ -BOOLEAN -CheckBarType ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 BarIndex, - IN PCI_BAR_TYPE BarType - ) -{ - switch (BarType) { - - case PciBarTypeMem: - - if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 && - PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 && - PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 && - PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) { - return FALSE; - } - - return TRUE; - - case PciBarTypeIo: - if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 && - PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){ - return FALSE; - } - - return TRUE; - - default: - break; - } - - return FALSE; -} - -/** - Set/Disable new attributes to a Root Bridge. - - @param PciIoDevice Pci device instance. - @param Attributes New attribute want to be set. - @param Operation Set or Disable. - - @retval EFI_UNSUPPORTED If root bridge does not support change attribute. - @retval EFI_SUCCESS Successfully set new attributs. - -**/ -EFI_STATUS -ModifyRootBridgeAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT64 Attributes, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation - ) -{ - UINT64 PciRootBridgeSupports; - UINT64 PciRootBridgeAttributes; - UINT64 NewPciRootBridgeAttributes; - EFI_STATUS Status; - - // - // Get the current attributes of this PCI device's PCI Root Bridge - // - Status = PciIoDevice->PciRootBridgeIo->GetAttributes ( - PciIoDevice->PciRootBridgeIo, - &PciRootBridgeSupports, - &PciRootBridgeAttributes - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Mask off attributes not supported by PCI root bridge. - // - Attributes &= ~(UINT64)(EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE | - EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM | - EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE); - - // - // Record the new attribute of the Root Bridge - // - if (Operation == EfiPciIoAttributeOperationEnable) { - NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes; - } else { - NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes); - } - - // - // Call the PCI Root Bridge to attempt to modify the attributes - // - if ((NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) != 0) { - - Status = PciIoDevice->PciRootBridgeIo->SetAttributes ( - PciIoDevice->PciRootBridgeIo, - NewPciRootBridgeAttributes, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - // - // The PCI Root Bridge could not modify the attributes, so return the error. - // - return EFI_UNSUPPORTED; - } - } - - // - // Also update the attributes for this Root Bridge structure - // - PciIoDevice->Attributes = NewPciRootBridgeAttributes; - - return EFI_SUCCESS; -} - -/** - Check whether this device can be enable/disable to snoop. - - @param PciIoDevice Pci device instance. - @param Operation Enable/Disable. - - @retval EFI_UNSUPPORTED Pci device is not GFX device or not support snoop. - @retval EFI_SUCCESS Snoop can be supported. - -**/ -EFI_STATUS -SupportPaletteSnoopAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation - ) -{ - PCI_IO_DEVICE *Temp; - UINT16 VGACommand; - - // - // Snoop attribute can be only modified by GFX - // - if (!IS_PCI_GFX (&PciIoDevice->Pci)) { - return EFI_UNSUPPORTED; - } - - // - // Get the boot VGA on the same segement - // - Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice); - - if (Temp == NULL) { - // - // If there is no VGA device on the segement, set - // this graphics card to decode the palette range - // - return EFI_SUCCESS; - } - - // - // Check these two agents are on the same path - // - if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) { - // - // they are not on the same path, so snoop can be enabled or disabled - // - return EFI_SUCCESS; - } - // - // Check if they are on the same bus - // - if (Temp->Parent == PciIoDevice->Parent) { - - PCI_READ_COMMAND_REGISTER (Temp, &VGACommand); - - // - // If they are on the same bus, either one can - // be set to snoop, the other set to decode - // - if ((VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) != 0) { - // - // VGA has set to snoop, so GFX can be only set to disable snoop - // - if (Operation == EfiPciIoAttributeOperationEnable) { - return EFI_UNSUPPORTED; - } - } else { - // - // VGA has disabled to snoop, so GFX can be only enabled - // - if (Operation == EfiPciIoAttributeOperationDisable) { - return EFI_UNSUPPORTED; - } - } - - return EFI_SUCCESS; - } - - // - // If they are on the same path but on the different bus - // The first agent is set to snoop, the second one set to - // decode - // - - if (Temp->BusNumber < PciIoDevice->BusNumber) { - // - // GFX should be set to decode - // - if (Operation == EfiPciIoAttributeOperationDisable) { - PCI_ENABLE_COMMAND_REGISTER (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); - Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; - } else { - return EFI_UNSUPPORTED; - } - - } else { - // - // GFX should be set to snoop - // - if (Operation == EfiPciIoAttributeOperationEnable) { - PCI_DISABLE_COMMAND_REGISTER (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); - Temp->Attributes &= (~(UINT64)EFI_PCI_COMMAND_VGA_PALETTE_SNOOP); - } else { - return EFI_UNSUPPORTED; - } - - } - - return EFI_SUCCESS; -} - -/** - Performs an operation on the attributes that this PCI controller supports. The operations include - getting the set of supported attributes, retrieving the current attributes, setting the current - attributes, enabling attributes, and disabling attributes. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Operation The operation to perform on the attributes for this PCI controller. - @param Attributes The mask of attributes that are used for Set, Enable, and Disable - operations. - @param Result A pointer to the result mask of attributes that are returned for the Get - and Supported operations. - - @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED one or more of the bits set in - Attributes are not supported by this PCI controller or one of - its parent bridges when Operation is Set, Enable or Disable. - -**/ -EFI_STATUS -EFIAPI -PciIoAttributes ( - IN EFI_PCI_IO_PROTOCOL * This, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes, - OUT UINT64 *Result OPTIONAL - ) -{ - EFI_STATUS Status; - - PCI_IO_DEVICE *PciIoDevice; - PCI_IO_DEVICE *UpStreamBridge; - PCI_IO_DEVICE *Temp; - - UINT64 Supports; - UINT64 UpStreamAttributes; - UINT16 BridgeControl; - UINT16 Command; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - switch (Operation) { - case EfiPciIoAttributeOperationGet: - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Result = PciIoDevice->Attributes; - return EFI_SUCCESS; - - case EfiPciIoAttributeOperationSupported: - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Result = PciIoDevice->Supports; - return EFI_SUCCESS; - - case EfiPciIoAttributeOperationSet: - Status = PciIoDevice->PciIo.Attributes ( - &(PciIoDevice->PciIo), - EfiPciIoAttributeOperationEnable, - Attributes, - NULL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIoDevice->PciIo.Attributes ( - &(PciIoDevice->PciIo), - EfiPciIoAttributeOperationDisable, - (~Attributes) & (PciIoDevice->Supports), - NULL - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; - - case EfiPciIoAttributeOperationEnable: - case EfiPciIoAttributeOperationDisable: - break; - - default: - return EFI_INVALID_PARAMETER; - } - // - // Just a trick for ENABLE attribute - // EFI_PCI_DEVICE_ENABLE is not defined in UEFI spec, which is the internal usage. - // So, this logic doesn't confrom to UEFI spec, which should be removed. - // But this trick logic is still kept for some binary drivers that depend on it. - // - if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) { - Attributes &= (PciIoDevice->Supports); - - // - // Raise the EFI_P_PC_ENABLE Status code - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_P_PC_ENABLE, - PciIoDevice->DevicePath - ); - } - - // - // Check VGA and VGA16, they can not be set at the same time - // - if ((Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO)) != 0) { - if ((Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) != 0) { - return EFI_UNSUPPORTED; - } - } - - // - // If no attributes can be supported, then return. - // Otherwise, set the attributes that it can support. - // - Supports = (PciIoDevice->Supports) & Attributes; - if (Supports != Attributes) { - return EFI_UNSUPPORTED; - } - - // - // For Root Bridge, just call RootBridgeIo to set attributes; - // - if (PciIoDevice->Parent == NULL) { - Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation); - return Status; - } - - Command = 0; - BridgeControl = 0; - - // - // For PPB & P2C, set relevant attribute bits - // - if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { - - if ((Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) != 0) { - BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA; - } - - if ((Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) != 0) { - BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA; - } - - if ((Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) != 0) { - Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO; - } - - if ((Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) != 0) { - BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA_16; - } - - } else { - // - // Do with the attributes on VGA - // Only for VGA's legacy resource, we just can enable once. - // - if ((Attributes & - (EFI_PCI_IO_ATTRIBUTE_VGA_IO | - EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | - EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY)) != 0) { - // - // Check if a VGA has been enabled before enabling a new one - // - if (Operation == EfiPciIoAttributeOperationEnable) { - // - // Check if there have been an active VGA device on the same segment - // - Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice); - if (Temp != NULL && Temp != PciIoDevice) { - // - // An active VGA has been detected, so can not enable another - // - return EFI_UNSUPPORTED; - } - } - } - - // - // Do with the attributes on GFX - // - if ((Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) != 0) { - - if (Operation == EfiPciIoAttributeOperationEnable) { - // - // Check if snoop can be enabled in current configuration - // - Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation); - - if (EFI_ERROR (Status)) { - - // - // Enable operation is forbidden, so mask the bit in attributes - // so as to keep consistent with the actual Status - // - // Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO); - // - // - // - return EFI_UNSUPPORTED; - - } - } - - // - // It can be supported, so get ready to set the bit - // - Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP; - } - } - - if ((Attributes & EFI_PCI_IO_ATTRIBUTE_IO) != 0) { - Command |= EFI_PCI_COMMAND_IO_SPACE; - } - - if ((Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) != 0) { - Command |= EFI_PCI_COMMAND_MEMORY_SPACE; - } - - if ((Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) != 0) { - Command |= EFI_PCI_COMMAND_BUS_MASTER; - } - // - // The upstream bridge should be also set to revelant attribute - // expect for IO, Mem and BusMaster - // - UpStreamAttributes = Attributes & - (~(EFI_PCI_IO_ATTRIBUTE_IO | - EFI_PCI_IO_ATTRIBUTE_MEMORY | - EFI_PCI_IO_ATTRIBUTE_BUS_MASTER - ) - ); - UpStreamBridge = PciIoDevice->Parent; - - if (Operation == EfiPciIoAttributeOperationEnable) { - // - // Enable relevant attributes to command register and bridge control register - // - Status = PCI_ENABLE_COMMAND_REGISTER (PciIoDevice, Command); - if (BridgeControl != 0) { - Status = PCI_ENABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, BridgeControl); - } - - PciIoDevice->Attributes |= Attributes; - - // - // Enable attributes of the upstream bridge - // - Status = UpStreamBridge->PciIo.Attributes ( - &(UpStreamBridge->PciIo), - EfiPciIoAttributeOperationEnable, - UpStreamAttributes, - NULL - ); - } else { - - // - // Disable relevant attributes to command register and bridge control register - // - Status = PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, Command); - if (BridgeControl != 0) { - Status = PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, BridgeControl); - } - - PciIoDevice->Attributes &= (~Attributes); - Status = EFI_SUCCESS; - - } - - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR, - PciIoDevice->DevicePath - ); - } - - return Status; -} - -/** - Gets the attributes that this PCI controller supports setting on a BAR using - SetBarAttributes(), and retrieves the list of resource descriptors for a BAR. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for resource range. The legal range for this field is 0..5. - @param Supports A pointer to the mask of attributes that this PCI controller supports - setting for this BAR with SetBarAttributes(). - @param Resources A pointer to the ACPI 2.0 resource descriptors that describe the current - configuration of this BAR of the PCI controller. - - @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI - controller supports are returned in Supports. If Resources - is not NULL, then the ACPI 2.0 resource descriptors that the PCI - controller is currently using are returned in Resources. - @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate - Resources. - -**/ -EFI_STATUS -EFIAPI -PciIoGetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL * This, - IN UINT8 BarIndex, - OUT UINT64 *Supports, OPTIONAL - OUT VOID **Resources OPTIONAL - ) -{ - UINT8 *Configuration; - PCI_IO_DEVICE *PciIoDevice; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AddressSpace; - EFI_ACPI_END_TAG_DESCRIPTOR *End; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - if (Supports == NULL && Resources == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((BarIndex >= PCI_MAX_BAR) || (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown)) { - return EFI_UNSUPPORTED; - } - - // - // This driver does not support modifications to the WRITE_COMBINE or - // CACHED attributes for BAR ranges. - // - if (Supports != NULL) { - *Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE; - } - - if (Resources != NULL) { - Configuration = AllocateZeroPool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (Configuration == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - AddressSpace = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; - - AddressSpace->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - AddressSpace->Len = (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3); - - AddressSpace->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress; - AddressSpace->AddrLen = PciIoDevice->PciBar[BarIndex].Length; - AddressSpace->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment; - - switch (PciIoDevice->PciBar[BarIndex].BarType) { - case PciBarTypeIo16: - case PciBarTypeIo32: - // - // Io - // - AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; - break; - - case PciBarTypeMem32: - // - // Mem - // - AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // 32 bit - // - AddressSpace->AddrSpaceGranularity = 32; - break; - - case PciBarTypePMem32: - // - // Mem - // - AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // prefechable - // - AddressSpace->SpecificFlag = 0x6; - // - // 32 bit - // - AddressSpace->AddrSpaceGranularity = 32; - break; - - case PciBarTypeMem64: - // - // Mem - // - AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // 64 bit - // - AddressSpace->AddrSpaceGranularity = 64; - break; - - case PciBarTypePMem64: - // - // Mem - // - AddressSpace->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - // - // prefechable - // - AddressSpace->SpecificFlag = 0x6; - // - // 64 bit - // - AddressSpace->AddrSpaceGranularity = 64; - break; - - default: - break; - } - - // - // put the checksum - // - End = (EFI_ACPI_END_TAG_DESCRIPTOR *) (AddressSpace + 1); - End->Desc = ACPI_END_TAG_DESCRIPTOR; - End->Checksum = 0; - - *Resources = Configuration; - } - - return EFI_SUCCESS; -} - -/** - Sets the attributes for a range of a BAR on a PCI controller. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Attributes The mask of attributes to set for the resource range specified by - BarIndex, Offset, and Length. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for resource range. The legal range for this field is 0..5. - @param Offset A pointer to the BAR relative base address of the resource range to be - modified by the attributes specified by Attributes. - @param Length A pointer to the length of the resource range to be modified by the - attributes specified by Attributes. - - @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource - range specified by BarIndex, Offset, and Length were - set on the PCI controller, and the actual resource range is returned - in Offset and Length. - @retval EFI_INVALID_PARAMETER Offset or Length is NULL. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the attributes on the - resource range specified by BarIndex, Offset, and - Length. - -**/ -EFI_STATUS -EFIAPI -PciIoSetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINT64 Attributes, - IN UINT8 BarIndex, - IN OUT UINT64 *Offset, - IN OUT UINT64 *Length - ) -{ - EFI_STATUS Status; - PCI_IO_DEVICE *PciIoDevice; - UINT64 NonRelativeOffset; - UINT64 Supports; - - PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This); - - // - // Make sure Offset and Length are not NULL - // - if (Offset == NULL || Length == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) { - return EFI_UNSUPPORTED; - } - // - // This driver does not support setting the WRITE_COMBINE or the CACHED attributes. - // If Attributes is not 0, then return EFI_UNSUPPORTED. - // - Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE; - - if (Attributes != (Attributes & Supports)) { - return EFI_UNSUPPORTED; - } - // - // Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and - // Length are valid for this PCI device. - // - NonRelativeOffset = *Offset; - Status = PciIoVerifyBarAccess ( - PciIoDevice, - BarIndex, - PciBarTypeMem, - EfiPciIoWidthUint8, - (UINT32) *Length, - &NonRelativeOffset - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -/** - Program parent bridge's attribute recurrently. - - @param PciIoDevice Child Pci device instance - @param Operation The operation to perform on the attributes for this PCI controller. - @param Attributes The mask of attributes that are used for Set, Enable, and Disable - operations. - - @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED one or more of the bits set in - Attributes are not supported by this PCI controller or one of - its parent bridges when Operation is Set, Enable or Disable. - -**/ -EFI_STATUS -UpStreamBridgesAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes - ) -{ - PCI_IO_DEVICE *Parent; - EFI_PCI_IO_PROTOCOL *PciIo; - - Parent = PciIoDevice->Parent; - - while (Parent != NULL && IS_PCI_BRIDGE (&Parent->Pci)) { - - // - // Get the PciIo Protocol - // - PciIo = &Parent->PciIo; - - PciIo->Attributes (PciIo, Operation, Attributes, NULL); - - Parent = Parent->Parent; - } - - return EFI_SUCCESS; -} - -/** - Test whether two Pci devices has same parent bridge. - - @param PciDevice1 The first pci device for testing. - @param PciDevice2 The second pci device for testing. - - @retval TRUE Two Pci device has the same parent bridge. - @retval FALSE Two Pci device has not the same parent bridge. - -**/ -BOOLEAN -PciDevicesOnTheSamePath ( - IN PCI_IO_DEVICE *PciDevice1, - IN PCI_IO_DEVICE *PciDevice2 - ) -{ - BOOLEAN Existed1; - BOOLEAN Existed2; - - if (PciDevice1->Parent == PciDevice2->Parent) { - return TRUE; - } - - Existed1 = PciDeviceExisted (PciDevice1->Parent, PciDevice2); - Existed2 = PciDeviceExisted (PciDevice2->Parent, PciDevice1); - - return (BOOLEAN) (Existed1 || Existed2); -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.h deleted file mode 100644 index ac2def5acf..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciIo.h +++ /dev/null @@ -1,687 +0,0 @@ -/** @file - EFI PCI IO protocol functions declaration for PCI Bus module. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_IO_PROTOCOL_H_ -#define _EFI_PCI_IO_PROTOCOL_H_ - -/** - Initializes a PCI I/O Instance. - - @param PciIoDevice Pci device instance. - -**/ -VOID -InitializePciIoInstance ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Verifies access to a PCI Base Address Register (BAR). - - @param PciIoDevice Pci device instance. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Type Operation type could be memory or I/O. - @param Width Signifies the width of the memory or I/O operations. - @param Count The number of memory or I/O operations to perform. - @param Offset The offset within the PCI configuration space for the PCI controller. - - @retval EFI_INVALID_PARAMETER Invalid Width/BarIndex or Bar type. - @retval EFI_SUCCESS Successfully verified. - -**/ -EFI_STATUS -PciIoVerifyBarAccess ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 BarIndex, - IN PCI_BAR_TYPE Type, - IN IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN IN UINTN Count, - IN UINT64 *Offset - ); - -/** - Verifies access to a PCI Configuration Header. - - @param PciIoDevice Pci device instance. - @param Width Signifies the width of the memory or I/O operations. - @param Count The number of memory or I/O operations to perform. - @param Offset The offset within the PCI configuration space for the PCI controller. - - @retval EFI_INVALID_PARAMETER Invalid Width - @retval EFI_UNSUPPORTED Offset overflowed. - @retval EFI_SUCCESS Successfully verified. - -**/ -EFI_STATUS -PciIoVerifyConfigAccess ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINTN Count, - IN UINT64 *Offset - ); - -/** - Reads from the memory space of a PCI controller. Returns either when the polling exit criteria is - satisfied or after a defined duration. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory operation to perform. - @param Offset The offset within the selected BAR to start the memory operation. - @param Mask Mask used for the polling criteria. - @param Value The comparison value used for the polling exit criteria. - @param Delay The number of 100 ns units to poll. - @param Result Pointer to the last value read from the memory location. - - @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED Offset is not valid for the BarIndex of this PCI controller. - @retval EFI_TIMEOUT Delay expired before a match occurred. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoPollMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ); - -/** - Reads from the memory space of a PCI controller. Returns either when the polling exit criteria is - satisfied or after a defined duration. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory operation to perform. - @param Offset The offset within the selected BAR to start the memory operation. - @param Mask Mask used for the polling criteria. - @param Value The comparison value used for the polling exit criteria. - @param Delay The number of 100 ns units to poll. - @param Result Pointer to the last value read from the memory location. - - @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED Offset is not valid for the BarIndex of this PCI controller. - @retval EFI_TIMEOUT Delay expired before a match occurred. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoPollIo ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ); - -/** - Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. - @param Count The number of memory or I/O operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoMemRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. - @param Count The number of memory or I/O operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoMemWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. - @param Count The number of memory or I/O operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoIoRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory or I/O operations. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param Offset The offset within the selected BAR to start the memory or I/O operation. - @param Count The number of memory or I/O operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI BAR specified by BarIndex. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoIoWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 BarIndex, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Enable a PCI driver to access PCI controller registers in PCI configuration space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param Offset The offset within the PCI configuration space for the PCI controller. - @param Count The number of PCI configuration operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI configuration header of the PCI controller. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoConfigRead ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Enable a PCI driver to access PCI controller registers in PCI configuration space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param Offset The offset within the PCI configuration space for the PCI controller. - @param Count The number of PCI configuration operations to perform. - @param Buffer For read operations, the destination buffer to store the results. For write - operations, the source buffer to write data from. - - - @retval EFI_SUCCESS The data was read from or written to the PCI controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the PCI configuration header of the PCI controller. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoConfigWrite ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT32 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Enables a PCI driver to copy one region of PCI memory space to another region of PCI - memory space. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param DestBarIndex The BAR index in the standard PCI Configuration header to use as the - base address for the memory operation to perform. - @param DestOffset The destination offset within the BAR specified by DestBarIndex to - start the memory writes for the copy operation. - @param SrcBarIndex The BAR index in the standard PCI Configuration header to use as the - base address for the memory operation to perform. - @param SrcOffset The source offset within the BAR specified by SrcBarIndex to start - the memory reads for the copy operation. - @param Count The number of memory operations to perform. Bytes moved is Width - size * Count, starting at DestOffset and SrcOffset. - - @retval EFI_SUCCESS The data was copied from one memory region to another memory region. - @retval EFI_UNSUPPORTED DestBarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED SrcBarIndex not valid for this PCI controller. - @retval EFI_UNSUPPORTED The address range specified by DestOffset, Width, and Count - is not valid for the PCI BAR specified by DestBarIndex. - @retval EFI_UNSUPPORTED The address range specified by SrcOffset, Width, and Count is - not valid for the PCI BAR specified by SrcBarIndex. - @retval EFI_INVALID_PARAMETER Width is invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -EFIAPI -PciIoCopyMem ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_WIDTH Width, - IN UINT8 DestBarIndex, - IN UINT64 DestOffset, - IN UINT8 SrcBarIndex, - IN UINT64 SrcOffset, - IN UINTN Count - ); - -/** - Provides the PCI controller-specific addresses needed to access system memory. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Operation Indicates if the bus master is going to read or write to system memory. - @param HostAddress The system memory address to map to the PCI controller. - @param NumberOfBytes On input the number of bytes to map. On output the number of bytes - that were mapped. - @param DeviceAddress The resulting map address for the bus master PCI controller to use to - access the hosts HostAddress. - @param Mapping A resulting value to pass to Unmap(). - - @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. - -**/ -EFI_STATUS -EFIAPI -PciIoMap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ); - -/** - Completes the Map() operation and releases any corresponding resources. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Mapping The mapping value returned from Map(). - - @retval EFI_SUCCESS The range was unmapped. - @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. - -**/ -EFI_STATUS -EFIAPI -PciIoUnmap ( - IN EFI_PCI_IO_PROTOCOL *This, - IN VOID *Mapping - ); - -/** - Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer - mapping. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Type This parameter is not used and must be ignored. - @param MemoryType The type of memory to allocate, EfiBootServicesData or - EfiRuntimeServicesData. - @param Pages The number of pages to allocate. - @param HostAddress A pointer to store the base system memory address of the - allocated range. - @param Attributes The requested bit mask of attributes for the allocated range. - - @retval EFI_SUCCESS The requested memory pages were allocated. - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are - MEMORY_WRITE_COMBINE and MEMORY_CACHED. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. - -**/ -EFI_STATUS -EFIAPI -PciIoAllocateBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ); - -/** - Frees memory that was allocated with AllocateBuffer(). - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Pages The number of pages to free. - @param HostAddress The base system memory address of the allocated range. - - @retval EFI_SUCCESS The requested memory pages were freed. - @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages - was not allocated with AllocateBuffer(). - -**/ -EFI_STATUS -EFIAPI -PciIoFreeBuffer ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress - ); - -/** - Flushes all PCI posted write transactions from a PCI host bridge to system memory. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - - @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host - bridge to system memory. - @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI - host bridge due to a hardware error. - -**/ -EFI_STATUS -EFIAPI -PciIoFlush ( - IN EFI_PCI_IO_PROTOCOL *This - ); - -/** - Retrieves this PCI controller's current PCI bus number, device number, and function number. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param SegmentNumber The PCI controller's current PCI segment number. - @param BusNumber The PCI controller's current PCI bus number. - @param DeviceNumber The PCI controller's current PCI device number. - @param FunctionNumber The PCI controller's current PCI function number. - - @retval EFI_SUCCESS The PCI controller location was returned. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -PciIoGetLocation ( - IN EFI_PCI_IO_PROTOCOL *This, - OUT UINTN *Segment, - OUT UINTN *Bus, - OUT UINTN *Device, - OUT UINTN *Function - ); - -/** - Check BAR type for PCI resource. - - @param PciIoDevice PCI device instance. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for the memory or I/O operation to perform. - @param BarType Memory or I/O. - - @retval TRUE Pci device's bar type is same with input BarType. - @retval TRUE Pci device's bar type is not same with input BarType. - -**/ -BOOLEAN -CheckBarType ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT8 BarIndex, - IN PCI_BAR_TYPE BarType - ); - -/** - Set/Disable new attributes to a Root Bridge. - - @param PciIoDevice Pci device instance. - @param Attributes New attribute want to be set. - @param Operation Set or Disable. - - @retval EFI_UNSUPPORTED If root bridge does not support change attribute. - @retval EFI_SUCCESS Successfully set new attributs. - -**/ -EFI_STATUS -ModifyRootBridgeAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN UINT64 Attributes, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation - ); - -/** - Check whether this device can be enable/disable to snoop. - - @param PciIoDevice Pci device instance. - @param Operation Enable/Disable. - - @retval EFI_UNSUPPORTED Pci device is not GFX device or not support snoop. - @retval EFI_SUCCESS Snoop can be supported. - -**/ -EFI_STATUS -SupportPaletteSnoopAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation - ); - -/** - Performs an operation on the attributes that this PCI controller supports. The operations include - getting the set of supported attributes, retrieving the current attributes, setting the current - attributes, enabling attributes, and disabling attributes. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Operation The operation to perform on the attributes for this PCI controller. - @param Attributes The mask of attributes that are used for Set, Enable, and Disable - operations. - @param Result A pointer to the result mask of attributes that are returned for the Get - and Supported operations. - - @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED one or more of the bits set in - Attributes are not supported by this PCI controller or one of - its parent bridges when Operation is Set, Enable or Disable. - -**/ -EFI_STATUS -EFIAPI -PciIoAttributes ( - IN EFI_PCI_IO_PROTOCOL * This, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes, - OUT UINT64 *Result OPTIONAL - ); - -/** - Gets the attributes that this PCI controller supports setting on a BAR using - SetBarAttributes(), and retrieves the list of resource descriptors for a BAR. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for resource range. The legal range for this field is 0..5. - @param Supports A pointer to the mask of attributes that this PCI controller supports - setting for this BAR with SetBarAttributes(). - @param Resources A pointer to the ACPI 2.0 resource descriptors that describe the current - configuration of this BAR of the PCI controller. - - @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI - controller supports are returned in Supports. If Resources - is not NULL, then the ACPI 2.0 resource descriptors that the PCI - controller is currently using are returned in Resources. - @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate - Resources. - -**/ -EFI_STATUS -EFIAPI -PciIoGetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL * This, - IN UINT8 BarIndex, - OUT UINT64 *Supports, OPTIONAL - OUT VOID **Resources OPTIONAL - ); - -/** - Sets the attributes for a range of a BAR on a PCI controller. - - @param This A pointer to the EFI_PCI_IO_PROTOCOL instance. - @param Attributes The mask of attributes to set for the resource range specified by - BarIndex, Offset, and Length. - @param BarIndex The BAR index of the standard PCI Configuration header to use as the - base address for resource range. The legal range for this field is 0..5. - @param Offset A pointer to the BAR relative base address of the resource range to be - modified by the attributes specified by Attributes. - @param Length A pointer to the length of the resource range to be modified by the - attributes specified by Attributes. - - @retval EFI_SUCCESS The set of attributes specified by Attributes for the resource - range specified by BarIndex, Offset, and Length were - set on the PCI controller, and the actual resource range is returned - in Offset and Length. - @retval EFI_INVALID_PARAMETER Offset or Length is NULL. - @retval EFI_UNSUPPORTED BarIndex not valid for this PCI controller. - @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the attributes on the - resource range specified by BarIndex, Offset, and - Length. - -**/ -EFI_STATUS -EFIAPI -PciIoSetBarAttributes ( - IN EFI_PCI_IO_PROTOCOL *This, - IN UINT64 Attributes, - IN UINT8 BarIndex, - IN OUT UINT64 *Offset, - IN OUT UINT64 *Length - ); - -/** - Program parent bridge's attribute recurrently. - - @param PciIoDevice Child Pci device instance - @param Operation The operation to perform on the attributes for this PCI controller. - @param Attributes The mask of attributes that are used for Set, Enable, and Disable - operations. - - @retval EFI_SUCCESS The operation on the PCI controller's attributes was completed. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_UNSUPPORTED one or more of the bits set in - Attributes are not supported by this PCI controller or one of - its parent bridges when Operation is Set, Enable or Disable. - -**/ -EFI_STATUS -UpStreamBridgesAttributes ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, - IN UINT64 Attributes - ); - -/** - Test whether two Pci devices has same parent bridge. - - @param PciDevice1 The first pci device for testing. - @param PciDevice2 The second pci device for testing. - - @retval TRUE Two Pci device has the same parent bridge. - @retval FALSE Two Pci device has not the same parent bridge. - -**/ -BOOLEAN -PciDevicesOnTheSamePath ( - IN PCI_IO_DEVICE *PciDevice1, - IN PCI_IO_DEVICE *PciDevice2 - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c deleted file mode 100644 index f3407bcb63..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c +++ /dev/null @@ -1,1649 +0,0 @@ -/** @file - Internal library implementation for PCI Bus module. - -Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
-(C) Copyright 2015 Hewlett Packard Enterprise Development LP
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -GLOBAL_REMOVE_IF_UNREFERENCED -CHAR16 *mBarTypeStr[] = { - L"Unknow", - L" Io16", - L" Io32", - L" Mem32", - L"PMem32", - L" Mem64", - L"PMem64", - L" Io", - L" Mem", - L"Unknow" - }; - -/** - Retrieve the PCI Card device BAR information via PciIo interface. - - @param PciIoDevice PCI Card device instance. - -**/ -VOID -GetBackPcCardBar ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - UINT32 Address; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return; - } - - // - // Read PciBar information from the bar register - // - if (!gFullEnumeration) { - Address = 0; - PciIoDevice->PciIo.Pci.Read ( - &(PciIoDevice->PciIo), - EfiPciIoWidthUint32, - PCI_CARD_MEMORY_BASE_0, - 1, - &Address - ); - - (PciIoDevice->PciBar)[P2C_MEM_1].BaseAddress = (UINT64) (Address); - (PciIoDevice->PciBar)[P2C_MEM_1].Length = 0x2000000; - (PciIoDevice->PciBar)[P2C_MEM_1].BarType = PciBarTypeMem32; - - Address = 0; - PciIoDevice->PciIo.Pci.Read ( - &(PciIoDevice->PciIo), - EfiPciIoWidthUint32, - PCI_CARD_MEMORY_BASE_1, - 1, - &Address - ); - (PciIoDevice->PciBar)[P2C_MEM_2].BaseAddress = (UINT64) (Address); - (PciIoDevice->PciBar)[P2C_MEM_2].Length = 0x2000000; - (PciIoDevice->PciBar)[P2C_MEM_2].BarType = PciBarTypePMem32; - - Address = 0; - PciIoDevice->PciIo.Pci.Read ( - &(PciIoDevice->PciIo), - EfiPciIoWidthUint32, - PCI_CARD_IO_BASE_0_LOWER, - 1, - &Address - ); - (PciIoDevice->PciBar)[P2C_IO_1].BaseAddress = (UINT64) (Address); - (PciIoDevice->PciBar)[P2C_IO_1].Length = 0x100; - (PciIoDevice->PciBar)[P2C_IO_1].BarType = PciBarTypeIo16; - - Address = 0; - PciIoDevice->PciIo.Pci.Read ( - &(PciIoDevice->PciIo), - EfiPciIoWidthUint32, - PCI_CARD_IO_BASE_1_LOWER, - 1, - &Address - ); - (PciIoDevice->PciBar)[P2C_IO_2].BaseAddress = (UINT64) (Address); - (PciIoDevice->PciBar)[P2C_IO_2].Length = 0x100; - (PciIoDevice->PciBar)[P2C_IO_2].BarType = PciBarTypeIo16; - - } - - if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - GetResourcePaddingForHpb (PciIoDevice); - } -} - -/** - Remove rejected pci device from specific root bridge - handle. - - @param RootBridgeHandle Specific parent root bridge handle. - @param Bridge Bridge device instance. - -**/ -VOID -RemoveRejectedPciDevices ( - IN EFI_HANDLE RootBridgeHandle, - IN PCI_IO_DEVICE *Bridge - ) -{ - PCI_IO_DEVICE *Temp; - LIST_ENTRY *CurrentLink; - LIST_ENTRY *LastLink; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return; - } - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (IS_PCI_BRIDGE (&Temp->Pci)) { - // - // Remove rejected devices recusively - // - RemoveRejectedPciDevices (RootBridgeHandle, Temp); - } else { - // - // Skip rejection for all PPBs, while detect rejection for others - // - if (IsPciDeviceRejected (Temp)) { - - // - // For P2C, remove all devices on it - // - if (!IsListEmpty (&Temp->ChildList)) { - RemoveAllPciDeviceOnBridge (RootBridgeHandle, Temp); - } - - // - // Finally remove itself - // - LastLink = CurrentLink->BackLink; - RemoveEntryList (CurrentLink); - FreePciDevice (Temp); - - CurrentLink = LastLink; - } - } - - CurrentLink = CurrentLink->ForwardLink; - } -} - -/** - Dump the resourc map of the bridge device. - - @param[in] BridgeResource Resource descriptor of the bridge device. -**/ -VOID -DumpBridgeResource ( - IN PCI_RESOURCE_NODE *BridgeResource - ) -{ - LIST_ENTRY *Link; - PCI_RESOURCE_NODE *Resource; - PCI_BAR *Bar; - - if ((BridgeResource != NULL) && (BridgeResource->Length != 0)) { - DEBUG (( - EFI_D_INFO, "Type = %s; Base = 0x%lx;\tLength = 0x%lx;\tAlignment = 0x%lx\n", - mBarTypeStr[MIN (BridgeResource->ResType, PciBarTypeMaxType)], - BridgeResource->PciDev->PciBar[BridgeResource->Bar].BaseAddress, - BridgeResource->Length, BridgeResource->Alignment - )); - for ( Link = GetFirstNode (&BridgeResource->ChildList) - ; !IsNull (&BridgeResource->ChildList, Link) - ; Link = GetNextNode (&BridgeResource->ChildList, Link) - ) { - Resource = RESOURCE_NODE_FROM_LINK (Link); - if (Resource->ResourceUsage == PciResUsageTypical) { - Bar = Resource->Virtual ? Resource->PciDev->VfPciBar : Resource->PciDev->PciBar; - DEBUG (( - EFI_D_INFO, " Base = 0x%lx;\tLength = 0x%lx;\tAlignment = 0x%lx;\tOwner = %s [%02x|%02x|%02x:", - Bar[Resource->Bar].BaseAddress, Resource->Length, Resource->Alignment, - IS_PCI_BRIDGE (&Resource->PciDev->Pci) ? L"PPB" : - IS_CARDBUS_BRIDGE (&Resource->PciDev->Pci) ? L"P2C" : - L"PCI", - Resource->PciDev->BusNumber, Resource->PciDev->DeviceNumber, - Resource->PciDev->FunctionNumber - )); - - if ((!IS_PCI_BRIDGE (&Resource->PciDev->Pci) && !IS_CARDBUS_BRIDGE (&Resource->PciDev->Pci)) || - (IS_PCI_BRIDGE (&Resource->PciDev->Pci) && (Resource->Bar < PPB_IO_RANGE)) || - (IS_CARDBUS_BRIDGE (&Resource->PciDev->Pci) && (Resource->Bar < P2C_MEM_1)) - ) { - // - // The resource requirement comes from the device itself. - // - DEBUG ((EFI_D_INFO, "%02x]", Bar[Resource->Bar].Offset)); - } else { - // - // The resource requirement comes from the subordinate devices. - // - DEBUG ((EFI_D_INFO, "**]")); - } - } else { - DEBUG ((EFI_D_INFO, " Base = Padding;\tLength = 0x%lx;\tAlignment = 0x%lx", Resource->Length, Resource->Alignment)); - } - if (BridgeResource->ResType != Resource->ResType) { - DEBUG ((EFI_D_INFO, "; Type = %s", mBarTypeStr[MIN (Resource->ResType, PciBarTypeMaxType)])); - } - DEBUG ((EFI_D_INFO, "\n")); - } - } -} - -/** - Find the corresponding resource node for the Device in child list of BridgeResource. - - @param[in] Device Pointer to PCI_IO_DEVICE. - @param[in] BridgeResource Pointer to PCI_RESOURCE_NODE. - @param[out] DeviceResources Pointer to a buffer to receive resources for the Device. - - @return Count of the resource descriptors returned. -**/ -UINTN -FindResourceNode ( - IN PCI_IO_DEVICE *Device, - IN PCI_RESOURCE_NODE *BridgeResource, - OUT PCI_RESOURCE_NODE **DeviceResources OPTIONAL - ) -{ - LIST_ENTRY *Link; - PCI_RESOURCE_NODE *Resource; - UINTN Count; - - Count = 0; - for ( Link = BridgeResource->ChildList.ForwardLink - ; Link != &BridgeResource->ChildList - ; Link = Link->ForwardLink - ) { - Resource = RESOURCE_NODE_FROM_LINK (Link); - if (Resource->PciDev == Device) { - if (DeviceResources != NULL) { - DeviceResources[Count] = Resource; - } - Count++; - } - } - - return Count; -} - -/** - Dump the resource map of all the devices under Bridge. - - @param[in] Bridge Bridge device instance. - @param[in] Resources Resource descriptors for the bridge device. - @param[in] ResourceCount Count of resource descriptors. -**/ -VOID -DumpResourceMap ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE **Resources, - IN UINTN ResourceCount - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - PCI_IO_DEVICE *Device; - UINTN Index; - CHAR16 *Str; - PCI_RESOURCE_NODE **ChildResources; - UINTN ChildResourceCount; - - DEBUG ((EFI_D_INFO, "PciBus: Resource Map for ")); - - Status = gBS->OpenProtocol ( - Bridge->Handle, - &gEfiPciRootBridgeIoProtocolGuid, - NULL, - NULL, - NULL, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - if (EFI_ERROR (Status)) { - DEBUG (( - EFI_D_INFO, "Bridge [%02x|%02x|%02x]\n", - Bridge->BusNumber, Bridge->DeviceNumber, Bridge->FunctionNumber - )); - } else { - Str = ConvertDevicePathToText ( - DevicePathFromHandle (Bridge->Handle), - FALSE, - FALSE - ); - DEBUG ((EFI_D_INFO, "Root Bridge %s\n", Str != NULL ? Str : L"")); - if (Str != NULL) { - FreePool (Str); - } - } - - for (Index = 0; Index < ResourceCount; Index++) { - DumpBridgeResource (Resources[Index]); - } - DEBUG ((EFI_D_INFO, "\n")); - - for ( Link = Bridge->ChildList.ForwardLink - ; Link != &Bridge->ChildList - ; Link = Link->ForwardLink - ) { - Device = PCI_IO_DEVICE_FROM_LINK (Link); - if (IS_PCI_BRIDGE (&Device->Pci)) { - - ChildResourceCount = 0; - for (Index = 0; Index < ResourceCount; Index++) { - ChildResourceCount += FindResourceNode (Device, Resources[Index], NULL); - } - ChildResources = AllocatePool (sizeof (PCI_RESOURCE_NODE *) * ChildResourceCount); - ASSERT (ChildResources != NULL); - ChildResourceCount = 0; - for (Index = 0; Index < ResourceCount; Index++) { - ChildResourceCount += FindResourceNode (Device, Resources[Index], &ChildResources[ChildResourceCount]); - } - - DumpResourceMap (Device, ChildResources, ChildResourceCount); - FreePool (ChildResources); - } - } -} - -/** - Submits the I/O and memory resource requirements for the specified PCI Host Bridge. - - @param PciResAlloc Point to protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - - @retval EFI_SUCCESS Successfully finished resource allocation. - @retval EFI_NOT_FOUND Cannot get root bridge instance. - @retval EFI_OUT_OF_RESOURCES Platform failed to program the resources if no hot plug supported. - @retval other Some error occurred when allocating resources for the PCI Host Bridge. - - @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug. - -**/ -EFI_STATUS -PciHostBridgeResourceAllocator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -{ - PCI_IO_DEVICE *RootBridgeDev; - EFI_HANDLE RootBridgeHandle; - VOID *AcpiConfig; - EFI_STATUS Status; - UINT64 IoBase; - UINT64 Mem32Base; - UINT64 PMem32Base; - UINT64 Mem64Base; - UINT64 PMem64Base; - UINT64 IoResStatus; - UINT64 Mem32ResStatus; - UINT64 PMem32ResStatus; - UINT64 Mem64ResStatus; - UINT64 PMem64ResStatus; - UINT64 MaxOptionRomSize; - PCI_RESOURCE_NODE *IoBridge; - PCI_RESOURCE_NODE *Mem32Bridge; - PCI_RESOURCE_NODE *PMem32Bridge; - PCI_RESOURCE_NODE *Mem64Bridge; - PCI_RESOURCE_NODE *PMem64Bridge; - PCI_RESOURCE_NODE IoPool; - PCI_RESOURCE_NODE Mem32Pool; - PCI_RESOURCE_NODE PMem32Pool; - PCI_RESOURCE_NODE Mem64Pool; - PCI_RESOURCE_NODE PMem64Pool; - BOOLEAN ReAllocate; - EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD HandleExtendedData; - EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData; - - // - // Reallocate flag - // - ReAllocate = FALSE; - - // - // It may try several times if the resource allocation fails - // - while (TRUE) { - // - // Initialize resource pool - // - InitializeResourcePool (&IoPool, PciBarTypeIo16); - InitializeResourcePool (&Mem32Pool, PciBarTypeMem32); - InitializeResourcePool (&PMem32Pool, PciBarTypePMem32); - InitializeResourcePool (&Mem64Pool, PciBarTypeMem64); - InitializeResourcePool (&PMem64Pool, PciBarTypePMem64); - - RootBridgeDev = NULL; - RootBridgeHandle = 0; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - // - // Get Root Bridge Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Create the entire system resource map from the information collected by - // enumerator. Several resource tree was created - // - - // - // If non-stardard PCI Bridge I/O window alignment is supported, - // set I/O aligment to minimum possible alignment for root bridge. - // - IoBridge = CreateResourceNode ( - RootBridgeDev, - 0, - FeaturePcdGet (PcdPciBridgeIoAlignmentProbe) ? 0x1FF: 0xFFF, - RB_IO_RANGE, - PciBarTypeIo16, - PciResUsageTypical - ); - - Mem32Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - RB_MEM32_RANGE, - PciBarTypeMem32, - PciResUsageTypical - ); - - PMem32Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - RB_PMEM32_RANGE, - PciBarTypePMem32, - PciResUsageTypical - ); - - Mem64Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - RB_MEM64_RANGE, - PciBarTypeMem64, - PciResUsageTypical - ); - - PMem64Bridge = CreateResourceNode ( - RootBridgeDev, - 0, - 0xFFFFF, - RB_PMEM64_RANGE, - PciBarTypePMem64, - PciResUsageTypical - ); - - // - // Create resourcemap by going through all the devices subject to this root bridge - // - CreateResourceMap ( - RootBridgeDev, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge - ); - - // - // Get the max ROM size that the root bridge can process - // - RootBridgeDev->RomSize = Mem32Bridge->Length; - - // - // Skip to enlarge the resource request during realloction - // - if (!ReAllocate) { - // - // Get Max Option Rom size for current root bridge - // - MaxOptionRomSize = GetMaxOptionRomSize (RootBridgeDev); - - // - // Enlarger the mem32 resource to accomdate the option rom - // if the mem32 resource is not enough to hold the rom - // - if (MaxOptionRomSize > Mem32Bridge->Length) { - - Mem32Bridge->Length = MaxOptionRomSize; - RootBridgeDev->RomSize = MaxOptionRomSize; - - // - // Alignment should be adjusted as well - // - if (Mem32Bridge->Alignment < MaxOptionRomSize - 1) { - Mem32Bridge->Alignment = MaxOptionRomSize - 1; - } - } - } - - // - // Based on the all the resource tree, contruct ACPI resource node to - // submit the resource aperture to pci host bridge protocol - // - Status = ConstructAcpiResourceRequestor ( - RootBridgeDev, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge, - &AcpiConfig - ); - - // - // Insert these resource nodes into the database - // - InsertResourceNode (&IoPool, IoBridge); - InsertResourceNode (&Mem32Pool, Mem32Bridge); - InsertResourceNode (&PMem32Pool, PMem32Bridge); - InsertResourceNode (&Mem64Pool, Mem64Bridge); - InsertResourceNode (&PMem64Pool, PMem64Bridge); - - if (Status == EFI_SUCCESS) { - // - // Submit the resource requirement - // - Status = PciResAlloc->SubmitResources ( - PciResAlloc, - RootBridgeDev->Handle, - AcpiConfig - ); - // - // If SubmitResources returns error, PciBus isn't able to start. - // It's a fatal error so assertion is added. - // - DEBUG ((EFI_D_INFO, "PciBus: HostBridge->SubmitResources() - %r\n", Status)); - ASSERT_EFI_ERROR (Status); - } - - // - // Free acpi resource node - // - if (AcpiConfig != NULL) { - FreePool (AcpiConfig); - } - - if (EFI_ERROR (Status)) { - // - // Destroy all the resource tree - // - DestroyResourceTree (&IoPool); - DestroyResourceTree (&Mem32Pool); - DestroyResourceTree (&PMem32Pool); - DestroyResourceTree (&Mem64Pool); - DestroyResourceTree (&PMem64Pool); - return Status; - } - } - // - // End while, at least one Root Bridge should be found. - // - ASSERT (RootBridgeDev != NULL); - - // - // Notify platform to start to program the resource - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeAllocateResources); - DEBUG ((EFI_D_INFO, "PciBus: HostBridge->NotifyPhase(AllocateResources) - %r\n", Status)); - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - // - // If Hot Plug is not supported - // - if (EFI_ERROR (Status)) { - // - // Allocation failed, then return - // - return EFI_OUT_OF_RESOURCES; - } - // - // Allocation succeed. - // Get host bridge handle for status report, and then skip the main while - // - HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; - - break; - - } else { - // - // If Hot Plug is supported - // - if (!EFI_ERROR (Status)) { - // - // Allocation succeed, then continue the following - // - break; - } - - // - // If the resource allocation is unsuccessful, free resources on bridge - // - - RootBridgeDev = NULL; - RootBridgeHandle = 0; - - IoResStatus = EFI_RESOURCE_SATISFIED; - Mem32ResStatus = EFI_RESOURCE_SATISFIED; - PMem32ResStatus = EFI_RESOURCE_SATISFIED; - Mem64ResStatus = EFI_RESOURCE_SATISFIED; - PMem64ResStatus = EFI_RESOURCE_SATISFIED; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get host bridge handle for status report - // - HandleExtendedData.Handle = RootBridgeDev->PciRootBridgeIo->ParentHandle; - - // - // Get acpi resource node for all the resource types - // - AcpiConfig = NULL; - - Status = PciResAlloc->GetProposedResources ( - PciResAlloc, - RootBridgeDev->Handle, - &AcpiConfig - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - if (AcpiConfig != NULL) { - // - // Adjust resource allocation policy for each RB - // - GetResourceAllocationStatus ( - AcpiConfig, - &IoResStatus, - &Mem32ResStatus, - &PMem32ResStatus, - &Mem64ResStatus, - &PMem64ResStatus - ); - FreePool (AcpiConfig); - } - } - // - // End while - // - - // - // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code - // - // - // It is very difficult to follow the spec here - // Device path , Bar index can not be get here - // - ZeroMem (&AllocFailExtendedData, sizeof (AllocFailExtendedData)); - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT, - (VOID *) &AllocFailExtendedData, - sizeof (AllocFailExtendedData) - ); - - Status = PciHostBridgeAdjustAllocation ( - &IoPool, - &Mem32Pool, - &PMem32Pool, - &Mem64Pool, - &PMem64Pool, - IoResStatus, - Mem32ResStatus, - PMem32ResStatus, - Mem64ResStatus, - PMem64ResStatus - ); - - // - // Destroy all the resource tree - // - DestroyResourceTree (&IoPool); - DestroyResourceTree (&Mem32Pool); - DestroyResourceTree (&PMem32Pool); - DestroyResourceTree (&Mem64Pool); - DestroyResourceTree (&PMem64Pool); - - NotifyPhase (PciResAlloc, EfiPciHostBridgeFreeResources); - - if (EFI_ERROR (Status)) { - return Status; - } - - ReAllocate = TRUE; - } - } - // - // End main while - // - - // - // Raise the EFI_IOB_PCI_RES_ALLOC status code - // - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_PCI_RES_ALLOC, - (VOID *) &HandleExtendedData, - sizeof (HandleExtendedData) - ); - - // - // Notify pci bus driver starts to program the resource - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeSetResources); - - if (EFI_ERROR (Status)) { - return Status; - } - - RootBridgeDev = NULL; - - RootBridgeHandle = 0; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - // - // Get acpi resource node for all the resource types - // - AcpiConfig = NULL; - Status = PciResAlloc->GetProposedResources ( - PciResAlloc, - RootBridgeDev->Handle, - &AcpiConfig - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the resource base by interpreting acpi resource node - // - // - GetResourceBase ( - AcpiConfig, - &IoBase, - &Mem32Base, - &PMem32Base, - &Mem64Base, - &PMem64Base - ); - - // - // Process option rom for this root bridge - // - ProcessOptionRom (RootBridgeDev, Mem32Base, RootBridgeDev->RomSize); - - // - // Create the entire system resource map from the information collected by - // enumerator. Several resource tree was created - // - FindResourceNode (RootBridgeDev, &IoPool, &IoBridge); - FindResourceNode (RootBridgeDev, &Mem32Pool, &Mem32Bridge); - FindResourceNode (RootBridgeDev, &PMem32Pool, &PMem32Bridge); - FindResourceNode (RootBridgeDev, &Mem64Pool, &Mem64Bridge); - FindResourceNode (RootBridgeDev, &PMem64Pool, &PMem64Bridge); - - ASSERT (IoBridge != NULL); - ASSERT (Mem32Bridge != NULL); - ASSERT (PMem32Bridge != NULL); - ASSERT (Mem64Bridge != NULL); - ASSERT (PMem64Bridge != NULL); - - // - // Program IO resources - // - ProgramResource ( - IoBase, - IoBridge - ); - - // - // Program Mem32 resources - // - ProgramResource ( - Mem32Base, - Mem32Bridge - ); - - // - // Program PMem32 resources - // - ProgramResource ( - PMem32Base, - PMem32Bridge - ); - - // - // Program Mem64 resources - // - ProgramResource ( - Mem64Base, - Mem64Bridge - ); - - // - // Program PMem64 resources - // - ProgramResource ( - PMem64Base, - PMem64Bridge - ); - - IoBridge ->PciDev->PciBar[IoBridge ->Bar].BaseAddress = IoBase; - Mem32Bridge ->PciDev->PciBar[Mem32Bridge ->Bar].BaseAddress = Mem32Base; - PMem32Bridge->PciDev->PciBar[PMem32Bridge->Bar].BaseAddress = PMem32Base; - Mem64Bridge ->PciDev->PciBar[Mem64Bridge ->Bar].BaseAddress = Mem64Base; - PMem64Bridge->PciDev->PciBar[PMem64Bridge->Bar].BaseAddress = PMem64Base; - - // - // Dump the resource map for current root bridge - // - DEBUG_CODE ( - PCI_RESOURCE_NODE *Resources[5]; - Resources[0] = IoBridge; - Resources[1] = Mem32Bridge; - Resources[2] = PMem32Bridge; - Resources[3] = Mem64Bridge; - Resources[4] = PMem64Bridge; - DumpResourceMap (RootBridgeDev, Resources, sizeof (Resources) / sizeof (Resources[0])); - ); - - FreePool (AcpiConfig); - } - - // - // Destroy all the resource tree - // - DestroyResourceTree (&IoPool); - DestroyResourceTree (&Mem32Pool); - DestroyResourceTree (&PMem32Pool); - DestroyResourceTree (&Mem64Pool); - DestroyResourceTree (&PMem64Pool); - - // - // Notify the resource allocation phase is to end - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeEndResourceAllocation); - - return Status; -} - -/** - Allocate NumberOfBuses buses and return the next available PCI bus number. - - @param Bridge Bridge device instance. - @param StartBusNumber Current available PCI bus number. - @param NumberOfBuses Number of buses enumerated below the StartBusNumber. - @param NextBusNumber Next available PCI bus number. - - @retval EFI_SUCCESS Available bus number resource is enough. Next available PCI bus number - is returned in NextBusNumber. - @retval EFI_OUT_OF_RESOURCES Available bus number resource is not enough for allocation. - -**/ -EFI_STATUS -PciAllocateBusNumber ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - IN UINT8 NumberOfBuses, - OUT UINT8 *NextBusNumber - ) -{ - PCI_IO_DEVICE *RootBridge; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BusNumberRanges; - UINT8 NextNumber; - UINT64 MaxNumberInRange; - - // - // Get PCI Root Bridge device - // - RootBridge = Bridge; - while (RootBridge->Parent != NULL) { - RootBridge = RootBridge->Parent; - } - - // - // Get next available PCI bus number - // - BusNumberRanges = RootBridge->BusNumberRanges; - while (BusNumberRanges->Desc != ACPI_END_TAG_DESCRIPTOR) { - MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1; - if (StartBusNumber >= BusNumberRanges->AddrRangeMin && StartBusNumber <= MaxNumberInRange) { - NextNumber = (UINT8)(StartBusNumber + NumberOfBuses); - while (NextNumber > MaxNumberInRange) { - ++BusNumberRanges; - if (BusNumberRanges->Desc == ACPI_END_TAG_DESCRIPTOR) { - return EFI_OUT_OF_RESOURCES; - } - NextNumber = (UINT8)(NextNumber + (BusNumberRanges->AddrRangeMin - (MaxNumberInRange + 1))); - MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1; - } - *NextBusNumber = NextNumber; - return EFI_SUCCESS; - } - BusNumberRanges++; - } - return EFI_OUT_OF_RESOURCES; -} - -/** - Scan pci bus and assign bus number to the given PCI bus system. - - @param Bridge Bridge device instance. - @param StartBusNumber start point. - @param SubBusNumber Point to sub bus number. - @param PaddedBusRange Customized bus number. - - @retval EFI_SUCCESS Successfully scanned and assigned bus number. - @retval other Some error occurred when scanning pci bus. - - @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug. - -**/ -EFI_STATUS -PciScanBus ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber, - OUT UINT8 *PaddedBusRange - ) -{ - EFI_STATUS Status; - PCI_TYPE00 Pci; - UINT8 Device; - UINT8 Func; - UINT64 Address; - UINT8 SecondBus; - UINT8 PaddedSubBus; - UINT16 Register; - UINTN HpIndex; - PCI_IO_DEVICE *PciDevice; - EFI_EVENT Event; - EFI_HPC_STATE State; - UINT64 PciAddress; - EFI_HPC_PADDING_ATTRIBUTES Attributes; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; - UINT16 BusRange; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - BOOLEAN BusPadding; - UINT32 TempReservedBusNum; - - PciRootBridgeIo = Bridge->PciRootBridgeIo; - SecondBus = 0; - Register = 0; - State = 0; - Attributes = (EFI_HPC_PADDING_ATTRIBUTES) 0; - BusRange = 0; - BusPadding = FALSE; - PciDevice = NULL; - PciAddress = 0; - - for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) { - TempReservedBusNum = 0; - for (Func = 0; Func <= PCI_MAX_FUNC; Func++) { - - // - // Check to see whether a pci device is present - // - Status = PciDevicePresent ( - PciRootBridgeIo, - &Pci, - StartBusNumber, - Device, - Func - ); - - if (EFI_ERROR (Status) && Func == 0) { - // - // go to next device if there is no Function 0 - // - break; - } - - if (EFI_ERROR (Status)) { - continue; - } - - // - // Get the PCI device information - // - Status = PciSearchDevice ( - Bridge, - &Pci, - StartBusNumber, - Device, - Func, - &PciDevice - ); - - ASSERT (!EFI_ERROR (Status)); - - PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0); - - if (!IS_PCI_BRIDGE (&Pci)) { - // - // PCI bridges will be called later - // Here just need for PCI device or PCI to cardbus controller - // EfiPciBeforeChildBusEnumeration for PCI Device Node - // - PreprocessController ( - PciDevice, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - EfiPciBeforeChildBusEnumeration - ); - } - - if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - // - // For Pci Hotplug controller devcie only - // - if (gPciHotPlugInit != NULL) { - // - // Check if it is a Hotplug PCI controller - // - if (IsRootPciHotPlugController (PciDevice->DevicePath, &HpIndex)) { - gPciRootHpcData[HpIndex].Found = TRUE; - - if (!gPciRootHpcData[HpIndex].Initialized) { - - Status = CreateEventForHpc (HpIndex, &Event); - - ASSERT (!EFI_ERROR (Status)); - - Status = gPciHotPlugInit->InitializeRootHpc ( - gPciHotPlugInit, - gPciRootHpcPool[HpIndex].HpcDevicePath, - PciAddress, - Event, - &State - ); - - PreprocessController ( - PciDevice, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - EfiPciBeforeChildBusEnumeration - ); - } - } - } - } - - if (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci)) { - // - // For PPB - // - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - // - // If Hot Plug is not supported, - // get the bridge information - // - Status = PciSearchDevice ( - Bridge, - &Pci, - StartBusNumber, - Device, - Func, - &PciDevice - ); - - if (EFI_ERROR (Status)) { - return Status; - } - } else { - // - // If Hot Plug is supported, - // Get the bridge information - // - BusPadding = FALSE; - if (gPciHotPlugInit != NULL) { - - if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) { - - // - // If it is initialized, get the padded bus range - // - Status = gPciHotPlugInit->GetResourcePadding ( - gPciHotPlugInit, - gPciRootHpcPool[HpIndex].HpbDevicePath, - PciAddress, - &State, - (VOID **) &Descriptors, - &Attributes - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - BusRange = 0; - Status = PciGetBusRange ( - &Descriptors, - NULL, - NULL, - &BusRange - ); - - FreePool (Descriptors); - - if (EFI_ERROR (Status)) { - return Status; - } - - BusPadding = TRUE; - } - } - } - - Status = PciAllocateBusNumber (Bridge, *SubBusNumber, 1, SubBusNumber); - if (EFI_ERROR (Status)) { - return Status; - } - SecondBus = *SubBusNumber; - - Register = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber); - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET); - - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint16, - Address, - 1, - &Register - ); - - - // - // If it is PPB, resursively search down this bridge - // - if (IS_PCI_BRIDGE (&Pci)) { - - // - // Temporarily initialize SubBusNumber to maximum bus number to ensure the - // PCI configuration transaction to go through any PPB - // - Register = 0xFF; - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET); - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint8, - Address, - 1, - &Register - ); - - // - // Nofify EfiPciBeforeChildBusEnumeration for PCI Brige - // - PreprocessController ( - PciDevice, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - EfiPciBeforeChildBusEnumeration - ); - - Status = PciScanBus ( - PciDevice, - SecondBus, - SubBusNumber, - PaddedBusRange - ); - if (EFI_ERROR (Status)) { - return Status; - } - } - - if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport) && BusPadding) { - // - // Ensure the device is enabled and initialized - // - if ((Attributes == EfiPaddingPciRootBridge) && - (State & EFI_HPC_STATE_ENABLED) != 0 && - (State & EFI_HPC_STATE_INITIALIZED) != 0) { - *PaddedBusRange = (UINT8) ((UINT8) (BusRange) + *PaddedBusRange); - } else { - // - // Reserve the larger one between the actual occupied bus number and padded bus number - // - Status = PciAllocateBusNumber (PciDevice, SecondBus, (UINT8) (BusRange), &PaddedSubBus); - if (EFI_ERROR (Status)) { - return Status; - } - *SubBusNumber = MAX (PaddedSubBus, *SubBusNumber); - } - } - - // - // Set the current maximum bus number under the PPB - // - Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET); - - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint8, - Address, - 1, - SubBusNumber - ); - } else { - // - // It is device. Check PCI IOV for Bus reservation - // Go through each function, just reserve the MAX ReservedBusNum for one device - // - if (PcdGetBool (PcdSrIovSupport) && PciDevice->SrIovCapabilityOffset != 0) { - if (TempReservedBusNum < PciDevice->ReservedBusNum) { - - Status = PciAllocateBusNumber (PciDevice, *SubBusNumber, (UINT8) (PciDevice->ReservedBusNum - TempReservedBusNum), SubBusNumber); - if (EFI_ERROR (Status)) { - return Status; - } - TempReservedBusNum = PciDevice->ReservedBusNum; - - if (Func == 0) { - DEBUG ((EFI_D_INFO, "PCI-IOV ScanBus - SubBusNumber - 0x%x\n", *SubBusNumber)); - } else { - DEBUG ((EFI_D_INFO, "PCI-IOV ScanBus - SubBusNumber - 0x%x (Update)\n", *SubBusNumber)); - } - } - } - } - - if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) { - - // - // Skip sub functions, this is not a multi function device - // - - Func = PCI_MAX_FUNC; - } - } - } - - return EFI_SUCCESS; -} - -/** - Process Option Rom on the specified root bridge. - - @param Bridge Pci root bridge device instance. - - @retval EFI_SUCCESS Success process. - @retval other Some error occurred when processing Option Rom on the root bridge. - -**/ -EFI_STATUS -PciRootBridgeP2CProcess ( - IN PCI_IO_DEVICE *Bridge - ) -{ - LIST_ENTRY *CurrentLink; - PCI_IO_DEVICE *Temp; - EFI_HPC_STATE State; - UINT64 PciAddress; - EFI_STATUS Status; - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - if (IS_CARDBUS_BRIDGE (&Temp->Pci)) { - - if (gPciHotPlugInit != NULL && Temp->Allocated && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - - // - // Raise the EFI_IOB_PCI_HPC_INIT status code - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_IO_BUS_PCI | EFI_IOB_PCI_HPC_INIT, - Temp->DevicePath - ); - - PciAddress = EFI_PCI_ADDRESS (Temp->BusNumber, Temp->DeviceNumber, Temp->FunctionNumber, 0); - Status = gPciHotPlugInit->InitializeRootHpc ( - gPciHotPlugInit, - Temp->DevicePath, - PciAddress, - NULL, - &State - ); - - if (!EFI_ERROR (Status)) { - Status = PciBridgeEnumerator (Temp); - - if (EFI_ERROR (Status)) { - return Status; - } - } - - CurrentLink = CurrentLink->ForwardLink; - continue; - - } - } - - if (!IsListEmpty (&Temp->ChildList)) { - Status = PciRootBridgeP2CProcess (Temp); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -/** - Process Option Rom on the specified host bridge. - - @param PciResAlloc Pointer to instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - - @retval EFI_SUCCESS Success process. - @retval EFI_NOT_FOUND Can not find the root bridge instance. - @retval other Some error occurred when processing Option Rom on the host bridge. - -**/ -EFI_STATUS -PciHostBridgeP2CProcess ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -{ - EFI_HANDLE RootBridgeHandle; - PCI_IO_DEVICE *RootBridgeDev; - EFI_STATUS Status; - - if (!FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - return EFI_SUCCESS; - } - - RootBridgeHandle = NULL; - - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // Get RootBridg Device by handle - // - RootBridgeDev = GetRootBridgeByHandle (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_NOT_FOUND; - } - - Status = PciRootBridgeP2CProcess (RootBridgeDev); - if (EFI_ERROR (Status)) { - return Status; - } - - } - - return EFI_SUCCESS; -} - -/** - This function is used to enumerate the entire host bridge - in a given platform. - - @param PciResAlloc A pointer to the PCI Host Resource Allocation protocol. - - @retval EFI_SUCCESS Successfully enumerated the host bridge. - @retval EFI_OUT_OF_RESOURCES No enough memory available. - @retval other Some error occurred when enumerating the host bridge. - -**/ -EFI_STATUS -PciHostBridgeEnumerator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ) -{ - EFI_HANDLE RootBridgeHandle; - PCI_IO_DEVICE *RootBridgeDev; - EFI_STATUS Status; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - UINT16 MinBus; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Configuration; - UINT8 StartBusNumber; - LIST_ENTRY RootBridgeList; - LIST_ENTRY *Link; - - if (FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - InitializeHotPlugSupport (); - } - - InitializeListHead (&RootBridgeList); - - // - // Notify the bus allocation phase is about to start - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation); - - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG((EFI_D_INFO, "PCI Bus First Scanning\n")); - RootBridgeHandle = NULL; - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // if a root bridge instance is found, create root bridge device for it - // - - RootBridgeDev = CreateRootBridge (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Enumerate all the buses under this root bridge - // - Status = PciRootBridgeEnumerator ( - PciResAlloc, - RootBridgeDev - ); - - if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - InsertTailList (&RootBridgeList, &(RootBridgeDev->Link)); - } else { - DestroyRootBridge (RootBridgeDev); - } - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Notify the bus allocation phase is finished for the first time - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); - - if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - // - // Reset all assigned PCI bus number in all PPB - // - RootBridgeHandle = NULL; - Link = GetFirstNode (&RootBridgeList); - while ((PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) && - (!IsNull (&RootBridgeList, Link))) { - RootBridgeDev = PCI_IO_DEVICE_FROM_LINK (Link); - // - // Get the Bus information - // - Status = PciResAlloc->StartBusEnumeration ( - PciResAlloc, - RootBridgeHandle, - (VOID **) &Configuration - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the bus number to start with - // - StartBusNumber = (UINT8) (Configuration->AddrRangeMin); - - ResetAllPpbBusNumber ( - RootBridgeDev, - StartBusNumber - ); - - FreePool (Configuration); - Link = RemoveEntryList (Link); - DestroyRootBridge (RootBridgeDev); - } - - // - // Wait for all HPC initialized - // - Status = AllRootHPCInitialized (STALL_1_SECOND * 15); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Some root HPC failed to initialize\n")); - return Status; - } - - // - // Notify the bus allocation phase is about to start for the 2nd time - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginBusAllocation); - - if (EFI_ERROR (Status)) { - return Status; - } - - DEBUG((EFI_D_INFO, "PCI Bus Second Scanning\n")); - RootBridgeHandle = NULL; - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // if a root bridge instance is found, create root bridge device for it - // - RootBridgeDev = CreateRootBridge (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Enumerate all the buses under this root bridge - // - Status = PciRootBridgeEnumerator ( - PciResAlloc, - RootBridgeDev - ); - - DestroyRootBridge (RootBridgeDev); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Notify the bus allocation phase is to end for the 2nd time - // - NotifyPhase (PciResAlloc, EfiPciHostBridgeEndBusAllocation); - } - - // - // Notify the resource allocation phase is to start - // - Status = NotifyPhase (PciResAlloc, EfiPciHostBridgeBeginResourceAllocation); - - if (EFI_ERROR (Status)) { - return Status; - } - - RootBridgeHandle = NULL; - while (PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle) == EFI_SUCCESS) { - - // - // if a root bridge instance is found, create root bridge device for it - // - RootBridgeDev = CreateRootBridge (RootBridgeHandle); - - if (RootBridgeDev == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = StartManagingRootBridge (RootBridgeDev); - - if (EFI_ERROR (Status)) { - return Status; - } - - PciRootBridgeIo = RootBridgeDev->PciRootBridgeIo; - Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PciGetBusRange (&Descriptors, &MinBus, NULL, NULL); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Determine root bridge attribute by calling interface of Pcihostbridge - // protocol - // - DetermineRootBridgeAttributes ( - PciResAlloc, - RootBridgeDev - ); - - // - // Collect all the resource information under this root bridge - // A database that records all the information about pci device subject to this - // root bridge will then be created - // - Status = PciPciDeviceInfoCollector ( - RootBridgeDev, - (UINT8) MinBus - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - InsertRootBridge (RootBridgeDev); - - // - // Record the hostbridge handle - // - AddHostBridgeEnumerator (RootBridgeDev->PciRootBridgeIo->ParentHandle); - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.h deleted file mode 100644 index 6c2ade3f36..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.h +++ /dev/null @@ -1,165 +0,0 @@ -/** @file - Internal library declaration for PCI Bus module. - -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_LIB_H_ -#define _EFI_PCI_LIB_H_ - - -typedef struct { - EFI_HANDLE Handle; -} EFI_DEVICE_HANDLE_EXTENDED_DATA_PAYLOAD; - -typedef struct { - UINT32 Bar; - UINT16 DevicePathSize; - UINT16 ReqResSize; - UINT16 AllocResSize; - UINT8 *DevicePath; - UINT8 *ReqRes; - UINT8 *AllocRes; -} EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD; - - -/** - Retrieve the PCI Card device BAR information via PciIo interface. - - @param PciIoDevice PCI Card device instance. - -**/ -VOID -GetBackPcCardBar ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Remove rejected pci device from specific root bridge - handle. - - @param RootBridgeHandle Specific parent root bridge handle. - @param Bridge Bridge device instance. - -**/ -VOID -RemoveRejectedPciDevices ( - IN EFI_HANDLE RootBridgeHandle, - IN PCI_IO_DEVICE *Bridge - ); - -/** - Submits the I/O and memory resource requirements for the specified PCI Host Bridge. - - @param PciResAlloc Point to protocol instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - - @retval EFI_SUCCESS Successfully finished resource allocation. - @retval EFI_NOT_FOUND Cannot get root bridge instance. - @retval EFI_OUT_OF_RESOURCES Platform failed to program the resources if no hot plug supported. - @retval other Some error occurred when allocating resources for the PCI Host Bridge. - - @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug. - -**/ -EFI_STATUS -PciHostBridgeResourceAllocator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ); - -/** - Allocate NumberOfBuses buses and return the next available PCI bus number. - - @param Bridge Bridge device instance. - @param StartBusNumber Current available PCI bus number. - @param NumberOfBuses Number of buses enumerated below the StartBusNumber. - @param NextBusNumber Next available PCI bus number. - - @retval EFI_SUCCESS Available bus number resource is enough. Next available PCI bus number - is returned in NextBusNumber. - @retval EFI_OUT_OF_RESOURCES Available bus number resource is not enough for allocation. - -**/ -EFI_STATUS -PciAllocateBusNumber ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - IN UINT8 NumberOfBuses, - OUT UINT8 *NextBusNumber - ); - -/** - Scan pci bus and assign bus number to the given PCI bus system. - - @param Bridge Bridge device instance. - @param StartBusNumber start point. - @param SubBusNumber Point to sub bus number. - @param PaddedBusRange Customized bus number. - - @retval EFI_SUCCESS Successfully scanned and assigned bus number. - @retval other Some error occurred when scanning pci bus. - - @note Feature flag PcdPciBusHotplugDeviceSupport determine whether need support hotplug. - -**/ -EFI_STATUS -PciScanBus ( - IN PCI_IO_DEVICE *Bridge, - IN UINT8 StartBusNumber, - OUT UINT8 *SubBusNumber, - OUT UINT8 *PaddedBusRange - ); - -/** - Process Option Rom on the specified root bridge. - - @param Bridge Pci root bridge device instance. - - @retval EFI_SUCCESS Success process. - @retval other Some error occurred when processing Option Rom on the root bridge. - -**/ -EFI_STATUS -PciRootBridgeP2CProcess ( - IN PCI_IO_DEVICE *Bridge - ); - -/** - Process Option Rom on the specified host bridge. - - @param PciResAlloc Pointer to instance of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL. - - @retval EFI_SUCCESS Success process. - @retval EFI_NOT_FOUND Can not find the root bridge instance. - @retval other Some error occurred when processing Option Rom on the host bridge. - -**/ -EFI_STATUS -PciHostBridgeP2CProcess ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ); - -/** - This function is used to enumerate the entire host bridge - in a given platform. - - @param PciResAlloc A pointer to the PCI Host Resource Allocation protocol. - - @retval EFI_SUCCESS Successfully enumerated the host bridge. - @retval EFI_OUT_OF_RESOURCES No enough memory available. - @retval other Some error occurred when enumerating the host bridge. - -**/ -EFI_STATUS -PciHostBridgeEnumerator ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c deleted file mode 100644 index 2bc4f8c5e8..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.c +++ /dev/null @@ -1,783 +0,0 @@ -/** @file - PCI Rom supporting funtions implementation for PCI Bus module. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -/** - Load the EFI Image from Option ROM - - @param PciIoDevice PCI IO device instance. - @param FilePath The file path of the EFI Image - @param BufferSize On input the size of Buffer in bytes. On output with a return - code of EFI_SUCCESS, the amount of data transferred to Buffer. - On output with a return code of EFI_BUFFER_TOO_SMALL, - the size of Buffer required to retrieve the requested file. - @param Buffer The memory buffer to transfer the file to. If Buffer is NULL, - then no the size of the requested file is returned in BufferSize. - - @retval EFI_SUCCESS The file was loaded. - @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or - BufferSize is NULL. - @retval EFI_NOT_FOUND Not found PCI Option Rom on PCI device. - @retval EFI_DEVICE_ERROR Failed to decompress PCI Option Rom image. - @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. - BufferSize has been updated with the size needed to complete the request. -**/ -EFI_STATUS -LocalLoadFile2 ( - IN PCI_IO_DEVICE *PciIoDevice, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN OUT UINTN *BufferSize, - IN VOID *Buffer OPTIONAL - ) -{ - EFI_STATUS Status; - MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *EfiOpRomImageNode; - EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader; - PCI_DATA_STRUCTURE *Pcir; - UINT32 ImageSize; - UINT8 *ImageBuffer; - UINT32 ImageLength; - UINT32 DestinationSize; - UINT32 ScratchSize; - VOID *Scratch; - EFI_DECOMPRESS_PROTOCOL *Decompress; - UINT32 InitializationSize; - - EfiOpRomImageNode = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) FilePath; - if ((EfiOpRomImageNode == NULL) || - (DevicePathType (FilePath) != MEDIA_DEVICE_PATH) || - (DevicePathSubType (FilePath) != MEDIA_RELATIVE_OFFSET_RANGE_DP) || - (DevicePathNodeLength (FilePath) != sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)) || - (!IsDevicePathEnd (NextDevicePathNode (FilePath))) || - (EfiOpRomImageNode->StartingOffset > EfiOpRomImageNode->EndingOffset) || - (EfiOpRomImageNode->EndingOffset >= PciIoDevice->RomSize) || - (BufferSize == NULL) - ) { - return EFI_INVALID_PARAMETER; - } - - EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) ( - (UINT8 *) PciIoDevice->PciIo.RomImage + EfiOpRomImageNode->StartingOffset - ); - if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - return EFI_NOT_FOUND; - } - - - Pcir = (PCI_DATA_STRUCTURE *) ((UINT8 *) EfiRomHeader + EfiRomHeader->PcirOffset); - ASSERT (Pcir->Signature == PCI_DATA_STRUCTURE_SIGNATURE); - - if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) && - (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) && - ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) || - (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) && - (EfiRomHeader->CompressionType <= EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) - ) { - - ImageSize = Pcir->ImageLength * 512; - InitializationSize = (UINT32) EfiRomHeader->InitializationSize * 512; - if (InitializationSize > ImageSize || EfiRomHeader->EfiImageHeaderOffset >= InitializationSize) { - return EFI_NOT_FOUND; - } - - ImageBuffer = (UINT8 *) EfiRomHeader + EfiRomHeader->EfiImageHeaderOffset; - ImageLength = InitializationSize - EfiRomHeader->EfiImageHeaderOffset; - - if (EfiRomHeader->CompressionType != EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) { - // - // Uncompressed: Copy the EFI Image directly to user's buffer - // - if (Buffer == NULL || *BufferSize < ImageLength) { - *BufferSize = ImageLength; - return EFI_BUFFER_TOO_SMALL; - } - - *BufferSize = ImageLength; - CopyMem (Buffer, ImageBuffer, ImageLength); - return EFI_SUCCESS; - - } else { - // - // Compressed: Uncompress before copying - // - Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - Status = Decompress->GetInfo ( - Decompress, - ImageBuffer, - ImageLength, - &DestinationSize, - &ScratchSize - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - if (Buffer == NULL || *BufferSize < DestinationSize) { - *BufferSize = DestinationSize; - return EFI_BUFFER_TOO_SMALL; - } - - *BufferSize = DestinationSize; - Scratch = AllocatePool (ScratchSize); - if (Scratch == NULL) { - return EFI_DEVICE_ERROR; - } - - Status = Decompress->Decompress ( - Decompress, - ImageBuffer, - ImageLength, - Buffer, - DestinationSize, - Scratch, - ScratchSize - ); - FreePool (Scratch); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - -/** - Initialize a PCI LoadFile2 instance. - - @param PciIoDevice PCI IO Device. - -**/ -VOID -InitializePciLoadFile2 ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - PciIoDevice->LoadFile2.LoadFile = LoadFile2; -} - -/** - Causes the driver to load a specified file. - - @param This Indicates a pointer to the calling context. - @param FilePath The device specific path of the file to load. - @param BootPolicy Should always be FALSE. - @param BufferSize On input the size of Buffer in bytes. On output with a return - code of EFI_SUCCESS, the amount of data transferred to Buffer. - On output with a return code of EFI_BUFFER_TOO_SMALL, - the size of Buffer required to retrieve the requested file. - @param Buffer The memory buffer to transfer the file to. If Buffer is NULL, - then no the size of the requested file is returned in BufferSize. - - @retval EFI_SUCCESS The file was loaded. - @retval EFI_UNSUPPORTED BootPolicy is TRUE. - @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or - BufferSize is NULL. - @retval EFI_NOT_FOUND Not found PCI Option Rom on PCI device. - @retval EFI_DEVICE_ERROR Failed to decompress PCI Option Rom image. - @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. - BufferSize has been updated with the size needed to complete the request. - -**/ -EFI_STATUS -EFIAPI -LoadFile2 ( - IN EFI_LOAD_FILE2_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN BOOLEAN BootPolicy, - IN OUT UINTN *BufferSize, - IN VOID *Buffer OPTIONAL - ) -{ - PCI_IO_DEVICE *PciIoDevice; - - if (BootPolicy) { - return EFI_UNSUPPORTED; - } - PciIoDevice = PCI_IO_DEVICE_FROM_LOAD_FILE2_THIS (This); - - return LocalLoadFile2 ( - PciIoDevice, - FilePath, - BufferSize, - Buffer - ); -} - -/** - Get Pci device's oprom information. - - @param PciIoDevice Input Pci device instance. - Output Pci device instance with updated OptionRom size. - - @retval EFI_NOT_FOUND Pci device has not Option Rom. - @retval EFI_SUCCESS Pci device has Option Rom. - -**/ -EFI_STATUS -GetOpRomInfo ( - IN OUT PCI_IO_DEVICE *PciIoDevice - ) -{ - UINT8 RomBarIndex; - UINT32 AllOnes; - UINT64 Address; - EFI_STATUS Status; - UINT8 Bus; - UINT8 Device; - UINT8 Function; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - - Bus = PciIoDevice->BusNumber; - Device = PciIoDevice->DeviceNumber; - Function = PciIoDevice->FunctionNumber; - - PciRootBridgeIo = PciIoDevice->PciRootBridgeIo; - - // - // Offset is 0x30 if is not ppb - // - - // - // 0x30 - // - RomBarIndex = PCI_EXPANSION_ROM_BASE; - - if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) { - // - // If is ppb, 0x38 - // - RomBarIndex = PCI_BRIDGE_ROMBAR; - } - // - // The bit0 is 0 to prevent the enabling of the Rom address decoder - // - AllOnes = 0xfffffffe; - Address = EFI_PCI_ADDRESS (Bus, Device, Function, RomBarIndex); - - Status = PciRootBridgeIo->Pci.Write ( - PciRootBridgeIo, - EfiPciWidthUint32, - Address, - 1, - &AllOnes - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - // - // Read back - // - Status = PciRootBridgeIo->Pci.Read( - PciRootBridgeIo, - EfiPciWidthUint32, - Address, - 1, - &AllOnes - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - // - // Bits [1, 10] are reserved - // - AllOnes &= 0xFFFFF800; - if ((AllOnes == 0) || (AllOnes == 0xFFFFF800)) { - return EFI_NOT_FOUND; - } - - PciIoDevice->RomSize = (UINT64) ((~AllOnes) + 1); - return EFI_SUCCESS; -} - -/** - Check if the RomImage contains EFI Images. - - @param RomImage The ROM address of Image for check. - @param RomSize Size of ROM for check. - - @retval TRUE ROM contain EFI Image. - @retval FALSE ROM not contain EFI Image. - -**/ -BOOLEAN -ContainEfiImage ( - IN VOID *RomImage, - IN UINT64 RomSize - ) -{ - PCI_EXPANSION_ROM_HEADER *RomHeader; - PCI_DATA_STRUCTURE *RomPcir; - UINT8 Indicator; - - Indicator = 0; - RomHeader = RomImage; - if (RomHeader == NULL) { - return FALSE; - } - - do { - if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - RomHeader = (PCI_EXPANSION_ROM_HEADER *) ((UINT8 *) RomHeader + 512); - continue; - } - - // - // The PCI Data Structure must be DWORD aligned. - // - if (RomHeader->PcirOffset == 0 || - (RomHeader->PcirOffset & 3) != 0 || - (UINT8 *) RomHeader + RomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > (UINT8 *) RomImage + RomSize) { - break; - } - - RomPcir = (PCI_DATA_STRUCTURE *) ((UINT8 *) RomHeader + RomHeader->PcirOffset); - if (RomPcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { - break; - } - - if (RomPcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) { - return TRUE; - } - - Indicator = RomPcir->Indicator; - RomHeader = (PCI_EXPANSION_ROM_HEADER *) ((UINT8 *) RomHeader + RomPcir->ImageLength * 512); - } while (((UINT8 *) RomHeader < (UINT8 *) RomImage + RomSize) && ((Indicator & 0x80) == 0x00)); - - return FALSE; -} - -/** - Load Option Rom image for specified PCI device. - - @param PciDevice Pci device instance. - @param RomBase Base address of Option Rom. - - @retval EFI_OUT_OF_RESOURCES No enough memory to hold image. - @retval EFI_SUCESS Successfully loaded Option Rom. - -**/ -EFI_STATUS -LoadOpRomImage ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT64 RomBase - ) -{ - UINT8 RomBarIndex; - UINT8 Indicator; - UINT16 OffsetPcir; - UINT32 RomBarOffset; - UINT32 RomBar; - EFI_STATUS RetStatus; - BOOLEAN FirstCheck; - UINT8 *Image; - PCI_EXPANSION_ROM_HEADER *RomHeader; - PCI_DATA_STRUCTURE *RomPcir; - UINT64 RomSize; - UINT64 RomImageSize; - UINT32 LegacyImageLength; - UINT8 *RomInMemory; - UINT8 CodeType; - - RomSize = PciDevice->RomSize; - - Indicator = 0; - RomImageSize = 0; - RomInMemory = NULL; - CodeType = 0xFF; - - // - // Get the RomBarIndex - // - - // - // 0x30 - // - RomBarIndex = PCI_EXPANSION_ROM_BASE; - if (IS_PCI_BRIDGE (&(PciDevice->Pci))) { - // - // if is ppb - // - - // - // 0x38 - // - RomBarIndex = PCI_BRIDGE_ROMBAR; - } - // - // Allocate memory for Rom header and PCIR - // - RomHeader = AllocatePool (sizeof (PCI_EXPANSION_ROM_HEADER)); - if (RomHeader == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - RomPcir = AllocatePool (sizeof (PCI_DATA_STRUCTURE)); - if (RomPcir == NULL) { - FreePool (RomHeader); - return EFI_OUT_OF_RESOURCES; - } - - RomBar = (UINT32) RomBase; - - // - // Enable RomBar - // - RomDecode (PciDevice, RomBarIndex, RomBar, TRUE); - - RomBarOffset = RomBar; - RetStatus = EFI_NOT_FOUND; - FirstCheck = TRUE; - LegacyImageLength = 0; - - do { - PciDevice->PciRootBridgeIo->Mem.Read ( - PciDevice->PciRootBridgeIo, - EfiPciWidthUint8, - RomBarOffset, - sizeof (PCI_EXPANSION_ROM_HEADER), - (UINT8 *) RomHeader - ); - - if (RomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - RomBarOffset = RomBarOffset + 512; - if (FirstCheck) { - break; - } else { - RomImageSize = RomImageSize + 512; - continue; - } - } - - FirstCheck = FALSE; - OffsetPcir = RomHeader->PcirOffset; - // - // If the pointer to the PCI Data Structure is invalid, no further images can be located. - // The PCI Data Structure must be DWORD aligned. - // - if (OffsetPcir == 0 || - (OffsetPcir & 3) != 0 || - RomImageSize + OffsetPcir + sizeof (PCI_DATA_STRUCTURE) > RomSize) { - break; - } - PciDevice->PciRootBridgeIo->Mem.Read ( - PciDevice->PciRootBridgeIo, - EfiPciWidthUint8, - RomBarOffset + OffsetPcir, - sizeof (PCI_DATA_STRUCTURE), - (UINT8 *) RomPcir - ); - // - // If a valid signature is not present in the PCI Data Structure, no further images can be located. - // - if (RomPcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { - break; - } - if (RomImageSize + RomPcir->ImageLength * 512 > RomSize) { - break; - } - if (RomPcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { - CodeType = PCI_CODE_TYPE_PCAT_IMAGE; - LegacyImageLength = ((UINT32)((EFI_LEGACY_EXPANSION_ROM_HEADER *)RomHeader)->Size512) * 512; - } - Indicator = RomPcir->Indicator; - RomImageSize = RomImageSize + RomPcir->ImageLength * 512; - RomBarOffset = RomBarOffset + RomPcir->ImageLength * 512; - } while (((Indicator & 0x80) == 0x00) && ((RomBarOffset - RomBar) < RomSize)); - - // - // Some Legacy Cards do not report the correct ImageLength so used the maximum - // of the legacy length and the PCIR Image Length - // - if (CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { - RomImageSize = MAX (RomImageSize, LegacyImageLength); - } - - if (RomImageSize > 0) { - RetStatus = EFI_SUCCESS; - Image = AllocatePool ((UINT32) RomImageSize); - if (Image == NULL) { - RomDecode (PciDevice, RomBarIndex, RomBar, FALSE); - FreePool (RomHeader); - FreePool (RomPcir); - return EFI_OUT_OF_RESOURCES; - } - - // - // Copy Rom image into memory - // - PciDevice->PciRootBridgeIo->Mem.Read ( - PciDevice->PciRootBridgeIo, - EfiPciWidthUint8, - RomBar, - (UINT32) RomImageSize, - Image - ); - RomInMemory = Image; - } - - RomDecode (PciDevice, RomBarIndex, RomBar, FALSE); - - PciDevice->EmbeddedRom = TRUE; - PciDevice->PciIo.RomSize = RomImageSize; - PciDevice->PciIo.RomImage = RomInMemory; - - // - // For OpROM read from PCI device: - // Add the Rom Image to internal database for later PCI light enumeration - // - PciRomAddImageMapping ( - NULL, - PciDevice->PciRootBridgeIo->SegmentNumber, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - (UINT64) (UINTN) PciDevice->PciIo.RomImage, - PciDevice->PciIo.RomSize - ); - - // - // Free allocated memory - // - FreePool (RomHeader); - FreePool (RomPcir); - - return RetStatus; -} - -/** - Enable/Disable Option Rom decode. - - @param PciDevice Pci device instance. - @param RomBarIndex The BAR index of the standard PCI Configuration header to use as the - base address for resource range. The legal range for this field is 0..5. - @param RomBar Base address of Option Rom. - @param Enable Flag for enable/disable decode. - -**/ -VOID -RomDecode ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT8 RomBarIndex, - IN UINT32 RomBar, - IN BOOLEAN Enable - ) -{ - UINT32 Value32; - UINT32 Offset; - UINT32 OffsetMax; - EFI_PCI_IO_PROTOCOL *PciIo; - - PciIo = &PciDevice->PciIo; - if (Enable) { - // - // Clear all bars - // - OffsetMax = 0x24; - if (IS_PCI_BRIDGE(&PciDevice->Pci)) { - OffsetMax = 0x14; - } - - for (Offset = 0x10; Offset <= OffsetMax; Offset += sizeof (UINT32)) { - PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllZero); - } - - // - // set the Rom base address: now is hardcode - // enable its decoder - // - Value32 = RomBar | 0x1; - PciIo->Pci.Write ( - PciIo, - (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32, - RomBarIndex, - 1, - &Value32 - ); - - // - // Programe all upstream bridge - // - ProgrameUpstreamBridgeForRom(PciDevice, RomBar, TRUE); - - // - // Setting the memory space bit in the function's command register - // - PCI_ENABLE_COMMAND_REGISTER(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE); - - } else { - - // - // disable command register decode to memory - // - PCI_DISABLE_COMMAND_REGISTER(PciDevice, EFI_PCI_COMMAND_MEMORY_SPACE); - - // - // Destroy the programmed bar in all the upstream bridge. - // - ProgrameUpstreamBridgeForRom(PciDevice, RomBar, FALSE); - - // - // disable rom decode - // - Value32 = 0xFFFFFFFE; - PciIo->Pci.Write ( - PciIo, - (EFI_PCI_IO_PROTOCOL_WIDTH) EfiPciWidthUint32, - RomBarIndex, - 1, - &Value32 - ); - - } -} - -/** - Load and start the Option Rom image. - - @param PciDevice Pci device instance. - - @retval EFI_SUCCESS Successfully loaded and started PCI Option Rom image. - @retval EFI_NOT_FOUND Failed to process PCI Option Rom image. - -**/ -EFI_STATUS -ProcessOpRomImage ( - IN PCI_IO_DEVICE *PciDevice - ) -{ - UINT8 Indicator; - UINT32 ImageSize; - VOID *RomBar; - UINT8 *RomBarOffset; - EFI_HANDLE ImageHandle; - EFI_STATUS Status; - EFI_STATUS RetStatus; - EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader; - PCI_DATA_STRUCTURE *Pcir; - EFI_DEVICE_PATH_PROTOCOL *PciOptionRomImageDevicePath; - MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH EfiOpRomImageNode; - VOID *Buffer; - UINTN BufferSize; - - Indicator = 0; - - // - // Get the Address of the Option Rom image - // - RomBar = PciDevice->PciIo.RomImage; - RomBarOffset = (UINT8 *) RomBar; - RetStatus = EFI_NOT_FOUND; - - if (RomBar == NULL) { - return RetStatus; - } - ASSERT (((EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset)->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE); - - do { - EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) RomBarOffset; - if (EfiRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { - RomBarOffset += 512; - continue; - } - - Pcir = (PCI_DATA_STRUCTURE *) (RomBarOffset + EfiRomHeader->PcirOffset); - ASSERT (Pcir->Signature == PCI_DATA_STRUCTURE_SIGNATURE); - ImageSize = (UINT32) (Pcir->ImageLength * 512); - Indicator = Pcir->Indicator; - - // - // Skip the image if it is not an EFI PCI Option ROM image - // - if (Pcir->CodeType != PCI_CODE_TYPE_EFI_IMAGE) { - goto NextImage; - } - - // - // Skip the EFI PCI Option ROM image if its machine type is not supported - // - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (EfiRomHeader->EfiMachineType)) { - goto NextImage; - } - - // - // Ignore the EFI PCI Option ROM image if it is an EFI application - // - if (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) { - goto NextImage; - } - - // - // Create Pci Option Rom Image device path header - // - EfiOpRomImageNode.Header.Type = MEDIA_DEVICE_PATH; - EfiOpRomImageNode.Header.SubType = MEDIA_RELATIVE_OFFSET_RANGE_DP; - SetDevicePathNodeLength (&EfiOpRomImageNode.Header, sizeof (EfiOpRomImageNode)); - EfiOpRomImageNode.StartingOffset = (UINTN) RomBarOffset - (UINTN) RomBar; - EfiOpRomImageNode.EndingOffset = (UINTN) RomBarOffset + ImageSize - 1 - (UINTN) RomBar; - - PciOptionRomImageDevicePath = AppendDevicePathNode (PciDevice->DevicePath, &EfiOpRomImageNode.Header); - ASSERT (PciOptionRomImageDevicePath != NULL); - - // - // load image and start image - // - BufferSize = 0; - Buffer = NULL; - ImageHandle = NULL; - - Status = gBS->LoadImage ( - FALSE, - gPciBusDriverBinding.DriverBindingHandle, - PciOptionRomImageDevicePath, - Buffer, - BufferSize, - &ImageHandle - ); - - FreePool (PciOptionRomImageDevicePath); - - if (!EFI_ERROR (Status)) { - Status = gBS->StartImage (ImageHandle, NULL, NULL); - if (!EFI_ERROR (Status)) { - AddDriver (PciDevice, ImageHandle); - PciRomAddImageMapping ( - ImageHandle, - PciDevice->PciRootBridgeIo->SegmentNumber, - PciDevice->BusNumber, - PciDevice->DeviceNumber, - PciDevice->FunctionNumber, - (UINT64) (UINTN) PciDevice->PciIo.RomImage, - PciDevice->PciIo.RomSize - ); - RetStatus = EFI_SUCCESS; - } - } - -NextImage: - RomBarOffset += ImageSize; - - } while (((Indicator & 0x80) == 0x00) && ((UINTN) (RomBarOffset - (UINT8 *) RomBar) < PciDevice->RomSize)); - - return RetStatus; -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h deleted file mode 100644 index 25f78a417f..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciOptionRomSupport.h +++ /dev/null @@ -1,142 +0,0 @@ -/** @file - PCI Rom supporting funtions declaration for PCI Bus module. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_OPTION_ROM_SUPPORT_H_ -#define _EFI_PCI_OPTION_ROM_SUPPORT_H_ - - -/** - Initialize a PCI LoadFile2 instance. - - @param PciIoDevice PCI IO Device. - -**/ -VOID -InitializePciLoadFile2 ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -/** - Causes the driver to load a specified file. - - @param This Indicates a pointer to the calling context. - @param FilePath The device specific path of the file to load. - @param BootPolicy Should always be FALSE. - @param BufferSize On input the size of Buffer in bytes. On output with a return - code of EFI_SUCCESS, the amount of data transferred to Buffer. - On output with a return code of EFI_BUFFER_TOO_SMALL, - the size of Buffer required to retrieve the requested file. - @param Buffer The memory buffer to transfer the file to. If Buffer is NULL, - then no the size of the requested file is returned in BufferSize. - - @retval EFI_SUCCESS The file was loaded. - @retval EFI_UNSUPPORTED BootPolicy is TRUE. - @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or - BufferSize is NULL. - @retval EFI_NOT_FOUND Not found PCI Option Rom on PCI device. - @retval EFI_DEVICE_ERROR Failed to decompress PCI Option Rom image. - @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. - BufferSize has been updated with the size needed to complete the request. - -**/ -EFI_STATUS -EFIAPI -LoadFile2 ( - IN EFI_LOAD_FILE2_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN BOOLEAN BootPolicy, - IN OUT UINTN *BufferSize, - IN VOID *Buffer OPTIONAL - ); - -/** - Check if the RomImage contains EFI Images. - - @param RomImage The ROM address of Image for check. - @param RomSize Size of ROM for check. - - @retval TRUE ROM contain EFI Image. - @retval FALSE ROM not contain EFI Image. - -**/ -BOOLEAN -ContainEfiImage ( - IN VOID *RomImage, - IN UINT64 RomSize - ); - -/** - Get Pci device's oprom information. - - @param PciIoDevice Input Pci device instance. - Output Pci device instance with updated OptionRom size. - - @retval EFI_NOT_FOUND Pci device has not Option Rom. - @retval EFI_SUCCESS Pci device has Option Rom. - -**/ -EFI_STATUS -GetOpRomInfo ( - IN OUT PCI_IO_DEVICE *PciIoDevice - ); - -/** - Load Option Rom image for specified PCI device. - - @param PciDevice Pci device instance. - @param RomBase Base address of Option Rom. - - @retval EFI_OUT_OF_RESOURCES No enough memory to hold image. - @retval EFI_SUCESS Successfully loaded Option Rom. - -**/ -EFI_STATUS -LoadOpRomImage ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT64 RomBase - ); - -/** - Enable/Disable Option Rom decode. - - @param PciDevice Pci device instance. - @param RomBarIndex The BAR index of the standard PCI Configuration header to use as the - base address for resource range. The legal range for this field is 0..5. - @param RomBar Base address of Option Rom. - @param Enable Flag for enable/disable decode. - -**/ -VOID -RomDecode ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT8 RomBarIndex, - IN UINT32 RomBar, - IN BOOLEAN Enable - ); - -/** - Load and start the Option Rom image. - - @param PciDevice Pci device instance. - - @retval EFI_SUCCESS Successfully loaded and started PCI Option Rom image. - @retval EFI_NOT_FOUND Failed to process PCI Option Rom image. - -**/ -EFI_STATUS -ProcessOpRomImage ( - IN PCI_IO_DEVICE *PciDevice - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.c deleted file mode 100644 index ab655e7657..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.c +++ /dev/null @@ -1,88 +0,0 @@ -/** @file - Power management support fucntions implementation for PCI Bus module. - -Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -/** - This function is intended to turn off PWE assertion and - put the device to D0 state if the device supports - PCI Power Management. - - @param PciIoDevice PCI device instance. - - @retval EFI_UNSUPPORTED PCI Device does not support power management. - @retval EFI_SUCCESS Turned off PWE successfully. - -**/ -EFI_STATUS -ResetPowerManagementFeature ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - EFI_STATUS Status; - UINT8 PowerManagementRegBlock; - UINT16 PowerManagementCSR; - - PowerManagementRegBlock = 0; - - Status = LocateCapabilityRegBlock ( - PciIoDevice, - EFI_PCI_CAPABILITY_ID_PMI, - &PowerManagementRegBlock, - NULL - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Turn off the PWE assertion and put the device into D0 State - // - - // - // Read PMCSR - // - Status = PciIoDevice->PciIo.Pci.Read ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint16, - PowerManagementRegBlock + 4, - 1, - &PowerManagementCSR - ); - - if (!EFI_ERROR (Status)) { - // - // Clear PME_Status bit - // - PowerManagementCSR |= BIT15; - // - // Clear PME_En bit. PowerState = D0. - // - PowerManagementCSR &= ~(BIT8 | BIT1 | BIT0); - - // - // Write PMCSR - // - Status = PciIoDevice->PciIo.Pci.Write ( - &PciIoDevice->PciIo, - EfiPciIoWidthUint16, - PowerManagementRegBlock + 4, - 1, - &PowerManagementCSR - ); - } - return Status; -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.h deleted file mode 100644 index 45ba59f286..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciPowerManagement.h +++ /dev/null @@ -1,34 +0,0 @@ -/** @file - Power management support fucntions delaration for PCI Bus module. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_POWER_MANAGEMENT_H_ -#define _EFI_PCI_POWER_MANAGEMENT_H_ - -/** - This function is intended to turn off PWE assertion and - put the device to D0 state if the device supports - PCI Power Management. - - @param PciIoDevice PCI device instance. - - @retval EFI_UNSUPPORTED PCI Device does not support power management. - @retval EFI_SUCCESS Turned off PWE successfully. - -**/ -EFI_STATUS -ResetPowerManagementFeature ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c deleted file mode 100644 index e12d59f1d0..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c +++ /dev/null @@ -1,2291 +0,0 @@ -/** @file - PCI resouces support functions implemntation for PCI Bus module. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -// -// The default policy for the PCI bus driver is NOT to reserve I/O ranges for both ISA aliases and VGA aliases. -// -BOOLEAN mReserveIsaAliases = FALSE; -BOOLEAN mReserveVgaAliases = FALSE; -BOOLEAN mPolicyDetermined = FALSE; - -/** - The function is used to skip VGA range. - - @param Start Returned start address including VGA range. - @param Length The length of VGA range. - -**/ -VOID -SkipVGAAperture ( - OUT UINT64 *Start, - IN UINT64 Length - ) -{ - UINT64 Original; - UINT64 Mask; - UINT64 StartOffset; - UINT64 LimitOffset; - - ASSERT (Start != NULL); - // - // For legacy VGA, bit 10 to bit 15 is not decoded - // - Mask = 0x3FF; - - Original = *Start; - StartOffset = Original & Mask; - LimitOffset = ((*Start) + Length - 1) & Mask; - if (LimitOffset >= VGABASE1) { - *Start = *Start - StartOffset + VGALIMIT2 + 1; - } -} - -/** - This function is used to skip ISA aliasing aperture. - - @param Start Returned start address including ISA aliasing aperture. - @param Length The length of ISA aliasing aperture. - -**/ -VOID -SkipIsaAliasAperture ( - OUT UINT64 *Start, - IN UINT64 Length - ) -{ - - UINT64 Original; - UINT64 Mask; - UINT64 StartOffset; - UINT64 LimitOffset; - - ASSERT (Start != NULL); - - // - // For legacy ISA, bit 10 to bit 15 is not decoded - // - Mask = 0x3FF; - - Original = *Start; - StartOffset = Original & Mask; - LimitOffset = ((*Start) + Length - 1) & Mask; - - if (LimitOffset >= ISABASE) { - *Start = *Start - StartOffset + ISALIMIT + 1; - } -} - -/** - This function inserts a resource node into the resource list. - The resource list is sorted in descend order. - - @param Bridge PCI resource node for bridge. - @param ResNode Resource node want to be inserted. - -**/ -VOID -InsertResourceNode ( - IN OUT PCI_RESOURCE_NODE *Bridge, - IN PCI_RESOURCE_NODE *ResNode - ) -{ - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Temp; - UINT64 ResNodeAlignRest; - UINT64 TempAlignRest; - - ASSERT (Bridge != NULL); - ASSERT (ResNode != NULL); - - InsertHeadList (&Bridge->ChildList, &ResNode->Link); - - CurrentLink = Bridge->ChildList.ForwardLink->ForwardLink; - while (CurrentLink != &Bridge->ChildList) { - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (ResNode->Alignment > Temp->Alignment) { - break; - } else if (ResNode->Alignment == Temp->Alignment) { - ResNodeAlignRest = ResNode->Length & ResNode->Alignment; - TempAlignRest = Temp->Length & Temp->Alignment; - if ((ResNodeAlignRest == 0) || (ResNodeAlignRest >= TempAlignRest)) { - break; - } - } - - SwapListEntries (&ResNode->Link, CurrentLink); - - CurrentLink = ResNode->Link.ForwardLink; - } -} - -/** - This routine is used to merge two different resource trees in need of - resoure degradation. - - For example, if an upstream PPB doesn't support, - prefetchable memory decoding, the PCI bus driver will choose to call this function - to merge prefectchable memory resource list into normal memory list. - - If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource - type. - If Dst is NULL or Res is NULL, ASSERT (). - - @param Dst Point to destination resource tree. - @param Res Point to source resource tree. - @param TypeMerge If the TypeMerge is TRUE, Res resource type is changed to the type of - destination resource type. - -**/ -VOID -MergeResourceTree ( - IN PCI_RESOURCE_NODE *Dst, - IN PCI_RESOURCE_NODE *Res, - IN BOOLEAN TypeMerge - ) -{ - - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Temp; - - ASSERT (Dst != NULL); - ASSERT (Res != NULL); - - while (!IsListEmpty (&Res->ChildList)) { - CurrentLink = Res->ChildList.ForwardLink; - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (TypeMerge) { - Temp->ResType = Dst->ResType; - } - - RemoveEntryList (CurrentLink); - InsertResourceNode (Dst, Temp); - } -} - -/** - This function is used to calculate the IO16 aperture - for a bridge. - - @param Bridge PCI resource node for bridge. - -**/ -VOID -CalculateApertureIo16 ( - IN PCI_RESOURCE_NODE *Bridge - ) -{ - EFI_STATUS Status; - UINT64 Aperture; - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Node; - UINT64 Offset; - EFI_PCI_PLATFORM_POLICY PciPolicy; - UINT64 PaddingAperture; - - if (!mPolicyDetermined) { - // - // Check PciPlatform policy - // - Status = EFI_NOT_FOUND; - PciPolicy = 0; - if (gPciPlatformProtocol != NULL) { - Status = gPciPlatformProtocol->GetPlatformPolicy ( - gPciPlatformProtocol, - &PciPolicy - ); - } - - if (EFI_ERROR (Status) && gPciOverrideProtocol != NULL) { - Status = gPciOverrideProtocol->GetPlatformPolicy ( - gPciOverrideProtocol, - &PciPolicy - ); - } - - if (!EFI_ERROR (Status)) { - if ((PciPolicy & EFI_RESERVE_ISA_IO_ALIAS) != 0) { - mReserveIsaAliases = TRUE; - } - if ((PciPolicy & EFI_RESERVE_VGA_IO_ALIAS) != 0) { - mReserveVgaAliases = TRUE; - } - } - mPolicyDetermined = TRUE; - } - - Aperture = 0; - PaddingAperture = 0; - - if (Bridge == NULL) { - return ; - } - - // - // Assume the bridge is aligned - // - for ( CurrentLink = GetFirstNode (&Bridge->ChildList) - ; !IsNull (&Bridge->ChildList, CurrentLink) - ; CurrentLink = GetNextNode (&Bridge->ChildList, CurrentLink) - ) { - - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - if (Node->ResourceUsage == PciResUsagePadding) { - ASSERT (PaddingAperture == 0); - PaddingAperture = Node->Length; - continue; - } - // - // Consider the aperture alignment - // - Offset = Aperture & (Node->Alignment); - - if (Offset != 0) { - - Aperture = Aperture + (Node->Alignment + 1) - Offset; - - } - - // - // IsaEnable and VGAEnable can not be implemented now. - // If both of them are enabled, then the IO resource would - // become too limited to meet the requirement of most of devices. - // - if (mReserveIsaAliases || mReserveVgaAliases) { - if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci)) && !IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) { - // - // Check if there is need to support ISA/VGA decoding - // If so, we need to avoid isa/vga aliasing range - // - if (mReserveIsaAliases) { - SkipIsaAliasAperture ( - &Aperture, - Node->Length - ); - Offset = Aperture & (Node->Alignment); - if (Offset != 0) { - Aperture = Aperture + (Node->Alignment + 1) - Offset; - } - } else if (mReserveVgaAliases) { - SkipVGAAperture ( - &Aperture, - Node->Length - ); - Offset = Aperture & (Node->Alignment); - if (Offset != 0) { - Aperture = Aperture + (Node->Alignment + 1) - Offset; - } - } - } - } - - Node->Offset = Aperture; - - // - // Increment aperture by the length of node - // - Aperture += Node->Length; - } - - // - // Adjust the aperture with the bridge's alignment - // - Offset = Aperture & (Bridge->Alignment); - - if (Offset != 0) { - Aperture = Aperture + (Bridge->Alignment + 1) - Offset; - } - - Bridge->Length = Aperture; - // - // At last, adjust the bridge's alignment to the first child's alignment - // if the bridge has at least one child - // - CurrentLink = Bridge->ChildList.ForwardLink; - if (CurrentLink != &Bridge->ChildList) { - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - if (Node->Alignment > Bridge->Alignment) { - Bridge->Alignment = Node->Alignment; - } - } - - // - // Hotplug controller needs padding resources. - // Use the larger one between the padding resource and actual occupied resource. - // - Bridge->Length = MAX (Bridge->Length, PaddingAperture); -} - -/** - This function is used to calculate the resource aperture - for a given bridge device. - - @param Bridge PCI resouce node for given bridge device. - -**/ -VOID -CalculateResourceAperture ( - IN PCI_RESOURCE_NODE *Bridge - ) -{ - UINT64 Aperture; - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Node; - UINT64 PaddingAperture; - UINT64 Offset; - - Aperture = 0; - PaddingAperture = 0; - - if (Bridge == NULL) { - return ; - } - - if (Bridge->ResType == PciBarTypeIo16) { - - CalculateApertureIo16 (Bridge); - return ; - } - - // - // Assume the bridge is aligned - // - for ( CurrentLink = GetFirstNode (&Bridge->ChildList) - ; !IsNull (&Bridge->ChildList, CurrentLink) - ; CurrentLink = GetNextNode (&Bridge->ChildList, CurrentLink) - ) { - - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - if (Node->ResourceUsage == PciResUsagePadding) { - ASSERT (PaddingAperture == 0); - PaddingAperture = Node->Length; - continue; - } - - // - // Apply padding resource if available - // - Offset = Aperture & (Node->Alignment); - - if (Offset != 0) { - - Aperture = Aperture + (Node->Alignment + 1) - Offset; - - } - - // - // Recode current aperture as a offset - // this offset will be used in future real allocation - // - Node->Offset = Aperture; - - // - // Increment aperture by the length of node - // - Aperture += Node->Length; - } - - // - // At last, adjust the aperture with the bridge's - // alignment - // - Offset = Aperture & (Bridge->Alignment); - if (Offset != 0) { - Aperture = Aperture + (Bridge->Alignment + 1) - Offset; - } - - // - // If the bridge has already padded the resource and the - // amount of padded resource is larger, then keep the - // padded resource - // - if (Bridge->Length < Aperture) { - Bridge->Length = Aperture; - } - - // - // Adjust the bridge's alignment to the first child's alignment - // if the bridge has at least one child - // - CurrentLink = Bridge->ChildList.ForwardLink; - if (CurrentLink != &Bridge->ChildList) { - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - if (Node->Alignment > Bridge->Alignment) { - Bridge->Alignment = Node->Alignment; - } - } - - // - // Hotplug controller needs padding resources. - // Use the larger one between the padding resource and actual occupied resource. - // - Bridge->Length = MAX (Bridge->Length, PaddingAperture); -} - -/** - Get IO/Memory resource infor for given PCI device. - - @param PciDev Pci device instance. - @param IoNode Resource info node for IO . - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -GetResourceFromDevice ( - IN PCI_IO_DEVICE *PciDev, - IN OUT PCI_RESOURCE_NODE *IoNode, - IN OUT PCI_RESOURCE_NODE *Mem32Node, - IN OUT PCI_RESOURCE_NODE *PMem32Node, - IN OUT PCI_RESOURCE_NODE *Mem64Node, - IN OUT PCI_RESOURCE_NODE *PMem64Node - ) -{ - - UINT8 Index; - PCI_RESOURCE_NODE *Node; - BOOLEAN ResourceRequested; - - Node = NULL; - ResourceRequested = FALSE; - - for (Index = 0; Index < PCI_MAX_BAR; Index++) { - - switch ((PciDev->PciBar)[Index].BarType) { - - case PciBarTypeMem32: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypeMem32, - PciResUsageTypical - ); - - InsertResourceNode ( - Mem32Node, - Node - ); - - ResourceRequested = TRUE; - break; - - case PciBarTypeMem64: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypeMem64, - PciResUsageTypical - ); - - InsertResourceNode ( - Mem64Node, - Node - ); - - ResourceRequested = TRUE; - break; - - case PciBarTypePMem64: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypePMem64, - PciResUsageTypical - ); - - InsertResourceNode ( - PMem64Node, - Node - ); - - ResourceRequested = TRUE; - break; - - case PciBarTypePMem32: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypePMem32, - PciResUsageTypical - ); - - InsertResourceNode ( - PMem32Node, - Node - ); - ResourceRequested = TRUE; - break; - - case PciBarTypeIo16: - case PciBarTypeIo32: - - Node = CreateResourceNode ( - PciDev, - (PciDev->PciBar)[Index].Length, - (PciDev->PciBar)[Index].Alignment, - Index, - PciBarTypeIo16, - PciResUsageTypical - ); - - InsertResourceNode ( - IoNode, - Node - ); - ResourceRequested = TRUE; - break; - - case PciBarTypeUnknown: - break; - - default: - break; - } - } - - // - // Add VF resource - // - for (Index = 0; Index < PCI_MAX_BAR; Index++) { - - switch ((PciDev->VfPciBar)[Index].BarType) { - - case PciBarTypeMem32: - - Node = CreateVfResourceNode ( - PciDev, - (PciDev->VfPciBar)[Index].Length, - (PciDev->VfPciBar)[Index].Alignment, - Index, - PciBarTypeMem32, - PciResUsageTypical - ); - - InsertResourceNode ( - Mem32Node, - Node - ); - - break; - - case PciBarTypeMem64: - - Node = CreateVfResourceNode ( - PciDev, - (PciDev->VfPciBar)[Index].Length, - (PciDev->VfPciBar)[Index].Alignment, - Index, - PciBarTypeMem64, - PciResUsageTypical - ); - - InsertResourceNode ( - Mem64Node, - Node - ); - - break; - - case PciBarTypePMem64: - - Node = CreateVfResourceNode ( - PciDev, - (PciDev->VfPciBar)[Index].Length, - (PciDev->VfPciBar)[Index].Alignment, - Index, - PciBarTypePMem64, - PciResUsageTypical - ); - - InsertResourceNode ( - PMem64Node, - Node - ); - - break; - - case PciBarTypePMem32: - - Node = CreateVfResourceNode ( - PciDev, - (PciDev->VfPciBar)[Index].Length, - (PciDev->VfPciBar)[Index].Alignment, - Index, - PciBarTypePMem32, - PciResUsageTypical - ); - - InsertResourceNode ( - PMem32Node, - Node - ); - break; - - case PciBarTypeIo16: - case PciBarTypeIo32: - break; - - case PciBarTypeUnknown: - break; - - default: - break; - } - } - // If there is no resource requested from this device, - // then we indicate this device has been allocated naturally. - // - if (!ResourceRequested) { - PciDev->Allocated = TRUE; - } -} - -/** - This function is used to create a resource node. - - @param PciDev Pci device instance. - @param Length Length of Io/Memory resource. - @param Alignment Alignment of resource. - @param Bar Bar index. - @param ResType Type of resource: IO/Memory. - @param ResUsage Resource usage. - - @return PCI resource node created for given PCI device. - NULL means PCI resource node is not created. - -**/ -PCI_RESOURCE_NODE * -CreateResourceNode ( - IN PCI_IO_DEVICE *PciDev, - IN UINT64 Length, - IN UINT64 Alignment, - IN UINT8 Bar, - IN PCI_BAR_TYPE ResType, - IN PCI_RESOURCE_USAGE ResUsage - ) -{ - PCI_RESOURCE_NODE *Node; - - Node = NULL; - - Node = AllocateZeroPool (sizeof (PCI_RESOURCE_NODE)); - ASSERT (Node != NULL); - if (Node == NULL) { - return NULL; - } - - Node->Signature = PCI_RESOURCE_SIGNATURE; - Node->PciDev = PciDev; - Node->Length = Length; - Node->Alignment = Alignment; - Node->Bar = Bar; - Node->ResType = ResType; - Node->Reserved = FALSE; - Node->ResourceUsage = ResUsage; - InitializeListHead (&Node->ChildList); - - return Node; -} - -/** - This function is used to create a IOV VF resource node. - - @param PciDev Pci device instance. - @param Length Length of Io/Memory resource. - @param Alignment Alignment of resource. - @param Bar Bar index. - @param ResType Type of resource: IO/Memory. - @param ResUsage Resource usage. - - @return PCI resource node created for given VF PCI device. - NULL means PCI resource node is not created. - -**/ -PCI_RESOURCE_NODE * -CreateVfResourceNode ( - IN PCI_IO_DEVICE *PciDev, - IN UINT64 Length, - IN UINT64 Alignment, - IN UINT8 Bar, - IN PCI_BAR_TYPE ResType, - IN PCI_RESOURCE_USAGE ResUsage - ) -{ - PCI_RESOURCE_NODE *Node; - - Node = CreateResourceNode (PciDev, Length, Alignment, Bar, ResType, ResUsage); - if (Node == NULL) { - return Node; - } - - Node->Virtual = TRUE; - - return Node; -} - -/** - This function is used to extract resource request from - device node list. - - @param Bridge Pci device instance. - @param IoNode Resource info node for IO. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -CreateResourceMap ( - IN PCI_IO_DEVICE *Bridge, - IN OUT PCI_RESOURCE_NODE *IoNode, - IN OUT PCI_RESOURCE_NODE *Mem32Node, - IN OUT PCI_RESOURCE_NODE *PMem32Node, - IN OUT PCI_RESOURCE_NODE *Mem64Node, - IN OUT PCI_RESOURCE_NODE *PMem64Node - ) -{ - PCI_IO_DEVICE *Temp; - PCI_RESOURCE_NODE *IoBridge; - PCI_RESOURCE_NODE *Mem32Bridge; - PCI_RESOURCE_NODE *PMem32Bridge; - PCI_RESOURCE_NODE *Mem64Bridge; - PCI_RESOURCE_NODE *PMem64Bridge; - LIST_ENTRY *CurrentLink; - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { - - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); - - // - // Create resource nodes for this device by scanning the - // Bar array in the device private data - // If the upstream bridge doesn't support this device, - // no any resource node will be created for this device - // - GetResourceFromDevice ( - Temp, - IoNode, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - - if (IS_PCI_BRIDGE (&Temp->Pci)) { - - // - // If the device has children, create a bridge resource node for this PPB - // Note: For PPB, memory aperture is aligned with 1MB and IO aperture - // is aligned with 4KB (smaller alignments may be supported). - // - IoBridge = CreateResourceNode ( - Temp, - 0, - Temp->BridgeIoAlignment, - PPB_IO_RANGE, - PciBarTypeIo16, - PciResUsageTypical - ); - - Mem32Bridge = CreateResourceNode ( - Temp, - 0, - 0xFFFFF, - PPB_MEM32_RANGE, - PciBarTypeMem32, - PciResUsageTypical - ); - - PMem32Bridge = CreateResourceNode ( - Temp, - 0, - 0xFFFFF, - PPB_PMEM32_RANGE, - PciBarTypePMem32, - PciResUsageTypical - ); - - Mem64Bridge = CreateResourceNode ( - Temp, - 0, - 0xFFFFF, - PPB_MEM64_RANGE, - PciBarTypeMem64, - PciResUsageTypical - ); - - PMem64Bridge = CreateResourceNode ( - Temp, - 0, - 0xFFFFF, - PPB_PMEM64_RANGE, - PciBarTypePMem64, - PciResUsageTypical - ); - - // - // Recursively create resouce map on this bridge - // - CreateResourceMap ( - Temp, - IoBridge, - Mem32Bridge, - PMem32Bridge, - Mem64Bridge, - PMem64Bridge - ); - - if (ResourceRequestExisted (IoBridge)) { - InsertResourceNode ( - IoNode, - IoBridge - ); - } else { - FreePool (IoBridge); - IoBridge = NULL; - } - - // - // If there is node under this resource bridge, - // then calculate bridge's aperture of this type - // and insert it into the respective resource tree. - // If no, delete this resource bridge - // - if (ResourceRequestExisted (Mem32Bridge)) { - InsertResourceNode ( - Mem32Node, - Mem32Bridge - ); - } else { - FreePool (Mem32Bridge); - Mem32Bridge = NULL; - } - - // - // If there is node under this resource bridge, - // then calculate bridge's aperture of this type - // and insert it into the respective resource tree. - // If no, delete this resource bridge - // - if (ResourceRequestExisted (PMem32Bridge)) { - InsertResourceNode ( - PMem32Node, - PMem32Bridge - ); - } else { - FreePool (PMem32Bridge); - PMem32Bridge = NULL; - } - - // - // If there is node under this resource bridge, - // then calculate bridge's aperture of this type - // and insert it into the respective resource tree. - // If no, delete this resource bridge - // - if (ResourceRequestExisted (Mem64Bridge)) { - InsertResourceNode ( - Mem64Node, - Mem64Bridge - ); - } else { - FreePool (Mem64Bridge); - Mem64Bridge = NULL; - } - - // - // If there is node under this resource bridge, - // then calculate bridge's aperture of this type - // and insert it into the respective resource tree. - // If no, delete this resource bridge - // - if (ResourceRequestExisted (PMem64Bridge)) { - InsertResourceNode ( - PMem64Node, - PMem64Bridge - ); - } else { - FreePool (PMem64Bridge); - PMem64Bridge = NULL; - } - - } - - // - // If it is P2C, apply hard coded resource padding - // - if (IS_CARDBUS_BRIDGE (&Temp->Pci)) { - ResourcePaddingForCardBusBridge ( - Temp, - IoNode, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - // - // To do some platform specific resource padding ... - // - ResourcePaddingPolicy ( - Bridge, - IoNode, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - - // - // Degrade resource if necessary - // - DegradeResource ( - Bridge, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - - // - // Calculate resource aperture for this bridge device - // - CalculateResourceAperture (Mem32Node); - CalculateResourceAperture (PMem32Node); - CalculateResourceAperture (Mem64Node); - CalculateResourceAperture (PMem64Node); - CalculateResourceAperture (IoNode); -} - -/** - This function is used to do the resource padding for a specific platform. - - @param PciDev Pci device instance. - @param IoNode Resource info node for IO. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -ResourcePaddingPolicy ( - IN PCI_IO_DEVICE *PciDev, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ) -{ - // - // Create padding resource node - // - if (PciDev->ResourcePaddingDescriptors != NULL) { - ApplyResourcePadding ( - PciDev, - IoNode, - Mem32Node, - PMem32Node, - Mem64Node, - PMem64Node - ); - } -} - -/** - This function is used to degrade resource if the upstream bridge - doesn't support certain resource. Degradation path is - PMEM64 -> MEM64 -> MEM32 - PMEM64 -> PMEM32 -> MEM32 - IO32 -> IO16. - - @param Bridge Pci device instance. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -DegradeResource ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ) -{ - PCI_IO_DEVICE *Temp; - LIST_ENTRY *ChildDeviceLink; - LIST_ENTRY *ChildNodeLink; - LIST_ENTRY *NextChildNodeLink; - PCI_RESOURCE_NODE *TempNode; - - // - // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64 - // requests in case that if a legacy option ROM image can not access 64-bit resources. - // - ChildDeviceLink = Bridge->ChildList.ForwardLink; - while (ChildDeviceLink != NULL && ChildDeviceLink != &Bridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink); - if (Temp->RomSize != 0) { - if (!IsListEmpty (&Mem64Node->ChildList)) { - ChildNodeLink = Mem64Node->ChildList.ForwardLink; - while (ChildNodeLink != &Mem64Node->ChildList) { - TempNode = RESOURCE_NODE_FROM_LINK (ChildNodeLink); - NextChildNodeLink = ChildNodeLink->ForwardLink; - - if (TempNode->PciDev == Temp) { - RemoveEntryList (ChildNodeLink); - InsertResourceNode (Mem32Node, TempNode); - } - ChildNodeLink = NextChildNodeLink; - } - } - - if (!IsListEmpty (&PMem64Node->ChildList)) { - ChildNodeLink = PMem64Node->ChildList.ForwardLink; - while (ChildNodeLink != &PMem64Node->ChildList) { - TempNode = RESOURCE_NODE_FROM_LINK (ChildNodeLink); - NextChildNodeLink = ChildNodeLink->ForwardLink; - - if (TempNode->PciDev == Temp) { - RemoveEntryList (ChildNodeLink); - InsertResourceNode (PMem32Node, TempNode); - } - ChildNodeLink = NextChildNodeLink; - } - } - - } - ChildDeviceLink = ChildDeviceLink->ForwardLink; - } - - // - // If firmware is in 32-bit mode, - // then degrade PMEM64/MEM64 requests - // - if (sizeof (UINTN) <= 4) { - MergeResourceTree ( - Mem32Node, - Mem64Node, - TRUE - ); - - MergeResourceTree ( - PMem32Node, - PMem64Node, - TRUE - ); - } else { - // - // if the bridge does not support MEM64, degrade MEM64 to MEM32 - // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) { - MergeResourceTree ( - Mem32Node, - Mem64Node, - TRUE - ); - } - - // - // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32 - // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) { - MergeResourceTree ( - PMem32Node, - PMem64Node, - TRUE - ); - } - - // - // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied - // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32. - // - if (!IsListEmpty (&PMem64Node->ChildList) && Bridge->Parent != NULL) { - MergeResourceTree ( - Mem32Node, - PMem32Node, - TRUE - ); - } - } - - // - // If bridge doesn't support Pmem32 - // degrade it to mem32 - // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED)) { - MergeResourceTree ( - Mem32Node, - PMem32Node, - TRUE - ); - } - - // - // if root bridge supports combined Pmem Mem decoding - // merge these two type of resource - // - if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) { - MergeResourceTree ( - Mem32Node, - PMem32Node, - FALSE - ); - - // - // No need to check if to degrade MEM64 after merge, because - // if there are PMEM64 still here, 64-bit decode should be supported - // by the root bride. - // - MergeResourceTree ( - Mem64Node, - PMem64Node, - FALSE - ); - } -} - -/** - Test whether bridge device support decode resource. - - @param Bridge Bridge device instance. - @param Decode Decode type according to resource type. - - @return TRUE The bridge device support decode resource. - @return FALSE The bridge device don't support decode resource. - -**/ -BOOLEAN -BridgeSupportResourceDecode ( - IN PCI_IO_DEVICE *Bridge, - IN UINT32 Decode - ) -{ - if (((Bridge->Decodes) & Decode) != 0) { - return TRUE; - } - - return FALSE; -} - -/** - This function is used to program the resource allocated - for each resource node under specified bridge. - - @param Base Base address of resource to be progammed. - @param Bridge PCI resource node for the bridge device. - - @retval EFI_SUCCESS Successfully to program all resouces - on given PCI bridge device. - @retval EFI_OUT_OF_RESOURCES Base is all one. - -**/ -EFI_STATUS -ProgramResource ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Bridge - ) -{ - LIST_ENTRY *CurrentLink; - PCI_RESOURCE_NODE *Node; - EFI_STATUS Status; - - if (Base == gAllOne) { - return EFI_OUT_OF_RESOURCES; - } - - CurrentLink = Bridge->ChildList.ForwardLink; - - while (CurrentLink != &Bridge->ChildList) { - - Node = RESOURCE_NODE_FROM_LINK (CurrentLink); - - if (!IS_PCI_BRIDGE (&(Node->PciDev->Pci))) { - - if (IS_CARDBUS_BRIDGE (&(Node->PciDev->Pci))) { - // - // Program the PCI Card Bus device - // - ProgramP2C (Base, Node); - } else { - // - // Program the PCI device BAR - // - ProgramBar (Base, Node); - } - } else { - // - // Program the PCI devices under this bridge - // - Status = ProgramResource (Base + Node->Offset, Node); - if (EFI_ERROR (Status)) { - return Status; - } - - ProgramPpbApperture (Base, Node); - } - - CurrentLink = CurrentLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -/** - Program Bar register for PCI device. - - @param Base Base address for PCI device resource to be progammed. - @param Node Point to resoure node structure. - -**/ -VOID -ProgramBar ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Address; - UINT32 Address32; - - ASSERT (Node->Bar < PCI_MAX_BAR); - - // - // Check VF BAR - // - if (Node->Virtual) { - ProgramVfBar (Base, Node); - return; - } - - Address = 0; - PciIo = &(Node->PciDev->PciIo); - - Address = Base + Node->Offset; - - // - // Indicate pci bus driver has allocated - // resource for this device - // It might be a temporary solution here since - // pci device could have multiple bar - // - Node->PciDev->Allocated = TRUE; - - switch ((Node->PciDev->PciBar[Node->Bar]).BarType) { - - case PciBarTypeIo16: - case PciBarTypeIo32: - case PciBarTypeMem32: - case PciBarTypePMem32: - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - - break; - - case PciBarTypeMem64: - case PciBarTypePMem64: - - Address32 = (UINT32) (Address & 0x00000000FFFFFFFF); - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address32 - ); - - Address32 = (UINT32) RShiftU64 (Address, 32); - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4), - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - - break; - - default: - break; - } -} - -/** - Program IOV VF Bar register for PCI device. - - @param Base Base address for PCI device resource to be progammed. - @param Node Point to resoure node structure. - -**/ -EFI_STATUS -ProgramVfBar ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Address; - UINT32 Address32; - - ASSERT (Node->Bar < PCI_MAX_BAR); - ASSERT (Node->Virtual); - - Address = 0; - PciIo = &(Node->PciDev->PciIo); - - Address = Base + Node->Offset; - - // - // Indicate pci bus driver has allocated - // resource for this device - // It might be a temporary solution here since - // pci device could have multiple bar - // - Node->PciDev->Allocated = TRUE; - - switch ((Node->PciDev->VfPciBar[Node->Bar]).BarType) { - - case PciBarTypeMem32: - case PciBarTypePMem32: - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->VfPciBar[Node->Bar]).Offset, - 1, - &Address - ); - - Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address; - break; - - case PciBarTypeMem64: - case PciBarTypePMem64: - - Address32 = (UINT32) (Address & 0x00000000FFFFFFFF); - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->VfPciBar[Node->Bar]).Offset, - 1, - &Address32 - ); - - Address32 = (UINT32) RShiftU64 (Address, 32); - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - ((Node->PciDev->VfPciBar[Node->Bar]).Offset + 4), - 1, - &Address32 - ); - - Node->PciDev->VfPciBar[Node->Bar].BaseAddress = Address; - break; - - case PciBarTypeIo16: - case PciBarTypeIo32: - break; - - default: - break; - } - - return EFI_SUCCESS; -} - -/** - Program PCI-PCI bridge apperture. - - @param Base Base address for resource. - @param Node Point to resoure node structure. - -**/ -VOID -ProgramPpbApperture ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Address; - UINT32 Address32; - - Address = 0; - // - // If no device resource of this PPB, return anyway - // Apperture is set default in the initialization code - // - if (Node->Length == 0 || Node->ResourceUsage == PciResUsagePadding) { - // - // For padding resource node, just ignore when programming - // - return ; - } - - PciIo = &(Node->PciDev->PciIo); - Address = Base + Node->Offset; - - // - // Indicate the PPB resource has been allocated - // - Node->PciDev->Allocated = TRUE; - - switch (Node->Bar) { - - case PPB_BAR_0: - case PPB_BAR_1: - switch ((Node->PciDev->PciBar[Node->Bar]).BarType) { - - case PciBarTypeIo16: - case PciBarTypeIo32: - case PciBarTypeMem32: - case PciBarTypePMem32: - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - case PciBarTypeMem64: - case PciBarTypePMem64: - - Address32 = (UINT32) (Address & 0x00000000FFFFFFFF); - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address32 - ); - - Address32 = (UINT32) RShiftU64 (Address, 32); - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (UINT8) ((Node->PciDev->PciBar[Node->Bar]).Offset + 4), - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - default: - break; - } - break; - - case PPB_IO_RANGE: - - Address32 = ((UINT32) (Address)) >> 8; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint8, - 0x1C, - 1, - &Address32 - ); - - Address32 >>= 8; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0x30, - 1, - &Address32 - ); - - Address32 = (UINT32) (Address + Node->Length - 1); - Address32 = ((UINT32) (Address32)) >> 8; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint8, - 0x1D, - 1, - &Address32 - ); - - Address32 >>= 8; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0x32, - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - case PPB_MEM32_RANGE: - - Address32 = ((UINT32) (Address)) >> 16; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0x20, - 1, - &Address32 - ); - - Address32 = (UINT32) (Address + Node->Length - 1); - Address32 = ((UINT32) (Address32)) >> 16; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0x22, - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - case PPB_PMEM32_RANGE: - case PPB_PMEM64_RANGE: - - Address32 = ((UINT32) (Address)) >> 16; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0x24, - 1, - &Address32 - ); - - Address32 = (UINT32) (Address + Node->Length - 1); - Address32 = ((UINT32) (Address32)) >> 16; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - 0x26, - 1, - &Address32 - ); - - Address32 = (UINT32) RShiftU64 (Address, 32); - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - 0x28, - 1, - &Address32 - ); - - Address32 = (UINT32) RShiftU64 ((Address + Node->Length - 1), 32); - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - 0x2C, - 1, - &Address32 - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - default: - break; - } -} - -/** - Program parent bridge for Option Rom. - - @param PciDevice Pci deivce instance. - @param OptionRomBase Base address for Optiona Rom. - @param Enable Enable or disable PCI memory. - -**/ -VOID -ProgrameUpstreamBridgeForRom ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT32 OptionRomBase, - IN BOOLEAN Enable - ) -{ - PCI_IO_DEVICE *Parent; - PCI_RESOURCE_NODE Node; - // - // For root bridge, just return. - // - Parent = PciDevice->Parent; - ZeroMem (&Node, sizeof (Node)); - while (Parent != NULL) { - if (!IS_PCI_BRIDGE (&Parent->Pci)) { - break; - } - - Node.PciDev = Parent; - Node.Length = PciDevice->RomSize; - Node.Alignment = 0; - Node.Bar = PPB_MEM32_RANGE; - Node.ResType = PciBarTypeMem32; - Node.Offset = 0; - - // - // Program PPB to only open a single <= 16MB apperture - // - if (Enable) { - ProgramPpbApperture (OptionRomBase, &Node); - PCI_ENABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE); - } else { - InitializePpb (Parent); - PCI_DISABLE_COMMAND_REGISTER (Parent, EFI_PCI_COMMAND_MEMORY_SPACE); - } - - Parent = Parent->Parent; - } -} - -/** - Test whether resource exists for a bridge. - - @param Bridge Point to resource node for a bridge. - - @retval TRUE There is resource on the given bridge. - @retval FALSE There isn't resource on the given bridge. - -**/ -BOOLEAN -ResourceRequestExisted ( - IN PCI_RESOURCE_NODE *Bridge - ) -{ - if (Bridge != NULL) { - if (!IsListEmpty (&Bridge->ChildList) || Bridge->Length != 0) { - return TRUE; - } - } - - return FALSE; -} - -/** - Initialize resource pool structure. - - @param ResourcePool Point to resource pool structure. This pool - is reset to all zero when returned. - @param ResourceType Type of resource. - -**/ -VOID -InitializeResourcePool ( - IN OUT PCI_RESOURCE_NODE *ResourcePool, - IN PCI_BAR_TYPE ResourceType - ) -{ - ZeroMem (ResourcePool, sizeof (PCI_RESOURCE_NODE)); - ResourcePool->ResType = ResourceType; - ResourcePool->Signature = PCI_RESOURCE_SIGNATURE; - InitializeListHead (&ResourcePool->ChildList); -} - -/** - Destory given resource tree. - - @param Bridge PCI resource root node of resource tree. - -**/ -VOID -DestroyResourceTree ( - IN PCI_RESOURCE_NODE *Bridge - ) -{ - PCI_RESOURCE_NODE *Temp; - LIST_ENTRY *CurrentLink; - - while (!IsListEmpty (&Bridge->ChildList)) { - - CurrentLink = Bridge->ChildList.ForwardLink; - - Temp = RESOURCE_NODE_FROM_LINK (CurrentLink); - ASSERT (Temp); - - RemoveEntryList (CurrentLink); - - if (IS_PCI_BRIDGE (&(Temp->PciDev->Pci))) { - DestroyResourceTree (Temp); - } - - FreePool (Temp); - } -} - -/** - Insert resource padding for P2C. - - @param PciDev Pci device instance. - @param IoNode Resource info node for IO. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -ResourcePaddingForCardBusBridge ( - IN PCI_IO_DEVICE *PciDev, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ) -{ - PCI_RESOURCE_NODE *Node; - - Node = NULL; - - // - // Memory Base/Limit Register 0 - // Bar 1 denodes memory range 0 - // - Node = CreateResourceNode ( - PciDev, - 0x2000000, - 0x1ffffff, - 1, - PciBarTypeMem32, - PciResUsagePadding - ); - - InsertResourceNode ( - Mem32Node, - Node - ); - - // - // Memory Base/Limit Register 1 - // Bar 2 denodes memory range1 - // - Node = CreateResourceNode ( - PciDev, - 0x2000000, - 0x1ffffff, - 2, - PciBarTypePMem32, - PciResUsagePadding - ); - - InsertResourceNode ( - PMem32Node, - Node - ); - - // - // Io Base/Limit - // Bar 3 denodes io range 0 - // - Node = CreateResourceNode ( - PciDev, - 0x100, - 0xff, - 3, - PciBarTypeIo16, - PciResUsagePadding - ); - - InsertResourceNode ( - IoNode, - Node - ); - - // - // Io Base/Limit - // Bar 4 denodes io range 0 - // - Node = CreateResourceNode ( - PciDev, - 0x100, - 0xff, - 4, - PciBarTypeIo16, - PciResUsagePadding - ); - - InsertResourceNode ( - IoNode, - Node - ); -} - -/** - Program PCI Card device register for given resource node. - - @param Base Base address of PCI Card device to be programmed. - @param Node Given resource node. - -**/ -VOID -ProgramP2C ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Address; - UINT64 TempAddress; - UINT16 BridgeControl; - - Address = 0; - PciIo = &(Node->PciDev->PciIo); - - Address = Base + Node->Offset; - - // - // Indicate pci bus driver has allocated - // resource for this device - // It might be a temporary solution here since - // pci device could have multiple bar - // - Node->PciDev->Allocated = TRUE; - - switch (Node->Bar) { - - case P2C_BAR_0: - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - (Node->PciDev->PciBar[Node->Bar]).Offset, - 1, - &Address - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - break; - - case P2C_MEM_1: - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PCI_CARD_MEMORY_BASE_0, - 1, - &Address - ); - - TempAddress = Address + Node->Length - 1; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PCI_CARD_MEMORY_LIMIT_0, - 1, - &TempAddress - ); - - if (Node->ResType == PciBarTypeMem32) { - // - // Set non-prefetchable bit - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PCI_CARD_BRIDGE_CONTROL, - 1, - &BridgeControl - ); - - BridgeControl &= (UINT16) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - PCI_CARD_BRIDGE_CONTROL, - 1, - &BridgeControl - ); - - } else { - // - // Set pre-fetchable bit - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PCI_CARD_BRIDGE_CONTROL, - 1, - &BridgeControl - ); - - BridgeControl |= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - PCI_CARD_BRIDGE_CONTROL, - 1, - &BridgeControl - ); - } - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; - - break; - - case P2C_MEM_2: - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PCI_CARD_MEMORY_BASE_1, - 1, - &Address - ); - - TempAddress = Address + Node->Length - 1; - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PCI_CARD_MEMORY_LIMIT_1, - 1, - &TempAddress - ); - - if (Node->ResType == PciBarTypeMem32) { - - // - // Set non-prefetchable bit - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PCI_CARD_BRIDGE_CONTROL, - 1, - &BridgeControl - ); - - BridgeControl &= (UINT16) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE); - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - PCI_CARD_BRIDGE_CONTROL, - 1, - &BridgeControl - ); - - } else { - - // - // Set pre-fetchable bit - // - PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint16, - PCI_CARD_BRIDGE_CONTROL, - 1, - &BridgeControl - ); - - BridgeControl |= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - PCI_CARD_BRIDGE_CONTROL, - 1, - &BridgeControl - ); - } - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; - break; - - case P2C_IO_1: - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PCI_CARD_IO_BASE_0_LOWER, - 1, - &Address - ); - - TempAddress = Address + Node->Length - 1; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PCI_CARD_IO_LIMIT_0_LOWER, - 1, - &TempAddress - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; - - break; - - case P2C_IO_2: - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PCI_CARD_IO_BASE_1_LOWER, - 1, - &Address - ); - - TempAddress = Address + Node->Length - 1; - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint32, - PCI_CARD_IO_LIMIT_1_LOWER, - 1, - &TempAddress - ); - - Node->PciDev->PciBar[Node->Bar].BaseAddress = Address; - Node->PciDev->PciBar[Node->Bar].Length = Node->Length; - Node->PciDev->PciBar[Node->Bar].BarType = Node->ResType; - break; - - default: - break; - } -} - -/** - Create padding resource node. - - @param PciDev Pci device instance. - @param IoNode Resource info node for IO. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -ApplyResourcePadding ( - IN PCI_IO_DEVICE *PciDev, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ) -{ - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; - PCI_RESOURCE_NODE *Node; - UINT8 DummyBarIndex; - - DummyBarIndex = 0; - Ptr = PciDev->ResourcePaddingDescriptors; - - while (((EFI_ACPI_END_TAG_DESCRIPTOR *) Ptr)->Desc != ACPI_END_TAG_DESCRIPTOR) { - - if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) { - if (Ptr->AddrLen != 0) { - - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypeIo16, - PciResUsagePadding - ); - InsertResourceNode ( - IoNode, - Node - ); - } - - Ptr++; - continue; - } - - if (Ptr->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { - - if (Ptr->AddrSpaceGranularity == 32) { - - // - // prefechable - // - if (Ptr->SpecificFlag == 0x6) { - if (Ptr->AddrLen != 0) { - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypePMem32, - PciResUsagePadding - ); - InsertResourceNode ( - PMem32Node, - Node - ); - } - - Ptr++; - continue; - } - - // - // Non-prefechable - // - if (Ptr->SpecificFlag == 0) { - if (Ptr->AddrLen != 0) { - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypeMem32, - PciResUsagePadding - ); - InsertResourceNode ( - Mem32Node, - Node - ); - } - - Ptr++; - continue; - } - } - - if (Ptr->AddrSpaceGranularity == 64) { - - // - // prefechable - // - if (Ptr->SpecificFlag == 0x6) { - if (Ptr->AddrLen != 0) { - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypePMem64, - PciResUsagePadding - ); - InsertResourceNode ( - PMem64Node, - Node - ); - } - - Ptr++; - continue; - } - - // - // Non-prefechable - // - if (Ptr->SpecificFlag == 0) { - if (Ptr->AddrLen != 0) { - Node = CreateResourceNode ( - PciDev, - Ptr->AddrLen, - Ptr->AddrRangeMax, - DummyBarIndex, - PciBarTypeMem64, - PciResUsagePadding - ); - InsertResourceNode ( - Mem64Node, - Node - ); - } - - Ptr++; - continue; - } - } - } - - Ptr++; - } -} - -/** - Get padding resource for PCI-PCI bridge. - - @param PciIoDevice PCI-PCI bridge device instance. - - @note Feature flag PcdPciBusHotplugDeviceSupport determines - whether need to pad resource for them. -**/ -VOID -GetResourcePaddingPpb ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - if (gPciHotPlugInit != NULL && FeaturePcdGet (PcdPciBusHotplugDeviceSupport)) { - if (PciIoDevice->ResourcePaddingDescriptors == NULL) { - GetResourcePaddingForHpb (PciIoDevice); - } - } -} - diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h deleted file mode 100644 index 763ddbc4ed..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.h +++ /dev/null @@ -1,463 +0,0 @@ -/** @file - PCI resouces support functions declaration for PCI Bus module. - -Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_RESOURCE_SUPPORT_H_ -#define _EFI_PCI_RESOURCE_SUPPORT_H_ - -typedef enum { - PciResUsageTypical, - PciResUsagePadding -} PCI_RESOURCE_USAGE; - -#define PCI_RESOURCE_SIGNATURE SIGNATURE_32 ('p', 'c', 'r', 'c') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - LIST_ENTRY ChildList; - PCI_IO_DEVICE *PciDev; - UINT64 Alignment; - UINT64 Offset; - UINT8 Bar; - PCI_BAR_TYPE ResType; - UINT64 Length; - BOOLEAN Reserved; - PCI_RESOURCE_USAGE ResourceUsage; - BOOLEAN Virtual; -} PCI_RESOURCE_NODE; - -#define RESOURCE_NODE_FROM_LINK(a) \ - CR (a, PCI_RESOURCE_NODE, Link, PCI_RESOURCE_SIGNATURE) - -/** - The function is used to skip VGA range. - - @param Start Returned start address including VGA range. - @param Length The length of VGA range. - -**/ -VOID -SkipVGAAperture ( - OUT UINT64 *Start, - IN UINT64 Length - ); - -/** - This function is used to skip ISA aliasing aperture. - - @param Start Returned start address including ISA aliasing aperture. - @param Length The length of ISA aliasing aperture. - -**/ -VOID -SkipIsaAliasAperture ( - OUT UINT64 *Start, - IN UINT64 Length - ); - -/** - This function inserts a resource node into the resource list. - The resource list is sorted in descend order. - - @param Bridge PCI resource node for bridge. - @param ResNode Resource node want to be inserted. - -**/ -VOID -InsertResourceNode ( - IN OUT PCI_RESOURCE_NODE *Bridge, - IN PCI_RESOURCE_NODE *ResNode - ); - -/** - This routine is used to merge two different resource trees in need of - resoure degradation. - - For example, if an upstream PPB doesn't support, - prefetchable memory decoding, the PCI bus driver will choose to call this function - to merge prefectchable memory resource list into normal memory list. - - If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource - type. - If Dst is NULL or Res is NULL, ASSERT (). - - @param Dst Point to destination resource tree. - @param Res Point to source resource tree. - @param TypeMerge If the TypeMerge is TRUE, Res resource type is changed to the type of - destination resource type. - -**/ -VOID -MergeResourceTree ( - IN PCI_RESOURCE_NODE *Dst, - IN PCI_RESOURCE_NODE *Res, - IN BOOLEAN TypeMerge - ); - -/** - This function is used to calculate the IO16 aperture - for a bridge. - - @param Bridge PCI resource node for bridge. - -**/ -VOID -CalculateApertureIo16 ( - IN PCI_RESOURCE_NODE *Bridge - ); - -/** - This function is used to calculate the resource aperture - for a given bridge device. - - @param Bridge PCI resouce node for given bridge device. - -**/ -VOID -CalculateResourceAperture ( - IN PCI_RESOURCE_NODE *Bridge - ); - -/** - Get IO/Memory resource infor for given PCI device. - - @param PciDev Pci device instance. - @param IoNode Resource info node for IO . - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -GetResourceFromDevice ( - IN PCI_IO_DEVICE *PciDev, - IN OUT PCI_RESOURCE_NODE *IoNode, - IN OUT PCI_RESOURCE_NODE *Mem32Node, - IN OUT PCI_RESOURCE_NODE *PMem32Node, - IN OUT PCI_RESOURCE_NODE *Mem64Node, - IN OUT PCI_RESOURCE_NODE *PMem64Node - ); - -/** - This function is used to create a resource node. - - @param PciDev Pci device instance. - @param Length Length of Io/Memory resource. - @param Alignment Alignment of resource. - @param Bar Bar index. - @param ResType Type of resource: IO/Memory. - @param ResUsage Resource usage. - - @return PCI resource node created for given PCI device. - NULL means PCI resource node is not created. - -**/ -PCI_RESOURCE_NODE * -CreateResourceNode ( - IN PCI_IO_DEVICE *PciDev, - IN UINT64 Length, - IN UINT64 Alignment, - IN UINT8 Bar, - IN PCI_BAR_TYPE ResType, - IN PCI_RESOURCE_USAGE ResUsage - ); - -/** - This function is used to extract resource request from - IOV VF device node list. - - @param PciDev Pci device instance. - @param Length Length of Io/Memory resource. - @param Alignment Alignment of resource. - @param Bar Bar index. - @param ResType Type of resource: IO/Memory. - @param ResUsage Resource usage. - - @return PCI resource node created for given PCI device. - NULL means PCI resource node is not created. - -**/ -PCI_RESOURCE_NODE * -CreateVfResourceNode ( - IN PCI_IO_DEVICE *PciDev, - IN UINT64 Length, - IN UINT64 Alignment, - IN UINT8 Bar, - IN PCI_BAR_TYPE ResType, - IN PCI_RESOURCE_USAGE ResUsage - ); - -/** - This function is used to extract resource request from - device node list. - - @param Bridge Pci device instance. - @param IoNode Resource info node for IO. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -CreateResourceMap ( - IN PCI_IO_DEVICE *Bridge, - IN OUT PCI_RESOURCE_NODE *IoNode, - IN OUT PCI_RESOURCE_NODE *Mem32Node, - IN OUT PCI_RESOURCE_NODE *PMem32Node, - IN OUT PCI_RESOURCE_NODE *Mem64Node, - IN OUT PCI_RESOURCE_NODE *PMem64Node - ); - -/** - This function is used to do the resource padding for a specific platform. - - @param PciDev Pci device instance. - @param IoNode Resource info node for IO. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -ResourcePaddingPolicy ( - IN PCI_IO_DEVICE *PciDev, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ); - -/** - This function is used to degrade resource if the upstream bridge - doesn't support certain resource. Degradation path is - PMEM64 -> MEM64 -> MEM32 - PMEM64 -> PMEM32 -> MEM32 - IO32 -> IO16. - - @param Bridge Pci device instance. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -DegradeResource ( - IN PCI_IO_DEVICE *Bridge, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ); - -/** - Test whether bridge device support decode resource. - - @param Bridge Bridge device instance. - @param Decode Decode type according to resource type. - - @return TRUE The bridge device support decode resource. - @return FALSE The bridge device don't support decode resource. - -**/ -BOOLEAN -BridgeSupportResourceDecode ( - IN PCI_IO_DEVICE *Bridge, - IN UINT32 Decode - ); - -/** - This function is used to program the resource allocated - for each resource node under specified bridge. - - @param Base Base address of resource to be progammed. - @param Bridge PCI resource node for the bridge device. - - @retval EFI_SUCCESS Successfully to program all resouces - on given PCI bridge device. - @retval EFI_OUT_OF_RESOURCES Base is all one. - -**/ -EFI_STATUS -ProgramResource ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Bridge - ); - -/** - Program Bar register for PCI device. - - @param Base Base address for PCI device resource to be progammed. - @param Node Point to resoure node structure. - -**/ -VOID -ProgramBar ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ); - -/** - Program IOV VF Bar register for PCI device. - - @param Base Base address for PCI device resource to be progammed. - @param Node Point to resoure node structure. - -**/ -EFI_STATUS -ProgramVfBar ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ); - -/** - Program PCI-PCI bridge apperture. - - @param Base Base address for resource. - @param Node Point to resoure node structure. - -**/ -VOID -ProgramPpbApperture ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ); - -/** - Program parent bridge for Option Rom. - - @param PciDevice Pci deivce instance. - @param OptionRomBase Base address for Optiona Rom. - @param Enable Enable or disable PCI memory. - -**/ -VOID -ProgrameUpstreamBridgeForRom ( - IN PCI_IO_DEVICE *PciDevice, - IN UINT32 OptionRomBase, - IN BOOLEAN Enable - ); - -/** - Test whether resource exists for a bridge. - - @param Bridge Point to resource node for a bridge. - - @retval TRUE There is resource on the given bridge. - @retval FALSE There isn't resource on the given bridge. - -**/ -BOOLEAN -ResourceRequestExisted ( - IN PCI_RESOURCE_NODE *Bridge - ); - -/** - Initialize resource pool structure. - - @param ResourcePool Point to resource pool structure. This pool - is reset to all zero when returned. - @param ResourceType Type of resource. - -**/ -VOID -InitializeResourcePool ( - IN OUT PCI_RESOURCE_NODE *ResourcePool, - IN PCI_BAR_TYPE ResourceType - ); - -/** - Destory given resource tree. - - @param Bridge PCI resource root node of resource tree. - -**/ -VOID -DestroyResourceTree ( - IN PCI_RESOURCE_NODE *Bridge - ); - -/** - Insert resource padding for P2C. - - @param PciDev Pci device instance. - @param IoNode Resource info node for IO. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -ResourcePaddingForCardBusBridge ( - IN PCI_IO_DEVICE *PciDev, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ); - -/** - Program PCI Card device register for given resource node. - - @param Base Base address of PCI Card device to be programmed. - @param Node Given resource node. - -**/ -VOID -ProgramP2C ( - IN UINT64 Base, - IN PCI_RESOURCE_NODE *Node - ); - -/** - Create padding resource node. - - @param PciDev Pci device instance. - @param IoNode Resource info node for IO. - @param Mem32Node Resource info node for 32-bit memory. - @param PMem32Node Resource info node for 32-bit Prefetchable Memory. - @param Mem64Node Resource info node for 64-bit memory. - @param PMem64Node Resource info node for 64-bit Prefetchable Memory. - -**/ -VOID -ApplyResourcePadding ( - IN PCI_IO_DEVICE *PciDev, - IN PCI_RESOURCE_NODE *IoNode, - IN PCI_RESOURCE_NODE *Mem32Node, - IN PCI_RESOURCE_NODE *PMem32Node, - IN PCI_RESOURCE_NODE *Mem64Node, - IN PCI_RESOURCE_NODE *PMem64Node - ); - -/** - Get padding resource for PCI-PCI bridge. - - @param PciIoDevice PCI-PCI bridge device instance. - - @note Feature flag PcdPciBusHotplugDeviceSupport determines - whether need to pad resource for them. -**/ -VOID -GetResourcePaddingPpb ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c deleted file mode 100644 index f48c3a0c59..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.c +++ /dev/null @@ -1,126 +0,0 @@ -/** @file - Set up ROM Table for PCI Bus module. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciBus.h" - -// -// PCI ROM image information -// -typedef struct { - EFI_HANDLE ImageHandle; - UINTN Seg; - UINT8 Bus; - UINT8 Dev; - UINT8 Func; - UINT64 RomAddress; - UINT64 RomLength; -} EFI_PCI_ROM_IMAGE_MAPPING; - -UINTN mNumberOfPciRomImages = 0; -UINTN mMaxNumberOfPciRomImages = 0; -EFI_PCI_ROM_IMAGE_MAPPING *mRomImageTable = NULL; - -/** - Add the Rom Image to internal database for later PCI light enumeration. - - @param ImageHandle Option Rom image handle. - @param Seg Segment of PCI space. - @param Bus Bus NO of PCI space. - @param Dev Dev NO of PCI space. - @param Func Func NO of PCI space. - @param RomAddress Base address of OptionRom. - @param RomLength Length of rom image. - -**/ -VOID -PciRomAddImageMapping ( - IN EFI_HANDLE ImageHandle, - IN UINTN Seg, - IN UINT8 Bus, - IN UINT8 Dev, - IN UINT8 Func, - IN UINT64 RomAddress, - IN UINT64 RomLength - ) -{ - EFI_PCI_ROM_IMAGE_MAPPING *TempMapping; - - if (mNumberOfPciRomImages >= mMaxNumberOfPciRomImages) { - - mMaxNumberOfPciRomImages += 0x20; - - TempMapping = NULL; - TempMapping = AllocatePool (mMaxNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING)); - if (TempMapping == NULL) { - return ; - } - - CopyMem (TempMapping, mRomImageTable, mNumberOfPciRomImages * sizeof (EFI_PCI_ROM_IMAGE_MAPPING)); - - if (mRomImageTable != NULL) { - FreePool (mRomImageTable); - } - - mRomImageTable = TempMapping; - } - - mRomImageTable[mNumberOfPciRomImages].ImageHandle = ImageHandle; - mRomImageTable[mNumberOfPciRomImages].Seg = Seg; - mRomImageTable[mNumberOfPciRomImages].Bus = Bus; - mRomImageTable[mNumberOfPciRomImages].Dev = Dev; - mRomImageTable[mNumberOfPciRomImages].Func = Func; - mRomImageTable[mNumberOfPciRomImages].RomAddress = RomAddress; - mRomImageTable[mNumberOfPciRomImages].RomLength = RomLength; - mNumberOfPciRomImages++; -} - -/** - Get Option rom driver's mapping for PCI device. - - @param PciIoDevice Device instance. - - @retval TRUE Found Image mapping. - @retval FALSE Cannot found image mapping. - -**/ -BOOLEAN -PciRomGetImageMapping ( - IN PCI_IO_DEVICE *PciIoDevice - ) -{ - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; - UINTN Index; - BOOLEAN Found; - - PciRootBridgeIo = PciIoDevice->PciRootBridgeIo; - Found = FALSE; - - for (Index = 0; Index < mNumberOfPciRomImages; Index++) { - if (mRomImageTable[Index].Seg == PciRootBridgeIo->SegmentNumber && - mRomImageTable[Index].Bus == PciIoDevice->BusNumber && - mRomImageTable[Index].Dev == PciIoDevice->DeviceNumber && - mRomImageTable[Index].Func == PciIoDevice->FunctionNumber ) { - Found = TRUE; - - if (mRomImageTable[Index].ImageHandle != NULL) { - AddDriver (PciIoDevice, mRomImageTable[Index].ImageHandle); - } else { - PciIoDevice->PciIo.RomImage = (VOID *) (UINTN) mRomImageTable[Index].RomAddress; - PciIoDevice->PciIo.RomSize = (UINTN) mRomImageTable[Index].RomLength; - } - } - } - - return Found; -} diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h deleted file mode 100644 index d443f83336..0000000000 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciRomTable.h +++ /dev/null @@ -1,55 +0,0 @@ -/** @file - Set up ROM Table for PCI Bus module. - -Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PCI_ROM_TABLE_H_ -#define _EFI_PCI_ROM_TABLE_H_ - -/** - Add the Rom Image to internal database for later PCI light enumeration. - - @param ImageHandle Option Rom image handle. - @param Seg Segment of PCI space. - @param Bus Bus NO of PCI space. - @param Dev Dev NO of PCI space. - @param Func Func NO of PCI space. - @param RomAddress Base address of OptionRom. - @param RomLength Length of rom image. - -**/ -VOID -PciRomAddImageMapping ( - IN EFI_HANDLE ImageHandle, - IN UINTN Seg, - IN UINT8 Bus, - IN UINT8 Dev, - IN UINT8 Func, - IN UINT64 RomAddress, - IN UINT64 RomLength - ); - -/** - Get Option rom driver's mapping for PCI device. - - @param PciIoDevice Device instance. - - @retval TRUE Found Image mapping. - @retval FALSE Cannot found image mapping. - -**/ -BOOLEAN -PciRomGetImageMapping ( - IN PCI_IO_DEVICE *PciIoDevice - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c deleted file mode 100644 index c866e88016..0000000000 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c +++ /dev/null @@ -1,1471 +0,0 @@ -/** @file - - Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation. - -Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciHostBridge.h" -#include "PciRootBridge.h" -#include "PciHostResource.h" - - -EFI_METRONOME_ARCH_PROTOCOL *mMetronome; -EFI_CPU_IO2_PROTOCOL *mCpuIo; - -GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mAcpiAddressSpaceTypeStr[] = { - L"Mem", L"I/O", L"Bus" -}; -GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 *mPciResourceTypeStr[] = { - L"I/O", L"Mem", L"PMem", L"Mem64", L"PMem64", L"Bus" -}; - -/** - Ensure the compatibility of an IO space descriptor with the IO aperture. - - The IO space descriptor can come from the GCD IO space map, or it can - represent a gap between two neighboring IO space descriptors. In the latter - case, the GcdIoType field is expected to be EfiGcdIoTypeNonExistent. - - If the IO space descriptor already has type EfiGcdIoTypeIo, then no action is - taken -- it is by definition compatible with the aperture. - - Otherwise, the intersection of the IO space descriptor is calculated with the - aperture. If the intersection is the empty set (no overlap), no action is - taken; the IO space descriptor is compatible with the aperture. - - Otherwise, the type of the descriptor is investigated again. If the type is - EfiGcdIoTypeNonExistent (representing a gap, or a genuine descriptor with - such a type), then an attempt is made to add the intersection as IO space to - the GCD IO space map. This ensures continuity for the aperture, and the - descriptor is deemed compatible with the aperture. - - Otherwise, the IO space descriptor is incompatible with the IO aperture. - - @param[in] Base Base address of the aperture. - @param[in] Length Length of the aperture. - @param[in] Descriptor The descriptor to ensure compatibility with the - aperture for. - - @retval EFI_SUCCESS The descriptor is compatible. The GCD IO space - map may have been updated, for continuity - within the aperture. - @retval EFI_INVALID_PARAMETER The descriptor is incompatible. - @return Error codes from gDS->AddIoSpace(). -**/ -EFI_STATUS -IntersectIoDescriptor ( - IN UINT64 Base, - IN UINT64 Length, - IN CONST EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor - ) -{ - UINT64 IntersectionBase; - UINT64 IntersectionEnd; - EFI_STATUS Status; - - if (Descriptor->GcdIoType == EfiGcdIoTypeIo) { - return EFI_SUCCESS; - } - - IntersectionBase = MAX (Base, Descriptor->BaseAddress); - IntersectionEnd = MIN (Base + Length, - Descriptor->BaseAddress + Descriptor->Length); - if (IntersectionBase >= IntersectionEnd) { - // - // The descriptor and the aperture don't overlap. - // - return EFI_SUCCESS; - } - - if (Descriptor->GcdIoType == EfiGcdIoTypeNonExistent) { - Status = gDS->AddIoSpace (EfiGcdIoTypeIo, IntersectionBase, - IntersectionEnd - IntersectionBase); - - DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE, - "%a: %a: add [%Lx, %Lx): %r\n", gEfiCallerBaseName, __FUNCTION__, - IntersectionBase, IntersectionEnd, Status)); - return Status; - } - - DEBUG ((EFI_D_ERROR, "%a: %a: desc [%Lx, %Lx) type %u conflicts with " - "aperture [%Lx, %Lx)\n", gEfiCallerBaseName, __FUNCTION__, - Descriptor->BaseAddress, Descriptor->BaseAddress + Descriptor->Length, - (UINT32)Descriptor->GcdIoType, Base, Base + Length)); - return EFI_INVALID_PARAMETER; -} - -/** - Add IO space to GCD. - The routine checks the GCD database and only adds those which are - not added in the specified range to GCD. - - @param Base Base address of the IO space. - @param Length Length of the IO space. - - @retval EFI_SUCCES The IO space was added successfully. -**/ -EFI_STATUS -AddIoSpace ( - IN UINT64 Base, - IN UINT64 Length - ) -{ - EFI_STATUS Status; - UINTN Index; - UINTN NumberOfDescriptors; - EFI_GCD_IO_SPACE_DESCRIPTOR *IoSpaceMap; - - Status = gDS->GetIoSpaceMap (&NumberOfDescriptors, &IoSpaceMap); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: %a: GetIoSpaceMap(): %r\n", - gEfiCallerBaseName, __FUNCTION__, Status)); - return Status; - } - - for (Index = 0; Index < NumberOfDescriptors; Index++) { - Status = IntersectIoDescriptor (Base, Length, &IoSpaceMap[Index]); - if (EFI_ERROR (Status)) { - goto FreeIoSpaceMap; - } - } - - DEBUG_CODE ( - // - // Make sure there are adjacent descriptors covering [Base, Base + Length). - // It is possible that they have not been merged; merging can be prevented - // by allocation. - // - UINT64 CheckBase; - EFI_STATUS CheckStatus; - EFI_GCD_IO_SPACE_DESCRIPTOR Descriptor; - - for (CheckBase = Base; - CheckBase < Base + Length; - CheckBase = Descriptor.BaseAddress + Descriptor.Length) { - CheckStatus = gDS->GetIoSpaceDescriptor (CheckBase, &Descriptor); - ASSERT_EFI_ERROR (CheckStatus); - ASSERT (Descriptor.GcdIoType == EfiGcdIoTypeIo); - } - ); - -FreeIoSpaceMap: - FreePool (IoSpaceMap); - - return Status; -} - -/** - Ensure the compatibility of a memory space descriptor with the MMIO aperture. - - The memory space descriptor can come from the GCD memory space map, or it can - represent a gap between two neighboring memory space descriptors. In the - latter case, the GcdMemoryType field is expected to be - EfiGcdMemoryTypeNonExistent. - - If the memory space descriptor already has type - EfiGcdMemoryTypeMemoryMappedIo, and its capabilities are a superset of the - required capabilities, then no action is taken -- it is by definition - compatible with the aperture. - - Otherwise, the intersection of the memory space descriptor is calculated with - the aperture. If the intersection is the empty set (no overlap), no action is - taken; the memory space descriptor is compatible with the aperture. - - Otherwise, the type of the descriptor is investigated again. If the type is - EfiGcdMemoryTypeNonExistent (representing a gap, or a genuine descriptor with - such a type), then an attempt is made to add the intersection as MMIO space - to the GCD memory space map, with the specified capabilities. This ensures - continuity for the aperture, and the descriptor is deemed compatible with the - aperture. - - Otherwise, the memory space descriptor is incompatible with the MMIO - aperture. - - @param[in] Base Base address of the aperture. - @param[in] Length Length of the aperture. - @param[in] Capabilities Capabilities required by the aperture. - @param[in] Descriptor The descriptor to ensure compatibility with the - aperture for. - - @retval EFI_SUCCESS The descriptor is compatible. The GCD memory - space map may have been updated, for - continuity within the aperture. - @retval EFI_INVALID_PARAMETER The descriptor is incompatible. - @return Error codes from gDS->AddMemorySpace(). -**/ -EFI_STATUS -IntersectMemoryDescriptor ( - IN UINT64 Base, - IN UINT64 Length, - IN UINT64 Capabilities, - IN CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor - ) -{ - UINT64 IntersectionBase; - UINT64 IntersectionEnd; - EFI_STATUS Status; - - if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo && - (Descriptor->Capabilities & Capabilities) == Capabilities) { - return EFI_SUCCESS; - } - - IntersectionBase = MAX (Base, Descriptor->BaseAddress); - IntersectionEnd = MIN (Base + Length, - Descriptor->BaseAddress + Descriptor->Length); - if (IntersectionBase >= IntersectionEnd) { - // - // The descriptor and the aperture don't overlap. - // - return EFI_SUCCESS; - } - - if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeNonExistent) { - Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo, - IntersectionBase, IntersectionEnd - IntersectionBase, - Capabilities); - - DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE, - "%a: %a: add [%Lx, %Lx): %r\n", gEfiCallerBaseName, __FUNCTION__, - IntersectionBase, IntersectionEnd, Status)); - return Status; - } - - DEBUG ((EFI_D_ERROR, "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts " - "with aperture [%Lx, %Lx) cap %Lx\n", gEfiCallerBaseName, __FUNCTION__, - Descriptor->BaseAddress, Descriptor->BaseAddress + Descriptor->Length, - (UINT32)Descriptor->GcdMemoryType, Descriptor->Capabilities, - Base, Base + Length, Capabilities)); - return EFI_INVALID_PARAMETER; -} - -/** - Add MMIO space to GCD. - The routine checks the GCD database and only adds those which are - not added in the specified range to GCD. - - @param Base Base address of the MMIO space. - @param Length Length of the MMIO space. - @param Capabilities Capabilities of the MMIO space. - - @retval EFI_SUCCES The MMIO space was added successfully. -**/ -EFI_STATUS -AddMemoryMappedIoSpace ( - IN UINT64 Base, - IN UINT64 Length, - IN UINT64 Capabilities - ) -{ - EFI_STATUS Status; - UINTN Index; - UINTN NumberOfDescriptors; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; - - Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: %a: GetMemorySpaceMap(): %r\n", - gEfiCallerBaseName, __FUNCTION__, Status)); - return Status; - } - - for (Index = 0; Index < NumberOfDescriptors; Index++) { - Status = IntersectMemoryDescriptor (Base, Length, Capabilities, - &MemorySpaceMap[Index]); - if (EFI_ERROR (Status)) { - goto FreeMemorySpaceMap; - } - } - - DEBUG_CODE ( - // - // Make sure there are adjacent descriptors covering [Base, Base + Length). - // It is possible that they have not been merged; merging can be prevented - // by allocation and different capabilities. - // - UINT64 CheckBase; - EFI_STATUS CheckStatus; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; - - for (CheckBase = Base; - CheckBase < Base + Length; - CheckBase = Descriptor.BaseAddress + Descriptor.Length) { - CheckStatus = gDS->GetMemorySpaceDescriptor (CheckBase, &Descriptor); - ASSERT_EFI_ERROR (CheckStatus); - ASSERT (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo); - ASSERT ((Descriptor.Capabilities & Capabilities) == Capabilities); - } - ); - -FreeMemorySpaceMap: - FreePool (MemorySpaceMap); - - return Status; -} - -/** - - Entry point of this driver. - - @param ImageHandle Image handle of this driver. - @param SystemTable Pointer to standard EFI system table. - - @retval EFI_SUCCESS Succeed. - @retval EFI_DEVICE_ERROR Fail to install PCI_ROOT_BRIDGE_IO protocol. - -**/ -EFI_STATUS -EFIAPI -InitializePciHostBridge ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - PCI_ROOT_BRIDGE *RootBridges; - UINTN RootBridgeCount; - UINTN Index; - PCI_ROOT_BRIDGE_APERTURE *MemApertures[4]; - UINTN MemApertureIndex; - BOOLEAN ResourceAssigned; - LIST_ENTRY *Link; - - RootBridges = PciHostBridgeGetRootBridges (&RootBridgeCount); - if ((RootBridges == NULL) || (RootBridgeCount == 0)) { - return EFI_UNSUPPORTED; - } - - Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **) &mMetronome); - ASSERT_EFI_ERROR (Status); - Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **) &mCpuIo); - ASSERT_EFI_ERROR (Status); - - // - // Most systems in the world including complex servers have only one Host Bridge. - // - HostBridge = AllocateZeroPool (sizeof (PCI_HOST_BRIDGE_INSTANCE)); - ASSERT (HostBridge != NULL); - - HostBridge->Signature = PCI_HOST_BRIDGE_SIGNATURE; - HostBridge->CanRestarted = TRUE; - InitializeListHead (&HostBridge->RootBridges); - ResourceAssigned = FALSE; - - // - // Create Root Bridge Device Handle in this Host Bridge - // - for (Index = 0; Index < RootBridgeCount; Index++) { - // - // Create Root Bridge Handle Instance - // - RootBridge = CreateRootBridge (&RootBridges[Index]); - ASSERT (RootBridge != NULL); - if (RootBridge == NULL) { - continue; - } - - // - // Make sure all root bridges share the same ResourceAssigned value. - // - if (Index == 0) { - ResourceAssigned = RootBridges[Index].ResourceAssigned; - } else { - ASSERT (ResourceAssigned == RootBridges[Index].ResourceAssigned); - } - - if (RootBridges[Index].Io.Base <= RootBridges[Index].Io.Limit) { - Status = AddIoSpace ( - RootBridges[Index].Io.Base, - RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1 - ); - ASSERT_EFI_ERROR (Status); - if (ResourceAssigned) { - Status = gDS->AllocateIoSpace ( - EfiGcdAllocateAddress, - EfiGcdIoTypeIo, - 0, - RootBridges[Index].Io.Limit - RootBridges[Index].Io.Base + 1, - &RootBridges[Index].Io.Base, - gImageHandle, - NULL - ); - ASSERT_EFI_ERROR (Status); - } - } - - // - // Add all the Mem/PMem aperture to GCD - // Mem/PMem shouldn't overlap with each other - // Root bridge which needs to combine MEM and PMEM should only report - // the MEM aperture in Mem - // - MemApertures[0] = &RootBridges[Index].Mem; - MemApertures[1] = &RootBridges[Index].MemAbove4G; - MemApertures[2] = &RootBridges[Index].PMem; - MemApertures[3] = &RootBridges[Index].PMemAbove4G; - - for (MemApertureIndex = 0; MemApertureIndex < sizeof (MemApertures) / sizeof (MemApertures[0]); MemApertureIndex++) { - if (MemApertures[MemApertureIndex]->Base <= MemApertures[MemApertureIndex]->Limit) { - Status = AddMemoryMappedIoSpace ( - MemApertures[MemApertureIndex]->Base, - MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1, - EFI_MEMORY_UC - ); - ASSERT_EFI_ERROR (Status); - Status = gDS->SetMemorySpaceAttributes ( - MemApertures[MemApertureIndex]->Base, - MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1, - EFI_MEMORY_UC - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "PciHostBridge driver failed to set EFI_MEMORY_UC to MMIO aperture - %r.\n", Status)); - } - if (ResourceAssigned) { - Status = gDS->AllocateMemorySpace ( - EfiGcdAllocateAddress, - EfiGcdMemoryTypeMemoryMappedIo, - 0, - MemApertures[MemApertureIndex]->Limit - MemApertures[MemApertureIndex]->Base + 1, - &MemApertures[MemApertureIndex]->Base, - gImageHandle, - NULL - ); - ASSERT_EFI_ERROR (Status); - } - } - } - // - // Insert Root Bridge Handle Instance - // - InsertTailList (&HostBridge->RootBridges, &RootBridge->Link); - } - - // - // When resources were assigned, it's not needed to expose - // PciHostBridgeResourceAllocation protocol. - // - if (!ResourceAssigned) { - HostBridge->ResAlloc.NotifyPhase = NotifyPhase; - HostBridge->ResAlloc.GetNextRootBridge = GetNextRootBridge; - HostBridge->ResAlloc.GetAllocAttributes = GetAttributes; - HostBridge->ResAlloc.StartBusEnumeration = StartBusEnumeration; - HostBridge->ResAlloc.SetBusNumbers = SetBusNumbers; - HostBridge->ResAlloc.SubmitResources = SubmitResources; - HostBridge->ResAlloc.GetProposedResources = GetProposedResources; - HostBridge->ResAlloc.PreprocessController = PreprocessController; - - Status = gBS->InstallMultipleProtocolInterfaces ( - &HostBridge->Handle, - &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc, - NULL - ); - ASSERT_EFI_ERROR (Status); - } - - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - RootBridge->RootBridgeIo.ParentHandle = HostBridge->Handle; - - Status = gBS->InstallMultipleProtocolInterfaces ( - &RootBridge->Handle, - &gEfiDevicePathProtocolGuid, RootBridge->DevicePath, - &gEfiPciRootBridgeIoProtocolGuid, &RootBridge->RootBridgeIo, - NULL - ); - ASSERT_EFI_ERROR (Status); - } - PciHostBridgeFreeRootBridges (RootBridges, RootBridgeCount); - return Status; -} - -/** - This routine constructs the resource descriptors for all root bridges and call PciHostBridgeResourceConflict(). - - @param HostBridge The Host Bridge Instance where the resource adjustment happens. -**/ -VOID -ResourceConflict ( - IN PCI_HOST_BRIDGE_INSTANCE *HostBridge - ) -{ - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Resources; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; - EFI_ACPI_END_TAG_DESCRIPTOR *End; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - LIST_ENTRY *Link; - UINTN RootBridgeCount; - PCI_RESOURCE_TYPE Index; - PCI_RES_NODE *ResAllocNode; - - RootBridgeCount = 0; - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridgeCount++; - } - - Resources = AllocatePool ( - RootBridgeCount * (TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)) + - sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) - ); - ASSERT (Resources != NULL); - - for (Link = GetFirstNode (&HostBridge->RootBridges), Descriptor = Resources - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - for (Index = TypeIo; Index < TypeMax; Index++) { - ResAllocNode = &RootBridge->ResAllocNode[Index]; - - Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - Descriptor->AddrRangeMin = ResAllocNode->Base; - Descriptor->AddrRangeMax = ResAllocNode->Alignment; - Descriptor->AddrLen = ResAllocNode->Length; - switch (ResAllocNode->Type) { - - case TypeIo: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; - break; - - case TypePMem32: - Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE; - case TypeMem32: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - Descriptor->AddrSpaceGranularity = 32; - break; - - case TypePMem64: - Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE; - case TypeMem64: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - Descriptor->AddrSpaceGranularity = 64; - break; - - case TypeBus: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS; - break; - - default: - break; - } - - Descriptor++; - } - // - // Terminate the root bridge resources. - // - End = (EFI_ACPI_END_TAG_DESCRIPTOR *) Descriptor; - End->Desc = ACPI_END_TAG_DESCRIPTOR; - End->Checksum = 0x0; - - Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (End + 1); - } - // - // Terminate the host bridge resources. - // - End = (EFI_ACPI_END_TAG_DESCRIPTOR *) Descriptor; - End->Desc = ACPI_END_TAG_DESCRIPTOR; - End->Checksum = 0x0; - - DEBUG ((DEBUG_ERROR, "Call PciHostBridgeResourceConflict().\n")); - PciHostBridgeResourceConflict (HostBridge->Handle, Resources); - FreePool (Resources); -} - -/** - Allocate Length of MMIO or IO resource with alignment BitsOfAlignment - from GCD range [BaseAddress, Limit). - - @param Mmio TRUE for MMIO and FALSE for IO. - @param Length Length of the resource to allocate. - @param BitsOfAlignment Alignment of the resource to allocate. - @param BaseAddress The starting address the allocation is from. - @param Limit The ending address the allocation is to. - - @retval The base address of the allocated resource or MAX_UINT64 if allocation - fails. -**/ -UINT64 -AllocateResource ( - BOOLEAN Mmio, - UINT64 Length, - UINTN BitsOfAlignment, - UINT64 BaseAddress, - UINT64 Limit - ) -{ - EFI_STATUS Status; - - if (BaseAddress < Limit) { - // - // Have to make sure Aligment is handled since we are doing direct address allocation - // - BaseAddress = ALIGN_VALUE (BaseAddress, LShiftU64 (1, BitsOfAlignment)); - - while (BaseAddress + Length <= Limit + 1) { - if (Mmio) { - Status = gDS->AllocateMemorySpace ( - EfiGcdAllocateAddress, - EfiGcdMemoryTypeMemoryMappedIo, - BitsOfAlignment, - Length, - &BaseAddress, - gImageHandle, - NULL - ); - } else { - Status = gDS->AllocateIoSpace ( - EfiGcdAllocateAddress, - EfiGcdIoTypeIo, - BitsOfAlignment, - Length, - &BaseAddress, - gImageHandle, - NULL - ); - } - - if (!EFI_ERROR (Status)) { - return BaseAddress; - } - BaseAddress += LShiftU64 (1, BitsOfAlignment); - } - } - return MAX_UINT64; -} - -/** - - Enter a certain phase of the PCI enumeration process. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance. - @param Phase The phase during enumeration. - - @retval EFI_SUCCESS Succeed. - @retval EFI_INVALID_PARAMETER Wrong phase parameter passed in. - @retval EFI_NOT_READY Resources have not been submitted yet. - -**/ -EFI_STATUS -EFIAPI -NotifyPhase ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase - ) -{ - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - LIST_ENTRY *Link; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINTN BitsOfAlignment; - UINT64 Alignment; - EFI_STATUS Status; - EFI_STATUS ReturnStatus; - PCI_RESOURCE_TYPE Index; - PCI_RESOURCE_TYPE Index1; - PCI_RESOURCE_TYPE Index2; - BOOLEAN ResNodeHandled[TypeMax]; - UINT64 MaxAlignment; - - HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); - - switch (Phase) { - case EfiPciHostBridgeBeginEnumeration: - if (!HostBridge->CanRestarted) { - return EFI_NOT_READY; - } - // - // Reset Root Bridge - // - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - for (Index = TypeIo; Index < TypeMax; Index++) { - RootBridge->ResAllocNode[Index].Type = Index; - RootBridge->ResAllocNode[Index].Base = 0; - RootBridge->ResAllocNode[Index].Length = 0; - RootBridge->ResAllocNode[Index].Status = ResNone; - - RootBridge->ResourceSubmitted = FALSE; - } - } - - HostBridge->CanRestarted = TRUE; - break; - - case EfiPciHostBridgeBeginBusAllocation: - // - // No specific action is required here, can perform any chipset specific programing - // - HostBridge->CanRestarted = FALSE; - break; - - case EfiPciHostBridgeEndBusAllocation: - // - // No specific action is required here, can perform any chipset specific programing - // - break; - - case EfiPciHostBridgeBeginResourceAllocation: - // - // No specific action is required here, can perform any chipset specific programing - // - break; - - case EfiPciHostBridgeAllocateResources: - ReturnStatus = EFI_SUCCESS; - - // - // Make sure the resource for all root bridges has been submitted. - // - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - if (!RootBridge->ResourceSubmitted) { - return EFI_NOT_READY; - } - } - - DEBUG ((EFI_D_INFO, "PciHostBridge: NotifyPhase (AllocateResources)\n")); - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - for (Index = TypeIo; Index < TypeBus; Index++) { - ResNodeHandled[Index] = FALSE; - } - - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - DEBUG ((EFI_D_INFO, " RootBridge: %s\n", RootBridge->DevicePathStr)); - - for (Index1 = TypeIo; Index1 < TypeBus; Index1++) { - if (RootBridge->ResAllocNode[Index1].Status == ResNone) { - ResNodeHandled[Index1] = TRUE; - } else { - // - // Allocate the resource node with max alignment at first - // - MaxAlignment = 0; - Index = TypeMax; - for (Index2 = TypeIo; Index2 < TypeBus; Index2++) { - if (ResNodeHandled[Index2]) { - continue; - } - if (MaxAlignment <= RootBridge->ResAllocNode[Index2].Alignment) { - MaxAlignment = RootBridge->ResAllocNode[Index2].Alignment; - Index = Index2; - } - } - - ASSERT (Index < TypeMax); - ResNodeHandled[Index] = TRUE; - Alignment = RootBridge->ResAllocNode[Index].Alignment; - BitsOfAlignment = LowBitSet64 (Alignment + 1); - BaseAddress = MAX_UINT64; - - switch (Index) { - case TypeIo: - BaseAddress = AllocateResource ( - FALSE, - RootBridge->ResAllocNode[Index].Length, - MIN (15, BitsOfAlignment), - ALIGN_VALUE (RootBridge->Io.Base, Alignment + 1), - RootBridge->Io.Limit - ); - break; - - case TypeMem64: - BaseAddress = AllocateResource ( - TRUE, - RootBridge->ResAllocNode[Index].Length, - MIN (63, BitsOfAlignment), - ALIGN_VALUE (RootBridge->MemAbove4G.Base, Alignment + 1), - RootBridge->MemAbove4G.Limit - ); - if (BaseAddress != MAX_UINT64) { - break; - } - // - // If memory above 4GB is not available, try memory below 4GB - // - - case TypeMem32: - BaseAddress = AllocateResource ( - TRUE, - RootBridge->ResAllocNode[Index].Length, - MIN (31, BitsOfAlignment), - ALIGN_VALUE (RootBridge->Mem.Base, Alignment + 1), - RootBridge->Mem.Limit - ); - break; - - case TypePMem64: - BaseAddress = AllocateResource ( - TRUE, - RootBridge->ResAllocNode[Index].Length, - MIN (63, BitsOfAlignment), - ALIGN_VALUE (RootBridge->PMemAbove4G.Base, Alignment + 1), - RootBridge->PMemAbove4G.Limit - ); - if (BaseAddress != MAX_UINT64) { - break; - } - // - // If memory above 4GB is not available, try memory below 4GB - // - case TypePMem32: - BaseAddress = AllocateResource ( - TRUE, - RootBridge->ResAllocNode[Index].Length, - MIN (31, BitsOfAlignment), - ALIGN_VALUE (RootBridge->PMem.Base, Alignment + 1), - RootBridge->PMem.Limit - ); - break; - - default: - ASSERT (FALSE); - break; - } - - DEBUG ((DEBUG_INFO, " %s: Base/Length/Alignment = %lx/%lx/%lx - ", - mPciResourceTypeStr[Index], BaseAddress, RootBridge->ResAllocNode[Index].Length, Alignment)); - if (BaseAddress != MAX_UINT64) { - RootBridge->ResAllocNode[Index].Base = BaseAddress; - RootBridge->ResAllocNode[Index].Status = ResAllocated; - DEBUG ((DEBUG_INFO, "Success\n")); - } else { - ReturnStatus = EFI_OUT_OF_RESOURCES; - DEBUG ((DEBUG_ERROR, "Out Of Resource!\n")); - } - } - } - } - - if (ReturnStatus == EFI_OUT_OF_RESOURCES) { - ResourceConflict (HostBridge); - } - - // - // Set resource to zero for nodes where allocation fails - // - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - for (Index = TypeIo; Index < TypeBus; Index++) { - if (RootBridge->ResAllocNode[Index].Status != ResAllocated) { - RootBridge->ResAllocNode[Index].Length = 0; - } - } - } - return ReturnStatus; - - case EfiPciHostBridgeSetResources: - // - // HostBridgeInstance->CanRestarted = FALSE; - // - break; - - case EfiPciHostBridgeFreeResources: - // - // HostBridgeInstance->CanRestarted = FALSE; - // - ReturnStatus = EFI_SUCCESS; - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - for (Index = TypeIo; Index < TypeBus; Index++) { - if (RootBridge->ResAllocNode[Index].Status == ResAllocated) { - switch (Index) { - case TypeIo: - Status = gDS->FreeIoSpace (RootBridge->ResAllocNode[Index].Base, RootBridge->ResAllocNode[Index].Length); - if (EFI_ERROR (Status)) { - ReturnStatus = Status; - } - break; - - case TypeMem32: - case TypePMem32: - case TypeMem64: - case TypePMem64: - Status = gDS->FreeMemorySpace (RootBridge->ResAllocNode[Index].Base, RootBridge->ResAllocNode[Index].Length); - if (EFI_ERROR (Status)) { - ReturnStatus = Status; - } - break; - - default: - ASSERT (FALSE); - break; - } - - RootBridge->ResAllocNode[Index].Type = Index; - RootBridge->ResAllocNode[Index].Base = 0; - RootBridge->ResAllocNode[Index].Length = 0; - RootBridge->ResAllocNode[Index].Status = ResNone; - } - } - - RootBridge->ResourceSubmitted = FALSE; - } - - HostBridge->CanRestarted = TRUE; - return ReturnStatus; - - case EfiPciHostBridgeEndResourceAllocation: - // - // The resource allocation phase is completed. No specific action is required - // here. This notification can be used to perform any chipset specific programming. - // - break; - - case EfiPciHostBridgeEndEnumeration: - // - // The Host Bridge Enumeration is completed. No specific action is required here. - // This notification can be used to perform any chipset specific programming. - // - break; - - default: - return EFI_INVALID_PARAMETER; - } - - return EFI_SUCCESS; -} - -/** - - Return the device handle of the next PCI root bridge that is associated with - this Host Bridge. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle Returns the device handle of the next PCI Root Bridge. - On input, it holds the RootBridgeHandle returned by the most - recent call to GetNextRootBridge().The handle for the first - PCI Root Bridge is returned if RootBridgeHandle is NULL on input. - - @retval EFI_SUCCESS Succeed. - @retval EFI_NOT_FOUND Next PCI root bridge not found. - @retval EFI_INVALID_PARAMETER Wrong parameter passed in. - -**/ -EFI_STATUS -EFIAPI -GetNextRootBridge ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN OUT EFI_HANDLE *RootBridgeHandle - ) -{ - BOOLEAN ReturnNext; - LIST_ENTRY *Link; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - - if (RootBridgeHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); - ReturnNext = (BOOLEAN) (*RootBridgeHandle == NULL); - - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - if (ReturnNext) { - *RootBridgeHandle = RootBridge->Handle; - return EFI_SUCCESS; - } - - ReturnNext = (BOOLEAN) (*RootBridgeHandle == RootBridge->Handle); - } - - if (ReturnNext) { - ASSERT (IsNull (&HostBridge->RootBridges, Link)); - return EFI_NOT_FOUND; - } else { - return EFI_INVALID_PARAMETER; - } -} - -/** - - Returns the attributes of a PCI Root Bridge. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle The device handle of the PCI Root Bridge - that the caller is interested in. - @param Attributes The pointer to attributes of the PCI Root Bridge. - - @retval EFI_SUCCESS Succeed. - @retval EFI_INVALID_PARAMETER Attributes parameter passed in is NULL or - RootBridgeHandle is not an EFI_HANDLE - that was returned on a previous call to - GetNextRootBridge(). - -**/ -EFI_STATUS -EFIAPI -GetAttributes ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - OUT UINT64 *Attributes - ) -{ - LIST_ENTRY *Link; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - - if (Attributes == NULL) { - return EFI_INVALID_PARAMETER; - } - - HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - if (RootBridgeHandle == RootBridge->Handle) { - *Attributes = RootBridge->AllocationAttributes; - return EFI_SUCCESS; - } - } - - return EFI_INVALID_PARAMETER; -} - -/** - - This is the request from the PCI enumerator to set up - the specified PCI Root Bridge for bus enumeration process. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle The PCI Root Bridge to be set up. - @param Configuration Pointer to the pointer to the PCI bus resource descriptor. - - @retval EFI_SUCCESS Succeed. - @retval EFI_OUT_OF_RESOURCES Not enough pool to be allocated. - @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid handle. - -**/ -EFI_STATUS -EFIAPI -StartBusEnumeration ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - OUT VOID **Configuration - ) -{ - LIST_ENTRY *Link; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; - EFI_ACPI_END_TAG_DESCRIPTOR *End; - - if (Configuration == NULL) { - return EFI_INVALID_PARAMETER; - } - - HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - if (RootBridgeHandle == RootBridge->Handle) { - *Configuration = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (*Configuration == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) *Configuration; - Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS; - Descriptor->GenFlag = 0; - Descriptor->SpecificFlag = 0; - Descriptor->AddrSpaceGranularity = 0; - Descriptor->AddrRangeMin = RootBridge->Bus.Base; - Descriptor->AddrRangeMax = 0; - Descriptor->AddrTranslationOffset = 0; - Descriptor->AddrLen = RootBridge->Bus.Limit - RootBridge->Bus.Base + 1; - - End = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Descriptor + 1); - End->Desc = ACPI_END_TAG_DESCRIPTOR; - End->Checksum = 0x0; - - return EFI_SUCCESS; - } - } - - return EFI_INVALID_PARAMETER; -} - -/** - - This function programs the PCI Root Bridge hardware so that - it decodes the specified PCI bus range. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle The PCI Root Bridge whose bus range is to be programmed. - @param Configuration The pointer to the PCI bus resource descriptor. - - @retval EFI_SUCCESS Succeed. - @retval EFI_INVALID_PARAMETER Wrong parameters passed in. - -**/ -EFI_STATUS -EFIAPI -SetBusNumbers ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - IN VOID *Configuration - ) -{ - LIST_ENTRY *Link; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; - EFI_ACPI_END_TAG_DESCRIPTOR *End; - - if (Configuration == NULL) { - return EFI_INVALID_PARAMETER; - } - - Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; - End = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Descriptor + 1); - - // - // Check the Configuration is valid - // - if ((Descriptor->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) || - (Descriptor->ResType != ACPI_ADDRESS_SPACE_TYPE_BUS) || - (End->Desc != ACPI_END_TAG_DESCRIPTOR) - ) { - return EFI_INVALID_PARAMETER; - } - - HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - if (RootBridgeHandle == RootBridge->Handle) { - - if (Descriptor->AddrLen == 0) { - return EFI_INVALID_PARAMETER; - } - - if ((Descriptor->AddrRangeMin < RootBridge->Bus.Base) || - (Descriptor->AddrRangeMin + Descriptor->AddrLen - 1 > RootBridge->Bus.Limit) - ) { - return EFI_INVALID_PARAMETER; - } - // - // Update the Bus Range - // - RootBridge->ResAllocNode[TypeBus].Base = Descriptor->AddrRangeMin; - RootBridge->ResAllocNode[TypeBus].Length = Descriptor->AddrLen; - RootBridge->ResAllocNode[TypeBus].Status = ResAllocated; - return EFI_SUCCESS; - } - } - - return EFI_INVALID_PARAMETER; -} - -/** - - Submits the I/O and memory resource requirements for the specified PCI Root Bridge. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle The PCI Root Bridge whose I/O and memory resource requirements. - are being submitted. - @param Configuration The pointer to the PCI I/O and PCI memory resource descriptor. - - @retval EFI_SUCCESS Succeed. - @retval EFI_INVALID_PARAMETER Wrong parameters passed in. -**/ -EFI_STATUS -EFIAPI -SubmitResources ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - IN VOID *Configuration - ) -{ - LIST_ENTRY *Link; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; - PCI_RESOURCE_TYPE Type; - - // - // Check the input parameter: Configuration - // - if (Configuration == NULL) { - return EFI_INVALID_PARAMETER; - } - - HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - if (RootBridgeHandle == RootBridge->Handle) { - DEBUG ((EFI_D_INFO, "PciHostBridge: SubmitResources for %s\n", RootBridge->DevicePathStr)); - // - // Check the resource descriptors. - // If the Configuration includes one or more invalid resource descriptors, all the resource - // descriptors are ignored and the function returns EFI_INVALID_PARAMETER. - // - for (Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) { - if (Descriptor->ResType > ACPI_ADDRESS_SPACE_TYPE_BUS) { - return EFI_INVALID_PARAMETER; - } - - DEBUG ((EFI_D_INFO, " %s: Granularity/SpecificFlag = %ld / %02x%s\n", - mAcpiAddressSpaceTypeStr[Descriptor->ResType], Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag, - (Descriptor->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0 ? L" (Prefetchable)" : L"" - )); - DEBUG ((EFI_D_INFO, " Length/Alignment = 0x%lx / 0x%lx\n", Descriptor->AddrLen, Descriptor->AddrRangeMax)); - switch (Descriptor->ResType) { - case ACPI_ADDRESS_SPACE_TYPE_MEM: - if (Descriptor->AddrSpaceGranularity != 32 && Descriptor->AddrSpaceGranularity != 64) { - return EFI_INVALID_PARAMETER; - } - if (Descriptor->AddrSpaceGranularity == 32 && Descriptor->AddrLen >= SIZE_4GB) { - return EFI_INVALID_PARAMETER; - } - // - // If the PCI root bridge does not support separate windows for nonprefetchable and - // prefetchable memory, then the PCI bus driver needs to include requests for - // prefetchable memory in the nonprefetchable memory pool. - // - if (((RootBridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) && - ((Descriptor->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0) - ) { - return EFI_INVALID_PARAMETER; - } - case ACPI_ADDRESS_SPACE_TYPE_IO: - // - // Check aligment, it should be of the form 2^n-1 - // - if (GetPowerOfTwo64 (Descriptor->AddrRangeMax + 1) != (Descriptor->AddrRangeMax + 1)) { - return EFI_INVALID_PARAMETER; - } - break; - default: - ASSERT (FALSE); - break; - } - } - if (Descriptor->Desc != ACPI_END_TAG_DESCRIPTOR) { - return EFI_INVALID_PARAMETER; - } - - for (Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) { - if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { - if (Descriptor->AddrSpaceGranularity == 32) { - if ((Descriptor->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0) { - Type = TypePMem32; - } else { - Type = TypeMem32; - } - } else { - ASSERT (Descriptor->AddrSpaceGranularity == 64); - if ((Descriptor->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) != 0) { - Type = TypePMem64; - } else { - Type = TypeMem64; - } - } - } else { - ASSERT (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO); - Type = TypeIo; - } - RootBridge->ResAllocNode[Type].Length = Descriptor->AddrLen; - RootBridge->ResAllocNode[Type].Alignment = Descriptor->AddrRangeMax; - RootBridge->ResAllocNode[Type].Status = ResSubmitted; - } - RootBridge->ResourceSubmitted = TRUE; - return EFI_SUCCESS; - } - } - - return EFI_INVALID_PARAMETER; -} - -/** - - This function returns the proposed resource settings for the specified - PCI Root Bridge. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle The PCI Root Bridge handle. - @param Configuration The pointer to the pointer to the PCI I/O - and memory resource descriptor. - - @retval EFI_SUCCESS Succeed. - @retval EFI_OUT_OF_RESOURCES Not enough pool to be allocated. - @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid handle. - -**/ -EFI_STATUS -EFIAPI -GetProposedResources ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - OUT VOID **Configuration - ) -{ - LIST_ENTRY *Link; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - UINTN Index; - UINTN Number; - VOID *Buffer; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; - EFI_ACPI_END_TAG_DESCRIPTOR *End; - UINT64 ResStatus; - - HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - if (RootBridgeHandle == RootBridge->Handle) { - for (Index = 0, Number = 0; Index < TypeBus; Index++) { - if (RootBridge->ResAllocNode[Index].Status != ResNone) { - Number++; - } - } - - Buffer = AllocateZeroPool (Number * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)); - if (Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Buffer; - for (Index = 0; Index < TypeBus; Index++) { - ResStatus = RootBridge->ResAllocNode[Index].Status; - if (ResStatus != ResNone) { - Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;; - Descriptor->GenFlag = 0; - Descriptor->AddrRangeMin = RootBridge->ResAllocNode[Index].Base; - Descriptor->AddrRangeMax = 0; - Descriptor->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : PCI_RESOURCE_LESS; - Descriptor->AddrLen = RootBridge->ResAllocNode[Index].Length; - - switch (Index) { - - case TypeIo: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; - break; - - case TypePMem32: - Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE; - case TypeMem32: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - Descriptor->AddrSpaceGranularity = 32; - break; - - case TypePMem64: - Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE; - case TypeMem64: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - Descriptor->AddrSpaceGranularity = 64; - break; - } - - Descriptor++; - } - } - End = (EFI_ACPI_END_TAG_DESCRIPTOR *) Descriptor; - End->Desc = ACPI_END_TAG_DESCRIPTOR; - End->Checksum = 0; - - *Configuration = Buffer; - - return EFI_SUCCESS; - } - } - - return EFI_INVALID_PARAMETER; -} - -/** - - This function is called for all the PCI controllers that the PCI - bus driver finds. Can be used to Preprogram the controller. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle The PCI Root Bridge handle. - @param PciAddress Address of the controller on the PCI bus. - @param Phase The Phase during resource allocation. - - @retval EFI_SUCCESS Succeed. - @retval EFI_INVALID_PARAMETER RootBridgeHandle is not a valid handle. - -**/ -EFI_STATUS -EFIAPI -PreprocessController ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, - IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase - ) -{ - LIST_ENTRY *Link; - PCI_HOST_BRIDGE_INSTANCE *HostBridge; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - - if ((UINT32) Phase > EfiPciBeforeResourceCollection) { - return EFI_INVALID_PARAMETER; - } - - HostBridge = PCI_HOST_BRIDGE_FROM_THIS (This); - for (Link = GetFirstNode (&HostBridge->RootBridges) - ; !IsNull (&HostBridge->RootBridges, Link) - ; Link = GetNextNode (&HostBridge->RootBridges, Link) - ) { - RootBridge = ROOT_BRIDGE_FROM_LINK (Link); - if (RootBridgeHandle == RootBridge->Handle) { - return EFI_SUCCESS; - } - } - - return EFI_INVALID_PARAMETER; -} diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h deleted file mode 100644 index 9a8ca21f48..0000000000 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h +++ /dev/null @@ -1,252 +0,0 @@ -/** @file - - The Header file of the Pci Host Bridge Driver. - -Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _PCI_HOST_BRIDGE_H_ -#define _PCI_HOST_BRIDGE_H_ - - -#include -#include -#include -#include -#include -#include - -#include "PciRootBridge.h" - -#define PCI_HOST_BRIDGE_SIGNATURE SIGNATURE_32 ('p', 'h', 'b', 'g') -typedef struct { - UINTN Signature; - EFI_HANDLE Handle; - LIST_ENTRY RootBridges; - BOOLEAN CanRestarted; - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL ResAlloc; -} PCI_HOST_BRIDGE_INSTANCE; - -#define PCI_HOST_BRIDGE_FROM_THIS(a) CR (a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE) - -// -// Driver Entry Point -// -/** - - Entry point of this driver. - - @param ImageHandle - Image handle of this driver. - @param SystemTable - Pointer to standard EFI system table. - - @retval EFI_SUCCESS - Succeed. - @retval EFI_DEVICE_ERROR - Fail to install PCI_ROOT_BRIDGE_IO protocol. - -**/ -EFI_STATUS -EFIAPI -InitializePciHostBridge ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -// -// HostBridge Resource Allocation interface -// -/** - - Enter a certain phase of the PCI enumeration process. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance. - @param Phase The phase during enumeration. - - @retval EFI_SUCCESS Succeed. - @retval EFI_INVALID_PARAMETER Wrong phase parameter passed in. - @retval EFI_NOT_READY Resources have not been submitted yet. - -**/ -EFI_STATUS -EFIAPI -NotifyPhase ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase - ); - -/** - - Return the device handle of the next PCI root bridge that is associated with - this Host Bridge. - - @param This The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle Returns the device handle of the next PCI Root Bridge. - On input, it holds the RootBridgeHandle returned by the most - recent call to GetNextRootBridge().The handle for the first - PCI Root Bridge is returned if RootBridgeHandle is NULL on input. - - @retval EFI_SUCCESS Succeed. - @retval EFI_NOT_FOUND Next PCI root bridge not found. - @retval EFI_INVALID_PARAMETER Wrong parameter passed in. - -**/ -EFI_STATUS -EFIAPI -GetNextRootBridge ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN OUT EFI_HANDLE *RootBridgeHandle - ); - -/** - - Returns the attributes of a PCI Root Bridge. - - @param This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance - @param RootBridgeHandle - The device handle of the PCI Root Bridge - that the caller is interested in - @param Attributes - The pointer to attributes of the PCI Root Bridge - - @retval EFI_SUCCESS - Succeed. - @retval EFI_INVALID_PARAMETER - Attributes parameter passed in is NULL or - @retval RootBridgeHandle is not an EFI_HANDLE - @retval that was returned on a previous call to - @retval GetNextRootBridge(). - -**/ -EFI_STATUS -EFIAPI -GetAttributes ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - OUT UINT64 *Attributes - ); - -/** - - This is the request from the PCI enumerator to set up - the specified PCI Root Bridge for bus enumeration process. - - @param This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle - The PCI Root Bridge to be set up. - @param Configuration - Pointer to the pointer to the PCI bus resource descriptor. - - @retval EFI_SUCCESS - Succeed. - @retval EFI_OUT_OF_RESOURCES - Not enough pool to be allocated. - @retval EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle. - -**/ -EFI_STATUS -EFIAPI -StartBusEnumeration ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - OUT VOID **Configuration - ); - -/** - - This function programs the PCI Root Bridge hardware so that - it decodes the specified PCI bus range. - - @param This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle - The PCI Root Bridge whose bus range is to be programmed. - @param Configuration - The pointer to the PCI bus resource descriptor. - - @retval EFI_SUCCESS - Succeed. - @retval EFI_INVALID_PARAMETER - Wrong parameters passed in. - -**/ -EFI_STATUS -EFIAPI -SetBusNumbers ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - IN VOID *Configuration - ); - -/** - - Submits the I/O and memory resource requirements for the specified PCI Root Bridge. - - @param This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance - @param RootBridgeHandle - The PCI Root Bridge whose I/O and memory resource requirements - are being submitted - @param Configuration - The pointer to the PCI I/O and PCI memory resource descriptor - - @retval EFI_SUCCESS - Succeed. - @retval EFI_INVALID_PARAMETER - Wrong parameters passed in. - -**/ -EFI_STATUS -EFIAPI -SubmitResources ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - IN VOID *Configuration - ); - -/** - - This function returns the proposed resource settings for the specified - PCI Root Bridge. - - @param This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle - The PCI Root Bridge handle. - @param Configuration - The pointer to the pointer to the PCI I/O - and memory resource descriptor. - - @retval EFI_SUCCESS - Succeed. - @retval EFI_OUT_OF_RESOURCES - Not enough pool to be allocated. - @retval EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle. - -**/ -EFI_STATUS -EFIAPI -GetProposedResources ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - OUT VOID **Configuration - ); - -/** - - This function is called for all the PCI controllers that the PCI - bus driver finds. Can be used to Preprogram the controller. - - @param This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance. - @param RootBridgeHandle - The PCI Root Bridge handle. - @param PciAddress - Address of the controller on the PCI bus. - @param Phase - The Phase during resource allocation. - - @retval EFI_SUCCESS - Succeed. - @retval EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle. - -**/ -EFI_STATUS -EFIAPI -PreprocessController ( - IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This, - IN EFI_HANDLE RootBridgeHandle, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, - IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase - ); - -/** - This routine constructs the resource descriptors for all root bridges and call PciHostBridgeResourceConflict(). - - @param HostBridge The Host Bridge Instance where the resource adjustment happens. -**/ -VOID -ResourceConflict ( - IN PCI_HOST_BRIDGE_INSTANCE *HostBridge - ); - -extern EFI_METRONOME_ARCH_PROTOCOL *mMetronome; -extern EFI_CPU_IO2_PROTOCOL *mCpuIo; -#endif diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf deleted file mode 100644 index d8b0439699..0000000000 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf +++ /dev/null @@ -1,56 +0,0 @@ -## @file -# Generic PCI Host Bridge driver. -# -# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = PciHostBridgeDxe - FILE_GUID = 128FB770-5E79-4176-9E51-9BB268A17DD1 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = InitializePciHostBridge - -[Sources] - PciHostBridge.h - PciRootBridge.h - PciHostBridge.c - PciRootBridgeIo.c - PciHostResource.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - UefiBootServicesTableLib - DebugLib - DxeServicesTableLib - DevicePathLib - BaseMemoryLib - BaseLib - PciSegmentLib - PciHostBridgeLib - -[Protocols] - gEfiMetronomeArchProtocolGuid ## CONSUMES - gEfiCpuIo2ProtocolGuid ## CONSUMES - gEfiDevicePathProtocolGuid ## BY_START - gEfiPciRootBridgeIoProtocolGuid ## BY_START - gEfiPciHostBridgeResourceAllocationProtocolGuid ## BY_START - -[Depex] - gEfiCpuIo2ProtocolGuid AND - gEfiMetronomeArchProtocolGuid AND - gEfiCpuArchProtocolGuid diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostResource.h b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostResource.h deleted file mode 100644 index f35222b634..0000000000 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostResource.h +++ /dev/null @@ -1,47 +0,0 @@ -/** @file - - The Header file of the Pci Host Bridge Driver. - -Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#ifndef _PCI_HOST_RESOURCE_H_ -#define _PCI_HOST_RESOURCE_H_ - -#include - -#define PCI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFE - -typedef enum { - TypeIo = 0, - TypeMem32, - TypePMem32, - TypeMem64, - TypePMem64, - TypeBus, - TypeMax -} PCI_RESOURCE_TYPE; - -typedef enum { - ResNone, - ResSubmitted, - ResAllocated, - ResStatusMax -} RES_STATUS; - -typedef struct { - PCI_RESOURCE_TYPE Type; - UINT64 Base; - UINT64 Length; - UINT64 Alignment; - RES_STATUS Status; -} PCI_RES_NODE; - -#endif diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h deleted file mode 100644 index 13185b41ac..0000000000 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridge.h +++ /dev/null @@ -1,578 +0,0 @@ -/** @file - - The PCI Root Bridge header file. - -Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _PCI_ROOT_BRIDGE_H_ -#define _PCI_ROOT_BRIDGE_H_ - -#include -#include -#include - -// -// Driver Consumed Protocol Prototypes -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "PciHostResource.h" - - -typedef enum { - IoOperation, - MemOperation, - PciOperation -} OPERATION_TYPE; - -#define MAP_INFO_SIGNATURE SIGNATURE_32 ('_', 'm', 'a', 'p') -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation; - UINTN NumberOfBytes; - UINTN NumberOfPages; - EFI_PHYSICAL_ADDRESS HostAddress; - EFI_PHYSICAL_ADDRESS MappedHostAddress; -} MAP_INFO; -#define MAP_INFO_FROM_LINK(a) CR (a, MAP_INFO, Link, MAP_INFO_SIGNATURE) - -#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32 ('_', 'p', 'r', 'b') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_HANDLE Handle; - UINT64 AllocationAttributes; - UINT64 Attributes; - UINT64 Supports; - PCI_RES_NODE ResAllocNode[TypeMax]; - PCI_ROOT_BRIDGE_APERTURE Bus; - PCI_ROOT_BRIDGE_APERTURE Io; - PCI_ROOT_BRIDGE_APERTURE Mem; - PCI_ROOT_BRIDGE_APERTURE PMem; - PCI_ROOT_BRIDGE_APERTURE MemAbove4G; - PCI_ROOT_BRIDGE_APERTURE PMemAbove4G; - BOOLEAN DmaAbove4G; - BOOLEAN NoExtendedConfigSpace; - VOID *ConfigBuffer; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - CHAR16 *DevicePathStr; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL RootBridgeIo; - - BOOLEAN ResourceSubmitted; - LIST_ENTRY Maps; -} PCI_ROOT_BRIDGE_INSTANCE; - -#define ROOT_BRIDGE_FROM_THIS(a) CR (a, PCI_ROOT_BRIDGE_INSTANCE, RootBridgeIo, PCI_ROOT_BRIDGE_SIGNATURE) - -#define ROOT_BRIDGE_FROM_LINK(a) CR (a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE) - -/** - Construct the Pci Root Bridge instance. - - @param Bridge The root bridge instance. - - @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created - or NULL if creation fails. -**/ -PCI_ROOT_BRIDGE_INSTANCE * -CreateRootBridge ( - IN PCI_ROOT_BRIDGE *Bridge - ); - -// -// Protocol Member Function Prototypes -// -/** - - Poll an address in memory mapped space until an exit condition is met - or a timeout occurs. - - @param This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. - @param Width - Width of the memory operation. - @param Address - The base address of the memory operation. - @param Mask - Mask used for polling criteria. - @param Value - Comparison value used for polling exit criteria. - @param Delay - Number of 100ns units to poll. - @param Result - Pointer to the last value read from memory location. - - @retval EFI_SUCCESS - Success. - @retval EFI_INVALID_PARAMETER - Invalid parameter found. - @retval EFI_TIMEOUT - Delay expired before a match occurred. - @retval EFI_OUT_OF_RESOURCES - Fail due to lack of resources. - -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPollMem ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -; - -/** - - Poll an address in I/O space until an exit condition is met - or a timeout occurs. - - @param This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. - @param Width - Width of I/O operation. - @param Address - The base address of the I/O operation. - @param Mask - Mask used for polling criteria. - @param Value - Comparison value used for polling exit criteria. - @param Delay - Number of 100ns units to poll. - @param Result - Pointer to the last value read from memory location. - - @retval EFI_SUCCESS - Success. - @retval EFI_INVALID_PARAMETER - Invalid parameter found. - @retval EFI_TIMEOUT - Delay expired before a match occurred. - @retval EFI_OUT_OF_RESOURCES - Fail due to lack of resources. - -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPollIo ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -; - -/** - - Allow read from memory mapped I/O space. - - @param This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. - @param Width - The width of memory operation. - @param Address - Base address of the memory operation. - @param Count - Number of memory opeartion to perform. - @param Buffer - The destination buffer to store data. - - @retval EFI_SUCCESS - Success. - @retval EFI_INVALID_PARAMETER - Invalid parameter found. - @retval EFI_OUT_OF_RESOURCES - Fail due to lack of resources. - -**/ -EFI_STATUS -EFIAPI -RootBridgeIoMemRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -; - -/** - - Allow write to memory mapped I/O space. - - @param This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. - @param Width - The width of memory operation. - @param Address - Base address of the memory operation. - @param Count - Number of memory opeartion to perform. - @param Buffer - The source buffer to write data from. - - @retval EFI_SUCCESS - Success. - @retval EFI_INVALID_PARAMETER - Invalid parameter found. - @retval EFI_OUT_OF_RESOURCES - Fail due to lack of resources. - -**/ -EFI_STATUS -EFIAPI -RootBridgeIoMemWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -; - -/** - - Enable a PCI driver to read PCI controller registers in the - PCI root bridge I/O space. - - @param This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - @param Width - Signifies the width of the memory operation. - @param UserAddress - The base address of the I/O operation. - @param Count - The number of I/O operations to perform. - @param UserBuffer - The destination buffer to store the results. - - @retval EFI_SUCCESS - The data was read from the PCI root bridge. - @retval EFI_INVALID_PARAMETER - Invalid parameters found. - @retval EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of - @retval resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoIoRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 UserAddress, - IN UINTN Count, - IN OUT VOID *UserBuffer - ) -; - -/** - - Enable a PCI driver to write to PCI controller registers in the - PCI root bridge I/O space. - - @param This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - @param Width - Signifies the width of the memory operation. - @param UserAddress - The base address of the I/O operation. - @param Count - The number of I/O operations to perform. - @param UserBuffer - The source buffer to write data from. - - @retval EFI_SUCCESS - The data was written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER - Invalid parameters found. - @retval EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of - @retval resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoIoWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 UserAddress, - IN UINTN Count, - IN OUT VOID *UserBuffer - ) -; - -/** - - Copy one region of PCI root bridge memory space to be copied to - another region of PCI root bridge memory space. - - @param This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. - @param Width - Signifies the width of the memory operation. - @param DestAddress - Destination address of the memory operation. - @param SrcAddress - Source address of the memory operation. - @param Count - Number of memory operations to perform. - - @retval EFI_SUCCESS - The data was copied successfully. - @retval EFI_INVALID_PARAMETER - Invalid parameters found. - @retval EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of - @retval resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoCopyMem ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 DestAddress, - IN UINT64 SrcAddress, - IN UINTN Count - ) -; - -/** - - Allows read from PCI configuration space. - - @param This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - @param Width - Signifies the width of the memory operation. - @param Address - The address within the PCI configuration space - for the PCI controller. - @param Count - The number of PCI configuration operations - to perform. - @param Buffer - The destination buffer to store the results. - - @retval EFI_SUCCESS - The data was read from the PCI root bridge. - @retval EFI_INVALID_PARAMETER - Invalid parameters found. - @retval EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of - @retval resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPciRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -; - -/** - - Allows write to PCI configuration space. - - @param This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - @param Width - Signifies the width of the memory operation. - @param Address - The address within the PCI configuration space - for the PCI controller. - @param Count - The number of PCI configuration operations - to perform. - @param Buffer - The source buffer to get the results. - - @retval EFI_SUCCESS - The data was written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER - Invalid parameters found. - @retval EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of - @retval resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPciWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -; - -/** - Provides the PCI controller-specific address needed to access - system memory for DMA. - - @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Operation Indicate if the bus master is going to read or write - to system memory. - @param HostAddress The system memory address to map on the PCI controller. - @param NumberOfBytes On input the number of bytes to map. - On output the number of bytes that were mapped. - @param DeviceAddress The resulting map address for the bus master PCI - controller to use to access the system memory's HostAddress. - @param Mapping The value to pass to Unmap() when the bus master DMA - operation is complete. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameters found. - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. - @retval EFI_DEVICE_ERROR The System hardware could not map the requested address. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoMap ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -; - -/** - Completes the Map() operation and releases any corresponding resources. - - The Unmap() function completes the Map() operation and releases any - corresponding resources. - If the operation was an EfiPciOperationBusMasterWrite or - EfiPciOperationBusMasterWrite64, the data is committed to the target system - memory. - Any resources used for the mapping are freed. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[in] Mapping The mapping value returned from Map(). - - @retval EFI_SUCCESS The range was unmapped. - @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map(). - @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoUnmap ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN VOID *Mapping - ) -; - -/** - Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer - or EfiPciOperationBusMasterCommonBuffer64 mapping. - - @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Type This parameter is not used and must be ignored. - @param MemoryType The type of memory to allocate, EfiBootServicesData or - EfiRuntimeServicesData. - @param Pages The number of pages to allocate. - @param HostAddress A pointer to store the base system memory address of the - allocated range. - @param Attributes The requested bit mask of attributes for the allocated - range. Only the attributes - EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, - EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and - EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this - function. - - @retval EFI_SUCCESS The requested memory pages were allocated. - @retval EFI_INVALID_PARAMETER MemoryType is invalid. - @retval EFI_INVALID_PARAMETER HostAddress is NULL. - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal - attribute bits are MEMORY_WRITE_COMBINE, - MEMORY_CACHED, and DUAL_ADDRESS_CYCLE. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoAllocateBuffer ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ) -; - -/** - - Free memory allocated in AllocateBuffer. - - @param This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - instance. - @param Pages - Number of pages to free. - @param HostAddress - The base system memory address of the - allocated range. - - @retval EFI_SUCCESS - Requested memory pages were freed. - @retval EFI_INVALID_PARAMETER - Invalid parameter found. - -**/ -EFI_STATUS -EFIAPI -RootBridgeIoFreeBuffer ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN UINTN Pages, - OUT VOID *HostAddress - ) -; - -/** - - Flushes all PCI posted write transactions from a PCI host - bridge to system memory. - - @param This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. - - @retval EFI_SUCCESS - PCI posted write transactions were flushed - @retval from PCI host bridge to system memory. - @retval EFI_DEVICE_ERROR - Fail due to hardware error. - -**/ -EFI_STATUS -EFIAPI -RootBridgeIoFlush ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This - ) -; - -/** - Gets the attributes that a PCI root bridge supports setting with - SetAttributes(), and the attributes that a PCI root bridge is currently - using. - - The GetAttributes() function returns the mask of attributes that this PCI - root bridge supports and the mask of attributes that the PCI root bridge is - currently using. - - @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Supported A pointer to the mask of attributes that this PCI root - bridge supports setting with SetAttributes(). - @param Attributes A pointer to the mask of attributes that this PCI root - bridge is currently using. - - @retval EFI_SUCCESS If Supports is not NULL, then the attributes - that the PCI root bridge supports is returned - in Supports. If Attributes is not NULL, then - the attributes that the PCI root bridge is - currently using is returned in Attributes. - @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoGetAttributes ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - OUT UINT64 *Supported, - OUT UINT64 *Attributes - ) -; - -/** - - Sets the attributes for a resource range on a PCI root bridge. - - @param This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. - @param Attributes - The mask of attributes to set. - @param ResourceBase - Pointer to the base address of the resource range - to be modified by the attributes specified by Attributes. - @param ResourceLength - Pointer to the length of the resource range to be modified. - - @retval EFI_SUCCESS - Success. - @retval EFI_INVALID_PARAMETER - Invalid parameter found. - @retval EFI_OUT_OF_RESOURCES - Not enough resources to set the attributes upon. - -**/ -EFI_STATUS -EFIAPI -RootBridgeIoSetAttributes ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN UINT64 Attributes, - IN OUT UINT64 *ResourceBase, - IN OUT UINT64 *ResourceLength - ) -; - -/** - - Retrieves the current resource settings of this PCI root bridge - in the form of a set of ACPI 2.0 resource descriptor. - - @param This - Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance. - @param Resources - Pointer to the ACPI 2.0 resource descriptor that - describe the current configuration of this PCI root - bridge. - - @retval EFI_SUCCESS - Success. - @retval EFI_UNSUPPORTED - Current configuration of the PCI root bridge - @retval could not be retrieved. - -**/ -EFI_STATUS -EFIAPI -RootBridgeIoConfiguration ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - OUT VOID **Resources - ) -; - - -extern EFI_METRONOME_ARCH_PROTOCOL *mMetronome; -extern EFI_CPU_IO2_PROTOCOL *mCpuIo; -#endif diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c deleted file mode 100644 index b2d76d67af..0000000000 --- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c +++ /dev/null @@ -1,1594 +0,0 @@ -/** @file - - PCI Root Bridge Io Protocol code. - -Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PciHostBridge.h" -#include "PciRootBridge.h" -#include "PciHostResource.h" - -#define NO_MAPPING (VOID *) (UINTN) -1 - -// -// Lookup table for increment values based on transfer widths -// -UINT8 mInStride[] = { - 1, // EfiPciWidthUint8 - 2, // EfiPciWidthUint16 - 4, // EfiPciWidthUint32 - 8, // EfiPciWidthUint64 - 0, // EfiPciWidthFifoUint8 - 0, // EfiPciWidthFifoUint16 - 0, // EfiPciWidthFifoUint32 - 0, // EfiPciWidthFifoUint64 - 1, // EfiPciWidthFillUint8 - 2, // EfiPciWidthFillUint16 - 4, // EfiPciWidthFillUint32 - 8 // EfiPciWidthFillUint64 -}; - -// -// Lookup table for increment values based on transfer widths -// -UINT8 mOutStride[] = { - 1, // EfiPciWidthUint8 - 2, // EfiPciWidthUint16 - 4, // EfiPciWidthUint32 - 8, // EfiPciWidthUint64 - 1, // EfiPciWidthFifoUint8 - 2, // EfiPciWidthFifoUint16 - 4, // EfiPciWidthFifoUint32 - 8, // EfiPciWidthFifoUint64 - 0, // EfiPciWidthFillUint8 - 0, // EfiPciWidthFillUint16 - 0, // EfiPciWidthFillUint32 - 0 // EfiPciWidthFillUint64 -}; - -/** - Construct the Pci Root Bridge instance. - - @param Bridge The root bridge instance. - - @return The pointer to PCI_ROOT_BRIDGE_INSTANCE just created - or NULL if creation fails. -**/ -PCI_ROOT_BRIDGE_INSTANCE * -CreateRootBridge ( - IN PCI_ROOT_BRIDGE *Bridge - ) -{ - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - PCI_RESOURCE_TYPE Index; - CHAR16 *DevicePathStr; - PCI_ROOT_BRIDGE_APERTURE *Aperture; - - DevicePathStr = NULL; - - DEBUG ((EFI_D_INFO, "RootBridge: ")); - DEBUG ((EFI_D_INFO, "%s\n", DevicePathStr = ConvertDevicePathToText (Bridge->DevicePath, FALSE, FALSE))); - DEBUG ((EFI_D_INFO, " Support/Attr: %lx / %lx\n", Bridge->Supports, Bridge->Attributes)); - DEBUG ((EFI_D_INFO, " DmaAbove4G: %s\n", Bridge->DmaAbove4G ? L"Yes" : L"No")); - DEBUG ((EFI_D_INFO, "NoExtConfSpace: %s\n", Bridge->NoExtendedConfigSpace ? L"Yes" : L"No")); - DEBUG ((EFI_D_INFO, " AllocAttr: %lx (%s%s)\n", Bridge->AllocationAttributes, - (Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0 ? L"CombineMemPMem " : L"", - (Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) != 0 ? L"Mem64Decode" : L"" - )); - DEBUG ((EFI_D_INFO, " Bus: %lx - %lx\n", Bridge->Bus.Base, Bridge->Bus.Limit)); - DEBUG ((EFI_D_INFO, " Io: %lx - %lx\n", Bridge->Io.Base, Bridge->Io.Limit)); - DEBUG ((EFI_D_INFO, " Mem: %lx - %lx\n", Bridge->Mem.Base, Bridge->Mem.Limit)); - DEBUG ((EFI_D_INFO, " MemAbove4G: %lx - %lx\n", Bridge->MemAbove4G.Base, Bridge->MemAbove4G.Limit)); - DEBUG ((EFI_D_INFO, " PMem: %lx - %lx\n", Bridge->PMem.Base, Bridge->PMem.Limit)); - DEBUG ((EFI_D_INFO, " PMemAbove4G: %lx - %lx\n", Bridge->PMemAbove4G.Base, Bridge->PMemAbove4G.Limit)); - - // - // Make sure Mem and MemAbove4G apertures are valid - // - if (Bridge->Mem.Base <= Bridge->Mem.Limit) { - ASSERT (Bridge->Mem.Limit < SIZE_4GB); - if (Bridge->Mem.Limit >= SIZE_4GB) { - return NULL; - } - } - if (Bridge->MemAbove4G.Base <= Bridge->MemAbove4G.Limit) { - ASSERT (Bridge->MemAbove4G.Base >= SIZE_4GB); - if (Bridge->MemAbove4G.Base < SIZE_4GB) { - return NULL; - } - } - if (Bridge->PMem.Base <= Bridge->PMem.Limit) { - ASSERT (Bridge->PMem.Limit < SIZE_4GB); - if (Bridge->PMem.Limit >= SIZE_4GB) { - return NULL; - } - } - if (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit) { - ASSERT (Bridge->PMemAbove4G.Base >= SIZE_4GB); - if (Bridge->PMemAbove4G.Base < SIZE_4GB) { - return NULL; - } - } - - // - // Ignore AllocationAttributes when resources were already assigned. - // - if (!Bridge->ResourceAssigned) { - if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0) { - // - // If this bit is set, then the PCI Root Bridge does not - // support separate windows for Non-prefetchable and Prefetchable - // memory. - // - ASSERT (Bridge->PMem.Base > Bridge->PMem.Limit); - ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit); - if ((Bridge->PMem.Base <= Bridge->PMem.Limit) || - (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit) - ) { - return NULL; - } - } - - if ((Bridge->AllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) == 0) { - // - // If this bit is not set, then the PCI Root Bridge does not support - // 64 bit memory windows. - // - ASSERT (Bridge->MemAbove4G.Base > Bridge->MemAbove4G.Limit); - ASSERT (Bridge->PMemAbove4G.Base > Bridge->PMemAbove4G.Limit); - if ((Bridge->MemAbove4G.Base <= Bridge->MemAbove4G.Limit) || - (Bridge->PMemAbove4G.Base <= Bridge->PMemAbove4G.Limit) - ) { - return NULL; - } - } - } - - RootBridge = AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INSTANCE)); - ASSERT (RootBridge != NULL); - - RootBridge->Signature = PCI_ROOT_BRIDGE_SIGNATURE; - RootBridge->Supports = Bridge->Supports; - RootBridge->Attributes = Bridge->Attributes; - RootBridge->DmaAbove4G = Bridge->DmaAbove4G; - RootBridge->NoExtendedConfigSpace = Bridge->NoExtendedConfigSpace; - RootBridge->AllocationAttributes = Bridge->AllocationAttributes; - RootBridge->DevicePath = DuplicateDevicePath (Bridge->DevicePath); - RootBridge->DevicePathStr = DevicePathStr; - RootBridge->ConfigBuffer = AllocatePool ( - TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) - ); - ASSERT (RootBridge->ConfigBuffer != NULL); - InitializeListHead (&RootBridge->Maps); - - CopyMem (&RootBridge->Bus, &Bridge->Bus, sizeof (PCI_ROOT_BRIDGE_APERTURE)); - CopyMem (&RootBridge->Io, &Bridge->Io, sizeof (PCI_ROOT_BRIDGE_APERTURE)); - CopyMem (&RootBridge->Mem, &Bridge->Mem, sizeof (PCI_ROOT_BRIDGE_APERTURE)); - CopyMem (&RootBridge->MemAbove4G, &Bridge->MemAbove4G, sizeof (PCI_ROOT_BRIDGE_APERTURE)); - CopyMem (&RootBridge->PMem, &Bridge->PMem, sizeof (PCI_ROOT_BRIDGE_APERTURE)); - CopyMem (&RootBridge->PMemAbove4G, &Bridge->PMemAbove4G, sizeof (PCI_ROOT_BRIDGE_APERTURE)); - - for (Index = TypeIo; Index < TypeMax; Index++) { - switch (Index) { - case TypeBus: - Aperture = &RootBridge->Bus; - break; - case TypeIo: - Aperture = &RootBridge->Io; - break; - case TypeMem32: - Aperture = &RootBridge->Mem; - break; - case TypeMem64: - Aperture = &RootBridge->MemAbove4G; - break; - case TypePMem32: - Aperture = &RootBridge->PMem; - break; - case TypePMem64: - Aperture = &RootBridge->PMemAbove4G; - break; - default: - ASSERT (FALSE); - Aperture = NULL; - break; - } - RootBridge->ResAllocNode[Index].Type = Index; - if (Bridge->ResourceAssigned && (Aperture->Limit >= Aperture->Base)) { - RootBridge->ResAllocNode[Index].Base = Aperture->Base; - RootBridge->ResAllocNode[Index].Length = Aperture->Limit - Aperture->Base + 1; - RootBridge->ResAllocNode[Index].Status = ResAllocated; - } else { - RootBridge->ResAllocNode[Index].Base = 0; - RootBridge->ResAllocNode[Index].Length = 0; - RootBridge->ResAllocNode[Index].Status = ResNone; - } - } - - RootBridge->RootBridgeIo.SegmentNumber = Bridge->Segment; - RootBridge->RootBridgeIo.PollMem = RootBridgeIoPollMem; - RootBridge->RootBridgeIo.PollIo = RootBridgeIoPollIo; - RootBridge->RootBridgeIo.Mem.Read = RootBridgeIoMemRead; - RootBridge->RootBridgeIo.Mem.Write = RootBridgeIoMemWrite; - RootBridge->RootBridgeIo.Io.Read = RootBridgeIoIoRead; - RootBridge->RootBridgeIo.Io.Write = RootBridgeIoIoWrite; - RootBridge->RootBridgeIo.CopyMem = RootBridgeIoCopyMem; - RootBridge->RootBridgeIo.Pci.Read = RootBridgeIoPciRead; - RootBridge->RootBridgeIo.Pci.Write = RootBridgeIoPciWrite; - RootBridge->RootBridgeIo.Map = RootBridgeIoMap; - RootBridge->RootBridgeIo.Unmap = RootBridgeIoUnmap; - RootBridge->RootBridgeIo.AllocateBuffer = RootBridgeIoAllocateBuffer; - RootBridge->RootBridgeIo.FreeBuffer = RootBridgeIoFreeBuffer; - RootBridge->RootBridgeIo.Flush = RootBridgeIoFlush; - RootBridge->RootBridgeIo.GetAttributes = RootBridgeIoGetAttributes; - RootBridge->RootBridgeIo.SetAttributes = RootBridgeIoSetAttributes; - RootBridge->RootBridgeIo.Configuration = RootBridgeIoConfiguration; - - return RootBridge; -} - -/** - Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO. - - The I/O operations are carried out exactly as requested. The caller is - responsible for satisfying any alignment and I/O width restrictions that a PI - System on a platform might require. For example on some platforms, width - requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other - hand, will be handled by the driver. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - - @param[in] OperationType I/O operation type: IO/MMIO/PCI. - - @param[in] Width Signifies the width of the I/O or Memory operation. - - @param[in] Address The base address of the I/O operation. - - @param[in] Count The number of I/O operations to perform. The number - of bytes moved is Width size * Count, starting at - Address. - - @param[in] Buffer For read operations, the destination buffer to - store the results. For write operations, the source - buffer from which to write data. - - @retval EFI_SUCCESS The parameters for this request pass the - checks. - - @retval EFI_INVALID_PARAMETER Width is invalid for this PI system. - - @retval EFI_INVALID_PARAMETER Buffer is NULL. - - @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width. - - @retval EFI_UNSUPPORTED The address range specified by Address, Width, - and Count is not valid for this PI system. -**/ -EFI_STATUS -RootBridgeIoCheckParameter ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN OPERATION_TYPE OperationType, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN VOID *Buffer - ) -{ - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr; - UINT64 Base; - UINT64 Limit; - UINT32 Size; - - // - // Check to see if Buffer is NULL - // - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check to see if Width is in the valid range - // - if ((UINT32) Width >= EfiPciWidthMaximum) { - return EFI_INVALID_PARAMETER; - } - - // - // For FIFO type, the target address won't increase during the access, - // so treat Count as 1 - // - if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) { - Count = 1; - } - - Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03); - Size = 1 << Width; - - // - // Check to see if Address is aligned - // - if ((Address & (Size - 1)) != 0) { - return EFI_UNSUPPORTED; - } - - RootBridge = ROOT_BRIDGE_FROM_THIS (This); - - // - // Check to see if any address associated with this transfer exceeds the - // maximum allowed address. The maximum address implied by the parameters - // passed in is Address + Size * Count. If the following condition is met, - // then the transfer is not supported. - // - // Address + Size * Count > Limit + 1 - // - // Since Limit can be the maximum integer value supported by the CPU and - // Count can also be the maximum integer value supported by the CPU, this - // range check must be adjusted to avoid all oveflow conditions. - // - if (OperationType == IoOperation) { - // - // Allow Legacy IO access - // - if (Address + MultU64x32 (Count, Size) <= 0x1000) { - if ((RootBridge->Attributes & ( - EFI_PCI_ATTRIBUTE_ISA_IO | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_ATTRIBUTE_VGA_IO | - EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | - EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_ATTRIBUTE_VGA_IO_16)) != 0) { - return EFI_SUCCESS; - } - } - Base = RootBridge->Io.Base; - Limit = RootBridge->Io.Limit; - } else if (OperationType == MemOperation) { - // - // Allow Legacy MMIO access - // - if ((Address >= 0xA0000) && (Address + MultU64x32 (Count, Size)) <= 0xC0000) { - if ((RootBridge->Attributes & EFI_PCI_ATTRIBUTE_VGA_MEMORY) != 0) { - return EFI_SUCCESS; - } - } - // - // By comparing the Address against Limit we know which range to be used - // for checking - // - if (Address + MultU64x32 (Count, Size) <= RootBridge->Mem.Limit + 1) { - Base = RootBridge->Mem.Base; - Limit = RootBridge->Mem.Limit; - } else { - Base = RootBridge->MemAbove4G.Base; - Limit = RootBridge->MemAbove4G.Limit; - } - } else { - PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address; - if (PciRbAddr->Bus < RootBridge->Bus.Base || - PciRbAddr->Bus > RootBridge->Bus.Limit) { - return EFI_INVALID_PARAMETER; - } - - if (PciRbAddr->Device > PCI_MAX_DEVICE || - PciRbAddr->Function > PCI_MAX_FUNC) { - return EFI_INVALID_PARAMETER; - } - - if (PciRbAddr->ExtendedRegister != 0) { - Address = PciRbAddr->ExtendedRegister; - } else { - Address = PciRbAddr->Register; - } - Base = 0; - Limit = RootBridge->NoExtendedConfigSpace ? 0xFF : 0xFFF; - } - - if (Address < Base) { - return EFI_INVALID_PARAMETER; - } - - if (Address + MultU64x32 (Count, Size) > Limit + 1) { - return EFI_INVALID_PARAMETER; - } - - return EFI_SUCCESS; -} - -/** - Polls an address in memory mapped I/O space until an exit condition is met, - or a timeout occurs. - - This function provides a standard way to poll a PCI memory location. A PCI - memory read operation is performed at the PCI memory address specified by - Address for the width specified by Width. The result of this PCI memory read - operation is stored in Result. This PCI memory read operation is repeated - until either a timeout of Delay 100 ns units has expired, or (Result & Mask) - is equal to Value. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[in] Width Signifies the width of the memory operations. - @param[in] Address The base address of the memory operations. The caller - is responsible for aligning Address if required. - @param[in] Mask Mask used for the polling criteria. Bytes above Width - in Mask are ignored. The bits in the bytes below Width - which are zero in Mask are ignored when polling the - memory address. - @param[in] Value The comparison value used for the polling exit - criteria. - @param[in] Delay The number of 100 ns units to poll. Note that timer - available may be of poorer granularity. - @param[out] Result Pointer to the last value read from the memory - location. - - @retval EFI_SUCCESS The last data returned from the access matched - the poll exit criteria. - @retval EFI_INVALID_PARAMETER Width is invalid. - @retval EFI_INVALID_PARAMETER Result is NULL. - @retval EFI_TIMEOUT Delay expired before a match occurred. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPollMem ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -{ - EFI_STATUS Status; - UINT64 NumberOfTicks; - UINT32 Remainder; - - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((UINT32)Width > EfiPciWidthUint64) { - return EFI_INVALID_PARAMETER; - } - - // - // No matter what, always do a single poll. - // - Status = This->Mem.Read (This, Width, Address, 1, Result); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((*Result & Mask) == Value) { - return EFI_SUCCESS; - } - - if (Delay == 0) { - return EFI_SUCCESS; - - } else { - - // - // Determine the proper # of metronome ticks to wait for polling the - // location. The nuber of ticks is Roundup (Delay / - // mMetronome->TickPeriod)+1 - // The "+1" to account for the possibility of the first tick being short - // because we started in the middle of a tick. - // - // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome - // protocol definition is updated. - // - NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, - &Remainder); - if (Remainder != 0) { - NumberOfTicks += 1; - } - NumberOfTicks += 1; - - while (NumberOfTicks != 0) { - - mMetronome->WaitForTick (mMetronome, 1); - - Status = This->Mem.Read (This, Width, Address, 1, Result); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((*Result & Mask) == Value) { - return EFI_SUCCESS; - } - - NumberOfTicks -= 1; - } - } - return EFI_TIMEOUT; -} - -/** - Reads from the I/O space of a PCI Root Bridge. Returns when either the - polling exit criteria is satisfied or after a defined duration. - - This function provides a standard way to poll a PCI I/O location. A PCI I/O - read operation is performed at the PCI I/O address specified by Address for - the width specified by Width. - The result of this PCI I/O read operation is stored in Result. This PCI I/O - read operation is repeated until either a timeout of Delay 100 ns units has - expired, or (Result & Mask) is equal to Value. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[in] Width Signifies the width of the I/O operations. - @param[in] Address The base address of the I/O operations. The caller is - responsible for aligning Address if required. - @param[in] Mask Mask used for the polling criteria. Bytes above Width in - Mask are ignored. The bits in the bytes below Width - which are zero in Mask are ignored when polling the I/O - address. - @param[in] Value The comparison value used for the polling exit criteria. - @param[in] Delay The number of 100 ns units to poll. Note that timer - available may be of poorer granularity. - @param[out] Result Pointer to the last value read from the memory location. - - @retval EFI_SUCCESS The last data returned from the access matched - the poll exit criteria. - @retval EFI_INVALID_PARAMETER Width is invalid. - @retval EFI_INVALID_PARAMETER Result is NULL. - @retval EFI_TIMEOUT Delay expired before a match occurred. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPollIo ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINT64 Mask, - IN UINT64 Value, - IN UINT64 Delay, - OUT UINT64 *Result - ) -{ - EFI_STATUS Status; - UINT64 NumberOfTicks; - UINT32 Remainder; - - // - // No matter what, always do a single poll. - // - - if (Result == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((UINT32)Width > EfiPciWidthUint64) { - return EFI_INVALID_PARAMETER; - } - - Status = This->Io.Read (This, Width, Address, 1, Result); - if (EFI_ERROR (Status)) { - return Status; - } - if ((*Result & Mask) == Value) { - return EFI_SUCCESS; - } - - if (Delay == 0) { - return EFI_SUCCESS; - - } else { - - // - // Determine the proper # of metronome ticks to wait for polling the - // location. The number of ticks is Roundup (Delay / - // mMetronome->TickPeriod)+1 - // The "+1" to account for the possibility of the first tick being short - // because we started in the middle of a tick. - // - NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, - &Remainder); - if (Remainder != 0) { - NumberOfTicks += 1; - } - NumberOfTicks += 1; - - while (NumberOfTicks != 0) { - - mMetronome->WaitForTick (mMetronome, 1); - - Status = This->Io.Read (This, Width, Address, 1, Result); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((*Result & Mask) == Value) { - return EFI_SUCCESS; - } - - NumberOfTicks -= 1; - } - } - return EFI_TIMEOUT; -} - -/** - Enables a PCI driver to access PCI controller registers in the PCI root - bridge memory space. - - The Mem.Read(), and Mem.Write() functions enable a driver to access PCI - controller registers in the PCI root bridge memory space. - The memory operations are carried out exactly as requested. The caller is - responsible for satisfying any alignment and memory width restrictions that a - PCI Root Bridge on a platform might require. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[in] Width Signifies the width of the memory operation. - @param[in] Address The base address of the memory operation. The caller - is responsible for aligning the Address if required. - @param[in] Count The number of memory operations to perform. Bytes - moved is Width size * Count, starting at Address. - @param[out] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer - to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI - root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoMemRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - - Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, - Count, Buffer); - if (EFI_ERROR (Status)) { - return Status; - } - return mCpuIo->Mem.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address, Count, Buffer); -} - -/** - Enables a PCI driver to access PCI controller registers in the PCI root - bridge memory space. - - The Mem.Read(), and Mem.Write() functions enable a driver to access PCI - controller registers in the PCI root bridge memory space. - The memory operations are carried out exactly as requested. The caller is - responsible for satisfying any alignment and memory width restrictions that a - PCI Root Bridge on a platform might require. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[in] Width Signifies the width of the memory operation. - @param[in] Address The base address of the memory operation. The caller - is responsible for aligning the Address if required. - @param[in] Count The number of memory operations to perform. Bytes - moved is Width size * Count, starting at Address. - @param[in] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer - to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI - root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoMemWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - - Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, - Count, Buffer); - if (EFI_ERROR (Status)) { - return Status; - } - return mCpuIo->Mem.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address, Count, Buffer); -} - -/** - Enables a PCI driver to access PCI controller registers in the PCI root - bridge I/O space. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[in] Width Signifies the width of the memory operations. - @param[in] Address The base address of the I/O operation. The caller is - responsible for aligning the Address if required. - @param[in] Count The number of I/O operations to perform. Bytes moved - is Width size * Count, starting at Address. - @param[out] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer - to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI - root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoIoRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - Status = RootBridgeIoCheckParameter ( - This, IoOperation, Width, - Address, Count, Buffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - return mCpuIo->Io.Read (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address, Count, Buffer); -} - -/** - Enables a PCI driver to access PCI controller registers in the PCI root - bridge I/O space. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[in] Width Signifies the width of the memory operations. - @param[in] Address The base address of the I/O operation. The caller is - responsible for aligning the Address if required. - @param[in] Count The number of I/O operations to perform. Bytes moved - is Width size * Count, starting at Address. - @param[in] Buffer For read operations, the destination buffer to store - the results. For write operations, the source buffer - to write data from. - - @retval EFI_SUCCESS The data was read from or written to the PCI - root bridge. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_INVALID_PARAMETER Buffer is NULL. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoIoWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - Status = RootBridgeIoCheckParameter ( - This, IoOperation, Width, - Address, Count, Buffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - return mCpuIo->Io.Write (mCpuIo, (EFI_CPU_IO_PROTOCOL_WIDTH) Width, Address, Count, Buffer); -} - -/** - Enables a PCI driver to copy one region of PCI root bridge memory space to - another region of PCI root bridge memory space. - - The CopyMem() function enables a PCI driver to copy one region of PCI root - bridge memory space to another region of PCI root bridge memory space. This - is especially useful for video scroll operation on a memory mapped video - buffer. - The memory operations are carried out exactly as requested. The caller is - responsible for satisfying any alignment and memory width restrictions that a - PCI root bridge on a platform might require. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - instance. - @param[in] Width Signifies the width of the memory operations. - @param[in] DestAddress The destination address of the memory operation. The - caller is responsible for aligning the DestAddress if - required. - @param[in] SrcAddress The source address of the memory operation. The caller - is responsible for aligning the SrcAddress if - required. - @param[in] Count The number of memory operations to perform. Bytes - moved is Width size * Count, starting at DestAddress - and SrcAddress. - - @retval EFI_SUCCESS The data was copied from one memory region - to another memory region. - @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a - lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoCopyMem ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 DestAddress, - IN UINT64 SrcAddress, - IN UINTN Count - ) -{ - EFI_STATUS Status; - BOOLEAN Forward; - UINTN Stride; - UINTN Index; - UINT64 Result; - - if ((UINT32) Width > EfiPciWidthUint64) { - return EFI_INVALID_PARAMETER; - } - - if (DestAddress == SrcAddress) { - return EFI_SUCCESS; - } - - Stride = (UINTN) (1 << Width); - - Forward = TRUE; - if ((DestAddress > SrcAddress) && - (DestAddress < (SrcAddress + Count * Stride))) { - Forward = FALSE; - SrcAddress = SrcAddress + (Count - 1) * Stride; - DestAddress = DestAddress + (Count - 1) * Stride; - } - - for (Index = 0; Index < Count; Index++) { - Status = RootBridgeIoMemRead ( - This, - Width, - SrcAddress, - 1, - &Result - ); - if (EFI_ERROR (Status)) { - return Status; - } - Status = RootBridgeIoMemWrite ( - This, - Width, - DestAddress, - 1, - &Result - ); - if (EFI_ERROR (Status)) { - return Status; - } - if (Forward) { - SrcAddress += Stride; - DestAddress += Stride; - } else { - SrcAddress -= Stride; - DestAddress -= Stride; - } - } - return EFI_SUCCESS; -} - - -/** - PCI configuration space access. - - @param This A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - @param Read TRUE indicating it's a read operation. - @param Width Signifies the width of the memory operation. - @param Address The address within the PCI configuration space - for the PCI controller. - @param Count The number of PCI configuration operations - to perform. - @param Buffer The destination buffer to store the results. - - @retval EFI_SUCCESS The data was read/written from/to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Invalid parameters found. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPciAccess ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN BOOLEAN Read, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress; - UINT8 *Uint8Buffer; - UINT8 InStride; - UINT8 OutStride; - UINTN Size; - - Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Read Pci configuration space - // - RootBridge = ROOT_BRIDGE_FROM_THIS (This); - CopyMem (&PciAddress, &Address, sizeof (PciAddress)); - - if (PciAddress.ExtendedRegister == 0) { - PciAddress.ExtendedRegister = PciAddress.Register; - } - - Address = PCI_SEGMENT_LIB_ADDRESS ( - RootBridge->RootBridgeIo.SegmentNumber, - PciAddress.Bus, - PciAddress.Device, - PciAddress.Function, - PciAddress.ExtendedRegister - ); - - // - // Select loop based on the width of the transfer - // - InStride = mInStride[Width]; - OutStride = mOutStride[Width]; - Size = (UINTN) (1 << (Width & 0x03)); - for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) { - if (Read) { - PciSegmentReadBuffer (Address, Size, Uint8Buffer); - } else { - PciSegmentWriteBuffer (Address, Size, Uint8Buffer); - } - } - return EFI_SUCCESS; -} - -/** - Allows read from PCI configuration space. - - @param This A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - @param Width Signifies the width of the memory operation. - @param Address The address within the PCI configuration space - for the PCI controller. - @param Count The number of PCI configuration operations - to perform. - @param Buffer The destination buffer to store the results. - - @retval EFI_SUCCESS The data was read from the PCI root bridge. - @retval EFI_INVALID_PARAMETER Invalid parameters found. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPciRead ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - return RootBridgeIoPciAccess (This, TRUE, Width, Address, Count, Buffer); -} - -/** - Allows write to PCI configuration space. - - @param This A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL - @param Width Signifies the width of the memory operation. - @param Address The address within the PCI configuration space - for the PCI controller. - @param Count The number of PCI configuration operations - to perform. - @param Buffer The source buffer to get the results. - - @retval EFI_SUCCESS The data was written to the PCI root bridge. - @retval EFI_INVALID_PARAMETER Invalid parameters found. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoPciWrite ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - return RootBridgeIoPciAccess (This, FALSE, Width, Address, Count, Buffer); -} - -/** - Provides the PCI controller-specific address needed to access - system memory for DMA. - - @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Operation Indicate if the bus master is going to read or write - to system memory. - @param HostAddress The system memory address to map on the PCI controller. - @param NumberOfBytes On input the number of bytes to map. - On output the number of bytes that were mapped. - @param DeviceAddress The resulting map address for the bus master PCI - controller to use to access the system memory's HostAddress. - @param Mapping The value to pass to Unmap() when the bus master DMA - operation is complete. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER Invalid parameters found. - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. - @retval EFI_DEVICE_ERROR The System hardware could not map the requested address. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to lack of resources. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoMap ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -{ - EFI_STATUS Status; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - EFI_PHYSICAL_ADDRESS PhysicalAddress; - MAP_INFO *MapInfo; - - if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || - Mapping == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Make sure that Operation is valid - // - if ((UINT32) Operation >= EfiPciOperationMaximum) { - return EFI_INVALID_PARAMETER; - } - - RootBridge = ROOT_BRIDGE_FROM_THIS (This); - - PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress; - if (!RootBridge->DmaAbove4G && ((PhysicalAddress + *NumberOfBytes) > SIZE_4GB)) { - // - // If the root bridge can not handle performing DMA above 4GB but - // any part of the DMA transfer being mapped is above 4GB, then - // map the DMA transfer to a buffer below 4GB. - // - - if (Operation == EfiPciOperationBusMasterCommonBuffer || - Operation == EfiPciOperationBusMasterCommonBuffer64) { - // - // Common Buffer operations can not be remapped. If the common buffer - // if above 4GB, then it is not possible to generate a mapping, so return - // an error. - // - return EFI_UNSUPPORTED; - } - - // - // Allocate a MAP_INFO structure to remember the mapping when Unmap() is - // called later. - // - MapInfo = AllocatePool (sizeof (MAP_INFO)); - if (MapInfo == NULL) { - *NumberOfBytes = 0; - return EFI_OUT_OF_RESOURCES; - } - - // - // Initialize the MAP_INFO structure - // - MapInfo->Signature = MAP_INFO_SIGNATURE; - MapInfo->Operation = Operation; - MapInfo->NumberOfBytes = *NumberOfBytes; - MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes); - MapInfo->HostAddress = PhysicalAddress; - MapInfo->MappedHostAddress = SIZE_4GB - 1; - - // - // Allocate a buffer below 4GB to map the transfer to. - // - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiBootServicesData, - MapInfo->NumberOfPages, - &MapInfo->MappedHostAddress - ); - if (EFI_ERROR (Status)) { - FreePool (MapInfo); - *NumberOfBytes = 0; - return Status; - } - - // - // If this is a read operation from the Bus Master's point of view, - // then copy the contents of the real buffer into the mapped buffer - // so the Bus Master can read the contents of the real buffer. - // - if (Operation == EfiPciOperationBusMasterRead || - Operation == EfiPciOperationBusMasterRead64) { - CopyMem ( - (VOID *) (UINTN) MapInfo->MappedHostAddress, - (VOID *) (UINTN) MapInfo->HostAddress, - MapInfo->NumberOfBytes - ); - } - - InsertTailList (&RootBridge->Maps, &MapInfo->Link); - - // - // The DeviceAddress is the address of the maped buffer below 4GB - // - *DeviceAddress = MapInfo->MappedHostAddress; - // - // Return a pointer to the MAP_INFO structure in Mapping - // - *Mapping = MapInfo; - } else { - // - // If the root bridge CAN handle performing DMA above 4GB or - // the transfer is below 4GB, so the DeviceAddress is simply the - // HostAddress - // - *DeviceAddress = PhysicalAddress; - *Mapping = NO_MAPPING; - } - - return EFI_SUCCESS; -} - -/** - Completes the Map() operation and releases any corresponding resources. - - The Unmap() function completes the Map() operation and releases any - corresponding resources. - If the operation was an EfiPciOperationBusMasterWrite or - EfiPciOperationBusMasterWrite64, the data is committed to the target system - memory. - Any resources used for the mapping are freed. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[in] Mapping The mapping value returned from Map(). - - @retval EFI_SUCCESS The range was unmapped. - @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map(). - @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoUnmap ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN VOID *Mapping - ) -{ - MAP_INFO *MapInfo; - LIST_ENTRY *Link; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - - RootBridge = ROOT_BRIDGE_FROM_THIS (This); - // - // See if the Map() operation associated with this Unmap() required a mapping - // buffer. If a mapping buffer was not required, then this function simply - // returns EFI_SUCCESS. - // - if (Mapping == NO_MAPPING) { - return EFI_SUCCESS; - } - - MapInfo = NO_MAPPING; - for (Link = GetFirstNode (&RootBridge->Maps) - ; !IsNull (&RootBridge->Maps, Link) - ; Link = GetNextNode (&RootBridge->Maps, Link) - ) { - MapInfo = MAP_INFO_FROM_LINK (Link); - if (MapInfo == Mapping) { - break; - } - } - // - // Mapping is not a valid value returned by Map() - // - if (MapInfo != Mapping) { - return EFI_INVALID_PARAMETER; - } - RemoveEntryList (&MapInfo->Link); - - // - // If this is a write operation from the Bus Master's point of view, - // then copy the contents of the mapped buffer into the real buffer - // so the processor can read the contents of the real buffer. - // - if (MapInfo->Operation == EfiPciOperationBusMasterWrite || - MapInfo->Operation == EfiPciOperationBusMasterWrite64) { - CopyMem ( - (VOID *) (UINTN) MapInfo->HostAddress, - (VOID *) (UINTN) MapInfo->MappedHostAddress, - MapInfo->NumberOfBytes - ); - } - - // - // Free the mapped buffer and the MAP_INFO structure. - // - gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages); - FreePool (Mapping); - return EFI_SUCCESS; -} - -/** - Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer - or EfiPciOperationBusMasterCommonBuffer64 mapping. - - @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Type This parameter is not used and must be ignored. - @param MemoryType The type of memory to allocate, EfiBootServicesData or - EfiRuntimeServicesData. - @param Pages The number of pages to allocate. - @param HostAddress A pointer to store the base system memory address of the - allocated range. - @param Attributes The requested bit mask of attributes for the allocated - range. Only the attributes - EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, - EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and - EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this - function. - - @retval EFI_SUCCESS The requested memory pages were allocated. - @retval EFI_INVALID_PARAMETER MemoryType is invalid. - @retval EFI_INVALID_PARAMETER HostAddress is NULL. - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal - attribute bits are MEMORY_WRITE_COMBINE, - MEMORY_CACHED, and DUAL_ADDRESS_CYCLE. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoAllocateBuffer ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS PhysicalAddress; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - EFI_ALLOCATE_TYPE AllocateType; - - // - // Validate Attributes - // - if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) { - return EFI_UNSUPPORTED; - } - - // - // Check for invalid inputs - // - if (HostAddress == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // The only valid memory types are EfiBootServicesData and - // EfiRuntimeServicesData - // - if (MemoryType != EfiBootServicesData && - MemoryType != EfiRuntimeServicesData) { - return EFI_INVALID_PARAMETER; - } - - RootBridge = ROOT_BRIDGE_FROM_THIS (This); - - AllocateType = AllocateAnyPages; - if (!RootBridge->DmaAbove4G) { - // - // Limit allocations to memory below 4GB - // - AllocateType = AllocateMaxAddress; - PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1); - } - Status = gBS->AllocatePages ( - AllocateType, - MemoryType, - Pages, - &PhysicalAddress - ); - if (!EFI_ERROR (Status)) { - *HostAddress = (VOID *) (UINTN) PhysicalAddress; - } - - return Status; -} - -/** - Frees memory that was allocated with AllocateBuffer(). - - The FreeBuffer() function frees memory that was allocated with - AllocateBuffer(). - - @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Pages The number of pages to free. - @param HostAddress The base system memory address of the allocated range. - - @retval EFI_SUCCESS The requested memory pages were freed. - @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and - Pages was not allocated with AllocateBuffer(). -**/ -EFI_STATUS -EFIAPI -RootBridgeIoFreeBuffer ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN UINTN Pages, - OUT VOID *HostAddress - ) -{ - return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages); -} - -/** - Flushes all PCI posted write transactions from a PCI host bridge to system - memory. - - The Flush() function flushes any PCI posted write transactions from a PCI - host bridge to system memory. Posted write transactions are generated by PCI - bus masters when they perform write transactions to target addresses in - system memory. - This function does not flush posted write transactions from any PCI bridges. - A PCI controller specific action must be taken to guarantee that the posted - write transactions have been flushed from the PCI controller and from all the - PCI bridges into the PCI host bridge. This is typically done with a PCI read - transaction from the PCI controller prior to calling Flush(). - - @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - - @retval EFI_SUCCESS The PCI posted write transactions were flushed - from the PCI host bridge to system memory. - @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed - from the PCI host bridge due to a hardware error. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoFlush ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This - ) -{ - return EFI_SUCCESS; -} - -/** - Gets the attributes that a PCI root bridge supports setting with - SetAttributes(), and the attributes that a PCI root bridge is currently - using. - - The GetAttributes() function returns the mask of attributes that this PCI - root bridge supports and the mask of attributes that the PCI root bridge is - currently using. - - @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Supported A pointer to the mask of attributes that this PCI root - bridge supports setting with SetAttributes(). - @param Attributes A pointer to the mask of attributes that this PCI root - bridge is currently using. - - @retval EFI_SUCCESS If Supports is not NULL, then the attributes - that the PCI root bridge supports is returned - in Supports. If Attributes is not NULL, then - the attributes that the PCI root bridge is - currently using is returned in Attributes. - @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoGetAttributes ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - OUT UINT64 *Supported, - OUT UINT64 *Attributes - ) -{ - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - - if (Attributes == NULL && Supported == NULL) { - return EFI_INVALID_PARAMETER; - } - - RootBridge = ROOT_BRIDGE_FROM_THIS (This); - // - // Set the return value for Supported and Attributes - // - if (Supported != NULL) { - *Supported = RootBridge->Supports; - } - - if (Attributes != NULL) { - *Attributes = RootBridge->Attributes; - } - - return EFI_SUCCESS; -} - -/** - Sets attributes for a resource range on a PCI root bridge. - - The SetAttributes() function sets the attributes specified in Attributes for - the PCI root bridge on the resource range specified by ResourceBase and - ResourceLength. Since the granularity of setting these attributes may vary - from resource type to resource type, and from platform to platform, the - actual resource range and the one passed in by the caller may differ. As a - result, this function may set the attributes specified by Attributes on a - larger resource range than the caller requested. The actual range is returned - in ResourceBase and ResourceLength. The caller is responsible for verifying - that the actual range for which the attributes were set is acceptable. - - @param This A pointer to the - EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param Attributes The mask of attributes to set. If the - attribute bit MEMORY_WRITE_COMBINE, - MEMORY_CACHED, or MEMORY_DISABLE is set, - then the resource range is specified by - ResourceBase and ResourceLength. If - MEMORY_WRITE_COMBINE, MEMORY_CACHED, and - MEMORY_DISABLE are not set, then - ResourceBase and ResourceLength are ignored, - and may be NULL. - @param ResourceBase A pointer to the base address of the - resource range to be modified by the - attributes specified by Attributes. - @param ResourceLength A pointer to the length of the resource - range to be modified by the attributes - specified by Attributes. - - @retval EFI_SUCCESS The current configuration of this PCI root bridge - was returned in Resources. - @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge - could not be retrieved. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoSetAttributes ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - IN UINT64 Attributes, - IN OUT UINT64 *ResourceBase, - IN OUT UINT64 *ResourceLength - ) -{ - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - - RootBridge = ROOT_BRIDGE_FROM_THIS (This); - - if ((Attributes & (~RootBridge->Supports)) != 0) { - return EFI_UNSUPPORTED; - } - - RootBridge->Attributes = Attributes; - return EFI_SUCCESS; -} - -/** - Retrieves the current resource settings of this PCI root bridge in the form - of a set of ACPI 2.0 resource descriptors. - - There are only two resource descriptor types from the ACPI Specification that - may be used to describe the current resources allocated to a PCI root bridge. - These are the QWORD Address Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), - and the End Tag (ACPI 2.0 Section 6.4.2.8). The QWORD Address Space - Descriptor can describe memory, I/O, and bus number ranges for dynamic or - fixed resources. The configuration of a PCI root bridge is described with one - or more QWORD Address Space Descriptors followed by an End Tag. - - @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL. - @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that - describe the current configuration of this PCI root - bridge. The storage for the ACPI 2.0 resource - descriptors is allocated by this function. The - caller must treat the return buffer as read-only - data, and the buffer must not be freed by the - caller. - - @retval EFI_SUCCESS The current configuration of this PCI root bridge - was returned in Resources. - @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge - could not be retrieved. -**/ -EFI_STATUS -EFIAPI -RootBridgeIoConfiguration ( - IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, - OUT VOID **Resources - ) -{ - PCI_RESOURCE_TYPE Index; - PCI_ROOT_BRIDGE_INSTANCE *RootBridge; - PCI_RES_NODE *ResAllocNode; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; - EFI_ACPI_END_TAG_DESCRIPTOR *End; - - // - // Get this instance of the Root Bridge. - // - RootBridge = ROOT_BRIDGE_FROM_THIS (This); - ZeroMem ( - RootBridge->ConfigBuffer, - TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) - ); - Descriptor = RootBridge->ConfigBuffer; - for (Index = TypeIo; Index < TypeMax; Index++) { - - ResAllocNode = &RootBridge->ResAllocNode[Index]; - - if (ResAllocNode->Status != ResAllocated) { - continue; - } - - Descriptor->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; - Descriptor->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3; - Descriptor->AddrRangeMin = ResAllocNode->Base; - Descriptor->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1; - Descriptor->AddrLen = ResAllocNode->Length; - switch (ResAllocNode->Type) { - - case TypeIo: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_IO; - break; - - case TypePMem32: - Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE; - case TypeMem32: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - Descriptor->AddrSpaceGranularity = 32; - break; - - case TypePMem64: - Descriptor->SpecificFlag = EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE; - case TypeMem64: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; - Descriptor->AddrSpaceGranularity = 64; - break; - - case TypeBus: - Descriptor->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS; - break; - - default: - break; - } - - Descriptor++; - } - // - // Terminate the entries. - // - End = (EFI_ACPI_END_TAG_DESCRIPTOR *) Descriptor; - End->Desc = ACPI_END_TAG_DESCRIPTOR; - End->Checksum = 0x0; - - *Resources = RootBridge->ConfigBuffer; - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/PciSioSerialDxe/ComponentName.c deleted file mode 100644 index 994dc847c9..0000000000 --- a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/ComponentName.c +++ /dev/null @@ -1,288 +0,0 @@ -/** @file - UEFI Component Name and Name2 protocol for Isa serial driver. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Serial.h" - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPciSioSerialComponentName = { - SerialComponentNameGetDriverName, - SerialComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPciSioSerialComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SerialComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) SerialComponentNameGetControllerName, - "en" -}; - - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSerialDriverNameTable[] = { - { - "eng;en", - L"PCI SIO Serial Driver" - }, - { - NULL, - NULL - } -}; - -GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 mSioSerialPortName[] = L"SIO Serial Port #%d"; -GLOBAL_REMOVE_IF_UNREFERENCED CHAR16 mPciSerialPortName[] = L"PCI Serial Port #%d"; - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -SerialComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mSerialDriverNameTable, - DriverName, - (BOOLEAN)(This == &gPciSioSerialComponentName) - ); -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -SerialComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - EFI_SERIAL_IO_PROTOCOL *SerialIo; - SERIAL_DEV *SerialDevice; - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - EFI_GUID *IoProtocolGuid; - - // - // Make sure this driver is currently managing ControllerHandle - // - IoProtocolGuid = &gEfiSioProtocolGuid; - Status = EfiTestManagedDevice ( - ControllerHandle, - gSerialControllerDriver.DriverBindingHandle, - IoProtocolGuid - ); - if (EFI_ERROR (Status)) { - IoProtocolGuid = &gEfiPciIoProtocolGuid; - Status = EfiTestManagedDevice ( - ControllerHandle, - gSerialControllerDriver.DriverBindingHandle, - IoProtocolGuid - ); - } - - if (EFI_ERROR (Status)) { - return Status; - } - - ControllerNameTable = NULL; - if (ChildHandle != NULL) { - Status = EfiTestChildHandle ( - ControllerHandle, - ChildHandle, - IoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the Serial I/O Protocol from the child handle - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiSerialIoProtocolGuid, - (VOID **) &SerialIo, - gSerialControllerDriver.DriverBindingHandle, - ChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the Serial Controller's Device structure - // - SerialDevice = SERIAL_DEV_FROM_THIS (SerialIo); - ControllerNameTable = SerialDevice->ControllerNameTable; - } - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - ControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gPciSioSerialComponentName) - ); -} - -/** - Add the ISO639-2 and RFC4646 component name both for the Serial IO device - - @param SerialDevice A pointer to the SERIAL_DEV instance. - @param Instance Instance ID for the serial device. -**/ -VOID -AddName ( - IN SERIAL_DEV *SerialDevice, - IN UINT32 Instance - ) -{ - CHAR16 SerialPortName[SERIAL_PORT_NAME_LEN]; - UnicodeSPrint ( - SerialPortName, - sizeof (SerialPortName), - (SerialDevice->PciDeviceInfo != NULL) ? PCI_SERIAL_PORT_NAME : SIO_SERIAL_PORT_NAME, - Instance - ); - AddUnicodeString2 ( - "eng", - gPciSioSerialComponentName.SupportedLanguages, - &SerialDevice->ControllerNameTable, - SerialPortName, - TRUE - ); - AddUnicodeString2 ( - "en", - gPciSioSerialComponentName2.SupportedLanguages, - &SerialDevice->ControllerNameTable, - SerialPortName, - FALSE - ); - -} diff --git a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf b/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf deleted file mode 100644 index 03fddfe75e..0000000000 --- a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf +++ /dev/null @@ -1,81 +0,0 @@ -## @file -# Serial driver for standard UARTS on a SIO chip or PCI/PCIE card. -# -# Produces the Serial I/O protocol for standard UARTS using Super I/O or PCI I/O. -# -# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = PciSioSerialDxe - MODULE_UNI_FILE = PciSioSerialDxe.uni - FILE_GUID = E2775B47-D453-4EE3-ADA7-391A1B05AC17 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = InitializePciSioSerial - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# -# DRIVER_BINDING = gSerialControllerDriver -# COMPONENT_NAME = gPciSioSerialComponentName -# COMPONENT_NAME2 = gPciSioSerialComponentName2 -# - -[Sources] - ComponentName.c - SerialIo.c - Serial.h - Serial.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - PcdLib - ReportStatusCodeLib - UefiBootServicesTableLib - MemoryAllocationLib - BaseMemoryLib - DevicePathLib - UefiLib - UefiDriverEntryPoint - DebugLib - IoLib - -[Guids] - gEfiUartDevicePathGuid ## SOMETIMES_CONSUMES ## GUID - -[Protocols] - gEfiSioProtocolGuid ## TO_START - gEfiDevicePathProtocolGuid ## TO_START - gEfiPciIoProtocolGuid ## TO_START - gEfiSerialIoProtocolGuid ## BY_START - gEfiDevicePathProtocolGuid ## BY_START - -[FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHalfHandshake|FALSE ## CONSUMES - -[Pcd] - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200 ## CONSUMES - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8 ## CONSUMES - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1 ## CONSUMES - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1 ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|1843200 ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPciSerialParameters ## CONSUMES - -[UserExtensions.TianoCore."ExtraFiles"] - PciSioSerialDxeExtra.uni diff --git a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.uni b/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.uni deleted file mode 100644 index 617f583b35..0000000000 Binary files a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxeExtra.uni b/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxeExtra.uni deleted file mode 100644 index 935bdba93e..0000000000 Binary files a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxeExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.c b/MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.c deleted file mode 100644 index aeafee247c..0000000000 --- a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.c +++ /dev/null @@ -1,1248 +0,0 @@ -/** @file - Serial driver for PCI or SIO UARTS. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Serial.h" - -// -// ISA Serial Driver Global Variables -// - -EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver = { - SerialControllerDriverSupported, - SerialControllerDriverStart, - SerialControllerDriverStop, - 0xa, - NULL, - NULL -}; - -CONTROLLER_DEVICE_PATH mControllerDevicePathTemplate = { - { - HARDWARE_DEVICE_PATH, - HW_CONTROLLER_DP, - { - (UINT8) (sizeof (CONTROLLER_DEVICE_PATH)), - (UINT8) ((sizeof (CONTROLLER_DEVICE_PATH)) >> 8) - } - }, - 0 -}; - -SERIAL_DEV gSerialDevTemplate = { - SERIAL_DEV_SIGNATURE, - NULL, - { - SERIAL_IO_INTERFACE_REVISION, - SerialReset, - SerialSetAttributes, - SerialSetControl, - SerialGetControl, - SerialWrite, - SerialRead, - NULL - }, // SerialIo - { - SERIAL_PORT_SUPPORT_CONTROL_MASK, - SERIAL_PORT_DEFAULT_TIMEOUT, - 0, - 16, - 0, - 0, - 0 - }, // SerialMode - NULL, // DevicePath - NULL, // ParentDevicePath - { - { - MESSAGING_DEVICE_PATH, - MSG_UART_DP, - { - (UINT8) (sizeof (UART_DEVICE_PATH)), - (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) - } - }, - 0, 0, 0, 0, 0 - }, // UartDevicePath - 0, // BaseAddress - FALSE, // MmioAccess - 1, // RegisterStride - 0, // ClockRate - 16, // ReceiveFifoDepth - { 0, 0 }, // Receive; - 16, // TransmitFifoDepth - { 0, 0 }, // Transmit; - FALSE, // SoftwareLoopbackEnable; - FALSE, // HardwareFlowControl; - NULL, // *ControllerNameTable; - FALSE, // ContainsControllerNode; - 0, // Instance; - NULL // *PciDeviceInfo; -}; - -/** - Check the device path node whether it's the Flow Control node or not. - - @param[in] FlowControl The device path node to be checked. - - @retval TRUE It's the Flow Control node. - @retval FALSE It's not. - -**/ -BOOLEAN -IsUartFlowControlDevicePathNode ( - IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl - ) -{ - return (BOOLEAN) ( - (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) && - (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) && - (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid)) - ); -} - -/** - The user Entry Point for module PciSioSerial. The user code starts with this function. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval other Some error occurs when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -InitializePciSioSerial ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - // - // Install driver model protocol(s). - // - Status = EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gSerialControllerDriver, - ImageHandle, - &gPciSioSerialComponentName, - &gPciSioSerialComponentName2 - ); - ASSERT_EFI_ERROR (Status); - - // - // Initialize UART default setting in gSerialDevTempate - // - gSerialDevTemplate.SerialMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate); - gSerialDevTemplate.SerialMode.DataBits = PcdGet8 (PcdUartDefaultDataBits); - gSerialDevTemplate.SerialMode.Parity = PcdGet8 (PcdUartDefaultParity); - gSerialDevTemplate.SerialMode.StopBits = PcdGet8 (PcdUartDefaultStopBits); - gSerialDevTemplate.UartDevicePath.BaudRate = PcdGet64 (PcdUartDefaultBaudRate); - gSerialDevTemplate.UartDevicePath.DataBits = PcdGet8 (PcdUartDefaultDataBits); - gSerialDevTemplate.UartDevicePath.Parity = PcdGet8 (PcdUartDefaultParity); - gSerialDevTemplate.UartDevicePath.StopBits = PcdGet8 (PcdUartDefaultStopBits); - gSerialDevTemplate.ClockRate = PcdGet32 (PcdSerialClockRate); - - return Status; -} - -/** - Return whether the controller is a SIO serial controller. - - @param Controller The controller handle. - - @retval EFI_SUCCESS The controller is a SIO serial controller. - @retval others The controller is not a SIO serial controller. -**/ -EFI_STATUS -IsSioSerialController ( - EFI_HANDLE Controller - ) -{ - EFI_STATUS Status; - EFI_SIO_PROTOCOL *Sio; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - ACPI_HID_DEVICE_PATH *Acpi; - - // - // Open the IO Abstraction(s) needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiSioProtocolGuid, - (VOID **) &Sio, - gSerialControllerDriver.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (!EFI_ERROR (Status)) { - // - // Close the I/O Abstraction(s) used to perform the supported test - // - gBS->CloseProtocol ( - Controller, - &gEfiSioProtocolGuid, - gSerialControllerDriver.DriverBindingHandle, - Controller - ); - - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &DevicePath, - gSerialControllerDriver.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - ASSERT (Status != EFI_ALREADY_STARTED); - - if (!EFI_ERROR (Status)) { - do { - Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath; - DevicePath = NextDevicePathNode (DevicePath); - } while (!IsDevicePathEnd (DevicePath)); - - if (DevicePathType (Acpi) != ACPI_DEVICE_PATH || - (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP) || - Acpi->HID != EISA_PNP_ID (0x501) - ) { - Status = EFI_UNSUPPORTED; - } - } - - // - // Close protocol, don't use device path protocol in the Support() function - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - gSerialControllerDriver.DriverBindingHandle, - Controller - ); - } - return Status; -} - -/** - Return whether the controller is a PCI serial controller. - - @param Controller The controller handle. - - @retval EFI_SUCCESS The controller is a PCI serial controller. - @retval others The controller is not a PCI serial controller. -**/ -EFI_STATUS -IsPciSerialController ( - EFI_HANDLE Controller - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - PCI_TYPE00 Pci; - PCI_SERIAL_PARAMETER *PciSerialParameter; - - // - // Open the IO Abstraction(s) needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - gSerialControllerDriver.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (Status == EFI_ALREADY_STARTED) { - return EFI_SUCCESS; - } - - if (!EFI_ERROR (Status)) { - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (Pci), &Pci); - if (!EFI_ERROR (Status)) { - if (!IS_PCI_16550_SERIAL (&Pci)) { - for (PciSerialParameter = (PCI_SERIAL_PARAMETER *) PcdGetPtr (PcdPciSerialParameters) - ; PciSerialParameter->VendorId != 0xFFFF - ; PciSerialParameter++ - ) { - if ((Pci.Hdr.VendorId == PciSerialParameter->VendorId) && - (Pci.Hdr.DeviceId == PciSerialParameter->DeviceId) - ) { - break; - } - } - if (PciSerialParameter->VendorId == 0xFFFF) { - Status = EFI_UNSUPPORTED; - } else { - Status = EFI_SUCCESS; - } - } - } - - // - // Close the I/O Abstraction(s) used to perform the supported test - // - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - gSerialControllerDriver.DriverBindingHandle, - Controller - ); - } - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Open the EFI Device Path protocol needed to perform the supported test - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &DevicePath, - gSerialControllerDriver.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - ASSERT (Status != EFI_ALREADY_STARTED); - - // - // Close protocol, don't use device path protocol in the Support() function - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - gSerialControllerDriver.DriverBindingHandle, - Controller - ); - - return Status; -} - -/** - Check to see if this driver supports the given controller - - @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param Controller The handle of the controller to test. - @param RemainingDevicePath A pointer to the remaining portion of a device path. - - @return EFI_SUCCESS This driver can support the given controller - -**/ -EFI_STATUS -EFIAPI -SerialControllerDriverSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) - -{ - EFI_STATUS Status; - UART_DEVICE_PATH *Uart; - UART_FLOW_CONTROL_DEVICE_PATH *FlowControl; - - // - // Test RemainingDevicePath - // - if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) { - Status = EFI_UNSUPPORTED; - - Uart = SkipControllerDevicePathNode (RemainingDevicePath, NULL, NULL); - if (DevicePathType (Uart) != MESSAGING_DEVICE_PATH || - DevicePathSubType (Uart) != MSG_UART_DP || - DevicePathNodeLength (Uart) != sizeof (UART_DEVICE_PATH) - ) { - return EFI_UNSUPPORTED; - } - - // - // Do a rough check because Clock Rate is unknown until DriverBindingStart() - // - if (!VerifyUartParameters (0, Uart->BaudRate, Uart->DataBits, Uart->Parity, Uart->StopBits, NULL, NULL)) { - return EFI_UNSUPPORTED; - } - - FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart); - if (IsUartFlowControlDevicePathNode (FlowControl)) { - // - // If the second node is Flow Control Node, - // return error when it request other than hardware flow control. - // - if ((ReadUnaligned32 (&FlowControl->FlowControlMap) & ~UART_FLOW_CONTROL_HARDWARE) != 0) { - return EFI_UNSUPPORTED; - } - } - } - - Status = IsSioSerialController (Controller); - if (EFI_ERROR (Status)) { - Status = IsPciSerialController (Controller); - } - return Status; -} - -/** - Create the child serial device instance. - - @param Controller The parent controller handle. - @param Uart Pointer to the UART device path node in RemainingDevicePath, - or NULL if RemainingDevicePath is NULL. - @param ParentDevicePath Pointer to the parent device path. - @param CreateControllerNode TRUE to create the controller node. - @param Instance Instance number of the serial device. - The value will be set to the controller node - if CreateControllerNode is TRUE. - @param ParentIo A union type pointer to either Sio or PciIo. - @param PciSerialParameter The PCI serial parameter to be used by current serial device. - NULL for SIO serial device. - @param PciDeviceInfo The PCI device info for the current serial device. - NULL for SIO serial device. - - @retval EFI_SUCCESS The serial device was created successfully. - @retval others The serial device wasn't created. -**/ -EFI_STATUS -CreateSerialDevice ( - IN EFI_HANDLE Controller, - IN UART_DEVICE_PATH *Uart, - IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN BOOLEAN CreateControllerNode, - IN UINT32 Instance, - IN PARENT_IO_PROTOCOL_PTR ParentIo, - IN PCI_SERIAL_PARAMETER *PciSerialParameter, OPTIONAL - IN PCI_DEVICE_INFO *PciDeviceInfo OPTIONAL - ) -{ - EFI_STATUS Status; - SERIAL_DEV *SerialDevice; - UINT8 BarIndex; - UINT64 Offset; - UART_FLOW_CONTROL_DEVICE_PATH *FlowControl; - UINT32 FlowControlMap; - ACPI_RESOURCE_HEADER_PTR Resources; - EFI_ACPI_IO_PORT_DESCRIPTOR *Io; - EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *FixedIo; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *AddressSpace; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - - BarIndex = 0; - Offset = 0; - FlowControl = NULL; - FlowControlMap = 0; - - // - // Initialize the serial device instance - // - SerialDevice = AllocateCopyPool (sizeof (SERIAL_DEV), &gSerialDevTemplate); - ASSERT (SerialDevice != NULL); - - SerialDevice->SerialIo.Mode = &(SerialDevice->SerialMode); - SerialDevice->ParentDevicePath = ParentDevicePath; - SerialDevice->PciDeviceInfo = PciDeviceInfo; - SerialDevice->Instance = Instance; - - if (Uart != NULL) { - CopyMem (&SerialDevice->UartDevicePath, Uart, sizeof (UART_DEVICE_PATH)); - FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart); - if (IsUartFlowControlDevicePathNode (FlowControl)) { - FlowControlMap = ReadUnaligned32 (&FlowControl->FlowControlMap); - } else { - FlowControl = NULL; - } - } - - // - // For PCI serial device, use the information from PCD - // - if (PciSerialParameter != NULL) { - BarIndex = (PciSerialParameter->BarIndex == PCI_BAR_ALL) ? 0 : PciSerialParameter->BarIndex; - Offset = PciSerialParameter->Offset; - if (PciSerialParameter->RegisterStride != 0) { - SerialDevice->RegisterStride = PciSerialParameter->RegisterStride; - } - if (PciSerialParameter->ClockRate != 0) { - SerialDevice->ClockRate = PciSerialParameter->ClockRate; - } - if (PciSerialParameter->ReceiveFifoDepth != 0) { - SerialDevice->ReceiveFifoDepth = PciSerialParameter->ReceiveFifoDepth; - } - if (PciSerialParameter->TransmitFifoDepth != 0) { - SerialDevice->TransmitFifoDepth = PciSerialParameter->TransmitFifoDepth; - } - } - - // - // Pass NULL ActualBaudRate to VerifyUartParameters to disallow baudrate degrade. - // DriverBindingStart() shouldn't create a handle with different UART device path. - // - if (!VerifyUartParameters (SerialDevice->ClockRate, SerialDevice->UartDevicePath.BaudRate, SerialDevice->UartDevicePath.DataBits, - SerialDevice->UartDevicePath.Parity, SerialDevice->UartDevicePath.StopBits, NULL, NULL - )) { - Status = EFI_INVALID_PARAMETER; - goto CreateError; - } - - if (PciSerialParameter == NULL) { - Status = ParentIo.Sio->GetResources (ParentIo.Sio, &Resources); - } else { - Status = ParentIo.PciIo->GetBarAttributes (ParentIo.PciIo, BarIndex, NULL, (VOID **) &Resources); - } - - if (!EFI_ERROR (Status)) { - // - // Get the base address information from ACPI resource descriptor. - // ACPI_IO_PORT_DESCRIPTOR and ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR are returned from Sio; - // ACPI_ADDRESS_SPACE_DESCRIPTOR is returned from PciIo. - // - while ((Resources.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) && (SerialDevice->BaseAddress == 0)) { - switch (Resources.SmallHeader->Byte) { - case ACPI_IO_PORT_DESCRIPTOR: - Io = (EFI_ACPI_IO_PORT_DESCRIPTOR *) Resources.SmallHeader; - if (Io->Length != 0) { - SerialDevice->BaseAddress = Io->BaseAddressMin; - } - break; - - case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR: - FixedIo = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) Resources.SmallHeader; - if (FixedIo->Length != 0) { - SerialDevice->BaseAddress = FixedIo->BaseAddress; - } - break; - - case ACPI_ADDRESS_SPACE_DESCRIPTOR: - AddressSpace = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Resources.SmallHeader; - if (AddressSpace->AddrLen != 0) { - if (AddressSpace->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { - SerialDevice->MmioAccess = TRUE; - } - SerialDevice->BaseAddress = AddressSpace->AddrRangeMin + Offset; - } - break; - } - - if (Resources.SmallHeader->Bits.Type == 0) { - Resources.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) Resources.SmallHeader - + Resources.SmallHeader->Bits.Length - + sizeof (*Resources.SmallHeader)); - } else { - Resources.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) Resources.LargeHeader - + Resources.LargeHeader->Length - + sizeof (*Resources.LargeHeader)); - } - } - } - - if (SerialDevice->BaseAddress == 0) { - Status = EFI_INVALID_PARAMETER; - goto CreateError; - } - - SerialDevice->HardwareFlowControl = (BOOLEAN) (FlowControlMap == UART_FLOW_CONTROL_HARDWARE); - - // - // Report status code the serial present - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_P_PC_PRESENCE_DETECT | EFI_PERIPHERAL_SERIAL_PORT, - SerialDevice->ParentDevicePath - ); - - if (!SerialPresent (SerialDevice)) { - Status = EFI_DEVICE_ERROR; - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE, - EFI_P_EC_NOT_DETECTED | EFI_PERIPHERAL_SERIAL_PORT, - SerialDevice->ParentDevicePath - ); - goto CreateError; - } - - // - // 1. Append Controller device path node. - // - if (CreateControllerNode) { - mControllerDevicePathTemplate.ControllerNumber = SerialDevice->Instance; - SerialDevice->DevicePath = AppendDevicePathNode ( - SerialDevice->ParentDevicePath, - (EFI_DEVICE_PATH_PROTOCOL *) &mControllerDevicePathTemplate - ); - SerialDevice->ContainsControllerNode = TRUE; - } - - // - // 2. Append UART device path node. - // The Uart setings are zero here. - // SetAttribute() will update them to match the default setings. - // - TempDevicePath = SerialDevice->DevicePath; - if (TempDevicePath != NULL) { - SerialDevice->DevicePath = AppendDevicePathNode ( - TempDevicePath, - (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath - ); - FreePool (TempDevicePath); - } else { - SerialDevice->DevicePath = AppendDevicePathNode ( - SerialDevice->ParentDevicePath, - (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath - ); - } - // - // 3. Append the Flow Control device path node. - // Only produce the Flow Control node when remaining device path has it - // - if (FlowControl != NULL) { - TempDevicePath = SerialDevice->DevicePath; - if (TempDevicePath != NULL) { - SerialDevice->DevicePath = AppendDevicePathNode ( - TempDevicePath, - (EFI_DEVICE_PATH_PROTOCOL *) FlowControl - ); - FreePool (TempDevicePath); - } - } - ASSERT (SerialDevice->DevicePath != NULL); - - // - // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults. - // - SerialDevice->SerialMode.BaudRate = SerialDevice->UartDevicePath.BaudRate; - SerialDevice->SerialMode.DataBits = SerialDevice->UartDevicePath.DataBits; - SerialDevice->SerialMode.Parity = SerialDevice->UartDevicePath.Parity; - SerialDevice->SerialMode.StopBits = SerialDevice->UartDevicePath.StopBits; - - // - // Issue a reset to initialize the COM port - // - Status = SerialDevice->SerialIo.Reset (&SerialDevice->SerialIo); - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE, - EFI_P_EC_CONTROLLER_ERROR | EFI_PERIPHERAL_SERIAL_PORT, - SerialDevice->DevicePath - ); - goto CreateError; - } - - AddName (SerialDevice, Instance); - // - // Install protocol interfaces for the serial device. - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &SerialDevice->Handle, - &gEfiDevicePathProtocolGuid, SerialDevice->DevicePath, - &gEfiSerialIoProtocolGuid, &SerialDevice->SerialIo, - NULL - ); - if (EFI_ERROR (Status)) { - goto CreateError; - } - // - // Open For Child Device - // - Status = gBS->OpenProtocol ( - Controller, - PciSerialParameter != NULL ? &gEfiPciIoProtocolGuid : &gEfiSioProtocolGuid, - (VOID **) &ParentIo, - gSerialControllerDriver.DriverBindingHandle, - SerialDevice->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - &SerialDevice->Handle, - &gEfiDevicePathProtocolGuid, SerialDevice->DevicePath, - &gEfiSerialIoProtocolGuid, &SerialDevice->SerialIo, - NULL - ); - } - -CreateError: - if (EFI_ERROR (Status)) { - if (SerialDevice->DevicePath != NULL) { - FreePool (SerialDevice->DevicePath); - } - if (SerialDevice->ControllerNameTable != NULL) { - FreeUnicodeStringTable (SerialDevice->ControllerNameTable); - } - FreePool (SerialDevice); - } - return Status; -} - -/** - Returns an array of pointers containing all the child serial device pointers. - - @param Controller The parent controller handle. - @param IoProtocolGuid The protocol GUID, either equals to gEfiSioProtocolGuid - or equals to gEfiPciIoProtocolGuid. - @param Count Count of the serial devices. - - @return An array of pointers containing all the child serial device pointers. -**/ -SERIAL_DEV ** -GetChildSerialDevices ( - IN EFI_HANDLE Controller, - IN EFI_GUID *IoProtocolGuid, - OUT UINTN *Count - ) -{ - EFI_STATUS Status; - UINTN Index; - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; - UINTN EntryCount; - SERIAL_DEV **SerialDevices; - EFI_SERIAL_IO_PROTOCOL *SerialIo; - BOOLEAN OpenByDriver; - - *Count = 0; - // - // If the SerialIo instance specified by RemainingDevicePath is already created, - // update the attributes/control. - // - Status = gBS->OpenProtocolInformation ( - Controller, - IoProtocolGuid, - &OpenInfoBuffer, - &EntryCount - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - SerialDevices = AllocatePool (EntryCount * sizeof (SERIAL_DEV *)); - ASSERT (SerialDevices != NULL); - - *Count = 0; - OpenByDriver = FALSE; - for (Index = 0; Index < EntryCount; Index++) { - if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { - Status = gBS->OpenProtocol ( - OpenInfoBuffer[Index].ControllerHandle, - &gEfiSerialIoProtocolGuid, - (VOID **) &SerialIo, - gSerialControllerDriver.DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - SerialDevices[(*Count)++] = SERIAL_DEV_FROM_THIS (SerialIo); - } - } - - - if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - ASSERT (OpenInfoBuffer[Index].AgentHandle == gSerialControllerDriver.DriverBindingHandle); - OpenByDriver = TRUE; - } - } - if (OpenInfoBuffer != NULL) { - FreePool (OpenInfoBuffer); - } - - ASSERT ((*Count == 0) || (OpenByDriver)); - - return SerialDevices; -} - -/** - Start to management the controller passed in - - @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param Controller The handle of the controller to test. - @param RemainingDevicePath A pointer to the remaining portion of a device path. - - @return EFI_SUCCESS Driver is started successfully -**/ -EFI_STATUS -EFIAPI -SerialControllerDriverStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - UINTN Index; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_DEVICE_PATH_PROTOCOL *Node; - EFI_SERIAL_IO_PROTOCOL *SerialIo; - UINT32 ControllerNumber; - UART_DEVICE_PATH *Uart; - UART_FLOW_CONTROL_DEVICE_PATH *FlowControl; - UINT32 Control; - PARENT_IO_PROTOCOL_PTR ParentIo; - ACPI_HID_DEVICE_PATH *Acpi; - EFI_GUID *IoProtocolGuid; - PCI_SERIAL_PARAMETER *PciSerialParameter; - PCI_SERIAL_PARAMETER DefaultPciSerialParameter; - PCI_TYPE00 Pci; - UINT32 PciSerialCount; - SERIAL_DEV **SerialDevices; - UINTN SerialDeviceCount; - PCI_DEVICE_INFO *PciDeviceInfo; - UINT64 Supports; - BOOLEAN ContainsControllerNode; - - // - // Get the Parent Device Path - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { - return Status; - } - // - // Report status code enable the serial - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_P_PC_ENABLE | EFI_PERIPHERAL_SERIAL_PORT, - ParentDevicePath - ); - - // - // Grab the IO abstraction we need to get any work done - // - IoProtocolGuid = &gEfiSioProtocolGuid; - Status = gBS->OpenProtocol ( - Controller, - IoProtocolGuid, - (VOID **) &ParentIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { - IoProtocolGuid = &gEfiPciIoProtocolGuid; - Status = gBS->OpenProtocol ( - Controller, - IoProtocolGuid, - (VOID **) &ParentIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - } - ASSERT (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED); - - // - // Do nothing for END device path node - // - if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) { - return EFI_SUCCESS; - } - - ControllerNumber = 0; - ContainsControllerNode = FALSE; - SerialDevices = GetChildSerialDevices (Controller, IoProtocolGuid, &SerialDeviceCount); - // - // If the SerialIo instance specified by RemainingDevicePath is already created, - // update the attributes/control. - // - if ((SerialDeviceCount != 0) && (RemainingDevicePath != NULL)) { - Uart = (UART_DEVICE_PATH *) SkipControllerDevicePathNode (RemainingDevicePath, &ContainsControllerNode, &ControllerNumber); - for (Index = 0; Index < SerialDeviceCount; Index++) { - ASSERT ((SerialDevices != NULL) && (SerialDevices[Index] != NULL)); - if ((!SerialDevices[Index]->ContainsControllerNode && !ContainsControllerNode) || - (SerialDevices[Index]->ContainsControllerNode && ContainsControllerNode && SerialDevices[Index]->Instance == ControllerNumber) - ) { - SerialIo = &SerialDevices[Index]->SerialIo; - Status = EFI_INVALID_PARAMETER; - // - // Pass NULL ActualBaudRate to VerifyUartParameters to disallow baudrate degrade. - // DriverBindingStart() shouldn't create a handle with different UART device path. - // - if (VerifyUartParameters (SerialDevices[Index]->ClockRate, Uart->BaudRate, Uart->DataBits, - (EFI_PARITY_TYPE) Uart->Parity, (EFI_STOP_BITS_TYPE) Uart->StopBits, NULL, NULL)) { - Status = SerialIo->SetAttributes ( - SerialIo, - Uart->BaudRate, - SerialIo->Mode->ReceiveFifoDepth, - SerialIo->Mode->Timeout, - (EFI_PARITY_TYPE) Uart->Parity, - Uart->DataBits, - (EFI_STOP_BITS_TYPE) Uart->StopBits - ); - } - FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart); - if (!EFI_ERROR (Status) && IsUartFlowControlDevicePathNode (FlowControl)) { - Status = SerialIo->GetControl (SerialIo, &Control); - if (!EFI_ERROR (Status)) { - if (ReadUnaligned32 (&FlowControl->FlowControlMap) == UART_FLOW_CONTROL_HARDWARE) { - Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; - } else { - Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; - } - // - // Clear the bits that are not allowed to pass to SetControl - // - Control &= (EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY | - EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | - EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE); - Status = SerialIo->SetControl (SerialIo, Control); - } - } - break; - } - } - if (Index != SerialDeviceCount) { - // - // Directly return if the SerialIo instance specified by RemainingDevicePath is found and updated. - // Otherwise continue to create the instance specified by RemainingDevicePath. - // - if (SerialDevices != NULL) { - FreePool (SerialDevices); - } - return Status; - } - } - - if (RemainingDevicePath != NULL) { - Uart = (UART_DEVICE_PATH *) SkipControllerDevicePathNode (RemainingDevicePath, &ContainsControllerNode, &ControllerNumber); - } else { - Uart = NULL; - } - - PciDeviceInfo = NULL; - if (IoProtocolGuid == &gEfiSioProtocolGuid) { - Status = EFI_NOT_FOUND; - if (RemainingDevicePath == NULL || !ContainsControllerNode) { - Node = ParentDevicePath; - do { - Acpi = (ACPI_HID_DEVICE_PATH *) Node; - Node = NextDevicePathNode (Node); - } while (!IsDevicePathEnd (Node)); - Status = CreateSerialDevice (Controller, Uart, ParentDevicePath, FALSE, Acpi->UID, ParentIo, NULL, NULL); - DEBUG ((EFI_D_INFO, "PciSioSerial: Create SIO child serial device - %r\n", Status)); - } - } else { - Status = ParentIo.PciIo->Pci.Read (ParentIo.PciIo, EfiPciIoWidthUint8, 0, sizeof (Pci), &Pci); - if (!EFI_ERROR (Status)) { - // - // PcdPciSerialParameters takes the higher priority. - // - PciSerialCount = 0; - for (PciSerialParameter = PcdGetPtr (PcdPciSerialParameters); PciSerialParameter->VendorId != 0xFFFF; PciSerialParameter++) { - if ((PciSerialParameter->VendorId == Pci.Hdr.VendorId) && - (PciSerialParameter->DeviceId == Pci.Hdr.DeviceId) - ) { - PciSerialCount++; - } - } - - if (SerialDeviceCount == 0) { - // - // Enable the IO & MEM decoding when creating the first child. - // Restore the PCI attributes when all children is destroyed (PciDeviceInfo->ChildCount == 0). - // - PciDeviceInfo = AllocatePool (sizeof (PCI_DEVICE_INFO)); - ASSERT (PciDeviceInfo != NULL); - PciDeviceInfo->ChildCount = 0; - PciDeviceInfo->PciIo = ParentIo.PciIo; - Status = ParentIo.PciIo->Attributes ( - ParentIo.PciIo, - EfiPciIoAttributeOperationGet, - 0, - &PciDeviceInfo->PciAttributes - ); - - if (!EFI_ERROR (Status)) { - Status = ParentIo.PciIo->Attributes ( - ParentIo.PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)(EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY); - Status = ParentIo.PciIo->Attributes ( - ParentIo.PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - } - } else { - // - // Re-use the PciDeviceInfo stored in existing children. - // - ASSERT ((SerialDevices != NULL) && (SerialDevices[0] != NULL)); - PciDeviceInfo = SerialDevices[0]->PciDeviceInfo; - ASSERT (PciDeviceInfo != NULL); - } - - Status = EFI_NOT_FOUND; - if (PciSerialCount <= 1) { - // - // PCI serial device contains only one UART - // - if (RemainingDevicePath == NULL || !ContainsControllerNode) { - // - // This PCI serial device is matched by class code in Supported() - // - if (PciSerialCount == 0) { - DefaultPciSerialParameter.VendorId = Pci.Hdr.VendorId; - DefaultPciSerialParameter.DeviceId = Pci.Hdr.DeviceId; - DefaultPciSerialParameter.BarIndex = 0; - DefaultPciSerialParameter.Offset = 0; - DefaultPciSerialParameter.RegisterStride = 0; - DefaultPciSerialParameter.ClockRate = 0; - PciSerialParameter = &DefaultPciSerialParameter; - } else if (PciSerialCount == 1) { - PciSerialParameter = PcdGetPtr (PcdPciSerialParameters); - } - - Status = CreateSerialDevice (Controller, Uart, ParentDevicePath, FALSE, 0, ParentIo, PciSerialParameter, PciDeviceInfo); - DEBUG ((EFI_D_INFO, "PciSioSerial: Create PCI child serial device (single) - %r\n", Status)); - if (!EFI_ERROR (Status)) { - PciDeviceInfo->ChildCount++; - } - } - } else { - // - // PCI serial device contains multiple UARTs - // - if (RemainingDevicePath == NULL || ContainsControllerNode) { - PciSerialCount = 0; - for (PciSerialParameter = PcdGetPtr (PcdPciSerialParameters); PciSerialParameter->VendorId != 0xFFFF; PciSerialParameter++) { - if ((PciSerialParameter->VendorId == Pci.Hdr.VendorId) && - (PciSerialParameter->DeviceId == Pci.Hdr.DeviceId) && - ((RemainingDevicePath == NULL) || (ControllerNumber == PciSerialCount)) - ) { - // - // Create controller node when PCI serial device contains multiple UARTs - // - Status = CreateSerialDevice (Controller, Uart, ParentDevicePath, TRUE, PciSerialCount, ParentIo, PciSerialParameter, PciDeviceInfo); - PciSerialCount++; - DEBUG ((EFI_D_INFO, "PciSioSerial: Create PCI child serial device (multiple) - %r\n", Status)); - if (!EFI_ERROR (Status)) { - PciDeviceInfo->ChildCount++; - } - } - } - } - } - } - } - - if (SerialDevices != NULL) { - FreePool (SerialDevices); - } - - // - // For multiple PCI serial devices, set Status to SUCCESS if one child is created successfully - // - if ((PciDeviceInfo != NULL) && (PciDeviceInfo->ChildCount != 0)) { - Status = EFI_SUCCESS; - } - - if (EFI_ERROR (Status) && (SerialDeviceCount == 0)) { - if (PciDeviceInfo != NULL) { - Status = ParentIo.PciIo->Attributes ( - ParentIo.PciIo, - EfiPciIoAttributeOperationSet, - PciDeviceInfo->PciAttributes, - NULL - ); - ASSERT_EFI_ERROR (Status); - FreePool (PciDeviceInfo); - } - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - gBS->CloseProtocol ( - Controller, - IoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - } - - return Status; -} - -/** - Disconnect this driver with the controller, uninstall related protocol instance - - @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param Controller The handle of the controller to test. - @param NumberOfChildren Number of child device. - @param ChildHandleBuffer A pointer to the remaining portion of a device path. - - @retval EFI_SUCCESS Operation successfully - @retval EFI_DEVICE_ERROR Cannot stop the driver successfully - -**/ -EFI_STATUS -EFIAPI -SerialControllerDriverStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) - -{ - EFI_STATUS Status; - UINTN Index; - BOOLEAN AllChildrenStopped; - EFI_SERIAL_IO_PROTOCOL *SerialIo; - SERIAL_DEV *SerialDevice; - VOID *IoProtocol; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - PCI_DEVICE_INFO *PciDeviceInfo; - - PciDeviceInfo = NULL; - - Status = gBS->HandleProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &DevicePath - ); - - // - // Report the status code disable the serial - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_P_PC_DISABLE | EFI_PERIPHERAL_SERIAL_PORT, - DevicePath - ); - - if (NumberOfChildren == 0) { - // - // Close the bus driver - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - &IoProtocol, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - gBS->CloseProtocol ( - Controller, - !EFI_ERROR (Status) ? &gEfiPciIoProtocolGuid : &gEfiSioProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - return EFI_SUCCESS; - } - - AllChildrenStopped = TRUE; - - for (Index = 0; Index < NumberOfChildren; Index++) { - - Status = gBS->OpenProtocol ( - ChildHandleBuffer[Index], - &gEfiSerialIoProtocolGuid, - (VOID **) &SerialIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - - SerialDevice = SERIAL_DEV_FROM_THIS (SerialIo); - ASSERT ((PciDeviceInfo == NULL) || (PciDeviceInfo == SerialDevice->PciDeviceInfo)); - PciDeviceInfo = SerialDevice->PciDeviceInfo; - - Status = gBS->CloseProtocol ( - Controller, - PciDeviceInfo != NULL ? &gEfiPciIoProtocolGuid : &gEfiSioProtocolGuid, - This->DriverBindingHandle, - ChildHandleBuffer[Index] - ); - - Status = gBS->UninstallMultipleProtocolInterfaces ( - ChildHandleBuffer[Index], - &gEfiDevicePathProtocolGuid, SerialDevice->DevicePath, - &gEfiSerialIoProtocolGuid, &SerialDevice->SerialIo, - NULL - ); - if (EFI_ERROR (Status)) { - gBS->OpenProtocol ( - Controller, - PciDeviceInfo != NULL ? &gEfiPciIoProtocolGuid : &gEfiSioProtocolGuid, - &IoProtocol, - This->DriverBindingHandle, - ChildHandleBuffer[Index], - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - } else { - FreePool (SerialDevice->DevicePath); - FreeUnicodeStringTable (SerialDevice->ControllerNameTable); - FreePool (SerialDevice); - - if (PciDeviceInfo != NULL) { - ASSERT (PciDeviceInfo->ChildCount != 0); - PciDeviceInfo->ChildCount--; - } - } - } - - if (EFI_ERROR (Status)) { - AllChildrenStopped = FALSE; - } - } - - if (!AllChildrenStopped) { - return EFI_DEVICE_ERROR; - } else { - // - // If all children are destroyed, restore the PCI attributes. - // - if ((PciDeviceInfo != NULL) && (PciDeviceInfo->ChildCount == 0)) { - ASSERT (PciDeviceInfo->PciIo != NULL); - Status = PciDeviceInfo->PciIo->Attributes ( - PciDeviceInfo->PciIo, - EfiPciIoAttributeOperationSet, - PciDeviceInfo->PciAttributes, - NULL - ); - ASSERT_EFI_ERROR (Status); - FreePool (PciDeviceInfo); - } - return EFI_SUCCESS; - } -} diff --git a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.h b/MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.h deleted file mode 100644 index f147e69044..0000000000 --- a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/Serial.h +++ /dev/null @@ -1,789 +0,0 @@ -/** @file - Header file for PciSioSerial Driver - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SERIAL_H_ -#define _SERIAL_H_ - - -#include - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Driver Binding Externs -// -extern EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver; -extern EFI_COMPONENT_NAME_PROTOCOL gPciSioSerialComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gPciSioSerialComponentName2; - -#define SIO_SERIAL_PORT_NAME L"SIO Serial Port #%d" -#define PCI_SERIAL_PORT_NAME L"PCI Serial Port #%d" -#define SERIAL_PORT_NAME_LEN (sizeof (SIO_SERIAL_PORT_NAME) / sizeof (CHAR16) + MAXIMUM_VALUE_CHARACTERS) - -// -// Internal Data Structures -// -#define TIMEOUT_STALL_INTERVAL 10 - -#pragma pack(1) -/// -/// PcdPciSerialParameters contains zero or more instances of the below structure. -/// If a PCI device contains multiple UARTs, PcdPciSerialParameters needs to contain -/// two instances of the below structure, with the VendorId and DeviceId equals to the -/// device ID and vendor ID of the device. If the PCI device uses the first two BARs -/// to support multiple UARTs, BarIndex of first instance equals to 0 and BarIndex of -/// second one equals to 1; if the PCI device uses the first BAR to support multiple -/// UARTs, BarIndex of both instance equals to 0 and Offset of first instance equals -/// to 0 while Offset of second one equals to some value bigger or equal to 8. -/// For certain UART whose register needs to be accessed in DWORD aligned address, -/// RegisterStride equals to 4. -/// -typedef struct { - UINT16 VendorId; ///< Vendor ID to match the PCI device. The value 0xFFFF terminates the list of entries. - UINT16 DeviceId; ///< Device ID to match the PCI device - UINT32 ClockRate; ///< UART clock rate. Set to 0 for default clock rate of 1843200 Hz - UINT64 Offset; ///< The byte offset into to the BAR - UINT8 BarIndex; ///< Which BAR to get the UART base address - UINT8 RegisterStride; ///< UART register stride in bytes. Set to 0 for default register stride of 1 byte. - UINT16 ReceiveFifoDepth; ///< UART receive FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes. - UINT16 TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes. - UINT8 Reserved[2]; -} PCI_SERIAL_PARAMETER; -#pragma pack() - -#define SERIAL_MAX_FIFO_SIZE 17 ///< Actual FIFO size is 16. FIFO based on circular wastes one unit. -typedef struct { - UINT16 Head; ///< Head pointer of the FIFO. Empty when (Head == Tail). - UINT16 Tail; ///< Tail pointer of the FIFO. Full when ((Tail + 1) % SERIAL_MAX_FIFO_SIZE == Head). - UINT8 Data[SERIAL_MAX_FIFO_SIZE]; ///< Store the FIFO data. -} SERIAL_DEV_FIFO; - -typedef union { - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_SIO_PROTOCOL *Sio; -} PARENT_IO_PROTOCOL_PTR; - -typedef struct { - EFI_PCI_IO_PROTOCOL *PciIo; // Pointer to parent PciIo instance. - UINTN ChildCount; // Count of child SerialIo instance. - UINT64 PciAttributes; // Original PCI attributes. -} PCI_DEVICE_INFO; - -typedef struct { - UINT32 Signature; - EFI_HANDLE Handle; - EFI_SERIAL_IO_PROTOCOL SerialIo; - EFI_SERIAL_IO_MODE SerialMode; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - UART_DEVICE_PATH UartDevicePath; - - EFI_PHYSICAL_ADDRESS BaseAddress; ///< UART base address - BOOLEAN MmioAccess; ///< TRUE for MMIO, FALSE for IO - UINT8 RegisterStride; ///< UART Register Stride - UINT32 ClockRate; ///< UART clock rate - - UINT16 ReceiveFifoDepth; ///< UART receive FIFO depth in bytes. - SERIAL_DEV_FIFO Receive; ///< The FIFO used to store received data - - UINT16 TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. - SERIAL_DEV_FIFO Transmit; ///< The FIFO used to store to-transmit data - - BOOLEAN SoftwareLoopbackEnable; - BOOLEAN HardwareFlowControl; - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - BOOLEAN ContainsControllerNode; ///< TRUE if the device produced contains Controller node - UINT32 Instance; - PCI_DEVICE_INFO *PciDeviceInfo; -} SERIAL_DEV; - -#define SERIAL_DEV_SIGNATURE SIGNATURE_32 ('s', 'e', 'r', 'd') -#define SERIAL_DEV_FROM_THIS(a) CR (a, SERIAL_DEV, SerialIo, SERIAL_DEV_SIGNATURE) - -// -// Serial Driver Defaults -// -#define SERIAL_PORT_DEFAULT_TIMEOUT 1000000 -#define SERIAL_PORT_SUPPORT_CONTROL_MASK (EFI_SERIAL_CLEAR_TO_SEND | \ - EFI_SERIAL_DATA_SET_READY | \ - EFI_SERIAL_RING_INDICATE | \ - EFI_SERIAL_CARRIER_DETECT | \ - EFI_SERIAL_REQUEST_TO_SEND | \ - EFI_SERIAL_DATA_TERMINAL_READY | \ - EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | \ - EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | \ - EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE | \ - EFI_SERIAL_OUTPUT_BUFFER_EMPTY | \ - EFI_SERIAL_INPUT_BUFFER_EMPTY) - -#define SERIAL_PORT_MIN_TIMEOUT 1 // 1 uS -#define SERIAL_PORT_MAX_TIMEOUT 100000000 // 100 seconds -// -// UART Registers -// -#define SERIAL_REGISTER_THR 0 ///< WO Transmit Holding Register -#define SERIAL_REGISTER_RBR 0 ///< RO Receive Buffer Register -#define SERIAL_REGISTER_DLL 0 ///< R/W Divisor Latch LSB -#define SERIAL_REGISTER_DLM 1 ///< R/W Divisor Latch MSB -#define SERIAL_REGISTER_IER 1 ///< R/W Interrupt Enable Register -#define SERIAL_REGISTER_IIR 2 ///< RO Interrupt Identification Register -#define SERIAL_REGISTER_FCR 2 ///< WO FIFO Cotrol Register -#define SERIAL_REGISTER_LCR 3 ///< R/W Line Control Register -#define SERIAL_REGISTER_MCR 4 ///< R/W Modem Control Register -#define SERIAL_REGISTER_LSR 5 ///< R/W Line Status Register -#define SERIAL_REGISTER_MSR 6 ///< R/W Modem Status Register -#define SERIAL_REGISTER_SCR 7 ///< R/W Scratch Pad Register -#pragma pack(1) - -/// -/// Interrupt Enable Register -/// -typedef union { - struct { - UINT8 Ravie : 1; ///< Receiver Data Available Interrupt Enable - UINT8 Theie : 1; ///< Transmistter Holding Register Empty Interrupt Enable - UINT8 Rie : 1; ///< Receiver Interrupt Enable - UINT8 Mie : 1; ///< Modem Interrupt Enable - UINT8 Reserved : 4; - } Bits; - UINT8 Data; -} SERIAL_PORT_IER; - -/// -/// FIFO Control Register -/// -typedef union { - struct { - UINT8 TrFIFOE : 1; ///< Transmit and Receive FIFO Enable - UINT8 ResetRF : 1; ///< Reset Reciever FIFO - UINT8 ResetTF : 1; ///< Reset Transmistter FIFO - UINT8 Dms : 1; ///< DMA Mode Select - UINT8 Reserved : 1; - UINT8 TrFIFO64 : 1; ///< Enable 64 byte FIFO - UINT8 Rtb : 2; ///< Receive Trigger Bits - } Bits; - UINT8 Data; -} SERIAL_PORT_FCR; - -/// -/// Line Control Register -/// -typedef union { - struct { - UINT8 SerialDB : 2; ///< Number of Serial Data Bits - UINT8 StopB : 1; ///< Number of Stop Bits - UINT8 ParEn : 1; ///< Parity Enable - UINT8 EvenPar : 1; ///< Even Parity Select - UINT8 SticPar : 1; ///< Sticky Parity - UINT8 BrCon : 1; ///< Break Control - UINT8 DLab : 1; ///< Divisor Latch Access Bit - } Bits; - UINT8 Data; -} SERIAL_PORT_LCR; - -/// -/// Modem Control Register -/// -typedef union { - struct { - UINT8 DtrC : 1; ///< Data Terminal Ready Control - UINT8 Rts : 1; ///< Request To Send Control - UINT8 Out1 : 1; ///< Output1 - UINT8 Out2 : 1; ///< Output2, used to disable interrupt - UINT8 Lme : 1; ///< Loopback Mode Enable - UINT8 Reserved : 3; - } Bits; - UINT8 Data; -} SERIAL_PORT_MCR; - -/// -/// Line Status Register -/// -typedef union { - struct { - UINT8 Dr : 1; ///< Receiver Data Ready Status - UINT8 Oe : 1; ///< Overrun Error Status - UINT8 Pe : 1; ///< Parity Error Status - UINT8 Fe : 1; ///< Framing Error Status - UINT8 Bi : 1; ///< Break Interrupt Status - UINT8 Thre : 1; ///< Transmistter Holding Register Status - UINT8 Temt : 1; ///< Transmitter Empty Status - UINT8 FIFOe : 1; ///< FIFO Error Status - } Bits; - UINT8 Data; -} SERIAL_PORT_LSR; - -/// -/// Modem Status Register -/// -typedef union { - struct { - UINT8 DeltaCTS : 1; ///< Delta Clear To Send Status - UINT8 DeltaDSR : 1; ///< Delta Data Set Ready Status - UINT8 TrailingEdgeRI : 1; ///< Trailing Edge of Ring Indicator Status - UINT8 DeltaDCD : 1; ///< Delta Data Carrier Detect Status - UINT8 Cts : 1; ///< Clear To Send Status - UINT8 Dsr : 1; ///< Data Set Ready Status - UINT8 Ri : 1; ///< Ring Indicator Status - UINT8 Dcd : 1; ///< Data Carrier Detect Status - } Bits; - UINT8 Data; -} SERIAL_PORT_MSR; - -#pragma pack() -// -// Define serial register I/O macros -// -#define READ_RBR(S) SerialReadRegister (S, SERIAL_REGISTER_RBR) -#define READ_DLL(S) SerialReadRegister (S, SERIAL_REGISTER_DLL) -#define READ_DLM(S) SerialReadRegister (S, SERIAL_REGISTER_DLM) -#define READ_IER(S) SerialReadRegister (S, SERIAL_REGISTER_IER) -#define READ_IIR(S) SerialReadRegister (S, SERIAL_REGISTER_IIR) -#define READ_LCR(S) SerialReadRegister (S, SERIAL_REGISTER_LCR) -#define READ_MCR(S) SerialReadRegister (S, SERIAL_REGISTER_MCR) -#define READ_LSR(S) SerialReadRegister (S, SERIAL_REGISTER_LSR) -#define READ_MSR(S) SerialReadRegister (S, SERIAL_REGISTER_MSR) -#define READ_SCR(S) SerialReadRegister (S, SERIAL_REGISTER_SCR) - -#define WRITE_THR(S, D) SerialWriteRegister (S, SERIAL_REGISTER_THR, D) -#define WRITE_DLL(S, D) SerialWriteRegister (S, SERIAL_REGISTER_DLL, D) -#define WRITE_DLM(S, D) SerialWriteRegister (S, SERIAL_REGISTER_DLM, D) -#define WRITE_IER(S, D) SerialWriteRegister (S, SERIAL_REGISTER_IER, D) -#define WRITE_FCR(S, D) SerialWriteRegister (S, SERIAL_REGISTER_FCR, D) -#define WRITE_LCR(S, D) SerialWriteRegister (S, SERIAL_REGISTER_LCR, D) -#define WRITE_MCR(S, D) SerialWriteRegister (S, SERIAL_REGISTER_MCR, D) -#define WRITE_LSR(S, D) SerialWriteRegister (S, SERIAL_REGISTER_LSR, D) -#define WRITE_MSR(S, D) SerialWriteRegister (S, SERIAL_REGISTER_MSR, D) -#define WRITE_SCR(S, D) SerialWriteRegister (S, SERIAL_REGISTER_SCR, D) - -// -// Prototypes -// Driver model protocol interface -// -/** - Check to see if this driver supports the given controller - - @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param Controller The handle of the controller to test. - @param RemainingDevicePath A pointer to the remaining portion of a device path. - - @return EFI_SUCCESS This driver can support the given controller - -**/ -EFI_STATUS -EFIAPI -SerialControllerDriverSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Start to management the controller passed in - - @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param Controller The handle of the controller to test. - @param RemainingDevicePath A pointer to the remaining portion of a device path. - - @return EFI_SUCCESS Driver is started successfully -**/ -EFI_STATUS -EFIAPI -SerialControllerDriverStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Disconnect this driver with the controller, uninstall related protocol instance - - @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param Controller The handle of the controller to test. - @param NumberOfChildren Number of child device. - @param ChildHandleBuffer A pointer to the remaining portion of a device path. - - @retval EFI_SUCCESS Operation successfully - @retval EFI_DEVICE_ERROR Cannot stop the driver successfully - -**/ -EFI_STATUS -EFIAPI -SerialControllerDriverStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -// -// Serial I/O Protocol Interface -// -/** - Reset serial device. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - - @retval EFI_SUCCESS Reset successfully - @retval EFI_DEVICE_ERROR Failed to reset - -**/ -EFI_STATUS -EFIAPI -SerialReset ( - IN EFI_SERIAL_IO_PROTOCOL *This - ); - -/** - Set new attributes to a serial device. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param BaudRate The baudrate of the serial device - @param ReceiveFifoDepth The depth of receive FIFO buffer - @param Timeout The request timeout for a single char - @param Parity The type of parity used in serial device - @param DataBits Number of databits used in serial device - @param StopBits Number of stopbits used in serial device - - @retval EFI_SUCCESS The new attributes were set - @retval EFI_INVALID_PARAMETERS One or more attributes have an unsupported value - @retval EFI_UNSUPPORTED Data Bits can not set to 5 or 6 - @retval EFI_DEVICE_ERROR The serial device is not functioning correctly (no return) - -**/ -EFI_STATUS -EFIAPI -SerialSetAttributes ( - IN EFI_SERIAL_IO_PROTOCOL *This, - IN UINT64 BaudRate, - IN UINT32 ReceiveFifoDepth, - IN UINT32 Timeout, - IN EFI_PARITY_TYPE Parity, - IN UINT8 DataBits, - IN EFI_STOP_BITS_TYPE StopBits - ); - -/** - Set Control Bits. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param Control Control bits that can be settable - - @retval EFI_SUCCESS New Control bits were set successfully - @retval EFI_UNSUPPORTED The Control bits wanted to set are not supported - -**/ -EFI_STATUS -EFIAPI -SerialSetControl ( - IN EFI_SERIAL_IO_PROTOCOL *This, - IN UINT32 Control - ); - -/** - Get ControlBits. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param Control Control signals of the serial device - - @retval EFI_SUCCESS Get Control signals successfully - -**/ -EFI_STATUS -EFIAPI -SerialGetControl ( - IN EFI_SERIAL_IO_PROTOCOL *This, - OUT UINT32 *Control - ); - -/** - Write the specified number of bytes to serial device. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param BufferSize On input the size of Buffer, on output the amount of - data actually written - @param Buffer The buffer of data to write - - @retval EFI_SUCCESS The data were written successfully - @retval EFI_DEVICE_ERROR The device reported an error - @retval EFI_TIMEOUT The write operation was stopped due to timeout - -**/ -EFI_STATUS -EFIAPI -SerialWrite ( - IN EFI_SERIAL_IO_PROTOCOL *This, - IN OUT UINTN *BufferSize, - IN VOID *Buffer - ); - -/** - Read the specified number of bytes from serial device. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param BufferSize On input the size of Buffer, on output the amount of - data returned in buffer - @param Buffer The buffer to return the data into - - @retval EFI_SUCCESS The data were read successfully - @retval EFI_DEVICE_ERROR The device reported an error - @retval EFI_TIMEOUT The read operation was stopped due to timeout - -**/ -EFI_STATUS -EFIAPI -SerialRead ( - IN EFI_SERIAL_IO_PROTOCOL *This, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ); - -// -// Internal Functions -// -/** - Use scratchpad register to test if this serial port is present. - - @param SerialDevice Pointer to serial device structure - - @return if this serial port is present -**/ -BOOLEAN -SerialPresent ( - IN SERIAL_DEV *SerialDevice - ); - -/** - Detect whether specific FIFO is full or not. - - @param Fifo A pointer to the Data Structure SERIAL_DEV_FIFO - - @return whether specific FIFO is full or not - -**/ -BOOLEAN -SerialFifoFull ( - IN SERIAL_DEV_FIFO *Fifo - ); - -/** - Detect whether specific FIFO is empty or not. - - @param Fifo A pointer to the Data Structure SERIAL_DEV_FIFO - - @return whether specific FIFO is empty or not - -**/ -BOOLEAN -SerialFifoEmpty ( - IN SERIAL_DEV_FIFO *Fifo - ); - -/** - Add data to specific FIFO. - - @param Fifo A pointer to the Data Structure SERIAL_DEV_FIFO - @param Data the data added to FIFO - - @retval EFI_SUCCESS Add data to specific FIFO successfully - @retval EFI_OUT_OF_RESOURCE Failed to add data because FIFO is already full - -**/ -EFI_STATUS -SerialFifoAdd ( - IN SERIAL_DEV_FIFO *Fifo, - IN UINT8 Data - ); - -/** - Remove data from specific FIFO. - - @param Fifo A pointer to the Data Structure SERIAL_DEV_FIFO - @param Data the data removed from FIFO - - @retval EFI_SUCCESS Remove data from specific FIFO successfully - @retval EFI_OUT_OF_RESOURCE Failed to remove data because FIFO is empty - -**/ -EFI_STATUS -SerialFifoRemove ( - IN SERIAL_DEV_FIFO *Fifo, - OUT UINT8 *Data - ); - -/** - Reads and writes all avaliable data. - - @param SerialDevice The device to flush - - @retval EFI_SUCCESS Data was read/written successfully. - @retval EFI_OUT_OF_RESOURCE Failed because software receive FIFO is full. Note, when - this happens, pending writes are not done. - -**/ -EFI_STATUS -SerialReceiveTransmit ( - IN SERIAL_DEV *SerialDevice - ); - -/** - Read serial port. - - @param SerialDev Pointer to serial device - @param Offset Offset in register group - - @return Data read from serial port -**/ -UINT8 -SerialReadRegister ( - IN SERIAL_DEV *SerialDev, - IN UINT32 Offset - ); - -/** - Write serial port. - - @param SerialDev Pointer to serial device - @param Offset Offset in register group - @param Data data which is to be written to some serial port register -**/ -VOID -SerialWriteRegister ( - IN SERIAL_DEV *SerialDev, - IN UINT32 Offset, - IN UINT8 Data - ); - - -// -// EFI Component Name Functions -// -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -SerialComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -SerialComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -/** - Add the component name for the serial io device - - @param SerialDevice A pointer to the SERIAL_DEV instance. - @param Uid Unique ID for the serial device. -**/ -VOID -AddName ( - IN SERIAL_DEV *SerialDevice, - IN UINT32 Uid - ); - -/** - Checks whether the UART parameters are valid and computes the Divisor. - - @param ClockRate The clock rate of the serial device used to verify - the BaudRate. Do not verify the BaudRate if it's 0. - @param BaudRate The requested baudrate of the serial device. - @param DataBits Number of databits used in serial device. - @param Parity The type of parity used in serial device. - @param StopBits Number of stopbits used in serial device. - @param Divisor Return the divisor if ClockRate is not 0. - @param ActualBaudRate Return the actual supported baudrate without - exceeding BaudRate. NULL means baudrate degradation - is not allowed. - If the requested BaudRate is not supported, the routine - returns TRUE and the Actual Baud Rate when ActualBaudRate - is not NULL, returns FALSE when ActualBaudRate is NULL. - - @retval TRUE The UART parameters are valid. - @retval FALSE The UART parameters are not valid. -**/ -BOOLEAN -VerifyUartParameters ( - IN UINT32 ClockRate, - IN UINT64 BaudRate, - IN UINT8 DataBits, - IN EFI_PARITY_TYPE Parity, - IN EFI_STOP_BITS_TYPE StopBits, - OUT UINT64 *Divisor, - OUT UINT64 *ActualBaudRate - ); - -/** - Skip the optional Controller device path node and return the - pointer to the next device path node. - - @param DevicePath Pointer to the device path. - @param ContainsControllerNode Returns TRUE if the Controller device path exists. - @param ControllerNumber Returns the Controller Number if Controller device path exists. - - @return Pointer to the next device path node. -**/ -UART_DEVICE_PATH * -SkipControllerDevicePathNode ( - EFI_DEVICE_PATH_PROTOCOL *DevicePath, - BOOLEAN *ContainsControllerNode, - UINT32 *ControllerNumber - ); - -/** - Check the device path node whether it's the Flow Control node or not. - - @param[in] FlowControl The device path node to be checked. - - @retval TRUE It's the Flow Control node. - @retval FALSE It's not. - -**/ -BOOLEAN -IsUartFlowControlDevicePathNode ( - IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl - ); -#endif diff --git a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/SerialIo.c b/MdeModulePkg/Bus/Pci/PciSioSerialDxe/SerialIo.c deleted file mode 100644 index f1870f3a1b..0000000000 --- a/MdeModulePkg/Bus/Pci/PciSioSerialDxe/SerialIo.c +++ /dev/null @@ -1,1320 +0,0 @@ -/** @file - SerialIo implementation for PCI or SIO UARTs. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Serial.h" - -/** - Skip the optional Controller device path node and return the - pointer to the next device path node. - - @param DevicePath Pointer to the device path. - @param ContainsControllerNode Returns TRUE if the Controller device path exists. - @param ControllerNumber Returns the Controller Number if Controller device path exists. - - @return Pointer to the next device path node. -**/ -UART_DEVICE_PATH * -SkipControllerDevicePathNode ( - EFI_DEVICE_PATH_PROTOCOL *DevicePath, - BOOLEAN *ContainsControllerNode, - UINT32 *ControllerNumber - ) -{ - if ((DevicePathType (DevicePath) == HARDWARE_DEVICE_PATH) && - (DevicePathSubType (DevicePath) == HW_CONTROLLER_DP) - ) { - if (ContainsControllerNode != NULL) { - *ContainsControllerNode = TRUE; - } - if (ControllerNumber != NULL) { - *ControllerNumber = ((CONTROLLER_DEVICE_PATH *) DevicePath)->ControllerNumber; - } - DevicePath = NextDevicePathNode (DevicePath); - } else { - if (ContainsControllerNode != NULL) { - *ContainsControllerNode = FALSE; - } - } - return (UART_DEVICE_PATH *) DevicePath; -} - -/** - Checks whether the UART parameters are valid and computes the Divisor. - - @param ClockRate The clock rate of the serial device used to verify - the BaudRate. Do not verify the BaudRate if it's 0. - @param BaudRate The requested baudrate of the serial device. - @param DataBits Number of databits used in serial device. - @param Parity The type of parity used in serial device. - @param StopBits Number of stopbits used in serial device. - @param Divisor Return the divisor if ClockRate is not 0. - @param ActualBaudRate Return the actual supported baudrate without - exceeding BaudRate. NULL means baudrate degradation - is not allowed. - If the requested BaudRate is not supported, the routine - returns TRUE and the Actual Baud Rate when ActualBaudRate - is not NULL, returns FALSE when ActualBaudRate is NULL. - - @retval TRUE The UART parameters are valid. - @retval FALSE The UART parameters are not valid. -**/ -BOOLEAN -VerifyUartParameters ( - IN UINT32 ClockRate, - IN UINT64 BaudRate, - IN UINT8 DataBits, - IN EFI_PARITY_TYPE Parity, - IN EFI_STOP_BITS_TYPE StopBits, - OUT UINT64 *Divisor, - OUT UINT64 *ActualBaudRate - ) -{ - UINT64 Remainder; - UINT32 ComputedBaudRate; - UINT64 ComputedDivisor; - UINT64 Percent; - - if ((DataBits < 5) || (DataBits > 8) || - (Parity < NoParity) || (Parity > SpaceParity) || - (StopBits < OneStopBit) || (StopBits > TwoStopBits) || - ((DataBits == 5) && (StopBits == TwoStopBits)) || - ((DataBits >= 6) && (DataBits <= 8) && (StopBits == OneFiveStopBits)) - ) { - return FALSE; - } - - // - // Do not verify the baud rate if clock rate is unknown (0). - // - if (ClockRate == 0) { - return TRUE; - } - - // - // Compute divisor use to program the baud rate using a round determination - // Divisor = ClockRate / 16 / BaudRate = ClockRate / (16 * BaudRate) - // = ClockRate / (BaudRate << 4) - // - ComputedDivisor = DivU64x64Remainder (ClockRate, LShiftU64 (BaudRate, 4), &Remainder); - // - // Round Divisor up by 1 if the Remainder is more than half (16 * BaudRate) - // BaudRate * 16 / 2 = BaudRate * 8 = (BaudRate << 3) - // - if (Remainder >= LShiftU64 (BaudRate, 3)) { - ComputedDivisor++; - } - // - // If the computed divisor is larger than the maximum value that can be programmed - // into the UART, then the requested baud rate can not be supported. - // - if (ComputedDivisor > MAX_UINT16) { - return FALSE; - } - - // - // If the computed divisor is 0, then use a computed divisor of 1, which will select - // the maximum supported baud rate. - // - if (ComputedDivisor == 0) { - ComputedDivisor = 1; - } - - // - // Actual baud rate that the serial port will be programmed for - // should be with in 4% of requested one. - // - ComputedBaudRate = ClockRate / ((UINT16) ComputedDivisor << 4); - if (ComputedBaudRate == 0) { - return FALSE; - } - - Percent = DivU64x32 (MultU64x32 (BaudRate, 100), ComputedBaudRate); - DEBUG ((EFI_D_INFO, "ClockRate = %d\n", ClockRate)); - DEBUG ((EFI_D_INFO, "Divisor = %ld\n", ComputedDivisor)); - DEBUG ((EFI_D_INFO, "BaudRate/Actual (%ld/%d) = %d%%\n", BaudRate, ComputedBaudRate, Percent)); - - // - // If the requested BaudRate is not supported: - // Returns TRUE and the Actual Baud Rate when ActualBaudRate is not NULL; - // Returns FALSE when ActualBaudRate is NULL. - // - if ((Percent >= 96) && (Percent <= 104)) { - if (ActualBaudRate != NULL) { - *ActualBaudRate = BaudRate; - } - if (Divisor != NULL) { - *Divisor = ComputedDivisor; - } - return TRUE; - } - if (ComputedBaudRate < BaudRate) { - if (ActualBaudRate != NULL) { - *ActualBaudRate = ComputedBaudRate; - } - if (Divisor != NULL) { - *Divisor = ComputedDivisor; - } - return TRUE; - } - - // - // ActualBaudRate is higher than requested baud rate and more than 4% - // higher than the requested value. Increment Divisor if it is less - // than MAX_UINT16 and computed baud rate with new divisor. - // - if (ComputedDivisor == MAX_UINT16) { - return FALSE; - } - ComputedDivisor++; - ComputedBaudRate = ClockRate / ((UINT16) ComputedDivisor << 4); - if (ComputedBaudRate == 0) { - return FALSE; - } - - DEBUG ((EFI_D_INFO, "ClockRate = %d\n", ClockRate)); - DEBUG ((EFI_D_INFO, "Divisor = %ld\n", ComputedDivisor)); - DEBUG ((EFI_D_INFO, "BaudRate/Actual (%ld/%d) = %d%%\n", BaudRate, ComputedBaudRate, Percent)); - - if (ActualBaudRate != NULL) { - *ActualBaudRate = ComputedBaudRate; - } - if (Divisor != NULL) { - *Divisor = ComputedDivisor; - } - return TRUE; -} - -/** - Detect whether specific FIFO is full or not. - - @param Fifo A pointer to the Data Structure SERIAL_DEV_FIFO - - @return whether specific FIFO is full or not -**/ -BOOLEAN -SerialFifoFull ( - IN SERIAL_DEV_FIFO *Fifo - ) -{ - return (BOOLEAN) (((Fifo->Tail + 1) % SERIAL_MAX_FIFO_SIZE) == Fifo->Head); -} - -/** - Detect whether specific FIFO is empty or not. - - @param Fifo A pointer to the Data Structure SERIAL_DEV_FIFO - - @return whether specific FIFO is empty or not -**/ -BOOLEAN -SerialFifoEmpty ( - IN SERIAL_DEV_FIFO *Fifo - ) - -{ - return (BOOLEAN) (Fifo->Head == Fifo->Tail); -} - -/** - Add data to specific FIFO. - - @param Fifo A pointer to the Data Structure SERIAL_DEV_FIFO - @param Data the data added to FIFO - - @retval EFI_SUCCESS Add data to specific FIFO successfully - @retval EFI_OUT_OF_RESOURCE Failed to add data because FIFO is already full -**/ -EFI_STATUS -SerialFifoAdd ( - IN OUT SERIAL_DEV_FIFO *Fifo, - IN UINT8 Data - ) -{ - // - // if FIFO full can not add data - // - if (SerialFifoFull (Fifo)) { - return EFI_OUT_OF_RESOURCES; - } - // - // FIFO is not full can add data - // - Fifo->Data[Fifo->Tail] = Data; - Fifo->Tail = (Fifo->Tail + 1) % SERIAL_MAX_FIFO_SIZE; - return EFI_SUCCESS; -} - -/** - Remove data from specific FIFO. - - @param Fifo A pointer to the Data Structure SERIAL_DEV_FIFO - @param Data the data removed from FIFO - - @retval EFI_SUCCESS Remove data from specific FIFO successfully - @retval EFI_OUT_OF_RESOURCE Failed to remove data because FIFO is empty - -**/ -EFI_STATUS -SerialFifoRemove ( - IN OUT SERIAL_DEV_FIFO *Fifo, - OUT UINT8 *Data - ) -{ - // - // if FIFO is empty, no data can remove - // - if (SerialFifoEmpty (Fifo)) { - return EFI_OUT_OF_RESOURCES; - } - // - // FIFO is not empty, can remove data - // - *Data = Fifo->Data[Fifo->Head]; - Fifo->Head = (Fifo->Head + 1) % SERIAL_MAX_FIFO_SIZE; - return EFI_SUCCESS; -} - -/** - Reads and writes all avaliable data. - - @param SerialDevice The device to transmit. - - @retval EFI_SUCCESS Data was read/written successfully. - @retval EFI_OUT_OF_RESOURCE Failed because software receive FIFO is full. Note, when - this happens, pending writes are not done. - -**/ -EFI_STATUS -SerialReceiveTransmit ( - IN SERIAL_DEV *SerialDevice - ) - -{ - SERIAL_PORT_LSR Lsr; - UINT8 Data; - BOOLEAN ReceiveFifoFull; - SERIAL_PORT_MSR Msr; - SERIAL_PORT_MCR Mcr; - UINTN TimeOut; - - Data = 0; - - // - // Begin the read or write - // - if (SerialDevice->SoftwareLoopbackEnable) { - do { - ReceiveFifoFull = SerialFifoFull (&SerialDevice->Receive); - if (!SerialFifoEmpty (&SerialDevice->Transmit)) { - SerialFifoRemove (&SerialDevice->Transmit, &Data); - if (ReceiveFifoFull) { - return EFI_OUT_OF_RESOURCES; - } - - SerialFifoAdd (&SerialDevice->Receive, Data); - } - } while (!SerialFifoEmpty (&SerialDevice->Transmit)); - } else { - ReceiveFifoFull = SerialFifoFull (&SerialDevice->Receive); - // - // For full handshake flow control, tell the peer to send data - // if receive buffer is available. - // - if (SerialDevice->HardwareFlowControl && - !FeaturePcdGet(PcdSerialUseHalfHandshake)&& - !ReceiveFifoFull - ) { - Mcr.Data = READ_MCR (SerialDevice); - Mcr.Bits.Rts = 1; - WRITE_MCR (SerialDevice, Mcr.Data); - } - do { - Lsr.Data = READ_LSR (SerialDevice); - - // - // Flush incomming data to prevent a an overrun during a long write - // - if ((Lsr.Bits.Dr == 1) && !ReceiveFifoFull) { - ReceiveFifoFull = SerialFifoFull (&SerialDevice->Receive); - if (!ReceiveFifoFull) { - if (Lsr.Bits.FIFOe == 1 || Lsr.Bits.Oe == 1 || Lsr.Bits.Pe == 1 || Lsr.Bits.Fe == 1 || Lsr.Bits.Bi == 1) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE, - EFI_P_EC_INPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT, - SerialDevice->DevicePath - ); - if (Lsr.Bits.FIFOe == 1 || Lsr.Bits.Pe == 1|| Lsr.Bits.Fe == 1 || Lsr.Bits.Bi == 1) { - Data = READ_RBR (SerialDevice); - continue; - } - } - - Data = READ_RBR (SerialDevice); - - SerialFifoAdd (&SerialDevice->Receive, Data); - - // - // For full handshake flow control, if receive buffer full - // tell the peer to stop sending data. - // - if (SerialDevice->HardwareFlowControl && - !FeaturePcdGet(PcdSerialUseHalfHandshake) && - SerialFifoFull (&SerialDevice->Receive) - ) { - Mcr.Data = READ_MCR (SerialDevice); - Mcr.Bits.Rts = 0; - WRITE_MCR (SerialDevice, Mcr.Data); - } - - - continue; - } else { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER | EFI_PERIPHERAL_SERIAL_PORT, - SerialDevice->DevicePath - ); - } - } - // - // Do the write - // - if (Lsr.Bits.Thre == 1 && !SerialFifoEmpty (&SerialDevice->Transmit)) { - // - // Make sure the transmit data will not be missed - // - if (SerialDevice->HardwareFlowControl) { - // - // For half handshake flow control assert RTS before sending. - // - if (FeaturePcdGet(PcdSerialUseHalfHandshake)) { - Mcr.Data = READ_MCR (SerialDevice); - Mcr.Bits.Rts= 0; - WRITE_MCR (SerialDevice, Mcr.Data); - } - // - // Wait for CTS - // - TimeOut = 0; - Msr.Data = READ_MSR (SerialDevice); - while ((Msr.Bits.Dcd == 1) && ((Msr.Bits.Cts == 0) ^ FeaturePcdGet(PcdSerialUseHalfHandshake))) { - gBS->Stall (TIMEOUT_STALL_INTERVAL); - TimeOut++; - if (TimeOut > 5) { - break; - } - - Msr.Data = READ_MSR (SerialDevice); - } - - if ((Msr.Bits.Dcd == 0) || ((Msr.Bits.Cts == 1) ^ FeaturePcdGet(PcdSerialUseHalfHandshake))) { - SerialFifoRemove (&SerialDevice->Transmit, &Data); - WRITE_THR (SerialDevice, Data); - } - - // - // For half handshake flow control, tell DCE we are done. - // - if (FeaturePcdGet(PcdSerialUseHalfHandshake)) { - Mcr.Data = READ_MCR (SerialDevice); - Mcr.Bits.Rts = 1; - WRITE_MCR (SerialDevice, Mcr.Data); - } - } else { - SerialFifoRemove (&SerialDevice->Transmit, &Data); - WRITE_THR (SerialDevice, Data); - } - } - } while (Lsr.Bits.Thre == 1 && !SerialFifoEmpty (&SerialDevice->Transmit)); - } - - return EFI_SUCCESS; -} - -/** - Flush the serial hardware transmit FIFO and shift register. - - @param SerialDevice The device to flush. -**/ -VOID -SerialFlushTransmitFifo ( - SERIAL_DEV *SerialDevice - ) -{ - SERIAL_PORT_LSR Lsr; - - // - // Wait for the serial port to be ready, to make sure both the transmit FIFO - // and shift register empty. - // - do { - Lsr.Data = READ_LSR (SerialDevice); - } while (Lsr.Bits.Temt == 0); -} - -// -// Interface Functions -// -/** - Reset serial device. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - - @retval EFI_SUCCESS Reset successfully - @retval EFI_DEVICE_ERROR Failed to reset - -**/ -EFI_STATUS -EFIAPI -SerialReset ( - IN EFI_SERIAL_IO_PROTOCOL *This - ) -{ - EFI_STATUS Status; - SERIAL_DEV *SerialDevice; - SERIAL_PORT_LCR Lcr; - SERIAL_PORT_IER Ier; - SERIAL_PORT_MCR Mcr; - SERIAL_PORT_FCR Fcr; - EFI_TPL Tpl; - UINT32 Control; - - SerialDevice = SERIAL_DEV_FROM_THIS (This); - - // - // Report the status code reset the serial - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - EFI_P_PC_RESET | EFI_PERIPHERAL_SERIAL_PORT, - SerialDevice->DevicePath - ); - - Tpl = gBS->RaiseTPL (TPL_NOTIFY); - - SerialFlushTransmitFifo (SerialDevice); - - // - // Make sure DLAB is 0. - // - Lcr.Data = READ_LCR (SerialDevice); - Lcr.Bits.DLab = 0; - WRITE_LCR (SerialDevice, Lcr.Data); - - // - // Turn off all interrupts - // - Ier.Data = READ_IER (SerialDevice); - Ier.Bits.Ravie = 0; - Ier.Bits.Theie = 0; - Ier.Bits.Rie = 0; - Ier.Bits.Mie = 0; - WRITE_IER (SerialDevice, Ier.Data); - - // - // Reset the FIFO - // - Fcr.Data = 0; - Fcr.Bits.TrFIFOE = 0; - WRITE_FCR (SerialDevice, Fcr.Data); - - // - // Turn off loopback and disable device interrupt. - // - Mcr.Data = READ_MCR (SerialDevice); - Mcr.Bits.Out1 = 0; - Mcr.Bits.Out2 = 0; - Mcr.Bits.Lme = 0; - WRITE_MCR (SerialDevice, Mcr.Data); - - // - // Clear the scratch pad register - // - WRITE_SCR (SerialDevice, 0); - - // - // Enable FIFO - // - Fcr.Bits.TrFIFOE = 1; - if (SerialDevice->ReceiveFifoDepth > 16) { - Fcr.Bits.TrFIFO64 = 1; - } - Fcr.Bits.ResetRF = 1; - Fcr.Bits.ResetTF = 1; - WRITE_FCR (SerialDevice, Fcr.Data); - - // - // Go set the current attributes - // - Status = This->SetAttributes ( - This, - This->Mode->BaudRate, - This->Mode->ReceiveFifoDepth, - This->Mode->Timeout, - (EFI_PARITY_TYPE) This->Mode->Parity, - (UINT8) This->Mode->DataBits, - (EFI_STOP_BITS_TYPE) This->Mode->StopBits - ); - - if (EFI_ERROR (Status)) { - gBS->RestoreTPL (Tpl); - return EFI_DEVICE_ERROR; - } - // - // Go set the current control bits - // - Control = 0; - if (SerialDevice->HardwareFlowControl) { - Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; - } - if (SerialDevice->SoftwareLoopbackEnable) { - Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE; - } - Status = This->SetControl ( - This, - Control - ); - - if (EFI_ERROR (Status)) { - gBS->RestoreTPL (Tpl); - return EFI_DEVICE_ERROR; - } - - // - // Reset the software FIFO - // - SerialDevice->Receive.Head = SerialDevice->Receive.Tail = 0; - SerialDevice->Transmit.Head = SerialDevice->Transmit.Tail = 0; - gBS->RestoreTPL (Tpl); - - // - // Device reset is complete - // - return EFI_SUCCESS; -} - -/** - Set new attributes to a serial device. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param BaudRate The baudrate of the serial device - @param ReceiveFifoDepth The depth of receive FIFO buffer - @param Timeout The request timeout for a single char - @param Parity The type of parity used in serial device - @param DataBits Number of databits used in serial device - @param StopBits Number of stopbits used in serial device - - @retval EFI_SUCCESS The new attributes were set - @retval EFI_INVALID_PARAMETERS One or more attributes have an unsupported value - @retval EFI_UNSUPPORTED Data Bits can not set to 5 or 6 - @retval EFI_DEVICE_ERROR The serial device is not functioning correctly (no return) - -**/ -EFI_STATUS -EFIAPI -SerialSetAttributes ( - IN EFI_SERIAL_IO_PROTOCOL *This, - IN UINT64 BaudRate, - IN UINT32 ReceiveFifoDepth, - IN UINT32 Timeout, - IN EFI_PARITY_TYPE Parity, - IN UINT8 DataBits, - IN EFI_STOP_BITS_TYPE StopBits - ) -{ - EFI_STATUS Status; - SERIAL_DEV *SerialDevice; - UINT64 Divisor; - SERIAL_PORT_LCR Lcr; - UART_DEVICE_PATH *Uart; - EFI_TPL Tpl; - - SerialDevice = SERIAL_DEV_FROM_THIS (This); - - // - // Check for default settings and fill in actual values. - // - if (BaudRate == 0) { - BaudRate = PcdGet64 (PcdUartDefaultBaudRate); - } - - if (ReceiveFifoDepth == 0) { - ReceiveFifoDepth = SerialDevice->ReceiveFifoDepth; - } - - if (Timeout == 0) { - Timeout = SERIAL_PORT_DEFAULT_TIMEOUT; - } - - if (Parity == DefaultParity) { - Parity = (EFI_PARITY_TYPE) PcdGet8 (PcdUartDefaultParity); - } - - if (DataBits == 0) { - DataBits = PcdGet8 (PcdUartDefaultDataBits); - } - - if (StopBits == DefaultStopBits) { - StopBits = (EFI_STOP_BITS_TYPE) PcdGet8 (PcdUartDefaultStopBits); - } - - if (!VerifyUartParameters (SerialDevice->ClockRate, BaudRate, DataBits, Parity, StopBits, &Divisor, &BaudRate)) { - return EFI_INVALID_PARAMETER; - } - - if ((ReceiveFifoDepth == 0) || (ReceiveFifoDepth > SerialDevice->ReceiveFifoDepth)) { - return EFI_INVALID_PARAMETER; - } - - if ((Timeout < SERIAL_PORT_MIN_TIMEOUT) || (Timeout > SERIAL_PORT_MAX_TIMEOUT)) { - return EFI_INVALID_PARAMETER; - } - - Tpl = gBS->RaiseTPL (TPL_NOTIFY); - - SerialFlushTransmitFifo (SerialDevice); - - // - // Put serial port on Divisor Latch Mode - // - Lcr.Data = READ_LCR (SerialDevice); - Lcr.Bits.DLab = 1; - WRITE_LCR (SerialDevice, Lcr.Data); - - // - // Write the divisor to the serial port - // - WRITE_DLL (SerialDevice, (UINT8) Divisor); - WRITE_DLM (SerialDevice, (UINT8) ((UINT16) Divisor >> 8)); - - // - // Put serial port back in normal mode and set remaining attributes. - // - Lcr.Bits.DLab = 0; - - switch (Parity) { - case NoParity: - Lcr.Bits.ParEn = 0; - Lcr.Bits.EvenPar = 0; - Lcr.Bits.SticPar = 0; - break; - - case EvenParity: - Lcr.Bits.ParEn = 1; - Lcr.Bits.EvenPar = 1; - Lcr.Bits.SticPar = 0; - break; - - case OddParity: - Lcr.Bits.ParEn = 1; - Lcr.Bits.EvenPar = 0; - Lcr.Bits.SticPar = 0; - break; - - case SpaceParity: - Lcr.Bits.ParEn = 1; - Lcr.Bits.EvenPar = 1; - Lcr.Bits.SticPar = 1; - break; - - case MarkParity: - Lcr.Bits.ParEn = 1; - Lcr.Bits.EvenPar = 0; - Lcr.Bits.SticPar = 1; - break; - - default: - break; - } - - switch (StopBits) { - case OneStopBit: - Lcr.Bits.StopB = 0; - break; - - case OneFiveStopBits: - case TwoStopBits: - Lcr.Bits.StopB = 1; - break; - - default: - break; - } - // - // DataBits - // - Lcr.Bits.SerialDB = (UINT8) ((DataBits - 5) & 0x03); - WRITE_LCR (SerialDevice, Lcr.Data); - - // - // Set the Serial I/O mode - // - This->Mode->BaudRate = BaudRate; - This->Mode->ReceiveFifoDepth = ReceiveFifoDepth; - This->Mode->Timeout = Timeout; - This->Mode->Parity = Parity; - This->Mode->DataBits = DataBits; - This->Mode->StopBits = StopBits; - - // - // See if Device Path Node has actually changed - // - if (SerialDevice->UartDevicePath.BaudRate == BaudRate && - SerialDevice->UartDevicePath.DataBits == DataBits && - SerialDevice->UartDevicePath.Parity == Parity && - SerialDevice->UartDevicePath.StopBits == StopBits - ) { - gBS->RestoreTPL (Tpl); - return EFI_SUCCESS; - } - // - // Update the device path - // - SerialDevice->UartDevicePath.BaudRate = BaudRate; - SerialDevice->UartDevicePath.DataBits = DataBits; - SerialDevice->UartDevicePath.Parity = (UINT8) Parity; - SerialDevice->UartDevicePath.StopBits = (UINT8) StopBits; - - Status = EFI_SUCCESS; - if (SerialDevice->Handle != NULL) { - - // - // Skip the optional Controller device path node - // - Uart = SkipControllerDevicePathNode ( - (EFI_DEVICE_PATH_PROTOCOL *) ( - (UINT8 *) SerialDevice->DevicePath + GetDevicePathSize (SerialDevice->ParentDevicePath) - END_DEVICE_PATH_LENGTH - ), - NULL, - NULL - ); - CopyMem (Uart, &SerialDevice->UartDevicePath, sizeof (UART_DEVICE_PATH)); - Status = gBS->ReinstallProtocolInterface ( - SerialDevice->Handle, - &gEfiDevicePathProtocolGuid, - SerialDevice->DevicePath, - SerialDevice->DevicePath - ); - } - - gBS->RestoreTPL (Tpl); - - return Status; -} - -/** - Set Control Bits. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param Control Control bits that can be settable - - @retval EFI_SUCCESS New Control bits were set successfully - @retval EFI_UNSUPPORTED The Control bits wanted to set are not supported - -**/ -EFI_STATUS -EFIAPI -SerialSetControl ( - IN EFI_SERIAL_IO_PROTOCOL *This, - IN UINT32 Control - ) -{ - SERIAL_DEV *SerialDevice; - SERIAL_PORT_MCR Mcr; - EFI_TPL Tpl; - UART_FLOW_CONTROL_DEVICE_PATH *FlowControl; - EFI_STATUS Status; - - // - // The control bits that can be set are : - // EFI_SERIAL_DATA_TERMINAL_READY: 0x0001 // WO - // EFI_SERIAL_REQUEST_TO_SEND: 0x0002 // WO - // EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE: 0x1000 // RW - // EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE: 0x2000 // RW - // EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE: 0x4000 // RW - // - SerialDevice = SERIAL_DEV_FROM_THIS (This); - - // - // first determine the parameter is invalid - // - if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY | - EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | - EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) { - return EFI_UNSUPPORTED; - } - - Tpl = gBS->RaiseTPL (TPL_NOTIFY); - - Mcr.Data = READ_MCR (SerialDevice); - Mcr.Bits.DtrC = 0; - Mcr.Bits.Rts = 0; - Mcr.Bits.Lme = 0; - SerialDevice->SoftwareLoopbackEnable = FALSE; - SerialDevice->HardwareFlowControl = FALSE; - - if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) { - Mcr.Bits.DtrC = 1; - } - - if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) { - Mcr.Bits.Rts = 1; - } - - if ((Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) == EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) { - Mcr.Bits.Lme = 1; - } - - if ((Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) == EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) { - SerialDevice->HardwareFlowControl = TRUE; - } - - WRITE_MCR (SerialDevice, Mcr.Data); - - if ((Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) == EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) { - SerialDevice->SoftwareLoopbackEnable = TRUE; - } - - Status = EFI_SUCCESS; - if (SerialDevice->Handle != NULL) { - FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) ( - (UINTN) SerialDevice->DevicePath - + GetDevicePathSize (SerialDevice->ParentDevicePath) - - END_DEVICE_PATH_LENGTH - + sizeof (UART_DEVICE_PATH) - ); - if (IsUartFlowControlDevicePathNode (FlowControl) && - ((BOOLEAN) (ReadUnaligned32 (&FlowControl->FlowControlMap) == UART_FLOW_CONTROL_HARDWARE) != SerialDevice->HardwareFlowControl)) { - // - // Flow Control setting is changed, need to reinstall device path protocol - // - WriteUnaligned32 (&FlowControl->FlowControlMap, SerialDevice->HardwareFlowControl ? UART_FLOW_CONTROL_HARDWARE : 0); - Status = gBS->ReinstallProtocolInterface ( - SerialDevice->Handle, - &gEfiDevicePathProtocolGuid, - SerialDevice->DevicePath, - SerialDevice->DevicePath - ); - } - } - - gBS->RestoreTPL (Tpl); - - return Status; -} - -/** - Get ControlBits. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param Control Control signals of the serial device - - @retval EFI_SUCCESS Get Control signals successfully - -**/ -EFI_STATUS -EFIAPI -SerialGetControl ( - IN EFI_SERIAL_IO_PROTOCOL *This, - OUT UINT32 *Control - ) -{ - SERIAL_DEV *SerialDevice; - SERIAL_PORT_MSR Msr; - SERIAL_PORT_MCR Mcr; - EFI_TPL Tpl; - - Tpl = gBS->RaiseTPL (TPL_NOTIFY); - - SerialDevice = SERIAL_DEV_FROM_THIS (This); - - *Control = 0; - - // - // Read the Modem Status Register - // - Msr.Data = READ_MSR (SerialDevice); - - if (Msr.Bits.Cts == 1) { - *Control |= EFI_SERIAL_CLEAR_TO_SEND; - } - - if (Msr.Bits.Dsr == 1) { - *Control |= EFI_SERIAL_DATA_SET_READY; - } - - if (Msr.Bits.Ri == 1) { - *Control |= EFI_SERIAL_RING_INDICATE; - } - - if (Msr.Bits.Dcd == 1) { - *Control |= EFI_SERIAL_CARRIER_DETECT; - } - // - // Read the Modem Control Register - // - Mcr.Data = READ_MCR (SerialDevice); - - if (Mcr.Bits.DtrC == 1) { - *Control |= EFI_SERIAL_DATA_TERMINAL_READY; - } - - if (Mcr.Bits.Rts == 1) { - *Control |= EFI_SERIAL_REQUEST_TO_SEND; - } - - if (Mcr.Bits.Lme == 1) { - *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE; - } - - if (SerialDevice->HardwareFlowControl) { - *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; - } - // - // Update FIFO status - // - SerialReceiveTransmit (SerialDevice); - - // - // See if the Transmit FIFO is empty - // - if (SerialFifoEmpty (&SerialDevice->Transmit)) { - *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; - } - - // - // See if the Receive FIFO is empty. - // - if (SerialFifoEmpty (&SerialDevice->Receive)) { - *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY; - } - - if (SerialDevice->SoftwareLoopbackEnable) { - *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE; - } - - gBS->RestoreTPL (Tpl); - - return EFI_SUCCESS; -} - -/** - Write the specified number of bytes to serial device. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param BufferSize On input the size of Buffer, on output the amount of - data actually written - @param Buffer The buffer of data to write - - @retval EFI_SUCCESS The data were written successfully - @retval EFI_DEVICE_ERROR The device reported an error - @retval EFI_TIMEOUT The write operation was stopped due to timeout - -**/ -EFI_STATUS -EFIAPI -SerialWrite ( - IN EFI_SERIAL_IO_PROTOCOL *This, - IN OUT UINTN *BufferSize, - IN VOID *Buffer - ) -{ - SERIAL_DEV *SerialDevice; - UINT8 *CharBuffer; - UINT32 Index; - UINTN Elapsed; - UINTN ActualWrite; - EFI_TPL Tpl; - UINTN Timeout; - UINTN BitsPerCharacter; - - SerialDevice = SERIAL_DEV_FROM_THIS (This); - Elapsed = 0; - ActualWrite = 0; - - if (*BufferSize == 0) { - return EFI_SUCCESS; - } - - if (Buffer == NULL) { - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE, - EFI_P_EC_OUTPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT, - SerialDevice->DevicePath - ); - - return EFI_DEVICE_ERROR; - } - - Tpl = gBS->RaiseTPL (TPL_NOTIFY); - - CharBuffer = (UINT8 *) Buffer; - - // - // Compute the number of bits in a single character. This is a start bit, - // followed by the number of data bits, followed by the number of stop bits. - // The number of stop bits is specified by an enumeration that includes - // support for 1.5 stop bits. Treat 1.5 stop bits as 2 stop bits. - // - BitsPerCharacter = - 1 + - This->Mode->DataBits + - ((This->Mode->StopBits == TwoStopBits) ? 2 : This->Mode->StopBits); - - // - // Compute the timeout in microseconds to wait for a single byte to be - // transmitted. The Mode structure contans a Timeout field that is the - // maximum time to transmit or receive a character. However, many UARTs - // have a FIFO for transmits, so the time required to add one new character - // to the transmit FIFO may be the time required to flush a full FIFO. If - // the Timeout in the Mode structure is smaller than the time required to - // flush a full FIFO at the current baud rate, then use a timeout value that - // is required to flush a full transmit FIFO. - // - Timeout = MAX ( - This->Mode->Timeout, - (UINTN)DivU64x64Remainder ( - BitsPerCharacter * (SerialDevice->TransmitFifoDepth + 1) * 1000000, - This->Mode->BaudRate, - NULL - ) - ); - - for (Index = 0; Index < *BufferSize; Index++) { - SerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]); - - while (SerialReceiveTransmit (SerialDevice) != EFI_SUCCESS || !SerialFifoEmpty (&SerialDevice->Transmit)) { - // - // Unsuccessful write so check if timeout has expired, if not, - // stall for a bit, increment time elapsed, and try again - // - if (Elapsed >= Timeout) { - *BufferSize = ActualWrite; - gBS->RestoreTPL (Tpl); - return EFI_TIMEOUT; - } - - gBS->Stall (TIMEOUT_STALL_INTERVAL); - - Elapsed += TIMEOUT_STALL_INTERVAL; - } - - ActualWrite++; - // - // Successful write so reset timeout - // - Elapsed = 0; - } - - gBS->RestoreTPL (Tpl); - - return EFI_SUCCESS; -} - -/** - Read the specified number of bytes from serial device. - - @param This Pointer to EFI_SERIAL_IO_PROTOCOL - @param BufferSize On input the size of Buffer, on output the amount of - data returned in buffer - @param Buffer The buffer to return the data into - - @retval EFI_SUCCESS The data were read successfully - @retval EFI_DEVICE_ERROR The device reported an error - @retval EFI_TIMEOUT The read operation was stopped due to timeout - -**/ -EFI_STATUS -EFIAPI -SerialRead ( - IN EFI_SERIAL_IO_PROTOCOL *This, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - SERIAL_DEV *SerialDevice; - UINT32 Index; - UINT8 *CharBuffer; - UINTN Elapsed; - EFI_STATUS Status; - EFI_TPL Tpl; - - SerialDevice = SERIAL_DEV_FROM_THIS (This); - Elapsed = 0; - - if (*BufferSize == 0) { - return EFI_SUCCESS; - } - - if (Buffer == NULL) { - return EFI_DEVICE_ERROR; - } - - Tpl = gBS->RaiseTPL (TPL_NOTIFY); - - Status = SerialReceiveTransmit (SerialDevice); - - if (EFI_ERROR (Status)) { - *BufferSize = 0; - - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_ERROR_CODE, - EFI_P_EC_INPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT, - SerialDevice->DevicePath - ); - - gBS->RestoreTPL (Tpl); - - return EFI_DEVICE_ERROR; - } - - CharBuffer = (UINT8 *) Buffer; - for (Index = 0; Index < *BufferSize; Index++) { - while (SerialFifoRemove (&SerialDevice->Receive, &(CharBuffer[Index])) != EFI_SUCCESS) { - // - // Unsuccessful read so check if timeout has expired, if not, - // stall for a bit, increment time elapsed, and try again - // Need this time out to get conspliter to work. - // - if (Elapsed >= This->Mode->Timeout) { - *BufferSize = Index; - gBS->RestoreTPL (Tpl); - return EFI_TIMEOUT; - } - - gBS->Stall (TIMEOUT_STALL_INTERVAL); - Elapsed += TIMEOUT_STALL_INTERVAL; - - Status = SerialReceiveTransmit (SerialDevice); - if (Status == EFI_DEVICE_ERROR) { - *BufferSize = Index; - gBS->RestoreTPL (Tpl); - return EFI_DEVICE_ERROR; - } - } - // - // Successful read so reset timeout - // - Elapsed = 0; - } - - SerialReceiveTransmit (SerialDevice); - - gBS->RestoreTPL (Tpl); - - return EFI_SUCCESS; -} - -/** - Use scratchpad register to test if this serial port is present. - - @param SerialDevice Pointer to serial device structure - - @return if this serial port is present -**/ -BOOLEAN -SerialPresent ( - IN SERIAL_DEV *SerialDevice - ) - -{ - UINT8 Temp; - BOOLEAN Status; - - Status = TRUE; - - // - // Save SCR reg - // - Temp = READ_SCR (SerialDevice); - WRITE_SCR (SerialDevice, 0xAA); - - if (READ_SCR (SerialDevice) != 0xAA) { - Status = FALSE; - } - - WRITE_SCR (SerialDevice, 0x55); - - if (READ_SCR (SerialDevice) != 0x55) { - Status = FALSE; - } - // - // Restore SCR - // - WRITE_SCR (SerialDevice, Temp); - return Status; -} - -/** - Read serial port. - - @param SerialDev Pointer to serial device - @param Offset Offset in register group - - @return Data read from serial port - -**/ -UINT8 -SerialReadRegister ( - IN SERIAL_DEV *SerialDev, - IN UINT32 Offset - ) -{ - UINT8 Data; - EFI_STATUS Status; - - if (SerialDev->PciDeviceInfo == NULL) { - return IoRead8 ((UINTN) SerialDev->BaseAddress + Offset * SerialDev->RegisterStride); - } else { - if (SerialDev->MmioAccess) { - Status = SerialDev->PciDeviceInfo->PciIo->Mem.Read (SerialDev->PciDeviceInfo->PciIo, EfiPciIoWidthUint8, EFI_PCI_IO_PASS_THROUGH_BAR, - SerialDev->BaseAddress + Offset * SerialDev->RegisterStride, 1, &Data); - } else { - Status = SerialDev->PciDeviceInfo->PciIo->Io.Read (SerialDev->PciDeviceInfo->PciIo, EfiPciIoWidthUint8, EFI_PCI_IO_PASS_THROUGH_BAR, - SerialDev->BaseAddress + Offset * SerialDev->RegisterStride, 1, &Data); - } - ASSERT_EFI_ERROR (Status); - return Data; - } -} - -/** - Write serial port. - - @param SerialDev Pointer to serial device - @param Offset Offset in register group - @param Data data which is to be written to some serial port register -**/ -VOID -SerialWriteRegister ( - IN SERIAL_DEV *SerialDev, - IN UINT32 Offset, - IN UINT8 Data - ) -{ - EFI_STATUS Status; - - if (SerialDev->PciDeviceInfo == NULL) { - IoWrite8 ((UINTN) SerialDev->BaseAddress + Offset * SerialDev->RegisterStride, Data); - } else { - if (SerialDev->MmioAccess) { - Status = SerialDev->PciDeviceInfo->PciIo->Mem.Write (SerialDev->PciDeviceInfo->PciIo, EfiPciIoWidthUint8, EFI_PCI_IO_PASS_THROUGH_BAR, - SerialDev->BaseAddress + Offset * SerialDev->RegisterStride, 1, &Data); - } else { - Status = SerialDev->PciDeviceInfo->PciIo->Io.Write (SerialDev->PciDeviceInfo->PciIo, EfiPciIoWidthUint8, EFI_PCI_IO_PASS_THROUGH_BAR, - SerialDev->BaseAddress + Offset * SerialDev->RegisterStride, 1, &Data); - } - ASSERT_EFI_ERROR (Status); - } -} diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c deleted file mode 100644 index 1e2db1a876..0000000000 --- a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c +++ /dev/null @@ -1,225 +0,0 @@ -/** @file - UfsHcDxe driver produces EFI_UFS_HOST_CONTROLLER_PROTOCOL. The upper layer module - uses it to query the MMIO base address of the UFS host controller. - - Copyright (c) 2014, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "UfsPciHcDxe.h" - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUfsHcComponentName = { - UfsHcComponentNameGetDriverName, - UfsHcComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUfsHcComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UfsHcComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UfsHcComponentNameGetControllerName, - "en" -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUfsHcDriverNameTable[] = { - { - "eng;en", - L"Universal Flash Storage (UFS) Pci Host Controller Driver" - }, - { - NULL, - NULL - } -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUfsHcControllerNameTable[] = { - { - "eng;en", - L"Universal Flash Storage (UFS) Pci Host Controller" - }, - { - NULL, - NULL - } -}; - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -UfsHcComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mUfsHcDriverNameTable, - DriverName, - (BOOLEAN)(This == &gUfsHcComponentName) - ); -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -UfsHcComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - - if (Language == NULL || ControllerName == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // This is a device driver, so ChildHandle must be NULL. - // - if (ChildHandle != NULL) { - return EFI_UNSUPPORTED; - } - - // - // Make sure this driver is currently managing Controller Handle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gUfsHcDriverBinding.DriverBindingHandle, - &gEfiPciIoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mUfsHcControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gUfsHcComponentName) - ); - -} diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c deleted file mode 100644 index 23ebbf108f..0000000000 --- a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c +++ /dev/null @@ -1,818 +0,0 @@ -/** @file - UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller - MMIO base, to upper layer UFS drivers. - - Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "UfsPciHcDxe.h" - -// -// NVM Express Driver Binding Protocol Instance -// -EFI_DRIVER_BINDING_PROTOCOL gUfsHcDriverBinding = { - UfsHcDriverBindingSupported, - UfsHcDriverBindingStart, - UfsHcDriverBindingStop, - 0x10, - NULL, - NULL -}; - -// -// Template for Ufs host controller private data. -// -UFS_HOST_CONTROLLER_PRIVATE_DATA gUfsHcTemplate = { - UFS_HC_PRIVATE_DATA_SIGNATURE, // Signature - NULL, // Handle - { // UfsHcProtocol - UfsHcGetMmioBar, - UfsHcAllocateBuffer, - UfsHcFreeBuffer, - UfsHcMap, - UfsHcUnmap, - UfsHcFlush, - UfsHcMmioRead, - UfsHcMmioWrite - }, - NULL, // PciIo - 0, // BarIndex - 0 // PciAttributes -}; - -/** - Get the MMIO base of the UFS host controller. - - @param[in] This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param[out] MmioBar The MMIO base address of UFS host controller. - - @retval EFI_SUCCESS The operation succeeds. - @retval others The operation fails. -**/ -EFI_STATUS -EFIAPI -UfsHcGetMmioBar ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - OUT UINTN *MmioBar - ) -{ - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT8 BarIndex; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; - - if ((This == NULL) || (MmioBar == NULL)) { - return EFI_INVALID_PARAMETER; - } - - BarDesc = NULL; - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); - PciIo = Private->PciIo; - BarIndex = Private->BarIndex; - - Status = PciIo->GetBarAttributes ( - PciIo, - BarIndex, - NULL, - (VOID**) &BarDesc - ); - if (EFI_ERROR (Status)) { - return Status; - } - - *MmioBar = (UINTN)BarDesc->AddrRangeMin; - - FreePool (BarDesc); - - return Status; -} - -/** - Provides the UFS controller-specific addresses needed to access system memory. - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Operation Indicates if the bus master is going to read or write to system memory. - @param HostAddress The system memory address to map to the UFS controller. - @param NumberOfBytes On input the number of bytes to map. On output the number of bytes - that were mapped. - @param DeviceAddress The resulting map address for the bus master UFS controller to use to - access the hosts HostAddress. - @param Mapping A resulting value to pass to Unmap(). - - @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. - -**/ -EFI_STATUS -EFIAPI -UfsHcMap ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN EDKII_UFS_HOST_CONTROLLER_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -{ - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - - if ((This == NULL) || (HostAddress == NULL) || (NumberOfBytes == NULL) || (DeviceAddress == NULL) || (Mapping == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); - PciIo = Private->PciIo; - - Status = PciIo->Map (PciIo, (EFI_PCI_IO_PROTOCOL_OPERATION)Operation, HostAddress, NumberOfBytes, DeviceAddress, Mapping); - return Status; -} - -/** - Completes the Map() operation and releases any corresponding resources. - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Mapping The mapping value returned from Map(). - - @retval EFI_SUCCESS The range was unmapped. - @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. - -**/ -EFI_STATUS -EFIAPI -UfsHcUnmap ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN VOID *Mapping - ) -{ - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - - if ((This == NULL) || (Mapping == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); - PciIo = Private->PciIo; - - Status = PciIo->Unmap (PciIo, Mapping); - return Status; -} - -/** - Allocates pages that are suitable for an EfiUfsHcOperationBusMasterCommonBuffer - mapping. - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Type This parameter is not used and must be ignored. - @param MemoryType The type of memory to allocate, EfiBootServicesData or - EfiRuntimeServicesData. - @param Pages The number of pages to allocate. - @param HostAddress A pointer to store the base system memory address of the - allocated range. - @param Attributes The requested bit mask of attributes for the allocated range. - - @retval EFI_SUCCESS The requested memory pages were allocated. - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are - MEMORY_WRITE_COMBINE and MEMORY_CACHED. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. - -**/ -EFI_STATUS -EFIAPI -UfsHcAllocateBuffer ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ) -{ - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - - if ((This == NULL) || (HostAddress == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); - PciIo = Private->PciIo; - - Status = PciIo->AllocateBuffer (PciIo, Type, MemoryType, Pages, HostAddress, Attributes); - return Status; -} - -/** - Frees memory that was allocated with AllocateBuffer(). - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Pages The number of pages to free. - @param HostAddress The base system memory address of the allocated range. - - @retval EFI_SUCCESS The requested memory pages were freed. - @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages - was not allocated with AllocateBuffer(). - -**/ -EFI_STATUS -EFIAPI -UfsHcFreeBuffer ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress - ) -{ - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - - if ((This == NULL) || (HostAddress == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); - PciIo = Private->PciIo; - - Status = PciIo->FreeBuffer (PciIo, Pages, HostAddress); - return Status; -} - -/** - Flushes all posted write transactions from the UFS bus to attached UFS device. - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - - @retval EFI_SUCCESS The posted write transactions were flushed from the UFS bus - to attached UFS device. - @retval EFI_DEVICE_ERROR The posted write transactions were not flushed from the UFS - bus to attached UFS device due to a hardware error. - -**/ -EFI_STATUS -EFIAPI -UfsHcFlush ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This - ) -{ - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); - PciIo = Private->PciIo; - - Status = PciIo->Flush (PciIo); - return Status; -} - -/** - Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space. - - @param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param Offset The offset within the UFS Host Controller MMIO space to start the - memory operation. - @param Count The number of memory operations to perform. - @param Buffer For read operations, the destination buffer to store the results. - For write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the UFS host controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the UFS Host Controller memory space. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -UfsHcMmioRead ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT8 BarIndex; - - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); - PciIo = Private->PciIo; - BarIndex = Private->BarIndex; - - Status = PciIo->Mem.Read (PciIo, (EFI_PCI_IO_PROTOCOL_WIDTH)Width, BarIndex, Offset, Count, Buffer); - - return Status; -} - -/** - Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space. - - @param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param Offset The offset within the UFS Host Controller MMIO space to start the - memory operation. - @param Count The number of memory operations to perform. - @param Buffer For read operations, the destination buffer to store the results. - For write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the UFS host controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the UFS Host Controller memory space. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -UfsHcMmioWrite ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_STATUS Status; - UINT8 BarIndex; - - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); - PciIo = Private->PciIo; - BarIndex = Private->BarIndex; - - Status = PciIo->Mem.Write (PciIo, (EFI_PCI_IO_PROTOCOL_WIDTH)Width, BarIndex, Offset, Count, Buffer); - - return Status; -} - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -UfsHcDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - BOOLEAN UfsHcFound; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE00 PciData; - - PciIo = NULL; - ParentDevicePath = NULL; - UfsHcFound = FALSE; - - // - // UfsHcDxe is a device driver, and should ingore the - // "RemainingDevicePath" according to EFI spec - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID *) &ParentDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status)) { - // - // EFI_ALREADY_STARTED is also an error - // - return Status; - } - // - // Close the protocol because we don't use it here - // - gBS->CloseProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - // - // Now test the EfiPciIoProtocol - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Now further check the PCI header: Base class (offset 0x0B) and - // Sub Class (offset 0x0A). This controller should be an UFS controller - // - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - 0, - sizeof (PciData), - &PciData - ); - if (EFI_ERROR (Status)) { - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - return EFI_UNSUPPORTED; - } - // - // Since we already got the PciData, we can close protocol to avoid to carry it on for multiple exit points. - // - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - // - // Examine UFS Host Controller PCI Configuration table fields - // - if (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE) { - if (PciData.Hdr.ClassCode[1] == 0x09 ) { //UFS Controller Subclass - UfsHcFound = TRUE; - } - } - - if (!UfsHcFound) { - return EFI_UNSUPPORTED; - } - - return Status; -} - - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -UfsHcDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - UINT64 Supports; - UINT8 BarIndex; - EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; - - PciIo = NULL; - Private = NULL; - Supports = 0; - BarDesc = NULL; - - // - // Now test and open the EfiPciIoProtocol - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - // - // Status == 0 - A normal execution flow, SUCCESS and the program proceeds. - // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates - // that the protocol has been opened and should be treated as a - // normal condition and the program proceeds. The Protocol will not - // opened 'again' by this call. - // Status != ALREADY_STARTED - Error status, terminate program execution - // - if (EFI_ERROR (Status)) { - // - // EFI_ALREADY_STARTED is also an error - // - return Status; - } - - Private = AllocateCopyPool (sizeof (UFS_HOST_CONTROLLER_PRIVATE_DATA), &gUfsHcTemplate); - if (Private == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - Private->PciIo = PciIo; - - for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) { - Status = PciIo->GetBarAttributes ( - PciIo, - BarIndex, - NULL, - (VOID**) &BarDesc - ); - if (Status == EFI_UNSUPPORTED) { - continue; - } else if (EFI_ERROR (Status)) { - goto Done; - } - - if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { - Private->BarIndex = BarIndex; - FreePool (BarDesc); - break; - } - - FreePool (BarDesc); - } - - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationGet, - 0, - &Private->PciAttributes - ); - - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } else { - goto Done; - } - - /// - /// Install UFS_HOST_CONTROLLER protocol - /// - Status = gBS->InstallProtocolInterface ( - &Controller, - &gEdkiiUfsHostControllerProtocolGuid, - EFI_NATIVE_INTERFACE, - (VOID*)&(Private->UfsHc) - ); - -Done: - if (EFI_ERROR (Status)) { - if ((Private != NULL) && (Private->PciAttributes != 0)) { - // - // Restore original PCI attributes - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSet, - Private->PciAttributes, - NULL - ); - ASSERT_EFI_ERROR (Status); - } - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - if (Private != NULL) { - FreePool (Private); - } - } - - return Status; -} - - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -UfsHcDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_STATUS Status; - UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; - EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc; - - /// - /// Get private data - /// - Status = gBS->OpenProtocol ( - Controller, - &gEdkiiUfsHostControllerProtocolGuid, - (VOID **) &UfsHc, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (UfsHc); - - Status = gBS->UninstallProtocolInterface ( - Controller, - &gEdkiiUfsHostControllerProtocolGuid, - &(Private->UfsHc) - ); - if (!EFI_ERROR (Status)) { - // - // Restore original PCI attributes - // - Status = Private->PciIo->Attributes ( - Private->PciIo, - EfiPciIoAttributeOperationSet, - Private->PciAttributes, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Close protocols opened by UFS host controller driver - // - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - FreePool (Private); - } - - return Status; -} - -/** - The entry point for UFS host controller driver, used to install this driver on the ImageHandle. - - @param[in] ImageHandle The firmware allocated handle for this driver image. - @param[in] SystemTable Pointer to the EFI system table. - - @retval EFI_SUCCESS Driver loaded. - @retval other Driver not loaded. - -**/ -EFI_STATUS -EFIAPI -UfsHcDriverEntry ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - Status = EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gUfsHcDriverBinding, - ImageHandle, - &gUfsHcComponentName, - &gUfsHcComponentName2 - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h deleted file mode 100644 index 89f19feb7a..0000000000 --- a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h +++ /dev/null @@ -1,511 +0,0 @@ -/** @file - UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller - MMIO base, to upper layer UFS drivers. - - Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_UFS_HOST_CONTROLLER_H_ -#define _EFI_UFS_HOST_CONTROLLER_H_ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -extern EFI_DRIVER_BINDING_PROTOCOL gUfsHcDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gUfsHcComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gUfsHcComponentName2; - -// -// Unique signature for private data structure. -// -#define UFS_HC_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('U','F','S','H') - -typedef struct _UFS_HOST_CONTROLLER_PRIVATE_DATA UFS_HOST_CONTROLLER_PRIVATE_DATA; - -// -// Nvme private data structure. -// -struct _UFS_HOST_CONTROLLER_PRIVATE_DATA { - UINT32 Signature; - EFI_HANDLE Handle; - - EDKII_UFS_HOST_CONTROLLER_PROTOCOL UfsHc; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 BarIndex; - UINT64 PciAttributes; -}; - -#define UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC(a) \ - CR (a, \ - UFS_HOST_CONTROLLER_PRIVATE_DATA, \ - UfsHc, \ - UFS_HC_PRIVATE_DATA_SIGNATURE \ - ) - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -UfsHcComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -UfsHcComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -/** - Tests to see if this driver supports a given controller. If a child device is provided, - it further tests to see if this driver supports creating a handle for the specified child device. - - This function checks to see if the driver specified by This supports the device specified by - ControllerHandle. Drivers will typically use the device path attached to - ControllerHandle and/or the services from the bus I/O abstraction attached to - ControllerHandle to determine if the driver supports ControllerHandle. This function - may be called many times during platform initialization. In order to reduce boot times, the tests - performed by this function must be very small, and take as little time as possible to execute. This - function must not change the state of any hardware devices, and this function must be aware that the - device specified by ControllerHandle may already be managed by the same driver or a - different driver. This function must match its calls to AllocatePages() with FreePages(), - AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). - Since ControllerHandle may have been previously started by the same driver, if a protocol is - already in the opened state, then it must not be closed with CloseProtocol(). This is required - to guarantee the state of ControllerHandle is not modified by this function. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to test. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For bus drivers, if this parameter is not NULL, then - the bus driver must determine if the bus controller specified - by ControllerHandle and the child controller specified - by RemainingDevicePath are both supported by this - bus driver. - - @retval EFI_SUCCESS The device specified by ControllerHandle and - RemainingDevicePath is supported by the driver specified by This. - @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by the driver - specified by This. - @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and - RemainingDevicePath is already being managed by a different - driver or an application that requires exclusive access. - Currently not implemented. - @retval EFI_UNSUPPORTED The device specified by ControllerHandle and - RemainingDevicePath is not supported by the driver specified by This. -**/ -EFI_STATUS -EFIAPI -UfsHcDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Starts a device controller or a bus controller. - - The Start() function is designed to be invoked from the EFI boot service ConnectController(). - As a result, much of the error checking on the parameters to Start() has been moved into this - common boot service. It is legal to call Start() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE. - 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned - EFI_DEVICE_PATH_PROTOCOL. - 3. Prior to calling Start(), the Supported() function for the driver specified by This must - have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle The handle of the controller to start. This handle - must support a protocol interface that supplies - an I/O abstraction to the driver. - @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This - parameter is ignored by device drivers, and is optional for bus - drivers. For a bus driver, if this parameter is NULL, then handles - for all the children of Controller are created by this driver. - If this parameter is not NULL and the first Device Path Node is - not the End of Device Path Node, then only the handle for the - child device specified by the first Device Path Node of - RemainingDevicePath is created by this driver. - If the first Device Path Node of RemainingDevicePath is - the End of Device Path Node, no child handle is created by this - driver. - - @retval EFI_SUCCESS The device was started. - @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval Others The driver failded to start the device. - -**/ -EFI_STATUS -EFIAPI -UfsHcDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stops a device controller or a bus controller. - - The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). - As a result, much of the error checking on the parameters to Stop() has been moved - into this common boot service. It is legal to call Stop() from other locations, - but the following calling restrictions must be followed or the system behavior will not be deterministic. - 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this - same driver's Start() function. - 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid - EFI_HANDLE. In addition, all of these handles must have been created in this driver's - Start() function, and the Start() function must have called OpenProtocol() on - ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. - - @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. - @param[in] ControllerHandle A handle to the device being stopped. The handle must - support a bus specific I/O protocol for the driver - to use to stop the device. - @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -UfsHcDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -/** - Get the MMIO base of the UFS host controller. - - @param[in] This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param[out] MmioBar The MMIO base address of UFS host controller. - - @retval EFI_SUCCESS The operation succeeds. - @retval others The operation fails. -**/ -EFI_STATUS -EFIAPI -UfsHcGetMmioBar ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - OUT UINTN *MmioBar - ); - -/** - Provides the UFS controller-specific addresses needed to access system memory. - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Operation Indicates if the bus master is going to read or write to system memory. - @param HostAddress The system memory address to map to the UFS controller. - @param NumberOfBytes On input the number of bytes to map. On output the number of bytes - that were mapped. - @param DeviceAddress The resulting map address for the bus master UFS controller to use to - access the hosts HostAddress. - @param Mapping A resulting value to pass to Unmap(). - - @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. - -**/ -EFI_STATUS -EFIAPI -UfsHcMap ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN EDKII_UFS_HOST_CONTROLLER_OPERATION Operation, - IN VOID *HostAddress, - IN OUT UINTN *NumberOfBytes, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ); - -/** - Completes the Map() operation and releases any corresponding resources. - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Mapping The mapping value returned from Map(). - - @retval EFI_SUCCESS The range was unmapped. - @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. - -**/ -EFI_STATUS -EFIAPI -UfsHcUnmap ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN VOID *Mapping - ); - -/** - Allocates pages that are suitable for an EfiUfsHcOperationBusMasterCommonBuffer - mapping. - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Type This parameter is not used and must be ignored. - @param MemoryType The type of memory to allocate, EfiBootServicesData or - EfiRuntimeServicesData. - @param Pages The number of pages to allocate. - @param HostAddress A pointer to store the base system memory address of the - allocated range. - @param Attributes The requested bit mask of attributes for the allocated range. - - @retval EFI_SUCCESS The requested memory pages were allocated. - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are - MEMORY_WRITE_COMBINE and MEMORY_CACHED. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. - -**/ -EFI_STATUS -EFIAPI -UfsHcAllocateBuffer ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT VOID **HostAddress, - IN UINT64 Attributes - ); - -/** - Frees memory that was allocated with AllocateBuffer(). - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Pages The number of pages to free. - @param HostAddress The base system memory address of the allocated range. - - @retval EFI_SUCCESS The requested memory pages were freed. - @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages - was not allocated with AllocateBuffer(). - -**/ -EFI_STATUS -EFIAPI -UfsHcFreeBuffer ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN UINTN Pages, - IN VOID *HostAddress - ); - -/** - Flushes all posted write transactions from the UFS bus to attached UFS device. - - @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. - - @retval EFI_SUCCESS The posted write transactions were flushed from the UFS bus - to attached UFS device. - @retval EFI_DEVICE_ERROR The posted write transactions were not flushed from the UFS - bus to attached UFS device due to a hardware error. - -**/ -EFI_STATUS -EFIAPI -UfsHcFlush ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This - ); - -/** - Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space. - - @param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param Offset The offset within the UFS Host Controller MMIO space to start the - memory operation. - @param Count The number of memory operations to perform. - @param Buffer For read operations, the destination buffer to store the results. - For write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the UFS host controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the UFS Host Controller memory space. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -UfsHcMmioRead ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space. - - @param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance. - @param Width Signifies the width of the memory operations. - @param Offset The offset within the UFS Host Controller MMIO space to start the - memory operation. - @param Count The number of memory operations to perform. - @param Buffer For read operations, the destination buffer to store the results. - For write operations, the source buffer to write data from. - - @retval EFI_SUCCESS The data was read from or written to the UFS host controller. - @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not - valid for the UFS Host Controller memory space. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -UfsHcMmioWrite ( - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, - IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width, - IN UINT64 Offset, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf deleted file mode 100644 index c1ce9ea851..0000000000 --- a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf +++ /dev/null @@ -1,56 +0,0 @@ -## @file -# Component Description File For Universal Flash Storage Pci Host Controller Module. -# -# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = UfsPciHcDxe - MODULE_UNI_FILE = UfsPciHcDxe.uni - FILE_GUID = AF43E178-C2E9-4712-A7CD-08BFDAC7482C - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 0.9 - ENTRY_POINT = UfsHcDriverEntry - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# -# DRIVER_BINDING = gUfsHcDriverBinding -# COMPONENT_NAME = gUfsHcComponentName -# COMPONENT_NAME2 = gUfsHcComponentName2 - -[Sources] - ComponentName.c - UfsPciHcDxe.c - UfsPciHcDxe.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - BaseLib - DebugLib - DevicePathLib - UefiDriverEntryPoint - UefiBootServicesTableLib - UefiLib - -[Protocols] - gEfiPciIoProtocolGuid ## TO_START - gEfiDevicePathProtocolGuid ## TO_START - gEdkiiUfsHostControllerProtocolGuid ## BY_START - -[UserExtensions.TianoCore."ExtraFiles"] - UfsPciHcDxeExtra.uni \ No newline at end of file diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni deleted file mode 100644 index 5b3a137d80..0000000000 Binary files a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni deleted file mode 100644 index fb359fd615..0000000000 Binary files a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.c b/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.c deleted file mode 100644 index 36325641e7..0000000000 --- a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.c +++ /dev/null @@ -1,152 +0,0 @@ -/** @file - UfsPciHcPei driver is used to provide platform-dependent info, mainly UFS host controller - MMIO base, to upper layer UFS drivers. - - Copyright (c) 2014, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "UfsPciHcPei.h" - -EDKII_UFS_HOST_CONTROLLER_PPI mUfsHostControllerPpi = { GetUfsHcMmioBar }; - -EFI_PEI_PPI_DESCRIPTOR mPpiList = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEdkiiPeiUfsHostControllerPpiGuid, - &mUfsHostControllerPpi -}; - -/** - Get the MMIO base address of UFS host controller. - - @param[in] This The protocol instance pointer. - @param[in] ControllerId The ID of the UFS host controller. - @param[out] MmioBar Pointer to the UFS host controller MMIO base address. - - @retval EFI_SUCCESS The operation succeeds. - @retval EFI_INVALID_PARAMETER The parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -GetUfsHcMmioBar ( - IN EDKII_UFS_HOST_CONTROLLER_PPI *This, - IN UINT8 ControllerId, - OUT UINTN *MmioBar - ) -{ - UFS_HC_PEI_PRIVATE_DATA *Private; - - if ((This == NULL) || (MmioBar == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Private = UFS_HC_PEI_PRIVATE_DATA_FROM_THIS (This); - - if (ControllerId >= Private->TotalUfsHcs) { - return EFI_INVALID_PARAMETER; - } - - *MmioBar = (UINTN)Private->UfsHcPciAddr[ControllerId]; - - return EFI_SUCCESS; -} - -/** - The user code starts with this function. - - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCCESS The driver is successfully initialized. - @retval Others Can't initialize the driver. - -**/ -EFI_STATUS -EFIAPI -InitializeUfsHcPeim ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - EFI_BOOT_MODE BootMode; - EFI_STATUS Status; - UINT16 Bus; - UINT16 Device; - UINT16 Function; - UINT32 Size; - UINT8 SubClass; - UINT8 BaseClass; - UFS_HC_PEI_PRIVATE_DATA *Private; - - // - // Shadow this PEIM to run from memory - // - if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { - return EFI_SUCCESS; - } - - Status = PeiServicesGetBootMode (&BootMode); - /// - /// We do not export this in S3 boot path, because it is only for recovery. - /// - if (BootMode == BOOT_ON_S3_RESUME) { - return EFI_SUCCESS; - } - - Private = (UFS_HC_PEI_PRIVATE_DATA *) AllocateZeroPool (sizeof (UFS_HC_PEI_PRIVATE_DATA)); - if (Private == NULL) { - DEBUG ((EFI_D_ERROR, "Failed to allocate memory for UFS_HC_PEI_PRIVATE_DATA! \n")); - return EFI_OUT_OF_RESOURCES; - } - - Private->Signature = UFS_HC_PEI_SIGNATURE; - Private->UfsHostControllerPpi = mUfsHostControllerPpi; - Private->PpiList = mPpiList; - Private->PpiList.Ppi = &Private->UfsHostControllerPpi; - - for (Bus = 0; Bus < 256; Bus++) { - for (Device = 0; Device < 32; Device++) { - for (Function = 0; Function < 8; Function++) { - SubClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0A)); - BaseClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0B)); - - if ((SubClass == 0x09) && (BaseClass == PCI_CLASS_MASS_STORAGE)) { - // - // Get the Ufs Pci host controller's MMIO region size. - // - PciAnd16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (UINT16)~(EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE)); - PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), 0xFFFFFFFF); - Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET)); - // - // Assign resource to the Ufs Pci host controller's MMIO BAR. - // Enable the Ufs Pci host controller by setting BME and MSE bits of PCI_CMD register. - // - PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), (UINT32)(PcdGet32 (PcdUfsPciHostControllerMmioBase) + Size * Private->TotalUfsHcs)); - PciOr16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE)); - // - // Record the allocated Mmio base address. - // - Private->UfsHcPciAddr[Private->TotalUfsHcs] = PcdGet32 (PcdUfsPciHostControllerMmioBase) + Size * Private->TotalUfsHcs; - Private->TotalUfsHcs++; - ASSERT (Private->TotalUfsHcs < MAX_UFS_HCS); - } - } - } - } - - /// - /// Install Ufs Host Controller PPI - /// - Status = PeiServicesInstallPpi (&Private->PpiList); - - ASSERT_EFI_ERROR (Status); - return Status; -} diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.h b/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.h deleted file mode 100644 index 2405dd76d8..0000000000 --- a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.h +++ /dev/null @@ -1,62 +0,0 @@ -/** @file - Copyright (c) 2014, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _UFS_PCI_HOST_CONTROLLER_PEI_H_ -#define _UFS_PCI_HOST_CONTROLLER_PEI_H_ - -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#define UFS_HC_PEI_SIGNATURE SIGNATURE_32 ('U', 'F', 'S', 'P') -#define MAX_UFS_HCS 8 - -typedef struct { - UINTN Signature; - EDKII_UFS_HOST_CONTROLLER_PPI UfsHostControllerPpi; - EFI_PEI_PPI_DESCRIPTOR PpiList; - UINTN TotalUfsHcs; - UINTN UfsHcPciAddr[MAX_UFS_HCS]; -} UFS_HC_PEI_PRIVATE_DATA; - -#define UFS_HC_PEI_PRIVATE_DATA_FROM_THIS(a) CR (a, UFS_HC_PEI_PRIVATE_DATA, UfsHostControllerPpi, UFS_HC_PEI_SIGNATURE) - -/** - Get the MMIO base address of UFS host controller. - - @param[in] This The protocol instance pointer. - @param[in] ControllerId The ID of the UFS host controller. - @param[out] MmioBar Pointer to the UFS host controller MMIO base address. - - @retval EFI_SUCCESS The operation succeeds. - @retval EFI_INVALID_PARAMETER The parameters are invalid. - -**/ -EFI_STATUS -EFIAPI -GetUfsHcMmioBar ( - IN EDKII_UFS_HOST_CONTROLLER_PPI *This, - IN UINT8 ControllerId, - OUT UINTN *MmioBar - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.inf b/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.inf deleted file mode 100644 index b16935628c..0000000000 --- a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.inf +++ /dev/null @@ -1,56 +0,0 @@ -## @file -# Component Description File For Universal Flash Storage Pci Host Controller Pei Module. -# -# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = UfsPciHcPei - MODULE_UNI_FILE = UfsPciHcPei.uni - FILE_GUID = 905DC1AD-C44D-4965-98AC-B6B4444BFD65 - MODULE_TYPE = PEIM - VERSION_STRING = 0.9 - - ENTRY_POINT = InitializeUfsHcPeim - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - UfsPciHcPei.c - UfsPciHcPei.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - PciLib - DebugLib - PeiServicesLib - MemoryAllocationLib - PeimEntryPoint - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdUfsPciHostControllerMmioBase ## CONSUMES - -[Ppis] - gEdkiiPeiUfsHostControllerPpiGuid ## PRODUCES - -[Depex] - gEfiPeiMasterBootModePpiGuid AND gEfiPeiMemoryDiscoveredPpiGuid - -[UserExtensions.TianoCore."ExtraFiles"] - UfsPciHcPeiExtra.uni \ No newline at end of file diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.uni b/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.uni deleted file mode 100644 index 7b7ea3af7b..0000000000 Binary files a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPei.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPeiExtra.uni b/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPeiExtra.uni deleted file mode 100644 index 4487eb968f..0000000000 Binary files a/MdeModulePkg/Bus/Pci/UfsPciHcPei/UfsPciHcPeiExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.c deleted file mode 100644 index ad2ba42b55..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.c +++ /dev/null @@ -1,231 +0,0 @@ -/** @file - UEFI Component Name(2) protocol implementation for UHCI driver. - -Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Uhci.h" - - -// -// EFI Component Name Protocol -// - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUhciComponentName = { - UhciComponentNameGetDriverName, - UhciComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUhciComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UhciComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UhciComponentNameGetControllerName, - "en" -}; - - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUhciDriverNameTable[] = { - { "eng;en", L"Usb Uhci Driver" }, - { NULL, NULL } -}; - - -// -// EFI Component Name Functions -// - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -UhciComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mUhciDriverNameTable, - DriverName, - (BOOLEAN)(This == &gUhciComponentName) - ); -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -UhciComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - USB_HC_DEV *UhciDev; - EFI_USB2_HC_PROTOCOL *Usb2Hc; - - // - // This is a device driver, so ChildHandle must be NULL. - // - if (ChildHandle != NULL) { - return EFI_UNSUPPORTED; - } - - // - // Make sure this driver is currently managing ControllerHandle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gUhciDriverBinding.DriverBindingHandle, - &gEfiPciIoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the device context - // - Status = gBS->OpenProtocol ( - ControllerHandle, - &gEfiUsb2HcProtocolGuid, - (VOID **) &Usb2Hc, - gUhciDriverBinding.DriverBindingHandle, - ControllerHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - UhciDev = UHC_FROM_USB2_HC_PROTO (Usb2Hc); - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - UhciDev->CtrlNameTable, - ControllerName, - (BOOLEAN)(This == &gUhciComponentName) - ); - -} diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.h b/MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.h deleted file mode 100644 index fd19a21ec6..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/ComponentName.h +++ /dev/null @@ -1,145 +0,0 @@ -/** @file - - This file contains the delarations for componet name routines. - -Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _COMPONENT_NAME_H_ -#define _COMPONENT_NAME_H_ - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -UhciComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -UhciComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c deleted file mode 100644 index 179e36c3a2..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c +++ /dev/null @@ -1,1889 +0,0 @@ -/** @file - - The UHCI driver model and HC protocol routines. - -Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Uhci.h" - - -EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = { - UhciDriverBindingSupported, - UhciDriverBindingStart, - UhciDriverBindingStop, - 0x20, - NULL, - NULL -}; - -/** - Provides software reset for the USB host controller according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param Attributes A bit mask of the reset operation to perform. See - below for a list of the supported bit mask values. - - @return EFI_SUCCESS The reset operation succeeded. - @return EFI_INVALID_PARAMETER Attributes is not valid. - @return EFI_UNSUPPORTED This type of reset is not currently supported. - @return EFI_DEVICE_ERROR Other errors. - -**/ -EFI_STATUS -EFIAPI -Uhci2Reset ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT16 Attributes - ) -{ - USB_HC_DEV *Uhc; - EFI_TPL OldTpl; - - if ((Attributes == EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG) || - (Attributes == EFI_USB_HC_RESET_HOST_WITH_DEBUG)) { - return EFI_UNSUPPORTED; - } - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - - if (Uhc->DevicePath != NULL) { - // - // Report Status Code to indicate reset happens - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_USB | EFI_IOB_PC_RESET), - Uhc->DevicePath - ); - } - - OldTpl = gBS->RaiseTPL (UHCI_TPL); - - switch (Attributes) { - case EFI_USB_HC_RESET_GLOBAL: - // - // Stop schedule and set the Global Reset bit in the command register - // - UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT); - UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET); - - gBS->Stall (UHC_ROOT_PORT_RESET_STALL); - - // - // Clear the Global Reset bit to zero. - // - UhciClearRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET); - - gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL); - break; - - case EFI_USB_HC_RESET_HOST_CONTROLLER: - // - // Stop schedule and set Host Controller Reset bit to 1 - // - UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT); - UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET); - - gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL); - break; - - default: - goto ON_INVAILD_PARAMETER; - } - - // - // Delete all old transactions on the USB bus, then - // reinitialize the frame list - // - UhciFreeAllAsyncReq (Uhc); - UhciDestoryFrameList (Uhc); - UhciInitFrameList (Uhc); - - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; - -ON_INVAILD_PARAMETER: - - gBS->RestoreTPL (OldTpl); - - return EFI_INVALID_PARAMETER; -} - - -/** - Retrieves current state of the USB host controller according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param State Variable to receive current device state. - - @return EFI_SUCCESS The state is returned. - @return EFI_INVALID_PARAMETER State is not valid. - @return EFI_DEVICE_ERROR Other errors. - -**/ -EFI_STATUS -EFIAPI -Uhci2GetState ( - IN EFI_USB2_HC_PROTOCOL *This, - OUT EFI_USB_HC_STATE *State - ) -{ - USB_HC_DEV *Uhc; - UINT16 UsbSts; - UINT16 UsbCmd; - - if (State == NULL) { - return EFI_INVALID_PARAMETER; - } - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - - UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET); - UsbSts = UhciReadReg (Uhc->PciIo, USBSTS_OFFSET); - - if ((UsbCmd & USBCMD_EGSM) !=0 ) { - *State = EfiUsbHcStateSuspend; - - } else if ((UsbSts & USBSTS_HCH) != 0) { - *State = EfiUsbHcStateHalt; - - } else { - *State = EfiUsbHcStateOperational; - } - - return EFI_SUCCESS; -} - - -/** - Sets the USB host controller to a specific state according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param State Indicates the state of the host controller that will - be set. - - @return EFI_SUCCESS Host controller was successfully placed in the state. - @return EFI_INVALID_PARAMETER State is invalid. - @return EFI_DEVICE_ERROR Failed to set the state. - -**/ -EFI_STATUS -EFIAPI -Uhci2SetState ( - IN EFI_USB2_HC_PROTOCOL *This, - IN EFI_USB_HC_STATE State - ) -{ - EFI_USB_HC_STATE CurState; - USB_HC_DEV *Uhc; - EFI_TPL OldTpl; - EFI_STATUS Status; - UINT16 UsbCmd; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - Status = Uhci2GetState (This, &CurState); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - if (CurState == State) { - return EFI_SUCCESS; - } - - Status = EFI_SUCCESS; - OldTpl = gBS->RaiseTPL (UHCI_TPL); - - switch (State) { - case EfiUsbHcStateHalt: - Status = UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT); - break; - - case EfiUsbHcStateOperational: - UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET); - - if (CurState == EfiUsbHcStateHalt) { - // - // Set Run/Stop bit to 1, also set the bandwidht reclamation - // point to 64 bytes - // - UsbCmd |= USBCMD_RS | USBCMD_MAXP; - UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd); - - } else if (CurState == EfiUsbHcStateSuspend) { - // - // If FGR(Force Global Resume) bit is 0, set it - // - if ((UsbCmd & USBCMD_FGR) == 0) { - UsbCmd |= USBCMD_FGR; - UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd); - } - - // - // wait 20ms to let resume complete (20ms is specified by UHCI spec) - // - gBS->Stall (UHC_FORCE_GLOBAL_RESUME_STALL); - - // - // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0 - // - UsbCmd &= ~USBCMD_FGR; - UsbCmd &= ~USBCMD_EGSM; - UsbCmd |= USBCMD_RS; - UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd); - } - - break; - - case EfiUsbHcStateSuspend: - Status = Uhci2SetState (This, EfiUsbHcStateHalt); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto ON_EXIT; - } - - // - // Set Enter Global Suspend Mode bit to 1. - // - UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET); - UsbCmd |= USBCMD_EGSM; - UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd); - break; - - default: - Status = EFI_INVALID_PARAMETER; - break; - } - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Retrieves capabilities of USB host controller according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param MaxSpeed A pointer to the max speed USB host controller - supports. - @param PortNumber A pointer to the number of root hub ports. - @param Is64BitCapable A pointer to an integer to show whether USB host - controller supports 64-bit memory addressing. - - @return EFI_SUCCESS capabilities were retrieved successfully. - @return EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL. - @return EFI_DEVICE_ERROR An error was encountered. - -**/ -EFI_STATUS -EFIAPI -Uhci2GetCapability ( - IN EFI_USB2_HC_PROTOCOL *This, - OUT UINT8 *MaxSpeed, - OUT UINT8 *PortNumber, - OUT UINT8 *Is64BitCapable - ) -{ - USB_HC_DEV *Uhc; - UINT32 Offset; - UINT16 PortSC; - UINT32 Index; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - - if ((NULL == MaxSpeed) || (NULL == PortNumber) || (NULL == Is64BitCapable)) { - return EFI_INVALID_PARAMETER; - } - - *MaxSpeed = EFI_USB_SPEED_FULL; - *Is64BitCapable = (UINT8) FALSE; - - *PortNumber = 0; - - for (Index = 0; Index < USB_MAX_ROOTHUB_PORT; Index++) { - Offset = USBPORTSC_OFFSET + Index * 2; - PortSC = UhciReadReg (Uhc->PciIo, Offset); - - // - // Port status's bit 7 is reserved and always returns 1 if - // the port number is valid. Intel's UHCI (in EHCI controller) - // returns 0 in this bit if port number is invalid. Also, if - // PciIo IoRead returns error, 0xFFFF is returned to caller. - // - if (((PortSC & 0x80) == 0) || (PortSC == 0xFFFF)) { - break; - } - (*PortNumber)++; - } - - Uhc->RootPorts = *PortNumber; - - DEBUG ((EFI_D_INFO, "Uhci2GetCapability: %d ports\n", (UINT32)Uhc->RootPorts)); - return EFI_SUCCESS; -} - - -/** - Retrieves the current status of a USB root hub port according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL. - @param PortNumber The port to get status. - @param PortStatus A pointer to the current port status bits and port - status change bits. - - @return EFI_SUCCESS status of the USB root hub port was returned in PortStatus. - @return EFI_INVALID_PARAMETER PortNumber is invalid. - @return EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -Uhci2GetRootHubPortStatus ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - OUT EFI_USB_PORT_STATUS *PortStatus - ) -{ - USB_HC_DEV *Uhc; - UINT32 Offset; - UINT16 PortSC; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - - if (PortStatus == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (PortNumber >= Uhc->RootPorts) { - return EFI_INVALID_PARAMETER; - } - - Offset = USBPORTSC_OFFSET + PortNumber * 2; - PortStatus->PortStatus = 0; - PortStatus->PortChangeStatus = 0; - - PortSC = UhciReadReg (Uhc->PciIo, Offset); - - if ((PortSC & USBPORTSC_CCS) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION; - } - - if ((PortSC & USBPORTSC_PED) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_ENABLE; - } - - if ((PortSC & USBPORTSC_SUSP) != 0) { - DEBUG ((EFI_D_INFO, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber)); - PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND; - } - - if ((PortSC & USBPORTSC_PR) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_RESET; - } - - if ((PortSC & USBPORTSC_LSDA) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED; - } - - // - // CHC will always return one in port owner bit - // - PortStatus->PortStatus |= USB_PORT_STAT_OWNER; - - if ((PortSC & USBPORTSC_CSC) != 0) { - PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION; - } - - if ((PortSC & USBPORTSC_PEDC) != 0) { - PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE; - } - - return EFI_SUCCESS; -} - - -/** - Sets a feature for the specified root hub port according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL. - @param PortNumber Specifies the root hub port whose feature is - requested to be set. - @param PortFeature Indicates the feature selector associated with the - feature set request. - - @return EFI_SUCCESS PortFeature was set for the root port. - @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @return EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -Uhci2SetRootHubPortFeature ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - USB_HC_DEV *Uhc; - EFI_TPL OldTpl; - UINT32 Offset; - UINT16 PortSC; - UINT16 Command; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - - if (PortNumber >= Uhc->RootPorts) { - return EFI_INVALID_PARAMETER; - } - - Offset = USBPORTSC_OFFSET + PortNumber * 2; - - OldTpl = gBS->RaiseTPL (UHCI_TPL); - PortSC = UhciReadReg (Uhc->PciIo, Offset); - - switch (PortFeature) { - case EfiUsbPortSuspend: - Command = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET); - if ((Command & USBCMD_EGSM) == 0) { - // - // if global suspend is not active, can set port suspend - // - PortSC &= 0xfff5; - PortSC |= USBPORTSC_SUSP; - } - break; - - case EfiUsbPortReset: - PortSC &= 0xfff5; - PortSC |= USBPORTSC_PR; - break; - - case EfiUsbPortPower: - // - // No action - // - break; - - case EfiUsbPortEnable: - PortSC &= 0xfff5; - PortSC |= USBPORTSC_PED; - break; - - default: - gBS->RestoreTPL (OldTpl); - return EFI_INVALID_PARAMETER; - } - - UhciWriteReg (Uhc->PciIo, Offset, PortSC); - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; -} - - -/** - Clears a feature for the specified root hub port according to Uefi 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param PortNumber Specifies the root hub port whose feature is - requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. - - @return EFI_SUCCESS PortFeature was cleared for the USB root hub port. - @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @return EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -Uhci2ClearRootHubPortFeature ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - USB_HC_DEV *Uhc; - EFI_TPL OldTpl; - UINT32 Offset; - UINT16 PortSC; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - - if (PortNumber >= Uhc->RootPorts) { - return EFI_INVALID_PARAMETER; - } - - Offset = USBPORTSC_OFFSET + PortNumber * 2; - - OldTpl = gBS->RaiseTPL (UHCI_TPL); - PortSC = UhciReadReg (Uhc->PciIo, Offset); - - switch (PortFeature) { - case EfiUsbPortEnable: - PortSC &= 0xfff5; - PortSC &= ~USBPORTSC_PED; - break; - - case EfiUsbPortSuspend: - // - // Cause a resume on the specified port if in suspend mode. - // - PortSC &= 0xfff5; - PortSC &= ~USBPORTSC_SUSP; - break; - - case EfiUsbPortPower: - // - // No action - // - break; - - case EfiUsbPortReset: - PortSC &= 0xfff5; - PortSC &= ~USBPORTSC_PR; - break; - - case EfiUsbPortConnectChange: - PortSC &= 0xfff5; - PortSC |= USBPORTSC_CSC; - break; - - case EfiUsbPortEnableChange: - PortSC &= 0xfff5; - PortSC |= USBPORTSC_PEDC; - break; - - case EfiUsbPortSuspendChange: - // - // Root hub does not support this - // - break; - - case EfiUsbPortOverCurrentChange: - // - // Root hub does not support this - // - break; - - case EfiUsbPortResetChange: - // - // Root hub does not support this - // - break; - - default: - gBS->RestoreTPL (OldTpl); - return EFI_INVALID_PARAMETER; - } - - UhciWriteReg (Uhc->PciIo, Offset, PortSC); - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; -} - - -/** - Submits control transfer to a target USB device accroding to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param DeviceSpeed Device speed. - @param MaximumPacketLength Maximum packet size of the target endpoint. - @param Request USB device request to send. - @param TransferDirection Data direction of the Data stage in control transfer. - @param Data Data to transmit/receive in data stage. - @param DataLength Length of the data. - @param TimeOut Maximum time, in microseconds, for transfer to complete. - @param Translator Transaction translator to be used by this device. - @param TransferResult Variable to receive the transfer result. - - @return EFI_SUCCESS The control transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES Failed due to lack of resource. - @return EFI_INVALID_PARAMETER Some parameters are invalid. - @return EFI_TIMEOUT Failed due to timeout. - @return EFI_DEVICE_ERROR Failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -Uhci2ControlTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN EFI_USB_DEVICE_REQUEST *Request, - IN EFI_USB_DATA_DIRECTION TransferDirection, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - USB_HC_DEV *Uhc; - UHCI_TD_SW *TDs; - EFI_TPL OldTpl; - EFI_STATUS Status; - UHCI_QH_RESULT QhResult; - UINT8 PktId; - UINT8 *RequestPhy; - VOID *RequestMap; - UINT8 *DataPhy; - VOID *DataMap; - BOOLEAN IsSlowDevice; - UINTN TransferDataLength; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - TDs = NULL; - DataPhy = NULL; - DataMap = NULL; - RequestPhy = NULL; - RequestMap = NULL; - - IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE); - - // - // Parameters Checking - // - if (Request == NULL || TransferResult == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (IsSlowDevice && (MaximumPacketLength != 8)) { - return EFI_INVALID_PARAMETER; - } - - if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) && - (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) { - - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbNoData) && (Data == NULL || DataLength == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (TransferDirection == EfiUsbNoData) { - TransferDataLength = 0; - } else { - TransferDataLength = *DataLength; - } - - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_DEVICE_ERROR; - - // - // If errors exist that cause host controller halt, - // clear status then return EFI_DEVICE_ERROR. - // - UhciAckAllInterrupt (Uhc); - - if (!UhciIsHcWorking (Uhc->PciIo)) { - return EFI_DEVICE_ERROR; - } - - OldTpl = gBS->RaiseTPL (UHCI_TPL); - - // - // Map the Request and data for bus master access, - // then create a list of TD for this transfer - // - Status = UhciMapUserRequest (Uhc, Request, &RequestPhy, &RequestMap); - - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - Status = UhciMapUserData (Uhc, TransferDirection, Data, DataLength, &PktId, &DataPhy, &DataMap); - - if (EFI_ERROR (Status)) { - Uhc->PciIo->Unmap (Uhc->PciIo, RequestMap); - goto ON_EXIT; - } - - TDs = UhciCreateCtrlTds ( - Uhc, - DeviceAddress, - PktId, - (UINT8*)Request, - RequestPhy, - (UINT8*)Data, - DataPhy, - TransferDataLength, - (UINT8) MaximumPacketLength, - IsSlowDevice - ); - - if (TDs == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto UNMAP_DATA; - } - - // - // According to the speed of the end point, link - // the TD to corrosponding queue head, then check - // the execution result - // - UhciLinkTdToQh (Uhc, Uhc->CtrlQh, TDs); - Status = UhciExecuteTransfer (Uhc, Uhc->CtrlQh, TDs, TimeOut, IsSlowDevice, &QhResult); - UhciUnlinkTdFromQh (Uhc->CtrlQh, TDs); - - Uhc->PciIo->Flush (Uhc->PciIo); - - *TransferResult = QhResult.Result; - - if (DataLength != NULL) { - *DataLength = QhResult.Complete; - } - - UhciDestoryTds (Uhc, TDs); - -UNMAP_DATA: - Uhc->PciIo->Unmap (Uhc->PciIo, DataMap); - Uhc->PciIo->Unmap (Uhc->PciIo, RequestMap); - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Submits bulk transfer to a bulk endpoint of a USB device. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and direction. - @param DeviceSpeed Device speed. - @param MaximumPacketLength Maximum packet size of the target endpoint. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data. - @param DataLength On input, size of the data buffer, On output, - actually transferred data size. - @param DataToggle On input, data toggle to use; On output, next data toggle. - @param TimeOut Maximum time out, in microseconds. - @param Translator A pointr to the transaction translator data. - @param TransferResult Variable to receive transfer result. - - @return EFI_SUCCESS The bulk transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES Failed due to lack of resource. - @return EFI_INVALID_PARAMETER Some parameters are invalid. - @return EFI_TIMEOUT Failed due to timeout. - @return EFI_DEVICE_ERROR Failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -Uhci2BulkTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - EFI_USB_DATA_DIRECTION Direction; - EFI_TPL OldTpl; - USB_HC_DEV *Uhc; - UHCI_TD_SW *TDs; - UHCI_QH_SW *BulkQh; - UHCI_QH_RESULT QhResult; - EFI_STATUS Status; - UINT8 PktId; - UINT8 *DataPhy; - VOID *DataMap; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - DataPhy = NULL; - DataMap = NULL; - - if (DeviceSpeed == EFI_USB_SPEED_LOW) { - return EFI_INVALID_PARAMETER; - } - - if ((DataLength == NULL) || (*DataLength == 0) || (Data == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 1) && (*DataToggle != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) && - (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) { - return EFI_INVALID_PARAMETER; - } - - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_OUT_OF_RESOURCES; - - // - // If has errors that cause host controller halt, - // then return EFI_DEVICE_ERROR directly. - // - UhciAckAllInterrupt (Uhc); - - if (!UhciIsHcWorking (Uhc->PciIo)) { - return EFI_DEVICE_ERROR; - } - - OldTpl = gBS->RaiseTPL (UHCI_TPL); - - // - // Map the source data buffer for bus master access, - // then create a list of TDs - // - if ((EndPointAddress & 0x80) != 0) { - Direction = EfiUsbDataIn; - } else { - Direction = EfiUsbDataOut; - } - - Status = UhciMapUserData (Uhc, Direction, *Data, DataLength, &PktId, &DataPhy, &DataMap); - - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - Status = EFI_OUT_OF_RESOURCES; - TDs = UhciCreateBulkOrIntTds ( - Uhc, - DeviceAddress, - EndPointAddress, - PktId, - (UINT8 *)*Data, - DataPhy, - *DataLength, - DataToggle, - (UINT8) MaximumPacketLength, - FALSE - ); - - if (TDs == NULL) { - Uhc->PciIo->Unmap (Uhc->PciIo, DataMap); - goto ON_EXIT; - } - - - // - // Link the TDs to bulk queue head. According to the platfore - // defintion of UHCI_NO_BW_RECLAMATION, BulkQh is either configured - // to do full speed bandwidth reclamation or not. - // - BulkQh = Uhc->BulkQh; - - UhciLinkTdToQh (Uhc, BulkQh, TDs); - Status = UhciExecuteTransfer (Uhc, BulkQh, TDs, TimeOut, FALSE, &QhResult); - UhciUnlinkTdFromQh (BulkQh, TDs); - - Uhc->PciIo->Flush (Uhc->PciIo); - - *TransferResult = QhResult.Result; - *DataToggle = QhResult.NextToggle; - *DataLength = QhResult.Complete; - - UhciDestoryTds (Uhc, TDs); - Uhc->PciIo->Unmap (Uhc->PciIo, DataMap); - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Submits an asynchronous interrupt transfer to an - interrupt endpoint of a USB device according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and direction. - @param DeviceSpeed Device speed. - @param MaximumPacketLength Maximum packet size of the target endpoint. - @param IsNewTransfer If TRUE, submit a new transfer, if FALSE cancel old transfer. - @param DataToggle On input, data toggle to use; On output, next data toggle. - @param PollingInterval Interrupt poll rate in milliseconds. - @param DataLength On input, size of the data buffer, On output, - actually transferred data size. - @param Translator A pointr to the transaction translator data. - @param CallBackFunction Function to call periodically. - @param Context User context. - - @return EFI_SUCCESS Transfer was submitted. - @return EFI_INVALID_PARAMETER Some parameters are invalid. - @return EFI_OUT_OF_RESOURCES Failed due to a lack of resources. - @return EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -Uhci2AsyncInterruptTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN BOOLEAN IsNewTransfer, - IN OUT UINT8 *DataToggle, - IN UINTN PollingInterval, - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction, - IN VOID *Context - ) -{ - USB_HC_DEV *Uhc; - BOOLEAN IsSlowDevice; - UHCI_QH_SW *Qh; - UHCI_TD_SW *IntTds; - EFI_TPL OldTpl; - EFI_STATUS Status; - UINT8 *DataPtr; - UINT8 *DataPhy; - UINT8 PktId; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - Qh = NULL; - IntTds = NULL; - DataPtr = NULL; - DataPhy = NULL; - - IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE); - - if ((EndPointAddress & 0x80) == 0) { - return EFI_INVALID_PARAMETER; - } - - // - // Delete Async interrupt transfer request - // - if (!IsNewTransfer) { - OldTpl = gBS->RaiseTPL (UHCI_TPL); - Status = UhciRemoveAsyncReq (Uhc, DeviceAddress, EndPointAddress, DataToggle); - - gBS->RestoreTPL (OldTpl); - return Status; - } - - if (PollingInterval < 1 || PollingInterval > 255) { - return EFI_INVALID_PARAMETER; - } - - if (DataLength == 0) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 1) && (*DataToggle != 0)) { - return EFI_INVALID_PARAMETER; - } - - // - // If has errors that cause host controller halt, - // then return EFI_DEVICE_ERROR directly. - // - UhciAckAllInterrupt (Uhc); - - if (!UhciIsHcWorking (Uhc->PciIo)) { - return EFI_DEVICE_ERROR; - } - - if ((EndPointAddress & 0x80) == 0) { - PktId = OUTPUT_PACKET_ID; - } else { - PktId = INPUT_PACKET_ID; - } - - // - // Allocate and map source data buffer for bus master access. - // - DataPtr = UsbHcAllocateMem (Uhc->MemPool, DataLength); - - if (DataPtr == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - DataPhy = (UINT8 *) (UINTN) UsbHcGetPciAddressForHostMem (Uhc->MemPool, DataPtr, DataLength); - - OldTpl = gBS->RaiseTPL (UHCI_TPL); - - Qh = UhciCreateQh (Uhc, PollingInterval); - - if (Qh == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto FREE_DATA; - } - - IntTds = UhciCreateBulkOrIntTds ( - Uhc, - DeviceAddress, - EndPointAddress, - PktId, - DataPtr, - DataPhy, - DataLength, - DataToggle, - (UINT8) MaximumPacketLength, - IsSlowDevice - ); - - if (IntTds == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto DESTORY_QH; - } - - UhciLinkTdToQh (Uhc, Qh, IntTds); - - // - // Save QH-TD structures to async Interrupt transfer list, - // for monitor interrupt transfer execution routine use. - // - Status = UhciCreateAsyncReq ( - Uhc, - Qh, - IntTds, - DeviceAddress, - EndPointAddress, - DataLength, - PollingInterval, - DataPtr, - CallBackFunction, - Context, - IsSlowDevice - ); - - if (EFI_ERROR (Status)) { - goto DESTORY_QH; - } - - UhciLinkQhToFrameList (Uhc, Qh); - - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; - -DESTORY_QH: - UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW)); - -FREE_DATA: - UsbHcFreeMem (Uhc->MemPool, DataPtr, DataLength); - Uhc->PciIo->Flush (Uhc->PciIo); - - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Submits synchronous interrupt transfer to an interrupt endpoint - of a USB device according to UEFI 2.0 spec. - - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and direction. - @param DeviceSpeed Device speed. - @param MaximumPacketLength Maximum packet size of the target endpoint. - @param Data Array of pointers to the buffers of data. - @param DataLength On input, size of the data buffer, On output, - actually transferred data size. - @param DataToggle On input, data toggle to use; On output, next data toggle. - @param TimeOut Maximum time out, in microseconds. - @param Translator A pointr to the transaction translator data. - @param TransferResult Variable to receive transfer result. - - @return EFI_SUCCESS The transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES Failed due to lack of resource. - @return EFI_INVALID_PARAMETER Some parameters are invalid. - @return EFI_TIMEOUT Failed due to timeout. - @return EFI_DEVICE_ERROR Failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -Uhci2SyncInterruptTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - EFI_STATUS Status; - USB_HC_DEV *Uhc; - UHCI_TD_SW *TDs; - UHCI_QH_RESULT QhResult; - EFI_TPL OldTpl; - UINT8 *DataPhy; - VOID *DataMap; - UINT8 PktId; - BOOLEAN IsSlowDevice; - - Uhc = UHC_FROM_USB2_HC_PROTO (This); - DataPhy = NULL; - DataMap = NULL; - TDs = NULL; - - if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - return EFI_INVALID_PARAMETER; - } - - IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE); - - if ((DataLength == NULL) || (Data == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 1) && (*DataToggle != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataLength == 0) || (MaximumPacketLength > 64)) { - return EFI_INVALID_PARAMETER; - } - - if (IsSlowDevice && (MaximumPacketLength > 8)) { - return EFI_INVALID_PARAMETER; - } - - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_DEVICE_ERROR; - - - UhciAckAllInterrupt (Uhc); - - if (!UhciIsHcWorking (Uhc->PciIo)) { - return Status; - } - - OldTpl = gBS->RaiseTPL (UHCI_TPL); - - // - // Map the source data buffer for bus master access. - // Create Tds list, then link it to the UHC's interrupt list - // - Status = UhciMapUserData ( - Uhc, - EfiUsbDataIn, - Data, - DataLength, - &PktId, - &DataPhy, - &DataMap - ); - - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - TDs = UhciCreateBulkOrIntTds ( - Uhc, - DeviceAddress, - EndPointAddress, - PktId, - (UINT8 *)Data, - DataPhy, - *DataLength, - DataToggle, - (UINT8) MaximumPacketLength, - IsSlowDevice - ); - - if (TDs == NULL) { - Uhc->PciIo->Unmap (Uhc->PciIo, DataMap); - - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - - UhciLinkTdToQh (Uhc, Uhc->SyncIntQh, TDs); - - Status = UhciExecuteTransfer (Uhc, Uhc->SyncIntQh, TDs, TimeOut, IsSlowDevice, &QhResult); - - UhciUnlinkTdFromQh (Uhc->SyncIntQh, TDs); - Uhc->PciIo->Flush (Uhc->PciIo); - - *TransferResult = QhResult.Result; - *DataToggle = QhResult.NextToggle; - *DataLength = QhResult.Complete; - - UhciDestoryTds (Uhc, TDs); - Uhc->PciIo->Unmap (Uhc->PciIo, DataMap); - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Submits isochronous transfer to a target USB device according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and direction. - @param DeviceSpeed Device speed. - @param MaximumPacketLength Maximum packet size of the target endpoint. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data. - @param DataLength On input, size of the data buffer, On output, - actually transferred data size. - @param Translator A pointr to the transaction translator data. - @param TransferResult Variable to receive transfer result. - - @return EFI_UNSUPPORTED - -**/ -EFI_STATUS -EFIAPI -Uhci2IsochronousTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - return EFI_UNSUPPORTED; -} - - -/** - Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and direction. - @param DeviceSpeed Device speed. - @param MaximumPacketLength Maximum packet size of the target endpoint. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data. - @param DataLength On input, size of the data buffer, On output, - actually transferred data size. - @param Translator A pointr to the transaction translator data. - @param IsochronousCallBack Function to call when the transfer complete. - @param Context Pass to the call back function as parameter. - - @return EFI_UNSUPPORTED - -**/ -EFI_STATUS -EFIAPI -Uhci2AsyncIsochronousTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, - IN VOID *Context - ) -{ - return EFI_UNSUPPORTED; -} - -/** - Entry point for EFI drivers. - - @param ImageHandle EFI_HANDLE. - @param SystemTable EFI_SYSTEM_TABLE. - - @retval EFI_SUCCESS Driver is successfully loaded. - @return Others Failed. - -**/ -EFI_STATUS -EFIAPI -UhciDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gUhciDriverBinding, - ImageHandle, - &gUhciComponentName, - &gUhciComponentName2 - ); -} - - -/** - Test to see if this driver supports ControllerHandle. Any - ControllerHandle that has UsbHcProtocol installed will be supported. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS This driver supports this device. - @return EFI_UNSUPPORTED This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -UhciDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS OpenStatus; - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - USB_CLASSC UsbClassCReg; - - // - // Test whether there is PCI IO Protocol attached on the controller handle. - // - OpenStatus = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (OpenStatus)) { - return OpenStatus; - } - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_CLASSCODE_OFFSET, - sizeof (USB_CLASSC) / sizeof (UINT8), - &UsbClassCReg - ); - - if (EFI_ERROR (Status)) { - Status = EFI_UNSUPPORTED; - goto ON_EXIT; - } - - // - // Test whether the controller belongs to UHCI type - // - if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || - (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) || - (UsbClassCReg.ProgInterface != PCI_IF_UHCI) - ) { - - Status = EFI_UNSUPPORTED; - } - -ON_EXIT: - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; - -} - - -/** - Allocate and initialize the empty UHCI device. - - @param PciIo The PCIIO to use. - @param DevicePath The device path of host controller. - @param OriginalPciAttributes The original PCI attributes. - - @return Allocated UHCI device. If err, return NULL. - -**/ -USB_HC_DEV * -UhciAllocateDev ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN UINT64 OriginalPciAttributes - ) -{ - USB_HC_DEV *Uhc; - EFI_STATUS Status; - - Uhc = AllocateZeroPool (sizeof (USB_HC_DEV)); - - if (Uhc == NULL) { - return NULL; - } - - // - // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL. - // USB_HC_PROTOCOL is for EFI 1.1 backward compability. - // - Uhc->Signature = USB_HC_DEV_SIGNATURE; - Uhc->Usb2Hc.GetCapability = Uhci2GetCapability; - Uhc->Usb2Hc.Reset = Uhci2Reset; - Uhc->Usb2Hc.GetState = Uhci2GetState; - Uhc->Usb2Hc.SetState = Uhci2SetState; - Uhc->Usb2Hc.ControlTransfer = Uhci2ControlTransfer; - Uhc->Usb2Hc.BulkTransfer = Uhci2BulkTransfer; - Uhc->Usb2Hc.AsyncInterruptTransfer = Uhci2AsyncInterruptTransfer; - Uhc->Usb2Hc.SyncInterruptTransfer = Uhci2SyncInterruptTransfer; - Uhc->Usb2Hc.IsochronousTransfer = Uhci2IsochronousTransfer; - Uhc->Usb2Hc.AsyncIsochronousTransfer = Uhci2AsyncIsochronousTransfer; - Uhc->Usb2Hc.GetRootHubPortStatus = Uhci2GetRootHubPortStatus; - Uhc->Usb2Hc.SetRootHubPortFeature = Uhci2SetRootHubPortFeature; - Uhc->Usb2Hc.ClearRootHubPortFeature = Uhci2ClearRootHubPortFeature; - Uhc->Usb2Hc.MajorRevision = 0x1; - Uhc->Usb2Hc.MinorRevision = 0x1; - - Uhc->PciIo = PciIo; - Uhc->DevicePath = DevicePath; - Uhc->OriginalPciAttributes = OriginalPciAttributes; - Uhc->MemPool = UsbHcInitMemPool (PciIo, TRUE, 0); - - if (Uhc->MemPool == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; - } - - InitializeListHead (&Uhc->AsyncIntList); - - Status = gBS->CreateEvent ( - EVT_TIMER | EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - UhciMonitorAsyncReqList, - Uhc, - &Uhc->AsyncIntMonitor - ); - - if (EFI_ERROR (Status)) { - UsbHcFreeMemPool (Uhc->MemPool); - goto ON_ERROR; - } - - return Uhc; - -ON_ERROR: - FreePool (Uhc); - return NULL; -} - - -/** - Free the UHCI device and release its associated resources. - - @param Uhc The UHCI device to release. - -**/ -VOID -UhciFreeDev ( - IN USB_HC_DEV *Uhc - ) -{ - if (Uhc->AsyncIntMonitor != NULL) { - gBS->CloseEvent (Uhc->AsyncIntMonitor); - } - - if (Uhc->ExitBootServiceEvent != NULL) { - gBS->CloseEvent (Uhc->ExitBootServiceEvent); - } - - if (Uhc->MemPool != NULL) { - UsbHcFreeMemPool (Uhc->MemPool); - } - - if (Uhc->CtrlNameTable != NULL) { - FreeUnicodeStringTable (Uhc->CtrlNameTable); - } - - FreePool (Uhc); -} - - -/** - Uninstall all Uhci Interface. - - @param Controller Controller handle. - @param This Protocol instance pointer. - -**/ -VOID -UhciCleanDevUp ( - IN EFI_HANDLE Controller, - IN EFI_USB2_HC_PROTOCOL *This - ) -{ - USB_HC_DEV *Uhc; - EFI_STATUS Status; - - // - // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller - // - Uhc = UHC_FROM_USB2_HC_PROTO (This); - - - Status = gBS->UninstallProtocolInterface ( - Controller, - &gEfiUsb2HcProtocolGuid, - &Uhc->Usb2Hc - ); - if (EFI_ERROR (Status)) { - return ; - } - - UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT); - UhciFreeAllAsyncReq (Uhc); - UhciDestoryFrameList (Uhc); - - // - // Restore original PCI attributes - // - Uhc->PciIo->Attributes ( - Uhc->PciIo, - EfiPciIoAttributeOperationSet, - Uhc->OriginalPciAttributes, - NULL - ); - - UhciFreeDev (Uhc); -} - -/** - One notified function to stop the Host Controller when gBS->ExitBootServices() called. - - @param Event Pointer to this event - @param Context Event handler private data - -**/ -VOID -EFIAPI -UhcExitBootService ( - EFI_EVENT Event, - VOID *Context - ) -{ - USB_HC_DEV *Uhc; - - Uhc = (USB_HC_DEV *) Context; - - // - // Stop the Host Controller - // - UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT); - - // - // Reset the Host Controller - // - UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET); - gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL); -} - -/** - Starting the Usb UHCI Driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @retval EFI_SUCCESS This driver supports this device. - @retval EFI_UNSUPPORTED This driver does not support this device. - @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error. - EFI_OUT_OF_RESOURCES- Failed due to resource shortage. - -**/ -EFI_STATUS -EFIAPI -UhciDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - USB_HC_DEV *Uhc; - UINT64 Supports; - UINT64 OriginalPciAttributes; - BOOLEAN PciAttributesSaved; - EFI_DEVICE_PATH_PROTOCOL *HcDevicePath; - - // - // Open PCIIO, then enable the EHC device and turn off emulation - // - Uhc = NULL; - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Open Device Path Protocol for on USB host controller - // - HcDevicePath = NULL; - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &HcDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - PciAttributesSaved = FALSE; - // - // Save original PCI attributes - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationGet, - 0, - &OriginalPciAttributes - ); - - if (EFI_ERROR (Status)) { - goto CLOSE_PCIIO; - } - PciAttributesSaved = TRUE; - - // - // Robustnesss improvement such as for UoL - // Default is not required. - // - if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) { - UhciTurnOffUsbEmulation (PciIo); - } - - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - - if (EFI_ERROR (Status)) { - goto CLOSE_PCIIO; - } - - Uhc = UhciAllocateDev (PciIo, HcDevicePath, OriginalPciAttributes); - - if (Uhc == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto CLOSE_PCIIO; - } - - // - // Allocate and Init Host Controller's Frame List Entry - // - Status = UhciInitFrameList (Uhc); - - if (EFI_ERROR (Status)) { - Status = EFI_OUT_OF_RESOURCES; - goto FREE_UHC; - } - - Status = gBS->SetTimer ( - Uhc->AsyncIntMonitor, - TimerPeriodic, - UHC_ASYNC_POLL_INTERVAL - ); - - if (EFI_ERROR (Status)) { - goto FREE_UHC; - } - - // - // Install USB2_HC_PROTOCOL - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &Controller, - &gEfiUsb2HcProtocolGuid, - &Uhc->Usb2Hc, - NULL - ); - - if (EFI_ERROR (Status)) { - goto FREE_UHC; - } - - // - // Create event to stop the HC when exit boot service. - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - UhcExitBootService, - Uhc, - &gEfiEventExitBootServicesGuid, - &Uhc->ExitBootServiceEvent - ); - if (EFI_ERROR (Status)) { - goto UNINSTALL_USBHC; - } - - // - // Install the component name protocol - // - Uhc->CtrlNameTable = NULL; - - AddUnicodeString2 ( - "eng", - gUhciComponentName.SupportedLanguages, - &Uhc->CtrlNameTable, - L"Usb Universal Host Controller", - TRUE - ); - AddUnicodeString2 ( - "en", - gUhciComponentName2.SupportedLanguages, - &Uhc->CtrlNameTable, - L"Usb Universal Host Controller", - FALSE - ); - - - // - // Start the UHCI hardware, also set its reclamation point to 64 bytes - // - UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, USBCMD_RS | USBCMD_MAXP); - - return EFI_SUCCESS; - -UNINSTALL_USBHC: - gBS->UninstallMultipleProtocolInterfaces ( - Controller, - &gEfiUsb2HcProtocolGuid, - &Uhc->Usb2Hc, - NULL - ); - -FREE_UHC: - UhciFreeDev (Uhc); - -CLOSE_PCIIO: - if (PciAttributesSaved) { - // - // Restore original PCI attributes - // - PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSet, - OriginalPciAttributes, - NULL - ); - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; -} - - -/** - Stop this driver on ControllerHandle. Support stoping any child handles - created by this driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on. - @param NumberOfChildren Number of Children in the ChildHandleBuffer. - @param ChildHandleBuffer List of handles for the children we need to stop. - - @return EFI_SUCCESS - @return others - -**/ -EFI_STATUS -EFIAPI -UhciDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_USB2_HC_PROTOCOL *Usb2Hc; - EFI_STATUS Status; - - Status = gBS->OpenProtocol ( - Controller, - &gEfiUsb2HcProtocolGuid, - (VOID **) &Usb2Hc, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - // - // Test whether the Controller handler passed in is a valid - // Usb controller handle that should be supported, if not, - // return the error status directly - // - if (EFI_ERROR (Status)) { - return Status; - } - - UhciCleanDevUp (Controller, Usb2Hc); - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return EFI_SUCCESS; -} - diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h deleted file mode 100644 index 8635d8231c..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h +++ /dev/null @@ -1,221 +0,0 @@ -/** @file - - The definition for UHCI driver model and HC protocol routines. - -Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_UHCI_H_ -#define _EFI_UHCI_H_ - - -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef struct _USB_HC_DEV USB_HC_DEV; - -#include "UsbHcMem.h" -#include "UhciQueue.h" -#include "UhciReg.h" -#include "UhciSched.h" -#include "UhciDebug.h" -#include "ComponentName.h" - -// -// UHC timeout experience values -// - -#define UHC_1_MICROSECOND 1 -#define UHC_1_MILLISECOND (1000 * UHC_1_MICROSECOND) -#define UHC_1_SECOND (1000 * UHC_1_MILLISECOND) - -// -// UHCI register operation timeout, set by experience -// -#define UHC_GENERIC_TIMEOUT UHC_1_SECOND - -// -// Wait for force global resume(FGR) complete, refers to -// specification[UHCI11-2.1.1] -// -#define UHC_FORCE_GLOBAL_RESUME_STALL (20 * UHC_1_MILLISECOND) - -// -// Wait for roothub port reset and recovery, reset stall -// is set by experience, and recovery stall refers to -// specification[UHCI11-2.1.1] -// -#define UHC_ROOT_PORT_RESET_STALL (50 * UHC_1_MILLISECOND) -#define UHC_ROOT_PORT_RECOVERY_STALL (10 * UHC_1_MILLISECOND) - -// -// Sync and Async transfer polling interval, set by experience, -// and the unit of Async is 100us. -// -#define UHC_SYNC_POLL_INTERVAL (1 * UHC_1_MILLISECOND) -#define UHC_ASYNC_POLL_INTERVAL EFI_TIMER_PERIOD_MILLISECONDS(1) - -// -// UHC raises TPL to TPL_NOTIFY to serialize all its operations -// to protect shared data structures. -// -#define UHCI_TPL TPL_NOTIFY - -#define USB_HC_DEV_SIGNATURE SIGNATURE_32 ('u', 'h', 'c', 'i') - -#pragma pack(1) -typedef struct { - UINT8 ProgInterface; - UINT8 SubClassCode; - UINT8 BaseCode; -} USB_CLASSC; -#pragma pack() - -#define UHC_FROM_USB2_HC_PROTO(This) CR(This, USB_HC_DEV, Usb2Hc, USB_HC_DEV_SIGNATURE) - -// -// USB_HC_DEV support the UHCI hardware controller. It schedules -// the asynchronous interrupt transfer with the same method as -// EHCI: a reversed tree structure. For synchronous interrupt, -// control and bulk transfer, it uses three static queue head to -// schedule them. SyncIntQh is for interrupt transfer. LsCtrlQh is -// for LOW speed control transfer, and FsCtrlBulkQh is for FULL -// speed control or bulk transfer. This is because FULL speed contrl -// or bulk transfer can reclaim the unused bandwidth. Some USB -// device requires this bandwidth reclamation capability. -// -struct _USB_HC_DEV { - UINT32 Signature; - EFI_USB2_HC_PROTOCOL Usb2Hc; - EFI_PCI_IO_PROTOCOL *PciIo; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UINT64 OriginalPciAttributes; - - // - // Schedule data structures - // - UINT32 *FrameBase; // the buffer pointed by this pointer is used to store pci bus address of the QH descriptor. - UINT32 *FrameBaseHostAddr; // the buffer pointed by this pointer is used to store host memory address of the QH descriptor. - UHCI_QH_SW *SyncIntQh; - UHCI_QH_SW *CtrlQh; - UHCI_QH_SW *BulkQh; - - // - // Structures to maintain asynchronus interrupt transfers. - // When asynchronous interrutp transfer is unlinked from - // the frame list, the hardware may still hold a pointer - // to it. To synchronize with hardware, its resoureces are - // released in two steps using Recycle and RecycleWait. - // Check the asynchronous interrupt management routines. - // - LIST_ENTRY AsyncIntList; - EFI_EVENT AsyncIntMonitor; - UHCI_ASYNC_REQUEST *Recycle; - UHCI_ASYNC_REQUEST *RecycleWait; - - - UINTN RootPorts; - USBHC_MEM_POOL *MemPool; - EFI_UNICODE_STRING_TABLE *CtrlNameTable; - VOID *FrameMapping; - - // - // ExitBootServicesEvent is used to stop the EHC DMA operation - // after exit boot service. - // - EFI_EVENT ExitBootServiceEvent; -}; - -extern EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gUhciComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gUhciComponentName2; - -/** - Test to see if this driver supports ControllerHandle. Any - ControllerHandle that has UsbHcProtocol installed will be supported. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS This driver supports this device. - @return EFI_UNSUPPORTED This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -UhciDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Starting the Usb UHCI Driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @retval EFI_SUCCESS This driver supports this device. - @retval EFI_UNSUPPORTED This driver does not support this device. - @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error. - EFI_OUT_OF_RESOURCES- Failed due to resource shortage. - -**/ -EFI_STATUS -EFIAPI -UhciDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stop this driver on ControllerHandle. Support stoping any child handles - created by this driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on. - @param NumberOfChildren Number of Children in the ChildHandleBuffer. - @param ChildHandleBuffer List of handles for the children we need to stop. - - @return EFI_SUCCESS - @return others - -**/ -EFI_STATUS -EFIAPI -UhciDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.c b/MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.c deleted file mode 100644 index 9bf53fd411..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.c +++ /dev/null @@ -1,77 +0,0 @@ -/** @file - - This file provides the information dump support for Uhci when in debug mode. - -Copyright (c) 2007, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Uhci.h" - -/** - Dump the content of QH structure. - - @param QhSw Pointer to software QH structure. - -**/ -VOID -UhciDumpQh ( - IN UHCI_QH_SW *QhSw - ) -{ - DEBUG ((EFI_D_VERBOSE, "&QhSw @ 0x%p\n", QhSw)); - DEBUG ((EFI_D_VERBOSE, "QhSw.NextQh - 0x%p\n", QhSw->NextQh)); - DEBUG ((EFI_D_VERBOSE, "QhSw.TDs - 0x%p\n", QhSw->TDs)); - DEBUG ((EFI_D_VERBOSE, "QhSw.QhHw:\n")); - DEBUG ((EFI_D_VERBOSE, " Horizon Link - %x\n", QhSw->QhHw.HorizonLink)); - DEBUG ((EFI_D_VERBOSE, " Vertical Link - %x\n\n", QhSw->QhHw.VerticalLink)); -} - - -/** - Dump the content of TD structure. - - @param TdSw Pointer to software TD structure. - -**/ -VOID -UhciDumpTds ( - IN UHCI_TD_SW *TdSw - ) -{ - UHCI_TD_SW *CurTdSw; - - CurTdSw = TdSw; - - while (CurTdSw != NULL) { - DEBUG ((EFI_D_VERBOSE, "TdSw @ 0x%p\n", CurTdSw)); - DEBUG ((EFI_D_VERBOSE, "TdSw.NextTd - 0x%p\n", CurTdSw->NextTd)); - DEBUG ((EFI_D_VERBOSE, "TdSw.DataLen - %d\n", CurTdSw->DataLen)); - DEBUG ((EFI_D_VERBOSE, "TdSw.Data - 0x%p\n", CurTdSw->Data)); - DEBUG ((EFI_D_VERBOSE, "TdHw:\n")); - DEBUG ((EFI_D_VERBOSE, " NextLink - 0x%x\n", CurTdSw->TdHw.NextLink)); - DEBUG ((EFI_D_VERBOSE, " ActualLen - %d\n", CurTdSw->TdHw.ActualLen)); - DEBUG ((EFI_D_VERBOSE, " Status - 0x%x\n", CurTdSw->TdHw.Status)); - DEBUG ((EFI_D_VERBOSE, " IOC - %d\n", CurTdSw->TdHw.IntOnCpl)); - DEBUG ((EFI_D_VERBOSE, " IsIsoCh - %d\n", CurTdSw->TdHw.IsIsoch)); - DEBUG ((EFI_D_VERBOSE, " LowSpeed - %d\n", CurTdSw->TdHw.LowSpeed)); - DEBUG ((EFI_D_VERBOSE, " ErrorCount - %d\n", CurTdSw->TdHw.ErrorCount)); - DEBUG ((EFI_D_VERBOSE, " ShortPacket - %d\n", CurTdSw->TdHw.ShortPacket)); - DEBUG ((EFI_D_VERBOSE, " PidCode - 0x%x\n", CurTdSw->TdHw.PidCode)); - DEBUG ((EFI_D_VERBOSE, " DevAddr - %d\n", CurTdSw->TdHw.DeviceAddr)); - DEBUG ((EFI_D_VERBOSE, " EndPoint - %d\n", CurTdSw->TdHw.EndPoint)); - DEBUG ((EFI_D_VERBOSE, " DataToggle - %d\n", CurTdSw->TdHw.DataToggle)); - DEBUG ((EFI_D_VERBOSE, " MaxPacketLen - %d\n", CurTdSw->TdHw.MaxPacketLen)); - DEBUG ((EFI_D_VERBOSE, " DataBuffer - 0x%x\n\n",CurTdSw->TdHw.DataBuffer)); - - CurTdSw = CurTdSw->NextTd; - } -} - diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.h b/MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.h deleted file mode 100644 index abdb64fa36..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDebug.h +++ /dev/null @@ -1,47 +0,0 @@ -/** @file - - This file contains the definination for host controller debug support routines - -Copyright (c) 2007, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_UHCI_DEBUG_H_ -#define _EFI_UHCI_DEBUG_H_ - - -/** - Dump the content of QH structure. - - @param QhSw Pointer to software QH structure. - - @return None. - -**/ -VOID -UhciDumpQh ( - IN UHCI_QH_SW *QhSw - ); - - -/** - Dump the content of TD structure. - - @param TdSw Pointer to software TD structure. - - @return None. - -**/ -VOID -UhciDumpTds ( - IN UHCI_TD_SW *TdSw - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf b/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf deleted file mode 100644 index 9c5ff7b6fc..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf +++ /dev/null @@ -1,86 +0,0 @@ -## @file -# The UhciDxe driver is responsible for managing the behavior of UHCI controller. -# It implements the interfaces of monitoring the status of all ports and transferring -# Control, Bulk, Interrupt and Isochronous requests to Usb1.x device -# -# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = UhciDxe - MODULE_UNI_FILE = UhciDxe.uni - FILE_GUID = 2FB92EFA-2EE0-4bae-9EB6-7464125E1EF7 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = UhciDriverEntryPoint - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64 -# -# DRIVER_BINDING = gUhciDriverBinding -# COMPONENT_NAME = gUhciComponentName -# COMPONENT_NAME2 = gUhciComponentName2 -# - -[Sources] - UhciSched.c - UhciDebug.c - UsbHcMem.h - UhciDebug.h - UhciQueue.c - UhciReg.c - UsbHcMem.c - UhciQueue.h - Uhci.c - Uhci.h - UhciReg.h - UhciSched.h - ComponentName.c - ComponentName.h - - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport ## CONSUMES - -[LibraryClasses] - MemoryAllocationLib - BaseLib - UefiLib - UefiBootServicesTableLib - UefiDriverEntryPoint - BaseMemoryLib - DebugLib - PcdLib - ReportStatusCodeLib - -[Guids] - gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event - -[Protocols] - gEfiPciIoProtocolGuid ## TO_START - gEfiUsb2HcProtocolGuid ## BY_START - -# [Event] -# EVENT_TYPE_PERIODIC_TIMER ## CONSUMES -# - -[UserExtensions.TianoCore."ExtraFiles"] - UhciDxeExtra.uni diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.uni b/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.uni deleted file mode 100644 index d011d39f1c..0000000000 Binary files a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxeExtra.uni b/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxeExtra.uni deleted file mode 100644 index 71d9f6cf77..0000000000 Binary files a/MdeModulePkg/Bus/Pci/UhciDxe/UhciDxeExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.c b/MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.c deleted file mode 100644 index 1a0aa6e636..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.c +++ /dev/null @@ -1,707 +0,0 @@ -/** @file - - The UHCI register operation routines. - -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Uhci.h" - - -/** - Map address of request structure buffer. - - @param Uhc The UHCI device. - @param Request The user request buffer. - @param MappedAddr Mapped address of request. - @param Map Identificaion of this mapping to return. - - @return EFI_SUCCESS Success. - @return EFI_DEVICE_ERROR Fail to map the user request. - -**/ -EFI_STATUS -UhciMapUserRequest ( - IN USB_HC_DEV *Uhc, - IN OUT VOID *Request, - OUT UINT8 **MappedAddr, - OUT VOID **Map - ) -{ - EFI_STATUS Status; - UINTN Len; - EFI_PHYSICAL_ADDRESS PhyAddr; - - Len = sizeof (EFI_USB_DEVICE_REQUEST); - Status = Uhc->PciIo->Map ( - Uhc->PciIo, - EfiPciIoOperationBusMasterRead, - Request, - &Len, - &PhyAddr, - Map - ); - - if (!EFI_ERROR (Status)) { - *MappedAddr = (UINT8 *) (UINTN) PhyAddr; - } - - return Status; -} - - -/** - Map address of user data buffer. - - @param Uhc The UHCI device. - @param Direction Direction of the data transfer. - @param Data The user data buffer. - @param Len Length of the user data. - @param PktId Packet identificaion. - @param MappedAddr Mapped address to return. - @param Map Identificaion of this mapping to return. - - @return EFI_SUCCESS Success. - @return EFI_DEVICE_ERROR Fail to map the user data. - -**/ -EFI_STATUS -UhciMapUserData ( - IN USB_HC_DEV *Uhc, - IN EFI_USB_DATA_DIRECTION Direction, - IN VOID *Data, - IN OUT UINTN *Len, - OUT UINT8 *PktId, - OUT UINT8 **MappedAddr, - OUT VOID **Map - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS PhyAddr; - - Status = EFI_SUCCESS; - - switch (Direction) { - case EfiUsbDataIn: - // - // BusMasterWrite means cpu read - // - *PktId = INPUT_PACKET_ID; - Status = Uhc->PciIo->Map ( - Uhc->PciIo, - EfiPciIoOperationBusMasterWrite, - Data, - Len, - &PhyAddr, - Map - ); - - if (EFI_ERROR (Status)) { - goto EXIT; - } - - *MappedAddr = (UINT8 *) (UINTN) PhyAddr; - break; - - case EfiUsbDataOut: - *PktId = OUTPUT_PACKET_ID; - Status = Uhc->PciIo->Map ( - Uhc->PciIo, - EfiPciIoOperationBusMasterRead, - Data, - Len, - &PhyAddr, - Map - ); - - if (EFI_ERROR (Status)) { - goto EXIT; - } - - *MappedAddr = (UINT8 *) (UINTN) PhyAddr; - break; - - case EfiUsbNoData: - if ((Len != NULL) && (*Len != 0)) { - Status = EFI_INVALID_PARAMETER; - goto EXIT; - } - - *PktId = OUTPUT_PACKET_ID; - *MappedAddr = NULL; - *Map = NULL; - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - -EXIT: - return Status; -} - - -/** - Link the TD To QH. - - @param Uhc The UHCI device. - @param Qh The queue head for the TD to link to. - @param Td The TD to link. - -**/ -VOID -UhciLinkTdToQh ( - IN USB_HC_DEV *Uhc, - IN UHCI_QH_SW *Qh, - IN UHCI_TD_SW *Td - ) -{ - EFI_PHYSICAL_ADDRESS PhyAddr; - - PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Td, sizeof (UHCI_TD_HW)); - - ASSERT ((Qh != NULL) && (Td != NULL)); - - Qh->QhHw.VerticalLink = QH_VLINK (PhyAddr, FALSE); - Qh->TDs = (VOID *) Td; -} - - -/** - Unlink TD from the QH. - - @param Qh The queue head to unlink from. - @param Td The TD to unlink. - -**/ -VOID -UhciUnlinkTdFromQh ( - IN UHCI_QH_SW *Qh, - IN UHCI_TD_SW *Td - ) -{ - ASSERT ((Qh != NULL) && (Td != NULL)); - - Qh->QhHw.VerticalLink = QH_VLINK (NULL, TRUE); - Qh->TDs = NULL; -} - - -/** - Append a new TD To the previous TD. - - @param Uhc The UHCI device. - @param PrevTd Previous UHCI_TD_SW to be linked to. - @param ThisTd TD to link. - -**/ -VOID -UhciAppendTd ( - IN USB_HC_DEV *Uhc, - IN UHCI_TD_SW *PrevTd, - IN UHCI_TD_SW *ThisTd - ) -{ - EFI_PHYSICAL_ADDRESS PhyAddr; - - PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, ThisTd, sizeof (UHCI_TD_HW)); - - ASSERT ((PrevTd != NULL) && (ThisTd != NULL)); - - PrevTd->TdHw.NextLink = TD_LINK (PhyAddr, TRUE, FALSE); - PrevTd->NextTd = (VOID *) ThisTd; -} - - -/** - Delete a list of TDs. - - @param Uhc The UHCI device. - @param FirstTd TD link list head. - - @return None. - -**/ -VOID -UhciDestoryTds ( - IN USB_HC_DEV *Uhc, - IN UHCI_TD_SW *FirstTd - ) -{ - UHCI_TD_SW *NextTd; - UHCI_TD_SW *ThisTd; - - NextTd = FirstTd; - - while (NextTd != NULL) { - ThisTd = NextTd; - NextTd = ThisTd->NextTd; - UsbHcFreeMem (Uhc->MemPool, ThisTd, sizeof (UHCI_TD_SW)); - } -} - - -/** - Create an initialize a new queue head. - - @param Uhc The UHCI device. - @param Interval The polling interval for the queue. - - @return The newly created queue header. - -**/ -UHCI_QH_SW * -UhciCreateQh ( - IN USB_HC_DEV *Uhc, - IN UINTN Interval - ) -{ - UHCI_QH_SW *Qh; - - Qh = UsbHcAllocateMem (Uhc->MemPool, sizeof (UHCI_QH_SW)); - - if (Qh == NULL) { - return NULL; - } - - Qh->QhHw.HorizonLink = QH_HLINK (NULL, TRUE); - Qh->QhHw.VerticalLink = QH_VLINK (NULL, TRUE); - Qh->Interval = UhciConvertPollRate(Interval); - Qh->TDs = NULL; - Qh->NextQh = NULL; - - return Qh; -} - - -/** - Create and intialize a TD. - - @param Uhc The UHCI device. - - @return The newly allocated and initialized TD. - -**/ -UHCI_TD_SW * -UhciCreateTd ( - IN USB_HC_DEV *Uhc - ) -{ - UHCI_TD_SW *Td; - - Td = UsbHcAllocateMem (Uhc->MemPool, sizeof (UHCI_TD_SW)); - if (Td == NULL) { - return NULL; - } - - Td->TdHw.NextLink = TD_LINK (NULL, FALSE, TRUE); - Td->NextTd = NULL; - Td->Data = NULL; - Td->DataLen = 0; - - return Td; -} - - -/** - Create and initialize a TD for Setup Stage of a control transfer. - - @param Uhc The UHCI device. - @param DevAddr Device address. - @param Request A pointer to cpu memory address of Device request. - @param RequestPhy A pointer to pci memory address of Device request. - @param IsLow Full speed or low speed. - - @return The created setup Td Pointer. - -**/ -UHCI_TD_SW * -UhciCreateSetupTd ( - IN USB_HC_DEV *Uhc, - IN UINT8 DevAddr, - IN UINT8 *Request, - IN UINT8 *RequestPhy, - IN BOOLEAN IsLow - ) -{ - UHCI_TD_SW *Td; - - Td = UhciCreateTd (Uhc); - - if (Td == NULL) { - return NULL; - } - - Td->TdHw.NextLink = TD_LINK (NULL, TRUE, TRUE); - Td->TdHw.ShortPacket = FALSE; - Td->TdHw.IsIsoch = FALSE; - Td->TdHw.IntOnCpl = FALSE; - Td->TdHw.ErrorCount = 0x03; - Td->TdHw.Status |= USBTD_ACTIVE; - Td->TdHw.DataToggle = 0; - Td->TdHw.EndPoint = 0; - Td->TdHw.LowSpeed = IsLow ? 1 : 0; - Td->TdHw.DeviceAddr = DevAddr & 0x7F; - Td->TdHw.MaxPacketLen = (UINT32) (sizeof (EFI_USB_DEVICE_REQUEST) - 1); - Td->TdHw.PidCode = SETUP_PACKET_ID; - Td->TdHw.DataBuffer = (UINT32) (UINTN) RequestPhy; - - Td->Data = Request; - Td->DataLen = (UINT16) sizeof (EFI_USB_DEVICE_REQUEST); - - return Td; -} - - -/** - Create a TD for data. - - @param Uhc The UHCI device. - @param DevAddr Device address. - @param Endpoint Endpoint number. - @param DataPtr A pointer to cpu memory address of Data buffer. - @param DataPhyPtr A pointer to pci memory address of Data buffer. - @param Len Data length. - @param PktId Packet ID. - @param Toggle Data toggle value. - @param IsLow Full speed or low speed. - - @return Data Td pointer if success, otherwise NULL. - -**/ -UHCI_TD_SW * -UhciCreateDataTd ( - IN USB_HC_DEV *Uhc, - IN UINT8 DevAddr, - IN UINT8 Endpoint, - IN UINT8 *DataPtr, - IN UINT8 *DataPhyPtr, - IN UINTN Len, - IN UINT8 PktId, - IN UINT8 Toggle, - IN BOOLEAN IsLow - ) -{ - UHCI_TD_SW *Td; - - // - // Code as length - 1, and the max valid length is 0x500 - // - ASSERT (Len <= 0x500); - - Td = UhciCreateTd (Uhc); - - if (Td == NULL) { - return NULL; - } - - Td->TdHw.NextLink = TD_LINK (NULL, TRUE, TRUE); - Td->TdHw.ShortPacket = FALSE; - Td->TdHw.IsIsoch = FALSE; - Td->TdHw.IntOnCpl = FALSE; - Td->TdHw.ErrorCount = 0x03; - Td->TdHw.Status = USBTD_ACTIVE; - Td->TdHw.LowSpeed = IsLow ? 1 : 0; - Td->TdHw.DataToggle = Toggle & 0x01; - Td->TdHw.EndPoint = Endpoint & 0x0F; - Td->TdHw.DeviceAddr = DevAddr & 0x7F; - Td->TdHw.MaxPacketLen = (UINT32) (Len - 1); - Td->TdHw.PidCode = (UINT8) PktId; - Td->TdHw.DataBuffer = (UINT32) (UINTN) DataPhyPtr; - - Td->Data = DataPtr; - Td->DataLen = (UINT16) Len; - - return Td; -} - - -/** - Create TD for the Status Stage of control transfer. - - @param Uhc The UHCI device. - @param DevAddr Device address. - @param PktId Packet ID. - @param IsLow Full speed or low speed. - - @return Status Td Pointer. - -**/ -UHCI_TD_SW * -UhciCreateStatusTd ( - IN USB_HC_DEV *Uhc, - IN UINT8 DevAddr, - IN UINT8 PktId, - IN BOOLEAN IsLow - ) -{ - UHCI_TD_SW *Td; - - Td = UhciCreateTd (Uhc); - - if (Td == NULL) { - return NULL; - } - - Td->TdHw.NextLink = TD_LINK (NULL, TRUE, TRUE); - Td->TdHw.ShortPacket = FALSE; - Td->TdHw.IsIsoch = FALSE; - Td->TdHw.IntOnCpl = FALSE; - Td->TdHw.ErrorCount = 0x03; - Td->TdHw.Status |= USBTD_ACTIVE; - Td->TdHw.MaxPacketLen = 0x7FF; //0x7FF: there is no data (refer to UHCI spec) - Td->TdHw.DataToggle = 1; - Td->TdHw.EndPoint = 0; - Td->TdHw.LowSpeed = IsLow ? 1 : 0; - Td->TdHw.DeviceAddr = DevAddr & 0x7F; - Td->TdHw.PidCode = (UINT8) PktId; - Td->TdHw.DataBuffer = (UINT32) (UINTN) NULL; - - Td->Data = NULL; - Td->DataLen = 0; - - return Td; -} - - -/** - Create Tds list for Control Transfer. - - @param Uhc The UHCI device. - @param DeviceAddr The device address. - @param DataPktId Packet Identification of Data Tds. - @param Request A pointer to cpu memory address of request structure buffer to transfer. - @param RequestPhy A pointer to pci memory address of request structure buffer to transfer. - @param Data A pointer to cpu memory address of user data buffer to transfer. - @param DataPhy A pointer to pci memory address of user data buffer to transfer. - @param DataLen Length of user data to transfer. - @param MaxPacket Maximum packet size for control transfer. - @param IsLow Full speed or low speed. - - @return The Td list head for the control transfer. - -**/ -UHCI_TD_SW * -UhciCreateCtrlTds ( - IN USB_HC_DEV *Uhc, - IN UINT8 DeviceAddr, - IN UINT8 DataPktId, - IN UINT8 *Request, - IN UINT8 *RequestPhy, - IN UINT8 *Data, - IN UINT8 *DataPhy, - IN UINTN DataLen, - IN UINT8 MaxPacket, - IN BOOLEAN IsLow - ) -{ - UHCI_TD_SW *SetupTd; - UHCI_TD_SW *FirstDataTd; - UHCI_TD_SW *DataTd; - UHCI_TD_SW *PrevDataTd; - UHCI_TD_SW *StatusTd; - UINT8 DataToggle; - UINT8 StatusPktId; - UINTN ThisTdLen; - - - DataTd = NULL; - SetupTd = NULL; - FirstDataTd = NULL; - PrevDataTd = NULL; - StatusTd = NULL; - - // - // Create setup packets for the transfer - // - SetupTd = UhciCreateSetupTd (Uhc, DeviceAddr, Request, RequestPhy, IsLow); - - if (SetupTd == NULL) { - return NULL; - } - - // - // Create data packets for the transfer - // - DataToggle = 1; - - while (DataLen > 0) { - // - // PktSize is the data load size in each Td. - // - ThisTdLen = (DataLen > MaxPacket ? MaxPacket : DataLen); - - DataTd = UhciCreateDataTd ( - Uhc, - DeviceAddr, - 0, - Data, //cpu memory address - DataPhy, //Pci memory address - ThisTdLen, - DataPktId, - DataToggle, - IsLow - ); - - if (DataTd == NULL) { - goto FREE_TD; - } - - if (FirstDataTd == NULL) { - FirstDataTd = DataTd; - FirstDataTd->NextTd = NULL; - } else { - UhciAppendTd (Uhc, PrevDataTd, DataTd); - } - - DataToggle ^= 1; - PrevDataTd = DataTd; - Data += ThisTdLen; - DataPhy += ThisTdLen; - DataLen -= ThisTdLen; - } - - // - // Status packet is on the opposite direction to data packets - // - if (OUTPUT_PACKET_ID == DataPktId) { - StatusPktId = INPUT_PACKET_ID; - } else { - StatusPktId = OUTPUT_PACKET_ID; - } - - StatusTd = UhciCreateStatusTd (Uhc, DeviceAddr, StatusPktId, IsLow); - - if (StatusTd == NULL) { - goto FREE_TD; - } - - // - // Link setup Td -> data Tds -> status Td together - // - if (FirstDataTd != NULL) { - UhciAppendTd (Uhc, SetupTd, FirstDataTd); - UhciAppendTd (Uhc, PrevDataTd, StatusTd); - } else { - UhciAppendTd (Uhc, SetupTd, StatusTd); - } - - return SetupTd; - -FREE_TD: - if (SetupTd != NULL) { - UhciDestoryTds (Uhc, SetupTd); - } - - if (FirstDataTd != NULL) { - UhciDestoryTds (Uhc, FirstDataTd); - } - - return NULL; -} - - -/** - Create Tds list for Bulk/Interrupt Transfer. - - @param Uhc USB_HC_DEV. - @param DevAddr Address of Device. - @param EndPoint Endpoint Number. - @param PktId Packet Identification of Data Tds. - @param Data A pointer to cpu memory address of user data buffer to transfer. - @param DataPhy A pointer to pci memory address of user data buffer to transfer. - @param DataLen Length of user data to transfer. - @param DataToggle Data Toggle Pointer. - @param MaxPacket Maximum packet size for Bulk/Interrupt transfer. - @param IsLow Is Low Speed Device. - - @return The Tds list head for the bulk transfer. - -**/ -UHCI_TD_SW * -UhciCreateBulkOrIntTds ( - IN USB_HC_DEV *Uhc, - IN UINT8 DevAddr, - IN UINT8 EndPoint, - IN UINT8 PktId, - IN UINT8 *Data, - IN UINT8 *DataPhy, - IN UINTN DataLen, - IN OUT UINT8 *DataToggle, - IN UINT8 MaxPacket, - IN BOOLEAN IsLow - ) -{ - UHCI_TD_SW *DataTd; - UHCI_TD_SW *FirstDataTd; - UHCI_TD_SW *PrevDataTd; - UINTN ThisTdLen; - - DataTd = NULL; - FirstDataTd = NULL; - PrevDataTd = NULL; - - // - // Create data packets for the transfer - // - while (DataLen > 0) { - // - // PktSize is the data load size that each Td. - // - ThisTdLen = DataLen; - - if (DataLen > MaxPacket) { - ThisTdLen = MaxPacket; - } - - DataTd = UhciCreateDataTd ( - Uhc, - DevAddr, - EndPoint, - Data, - DataPhy, - ThisTdLen, - PktId, - *DataToggle, - IsLow - ); - - if (DataTd == NULL) { - goto FREE_TD; - } - - if (PktId == INPUT_PACKET_ID) { - DataTd->TdHw.ShortPacket = TRUE; - } - - if (FirstDataTd == NULL) { - FirstDataTd = DataTd; - FirstDataTd->NextTd = NULL; - } else { - UhciAppendTd (Uhc, PrevDataTd, DataTd); - } - - *DataToggle ^= 1; - PrevDataTd = DataTd; - Data += ThisTdLen; - DataPhy += ThisTdLen; - DataLen -= ThisTdLen; - } - - return FirstDataTd; - -FREE_TD: - if (FirstDataTd != NULL) { - UhciDestoryTds (Uhc, FirstDataTd); - } - - return NULL; -} diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.h b/MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.h deleted file mode 100644 index 9ddca38302..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.h +++ /dev/null @@ -1,272 +0,0 @@ -/** @file - - The definition for UHCI register operation routines. - -Copyright (c) 2007, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_UHCI_QUEUE_H_ -#define _EFI_UHCI_QUEUE_H_ - -// -// Macroes used to set various links in UHCI's driver. -// In this UHCI driver, QH's horizontal link always pointers to other QH, -// and its vertical link always pointers to TD. TD's next pointer always -// pointers to other sibling TD. Frame link always pointers to QH because -// ISO transfer isn't supported. -// -// We should use UINT32 to access these pointers to void race conditions -// with hardware. -// -#define QH_HLINK(Pointer, Terminate) \ - (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | 0x02 | ((Terminate) ? 0x01 : 0)) - -#define QH_VLINK(Pointer, Terminate) \ - (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | ((Terminate) ? 0x01 : 0)) - -#define TD_LINK(Pointer, VertFirst, Terminate) \ - (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | \ - ((VertFirst) ? 0x04 : 0) | ((Terminate) ? 0x01 : 0)) - -#define LINK_TERMINATED(Link) (((Link) & 0x01) != 0) - -#define UHCI_ADDR(QhOrTd) ((VOID *) (UINTN) ((QhOrTd) & 0xFFFFFFF0)) - -#pragma pack(1) -// -// Both links in QH has this internal structure: -// Next pointer: 28, Reserved: 2, NextIsQh: 1, Terminate: 1 -// This is the same as frame list entry. -// -typedef struct { - UINT32 HorizonLink; - UINT32 VerticalLink; -} UHCI_QH_HW; - -// -// Next link in TD has this internal structure: -// Next pointer: 28, Reserved: 1, Vertical First: 1, NextIsQh: 1, Terminate: 1 -// -typedef struct { - UINT32 NextLink; - UINT32 ActualLen : 11; - UINT32 Reserved1 : 5; - UINT32 Status : 8; - UINT32 IntOnCpl : 1; - UINT32 IsIsoch : 1; - UINT32 LowSpeed : 1; - UINT32 ErrorCount : 2; - UINT32 ShortPacket : 1; - UINT32 Reserved2 : 2; - UINT32 PidCode : 8; - UINT32 DeviceAddr : 7; - UINT32 EndPoint : 4; - UINT32 DataToggle : 1; - UINT32 Reserved3 : 1; - UINT32 MaxPacketLen: 11; - UINT32 DataBuffer; -} UHCI_TD_HW; -#pragma pack() - -typedef struct _UHCI_TD_SW UHCI_TD_SW; -typedef struct _UHCI_QH_SW UHCI_QH_SW; - -struct _UHCI_QH_SW { - UHCI_QH_HW QhHw; - UHCI_QH_SW *NextQh; - UHCI_TD_SW *TDs; - UINTN Interval; -}; - -struct _UHCI_TD_SW { - UHCI_TD_HW TdHw; - UHCI_TD_SW *NextTd; - UINT8 *Data; - UINT16 DataLen; -}; - - -/** - Link the TD To QH. - - @param Uhc The UHCI device. - @param Qh The queue head for the TD to link to. - @param Td The TD to link. - -**/ -VOID -UhciLinkTdToQh ( - IN USB_HC_DEV *Uhc, - IN UHCI_QH_SW *Qh, - IN UHCI_TD_SW *Td - ); - - -/** - Unlink TD from the QH. - - @param Qh The queue head to unlink from. - @param Td The TD to unlink. - - @return None. - -**/ -VOID -UhciUnlinkTdFromQh ( - IN UHCI_QH_SW *Qh, - IN UHCI_TD_SW *Td - ); - - -/** - Map address of request structure buffer. - - @param Uhc The UHCI device. - @param Request The user request buffer. - @param MappedAddr Mapped address of request. - @param Map Identificaion of this mapping to return. - - @return EFI_SUCCESS Success. - @return EFI_DEVICE_ERROR Fail to map the user request. - -**/ -EFI_STATUS -UhciMapUserRequest ( - IN USB_HC_DEV *Uhc, - IN OUT VOID *Request, - OUT UINT8 **MappedAddr, - OUT VOID **Map - ); - - -/** - Map address of user data buffer. - - @param Uhc The UHCI device. - @param Direction Direction of the data transfer. - @param Data The user data buffer. - @param Len Length of the user data. - @param PktId Packet identificaion. - @param MappedAddr Mapped address to return. - @param Map Identificaion of this mapping to return. - - @return EFI_SUCCESS Success. - @return EFI_DEVICE_ERROR Fail to map the user data. - -**/ -EFI_STATUS -UhciMapUserData ( - IN USB_HC_DEV *Uhc, - IN EFI_USB_DATA_DIRECTION Direction, - IN VOID *Data, - IN OUT UINTN *Len, - OUT UINT8 *PktId, - OUT UINT8 **MappedAddr, - OUT VOID **Map - ); - - -/** - Delete a list of TDs. - - @param Uhc The UHCI device. - @param FirstTd TD link list head. - - @return None. - -**/ -VOID -UhciDestoryTds ( - IN USB_HC_DEV *Uhc, - IN UHCI_TD_SW *FirstTd - ); - - -/** - Create an initialize a new queue head. - - @param Uhc The UHCI device. - @param Interval The polling interval for the queue. - - @return The newly created queue header. - -**/ -UHCI_QH_SW * -UhciCreateQh ( - IN USB_HC_DEV *Uhc, - IN UINTN Interval - ); - - -/** - Create Tds list for Control Transfer. - - @param Uhc The UHCI device. - @param DeviceAddr The device address. - @param DataPktId Packet Identification of Data Tds. - @param Request A pointer to cpu memory address of request structure buffer to transfer. - @param RequestPhy A pointer to pci memory address of request structure buffer to transfer. - @param Data A pointer to cpu memory address of user data buffer to transfer. - @param DataPhy A pointer to pci memory address of user data buffer to transfer. - @param DataLen Length of user data to transfer. - @param MaxPacket Maximum packet size for control transfer. - @param IsLow Full speed or low speed. - - @return The Td list head for the control transfer. - -**/ -UHCI_TD_SW * -UhciCreateCtrlTds ( - IN USB_HC_DEV *Uhc, - IN UINT8 DeviceAddr, - IN UINT8 DataPktId, - IN UINT8 *Request, - IN UINT8 *RequestPhy, - IN UINT8 *Data, - IN UINT8 *DataPhy, - IN UINTN DataLen, - IN UINT8 MaxPacket, - IN BOOLEAN IsLow - ); - - -/** - Create Tds list for Bulk/Interrupt Transfer. - - @param Uhc USB_HC_DEV. - @param DevAddr Address of Device. - @param EndPoint Endpoint Number. - @param PktId Packet Identification of Data Tds. - @param Data A pointer to cpu memory address of user data buffer to transfer. - @param DataPhy A pointer to pci memory address of user data buffer to transfer. - @param DataLen Length of user data to transfer. - @param DataToggle Data Toggle Pointer. - @param MaxPacket Maximum packet size for Bulk/Interrupt transfer. - @param IsLow Is Low Speed Device. - - @return The Tds list head for the bulk transfer. - -**/ -UHCI_TD_SW * -UhciCreateBulkOrIntTds ( - IN USB_HC_DEV *Uhc, - IN UINT8 DevAddr, - IN UINT8 EndPoint, - IN UINT8 PktId, - IN UINT8 *Data, - IN UINT8 *DataPhy, - IN UINTN DataLen, - IN OUT UINT8 *DataToggle, - IN UINT8 MaxPacket, - IN BOOLEAN IsLow - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.c b/MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.c deleted file mode 100644 index 0fd16284b3..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.c +++ /dev/null @@ -1,281 +0,0 @@ -/** @file - - The UHCI register operation routines. - -Copyright (c) 2007, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Uhci.h" - - -/** - Read a UHCI register. - - @param PciIo The EFI_PCI_IO_PROTOCOL to use. - @param Offset Register offset to USB_BAR_INDEX. - - @return Content of register. - -**/ -UINT16 -UhciReadReg ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT32 Offset - ) -{ - UINT16 Data; - EFI_STATUS Status; - - Status = PciIo->Io.Read ( - PciIo, - EfiPciIoWidthUint16, - USB_BAR_INDEX, - Offset, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "UhciReadReg: PciIo Io.Read error: %r at offset %d\n", Status, Offset)); - - Data = 0xFFFF; - } - - return Data; -} - - -/** - Write data to UHCI register. - - @param PciIo The EFI_PCI_IO_PROTOCOL to use. - @param Offset Register offset to USB_BAR_INDEX. - @param Data Data to write. - -**/ -VOID -UhciWriteReg ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT32 Offset, - IN UINT16 Data - ) -{ - EFI_STATUS Status; - - Status = PciIo->Io.Write ( - PciIo, - EfiPciIoWidthUint16, - USB_BAR_INDEX, - Offset, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "UhciWriteReg: PciIo Io.Write error: %r at offset %d\n", Status, Offset)); - } -} - - -/** - Set a bit of the UHCI Register. - - @param PciIo The EFI_PCI_IO_PROTOCOL to use. - @param Offset Register offset to USB_BAR_INDEX. - @param Bit The bit to set. - -**/ -VOID -UhciSetRegBit ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT32 Offset, - IN UINT16 Bit - ) -{ - UINT16 Data; - - Data = UhciReadReg (PciIo, Offset); - Data = (UINT16) (Data |Bit); - UhciWriteReg (PciIo, Offset, Data); -} - - -/** - Clear a bit of the UHCI Register. - - @param PciIo The PCI_IO protocol to access the PCI. - @param Offset Register offset to USB_BAR_INDEX. - @param Bit The bit to clear. - -**/ -VOID -UhciClearRegBit ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT32 Offset, - IN UINT16 Bit - ) -{ - UINT16 Data; - - Data = UhciReadReg (PciIo, Offset); - Data = (UINT16) (Data & ~Bit); - UhciWriteReg (PciIo, Offset, Data); -} - - -/** - Clear all the interrutp status bits, these bits - are Write-Clean. - - @param Uhc The UHCI device. - -**/ -VOID -UhciAckAllInterrupt ( - IN USB_HC_DEV *Uhc - ) -{ - UhciWriteReg (Uhc->PciIo, USBSTS_OFFSET, 0x3F); - - // - // If current HC is halted, re-enable it. Host Controller Process Error - // is a temporary error status. - // - if (!UhciIsHcWorking (Uhc->PciIo)) { - DEBUG ((EFI_D_ERROR, "UhciAckAllInterrupt: re-enable the UHCI from system error\n")); - Uhc->Usb2Hc.SetState (&Uhc->Usb2Hc, EfiUsbHcStateOperational); - } -} - - -/** - Stop the host controller. - - @param Uhc The UHCI device. - @param Timeout Max time allowed. - - @retval EFI_SUCCESS The host controller is stopped. - @retval EFI_TIMEOUT Failed to stop the host controller. - -**/ -EFI_STATUS -UhciStopHc ( - IN USB_HC_DEV *Uhc, - IN UINTN Timeout - ) -{ - UINT16 UsbSts; - UINTN Index; - - UhciClearRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_RS); - - // - // ensure the HC is in halt status after send the stop command - // Timeout is in us unit. - // - for (Index = 0; Index < (Timeout / 50) + 1; Index++) { - UsbSts = UhciReadReg (Uhc->PciIo, USBSTS_OFFSET); - - if ((UsbSts & USBSTS_HCH) == USBSTS_HCH) { - return EFI_SUCCESS; - } - - gBS->Stall (50); - } - - return EFI_TIMEOUT; -} - - -/** - Check whether the host controller operates well. - - @param PciIo The PCI_IO protocol to use. - - @retval TRUE Host controller is working. - @retval FALSE Host controller is halted or system error. - -**/ -BOOLEAN -UhciIsHcWorking ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ) -{ - UINT16 UsbSts; - - UsbSts = UhciReadReg (PciIo, USBSTS_OFFSET); - - if ((UsbSts & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) != 0) { - DEBUG ((EFI_D_ERROR, "UhciIsHcWorking: current USB state is %x\n", UsbSts)); - return FALSE; - } - - return TRUE; -} - - -/** - Set the UHCI frame list base address. It can't use - UhciWriteReg which access memory in UINT16. - - @param PciIo The EFI_PCI_IO_PROTOCOL to use. - @param Addr Address to set. - -**/ -VOID -UhciSetFrameListBaseAddr ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN VOID *Addr - ) -{ - EFI_STATUS Status; - UINT32 Data; - - Data = (UINT32) ((UINTN) Addr & 0xFFFFF000); - - Status = PciIo->Io.Write ( - PciIo, - EfiPciIoWidthUint32, - USB_BAR_INDEX, - (UINT64) USB_FRAME_BASE_OFFSET, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "UhciSetFrameListBaseAddr: PciIo Io.Write error: %r\n", Status)); - } -} - - -/** - Disable USB Emulation. - - @param PciIo The EFI_PCI_IO_PROTOCOL protocol to use. - -**/ -VOID -UhciTurnOffUsbEmulation ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ) -{ - UINT16 Command; - - Command = 0; - - PciIo->Pci.Write ( - PciIo, - EfiPciIoWidthUint16, - USB_EMULATION_OFFSET, - 1, - &Command - ); -} diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.h b/MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.h deleted file mode 100644 index 7212ad0dfa..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciReg.h +++ /dev/null @@ -1,248 +0,0 @@ -/** @file - - The definition for UHCI register operation routines. - -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_UHCI_REG_H_ -#define _EFI_UHCI_REG_H_ - -// -// UHCI register offset -// - -#define UHCI_FRAME_NUM 1024 - -// -// Register offset and PCI related staff -// -#define USB_BAR_INDEX 4 - -#define USBCMD_OFFSET 0 -#define USBSTS_OFFSET 2 -#define USBINTR_OFFSET 4 -#define USBPORTSC_OFFSET 0x10 -#define USB_FRAME_NO_OFFSET 6 -#define USB_FRAME_BASE_OFFSET 8 -#define USB_EMULATION_OFFSET 0xC0 - -// -// Packet IDs -// -#define SETUP_PACKET_ID 0x2D -#define INPUT_PACKET_ID 0x69 -#define OUTPUT_PACKET_ID 0xE1 -#define ERROR_PACKET_ID 0x55 - -// -// USB port status and control bit definition. -// -#define USBPORTSC_CCS BIT0 // Current Connect Status -#define USBPORTSC_CSC BIT1 // Connect Status Change -#define USBPORTSC_PED BIT2 // Port Enable / Disable -#define USBPORTSC_PEDC BIT3 // Port Enable / Disable Change -#define USBPORTSC_LSL BIT4 // Line Status Low BIT -#define USBPORTSC_LSH BIT5 // Line Status High BIT -#define USBPORTSC_RD BIT6 // Resume Detect -#define USBPORTSC_LSDA BIT8 // Low Speed Device Attached -#define USBPORTSC_PR BIT9 // Port Reset -#define USBPORTSC_SUSP BIT12 // Suspend - -// -// UHCI Spec said it must implement 2 ports each host at least, -// and if more, check whether the bit7 of PORTSC is always 1. -// So here assume the max of port number each host is 16. -// -#define USB_MAX_ROOTHUB_PORT 0x0F - -// -// Command register bit definitions -// -#define USBCMD_RS BIT0 // Run/Stop -#define USBCMD_HCRESET BIT1 // Host reset -#define USBCMD_GRESET BIT2 // Global reset -#define USBCMD_EGSM BIT3 // Global Suspend Mode -#define USBCMD_FGR BIT4 // Force Global Resume -#define USBCMD_SWDBG BIT5 // SW Debug mode -#define USBCMD_CF BIT6 // Config Flag (sw only) -#define USBCMD_MAXP BIT7 // Max Packet (0 = 32, 1 = 64) - -// -// USB Status register bit definitions -// -#define USBSTS_USBINT BIT0 // Interrupt due to IOC -#define USBSTS_ERROR BIT1 // Interrupt due to error -#define USBSTS_RD BIT2 // Resume Detect -#define USBSTS_HSE BIT3 // Host System Error -#define USBSTS_HCPE BIT4 // Host Controller Process Error -#define USBSTS_HCH BIT5 // HC Halted - -#define USBTD_ACTIVE BIT7 // TD is still active -#define USBTD_STALLED BIT6 // TD is stalled -#define USBTD_BUFFERR BIT5 // Buffer underflow or overflow -#define USBTD_BABBLE BIT4 // Babble condition -#define USBTD_NAK BIT3 // NAK is received -#define USBTD_CRC BIT2 // CRC/Time out error -#define USBTD_BITSTUFF BIT1 // Bit stuff error - - -/** - Read a UHCI register. - - @param PciIo The EFI_PCI_IO_PROTOCOL to use. - @param Offset Register offset to USB_BAR_INDEX. - - @return Content of register. - -**/ -UINT16 -UhciReadReg ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT32 Offset - ); - - - -/** - Write data to UHCI register. - - @param PciIo The EFI_PCI_IO_PROTOCOL to use. - @param Offset Register offset to USB_BAR_INDEX. - @param Data Data to write. - - @return None. - -**/ -VOID -UhciWriteReg ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT32 Offset, - IN UINT16 Data - ); - - - -/** - Set a bit of the UHCI Register. - - @param PciIo The EFI_PCI_IO_PROTOCOL to use. - @param Offset Register offset to USB_BAR_INDEX. - @param Bit The bit to set. - - @return None. - -**/ -VOID -UhciSetRegBit ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT32 Offset, - IN UINT16 Bit - ); - - - -/** - Clear a bit of the UHCI Register. - - @param PciIo The PCI_IO protocol to access the PCI. - @param Offset Register offset to USB_BAR_INDEX. - @param Bit The bit to clear. - - @return None. - -**/ -VOID -UhciClearRegBit ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT32 Offset, - IN UINT16 Bit - ); - - -/** - Clear all the interrutp status bits, these bits - are Write-Clean. - - @param Uhc The UHCI device. - - @return None. - -**/ -VOID -UhciAckAllInterrupt ( - IN USB_HC_DEV *Uhc - ); - - -/** - Stop the host controller. - - @param Uhc The UHCI device. - @param Timeout Max time allowed. - - @retval EFI_SUCCESS The host controller is stopped. - @retval EFI_TIMEOUT Failed to stop the host controller. - -**/ -EFI_STATUS -UhciStopHc ( - IN USB_HC_DEV *Uhc, - IN UINTN Timeout - ); - - - -/** - Check whether the host controller operates well. - - @param PciIo The PCI_IO protocol to use. - - @retval TRUE Host controller is working. - @retval FALSE Host controller is halted or system error. - -**/ -BOOLEAN -UhciIsHcWorking ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ); - - -/** - Set the UHCI frame list base address. It can't use - UhciWriteReg which access memory in UINT16. - - @param PciIo The EFI_PCI_IO_PROTOCOL to use. - @param Addr Address to set. - - @return None. - -**/ -VOID -UhciSetFrameListBaseAddr ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN VOID *Addr - ); - - -/** - Disable USB Emulation. - - @param PciIo The EFI_PCI_IO_PROTOCOL protocol to use. - - @return None. - -**/ -VOID -UhciTurnOffUsbEmulation ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ); -#endif diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c b/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c deleted file mode 100644 index 90f010c998..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c +++ /dev/null @@ -1,1045 +0,0 @@ -/** @file - - The EHCI register operation routines. - -Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Uhci.h" - - -/** - Create Frame List Structure. - - @param Uhc UHCI device. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_UNSUPPORTED Map memory fail. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -UhciInitFrameList ( - IN USB_HC_DEV *Uhc - ) -{ - EFI_PHYSICAL_ADDRESS MappedAddr; - EFI_STATUS Status; - VOID *Buffer; - VOID *Mapping; - UINTN Pages; - UINTN Bytes; - UINTN Index; - EFI_PHYSICAL_ADDRESS PhyAddr; - - // - // The Frame List is a common buffer that will be - // accessed by both the cpu and the usb bus master - // at the same time. The Frame List ocupies 4K bytes, - // and must be aligned on 4-Kbyte boundaries. - // - Bytes = 4096; - Pages = EFI_SIZE_TO_PAGES (Bytes); - - Status = Uhc->PciIo->AllocateBuffer ( - Uhc->PciIo, - AllocateAnyPages, - EfiBootServicesData, - Pages, - &Buffer, - 0 - ); - - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - Status = Uhc->PciIo->Map ( - Uhc->PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - Buffer, - &Bytes, - &MappedAddr, - &Mapping - ); - - if (EFI_ERROR (Status) || (Bytes != 4096)) { - Status = EFI_UNSUPPORTED; - goto ON_ERROR; - } - - Uhc->FrameBase = (UINT32 *) (UINTN) Buffer; - Uhc->FrameMapping = Mapping; - - // - // Tell the Host Controller where the Frame List lies, - // by set the Frame List Base Address Register. - // - UhciSetFrameListBaseAddr (Uhc->PciIo, (VOID *) (UINTN) MappedAddr); - - // - // Allocate the QH used by sync interrupt/control/bulk transfer. - // FS ctrl/bulk queue head is set to loopback so additional BW - // can be reclaimed. Notice, LS don't support bulk transfer and - // also doesn't support BW reclamation. - // - Uhc->SyncIntQh = UhciCreateQh (Uhc, 1); - Uhc->CtrlQh = UhciCreateQh (Uhc, 1); - Uhc->BulkQh = UhciCreateQh (Uhc, 1); - - if ((Uhc->SyncIntQh == NULL) || (Uhc->CtrlQh == NULL) || (Uhc->BulkQh == NULL)) { - Uhc->PciIo->Unmap (Uhc->PciIo, Mapping); - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; - } - - // - // +-------------+ - // | | - // Link the three together: SyncIntQh->CtrlQh->BulkQh <---------+ - // Each frame entry is linked to this sequence of QH. These QH - // will remain on the schedul, never got removed - // - PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->CtrlQh, sizeof (UHCI_QH_HW)); - Uhc->SyncIntQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE); - Uhc->SyncIntQh->NextQh = Uhc->CtrlQh; - - PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->BulkQh, sizeof (UHCI_QH_HW)); - Uhc->CtrlQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE); - Uhc->CtrlQh->NextQh = Uhc->BulkQh; - - // - // Some old platform such as Intel's Tiger 4 has a difficult time - // in supporting the full speed bandwidth reclamation in the previous - // mentioned form. Most new platforms don't suffer it. - // - Uhc->BulkQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE); - - Uhc->BulkQh->NextQh = NULL; - - Uhc->FrameBaseHostAddr = AllocateZeroPool (4096); - if (Uhc->FrameBaseHostAddr == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; - } - - PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_HW)); - for (Index = 0; Index < UHCI_FRAME_NUM; Index++) { - Uhc->FrameBase[Index] = QH_HLINK (PhyAddr, FALSE); - Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Uhc->SyncIntQh; - } - - return EFI_SUCCESS; - -ON_ERROR: - if (Uhc->SyncIntQh != NULL) { - UsbHcFreeMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_SW)); - } - - if (Uhc->CtrlQh != NULL) { - UsbHcFreeMem (Uhc->MemPool, Uhc->CtrlQh, sizeof (UHCI_QH_SW)); - } - - if (Uhc->BulkQh != NULL) { - UsbHcFreeMem (Uhc->MemPool, Uhc->BulkQh, sizeof (UHCI_QH_SW)); - } - - Uhc->PciIo->FreeBuffer (Uhc->PciIo, Pages, Buffer); - return Status; -} - - -/** - Destory FrameList buffer. - - @param Uhc The UHCI device. - -**/ -VOID -UhciDestoryFrameList ( - IN USB_HC_DEV *Uhc - ) -{ - // - // Unmap the common buffer for framelist entry, - // and free the common buffer. - // Uhci's frame list occupy 4k memory. - // - Uhc->PciIo->Unmap (Uhc->PciIo, Uhc->FrameMapping); - - Uhc->PciIo->FreeBuffer ( - Uhc->PciIo, - EFI_SIZE_TO_PAGES (4096), - (VOID *) Uhc->FrameBase - ); - - if (Uhc->FrameBaseHostAddr != NULL) { - FreePool (Uhc->FrameBaseHostAddr); - } - - if (Uhc->SyncIntQh != NULL) { - UsbHcFreeMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_SW)); - } - - if (Uhc->CtrlQh != NULL) { - UsbHcFreeMem (Uhc->MemPool, Uhc->CtrlQh, sizeof (UHCI_QH_SW)); - } - - if (Uhc->BulkQh != NULL) { - UsbHcFreeMem (Uhc->MemPool, Uhc->BulkQh, sizeof (UHCI_QH_SW)); - } - - Uhc->FrameBase = NULL; - Uhc->FrameBaseHostAddr = NULL; - Uhc->SyncIntQh = NULL; - Uhc->CtrlQh = NULL; - Uhc->BulkQh = NULL; -} - - -/** - Convert the poll rate to the maxium 2^n that is smaller - than Interval. - - @param Interval The poll rate to convert. - - @return The converted poll rate. - -**/ -UINTN -UhciConvertPollRate ( - IN UINTN Interval - ) -{ - UINTN BitCount; - - ASSERT (Interval != 0); - - // - // Find the index (1 based) of the highest non-zero bit - // - BitCount = 0; - - while (Interval != 0) { - Interval >>= 1; - BitCount++; - } - - return (UINTN)1 << (BitCount - 1); -} - - -/** - Link a queue head (for asynchronous interrupt transfer) to - the frame list. - - @param Uhc The UHCI device. - @param Qh The queue head to link into. - -**/ -VOID -UhciLinkQhToFrameList ( - USB_HC_DEV *Uhc, - UHCI_QH_SW *Qh - ) -{ - UINTN Index; - UHCI_QH_SW *Prev; - UHCI_QH_SW *Next; - EFI_PHYSICAL_ADDRESS PhyAddr; - EFI_PHYSICAL_ADDRESS QhPciAddr; - - ASSERT ((Uhc->FrameBase != NULL) && (Qh != NULL)); - - QhPciAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_HW)); - - for (Index = 0; Index < UHCI_FRAME_NUM; Index += Qh->Interval) { - // - // First QH can't be NULL because we always keep static queue - // heads on the frame list - // - ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index])); - Next = (UHCI_QH_SW*)(UINTN)Uhc->FrameBaseHostAddr[Index]; - Prev = NULL; - - // - // Now, insert the queue head (Qh) into this frame: - // 1. Find a queue head with the same poll interval, just insert - // Qh after this queue head, then we are done. - // - // 2. Find the position to insert the queue head into: - // Previous head's interval is bigger than Qh's - // Next head's interval is less than Qh's - // Then, insert the Qh between then - // - // This method is very much the same as that used by EHCI. - // Because each QH's interval is round down to 2^n, poll - // rate is correct. - // - while (Next->Interval > Qh->Interval) { - Prev = Next; - Next = Next->NextQh; - ASSERT (Next != NULL); - } - - // - // The entry may have been linked into the frame by early insertation. - // For example: if insert a Qh with Qh.Interval == 4, and there is a Qh - // with Qh.Interval == 8 on the frame. If so, we are done with this frame. - // It isn't necessary to compare all the QH with the same interval to - // Qh. This is because if there is other QH with the same interval, Qh - // should has been inserted after that at FrameBase[0] and at FrameBase[0] it is - // impossible (Next == Qh) - // - if (Next == Qh) { - continue; - } - - if (Next->Interval == Qh->Interval) { - // - // If there is a QH with the same interval, it locates at - // FrameBase[0], and we can simply insert it after this QH. We - // are all done. - // - ASSERT ((Index == 0) && (Qh->NextQh == NULL)); - - Prev = Next; - Next = Next->NextQh; - - Qh->NextQh = Next; - Prev->NextQh = Qh; - - Qh->QhHw.HorizonLink = Prev->QhHw.HorizonLink; - - Prev->QhHw.HorizonLink = QH_HLINK (QhPciAddr, FALSE); - break; - } - - // - // OK, find the right position, insert it in. If Qh's next - // link has already been set, it is in position. This is - // guarranted by 2^n polling interval. - // - if (Qh->NextQh == NULL) { - Qh->NextQh = Next; - PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Next, sizeof (UHCI_QH_HW)); - Qh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE); - } - - if (Prev == NULL) { - Uhc->FrameBase[Index] = QH_HLINK (QhPciAddr, FALSE); - Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Qh; - } else { - Prev->NextQh = Qh; - Prev->QhHw.HorizonLink = QH_HLINK (QhPciAddr, FALSE); - } - } -} - - -/** - Unlink QH from the frame list is easier: find all - the precedence node, and pointer there next to QhSw's - next. - - @param Uhc The UHCI device. - @param Qh The queue head to unlink. - -**/ -VOID -UhciUnlinkQhFromFrameList ( - USB_HC_DEV *Uhc, - UHCI_QH_SW *Qh - ) -{ - UINTN Index; - UHCI_QH_SW *Prev; - UHCI_QH_SW *This; - - ASSERT ((Uhc->FrameBase != NULL) && (Qh != NULL)); - - for (Index = 0; Index < UHCI_FRAME_NUM; Index += Qh->Interval) { - // - // Frame link can't be NULL because we always keep static - // queue heads on the frame list - // - ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index])); - This = (UHCI_QH_SW*)(UINTN)Uhc->FrameBaseHostAddr[Index]; - Prev = NULL; - - // - // Walk through the frame's QH list to find the - // queue head to remove - // - while ((This != NULL) && (This != Qh)) { - Prev = This; - This = This->NextQh; - } - - // - // Qh may have already been unlinked from this frame - // by early action. - // - if (This == NULL) { - continue; - } - - if (Prev == NULL) { - // - // Qh is the first entry in the frame - // - Uhc->FrameBase[Index] = Qh->QhHw.HorizonLink; - Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Qh->NextQh; - } else { - Prev->NextQh = Qh->NextQh; - Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink; - } - } -} - - -/** - Check TDs Results. - - @param Uhc This UHCI device. - @param Td UHCI_TD_SW to check. - @param IsLow Is Low Speed Device. - @param QhResult Return the result of this TD list. - - @return Whether the TD's result is finialized. - -**/ -BOOLEAN -UhciCheckTdStatus ( - IN USB_HC_DEV *Uhc, - IN UHCI_TD_SW *Td, - IN BOOLEAN IsLow, - OUT UHCI_QH_RESULT *QhResult - ) -{ - UINTN Len; - UINT8 State; - UHCI_TD_HW *TdHw; - BOOLEAN Finished; - - Finished = TRUE; - - // - // Initialize the data toggle to that of the first - // TD. The next toggle to use is either: - // 1. first TD's toggle if no TD is executed OK - // 2. the next toggle of last executed-OK TD - // - QhResult->Result = EFI_USB_NOERROR; - QhResult->NextToggle = (UINT8)Td->TdHw.DataToggle; - QhResult->Complete = 0; - - while (Td != NULL) { - TdHw = &Td->TdHw; - State = (UINT8)TdHw->Status; - - // - // UHCI will set STALLED bit when it abort the execution - // of TD list. There are several reasons: - // 1. BABBLE error happened - // 2. Received a STALL response - // 3. Error count decreased to zero. - // - // It also set CRC/Timeout/NAK/Buffer Error/BitStuff Error - // bits when corresponding conditions happen. But these - // conditions are not deadly, that is a TD can successfully - // completes even these bits are set. But it is likely that - // upper layer won't distinguish these condtions. So, only - // set these bits when TD is actually halted. - // - if ((State & USBTD_STALLED) != 0) { - if ((State & USBTD_BABBLE) != 0) { - QhResult->Result |= EFI_USB_ERR_BABBLE; - - } else if (TdHw->ErrorCount != 0) { - QhResult->Result |= EFI_USB_ERR_STALL; - } - - if ((State & USBTD_CRC) != 0) { - QhResult->Result |= EFI_USB_ERR_CRC; - } - - if ((State & USBTD_BUFFERR) != 0) { - QhResult->Result |= EFI_USB_ERR_BUFFER; - } - - if ((Td->TdHw.Status & USBTD_BITSTUFF) != 0) { - QhResult->Result |= EFI_USB_ERR_BITSTUFF; - } - - if (TdHw->ErrorCount == 0) { - QhResult->Result |= EFI_USB_ERR_TIMEOUT; - } - - Finished = TRUE; - goto ON_EXIT; - - } else if ((State & USBTD_ACTIVE) != 0) { - // - // The TD is still active, no need to check further. - // - QhResult->Result |= EFI_USB_ERR_NOTEXECUTE; - - Finished = FALSE; - goto ON_EXIT; - - } else { - // - // Update the next data toggle, it is always the - // next to the last known-good TD's data toggle if - // any TD is executed OK - // - QhResult->NextToggle = (UINT8) (1 - (UINT8)TdHw->DataToggle); - - // - // This TD is finished OK or met short packet read. Update the - // transfer length if it isn't a SETUP. - // - Len = (TdHw->ActualLen + 1) & 0x7FF; - - if (TdHw->PidCode != SETUP_PACKET_ID) { - QhResult->Complete += Len; - } - - // - // Short packet condition for full speed input TD, also - // terminate the transfer - // - if (!IsLow && (TdHw->ShortPacket == 1) && (Len < Td->DataLen)) { - DEBUG ((EFI_D_VERBOSE, "UhciCheckTdStatus: short packet read occured\n")); - - Finished = TRUE; - goto ON_EXIT; - } - } - - Td = Td->NextTd; - } - -ON_EXIT: - // - // Check whether HC is halted. Don't move this up. It must be - // called after data toggle is successfully updated. - // - if (!UhciIsHcWorking (Uhc->PciIo)) { - QhResult->Result |= EFI_USB_ERR_SYSTEM; - Finished = TRUE; - } - - if (Finished) { - Uhc->PciIo->Flush (Uhc->PciIo); - } - - UhciAckAllInterrupt (Uhc); - return Finished; -} - - -/** - Check the result of the transfer. - - @param Uhc The UHCI device. - @param Qh The queue head of the transfer. - @param Td The first TDs of the transfer. - @param TimeOut TimeOut value in milliseconds. - @param IsLow Is Low Speed Device. - @param QhResult The variable to return result. - - @retval EFI_SUCCESS The transfer finished with success. - @retval EFI_DEVICE_ERROR Transfer failed. - -**/ -EFI_STATUS -UhciExecuteTransfer ( - IN USB_HC_DEV *Uhc, - IN UHCI_QH_SW *Qh, - IN UHCI_TD_SW *Td, - IN UINTN TimeOut, - IN BOOLEAN IsLow, - OUT UHCI_QH_RESULT *QhResult - ) -{ - UINTN Index; - UINTN Delay; - BOOLEAN Finished; - EFI_STATUS Status; - BOOLEAN InfiniteLoop; - - Finished = FALSE; - Status = EFI_SUCCESS; - Delay = TimeOut * UHC_1_MILLISECOND; - InfiniteLoop = FALSE; - - // - // According to UEFI spec section 16.2.4, If Timeout is 0, then the caller - // must wait for the function to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR - // is returned. - // - if (TimeOut == 0) { - InfiniteLoop = TRUE; - } - - for (Index = 0; InfiniteLoop || (Index < Delay); Index++) { - Finished = UhciCheckTdStatus (Uhc, Td, IsLow, QhResult); - - // - // Transfer is OK or some error occured (TD inactive) - // - if (Finished) { - break; - } - - gBS->Stall (UHC_1_MICROSECOND); - } - - if (!Finished) { - DEBUG ((EFI_D_ERROR, "UhciExecuteTransfer: execution not finished for %dms\n", (UINT32)TimeOut)); - UhciDumpQh (Qh); - UhciDumpTds (Td); - - Status = EFI_TIMEOUT; - - } else if (QhResult->Result != EFI_USB_NOERROR) { - DEBUG ((EFI_D_ERROR, "UhciExecuteTransfer: execution failed with result %x\n", QhResult->Result)); - UhciDumpQh (Qh); - UhciDumpTds (Td); - - Status = EFI_DEVICE_ERROR; - } - - return Status; -} - - -/** - Update Async Request, QH and TDs. - - @param Uhc The UHCI device. - @param AsyncReq The UHCI asynchronous transfer to update. - @param Result Transfer reslut. - @param NextToggle The toggle of next data. - -**/ -VOID -UhciUpdateAsyncReq ( - IN USB_HC_DEV *Uhc, - IN UHCI_ASYNC_REQUEST *AsyncReq, - IN UINT32 Result, - IN UINT32 NextToggle - ) -{ - UHCI_QH_SW *Qh; - UHCI_TD_SW *FirstTd; - UHCI_TD_SW *Td; - - Qh = AsyncReq->QhSw; - FirstTd = AsyncReq->FirstTd; - - if (Result == EFI_USB_NOERROR) { - // - // The last transfer succeeds. Then we need to update - // the Qh and Td for next round of transfer. - // 1. Update the TD's data toggle - // 2. Activate all the TDs - // 3. Link the TD to the queue head again since during - // execution, queue head's TD pointer is changed by - // hardware. - // - for (Td = FirstTd; Td != NULL; Td = Td->NextTd) { - Td->TdHw.DataToggle = NextToggle; - NextToggle ^= 1; - Td->TdHw.Status |= USBTD_ACTIVE; - } - - UhciLinkTdToQh (Uhc, Qh, FirstTd); - return ; - } -} - - -/** - Create Async Request node, and Link to List. - - @param Uhc The UHCI device. - @param Qh The queue head of the transfer. - @param FirstTd First TD of the transfer. - @param DevAddr Device Address. - @param EndPoint EndPoint Address. - @param DataLen Data length. - @param Interval Polling Interval when inserted to frame list. - @param Data Data buffer, unmapped. - @param Callback Callback after interrupt transfeer. - @param Context Callback Context passed as function parameter. - @param IsLow Is Low Speed. - - @retval EFI_SUCCESS An asynchronous transfer is created. - @retval EFI_INVALID_PARAMETER Paremeter is error. - @retval EFI_OUT_OF_RESOURCES Failed because of resource shortage. - -**/ -EFI_STATUS -UhciCreateAsyncReq ( - IN USB_HC_DEV *Uhc, - IN UHCI_QH_SW *Qh, - IN UHCI_TD_SW *FirstTd, - IN UINT8 DevAddr, - IN UINT8 EndPoint, - IN UINTN DataLen, - IN UINTN Interval, - IN UINT8 *Data, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context, - IN BOOLEAN IsLow - ) -{ - UHCI_ASYNC_REQUEST *AsyncReq; - - AsyncReq = AllocatePool (sizeof (UHCI_ASYNC_REQUEST)); - - if (AsyncReq == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Fill Request field. Data is allocated host memory, not mapped - // - AsyncReq->Signature = UHCI_ASYNC_INT_SIGNATURE; - AsyncReq->DevAddr = DevAddr; - AsyncReq->EndPoint = EndPoint; - AsyncReq->DataLen = DataLen; - AsyncReq->Interval = UhciConvertPollRate(Interval); - AsyncReq->Data = Data; - AsyncReq->Callback = Callback; - AsyncReq->Context = Context; - AsyncReq->QhSw = Qh; - AsyncReq->FirstTd = FirstTd; - AsyncReq->IsLow = IsLow; - - // - // Insert the new interrupt transfer to the head of the list. - // The interrupt transfer's monitor function scans the whole - // list from head to tail. The new interrupt transfer MUST be - // added to the head of the list. - // - InsertHeadList (&(Uhc->AsyncIntList), &(AsyncReq->Link)); - - return EFI_SUCCESS; -} - - -/** - Free an asynchronous request's resource such as memory. - - @param Uhc The UHCI device. - @param AsyncReq The asynchronous request to free. - -**/ -VOID -UhciFreeAsyncReq ( - IN USB_HC_DEV *Uhc, - IN UHCI_ASYNC_REQUEST *AsyncReq - ) -{ - ASSERT ((Uhc != NULL) && (AsyncReq != NULL)); - - UhciDestoryTds (Uhc, AsyncReq->FirstTd); - UsbHcFreeMem (Uhc->MemPool, AsyncReq->QhSw, sizeof (UHCI_QH_SW)); - - if (AsyncReq->Data != NULL) { - UsbHcFreeMem (Uhc->MemPool, AsyncReq->Data, AsyncReq->DataLen); - } - - gBS->FreePool (AsyncReq); -} - - -/** - Unlink an asynchronous request's from UHC's asynchronus list. - also remove the queue head from the frame list. If FreeNow, - release its resource also. Otherwise, add the request to the - UHC's recycle list to wait for a while before release the memory. - Until then, hardware won't hold point to the request. - - @param Uhc The UHCI device. - @param AsyncReq The asynchronous request to free. - @param FreeNow If TRUE, free the resource immediately, otherwise - add the request to recycle wait list. - -**/ -VOID -UhciUnlinkAsyncReq ( - IN USB_HC_DEV *Uhc, - IN UHCI_ASYNC_REQUEST *AsyncReq, - IN BOOLEAN FreeNow - ) -{ - ASSERT ((Uhc != NULL) && (AsyncReq != NULL)); - - RemoveEntryList (&(AsyncReq->Link)); - UhciUnlinkQhFromFrameList (Uhc, AsyncReq->QhSw); - - if (FreeNow) { - UhciFreeAsyncReq (Uhc, AsyncReq); - } else { - // - // To sychronize with hardware, mark the queue head as inactive - // then add AsyncReq to UHC's recycle list - // - AsyncReq->QhSw->QhHw.VerticalLink = QH_VLINK (NULL, TRUE); - AsyncReq->Recycle = Uhc->RecycleWait; - Uhc->RecycleWait = AsyncReq; - } -} - - -/** - Delete Async Interrupt QH and TDs. - - @param Uhc The UHCI device. - @param DevAddr Device Address. - @param EndPoint EndPoint Address. - @param Toggle The next data toggle to use. - - @retval EFI_SUCCESS The request is deleted. - @retval EFI_INVALID_PARAMETER Paremeter is error. - @retval EFI_NOT_FOUND The asynchronous isn't found. - -**/ -EFI_STATUS -UhciRemoveAsyncReq ( - IN USB_HC_DEV *Uhc, - IN UINT8 DevAddr, - IN UINT8 EndPoint, - OUT UINT8 *Toggle - ) -{ - EFI_STATUS Status; - UHCI_ASYNC_REQUEST *AsyncReq; - UHCI_QH_RESULT QhResult; - LIST_ENTRY *Link; - BOOLEAN Found; - - Status = EFI_SUCCESS; - - // - // If no asynchronous interrupt transaction exists - // - if (IsListEmpty (&(Uhc->AsyncIntList))) { - return EFI_SUCCESS; - } - - // - // Find the asynchronous transfer to this device/endpoint pair - // - Found = FALSE; - Link = Uhc->AsyncIntList.ForwardLink; - - do { - AsyncReq = UHCI_ASYNC_INT_FROM_LINK (Link); - Link = Link->ForwardLink; - - if ((AsyncReq->DevAddr == DevAddr) && (AsyncReq->EndPoint == EndPoint)) { - Found = TRUE; - break; - } - - } while (Link != &(Uhc->AsyncIntList)); - - if (!Found) { - return EFI_NOT_FOUND; - } - - // - // Check the result of the async transfer then update it - // to get the next data toggle to use. - // - UhciCheckTdStatus (Uhc, AsyncReq->FirstTd, AsyncReq->IsLow, &QhResult); - *Toggle = QhResult.NextToggle; - - // - // Don't release the request now, keep it to synchronize with hardware. - // - UhciUnlinkAsyncReq (Uhc, AsyncReq, FALSE); - return Status; -} - - -/** - Recycle the asynchronouse request. When a queue head - is unlinked from frame list, host controller hardware - may still hold a cached pointer to it. To synchronize - with hardware, the request is released in two steps: - first it is linked to the UHC's RecycleWait list. At - the next time UhciMonitorAsyncReqList is fired, it is - moved to UHC's Recylelist. Then, at another timer - activation, all the requests on Recycle list is freed. - This guarrantes that each unlink queue head keeps - existing for at least 50ms, far enough for the hardware - to clear its cache. - - @param Uhc The UHCI device. - -**/ -VOID -UhciRecycleAsyncReq ( - IN USB_HC_DEV *Uhc - ) -{ - UHCI_ASYNC_REQUEST *Req; - UHCI_ASYNC_REQUEST *Next; - - Req = Uhc->Recycle; - - while (Req != NULL) { - Next = Req->Recycle; - UhciFreeAsyncReq (Uhc, Req); - Req = Next; - } - - Uhc->Recycle = Uhc->RecycleWait; - Uhc->RecycleWait = NULL; -} - - - -/** - Release all the asynchronous transfers on the lsit. - - @param Uhc The UHCI device. - -**/ -VOID -UhciFreeAllAsyncReq ( - IN USB_HC_DEV *Uhc - ) -{ - LIST_ENTRY *Head; - UHCI_ASYNC_REQUEST *AsyncReq; - - // - // Call UhciRecycleAsyncReq twice. The requests on Recycle - // will be released at the first call; The requests on - // RecycleWait will be released at the second call. - // - UhciRecycleAsyncReq (Uhc); - UhciRecycleAsyncReq (Uhc); - - Head = &(Uhc->AsyncIntList); - - if (IsListEmpty (Head)) { - return; - } - - while (!IsListEmpty (Head)) { - AsyncReq = UHCI_ASYNC_INT_FROM_LINK (Head->ForwardLink); - UhciUnlinkAsyncReq (Uhc, AsyncReq, TRUE); - } -} - - -/** - Interrupt transfer periodic check handler. - - @param Event The event of the time. - @param Context Context of the event, pointer to USB_HC_DEV. - -**/ -VOID -EFIAPI -UhciMonitorAsyncReqList ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - UHCI_ASYNC_REQUEST *AsyncReq; - LIST_ENTRY *Link; - USB_HC_DEV *Uhc; - VOID *Data; - BOOLEAN Finished; - UHCI_QH_RESULT QhResult; - - Uhc = (USB_HC_DEV *) Context; - - // - // Recycle the asynchronous requests expired, and promote - // requests waiting to be recycled the next time when this - // timer expires - // - UhciRecycleAsyncReq (Uhc); - - if (IsListEmpty (&(Uhc->AsyncIntList))) { - return ; - } - - // - // This loop must be delete safe - // - Link = Uhc->AsyncIntList.ForwardLink; - - do { - AsyncReq = UHCI_ASYNC_INT_FROM_LINK (Link); - Link = Link->ForwardLink; - - Finished = UhciCheckTdStatus (Uhc, AsyncReq->FirstTd, AsyncReq->IsLow, &QhResult); - - if (!Finished) { - continue; - } - - // - // Copy the data to temporary buffer if there are some - // data transferred. We may have zero-length packet - // - Data = NULL; - - if (QhResult.Complete != 0) { - Data = AllocatePool (QhResult.Complete); - - if (Data == NULL) { - return ; - } - - CopyMem (Data, AsyncReq->FirstTd->Data, QhResult.Complete); - } - - UhciUpdateAsyncReq (Uhc, AsyncReq, QhResult.Result, QhResult.NextToggle); - - // - // Now, either transfer is SUCCESS or met errors since - // we have skipped to next transfer earlier if current - // transfer is still active. - // - if (QhResult.Result == EFI_USB_NOERROR) { - AsyncReq->Callback (Data, QhResult.Complete, AsyncReq->Context, QhResult.Result); - } else { - // - // Leave error recovery to its related device driver. - // A common case of the error recovery is to re-submit - // the interrupt transfer. When an interrupt transfer - // is re-submitted, its position in the linked list is - // changed. It is inserted to the head of the linked - // list, while this function scans the whole list from - // head to tail. Thus, the re-submitted interrupt transfer's - // callback function will not be called again in this round. - // - AsyncReq->Callback (NULL, 0, AsyncReq->Context, QhResult.Result); - } - - if (Data != NULL) { - gBS->FreePool (Data); - } - } while (Link != &(Uhc->AsyncIntList)); -} diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.h b/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.h deleted file mode 100644 index f6d4fc40a7..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.h +++ /dev/null @@ -1,271 +0,0 @@ -/** @file - - The definition for EHCI register operation routines. - -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_UHCI_SCHED_H_ -#define _EFI_UHCI_SCHED_H_ - - -#define UHCI_ASYNC_INT_SIGNATURE SIGNATURE_32 ('u', 'h', 'c', 'a') -// -// The failure mask for USB transfer return status. If any of -// these bit is set, the transfer failed. EFI_USB_ERR_NOEXECUTE -// and EFI_USB_ERR_NAK are not considered as error condition: -// the transfer is still going on. -// -#define USB_ERR_FAIL_MASK (EFI_USB_ERR_STALL | EFI_USB_ERR_BUFFER | \ - EFI_USB_ERR_BABBLE | EFI_USB_ERR_CRC | \ - EFI_USB_ERR_TIMEOUT | EFI_USB_ERR_BITSTUFF | \ - EFI_USB_ERR_SYSTEM) - - -// -// Structure to return the result of UHCI QH execution. -// Result is the final result of the QH's QTD. NextToggle -// is the next data toggle to use. Complete is the actual -// length of data transferred. -// -typedef struct { - UINT32 Result; - UINT8 NextToggle; - UINTN Complete; -} UHCI_QH_RESULT; - -typedef struct _UHCI_ASYNC_REQUEST UHCI_ASYNC_REQUEST; - -// -// Structure used to manager the asynchronous interrupt transfers. -// -struct _UHCI_ASYNC_REQUEST{ - UINTN Signature; - LIST_ENTRY Link; - UHCI_ASYNC_REQUEST *Recycle; - - // - // Endpoint attributes - // - UINT8 DevAddr; - UINT8 EndPoint; - BOOLEAN IsLow; - UINTN Interval; - - // - // Data and UHC structures - // - UHCI_QH_SW *QhSw; - UHCI_TD_SW *FirstTd; - UINT8 *Data; // Allocated host memory, not mapped memory - UINTN DataLen; - VOID *Mapping; - - // - // User callback and its context - // - EFI_ASYNC_USB_TRANSFER_CALLBACK Callback; - VOID *Context; -}; - -#define UHCI_ASYNC_INT_FROM_LINK(a) \ - CR (a, UHCI_ASYNC_REQUEST, Link, UHCI_ASYNC_INT_SIGNATURE) - - -/** - Create Frame List Structure. - - @param Uhc The UHCI device. - - @return EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @return EFI_UNSUPPORTED Map memory fail. - @return EFI_SUCCESS Success. - -**/ -EFI_STATUS -UhciInitFrameList ( - IN USB_HC_DEV *Uhc - ); - -/** - Destory FrameList buffer. - - @param Uhc The UHCI device. - - @return None. - -**/ -VOID -UhciDestoryFrameList ( - IN USB_HC_DEV *Uhc - ); - - -/** - Convert the poll rate to the maxium 2^n that is smaller - than Interval. - - @param Interval The poll rate to convert. - - @return The converted poll rate. - -**/ -UINTN -UhciConvertPollRate ( - IN UINTN Interval - ); - - -/** - Link a queue head (for asynchronous interrupt transfer) to - the frame list. - - @param Uhc The UHCI device. - @param Qh The queue head to link into. - -**/ -VOID -UhciLinkQhToFrameList ( - USB_HC_DEV *Uhc, - UHCI_QH_SW *Qh - ); - - -/** - Unlink QH from the frame list is easier: find all - the precedence node, and pointer there next to QhSw's - next. - - @param Uhc The UHCI device. - @param Qh The queue head to unlink. - -**/ -VOID -UhciUnlinkQhFromFrameList ( - USB_HC_DEV *Uhc, - UHCI_QH_SW *Qh - ); - - -/** - Check the result of the transfer. - - @param Uhc The UHCI device. - @param Qh The queue head of the transfer. - @param Td The first TDs of the transfer. - @param TimeOut TimeOut value in milliseconds. - @param IsLow Is Low Speed Device. - @param QhResult The variable to return result. - - @retval EFI_SUCCESS The transfer finished with success. - @retval EFI_DEVICE_ERROR Transfer failed. - -**/ -EFI_STATUS -UhciExecuteTransfer ( - IN USB_HC_DEV *Uhc, - IN UHCI_QH_SW *Qh, - IN UHCI_TD_SW *Td, - IN UINTN TimeOut, - IN BOOLEAN IsLow, - OUT UHCI_QH_RESULT *QhResult - ); - - -/** - Create Async Request node, and Link to List. - - @param Uhc The UHCI device. - @param Qh The queue head of the transfer. - @param FirstTd First TD of the transfer. - @param DevAddr Device Address. - @param EndPoint EndPoint Address. - @param DataLen Data length. - @param Interval Polling Interval when inserted to frame list. - @param Data Data buffer, unmapped. - @param Callback Callback after interrupt transfeer. - @param Context Callback Context passed as function parameter. - @param IsLow Is Low Speed. - - @retval EFI_SUCCESS An asynchronous transfer is created. - @retval EFI_INVALID_PARAMETER Paremeter is error. - @retval EFI_OUT_OF_RESOURCES Failed because of resource shortage. - -**/ -EFI_STATUS -UhciCreateAsyncReq ( - IN USB_HC_DEV *Uhc, - IN UHCI_QH_SW *Qh, - IN UHCI_TD_SW *FirstTd, - IN UINT8 DevAddr, - IN UINT8 EndPoint, - IN UINTN DataLen, - IN UINTN Interval, - IN UINT8 *Data, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context, - IN BOOLEAN IsLow - ); - - -/** - Delete Async Interrupt QH and TDs. - - @param Uhc The UHCI device. - @param DevAddr Device Address. - @param EndPoint EndPoint Address. - @param Toggle The next data toggle to use. - - @retval EFI_SUCCESS The request is deleted. - @retval EFI_INVALID_PARAMETER Paremeter is error. - @retval EFI_NOT_FOUND The asynchronous isn't found. - -**/ -EFI_STATUS -UhciRemoveAsyncReq ( - IN USB_HC_DEV *Uhc, - IN UINT8 DevAddr, - IN UINT8 EndPoint, - OUT UINT8 *Toggle - ); - - -/** - Release all the asynchronous transfers on the lsit. - - @param Uhc The UHCI device. - - @return None. - -**/ -VOID -UhciFreeAllAsyncReq ( - IN USB_HC_DEV *Uhc - ); - - -/** - Interrupt transfer periodic check handler. - - @param Event The event of the time. - @param Context Context of the event, pointer to USB_HC_DEV. - - @return None. - -**/ -VOID -EFIAPI -UhciMonitorAsyncReqList ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c deleted file mode 100644 index e42d482885..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c +++ /dev/null @@ -1,564 +0,0 @@ -/** @file - - The routine procedure for uhci memory allocate/free. - -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Uhci.h" - - -/** - Allocate a block of memory to be used by the buffer pool. - - @param Pool The buffer pool to allocate memory for. - @param Pages How many pages to allocate. - - @return The allocated memory block or NULL if failed. - -**/ -USBHC_MEM_BLOCK * -UsbHcAllocMemBlock ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Pages - ) -{ - USBHC_MEM_BLOCK *Block; - EFI_PCI_IO_PROTOCOL *PciIo; - VOID *BufHost; - VOID *Mapping; - EFI_PHYSICAL_ADDRESS MappedAddr; - UINTN Bytes; - EFI_STATUS Status; - - PciIo = Pool->PciIo; - - Block = AllocateZeroPool (sizeof (USBHC_MEM_BLOCK)); - if (Block == NULL) { - return NULL; - } - - // - // each bit in the bit array represents USBHC_MEM_UNIT - // bytes of memory in the memory block. - // - ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE); - - Block->BufLen = EFI_PAGES_TO_SIZE (Pages); - Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8); - Block->Bits = AllocateZeroPool (Block->BitsLen); - - if (Block->Bits == NULL) { - gBS->FreePool (Block); - return NULL; - } - - // - // Allocate the number of Pages of memory, then map it for - // bus master read and write. - // - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - Pages, - &BufHost, - 0 - ); - - if (EFI_ERROR (Status)) { - goto FREE_BITARRAY; - } - - Bytes = EFI_PAGES_TO_SIZE (Pages); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - BufHost, - &Bytes, - &MappedAddr, - &Mapping - ); - - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) { - goto FREE_BUFFER; - } - - // - // Check whether the data structure used by the host controller - // should be restricted into the same 4G - // - if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) { - PciIo->Unmap (PciIo, Mapping); - goto FREE_BUFFER; - } - - Block->BufHost = BufHost; - Block->Buf = (UINT8 *) ((UINTN) MappedAddr); - Block->Mapping = Mapping; - - return Block; - -FREE_BUFFER: - PciIo->FreeBuffer (PciIo, Pages, BufHost); - -FREE_BITARRAY: - gBS->FreePool (Block->Bits); - gBS->FreePool (Block); - return NULL; -} - - -/** - Free the memory block from the memory pool. - - @param Pool The memory pool to free the block from. - @param Block The memory block to free. - -**/ -VOID -UsbHcFreeMemBlock ( - IN USBHC_MEM_POOL *Pool, - IN USBHC_MEM_BLOCK *Block - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - ASSERT ((Pool != NULL) && (Block != NULL)); - - PciIo = Pool->PciIo; - - // - // Unmap the common buffer then free the structures - // - PciIo->Unmap (PciIo, Block->Mapping); - PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost); - - gBS->FreePool (Block->Bits); - gBS->FreePool (Block); -} - - -/** - Alloc some memory from the block. - - @param Block The memory block to allocate memory from. - @param Units Number of memory units to allocate. - - @return EFI_SUCCESS The needed memory is allocated. - @return EFI_NOT_FOUND Can't find the free memory. - -**/ -VOID * -UsbHcAllocMemFromBlock ( - IN USBHC_MEM_BLOCK *Block, - IN UINTN Units - ) -{ - UINTN Byte; - UINT8 Bit; - UINTN StartByte; - UINT8 StartBit; - UINTN Available; - UINTN Count; - - ASSERT ((Block != 0) && (Units != 0)); - - StartByte = 0; - StartBit = 0; - Available = 0; - - for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) { - // - // If current bit is zero, the corresponding memory unit is - // available, otherwise we need to restart our searching. - // Available counts the consective number of zero bit. - // - if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) { - Available++; - - if (Available >= Units) { - break; - } - - NEXT_BIT (Byte, Bit); - - } else { - NEXT_BIT (Byte, Bit); - - Available = 0; - StartByte = Byte; - StartBit = Bit; - } - } - - if (Available < Units) { - return NULL; - } - - // - // Mark the memory as allocated - // - Byte = StartByte; - Bit = StartBit; - - for (Count = 0; Count < Units; Count++) { - ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT; -} - -/** - Calculate the corresponding pci bus address according to the Mem parameter. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to host memory. - @param Size The size of the memory region. - - @return the pci memory address -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetPciAddressForHostMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINTN AllocSize; - EFI_PHYSICAL_ADDRESS PhyAddr; - UINTN Offset; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - - if (Mem == NULL) { - return 0; - } - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the allocated memory. - // - if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) { - break; - } - } - - ASSERT ((Block != NULL)); - // - // calculate the pci memory address for host memory address. - // - Offset = (UINT8 *)Mem - Block->BufHost; - PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset); - return PhyAddr; -} - -/** - Insert the memory block to the pool's list of the blocks. - - @param Head The head of the memory pool's block list. - @param Block The memory block to insert. - -**/ -VOID -UsbHcInsertMemBlockToPool ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *Block - ) -{ - ASSERT ((Head != NULL) && (Block != NULL)); - Block->Next = Head->Next; - Head->Next = Block; -} - - -/** - Is the memory block empty? - - @param Block The memory block to check. - - @return TRUE The memory block is empty. - @return FALSE The memory block isn't empty. - -**/ -BOOLEAN -UsbHcIsMemBlockEmpty ( - IN USBHC_MEM_BLOCK *Block - ) -{ - UINTN Index; - - for (Index = 0; Index < Block->BitsLen; Index++) { - if (Block->Bits[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - - -/** - Unlink the memory block from the pool's list. - - @param Head The block list head of the memory's pool. - @param BlockToUnlink The memory block to unlink. - -**/ -VOID -UsbHcUnlinkMemBlock ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *BlockToUnlink - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT ((Head != NULL) && (BlockToUnlink != NULL)); - - for (Block = Head; Block != NULL; Block = Block->Next) { - if (Block->Next == BlockToUnlink) { - Block->Next = BlockToUnlink->Next; - BlockToUnlink->Next = NULL; - break; - } - } -} - - -/** - Initialize the memory management pool for the host controller. - - @param PciIo The PciIo that can be used to access the host controller. - @param Check4G Whether the host controller requires allocated memory - from one 4G address space. - @param Which4G The 4G memory area each memory allocated should be from. - - @return EFI_SUCCESS The memory pool is initialized. - @return EFI_OUT_OF_RESOURCE Fail to init the memory pool. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN BOOLEAN Check4G, - IN UINT32 Which4G - ) -{ - USBHC_MEM_POOL *Pool; - - Pool = AllocatePool (sizeof (USBHC_MEM_POOL)); - - if (Pool == NULL) { - return Pool; - } - - Pool->PciIo = PciIo; - Pool->Check4G = Check4G; - Pool->Which4G = Which4G; - Pool->Head = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES); - - if (Pool->Head == NULL) { - gBS->FreePool (Pool); - Pool = NULL; - } - - return Pool; -} - - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - - @return EFI_SUCCESS The memory pool is freed. - @return EFI_DEVICE_ERROR Failed to free the memory pool. - -**/ -EFI_STATUS -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT (Pool->Head != NULL); - - // - // Unlink all the memory blocks from the pool, then free them. - // UsbHcUnlinkMemBlock can't be used to unlink and free the - // first block. - // - for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) { - UsbHcUnlinkMemBlock (Pool->Head, Block); - UsbHcFreeMemBlock (Pool, Block); - } - - UsbHcFreeMemBlock (Pool, Pool->Head); - gBS->FreePool (Pool); - return EFI_SUCCESS; -} - - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - USBHC_MEM_BLOCK *NewBlock; - VOID *Mem; - UINTN AllocSize; - UINTN Pages; - - Mem = NULL; - AllocSize = USBHC_MEM_ROUND (Size); - Head = Pool->Head; - ASSERT (Head != NULL); - - // - // First check whether current memory blocks can satisfy the allocation. - // - for (Block = Head; Block != NULL; Block = Block->Next) { - Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - break; - } - } - - if (Mem != NULL) { - return Mem; - } - - // - // Create a new memory block if there is not enough memory - // in the pool. If the allocation size is larger than the - // default page number, just allocate a large enough memory - // block. Otherwise allocate default pages. - // - if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) { - Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1; - } else { - Pages = USBHC_MEM_DEFAULT_PAGES; - } - - NewBlock = UsbHcAllocMemBlock (Pool, Pages); - - if (NewBlock == NULL) { - DEBUG ((EFI_D_INFO, "UsbHcAllocateMem: failed to allocate block\n")); - return NULL; - } - - // - // Add the new memory block to the pool, then allocate memory from it - // - UsbHcInsertMemBlockToPool (Head, NewBlock); - Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - } - - return Mem; -} - - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINT8 *ToFree; - UINTN AllocSize; - UINTN Byte; - UINTN Bit; - UINTN Count; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - ToFree = (UINT8 *) Mem; - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the memory to free. - // - if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) { - // - // compute the start byte and bit in the bit array - // - Byte = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) / 8; - Bit = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) % 8; - - // - // reset associated bits in bit arry - // - for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) { - ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - break; - } - } - - // - // If Block == NULL, it means that the current memory isn't - // in the host controller's pool. This is critical because - // the caller has passed in a wrong memory point - // - ASSERT (Block != NULL); - - // - // Release the current memory block if it is empty and not the head - // - if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) { - UsbHcUnlinkMemBlock (Head, Block); - UsbHcFreeMemBlock (Pool, Block); - } - - return ; -} diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.h deleted file mode 100644 index c53d0b78f2..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.h +++ /dev/null @@ -1,161 +0,0 @@ -/** @file - - This file contains the definination for host controller memory management routines - -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_EHCI_MEM_H_ -#define _EFI_EHCI_MEM_H_ - -#define USB_HC_BIT(a) ((UINTN)(1 << (a))) - -#define USB_HC_BIT_IS_SET(Data, Bit) \ - ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit))) - -#define USB_HC_HIGH_32BIT(Addr64) \ - ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF)) - - -typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK; -struct _USBHC_MEM_BLOCK { - UINT8 *Bits; // Bit array to record which unit is allocated - UINTN BitsLen; - UINT8 *Buf; - UINT8 *BufHost; - UINTN BufLen; // Memory size in bytes - VOID *Mapping; - USBHC_MEM_BLOCK *Next; -}; - -// -// USBHC_MEM_POOL is used to manage the memory used by USB -// host controller. EHCI requires the control memory and transfer -// data to be on the same 4G memory. -// -typedef struct _USBHC_MEM_POOL { - EFI_PCI_IO_PROTOCOL *PciIo; - BOOLEAN Check4G; - UINT32 Which4G; - USBHC_MEM_BLOCK *Head; -} USBHC_MEM_POOL; - -// -// Memory allocation unit, must be 2^n, n>4 -// -#define USBHC_MEM_UNIT 64 - -#define USBHC_MEM_UNIT_MASK (USBHC_MEM_UNIT - 1) -#define USBHC_MEM_DEFAULT_PAGES 16 - -#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK)) - -// -// Advance the byte and bit to the next bit, adjust byte accordingly. -// -#define NEXT_BIT(Byte, Bit) \ - do { \ - (Bit)++; \ - if ((Bit) > 7) { \ - (Byte)++; \ - (Bit) = 0; \ - } \ - } while (0) - - -/** - Initialize the memory management pool for the host controller. - - @param PciIo The PciIo that can be used to access the host controller. - @param Check4G Whether the host controller requires allocated memory - from one 4G address space. - @param Which4G The 4G memory area each memory allocated should be from. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN BOOLEAN Check4G, - IN UINT32 Which4G - ); - - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - - @return EFI_SUCCESS The memory pool is freed. - @return EFI_DEVICE_ERROR Failed to free the memory pool. - -**/ -EFI_STATUS -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ); - - - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ); - - - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - - @return None. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -/** - Calculate the corresponding pci bus address according to the Mem parameter. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to host memory. - @param Size The size of the memory region. - - @return the pci memory address -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetPciAddressForHostMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.c b/MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.c deleted file mode 100644 index 368b75d753..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.c +++ /dev/null @@ -1,3219 +0,0 @@ -/** @file -PEIM to produce gPeiUsbHostControllerPpiGuid based on gPeiUsbControllerPpiGuid -which is used to enable recovery function from USB Drivers. - -Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "UhcPeim.h" - -/** - Initializes Usb Host Controller. - - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCCESS PPI successfully installed. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -EFIAPI -UhcPeimEntry ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - PEI_USB_CONTROLLER_PPI *ChipSetUsbControllerPpi; - EFI_STATUS Status; - UINT8 Index; - UINTN ControllerType; - UINTN BaseAddress; - UINTN MemPages; - USB_UHC_DEV *UhcDev; - EFI_PHYSICAL_ADDRESS TempPtr; - - // - // Shadow this PEIM to run from memory - // - if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { - return EFI_SUCCESS; - } - - Status = PeiServicesLocatePpi ( - &gPeiUsbControllerPpiGuid, - 0, - NULL, - (VOID **) &ChipSetUsbControllerPpi - ); - // - // If failed to locate, it is a bug in dispather as depex has gPeiUsbControllerPpiGuid. - // - ASSERT_EFI_ERROR (Status); - - Index = 0; - while (TRUE) { - Status = ChipSetUsbControllerPpi->GetUsbController ( - (EFI_PEI_SERVICES **) PeiServices, - ChipSetUsbControllerPpi, - Index, - &ControllerType, - &BaseAddress - ); - // - // When status is error, meant no controller is found - // - if (EFI_ERROR (Status)) { - break; - } - - // - // This PEIM is for UHC type controller. - // - if (ControllerType != PEI_UHCI_CONTROLLER) { - Index++; - continue; - } - - MemPages = sizeof (USB_UHC_DEV) / EFI_PAGE_SIZE + 1; - - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - MemPages, - &TempPtr - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - UhcDev = (USB_UHC_DEV *) ((UINTN) TempPtr); - UhcDev->Signature = USB_UHC_DEV_SIGNATURE; - UhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress; - - // - // Init local memory management service - // - Status = InitializeMemoryManagement (UhcDev); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Initialize Uhc's hardware - // - Status = InitializeUsbHC (UhcDev); - if (EFI_ERROR (Status)) { - return Status; - } - - UhcDev->UsbHostControllerPpi.ControlTransfer = UhcControlTransfer; - UhcDev->UsbHostControllerPpi.BulkTransfer = UhcBulkTransfer; - UhcDev->UsbHostControllerPpi.GetRootHubPortNumber = UhcGetRootHubPortNumber; - UhcDev->UsbHostControllerPpi.GetRootHubPortStatus = UhcGetRootHubPortStatus; - UhcDev->UsbHostControllerPpi.SetRootHubPortFeature = UhcSetRootHubPortFeature; - UhcDev->UsbHostControllerPpi.ClearRootHubPortFeature = UhcClearRootHubPortFeature; - - UhcDev->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); - UhcDev->PpiDescriptor.Guid = &gPeiUsbHostControllerPpiGuid; - UhcDev->PpiDescriptor.Ppi = &UhcDev->UsbHostControllerPpi; - - Status = PeiServicesInstallPpi (&UhcDev->PpiDescriptor); - if (EFI_ERROR (Status)) { - Index++; - continue; - } - - Index++; - } - - return EFI_SUCCESS; -} - -/** - Submits control transfer to a target USB device. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. - @param DeviceAddress The target device address. - @param DeviceSpeed Target device speed. - @param MaximumPacketLength Maximum packet size the default control transfer - endpoint is capable of sending or receiving. - @param Request USB device request to send. - @param TransferDirection Specifies the data direction for the data stage. - @param Data Data buffer to be transmitted or received from USB device. - @param DataLength The size (in bytes) of the data buffer. - @param TimeOut Indicates the maximum timeout, in millisecond. - If Timeout is 0, then the caller must wait for the function - to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - @param TransferResult Return the result of this control transfer. - - @retval EFI_SUCCESS Transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT Transfer failed due to timeout. - @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -UhcControlTransfer ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 DeviceAddress, - IN UINT8 DeviceSpeed, - IN UINT8 MaximumPacketLength, - IN EFI_USB_DEVICE_REQUEST *Request, - IN EFI_USB_DATA_DIRECTION TransferDirection, - IN OUT VOID *Data OPTIONAL, - IN OUT UINTN *DataLength OPTIONAL, - IN UINTN TimeOut, - OUT UINT32 *TransferResult - ) -{ - USB_UHC_DEV *UhcDev; - UINT32 StatusReg; - UINT8 PktID; - QH_STRUCT *PtrQH; - TD_STRUCT *PtrTD; - TD_STRUCT *PtrPreTD; - TD_STRUCT *PtrSetupTD; - TD_STRUCT *PtrStatusTD; - EFI_STATUS Status; - UINT32 DataLen; - UINT8 *PtrDataSource; - UINT8 *Ptr; - UINT8 DataToggle; - - UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This); - - StatusReg = UhcDev->UsbHostControllerBaseAddress + USBSTS; - - PktID = INPUT_PACKET_ID; - - if (Request == NULL || TransferResult == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // if errors exist that cause host controller halt, - // then return EFI_DEVICE_ERROR. - // - - if (!IsStatusOK (UhcDev, StatusReg)) { - ClearStatusReg (UhcDev, StatusReg); - *TransferResult = EFI_USB_ERR_SYSTEM; - return EFI_DEVICE_ERROR; - } - - ClearStatusReg (UhcDev, StatusReg); - - // - // generate Setup Stage TD - // - - PtrQH = UhcDev->ConfigQH; - - GenSetupStageTD ( - UhcDev, - DeviceAddress, - 0, - DeviceSpeed, - (UINT8 *) Request, - (UINT8) sizeof (EFI_USB_DEVICE_REQUEST), - &PtrSetupTD - ); - - // - // link setup TD structures to QH structure - // - LinkTDToQH (PtrQH, PtrSetupTD); - - PtrPreTD = PtrSetupTD; - - // - // Data Stage of Control Transfer - // - switch (TransferDirection) { - - case EfiUsbDataIn: - PktID = INPUT_PACKET_ID; - PtrDataSource = Data; - DataLen = (UINT32) *DataLength; - Ptr = PtrDataSource; - break; - - case EfiUsbDataOut: - PktID = OUTPUT_PACKET_ID; - PtrDataSource = Data; - DataLen = (UINT32) *DataLength; - Ptr = PtrDataSource; - break; - - // - // no data stage - // - case EfiUsbNoData: - if (*DataLength != 0) { - return EFI_INVALID_PARAMETER; - } - - PktID = OUTPUT_PACKET_ID; - PtrDataSource = NULL; - DataLen = 0; - Ptr = NULL; - break; - - default: - return EFI_INVALID_PARAMETER; - } - - DataToggle = 1; - - PtrTD = PtrSetupTD; - while (DataLen > 0) { - // - // create TD structures and link together - // - UINT8 PacketSize; - - // - // PacketSize is the data load size of each TD carries. - // - PacketSize = (UINT8) DataLen; - if (DataLen > MaximumPacketLength) { - PacketSize = MaximumPacketLength; - } - - GenDataTD ( - UhcDev, - DeviceAddress, - 0, - Ptr, - PacketSize, - PktID, - DataToggle, - DeviceSpeed, - &PtrTD - ); - - // - // Link two TDs in vertical depth - // - LinkTDToTD (PtrPreTD, PtrTD); - PtrPreTD = PtrTD; - - DataToggle ^= 1; - Ptr += PacketSize; - DataLen -= PacketSize; - } - - // - // PtrPreTD points to the last TD before the Setup-Stage TD. - // - PtrPreTD = PtrTD; - - // - // Status Stage of Control Transfer - // - if (PktID == OUTPUT_PACKET_ID) { - PktID = INPUT_PACKET_ID; - } else { - PktID = OUTPUT_PACKET_ID; - } - // - // create Status Stage TD structure - // - CreateStatusTD ( - UhcDev, - DeviceAddress, - 0, - PktID, - DeviceSpeed, - &PtrStatusTD - ); - - LinkTDToTD (PtrPreTD, PtrStatusTD); - - // - // Poll QH-TDs execution and get result. - // detail status is returned - // - Status = ExecuteControlTransfer ( - UhcDev, - PtrSetupTD, - DataLength, - TimeOut, - TransferResult - ); - - // - // TRUE means must search other framelistindex - // - SetQHVerticalValidorInvalid(PtrQH, FALSE); - DeleteQueuedTDs (UhcDev, PtrSetupTD); - - // - // if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly. - // - if (!IsStatusOK (UhcDev, StatusReg)) { - - ClearStatusReg (UhcDev, StatusReg); - *TransferResult |= EFI_USB_ERR_SYSTEM; - return EFI_DEVICE_ERROR; - } - - ClearStatusReg (UhcDev, StatusReg); - - return Status; -} - -/** - Submits bulk transfer to a bulk endpoint of a USB device. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction in bit 7. - @param MaximumPacketLength Maximum packet size the endpoint is capable of - sending or receiving. - @param Data Array of pointers to the buffers of data to transmit - from or receive into. - @param DataLength The lenght of the data buffer. - @param DataToggle On input, the initial data toggle for the transfer; - On output, it is updated to to next data toggle to use of - the subsequent bulk transfer. - @param TimeOut Indicates the maximum time, in millisecond, which the - transfer is allowed to complete. - If Timeout is 0, then the caller must wait for the function - to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - @param TransferResult A pointer to the detailed result information of the - bulk transfer. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @retval EFI_INVALID_PARAMETER Parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -UhcBulkTransfer ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 MaximumPacketLength, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN TimeOut, - OUT UINT32 *TransferResult - ) -{ - USB_UHC_DEV *UhcDev; - UINT32 StatusReg; - - UINT32 DataLen; - - QH_STRUCT *PtrQH; - TD_STRUCT *PtrFirstTD; - TD_STRUCT *PtrTD; - TD_STRUCT *PtrPreTD; - - UINT8 PktID; - UINT8 *PtrDataSource; - UINT8 *Ptr; - - BOOLEAN IsFirstTD; - - EFI_STATUS Status; - - EFI_USB_DATA_DIRECTION TransferDirection; - - BOOLEAN ShortPacketEnable; - - UINT16 CommandContent; - - UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This); - - // - // Enable the maximum packet size (64bytes) - // that can be used for full speed bandwidth reclamation - // at the end of a frame. - // - CommandContent = USBReadPortW (UhcDev, UhcDev->UsbHostControllerBaseAddress + USBCMD); - if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) { - CommandContent |= USBCMD_MAXP; - USBWritePortW (UhcDev, UhcDev->UsbHostControllerBaseAddress + USBCMD, CommandContent); - } - - StatusReg = UhcDev->UsbHostControllerBaseAddress + USBSTS; - - // - // these code lines are added here per complier's strict demand - // - PktID = INPUT_PACKET_ID; - PtrTD = NULL; - PtrFirstTD = NULL; - PtrPreTD = NULL; - DataLen = 0; - Ptr = NULL; - - ShortPacketEnable = FALSE; - - if ((DataLength == 0) || (Data == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 1) && (*DataToggle != 0)) { - return EFI_INVALID_PARAMETER; - } - - if (MaximumPacketLength != 8 && MaximumPacketLength != 16 - && MaximumPacketLength != 32 && MaximumPacketLength != 64) { - return EFI_INVALID_PARAMETER; - } - // - // if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly. - // - if (!IsStatusOK (UhcDev, StatusReg)) { - - ClearStatusReg (UhcDev, StatusReg); - *TransferResult = EFI_USB_ERR_SYSTEM; - return EFI_DEVICE_ERROR; - } - - ClearStatusReg (UhcDev, StatusReg); - - if ((EndPointAddress & 0x80) != 0) { - TransferDirection = EfiUsbDataIn; - } else { - TransferDirection = EfiUsbDataOut; - } - - switch (TransferDirection) { - - case EfiUsbDataIn: - ShortPacketEnable = TRUE; - PktID = INPUT_PACKET_ID; - PtrDataSource = Data; - DataLen = (UINT32) *DataLength; - Ptr = PtrDataSource; - break; - - case EfiUsbDataOut: - PktID = OUTPUT_PACKET_ID; - PtrDataSource = Data; - DataLen = (UINT32) *DataLength; - Ptr = PtrDataSource; - break; - - default: - break; - } - - PtrQH = UhcDev->BulkQH; - - IsFirstTD = TRUE; - while (DataLen > 0) { - // - // create TD structures and link together - // - UINT8 PacketSize; - - PacketSize = (UINT8) DataLen; - if (DataLen > MaximumPacketLength) { - PacketSize = MaximumPacketLength; - } - - GenDataTD ( - UhcDev, - DeviceAddress, - EndPointAddress, - Ptr, - PacketSize, - PktID, - *DataToggle, - USB_FULL_SPEED_DEVICE, - &PtrTD - ); - - // - // Enable short packet detection. - // (default action is disabling short packet detection) - // - if (ShortPacketEnable) { - EnableorDisableTDShortPacket (PtrTD, TRUE); - } - - if (IsFirstTD) { - PtrFirstTD = PtrTD; - PtrFirstTD->PtrNextTD = NULL; - IsFirstTD = FALSE; - } else { - // - // Link two TDs in vertical depth - // - LinkTDToTD (PtrPreTD, PtrTD); - } - - PtrPreTD = PtrTD; - - *DataToggle ^= 1; - Ptr += PacketSize; - DataLen -= PacketSize; - } - // - // link TD structures to QH structure - // - LinkTDToQH (PtrQH, PtrFirstTD); - - // - // Execute QH-TD and get result - // - // - // detail status is put into the Result field in the pIRP - // the Data Toggle value is also re-updated to the value - // of the last successful TD - // - Status = ExecBulkTransfer ( - UhcDev, - PtrFirstTD, - DataLength, - DataToggle, - TimeOut, - TransferResult - ); - - // - // Delete Bulk transfer TD structure - // - DeleteQueuedTDs (UhcDev, PtrFirstTD); - - // - // if has errors that cause host controller halt, then return EFI_DEVICE_ERROR directly. - // - if (!IsStatusOK (UhcDev, StatusReg)) { - - ClearStatusReg (UhcDev, StatusReg); - *TransferResult |= EFI_USB_ERR_SYSTEM; - return EFI_DEVICE_ERROR; - } - - ClearStatusReg (UhcDev, StatusReg); - - return Status; -} - -/** - Retrieves the number of root hub ports. - - @param[in] PeiServices The pointer to the PEI Services Table. - @param[in] This The pointer to this instance of the - PEI_USB_HOST_CONTROLLER_PPI. - @param[out] PortNumber The pointer to the number of the root hub ports. - - @retval EFI_SUCCESS The port number was retrieved successfully. - @retval EFI_INVALID_PARAMETER PortNumber is NULL. - -**/ -EFI_STATUS -EFIAPI -UhcGetRootHubPortNumber ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - OUT UINT8 *PortNumber - ) -{ - USB_UHC_DEV *UhcDev; - UINT32 PSAddr; - UINT16 RHPortControl; - UINT32 Index; - - UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This); - - if (PortNumber == NULL) { - return EFI_INVALID_PARAMETER; - } - - *PortNumber = 0; - - for (Index = 0; Index < 2; Index++) { - PSAddr = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + Index * 2; - RHPortControl = USBReadPortW (UhcDev, PSAddr); - // - // Port Register content is valid - // - if (RHPortControl != 0xff) { - (*PortNumber)++; - } - } - - return EFI_SUCCESS; -} - -/** - Retrieves the current status of a USB root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. - @param PortNumber The root hub port to retrieve the state from. - @param PortStatus Variable to receive the port state. - - @retval EFI_SUCCESS The status of the USB root hub port specified. - by PortNumber was returned in PortStatus. - @retval EFI_INVALID_PARAMETER PortNumber is invalid. - -**/ -EFI_STATUS -EFIAPI -UhcGetRootHubPortStatus ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - OUT EFI_USB_PORT_STATUS *PortStatus - ) -{ - USB_UHC_DEV *UhcDev; - UINT32 PSAddr; - UINT16 RHPortStatus; - UINT8 TotalPortNumber; - - if (PortStatus == NULL) { - return EFI_INVALID_PARAMETER; - } - - UhcGetRootHubPortNumber (PeiServices, This, &TotalPortNumber); - if (PortNumber > TotalPortNumber) { - return EFI_INVALID_PARAMETER; - } - - UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This); - PSAddr = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + PortNumber * 2; - - PortStatus->PortStatus = 0; - PortStatus->PortChangeStatus = 0; - - RHPortStatus = USBReadPortW (UhcDev, PSAddr); - - // - // Current Connect Status - // - if ((RHPortStatus & USBPORTSC_CCS) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION; - } - // - // Port Enabled/Disabled - // - if ((RHPortStatus & USBPORTSC_PED) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_ENABLE; - } - // - // Port Suspend - // - if ((RHPortStatus & USBPORTSC_SUSP) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND; - } - // - // Port Reset - // - if ((RHPortStatus & USBPORTSC_PR) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_RESET; - } - // - // Low Speed Device Attached - // - if ((RHPortStatus & USBPORTSC_LSDA) != 0) { - PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED; - } - // - // Fill Port Status Change bits - // - // - // Connect Status Change - // - if ((RHPortStatus & USBPORTSC_CSC) != 0) { - PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION; - } - // - // Port Enabled/Disabled Change - // - if ((RHPortStatus & USBPORTSC_PEDC) != 0) { - PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE; - } - - return EFI_SUCCESS; -} - -/** - Sets a feature for the specified root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI - @param PortNumber Root hub port to set. - @param PortFeature Feature to set. - - @retval EFI_SUCCESS The feature specified by PortFeature was set. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -EFIAPI -UhcSetRootHubPortFeature ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - USB_UHC_DEV *UhcDev; - UINT32 PSAddr; - UINT32 CommandRegAddr; - UINT16 RHPortControl; - UINT8 TotalPortNumber; - - UhcGetRootHubPortNumber (PeiServices, This, &TotalPortNumber); - if (PortNumber > TotalPortNumber) { - return EFI_INVALID_PARAMETER; - } - - UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This); - PSAddr = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + PortNumber * 2; - CommandRegAddr = UhcDev->UsbHostControllerBaseAddress + USBCMD; - - RHPortControl = USBReadPortW (UhcDev, PSAddr); - - switch (PortFeature) { - - case EfiUsbPortSuspend: - if ((USBReadPortW (UhcDev, CommandRegAddr) & USBCMD_EGSM) == 0) { - // - // if global suspend is not active, can set port suspend - // - RHPortControl &= 0xfff5; - RHPortControl |= USBPORTSC_SUSP; - } - break; - - case EfiUsbPortReset: - RHPortControl &= 0xfff5; - RHPortControl |= USBPORTSC_PR; - // - // Set the reset bit - // - break; - - case EfiUsbPortPower: - break; - - case EfiUsbPortEnable: - RHPortControl &= 0xfff5; - RHPortControl |= USBPORTSC_PED; - break; - - default: - return EFI_INVALID_PARAMETER; - } - - USBWritePortW (UhcDev, PSAddr, RHPortControl); - - return EFI_SUCCESS; -} - -/** - Clears a feature for the specified root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. - @param PortNumber Specifies the root hub port whose feature - is requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. - - @retval EFI_SUCCESS The feature specified by PortFeature was cleared - for the USB root hub port specified by PortNumber. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - -**/ -EFI_STATUS -EFIAPI -UhcClearRootHubPortFeature ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - USB_UHC_DEV *UhcDev; - UINT32 PSAddr; - UINT16 RHPortControl; - UINT8 TotalPortNumber; - - UhcGetRootHubPortNumber (PeiServices, This, &TotalPortNumber); - - if (PortNumber > TotalPortNumber) { - return EFI_INVALID_PARAMETER; - } - - UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS (This); - PSAddr = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + PortNumber * 2; - - RHPortControl = USBReadPortW (UhcDev, PSAddr); - - switch (PortFeature) { - // - // clear PORT_ENABLE feature means disable port. - // - case EfiUsbPortEnable: - RHPortControl &= 0xfff5; - RHPortControl &= ~USBPORTSC_PED; - break; - - // - // clear PORT_SUSPEND feature means resume the port. - // (cause a resume on the specified port if in suspend mode) - // - case EfiUsbPortSuspend: - RHPortControl &= 0xfff5; - RHPortControl &= ~USBPORTSC_SUSP; - break; - - // - // no operation - // - case EfiUsbPortPower: - break; - - // - // clear PORT_RESET means clear the reset signal. - // - case EfiUsbPortReset: - RHPortControl &= 0xfff5; - RHPortControl &= ~USBPORTSC_PR; - break; - - // - // clear connect status change - // - case EfiUsbPortConnectChange: - RHPortControl &= 0xfff5; - RHPortControl |= USBPORTSC_CSC; - break; - - // - // clear enable/disable status change - // - case EfiUsbPortEnableChange: - RHPortControl &= 0xfff5; - RHPortControl |= USBPORTSC_PEDC; - break; - - // - // root hub does not support this request - // - case EfiUsbPortSuspendChange: - break; - - // - // root hub does not support this request - // - case EfiUsbPortOverCurrentChange: - break; - - // - // root hub does not support this request - // - case EfiUsbPortResetChange: - break; - - default: - return EFI_INVALID_PARAMETER; - } - - USBWritePortW (UhcDev, PSAddr, RHPortControl); - - return EFI_SUCCESS; -} - -/** - Initialize UHCI. - - @param UhcDev UHCI Device. - - @retval EFI_SUCCESS UHCI successfully initialized. - @retval EFI_OUT_OF_RESOURCES Resource can not be allocated. - -**/ -EFI_STATUS -InitializeUsbHC ( - IN USB_UHC_DEV *UhcDev - ) -{ - EFI_STATUS Status; - UINT32 FrameListBaseAddrReg; - UINT32 CommandReg; - UINT16 Command; - - // - // Create and Initialize Frame List For the Host Controller. - // - Status = CreateFrameList (UhcDev); - if (EFI_ERROR (Status)) { - return Status; - } - - FrameListBaseAddrReg = UhcDev->UsbHostControllerBaseAddress + USBFLBASEADD; - CommandReg = UhcDev->UsbHostControllerBaseAddress + USBCMD; - - // - // Set Frame List Base Address to the specific register to inform the hardware. - // - SetFrameListBaseAddress (UhcDev, FrameListBaseAddrReg, (UINT32) (UINTN) (UhcDev->FrameListEntry)); - - Command = USBReadPortW (UhcDev, CommandReg); - Command |= USBCMD_GRESET; - USBWritePortW (UhcDev, CommandReg, Command); - - MicroSecondDelay (50 * 1000); - - - Command &= ~USBCMD_GRESET; - - USBWritePortW (UhcDev, CommandReg, Command); - - // - //UHCI spec page120 reset recovery time - // - MicroSecondDelay (20 * 1000); - - // - // Set Run/Stop bit to 1. - // - Command = USBReadPortW (UhcDev, CommandReg); - Command |= USBCMD_RS | USBCMD_MAXP; - USBWritePortW (UhcDev, CommandReg, Command); - - return EFI_SUCCESS; -} - -/** - Create Frame List Structure. - - @param UhcDev UHCI device. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -CreateFrameList ( - USB_UHC_DEV *UhcDev - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS FrameListBaseAddr; - FRAMELIST_ENTRY *FrameListPtr; - UINTN Index; - - // - // The Frame List ocupies 4K bytes, - // and must be aligned on 4-Kbyte boundaries. - // - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - 1, - &FrameListBaseAddr - ); - - if (Status != EFI_SUCCESS) { - return EFI_OUT_OF_RESOURCES; - } - - // - //Create Control QH and Bulk QH and link them into Framelist Entry - // - Status = CreateQH(UhcDev, &UhcDev->ConfigQH); - if (Status != EFI_SUCCESS) { - return EFI_OUT_OF_RESOURCES; - } - ASSERT (UhcDev->ConfigQH != NULL); - - Status = CreateQH(UhcDev, &UhcDev->BulkQH); - if (Status != EFI_SUCCESS) { - return EFI_OUT_OF_RESOURCES; - } - ASSERT (UhcDev->BulkQH != NULL); - - // - //Set the corresponding QH pointer - // - SetQHHorizontalLinkPtr(UhcDev->ConfigQH, UhcDev->BulkQH); - SetQHHorizontalQHorTDSelect (UhcDev->ConfigQH, TRUE); - SetQHHorizontalValidorInvalid (UhcDev->ConfigQH, TRUE); - - UhcDev->FrameListEntry = (FRAMELIST_ENTRY *) ((UINTN) FrameListBaseAddr); - - FrameListPtr = UhcDev->FrameListEntry; - - for (Index = 0; Index < 1024; Index++) { - FrameListPtr->FrameListPtrTerminate = 0; - FrameListPtr->FrameListPtr = (UINT32)(UINTN)UhcDev->ConfigQH >> 4; - FrameListPtr->FrameListPtrQSelect = 1; - FrameListPtr->FrameListRsvd = 0; - FrameListPtr ++; - } - - return EFI_SUCCESS; -} - -/** - Read a 16bit width data from Uhc HC IO space register. - - @param UhcDev The UHCI device. - @param Port The IO space address of the register. - - @retval the register content read. - -**/ -UINT16 -USBReadPortW ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 Port - ) -{ - return IoRead16 (Port); -} - -/** - Write a 16bit width data into Uhc HC IO space register. - - @param UhcDev The UHCI device. - @param Port The IO space address of the register. - @param Data The data written into the register. - -**/ -VOID -USBWritePortW ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 Port, - IN UINT16 Data - ) -{ - IoWrite16 (Port, Data); -} - -/** - Write a 32bit width data into Uhc HC IO space register. - - @param UhcDev The UHCI device. - @param Port The IO space address of the register. - @param Data The data written into the register. - -**/ -VOID -USBWritePortDW ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 Port, - IN UINT32 Data - ) -{ - IoWrite32 (Port, Data); -} - -/** - Clear the content of UHCI's Status Register. - - @param UhcDev The UHCI device. - @param StatusAddr The IO space address of the register. - -**/ -VOID -ClearStatusReg ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 StatusAddr - ) -{ - // - // Clear the content of UHCI's Status Register - // - USBWritePortW (UhcDev, StatusAddr, 0x003F); -} - -/** - Check whether the host controller operates well. - - @param UhcDev The UHCI device. - @param StatusRegAddr The io address of status register. - - @retval TRUE Host controller is working. - @retval FALSE Host controller is halted or system error. - -**/ -BOOLEAN -IsStatusOK ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 StatusRegAddr - ) -{ - UINT16 StatusValue; - - StatusValue = USBReadPortW (UhcDev, StatusRegAddr); - - if ((StatusValue & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) != 0) { - return FALSE; - } else { - return TRUE; - } -} - -/** - Get Current Frame Number. - - @param UhcDev The UHCI device. - @param FrameNumberAddr The address of frame list register. - - @retval The content of the frame list register. - -**/ -UINT16 -GetCurrentFrameNumber ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 FrameNumberAddr - ) -{ - // - // Gets value in the USB frame number register. - // - return (UINT16) (USBReadPortW (UhcDev, FrameNumberAddr) & 0x03FF); -} - -/** - Set Frame List Base Address. - - @param UhcDev The UHCI device. - @param FrameListRegAddr The address of frame list register. - @param Addr The address of frame list table. - -**/ -VOID -SetFrameListBaseAddress ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 FrameListRegAddr, - IN UINT32 Addr - ) -{ - // - // Sets value in the USB Frame List Base Address register. - // - USBWritePortDW (UhcDev, FrameListRegAddr, (UINT32) (Addr & 0xFFFFF000)); -} - -/** - Create QH and initialize. - - @param UhcDev The UHCI device. - @param PtrQH Place to store QH_STRUCT pointer. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -CreateQH ( - IN USB_UHC_DEV *UhcDev, - OUT QH_STRUCT **PtrQH - ) -{ - EFI_STATUS Status; - - // - // allocate align memory for QH_STRUCT - // - Status = AllocateTDorQHStruct (UhcDev, sizeof(QH_STRUCT), (void **)PtrQH); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - // - // init each field of the QH_STRUCT - // - SetQHHorizontalValidorInvalid (*PtrQH, FALSE); - SetQHVerticalValidorInvalid (*PtrQH, FALSE); - - return EFI_SUCCESS; -} - -/** - Set the horizontal link pointer in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param PtrNext Place to the next QH_STRUCT. - -**/ -VOID -SetQHHorizontalLinkPtr ( - IN QH_STRUCT *PtrQH, - IN VOID *PtrNext - ) -{ - // - // Since the QH_STRUCT is aligned on 16-byte boundaries, - // Only the highest 28bit of the address is valid - // (take 32bit address as an example). - // - PtrQH->QueueHead.QHHorizontalPtr = (UINT32) (UINTN) PtrNext >> 4; -} - -/** - Get the horizontal link pointer in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - - @retval The horizontal link pointer in QH. - -**/ -VOID * -GetQHHorizontalLinkPtr ( - IN QH_STRUCT *PtrQH - ) -{ - // - // Restore the 28bit address to 32bit address - // (take 32bit address as an example) - // - return (VOID *) (UINTN) ((PtrQH->QueueHead.QHHorizontalPtr) << 4); -} - -/** - Set a QH or TD horizontally to be connected with a specific QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param IsQH Specify QH or TD is connected. - -**/ -VOID -SetQHHorizontalQHorTDSelect ( - IN QH_STRUCT *PtrQH, - IN BOOLEAN IsQH - ) -{ - // - // if QH is connected, the specified bit is set, - // if TD is connected, the specified bit is cleared. - // - PtrQH->QueueHead.QHHorizontalQSelect = IsQH ? 1 : 0; -} - -/** - Set the horizontal validor bit in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param IsValid Specify the horizontal linker is valid or not. - -**/ -VOID -SetQHHorizontalValidorInvalid ( - IN QH_STRUCT *PtrQH, - IN BOOLEAN IsValid - ) -{ - // - // Valid means the horizontal link pointer is valid, - // else, it's invalid. - // - PtrQH->QueueHead.QHHorizontalTerminate = IsValid ? 0 : 1; -} - -/** - Set the vertical link pointer in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param PtrNext Place to the next QH_STRUCT. - -**/ -VOID -SetQHVerticalLinkPtr ( - IN QH_STRUCT *PtrQH, - IN VOID *PtrNext - ) -{ - // - // Since the QH_STRUCT is aligned on 16-byte boundaries, - // Only the highest 28bit of the address is valid - // (take 32bit address as an example). - // - PtrQH->QueueHead.QHVerticalPtr = (UINT32) (UINTN) PtrNext >> 4; -} - -/** - Set a QH or TD vertically to be connected with a specific QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param IsQH Specify QH or TD is connected. - -**/ -VOID -SetQHVerticalQHorTDSelect ( - IN QH_STRUCT *PtrQH, - IN BOOLEAN IsQH - ) -{ - // - // Set the specified bit if the Vertical Link Pointer pointing to a QH, - // Clear the specified bit if the Vertical Link Pointer pointing to a TD. - // - PtrQH->QueueHead.QHVerticalQSelect = IsQH ? 1 : 0; -} - -/** - Set the vertical validor bit in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param IsValid Specify the vertical linker is valid or not. - -**/ -VOID -SetQHVerticalValidorInvalid ( - IN QH_STRUCT *PtrQH, - IN BOOLEAN IsValid - ) -{ - // - // If TRUE, meaning the Vertical Link Pointer field is valid, - // else, the field is invalid. - // - PtrQH->QueueHead.QHVerticalTerminate = IsValid ? 0 : 1; -} - -/** - Get the vertical validor bit in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - - @retval The vertical linker is valid or not. - -**/ -BOOLEAN -GetQHHorizontalValidorInvalid ( - IN QH_STRUCT *PtrQH - ) -{ - // - // If TRUE, meaning the Horizontal Link Pointer field is valid, - // else, the field is invalid. - // - return (BOOLEAN) (!(PtrQH->QueueHead.QHHorizontalTerminate)); -} - -/** - Allocate TD or QH Struct. - - @param UhcDev The UHCI device. - @param Size The size of allocation. - @param PtrStruct Place to store TD_STRUCT pointer. - - @return EFI_SUCCESS Allocate successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -AllocateTDorQHStruct ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 Size, - OUT VOID **PtrStruct - ) -{ - EFI_STATUS Status; - - Status = EFI_SUCCESS; - *PtrStruct = NULL; - - Status = UhcAllocatePool ( - UhcDev, - (UINT8 **) PtrStruct, - Size - ); - if (EFI_ERROR (Status)) { - return Status; - } - - ZeroMem (*PtrStruct, Size); - - return Status; -} - -/** - Create a TD Struct. - - @param UhcDev The UHCI device. - @param PtrTD Place to store TD_STRUCT pointer. - - @return EFI_SUCCESS Allocate successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -CreateTD ( - IN USB_UHC_DEV *UhcDev, - OUT TD_STRUCT **PtrTD - ) -{ - EFI_STATUS Status; - // - // create memory for TD_STRUCT, and align the memory. - // - Status = AllocateTDorQHStruct (UhcDev, sizeof(TD_STRUCT), (void **)PtrTD); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Make TD ready. - // - SetTDLinkPtrValidorInvalid (*PtrTD, FALSE); - - return EFI_SUCCESS; -} - -/** - Generate Setup Stage TD. - - @param UhcDev The UHCI device. - @param DevAddr Device address. - @param Endpoint Endpoint number. - @param DeviceSpeed Device Speed. - @param DevRequest Device reuquest. - @param RequestLen Request length. - @param PtrTD TD_STRUCT generated. - - @return EFI_SUCCESS Generate setup stage TD successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -GenSetupStageTD ( - IN USB_UHC_DEV *UhcDev, - IN UINT8 DevAddr, - IN UINT8 Endpoint, - IN UINT8 DeviceSpeed, - IN UINT8 *DevRequest, - IN UINT8 RequestLen, - OUT TD_STRUCT **PtrTD - ) -{ - TD_STRUCT *TdStruct; - EFI_STATUS Status; - - Status = CreateTD (UhcDev, &TdStruct); - if (EFI_ERROR (Status)) { - return Status; - } - - SetTDLinkPtr (TdStruct, NULL); - - // - // Depth first fashion - // - SetTDLinkPtrDepthorBreadth (TdStruct, TRUE); - - // - // initialize as the last TD in the QH context, - // this field will be updated in the TD linkage process. - // - SetTDLinkPtrValidorInvalid (TdStruct, FALSE); - - // - // Disable Short Packet Detection by default - // - EnableorDisableTDShortPacket (TdStruct, FALSE); - - // - // Max error counter is 3, retry 3 times when error encountered. - // - SetTDControlErrorCounter (TdStruct, 3); - - // - // set device speed attribute - // (TRUE - Slow Device; FALSE - Full Speed Device) - // - switch (DeviceSpeed) { - case USB_SLOW_SPEED_DEVICE: - SetTDLoworFullSpeedDevice (TdStruct, TRUE); - break; - - case USB_FULL_SPEED_DEVICE: - SetTDLoworFullSpeedDevice (TdStruct, FALSE); - break; - } - // - // Non isochronous transfer TD - // - SetTDControlIsochronousorNot (TdStruct, FALSE); - - // - // Interrupt On Complete bit be set to zero, - // Disable IOC interrupt. - // - SetorClearTDControlIOC (TdStruct, FALSE); - - // - // Set TD Active bit - // - SetTDStatusActiveorInactive (TdStruct, TRUE); - - SetTDTokenMaxLength (TdStruct, RequestLen); - - SetTDTokenDataToggle0 (TdStruct); - - SetTDTokenEndPoint (TdStruct, Endpoint); - - SetTDTokenDeviceAddress (TdStruct, DevAddr); - - SetTDTokenPacketID (TdStruct, SETUP_PACKET_ID); - - TdStruct->PtrTDBuffer = (UINT8 *) DevRequest; - TdStruct->TDBufferLength = RequestLen; - SetTDDataBuffer (TdStruct); - - *PtrTD = TdStruct; - - return EFI_SUCCESS; -} - -/** - Generate Data Stage TD. - - @param UhcDev The UHCI device. - @param DevAddr Device address. - @param Endpoint Endpoint number. - @param PtrData Data buffer. - @param Len Data length. - @param PktID PacketID. - @param Toggle Data toggle value. - @param DeviceSpeed Device Speed. - @param PtrTD TD_STRUCT generated. - - @return EFI_SUCCESS Generate data stage TD successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -GenDataTD ( - IN USB_UHC_DEV *UhcDev, - IN UINT8 DevAddr, - IN UINT8 Endpoint, - IN UINT8 *PtrData, - IN UINT8 Len, - IN UINT8 PktID, - IN UINT8 Toggle, - IN UINT8 DeviceSpeed, - OUT TD_STRUCT **PtrTD - ) -{ - TD_STRUCT *TdStruct; - EFI_STATUS Status; - - Status = CreateTD (UhcDev, &TdStruct); - if (EFI_ERROR (Status)) { - return Status; - } - - SetTDLinkPtr (TdStruct, NULL); - - // - // Depth first fashion - // - SetTDLinkPtrDepthorBreadth (TdStruct, TRUE); - - // - // Link pointer pointing to TD struct - // - SetTDLinkPtrQHorTDSelect (TdStruct, FALSE); - - // - // initialize as the last TD in the QH context, - // this field will be updated in the TD linkage process. - // - SetTDLinkPtrValidorInvalid (TdStruct, FALSE); - - // - // Disable short packet detect - // - EnableorDisableTDShortPacket (TdStruct, FALSE); - // - // Max error counter is 3 - // - SetTDControlErrorCounter (TdStruct, 3); - - // - // set device speed attribute - // (TRUE - Slow Device; FALSE - Full Speed Device) - // - switch (DeviceSpeed) { - case USB_SLOW_SPEED_DEVICE: - SetTDLoworFullSpeedDevice (TdStruct, TRUE); - break; - - case USB_FULL_SPEED_DEVICE: - SetTDLoworFullSpeedDevice (TdStruct, FALSE); - break; - } - // - // Non isochronous transfer TD - // - SetTDControlIsochronousorNot (TdStruct, FALSE); - - // - // Disable Interrupt On Complete - // Disable IOC interrupt. - // - SetorClearTDControlIOC (TdStruct, FALSE); - - // - // Set Active bit - // - SetTDStatusActiveorInactive (TdStruct, TRUE); - - SetTDTokenMaxLength (TdStruct, Len); - - if (Toggle != 0) { - SetTDTokenDataToggle1 (TdStruct); - } else { - SetTDTokenDataToggle0 (TdStruct); - } - - SetTDTokenEndPoint (TdStruct, Endpoint); - - SetTDTokenDeviceAddress (TdStruct, DevAddr); - - SetTDTokenPacketID (TdStruct, PktID); - - TdStruct->PtrTDBuffer = (UINT8 *) PtrData; - TdStruct->TDBufferLength = Len; - SetTDDataBuffer (TdStruct); - - *PtrTD = TdStruct; - - return EFI_SUCCESS; -} - -/** - Generate Status Stage TD. - - @param UhcDev The UHCI device. - @param DevAddr Device address. - @param Endpoint Endpoint number. - @param PktID PacketID. - @param DeviceSpeed Device Speed. - @param PtrTD TD_STRUCT generated. - - @return EFI_SUCCESS Generate status stage TD successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -CreateStatusTD ( - IN USB_UHC_DEV *UhcDev, - IN UINT8 DevAddr, - IN UINT8 Endpoint, - IN UINT8 PktID, - IN UINT8 DeviceSpeed, - OUT TD_STRUCT **PtrTD - ) -{ - TD_STRUCT *PtrTDStruct; - EFI_STATUS Status; - - Status = CreateTD (UhcDev, &PtrTDStruct); - if (EFI_ERROR (Status)) { - return Status; - } - - SetTDLinkPtr (PtrTDStruct, NULL); - - // - // Depth first fashion - // - SetTDLinkPtrDepthorBreadth (PtrTDStruct, TRUE); - - // - // initialize as the last TD in the QH context, - // this field will be updated in the TD linkage process. - // - SetTDLinkPtrValidorInvalid (PtrTDStruct, FALSE); - - // - // Disable short packet detect - // - EnableorDisableTDShortPacket (PtrTDStruct, FALSE); - - // - // Max error counter is 3 - // - SetTDControlErrorCounter (PtrTDStruct, 3); - - // - // set device speed attribute - // (TRUE - Slow Device; FALSE - Full Speed Device) - // - switch (DeviceSpeed) { - case USB_SLOW_SPEED_DEVICE: - SetTDLoworFullSpeedDevice (PtrTDStruct, TRUE); - break; - - case USB_FULL_SPEED_DEVICE: - SetTDLoworFullSpeedDevice (PtrTDStruct, FALSE); - break; - } - // - // Non isochronous transfer TD - // - SetTDControlIsochronousorNot (PtrTDStruct, FALSE); - - // - // Disable Interrupt On Complete - // Disable IOC interrupt. - // - SetorClearTDControlIOC (PtrTDStruct, FALSE); - - // - // Set TD Active bit - // - SetTDStatusActiveorInactive (PtrTDStruct, TRUE); - - SetTDTokenMaxLength (PtrTDStruct, 0); - - SetTDTokenDataToggle1 (PtrTDStruct); - - SetTDTokenEndPoint (PtrTDStruct, Endpoint); - - SetTDTokenDeviceAddress (PtrTDStruct, DevAddr); - - SetTDTokenPacketID (PtrTDStruct, PktID); - - PtrTDStruct->PtrTDBuffer = NULL; - PtrTDStruct->TDBufferLength = 0; - SetTDDataBuffer (PtrTDStruct); - - *PtrTD = PtrTDStruct; - - return EFI_SUCCESS; -} - -/** - Set the link pointer validor bit in TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsValid Specify the linker pointer is valid or not. - -**/ -VOID -SetTDLinkPtrValidorInvalid ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsValid - ) -{ - // - // Valid means the link pointer is valid, - // else, it's invalid. - // - PtrTDStruct->TDData.TDLinkPtrTerminate = (IsValid ? 0 : 1); -} - -/** - Set the Link Pointer pointing to a QH or TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsQH Specify QH or TD is connected. - -**/ -VOID -SetTDLinkPtrQHorTDSelect ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsQH - ) -{ - // - // Indicate whether the Link Pointer pointing to a QH or TD - // - PtrTDStruct->TDData.TDLinkPtrQSelect = (IsQH ? 1 : 0); -} - -/** - Set the traverse is depth-first or breadth-first. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsDepth Specify the traverse is depth-first or breadth-first. - -**/ -VOID -SetTDLinkPtrDepthorBreadth ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsDepth - ) -{ - // - // If TRUE, indicating the host controller should process in depth first fashion, - // else, the host controller should process in breadth first fashion - // - PtrTDStruct->TDData.TDLinkPtrDepthSelect = (IsDepth ? 1 : 0); -} - -/** - Set TD Link Pointer in TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param PtrNext Place to the next TD_STRUCT. - -**/ -VOID -SetTDLinkPtr ( - IN TD_STRUCT *PtrTDStruct, - IN VOID *PtrNext - ) -{ - // - // Set TD Link Pointer. Since QH,TD align on 16-byte boundaries, - // only the highest 28 bits are valid. (if take 32bit address as an example) - // - PtrTDStruct->TDData.TDLinkPtr = (UINT32) (UINTN) PtrNext >> 4; -} - -/** - Get TD Link Pointer. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval Get TD Link Pointer in TD. - -**/ -VOID * -GetTDLinkPtr ( - IN TD_STRUCT *PtrTDStruct - ) -{ - // - // Get TD Link Pointer. Restore it back to 32bit - // (if take 32bit address as an example) - // - return (VOID *) (UINTN) ((PtrTDStruct->TDData.TDLinkPtr) << 4); -} - -/** - Get the information about whether the Link Pointer field pointing to - a QH or a TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval whether the Link Pointer field pointing to a QH or a TD. - -**/ -BOOLEAN -IsTDLinkPtrQHOrTD ( - IN TD_STRUCT *PtrTDStruct - ) -{ - // - // Get the information about whether the Link Pointer field pointing to - // a QH or a TD. - // - return (BOOLEAN) (PtrTDStruct->TDData.TDLinkPtrQSelect); -} - -/** - Enable/Disable short packet detection mechanism. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsEnable Enable or disable short packet detection mechanism. - -**/ -VOID -EnableorDisableTDShortPacket ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsEnable - ) -{ - // - // TRUE means enable short packet detection mechanism. - // - PtrTDStruct->TDData.TDStatusSPD = (IsEnable ? 1 : 0); -} - -/** - Set the max error counter in TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param MaxErrors The number of allowable error. - -**/ -VOID -SetTDControlErrorCounter ( - IN TD_STRUCT *PtrTDStruct, - IN UINT8 MaxErrors - ) -{ - // - // valid value of MaxErrors is 0,1,2,3 - // - if (MaxErrors > 3) { - MaxErrors = 3; - } - - PtrTDStruct->TDData.TDStatusErr = MaxErrors; -} - -/** - Set the TD is targeting a low-speed device or not. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsLowSpeedDevice Whether The device is low-speed. - -**/ -VOID -SetTDLoworFullSpeedDevice ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsLowSpeedDevice - ) -{ - // - // TRUE means the TD is targeting at a Low-speed device - // - PtrTDStruct->TDData.TDStatusLS = (IsLowSpeedDevice ? 1 : 0); -} - -/** - Set the TD is isochronous transfer type or not. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsIsochronous Whether the transaction isochronous transfer type. - -**/ -VOID -SetTDControlIsochronousorNot ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsIsochronous - ) -{ - // - // TRUE means the TD belongs to Isochronous transfer type. - // - PtrTDStruct->TDData.TDStatusIOS = (IsIsochronous ? 1 : 0); -} - -/** - Set if UCHI should issue an interrupt on completion of the frame - in which this TD is executed - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsSet Whether HC should issue an interrupt on completion. - -**/ -VOID -SetorClearTDControlIOC ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsSet - ) -{ - // - // If this bit is set, it indicates that the host controller should issue - // an interrupt on completion of the frame in which this TD is executed. - // - PtrTDStruct->TDData.TDStatusIOC = IsSet ? 1 : 0; -} - -/** - Set if the TD is active and can be executed. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsActive Whether the TD is active and can be executed. - -**/ -VOID -SetTDStatusActiveorInactive ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsActive - ) -{ - // - // If this bit is set, it indicates that the TD is active and can be - // executed. - // - if (IsActive) { - PtrTDStruct->TDData.TDStatus |= 0x80; - } else { - PtrTDStruct->TDData.TDStatus &= 0x7F; - } -} - -/** - Specifies the maximum number of data bytes allowed for the transfer. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param MaxLen The maximum number of data bytes allowed. - - @retval The allowed maximum number of data. -**/ -UINT16 -SetTDTokenMaxLength ( - IN TD_STRUCT *PtrTDStruct, - IN UINT16 MaxLen - ) -{ - // - // Specifies the maximum number of data bytes allowed for the transfer. - // the legal value extent is 0 ~ 0x500. - // - if (MaxLen > 0x500) { - MaxLen = 0x500; - } - - PtrTDStruct->TDData.TDTokenMaxLen = MaxLen - 1; - - return MaxLen; -} - -/** - Set the data toggle bit to DATA1. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - -**/ -VOID -SetTDTokenDataToggle1 ( - IN TD_STRUCT *PtrTDStruct - ) -{ - // - // Set the data toggle bit to DATA1 - // - PtrTDStruct->TDData.TDTokenDataToggle = 1; -} - -/** - Set the data toggle bit to DATA0. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - -**/ -VOID -SetTDTokenDataToggle0 ( - IN TD_STRUCT *PtrTDStruct - ) -{ - // - // Set the data toggle bit to DATA0 - // - PtrTDStruct->TDData.TDTokenDataToggle = 0; -} - -/** - Set EndPoint Number the TD is targeting at. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param EndPoint The Endport number of the target. - -**/ -VOID -SetTDTokenEndPoint ( - IN TD_STRUCT *PtrTDStruct, - IN UINTN EndPoint - ) -{ - // - // Set EndPoint Number the TD is targeting at. - // - PtrTDStruct->TDData.TDTokenEndPt = (UINT8) EndPoint; -} - -/** - Set Device Address the TD is targeting at. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param DevAddr The Device Address of the target. - -**/ -VOID -SetTDTokenDeviceAddress ( - IN TD_STRUCT *PtrTDStruct, - IN UINTN DevAddr - ) -{ - // - // Set Device Address the TD is targeting at. - // - PtrTDStruct->TDData.TDTokenDevAddr = (UINT8) DevAddr; -} - -/** - Set Packet Identification the TD is targeting at. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param PacketID The Packet Identification of the target. - -**/ -VOID -SetTDTokenPacketID ( - IN TD_STRUCT *PtrTDStruct, - IN UINT8 PacketID - ) -{ - // - // Set the Packet Identification to be used for this transaction. - // - PtrTDStruct->TDData.TDTokenPID = PacketID; -} - -/** - Set the beginning address of the data buffer that will be used - during the transaction. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - -**/ -VOID -SetTDDataBuffer ( - IN TD_STRUCT *PtrTDStruct - ) -{ - // - // Set the beginning address of the data buffer that will be used - // during the transaction. - // - PtrTDStruct->TDData.TDBufferPtr = (UINT32) (UINTN) (PtrTDStruct->PtrTDBuffer); -} - -/** - Detect whether the TD is active. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The TD is active or not. - -**/ -BOOLEAN -IsTDStatusActive ( - IN TD_STRUCT *PtrTDStruct - ) -{ - UINT8 TDStatus; - - // - // Detect whether the TD is active. - // - TDStatus = (UINT8) (PtrTDStruct->TDData.TDStatus); - return (BOOLEAN) (TDStatus & 0x80); -} - -/** - Detect whether the TD is stalled. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The TD is stalled or not. - -**/ -BOOLEAN -IsTDStatusStalled ( - IN TD_STRUCT *PtrTDStruct - ) -{ - UINT8 TDStatus; - - // - // Detect whether the device/endpoint addressed by this TD is stalled. - // - TDStatus = (UINT8) (PtrTDStruct->TDData.TDStatus); - return (BOOLEAN) (TDStatus & 0x40); -} - -/** - Detect whether Data Buffer Error is happened. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The Data Buffer Error is happened or not. - -**/ -BOOLEAN -IsTDStatusBufferError ( - IN TD_STRUCT *PtrTDStruct - ) -{ - UINT8 TDStatus; - - // - // Detect whether Data Buffer Error is happened. - // - TDStatus = (UINT8) (PtrTDStruct->TDData.TDStatus); - return (BOOLEAN) (TDStatus & 0x20); -} - -/** - Detect whether Babble Error is happened. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The Babble Error is happened or not. - -**/ -BOOLEAN -IsTDStatusBabbleError ( - IN TD_STRUCT *PtrTDStruct - ) -{ - UINT8 TDStatus; - - // - // Detect whether Babble Error is happened. - // - TDStatus = (UINT8) (PtrTDStruct->TDData.TDStatus); - return (BOOLEAN) (TDStatus & 0x10); -} - -/** - Detect whether NAK is received. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The NAK is received or not. - -**/ -BOOLEAN -IsTDStatusNAKReceived ( - IN TD_STRUCT *PtrTDStruct - ) -{ - UINT8 TDStatus; - - // - // Detect whether NAK is received. - // - TDStatus = (UINT8) (PtrTDStruct->TDData.TDStatus); - return (BOOLEAN) (TDStatus & 0x08); -} - -/** - Detect whether CRC/Time Out Error is encountered. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The CRC/Time Out Error is encountered or not. - -**/ -BOOLEAN -IsTDStatusCRCTimeOutError ( - IN TD_STRUCT *PtrTDStruct - ) -{ - UINT8 TDStatus; - - // - // Detect whether CRC/Time Out Error is encountered. - // - TDStatus = (UINT8) (PtrTDStruct->TDData.TDStatus); - return (BOOLEAN) (TDStatus & 0x04); -} - -/** - Detect whether Bitstuff Error is received. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The Bitstuff Error is received or not. - -**/ -BOOLEAN -IsTDStatusBitStuffError ( - IN TD_STRUCT *PtrTDStruct - ) -{ - UINT8 TDStatus; - - // - // Detect whether Bitstuff Error is received. - // - TDStatus = (UINT8) (PtrTDStruct->TDData.TDStatus); - return (BOOLEAN) (TDStatus & 0x02); -} - -/** - Retrieve the actual number of bytes that were tansferred. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The actual number of bytes that were tansferred. - -**/ -UINT16 -GetTDStatusActualLength ( - IN TD_STRUCT *PtrTDStruct - ) -{ - // - // Retrieve the actual number of bytes that were tansferred. - // the value is encoded as n-1. so return the decoded value. - // - return (UINT16) ((PtrTDStruct->TDData.TDStatusActualLength) + 1); -} - -/** - Retrieve the information of whether the Link Pointer field is valid or not. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The linker pointer field is valid or not. - -**/ -BOOLEAN -GetTDLinkPtrValidorInvalid ( - IN TD_STRUCT *PtrTDStruct - ) -{ - // - // Retrieve the information of whether the Link Pointer field - // is valid or not. - // - if ((PtrTDStruct->TDData.TDLinkPtrTerminate & BIT0) != 0) { - return FALSE; - } else { - return TRUE; - } - -} - -/** - Count TD Number from PtrFirstTD. - - @param PtrFirstTD Place to store TD_STRUCT pointer. - - @retval The queued TDs number. - -**/ -UINTN -CountTDsNumber ( - IN TD_STRUCT *PtrFirstTD - ) -{ - UINTN Number; - TD_STRUCT *Ptr; - - // - // Count the queued TDs number. - // - Number = 0; - Ptr = PtrFirstTD; - while (Ptr != 0) { - Ptr = (TD_STRUCT *) Ptr->PtrNextTD; - Number++; - } - - return Number; -} - -/** - Link TD To QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param PtrTD Place to store TD_STRUCT pointer. - -**/ -VOID -LinkTDToQH ( - IN QH_STRUCT *PtrQH, - IN TD_STRUCT *PtrTD - ) -{ - if (PtrQH == NULL || PtrTD == NULL) { - return ; - } - // - // Validate QH Vertical Ptr field - // - SetQHVerticalValidorInvalid (PtrQH, TRUE); - - // - // Vertical Ptr pointing to TD structure - // - SetQHVerticalQHorTDSelect (PtrQH, FALSE); - - SetQHVerticalLinkPtr (PtrQH, (VOID *) PtrTD); - - PtrQH->PtrDown = (VOID *) PtrTD; -} - -/** - Link TD To TD. - - @param PtrPreTD Place to store TD_STRUCT pointer. - @param PtrTD Place to store TD_STRUCT pointer. - -**/ -VOID -LinkTDToTD ( - IN TD_STRUCT *PtrPreTD, - IN TD_STRUCT *PtrTD - ) -{ - if (PtrPreTD == NULL || PtrTD == NULL) { - return ; - } - // - // Depth first fashion - // - SetTDLinkPtrDepthorBreadth (PtrPreTD, TRUE); - - // - // Link pointer pointing to TD struct - // - SetTDLinkPtrQHorTDSelect (PtrPreTD, FALSE); - - // - // Validate the link pointer valid bit - // - SetTDLinkPtrValidorInvalid (PtrPreTD, TRUE); - - SetTDLinkPtr (PtrPreTD, PtrTD); - - PtrPreTD->PtrNextTD = (VOID *) PtrTD; - - PtrTD->PtrNextTD = NULL; -} - -/** - Execute Control Transfer. - - @param UhcDev The UCHI device. - @param PtrTD A pointer to TD_STRUCT data. - @param ActualLen Actual transfer Length. - @param TimeOut TimeOut value. - @param TransferResult Transfer Result. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -ExecuteControlTransfer ( - IN USB_UHC_DEV *UhcDev, - IN TD_STRUCT *PtrTD, - OUT UINTN *ActualLen, - IN UINTN TimeOut, - OUT UINT32 *TransferResult - ) -{ - UINTN ErrTDPos; - UINTN Delay; - BOOLEAN InfiniteLoop; - - ErrTDPos = 0; - *TransferResult = EFI_USB_NOERROR; - *ActualLen = 0; - InfiniteLoop = FALSE; - - Delay = TimeOut * STALL_1_MILLI_SECOND; - // - // If Timeout is 0, then the caller must wait for the function to be completed - // until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - // - if (TimeOut == 0) { - InfiniteLoop = TRUE; - } - - do { - - CheckTDsResults (PtrTD, TransferResult, &ErrTDPos, ActualLen); - - // - // TD is inactive, means the control transfer is end. - // - if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) { - break; - } - MicroSecondDelay (STALL_1_MICRO_SECOND); - Delay--; - - } while (InfiniteLoop || (Delay != 0)); - - if (*TransferResult != EFI_USB_NOERROR) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - Execute Bulk Transfer. - - @param UhcDev The UCHI device. - @param PtrTD A pointer to TD_STRUCT data. - @param ActualLen Actual transfer Length. - @param DataToggle DataToggle value. - @param TimeOut TimeOut value. - @param TransferResult Transfer Result. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -ExecBulkTransfer ( - IN USB_UHC_DEV *UhcDev, - IN TD_STRUCT *PtrTD, - IN OUT UINTN *ActualLen, - IN UINT8 *DataToggle, - IN UINTN TimeOut, - OUT UINT32 *TransferResult - ) -{ - UINTN ErrTDPos; - UINTN ScrollNum; - UINTN Delay; - BOOLEAN InfiniteLoop; - - ErrTDPos = 0; - *TransferResult = EFI_USB_NOERROR; - *ActualLen = 0; - InfiniteLoop = FALSE; - - Delay = TimeOut * STALL_1_MILLI_SECOND; - // - // If Timeout is 0, then the caller must wait for the function to be completed - // until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - // - if (TimeOut == 0) { - InfiniteLoop = TRUE; - } - - do { - - CheckTDsResults (PtrTD, TransferResult, &ErrTDPos, ActualLen); - // - // TD is inactive, thus meaning bulk transfer's end. - // - if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) { - break; - } - MicroSecondDelay (STALL_1_MICRO_SECOND); - Delay--; - - } while (InfiniteLoop || (Delay != 0)); - - // - // has error - // - if (*TransferResult != EFI_USB_NOERROR) { - // - // scroll the Data Toggle back to the last success TD - // - ScrollNum = CountTDsNumber (PtrTD) - ErrTDPos; - if ((ScrollNum % 2) != 0) { - *DataToggle ^= 1; - } - - // - // If error, wait 100ms to retry by upper layer - // - MicroSecondDelay (100 * 1000); - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - Delete Queued TDs. - - @param UhcDev The UCHI device. - @param PtrFirstTD Place to store TD_STRUCT pointer. - -**/ -VOID -DeleteQueuedTDs ( - IN USB_UHC_DEV *UhcDev, - IN TD_STRUCT *PtrFirstTD - ) -{ - TD_STRUCT *Tptr1; - - TD_STRUCT *Tptr2; - - Tptr1 = PtrFirstTD; - // - // Delete all the TDs in a queue. - // - while (Tptr1 != NULL) { - - Tptr2 = Tptr1; - - if (!GetTDLinkPtrValidorInvalid (Tptr2)) { - Tptr1 = NULL; - } else { - // - // has more than one TD in the queue. - // - Tptr1 = GetTDLinkPtr (Tptr2); - } - - UhcFreePool (UhcDev, (UINT8 *) Tptr2, sizeof (TD_STRUCT)); - } - - return ; -} - -/** - Check TDs Results. - - @param PtrTD A pointer to TD_STRUCT data. - @param Result The result to return. - @param ErrTDPos The Error TD position. - @param ActualTransferSize Actual transfer size. - - @retval The TD is executed successfully or not. - -**/ -BOOLEAN -CheckTDsResults ( - IN TD_STRUCT *PtrTD, - OUT UINT32 *Result, - OUT UINTN *ErrTDPos, - OUT UINTN *ActualTransferSize - ) -{ - UINTN Len; - - *Result = EFI_USB_NOERROR; - *ErrTDPos = 0; - - // - // Init to zero. - // - *ActualTransferSize = 0; - - while (PtrTD != NULL) { - - if (IsTDStatusActive (PtrTD)) { - *Result |= EFI_USB_ERR_NOTEXECUTE; - } - - if (IsTDStatusStalled (PtrTD)) { - *Result |= EFI_USB_ERR_STALL; - } - - if (IsTDStatusBufferError (PtrTD)) { - *Result |= EFI_USB_ERR_BUFFER; - } - - if (IsTDStatusBabbleError (PtrTD)) { - *Result |= EFI_USB_ERR_BABBLE; - } - - if (IsTDStatusNAKReceived (PtrTD)) { - *Result |= EFI_USB_ERR_NAK; - } - - if (IsTDStatusCRCTimeOutError (PtrTD)) { - *Result |= EFI_USB_ERR_TIMEOUT; - } - - if (IsTDStatusBitStuffError (PtrTD)) { - *Result |= EFI_USB_ERR_BITSTUFF; - } - // - // Accumulate actual transferred data length in each TD. - // - Len = GetTDStatusActualLength (PtrTD) & 0x7FF; - *ActualTransferSize += Len; - - // - // if any error encountered, stop processing the left TDs. - // - if ((*Result) != 0) { - return FALSE; - } - - PtrTD = (TD_STRUCT *) (PtrTD->PtrNextTD); - // - // Record the first Error TD's position in the queue, - // this value is zero-based. - // - (*ErrTDPos)++; - } - - return TRUE; -} - -/** - Create Memory Block. - - @param UhcDev The UCHI device. - @param MemoryHeader The Pointer to allocated memory block. - @param MemoryBlockSizeInPages The page size of memory block to be allocated. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -CreateMemoryBlock ( - IN USB_UHC_DEV *UhcDev, - OUT MEMORY_MANAGE_HEADER **MemoryHeader, - IN UINTN MemoryBlockSizeInPages - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS TempPtr; - UINTN MemPages; - UINT8 *Ptr; - - // - // Memory Block uses MemoryBlockSizeInPages pages, - // memory management header and bit array use 1 page - // - MemPages = MemoryBlockSizeInPages + 1; - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - MemPages, - &TempPtr - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Ptr = (UINT8 *) ((UINTN) TempPtr); - - ZeroMem (Ptr, MemPages * EFI_PAGE_SIZE); - - *MemoryHeader = (MEMORY_MANAGE_HEADER *) Ptr; - // - // adjust Ptr pointer to the next empty memory - // - Ptr += sizeof (MEMORY_MANAGE_HEADER); - // - // Set Bit Array initial address - // - (*MemoryHeader)->BitArrayPtr = Ptr; - - (*MemoryHeader)->Next = NULL; - - // - // Memory block initial address - // - Ptr = (UINT8 *) ((UINTN) TempPtr); - Ptr += EFI_PAGE_SIZE; - (*MemoryHeader)->MemoryBlockPtr = Ptr; - // - // set Memory block size - // - (*MemoryHeader)->MemoryBlockSizeInBytes = MemoryBlockSizeInPages * EFI_PAGE_SIZE; - // - // each bit in Bit Array will manage 32byte memory in memory block - // - (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8; - - return EFI_SUCCESS; -} - -/** - Initialize UHCI memory management. - - @param UhcDev The UCHI device. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -InitializeMemoryManagement ( - IN USB_UHC_DEV *UhcDev - ) -{ - MEMORY_MANAGE_HEADER *MemoryHeader; - EFI_STATUS Status; - UINTN MemPages; - - MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES; - Status = CreateMemoryBlock (UhcDev, &MemoryHeader, MemPages); - if (EFI_ERROR (Status)) { - return Status; - } - - UhcDev->Header1 = MemoryHeader; - - return EFI_SUCCESS; -} - -/** - Initialize UHCI memory management. - - @param UhcDev The UCHI device. - @param Pool Buffer pointer to store the buffer pointer. - @param AllocSize The size of the pool to be allocated. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -UhcAllocatePool ( - IN USB_UHC_DEV *UhcDev, - OUT UINT8 **Pool, - IN UINTN AllocSize - ) -{ - MEMORY_MANAGE_HEADER *MemoryHeader; - MEMORY_MANAGE_HEADER *TempHeaderPtr; - MEMORY_MANAGE_HEADER *NewMemoryHeader; - UINTN RealAllocSize; - UINTN MemoryBlockSizeInPages; - EFI_STATUS Status; - - *Pool = NULL; - - MemoryHeader = UhcDev->Header1; - - // - // allocate unit is 32 byte (align on 32 byte) - // - if ((AllocSize & 0x1F) != 0) { - RealAllocSize = (AllocSize / 32 + 1) * 32; - } else { - RealAllocSize = AllocSize; - } - - Status = EFI_NOT_FOUND; - for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) { - - Status = AllocMemInMemoryBlock ( - TempHeaderPtr, - (VOID **) Pool, - RealAllocSize / 32 - ); - if (!EFI_ERROR (Status)) { - return EFI_SUCCESS; - } - } - // - // There is no enough memory, - // Create a new Memory Block - // - // - // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES, - // just allocate a large enough memory block. - // - if (RealAllocSize > (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES * EFI_PAGE_SIZE)) { - MemoryBlockSizeInPages = RealAllocSize / EFI_PAGE_SIZE + 1; - } else { - MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES; - } - - Status = CreateMemoryBlock (UhcDev, &NewMemoryHeader, MemoryBlockSizeInPages); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Link the new Memory Block to the Memory Header list - // - InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader); - - Status = AllocMemInMemoryBlock ( - NewMemoryHeader, - (VOID **) Pool, - RealAllocSize / 32 - ); - return Status; -} - -/** - Alloc Memory In MemoryBlock. - - @param MemoryHeader The pointer to memory manage header. - @param Pool Buffer pointer to store the buffer pointer. - @param NumberOfMemoryUnit The size of the pool to be allocated. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -AllocMemInMemoryBlock ( - IN MEMORY_MANAGE_HEADER *MemoryHeader, - OUT VOID **Pool, - IN UINTN NumberOfMemoryUnit - ) -{ - UINTN TempBytePos; - UINTN FoundBytePos; - UINT8 Index; - UINT8 FoundBitPos; - UINT8 ByteValue; - UINT8 BitValue; - UINTN NumberOfZeros; - UINTN Count; - - FoundBytePos = 0; - FoundBitPos = 0; - - ByteValue = MemoryHeader->BitArrayPtr[0]; - NumberOfZeros = 0; - Index = 0; - for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) { - // - // Pop out BitValue from a byte in TempBytePos. - // - BitValue = (UINT8)(ByteValue & 0x1); - - if (BitValue == 0) { - // - // Found a free bit, the NumberOfZeros only record the number of those consecutive zeros - // - NumberOfZeros++; - // - // Found enough consecutive free space, break the loop - // - if (NumberOfZeros >= NumberOfMemoryUnit) { - break; - } - } else { - // - // Encountering a '1', meant the bit is ocupied. - // - if (NumberOfZeros >= NumberOfMemoryUnit) { - // - // Found enough consecutive free space,break the loop - // - break; - } else { - // - // the NumberOfZeros only record the number of those consecutive zeros, - // so reset the NumberOfZeros to 0 when encountering '1' before finding - // enough consecutive '0's - // - NumberOfZeros = 0; - // - // reset the (FoundBytePos,FoundBitPos) to the position of '1' - // - FoundBytePos = TempBytePos; - FoundBitPos = Index; - } - } - // - // right shift the byte - // - ByteValue /= 2; - - // - // step forward a bit - // - Index++; - if (Index == 8) { - // - // step forward a byte, getting the byte value, - // and reset the bit pos. - // - TempBytePos += 1; - ByteValue = MemoryHeader->BitArrayPtr[TempBytePos]; - Index = 0; - } - } - - if (NumberOfZeros < NumberOfMemoryUnit) { - return EFI_NOT_FOUND; - } - // - // Found enough free space. - // - // - // The values recorded in (FoundBytePos,FoundBitPos) have two conditions: - // 1)(FoundBytePos,FoundBitPos) record the position - // of the last '1' before the consecutive '0's, it must - // be adjusted to the start position of the consecutive '0's. - // 2)the start address of the consecutive '0's is just the start of - // the bitarray. so no need to adjust the values of (FoundBytePos,FoundBitPos). - // - if ((MemoryHeader->BitArrayPtr[0] & BIT0) != 0) { - FoundBitPos += 1; - } - // - // Have the (FoundBytePos,FoundBitPos) make sense. - // - if (FoundBitPos > 7) { - FoundBytePos += 1; - FoundBitPos -= 8; - } - // - // Set the memory as allocated - // - for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) { - - MemoryHeader->BitArrayPtr[TempBytePos] = (UINT8) (MemoryHeader->BitArrayPtr[TempBytePos] | (1 << Index)); - Index++; - if (Index == 8) { - TempBytePos += 1; - Index = 0; - } - } - - *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32; - - return EFI_SUCCESS; -} - -/** - Uhci Free Pool. - - @param UhcDev The UHCI device. - @param Pool A pointer to store the buffer address. - @param AllocSize The size of the pool to be freed. - -**/ -VOID -UhcFreePool ( - IN USB_UHC_DEV *UhcDev, - IN UINT8 *Pool, - IN UINTN AllocSize - ) -{ - MEMORY_MANAGE_HEADER *MemoryHeader; - MEMORY_MANAGE_HEADER *TempHeaderPtr; - UINTN StartBytePos; - UINTN Index; - UINT8 StartBitPos; - UINT8 Index2; - UINTN Count; - UINTN RealAllocSize; - - MemoryHeader = UhcDev->Header1; - - // - // allocate unit is 32 byte (align on 32 byte) - // - if ((AllocSize & 0x1F) != 0) { - RealAllocSize = (AllocSize / 32 + 1) * 32; - } else { - RealAllocSize = AllocSize; - } - - for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; - TempHeaderPtr = TempHeaderPtr->Next) { - - if ((Pool >= TempHeaderPtr->MemoryBlockPtr) && - ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + - TempHeaderPtr->MemoryBlockSizeInBytes))) { - - // - // Pool is in the Memory Block area, - // find the start byte and bit in the bit array - // - StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8; - StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) % 8); - - // - // reset associated bits in bit arry - // - for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) { - - TempHeaderPtr->BitArrayPtr[Index] = (UINT8) (TempHeaderPtr->BitArrayPtr[Index] ^ (1 << Index2)); - Index2++; - if (Index2 == 8) { - Index += 1; - Index2 = 0; - } - } - // - // break the loop - // - break; - } - } - -} - -/** - Insert a new memory header into list. - - @param MemoryHeader A pointer to the memory header list. - @param NewMemoryHeader A new memory header to be inserted into the list. - -**/ -VOID -InsertMemoryHeaderToList ( - IN MEMORY_MANAGE_HEADER *MemoryHeader, - IN MEMORY_MANAGE_HEADER *NewMemoryHeader - ) -{ - MEMORY_MANAGE_HEADER *TempHeaderPtr; - - for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) { - if (TempHeaderPtr->Next == NULL) { - TempHeaderPtr->Next = NewMemoryHeader; - break; - } - } -} - -/** - Judge the memory block in the memory header is empty or not. - - @param MemoryHeaderPtr A pointer to the memory header list. - - @retval Whether the memory block in the memory header is empty or not. - -**/ -BOOLEAN -IsMemoryBlockEmptied ( - IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr - ) -{ - UINTN Index; - - for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) { - if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - -/** - remove a memory header from list. - - @param FirstMemoryHeader A pointer to the memory header list. - @param FreeMemoryHeader A memory header to be removed into the list. - -**/ -VOID -DelinkMemoryBlock ( - IN MEMORY_MANAGE_HEADER *FirstMemoryHeader, - IN MEMORY_MANAGE_HEADER *FreeMemoryHeader - ) -{ - MEMORY_MANAGE_HEADER *TempHeaderPtr; - - if ((FirstMemoryHeader == NULL) || (FreeMemoryHeader == NULL)) { - return ; - } - - for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) { - - if (TempHeaderPtr->Next == FreeMemoryHeader) { - // - // Link the before and after - // - TempHeaderPtr->Next = FreeMemoryHeader->Next; - break; - } - } -} diff --git a/MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.h b/MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.h deleted file mode 100644 index 460db7eab9..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciPei/UhcPeim.h +++ /dev/null @@ -1,1333 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _RECOVERY_UHC_H_ -#define _RECOVERY_UHC_H_ - - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define USB_SLOW_SPEED_DEVICE 0x01 -#define USB_FULL_SPEED_DEVICE 0x02 - -// -// One memory block uses 16 page -// -#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 16 - -#define USBCMD 0 /* Command Register Offset 00-01h */ -#define USBCMD_RS BIT0 /* Run/Stop */ -#define USBCMD_HCRESET BIT1 /* Host reset */ -#define USBCMD_GRESET BIT2 /* Global reset */ -#define USBCMD_EGSM BIT3 /* Global Suspend Mode */ -#define USBCMD_FGR BIT4 /* Force Global Resume */ -#define USBCMD_SWDBG BIT5 /* SW Debug mode */ -#define USBCMD_CF BIT6 /* Config Flag (sw only) */ -#define USBCMD_MAXP BIT7 /* Max Packet (0 = 32, 1 = 64) */ - -/* Status register */ -#define USBSTS 2 /* Status Register Offset 02-03h */ -#define USBSTS_USBINT BIT0 /* Interrupt due to IOC */ -#define USBSTS_ERROR BIT1 /* Interrupt due to error */ -#define USBSTS_RD BIT2 /* Resume Detect */ -#define USBSTS_HSE BIT3 /* Host System Error - basically PCI problems */ -#define USBSTS_HCPE BIT4 /* Host Controller Process Error - the scripts were buggy */ -#define USBSTS_HCH BIT5 /* HC Halted */ - -/* Interrupt enable register */ -#define USBINTR 4 /* Interrupt Enable Register 04-05h */ -#define USBINTR_TIMEOUT BIT0 /* Timeout/CRC error enable */ -#define USBINTR_RESUME BIT1 /* Resume interrupt enable */ -#define USBINTR_IOC BIT2 /* Interrupt On Complete enable */ -#define USBINTR_SP BIT3 /* Short packet interrupt enable */ - -/* Frame Number Register Offset 06-08h */ -#define USBFRNUM 6 - -/* Frame List Base Address Register Offset 08-0Bh */ -#define USBFLBASEADD 8 - -/* Start of Frame Modify Register Offset 0Ch */ -#define USBSOF 0x0c - -/* USB port status and control registers */ -#define USBPORTSC1 0x10 /*Port 1 offset 10-11h */ -#define USBPORTSC2 0x12 /*Port 2 offset 12-13h */ - -#define USBPORTSC_CCS BIT0 /* Current Connect Status ("device present") */ -#define USBPORTSC_CSC BIT1 /* Connect Status Change */ -#define USBPORTSC_PED BIT2 /* Port Enable / Disable */ -#define USBPORTSC_PEDC BIT3 /* Port Enable / Disable Change */ -#define USBPORTSC_LSL BIT4 /* Line Status Low bit*/ -#define USBPORTSC_LSH BIT5 /* Line Status High bit*/ -#define USBPORTSC_RD BIT6 /* Resume Detect */ -#define USBPORTSC_LSDA BIT8 /* Low Speed Device Attached */ -#define USBPORTSC_PR BIT9 /* Port Reset */ -#define USBPORTSC_SUSP BIT12 /* Suspend */ - -#define SETUP_PACKET_ID 0x2D -#define INPUT_PACKET_ID 0x69 -#define OUTPUT_PACKET_ID 0xE1 -#define ERROR_PACKET_ID 0x55 - -#define STALL_1_MICRO_SECOND 1 -#define STALL_1_MILLI_SECOND 1000 - - -#pragma pack(1) - -typedef struct { - UINT32 FrameListPtrTerminate : 1; - UINT32 FrameListPtrQSelect : 1; - UINT32 FrameListRsvd : 2; - UINT32 FrameListPtr : 28; -} FRAMELIST_ENTRY; - -typedef struct { - UINT32 QHHorizontalTerminate : 1; - UINT32 QHHorizontalQSelect : 1; - UINT32 QHHorizontalRsvd : 2; - UINT32 QHHorizontalPtr : 28; - UINT32 QHVerticalTerminate : 1; - UINT32 QHVerticalQSelect : 1; - UINT32 QHVerticalRsvd : 2; - UINT32 QHVerticalPtr : 28; -} QUEUE_HEAD; - -typedef struct { - QUEUE_HEAD QueueHead; - UINT32 Reserved1; - UINT32 Reserved2; - VOID *PtrNext; - VOID *PtrDown; - VOID *Reserved3; - UINT32 Reserved4; -} QH_STRUCT; - -typedef struct { - UINT32 TDLinkPtrTerminate : 1; - UINT32 TDLinkPtrQSelect : 1; - UINT32 TDLinkPtrDepthSelect : 1; - UINT32 TDLinkPtrRsvd : 1; - UINT32 TDLinkPtr : 28; - UINT32 TDStatusActualLength : 11; - UINT32 TDStatusRsvd : 5; - UINT32 TDStatus : 8; - UINT32 TDStatusIOC : 1; - UINT32 TDStatusIOS : 1; - UINT32 TDStatusLS : 1; - UINT32 TDStatusErr : 2; - UINT32 TDStatusSPD : 1; - UINT32 TDStatusRsvd2 : 2; - UINT32 TDTokenPID : 8; - UINT32 TDTokenDevAddr : 7; - UINT32 TDTokenEndPt : 4; - UINT32 TDTokenDataToggle : 1; - UINT32 TDTokenRsvd : 1; - UINT32 TDTokenMaxLen : 11; - UINT32 TDBufferPtr; -} TD; - -typedef struct { - TD TDData; - UINT8 *PtrTDBuffer; - VOID *PtrNextTD; - VOID *PtrNextQH; - UINT16 TDBufferLength; - UINT16 Reserved; -} TD_STRUCT; - -#pragma pack() - -typedef struct _MEMORY_MANAGE_HEADER MEMORY_MANAGE_HEADER; - -struct _MEMORY_MANAGE_HEADER { - UINT8 *BitArrayPtr; - UINTN BitArraySizeInBytes; - UINT8 *MemoryBlockPtr; - UINTN MemoryBlockSizeInBytes; - MEMORY_MANAGE_HEADER *Next; -}; - -#define USB_UHC_DEV_SIGNATURE SIGNATURE_32 ('p', 'u', 'h', 'c') -typedef struct { - UINTN Signature; - PEI_USB_HOST_CONTROLLER_PPI UsbHostControllerPpi; - EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; - - UINT32 UsbHostControllerBaseAddress; - FRAMELIST_ENTRY *FrameListEntry; - QH_STRUCT *ConfigQH; - QH_STRUCT *BulkQH; - // - // Header1 used for QH,TD memory blocks management - // - MEMORY_MANAGE_HEADER *Header1; - -} USB_UHC_DEV; - -#define PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS(a) CR (a, USB_UHC_DEV, UsbHostControllerPpi, USB_UHC_DEV_SIGNATURE) - -/** - Submits control transfer to a target USB device. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. - @param DeviceAddress The target device address. - @param DeviceSpeed Target device speed. - @param MaximumPacketLength Maximum packet size the default control transfer - endpoint is capable of sending or receiving. - @param Request USB device request to send. - @param TransferDirection Specifies the data direction for the data stage. - @param Data Data buffer to be transmitted or received from USB device. - @param DataLength The size (in bytes) of the data buffer. - @param TimeOut Indicates the maximum timeout, in millisecond. - @param TransferResult Return the result of this control transfer. - - @retval EFI_SUCCESS Transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT Transfer failed due to timeout. - @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -UhcControlTransfer ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI * This, - IN UINT8 DeviceAddress, - IN UINT8 DeviceSpeed, - IN UINT8 MaximumPacketLength, - IN EFI_USB_DEVICE_REQUEST * Request, - IN EFI_USB_DATA_DIRECTION TransferDirection, - IN OUT VOID *Data OPTIONAL, - IN OUT UINTN *DataLength OPTIONAL, - IN UINTN TimeOut, - OUT UINT32 *TransferResult - ); - -/** - Submits bulk transfer to a bulk endpoint of a USB device. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction in bit 7. - @param MaximumPacketLength Maximum packet size the endpoint is capable of - sending or receiving. - @param Data Array of pointers to the buffers of data to transmit - from or receive into. - @param DataLength The lenght of the data buffer. - @param DataToggle On input, the initial data toggle for the transfer; - On output, it is updated to to next data toggle to use of - the subsequent bulk transfer. - @param TimeOut Indicates the maximum time, in millisecond, which the - transfer is allowed to complete. - @param TransferResult A pointer to the detailed result information of the - bulk transfer. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @retval EFI_INVALID_PARAMETER Parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -UhcBulkTransfer ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 MaximumPacketLength, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN TimeOut, - OUT UINT32 *TransferResult - ); - -/** - Retrieves the number of root hub ports. - - @param[in] PeiServices The pointer to the PEI Services Table. - @param[in] This The pointer to this instance of the - PEI_USB_HOST_CONTROLLER_PPI. - @param[out] PortNumber The pointer to the number of the root hub ports. - - @retval EFI_SUCCESS The port number was retrieved successfully. - @retval EFI_INVALID_PARAMETER PortNumber is NULL. - -**/ -EFI_STATUS -EFIAPI -UhcGetRootHubPortNumber ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - OUT UINT8 *PortNumber - ); - -/** - Retrieves the current status of a USB root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. - @param PortNumber The root hub port to retrieve the state from. - @param PortStatus Variable to receive the port state. - - @retval EFI_SUCCESS The status of the USB root hub port specified. - by PortNumber was returned in PortStatus. - @retval EFI_INVALID_PARAMETER PortNumber is invalid. - -**/ -EFI_STATUS -EFIAPI -UhcGetRootHubPortStatus ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - OUT EFI_USB_PORT_STATUS *PortStatus - ); - -/** - Sets a feature for the specified root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI - @param PortNumber Root hub port to set. - @param PortFeature Feature to set. - - @retval EFI_SUCCESS The feature specified by PortFeature was set. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -EFIAPI -UhcSetRootHubPortFeature ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ); - -/** - Clears a feature for the specified root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB_HOST_CONTROLLER_PPI. - @param PortNumber Specifies the root hub port whose feature - is requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. - - @retval EFI_SUCCESS The feature specified by PortFeature was cleared - for the USB root hub port specified by PortNumber. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - -**/ -EFI_STATUS -EFIAPI -UhcClearRootHubPortFeature ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ); - -/** - Initialize UHCI. - - @param UhcDev UHCI Device. - - @retval EFI_SUCCESS UHCI successfully initialized. - @retval EFI_OUT_OF_RESOURCES Resource can not be allocated. - -**/ -EFI_STATUS -InitializeUsbHC ( - IN USB_UHC_DEV *UhcDev - ); - -/** - Create Frame List Structure. - - @param UhcDev UHCI device. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -CreateFrameList ( - USB_UHC_DEV *UhcDev - ); - -/** - Read a 16bit width data from Uhc HC IO space register. - - @param UhcDev The UHCI device. - @param Port The IO space address of the register. - - @retval the register content read. - -**/ -UINT16 -USBReadPortW ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 Port - ); - -/** - Write a 16bit width data into Uhc HC IO space register. - - @param UhcDev The UHCI device. - @param Port The IO space address of the register. - @param Data The data written into the register. - -**/ -VOID -USBWritePortW ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 Port, - IN UINT16 Data - ); - -/** - Write a 32bit width data into Uhc HC IO space register. - - @param UhcDev The UHCI device. - @param Port The IO space address of the register. - @param Data The data written into the register. - -**/ -VOID -USBWritePortDW ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 Port, - IN UINT32 Data - ); - -/** - Clear the content of UHCI's Status Register. - - @param UhcDev The UHCI device. - @param StatusAddr The IO space address of the register. - -**/ -VOID -ClearStatusReg ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 StatusAddr - ); - -/** - Check whether the host controller operates well. - - @param UhcDev The UHCI device. - @param StatusRegAddr The io address of status register. - - @retval TRUE Host controller is working. - @retval FALSE Host controller is halted or system error. - -**/ -BOOLEAN -IsStatusOK ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 StatusRegAddr - ); - -/** - Get Current Frame Number. - - @param UhcDev The UHCI device. - @param FrameNumberAddr The address of frame list register. - - @retval The content of the frame list register. - -**/ -UINT16 -GetCurrentFrameNumber ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 FrameNumberAddr - ); - -/** - Set Frame List Base Address. - - @param UhcDev The UHCI device. - @param FrameListRegAddr The address of frame list register. - @param Addr The address of frame list table. - -**/ -VOID -SetFrameListBaseAddress ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 FrameListRegAddr, - IN UINT32 Addr - ); - -/** - Create QH and initialize. - - @param UhcDev The UHCI device. - @param PtrQH Place to store QH_STRUCT pointer. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -CreateQH ( - IN USB_UHC_DEV *UhcDev, - OUT QH_STRUCT **PtrQH - ); - -/** - Set the horizontal link pointer in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param PtrNext Place to the next QH_STRUCT. - -**/ -VOID -SetQHHorizontalLinkPtr ( - IN QH_STRUCT *PtrQH, - IN VOID *PtrNext - ); - -/** - Get the horizontal link pointer in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - - @retval The horizontal link pointer in QH. - -**/ -VOID * -GetQHHorizontalLinkPtr ( - IN QH_STRUCT *PtrQH - ); - -/** - Set a QH or TD horizontally to be connected with a specific QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param IsQH Specify QH or TD is connected. - -**/ -VOID -SetQHHorizontalQHorTDSelect ( - IN QH_STRUCT *PtrQH, - IN BOOLEAN IsQH - ); - -/** - Set the horizontal validor bit in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param IsValid Specify the horizontal linker is valid or not. - -**/ -VOID -SetQHHorizontalValidorInvalid ( - IN QH_STRUCT *PtrQH, - IN BOOLEAN IsValid - ); - -/** - Set the vertical link pointer in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param PtrNext Place to the next QH_STRUCT. - -**/ -VOID -SetQHVerticalLinkPtr ( - IN QH_STRUCT *PtrQH, - IN VOID *PtrNext - ); - -/** - Set a QH or TD vertically to be connected with a specific QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param IsQH Specify QH or TD is connected. - -**/ -VOID -SetQHVerticalQHorTDSelect ( - IN QH_STRUCT *PtrQH, - IN BOOLEAN IsQH - ); - -/** - Set the vertical validor bit in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param IsValid Specify the vertical linker is valid or not. - -**/ -VOID -SetQHVerticalValidorInvalid ( - IN QH_STRUCT *PtrQH, - IN BOOLEAN IsValid - ); - -/** - Get the vertical validor bit in QH. - - @param PtrQH Place to store QH_STRUCT pointer. - - @retval The vertical linker is valid or not. - -**/ -BOOLEAN -GetQHHorizontalValidorInvalid ( - IN QH_STRUCT *PtrQH - ); - -/** - Allocate TD or QH Struct. - - @param UhcDev The UHCI device. - @param Size The size of allocation. - @param PtrStruct Place to store TD_STRUCT pointer. - - @return EFI_SUCCESS Allocate successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -AllocateTDorQHStruct ( - IN USB_UHC_DEV *UhcDev, - IN UINT32 Size, - OUT VOID **PtrStruct - ); - -/** - Create a TD Struct. - - @param UhcDev The UHCI device. - @param PtrTD Place to store TD_STRUCT pointer. - - @return EFI_SUCCESS Allocate successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -CreateTD ( - IN USB_UHC_DEV *UhcDev, - OUT TD_STRUCT **PtrTD - ); - -/** - Generate Setup Stage TD. - - @param UhcDev The UHCI device. - @param DevAddr Device address. - @param Endpoint Endpoint number. - @param DeviceSpeed Device Speed. - @param DevRequest Device reuquest. - @param RequestLen Request length. - @param PtrTD TD_STRUCT generated. - - @return EFI_SUCCESS Generate setup stage TD successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -GenSetupStageTD ( - IN USB_UHC_DEV *UhcDev, - IN UINT8 DevAddr, - IN UINT8 Endpoint, - IN UINT8 DeviceSpeed, - IN UINT8 *DevRequest, - IN UINT8 RequestLen, - OUT TD_STRUCT **PtrTD - ); - -/** - Generate Data Stage TD. - - @param UhcDev The UHCI device. - @param DevAddr Device address. - @param Endpoint Endpoint number. - @param PtrData Data buffer. - @param Len Data length. - @param PktID PacketID. - @param Toggle Data toggle value. - @param DeviceSpeed Device Speed. - @param PtrTD TD_STRUCT generated. - - @return EFI_SUCCESS Generate data stage TD successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -GenDataTD ( - IN USB_UHC_DEV *UhcDev, - IN UINT8 DevAddr, - IN UINT8 Endpoint, - IN UINT8 *PtrData, - IN UINT8 Len, - IN UINT8 PktID, - IN UINT8 Toggle, - IN UINT8 DeviceSpeed, - OUT TD_STRUCT **PtrTD - ); - -/** - Generate Status Stage TD. - - @param UhcDev The UHCI device. - @param DevAddr Device address. - @param Endpoint Endpoint number. - @param PktID PacketID. - @param DeviceSpeed Device Speed. - @param PtrTD TD_STRUCT generated. - - @return EFI_SUCCESS Generate status stage TD successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. - -**/ -EFI_STATUS -CreateStatusTD ( - IN USB_UHC_DEV *UhcDev, - IN UINT8 DevAddr, - IN UINT8 Endpoint, - IN UINT8 PktID, - IN UINT8 DeviceSpeed, - OUT TD_STRUCT **PtrTD - ); - -/** - Set the link pointer validor bit in TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsValid Specify the linker pointer is valid or not. - -**/ -VOID -SetTDLinkPtrValidorInvalid ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsValid - ); - -/** - Set the Link Pointer pointing to a QH or TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsQH Specify QH or TD is connected. - -**/ -VOID -SetTDLinkPtrQHorTDSelect ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsQH - ); - -/** - Set the traverse is depth-first or breadth-first. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsDepth Specify the traverse is depth-first or breadth-first. - -**/ -VOID -SetTDLinkPtrDepthorBreadth ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsDepth - ); - -/** - Set TD Link Pointer in TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param PtrNext Place to the next TD_STRUCT. - -**/ -VOID -SetTDLinkPtr ( - IN TD_STRUCT *PtrTDStruct, - IN VOID *PtrNext - ); - -/** - Get TD Link Pointer. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval Get TD Link Pointer in TD. - -**/ -VOID* -GetTDLinkPtr ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Get the information about whether the Link Pointer field pointing to - a QH or a TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval whether the Link Pointer field pointing to a QH or a TD. - -**/ -BOOLEAN -IsTDLinkPtrQHOrTD ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Enable/Disable short packet detection mechanism. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsEnable Enable or disable short packet detection mechanism. - -**/ -VOID -EnableorDisableTDShortPacket ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsEnable - ); - -/** - Set the max error counter in TD. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param MaxErrors The number of allowable error. - -**/ -VOID -SetTDControlErrorCounter ( - IN TD_STRUCT *PtrTDStruct, - IN UINT8 MaxErrors - ); - -/** - Set the TD is targeting a low-speed device or not. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsLowSpeedDevice Whether The device is low-speed. - -**/ -VOID -SetTDLoworFullSpeedDevice ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsLowSpeedDevice - ); - -/** - Set the TD is isochronous transfer type or not. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsIsochronous Whether the transaction isochronous transfer type. - -**/ -VOID -SetTDControlIsochronousorNot ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsIsochronous - ); - -/** - Set if UCHI should issue an interrupt on completion of the frame - in which this TD is executed - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsSet Whether HC should issue an interrupt on completion. - -**/ -VOID -SetorClearTDControlIOC ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsSet - ); - -/** - Set if the TD is active and can be executed. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param IsActive Whether the TD is active and can be executed. - -**/ -VOID -SetTDStatusActiveorInactive ( - IN TD_STRUCT *PtrTDStruct, - IN BOOLEAN IsActive - ); - -/** - Specifies the maximum number of data bytes allowed for the transfer. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param MaxLen The maximum number of data bytes allowed. - - @retval The allowed maximum number of data. -**/ -UINT16 -SetTDTokenMaxLength ( - IN TD_STRUCT *PtrTDStruct, - IN UINT16 MaxLen - ); - -/** - Set the data toggle bit to DATA1. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - -**/ -VOID -SetTDTokenDataToggle1 ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Set the data toggle bit to DATA0. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - -**/ -VOID -SetTDTokenDataToggle0 ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Set EndPoint Number the TD is targeting at. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param EndPoint The Endport number of the target. - -**/ -VOID -SetTDTokenEndPoint ( - IN TD_STRUCT *PtrTDStruct, - IN UINTN EndPoint - ); - -/** - Set Device Address the TD is targeting at. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param DevAddr The Device Address of the target. - -**/ -VOID -SetTDTokenDeviceAddress ( - IN TD_STRUCT *PtrTDStruct, - IN UINTN DevAddr - ); - -/** - Set Packet Identification the TD is targeting at. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - @param PacketID The Packet Identification of the target. - -**/ -VOID -SetTDTokenPacketID ( - IN TD_STRUCT *PtrTDStruct, - IN UINT8 PacketID - ); - -/** - Set the beginning address of the data buffer that will be used - during the transaction. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - -**/ -VOID -SetTDDataBuffer ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Detect whether the TD is active. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The TD is active or not. - -**/ -BOOLEAN -IsTDStatusActive ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Detect whether the TD is stalled. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The TD is stalled or not. - -**/ -BOOLEAN -IsTDStatusStalled ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Detect whether Data Buffer Error is happened. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The Data Buffer Error is happened or not. - -**/ -BOOLEAN -IsTDStatusBufferError ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Detect whether Babble Error is happened. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The Babble Error is happened or not. - -**/ -BOOLEAN -IsTDStatusBabbleError ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Detect whether NAK is received. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The NAK is received or not. - -**/ -BOOLEAN -IsTDStatusNAKReceived ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Detect whether CRC/Time Out Error is encountered. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The CRC/Time Out Error is encountered or not. - -**/ -BOOLEAN -IsTDStatusCRCTimeOutError ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Detect whether Bitstuff Error is received. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The Bitstuff Error is received or not. - -**/ -BOOLEAN -IsTDStatusBitStuffError ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Retrieve the actual number of bytes that were tansferred. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The actual number of bytes that were tansferred. - -**/ -UINT16 -GetTDStatusActualLength ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Retrieve the information of whether the Link Pointer field is valid or not. - - @param PtrTDStruct Place to store TD_STRUCT pointer. - - @retval The linker pointer field is valid or not. - -**/ -BOOLEAN -GetTDLinkPtrValidorInvalid ( - IN TD_STRUCT *PtrTDStruct - ); - -/** - Count TD Number from PtrFirstTD. - - @param PtrFirstTD Place to store TD_STRUCT pointer. - - @retval The queued TDs number. - -**/ -UINTN -CountTDsNumber ( - IN TD_STRUCT *PtrFirstTD - ); - -/** - Link TD To QH. - - @param PtrQH Place to store QH_STRUCT pointer. - @param PtrTD Place to store TD_STRUCT pointer. - -**/ -VOID -LinkTDToQH ( - IN QH_STRUCT *PtrQH, - IN TD_STRUCT *PtrTD - ); - -/** - Link TD To TD. - - @param PtrPreTD Place to store TD_STRUCT pointer. - @param PtrTD Place to store TD_STRUCT pointer. - -**/ -VOID -LinkTDToTD ( - IN TD_STRUCT *PtrPreTD, - IN TD_STRUCT *PtrTD - ); - -/** - Execute Control Transfer. - - @param UhcDev The UCHI device. - @param PtrTD A pointer to TD_STRUCT data. - @param ActualLen Actual transfer Length. - @param TimeOut TimeOut value. - @param TransferResult Transfer Result. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -ExecuteControlTransfer ( - IN USB_UHC_DEV *UhcDev, - IN TD_STRUCT *PtrTD, - OUT UINTN *ActualLen, - IN UINTN TimeOut, - OUT UINT32 *TransferResult - ); - -/** - Execute Bulk Transfer. - - @param UhcDev The UCHI device. - @param PtrTD A pointer to TD_STRUCT data. - @param ActualLen Actual transfer Length. - @param DataToggle DataToggle value. - @param TimeOut TimeOut value. - @param TransferResult Transfer Result. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -ExecBulkTransfer ( - IN USB_UHC_DEV *UhcDev, - IN TD_STRUCT *PtrTD, - IN OUT UINTN *ActualLen, - IN UINT8 *DataToggle, - IN UINTN TimeOut, - OUT UINT32 *TransferResult - ); - -/** - Delete Queued TDs. - - @param UhcDev The UCHI device. - @param PtrFirstTD Place to store TD_STRUCT pointer. - -**/ -VOID -DeleteQueuedTDs ( - IN USB_UHC_DEV *UhcDev, - IN TD_STRUCT *PtrFirstTD - ); - -/** - Check TDs Results. - - @param PtrTD A pointer to TD_STRUCT data. - @param Result The result to return. - @param ErrTDPos The Error TD position. - @param ActualTransferSize Actual transfer size. - - @retval The TD is executed successfully or not. - -**/ -BOOLEAN -CheckTDsResults ( - IN TD_STRUCT *PtrTD, - OUT UINT32 *Result, - OUT UINTN *ErrTDPos, - OUT UINTN *ActualTransferSize - ); - -/** - Create Memory Block. - - @param UhcDev The UCHI device. - @param MemoryHeader The Pointer to allocated memory block. - @param MemoryBlockSizeInPages The page size of memory block to be allocated. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -CreateMemoryBlock ( - IN USB_UHC_DEV *UhcDev, - OUT MEMORY_MANAGE_HEADER **MemoryHeader, - IN UINTN MemoryBlockSizeInPages - ); - -/** - Initialize UHCI memory management. - - @param UhcDev The UCHI device. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -InitializeMemoryManagement ( - IN USB_UHC_DEV *UhcDev - ); - -/** - Initialize UHCI memory management. - - @param UhcDev The UCHI device. - @param Pool Buffer pointer to store the buffer pointer. - @param AllocSize The size of the pool to be allocated. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -UhcAllocatePool ( - IN USB_UHC_DEV *UhcDev, - OUT UINT8 **Pool, - IN UINTN AllocSize - ); - -/** - Alloc Memory In MemoryBlock. - - @param MemoryHeader The pointer to memory manage header. - @param Pool Buffer pointer to store the buffer pointer. - @param NumberOfMemoryUnit The size of the pool to be allocated. - - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_SUCCESS Success. - -**/ -EFI_STATUS -AllocMemInMemoryBlock ( - IN MEMORY_MANAGE_HEADER *MemoryHeader, - OUT VOID **Pool, - IN UINTN NumberOfMemoryUnit - ); - -/** - Uhci Free Pool. - - @param UhcDev The UHCI device. - @param Pool A pointer to store the buffer address. - @param AllocSize The size of the pool to be freed. - -**/ -VOID -UhcFreePool ( - IN USB_UHC_DEV *UhcDev, - IN UINT8 *Pool, - IN UINTN AllocSize - ); - -/** - Insert a new memory header into list. - - @param MemoryHeader A pointer to the memory header list. - @param NewMemoryHeader A new memory header to be inserted into the list. - -**/ -VOID -InsertMemoryHeaderToList ( - IN MEMORY_MANAGE_HEADER *MemoryHeader, - IN MEMORY_MANAGE_HEADER *NewMemoryHeader - ); - -/** - Judge the memory block in the memory header is empty or not. - - @param MemoryHeaderPtr A pointer to the memory header list. - - @retval Whether the memory block in the memory header is empty or not. - -**/ -BOOLEAN -IsMemoryBlockEmptied ( - IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr - ); - -/** - remove a memory header from list. - - @param FirstMemoryHeader A pointer to the memory header list. - @param FreeMemoryHeader A memory header to be removed into the list. - -**/ -VOID -DelinkMemoryBlock ( - IN MEMORY_MANAGE_HEADER *FirstMemoryHeader, - IN MEMORY_MANAGE_HEADER *FreeMemoryHeader - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/UhciPei/UhciPei.inf b/MdeModulePkg/Bus/Pci/UhciPei/UhciPei.inf deleted file mode 100644 index 7baa07612d..0000000000 --- a/MdeModulePkg/Bus/Pci/UhciPei/UhciPei.inf +++ /dev/null @@ -1,64 +0,0 @@ -## @file -# The UhcPeim driver is responsible for managing the behavior of UHCI controller at PEI phase. -# -# It produces gPeiUsbHostControllerPpiGuid based on gPeiUsbControllerPpiGuid which is used -# to enable recovery function from USB Drivers. -# -# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions -# of the BSD License which accompanies this distribution. The -# full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = UhciPei - MODULE_UNI_FILE = UhciPei.uni - FILE_GUID = C463CEAC-FC57-4f36-88B7-356C750C3BCA - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - - ENTRY_POINT = UhcPeimEntry - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - UhcPeim.c - UhcPeim.h - - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - - -[LibraryClasses] - IoLib - TimerLib - BaseMemoryLib - PeiServicesLib - PeimEntryPoint - DebugLib - - -[Ppis] - gPeiUsbHostControllerPpiGuid ## PRODUCES - gPeiUsbControllerPpiGuid ## CONSUMES - - -[Depex] - gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid - -[UserExtensions.TianoCore."ExtraFiles"] - UhciPeiExtra.uni diff --git a/MdeModulePkg/Bus/Pci/UhciPei/UhciPei.uni b/MdeModulePkg/Bus/Pci/UhciPei/UhciPei.uni deleted file mode 100644 index b3cfb23139..0000000000 Binary files a/MdeModulePkg/Bus/Pci/UhciPei/UhciPei.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/UhciPei/UhciPeiExtra.uni b/MdeModulePkg/Bus/Pci/UhciPei/UhciPeiExtra.uni deleted file mode 100644 index 5cde35591a..0000000000 Binary files a/MdeModulePkg/Bus/Pci/UhciPei/UhciPeiExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c deleted file mode 100644 index 706aa292c8..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.c +++ /dev/null @@ -1,224 +0,0 @@ -/** @file - UEFI Component Name(2) protocol implementation for XHCI driver. - -Copyright (c) 2011, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Xhci.h" - -// -// EFI Component Name Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gXhciComponentName = { - XhciComponentNameGetDriverName, - XhciComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gXhciComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) XhciComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) XhciComponentNameGetControllerName, - "en" -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mXhciDriverNameTable[] = { - { "eng;en", L"Usb Xhci Driver" }, - { NULL , NULL } -}; - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -XhciComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mXhciDriverNameTable, - DriverName, - (BOOLEAN)(This == &gXhciComponentName) - ); -} - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -XhciComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - EFI_USB2_HC_PROTOCOL *Usb2Hc; - USB_XHCI_INSTANCE *XhciDev; - - // - // This is a device driver, so ChildHandle must be NULL. - // - if (ChildHandle != NULL) { - return EFI_UNSUPPORTED; - } - - // - // Make sure this driver is currently managing ControllerHandle - // - Status = EfiTestManagedDevice ( - ControllerHandle, - gXhciDriverBinding.DriverBindingHandle, - &gEfiPciIoProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Get the device context - // - Status = gBS->OpenProtocol ( - ControllerHandle, - &gEfiUsb2HcProtocolGuid, - (VOID **) &Usb2Hc, - gXhciDriverBinding.DriverBindingHandle, - ControllerHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - XhciDev = XHC_FROM_THIS (Usb2Hc); - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - XhciDev->ControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gXhciComponentName) - ); - -} diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h b/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h deleted file mode 100644 index c3c44ccdfb..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/ComponentName.h +++ /dev/null @@ -1,146 +0,0 @@ -/** @file - - This file contains the delarations for componet name routines. - -Copyright (c) 2011, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_COMPONENT_NAME_H_ -#define _EFI_COMPONENT_NAME_H_ - -/** - Retrieves a Unicode string that is the user readable name of the driver. - - This function retrieves the user readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param DriverName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -XhciComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - - -/** - Retrieves a Unicode string that is the user readable name of the controller - that is being managed by a driver. - - This function retrieves the user readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param ControllerHandle[in] The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param ChildHandle[in] The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param Language[in] A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param ControllerName[out] A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -XhciComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -#endif - diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c deleted file mode 100644 index 54c69d78ed..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.c +++ /dev/null @@ -1,758 +0,0 @@ -/** @file - - Routine procedures for memory allocate/free. - -Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "Xhci.h" - - -/** - Allocate a block of memory to be used by the buffer pool. - - @param Pool The buffer pool to allocate memory for. - @param Pages How many pages to allocate. - - @return The allocated memory block or NULL if failed. - -**/ -USBHC_MEM_BLOCK * -UsbHcAllocMemBlock ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Pages - ) -{ - USBHC_MEM_BLOCK *Block; - EFI_PCI_IO_PROTOCOL *PciIo; - VOID *BufHost; - VOID *Mapping; - EFI_PHYSICAL_ADDRESS MappedAddr; - UINTN Bytes; - EFI_STATUS Status; - - PciIo = Pool->PciIo; - - Block = AllocateZeroPool (sizeof (USBHC_MEM_BLOCK)); - if (Block == NULL) { - return NULL; - } - - // - // each bit in the bit array represents USBHC_MEM_UNIT - // bytes of memory in the memory block. - // - ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE); - - Block->BufLen = EFI_PAGES_TO_SIZE (Pages); - Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8); - Block->Bits = AllocateZeroPool (Block->BitsLen); - - if (Block->Bits == NULL) { - gBS->FreePool (Block); - return NULL; - } - - // - // Allocate the number of Pages of memory, then map it for - // bus master read and write. - // - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - Pages, - &BufHost, - 0 - ); - - if (EFI_ERROR (Status)) { - goto FREE_BITARRAY; - } - - Bytes = EFI_PAGES_TO_SIZE (Pages); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - BufHost, - &Bytes, - &MappedAddr, - &Mapping - ); - - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) { - goto FREE_BUFFER; - } - - Block->BufHost = BufHost; - Block->Buf = (UINT8 *) ((UINTN) MappedAddr); - Block->Mapping = Mapping; - - return Block; - -FREE_BUFFER: - PciIo->FreeBuffer (PciIo, Pages, BufHost); - -FREE_BITARRAY: - gBS->FreePool (Block->Bits); - gBS->FreePool (Block); - return NULL; -} - - -/** - Free the memory block from the memory pool. - - @param Pool The memory pool to free the block from. - @param Block The memory block to free. - -**/ -VOID -UsbHcFreeMemBlock ( - IN USBHC_MEM_POOL *Pool, - IN USBHC_MEM_BLOCK *Block - ) -{ - EFI_PCI_IO_PROTOCOL *PciIo; - - ASSERT ((Pool != NULL) && (Block != NULL)); - - PciIo = Pool->PciIo; - - // - // Unmap the common buffer then free the structures - // - PciIo->Unmap (PciIo, Block->Mapping); - PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost); - - gBS->FreePool (Block->Bits); - gBS->FreePool (Block); -} - - -/** - Alloc some memory from the block. - - @param Block The memory block to allocate memory from. - @param Units Number of memory units to allocate. - - @return The pointer to the allocated memory. If couldn't allocate the needed memory, - the return value is NULL. - -**/ -VOID * -UsbHcAllocMemFromBlock ( - IN USBHC_MEM_BLOCK *Block, - IN UINTN Units - ) -{ - UINTN Byte; - UINT8 Bit; - UINTN StartByte; - UINT8 StartBit; - UINTN Available; - UINTN Count; - - ASSERT ((Block != 0) && (Units != 0)); - - StartByte = 0; - StartBit = 0; - Available = 0; - - for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) { - // - // If current bit is zero, the corresponding memory unit is - // available, otherwise we need to restart our searching. - // Available counts the consective number of zero bit. - // - if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) { - Available++; - - if (Available >= Units) { - break; - } - - NEXT_BIT (Byte, Bit); - - } else { - NEXT_BIT (Byte, Bit); - - Available = 0; - StartByte = Byte; - StartBit = Bit; - } - } - - if (Available < Units) { - return NULL; - } - - // - // Mark the memory as allocated - // - Byte = StartByte; - Bit = StartBit; - - for (Count = 0; Count < Units; Count++) { - ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT; -} - -/** - Calculate the corresponding pci bus address according to the Mem parameter. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to host memory. - @param Size The size of the memory region. - - @return The pci memory address - -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetPciAddrForHostAddr ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINTN AllocSize; - EFI_PHYSICAL_ADDRESS PhyAddr; - UINTN Offset; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - - if (Mem == NULL) { - return 0; - } - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the allocated memory. - // - if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) { - break; - } - } - - ASSERT ((Block != NULL)); - // - // calculate the pci memory address for host memory address. - // - Offset = (UINT8 *)Mem - Block->BufHost; - PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset); - return PhyAddr; -} - -/** - Calculate the corresponding host address according to the pci address. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to pci memory. - @param Size The size of the memory region. - - @return The host memory address - -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetHostAddrForPciAddr ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINTN AllocSize; - EFI_PHYSICAL_ADDRESS HostAddr; - UINTN Offset; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - - if (Mem == NULL) { - return 0; - } - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the allocated memory. - // - if ((Block->Buf <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->Buf + Block->BufLen))) { - break; - } - } - - ASSERT ((Block != NULL)); - // - // calculate the pci memory address for host memory address. - // - Offset = (UINT8 *)Mem - Block->Buf; - HostAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->BufHost + Offset); - return HostAddr; -} - -/** - Insert the memory block to the pool's list of the blocks. - - @param Head The head of the memory pool's block list. - @param Block The memory block to insert. - -**/ -VOID -UsbHcInsertMemBlockToPool ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *Block - ) -{ - ASSERT ((Head != NULL) && (Block != NULL)); - Block->Next = Head->Next; - Head->Next = Block; -} - - -/** - Is the memory block empty? - - @param Block The memory block to check. - - @retval TRUE The memory block is empty. - @retval FALSE The memory block isn't empty. - -**/ -BOOLEAN -UsbHcIsMemBlockEmpty ( - IN USBHC_MEM_BLOCK *Block - ) -{ - UINTN Index; - - for (Index = 0; Index < Block->BitsLen; Index++) { - if (Block->Bits[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - - -/** - Unlink the memory block from the pool's list. - - @param Head The block list head of the memory's pool. - @param BlockToUnlink The memory block to unlink. - -**/ -VOID -UsbHcUnlinkMemBlock ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *BlockToUnlink - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT ((Head != NULL) && (BlockToUnlink != NULL)); - - for (Block = Head; Block != NULL; Block = Block->Next) { - if (Block->Next == BlockToUnlink) { - Block->Next = BlockToUnlink->Next; - BlockToUnlink->Next = NULL; - break; - } - } -} - - -/** - Initialize the memory management pool for the host controller. - - @param PciIo The PciIo that can be used to access the host controller. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ) -{ - USBHC_MEM_POOL *Pool; - - Pool = AllocatePool (sizeof (USBHC_MEM_POOL)); - - if (Pool == NULL) { - return Pool; - } - - Pool->PciIo = PciIo; - Pool->Head = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES); - - if (Pool->Head == NULL) { - gBS->FreePool (Pool); - Pool = NULL; - } - - return Pool; -} - - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - - @retval EFI_SUCCESS The memory pool is freed. - @retval EFI_DEVICE_ERROR Failed to free the memory pool. - -**/ -EFI_STATUS -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT (Pool->Head != NULL); - - // - // Unlink all the memory blocks from the pool, then free them. - // UsbHcUnlinkMemBlock can't be used to unlink and free the - // first block. - // - for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) { - UsbHcUnlinkMemBlock (Pool->Head, Block); - UsbHcFreeMemBlock (Pool, Block); - } - - UsbHcFreeMemBlock (Pool, Pool->Head); - gBS->FreePool (Pool); - return EFI_SUCCESS; -} - - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - USBHC_MEM_BLOCK *NewBlock; - VOID *Mem; - UINTN AllocSize; - UINTN Pages; - - Mem = NULL; - AllocSize = USBHC_MEM_ROUND (Size); - Head = Pool->Head; - ASSERT (Head != NULL); - - // - // First check whether current memory blocks can satisfy the allocation. - // - for (Block = Head; Block != NULL; Block = Block->Next) { - Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - break; - } - } - - if (Mem != NULL) { - return Mem; - } - - // - // Create a new memory block if there is not enough memory - // in the pool. If the allocation size is larger than the - // default page number, just allocate a large enough memory - // block. Otherwise allocate default pages. - // - if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) { - Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1; - } else { - Pages = USBHC_MEM_DEFAULT_PAGES; - } - - NewBlock = UsbHcAllocMemBlock (Pool, Pages); - - if (NewBlock == NULL) { - DEBUG ((EFI_D_ERROR, "UsbHcAllocateMem: failed to allocate block\n")); - return NULL; - } - - // - // Add the new memory block to the pool, then allocate memory from it - // - UsbHcInsertMemBlockToPool (Head, NewBlock); - Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - } - - return Mem; -} - - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINT8 *ToFree; - UINTN AllocSize; - UINTN Byte; - UINTN Bit; - UINTN Count; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - ToFree = (UINT8 *) Mem; - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the memory to free. - // - if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) { - // - // compute the start byte and bit in the bit array - // - Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8; - Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8; - - // - // reset associated bits in bit arry - // - for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) { - ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - break; - } - } - - // - // If Block == NULL, it means that the current memory isn't - // in the host controller's pool. This is critical because - // the caller has passed in a wrong memory point - // - ASSERT (Block != NULL); - - // - // Release the current memory block if it is empty and not the head - // - if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) { - UsbHcUnlinkMemBlock (Head, Block); - UsbHcFreeMemBlock (Pool, Block); - } - - return ; -} - -/** - Allocates pages at a specified alignment that are suitable for an EfiPciIoOperationBusMasterCommonBuffer mapping. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param PciIo The PciIo that can be used to access the host controller. - @param Pages The number of pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - @param HostAddress The system memory address to map to the PCI controller. - @param DeviceAddress The resulting map address for the bus master PCI controller to - use to access the hosts HostAddress. - @param Mapping A resulting value to pass to Unmap(). - - @retval EFI_SUCCESS Success to allocate aligned pages. - @retval EFI_INVALID_PARAMETER Pages or Alignment is not valid. - @retval EFI_OUT_OF_RESOURCES Do not have enough resources to allocate memory. - - -**/ -EFI_STATUS -UsbHcAllocateAlignedPages ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINTN Pages, - IN UINTN Alignment, - OUT VOID **HostAddress, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ) -{ - EFI_STATUS Status; - VOID *Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - UINTN Bytes; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if ((Alignment & (Alignment - 1)) != 0) { - return EFI_INVALID_PARAMETER; - } - - if (Pages == 0) { - return EFI_INVALID_PARAMETER; - } - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - Pages, - &Memory, - 0 - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = PciIo->FreeBuffer (PciIo, UnalignedPages, Memory); - ASSERT_EFI_ERROR (Status); - } - Memory = (VOID *)(UINTN)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = PciIo->FreeBuffer (PciIo, UnalignedPages, Memory); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = PciIo->AllocateBuffer ( - PciIo, - AllocateAnyPages, - EfiBootServicesData, - Pages, - &Memory, - 0 - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - AlignedMemory = (UINTN) Memory; - } - - Bytes = EFI_PAGES_TO_SIZE (Pages); - Status = PciIo->Map ( - PciIo, - EfiPciIoOperationBusMasterCommonBuffer, - (VOID *) AlignedMemory, - &Bytes, - DeviceAddress, - Mapping - ); - - if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) { - Status = PciIo->FreeBuffer (PciIo, Pages, (VOID *) AlignedMemory); - return EFI_OUT_OF_RESOURCES; - } - - *HostAddress = (VOID *) AlignedMemory; - - return EFI_SUCCESS; -} - -/** - Frees memory that was allocated with UsbHcAllocateAlignedPages(). - - @param PciIo The PciIo that can be used to access the host controller. - @param HostAddress The system memory address to map to the PCI controller. - @param Pages The number of 4 KB pages to free. - @param Mapping The mapping value returned from Map(). - -**/ -VOID -UsbHcFreeAlignedPages ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN VOID *HostAddress, - IN UINTN Pages, - VOID *Mapping - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - - Status = PciIo->Unmap (PciIo, Mapping); - ASSERT_EFI_ERROR (Status); - - Status = PciIo->FreeBuffer ( - PciIo, - Pages, - HostAddress - ); - ASSERT_EFI_ERROR (Status); -} diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h deleted file mode 100644 index 1907685ddd..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/UsbHcMem.h +++ /dev/null @@ -1,213 +0,0 @@ -/** @file - - This file contains the definination for host controller memory management routines. - -Copyright (c) 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_XHCI_MEM_H_ -#define _EFI_XHCI_MEM_H_ - -#define USB_HC_BIT(a) ((UINTN)(1 << (a))) - -#define USB_HC_BIT_IS_SET(Data, Bit) \ - ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit))) - -typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK; -struct _USBHC_MEM_BLOCK { - UINT8 *Bits; // Bit array to record which unit is allocated - UINTN BitsLen; - UINT8 *Buf; - UINT8 *BufHost; - UINTN BufLen; // Memory size in bytes - VOID *Mapping; - USBHC_MEM_BLOCK *Next; -}; - -// -// USBHC_MEM_POOL is used to manage the memory used by USB -// host controller. XHCI requires the control memory and transfer -// data to be on the same 4G memory. -// -typedef struct _USBHC_MEM_POOL { - EFI_PCI_IO_PROTOCOL *PciIo; - BOOLEAN Check4G; - UINT32 Which4G; - USBHC_MEM_BLOCK *Head; -} USBHC_MEM_POOL; - -// -// Memory allocation unit, must be 2^n, n>4 -// -#define USBHC_MEM_UNIT 64 - -#define USBHC_MEM_UNIT_MASK (USBHC_MEM_UNIT - 1) -#define USBHC_MEM_DEFAULT_PAGES 16 - -#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK)) - -// -// Advance the byte and bit to the next bit, adjust byte accordingly. -// -#define NEXT_BIT(Byte, Bit) \ - do { \ - (Bit)++; \ - if ((Bit) > 7) { \ - (Byte)++; \ - (Bit) = 0; \ - } \ - } while (0) - - - -/** - Initialize the memory management pool for the host controller. - - @param PciIo The PciIo that can be used to access the host controller. - - @retval EFI_SUCCESS The memory pool is initialized. - @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - IN EFI_PCI_IO_PROTOCOL *PciIo - ); - - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - - @retval EFI_SUCCESS The memory pool is freed. - @retval EFI_DEVICE_ERROR Failed to free the memory pool. - -**/ -EFI_STATUS -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ); - - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ); - - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -/** - Calculate the corresponding pci bus address according to the Mem parameter. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to host memory. - @param Size The size of the memory region. - - @return The pci memory address - -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetPciAddrForHostAddr ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -/** - Calculate the corresponding host address according to the pci address. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to pci memory. - @param Size The size of the memory region. - - @return The host memory address - -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetHostAddrForPciAddr ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -/** - Allocates pages at a specified alignment that are suitable for an EfiPciIoOperationBusMasterCommonBuffer mapping. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param PciIo The PciIo that can be used to access the host controller. - @param Pages The number of pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - @param HostAddress The system memory address to map to the PCI controller. - @param DeviceAddress The resulting map address for the bus master PCI controller to - use to access the hosts HostAddress. - @param Mapping A resulting value to pass to Unmap(). - - @retval EFI_SUCCESS Success to allocate aligned pages. - @retval EFI_INVALID_PARAMETER Pages or Alignment is not valid. - @retval EFI_OUT_OF_RESOURCES Do not have enough resources to allocate memory. - - -**/ -EFI_STATUS -UsbHcAllocateAlignedPages ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINTN Pages, - IN UINTN Alignment, - OUT VOID **HostAddress, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, - OUT VOID **Mapping - ); - -/** - Frees memory that was allocated with UsbHcAllocateAlignedPages(). - - @param PciIo The PciIo that can be used to access the host controller. - @param HostAddress The system memory address to map to the PCI controller. - @param Pages The number of pages to free. - @param Mapping The mapping value returned from Map(). - -**/ -VOID -UsbHcFreeAlignedPages ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN VOID *HostAddress, - IN UINTN Pages, - VOID *Mapping - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c deleted file mode 100644 index 39c28ab7d8..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c +++ /dev/null @@ -1,2250 +0,0 @@ -/** @file - The XHCI controller driver. - -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Xhci.h" - -// -// Two arrays used to translate the XHCI port state (change) -// to the UEFI protocol's port state (change). -// -USB_PORT_STATE_MAP mUsbPortStateMap[] = { - {XHC_PORTSC_CCS, USB_PORT_STAT_CONNECTION}, - {XHC_PORTSC_PED, USB_PORT_STAT_ENABLE}, - {XHC_PORTSC_OCA, USB_PORT_STAT_OVERCURRENT}, - {XHC_PORTSC_RESET, USB_PORT_STAT_RESET} -}; - -USB_PORT_STATE_MAP mUsbPortChangeMap[] = { - {XHC_PORTSC_CSC, USB_PORT_STAT_C_CONNECTION}, - {XHC_PORTSC_PEC, USB_PORT_STAT_C_ENABLE}, - {XHC_PORTSC_OCC, USB_PORT_STAT_C_OVERCURRENT}, - {XHC_PORTSC_PRC, USB_PORT_STAT_C_RESET} -}; - -USB_CLEAR_PORT_MAP mUsbClearPortChangeMap[] = { - {XHC_PORTSC_CSC, EfiUsbPortConnectChange}, - {XHC_PORTSC_PEC, EfiUsbPortEnableChange}, - {XHC_PORTSC_OCC, EfiUsbPortOverCurrentChange}, - {XHC_PORTSC_PRC, EfiUsbPortResetChange} -}; - -USB_PORT_STATE_MAP mUsbHubPortStateMap[] = { - {XHC_HUB_PORTSC_CCS, USB_PORT_STAT_CONNECTION}, - {XHC_HUB_PORTSC_PED, USB_PORT_STAT_ENABLE}, - {XHC_HUB_PORTSC_OCA, USB_PORT_STAT_OVERCURRENT}, - {XHC_HUB_PORTSC_RESET, USB_PORT_STAT_RESET} -}; - -USB_PORT_STATE_MAP mUsbHubPortChangeMap[] = { - {XHC_HUB_PORTSC_CSC, USB_PORT_STAT_C_CONNECTION}, - {XHC_HUB_PORTSC_PEC, USB_PORT_STAT_C_ENABLE}, - {XHC_HUB_PORTSC_OCC, USB_PORT_STAT_C_OVERCURRENT}, - {XHC_HUB_PORTSC_PRC, USB_PORT_STAT_C_RESET} -}; - -USB_CLEAR_PORT_MAP mUsbHubClearPortChangeMap[] = { - {XHC_HUB_PORTSC_CSC, EfiUsbPortConnectChange}, - {XHC_HUB_PORTSC_PEC, EfiUsbPortEnableChange}, - {XHC_HUB_PORTSC_OCC, EfiUsbPortOverCurrentChange}, - {XHC_HUB_PORTSC_PRC, EfiUsbPortResetChange}, - {XHC_HUB_PORTSC_BHRC, Usb3PortBHPortResetChange} -}; - -EFI_DRIVER_BINDING_PROTOCOL gXhciDriverBinding = { - XhcDriverBindingSupported, - XhcDriverBindingStart, - XhcDriverBindingStop, - 0x30, - NULL, - NULL -}; - -// -// Template for Xhci's Usb2 Host Controller Protocol Instance. -// -EFI_USB2_HC_PROTOCOL gXhciUsb2HcTemplate = { - XhcGetCapability, - XhcReset, - XhcGetState, - XhcSetState, - XhcControlTransfer, - XhcBulkTransfer, - XhcAsyncInterruptTransfer, - XhcSyncInterruptTransfer, - XhcIsochronousTransfer, - XhcAsyncIsochronousTransfer, - XhcGetRootHubPortStatus, - XhcSetRootHubPortFeature, - XhcClearRootHubPortFeature, - 0x3, - 0x0 -}; - -/** - Retrieves the capability of root hub ports. - - @param This The EFI_USB2_HC_PROTOCOL instance. - @param MaxSpeed Max speed supported by the controller. - @param PortNumber Number of the root hub ports. - @param Is64BitCapable Whether the controller supports 64-bit memory - addressing. - - @retval EFI_SUCCESS Host controller capability were retrieved successfully. - @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL. - -**/ -EFI_STATUS -EFIAPI -XhcGetCapability ( - IN EFI_USB2_HC_PROTOCOL *This, - OUT UINT8 *MaxSpeed, - OUT UINT8 *PortNumber, - OUT UINT8 *Is64BitCapable - ) -{ - USB_XHCI_INSTANCE *Xhc; - EFI_TPL OldTpl; - - if ((MaxSpeed == NULL) || (PortNumber == NULL) || (Is64BitCapable == NULL)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - *MaxSpeed = EFI_USB_SPEED_SUPER; - *PortNumber = (UINT8) (Xhc->HcSParams1.Data.MaxPorts); - *Is64BitCapable = (UINT8) (Xhc->HcCParams.Data.Ac64); - DEBUG ((EFI_D_INFO, "XhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable)); - - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; -} - - -/** - Provides software reset for the USB host controller. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param Attributes A bit mask of the reset operation to perform. - - @retval EFI_SUCCESS The reset operation succeeded. - @retval EFI_INVALID_PARAMETER Attributes is not valid. - @retval EFI_UNSUPPOURTED The type of reset specified by Attributes is - not currently supported by the host controller. - @retval EFI_DEVICE_ERROR Host controller isn't halted to reset. - -**/ -EFI_STATUS -EFIAPI -XhcReset ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT16 Attributes - ) -{ - USB_XHCI_INSTANCE *Xhc; - EFI_STATUS Status; - EFI_TPL OldTpl; - - Xhc = XHC_FROM_THIS (This); - - if (Xhc->DevicePath != NULL) { - // - // Report Status Code to indicate reset happens - // - REPORT_STATUS_CODE_WITH_DEVICE_PATH ( - EFI_PROGRESS_CODE, - (EFI_IO_BUS_USB | EFI_IOB_PC_RESET), - Xhc->DevicePath - ); - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - switch (Attributes) { - case EFI_USB_HC_RESET_GLOBAL: - // - // Flow through, same behavior as Host Controller Reset - // - case EFI_USB_HC_RESET_HOST_CONTROLLER: - if ((Xhc->DebugCapSupOffset != 0xFFFFFFFF) && ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) == XHC_CAP_USB_DEBUG) && - ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) != 0)) { - Status = EFI_SUCCESS; - goto ON_EXIT; - } - // - // Host Controller must be Halt when Reset it - // - if (!XhcIsHalt (Xhc)) { - Status = XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto ON_EXIT; - } - } - - Status = XhcResetHC (Xhc, XHC_RESET_TIMEOUT); - ASSERT (!(XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_CNR))); - - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - // - // Clean up the asynchronous transfers, currently only - // interrupt supports asynchronous operation. - // - XhciDelAllAsyncIntTransfers (Xhc); - XhcFreeSched (Xhc); - - XhcInitSched (Xhc); - break; - - case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG: - case EFI_USB_HC_RESET_HOST_WITH_DEBUG: - Status = EFI_UNSUPPORTED; - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - -ON_EXIT: - DEBUG ((EFI_D_INFO, "XhcReset: status %r\n", Status)); - gBS->RestoreTPL (OldTpl); - - return Status; -} - - -/** - Retrieve the current state of the USB host controller. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param State Variable to return the current host controller - state. - - @retval EFI_SUCCESS Host controller state was returned in State. - @retval EFI_INVALID_PARAMETER State is NULL. - @retval EFI_DEVICE_ERROR An error was encountered while attempting to - retrieve the host controller's current state. - -**/ -EFI_STATUS -EFIAPI -XhcGetState ( - IN EFI_USB2_HC_PROTOCOL *This, - OUT EFI_USB_HC_STATE *State - ) -{ - USB_XHCI_INSTANCE *Xhc; - EFI_TPL OldTpl; - - if (State == NULL) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - - if (XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) { - *State = EfiUsbHcStateHalt; - } else { - *State = EfiUsbHcStateOperational; - } - - DEBUG ((EFI_D_INFO, "XhcGetState: current state %d\n", *State)); - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; -} - -/** - Sets the USB host controller to a specific state. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param State The state of the host controller that will be set. - - @retval EFI_SUCCESS The USB host controller was successfully placed - in the state specified by State. - @retval EFI_INVALID_PARAMETER State is invalid. - @retval EFI_DEVICE_ERROR Failed to set the state due to device error. - -**/ -EFI_STATUS -EFIAPI -XhcSetState ( - IN EFI_USB2_HC_PROTOCOL *This, - IN EFI_USB_HC_STATE State - ) -{ - USB_XHCI_INSTANCE *Xhc; - EFI_STATUS Status; - EFI_USB_HC_STATE CurState; - EFI_TPL OldTpl; - - Status = XhcGetState (This, &CurState); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - if (CurState == State) { - return EFI_SUCCESS; - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - - switch (State) { - case EfiUsbHcStateHalt: - Status = XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT); - break; - - case EfiUsbHcStateOperational: - if (XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE)) { - Status = EFI_DEVICE_ERROR; - break; - } - - // - // Software must not write a one to this field unless the host controller - // is in the Halted state. Doing so will yield undefined results. - // refers to Spec[XHCI1.0-2.3.1] - // - if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) { - Status = EFI_DEVICE_ERROR; - break; - } - - Status = XhcRunHC (Xhc, XHC_GENERIC_TIMEOUT); - break; - - case EfiUsbHcStateSuspend: - Status = EFI_UNSUPPORTED; - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - - DEBUG ((EFI_D_INFO, "XhcSetState: status %r\n", Status)); - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Retrieves the current status of a USB root hub port. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param PortNumber The root hub port to retrieve the state from. - This value is zero-based. - @param PortStatus Variable to receive the port state. - - @retval EFI_SUCCESS The status of the USB root hub port specified. - by PortNumber was returned in PortStatus. - @retval EFI_INVALID_PARAMETER PortNumber is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -XhcGetRootHubPortStatus ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - OUT EFI_USB_PORT_STATUS *PortStatus - ) -{ - USB_XHCI_INSTANCE *Xhc; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - UINTN Index; - UINTN MapSize; - EFI_STATUS Status; - USB_DEV_ROUTE ParentRouteChart; - EFI_TPL OldTpl; - - if (PortStatus == NULL) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - Status = EFI_SUCCESS; - - TotalPort = Xhc->HcSParams1.Data.MaxPorts; - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = (UINT32) (XHC_PORTSC_OFFSET + (0x10 * PortNumber)); - PortStatus->PortStatus = 0; - PortStatus->PortChangeStatus = 0; - - State = XhcReadOpReg (Xhc, Offset); - - // - // According to XHCI 1.0 spec, bit 10~13 of the root port status register identifies the speed of the attached device. - // - switch ((State & XHC_PORTSC_PS) >> 10) { - case 2: - PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED; - break; - - case 3: - PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED; - break; - - case 4: - PortStatus->PortStatus |= USB_PORT_STAT_SUPER_SPEED; - break; - - default: - break; - } - - // - // Convert the XHCI port/port change state to UEFI status - // - MapSize = sizeof (mUsbPortStateMap) / sizeof (USB_PORT_STATE_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) { - PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState); - } - } - // - // Bit5~8 reflects its current link state. - // - if ((State & XHC_PORTSC_PLS) >> 5 == 3) { - PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND; - } - - MapSize = sizeof (mUsbPortChangeMap) / sizeof (USB_PORT_STATE_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) { - PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState); - } - } - - MapSize = sizeof (mUsbClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbClearPortChangeMap[Index].HwState)) { - XhcClearRootHubPortFeature (This, PortNumber, (EFI_USB_PORT_FEATURE)mUsbClearPortChangeMap[Index].Selector); - } - } - - // - // Poll the root port status register to enable/disable corresponding device slot if there is a device attached/detached. - // For those devices behind hub, we get its attach/detach event by hooking Get_Port_Status request at control transfer for those hub. - // - ParentRouteChart.Dword = 0; - XhcPollPortStatusChange (Xhc, ParentRouteChart, PortNumber, PortStatus); - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Sets a feature for the specified root hub port. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param PortNumber Root hub port to set. - @param PortFeature Feature to set. - - @retval EFI_SUCCESS The feature specified by PortFeature was set. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -XhcSetRootHubPortFeature ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - USB_XHCI_INSTANCE *Xhc; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - Status = EFI_SUCCESS; - - TotalPort = (Xhc->HcSParams1.Data.MaxPorts); - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = (UINT32) (XHC_PORTSC_OFFSET + (0x10 * PortNumber)); - State = XhcReadOpReg (Xhc, Offset); - - // - // Mask off the port status change bits, these bits are - // write clean bit - // - State &= ~ (BIT1 | BIT17 | BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23); - - switch (PortFeature) { - case EfiUsbPortEnable: - // - // Ports may only be enabled by the xHC. Software cannot enable a port by writing a '1' to this flag. - // A port may be disabled by software writing a '1' to this flag. - // - Status = EFI_SUCCESS; - break; - - case EfiUsbPortSuspend: - State |= XHC_PORTSC_LWS; - XhcWriteOpReg (Xhc, Offset, State); - State &= ~XHC_PORTSC_PLS; - State |= (3 << 5) ; - XhcWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortReset: - DEBUG ((EFI_D_INFO, "XhcUsbPortReset!\n")); - // - // Make sure Host Controller not halt before reset it - // - if (XhcIsHalt (Xhc)) { - Status = XhcRunHC (Xhc, XHC_GENERIC_TIMEOUT); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, "XhcSetRootHubPortFeature :failed to start HC - %r\n", Status)); - break; - } - } - - // - // 4.3.1 Resetting a Root Hub Port - // 1) Write the PORTSC register with the Port Reset (PR) bit set to '1'. - // - State |= XHC_PORTSC_RESET; - XhcWriteOpReg (Xhc, Offset, State); - XhcWaitOpRegBit(Xhc, Offset, XHC_PORTSC_PRC, TRUE, XHC_GENERIC_TIMEOUT); - break; - - case EfiUsbPortPower: - // - // Not supported, ignore the operation - // - Status = EFI_SUCCESS; - break; - - case EfiUsbPortOwner: - // - // XHCI root hub port don't has the owner bit, ignore the operation - // - Status = EFI_SUCCESS; - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - -ON_EXIT: - DEBUG ((EFI_D_INFO, "XhcSetRootHubPortFeature: status %r\n", Status)); - gBS->RestoreTPL (OldTpl); - - return Status; -} - - -/** - Clears a feature for the specified root hub port. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param PortNumber Specifies the root hub port whose feature is - requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. - - @retval EFI_SUCCESS The feature specified by PortFeature was cleared - for the USB root hub port specified by PortNumber. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -XhcClearRootHubPortFeature ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - USB_XHCI_INSTANCE *Xhc; - UINT32 Offset; - UINT32 State; - UINT32 TotalPort; - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - Status = EFI_SUCCESS; - - TotalPort = (Xhc->HcSParams1.Data.MaxPorts); - - if (PortNumber >= TotalPort) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = XHC_PORTSC_OFFSET + (0x10 * PortNumber); - - // - // Mask off the port status change bits, these bits are - // write clean bit - // - State = XhcReadOpReg (Xhc, Offset); - State &= ~ (BIT1 | BIT17 | BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23); - - switch (PortFeature) { - case EfiUsbPortEnable: - // - // Ports may only be enabled by the xHC. Software cannot enable a port by writing a '1' to this flag. - // A port may be disabled by software writing a '1' to this flag. - // - State |= XHC_PORTSC_PED; - State &= ~XHC_PORTSC_RESET; - XhcWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortSuspend: - State |= XHC_PORTSC_LWS; - XhcWriteOpReg (Xhc, Offset, State); - State &= ~XHC_PORTSC_PLS; - XhcWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortReset: - // - // PORTSC_RESET BIT(4) bit is RW1S attribute, which means Write-1-to-set status: - // Register bits indicate status when read, a clear bit may be set by - // writing a '1'. Writing a '0' to RW1S bits has no effect. - // - break; - - case EfiUsbPortOwner: - // - // XHCI root hub port don't has the owner bit, ignore the operation - // - break; - - case EfiUsbPortConnectChange: - // - // Clear connect status change - // - State |= XHC_PORTSC_CSC; - XhcWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortEnableChange: - // - // Clear enable status change - // - State |= XHC_PORTSC_PEC; - XhcWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortOverCurrentChange: - // - // Clear PortOverCurrent change - // - State |= XHC_PORTSC_OCC; - XhcWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortResetChange: - // - // Clear Port Reset change - // - State |= XHC_PORTSC_PRC; - XhcWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortPower: - case EfiUsbPortSuspendChange: - // - // Not supported or not related operation - // - break; - - default: - Status = EFI_INVALID_PARAMETER; - break; - } - -ON_EXIT: - DEBUG ((EFI_D_INFO, "XhcClearRootHubPortFeature: status %r\n", Status)); - gBS->RestoreTPL (OldTpl); - - return Status; -} - - -/** - Submits control transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress The target device address. - @param DeviceSpeed Target device speed. - @param MaximumPacketLength Maximum packet size the default control transfer - endpoint is capable of sending or receiving. - @param Request USB device request to send. - @param TransferDirection Specifies the data direction for the data stage - @param Data Data buffer to be transmitted or received from USB - device. - @param DataLength The size (in bytes) of the data buffer. - @param Timeout Indicates the maximum timeout, in millisecond. - @param Translator Transaction translator to be used by this device. - @param TransferResult Return the result of this control transfer. - - @retval EFI_SUCCESS Transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT Transfer failed due to timeout. - @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -XhcControlTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN EFI_USB_DEVICE_REQUEST *Request, - IN EFI_USB_DATA_DIRECTION TransferDirection, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN UINTN Timeout, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - USB_XHCI_INSTANCE *Xhc; - URB *Urb; - UINT8 Endpoint; - UINT8 Index; - UINT8 DescriptorType; - UINT8 SlotId; - UINT8 TTT; - UINT8 MTT; - UINT32 MaxPacket0; - EFI_USB_HUB_DESCRIPTOR *HubDesc; - EFI_TPL OldTpl; - EFI_STATUS Status; - EFI_STATUS RecoveryStatus; - UINTN MapSize; - EFI_USB_PORT_STATUS PortStatus; - UINT32 State; - EFI_USB_DEVICE_REQUEST ClearPortRequest; - UINTN Len; - - // - // Validate parameters - // - if ((Request == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbDataIn) && - (TransferDirection != EfiUsbDataOut) && - (TransferDirection != EfiUsbNoData)) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection == EfiUsbNoData) && - ((Data != NULL) || (*DataLength != 0))) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbNoData) && - ((Data == NULL) || (*DataLength == 0))) { - return EFI_INVALID_PARAMETER; - } - - if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) && - (MaximumPacketLength != 32) && (MaximumPacketLength != 64) && - (MaximumPacketLength != 512) - ) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_SUPER) && (MaximumPacketLength != 512)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - - Status = EFI_DEVICE_ERROR; - *TransferResult = EFI_USB_ERR_SYSTEM; - Len = 0; - - if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) { - DEBUG ((EFI_D_ERROR, "XhcControlTransfer: HC halted at entrance\n")); - goto ON_EXIT; - } - - // - // Check if the device is still enabled before every transaction. - // - SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress); - if (SlotId == 0) { - goto ON_EXIT; - } - - // - // Hook the Set_Address request from UsbBus. - // According to XHCI 1.0 spec, the Set_Address request is replaced by XHCI's Address_Device cmd. - // - if ((Request->Request == USB_REQ_SET_ADDRESS) && - (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) { - // - // Reset the BusDevAddr field of all disabled entries in UsbDevContext array firstly. - // This way is used to clean the history to avoid using wrong device address by XhcAsyncInterruptTransfer(). - // - for (Index = 0; Index < 255; Index++) { - if (!Xhc->UsbDevContext[Index + 1].Enabled && - (Xhc->UsbDevContext[Index + 1].SlotId == 0) && - (Xhc->UsbDevContext[Index + 1].BusDevAddr == (UINT8)Request->Value)) { - Xhc->UsbDevContext[Index + 1].BusDevAddr = 0; - } - } - - if (Xhc->UsbDevContext[SlotId].XhciDevAddr == 0) { - Status = EFI_DEVICE_ERROR; - goto ON_EXIT; - } - // - // The actual device address has been assigned by XHCI during initializing the device slot. - // So we just need establish the mapping relationship between the device address requested from UsbBus - // and the actual device address assigned by XHCI. The the following invocations through EFI_USB2_HC_PROTOCOL interface - // can find out the actual device address by it. - // - Xhc->UsbDevContext[SlotId].BusDevAddr = (UINT8)Request->Value; - Status = EFI_SUCCESS; - goto ON_EXIT; - } - - // - // Create a new URB, insert it into the asynchronous - // schedule list, then poll the execution status. - // Note that we encode the direction in address although default control - // endpoint is bidirectional. XhcCreateUrb expects this - // combination of Ep addr and its direction. - // - Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0)); - Urb = XhcCreateUrb ( - Xhc, - DeviceAddress, - Endpoint, - DeviceSpeed, - MaximumPacketLength, - XHC_CTRL_TRANSFER, - Request, - Data, - *DataLength, - NULL, - NULL - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "XhcControlTransfer: failed to create URB")); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout); - - // - // Get the status from URB. The result is updated in XhcCheckUrbResult - // which is called by XhcExecTransfer - // - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - - if (Status == EFI_TIMEOUT) { - // - // The transfer timed out. Abort the transfer by dequeueing of the TD. - // - RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb); - if (EFI_ERROR(RecoveryStatus)) { - DEBUG((EFI_D_ERROR, "XhcControlTransfer: XhcDequeueTrbFromEndpoint failed\n")); - } - goto FREE_URB; - } else { - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } else if (*TransferResult == EFI_USB_ERR_STALL) { - RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb); - if (EFI_ERROR (RecoveryStatus)) { - DEBUG ((EFI_D_ERROR, "XhcControlTransfer: XhcRecoverHaltedEndpoint failed\n")); - } - Status = EFI_DEVICE_ERROR; - goto FREE_URB; - } else { - goto FREE_URB; - } - } - - Xhc->PciIo->Flush (Xhc->PciIo); - - if (Urb->DataMap != NULL) { - Status = Xhc->PciIo->Unmap (Xhc->PciIo, Urb->DataMap); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto FREE_URB; - } - } - - // - // Hook Get_Descriptor request from UsbBus as we need evaluate context and configure endpoint. - // Hook Get_Status request form UsbBus as we need trace device attach/detach event happened at hub. - // Hook Set_Config request from UsbBus as we need configure device endpoint. - // - if ((Request->Request == USB_REQ_GET_DESCRIPTOR) && - ((Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE)) || - ((Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_DEVICE))))) { - DescriptorType = (UINT8)(Request->Value >> 8); - if ((DescriptorType == USB_DESC_TYPE_DEVICE) && ((*DataLength == sizeof (EFI_USB_DEVICE_DESCRIPTOR)) || ((DeviceSpeed == EFI_USB_SPEED_FULL) && (*DataLength == 8)))) { - ASSERT (Data != NULL); - // - // Store a copy of device scriptor as hub device need this info to configure endpoint. - // - CopyMem (&Xhc->UsbDevContext[SlotId].DevDesc, Data, *DataLength); - if (Xhc->UsbDevContext[SlotId].DevDesc.BcdUSB == 0x0300) { - // - // If it's a usb3.0 device, then its max packet size is a 2^n. - // - MaxPacket0 = 1 << Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0; - } else { - MaxPacket0 = Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0; - } - Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *)); - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcEvaluateContext (Xhc, SlotId, MaxPacket0); - } else { - Status = XhcEvaluateContext64 (Xhc, SlotId, MaxPacket0); - } - } else if (DescriptorType == USB_DESC_TYPE_CONFIG) { - ASSERT (Data != NULL); - if (*DataLength == ((UINT16 *)Data)[1]) { - // - // Get configuration value from request, Store the configuration descriptor for Configure_Endpoint cmd. - // - Index = (UINT8)Request->Value; - ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations); - Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool(*DataLength); - CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength); - // - // Default to use AlternateSetting 0 for all interfaces. - // - Xhc->UsbDevContext[SlotId].ActiveAlternateSetting = AllocateZeroPool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->NumInterfaces * sizeof (UINT8)); - } - } else if (((DescriptorType == USB_DESC_TYPE_HUB) || - (DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && (*DataLength > 2)) { - ASSERT (Data != NULL); - HubDesc = (EFI_USB_HUB_DESCRIPTOR *)Data; - ASSERT (HubDesc->NumPorts <= 15); - // - // The bit 5,6 of HubCharacter field of Hub Descriptor is TTT. - // - TTT = (UINT8)((HubDesc->HubCharacter & (BIT5 | BIT6)) >> 5); - if (Xhc->UsbDevContext[SlotId].DevDesc.DeviceProtocol == 2) { - // - // Don't support multi-TT feature for super speed hub now. - // - MTT = 0; - DEBUG ((EFI_D_ERROR, "XHCI: Don't support multi-TT feature for Hub now. (force to disable MTT)\n")); - } else { - MTT = 0; - } - - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcConfigHubContext (Xhc, SlotId, HubDesc->NumPorts, TTT, MTT); - } else { - Status = XhcConfigHubContext64 (Xhc, SlotId, HubDesc->NumPorts, TTT, MTT); - } - } - } else if ((Request->Request == USB_REQ_SET_CONFIG) && - (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) { - // - // Hook Set_Config request from UsbBus as we need configure device endpoint. - // - for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) { - if (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->ConfigurationValue == (UINT8)Request->Value) { - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcSetConfigCmd (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Index]); - } else { - Status = XhcSetConfigCmd64 (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Index]); - } - break; - } - } - } else if ((Request->Request == USB_REQ_SET_INTERFACE) && - (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_INTERFACE))) { - // - // Hook Set_Interface request from UsbBus as we need configure interface setting. - // Request->Value indicates AlterlateSetting to set - // Request->Index indicates Interface to set - // - if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] != (UINT8) Request->Value) { - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcSetInterface (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request); - } else { - Status = XhcSetInterface64 (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Xhc->UsbDevContext[SlotId].ActiveConfiguration - 1], Request); - } - } - } else if ((Request->Request == USB_REQ_GET_STATUS) && - (Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER))) { - ASSERT (Data != NULL); - // - // Hook Get_Status request from UsbBus to keep track of the port status change. - // - State = *(UINT32 *)Data; - PortStatus.PortStatus = 0; - PortStatus.PortChangeStatus = 0; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - // - // For super speed hub, its bit10~12 presents the attached device speed. - // - if ((State & XHC_PORTSC_PS) >> 10 == 0) { - PortStatus.PortStatus |= USB_PORT_STAT_SUPER_SPEED; - } - } else { - // - // For high or full/low speed hub, its bit9~10 presents the attached device speed. - // - if (XHC_BIT_IS_SET (State, BIT9)) { - PortStatus.PortStatus |= USB_PORT_STAT_LOW_SPEED; - } else if (XHC_BIT_IS_SET (State, BIT10)) { - PortStatus.PortStatus |= USB_PORT_STAT_HIGH_SPEED; - } - } - - // - // Convert the XHCI port/port change state to UEFI status - // - MapSize = sizeof (mUsbHubPortStateMap) / sizeof (USB_PORT_STATE_MAP); - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbHubPortStateMap[Index].HwState)) { - PortStatus.PortStatus = (UINT16) (PortStatus.PortStatus | mUsbHubPortStateMap[Index].UefiState); - } - } - - MapSize = sizeof (mUsbHubPortChangeMap) / sizeof (USB_PORT_STATE_MAP); - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbHubPortChangeMap[Index].HwState)) { - PortStatus.PortChangeStatus = (UINT16) (PortStatus.PortChangeStatus | mUsbHubPortChangeMap[Index].UefiState); - } - } - - MapSize = sizeof (mUsbHubClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbHubClearPortChangeMap[Index].HwState)) { - ZeroMem (&ClearPortRequest, sizeof (EFI_USB_DEVICE_REQUEST)); - ClearPortRequest.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER); - ClearPortRequest.Request = (UINT8) USB_REQ_CLEAR_FEATURE; - ClearPortRequest.Value = mUsbHubClearPortChangeMap[Index].Selector; - ClearPortRequest.Index = Request->Index; - ClearPortRequest.Length = 0; - - XhcControlTransfer ( - This, - DeviceAddress, - DeviceSpeed, - MaximumPacketLength, - &ClearPortRequest, - EfiUsbNoData, - NULL, - &Len, - Timeout, - Translator, - TransferResult - ); - } - } - - XhcPollPortStatusChange (Xhc, Xhc->UsbDevContext[SlotId].RouteString, (UINT8)Request->Index, &PortStatus); - - *(UINT32 *)Data = *(UINT32*)&PortStatus; - } - -FREE_URB: - FreePool (Urb); - -ON_EXIT: - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - - -/** - Submits bulk transfer to a bulk endpoint of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction in bit 7. - @param DeviceSpeed Device speed, Low speed device doesn't support bulk - transfer. - @param MaximumPacketLength Maximum packet size the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data to transmit - from or receive into. - @param DataLength The lenght of the data buffer. - @param DataToggle On input, the initial data toggle for the transfer; - On output, it is updated to to next data toggle to - use of the subsequent bulk transfer. - @param Timeout Indicates the maximum time, in millisecond, which - the transfer is allowed to complete. - @param Translator A pointr to the transaction translator data. - @param TransferResult A pointer to the detailed result information of the - bulk transfer. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -XhcBulkTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN Timeout, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - USB_XHCI_INSTANCE *Xhc; - URB *Urb; - UINT8 SlotId; - EFI_STATUS Status; - EFI_STATUS RecoveryStatus; - EFI_TPL OldTpl; - - // - // Validate the parameters - // - if ((DataLength == NULL) || (*DataLength == 0) || - (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 0) && (*DataToggle != 1)) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_LOW) || - ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) || - ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512)) || - ((EFI_USB_SPEED_SUPER == DeviceSpeed) && (MaximumPacketLength > 1024))) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_DEVICE_ERROR; - - if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) { - DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: HC is halted\n")); - goto ON_EXIT; - } - - // - // Check if the device is still enabled before every transaction. - // - SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress); - if (SlotId == 0) { - goto ON_EXIT; - } - - // - // Create a new URB, insert it into the asynchronous - // schedule list, then poll the execution status. - // - Urb = XhcCreateUrb ( - Xhc, - DeviceAddress, - EndPointAddress, - DeviceSpeed, - MaximumPacketLength, - XHC_BULK_TRANSFER, - NULL, - Data[0], - *DataLength, - NULL, - NULL - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: failed to create URB\n")); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout); - - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - - if (Status == EFI_TIMEOUT) { - // - // The transfer timed out. Abort the transfer by dequeueing of the TD. - // - RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb); - if (EFI_ERROR(RecoveryStatus)) { - DEBUG((EFI_D_ERROR, "XhcBulkTransfer: XhcDequeueTrbFromEndpoint failed\n")); - } - } else { - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } else if (*TransferResult == EFI_USB_ERR_STALL) { - RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb); - if (EFI_ERROR (RecoveryStatus)) { - DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: XhcRecoverHaltedEndpoint failed\n")); - } - Status = EFI_DEVICE_ERROR; - } - } - - Xhc->PciIo->Flush (Xhc->PciIo); - XhcFreeUrb (Xhc, Urb); - -ON_EXIT: - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); - } - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Submits an asynchronous interrupt transfer to an - interrupt endpoint of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction encoded in bit 7 - @param DeviceSpeed Indicates device speed. - @param MaximumPacketLength Maximum packet size the target endpoint is capable - @param IsNewTransfer If TRUE, to submit an new asynchronous interrupt - transfer If FALSE, to remove the specified - asynchronous interrupt. - @param DataToggle On input, the initial data toggle to use; on output, - it is updated to indicate the next data toggle. - @param PollingInterval The he interval, in milliseconds, that the transfer - is polled. - @param DataLength The length of data to receive at the rate specified - by PollingInterval. - @param Translator Transaction translator to use. - @param CallBackFunction Function to call at the rate specified by - PollingInterval. - @param Context Context to CallBackFunction. - - @retval EFI_SUCCESS The request has been successfully submitted or canceled. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The request failed due to a lack of resources. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -XhcAsyncInterruptTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN BOOLEAN IsNewTransfer, - IN OUT UINT8 *DataToggle, - IN UINTN PollingInterval, - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction, - IN VOID *Context OPTIONAL - ) -{ - USB_XHCI_INSTANCE *Xhc; - URB *Urb; - EFI_STATUS Status; - UINT8 SlotId; - UINT8 Index; - UINT8 *Data; - EFI_TPL OldTpl; - - // - // Validate parameters - // - if (!XHCI_IS_DATAIN (EndPointAddress)) { - return EFI_INVALID_PARAMETER; - } - - if (IsNewTransfer) { - if (DataLength == 0) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 1) && (*DataToggle != 0)) { - return EFI_INVALID_PARAMETER; - } - - if ((PollingInterval > 255) || (PollingInterval < 1)) { - return EFI_INVALID_PARAMETER; - } - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - - // - // Delete Async interrupt transfer request. - // - if (!IsNewTransfer) { - // - // The delete request may happen after device is detached. - // - for (Index = 0; Index < 255; Index++) { - if (Xhc->UsbDevContext[Index + 1].BusDevAddr == DeviceAddress) { - break; - } - } - - if (Index == 255) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Status = XhciDelAsyncIntTransfer (Xhc, DeviceAddress, EndPointAddress); - DEBUG ((EFI_D_INFO, "XhcAsyncInterruptTransfer: remove old transfer for addr %d, Status = %r\n", DeviceAddress, Status)); - goto ON_EXIT; - } - - Status = EFI_SUCCESS; - - if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) { - DEBUG ((EFI_D_ERROR, "XhcAsyncInterruptTransfer: HC is halt\n")); - Status = EFI_DEVICE_ERROR; - goto ON_EXIT; - } - - // - // Check if the device is still enabled before every transaction. - // - SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress); - if (SlotId == 0) { - goto ON_EXIT; - } - - Data = AllocateZeroPool (DataLength); - - if (Data == NULL) { - DEBUG ((EFI_D_ERROR, "XhcAsyncInterruptTransfer: failed to allocate buffer\n")); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Urb = XhcCreateUrb ( - Xhc, - DeviceAddress, - EndPointAddress, - DeviceSpeed, - MaximumPacketLength, - XHC_INT_TRANSFER_ASYNC, - NULL, - Data, - DataLength, - CallBackFunction, - Context - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "XhcAsyncInterruptTransfer: failed to create URB\n")); - FreePool (Data); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - InsertHeadList (&Xhc->AsyncIntTransfers, &Urb->UrbList); - // - // Ring the doorbell - // - Status = RingIntTransferDoorBell (Xhc, Urb); - -ON_EXIT: - Xhc->PciIo->Flush (Xhc->PciIo); - gBS->RestoreTPL (OldTpl); - - return Status; -} - - -/** - Submits synchronous interrupt transfer to an interrupt endpoint - of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction encoded in bit 7 - @param DeviceSpeed Indicates device speed. - @param MaximumPacketLength Maximum packet size the target endpoint is capable - of sending or receiving. - @param Data Buffer of data that will be transmitted to USB - device or received from USB device. - @param DataLength On input, the size, in bytes, of the data buffer; On - output, the number of bytes transferred. - @param DataToggle On input, the initial data toggle to use; on output, - it is updated to indicate the next data toggle. - @param Timeout Maximum time, in second, to complete. - @param Translator Transaction translator to use. - @param TransferResult Variable to receive the transfer result. - - @return EFI_SUCCESS The transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @return EFI_INVALID_PARAMETER Some parameters are invalid. - @return EFI_TIMEOUT The transfer failed due to timeout. - @return EFI_DEVICE_ERROR The failed due to host controller or device error - -**/ -EFI_STATUS -EFIAPI -XhcSyncInterruptTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN Timeout, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - USB_XHCI_INSTANCE *Xhc; - URB *Urb; - UINT8 SlotId; - EFI_STATUS Status; - EFI_STATUS RecoveryStatus; - EFI_TPL OldTpl; - - // - // Validates parameters - // - if ((DataLength == NULL) || (*DataLength == 0) || - (Data == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 1) && (*DataToggle != 0)) { - return EFI_INVALID_PARAMETER; - } - - if (((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) || - ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) || - ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072))) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = XHC_FROM_THIS (This); - - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_DEVICE_ERROR; - - if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) { - DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: HC is halt\n")); - goto ON_EXIT; - } - - // - // Check if the device is still enabled before every transaction. - // - SlotId = XhcBusDevAddrToSlotId (Xhc, DeviceAddress); - if (SlotId == 0) { - goto ON_EXIT; - } - - Urb = XhcCreateUrb ( - Xhc, - DeviceAddress, - EndPointAddress, - DeviceSpeed, - MaximumPacketLength, - XHC_INT_TRANSFER_SYNC, - NULL, - Data, - *DataLength, - NULL, - NULL - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "XhcSyncInterruptTransfer: failed to create URB\n")); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout); - - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - - if (Status == EFI_TIMEOUT) { - // - // The transfer timed out. Abort the transfer by dequeueing of the TD. - // - RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb); - if (EFI_ERROR(RecoveryStatus)) { - DEBUG((EFI_D_ERROR, "XhcSyncInterruptTransfer: XhcDequeueTrbFromEndpoint failed\n")); - } - } else { - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } else if (*TransferResult == EFI_USB_ERR_STALL) { - RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb); - if (EFI_ERROR (RecoveryStatus)) { - DEBUG ((EFI_D_ERROR, "XhcSyncInterruptTransfer: XhcRecoverHaltedEndpoint failed\n")); - } - Status = EFI_DEVICE_ERROR; - } - } - - Xhc->PciIo->Flush (Xhc->PciIo); - XhcFreeUrb (Xhc, Urb); - -ON_EXIT: - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); - } - gBS->RestoreTPL (OldTpl); - - return Status; -} - - -/** - Submits isochronous transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress End point address with its direction. - @param DeviceSpeed Device speed, Low speed device doesn't support this - type. - @param MaximumPacketLength Maximum packet size that the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data that will - be transmitted to USB device or received from USB - device. - @param DataLength The size, in bytes, of the data buffer. - @param Translator Transaction translator to use. - @param TransferResult Variable to receive the transfer result. - - @return EFI_UNSUPPORTED Isochronous transfer is unsupported. - -**/ -EFI_STATUS -EFIAPI -XhcIsochronousTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - return EFI_UNSUPPORTED; -} - - -/** - Submits Async isochronous transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress End point address with its direction. - @param DeviceSpeed Device speed, Low speed device doesn't support this - type. - @param MaximumPacketLength Maximum packet size that the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data that will - be transmitted to USB device or received from USB - device. - @param DataLength The size, in bytes, of the data buffer. - @param Translator Transaction translator to use. - @param IsochronousCallBack Function to be called when the transfer complete. - @param Context Context passed to the call back function as - parameter. - - @return EFI_UNSUPPORTED Isochronous transfer isn't supported. - -**/ -EFI_STATUS -EFIAPI -XhcAsyncIsochronousTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, - IN VOID *Context - ) -{ - return EFI_UNSUPPORTED; -} - -/** - Entry point for EFI drivers. - - @param ImageHandle EFI_HANDLE. - @param SystemTable EFI_SYSTEM_TABLE. - - @retval EFI_SUCCESS Success. - @retval Others Fail. - -**/ -EFI_STATUS -EFIAPI -XhcDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gXhciDriverBinding, - ImageHandle, - &gXhciComponentName, - &gXhciComponentName2 - ); -} - - -/** - Test to see if this driver supports ControllerHandle. Any - ControllerHandle that has Usb2HcProtocol installed will - be supported. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS This driver supports this device. - @return EFI_UNSUPPORTED This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -XhcDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - USB_CLASSC UsbClassCReg; - - // - // Test whether there is PCI IO Protocol attached on the controller handle. - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - PCI_CLASSCODE_OFFSET, - sizeof (USB_CLASSC) / sizeof (UINT8), - &UsbClassCReg - ); - - if (EFI_ERROR (Status)) { - Status = EFI_UNSUPPORTED; - goto ON_EXIT; - } - - // - // Test whether the controller belongs to Xhci type - // - if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || - (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) || - (UsbClassCReg.ProgInterface != PCI_IF_XHCI)) { - Status = EFI_UNSUPPORTED; - } - -ON_EXIT: - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; -} - -/** - Create and initialize a USB_XHCI_INSTANCE structure. - - @param PciIo The PciIo on this device. - @param DevicePath The device path of host controller. - @param OriginalPciAttributes Original PCI attributes. - - @return The allocated and initialized USB_XHCI_INSTANCE structure if created, - otherwise NULL. - -**/ -USB_XHCI_INSTANCE* -XhcCreateUsbHc ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN UINT64 OriginalPciAttributes - ) -{ - USB_XHCI_INSTANCE *Xhc; - EFI_STATUS Status; - UINT32 PageSize; - UINT16 ExtCapReg; - - Xhc = AllocateZeroPool (sizeof (USB_XHCI_INSTANCE)); - - if (Xhc == NULL) { - return NULL; - } - - // - // Initialize private data structure - // - Xhc->Signature = XHCI_INSTANCE_SIG; - Xhc->PciIo = PciIo; - Xhc->DevicePath = DevicePath; - Xhc->OriginalPciAttributes = OriginalPciAttributes; - CopyMem (&Xhc->Usb2Hc, &gXhciUsb2HcTemplate, sizeof (EFI_USB2_HC_PROTOCOL)); - - InitializeListHead (&Xhc->AsyncIntTransfers); - - // - // Be caution that the Offset passed to XhcReadCapReg() should be Dword align - // - Xhc->CapLength = XhcReadCapReg8 (Xhc, XHC_CAPLENGTH_OFFSET); - Xhc->HcSParams1.Dword = XhcReadCapReg (Xhc, XHC_HCSPARAMS1_OFFSET); - Xhc->HcSParams2.Dword = XhcReadCapReg (Xhc, XHC_HCSPARAMS2_OFFSET); - Xhc->HcCParams.Dword = XhcReadCapReg (Xhc, XHC_HCCPARAMS_OFFSET); - Xhc->DBOff = XhcReadCapReg (Xhc, XHC_DBOFF_OFFSET); - Xhc->RTSOff = XhcReadCapReg (Xhc, XHC_RTSOFF_OFFSET); - - // - // This PageSize field defines the page size supported by the xHC implementation. - // This xHC supports a page size of 2^(n+12) if bit n is Set. For example, - // if bit 0 is Set, the xHC supports 4k byte page sizes. - // - PageSize = XhcReadOpReg(Xhc, XHC_PAGESIZE_OFFSET) & XHC_PAGESIZE_MASK; - Xhc->PageSize = 1 << (HighBitSet32(PageSize) + 12); - - ExtCapReg = (UINT16) (Xhc->HcCParams.Data.ExtCapReg); - Xhc->ExtCapRegBase = ExtCapReg << 2; - Xhc->UsbLegSupOffset = XhcGetCapabilityAddr (Xhc, XHC_CAP_USB_LEGACY); - Xhc->DebugCapSupOffset = XhcGetCapabilityAddr (Xhc, XHC_CAP_USB_DEBUG); - - DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: Capability length 0x%x\n", Xhc->CapLength)); - DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: HcSParams1 0x%x\n", Xhc->HcSParams1)); - DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: HcSParams2 0x%x\n", Xhc->HcSParams2)); - DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: HcCParams 0x%x\n", Xhc->HcCParams)); - DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: DBOff 0x%x\n", Xhc->DBOff)); - DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: RTSOff 0x%x\n", Xhc->RTSOff)); - DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: UsbLegSupOffset 0x%x\n", Xhc->UsbLegSupOffset)); - DEBUG ((EFI_D_INFO, "XhcCreateUsb3Hc: DebugCapSupOffset 0x%x\n", Xhc->DebugCapSupOffset)); - - // - // Create AsyncRequest Polling Timer - // - Status = gBS->CreateEvent ( - EVT_TIMER | EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - XhcMonitorAsyncRequests, - Xhc, - &Xhc->PollTimer - ); - - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - return Xhc; - -ON_ERROR: - FreePool (Xhc); - return NULL; -} - -/** - One notified function to stop the Host Controller when gBS->ExitBootServices() called. - - @param Event Pointer to this event - @param Context Event handler private data - -**/ -VOID -EFIAPI -XhcExitBootService ( - EFI_EVENT Event, - VOID *Context - ) - -{ - USB_XHCI_INSTANCE *Xhc; - EFI_PCI_IO_PROTOCOL *PciIo; - - Xhc = (USB_XHCI_INSTANCE*) Context; - PciIo = Xhc->PciIo; - - // - // Stop AsyncRequest Polling timer then stop the XHCI driver - // and uninstall the XHCI protocl. - // - gBS->SetTimer (Xhc->PollTimer, TimerCancel, 0); - XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT); - - if (Xhc->PollTimer != NULL) { - gBS->CloseEvent (Xhc->PollTimer); - } - - XhcClearBiosOwnership (Xhc); - - // - // Restore original PCI attributes - // - PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSet, - Xhc->OriginalPciAttributes, - NULL - ); -} - -/** - Starting the Usb XHCI Driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS supports this device. - @return EFI_UNSUPPORTED do not support this device. - @return EFI_DEVICE_ERROR cannot be started due to device Error. - @return EFI_OUT_OF_RESOURCES cannot allocate resources. - -**/ -EFI_STATUS -EFIAPI -XhcDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 Supports; - UINT64 OriginalPciAttributes; - BOOLEAN PciAttributesSaved; - USB_XHCI_INSTANCE *Xhc; - EFI_DEVICE_PATH_PROTOCOL *HcDevicePath; - - // - // Open the PciIo Protocol, then enable the USB host controller - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Open Device Path Protocol for on USB host controller - // - HcDevicePath = NULL; - Status = gBS->OpenProtocol ( - Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &HcDevicePath, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - PciAttributesSaved = FALSE; - // - // Save original PCI attributes - // - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationGet, - 0, - &OriginalPciAttributes - ); - - if (EFI_ERROR (Status)) { - goto CLOSE_PCIIO; - } - PciAttributesSaved = TRUE; - - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSupported, - 0, - &Supports - ); - if (!EFI_ERROR (Status)) { - Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; - Status = PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationEnable, - Supports, - NULL - ); - } - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to enable controller\n")); - goto CLOSE_PCIIO; - } - - // - // Create then install USB2_HC_PROTOCOL - // - Xhc = XhcCreateUsbHc (PciIo, HcDevicePath, OriginalPciAttributes); - - if (Xhc == NULL) { - DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to create USB2_HC\n")); - return EFI_OUT_OF_RESOURCES; - } - - XhcSetBiosOwnership (Xhc); - - XhcResetHC (Xhc, XHC_RESET_TIMEOUT); - ASSERT (XhcIsHalt (Xhc)); - - // - // After Chip Hardware Reset wait until the Controller Not Ready (CNR) flag - // in the USBSTS is '0' before writing any xHC Operational or Runtime registers. - // - ASSERT (!(XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_CNR))); - - // - // Initialize the schedule - // - XhcInitSched (Xhc); - - // - // Start the Host Controller - // - XhcRunHC(Xhc, XHC_GENERIC_TIMEOUT); - - // - // Start the asynchronous interrupt monitor - // - Status = gBS->SetTimer (Xhc->PollTimer, TimerPeriodic, XHC_ASYNC_TIMER_INTERVAL); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to start async interrupt monitor\n")); - XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT); - goto FREE_POOL; - } - - // - // Create event to stop the HC when exit boot service. - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - XhcExitBootService, - Xhc, - &gEfiEventExitBootServicesGuid, - &Xhc->ExitBootServiceEvent - ); - if (EFI_ERROR (Status)) { - goto FREE_POOL; - } - - // - // Install the component name protocol, don't fail the start - // because of something for display. - // - AddUnicodeString2 ( - "eng", - gXhciComponentName.SupportedLanguages, - &Xhc->ControllerNameTable, - L"eXtensible Host Controller (USB 3.0)", - TRUE - ); - AddUnicodeString2 ( - "en", - gXhciComponentName2.SupportedLanguages, - &Xhc->ControllerNameTable, - L"eXtensible Host Controller (USB 3.0)", - FALSE - ); - - Status = gBS->InstallProtocolInterface ( - &Controller, - &gEfiUsb2HcProtocolGuid, - EFI_NATIVE_INTERFACE, - &Xhc->Usb2Hc - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcDriverBindingStart: failed to install USB2_HC Protocol\n")); - goto FREE_POOL; - } - - DEBUG ((EFI_D_INFO, "XhcDriverBindingStart: XHCI started for controller @ %x\n", Controller)); - return EFI_SUCCESS; - -FREE_POOL: - gBS->CloseEvent (Xhc->PollTimer); - XhcFreeSched (Xhc); - FreePool (Xhc); - -CLOSE_PCIIO: - if (PciAttributesSaved) { - // - // Restore original PCI attributes - // - PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSet, - OriginalPciAttributes, - NULL - ); - } - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - return Status; -} - - -/** - Stop this driver on ControllerHandle. Support stoping any child handles - created by this driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on. - @param NumberOfChildren Number of Children in the ChildHandleBuffer. - @param ChildHandleBuffer List of handles for the children we need to stop. - - @return EFI_SUCCESS Success. - @return EFI_DEVICE_ERROR Fail. - -**/ -EFI_STATUS -EFIAPI -XhcDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ) -{ - EFI_STATUS Status; - EFI_USB2_HC_PROTOCOL *Usb2Hc; - EFI_PCI_IO_PROTOCOL *PciIo; - USB_XHCI_INSTANCE *Xhc; - UINT8 Index; - - // - // Test whether the Controller handler passed in is a valid - // Usb controller handle that should be supported, if not, - // return the error status directly - // - Status = gBS->OpenProtocol ( - Controller, - &gEfiUsb2HcProtocolGuid, - (VOID **) &Usb2Hc, - This->DriverBindingHandle, - Controller, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Status = gBS->UninstallProtocolInterface ( - Controller, - &gEfiUsb2HcProtocolGuid, - Usb2Hc - ); - - if (EFI_ERROR (Status)) { - return Status; - } - - Xhc = XHC_FROM_THIS (Usb2Hc); - PciIo = Xhc->PciIo; - - // - // Stop AsyncRequest Polling timer then stop the XHCI driver - // and uninstall the XHCI protocl. - // - gBS->SetTimer (Xhc->PollTimer, TimerCancel, 0); - - // - // Disable the device slots occupied by these devices on its downstream ports. - // Entry 0 is reserved. - // - for (Index = 0; Index < 255; Index++) { - if (!Xhc->UsbDevContext[Index + 1].Enabled || - (Xhc->UsbDevContext[Index + 1].SlotId == 0)) { - continue; - } - if (Xhc->HcCParams.Data.Csz == 0) { - XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId); - } else { - XhcDisableSlotCmd64 (Xhc, Xhc->UsbDevContext[Index + 1].SlotId); - } - } - - if (Xhc->PollTimer != NULL) { - gBS->CloseEvent (Xhc->PollTimer); - } - - if (Xhc->ExitBootServiceEvent != NULL) { - gBS->CloseEvent (Xhc->ExitBootServiceEvent); - } - - XhcHaltHC (Xhc, XHC_GENERIC_TIMEOUT); - XhcClearBiosOwnership (Xhc); - XhciDelAllAsyncIntTransfers (Xhc); - XhcFreeSched (Xhc); - - if (Xhc->ControllerNameTable) { - FreeUnicodeStringTable (Xhc->ControllerNameTable); - } - - // - // Restore original PCI attributes - // - PciIo->Attributes ( - PciIo, - EfiPciIoAttributeOperationSet, - Xhc->OriginalPciAttributes, - NULL - ); - - gBS->CloseProtocol ( - Controller, - &gEfiPciIoProtocolGuid, - This->DriverBindingHandle, - Controller - ); - - FreePool (Xhc); - - return EFI_SUCCESS; -} - diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h deleted file mode 100644 index 7999151b3f..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h +++ /dev/null @@ -1,727 +0,0 @@ -/** @file - - Provides some data structure definitions used by the XHCI host controller driver. - -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_XHCI_H_ -#define _EFI_XHCI_H_ - -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef struct _USB_XHCI_INSTANCE USB_XHCI_INSTANCE; -typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT; - -#include "XhciReg.h" -#include "XhciSched.h" -#include "ComponentName.h" -#include "UsbHcMem.h" - -// -// The unit is microsecond, setting it as 1us. -// -#define XHC_1_MICROSECOND (1) -// -// The unit is microsecond, setting it as 1ms. -// -#define XHC_1_MILLISECOND (1000) -// -// XHC generic timeout experience values. -// The unit is millisecond, setting it as 10s. -// -#define XHC_GENERIC_TIMEOUT (10 * 1000) -// -// XHC reset timeout experience values. -// The unit is millisecond, setting it as 1s. -// -#define XHC_RESET_TIMEOUT (1000) -// -// XHC async transfer timer interval, set by experience. -// The unit is 100us, takes 1ms as interval. -// -#define XHC_ASYNC_TIMER_INTERVAL EFI_TIMER_PERIOD_MILLISECONDS(1) - -// -// XHC raises TPL to TPL_NOTIFY to serialize all its operations -// to protect shared data structures. -// -#define XHC_TPL TPL_NOTIFY - -#define CMD_RING_TRB_NUMBER 0x100 -#define TR_RING_TRB_NUMBER 0x100 -#define ERST_NUMBER 0x01 -#define EVENT_RING_TRB_NUMBER 0x200 - -#define CMD_INTER 0 -#define CTRL_INTER 1 -#define BULK_INTER 2 -#define INT_INTER 3 -#define INT_INTER_ASYNC 4 - -// -// Iterate through the doule linked list. This is delete-safe. -// Don't touch NextEntry -// -#define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \ - for (Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\ - Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLink) - -#define EFI_LIST_CONTAINER(Entry, Type, Field) BASE_CR(Entry, Type, Field) - -#define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0xFFFFFFFF)) -#define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINT64)(UINTN)(Addr64), 32) & 0xFFFFFFFF)) -#define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit))) - -#define XHC_REG_BIT_IS_SET(Xhc, Offset, Bit) \ - (XHC_BIT_IS_SET(XhcReadOpReg ((Xhc), (Offset)), (Bit))) - -#define XHCI_IS_DATAIN(EndpointAddr) XHC_BIT_IS_SET((EndpointAddr), 0x80) - -#define XHCI_INSTANCE_SIG SIGNATURE_32 ('x', 'h', 'c', 'i') -#define XHC_FROM_THIS(a) CR(a, USB_XHCI_INSTANCE, Usb2Hc, XHCI_INSTANCE_SIG) - -#define USB_DESC_TYPE_HUB 0x29 -#define USB_DESC_TYPE_HUB_SUPER_SPEED 0x2a - -// -// The RequestType in EFI_USB_DEVICE_REQUEST is composed of -// three fields: One bit direction, 2 bit type, and 5 bit -// target. -// -#define USB_REQUEST_TYPE(Dir, Type, Target) \ - ((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target))) - -// -// Xhci Data and Ctrl Structures -// -#pragma pack(1) -typedef struct { - UINT8 ProgInterface; - UINT8 SubClassCode; - UINT8 BaseCode; -} USB_CLASSC; - -typedef struct { - UINT8 Length; - UINT8 DescType; - UINT8 NumPorts; - UINT16 HubCharacter; - UINT8 PwrOn2PwrGood; - UINT8 HubContrCurrent; - UINT8 Filler[16]; -} EFI_USB_HUB_DESCRIPTOR; -#pragma pack() - -struct _USB_DEV_CONTEXT { - // - // Whether this entry in UsbDevContext array is used or not. - // - BOOLEAN Enabled; - // - // The slot id assigned to the new device through XHCI's Enable_Slot cmd. - // - UINT8 SlotId; - // - // The route string presented an attached usb device. - // - USB_DEV_ROUTE RouteString; - // - // The route string of parent device if it exists. Otherwise it's zero. - // - USB_DEV_ROUTE ParentRouteString; - // - // The actual device address assigned by XHCI through Address_Device command. - // - UINT8 XhciDevAddr; - // - // The requested device address from UsbBus driver through Set_Address standard usb request. - // As XHCI spec replaces this request with Address_Device command, we have to record the - // requested device address and establish a mapping relationship with the actual device address. - // Then UsbBus driver just need to be aware of the requested device address to access usb device - // through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual - // device address and access the actual device. - // - UINT8 BusDevAddr; - // - // The pointer to the input device context. - // - VOID *InputContext; - // - // The pointer to the output device context. - // - VOID *OutputContext; - // - // The transfer queue for every endpoint. - // - VOID *EndpointTransferRing[31]; - // - // The device descriptor which is stored to support XHCI's Evaluate_Context cmd. - // - EFI_USB_DEVICE_DESCRIPTOR DevDesc; - // - // As a usb device may include multiple configuration descriptors, we dynamically allocate an array - // to store them. - // Note that every configuration descriptor stored here includes those lower level descriptors, - // such as Interface descriptor, Endpoint descriptor, and so on. - // These information is used to support XHCI's Config_Endpoint cmd. - // - EFI_USB_CONFIG_DESCRIPTOR **ConfDesc; - // - // A device has an active Configuration. - // - UINT8 ActiveConfiguration; - // - // Every interface has an active AlternateSetting. - // - UINT8 *ActiveAlternateSetting; -}; - -struct _USB_XHCI_INSTANCE { - UINT32 Signature; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT64 OriginalPciAttributes; - USBHC_MEM_POOL *MemPool; - - EFI_USB2_HC_PROTOCOL Usb2Hc; - - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - // - // ExitBootServicesEvent is used to set OS semaphore and - // stop the XHC DMA operation after exit boot service. - // - EFI_EVENT ExitBootServiceEvent; - EFI_EVENT PollTimer; - LIST_ENTRY AsyncIntTransfers; - - UINT8 CapLength; ///< Capability Register Length - XHC_HCSPARAMS1 HcSParams1; ///< Structural Parameters 1 - XHC_HCSPARAMS2 HcSParams2; ///< Structural Parameters 2 - XHC_HCCPARAMS HcCParams; ///< Capability Parameters - UINT32 DBOff; ///< Doorbell Offset - UINT32 RTSOff; ///< Runtime Register Space Offset - UINT16 MaxInterrupt; - UINT32 PageSize; - UINT64 *ScratchBuf; - VOID *ScratchMap; - UINT32 MaxScratchpadBufs; - UINT64 *ScratchEntry; - UINTN *ScratchEntryMap; - UINT32 ExtCapRegBase; - UINT32 UsbLegSupOffset; - UINT32 DebugCapSupOffset; - UINT64 *DCBAA; - VOID *DCBAAMap; - UINT32 MaxSlotsEn; - // - // Cmd Transfer Ring - // - TRANSFER_RING CmdRing; - // - // EventRing - // - EVENT_RING EventRing; - // - // Misc - // - EFI_UNICODE_STRING_TABLE *ControllerNameTable; - - // - // Store device contexts managed by XHCI instance - // The array supports up to 255 devices, entry 0 is reserved and should not be used. - // - USB_DEV_CONTEXT UsbDevContext[256]; -}; - - -extern EFI_DRIVER_BINDING_PROTOCOL gXhciDriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gXhciComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gXhciComponentName2; - -/** - Test to see if this driver supports ControllerHandle. Any - ControllerHandle that has Usb2HcProtocol installed will - be supported. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS This driver supports this device. - @return EFI_UNSUPPORTED This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -XhcDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Starting the Usb XHCI Driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to test. - @param RemainingDevicePath Not used. - - @return EFI_SUCCESS supports this device. - @return EFI_UNSUPPORTED do not support this device. - @return EFI_DEVICE_ERROR cannot be started due to device Error. - @return EFI_OUT_OF_RESOURCES cannot allocate resources. - -**/ -EFI_STATUS -EFIAPI -XhcDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ); - -/** - Stop this driver on ControllerHandle. Support stoping any child handles - created by this driver. - - @param This Protocol instance pointer. - @param Controller Handle of device to stop driver on. - @param NumberOfChildren Number of Children in the ChildHandleBuffer. - @param ChildHandleBuffer List of handles for the children we need to stop. - - @return EFI_SUCCESS Success. - @return EFI_DEVICE_ERROR Fail. - -**/ -EFI_STATUS -EFIAPI -XhcDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE Controller, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer - ); - -/** - Retrieves the capability of root hub ports. - - @param This The EFI_USB2_HC_PROTOCOL instance. - @param MaxSpeed Max speed supported by the controller. - @param PortNumber Number of the root hub ports. - @param Is64BitCapable Whether the controller supports 64-bit memory - addressing. - - @retval EFI_SUCCESS Host controller capability were retrieved successfully. - @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL. - -**/ -EFI_STATUS -EFIAPI -XhcGetCapability ( - IN EFI_USB2_HC_PROTOCOL *This, - OUT UINT8 *MaxSpeed, - OUT UINT8 *PortNumber, - OUT UINT8 *Is64BitCapable - ); - -/** - Provides software reset for the USB host controller. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param Attributes A bit mask of the reset operation to perform. - - @retval EFI_SUCCESS The reset operation succeeded. - @retval EFI_INVALID_PARAMETER Attributes is not valid. - @retval EFI_UNSUPPOURTED The type of reset specified by Attributes is - not currently supported by the host controller. - @retval EFI_DEVICE_ERROR Host controller isn't halted to reset. - -**/ -EFI_STATUS -EFIAPI -XhcReset ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT16 Attributes - ); - -/** - Retrieve the current state of the USB host controller. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param State Variable to return the current host controller - state. - - @retval EFI_SUCCESS Host controller state was returned in State. - @retval EFI_INVALID_PARAMETER State is NULL. - @retval EFI_DEVICE_ERROR An error was encountered while attempting to - retrieve the host controller's current state. - -**/ -EFI_STATUS -EFIAPI -XhcGetState ( - IN EFI_USB2_HC_PROTOCOL *This, - OUT EFI_USB_HC_STATE *State - ); - -/** - Sets the USB host controller to a specific state. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param State The state of the host controller that will be set. - - @retval EFI_SUCCESS The USB host controller was successfully placed - in the state specified by State. - @retval EFI_INVALID_PARAMETER State is invalid. - @retval EFI_DEVICE_ERROR Failed to set the state due to device error. - -**/ -EFI_STATUS -EFIAPI -XhcSetState ( - IN EFI_USB2_HC_PROTOCOL *This, - IN EFI_USB_HC_STATE State - ); - -/** - Retrieves the current status of a USB root hub port. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param PortNumber The root hub port to retrieve the state from. - This value is zero-based. - @param PortStatus Variable to receive the port state. - - @retval EFI_SUCCESS The status of the USB root hub port specified. - by PortNumber was returned in PortStatus. - @retval EFI_INVALID_PARAMETER PortNumber is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -XhcGetRootHubPortStatus ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - OUT EFI_USB_PORT_STATUS *PortStatus - ); - -/** - Sets a feature for the specified root hub port. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param PortNumber Root hub port to set. - @param PortFeature Feature to set. - - @retval EFI_SUCCESS The feature specified by PortFeature was set. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -XhcSetRootHubPortFeature ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ); - -/** - Clears a feature for the specified root hub port. - - @param This A pointer to the EFI_USB2_HC_PROTOCOL instance. - @param PortNumber Specifies the root hub port whose feature is - requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. - - @retval EFI_SUCCESS The feature specified by PortFeature was cleared - for the USB root hub port specified by PortNumber. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_DEVICE_ERROR Can't read register. - -**/ -EFI_STATUS -EFIAPI -XhcClearRootHubPortFeature ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ); - -/** - Submits control transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress The target device address. - @param DeviceSpeed Target device speed. - @param MaximumPacketLength Maximum packet size the default control transfer - endpoint is capable of sending or receiving. - @param Request USB device request to send. - @param TransferDirection Specifies the data direction for the data stage - @param Data Data buffer to be transmitted or received from USB - device. - @param DataLength The size (in bytes) of the data buffer. - @param Timeout Indicates the maximum timeout, in millisecond. - @param Translator Transaction translator to be used by this device. - @param TransferResult Return the result of this control transfer. - - @retval EFI_SUCCESS Transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT Transfer failed due to timeout. - @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -XhcControlTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN EFI_USB_DEVICE_REQUEST *Request, - IN EFI_USB_DATA_DIRECTION TransferDirection, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN UINTN Timeout, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ); - -/** - Submits bulk transfer to a bulk endpoint of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction in bit 7. - @param DeviceSpeed Device speed, Low speed device doesn't support bulk - transfer. - @param MaximumPacketLength Maximum packet size the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data to transmit - from or receive into. - @param DataLength The lenght of the data buffer. - @param DataToggle On input, the initial data toggle for the transfer; - On output, it is updated to to next data toggle to - use of the subsequent bulk transfer. - @param Timeout Indicates the maximum time, in millisecond, which - the transfer is allowed to complete. - @param Translator A pointr to the transaction translator data. - @param TransferResult A pointer to the detailed result information of the - bulk transfer. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -XhcBulkTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN Timeout, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ); - -/** - Submits an asynchronous interrupt transfer to an - interrupt endpoint of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction encoded in bit 7 - @param DeviceSpeed Indicates device speed. - @param MaximumPacketLength Maximum packet size the target endpoint is capable - @param IsNewTransfer If TRUE, to submit an new asynchronous interrupt - transfer If FALSE, to remove the specified - asynchronous interrupt. - @param DataToggle On input, the initial data toggle to use; on output, - it is updated to indicate the next data toggle. - @param PollingInterval The he interval, in milliseconds, that the transfer - is polled. - @param DataLength The length of data to receive at the rate specified - by PollingInterval. - @param Translator Transaction translator to use. - @param CallBackFunction Function to call at the rate specified by - PollingInterval. - @param Context Context to CallBackFunction. - - @retval EFI_SUCCESS The request has been successfully submitted or canceled. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The request failed due to a lack of resources. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -XhcAsyncInterruptTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN BOOLEAN IsNewTransfer, - IN OUT UINT8 *DataToggle, - IN UINTN PollingInterval, - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction, - IN VOID *Context OPTIONAL - ); - -/** - Submits synchronous interrupt transfer to an interrupt endpoint - of a USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction encoded in bit 7 - @param DeviceSpeed Indicates device speed. - @param MaximumPacketLength Maximum packet size the target endpoint is capable - of sending or receiving. - @param Data Buffer of data that will be transmitted to USB - device or received from USB device. - @param DataLength On input, the size, in bytes, of the data buffer; On - output, the number of bytes transferred. - @param DataToggle On input, the initial data toggle to use; on output, - it is updated to indicate the next data toggle. - @param Timeout Maximum time, in second, to complete. - @param Translator Transaction translator to use. - @param TransferResult Variable to receive the transfer result. - - @return EFI_SUCCESS The transfer was completed successfully. - @return EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @return EFI_INVALID_PARAMETER Some parameters are invalid. - @return EFI_TIMEOUT The transfer failed due to timeout. - @return EFI_DEVICE_ERROR The failed due to host controller or device error - -**/ -EFI_STATUS -EFIAPI -XhcSyncInterruptTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN Timeout, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ); - -/** - Submits isochronous transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress End point address with its direction. - @param DeviceSpeed Device speed, Low speed device doesn't support this - type. - @param MaximumPacketLength Maximum packet size that the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data that will - be transmitted to USB device or received from USB - device. - @param DataLength The size, in bytes, of the data buffer. - @param Translator Transaction translator to use. - @param TransferResult Variable to receive the transfer result. - - @return EFI_UNSUPPORTED Isochronous transfer is unsupported. - -**/ -EFI_STATUS -EFIAPI -XhcIsochronousTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ); - -/** - Submits Async isochronous transfer to a target USB device. - - @param This This EFI_USB2_HC_PROTOCOL instance. - @param DeviceAddress Target device address. - @param EndPointAddress End point address with its direction. - @param DeviceSpeed Device speed, Low speed device doesn't support this - type. - @param MaximumPacketLength Maximum packet size that the endpoint is capable of - sending or receiving. - @param DataBuffersNumber Number of data buffers prepared for the transfer. - @param Data Array of pointers to the buffers of data that will - be transmitted to USB device or received from USB - device. - @param DataLength The size, in bytes, of the data buffer. - @param Translator Transaction translator to use. - @param IsochronousCallBack Function to be called when the transfer complete. - @param Context Context passed to the call back function as - parameter. - - @return EFI_UNSUPPORTED Isochronous transfer isn't supported. - -**/ -EFI_STATUS -EFIAPI -XhcAsyncIsochronousTransfer ( - IN EFI_USB2_HC_PROTOCOL *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN UINT8 DataBuffersNumber, - IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], - IN UINTN DataLength, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack, - IN VOID *Context - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf b/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf deleted file mode 100644 index 614938ac89..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf +++ /dev/null @@ -1,76 +0,0 @@ -## @file -# The XhciDxe driver is responsible for managing the behavior of XHCI controller. -# It implements the interfaces of monitoring the status of all ports and transferring -# Control, Bulk, Interrupt and Isochronous requests to those attached usb LS/FS/HS/SS devices. -# -# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = XhciDxe - MODULE_UNI_FILE = XhciDxe.uni - FILE_GUID = B7F50E91-A759-412c-ADE4-DCD03E7F7C28 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = XhcDriverEntryPoint - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64 -# -# DRIVER_BINDING = gXhciDriverBinding -# COMPONENT_NAME = gXhciComponentName -# COMPONENT_NAME2 = gXhciComponentName2 -# - -[Sources] - Xhci.c - XhciReg.c - XhciSched.c - UsbHcMem.c - UsbHcMem.h - ComponentName.c - ComponentName.h - Xhci.h - XhciReg.h - XhciSched.h - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - MemoryAllocationLib - BaseLib - UefiLib - UefiBootServicesTableLib - UefiDriverEntryPoint - BaseMemoryLib - DebugLib - ReportStatusCodeLib - -[Guids] - gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event - -[Protocols] - gEfiPciIoProtocolGuid ## TO_START - gEfiUsb2HcProtocolGuid ## BY_START - -# [Event] -# EVENT_TYPE_PERIODIC_TIMER ## CONSUMES -# - -[UserExtensions.TianoCore."ExtraFiles"] - XhciDxeExtra.uni diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.uni b/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.uni deleted file mode 100644 index eea95dfa2b..0000000000 Binary files a/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxeExtra.uni b/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxeExtra.uni deleted file mode 100644 index 9c598b1868..0000000000 Binary files a/MdeModulePkg/Bus/Pci/XhciDxe/XhciDxeExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c deleted file mode 100644 index d0f22050ad..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c +++ /dev/null @@ -1,743 +0,0 @@ -/** @file - - The XHCI register operation routines. - -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Xhci.h" - -/** - Read 1-byte width XHCI capability register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 1-byte width capability register. - - @return The register content read. - @retval If err, return 0xFF. - -**/ -UINT8 -XhcReadCapReg8 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ) -{ - UINT8 Data; - EFI_STATUS Status; - - Status = Xhc->PciIo->Mem.Read ( - Xhc->PciIo, - EfiPciIoWidthUint8, - XHC_BAR_INDEX, - (UINT64) Offset, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset)); - Data = 0xFF; - } - - return Data; -} - -/** - Read 4-bytes width XHCI capability register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 4-bytes width capability register. - - @return The register content read. - @retval If err, return 0xFFFFFFFF. - -**/ -UINT32 -XhcReadCapReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - EFI_STATUS Status; - - Status = Xhc->PciIo->Mem.Read ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) Offset, - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset)); - Data = 0xFFFFFFFF; - } - - return Data; -} - -/** - Read 4-bytes width XHCI Operational register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 4-bytes width operational register. - - @return The register content read. - @retval If err, return 0xFFFFFFFF. - -**/ -UINT32 -XhcReadOpReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - EFI_STATUS Status; - - ASSERT (Xhc->CapLength != 0); - - Status = Xhc->PciIo->Mem.Read ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) (Xhc->CapLength + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset)); - Data = 0xFFFFFFFF; - } - - return Data; -} - -/** - Write the data to the 4-bytes width XHCI operational register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 4-bytes width operational register. - @param Data The data to write. - -**/ -VOID -XhcWriteOpReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - EFI_STATUS Status; - - ASSERT (Xhc->CapLength != 0); - - Status = Xhc->PciIo->Mem.Write ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) (Xhc->CapLength + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset)); - } -} - -/** - Write the data to the 2-bytes width XHCI operational register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 2-bytes width operational register. - @param Data The data to write. - -**/ -VOID -XhcWriteOpReg16 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT16 Data - ) -{ - EFI_STATUS Status; - - ASSERT (Xhc->CapLength != 0); - - Status = Xhc->PciIo->Mem.Write ( - Xhc->PciIo, - EfiPciIoWidthUint16, - XHC_BAR_INDEX, - (UINT64) (Xhc->CapLength + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcWriteOpReg16: Pci Io Write error: %r at %d\n", Status, Offset)); - } -} - -/** - Read XHCI door bell register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the door bell register. - - @return The register content read - -**/ -UINT32 -XhcReadDoorBellReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - EFI_STATUS Status; - - ASSERT (Xhc->DBOff != 0); - - Status = Xhc->PciIo->Mem.Read ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) (Xhc->DBOff + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcReadDoorBellReg: Pci Io Read error - %r at %d\n", Status, Offset)); - Data = 0xFFFFFFFF; - } - - return Data; -} - -/** - Write the data to the XHCI door bell register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the door bell register. - @param Data The data to write. - -**/ -VOID -XhcWriteDoorBellReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - EFI_STATUS Status; - - ASSERT (Xhc->DBOff != 0); - - Status = Xhc->PciIo->Mem.Write ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) (Xhc->DBOff + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset)); - } -} - -/** - Read XHCI runtime register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - - @return The register content read - -**/ -UINT32 -XhcReadRuntimeReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - EFI_STATUS Status; - - ASSERT (Xhc->RTSOff != 0); - - Status = Xhc->PciIo->Mem.Read ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) (Xhc->RTSOff + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset)); - Data = 0xFFFFFFFF; - } - - return Data; -} - -/** - Write the data to the XHCI runtime register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - @param Data The data to write. - -**/ -VOID -XhcWriteRuntimeReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - EFI_STATUS Status; - - ASSERT (Xhc->RTSOff != 0); - - Status = Xhc->PciIo->Mem.Write ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) (Xhc->RTSOff + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset)); - } -} - -/** - Read XHCI extended capability register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the extended capability register. - - @return The register content read - -**/ -UINT32 -XhcReadExtCapReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - EFI_STATUS Status; - - ASSERT (Xhc->ExtCapRegBase != 0); - - Status = Xhc->PciIo->Mem.Read ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) (Xhc->ExtCapRegBase + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset)); - Data = 0xFFFFFFFF; - } - - return Data; -} - -/** - Write the data to the XHCI extended capability register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the extended capability register. - @param Data The data to write. - -**/ -VOID -XhcWriteExtCapReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - EFI_STATUS Status; - - ASSERT (Xhc->ExtCapRegBase != 0); - - Status = Xhc->PciIo->Mem.Write ( - Xhc->PciIo, - EfiPciIoWidthUint32, - XHC_BAR_INDEX, - (UINT64) (Xhc->ExtCapRegBase + Offset), - 1, - &Data - ); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset)); - } -} - - -/** - Set one bit of the runtime register while keeping other bits. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcSetRuntimeRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = XhcReadRuntimeReg (Xhc, Offset); - Data |= Bit; - XhcWriteRuntimeReg (Xhc, Offset, Data); -} - -/** - Clear one bit of the runtime register while keeping other bits. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcClearRuntimeRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = XhcReadRuntimeReg (Xhc, Offset); - Data &= ~Bit; - XhcWriteRuntimeReg (Xhc, Offset, Data); -} - -/** - Set one bit of the operational register while keeping other bits. - - @param Xhc The XHCI Instance. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcSetOpRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = XhcReadOpReg (Xhc, Offset); - Data |= Bit; - XhcWriteOpReg (Xhc, Offset, Data); -} - - -/** - Clear one bit of the operational register while keeping other bits. - - @param Xhc The XHCI Instance. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to clear. - -**/ -VOID -XhcClearOpRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = XhcReadOpReg (Xhc, Offset); - Data &= ~Bit; - XhcWriteOpReg (Xhc, Offset, Data); -} - -/** - Wait the operation register's bit as specified by Bit - to become set (or clear). - - @param Xhc The XHCI Instance. - @param Offset The offset of the operation register. - @param Bit The bit of the register to wait for. - @param WaitToSet Wait the bit to set or clear. - @param Timeout The time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS The bit successfully changed by host controller. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -XhcWaitOpRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit, - IN BOOLEAN WaitToSet, - IN UINT32 Timeout - ) -{ - UINT32 Index; - UINT64 Loop; - - Loop = Timeout * XHC_1_MILLISECOND; - - for (Index = 0; Index < Loop; Index++) { - if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) { - return EFI_SUCCESS; - } - - gBS->Stall (XHC_1_MICROSECOND); - } - - return EFI_TIMEOUT; -} - -/** - Set Bios Ownership - - @param Xhc The XHCI Instance. - -**/ -VOID -XhcSetBiosOwnership ( - IN USB_XHCI_INSTANCE *Xhc - ) -{ - UINT32 Buffer; - - if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) { - return; - } - - DEBUG ((EFI_D_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n")); - - Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset); - Buffer = ((Buffer & (~USBLEGSP_OS_SEMAPHORE)) | USBLEGSP_BIOS_SEMAPHORE); - XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer); -} - -/** - Clear Bios Ownership - - @param Xhc The XHCI Instance. - -**/ -VOID -XhcClearBiosOwnership ( - IN USB_XHCI_INSTANCE *Xhc - ) -{ - UINT32 Buffer; - - if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) { - return; - } - - DEBUG ((EFI_D_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n")); - - Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset); - Buffer = ((Buffer & (~USBLEGSP_BIOS_SEMAPHORE)) | USBLEGSP_OS_SEMAPHORE); - XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer); -} - -/** - Calculate the offset of the XHCI capability. - - @param Xhc The XHCI Instance. - @param CapId The XHCI Capability ID. - - @return The offset of XHCI legacy support capability register. - -**/ -UINT32 -XhcGetCapabilityAddr ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 CapId - ) -{ - UINT32 ExtCapOffset; - UINT8 NextExtCapReg; - UINT32 Data; - - ExtCapOffset = 0; - - do { - // - // Check if the extended capability register's capability id is USB Legacy Support. - // - Data = XhcReadExtCapReg (Xhc, ExtCapOffset); - if ((Data & 0xFF) == CapId) { - return ExtCapOffset; - } - // - // If not, then traverse all of the ext capability registers till finding out it. - // - NextExtCapReg = (UINT8)((Data >> 8) & 0xFF); - ExtCapOffset += (NextExtCapReg << 2); - } while (NextExtCapReg != 0); - - return 0xFFFFFFFF; -} - -/** - Whether the XHCI host controller is halted. - - @param Xhc The XHCI Instance. - - @retval TRUE The controller is halted. - @retval FALSE It isn't halted. - -**/ -BOOLEAN -XhcIsHalt ( - IN USB_XHCI_INSTANCE *Xhc - ) -{ - return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT); -} - - -/** - Whether system error occurred. - - @param Xhc The XHCI Instance. - - @retval TRUE System error happened. - @retval FALSE No system error. - -**/ -BOOLEAN -XhcIsSysError ( - IN USB_XHCI_INSTANCE *Xhc - ) -{ - return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE); -} - -/** - Reset the XHCI host controller. - - @param Xhc The XHCI Instance. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS The XHCI host controller is reset. - @return Others Failed to reset the XHCI before Timeout. - -**/ -EFI_STATUS -XhcResetHC ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - Status = EFI_SUCCESS; - - DEBUG ((EFI_D_INFO, "XhcResetHC!\n")); - // - // Host can only be reset when it is halt. If not so, halt it - // - if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) { - Status = XhcHaltHC (Xhc, Timeout); - - if (EFI_ERROR (Status)) { - return Status; - } - } - - if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) || - ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0)) { - XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET); - Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout); - } - - return Status; -} - - -/** - Halt the XHCI host controller. - - @param Xhc The XHCI Instance. - @param Timeout Time to wait before abort (in millisecond, ms). - - @return EFI_SUCCESS The XHCI host controller is halt. - @return EFI_TIMEOUT Failed to halt the XHCI before Timeout. - -**/ -EFI_STATUS -XhcHaltHC ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - XhcClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN); - Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, TRUE, Timeout); - return Status; -} - - -/** - Set the XHCI host controller to run. - - @param Xhc The XHCI Instance. - @param Timeout Time to wait before abort (in millisecond, ms). - - @return EFI_SUCCESS The XHCI host controller is running. - @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout. - -**/ -EFI_STATUS -XhcRunHC ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN); - Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout); - return Status; -} - diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h deleted file mode 100644 index b748c8d397..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h +++ /dev/null @@ -1,583 +0,0 @@ -/** @file - - This file contains the register definition of XHCI host controller. - -Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_XHCI_REG_H_ -#define _EFI_XHCI_REG_H_ - -#define PCI_IF_XHCI 0x30 - -// -// PCI Configuration Registers -// -#define XHC_BAR_INDEX 0x00 - -#define XHC_PCI_BAR_OFFSET 0x10 // Memory Bar Register Offset -#define XHC_PCI_BAR_MASK 0xFFFF // Memory Base Address Mask - -#define USB_HUB_CLASS_CODE 0x09 -#define USB_HUB_SUBCLASS_CODE 0x00 - -#define XHC_CAP_USB_LEGACY 0x01 -#define XHC_CAP_USB_DEBUG 0x0A - -//============================================// -// XHCI register offset // -//============================================// - -// -// Capability registers offset -// -#define XHC_CAPLENGTH_OFFSET 0x00 // Capability register length offset -#define XHC_HCIVERSION_OFFSET 0x02 // Interface Version Number 02-03h -#define XHC_HCSPARAMS1_OFFSET 0x04 // Structural Parameters 1 -#define XHC_HCSPARAMS2_OFFSET 0x08 // Structural Parameters 2 -#define XHC_HCSPARAMS3_OFFSET 0x0c // Structural Parameters 3 -#define XHC_HCCPARAMS_OFFSET 0x10 // Capability Parameters -#define XHC_DBOFF_OFFSET 0x14 // Doorbell Offset -#define XHC_RTSOFF_OFFSET 0x18 // Runtime Register Space Offset - -// -// Operational registers offset -// -#define XHC_USBCMD_OFFSET 0x0000 // USB Command Register Offset -#define XHC_USBSTS_OFFSET 0x0004 // USB Status Register Offset -#define XHC_PAGESIZE_OFFSET 0x0008 // USB Page Size Register Offset -#define XHC_DNCTRL_OFFSET 0x0014 // Device Notification Control Register Offset -#define XHC_CRCR_OFFSET 0x0018 // Command Ring Control Register Offset -#define XHC_DCBAAP_OFFSET 0x0030 // Device Context Base Address Array Pointer Register Offset -#define XHC_CONFIG_OFFSET 0x0038 // Configure Register Offset -#define XHC_PORTSC_OFFSET 0x0400 // Port Status and Control Register Offset - -// -// Runtime registers offset -// -#define XHC_MFINDEX_OFFSET 0x00 // Microframe Index Register Offset -#define XHC_IMAN_OFFSET 0x20 // Interrupter X Management Register Offset -#define XHC_IMOD_OFFSET 0x24 // Interrupter X Moderation Register Offset -#define XHC_ERSTSZ_OFFSET 0x28 // Event Ring Segment Table Size Register Offset -#define XHC_ERSTBA_OFFSET 0x30 // Event Ring Segment Table Base Address Register Offset -#define XHC_ERDP_OFFSET 0x38 // Event Ring Dequeue Pointer Register Offset - -// -// Debug registers offset -// -#define XHC_DC_DCCTRL 0x20 - -#define USBLEGSP_BIOS_SEMAPHORE BIT16 // HC BIOS Owned Semaphore -#define USBLEGSP_OS_SEMAPHORE BIT24 // HC OS Owned Semaphore - -#pragma pack (1) -typedef struct { - UINT8 MaxSlots; // Number of Device Slots - UINT16 MaxIntrs:11; // Number of Interrupters - UINT16 Rsvd:5; - UINT8 MaxPorts; // Number of Ports -} HCSPARAMS1; - -// -// Structural Parameters 1 Register Bitmap Definition -// -typedef union { - UINT32 Dword; - HCSPARAMS1 Data; -} XHC_HCSPARAMS1; - -typedef struct { - UINT32 Ist:4; // Isochronous Scheduling Threshold - UINT32 Erst:4; // Event Ring Segment Table Max - UINT32 Rsvd:13; - UINT32 ScratchBufHi:5; // Max Scratchpad Buffers Hi - UINT32 Spr:1; // Scratchpad Restore - UINT32 ScratchBufLo:5; // Max Scratchpad Buffers Lo -} HCSPARAMS2; - -// -// Structural Parameters 2 Register Bitmap Definition -// -typedef union { - UINT32 Dword; - HCSPARAMS2 Data; -} XHC_HCSPARAMS2; - -typedef struct { - UINT16 Ac64:1; // 64-bit Addressing Capability - UINT16 Bnc:1; // BW Negotiation Capability - UINT16 Csz:1; // Context Size - UINT16 Ppc:1; // Port Power Control - UINT16 Pind:1; // Port Indicators - UINT16 Lhrc:1; // Light HC Reset Capability - UINT16 Ltc:1; // Latency Tolerance Messaging Capability - UINT16 Nss:1; // No Secondary SID Support - UINT16 Pae:1; // Parse All Event Data - UINT16 Rsvd:3; - UINT16 MaxPsaSize:4; // Maximum Primary Stream Array Size - UINT16 ExtCapReg; // xHCI Extended Capabilities Pointer -} HCCPARAMS; - -// -// Capability Parameters Register Bitmap Definition -// -typedef union { - UINT32 Dword; - HCCPARAMS Data; -} XHC_HCCPARAMS; - -#pragma pack () - -// -// Register Bit Definition -// -#define XHC_USBCMD_RUN BIT0 // Run/Stop -#define XHC_USBCMD_RESET BIT1 // Host Controller Reset -#define XHC_USBCMD_INTE BIT2 // Interrupter Enable -#define XHC_USBCMD_HSEE BIT3 // Host System Error Enable - -#define XHC_USBSTS_HALT BIT0 // Host Controller Halted -#define XHC_USBSTS_HSE BIT2 // Host System Error -#define XHC_USBSTS_EINT BIT3 // Event Interrupt -#define XHC_USBSTS_PCD BIT4 // Port Change Detect -#define XHC_USBSTS_SSS BIT8 // Save State Status -#define XHC_USBSTS_RSS BIT9 // Restore State Status -#define XHC_USBSTS_SRE BIT10 // Save/Restore Error -#define XHC_USBSTS_CNR BIT11 // Host Controller Not Ready -#define XHC_USBSTS_HCE BIT12 // Host Controller Error - -#define XHC_PAGESIZE_MASK 0xFFFF // Page Size - -#define XHC_CRCR_RCS BIT0 // Ring Cycle State -#define XHC_CRCR_CS BIT1 // Command Stop -#define XHC_CRCR_CA BIT2 // Command Abort -#define XHC_CRCR_CRR BIT3 // Command Ring Running - -#define XHC_CONFIG_MASK 0xFF // Command Ring Running - -#define XHC_PORTSC_CCS BIT0 // Current Connect Status -#define XHC_PORTSC_PED BIT1 // Port Enabled/Disabled -#define XHC_PORTSC_OCA BIT3 // Over-current Active -#define XHC_PORTSC_RESET BIT4 // Port Reset -#define XHC_PORTSC_PLS (BIT5|BIT6|BIT7|BIT8) // Port Link State -#define XHC_PORTSC_PP BIT9 // Port Power -#define XHC_PORTSC_PS (BIT10|BIT11|BIT12) // Port Speed -#define XHC_PORTSC_LWS BIT16 // Port Link State Write Strobe -#define XHC_PORTSC_CSC BIT17 // Connect Status Change -#define XHC_PORTSC_PEC BIT18 // Port Enabled/Disabled Change -#define XHC_PORTSC_WRC BIT19 // Warm Port Reset Change -#define XHC_PORTSC_OCC BIT20 // Over-Current Change -#define XHC_PORTSC_PRC BIT21 // Port Reset Change -#define XHC_PORTSC_PLC BIT22 // Port Link State Change -#define XHC_PORTSC_CEC BIT23 // Port Config Error Change -#define XHC_PORTSC_CAS BIT24 // Cold Attach Status - -#define XHC_HUB_PORTSC_CCS BIT0 // Hub's Current Connect Status -#define XHC_HUB_PORTSC_PED BIT1 // Hub's Port Enabled/Disabled -#define XHC_HUB_PORTSC_OCA BIT3 // Hub's Over-current Active -#define XHC_HUB_PORTSC_RESET BIT4 // Hub's Port Reset -#define XHC_HUB_PORTSC_PP BIT9 // Hub's Port Power -#define XHC_HUB_PORTSC_CSC BIT16 // Hub's Connect Status Change -#define XHC_HUB_PORTSC_PEC BIT17 // Hub's Port Enabled/Disabled Change -#define XHC_HUB_PORTSC_OCC BIT19 // Hub's Over-Current Change -#define XHC_HUB_PORTSC_PRC BIT20 // Hub's Port Reset Change -#define XHC_HUB_PORTSC_BHRC BIT21 // Hub's Port Warm Reset Change -#define XHC_IMAN_IP BIT0 // Interrupt Pending -#define XHC_IMAN_IE BIT1 // Interrupt Enable - -#define XHC_IMODI_MASK 0x0000FFFF // Interrupt Moderation Interval -#define XHC_IMODC_MASK 0xFFFF0000 // Interrupt Moderation Counter - -// -// Hub Class Feature Selector for Clear Port Feature Request -// It's the extension of hub class feature selector of USB 2.0 in USB 3.0 Spec. -// For more details, Please refer to USB 3.0 Spec Table 10-7. -// -typedef enum { - Usb3PortBHPortReset = 28, - Usb3PortBHPortResetChange = 29 -} XHC_PORT_FEATURE; - -// -// Structure to map the hardware port states to the -// UEFI's port states. -// -typedef struct { - UINT32 HwState; - UINT16 UefiState; -} USB_PORT_STATE_MAP; - -// -// Structure to map the hardware port states to feature selector for clear port feature request. -// -typedef struct { - UINT32 HwState; - UINT16 Selector; -} USB_CLEAR_PORT_MAP; - -/** - Read 1-byte width XHCI capability register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 1-byte width capability register. - - @return The register content read. - @retval If err, return 0xFFFF. - -**/ -UINT8 -XhcReadCapReg8 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ); - -/** - Read 4-bytes width XHCI capability register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 4-bytes width capability register. - - @return The register content read. - @retval If err, return 0xFFFFFFFF. - -**/ -UINT32 -XhcReadCapReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ); - -/** - Read 4-bytes width XHCI Operational register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 4-bytes width operational register. - - @return The register content read. - @retval If err, return 0xFFFFFFFF. - -**/ -UINT32 -XhcReadOpReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ); - -/** - Write the data to the 4-bytes width XHCI operational register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 4-bytes width operational register. - @param Data The data to write. - -**/ -VOID -XhcWriteOpReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ); - -/** - Write the data to the 2-bytes width XHCI operational register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the 2-bytes width operational register. - @param Data The data to write. - -**/ -VOID -XhcWriteOpReg16 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT16 Data - ); - -/** - Read XHCI runtime register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - - @return The register content read - -**/ -UINT32 -XhcReadRuntimeReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ); - -/** - Write the data to the XHCI runtime register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - @param Data The data to write. - -**/ -VOID -XhcWriteRuntimeReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ); - -/** - Read XHCI door bell register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the door bell register. - - @return The register content read - -**/ -UINT32 -XhcReadDoorBellReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ); - -/** - Write the data to the XHCI door bell register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the door bell register. - @param Data The data to write. - -**/ -VOID -XhcWriteDoorBellReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ); - -/** - Set one bit of the operational register while keeping other bits. - - @param Xhc The XHCI Instance. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcSetOpRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Clear one bit of the operational register while keeping other bits. - - @param Xhc The XHCI Instance. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to clear. - -**/ -VOID -XhcClearOpRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Wait the operation register's bit as specified by Bit - to be set (or clear). - - @param Xhc The XHCI Instance. - @param Offset The offset of the operational register. - @param Bit The bit of the register to wait for. - @param WaitToSet Wait the bit to set or clear. - @param Timeout The time to wait before abort (in microsecond, us). - - @retval EFI_SUCCESS The bit successfully changed by host controller. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -XhcWaitOpRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit, - IN BOOLEAN WaitToSet, - IN UINT32 Timeout - ); - -/** - Read XHCI runtime register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - - @return The register content read - -**/ -UINT32 -XhcReadRuntimeReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ); - -/** - Write the data to the XHCI runtime register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - @param Data The data to write. - -**/ -VOID -XhcWriteRuntimeReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ); - -/** - Set one bit of the runtime register while keeping other bits. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcSetRuntimeRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Clear one bit of the runtime register while keeping other bits. - - @param Xhc The XHCI Instance. - @param Offset The offset of the runtime register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcClearRuntimeRegBit ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Read XHCI extended capability register. - - @param Xhc The XHCI Instance. - @param Offset The offset of the extended capability register. - - @return The register content read - -**/ -UINT32 -XhcReadExtCapReg ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Offset - ); - -/** - Whether the XHCI host controller is halted. - - @param Xhc The XHCI Instance. - - @retval TRUE The controller is halted. - @retval FALSE It isn't halted. - -**/ -BOOLEAN -XhcIsHalt ( - IN USB_XHCI_INSTANCE *Xhc - ); - -/** - Whether system error occurred. - - @param Xhc The XHCI Instance. - - @retval TRUE System error happened. - @retval FALSE No system error. - -**/ -BOOLEAN -XhcIsSysError ( - IN USB_XHCI_INSTANCE *Xhc - ); - -/** - Reset the XHCI host controller. - - @param Xhc The XHCI Instance. - @param Timeout Time to wait before abort (in microsecond, us). - - @retval EFI_SUCCESS The XHCI host controller is reset. - @return Others Failed to reset the XHCI before Timeout. - -**/ -EFI_STATUS -XhcResetHC ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Timeout - ); - -/** - Halt the XHCI host controller. - - @param Xhc The XHCI Instance. - @param Timeout Time to wait before abort (in microsecond, us). - - @return EFI_SUCCESS The XHCI host controller is halt. - @return EFI_TIMEOUT Failed to halt the XHCI before Timeout. - -**/ -EFI_STATUS -XhcHaltHC ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Timeout - ); - -/** - Set the XHCI host controller to run. - - @param Xhc The XHCI Instance. - @param Timeout Time to wait before abort (in microsecond, us). - - @return EFI_SUCCESS The XHCI host controller is running. - @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout. - -**/ -EFI_STATUS -XhcRunHC ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT32 Timeout - ); - -/** - Calculate the offset of the XHCI capability. - - @param Xhc The XHCI Instance. - @param CapId The XHCI Capability ID. - - @return The offset of XHCI legacy support capability register. - -**/ -UINT32 -XhcGetCapabilityAddr ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 CapId - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c deleted file mode 100644 index c25342dc1f..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c +++ /dev/null @@ -1,3838 +0,0 @@ -/** @file - - XHCI transfer scheduling routines. - -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Xhci.h" - -/** - Create a command transfer TRB to support XHCI command interfaces. - - @param Xhc The XHCI Instance. - @param CmdTrb The cmd TRB to be executed. - - @return Created URB or NULL. - -**/ -URB* -XhcCreateCmdTrb ( - IN USB_XHCI_INSTANCE *Xhc, - IN TRB_TEMPLATE *CmdTrb - ) -{ - URB *Urb; - - Urb = AllocateZeroPool (sizeof (URB)); - if (Urb == NULL) { - return NULL; - } - - Urb->Signature = XHC_URB_SIG; - - Urb->Ring = &Xhc->CmdRing; - XhcSyncTrsRing (Xhc, Urb->Ring); - Urb->TrbNum = 1; - Urb->TrbStart = Urb->Ring->RingEnqueue; - CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB_TEMPLATE)); - Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0; - Urb->TrbEnd = Urb->TrbStart; - - return Urb; -} - -/** - Execute a XHCI cmd TRB pointed by CmdTrb. - - @param Xhc The XHCI Instance. - @param CmdTrb The cmd TRB to be executed. - @param Timeout Indicates the maximum time, in millisecond, which the - transfer is allowed to complete. - @param EvtTrb The event TRB corresponding to the cmd TRB. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -XhcCmdTransfer ( - IN USB_XHCI_INSTANCE *Xhc, - IN TRB_TEMPLATE *CmdTrb, - IN UINTN Timeout, - OUT TRB_TEMPLATE **EvtTrb - ) -{ - EFI_STATUS Status; - URB *Urb; - - // - // Validate the parameters - // - if ((Xhc == NULL) || (CmdTrb == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_DEVICE_ERROR; - - if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) { - DEBUG ((EFI_D_ERROR, "XhcCmdTransfer: HC is halted\n")); - goto ON_EXIT; - } - - // - // Create a new URB, then poll the execution status. - // - Urb = XhcCreateCmdTrb (Xhc, CmdTrb); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "XhcCmdTransfer: failed to create URB\n")); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = XhcExecTransfer (Xhc, TRUE, Urb, Timeout); - *EvtTrb = Urb->EvtTrb; - - if (Urb->Result == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } - - XhcFreeUrb (Xhc, Urb); - -ON_EXIT: - return Status; -} - -/** - Create a new URB for a new transaction. - - @param Xhc The XHCI Instance - @param BusAddr The logical device address assigned by UsbBus driver - @param EpAddr Endpoint addrress - @param DevSpeed The device speed - @param MaxPacket The max packet length of the endpoint - @param Type The transaction type - @param Request The standard USB request for control transfer - @param Data The user data to transfer - @param DataLen The length of data buffer - @param Callback The function to call when data is transferred - @param Context The context to the callback - - @return Created URB or NULL - -**/ -URB* -XhcCreateUrb ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 BusAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINTN MaxPacket, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context - ) -{ - USB_ENDPOINT *Ep; - EFI_STATUS Status; - URB *Urb; - - Urb = AllocateZeroPool (sizeof (URB)); - if (Urb == NULL) { - return NULL; - } - - Urb->Signature = XHC_URB_SIG; - InitializeListHead (&Urb->UrbList); - - Ep = &Urb->Ep; - Ep->BusAddr = BusAddr; - Ep->EpAddr = (UINT8)(EpAddr & 0x0F); - Ep->Direction = ((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut; - Ep->DevSpeed = DevSpeed; - Ep->MaxPacket = MaxPacket; - Ep->Type = Type; - - Urb->Request = Request; - Urb->Data = Data; - Urb->DataLen = DataLen; - Urb->Callback = Callback; - Urb->Context = Context; - - Status = XhcCreateTransferTrb (Xhc, Urb); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcCreateUrb: XhcCreateTransferTrb Failed, Status = %r\n", Status)); - FreePool (Urb); - Urb = NULL; - } - - return Urb; -} - -/** - Free an allocated URB. - - @param Xhc The XHCI device. - @param Urb The URB to free. - -**/ -VOID -XhcFreeUrb ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ) -{ - if ((Xhc == NULL) || (Urb == NULL)) { - return; - } - - if (Urb->DataMap != NULL) { - Xhc->PciIo->Unmap (Xhc->PciIo, Urb->DataMap); - } - - FreePool (Urb); -} - -/** - Create a transfer TRB. - - @param Xhc The XHCI Instance - @param Urb The urb used to construct the transfer TRB. - - @return Created TRB or NULL - -**/ -EFI_STATUS -XhcCreateTransferTrb ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ) -{ - VOID *OutputContext; - TRANSFER_RING *EPRing; - UINT8 EPType; - UINT8 SlotId; - UINT8 Dci; - TRB *TrbStart; - UINTN TotalLen; - UINTN Len; - UINTN TrbNum; - EFI_PCI_IO_PROTOCOL_OPERATION MapOp; - EFI_PHYSICAL_ADDRESS PhyAddr; - VOID *Map; - EFI_STATUS Status; - - SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - return EFI_DEVICE_ERROR; - } - - Urb->Finished = FALSE; - Urb->StartDone = FALSE; - Urb->EndDone = FALSE; - Urb->Completed = 0; - Urb->Result = EFI_USB_NOERROR; - - Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); - ASSERT (Dci < 32); - EPRing = (TRANSFER_RING *)(UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]; - Urb->Ring = EPRing; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - if (Xhc->HcCParams.Data.Csz == 0) { - EPType = (UINT8) ((DEVICE_CONTEXT *)OutputContext)->EP[Dci-1].EPType; - } else { - EPType = (UINT8) ((DEVICE_CONTEXT_64 *)OutputContext)->EP[Dci-1].EPType; - } - - if (Urb->Data != NULL) { - if (((UINT8) (Urb->Ep.Direction)) == EfiUsbDataIn) { - MapOp = EfiPciIoOperationBusMasterWrite; - } else { - MapOp = EfiPciIoOperationBusMasterRead; - } - - Len = Urb->DataLen; - Status = Xhc->PciIo->Map (Xhc->PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map); - - if (EFI_ERROR (Status) || (Len != Urb->DataLen)) { - DEBUG ((EFI_D_ERROR, "XhcCreateTransferTrb: Fail to map Urb->Data.\n")); - return EFI_OUT_OF_RESOURCES; - } - - Urb->DataPhy = (VOID *) ((UINTN) PhyAddr); - Urb->DataMap = Map; - } - - // - // Construct the TRB - // - XhcSyncTrsRing (Xhc, EPRing); - Urb->TrbStart = EPRing->RingEnqueue; - switch (EPType) { - case ED_CONTROL_BIDIR: - // - // For control transfer, create SETUP_STAGE_TRB first. - // - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - TrbStart->TrbCtrSetup.bmRequestType = Urb->Request->RequestType; - TrbStart->TrbCtrSetup.bRequest = Urb->Request->Request; - TrbStart->TrbCtrSetup.wValue = Urb->Request->Value; - TrbStart->TrbCtrSetup.wIndex = Urb->Request->Index; - TrbStart->TrbCtrSetup.wLength = Urb->Request->Length; - TrbStart->TrbCtrSetup.Length = 8; - TrbStart->TrbCtrSetup.IntTarget = 0; - TrbStart->TrbCtrSetup.IOC = 1; - TrbStart->TrbCtrSetup.IDT = 1; - TrbStart->TrbCtrSetup.Type = TRB_TYPE_SETUP_STAGE; - if (Urb->Ep.Direction == EfiUsbDataIn) { - TrbStart->TrbCtrSetup.TRT = 3; - } else if (Urb->Ep.Direction == EfiUsbDataOut) { - TrbStart->TrbCtrSetup.TRT = 2; - } else { - TrbStart->TrbCtrSetup.TRT = 0; - } - // - // Update the cycle bit - // - TrbStart->TrbCtrSetup.CycleBit = EPRing->RingPCS & BIT0; - Urb->TrbNum++; - - // - // For control transfer, create DATA_STAGE_TRB. - // - if (Urb->DataLen > 0) { - XhcSyncTrsRing (Xhc, EPRing); - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT(Urb->DataPhy); - TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT(Urb->DataPhy); - TrbStart->TrbCtrData.Length = (UINT32) Urb->DataLen; - TrbStart->TrbCtrData.TDSize = 0; - TrbStart->TrbCtrData.IntTarget = 0; - TrbStart->TrbCtrData.ISP = 1; - TrbStart->TrbCtrData.IOC = 1; - TrbStart->TrbCtrData.IDT = 0; - TrbStart->TrbCtrData.CH = 0; - TrbStart->TrbCtrData.Type = TRB_TYPE_DATA_STAGE; - if (Urb->Ep.Direction == EfiUsbDataIn) { - TrbStart->TrbCtrData.DIR = 1; - } else if (Urb->Ep.Direction == EfiUsbDataOut) { - TrbStart->TrbCtrData.DIR = 0; - } else { - TrbStart->TrbCtrData.DIR = 0; - } - // - // Update the cycle bit - // - TrbStart->TrbCtrData.CycleBit = EPRing->RingPCS & BIT0; - Urb->TrbNum++; - } - // - // For control transfer, create STATUS_STAGE_TRB. - // Get the pointer to next TRB for status stage use - // - XhcSyncTrsRing (Xhc, EPRing); - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - TrbStart->TrbCtrStatus.IntTarget = 0; - TrbStart->TrbCtrStatus.IOC = 1; - TrbStart->TrbCtrStatus.CH = 0; - TrbStart->TrbCtrStatus.Type = TRB_TYPE_STATUS_STAGE; - if (Urb->Ep.Direction == EfiUsbDataIn) { - TrbStart->TrbCtrStatus.DIR = 0; - } else if (Urb->Ep.Direction == EfiUsbDataOut) { - TrbStart->TrbCtrStatus.DIR = 1; - } else { - TrbStart->TrbCtrStatus.DIR = 0; - } - // - // Update the cycle bit - // - TrbStart->TrbCtrStatus.CycleBit = EPRing->RingPCS & BIT0; - // - // Update the enqueue pointer - // - XhcSyncTrsRing (Xhc, EPRing); - Urb->TrbNum++; - Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart; - - break; - - case ED_BULK_OUT: - case ED_BULK_IN: - TotalLen = 0; - Len = 0; - TrbNum = 0; - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - while (TotalLen < Urb->DataLen) { - if ((TotalLen + 0x10000) >= Urb->DataLen) { - Len = Urb->DataLen - TotalLen; - } else { - Len = 0x10000; - } - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->DataPhy + TotalLen); - TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->DataPhy + TotalLen); - TrbStart->TrbNormal.Length = (UINT32) Len; - TrbStart->TrbNormal.TDSize = 0; - TrbStart->TrbNormal.IntTarget = 0; - TrbStart->TrbNormal.ISP = 1; - TrbStart->TrbNormal.IOC = 1; - TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL; - // - // Update the cycle bit - // - TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0; - - XhcSyncTrsRing (Xhc, EPRing); - TrbNum++; - TotalLen += Len; - } - - Urb->TrbNum = TrbNum; - Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart; - break; - - case ED_INTERRUPT_OUT: - case ED_INTERRUPT_IN: - TotalLen = 0; - Len = 0; - TrbNum = 0; - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - while (TotalLen < Urb->DataLen) { - if ((TotalLen + 0x10000) >= Urb->DataLen) { - Len = Urb->DataLen - TotalLen; - } else { - Len = 0x10000; - } - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->DataPhy + TotalLen); - TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->DataPhy + TotalLen); - TrbStart->TrbNormal.Length = (UINT32) Len; - TrbStart->TrbNormal.TDSize = 0; - TrbStart->TrbNormal.IntTarget = 0; - TrbStart->TrbNormal.ISP = 1; - TrbStart->TrbNormal.IOC = 1; - TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL; - // - // Update the cycle bit - // - TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0; - - XhcSyncTrsRing (Xhc, EPRing); - TrbNum++; - TotalLen += Len; - } - - Urb->TrbNum = TrbNum; - Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart; - break; - - default: - DEBUG ((EFI_D_INFO, "Not supported EPType 0x%x!\n",EPType)); - ASSERT (FALSE); - break; - } - - return EFI_SUCCESS; -} - - -/** - Initialize the XHCI host controller for schedule. - - @param Xhc The XHCI Instance to be initialized. - -**/ -VOID -XhcInitSched ( - IN USB_XHCI_INSTANCE *Xhc - ) -{ - VOID *Dcbaa; - EFI_PHYSICAL_ADDRESS DcbaaPhy; - UINT64 CmdRing; - EFI_PHYSICAL_ADDRESS CmdRingPhy; - UINTN Entries; - UINT32 MaxScratchpadBufs; - UINT64 *ScratchBuf; - EFI_PHYSICAL_ADDRESS ScratchPhy; - UINT64 *ScratchEntry; - EFI_PHYSICAL_ADDRESS ScratchEntryPhy; - UINT32 Index; - UINTN *ScratchEntryMap; - EFI_STATUS Status; - - // - // Initialize memory management. - // - Xhc->MemPool = UsbHcInitMemPool (Xhc->PciIo); - ASSERT (Xhc->MemPool != NULL); - - // - // Program the Max Device Slots Enabled (MaxSlotsEn) field in the CONFIG register (5.4.7) - // to enable the device slots that system software is going to use. - // - Xhc->MaxSlotsEn = Xhc->HcSParams1.Data.MaxSlots; - ASSERT (Xhc->MaxSlotsEn >= 1 && Xhc->MaxSlotsEn <= 255); - XhcWriteOpReg (Xhc, XHC_CONFIG_OFFSET, Xhc->MaxSlotsEn); - - // - // The Device Context Base Address Array entry associated with each allocated Device Slot - // shall contain a 64-bit pointer to the base of the associated Device Context. - // The Device Context Base Address Array shall contain MaxSlotsEn + 1 entries. - // Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'. - // - Entries = (Xhc->MaxSlotsEn + 1) * sizeof(UINT64); - Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Entries); - ASSERT (Dcbaa != NULL); - ZeroMem (Dcbaa, Entries); - - // - // A Scratchpad Buffer is a PAGESIZE block of system memory located on a PAGESIZE boundary. - // System software shall allocate the Scratchpad Buffer(s) before placing the xHC in to Run - // mode (Run/Stop(R/S) ='1'). - // - MaxScratchpadBufs = ((Xhc->HcSParams2.Data.ScratchBufHi) << 5) | (Xhc->HcSParams2.Data.ScratchBufLo); - Xhc->MaxScratchpadBufs = MaxScratchpadBufs; - ASSERT (MaxScratchpadBufs <= 1023); - if (MaxScratchpadBufs != 0) { - // - // Allocate the buffer to record the Mapping for each scratch buffer in order to Unmap them - // - ScratchEntryMap = AllocateZeroPool (sizeof (UINTN) * MaxScratchpadBufs); - ASSERT (ScratchEntryMap != NULL); - Xhc->ScratchEntryMap = ScratchEntryMap; - - // - // Allocate the buffer to record the host address for each entry - // - ScratchEntry = AllocateZeroPool (sizeof (UINT64) * MaxScratchpadBufs); - ASSERT (ScratchEntry != NULL); - Xhc->ScratchEntry = ScratchEntry; - - ScratchPhy = 0; - Status = UsbHcAllocateAlignedPages ( - Xhc->PciIo, - EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)), - Xhc->PageSize, - (VOID **) &ScratchBuf, - &ScratchPhy, - &Xhc->ScratchMap - ); - ASSERT_EFI_ERROR (Status); - - ZeroMem (ScratchBuf, MaxScratchpadBufs * sizeof (UINT64)); - Xhc->ScratchBuf = ScratchBuf; - - // - // Allocate each scratch buffer - // - for (Index = 0; Index < MaxScratchpadBufs; Index++) { - ScratchEntryPhy = 0; - Status = UsbHcAllocateAlignedPages ( - Xhc->PciIo, - EFI_SIZE_TO_PAGES (Xhc->PageSize), - Xhc->PageSize, - (VOID **) &ScratchEntry[Index], - &ScratchEntryPhy, - (VOID **) &ScratchEntryMap[Index] - ); - ASSERT_EFI_ERROR (Status); - ZeroMem ((VOID *)(UINTN)ScratchEntry[Index], Xhc->PageSize); - // - // Fill with the PCI device address - // - *ScratchBuf++ = ScratchEntryPhy; - } - // - // The Scratchpad Buffer Array contains pointers to the Scratchpad Buffers. Entry 0 of the - // Device Context Base Address Array points to the Scratchpad Buffer Array. - // - *(UINT64 *)Dcbaa = (UINT64)(UINTN) ScratchPhy; - } - - // - // Program the Device Context Base Address Array Pointer (DCBAAP) register (5.4.6) with - // a 64-bit address pointing to where the Device Context Base Address Array is located. - // - Xhc->DCBAA = (UINT64 *)(UINTN)Dcbaa; - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - DcbaaPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Dcbaa, Entries); - XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET, XHC_LOW_32BIT(DcbaaPhy)); - XhcWriteOpReg (Xhc, XHC_DCBAAP_OFFSET + 4, XHC_HIGH_32BIT (DcbaaPhy)); - - DEBUG ((EFI_D_INFO, "XhcInitSched:DCBAA=0x%x\n", (UINT64)(UINTN)Xhc->DCBAA)); - - // - // Define the Command Ring Dequeue Pointer by programming the Command Ring Control Register - // (5.4.5) with a 64-bit address pointing to the starting address of the first TRB of the Command Ring. - // Note: The Command Ring is 64 byte aligned, so the low order 6 bits of the Command Ring Pointer shall - // always be '0'. - // - CreateTransferRing (Xhc, CMD_RING_TRB_NUMBER, &Xhc->CmdRing); - // - // The xHC uses the Enqueue Pointer to determine when a Transfer Ring is empty. As it fetches TRBs from a - // Transfer Ring it checks for a Cycle bit transition. If a transition detected, the ring is empty. - // So we set RCS as inverted PCS init value to let Command Ring empty - // - CmdRing = (UINT64)(UINTN)Xhc->CmdRing.RingSeg0; - CmdRingPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, (VOID *)(UINTN) CmdRing, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER); - ASSERT ((CmdRingPhy & 0x3F) == 0); - CmdRingPhy |= XHC_CRCR_RCS; - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT(CmdRingPhy)); - XhcWriteOpReg (Xhc, XHC_CRCR_OFFSET + 4, XHC_HIGH_32BIT (CmdRingPhy)); - - DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_CRCR=0x%x\n", Xhc->CmdRing.RingSeg0)); - - // - // Disable the 'interrupter enable' bit in USB_CMD - // and clear IE & IP bit in all Interrupter X Management Registers. - // - XhcClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_INTE); - for (Index = 0; Index < (UINT16)(Xhc->HcSParams1.Data.MaxIntrs); Index++) { - XhcClearRuntimeRegBit (Xhc, XHC_IMAN_OFFSET + (Index * 32), XHC_IMAN_IE); - XhcSetRuntimeRegBit (Xhc, XHC_IMAN_OFFSET + (Index * 32), XHC_IMAN_IP); - } - - // - // Allocate EventRing for Cmd, Ctrl, Bulk, Interrupt, AsynInterrupt transfer - // - CreateEventRing (Xhc, &Xhc->EventRing); - DEBUG ((EFI_D_INFO, "XhcInitSched:XHC_EVENTRING=0x%x\n", Xhc->EventRing.EventRingSeg0)); -} - -/** - System software shall use a Reset Endpoint Command (section 4.11.4.7) to remove the Halted - condition in the xHC. After the successful completion of the Reset Endpoint Command, the Endpoint - Context is transitioned from the Halted to the Stopped state and the Transfer Ring of the endpoint is - reenabled. The next write to the Doorbell of the Endpoint will transition the Endpoint Context from the - Stopped to the Running state. - - @param Xhc The XHCI Instance. - @param Urb The urb which makes the endpoint halted. - - @retval EFI_SUCCESS The recovery is successful. - @retval Others Failed to recovery halted endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcRecoverHaltedEndpoint ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ) -{ - EFI_STATUS Status; - UINT8 Dci; - UINT8 SlotId; - - Status = EFI_SUCCESS; - SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - return EFI_DEVICE_ERROR; - } - Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); - ASSERT (Dci < 32); - - DEBUG ((EFI_D_INFO, "Recovery Halted Slot = %x,Dci = %x\n", SlotId, Dci)); - - // - // 1) Send Reset endpoint command to transit from halt to stop state - // - Status = XhcResetEndpoint(Xhc, SlotId, Dci); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcRecoverHaltedEndpoint: Reset Endpoint Failed, Status = %r\n", Status)); - goto Done; - } - - // - // 2)Set dequeue pointer - // - Status = XhcSetTrDequeuePointer(Xhc, SlotId, Dci, Urb); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcRecoverHaltedEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status)); - goto Done; - } - - // - // 3)Ring the doorbell to transit from stop to active - // - XhcRingDoorBell (Xhc, SlotId, Dci); - -Done: - return Status; -} - -/** - System software shall use a Stop Endpoint Command (section 4.6.9) and the Set TR Dequeue Pointer - Command (section 4.6.10) to remove the timed-out TDs from the xHC transfer ring. The next write to - the Doorbell of the Endpoint will transition the Endpoint Context from the Stopped to the Running - state. - - @param Xhc The XHCI Instance. - @param Urb The urb which doesn't get completed in a specified timeout range. - - @retval EFI_SUCCESS The dequeuing of the TDs is successful. - @retval Others Failed to stop the endpoint and dequeue the TDs. - -**/ -EFI_STATUS -EFIAPI -XhcDequeueTrbFromEndpoint ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ) -{ - EFI_STATUS Status; - UINT8 Dci; - UINT8 SlotId; - - Status = EFI_SUCCESS; - SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - return EFI_DEVICE_ERROR; - } - Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); - ASSERT (Dci < 32); - - DEBUG ((EFI_D_INFO, "Stop Slot = %x,Dci = %x\n", SlotId, Dci)); - - // - // 1) Send Stop endpoint command to stop xHC from executing of the TDs on the endpoint - // - Status = XhcStopEndpoint(Xhc, SlotId, Dci); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcDequeueTrbFromEndpoint: Stop Endpoint Failed, Status = %r\n", Status)); - goto Done; - } - - // - // 2)Set dequeue pointer - // - Status = XhcSetTrDequeuePointer(Xhc, SlotId, Dci, Urb); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcDequeueTrbFromEndpoint: Set Transfer Ring Dequeue Pointer Failed, Status = %r\n", Status)); - goto Done; - } - - // - // 3)Ring the doorbell to transit from stop to active - // - XhcRingDoorBell (Xhc, SlotId, Dci); - -Done: - return Status; -} - -/** - Create XHCI event ring. - - @param Xhc The XHCI Instance. - @param EventRing The created event ring. - -**/ -VOID -CreateEventRing ( - IN USB_XHCI_INSTANCE *Xhc, - OUT EVENT_RING *EventRing - ) -{ - VOID *Buf; - EVENT_RING_SEG_TABLE_ENTRY *ERSTBase; - UINTN Size; - EFI_PHYSICAL_ADDRESS ERSTPhy; - EFI_PHYSICAL_ADDRESS DequeuePhy; - - ASSERT (EventRing != NULL); - - Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER; - Buf = UsbHcAllocateMem (Xhc->MemPool, Size); - ASSERT (Buf != NULL); - ASSERT (((UINTN) Buf & 0x3F) == 0); - ZeroMem (Buf, Size); - - EventRing->EventRingSeg0 = Buf; - EventRing->TrbNumber = EVENT_RING_TRB_NUMBER; - EventRing->EventRingDequeue = (TRB_TEMPLATE *) EventRing->EventRingSeg0; - EventRing->EventRingEnqueue = (TRB_TEMPLATE *) EventRing->EventRingSeg0; - - DequeuePhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, Size); - - // - // Software maintains an Event Ring Consumer Cycle State (CCS) bit, initializing it to '1' - // and toggling it every time the Event Ring Dequeue Pointer wraps back to the beginning of the Event Ring. - // - EventRing->EventRingCCS = 1; - - Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER; - Buf = UsbHcAllocateMem (Xhc->MemPool, Size); - ASSERT (Buf != NULL); - ASSERT (((UINTN) Buf & 0x3F) == 0); - ZeroMem (Buf, Size); - - ERSTBase = (EVENT_RING_SEG_TABLE_ENTRY *) Buf; - EventRing->ERSTBase = ERSTBase; - ERSTBase->PtrLo = XHC_LOW_32BIT (DequeuePhy); - ERSTBase->PtrHi = XHC_HIGH_32BIT (DequeuePhy); - ERSTBase->RingTrbSize = EVENT_RING_TRB_NUMBER; - - ERSTPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, ERSTBase, Size); - - // - // Program the Interrupter Event Ring Segment Table Size (ERSTSZ) register (5.5.2.3.1) - // - XhcWriteRuntimeReg ( - Xhc, - XHC_ERSTSZ_OFFSET, - ERST_NUMBER - ); - // - // Program the Interrupter Event Ring Dequeue Pointer (ERDP) register (5.5.2.3.3) - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - XhcWriteRuntimeReg ( - Xhc, - XHC_ERDP_OFFSET, - XHC_LOW_32BIT((UINT64)(UINTN)DequeuePhy) - ); - XhcWriteRuntimeReg ( - Xhc, - XHC_ERDP_OFFSET + 4, - XHC_HIGH_32BIT((UINT64)(UINTN)DequeuePhy) - ); - // - // Program the Interrupter Event Ring Segment Table Base Address (ERSTBA) register(5.5.2.3.2) - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - XhcWriteRuntimeReg ( - Xhc, - XHC_ERSTBA_OFFSET, - XHC_LOW_32BIT((UINT64)(UINTN)ERSTPhy) - ); - XhcWriteRuntimeReg ( - Xhc, - XHC_ERSTBA_OFFSET + 4, - XHC_HIGH_32BIT((UINT64)(UINTN)ERSTPhy) - ); - // - // Need set IMAN IE bit to enble the ring interrupt - // - XhcSetRuntimeRegBit (Xhc, XHC_IMAN_OFFSET, XHC_IMAN_IE); -} - -/** - Create XHCI transfer ring. - - @param Xhc The XHCI Instance. - @param TrbNum The number of TRB in the ring. - @param TransferRing The created transfer ring. - -**/ -VOID -CreateTransferRing ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINTN TrbNum, - OUT TRANSFER_RING *TransferRing - ) -{ - VOID *Buf; - LINK_TRB *EndTrb; - EFI_PHYSICAL_ADDRESS PhyAddr; - - Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum); - ASSERT (Buf != NULL); - ASSERT (((UINTN) Buf & 0x3F) == 0); - ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum); - - TransferRing->RingSeg0 = Buf; - TransferRing->TrbNumber = TrbNum; - TransferRing->RingEnqueue = (TRB_TEMPLATE *) TransferRing->RingSeg0; - TransferRing->RingDequeue = (TRB_TEMPLATE *) TransferRing->RingSeg0; - TransferRing->RingPCS = 1; - // - // 4.9.2 Transfer Ring Management - // To form a ring (or circular queue) a Link TRB may be inserted at the end of a ring to - // point to the first TRB in the ring. - // - EndTrb = (LINK_TRB *) ((UINTN)Buf + sizeof (TRB_TEMPLATE) * (TrbNum - 1)); - EndTrb->Type = TRB_TYPE_LINK; - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, sizeof (TRB_TEMPLATE) * TrbNum); - EndTrb->PtrLo = XHC_LOW_32BIT (PhyAddr); - EndTrb->PtrHi = XHC_HIGH_32BIT (PhyAddr); - // - // Toggle Cycle (TC). When set to '1', the xHC shall toggle its interpretation of the Cycle bit. - // - EndTrb->TC = 1; - // - // Set Cycle bit as other TRB PCS init value - // - EndTrb->CycleBit = 0; -} - -/** - Free XHCI event ring. - - @param Xhc The XHCI Instance. - @param EventRing The event ring to be freed. - -**/ -EFI_STATUS -EFIAPI -XhcFreeEventRing ( - IN USB_XHCI_INSTANCE *Xhc, - IN EVENT_RING *EventRing -) -{ - if(EventRing->EventRingSeg0 == NULL) { - return EFI_SUCCESS; - } - - // - // Free EventRing Segment 0 - // - UsbHcFreeMem (Xhc->MemPool, EventRing->EventRingSeg0, sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER); - - // - // Free ESRT table - // - UsbHcFreeMem (Xhc->MemPool, EventRing->ERSTBase, sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER); - return EFI_SUCCESS; -} - -/** - Free the resouce allocated at initializing schedule. - - @param Xhc The XHCI Instance. - -**/ -VOID -XhcFreeSched ( - IN USB_XHCI_INSTANCE *Xhc - ) -{ - UINT32 Index; - UINT64 *ScratchEntry; - - if (Xhc->ScratchBuf != NULL) { - ScratchEntry = Xhc->ScratchEntry; - for (Index = 0; Index < Xhc->MaxScratchpadBufs; Index++) { - // - // Free Scratchpad Buffers - // - UsbHcFreeAlignedPages (Xhc->PciIo, (VOID*)(UINTN)ScratchEntry[Index], EFI_SIZE_TO_PAGES (Xhc->PageSize), (VOID *) Xhc->ScratchEntryMap[Index]); - } - // - // Free Scratchpad Buffer Array - // - UsbHcFreeAlignedPages (Xhc->PciIo, Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64)), Xhc->ScratchMap); - FreePool (Xhc->ScratchEntryMap); - FreePool (Xhc->ScratchEntry); - } - - if (Xhc->CmdRing.RingSeg0 != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->CmdRing.RingSeg0, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER); - Xhc->CmdRing.RingSeg0 = NULL; - } - - XhcFreeEventRing (Xhc,&Xhc->EventRing); - - if (Xhc->DCBAA != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->DCBAA, (Xhc->MaxSlotsEn + 1) * sizeof(UINT64)); - Xhc->DCBAA = NULL; - } - - // - // Free memory pool at last - // - if (Xhc->MemPool != NULL) { - UsbHcFreeMemPool (Xhc->MemPool); - Xhc->MemPool = NULL; - } -} - -/** - Check if the Trb is a transaction of the URBs in XHCI's asynchronous transfer list. - - @param Xhc The XHCI Instance. - @param Trb The TRB to be checked. - @param Urb The pointer to the matched Urb. - - @retval TRUE The Trb is matched with a transaction of the URBs in the async list. - @retval FALSE The Trb is not matched with any URBs in the async list. - -**/ -BOOLEAN -IsAsyncIntTrb ( - IN USB_XHCI_INSTANCE *Xhc, - IN TRB_TEMPLATE *Trb, - OUT URB **Urb - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - TRB_TEMPLATE *CheckedTrb; - URB *CheckedUrb; - UINTN Index; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) { - CheckedUrb = EFI_LIST_CONTAINER (Entry, URB, UrbList); - CheckedTrb = CheckedUrb->TrbStart; - for (Index = 0; Index < CheckedUrb->TrbNum; Index++) { - if (Trb == CheckedTrb) { - *Urb = CheckedUrb; - return TRUE; - } - CheckedTrb++; - if ((UINTN)CheckedTrb >= ((UINTN) CheckedUrb->Ring->RingSeg0 + sizeof (TRB_TEMPLATE) * CheckedUrb->Ring->TrbNumber)) { - CheckedTrb = (TRB_TEMPLATE*) CheckedUrb->Ring->RingSeg0; - } - } - } - - return FALSE; -} - -/** - Check if the Trb is a transaction of the URB. - - @param Trb The TRB to be checked - @param Urb The transfer ring to be checked. - - @retval TRUE It is a transaction of the URB. - @retval FALSE It is not any transaction of the URB. - -**/ -BOOLEAN -IsTransferRingTrb ( - IN TRB_TEMPLATE *Trb, - IN URB *Urb - ) -{ - TRB_TEMPLATE *CheckedTrb; - UINTN Index; - - CheckedTrb = Urb->Ring->RingSeg0; - - ASSERT (Urb->Ring->TrbNumber == CMD_RING_TRB_NUMBER || Urb->Ring->TrbNumber == TR_RING_TRB_NUMBER); - - for (Index = 0; Index < Urb->Ring->TrbNumber; Index++) { - if (Trb == CheckedTrb) { - return TRUE; - } - CheckedTrb++; - } - - return FALSE; -} - -/** - Check the URB's execution result and update the URB's - result accordingly. - - @param Xhc The XHCI Instance. - @param Urb The URB to check result. - - @return Whether the result of URB transfer is finialized. - -**/ -BOOLEAN -XhcCheckUrbResult ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ) -{ - EVT_TRB_TRANSFER *EvtTrb; - TRB_TEMPLATE *TRBPtr; - UINTN Index; - UINT8 TRBType; - EFI_STATUS Status; - URB *AsyncUrb; - URB *CheckedUrb; - UINT64 XhcDequeue; - UINT32 High; - UINT32 Low; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT ((Xhc != NULL) && (Urb != NULL)); - - Status = EFI_SUCCESS; - AsyncUrb = NULL; - - if (Urb->Finished) { - goto EXIT; - } - - EvtTrb = NULL; - - if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) { - Urb->Result |= EFI_USB_ERR_SYSTEM; - goto EXIT; - } - - // - // Traverse the event ring to find out all new events from the previous check. - // - XhcSyncEventRing (Xhc, &Xhc->EventRing); - for (Index = 0; Index < Xhc->EventRing.TrbNumber; Index++) { - Status = XhcCheckNewEvent (Xhc, &Xhc->EventRing, ((TRB_TEMPLATE **)&EvtTrb)); - if (Status == EFI_NOT_READY) { - // - // All new events are handled, return directly. - // - goto EXIT; - } - - // - // Only handle COMMAND_COMPLETETION_EVENT and TRANSFER_EVENT. - // - if ((EvtTrb->Type != TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type != TRB_TYPE_TRANS_EVENT)) { - continue; - } - - // - // Need convert pci device address to host address - // - PhyAddr = (EFI_PHYSICAL_ADDRESS)(EvtTrb->TRBPtrLo | LShiftU64 ((UINT64) EvtTrb->TRBPtrHi, 32)); - TRBPtr = (TRB_TEMPLATE *)(UINTN) UsbHcGetHostAddrForPciAddr (Xhc->MemPool, (VOID *)(UINTN) PhyAddr, sizeof (TRB_TEMPLATE)); - - // - // Update the status of Urb according to the finished event regardless of whether - // the urb is current checked one or in the XHCI's async transfer list. - // This way is used to avoid that those completed async transfer events don't get - // handled in time and are flushed by newer coming events. - // - if (IsTransferRingTrb (TRBPtr, Urb)) { - CheckedUrb = Urb; - } else if (IsAsyncIntTrb (Xhc, TRBPtr, &AsyncUrb)) { - CheckedUrb = AsyncUrb; - } else { - continue; - } - - switch (EvtTrb->Completecode) { - case TRB_COMPLETION_STALL_ERROR: - CheckedUrb->Result |= EFI_USB_ERR_STALL; - CheckedUrb->Finished = TRUE; - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode)); - goto EXIT; - - case TRB_COMPLETION_BABBLE_ERROR: - CheckedUrb->Result |= EFI_USB_ERR_BABBLE; - CheckedUrb->Finished = TRUE; - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode)); - goto EXIT; - - case TRB_COMPLETION_DATA_BUFFER_ERROR: - CheckedUrb->Result |= EFI_USB_ERR_BUFFER; - CheckedUrb->Finished = TRUE; - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode)); - goto EXIT; - - case TRB_COMPLETION_USB_TRANSACTION_ERROR: - CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT; - CheckedUrb->Finished = TRUE; - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode)); - goto EXIT; - - case TRB_COMPLETION_SHORT_PACKET: - case TRB_COMPLETION_SUCCESS: - if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) { - DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: short packet happens!\n")); - } - - TRBType = (UINT8) (TRBPtr->Type); - if ((TRBType == TRB_TYPE_DATA_STAGE) || - (TRBType == TRB_TYPE_NORMAL) || - (TRBType == TRB_TYPE_ISOCH)) { - CheckedUrb->Completed += (((TRANSFER_TRB_NORMAL*)TRBPtr)->Length - EvtTrb->Length); - } - - break; - - default: - DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode)); - CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT; - CheckedUrb->Finished = TRUE; - goto EXIT; - } - - // - // Only check first and end Trb event address - // - if (TRBPtr == CheckedUrb->TrbStart) { - CheckedUrb->StartDone = TRUE; - } - - if (TRBPtr == CheckedUrb->TrbEnd) { - CheckedUrb->EndDone = TRUE; - } - - if (CheckedUrb->StartDone && CheckedUrb->EndDone) { - CheckedUrb->Finished = TRUE; - CheckedUrb->EvtTrb = (TRB_TEMPLATE *)EvtTrb; - } - } - -EXIT: - - // - // Advance event ring to last available entry - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - Low = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET); - High = XhcReadRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4); - XhcDequeue = (UINT64)(LShiftU64((UINT64)High, 32) | Low); - - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->EventRing.EventRingDequeue, sizeof (TRB_TEMPLATE)); - - if ((XhcDequeue & (~0x0F)) != (PhyAddr & (~0x0F))) { - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - XhcWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET, XHC_LOW_32BIT (PhyAddr) | BIT3); - XhcWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4, XHC_HIGH_32BIT (PhyAddr)); - } - - return Urb->Finished; -} - - -/** - Execute the transfer by polling the URB. This is a synchronous operation. - - @param Xhc The XHCI Instance. - @param CmdTransfer The executed URB is for cmd transfer or not. - @param Urb The URB to execute. - @param Timeout The time to wait before abort, in millisecond. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -XhcExecTransfer ( - IN USB_XHCI_INSTANCE *Xhc, - IN BOOLEAN CmdTransfer, - IN URB *Urb, - IN UINTN Timeout - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT64 Loop; - UINT8 SlotId; - UINT8 Dci; - BOOLEAN Finished; - - if (CmdTransfer) { - SlotId = 0; - Dci = 0; - } else { - SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - return EFI_DEVICE_ERROR; - } - Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); - ASSERT (Dci < 32); - } - - Status = EFI_SUCCESS; - Loop = Timeout * XHC_1_MILLISECOND; - if (Timeout == 0) { - Loop = 0xFFFFFFFF; - } - - XhcRingDoorBell (Xhc, SlotId, Dci); - - for (Index = 0; Index < Loop; Index++) { - Finished = XhcCheckUrbResult (Xhc, Urb); - if (Finished) { - break; - } - gBS->Stall (XHC_1_MICROSECOND); - } - - if (Index == Loop) { - Urb->Result = EFI_USB_ERR_TIMEOUT; - Status = EFI_TIMEOUT; - } else if (Urb->Result != EFI_USB_NOERROR) { - Status = EFI_DEVICE_ERROR; - } - - return Status; -} - -/** - Delete a single asynchronous interrupt transfer for - the device and endpoint. - - @param Xhc The XHCI Instance. - @param BusAddr The logical device address assigned by UsbBus driver. - @param EpNum The endpoint of the target. - - @retval EFI_SUCCESS An asynchronous transfer is removed. - @retval EFI_NOT_FOUND No transfer for the device is found. - -**/ -EFI_STATUS -XhciDelAsyncIntTransfer ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 BusAddr, - IN UINT8 EpNum - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - URB *Urb; - EFI_USB_DATA_DIRECTION Direction; - - Direction = ((EpNum & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut; - EpNum &= 0x0F; - - Urb = NULL; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) { - Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList); - if ((Urb->Ep.BusAddr == BusAddr) && - (Urb->Ep.EpAddr == EpNum) && - (Urb->Ep.Direction == Direction)) { - RemoveEntryList (&Urb->UrbList); - FreePool (Urb->Data); - XhcFreeUrb (Xhc, Urb); - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} - -/** - Remove all the asynchronous interrutp transfers. - - @param Xhc The XHCI Instance. - -**/ -VOID -XhciDelAllAsyncIntTransfers ( - IN USB_XHCI_INSTANCE *Xhc - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - URB *Urb; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) { - Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList); - RemoveEntryList (&Urb->UrbList); - FreePool (Urb->Data); - XhcFreeUrb (Xhc, Urb); - } -} - -/** - Update the queue head for next round of asynchronous transfer - - @param Xhc The XHCI Instance. - @param Urb The URB to update - -**/ -VOID -XhcUpdateAsyncRequest ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ) -{ - EFI_STATUS Status; - - if (Urb->Result == EFI_USB_NOERROR) { - Status = XhcCreateTransferTrb (Xhc, Urb); - if (EFI_ERROR (Status)) { - return; - } - Status = RingIntTransferDoorBell (Xhc, Urb); - if (EFI_ERROR (Status)) { - return; - } - } -} - -/** - Flush data from PCI controller specific address to mapped system - memory address. - - @param Xhc The XHCI device. - @param Urb The URB to unmap. - - @retval EFI_SUCCESS Success to flush data to mapped system memory. - @retval EFI_DEVICE_ERROR Fail to flush data to mapped system memory. - -**/ -EFI_STATUS -XhcFlushAsyncIntMap ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS PhyAddr; - EFI_PCI_IO_PROTOCOL_OPERATION MapOp; - EFI_PCI_IO_PROTOCOL *PciIo; - UINTN Len; - VOID *Map; - - PciIo = Xhc->PciIo; - Len = Urb->DataLen; - - if (Urb->Ep.Direction == EfiUsbDataIn) { - MapOp = EfiPciIoOperationBusMasterWrite; - } else { - MapOp = EfiPciIoOperationBusMasterRead; - } - - if (Urb->DataMap != NULL) { - Status = PciIo->Unmap (PciIo, Urb->DataMap); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - } - - Urb->DataMap = NULL; - - Status = PciIo->Map (PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map); - if (EFI_ERROR (Status) || (Len != Urb->DataLen)) { - goto ON_ERROR; - } - - Urb->DataPhy = (VOID *) ((UINTN) PhyAddr); - Urb->DataMap = Map; - return EFI_SUCCESS; - -ON_ERROR: - return EFI_DEVICE_ERROR; -} - -/** - Interrupt transfer periodic check handler. - - @param Event Interrupt event. - @param Context Pointer to USB_XHCI_INSTANCE. - -**/ -VOID -EFIAPI -XhcMonitorAsyncRequests ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - USB_XHCI_INSTANCE *Xhc; - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - UINT8 *ProcBuf; - URB *Urb; - UINT8 SlotId; - EFI_STATUS Status; - EFI_TPL OldTpl; - - OldTpl = gBS->RaiseTPL (XHC_TPL); - - Xhc = (USB_XHCI_INSTANCE*) Context; - - EFI_LIST_FOR_EACH_SAFE (Entry, Next, &Xhc->AsyncIntTransfers) { - Urb = EFI_LIST_CONTAINER (Entry, URB, UrbList); - - // - // Make sure that the device is available before every check. - // - SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - continue; - } - - // - // Check the result of URB execution. If it is still - // active, check the next one. - // - XhcCheckUrbResult (Xhc, Urb); - - if (!Urb->Finished) { - continue; - } - - // - // Flush any PCI posted write transactions from a PCI host - // bridge to system memory. - // - Status = XhcFlushAsyncIntMap (Xhc, Urb); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcMonitorAsyncRequests: Fail to Flush AsyncInt Mapped Memeory\n")); - } - - // - // Allocate a buffer then copy the transferred data for user. - // If failed to allocate the buffer, update the URB for next - // round of transfer. Ignore the data of this round. - // - ProcBuf = NULL; - if (Urb->Result == EFI_USB_NOERROR) { - ASSERT (Urb->Completed <= Urb->DataLen); - - ProcBuf = AllocateZeroPool (Urb->Completed); - - if (ProcBuf == NULL) { - XhcUpdateAsyncRequest (Xhc, Urb); - continue; - } - - CopyMem (ProcBuf, Urb->Data, Urb->Completed); - } - - // - // Leave error recovery to its related device driver. A - // common case of the error recovery is to re-submit the - // interrupt transfer which is linked to the head of the - // list. This function scans from head to tail. So the - // re-submitted interrupt transfer's callback function - // will not be called again in this round. Don't touch this - // URB after the callback, it may have been removed by the - // callback. - // - if (Urb->Callback != NULL) { - // - // Restore the old TPL, USB bus maybe connect device in - // his callback. Some drivers may has a lower TPL restriction. - // - gBS->RestoreTPL (OldTpl); - (Urb->Callback) (ProcBuf, Urb->Completed, Urb->Context, Urb->Result); - OldTpl = gBS->RaiseTPL (XHC_TPL); - } - - if (ProcBuf != NULL) { - gBS->FreePool (ProcBuf); - } - - XhcUpdateAsyncRequest (Xhc, Urb); - } - gBS->RestoreTPL (OldTpl); -} - -/** - Monitor the port status change. Enable/Disable device slot if there is a device attached/detached. - - @param Xhc The XHCI Instance. - @param ParentRouteChart The route string pointed to the parent device if it exists. - @param Port The port to be polled. - @param PortState The port state. - - @retval EFI_SUCCESS Successfully enable/disable device slot according to port state. - @retval Others Should not appear. - -**/ -EFI_STATUS -EFIAPI -XhcPollPortStatusChange ( - IN USB_XHCI_INSTANCE *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT8 Port, - IN EFI_USB_PORT_STATUS *PortState - ) -{ - EFI_STATUS Status; - UINT8 Speed; - UINT8 SlotId; - USB_DEV_ROUTE RouteChart; - - Status = EFI_SUCCESS; - - if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) { - return EFI_SUCCESS; - } - - if (ParentRouteChart.Dword == 0) { - RouteChart.Route.RouteString = 0; - RouteChart.Route.RootPortNum = Port + 1; - RouteChart.Route.TierNum = 1; - } else { - if(Port < 14) { - RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (Port << (4 * (ParentRouteChart.Route.TierNum - 1))); - } else { - RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (15 << (4 * (ParentRouteChart.Route.TierNum - 1))); - } - RouteChart.Route.RootPortNum = ParentRouteChart.Route.RootPortNum; - RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1; - } - - SlotId = XhcRouteStringToSlotId (Xhc, RouteChart); - if (SlotId != 0) { - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcDisableSlotCmd (Xhc, SlotId); - } else { - Status = XhcDisableSlotCmd64 (Xhc, SlotId); - } - } - - if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) && - ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) != 0)) { - // - // Has a device attached, Identify device speed after port is enabled. - // - Speed = EFI_USB_SPEED_FULL; - if ((PortState->PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) { - Speed = EFI_USB_SPEED_LOW; - } else if ((PortState->PortStatus & USB_PORT_STAT_HIGH_SPEED) != 0) { - Speed = EFI_USB_SPEED_HIGH; - } else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0) { - Speed = EFI_USB_SPEED_SUPER; - } - // - // Execute Enable_Slot cmd for attached device, initialize device context and assign device address. - // - SlotId = XhcRouteStringToSlotId (Xhc, RouteChart); - if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) { - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed); - } else { - Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed); - } - } - } - - return Status; -} - - -/** - Calculate the device context index by endpoint address and direction. - - @param EpAddr The target endpoint number. - @param Direction The direction of the target endpoint. - - @return The device context index of endpoint. - -**/ -UINT8 -XhcEndpointToDci ( - IN UINT8 EpAddr, - IN UINT8 Direction - ) -{ - UINT8 Index; - - if (EpAddr == 0) { - return 1; - } else { - Index = (UINT8) (2 * EpAddr); - if (Direction == EfiUsbDataIn) { - Index += 1; - } - return Index; - } -} - -/** - Find out the actual device address according to the requested device address from UsbBus. - - @param Xhc The XHCI Instance. - @param BusDevAddr The requested device address by UsbBus upper driver. - - @return The actual device address assigned to the device. - -**/ -UINT8 -EFIAPI -XhcBusDevAddrToSlotId ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 BusDevAddr - ) -{ - UINT8 Index; - - for (Index = 0; Index < 255; Index++) { - if (Xhc->UsbDevContext[Index + 1].Enabled && - (Xhc->UsbDevContext[Index + 1].SlotId != 0) && - (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) { - break; - } - } - - if (Index == 255) { - return 0; - } - - return Xhc->UsbDevContext[Index + 1].SlotId; -} - -/** - Find out the slot id according to the device's route string. - - @param Xhc The XHCI Instance. - @param RouteString The route string described the device location. - - @return The slot id used by the device. - -**/ -UINT8 -EFIAPI -XhcRouteStringToSlotId ( - IN USB_XHCI_INSTANCE *Xhc, - IN USB_DEV_ROUTE RouteString - ) -{ - UINT8 Index; - - for (Index = 0; Index < 255; Index++) { - if (Xhc->UsbDevContext[Index + 1].Enabled && - (Xhc->UsbDevContext[Index + 1].SlotId != 0) && - (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) { - break; - } - } - - if (Index == 255) { - return 0; - } - - return Xhc->UsbDevContext[Index + 1].SlotId; -} - -/** - Synchronize the specified event ring to update the enqueue and dequeue pointer. - - @param Xhc The XHCI Instance. - @param EvtRing The event ring to sync. - - @retval EFI_SUCCESS The event ring is synchronized successfully. - -**/ -EFI_STATUS -EFIAPI -XhcSyncEventRing ( - IN USB_XHCI_INSTANCE *Xhc, - IN EVENT_RING *EvtRing - ) -{ - UINTN Index; - TRB_TEMPLATE *EvtTrb1; - - ASSERT (EvtRing != NULL); - - // - // Calculate the EventRingEnqueue and EventRingCCS. - // Note: only support single Segment - // - EvtTrb1 = EvtRing->EventRingDequeue; - - for (Index = 0; Index < EvtRing->TrbNumber; Index++) { - if (EvtTrb1->CycleBit != EvtRing->EventRingCCS) { - break; - } - - EvtTrb1++; - - if ((UINTN)EvtTrb1 >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) { - EvtTrb1 = EvtRing->EventRingSeg0; - EvtRing->EventRingCCS = (EvtRing->EventRingCCS) ? 0 : 1; - } - } - - if (Index < EvtRing->TrbNumber) { - EvtRing->EventRingEnqueue = EvtTrb1; - } else { - ASSERT (FALSE); - } - - return EFI_SUCCESS; -} - -/** - Synchronize the specified transfer ring to update the enqueue and dequeue pointer. - - @param Xhc The XHCI Instance. - @param TrsRing The transfer ring to sync. - - @retval EFI_SUCCESS The transfer ring is synchronized successfully. - -**/ -EFI_STATUS -EFIAPI -XhcSyncTrsRing ( - IN USB_XHCI_INSTANCE *Xhc, - IN TRANSFER_RING *TrsRing - ) -{ - UINTN Index; - TRB_TEMPLATE *TrsTrb; - - ASSERT (TrsRing != NULL); - // - // Calculate the latest RingEnqueue and RingPCS - // - TrsTrb = TrsRing->RingEnqueue; - ASSERT (TrsTrb != NULL); - - for (Index = 0; Index < TrsRing->TrbNumber; Index++) { - if (TrsTrb->CycleBit != (TrsRing->RingPCS & BIT0)) { - break; - } - TrsTrb++; - if ((UINT8) TrsTrb->Type == TRB_TYPE_LINK) { - ASSERT (((LINK_TRB*)TrsTrb)->TC != 0); - // - // set cycle bit in Link TRB as normal - // - ((LINK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0; - // - // Toggle PCS maintained by software - // - TrsRing->RingPCS = (TrsRing->RingPCS & BIT0) ? 0 : 1; - TrsTrb = (TRB_TEMPLATE *) TrsRing->RingSeg0; // Use host address - } - } - - ASSERT (Index != TrsRing->TrbNumber); - - if (TrsTrb != TrsRing->RingEnqueue) { - TrsRing->RingEnqueue = TrsTrb; - } - - // - // Clear the Trb context for enqueue, but reserve the PCS bit - // - TrsTrb->Parameter1 = 0; - TrsTrb->Parameter2 = 0; - TrsTrb->Status = 0; - TrsTrb->RsvdZ1 = 0; - TrsTrb->Type = 0; - TrsTrb->Control = 0; - - return EFI_SUCCESS; -} - -/** - Check if there is a new generated event. - - @param Xhc The XHCI Instance. - @param EvtRing The event ring to check. - @param NewEvtTrb The new event TRB found. - - @retval EFI_SUCCESS Found a new event TRB at the event ring. - @retval EFI_NOT_READY The event ring has no new event. - -**/ -EFI_STATUS -EFIAPI -XhcCheckNewEvent ( - IN USB_XHCI_INSTANCE *Xhc, - IN EVENT_RING *EvtRing, - OUT TRB_TEMPLATE **NewEvtTrb - ) -{ - ASSERT (EvtRing != NULL); - - *NewEvtTrb = EvtRing->EventRingDequeue; - - if (EvtRing->EventRingDequeue == EvtRing->EventRingEnqueue) { - return EFI_NOT_READY; - } - - EvtRing->EventRingDequeue++; - // - // If the dequeue pointer is beyond the ring, then roll-back it to the begining of the ring. - // - if ((UINTN)EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) { - EvtRing->EventRingDequeue = EvtRing->EventRingSeg0; - } - - return EFI_SUCCESS; -} - -/** - Ring the door bell to notify XHCI there is a transaction to be executed. - - @param Xhc The XHCI Instance. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - - @retval EFI_SUCCESS Successfully ring the door bell. - -**/ -EFI_STATUS -EFIAPI -XhcRingDoorBell ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ) -{ - if (SlotId == 0) { - XhcWriteDoorBellReg (Xhc, 0, 0); - } else { - XhcWriteDoorBellReg (Xhc, SlotId * sizeof (UINT32), Dci); - } - - return EFI_SUCCESS; -} - -/** - Ring the door bell to notify XHCI there is a transaction to be executed through URB. - - @param Xhc The XHCI Instance. - @param Urb The URB to be rung. - - @retval EFI_SUCCESS Successfully ring the door bell. - -**/ -EFI_STATUS -RingIntTransferDoorBell ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ) -{ - UINT8 SlotId; - UINT8 Dci; - - SlotId = XhcBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - Dci = XhcEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); - XhcRingDoorBell (Xhc, SlotId, Dci); - return EFI_SUCCESS; -} - -/** - Assign and initialize the device slot for a new device. - - @param Xhc The XHCI Instance. - @param ParentRouteChart The route string pointed to the parent device. - @param ParentPort The port at which the device is located. - @param RouteChart The route string pointed to the device. - @param DeviceSpeed The device speed. - - @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it. - -**/ -EFI_STATUS -EFIAPI -XhcInitializeDeviceSlot ( - IN USB_XHCI_INSTANCE *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT16 ParentPort, - IN USB_DEV_ROUTE RouteChart, - IN UINT8 DeviceSpeed - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputContext; - TRANSFER_RING *EndpointTransferRing; - CMD_TRB_ADDRESS_DEVICE CmdTrbAddr; - UINT8 DeviceAddress; - CMD_TRB_ENABLE_SLOT CmdTrb; - UINT8 SlotId; - UINT8 ParentSlotId; - DEVICE_CONTEXT *ParentDeviceContext; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT)); - CmdTrb.CycleBit = 1; - CmdTrb.Type = TRB_TYPE_EN_SLOT; - - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrb, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcInitializeDeviceSlot: Enable Slot Failed, Status = %r\n", Status)); - return Status; - } - ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn); - DEBUG ((EFI_D_INFO, "Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId)); - SlotId = (UINT8)EvtTrb->SlotId; - ASSERT (SlotId != 0); - - ZeroMem (&Xhc->UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT)); - Xhc->UsbDevContext[SlotId].Enabled = TRUE; - Xhc->UsbDevContext[SlotId].SlotId = SlotId; - Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword; - Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword; - - // - // 4.3.3 Device Slot Initialization - // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'. - // - InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT)); - ASSERT (InputContext != NULL); - ASSERT (((UINTN) InputContext & 0x3F) == 0); - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - - Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext; - - // - // 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1 - // flags to '1'. These flags indicate that the Slot Context and the Endpoint 0 Context of the Input - // Context are affected by the command. - // - InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1); - - // - // 3) Initialize the Input Slot Context data structure - // - InputContext->Slot.RouteString = RouteChart.Route.RouteString; - InputContext->Slot.Speed = DeviceSpeed + 1; - InputContext->Slot.ContextEntries = 1; - InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum; - - if (RouteChart.Route.RouteString) { - // - // The device is behind of hub device. - // - ParentSlotId = XhcRouteStringToSlotId(Xhc, ParentRouteChart); - ASSERT (ParentSlotId != 0); - // - //if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context - // - ParentDeviceContext = (DEVICE_CONTEXT *)Xhc->UsbDevContext[ParentSlotId].OutputContext; - if ((ParentDeviceContext->Slot.TTPortNum == 0) && - (ParentDeviceContext->Slot.TTHubSlotId == 0)) { - if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) { - // - // Full/Low device attached to High speed hub port that isolates the high speed signaling - // environment from Full/Low speed signaling environment for a device - // - InputContext->Slot.TTPortNum = ParentPort; - InputContext->Slot.TTHubSlotId = ParentSlotId; - } - } else { - // - // Inherit the TT parameters from parent device. - // - InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum; - InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId; - // - // If the device is a High speed device then down the speed to be the same as its parent Hub - // - if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed; - } - } - } - - // - // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint. - // - EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]); - // - // 5) Initialize the Input default control Endpoint 0 Context (6.2.3). - // - InputContext->EP[0].EPType = ED_CONTROL_BIDIR; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - InputContext->EP[0].MaxPacketSize = 512; - } else if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - InputContext->EP[0].MaxPacketSize = 64; - } else { - InputContext->EP[0].MaxPacketSize = 8; - } - // - // Initial value of Average TRB Length for Control endpoints would be 8B, Interrupt endpoints - // 1KB, and Bulk and Isoch endpoints 3KB. - // - InputContext->EP[0].AverageTRBLength = 8; - InputContext->EP[0].MaxBurstSize = 0; - InputContext->EP[0].Interval = 0; - InputContext->EP[0].MaxPStreams = 0; - InputContext->EP[0].Mult = 0; - InputContext->EP[0].CErr = 3; - - // - // Init the DCS(dequeue cycle state) as the transfer ring's CCS - // - PhyAddr = UsbHcGetPciAddrForHostAddr ( - Xhc->MemPool, - ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0, - sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER - ); - InputContext->EP[0].PtrLo = XHC_LOW_32BIT (PhyAddr) | BIT0; - InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (PhyAddr); - - // - // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'. - // - OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT)); - ASSERT (OutputContext != NULL); - ASSERT (((UINTN) OutputContext & 0x3F) == 0); - ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT)); - - Xhc->UsbDevContext[SlotId].OutputContext = OutputContext; - // - // 7) Load the appropriate (Device Slot ID) entry in the Device Context Base Address Array (5.4.6) with - // a pointer to the Output Device Context data structure (6.2.1). - // - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, OutputContext, sizeof (DEVICE_CONTEXT)); - // - // Fill DCBAA with PCI device address - // - Xhc->DCBAA[SlotId] = (UINT64) (UINTN) PhyAddr; - - // - // 8) Issue an Address Device Command for the Device Slot, where the command points to the Input - // Context data structure described above. - // - ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbAddr.CycleBit = 1; - CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV; - CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (!EFI_ERROR (Status)) { - DeviceAddress = (UINT8) ((DEVICE_CONTEXT *) OutputContext)->Slot.DeviceAddress; - DEBUG ((EFI_D_INFO, " Address %d assigned successfully\n", DeviceAddress)); - Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress; - } - - return Status; -} - -/** - Assign and initialize the device slot for a new device. - - @param Xhc The XHCI Instance. - @param ParentRouteChart The route string pointed to the parent device. - @param ParentPort The port at which the device is located. - @param RouteChart The route string pointed to the device. - @param DeviceSpeed The device speed. - - @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it. - -**/ -EFI_STATUS -EFIAPI -XhcInitializeDeviceSlot64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT16 ParentPort, - IN USB_DEV_ROUTE RouteChart, - IN UINT8 DeviceSpeed - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT_64 *InputContext; - DEVICE_CONTEXT_64 *OutputContext; - TRANSFER_RING *EndpointTransferRing; - CMD_TRB_ADDRESS_DEVICE CmdTrbAddr; - UINT8 DeviceAddress; - CMD_TRB_ENABLE_SLOT CmdTrb; - UINT8 SlotId; - UINT8 ParentSlotId; - DEVICE_CONTEXT_64 *ParentDeviceContext; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT)); - CmdTrb.CycleBit = 1; - CmdTrb.Type = TRB_TYPE_EN_SLOT; - - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrb, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcInitializeDeviceSlot64: Enable Slot Failed, Status = %r\n", Status)); - return Status; - } - ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn); - DEBUG ((EFI_D_INFO, "Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId)); - SlotId = (UINT8)EvtTrb->SlotId; - ASSERT (SlotId != 0); - - ZeroMem (&Xhc->UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT)); - Xhc->UsbDevContext[SlotId].Enabled = TRUE; - Xhc->UsbDevContext[SlotId].SlotId = SlotId; - Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword; - Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword; - - // - // 4.3.3 Device Slot Initialization - // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'. - // - InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64)); - ASSERT (InputContext != NULL); - ASSERT (((UINTN) InputContext & 0x3F) == 0); - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - - Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext; - - // - // 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1 - // flags to '1'. These flags indicate that the Slot Context and the Endpoint 0 Context of the Input - // Context are affected by the command. - // - InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1); - - // - // 3) Initialize the Input Slot Context data structure - // - InputContext->Slot.RouteString = RouteChart.Route.RouteString; - InputContext->Slot.Speed = DeviceSpeed + 1; - InputContext->Slot.ContextEntries = 1; - InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum; - - if (RouteChart.Route.RouteString) { - // - // The device is behind of hub device. - // - ParentSlotId = XhcRouteStringToSlotId(Xhc, ParentRouteChart); - ASSERT (ParentSlotId != 0); - // - //if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context - // - ParentDeviceContext = (DEVICE_CONTEXT_64 *)Xhc->UsbDevContext[ParentSlotId].OutputContext; - if ((ParentDeviceContext->Slot.TTPortNum == 0) && - (ParentDeviceContext->Slot.TTHubSlotId == 0)) { - if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) { - // - // Full/Low device attached to High speed hub port that isolates the high speed signaling - // environment from Full/Low speed signaling environment for a device - // - InputContext->Slot.TTPortNum = ParentPort; - InputContext->Slot.TTHubSlotId = ParentSlotId; - } - } else { - // - // Inherit the TT parameters from parent device. - // - InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum; - InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId; - // - // If the device is a High speed device then down the speed to be the same as its parent Hub - // - if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed; - } - } - } - - // - // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint. - // - EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]); - // - // 5) Initialize the Input default control Endpoint 0 Context (6.2.3). - // - InputContext->EP[0].EPType = ED_CONTROL_BIDIR; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - InputContext->EP[0].MaxPacketSize = 512; - } else if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - InputContext->EP[0].MaxPacketSize = 64; - } else { - InputContext->EP[0].MaxPacketSize = 8; - } - // - // Initial value of Average TRB Length for Control endpoints would be 8B, Interrupt endpoints - // 1KB, and Bulk and Isoch endpoints 3KB. - // - InputContext->EP[0].AverageTRBLength = 8; - InputContext->EP[0].MaxBurstSize = 0; - InputContext->EP[0].Interval = 0; - InputContext->EP[0].MaxPStreams = 0; - InputContext->EP[0].Mult = 0; - InputContext->EP[0].CErr = 3; - - // - // Init the DCS(dequeue cycle state) as the transfer ring's CCS - // - PhyAddr = UsbHcGetPciAddrForHostAddr ( - Xhc->MemPool, - ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0, - sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER - ); - InputContext->EP[0].PtrLo = XHC_LOW_32BIT (PhyAddr) | BIT0; - InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (PhyAddr); - - // - // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'. - // - OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64)); - ASSERT (OutputContext != NULL); - ASSERT (((UINTN) OutputContext & 0x3F) == 0); - ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64)); - - Xhc->UsbDevContext[SlotId].OutputContext = OutputContext; - // - // 7) Load the appropriate (Device Slot ID) entry in the Device Context Base Address Array (5.4.6) with - // a pointer to the Output Device Context data structure (6.2.1). - // - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, OutputContext, sizeof (DEVICE_CONTEXT_64)); - // - // Fill DCBAA with PCI device address - // - Xhc->DCBAA[SlotId] = (UINT64) (UINTN) PhyAddr; - - // - // 8) Issue an Address Device Command for the Device Slot, where the command points to the Input - // Context data structure described above. - // - ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbAddr.CycleBit = 1; - CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV; - CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (!EFI_ERROR (Status)) { - DeviceAddress = (UINT8) ((DEVICE_CONTEXT_64 *) OutputContext)->Slot.DeviceAddress; - DEBUG ((EFI_D_INFO, " Address %d assigned successfully\n", DeviceAddress)); - Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress; - } - return Status; -} - - -/** - Disable the specified device slot. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be disabled. - - @retval EFI_SUCCESS Successfully disable the device slot. - -**/ -EFI_STATUS -EFIAPI -XhcDisableSlotCmd ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId - ) -{ - EFI_STATUS Status; - TRB_TEMPLATE *EvtTrb; - CMD_TRB_DISABLE_SLOT CmdTrbDisSlot; - UINT8 Index; - VOID *RingSeg; - - // - // Disable the device slots occupied by these devices on its downstream ports. - // Entry 0 is reserved. - // - for (Index = 0; Index < 255; Index++) { - if (!Xhc->UsbDevContext[Index + 1].Enabled || - (Xhc->UsbDevContext[Index + 1].SlotId == 0) || - (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) { - continue; - } - - Status = XhcDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n")); - Xhc->UsbDevContext[Index + 1].SlotId = 0; - } - } - - // - // Construct the disable slot command - // - DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId)); - - ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot)); - CmdTrbDisSlot.CycleBit = 1; - CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT; - CmdTrbDisSlot.SlotId = SlotId; - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status)); - return Status; - } - // - // Free the slot's device context entry - // - Xhc->DCBAA[SlotId] = 0; - - // - // Free the slot related data structure - // - for (Index = 0; Index < 31; Index++) { - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) { - RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0; - if (RingSeg != NULL) { - UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER); - } - FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] = NULL; - } - } - - for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) { - if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) { - FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]); - } - } - - if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting != NULL) { - FreePool (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting); - } - - if (Xhc->UsbDevContext[SlotId].InputContext != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT)); - } - - if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].OutputContext, sizeof (DEVICE_CONTEXT)); - } - // - // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established - // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to - // remove urb from XHCI's asynchronous transfer list. - // - Xhc->UsbDevContext[SlotId].Enabled = FALSE; - Xhc->UsbDevContext[SlotId].SlotId = 0; - - return Status; -} - -/** - Disable the specified device slot. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be disabled. - - @retval EFI_SUCCESS Successfully disable the device slot. - -**/ -EFI_STATUS -EFIAPI -XhcDisableSlotCmd64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId - ) -{ - EFI_STATUS Status; - TRB_TEMPLATE *EvtTrb; - CMD_TRB_DISABLE_SLOT CmdTrbDisSlot; - UINT8 Index; - VOID *RingSeg; - - // - // Disable the device slots occupied by these devices on its downstream ports. - // Entry 0 is reserved. - // - for (Index = 0; Index < 255; Index++) { - if (!Xhc->UsbDevContext[Index + 1].Enabled || - (Xhc->UsbDevContext[Index + 1].SlotId == 0) || - (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) { - continue; - } - - Status = XhcDisableSlotCmd64 (Xhc, Xhc->UsbDevContext[Index + 1].SlotId); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: failed to disable child, ignore error\n")); - Xhc->UsbDevContext[Index + 1].SlotId = 0; - } - } - - // - // Construct the disable slot command - // - DEBUG ((EFI_D_INFO, "Disable device slot %d!\n", SlotId)); - - ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot)); - CmdTrbDisSlot.CycleBit = 1; - CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT; - CmdTrbDisSlot.SlotId = SlotId; - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status)); - return Status; - } - // - // Free the slot's device context entry - // - Xhc->DCBAA[SlotId] = 0; - - // - // Free the slot related data structure - // - for (Index = 0; Index < 31; Index++) { - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) { - RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0; - if (RingSeg != NULL) { - UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER); - } - FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] = NULL; - } - } - - for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) { - if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) { - FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]); - } - } - - if (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting != NULL) { - FreePool (Xhc->UsbDevContext[SlotId].ActiveAlternateSetting); - } - - if (Xhc->UsbDevContext[SlotId].InputContext != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64)); - } - - if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].OutputContext, sizeof (DEVICE_CONTEXT_64)); - } - // - // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established - // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to - // remove urb from XHCI's asynchronous transfer list. - // - Xhc->UsbDevContext[SlotId].Enabled = FALSE; - Xhc->UsbDevContext[SlotId].SlotId = 0; - - return Status; -} - -/** - Initialize endpoint context in input context. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param InputContext The pointer to the input context. - @param IfDesc The pointer to the usb device interface descriptor. - - @return The maximum device context index of endpoint. - -**/ -UINT8 -EFIAPI -XhcInitializeEndpointContext ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN INPUT_CONTEXT *InputContext, - IN USB_INTERFACE_DESCRIPTOR *IfDesc - ) -{ - USB_ENDPOINT_DESCRIPTOR *EpDesc; - UINTN NumEp; - UINTN EpIndex; - UINT8 EpAddr; - UINT8 Direction; - UINT8 Dci; - UINT8 MaxDci; - EFI_PHYSICAL_ADDRESS PhyAddr; - UINT8 Interval; - TRANSFER_RING *EndpointTransferRing; - - MaxDci = 0; - - NumEp = IfDesc->NumEndpoints; - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1); - for (EpIndex = 0; EpIndex < NumEp; EpIndex++) { - while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) { - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - } - - EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F); - Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut); - - Dci = XhcEndpointToDci (EpAddr, Direction); - ASSERT (Dci < 32); - if (Dci > MaxDci) { - MaxDci = Dci; - } - - InputContext->InputControlContext.Dword2 |= (BIT0 << Dci); - InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - // - // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor. - // - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - } else { - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - } - - switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) { - case USB_ENDPOINT_BULK: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_BULK_IN; - } else { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_BULK_OUT; - } - - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); - } - - break; - case USB_ENDPOINT_ISO: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 0; - InputContext->EP[Dci-1].EPType = ED_ISOCH_IN; - } else { - InputContext->EP[Dci-1].CErr = 0; - InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT; - } - // - // Do not support isochronous transfer now. - // - DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext: Unsupport ISO EP found, Transfer ring is not allocated.\n")); - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - continue; - case USB_ENDPOINT_INTERRUPT: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN; - } else { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT; - } - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize; - // - // Get the bInterval from descriptor and init the the interval field of endpoint context - // - if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) { - Interval = EpDesc->Interval; - // - // Calculate through the bInterval field of Endpoint descriptor. - // - ASSERT (Interval != 0); - InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3; - } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) { - Interval = EpDesc->Interval; - ASSERT (Interval >= 1 && Interval <= 16); - // - // Refer to XHCI 1.0 spec section 6.2.3.6, table 61 - // - InputContext->EP[Dci-1].Interval = Interval - 1; - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - InputContext->EP[Dci-1].MaxESITPayload = 0x0002; - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - InputContext->EP[Dci-1].CErr = 3; - } - - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); - } - break; - - case USB_ENDPOINT_CONTROL: - // - // Do not support control transfer now. - // - DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext: Unsupport Control EP found, Transfer ring is not allocated.\n")); - default: - DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext: Unknown EP found, Transfer ring is not allocated.\n")); - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - continue; - } - - PhyAddr = UsbHcGetPciAddrForHostAddr ( - Xhc->MemPool, - ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0, - sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER - ); - PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F); - PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS; - InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr); - InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr); - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - } - - return MaxDci; -} - -/** - Initialize endpoint context in input context. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param InputContext The pointer to the input context. - @param IfDesc The pointer to the usb device interface descriptor. - - @return The maximum device context index of endpoint. - -**/ -UINT8 -EFIAPI -XhcInitializeEndpointContext64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN INPUT_CONTEXT_64 *InputContext, - IN USB_INTERFACE_DESCRIPTOR *IfDesc - ) -{ - USB_ENDPOINT_DESCRIPTOR *EpDesc; - UINTN NumEp; - UINTN EpIndex; - UINT8 EpAddr; - UINT8 Direction; - UINT8 Dci; - UINT8 MaxDci; - EFI_PHYSICAL_ADDRESS PhyAddr; - UINT8 Interval; - TRANSFER_RING *EndpointTransferRing; - - MaxDci = 0; - - NumEp = IfDesc->NumEndpoints; - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)(IfDesc + 1); - for (EpIndex = 0; EpIndex < NumEp; EpIndex++) { - while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) { - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - } - - EpAddr = (UINT8)(EpDesc->EndpointAddress & 0x0F); - Direction = (UINT8)((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut); - - Dci = XhcEndpointToDci (EpAddr, Direction); - ASSERT (Dci < 32); - if (Dci > MaxDci) { - MaxDci = Dci; - } - - InputContext->InputControlContext.Dword2 |= (BIT0 << Dci); - InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - // - // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor. - // - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - } else { - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - } - - switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) { - case USB_ENDPOINT_BULK: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_BULK_IN; - } else { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_BULK_OUT; - } - - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); - } - - break; - case USB_ENDPOINT_ISO: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 0; - InputContext->EP[Dci-1].EPType = ED_ISOCH_IN; - } else { - InputContext->EP[Dci-1].CErr = 0; - InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT; - } - // - // Do not support isochronous transfer now. - // - DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext64: Unsupport ISO EP found, Transfer ring is not allocated.\n")); - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - continue; - case USB_ENDPOINT_INTERRUPT: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN; - } else { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT; - } - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize; - // - // Get the bInterval from descriptor and init the the interval field of endpoint context - // - if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) { - Interval = EpDesc->Interval; - // - // Calculate through the bInterval field of Endpoint descriptor. - // - ASSERT (Interval != 0); - InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3; - } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) { - Interval = EpDesc->Interval; - ASSERT (Interval >= 1 && Interval <= 16); - // - // Refer to XHCI 1.0 spec section 6.2.3.6, table 61 - // - InputContext->EP[Dci-1].Interval = Interval - 1; - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - InputContext->EP[Dci-1].MaxESITPayload = 0x0002; - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - InputContext->EP[Dci-1].CErr = 3; - } - - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateZeroPool(sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - CreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); - } - break; - - case USB_ENDPOINT_CONTROL: - // - // Do not support control transfer now. - // - DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext64: Unsupport Control EP found, Transfer ring is not allocated.\n")); - default: - DEBUG ((EFI_D_INFO, "XhcInitializeEndpointContext64: Unknown EP found, Transfer ring is not allocated.\n")); - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - continue; - } - - PhyAddr = UsbHcGetPciAddrForHostAddr ( - Xhc->MemPool, - ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0, - sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER - ); - PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F); - PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS; - InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr); - InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr); - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - } - - return MaxDci; -} - -/** - Configure all the device endpoints through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - - @retval EFI_SUCCESS Successfully configure all the device endpoints. - -**/ -EFI_STATUS -EFIAPI -XhcSetConfigCmd ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc - ) -{ - EFI_STATUS Status; - USB_INTERFACE_DESCRIPTOR *IfDesc; - UINT8 Index; - UINT8 Dci; - UINT8 MaxDci; - EFI_PHYSICAL_ADDRESS PhyAddr; - - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputContext; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - // - // 4.6.6 Configure Endpoint - // - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT)); - - ASSERT (ConfigDesc != NULL); - - MaxDci = 0; - - IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1); - for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) { - while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) { - IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); - } - - Dci = XhcInitializeEndpointContext (Xhc, SlotId, DeviceSpeed, InputContext, IfDesc); - if (Dci > MaxDci) { - MaxDci = Dci; - } - - IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); - } - - InputContext->InputControlContext.Dword2 |= BIT0; - InputContext->Slot.ContextEntries = MaxDci; - // - // configure endpoint - // - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "Configure Endpoint\n")); - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status)); - } else { - Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue; - } - - return Status; -} - -/** - Configure all the device endpoints through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - - @retval EFI_SUCCESS Successfully configure all the device endpoints. - -**/ -EFI_STATUS -EFIAPI -XhcSetConfigCmd64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc - ) -{ - EFI_STATUS Status; - USB_INTERFACE_DESCRIPTOR *IfDesc; - UINT8 Index; - UINT8 Dci; - UINT8 MaxDci; - EFI_PHYSICAL_ADDRESS PhyAddr; - - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - INPUT_CONTEXT_64 *InputContext; - DEVICE_CONTEXT_64 *OutputContext; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - // - // 4.6.6 Configure Endpoint - // - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT_64)); - - ASSERT (ConfigDesc != NULL); - - MaxDci = 0; - - IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1); - for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) { - while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) { - IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); - } - - Dci = XhcInitializeEndpointContext64 (Xhc, SlotId, DeviceSpeed, InputContext, IfDesc); - if (Dci > MaxDci) { - MaxDci = Dci; - } - - IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); - } - - InputContext->InputControlContext.Dword2 |= BIT0; - InputContext->Slot.ContextEntries = MaxDci; - // - // configure endpoint - // - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "Configure Endpoint\n")); - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status)); - } else { - Xhc->UsbDevContext[SlotId].ActiveConfiguration = ConfigDesc->ConfigurationValue; - } - - return Status; -} - -/** - Stop endpoint through XHCI's Stop_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param Dci The device context index of endpoint. - - @retval EFI_SUCCESS Stop endpoint successfully. - @retval Others Failed to stop endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcStopEndpoint ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - CMD_TRB_STOP_ENDPOINT CmdTrbStopED; - - DEBUG ((EFI_D_INFO, "XhcStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci)); - - // - // Send stop endpoint command to transit Endpoint from running to stop state - // - ZeroMem (&CmdTrbStopED, sizeof (CmdTrbStopED)); - CmdTrbStopED.CycleBit = 1; - CmdTrbStopED.Type = TRB_TYPE_STOP_ENDPOINT; - CmdTrbStopED.EDID = Dci; - CmdTrbStopED.SlotId = SlotId; - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbStopED, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status)); - } - - return Status; -} - -/** - Reset endpoint through XHCI's Reset_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param Dci The device context index of endpoint. - - @retval EFI_SUCCESS Reset endpoint successfully. - @retval Others Failed to reset endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcResetEndpoint ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - CMD_TRB_RESET_ENDPOINT CmdTrbResetED; - - DEBUG ((EFI_D_INFO, "XhcResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci)); - - // - // Send stop endpoint command to transit Endpoint from running to stop state - // - ZeroMem (&CmdTrbResetED, sizeof (CmdTrbResetED)); - CmdTrbResetED.CycleBit = 1; - CmdTrbResetED.Type = TRB_TYPE_RESET_ENDPOINT; - CmdTrbResetED.EDID = Dci; - CmdTrbResetED.SlotId = SlotId; - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status)); - } - - return Status; -} - -/** - Set transfer ring dequeue pointer through XHCI's Set_Tr_Dequeue_Pointer cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param Dci The device context index of endpoint. - @param Urb The dequeue pointer of the transfer ring specified - by the urb to be updated. - - @retval EFI_SUCCESS Set transfer ring dequeue pointer succeeds. - @retval Others Failed to set transfer ring dequeue pointer. - -**/ -EFI_STATUS -EFIAPI -XhcSetTrDequeuePointer ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci, - IN URB *Urb - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - CMD_SET_TR_DEQ_POINTER CmdSetTRDeq; - EFI_PHYSICAL_ADDRESS PhyAddr; - - DEBUG ((EFI_D_INFO, "XhcSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb)); - - // - // Send stop endpoint command to transit Endpoint from running to stop state - // - ZeroMem (&CmdSetTRDeq, sizeof (CmdSetTRDeq)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, sizeof (CMD_SET_TR_DEQ_POINTER)); - CmdSetTRDeq.PtrLo = XHC_LOW_32BIT (PhyAddr) | Urb->Ring->RingPCS; - CmdSetTRDeq.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdSetTRDeq.CycleBit = 1; - CmdSetTRDeq.Type = TRB_TYPE_SET_TR_DEQUE; - CmdSetTRDeq.Endpoint = Dci; - CmdSetTRDeq.SlotId = SlotId; - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status)); - } - - return Status; -} - -/** - Set interface through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - @param Request USB device request to send. - - @retval EFI_SUCCESS Successfully set interface. - -**/ -EFI_STATUS -EFIAPI -XhcSetInterface ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc, - IN EFI_USB_DEVICE_REQUEST *Request - ) -{ - EFI_STATUS Status; - USB_INTERFACE_DESCRIPTOR *IfDescActive; - USB_INTERFACE_DESCRIPTOR *IfDescSet; - USB_INTERFACE_DESCRIPTOR *IfDesc; - USB_ENDPOINT_DESCRIPTOR *EpDesc; - UINTN NumEp; - UINTN EpIndex; - UINT8 EpAddr; - UINT8 Direction; - UINT8 Dci; - UINT8 MaxDci; - EFI_PHYSICAL_ADDRESS PhyAddr; - VOID *RingSeg; - - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputContext; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - - Status = EFI_SUCCESS; - - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - // - // XHCI 4.6.6 Configure Endpoint - // When this command is used to "Set an Alternate Interface on a device", software shall set the Drop - // Context and Add Context flags as follows: - // 1) If an endpoint is not modified by the Alternate Interface setting, then software shall set the Drop - // Context and Add Context flags to '0'. - // - // Except the interface indicated by Reqeust->Index, no impact to other interfaces. - // So the default Drop Context and Add Context flags can be '0' to cover 1). - // - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT)); - - ASSERT (ConfigDesc != NULL); - - MaxDci = 0; - - IfDescActive = NULL; - IfDescSet = NULL; - - IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1); - while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) { - if (IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) { - if (IfDesc->InterfaceNumber == (UINT8) Request->Index) { - if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) { - // - // Find out the active interface descriptor. - // - IfDescActive = IfDesc; - } else if (IfDesc->AlternateSetting == (UINT8) Request->Value) { - // - // Find out the interface descriptor to set. - // - IfDescSet = IfDesc; - } - } - } - IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); - } - - // - // XHCI 4.6.6 Configure Endpoint - // When this command is used to "Set an Alternate Interface on a device", software shall set the Drop - // Context and Add Context flags as follows: - // 2) If an endpoint previously disabled, is enabled by the Alternate Interface setting, then software shall set - // the Drop Context flag to '0' and Add Context flag to '1', and initialize the Input Endpoint Context. - // 3) If an endpoint previously enabled, is disabled by the Alternate Interface setting, then software shall set - // the Drop Context flag to '1' and Add Context flag to '0'. - // 4) If a parameter of an enabled endpoint is modified by an Alternate Interface setting, the Drop Context - // and Add Context flags shall be set to '1'. - // - // Below codes are to cover 2), 3) and 4). - // - - if ((IfDescActive != NULL) && (IfDescSet != NULL)) { - NumEp = IfDescActive->NumEndpoints; - EpDesc = (USB_ENDPOINT_DESCRIPTOR *) (IfDescActive + 1); - for (EpIndex = 0; EpIndex < NumEp; EpIndex++) { - while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) { - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - } - - EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F); - Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut); - - Dci = XhcEndpointToDci (EpAddr, Direction); - ASSERT (Dci < 32); - if (Dci > MaxDci) { - MaxDci = Dci; - } - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 1) Stop any Running Transfer Rings affected by the Alternate Interface setting. - // - Status = XhcStopEndpoint (Xhc, SlotId, Dci); - if (EFI_ERROR (Status)) { - return Status; - } - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 2) Free Transfer Rings of all endpoints that will be affected by the Alternate Interface setting. - // - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] != NULL) { - RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0; - if (RingSeg != NULL) { - UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER); - } - FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] = NULL; - } - - // - // Set the Drop Context flag to '1'. - // - InputContext->InputControlContext.Dword1 |= (BIT0 << Dci); - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - } - - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 3) Clear all the Endpoint Context fields of each endpoint that will be disabled by the Alternate - // Interface setting, to '0'. - // - // The step 3) has been covered by the ZeroMem () to InputContext at the start of the function. - // - - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 4) For each endpoint enabled by the Configure Endpoint Command: - // a. Allocate a Transfer Ring. - // b. Initialize the Transfer Ring Segment(s) by clearing all fields of all TRBs to '0'. - // c. Initialize the Endpoint Context data structure. - // - Dci = XhcInitializeEndpointContext (Xhc, SlotId, DeviceSpeed, InputContext, IfDescSet); - if (Dci > MaxDci) { - MaxDci = Dci; - } - - InputContext->InputControlContext.Dword2 |= BIT0; - InputContext->Slot.ContextEntries = MaxDci; - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 5) Issue and successfully complete a Configure Endpoint Command. - // - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "SetInterface: Configure Endpoint\n")); - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SetInterface: Config Endpoint Failed, Status = %r\n", Status)); - } else { - // - // Update the active AlternateSetting. - // - Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] = (UINT8) Request->Value; - } - } - - return Status; -} - -/** - Set interface through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - @param Request USB device request to send. - - @retval EFI_SUCCESS Successfully set interface. - -**/ -EFI_STATUS -EFIAPI -XhcSetInterface64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc, - IN EFI_USB_DEVICE_REQUEST *Request - ) -{ - EFI_STATUS Status; - USB_INTERFACE_DESCRIPTOR *IfDescActive; - USB_INTERFACE_DESCRIPTOR *IfDescSet; - USB_INTERFACE_DESCRIPTOR *IfDesc; - USB_ENDPOINT_DESCRIPTOR *EpDesc; - UINTN NumEp; - UINTN EpIndex; - UINT8 EpAddr; - UINT8 Direction; - UINT8 Dci; - UINT8 MaxDci; - EFI_PHYSICAL_ADDRESS PhyAddr; - VOID *RingSeg; - - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - INPUT_CONTEXT_64 *InputContext; - DEVICE_CONTEXT_64 *OutputContext; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - - Status = EFI_SUCCESS; - - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - // - // XHCI 4.6.6 Configure Endpoint - // When this command is used to "Set an Alternate Interface on a device", software shall set the Drop - // Context and Add Context flags as follows: - // 1) If an endpoint is not modified by the Alternate Interface setting, then software shall set the Drop - // Context and Add Context flags to '0'. - // - // Except the interface indicated by Reqeust->Index, no impact to other interfaces. - // So the default Drop Context and Add Context flags can be '0' to cover 1). - // - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT_64)); - - ASSERT (ConfigDesc != NULL); - - MaxDci = 0; - - IfDescActive = NULL; - IfDescSet = NULL; - - IfDesc = (USB_INTERFACE_DESCRIPTOR *)(ConfigDesc + 1); - while ((UINTN) IfDesc < ((UINTN) ConfigDesc + ConfigDesc->TotalLength)) { - if (IfDesc->DescriptorType == USB_DESC_TYPE_INTERFACE) { - if (IfDesc->InterfaceNumber == (UINT8) Request->Index) { - if (IfDesc->AlternateSetting == Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[IfDesc->InterfaceNumber]) { - // - // Find out the active interface descriptor. - // - IfDescActive = IfDesc; - } else if (IfDesc->AlternateSetting == (UINT8) Request->Value) { - // - // Find out the interface descriptor to set. - // - IfDescSet = IfDesc; - } - } - } - IfDesc = (USB_INTERFACE_DESCRIPTOR *)((UINTN)IfDesc + IfDesc->Length); - } - - // - // XHCI 4.6.6 Configure Endpoint - // When this command is used to "Set an Alternate Interface on a device", software shall set the Drop - // Context and Add Context flags as follows: - // 2) If an endpoint previously disabled, is enabled by the Alternate Interface setting, then software shall set - // the Drop Context flag to '0' and Add Context flag to '1', and initialize the Input Endpoint Context. - // 3) If an endpoint previously enabled, is disabled by the Alternate Interface setting, then software shall set - // the Drop Context flag to '1' and Add Context flag to '0'. - // 4) If a parameter of an enabled endpoint is modified by an Alternate Interface setting, the Drop Context - // and Add Context flags shall be set to '1'. - // - // Below codes are to cover 2), 3) and 4). - // - - if ((IfDescActive != NULL) && (IfDescSet != NULL)) { - NumEp = IfDescActive->NumEndpoints; - EpDesc = (USB_ENDPOINT_DESCRIPTOR *) (IfDescActive + 1); - for (EpIndex = 0; EpIndex < NumEp; EpIndex++) { - while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) { - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - } - - EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F); - Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut); - - Dci = XhcEndpointToDci (EpAddr, Direction); - ASSERT (Dci < 32); - if (Dci > MaxDci) { - MaxDci = Dci; - } - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 1) Stop any Running Transfer Rings affected by the Alternate Interface setting. - // - Status = XhcStopEndpoint (Xhc, SlotId, Dci); - if (EFI_ERROR (Status)) { - return Status; - } - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 2) Free Transfer Rings of all endpoints that will be affected by the Alternate Interface setting. - // - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] != NULL) { - RingSeg = ((TRANSFER_RING *)(UINTN)Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1])->RingSeg0; - if (RingSeg != NULL) { - UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER); - } - FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1]); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci - 1] = NULL; - } - - // - // Set the Drop Context flag to '1'. - // - InputContext->InputControlContext.Dword1 |= (BIT0 << Dci); - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - } - - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 3) Clear all the Endpoint Context fields of each endpoint that will be disabled by the Alternate - // Interface setting, to '0'. - // - // The step 3) has been covered by the ZeroMem () to InputContext at the start of the function. - // - - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 4) For each endpoint enabled by the Configure Endpoint Command: - // a. Allocate a Transfer Ring. - // b. Initialize the Transfer Ring Segment(s) by clearing all fields of all TRBs to '0'. - // c. Initialize the Endpoint Context data structure. - // - Dci = XhcInitializeEndpointContext64 (Xhc, SlotId, DeviceSpeed, InputContext, IfDescSet); - if (Dci > MaxDci) { - MaxDci = Dci; - } - - InputContext->InputControlContext.Dword2 |= BIT0; - InputContext->Slot.ContextEntries = MaxDci; - // - // XHCI 4.3.6 - Setting Alternate Interfaces - // 5) Issue and successfully complete a Configure Endpoint Command. - // - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "SetInterface64: Configure Endpoint\n")); - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SetInterface64: Config Endpoint Failed, Status = %r\n", Status)); - } else { - // - // Update the active AlternateSetting. - // - Xhc->UsbDevContext[SlotId].ActiveAlternateSetting[(UINT8) Request->Index] = (UINT8) Request->Value; - } - } - - return Status; -} - -/** - Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be evaluated. - @param MaxPacketSize The max packet size supported by the device control transfer. - - @retval EFI_SUCCESS Successfully evaluate the device endpoint 0. - -**/ -EFI_STATUS -EFIAPI -XhcEvaluateContext ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT32 MaxPacketSize - ) -{ - EFI_STATUS Status; - CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT *InputContext; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); - - // - // 4.6.7 Evaluate Context - // - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - - InputContext->InputControlContext.Dword2 |= BIT1; - InputContext->EP[0].MaxPacketSize = MaxPacketSize; - - ZeroMem (&CmdTrbEvalu, sizeof (CmdTrbEvalu)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbEvalu.CycleBit = 1; - CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT; - CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "Evaluate context\n")); - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcEvaluateContext: Evaluate Context Failed, Status = %r\n", Status)); - } - return Status; -} - -/** - Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be evaluated. - @param MaxPacketSize The max packet size supported by the device control transfer. - - @retval EFI_SUCCESS Successfully evaluate the device endpoint 0. - -**/ -EFI_STATUS -EFIAPI -XhcEvaluateContext64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT32 MaxPacketSize - ) -{ - EFI_STATUS Status; - CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT_64 *InputContext; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); - - // - // 4.6.7 Evaluate Context - // - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - - InputContext->InputControlContext.Dword2 |= BIT1; - InputContext->EP[0].MaxPacketSize = MaxPacketSize; - - ZeroMem (&CmdTrbEvalu, sizeof (CmdTrbEvalu)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbEvalu.CycleBit = 1; - CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT; - CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "Evaluate context\n")); - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcEvaluateContext64: Evaluate Context Failed, Status = %r\n", Status)); - } - return Status; -} - - -/** - Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param PortNum The total number of downstream port supported by the hub. - @param TTT The TT think time of the hub device. - @param MTT The multi-TT of the hub device. - - @retval EFI_SUCCESS Successfully configure the hub device's slot context. - -**/ -EFI_STATUS -XhcConfigHubContext ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 PortNum, - IN UINT8 TTT, - IN UINT8 MTT - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputContext; - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - - // - // 4.6.7 Evaluate Context - // - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - - InputContext->InputControlContext.Dword2 |= BIT0; - - // - // Copy the slot context from OutputContext to Input context - // - CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT)); - InputContext->Slot.Hub = 1; - InputContext->Slot.PortNum = PortNum; - InputContext->Slot.TTT = TTT; - InputContext->Slot.MTT = MTT; - - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n")); - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcConfigHubContext: Config Endpoint Failed, Status = %r\n", Status)); - } - return Status; -} - -/** - Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param PortNum The total number of downstream port supported by the hub. - @param TTT The TT think time of the hub device. - @param MTT The multi-TT of the hub device. - - @retval EFI_SUCCESS Successfully configure the hub device's slot context. - -**/ -EFI_STATUS -XhcConfigHubContext64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 PortNum, - IN UINT8 TTT, - IN UINT8 MTT - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT_64 *InputContext; - DEVICE_CONTEXT_64 *OutputContext; - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - - // - // 4.6.7 Evaluate Context - // - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - - InputContext->InputControlContext.Dword2 |= BIT0; - - // - // Copy the slot context from OutputContext to Input context - // - CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT_64)); - InputContext->Slot.Hub = 1; - InputContext->Slot.PortNum = PortNum; - InputContext->Slot.TTT = TTT; - InputContext->Slot.MTT = MTT; - - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n")); - Status = XhcCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcConfigHubContext64: Config Endpoint Failed, Status = %r\n", Status)); - } - return Status; -} - - diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h deleted file mode 100644 index 931c7efa0c..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.h +++ /dev/null @@ -1,1461 +0,0 @@ -/** @file - - This file contains the definition for XHCI host controller schedule routines. - -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_XHCI_SCHED_H_ -#define _EFI_XHCI_SCHED_H_ - -#define XHC_URB_SIG SIGNATURE_32 ('U', 'S', 'B', 'R') - -// -// Transfer types, used in URB to identify the transfer type -// -#define XHC_CTRL_TRANSFER 0x01 -#define XHC_BULK_TRANSFER 0x02 -#define XHC_INT_TRANSFER_SYNC 0x04 -#define XHC_INT_TRANSFER_ASYNC 0x08 -#define XHC_INT_ONLY_TRANSFER_ASYNC 0x10 - -// -// 6.4.6 TRB Types -// -#define TRB_TYPE_NORMAL 1 -#define TRB_TYPE_SETUP_STAGE 2 -#define TRB_TYPE_DATA_STAGE 3 -#define TRB_TYPE_STATUS_STAGE 4 -#define TRB_TYPE_ISOCH 5 -#define TRB_TYPE_LINK 6 -#define TRB_TYPE_EVENT_DATA 7 -#define TRB_TYPE_NO_OP 8 -#define TRB_TYPE_EN_SLOT 9 -#define TRB_TYPE_DIS_SLOT 10 -#define TRB_TYPE_ADDRESS_DEV 11 -#define TRB_TYPE_CON_ENDPOINT 12 -#define TRB_TYPE_EVALU_CONTXT 13 -#define TRB_TYPE_RESET_ENDPOINT 14 -#define TRB_TYPE_STOP_ENDPOINT 15 -#define TRB_TYPE_SET_TR_DEQUE 16 -#define TRB_TYPE_RESET_DEV 17 -#define TRB_TYPE_GET_PORT_BANW 21 -#define TRB_TYPE_FORCE_HEADER 22 -#define TRB_TYPE_NO_OP_COMMAND 23 -#define TRB_TYPE_TRANS_EVENT 32 -#define TRB_TYPE_COMMAND_COMPLT_EVENT 33 -#define TRB_TYPE_PORT_STATUS_CHANGE_EVENT 34 -#define TRB_TYPE_HOST_CONTROLLER_EVENT 37 -#define TRB_TYPE_DEVICE_NOTIFI_EVENT 38 -#define TRB_TYPE_MFINDEX_WRAP_EVENT 39 - -// -// Endpoint Type (EP Type). -// -#define ED_NOT_VALID 0 -#define ED_ISOCH_OUT 1 -#define ED_BULK_OUT 2 -#define ED_INTERRUPT_OUT 3 -#define ED_CONTROL_BIDIR 4 -#define ED_ISOCH_IN 5 -#define ED_BULK_IN 6 -#define ED_INTERRUPT_IN 7 - -// -// 6.4.5 TRB Completion Codes -// -#define TRB_COMPLETION_INVALID 0 -#define TRB_COMPLETION_SUCCESS 1 -#define TRB_COMPLETION_DATA_BUFFER_ERROR 2 -#define TRB_COMPLETION_BABBLE_ERROR 3 -#define TRB_COMPLETION_USB_TRANSACTION_ERROR 4 -#define TRB_COMPLETION_TRB_ERROR 5 -#define TRB_COMPLETION_STALL_ERROR 6 -#define TRB_COMPLETION_SHORT_PACKET 13 - -// -// The topology string used to present usb device location -// -typedef struct _USB_DEV_TOPOLOGY { - // - // The tier concatenation of down stream port. - // - UINT32 RouteString:20; - // - // The root port number of the chain. - // - UINT32 RootPortNum:8; - // - // The Tier the device reside. - // - UINT32 TierNum:4; -} USB_DEV_TOPOLOGY; - -// -// USB Device's RouteChart -// -typedef union _USB_DEV_ROUTE { - UINT32 Dword; - USB_DEV_TOPOLOGY Route; -} USB_DEV_ROUTE; - -// -// Endpoint address and its capabilities -// -typedef struct _USB_ENDPOINT { - // - // Store logical device address assigned by UsbBus - // It's because some XHCI host controllers may assign the same physcial device - // address for those devices inserted at different root port. - // - UINT8 BusAddr; - UINT8 DevAddr; - UINT8 EpAddr; - EFI_USB_DATA_DIRECTION Direction; - UINT8 DevSpeed; - UINTN MaxPacket; - UINTN Type; -} USB_ENDPOINT; - -// -// TRB Template -// -typedef struct _TRB_TEMPLATE { - UINT32 Parameter1; - - UINT32 Parameter2; - - UINT32 Status; - - UINT32 CycleBit:1; - UINT32 RsvdZ1:9; - UINT32 Type:6; - UINT32 Control:16; -} TRB_TEMPLATE; - -typedef struct _TRANSFER_RING { - VOID *RingSeg0; - UINTN TrbNumber; - TRB_TEMPLATE *RingEnqueue; - TRB_TEMPLATE *RingDequeue; - UINT32 RingPCS; -} TRANSFER_RING; - -typedef struct _EVENT_RING { - VOID *ERSTBase; - VOID *EventRingSeg0; - UINTN TrbNumber; - TRB_TEMPLATE *EventRingEnqueue; - TRB_TEMPLATE *EventRingDequeue; - UINT32 EventRingCCS; -} EVENT_RING; - -// -// URB (Usb Request Block) contains information for all kinds of -// usb requests. -// -typedef struct _URB { - UINT32 Signature; - LIST_ENTRY UrbList; - // - // Usb Device URB related information - // - USB_ENDPOINT Ep; - EFI_USB_DEVICE_REQUEST *Request; - VOID *Data; - UINTN DataLen; - VOID *DataPhy; - VOID *DataMap; - EFI_ASYNC_USB_TRANSFER_CALLBACK Callback; - VOID *Context; - // - // Execute result - // - UINT32 Result; - // - // completed data length - // - UINTN Completed; - // - // Command/Tranfer Ring info - // - TRANSFER_RING *Ring; - TRB_TEMPLATE *TrbStart; - TRB_TEMPLATE *TrbEnd; - UINTN TrbNum; - BOOLEAN StartDone; - BOOLEAN EndDone; - BOOLEAN Finished; - - TRB_TEMPLATE *EvtTrb; -} URB; - -// -// 6.5 Event Ring Segment Table -// The Event Ring Segment Table is used to define multi-segment Event Rings and to enable runtime -// expansion and shrinking of the Event Ring. The location of the Event Ring Segment Table is defined by the -// Event Ring Segment Table Base Address Register (5.5.2.3.2). The size of the Event Ring Segment Table -// is defined by the Event Ring Segment Table Base Size Register (5.5.2.3.1). -// -typedef struct _EVENT_RING_SEG_TABLE_ENTRY { - UINT32 PtrLo; - UINT32 PtrHi; - UINT32 RingTrbSize:16; - UINT32 RsvdZ1:16; - UINT32 RsvdZ2; -} EVENT_RING_SEG_TABLE_ENTRY; - -// -// 6.4.1.1 Normal TRB -// A Normal TRB is used in several ways; exclusively on Bulk and Interrupt Transfer Rings for normal and -// Scatter/Gather operations, to define additional data buffers for Scatter/Gather operations on Isoch Transfer -// Rings, and to define the Data stage information for Control Transfer Rings. -// -typedef struct _TRANSFER_TRB_NORMAL { - UINT32 TRBPtrLo; - - UINT32 TRBPtrHi; - - UINT32 Length:17; - UINT32 TDSize:5; - UINT32 IntTarget:10; - - UINT32 CycleBit:1; - UINT32 ENT:1; - UINT32 ISP:1; - UINT32 NS:1; - UINT32 CH:1; - UINT32 IOC:1; - UINT32 IDT:1; - UINT32 RsvdZ1:2; - UINT32 BEI:1; - UINT32 Type:6; - UINT32 RsvdZ2:16; -} TRANSFER_TRB_NORMAL; - -// -// 6.4.1.2.1 Setup Stage TRB -// A Setup Stage TRB is created by system software to initiate a USB Setup packet on a control endpoint. -// -typedef struct _TRANSFER_TRB_CONTROL_SETUP { - UINT32 bmRequestType:8; - UINT32 bRequest:8; - UINT32 wValue:16; - - UINT32 wIndex:16; - UINT32 wLength:16; - - UINT32 Length:17; - UINT32 RsvdZ1:5; - UINT32 IntTarget:10; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:4; - UINT32 IOC:1; - UINT32 IDT:1; - UINT32 RsvdZ3:3; - UINT32 Type:6; - UINT32 TRT:2; - UINT32 RsvdZ4:14; -} TRANSFER_TRB_CONTROL_SETUP; - -// -// 6.4.1.2.2 Data Stage TRB -// A Data Stage TRB is used generate the Data stage transaction of a USB Control transfer. -// -typedef struct _TRANSFER_TRB_CONTROL_DATA { - UINT32 TRBPtrLo; - - UINT32 TRBPtrHi; - - UINT32 Length:17; - UINT32 TDSize:5; - UINT32 IntTarget:10; - - UINT32 CycleBit:1; - UINT32 ENT:1; - UINT32 ISP:1; - UINT32 NS:1; - UINT32 CH:1; - UINT32 IOC:1; - UINT32 IDT:1; - UINT32 RsvdZ1:3; - UINT32 Type:6; - UINT32 DIR:1; - UINT32 RsvdZ2:15; -} TRANSFER_TRB_CONTROL_DATA; - -// -// 6.4.1.2.2 Data Stage TRB -// A Data Stage TRB is used generate the Data stage transaction of a USB Control transfer. -// -typedef struct _TRANSFER_TRB_CONTROL_STATUS { - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 RsvdZ3:22; - UINT32 IntTarget:10; - - UINT32 CycleBit:1; - UINT32 ENT:1; - UINT32 RsvdZ4:2; - UINT32 CH:1; - UINT32 IOC:1; - UINT32 RsvdZ5:4; - UINT32 Type:6; - UINT32 DIR:1; - UINT32 RsvdZ6:15; -} TRANSFER_TRB_CONTROL_STATUS; - -// -// 6.4.2.1 Transfer Event TRB -// A Transfer Event provides the completion status associated with a Transfer TRB. Refer to section 4.11.3.1 -// for more information on the use and operation of Transfer Events. -// -typedef struct _EVT_TRB_TRANSFER { - UINT32 TRBPtrLo; - - UINT32 TRBPtrHi; - - UINT32 Length:24; - UINT32 Completecode:8; - - UINT32 CycleBit:1; - UINT32 RsvdZ1:1; - UINT32 ED:1; - UINT32 RsvdZ2:7; - UINT32 Type:6; - UINT32 EndpointId:5; - UINT32 RsvdZ3:3; - UINT32 SlotId:8; -} EVT_TRB_TRANSFER; - -// -// 6.4.2.2 Command Completion Event TRB -// A Command Completion Event TRB shall be generated by the xHC when a command completes on the -// Command Ring. Refer to section 4.11.4 for more information on the use of Command Completion Events. -// -typedef struct _EVT_TRB_COMMAND_COMPLETION { - UINT32 TRBPtrLo; - - UINT32 TRBPtrHi; - - UINT32 RsvdZ2:24; - UINT32 Completecode:8; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 VFID:8; - UINT32 SlotId:8; -} EVT_TRB_COMMAND_COMPLETION; - -typedef union _TRB { - TRB_TEMPLATE TrbTemplate; - TRANSFER_TRB_NORMAL TrbNormal; - TRANSFER_TRB_CONTROL_SETUP TrbCtrSetup; - TRANSFER_TRB_CONTROL_DATA TrbCtrData; - TRANSFER_TRB_CONTROL_STATUS TrbCtrStatus; -} TRB; - -// -// 6.4.3.1 No Op Command TRB -// The No Op Command TRB provides a simple means for verifying the operation of the Command Ring -// mechanisms offered by the xHCI. -// -typedef struct _CMD_TRB_NO_OP { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 RsvdZ4:16; -} CMD_TRB_NO_OP; - -// -// 6.4.3.2 Enable Slot Command TRB -// The Enable Slot Command TRB causes the xHC to select an available Device Slot and return the ID of the -// selected slot to the host in a Command Completion Event. -// -typedef struct _CMD_TRB_ENABLE_SLOT { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 RsvdZ4:16; -} CMD_TRB_ENABLE_SLOT; - -// -// 6.4.3.3 Disable Slot Command TRB -// The Disable Slot Command TRB releases any bandwidth assigned to the disabled slot and frees any -// internal xHC resources assigned to the slot. -// -typedef struct _CMD_TRB_DISABLE_SLOT { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 RsvdZ4:8; - UINT32 SlotId:8; -} CMD_TRB_DISABLE_SLOT; - -// -// 6.4.3.4 Address Device Command TRB -// The Address Device Command TRB transitions the selected Device Context from the Default to the -// Addressed state and causes the xHC to select an address for the USB device in the Default State and -// issue a SET_ADDRESS request to the USB device. -// -typedef struct _CMD_TRB_ADDRESS_DEVICE { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:8; - UINT32 BSR:1; - UINT32 Type:6; - UINT32 RsvdZ3:8; - UINT32 SlotId:8; -} CMD_TRB_ADDRESS_DEVICE; - -// -// 6.4.3.5 Configure Endpoint Command TRB -// The Configure Endpoint Command TRB evaluates the bandwidth and resource requirements of the -// endpoints selected by the command. -// -typedef struct _CMD_TRB_CONFIG_ENDPOINT { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:8; - UINT32 DC:1; - UINT32 Type:6; - UINT32 RsvdZ3:8; - UINT32 SlotId:8; -} CMD_TRB_CONFIG_ENDPOINT; - -// -// 6.4.3.6 Evaluate Context Command TRB -// The Evaluate Context Command TRB is used by system software to inform the xHC that the selected -// Context data structures in the Device Context have been modified by system software and that the xHC -// shall evaluate any changes -// -typedef struct _CMD_TRB_EVALUATE_CONTEXT { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:9; - UINT32 Type:6; - UINT32 RsvdZ3:8; - UINT32 SlotId:8; -} CMD_TRB_EVALUATE_CONTEXT; - -// -// 6.4.3.7 Reset Endpoint Command TRB -// The Reset Endpoint Command TRB is used by system software to reset a specified Transfer Ring -// -typedef struct _CMD_TRB_RESET_ENDPOINT { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:8; - UINT32 TSP:1; - UINT32 Type:6; - UINT32 EDID:5; - UINT32 RsvdZ4:3; - UINT32 SlotId:8; -} CMD_TRB_RESET_ENDPOINT; - -// -// 6.4.3.8 Stop Endpoint Command TRB -// The Stop Endpoint Command TRB command allows software to stop the xHC execution of the TDs on a -// Transfer Ring and temporarily take ownership of TDs that had previously been passed to the xHC. -// -typedef struct _CMD_TRB_STOP_ENDPOINT { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 EDID:5; - UINT32 RsvdZ4:2; - UINT32 SP:1; - UINT32 SlotId:8; -} CMD_TRB_STOP_ENDPOINT; - -// -// 6.4.3.9 Set TR Dequeue Pointer Command TRB -// The Set TR Dequeue Pointer Command TRB is used by system software to modify the TR Dequeue -// Pointer and DCS fields of an Endpoint or Stream Context. -// -typedef struct _CMD_SET_TR_DEQ_POINTER { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1:16; - UINT32 StreamID:16; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:9; - UINT32 Type:6; - UINT32 Endpoint:5; - UINT32 RsvdZ3:3; - UINT32 SlotId:8; -} CMD_SET_TR_DEQ_POINTER; - -// -// 6.4.4.1 Link TRB -// A Link TRB provides support for non-contiguous TRB Rings. -// -typedef struct _LINK_TRB { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1:22; - UINT32 InterTarget:10; - - UINT32 CycleBit:1; - UINT32 TC:1; - UINT32 RsvdZ2:2; - UINT32 CH:1; - UINT32 IOC:1; - UINT32 RsvdZ3:4; - UINT32 Type:6; - UINT32 RsvdZ4:16; -} LINK_TRB; - -// -// 6.2.2 Slot Context -// -typedef struct _SLOT_CONTEXT { - UINT32 RouteString:20; - UINT32 Speed:4; - UINT32 RsvdZ1:1; - UINT32 MTT:1; - UINT32 Hub:1; - UINT32 ContextEntries:5; - - UINT32 MaxExitLatency:16; - UINT32 RootHubPortNum:8; - UINT32 PortNum:8; - - UINT32 TTHubSlotId:8; - UINT32 TTPortNum:8; - UINT32 TTT:2; - UINT32 RsvdZ2:4; - UINT32 InterTarget:10; - - UINT32 DeviceAddress:8; - UINT32 RsvdZ3:19; - UINT32 SlotState:5; - - UINT32 RsvdZ4; - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; -} SLOT_CONTEXT; - -typedef struct _SLOT_CONTEXT_64 { - UINT32 RouteString:20; - UINT32 Speed:4; - UINT32 RsvdZ1:1; - UINT32 MTT:1; - UINT32 Hub:1; - UINT32 ContextEntries:5; - - UINT32 MaxExitLatency:16; - UINT32 RootHubPortNum:8; - UINT32 PortNum:8; - - UINT32 TTHubSlotId:8; - UINT32 TTPortNum:8; - UINT32 TTT:2; - UINT32 RsvdZ2:4; - UINT32 InterTarget:10; - - UINT32 DeviceAddress:8; - UINT32 RsvdZ3:19; - UINT32 SlotState:5; - - UINT32 RsvdZ4; - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; - - UINT32 RsvdZ8; - UINT32 RsvdZ9; - UINT32 RsvdZ10; - UINT32 RsvdZ11; - - UINT32 RsvdZ12; - UINT32 RsvdZ13; - UINT32 RsvdZ14; - UINT32 RsvdZ15; - -} SLOT_CONTEXT_64; - - -// -// 6.2.3 Endpoint Context -// -typedef struct _ENDPOINT_CONTEXT { - UINT32 EPState:3; - UINT32 RsvdZ1:5; - UINT32 Mult:2; - UINT32 MaxPStreams:5; - UINT32 LSA:1; - UINT32 Interval:8; - UINT32 RsvdZ2:8; - - UINT32 RsvdZ3:1; - UINT32 CErr:2; - UINT32 EPType:3; - UINT32 RsvdZ4:1; - UINT32 HID:1; - UINT32 MaxBurstSize:8; - UINT32 MaxPacketSize:16; - - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 AverageTRBLength:16; - UINT32 MaxESITPayload:16; - - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; -} ENDPOINT_CONTEXT; - -typedef struct _ENDPOINT_CONTEXT_64 { - UINT32 EPState:3; - UINT32 RsvdZ1:5; - UINT32 Mult:2; - UINT32 MaxPStreams:5; - UINT32 LSA:1; - UINT32 Interval:8; - UINT32 RsvdZ2:8; - - UINT32 RsvdZ3:1; - UINT32 CErr:2; - UINT32 EPType:3; - UINT32 RsvdZ4:1; - UINT32 HID:1; - UINT32 MaxBurstSize:8; - UINT32 MaxPacketSize:16; - - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 AverageTRBLength:16; - UINT32 MaxESITPayload:16; - - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; - - UINT32 RsvdZ8; - UINT32 RsvdZ9; - UINT32 RsvdZ10; - UINT32 RsvdZ11; - - UINT32 RsvdZ12; - UINT32 RsvdZ13; - UINT32 RsvdZ14; - UINT32 RsvdZ15; - -} ENDPOINT_CONTEXT_64; - - -// -// 6.2.5.1 Input Control Context -// -typedef struct _INPUT_CONTRL_CONTEXT { - UINT32 Dword1; - UINT32 Dword2; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - UINT32 RsvdZ3; - UINT32 RsvdZ4; - UINT32 RsvdZ5; - UINT32 RsvdZ6; -} INPUT_CONTRL_CONTEXT; - -typedef struct _INPUT_CONTRL_CONTEXT_64 { - UINT32 Dword1; - UINT32 Dword2; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - UINT32 RsvdZ3; - UINT32 RsvdZ4; - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; - UINT32 RsvdZ8; - UINT32 RsvdZ9; - UINT32 RsvdZ10; - UINT32 RsvdZ11; - UINT32 RsvdZ12; - UINT32 RsvdZ13; - UINT32 RsvdZ14; -} INPUT_CONTRL_CONTEXT_64; - -// -// 6.2.1 Device Context -// -typedef struct _DEVICE_CONTEXT { - SLOT_CONTEXT Slot; - ENDPOINT_CONTEXT EP[31]; -} DEVICE_CONTEXT; - -typedef struct _DEVICE_CONTEXT_64 { - SLOT_CONTEXT_64 Slot; - ENDPOINT_CONTEXT_64 EP[31]; -} DEVICE_CONTEXT_64; - -// -// 6.2.5 Input Context -// -typedef struct _INPUT_CONTEXT { - INPUT_CONTRL_CONTEXT InputControlContext; - SLOT_CONTEXT Slot; - ENDPOINT_CONTEXT EP[31]; -} INPUT_CONTEXT; - -typedef struct _INPUT_CONTEXT_64 { - INPUT_CONTRL_CONTEXT_64 InputControlContext; - SLOT_CONTEXT_64 Slot; - ENDPOINT_CONTEXT_64 EP[31]; -} INPUT_CONTEXT_64; - - -/** - Initialize the XHCI host controller for schedule. - - @param Xhc The XHCI Instance to be initialized. - -**/ -VOID -XhcInitSched ( - IN USB_XHCI_INSTANCE *Xhc - ); - -/** - Free the resouce allocated at initializing schedule. - - @param Xhc The XHCI Instance. - -**/ -VOID -XhcFreeSched ( - IN USB_XHCI_INSTANCE *Xhc - ); - -/** - Ring the door bell to notify XHCI there is a transaction to be executed through URB. - - @param Xhc The XHCI Instance. - @param Urb The URB to be rung. - - @retval EFI_SUCCESS Successfully ring the door bell. - -**/ -EFI_STATUS -RingIntTransferDoorBell ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ); - -/** - Execute the transfer by polling the URB. This is a synchronous operation. - - @param Xhc The XHCI Instance. - @param CmdTransfer The executed URB is for cmd transfer or not. - @param Urb The URB to execute. - @param Timeout The time to wait before abort, in millisecond. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -XhcExecTransfer ( - IN USB_XHCI_INSTANCE *Xhc, - IN BOOLEAN CmdTransfer, - IN URB *Urb, - IN UINTN Timeout - ); - -/** - Delete a single asynchronous interrupt transfer for - the device and endpoint. - - @param Xhc The XHCI Instance. - @param BusAddr The logical device address assigned by UsbBus driver. - @param EpNum The endpoint of the target. - - @retval EFI_SUCCESS An asynchronous transfer is removed. - @retval EFI_NOT_FOUND No transfer for the device is found. - -**/ -EFI_STATUS -XhciDelAsyncIntTransfer ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 BusAddr, - IN UINT8 EpNum - ); - -/** - Remove all the asynchronous interrupt transfers. - - @param Xhc The XHCI Instance. - -**/ -VOID -XhciDelAllAsyncIntTransfers ( - IN USB_XHCI_INSTANCE *Xhc - ); - -/** - Set Bios Ownership - - @param Xhc The XHCI Instance. - -**/ -VOID -XhcSetBiosOwnership ( - IN USB_XHCI_INSTANCE *Xhc - ); - -/** - Clear Bios Ownership - - @param Xhc The XHCI Instance. - -**/ -VOID -XhcClearBiosOwnership ( - IN USB_XHCI_INSTANCE *Xhc - ); - -/** - Find out the slot id according to the device's route string. - - @param Xhc The XHCI Instance. - @param RouteString The route string described the device location. - - @return The slot id used by the device. - -**/ -UINT8 -EFIAPI -XhcRouteStringToSlotId ( - IN USB_XHCI_INSTANCE *Xhc, - IN USB_DEV_ROUTE RouteString - ); - -/** - Calculate the device context index by endpoint address and direction. - - @param EpAddr The target endpoint number. - @param Direction The direction of the target endpoint. - - @return The device context index of endpoint. - -**/ -UINT8 -XhcEndpointToDci ( - IN UINT8 EpAddr, - IN UINT8 Direction - ); - -/** - Ring the door bell to notify XHCI there is a transaction to be executed. - - @param Xhc The XHCI Instance. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - - @retval EFI_SUCCESS Successfully ring the door bell. - -**/ -EFI_STATUS -EFIAPI -XhcRingDoorBell ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ); - -/** - Interrupt transfer periodic check handler. - - @param Event Interrupt event. - @param Context Pointer to USB_XHCI_INSTANCE. - -**/ -VOID -EFIAPI -XhcMonitorAsyncRequests ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Monitor the port status change. Enable/Disable device slot if there is a device attached/detached. - - @param Xhc The XHCI Instance. - @param ParentRouteChart The route string pointed to the parent device if it exists. - @param Port The port to be polled. - @param PortState The port state. - - @retval EFI_SUCCESS Successfully enable/disable device slot according to port state. - @retval Others Should not appear. - -**/ -EFI_STATUS -EFIAPI -XhcPollPortStatusChange ( - IN USB_XHCI_INSTANCE *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT8 Port, - IN EFI_USB_PORT_STATUS *PortState - ); - -/** - Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param PortNum The total number of downstream port supported by the hub. - @param TTT The TT think time of the hub device. - @param MTT The multi-TT of the hub device. - - @retval EFI_SUCCESS Successfully configure the hub device's slot context. - -**/ -EFI_STATUS -XhcConfigHubContext ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 PortNum, - IN UINT8 TTT, - IN UINT8 MTT - ); - - -/** - Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param PortNum The total number of downstream port supported by the hub. - @param TTT The TT think time of the hub device. - @param MTT The multi-TT of the hub device. - - @retval EFI_SUCCESS Successfully configure the hub device's slot context. - -**/ -EFI_STATUS -XhcConfigHubContext64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 PortNum, - IN UINT8 TTT, - IN UINT8 MTT - ); - - -/** - Configure all the device endpoints through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - - @retval EFI_SUCCESS Successfully configure all the device endpoints. - -**/ -EFI_STATUS -EFIAPI -XhcSetConfigCmd ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc - ); - - -/** - Configure all the device endpoints through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - - @retval EFI_SUCCESS Successfully configure all the device endpoints. - -**/ -EFI_STATUS -EFIAPI -XhcSetConfigCmd64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc - ); - -/** - Set interface through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - @param Request USB device request to send. - - @retval EFI_SUCCESS Successfully set interface. - -**/ -EFI_STATUS -EFIAPI -XhcSetInterface ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc, - IN EFI_USB_DEVICE_REQUEST *Request - ); - -/** - Set interface through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - @param Request USB device request to send. - - @retval EFI_SUCCESS Successfully set interface. - -**/ -EFI_STATUS -EFIAPI -XhcSetInterface64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc, - IN EFI_USB_DEVICE_REQUEST *Request - ); - -/** - Find out the actual device address according to the requested device address from UsbBus. - - @param Xhc The XHCI Instance. - @param BusDevAddr The requested device address by UsbBus upper driver. - - @return The actual device address assigned to the device. - -**/ -UINT8 -EFIAPI -XhcBusDevAddrToSlotId ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 BusDevAddr - ); - -/** - Assign and initialize the device slot for a new device. - - @param Xhc The XHCI Instance. - @param ParentRouteChart The route string pointed to the parent device. - @param ParentPort The port at which the device is located. - @param RouteChart The route string pointed to the device. - @param DeviceSpeed The device speed. - - @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it. - -**/ -EFI_STATUS -EFIAPI -XhcInitializeDeviceSlot ( - IN USB_XHCI_INSTANCE *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT16 ParentPort, - IN USB_DEV_ROUTE RouteChart, - IN UINT8 DeviceSpeed - ); - -/** - Assign and initialize the device slot for a new device. - - @param Xhc The XHCI Instance. - @param ParentRouteChart The route string pointed to the parent device. - @param ParentPort The port at which the device is located. - @param RouteChart The route string pointed to the device. - @param DeviceSpeed The device speed. - - @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it. - -**/ -EFI_STATUS -EFIAPI -XhcInitializeDeviceSlot64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT16 ParentPort, - IN USB_DEV_ROUTE RouteChart, - IN UINT8 DeviceSpeed - ); - -/** - Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be evaluated. - @param MaxPacketSize The max packet size supported by the device control transfer. - - @retval EFI_SUCCESS Successfully evaluate the device endpoint 0. - -**/ -EFI_STATUS -EFIAPI -XhcEvaluateContext ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT32 MaxPacketSize - ); - - -/** - Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be evaluated. - @param MaxPacketSize The max packet size supported by the device control transfer. - - @retval EFI_SUCCESS Successfully evaluate the device endpoint 0. - -**/ -EFI_STATUS -EFIAPI -XhcEvaluateContext64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT32 MaxPacketSize - ); - - -/** - Disable the specified device slot. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be disabled. - - @retval EFI_SUCCESS Successfully disable the device slot. - -**/ -EFI_STATUS -EFIAPI -XhcDisableSlotCmd ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId - ); - - -/** - Disable the specified device slot. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be disabled. - - @retval EFI_SUCCESS Successfully disable the device slot. - -**/ -EFI_STATUS -EFIAPI -XhcDisableSlotCmd64 ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId - ); - - -/** - Synchronize the specified transfer ring to update the enqueue and dequeue pointer. - - @param Xhc The XHCI Instance. - @param TrsRing The transfer ring to sync. - - @retval EFI_SUCCESS The transfer ring is synchronized successfully. - -**/ -EFI_STATUS -EFIAPI -XhcSyncTrsRing ( - IN USB_XHCI_INSTANCE *Xhc, - TRANSFER_RING *TrsRing - ); - -/** - Synchronize the specified event ring to update the enqueue and dequeue pointer. - - @param Xhc The XHCI Instance. - @param EvtRing The event ring to sync. - - @retval EFI_SUCCESS The event ring is synchronized successfully. - -**/ -EFI_STATUS -EFIAPI -XhcSyncEventRing ( - IN USB_XHCI_INSTANCE *Xhc, - EVENT_RING *EvtRing - ); - -/** - Check if there is a new generated event. - - @param Xhc The XHCI Instance. - @param EvtRing The event ring to check. - @param NewEvtTrb The new event TRB found. - - @retval EFI_SUCCESS Found a new event TRB at the event ring. - @retval EFI_NOT_READY The event ring has no new event. - -**/ -EFI_STATUS -EFIAPI -XhcCheckNewEvent ( - IN USB_XHCI_INSTANCE *Xhc, - IN EVENT_RING *EvtRing, - OUT TRB_TEMPLATE **NewEvtTrb - ); - -/** - Create XHCI transfer ring. - - @param Xhc The XHCI Instance. - @param TrbNum The number of TRB in the ring. - @param TransferRing The created transfer ring. - -**/ -VOID -CreateTransferRing ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINTN TrbNum, - OUT TRANSFER_RING *TransferRing - ); - -/** - Create XHCI event ring. - - @param Xhc The XHCI Instance. - @param EventRing The created event ring. - -**/ -VOID -CreateEventRing ( - IN USB_XHCI_INSTANCE *Xhc, - OUT EVENT_RING *EventRing - ); - -/** - System software shall use a Reset Endpoint Command (section 4.11.4.7) to remove the Halted - condition in the xHC. After the successful completion of the Reset Endpoint Command, the Endpoint - Context is transitioned from the Halted to the Stopped state and the Transfer Ring of the endpoint is - reenabled. The next write to the Doorbell of the Endpoint will transition the Endpoint Context from the - Stopped to the Running state. - - @param Xhc The XHCI Instance. - @param Urb The urb which makes the endpoint halted. - - @retval EFI_SUCCESS The recovery is successful. - @retval Others Failed to recovery halted endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcRecoverHaltedEndpoint ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ); - -/** - System software shall use a Stop Endpoint Command (section 4.6.9) and the Set TR Dequeue Pointer - Command (section 4.6.10) to remove the timed-out TDs from the xHC transfer ring. The next write to - the Doorbell of the Endpoint will transition the Endpoint Context from the Stopped to the Running - state. - - @param Xhc The XHCI Instance. - @param Urb The urb which doesn't get completed in a specified timeout range. - - @retval EFI_SUCCESS The dequeuing of the TDs is successful. - @retval Others Failed to stop the endpoint and dequeue the TDs. - -**/ -EFI_STATUS -EFIAPI -XhcDequeueTrbFromEndpoint ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ); - -/** - Stop endpoint through XHCI's Stop_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param Dci The device context index of endpoint. - - @retval EFI_SUCCESS Stop endpoint successfully. - @retval Others Failed to stop endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcStopEndpoint ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ); - -/** - Reset endpoint through XHCI's Reset_Endpoint cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param Dci The device context index of endpoint. - - @retval EFI_SUCCESS Reset endpoint successfully. - @retval Others Failed to reset endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcResetEndpoint ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ); - -/** - Set transfer ring dequeue pointer through XHCI's Set_Tr_Dequeue_Pointer cmd. - - @param Xhc The XHCI Instance. - @param SlotId The slot id to be configured. - @param Dci The device context index of endpoint. - @param Urb The dequeue pointer of the transfer ring specified - by the urb to be updated. - - @retval EFI_SUCCESS Set transfer ring dequeue pointer succeeds. - @retval Others Failed to set transfer ring dequeue pointer. - -**/ -EFI_STATUS -EFIAPI -XhcSetTrDequeuePointer ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci, - IN URB *Urb - ); - -/** - Create a new URB for a new transaction. - - @param Xhc The XHCI Instance - @param DevAddr The device address - @param EpAddr Endpoint addrress - @param DevSpeed The device speed - @param MaxPacket The max packet length of the endpoint - @param Type The transaction type - @param Request The standard USB request for control transfer - @param Data The user data to transfer - @param DataLen The length of data buffer - @param Callback The function to call when data is transferred - @param Context The context to the callback - - @return Created URB or NULL - -**/ -URB* -XhcCreateUrb ( - IN USB_XHCI_INSTANCE *Xhc, - IN UINT8 DevAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINTN MaxPacket, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context - ); - -/** - Free an allocated URB. - - @param Xhc The XHCI device. - @param Urb The URB to free. - -**/ -VOID -XhcFreeUrb ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ); - -/** - Create a transfer TRB. - - @param Xhc The XHCI Instance - @param Urb The urb used to construct the transfer TRB. - - @return Created TRB or NULL - -**/ -EFI_STATUS -XhcCreateTransferTrb ( - IN USB_XHCI_INSTANCE *Xhc, - IN URB *Urb - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c b/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c deleted file mode 100644 index 663ba39d32..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.c +++ /dev/null @@ -1,662 +0,0 @@ -/** @file -PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -which is used to enable recovery function from USB Drivers. - -Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "XhcPeim.h" - -/** - Allocate a block of memory to be used by the buffer pool. - - @param Pages How many pages to allocate. - - @return Pointer to the allocated memory block or NULL if failed. - -**/ -USBHC_MEM_BLOCK * -UsbHcAllocMemBlock ( - IN UINTN Pages - ) -{ - USBHC_MEM_BLOCK *Block; - EFI_STATUS Status; - UINTN PageNumber; - EFI_PHYSICAL_ADDRESS TempPtr; - - PageNumber = EFI_SIZE_TO_PAGES (sizeof (USBHC_MEM_BLOCK)); - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - PageNumber, - &TempPtr - ); - - if (EFI_ERROR (Status)) { - return NULL; - } - ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (PageNumber)); - - // - // each bit in the bit array represents USBHC_MEM_UNIT - // bytes of memory in the memory block. - // - ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE); - - Block = (USBHC_MEM_BLOCK *) (UINTN) TempPtr; - Block->BufLen = EFI_PAGES_TO_SIZE (Pages); - Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8); - - PageNumber = EFI_SIZE_TO_PAGES (Block->BitsLen); - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - PageNumber, - &TempPtr - ); - - if (EFI_ERROR (Status)) { - return NULL; - } - ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (PageNumber)); - - Block->Bits = (UINT8 *) (UINTN) TempPtr; - - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - Pages, - &TempPtr - ); - if (EFI_ERROR (Status)) { - return NULL; - } - ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (Pages)); - - Block->BufHost = (UINT8 *) (UINTN) TempPtr;; - Block->Buf = (UINT8 *) (UINTN) TempPtr; - Block->Next = NULL; - - return Block; -} - -/** - Free the memory block from the memory pool. - - @param Pool The memory pool to free the block from. - @param Block The memory block to free. - -**/ -VOID -UsbHcFreeMemBlock ( - IN USBHC_MEM_POOL *Pool, - IN USBHC_MEM_BLOCK *Block - ) -{ - ASSERT ((Pool != NULL) && (Block != NULL)); - // - // No free memory in PEI. - // -} - -/** - Alloc some memory from the block. - - @param Block The memory block to allocate memory from. - @param Units Number of memory units to allocate. - - @return The pointer to the allocated memory. - If couldn't allocate the needed memory, the return value is NULL. - -**/ -VOID * -UsbHcAllocMemFromBlock ( - IN USBHC_MEM_BLOCK *Block, - IN UINTN Units - ) -{ - UINTN Byte; - UINT8 Bit; - UINTN StartByte; - UINT8 StartBit; - UINTN Available; - UINTN Count; - - ASSERT ((Block != 0) && (Units != 0)); - - StartByte = 0; - StartBit = 0; - Available = 0; - - for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) { - // - // If current bit is zero, the corresponding memory unit is - // available, otherwise we need to restart our searching. - // Available counts the consective number of zero bit. - // - if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) { - Available++; - - if (Available >= Units) { - break; - } - - NEXT_BIT (Byte, Bit); - } else { - NEXT_BIT (Byte, Bit); - - Available = 0; - StartByte = Byte; - StartBit = Bit; - } - } - - if (Available < Units) { - return NULL; - } - - // - // Mark the memory as allocated - // - Byte = StartByte; - Bit = StartBit; - - for (Count = 0; Count < Units; Count++) { - ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT; -} - -/** - Calculate the corresponding pci bus address according to the Mem parameter. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to host memory. - @param Size The size of the memory region. - - @return The pci memory address - -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetPciAddrForHostAddr ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINTN AllocSize; - EFI_PHYSICAL_ADDRESS PhyAddr; - UINTN Offset; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - - if (Mem == NULL) { - return 0; - } - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the allocated memory. - // - if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) { - break; - } - } - - ASSERT ((Block != NULL)); - // - // calculate the pci memory address for host memory address. - // - Offset = (UINT8 *) Mem - Block->BufHost; - PhyAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) (Block->Buf + Offset); - return PhyAddr; -} - -/** - Calculate the corresponding host address according to the pci address. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to pci memory. - @param Size The size of the memory region. - - @return The host memory address - -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetHostAddrForPciAddr ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINTN AllocSize; - EFI_PHYSICAL_ADDRESS HostAddr; - UINTN Offset; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - - if (Mem == NULL) { - return 0; - } - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the allocated memory. - // - if ((Block->Buf <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->Buf + Block->BufLen))) { - break; - } - } - - ASSERT ((Block != NULL)); - // - // calculate the host memory address for pci memory address. - // - Offset = (UINT8 *) Mem - Block->Buf; - HostAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) (Block->BufHost + Offset); - return HostAddr; -} - -/** - Insert the memory block to the pool's list of the blocks. - - @param Head The head of the memory pool's block list. - @param Block The memory block to insert. - -**/ -VOID -UsbHcInsertMemBlockToPool ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *Block - ) -{ - ASSERT ((Head != NULL) && (Block != NULL)); - Block->Next = Head->Next; - Head->Next = Block; -} - -/** - Is the memory block empty? - - @param Block The memory block to check. - - @retval TRUE The memory block is empty. - @retval FALSE The memory block isn't empty. - -**/ -BOOLEAN -UsbHcIsMemBlockEmpty ( - IN USBHC_MEM_BLOCK *Block - ) -{ - UINTN Index; - - for (Index = 0; Index < Block->BitsLen; Index++) { - if (Block->Bits[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - -/** - Unlink the memory block from the pool's list. - - @param Head The block list head of the memory's pool. - @param BlockToUnlink The memory block to unlink. - -**/ -VOID -UsbHcUnlinkMemBlock ( - IN USBHC_MEM_BLOCK *Head, - IN USBHC_MEM_BLOCK *BlockToUnlink - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT ((Head != NULL) && (BlockToUnlink != NULL)); - - for (Block = Head; Block != NULL; Block = Block->Next) { - if (Block->Next == BlockToUnlink) { - Block->Next = BlockToUnlink->Next; - BlockToUnlink->Next = NULL; - break; - } - } -} - -/** - Initialize the memory management pool for the host controller. - - @return Pointer to the allocated memory pool or NULL if failed. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - VOID - ) -{ - USBHC_MEM_POOL *Pool; - UINTN PageNumber; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS TempPtr; - - PageNumber = EFI_SIZE_TO_PAGES (sizeof (USBHC_MEM_POOL)); - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - PageNumber, - &TempPtr - ); - if (EFI_ERROR (Status)) { - return NULL; - } - ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (PageNumber)); - - Pool = (USBHC_MEM_POOL *) ((UINTN) TempPtr); - Pool->Head = UsbHcAllocMemBlock (USBHC_MEM_DEFAULT_PAGES); - - if (Pool->Head == NULL) { - // - // No free memory in PEI. - // - Pool = NULL; - } - - return Pool; -} - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - -**/ -VOID -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ) -{ - USBHC_MEM_BLOCK *Block; - - ASSERT (Pool->Head != NULL); - - // - // Unlink all the memory blocks from the pool, then free them. - // UsbHcUnlinkMemBlock can't be used to unlink and free the - // first block. - // - for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) { - //UsbHcUnlinkMemBlock (Pool->Head, Block); - UsbHcFreeMemBlock (Pool, Block); - } - - UsbHcFreeMemBlock (Pool, Pool->Head); -} - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - USBHC_MEM_BLOCK *NewBlock; - VOID *Mem; - UINTN AllocSize; - UINTN Pages; - - Mem = NULL; - AllocSize = USBHC_MEM_ROUND (Size); - Head = Pool->Head; - ASSERT (Head != NULL); - - // - // First check whether current memory blocks can satisfy the allocation. - // - for (Block = Head; Block != NULL; Block = Block->Next) { - Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - break; - } - } - - if (Mem != NULL) { - return Mem; - } - - // - // Create a new memory block if there is not enough memory - // in the pool. If the allocation size is larger than the - // default page number, just allocate a large enough memory - // block. Otherwise allocate default pages. - // - if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) { - Pages = EFI_SIZE_TO_PAGES (AllocSize); - } else { - Pages = USBHC_MEM_DEFAULT_PAGES; - } - NewBlock = UsbHcAllocMemBlock (Pages); - - if (NewBlock == NULL) { - return NULL; - } - - // - // Add the new memory block to the pool, then allocate memory from it - // - UsbHcInsertMemBlockToPool (Head, NewBlock); - Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT); - - if (Mem != NULL) { - ZeroMem (Mem, Size); - } - - return Mem; -} - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -{ - USBHC_MEM_BLOCK *Head; - USBHC_MEM_BLOCK *Block; - UINT8 *ToFree; - UINTN AllocSize; - UINTN Byte; - UINTN Bit; - UINTN Count; - - Head = Pool->Head; - AllocSize = USBHC_MEM_ROUND (Size); - ToFree = (UINT8 *) Mem; - - for (Block = Head; Block != NULL; Block = Block->Next) { - // - // scan the memory block list for the memory block that - // completely contains the memory to free. - // - if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) { - // - // compute the start byte and bit in the bit array - // - Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8; - Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8; - - // - // reset associated bits in bit arry - // - for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) { - ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)); - - Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit)); - NEXT_BIT (Byte, Bit); - } - - break; - } - } - - // - // If Block == NULL, it means that the current memory isn't - // in the host controller's pool. This is critical because - // the caller has passed in a wrong memory pointer - // - ASSERT (Block != NULL); - - // - // Release the current memory block if it is empty and not the head - // - if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) { - //UsbHcUnlinkMemBlock (Head, Block); - UsbHcFreeMemBlock (Pool, Block); - } -} - -/** - Allocates pages at a specified alignment. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param Pages The number of pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - @param HostAddress The system memory address to map to the PCI controller. - @param DeviceAddress The resulting map address for the bus master PCI controller to - use to access the hosts HostAddress. - - @retval EFI_SUCCESS Success to allocate aligned pages. - @retval EFI_INVALID_PARAMETER Pages or Alignment is not valid. - @retval EFI_OUT_OF_RESOURCES Do not have enough resources to allocate memory. - -**/ -EFI_STATUS -UsbHcAllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment, - OUT VOID **HostAddress, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if ((Alignment & (Alignment - 1)) != 0) { - return EFI_INVALID_PARAMETER; - } - - if (Pages == 0) { - return EFI_INVALID_PARAMETER; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - Pages, - &Memory - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask; - } else { - // - // Do not over-allocate pages in this case. - // - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - Pages, - &Memory - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - AlignedMemory = (UINTN) Memory; - } - - *HostAddress = (VOID *) AlignedMemory; - *DeviceAddress = (EFI_PHYSICAL_ADDRESS) AlignedMemory; - - return EFI_SUCCESS; -} - -/** - Frees memory that was allocated with UsbHcAllocateAlignedPages(). - - @param HostAddress The system memory address to map to the PCI controller. - @param Pages The number of pages to free. - -**/ -VOID -UsbHcFreeAlignedPages ( - IN VOID *HostAddress, - IN UINTN Pages - ) -{ - ASSERT (Pages != 0); - // - // No free memory in PEI. - // -} - diff --git a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h b/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h deleted file mode 100644 index c314e92004..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciPei/UsbHcMem.h +++ /dev/null @@ -1,142 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2014, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PEI_XHCI_MEM_H_ -#define _EFI_PEI_XHCI_MEM_H_ - -#include - -#define USBHC_MEM_DEFAULT_PAGES 16 - -typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK; - -struct _USBHC_MEM_BLOCK { - UINT8 *Bits; // Bit array to record which unit is allocated - UINTN BitsLen; - UINT8 *Buf; - UINT8 *BufHost; - UINTN BufLen; // Memory size in bytes - USBHC_MEM_BLOCK *Next; -}; - -// -// Memory allocation unit, must be 2^n, n>4 -// -#define USBHC_MEM_UNIT 64 - -#define USBHC_MEM_UNIT_MASK (USBHC_MEM_UNIT - 1) -#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK)) - -#define USB_HC_BIT(a) ((UINTN)(1 << (a))) - -#define USB_HC_BIT_IS_SET(Data, Bit) \ - ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit))) - -// -// Advance the byte and bit to the next bit, adjust byte accordingly. -// -#define NEXT_BIT(Byte, Bit) \ - do { \ - (Bit)++; \ - if ((Bit) > 7) { \ - (Byte)++; \ - (Bit) = 0; \ - } \ - } while (0) - -// -// USBHC_MEM_POOL is used to manage the memory used by USB -// host controller. XHCI requires the control memory and transfer -// data to be on the same 4G memory. -// -typedef struct _USBHC_MEM_POOL { - BOOLEAN Check4G; - UINT32 Which4G; - USBHC_MEM_BLOCK *Head; -} USBHC_MEM_POOL; - -/** - Calculate the corresponding pci bus address according to the Mem parameter. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to host memory. - @param Size The size of the memory region. - - @return The pci memory address - -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetPciAddrForHostAddr ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -/** - Calculate the corresponding host address according to the pci address. - - @param Pool The memory pool of the host controller. - @param Mem The pointer to pci memory. - @param Size The size of the memory region. - - @return The host memory address - -**/ -EFI_PHYSICAL_ADDRESS -UsbHcGetHostAddrForPciAddr ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ); - -/** - Allocates pages at a specified alignment. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param Pages The number of pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - @param HostAddress The system memory address to map to the PCI controller. - @param DeviceAddress The resulting map address for the bus master PCI controller to - use to access the hosts HostAddress. - - @retval EFI_SUCCESS Success to allocate aligned pages. - @retval EFI_INVALID_PARAMETER Pages or Alignment is not valid. - @retval EFI_OUT_OF_RESOURCES Do not have enough resources to allocate memory. - -**/ -EFI_STATUS -UsbHcAllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment, - OUT VOID **HostAddress, - OUT EFI_PHYSICAL_ADDRESS *DeviceAddress - ); - -/** - Frees memory that was allocated with UsbHcAllocateAlignedPages(). - - @param HostAddress The system memory address to map to the PCI controller. - @param Pages The number of pages to free. - -**/ -VOID -UsbHcFreeAlignedPages ( - IN VOID *HostAddress, - IN UINTN Pages - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c b/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c deleted file mode 100644 index eaea38d94d..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.c +++ /dev/null @@ -1,1534 +0,0 @@ -/** @file -PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -which is used to enable recovery function from USB Drivers. - -Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "XhcPeim.h" - -// -// Two arrays used to translate the XHCI port state (change) -// to the UEFI protocol's port state (change). -// -USB_PORT_STATE_MAP mUsbPortStateMap[] = { - {XHC_PORTSC_CCS, USB_PORT_STAT_CONNECTION}, - {XHC_PORTSC_PED, USB_PORT_STAT_ENABLE}, - {XHC_PORTSC_OCA, USB_PORT_STAT_OVERCURRENT}, - {XHC_PORTSC_PP, USB_PORT_STAT_POWER}, - {XHC_PORTSC_RESET, USB_PORT_STAT_RESET} -}; - -USB_PORT_STATE_MAP mUsbPortChangeMap[] = { - {XHC_PORTSC_CSC, USB_PORT_STAT_C_CONNECTION}, - {XHC_PORTSC_PEC, USB_PORT_STAT_C_ENABLE}, - {XHC_PORTSC_OCC, USB_PORT_STAT_C_OVERCURRENT}, - {XHC_PORTSC_PRC, USB_PORT_STAT_C_RESET} -}; - -USB_CLEAR_PORT_MAP mUsbClearPortChangeMap[] = { - {XHC_PORTSC_CSC, EfiUsbPortConnectChange}, - {XHC_PORTSC_PEC, EfiUsbPortEnableChange}, - {XHC_PORTSC_OCC, EfiUsbPortOverCurrentChange}, - {XHC_PORTSC_PRC, EfiUsbPortResetChange} -}; - -USB_PORT_STATE_MAP mUsbHubPortStateMap[] = { - {XHC_HUB_PORTSC_CCS, USB_PORT_STAT_CONNECTION}, - {XHC_HUB_PORTSC_PED, USB_PORT_STAT_ENABLE}, - {XHC_HUB_PORTSC_OCA, USB_PORT_STAT_OVERCURRENT}, - {XHC_HUB_PORTSC_PP, USB_PORT_STAT_POWER}, - {XHC_HUB_PORTSC_RESET, USB_PORT_STAT_RESET} -}; - -USB_PORT_STATE_MAP mUsbHubPortChangeMap[] = { - {XHC_HUB_PORTSC_CSC, USB_PORT_STAT_C_CONNECTION}, - {XHC_HUB_PORTSC_PEC, USB_PORT_STAT_C_ENABLE}, - {XHC_HUB_PORTSC_OCC, USB_PORT_STAT_C_OVERCURRENT}, - {XHC_HUB_PORTSC_PRC, USB_PORT_STAT_C_RESET} -}; - -USB_CLEAR_PORT_MAP mUsbHubClearPortChangeMap[] = { - {XHC_HUB_PORTSC_CSC, EfiUsbPortConnectChange}, - {XHC_HUB_PORTSC_PEC, EfiUsbPortEnableChange}, - {XHC_HUB_PORTSC_OCC, EfiUsbPortOverCurrentChange}, - {XHC_HUB_PORTSC_PRC, EfiUsbPortResetChange}, - {XHC_HUB_PORTSC_BHRC, Usb3PortBHPortResetChange} -}; - -/** - Read XHCI Operation register. - - @param Xhc The XHCI device. - @param Offset The operation register offset. - - @retval the register content read. - -**/ -UINT32 -XhcPeiReadOpReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - - ASSERT (Xhc->CapLength != 0); - - Data = MmioRead32 (Xhc->UsbHostControllerBaseAddress + Xhc->CapLength + Offset); - return Data; -} - -/** - Write the data to the XHCI operation register. - - @param Xhc The XHCI device. - @param Offset The operation register offset. - @param Data The data to write. - -**/ -VOID -XhcPeiWriteOpReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - ASSERT (Xhc->CapLength != 0); - - MmioWrite32 (Xhc->UsbHostControllerBaseAddress + Xhc->CapLength + Offset, Data); -} - -/** - Set one bit of the operational register while keeping other bits. - - @param Xhc The XHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcPeiSetOpRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = XhcPeiReadOpReg (Xhc, Offset); - Data |= Bit; - XhcPeiWriteOpReg (Xhc, Offset, Data); -} - -/** - Clear one bit of the operational register while keeping other bits. - - @param Xhc The XHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to clear. - -**/ -VOID -XhcPeiClearOpRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = XhcPeiReadOpReg (Xhc, Offset); - Data &= ~Bit; - XhcPeiWriteOpReg (Xhc, Offset, Data); -} - -/** - Wait the operation register's bit as specified by Bit - to become set (or clear). - - @param Xhc The XHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to wait for. - @param WaitToSet Wait the bit to set or clear. - @param Timeout The time to wait before abort (in millisecond, ms). - - @retval EFI_SUCCESS The bit successfully changed by host controller. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -XhcPeiWaitOpRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit, - IN BOOLEAN WaitToSet, - IN UINT32 Timeout - ) -{ - UINT64 Index; - - for (Index = 0; Index < Timeout * XHC_1_MILLISECOND; Index++) { - if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) { - return EFI_SUCCESS; - } - - MicroSecondDelay (XHC_1_MICROSECOND); - } - - return EFI_TIMEOUT; -} - -/** - Read XHCI capability register. - - @param Xhc The XHCI device. - @param Offset Capability register address. - - @retval the register content read. - -**/ -UINT32 -XhcPeiReadCapRegister ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - - Data = MmioRead32 (Xhc->UsbHostControllerBaseAddress + Offset); - - return Data; -} - -/** - Read XHCI door bell register. - - @param Xhc The XHCI device. - @param Offset The offset of the door bell register. - - @return The register content read - -**/ -UINT32 -XhcPeiReadDoorBellReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - - ASSERT (Xhc->DBOff != 0); - - Data = MmioRead32 (Xhc->UsbHostControllerBaseAddress + Xhc->DBOff + Offset); - - return Data; -} - -/** - Write the data to the XHCI door bell register. - - @param Xhc The XHCI device. - @param Offset The offset of the door bell register. - @param Data The data to write. - -**/ -VOID -XhcPeiWriteDoorBellReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - ASSERT (Xhc->DBOff != 0); - - MmioWrite32 (Xhc->UsbHostControllerBaseAddress + Xhc->DBOff + Offset, Data); -} - -/** - Read XHCI runtime register. - - @param Xhc The XHCI device. - @param Offset The offset of the runtime register. - - @return The register content read - -**/ -UINT32 -XhcPeiReadRuntimeReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset - ) -{ - UINT32 Data; - - ASSERT (Xhc->RTSOff != 0); - - Data = MmioRead32 (Xhc->UsbHostControllerBaseAddress + Xhc->RTSOff + Offset); - - return Data; -} - -/** - Write the data to the XHCI runtime register. - - @param Xhc The XHCI device. - @param Offset The offset of the runtime register. - @param Data The data to write. - -**/ -VOID -XhcPeiWriteRuntimeReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ) -{ - ASSERT (Xhc->RTSOff != 0); - - MmioWrite32 (Xhc->UsbHostControllerBaseAddress + Xhc->RTSOff + Offset, Data); -} - -/** - Set one bit of the runtime register while keeping other bits. - - @param Xhc The XHCI device. - @param Offset The offset of the runtime register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcPeiSetRuntimeRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = XhcPeiReadRuntimeReg (Xhc, Offset); - Data |= Bit; - XhcPeiWriteRuntimeReg (Xhc, Offset, Data); -} - -/** - Clear one bit of the runtime register while keeping other bits. - - @param Xhc The XHCI device. - @param Offset The offset of the runtime register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcPeiClearRuntimeRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ) -{ - UINT32 Data; - - Data = XhcPeiReadRuntimeReg (Xhc, Offset); - Data &= ~Bit; - XhcPeiWriteRuntimeReg (Xhc, Offset, Data); -} - -/** - Check whether Xhc is halted. - - @param Xhc The XHCI device. - - @retval TRUE The controller is halted. - @retval FALSE The controller isn't halted. - -**/ -BOOLEAN -XhcPeiIsHalt ( - IN PEI_XHC_DEV *Xhc - ) -{ - return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT); -} - -/** - Check whether system error occurred. - - @param Xhc The XHCI device. - - @retval TRUE System error happened. - @retval FALSE No system error. - -**/ -BOOLEAN -XhcPeiIsSysError ( - IN PEI_XHC_DEV *Xhc - ) -{ - return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE); -} - -/** - Reset the host controller. - - @param Xhc The XHCI device. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_TIMEOUT The transfer failed due to time out. - @retval Others Failed to reset the host. - -**/ -EFI_STATUS -XhcPeiResetHC ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - // - // Host can only be reset when it is halt. If not so, halt it - // - if (!XhcPeiIsHalt (Xhc)) { - Status = XhcPeiHaltHC (Xhc, Timeout); - - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - } - - XhcPeiSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET); - Status = XhcPeiWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout); -ON_EXIT: - DEBUG ((EFI_D_INFO, "XhcPeiResetHC: %r\n", Status)); - return Status; -} - -/** - Halt the host controller. - - @param Xhc The XHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_TIMEOUT Failed to halt the controller before Timeout. - @retval EFI_SUCCESS The XHCI is halt. - -**/ -EFI_STATUS -XhcPeiHaltHC ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - XhcPeiClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN); - Status = XhcPeiWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, TRUE, Timeout); - DEBUG ((EFI_D_INFO, "XhcPeiHaltHC: %r\n", Status)); - return Status; -} - -/** - Set the XHCI to run. - - @param Xhc The XHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_SUCCESS The XHCI is running. - @retval Others Failed to set the XHCI to run. - -**/ -EFI_STATUS -XhcPeiRunHC ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Timeout - ) -{ - EFI_STATUS Status; - - XhcPeiSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN); - Status = XhcPeiWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout); - DEBUG ((EFI_D_INFO, "XhcPeiRunHC: %r\n", Status)); - return Status; -} - -/** - Submits control transfer to a target USB device. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI. - @param DeviceAddress The target device address. - @param DeviceSpeed Target device speed. - @param MaximumPacketLength Maximum packet size the default control transfer - endpoint is capable of sending or receiving. - @param Request USB device request to send. - @param TransferDirection Specifies the data direction for the data stage. - @param Data Data buffer to be transmitted or received from USB device. - @param DataLength The size (in bytes) of the data buffer. - @param TimeOut Indicates the maximum timeout, in millisecond. - If Timeout is 0, then the caller must wait for the function - to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - @param Translator Transaction translator to be used by this device. - @param TransferResult Return the result of this control transfer. - - @retval EFI_SUCCESS Transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT Transfer failed due to timeout. - @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. - -**/ -EFI_STATUS -EFIAPI -XhcPeiControlTransfer ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 DeviceAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN EFI_USB_DEVICE_REQUEST *Request, - IN EFI_USB_DATA_DIRECTION TransferDirection, - IN OUT VOID *Data, - IN OUT UINTN *DataLength, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - PEI_XHC_DEV *Xhc; - URB *Urb; - UINT8 Endpoint; - UINT8 Index; - UINT8 DescriptorType; - UINT8 SlotId; - UINT8 TTT; - UINT8 MTT; - UINT32 MaxPacket0; - EFI_USB_HUB_DESCRIPTOR *HubDesc; - EFI_STATUS Status; - EFI_STATUS RecoveryStatus; - UINTN MapSize; - EFI_USB_PORT_STATUS PortStatus; - UINT32 State; - EFI_USB_DEVICE_REQUEST ClearPortRequest; - UINTN Len; - - // - // Validate parameters - // - if ((Request == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbDataIn) && - (TransferDirection != EfiUsbDataOut) && - (TransferDirection != EfiUsbNoData)) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection == EfiUsbNoData) && - ((Data != NULL) || (*DataLength != 0))) { - return EFI_INVALID_PARAMETER; - } - - if ((TransferDirection != EfiUsbNoData) && - ((Data == NULL) || (*DataLength == 0))) { - return EFI_INVALID_PARAMETER; - } - - if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) && - (MaximumPacketLength != 32) && (MaximumPacketLength != 64) && - (MaximumPacketLength != 512) - ) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_SUPER) && (MaximumPacketLength != 512)) { - return EFI_INVALID_PARAMETER; - } - - Xhc = PEI_RECOVERY_USB_XHC_DEV_FROM_THIS (This); - - Status = EFI_DEVICE_ERROR; - *TransferResult = EFI_USB_ERR_SYSTEM; - Len = 0; - - if (XhcPeiIsHalt (Xhc) || XhcPeiIsSysError (Xhc)) { - DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: HC is halted or has system error\n")); - goto ON_EXIT; - } - - // - // Check if the device is still enabled before every transaction. - // - SlotId = XhcPeiBusDevAddrToSlotId (Xhc, DeviceAddress); - if (SlotId == 0) { - goto ON_EXIT; - } - - // - // Hook the Set_Address request from UsbBus. - // According to XHCI 1.0 spec, the Set_Address request is replaced by XHCI's Address_Device cmd. - // - if ((Request->Request == USB_REQ_SET_ADDRESS) && - (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) { - // - // Reset the BusDevAddr field of all disabled entries in UsbDevContext array firstly. - // This way is used to clean the history to avoid using wrong device address afterwards. - // - for (Index = 0; Index < 255; Index++) { - if (!Xhc->UsbDevContext[Index + 1].Enabled && - (Xhc->UsbDevContext[Index + 1].SlotId == 0) && - (Xhc->UsbDevContext[Index + 1].BusDevAddr == (UINT8) Request->Value)) { - Xhc->UsbDevContext[Index + 1].BusDevAddr = 0; - } - } - - if (Xhc->UsbDevContext[SlotId].XhciDevAddr == 0) { - goto ON_EXIT; - } - // - // The actual device address has been assigned by XHCI during initializing the device slot. - // So we just need establish the mapping relationship between the device address requested from UsbBus - // and the actual device address assigned by XHCI. The following invocations through EFI_USB2_HC_PROTOCOL interface - // can find out the actual device address by it. - // - Xhc->UsbDevContext[SlotId].BusDevAddr = (UINT8) Request->Value; - Status = EFI_SUCCESS; - goto ON_EXIT; - } - - // - // Create a new URB, insert it into the asynchronous - // schedule list, then poll the execution status. - // Note that we encode the direction in address although default control - // endpoint is bidirectional. XhcPeiCreateUrb expects this - // combination of Ep addr and its direction. - // - Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0)); - Urb = XhcPeiCreateUrb ( - Xhc, - DeviceAddress, - Endpoint, - DeviceSpeed, - MaximumPacketLength, - XHC_CTRL_TRANSFER, - Request, - Data, - *DataLength, - NULL, - NULL - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: failed to create URB")); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = XhcPeiExecTransfer (Xhc, FALSE, Urb, TimeOut); - - // - // Get the status from URB. The result is updated in XhcPeiCheckUrbResult - // which is called by XhcPeiExecTransfer - // - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - - if (Status == EFI_TIMEOUT) { - // - // The transfer timed out. Abort the transfer by dequeueing of the TD. - // - RecoveryStatus = XhcPeiDequeueTrbFromEndpoint(Xhc, Urb); - if (EFI_ERROR(RecoveryStatus)) { - DEBUG((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiDequeueTrbFromEndpoint failed\n")); - } - goto FREE_URB; - } else { - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } else if (*TransferResult == EFI_USB_ERR_STALL) { - RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb); - if (EFI_ERROR (RecoveryStatus)) { - DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: XhcPeiRecoverHaltedEndpoint failed\n")); - } - Status = EFI_DEVICE_ERROR; - goto FREE_URB; - } else { - goto FREE_URB; - } - } - - // - // Hook Get_Descriptor request from UsbBus as we need evaluate context and configure endpoint. - // Hook Get_Status request form UsbBus as we need trace device attach/detach event happened at hub. - // Hook Set_Config request from UsbBus as we need configure device endpoint. - // - if ((Request->Request == USB_REQ_GET_DESCRIPTOR) && - ((Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE)) || - ((Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_DEVICE))))) { - DescriptorType = (UINT8) (Request->Value >> 8); - if ((DescriptorType == USB_DESC_TYPE_DEVICE) && ((*DataLength == sizeof (EFI_USB_DEVICE_DESCRIPTOR)) || ((DeviceSpeed == EFI_USB_SPEED_FULL) && (*DataLength == 8)))) { - ASSERT (Data != NULL); - // - // Store a copy of device scriptor as hub device need this info to configure endpoint. - // - CopyMem (&Xhc->UsbDevContext[SlotId].DevDesc, Data, *DataLength); - if (Xhc->UsbDevContext[SlotId].DevDesc.BcdUSB == 0x0300) { - // - // If it's a usb3.0 device, then its max packet size is a 2^n. - // - MaxPacket0 = 1 << Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0; - } else { - MaxPacket0 = Xhc->UsbDevContext[SlotId].DevDesc.MaxPacketSize0; - } - Xhc->UsbDevContext[SlotId].ConfDesc = AllocateZeroPool (Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations * sizeof (EFI_USB_CONFIG_DESCRIPTOR *)); - if (Xhc->UsbDevContext[SlotId].ConfDesc == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto FREE_URB; - } - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcPeiEvaluateContext (Xhc, SlotId, MaxPacket0); - } else { - Status = XhcPeiEvaluateContext64 (Xhc, SlotId, MaxPacket0); - } - } else if (DescriptorType == USB_DESC_TYPE_CONFIG) { - ASSERT (Data != NULL); - if (*DataLength == ((UINT16 *) Data)[1]) { - // - // Get configuration value from request, store the configuration descriptor for Configure_Endpoint cmd. - // - Index = (UINT8) Request->Value; - ASSERT (Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations); - Xhc->UsbDevContext[SlotId].ConfDesc[Index] = AllocateZeroPool (*DataLength); - if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto FREE_URB; - } - CopyMem (Xhc->UsbDevContext[SlotId].ConfDesc[Index], Data, *DataLength); - } - } else if (((DescriptorType == USB_DESC_TYPE_HUB) || - (DescriptorType == USB_DESC_TYPE_HUB_SUPER_SPEED)) && (*DataLength > 2)) { - ASSERT (Data != NULL); - HubDesc = (EFI_USB_HUB_DESCRIPTOR *) Data; - ASSERT (HubDesc->NumPorts <= 15); - // - // The bit 5,6 of HubCharacter field of Hub Descriptor is TTT. - // - TTT = (UINT8) ((HubDesc->HubCharacter & (BIT5 | BIT6)) >> 5); - if (Xhc->UsbDevContext[SlotId].DevDesc.DeviceProtocol == 2) { - // - // Don't support multi-TT feature for super speed hub now. - // - MTT = 0; - DEBUG ((EFI_D_ERROR, "XHCI: Don't support multi-TT feature for Hub now. (force to disable MTT)\n")); - } else { - MTT = 0; - } - - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcPeiConfigHubContext (Xhc, SlotId, HubDesc->NumPorts, TTT, MTT); - } else { - Status = XhcPeiConfigHubContext64 (Xhc, SlotId, HubDesc->NumPorts, TTT, MTT); - } - } - } else if ((Request->Request == USB_REQ_SET_CONFIG) && - (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, USB_TARGET_DEVICE))) { - // - // Hook Set_Config request from UsbBus as we need configure device endpoint. - // - for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) { - if (Xhc->UsbDevContext[SlotId].ConfDesc[Index]->ConfigurationValue == (UINT8)Request->Value) { - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcPeiSetConfigCmd (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Index]); - } else { - Status = XhcPeiSetConfigCmd64 (Xhc, SlotId, DeviceSpeed, Xhc->UsbDevContext[SlotId].ConfDesc[Index]); - } - break; - } - } - } else if ((Request->Request == USB_REQ_GET_STATUS) && - (Request->RequestType == USB_REQUEST_TYPE (EfiUsbDataIn, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER))) { - ASSERT (Data != NULL); - // - // Hook Get_Status request from UsbBus to keep track of the port status change. - // - State = *(UINT32 *) Data; - PortStatus.PortStatus = 0; - PortStatus.PortChangeStatus = 0; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - // - // For super speed hub, its bit10~12 presents the attached device speed. - // - if ((State & XHC_PORTSC_PS) >> 10 == 0) { - PortStatus.PortStatus |= USB_PORT_STAT_SUPER_SPEED; - } - } else { - // - // For high or full/low speed hub, its bit9~10 presents the attached device speed. - // - if (XHC_BIT_IS_SET (State, BIT9)) { - PortStatus.PortStatus |= USB_PORT_STAT_LOW_SPEED; - } else if (XHC_BIT_IS_SET (State, BIT10)) { - PortStatus.PortStatus |= USB_PORT_STAT_HIGH_SPEED; - } - } - - // - // Convert the XHCI port/port change state to UEFI status - // - MapSize = sizeof (mUsbHubPortStateMap) / sizeof (USB_PORT_STATE_MAP); - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbHubPortStateMap[Index].HwState)) { - PortStatus.PortStatus = (UINT16) (PortStatus.PortStatus | mUsbHubPortStateMap[Index].UefiState); - } - } - - MapSize = sizeof (mUsbHubPortChangeMap) / sizeof (USB_PORT_STATE_MAP); - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbHubPortChangeMap[Index].HwState)) { - PortStatus.PortChangeStatus = (UINT16) (PortStatus.PortChangeStatus | mUsbHubPortChangeMap[Index].UefiState); - } - } - - MapSize = sizeof (mUsbHubClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbHubClearPortChangeMap[Index].HwState)) { - ZeroMem (&ClearPortRequest, sizeof (EFI_USB_DEVICE_REQUEST)); - ClearPortRequest.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER); - ClearPortRequest.Request = (UINT8) USB_REQ_CLEAR_FEATURE; - ClearPortRequest.Value = mUsbHubClearPortChangeMap[Index].Selector; - ClearPortRequest.Index = Request->Index; - ClearPortRequest.Length = 0; - - XhcPeiControlTransfer ( - PeiServices, - This, - DeviceAddress, - DeviceSpeed, - MaximumPacketLength, - &ClearPortRequest, - EfiUsbNoData, - NULL, - &Len, - TimeOut, - Translator, - TransferResult - ); - } - } - - XhcPeiPollPortStatusChange (Xhc, Xhc->UsbDevContext[SlotId].RouteString, (UINT8)Request->Index, &PortStatus); - - *(UINT32 *) Data = *(UINT32 *) &PortStatus; - } - -FREE_URB: - XhcPeiFreeUrb (Xhc, Urb); - -ON_EXIT: - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); - } - - return Status; -} - -/** - Submits bulk transfer to a bulk endpoint of a USB device. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI. - @param DeviceAddress Target device address. - @param EndPointAddress Endpoint number and its direction in bit 7. - @param DeviceSpeed Device speed, Low speed device doesn't support - bulk transfer. - @param MaximumPacketLength Maximum packet size the endpoint is capable of - sending or receiving. - @param Data Array of pointers to the buffers of data to transmit - from or receive into. - @param DataLength The lenght of the data buffer. - @param DataToggle On input, the initial data toggle for the transfer; - On output, it is updated to to next data toggle to use of - the subsequent bulk transfer. - @param TimeOut Indicates the maximum time, in millisecond, which the - transfer is allowed to complete. - If Timeout is 0, then the caller must wait for the function - to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned. - @param Translator A pointr to the transaction translator data. - @param TransferResult A pointer to the detailed result information of the - bulk transfer. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. - @retval EFI_INVALID_PARAMETER Parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -EFIAPI -XhcPeiBulkTransfer ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 DeviceAddress, - IN UINT8 EndPointAddress, - IN UINT8 DeviceSpeed, - IN UINTN MaximumPacketLength, - IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], - IN OUT UINTN *DataLength, - IN OUT UINT8 *DataToggle, - IN UINTN TimeOut, - IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, - OUT UINT32 *TransferResult - ) -{ - PEI_XHC_DEV *Xhc; - URB *Urb; - UINT8 SlotId; - EFI_STATUS Status; - EFI_STATUS RecoveryStatus; - - // - // Validate the parameters - // - if ((DataLength == NULL) || (*DataLength == 0) || - (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((*DataToggle != 0) && (*DataToggle != 1)) { - return EFI_INVALID_PARAMETER; - } - - if ((DeviceSpeed == EFI_USB_SPEED_LOW) || - ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) || - ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 512)) || - ((DeviceSpeed == EFI_USB_SPEED_SUPER) && (MaximumPacketLength > 1024))) { - return EFI_INVALID_PARAMETER; - } - - Xhc = PEI_RECOVERY_USB_XHC_DEV_FROM_THIS (This); - - *TransferResult = EFI_USB_ERR_SYSTEM; - Status = EFI_DEVICE_ERROR; - - if (XhcPeiIsHalt (Xhc) || XhcPeiIsSysError (Xhc)) { - DEBUG ((EFI_D_ERROR, "XhcPeiBulkTransfer: HC is halted or has system error\n")); - goto ON_EXIT; - } - - // - // Check if the device is still enabled before every transaction. - // - SlotId = XhcPeiBusDevAddrToSlotId (Xhc, DeviceAddress); - if (SlotId == 0) { - goto ON_EXIT; - } - - // - // Create a new URB, insert it into the asynchronous - // schedule list, then poll the execution status. - // - Urb = XhcPeiCreateUrb ( - Xhc, - DeviceAddress, - EndPointAddress, - DeviceSpeed, - MaximumPacketLength, - XHC_BULK_TRANSFER, - NULL, - Data[0], - *DataLength, - NULL, - NULL - ); - - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "XhcPeiBulkTransfer: failed to create URB\n")); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = XhcPeiExecTransfer (Xhc, FALSE, Urb, TimeOut); - - *TransferResult = Urb->Result; - *DataLength = Urb->Completed; - - if (Status == EFI_TIMEOUT) { - // - // The transfer timed out. Abort the transfer by dequeueing of the TD. - // - RecoveryStatus = XhcPeiDequeueTrbFromEndpoint(Xhc, Urb); - if (EFI_ERROR(RecoveryStatus)) { - DEBUG((EFI_D_ERROR, "XhcPeiBulkTransfer: XhcPeiDequeueTrbFromEndpoint failed\n")); - } - } else { - if (*TransferResult == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } else if (*TransferResult == EFI_USB_ERR_STALL) { - RecoveryStatus = XhcPeiRecoverHaltedEndpoint(Xhc, Urb); - if (EFI_ERROR (RecoveryStatus)) { - DEBUG ((EFI_D_ERROR, "XhcPeiBulkTransfer: XhcPeiRecoverHaltedEndpoint failed\n")); - } - Status = EFI_DEVICE_ERROR; - } - } - - XhcPeiFreeUrb (Xhc, Urb); - -ON_EXIT: - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult)); - } - - return Status; -} - -/** - Retrieves the number of root hub ports. - - @param[in] PeiServices The pointer to the PEI Services Table. - @param[in] This The pointer to this instance of the - PEI_USB2_HOST_CONTROLLER_PPI. - @param[out] PortNumber The pointer to the number of the root hub ports. - - @retval EFI_SUCCESS The port number was retrieved successfully. - @retval EFI_INVALID_PARAMETER PortNumber is NULL. - -**/ -EFI_STATUS -EFIAPI -XhcPeiGetRootHubPortNumber ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - OUT UINT8 *PortNumber - ) -{ - PEI_XHC_DEV *XhcDev; - XhcDev = PEI_RECOVERY_USB_XHC_DEV_FROM_THIS (This); - - if (PortNumber == NULL) { - return EFI_INVALID_PARAMETER; - } - - *PortNumber = XhcDev->HcSParams1.Data.MaxPorts; - DEBUG ((EFI_D_INFO, "XhcPeiGetRootHubPortNumber: PortNumber = %x\n", *PortNumber)); - return EFI_SUCCESS; -} - -/** - Clears a feature for the specified root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI. - @param PortNumber Specifies the root hub port whose feature - is requested to be cleared. - @param PortFeature Indicates the feature selector associated with the - feature clear request. - - @retval EFI_SUCCESS The feature specified by PortFeature was cleared - for the USB root hub port specified by PortNumber. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - -**/ -EFI_STATUS -EFIAPI -XhcPeiClearRootHubPortFeature ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - PEI_XHC_DEV *Xhc; - UINT32 Offset; - UINT32 State; - EFI_STATUS Status; - - Xhc = PEI_RECOVERY_USB_XHC_DEV_FROM_THIS (This); - Status = EFI_SUCCESS; - - if (PortNumber >= Xhc->HcSParams1.Data.MaxPorts) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = (UINT32) (XHC_PORTSC_OFFSET + (0x10 * PortNumber)); - State = XhcPeiReadOpReg (Xhc, Offset); - DEBUG ((EFI_D_INFO, "XhcPeiClearRootHubPortFeature: Port: %x State: %x\n", PortNumber, State)); - - // - // Mask off the port status change bits, these bits are - // write clean bits - // - State &= ~ (BIT1 | BIT17 | BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23); - - switch (PortFeature) { - case EfiUsbPortEnable: - // - // Ports may only be enabled by the xHC. Software cannot enable a port by writing a '1' to this flag. - // A port may be disabled by software writing a '1' to this flag. - // - State |= XHC_PORTSC_PED; - State &= ~XHC_PORTSC_RESET; - XhcPeiWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortSuspend: - State |= XHC_PORTSC_LWS; - XhcPeiWriteOpReg (Xhc, Offset, State); - State &= ~XHC_PORTSC_PLS; - XhcPeiWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortReset: - // - // PORTSC_RESET BIT(4) bit is RW1S attribute, which means Write-1-to-set status: - // Register bits indicate status when read, a clear bit may be set by - // writing a '1'. Writing a '0' to RW1S bits has no effect. - // - break; - - case EfiUsbPortPower: - if (Xhc->HcCParams.Data.Ppc) { - // - // Port Power Control supported - // - State &= ~XHC_PORTSC_PP; - XhcPeiWriteOpReg (Xhc, Offset, State); - } - break; - - case EfiUsbPortOwner: - // - // XHCI root hub port don't has the owner bit, ignore the operation - // - break; - - case EfiUsbPortConnectChange: - // - // Clear connect status change - // - State |= XHC_PORTSC_CSC; - XhcPeiWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortEnableChange: - // - // Clear enable status change - // - State |= XHC_PORTSC_PEC; - XhcPeiWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortOverCurrentChange: - // - // Clear PortOverCurrent change - // - State |= XHC_PORTSC_OCC; - XhcPeiWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortResetChange: - // - // Clear Port Reset change - // - State |= XHC_PORTSC_PRC; - XhcPeiWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortSuspendChange: - // - // Not supported or not related operation - // - break; - - default: - Status = EFI_INVALID_PARAMETER; - break; - } - -ON_EXIT: - DEBUG ((EFI_D_INFO, "XhcPeiClearRootHubPortFeature: PortFeature: %x Status = %r\n", PortFeature, Status)); - return Status; -} - -/** - Sets a feature for the specified root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI - @param PortNumber Root hub port to set. - @param PortFeature Feature to set. - - @retval EFI_SUCCESS The feature specified by PortFeature was set. - @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -EFIAPI -XhcPeiSetRootHubPortFeature ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - IN EFI_USB_PORT_FEATURE PortFeature - ) -{ - PEI_XHC_DEV *Xhc; - UINT32 Offset; - UINT32 State; - EFI_STATUS Status; - - Xhc = PEI_RECOVERY_USB_XHC_DEV_FROM_THIS (This); - Status = EFI_SUCCESS; - - if (PortNumber >= Xhc->HcSParams1.Data.MaxPorts) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Offset = (UINT32) (XHC_PORTSC_OFFSET + (0x10 * PortNumber)); - State = XhcPeiReadOpReg (Xhc, Offset); - DEBUG ((EFI_D_INFO, "XhcPeiSetRootHubPortFeature: Port: %x State: %x\n", PortNumber, State)); - - // - // Mask off the port status change bits, these bits are - // write clean bits - // - State &= ~ (BIT1 | BIT17 | BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23); - - switch (PortFeature) { - case EfiUsbPortEnable: - // - // Ports may only be enabled by the xHC. Software cannot enable a port by writing a '1' to this flag. - // A port may be disabled by software writing a '1' to this flag. - // - break; - - case EfiUsbPortSuspend: - State |= XHC_PORTSC_LWS; - XhcPeiWriteOpReg (Xhc, Offset, State); - State &= ~XHC_PORTSC_PLS; - State |= (3 << 5) ; - XhcPeiWriteOpReg (Xhc, Offset, State); - break; - - case EfiUsbPortReset: - // - // Make sure Host Controller not halt before reset it - // - if (XhcPeiIsHalt (Xhc)) { - Status = XhcPeiRunHC (Xhc, XHC_GENERIC_TIMEOUT); - if (EFI_ERROR (Status)) { - break; - } - } - - // - // 4.3.1 Resetting a Root Hub Port - // 1) Write the PORTSC register with the Port Reset (PR) bit set to '1'. - // 2) Wait for a successful Port Status Change Event for the port, where the Port Reset Change (PRC) - // bit in the PORTSC field is set to '1'. - // - State |= XHC_PORTSC_RESET; - XhcPeiWriteOpReg (Xhc, Offset, State); - XhcPeiWaitOpRegBit(Xhc, Offset, XHC_PORTSC_PRC, TRUE, XHC_GENERIC_TIMEOUT); - break; - - case EfiUsbPortPower: - if (Xhc->HcCParams.Data.Ppc) { - // - // Port Power Control supported - // - State |= XHC_PORTSC_PP; - XhcPeiWriteOpReg (Xhc, Offset, State); - } - break; - - case EfiUsbPortOwner: - // - // XHCI root hub port don't has the owner bit, ignore the operation - // - break; - - default: - Status = EFI_INVALID_PARAMETER; - } - -ON_EXIT: - DEBUG ((EFI_D_INFO, "XhcPeiSetRootHubPortFeature: PortFeature: %x Status = %r\n", PortFeature, Status)); - return Status; -} - -/** - Retrieves the current status of a USB root hub port. - - @param PeiServices The pointer of EFI_PEI_SERVICES. - @param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI. - @param PortNumber The root hub port to retrieve the state from. - @param PortStatus Variable to receive the port state. - - @retval EFI_SUCCESS The status of the USB root hub port specified. - by PortNumber was returned in PortStatus. - @retval EFI_INVALID_PARAMETER PortNumber is invalid. - -**/ -EFI_STATUS -EFIAPI -XhcPeiGetRootHubPortStatus ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_USB2_HOST_CONTROLLER_PPI *This, - IN UINT8 PortNumber, - OUT EFI_USB_PORT_STATUS *PortStatus - ) -{ - PEI_XHC_DEV *Xhc; - UINT32 Offset; - UINT32 State; - UINTN Index; - UINTN MapSize; - USB_DEV_ROUTE ParentRouteChart; - - if (PortStatus == NULL) { - return EFI_INVALID_PARAMETER; - } - - Xhc = PEI_RECOVERY_USB_XHC_DEV_FROM_THIS (This); - - if (PortNumber >= Xhc->HcSParams1.Data.MaxPorts) { - return EFI_INVALID_PARAMETER; - } - - // - // Clear port status. - // - PortStatus->PortStatus = 0; - PortStatus->PortChangeStatus = 0; - - Offset = (UINT32) (XHC_PORTSC_OFFSET + (0x10 * PortNumber)); - State = XhcPeiReadOpReg (Xhc, Offset); - DEBUG ((EFI_D_INFO, "XhcPeiGetRootHubPortStatus: Port: %x State: %x\n", PortNumber, State)); - - // - // According to XHCI 1.0 spec, bit 10~13 of the root port status register identifies the speed of the attached device. - // - switch ((State & XHC_PORTSC_PS) >> 10) { - case 2: - PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED; - break; - - case 3: - PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED; - break; - - case 4: - PortStatus->PortStatus |= USB_PORT_STAT_SUPER_SPEED; - break; - - default: - break; - } - - // - // Convert the XHCI port/port change state to UEFI status - // - MapSize = sizeof (mUsbPortStateMap) / sizeof (USB_PORT_STATE_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) { - PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState); - } - } - // - // Bit5~8 reflects its current link state. - // - if ((State & XHC_PORTSC_PLS) >> 5 == 3) { - PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND; - } - - MapSize = sizeof (mUsbPortChangeMap) / sizeof (USB_PORT_STATE_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) { - PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState); - } - } - - MapSize = sizeof (mUsbClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP); - - for (Index = 0; Index < MapSize; Index++) { - if (XHC_BIT_IS_SET (State, mUsbClearPortChangeMap[Index].HwState)) { - XhcPeiClearRootHubPortFeature (PeiServices, This, PortNumber, (EFI_USB_PORT_FEATURE)mUsbClearPortChangeMap[Index].Selector); - } - } - - // - // Poll the root port status register to enable/disable corresponding device slot if there is a device attached/detached. - // For those devices behind hub, we get its attach/detach event by hooking Get_Port_Status request at control transfer for those hub. - // - ParentRouteChart.Dword = 0; - XhcPeiPollPortStatusChange (Xhc, ParentRouteChart, PortNumber, PortStatus); - - DEBUG ((EFI_D_INFO, "XhcPeiGetRootHubPortStatus: PortChangeStatus: %x PortStatus: %x\n", PortStatus->PortChangeStatus, PortStatus->PortStatus)); - return EFI_SUCCESS; -} - -/** - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCCESS PPI successfully installed. - -**/ -EFI_STATUS -EFIAPI -XhcPeimEntry ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - PEI_USB_CONTROLLER_PPI *UsbControllerPpi; - EFI_STATUS Status; - UINT8 Index; - UINTN ControllerType; - UINTN BaseAddress; - UINTN MemPages; - PEI_XHC_DEV *XhcDev; - EFI_PHYSICAL_ADDRESS TempPtr; - UINT32 PageSize; - - // - // Shadow this PEIM to run from memory. - // - if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { - return EFI_SUCCESS; - } - - Status = PeiServicesLocatePpi ( - &gPeiUsbControllerPpiGuid, - 0, - NULL, - (VOID **) &UsbControllerPpi - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - Index = 0; - while (TRUE) { - Status = UsbControllerPpi->GetUsbController ( - (EFI_PEI_SERVICES **) PeiServices, - UsbControllerPpi, - Index, - &ControllerType, - &BaseAddress - ); - // - // When status is error, it means no controller is found. - // - if (EFI_ERROR (Status)) { - break; - } - - // - // This PEIM is for XHC type controller. - // - if (ControllerType != PEI_XHCI_CONTROLLER) { - Index++; - continue; - } - - MemPages = EFI_SIZE_TO_PAGES (sizeof (PEI_XHC_DEV)); - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - MemPages, - &TempPtr - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - ZeroMem ((VOID *) (UINTN) TempPtr, EFI_PAGES_TO_SIZE (MemPages)); - XhcDev = (PEI_XHC_DEV *) ((UINTN) TempPtr); - - XhcDev->Signature = USB_XHC_DEV_SIGNATURE; - XhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress; - XhcDev->CapLength = (UINT8) (XhcPeiReadCapRegister (XhcDev, XHC_CAPLENGTH_OFFSET) & 0x0FF); - XhcDev->HcSParams1.Dword = XhcPeiReadCapRegister (XhcDev, XHC_HCSPARAMS1_OFFSET); - XhcDev->HcSParams2.Dword = XhcPeiReadCapRegister (XhcDev, XHC_HCSPARAMS2_OFFSET); - XhcDev->HcCParams.Dword = XhcPeiReadCapRegister (XhcDev, XHC_HCCPARAMS_OFFSET); - XhcDev->DBOff = XhcPeiReadCapRegister (XhcDev, XHC_DBOFF_OFFSET); - XhcDev->RTSOff = XhcPeiReadCapRegister (XhcDev, XHC_RTSOFF_OFFSET); - - // - // This PageSize field defines the page size supported by the xHC implementation. - // This xHC supports a page size of 2^(n+12) if bit n is Set. For example, - // if bit 0 is Set, the xHC supports 4k byte page sizes. - // - PageSize = XhcPeiReadOpReg (XhcDev, XHC_PAGESIZE_OFFSET) & XHC_PAGESIZE_MASK; - XhcDev->PageSize = 1 << (HighBitSet32 (PageSize) + 12); - - DEBUG ((EFI_D_INFO, "XhciPei: UsbHostControllerBaseAddress: %x\n", XhcDev->UsbHostControllerBaseAddress)); - DEBUG ((EFI_D_INFO, "XhciPei: CapLength: %x\n", XhcDev->CapLength)); - DEBUG ((EFI_D_INFO, "XhciPei: HcSParams1: %x\n", XhcDev->HcSParams1.Dword)); - DEBUG ((EFI_D_INFO, "XhciPei: HcSParams2: %x\n", XhcDev->HcSParams2.Dword)); - DEBUG ((EFI_D_INFO, "XhciPei: HcCParams: %x\n", XhcDev->HcCParams.Dword)); - DEBUG ((EFI_D_INFO, "XhciPei: DBOff: %x\n", XhcDev->DBOff)); - DEBUG ((EFI_D_INFO, "XhciPei: RTSOff: %x\n", XhcDev->RTSOff)); - DEBUG ((EFI_D_INFO, "XhciPei: PageSize: %x\n", XhcDev->PageSize)); - - XhcPeiResetHC (XhcDev, XHC_RESET_TIMEOUT); - ASSERT (XhcPeiIsHalt (XhcDev)); - - // - // Initialize the schedule - // - XhcPeiInitSched (XhcDev); - - // - // Start the Host Controller - // - XhcPeiRunHC (XhcDev, XHC_GENERIC_TIMEOUT); - - // - // Wait for root port state stable - // - MicroSecondDelay (XHC_ROOT_PORT_STATE_STABLE); - - XhcDev->Usb2HostControllerPpi.ControlTransfer = XhcPeiControlTransfer; - XhcDev->Usb2HostControllerPpi.BulkTransfer = XhcPeiBulkTransfer; - XhcDev->Usb2HostControllerPpi.GetRootHubPortNumber = XhcPeiGetRootHubPortNumber; - XhcDev->Usb2HostControllerPpi.GetRootHubPortStatus = XhcPeiGetRootHubPortStatus; - XhcDev->Usb2HostControllerPpi.SetRootHubPortFeature = XhcPeiSetRootHubPortFeature; - XhcDev->Usb2HostControllerPpi.ClearRootHubPortFeature = XhcPeiClearRootHubPortFeature; - - XhcDev->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); - XhcDev->PpiDescriptor.Guid = &gPeiUsb2HostControllerPpiGuid; - XhcDev->PpiDescriptor.Ppi = &XhcDev->Usb2HostControllerPpi; - - PeiServicesInstallPpi (&XhcDev->PpiDescriptor); - - Index++; - } - - return EFI_SUCCESS; -} - diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h b/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h deleted file mode 100644 index ccf4dc26e5..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciPei/XhcPeim.h +++ /dev/null @@ -1,239 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _RECOVERY_XHC_H_ -#define _RECOVERY_XHC_H_ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -typedef struct _PEI_XHC_DEV PEI_XHC_DEV; -typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT; - -#include "UsbHcMem.h" -#include "XhciReg.h" -#include "XhciSched.h" - -#define CMD_RING_TRB_NUMBER 0x100 -#define TR_RING_TRB_NUMBER 0x100 -#define ERST_NUMBER 0x01 -#define EVENT_RING_TRB_NUMBER 0x200 - -#define XHC_1_MICROSECOND 1 -#define XHC_1_MILLISECOND (1000 * XHC_1_MICROSECOND) -#define XHC_1_SECOND (1000 * XHC_1_MILLISECOND) - -// -// XHC reset timeout experience values. -// The unit is millisecond, setting it as 1s. -// -#define XHC_RESET_TIMEOUT (1000) - -// -// Wait for root port state stable. -// -#define XHC_ROOT_PORT_STATE_STABLE (200 * XHC_1_MILLISECOND) - -// -// XHC generic timeout experience values. -// The unit is millisecond, setting it as 10s. -// -#define XHC_GENERIC_TIMEOUT (10 * 1000) - -#define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0XFFFFFFFF)) -#define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF)) -#define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit))) - -#define XHC_REG_BIT_IS_SET(XHC, Offset, Bit) \ - (XHC_BIT_IS_SET(XhcPeiReadOpReg ((XHC), (Offset)), (Bit))) - -#define USB_DESC_TYPE_HUB 0x29 -#define USB_DESC_TYPE_HUB_SUPER_SPEED 0x2a - -// -// The RequestType in EFI_USB_DEVICE_REQUEST is composed of -// three fields: One bit direction, 2 bit type, and 5 bit -// target. -// -#define USB_REQUEST_TYPE(Dir, Type, Target) \ - ((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target))) - -struct _USB_DEV_CONTEXT { - // - // Whether this entry in UsbDevContext array is used or not. - // - BOOLEAN Enabled; - // - // The slot id assigned to the new device through XHCI's Enable_Slot cmd. - // - UINT8 SlotId; - // - // The route string presented an attached usb device. - // - USB_DEV_ROUTE RouteString; - // - // The route string of parent device if it exists. Otherwise it's zero. - // - USB_DEV_ROUTE ParentRouteString; - // - // The actual device address assigned by XHCI through Address_Device command. - // - UINT8 XhciDevAddr; - // - // The requested device address from UsbBus driver through Set_Address standard usb request. - // As XHCI spec replaces this request with Address_Device command, we have to record the - // requested device address and establish a mapping relationship with the actual device address. - // Then UsbBus driver just need to be aware of the requested device address to access usb device - // through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual - // device address and access the actual device. - // - UINT8 BusDevAddr; - // - // The pointer to the input device context. - // - VOID *InputContext; - // - // The pointer to the output device context. - // - VOID *OutputContext; - // - // The transfer queue for every endpoint. - // - VOID *EndpointTransferRing[31]; - // - // The device descriptor which is stored to support XHCI's Evaluate_Context cmd. - // - EFI_USB_DEVICE_DESCRIPTOR DevDesc; - // - // As a usb device may include multiple configuration descriptors, we dynamically allocate an array - // to store them. - // Note that every configuration descriptor stored here includes those lower level descriptors, - // such as Interface descriptor, Endpoint descriptor, and so on. - // These information is used to support XHCI's Config_Endpoint cmd. - // - EFI_USB_CONFIG_DESCRIPTOR **ConfDesc; -}; - -#define USB_XHC_DEV_SIGNATURE SIGNATURE_32 ('x', 'h', 'c', 'i') - -struct _PEI_XHC_DEV { - UINTN Signature; - PEI_USB2_HOST_CONTROLLER_PPI Usb2HostControllerPpi; - EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; - UINT32 UsbHostControllerBaseAddress; - USBHC_MEM_POOL *MemPool; - - // - // XHCI configuration data - // - UINT8 CapLength; ///< Capability Register Length - XHC_HCSPARAMS1 HcSParams1; ///< Structural Parameters 1 - XHC_HCSPARAMS2 HcSParams2; ///< Structural Parameters 2 - XHC_HCCPARAMS HcCParams; ///< Capability Parameters - UINT32 DBOff; ///< Doorbell Offset - UINT32 RTSOff; ///< Runtime Register Space Offset - UINT32 PageSize; - UINT32 MaxScratchpadBufs; - UINT64 *ScratchBuf; - UINT64 *ScratchEntry; - UINT64 *DCBAA; - UINT32 MaxSlotsEn; - // - // Cmd Transfer Ring - // - TRANSFER_RING CmdRing; - // - // EventRing - // - EVENT_RING EventRing; - - // - // Store device contexts managed by XHCI device - // The array supports up to 255 devices, entry 0 is reserved and should not be used. - // - USB_DEV_CONTEXT UsbDevContext[256]; -}; - -#define PEI_RECOVERY_USB_XHC_DEV_FROM_THIS(a) CR (a, PEI_XHC_DEV, Usb2HostControllerPpi, USB_XHC_DEV_SIGNATURE) - -/** - Initialize the memory management pool for the host controller. - - @return Pointer to the allocated memory pool or NULL if failed. - -**/ -USBHC_MEM_POOL * -UsbHcInitMemPool ( - VOID - ) -; - -/** - Release the memory management pool. - - @param Pool The USB memory pool to free. - -**/ -VOID -UsbHcFreeMemPool ( - IN USBHC_MEM_POOL *Pool - ) -; - -/** - Allocate some memory from the host controller's memory pool - which can be used to communicate with host controller. - - @param Pool The host controller's memory pool. - @param Size Size of the memory to allocate. - - @return The allocated memory or NULL. - -**/ -VOID * -UsbHcAllocateMem ( - IN USBHC_MEM_POOL *Pool, - IN UINTN Size - ) -; - -/** - Free the allocated memory back to the memory pool. - - @param Pool The memory pool of the host controller. - @param Mem The memory to free. - @param Size The size of the memory to free. - -**/ -VOID -UsbHcFreeMem ( - IN USBHC_MEM_POOL *Pool, - IN VOID *Mem, - IN UINTN Size - ) -; - -#endif diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf b/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf deleted file mode 100644 index dc65f283bc..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.inf +++ /dev/null @@ -1,64 +0,0 @@ -## @file -# The XhcPeim driver is responsible for managing the behavior of XHCI controller at PEI phase. -# -# It produces gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -# which is used to enable recovery function from USB Drivers. -# -# Copyright (c) 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions -# of the BSD License which accompanies this distribution. The -# full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = XhciPei - MODULE_UNI_FILE = XhciPei.uni - FILE_GUID = 65E5746E-9C14-467d-B5B3-932A66D59F79 - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - ENTRY_POINT = XhcPeimEntry - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - XhcPeim.c - XhcPeim.h - XhciSched.c - UsbHcMem.c - XhciReg.h - XhciSched.h - UsbHcMem.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - IoLib - TimerLib - BaseMemoryLib - PeimEntryPoint - PeiServicesLib - MemoryAllocationLib - -[Ppis] - gPeiUsb2HostControllerPpiGuid ## PRODUCES - gPeiUsbControllerPpiGuid ## CONSUMES - -[Depex] - gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid - -[UserExtensions.TianoCore."ExtraFiles"] - XhciPeiExtra.uni diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.uni b/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.uni deleted file mode 100644 index 451007efb6..0000000000 Binary files a/MdeModulePkg/Bus/Pci/XhciPei/XhciPei.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciPeiExtra.uni b/MdeModulePkg/Bus/Pci/XhciPei/XhciPeiExtra.uni deleted file mode 100644 index d977f2f8c2..0000000000 Binary files a/MdeModulePkg/Bus/Pci/XhciPei/XhciPeiExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciReg.h b/MdeModulePkg/Bus/Pci/XhciPei/XhciReg.h deleted file mode 100644 index 1a62560665..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciPei/XhciReg.h +++ /dev/null @@ -1,471 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2014, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PEI_XHCI_REG_H_ -#define _EFI_PEI_XHCI_REG_H_ - -// -// Capability registers offset -// -#define XHC_CAPLENGTH_OFFSET 0x00 // Capability register length offset -#define XHC_HCIVERSION_OFFSET 0x02 // Interface Version Number 02-03h -#define XHC_HCSPARAMS1_OFFSET 0x04 // Structural Parameters 1 -#define XHC_HCSPARAMS2_OFFSET 0x08 // Structural Parameters 2 -#define XHC_HCSPARAMS3_OFFSET 0x0c // Structural Parameters 3 -#define XHC_HCCPARAMS_OFFSET 0x10 // Capability Parameters -#define XHC_DBOFF_OFFSET 0x14 // Doorbell Offset -#define XHC_RTSOFF_OFFSET 0x18 // Runtime Register Space Offset - -// -// Operational registers offset -// -#define XHC_USBCMD_OFFSET 0x0000 // USB Command Register Offset -#define XHC_USBSTS_OFFSET 0x0004 // USB Status Register Offset -#define XHC_PAGESIZE_OFFSET 0x0008 // USB Page Size Register Offset -#define XHC_DNCTRL_OFFSET 0x0014 // Device Notification Control Register Offset -#define XHC_CRCR_OFFSET 0x0018 // Command Ring Control Register Offset -#define XHC_DCBAAP_OFFSET 0x0030 // Device Context Base Address Array Pointer Register Offset -#define XHC_CONFIG_OFFSET 0x0038 // Configure Register Offset -#define XHC_PORTSC_OFFSET 0x0400 // Port Status and Control Register Offset - -// -// Runtime registers offset -// -#define XHC_MFINDEX_OFFSET 0x00 // Microframe Index Register Offset -#define XHC_IMAN_OFFSET 0x20 // Interrupter X Management Register Offset -#define XHC_IMOD_OFFSET 0x24 // Interrupter X Moderation Register Offset -#define XHC_ERSTSZ_OFFSET 0x28 // Event Ring Segment Table Size Register Offset -#define XHC_ERSTBA_OFFSET 0x30 // Event Ring Segment Table Base Address Register Offset -#define XHC_ERDP_OFFSET 0x38 // Event Ring Dequeue Pointer Register Offset - -// -// Register Bit Definition -// -#define XHC_USBCMD_RUN BIT0 // Run/Stop -#define XHC_USBCMD_RESET BIT1 // Host Controller Reset -#define XHC_USBCMD_INTE BIT2 // Interrupter Enable -#define XHC_USBCMD_HSEE BIT3 // Host System Error Enable - -#define XHC_USBSTS_HALT BIT0 // Host Controller Halted -#define XHC_USBSTS_HSE BIT2 // Host System Error -#define XHC_USBSTS_EINT BIT3 // Event Interrupt -#define XHC_USBSTS_PCD BIT4 // Port Change Detect -#define XHC_USBSTS_SSS BIT8 // Save State Status -#define XHC_USBSTS_RSS BIT9 // Restore State Status -#define XHC_USBSTS_SRE BIT10 // Save/Restore Error -#define XHC_USBSTS_CNR BIT11 // Host Controller Not Ready -#define XHC_USBSTS_HCE BIT12 // Host Controller Error - -#define XHC_PAGESIZE_MASK 0xFFFF // Page Size - -#define XHC_CRCR_RCS BIT0 // Ring Cycle State -#define XHC_CRCR_CS BIT1 // Command Stop -#define XHC_CRCR_CA BIT2 // Command Abort -#define XHC_CRCR_CRR BIT3 // Command Ring Running - -#define XHC_CONFIG_MASK 0xFF // Max Device Slots Enabled - -#define XHC_PORTSC_CCS BIT0 // Current Connect Status -#define XHC_PORTSC_PED BIT1 // Port Enabled/Disabled -#define XHC_PORTSC_OCA BIT3 // Over-current Active -#define XHC_PORTSC_RESET BIT4 // Port Reset -#define XHC_PORTSC_PLS (BIT5|BIT6|BIT7|BIT8) // Port Link State -#define XHC_PORTSC_PP BIT9 // Port Power -#define XHC_PORTSC_PS (BIT10|BIT11|BIT12) // Port Speed -#define XHC_PORTSC_LWS BIT16 // Port Link State Write Strobe -#define XHC_PORTSC_CSC BIT17 // Connect Status Change -#define XHC_PORTSC_PEC BIT18 // Port Enabled/Disabled Change -#define XHC_PORTSC_WRC BIT19 // Warm Port Reset Change -#define XHC_PORTSC_OCC BIT20 // Over-Current Change -#define XHC_PORTSC_PRC BIT21 // Port Reset Change -#define XHC_PORTSC_PLC BIT22 // Port Link State Change -#define XHC_PORTSC_CEC BIT23 // Port Config Error Change -#define XHC_PORTSC_CAS BIT24 // Cold Attach Status - -#define XHC_HUB_PORTSC_CCS BIT0 // Hub's Current Connect Status -#define XHC_HUB_PORTSC_PED BIT1 // Hub's Port Enabled/Disabled -#define XHC_HUB_PORTSC_OCA BIT3 // Hub's Over-current Active -#define XHC_HUB_PORTSC_RESET BIT4 // Hub's Port Reset -#define XHC_HUB_PORTSC_PP BIT9 // Hub's Port Power -#define XHC_HUB_PORTSC_CSC BIT16 // Hub's Connect Status Change -#define XHC_HUB_PORTSC_PEC BIT17 // Hub's Port Enabled/Disabled Change -#define XHC_HUB_PORTSC_OCC BIT19 // Hub's Over-Current Change -#define XHC_HUB_PORTSC_PRC BIT20 // Hub's Port Reset Change -#define XHC_HUB_PORTSC_BHRC BIT21 // Hub's Port Warm Reset Change - -#define XHC_IMAN_IP BIT0 // Interrupt Pending -#define XHC_IMAN_IE BIT1 // Interrupt Enable - -#define XHC_IMODI_MASK 0x0000FFFF // Interrupt Moderation Interval -#define XHC_IMODC_MASK 0xFFFF0000 // Interrupt Moderation Counter - - -#pragma pack (1) -typedef struct { - UINT8 MaxSlots; // Number of Device Slots - UINT16 MaxIntrs:11; // Number of Interrupters - UINT16 Rsvd:5; - UINT8 MaxPorts; // Number of Ports -} HCSPARAMS1; - -// -// Structural Parameters 1 Register Bitmap Definition -// -typedef union { - UINT32 Dword; - HCSPARAMS1 Data; -} XHC_HCSPARAMS1; - -typedef struct { - UINT32 Ist:4; // Isochronous Scheduling Threshold - UINT32 Erst:4; // Event Ring Segment Table Max - UINT32 Rsvd:13; - UINT32 ScratchBufHi:5; // Max Scratchpad Buffers Hi - UINT32 Spr:1; // Scratchpad Restore - UINT32 ScratchBufLo:5; // Max Scratchpad Buffers Lo -} HCSPARAMS2; - -// -// Structural Parameters 2 Register Bitmap Definition -// -typedef union { - UINT32 Dword; - HCSPARAMS2 Data; -} XHC_HCSPARAMS2; - -typedef struct { - UINT16 Ac64:1; // 64-bit Addressing Capability - UINT16 Bnc:1; // BW Negotiation Capability - UINT16 Csz:1; // Context Size - UINT16 Ppc:1; // Port Power Control - UINT16 Pind:1; // Port Indicators - UINT16 Lhrc:1; // Light HC Reset Capability - UINT16 Ltc:1; // Latency Tolerance Messaging Capability - UINT16 Nss:1; // No Secondary SID Support - UINT16 Pae:1; // Parse All Event Data - UINT16 Rsvd:3; - UINT16 MaxPsaSize:4; // Maximum Primary Stream Array Size - UINT16 ExtCapReg; // xHCI Extended Capabilities Pointer -} HCCPARAMS; - -// -// Capability Parameters Register Bitmap Definition -// -typedef union { - UINT32 Dword; - HCCPARAMS Data; -} XHC_HCCPARAMS; - -#pragma pack () - -// -// XHCi Data and Ctrl Structures -// -#pragma pack(1) -typedef struct { - UINT8 Pi; - UINT8 SubClassCode; - UINT8 BaseCode; -} USB_CLASSC; - -typedef struct { - UINT8 Length; - UINT8 DescType; - UINT8 NumPorts; - UINT16 HubCharacter; - UINT8 PwrOn2PwrGood; - UINT8 HubContrCurrent; - UINT8 Filler[16]; -} EFI_USB_HUB_DESCRIPTOR; -#pragma pack() - -// -// Hub Class Feature Selector for Clear Port Feature Request -// It's the extension of hub class feature selector of USB 2.0 in USB 3.0 Spec. -// For more details, Please refer to USB 3.0 Spec Table 10-7. -// -typedef enum { - Usb3PortBHPortReset = 28, - Usb3PortBHPortResetChange = 29 -} XHC_PORT_FEATURE; - -// -// Structure to map the hardware port states to the -// UEFI's port states. -// -typedef struct { - UINT32 HwState; - UINT16 UefiState; -} USB_PORT_STATE_MAP; - -// -// Structure to map the hardware port states to feature selector for clear port feature request. -// -typedef struct { - UINT32 HwState; - UINT16 Selector; -} USB_CLEAR_PORT_MAP; - -/** - Read XHCI Operation register. - - @param Xhc The XHCI device. - @param Offset The operation register offset. - - @retval the register content read. - -**/ -UINT32 -XhcPeiReadOpReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset - ); - -/** - Write the data to the XHCI operation register. - - @param Xhc The XHCI device. - @param Offset The operation register offset. - @param Data The data to write. - -**/ -VOID -XhcPeiWriteOpReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ); - -/** - Set one bit of the operational register while keeping other bits. - - @param Xhc The XHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcPeiSetOpRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Clear one bit of the operational register while keeping other bits. - - @param Xhc The XHCI device. - @param Offset The offset of the operational register. - @param Bit The bit mask of the register to clear. - -**/ -VOID -XhcPeiClearOpRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Wait the operation register's bit as specified by Bit - to be set (or clear). - - @param Xhc The XHCI device. - @param Offset The offset of the operational register. - @param Bit The bit of the register to wait for. - @param WaitToSet Wait the bit to set or clear. - @param Timeout The time to wait before abort (in microsecond, us). - - @retval EFI_SUCCESS The bit successfully changed by host controller. - @retval EFI_TIMEOUT The time out occurred. - -**/ -EFI_STATUS -XhcPeiWaitOpRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit, - IN BOOLEAN WaitToSet, - IN UINT32 Timeout - ); - -/** - Read XHCI door bell register. - - @param Xhc The XHCI device. - @param Offset The offset of the door bell register. - - @return The register content read - -**/ -UINT32 -XhcPeiReadDoorBellReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset - ); - -/** - Write the data to the XHCI door bell register. - - @param Xhc The XHCI device. - @param Offset The offset of the door bell register. - @param Data The data to write. - -**/ -VOID -XhcPeiWriteDoorBellReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ); - -/** - Read XHCI runtime register. - - @param Xhc The XHCI device. - @param Offset The offset of the runtime register. - - @return The register content read - -**/ -UINT32 -XhcPeiReadRuntimeReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset - ); - -/** - Write the data to the XHCI runtime register. - - @param Xhc The XHCI device. - @param Offset The offset of the runtime register. - @param Data The data to write. - -**/ -VOID -XhcPeiWriteRuntimeReg ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Data - ); - -/** - Set one bit of the runtime register while keeping other bits. - - @param Xhc The XHCI device. - @param Offset The offset of the runtime register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcPeiSetRuntimeRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Clear one bit of the runtime register while keeping other bits. - - @param Xhc The XHCI device. - @param Offset The offset of the runtime register. - @param Bit The bit mask of the register to set. - -**/ -VOID -XhcPeiClearRuntimeRegBit ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Offset, - IN UINT32 Bit - ); - -/** - Check whether Xhc is halted. - - @param Xhc The XHCI device. - - @retval TRUE The controller is halted. - @retval FALSE The controller isn't halted. - -**/ -BOOLEAN -XhcPeiIsHalt ( - IN PEI_XHC_DEV *Xhc - ); - -/** - Check whether system error occurred. - - @param Xhc The XHCI device. - - @retval TRUE System error happened. - @retval FALSE No system error. - -**/ -BOOLEAN -XhcPeiIsSysError ( - IN PEI_XHC_DEV *Xhc - ); - -/** - Reset the host controller. - - @param Xhc The XHCI device. - @param Timeout Time to wait before abort (in millisecond, ms). - - @retval EFI_TIMEOUT The transfer failed due to time out. - @retval Others Failed to reset the host. - -**/ -EFI_STATUS -XhcPeiResetHC ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Timeout - ); - -/** - Halt the host controller. - - @param Xhc The XHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_TIMEOUT Failed to halt the controller before Timeout. - @retval EFI_SUCCESS The XHCI is halt. - -**/ -EFI_STATUS -XhcPeiHaltHC ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Timeout - ); - -/** - Set the XHCI to run. - - @param Xhc The XHCI device. - @param Timeout Time to wait before abort. - - @retval EFI_SUCCESS The XHCI is running. - @retval Others Failed to set the XHCI to run. - -**/ -EFI_STATUS -XhcPeiRunHC ( - IN PEI_XHC_DEV *Xhc, - IN UINT32 Timeout - ); - -#endif diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c deleted file mode 100644 index 3632e8a769..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.c +++ /dev/null @@ -1,2963 +0,0 @@ -/** @file -PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid -which is used to enable recovery function from USB Drivers. - -Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "XhcPeim.h" - -/** - Create a command transfer TRB to support XHCI command interfaces. - - @param Xhc The XHCI device. - @param CmdTrb The cmd TRB to be executed. - - @return Created URB or NULL. - -**/ -URB* -XhcPeiCreateCmdTrb ( - IN PEI_XHC_DEV *Xhc, - IN TRB_TEMPLATE *CmdTrb - ) -{ - URB *Urb; - - Urb = AllocateZeroPool (sizeof (URB)); - if (Urb == NULL) { - return NULL; - } - - Urb->Signature = XHC_URB_SIG; - - Urb->Ring = &Xhc->CmdRing; - XhcPeiSyncTrsRing (Xhc, Urb->Ring); - Urb->TrbNum = 1; - Urb->TrbStart = Urb->Ring->RingEnqueue; - CopyMem (Urb->TrbStart, CmdTrb, sizeof (TRB_TEMPLATE)); - Urb->TrbStart->CycleBit = Urb->Ring->RingPCS & BIT0; - Urb->TrbEnd = Urb->TrbStart; - - return Urb; -} - -/** - Execute a XHCI cmd TRB pointed by CmdTrb. - - @param Xhc The XHCI device. - @param CmdTrb The cmd TRB to be executed. - @param Timeout Indicates the maximum time, in millisecond, which the - transfer is allowed to complete. - @param EvtTrb The event TRB corresponding to the cmd TRB. - - @retval EFI_SUCCESS The transfer was completed successfully. - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_TIMEOUT The transfer failed due to timeout. - @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. - -**/ -EFI_STATUS -XhcPeiCmdTransfer ( - IN PEI_XHC_DEV *Xhc, - IN TRB_TEMPLATE *CmdTrb, - IN UINTN Timeout, - OUT TRB_TEMPLATE **EvtTrb - ) -{ - EFI_STATUS Status; - URB *Urb; - - // - // Validate the parameters - // - if ((Xhc == NULL) || (CmdTrb == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_DEVICE_ERROR; - - if (XhcPeiIsHalt (Xhc) || XhcPeiIsSysError (Xhc)) { - DEBUG ((EFI_D_ERROR, "XhcPeiCmdTransfer: HC is halted or has system error\n")); - goto ON_EXIT; - } - - // - // Create a new URB, then poll the execution status. - // - Urb = XhcPeiCreateCmdTrb (Xhc, CmdTrb); - if (Urb == NULL) { - DEBUG ((EFI_D_ERROR, "XhcPeiCmdTransfer: failed to create URB\n")); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = XhcPeiExecTransfer (Xhc, TRUE, Urb, Timeout); - *EvtTrb = Urb->EvtTrb; - - if (Urb->Result == EFI_USB_NOERROR) { - Status = EFI_SUCCESS; - } - - XhcPeiFreeUrb (Xhc, Urb); - -ON_EXIT: - return Status; -} - -/** - Create a new URB for a new transaction. - - @param Xhc The XHCI device - @param BusAddr The logical device address assigned by UsbBus driver - @param EpAddr Endpoint addrress - @param DevSpeed The device speed - @param MaxPacket The max packet length of the endpoint - @param Type The transaction type - @param Request The standard USB request for control transfer - @param Data The user data to transfer - @param DataLen The length of data buffer - @param Callback The function to call when data is transferred - @param Context The context to the callback - - @return Created URB or NULL - -**/ -URB* -XhcPeiCreateUrb ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 BusAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINTN MaxPacket, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context - ) -{ - USB_ENDPOINT *Ep; - EFI_STATUS Status; - URB *Urb; - - Urb = AllocateZeroPool (sizeof (URB)); - if (Urb == NULL) { - return NULL; - } - - Urb->Signature = XHC_URB_SIG; - - Ep = &Urb->Ep; - Ep->BusAddr = BusAddr; - Ep->EpAddr = (UINT8) (EpAddr & 0x0F); - Ep->Direction = ((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut; - Ep->DevSpeed = DevSpeed; - Ep->MaxPacket = MaxPacket; - Ep->Type = Type; - - Urb->Request = Request; - Urb->Data = Data; - Urb->DataLen = DataLen; - Urb->Callback = Callback; - Urb->Context = Context; - - Status = XhcPeiCreateTransferTrb (Xhc, Urb); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiCreateUrb: XhcPeiCreateTransferTrb Failed, Status = %r\n", Status)); - FreePool (Urb); - Urb = NULL; - } - - return Urb; -} - -/** - Free an allocated URB. - - @param Xhc The XHCI device. - @param Urb The URB to free. - -**/ -VOID -XhcPeiFreeUrb ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ) -{ - if ((Xhc == NULL) || (Urb == NULL)) { - return; - } - - FreePool (Urb); -} - -/** - Create a transfer TRB. - - @param Xhc The XHCI device - @param Urb The urb used to construct the transfer TRB. - - @return Created TRB or NULL - -**/ -EFI_STATUS -XhcPeiCreateTransferTrb ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ) -{ - VOID *OutputContext; - TRANSFER_RING *EPRing; - UINT8 EPType; - UINT8 SlotId; - UINT8 Dci; - TRB *TrbStart; - UINTN TotalLen; - UINTN Len; - UINTN TrbNum; - - SlotId = XhcPeiBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - return EFI_DEVICE_ERROR; - } - - Urb->Finished = FALSE; - Urb->StartDone = FALSE; - Urb->EndDone = FALSE; - Urb->Completed = 0; - Urb->Result = EFI_USB_NOERROR; - - Dci = XhcPeiEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); - EPRing = (TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]; - Urb->Ring = EPRing; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - if (Xhc->HcCParams.Data.Csz == 0) { - EPType = (UINT8) ((DEVICE_CONTEXT *)OutputContext)->EP[Dci-1].EPType; - } else { - EPType = (UINT8) ((DEVICE_CONTEXT_64 *)OutputContext)->EP[Dci-1].EPType; - } - - Urb->DataPhy = Urb->Data; - - // - // Construct the TRB - // - XhcPeiSyncTrsRing (Xhc, EPRing); - Urb->TrbStart = EPRing->RingEnqueue; - switch (EPType) { - case ED_CONTROL_BIDIR: - // - // For control transfer, create SETUP_STAGE_TRB first. - // - TrbStart = (TRB *) (UINTN) EPRing->RingEnqueue; - TrbStart->TrbCtrSetup.bmRequestType = Urb->Request->RequestType; - TrbStart->TrbCtrSetup.bRequest = Urb->Request->Request; - TrbStart->TrbCtrSetup.wValue = Urb->Request->Value; - TrbStart->TrbCtrSetup.wIndex = Urb->Request->Index; - TrbStart->TrbCtrSetup.wLength = Urb->Request->Length; - TrbStart->TrbCtrSetup.Length = 8; - TrbStart->TrbCtrSetup.IntTarget = 0; - TrbStart->TrbCtrSetup.IOC = 1; - TrbStart->TrbCtrSetup.IDT = 1; - TrbStart->TrbCtrSetup.Type = TRB_TYPE_SETUP_STAGE; - if (Urb->Ep.Direction == EfiUsbDataIn) { - TrbStart->TrbCtrSetup.TRT = 3; - } else if (Urb->Ep.Direction == EfiUsbDataOut) { - TrbStart->TrbCtrSetup.TRT = 2; - } else { - TrbStart->TrbCtrSetup.TRT = 0; - } - // - // Update the cycle bit - // - TrbStart->TrbCtrSetup.CycleBit = EPRing->RingPCS & BIT0; - Urb->TrbNum++; - - // - // For control transfer, create DATA_STAGE_TRB. - // - if (Urb->DataLen > 0) { - XhcPeiSyncTrsRing (Xhc, EPRing); - TrbStart = (TRB *) (UINTN) EPRing->RingEnqueue; - TrbStart->TrbCtrData.TRBPtrLo = XHC_LOW_32BIT (Urb->DataPhy); - TrbStart->TrbCtrData.TRBPtrHi = XHC_HIGH_32BIT (Urb->DataPhy); - TrbStart->TrbCtrData.Length = (UINT32) Urb->DataLen; - TrbStart->TrbCtrData.TDSize = 0; - TrbStart->TrbCtrData.IntTarget = 0; - TrbStart->TrbCtrData.ISP = 1; - TrbStart->TrbCtrData.IOC = 1; - TrbStart->TrbCtrData.IDT = 0; - TrbStart->TrbCtrData.CH = 0; - TrbStart->TrbCtrData.Type = TRB_TYPE_DATA_STAGE; - if (Urb->Ep.Direction == EfiUsbDataIn) { - TrbStart->TrbCtrData.DIR = 1; - } else if (Urb->Ep.Direction == EfiUsbDataOut) { - TrbStart->TrbCtrData.DIR = 0; - } else { - TrbStart->TrbCtrData.DIR = 0; - } - // - // Update the cycle bit - // - TrbStart->TrbCtrData.CycleBit = EPRing->RingPCS & BIT0; - Urb->TrbNum++; - } - // - // For control transfer, create STATUS_STAGE_TRB. - // Get the pointer to next TRB for status stage use - // - XhcPeiSyncTrsRing (Xhc, EPRing); - TrbStart = (TRB *) (UINTN) EPRing->RingEnqueue; - TrbStart->TrbCtrStatus.IntTarget = 0; - TrbStart->TrbCtrStatus.IOC = 1; - TrbStart->TrbCtrStatus.CH = 0; - TrbStart->TrbCtrStatus.Type = TRB_TYPE_STATUS_STAGE; - if (Urb->Ep.Direction == EfiUsbDataIn) { - TrbStart->TrbCtrStatus.DIR = 0; - } else if (Urb->Ep.Direction == EfiUsbDataOut) { - TrbStart->TrbCtrStatus.DIR = 1; - } else { - TrbStart->TrbCtrStatus.DIR = 0; - } - // - // Update the cycle bit - // - TrbStart->TrbCtrStatus.CycleBit = EPRing->RingPCS & BIT0; - // - // Update the enqueue pointer - // - XhcPeiSyncTrsRing (Xhc, EPRing); - Urb->TrbNum++; - Urb->TrbEnd = (TRB_TEMPLATE *) (UINTN) TrbStart; - - break; - - case ED_BULK_OUT: - case ED_BULK_IN: - TotalLen = 0; - Len = 0; - TrbNum = 0; - TrbStart = (TRB *) (UINTN) EPRing->RingEnqueue; - while (TotalLen < Urb->DataLen) { - if ((TotalLen + 0x10000) >= Urb->DataLen) { - Len = Urb->DataLen - TotalLen; - } else { - Len = 0x10000; - } - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->DataPhy + TotalLen); - TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->DataPhy + TotalLen); - TrbStart->TrbNormal.Length = (UINT32) Len; - TrbStart->TrbNormal.TDSize = 0; - TrbStart->TrbNormal.IntTarget = 0; - TrbStart->TrbNormal.ISP = 1; - TrbStart->TrbNormal.IOC = 1; - TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL; - // - // Update the cycle bit - // - TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0; - - XhcPeiSyncTrsRing (Xhc, EPRing); - TrbNum++; - TotalLen += Len; - } - - Urb->TrbNum = TrbNum; - Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart; - break; - - case ED_INTERRUPT_OUT: - case ED_INTERRUPT_IN: - TotalLen = 0; - Len = 0; - TrbNum = 0; - TrbStart = (TRB *) (UINTN) EPRing->RingEnqueue; - while (TotalLen < Urb->DataLen) { - if ((TotalLen + 0x10000) >= Urb->DataLen) { - Len = Urb->DataLen - TotalLen; - } else { - Len = 0x10000; - } - TrbStart = (TRB *)(UINTN)EPRing->RingEnqueue; - TrbStart->TrbNormal.TRBPtrLo = XHC_LOW_32BIT((UINT8 *) Urb->DataPhy + TotalLen); - TrbStart->TrbNormal.TRBPtrHi = XHC_HIGH_32BIT((UINT8 *) Urb->DataPhy + TotalLen); - TrbStart->TrbNormal.Length = (UINT32) Len; - TrbStart->TrbNormal.TDSize = 0; - TrbStart->TrbNormal.IntTarget = 0; - TrbStart->TrbNormal.ISP = 1; - TrbStart->TrbNormal.IOC = 1; - TrbStart->TrbNormal.Type = TRB_TYPE_NORMAL; - // - // Update the cycle bit - // - TrbStart->TrbNormal.CycleBit = EPRing->RingPCS & BIT0; - - XhcPeiSyncTrsRing (Xhc, EPRing); - TrbNum++; - TotalLen += Len; - } - - Urb->TrbNum = TrbNum; - Urb->TrbEnd = (TRB_TEMPLATE *)(UINTN)TrbStart; - break; - - default: - DEBUG ((EFI_D_INFO, "Not supported EPType 0x%x!\n",EPType)); - ASSERT (FALSE); - break; - } - - return EFI_SUCCESS; -} - -/** - System software shall use a Reset Endpoint Command (section 4.11.4.7) to remove the Halted - condition in the xHC. After the successful completion of the Reset Endpoint Command, the Endpoint - Context is transitioned from the Halted to the Stopped state and the Transfer Ring of the endpoint is - reenabled. The next write to the Doorbell of the Endpoint will transition the Endpoint Context from the - Stopped to the Running state. - - @param Xhc The XHCI device. - @param Urb The urb which makes the endpoint halted. - - @retval EFI_SUCCESS The recovery is successful. - @retval Others Failed to recovery halted endpoint. - -**/ -EFI_STATUS -XhcPeiRecoverHaltedEndpoint ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ) -{ - EFI_STATUS Status; - UINT8 Dci; - UINT8 SlotId; - - Status = EFI_SUCCESS; - SlotId = XhcPeiBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - return EFI_DEVICE_ERROR; - } - Dci = XhcPeiEndpointToDci (Urb->Ep.EpAddr, (UINT8) (Urb->Ep.Direction)); - - DEBUG ((EFI_D_INFO, "XhcPeiRecoverHaltedEndpoint: Recovery Halted Slot = %x, Dci = %x\n", SlotId, Dci)); - - // - // 1) Send Reset endpoint command to transit from halt to stop state - // - Status = XhcPeiResetEndpoint (Xhc, SlotId, Dci); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiRecoverHaltedEndpoint: Reset Endpoint Failed, Status = %r\n", Status)); - goto Done; - } - - // - // 2) Set dequeue pointer - // - Status = XhcPeiSetTrDequeuePointer (Xhc, SlotId, Dci, Urb); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiRecoverHaltedEndpoint: Set Dequeue Pointer Failed, Status = %r\n", Status)); - goto Done; - } - - // - // 3) Ring the doorbell to transit from stop to active - // - XhcPeiRingDoorBell (Xhc, SlotId, Dci); - -Done: - return Status; -} - -/** - System software shall use a Stop Endpoint Command (section 4.6.9) and the Set TR Dequeue Pointer - Command (section 4.6.10) to remove the timed-out TDs from the xHC transfer ring. The next write to - the Doorbell of the Endpoint will transition the Endpoint Context from the Stopped to the Running - state. - - @param Xhc The XHCI device. - @param Urb The urb which doesn't get completed in a specified timeout range. - - @retval EFI_SUCCESS The dequeuing of the TDs is successful. - @retval Others Failed to stop the endpoint and dequeue the TDs. - -**/ -EFI_STATUS -XhcPeiDequeueTrbFromEndpoint ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ) -{ - EFI_STATUS Status; - UINT8 Dci; - UINT8 SlotId; - - Status = EFI_SUCCESS; - SlotId = XhcPeiBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - return EFI_DEVICE_ERROR; - } - Dci = XhcPeiEndpointToDci (Urb->Ep.EpAddr, (UINT8) (Urb->Ep.Direction)); - - DEBUG ((EFI_D_INFO, "XhcPeiDequeueTrbFromEndpoint: Stop Slot = %x, Dci = %x\n", SlotId, Dci)); - - // - // 1) Send Stop endpoint command to stop endpoint. - // - Status = XhcPeiStopEndpoint (Xhc, SlotId, Dci); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiDequeueTrbFromEndpoint: Stop Endpoint Failed, Status = %r\n", Status)); - goto Done; - } - - // - // 2) Set dequeue pointer - // - Status = XhcPeiSetTrDequeuePointer (Xhc, SlotId, Dci, Urb); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiDequeueTrbFromEndpoint: Set Dequeue Pointer Failed, Status = %r\n", Status)); - goto Done; - } - - // - // 3) Ring the doorbell to transit from stop to active - // - XhcPeiRingDoorBell (Xhc, SlotId, Dci); - -Done: - return Status; -} - -/** - Check if the Trb is a transaction of the URB. - - @param Trb The TRB to be checked - @param Urb The transfer ring to be checked. - - @retval TRUE It is a transaction of the URB. - @retval FALSE It is not any transaction of the URB. - -**/ -BOOLEAN -XhcPeiIsTransferRingTrb ( - IN TRB_TEMPLATE *Trb, - IN URB *Urb - ) -{ - TRB_TEMPLATE *CheckedTrb; - UINTN Index; - - CheckedTrb = Urb->Ring->RingSeg0; - - ASSERT (Urb->Ring->TrbNumber == CMD_RING_TRB_NUMBER || Urb->Ring->TrbNumber == TR_RING_TRB_NUMBER); - - for (Index = 0; Index < Urb->Ring->TrbNumber; Index++) { - if (Trb == CheckedTrb) { - return TRUE; - } - CheckedTrb++; - } - - return FALSE; -} - -/** - Check the URB's execution result and update the URB's - result accordingly. - - @param Xhc The XHCI device. - @param Urb The URB to check result. - - @return Whether the result of URB transfer is finialized. - -**/ -BOOLEAN -XhcPeiCheckUrbResult ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ) -{ - EVT_TRB_TRANSFER *EvtTrb; - TRB_TEMPLATE *TRBPtr; - UINTN Index; - UINT8 TRBType; - EFI_STATUS Status; - URB *CheckedUrb; - UINT64 XhcDequeue; - UINT32 High; - UINT32 Low; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT ((Xhc != NULL) && (Urb != NULL)); - - Status = EFI_SUCCESS; - - if (Urb->Finished) { - goto EXIT; - } - - EvtTrb = NULL; - - if (XhcPeiIsHalt (Xhc) || XhcPeiIsSysError (Xhc)) { - Urb->Result |= EFI_USB_ERR_SYSTEM; - goto EXIT; - } - - // - // Traverse the event ring to find out all new events from the previous check. - // - XhcPeiSyncEventRing (Xhc, &Xhc->EventRing); - for (Index = 0; Index < Xhc->EventRing.TrbNumber; Index++) { - Status = XhcPeiCheckNewEvent (Xhc, &Xhc->EventRing, ((TRB_TEMPLATE **) &EvtTrb)); - if (Status == EFI_NOT_READY) { - // - // All new events are handled, return directly. - // - goto EXIT; - } - - // - // Only handle COMMAND_COMPLETETION_EVENT and TRANSFER_EVENT. - // - if ((EvtTrb->Type != TRB_TYPE_COMMAND_COMPLT_EVENT) && (EvtTrb->Type != TRB_TYPE_TRANS_EVENT)) { - continue; - } - - // - // Need convert pci device address to host address - // - PhyAddr = (EFI_PHYSICAL_ADDRESS) (EvtTrb->TRBPtrLo | LShiftU64 ((UINT64) EvtTrb->TRBPtrHi, 32)); - TRBPtr = (TRB_TEMPLATE *) (UINTN) UsbHcGetHostAddrForPciAddr (Xhc->MemPool, (VOID *) (UINTN) PhyAddr, sizeof (TRB_TEMPLATE)); - - // - // Update the status of Urb according to the finished event regardless of whether - // the urb is current checked one or in the XHCI's async transfer list. - // This way is used to avoid that those completed async transfer events don't get - // handled in time and are flushed by newer coming events. - // - if (XhcPeiIsTransferRingTrb (TRBPtr, Urb)) { - CheckedUrb = Urb; - } else { - continue; - } - - switch (EvtTrb->Completecode) { - case TRB_COMPLETION_STALL_ERROR: - CheckedUrb->Result |= EFI_USB_ERR_STALL; - CheckedUrb->Finished = TRUE; - DEBUG ((EFI_D_ERROR, "XhcPeiCheckUrbResult: STALL_ERROR! Completecode = %x\n", EvtTrb->Completecode)); - goto EXIT; - - case TRB_COMPLETION_BABBLE_ERROR: - CheckedUrb->Result |= EFI_USB_ERR_BABBLE; - CheckedUrb->Finished = TRUE; - DEBUG ((EFI_D_ERROR, "XhcPeiCheckUrbResult: BABBLE_ERROR! Completecode = %x\n", EvtTrb->Completecode)); - goto EXIT; - - case TRB_COMPLETION_DATA_BUFFER_ERROR: - CheckedUrb->Result |= EFI_USB_ERR_BUFFER; - CheckedUrb->Finished = TRUE; - DEBUG ((EFI_D_ERROR, "XhcPeiCheckUrbResult: ERR_BUFFER! Completecode = %x\n", EvtTrb->Completecode)); - goto EXIT; - - case TRB_COMPLETION_USB_TRANSACTION_ERROR: - CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT; - CheckedUrb->Finished = TRUE; - DEBUG ((EFI_D_ERROR, "XhcPeiCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n", EvtTrb->Completecode)); - goto EXIT; - - case TRB_COMPLETION_SHORT_PACKET: - case TRB_COMPLETION_SUCCESS: - if (EvtTrb->Completecode == TRB_COMPLETION_SHORT_PACKET) { - DEBUG ((EFI_D_ERROR, "XhcPeiCheckUrbResult: short packet happens!\n")); - } - - TRBType = (UINT8) (TRBPtr->Type); - if ((TRBType == TRB_TYPE_DATA_STAGE) || - (TRBType == TRB_TYPE_NORMAL) || - (TRBType == TRB_TYPE_ISOCH)) { - CheckedUrb->Completed += (((TRANSFER_TRB_NORMAL*)TRBPtr)->Length - EvtTrb->Length); - } - - break; - - default: - DEBUG ((EFI_D_ERROR, "XhcPeiCheckUrbResult: Transfer Default Error Occur! Completecode = 0x%x!\n", EvtTrb->Completecode)); - CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT; - CheckedUrb->Finished = TRUE; - goto EXIT; - } - - // - // Only check first and end Trb event address - // - if (TRBPtr == CheckedUrb->TrbStart) { - CheckedUrb->StartDone = TRUE; - } - - if (TRBPtr == CheckedUrb->TrbEnd) { - CheckedUrb->EndDone = TRUE; - } - - if (CheckedUrb->StartDone && CheckedUrb->EndDone) { - CheckedUrb->Finished = TRUE; - CheckedUrb->EvtTrb = (TRB_TEMPLATE *) EvtTrb; - } - } - -EXIT: - - // - // Advance event ring to last available entry - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - Low = XhcPeiReadRuntimeReg (Xhc, XHC_ERDP_OFFSET); - High = XhcPeiReadRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4); - XhcDequeue = (UINT64) (LShiftU64((UINT64) High, 32) | Low); - - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->EventRing.EventRingDequeue, sizeof (TRB_TEMPLATE)); - - if ((XhcDequeue & (~0x0F)) != (PhyAddr & (~0x0F))) { - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - XhcPeiWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET, XHC_LOW_32BIT (PhyAddr) | BIT3); - XhcPeiWriteRuntimeReg (Xhc, XHC_ERDP_OFFSET + 4, XHC_HIGH_32BIT (PhyAddr)); - } - - return Urb->Finished; -} - -/** - Execute the transfer by polling the URB. This is a synchronous operation. - - @param Xhc The XHCI device. - @param CmdTransfer The executed URB is for cmd transfer or not. - @param Urb The URB to execute. - @param Timeout The time to wait before abort, in millisecond. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -XhcPeiExecTransfer ( - IN PEI_XHC_DEV *Xhc, - IN BOOLEAN CmdTransfer, - IN URB *Urb, - IN UINTN Timeout - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT64 Loop; - UINT8 SlotId; - UINT8 Dci; - BOOLEAN Finished; - - if (CmdTransfer) { - SlotId = 0; - Dci = 0; - } else { - SlotId = XhcPeiBusDevAddrToSlotId (Xhc, Urb->Ep.BusAddr); - if (SlotId == 0) { - return EFI_DEVICE_ERROR; - } - Dci = XhcPeiEndpointToDci (Urb->Ep.EpAddr, (UINT8)(Urb->Ep.Direction)); - } - - Status = EFI_SUCCESS; - Loop = Timeout * XHC_1_MILLISECOND; - if (Timeout == 0) { - Loop = 0xFFFFFFFF; - } - - XhcPeiRingDoorBell (Xhc, SlotId, Dci); - - for (Index = 0; Index < Loop; Index++) { - Finished = XhcPeiCheckUrbResult (Xhc, Urb); - if (Finished) { - break; - } - MicroSecondDelay (XHC_1_MICROSECOND); - } - - if (Index == Loop) { - Urb->Result = EFI_USB_ERR_TIMEOUT; - Status = EFI_TIMEOUT; - } else if (Urb->Result != EFI_USB_NOERROR) { - Status = EFI_DEVICE_ERROR; - } - - return Status; -} - -/** - Monitor the port status change. Enable/Disable device slot if there is a device attached/detached. - - @param Xhc The XHCI device. - @param ParentRouteChart The route string pointed to the parent device if it exists. - @param Port The port to be polled. - @param PortState The port state. - - @retval EFI_SUCCESS Successfully enable/disable device slot according to port state. - @retval Others Should not appear. - -**/ -EFI_STATUS -XhcPeiPollPortStatusChange ( - IN PEI_XHC_DEV *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT8 Port, - IN EFI_USB_PORT_STATUS *PortState - ) -{ - EFI_STATUS Status; - UINT8 Speed; - UINT8 SlotId; - USB_DEV_ROUTE RouteChart; - - DEBUG ((EFI_D_INFO, "XhcPeiPollPortStatusChange: PortChangeStatus: %x PortStatus: %x\n", PortState->PortChangeStatus, PortState->PortStatus)); - - Status = EFI_SUCCESS; - - if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) { - return EFI_SUCCESS; - } - - if (ParentRouteChart.Dword == 0) { - RouteChart.Route.RouteString = 0; - RouteChart.Route.RootPortNum = Port + 1; - RouteChart.Route.TierNum = 1; - } else { - if(Port < 14) { - RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (Port << (4 * (ParentRouteChart.Route.TierNum - 1))); - } else { - RouteChart.Route.RouteString = ParentRouteChart.Route.RouteString | (15 << (4 * (ParentRouteChart.Route.TierNum - 1))); - } - RouteChart.Route.RootPortNum = ParentRouteChart.Route.RootPortNum; - RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1; - } - - SlotId = XhcPeiRouteStringToSlotId (Xhc, RouteChart); - if (SlotId != 0) { - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcPeiDisableSlotCmd (Xhc, SlotId); - } else { - Status = XhcPeiDisableSlotCmd64 (Xhc, SlotId); - } - } - - if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) && - ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) != 0)) { - // - // Has a device attached, Identify device speed after port is enabled. - // - Speed = EFI_USB_SPEED_FULL; - if ((PortState->PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) { - Speed = EFI_USB_SPEED_LOW; - } else if ((PortState->PortStatus & USB_PORT_STAT_HIGH_SPEED) != 0) { - Speed = EFI_USB_SPEED_HIGH; - } else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0) { - Speed = EFI_USB_SPEED_SUPER; - } - // - // Execute Enable_Slot cmd for attached device, initialize device context and assign device address. - // - SlotId = XhcPeiRouteStringToSlotId (Xhc, RouteChart); - if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) { - if (Xhc->HcCParams.Data.Csz == 0) { - Status = XhcPeiInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed); - } else { - Status = XhcPeiInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed); - } - } - } - - return Status; -} - -/** - Calculate the device context index by endpoint address and direction. - - @param EpAddr The target endpoint number. - @param Direction The direction of the target endpoint. - - @return The device context index of endpoint. - -**/ -UINT8 -XhcPeiEndpointToDci ( - IN UINT8 EpAddr, - IN EFI_USB_DATA_DIRECTION Direction - ) -{ - UINT8 Index; - - ASSERT (EpAddr <= 15); - - if (EpAddr == 0) { - return 1; - } else { - Index = (UINT8) (2 * EpAddr); - if (Direction == EfiUsbDataIn) { - Index += 1; - } - return Index; - } -} - -/** - Find out the actual device address according to the requested device address from UsbBus. - - @param Xhc The XHCI device. - @param BusDevAddr The requested device address by UsbBus upper driver. - - @return The actual device address assigned to the device. - -**/ -UINT8 -XhcPeiBusDevAddrToSlotId ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 BusDevAddr - ) -{ - UINT8 Index; - - for (Index = 0; Index < 255; Index++) { - if (Xhc->UsbDevContext[Index + 1].Enabled && - (Xhc->UsbDevContext[Index + 1].SlotId != 0) && - (Xhc->UsbDevContext[Index + 1].BusDevAddr == BusDevAddr)) { - break; - } - } - - if (Index == 255) { - return 0; - } - - return Xhc->UsbDevContext[Index + 1].SlotId; -} - -/** - Find out the slot id according to the device's route string. - - @param Xhc The XHCI device. - @param RouteString The route string described the device location. - - @return The slot id used by the device. - -**/ -UINT8 -XhcPeiRouteStringToSlotId ( - IN PEI_XHC_DEV *Xhc, - IN USB_DEV_ROUTE RouteString - ) -{ - UINT8 Index; - - for (Index = 0; Index < 255; Index++) { - if (Xhc->UsbDevContext[Index + 1].Enabled && - (Xhc->UsbDevContext[Index + 1].SlotId != 0) && - (Xhc->UsbDevContext[Index + 1].RouteString.Dword == RouteString.Dword)) { - break; - } - } - - if (Index == 255) { - return 0; - } - - return Xhc->UsbDevContext[Index + 1].SlotId; -} - -/** - Ring the door bell to notify XHCI there is a transaction to be executed. - - @param Xhc The XHCI device. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - -**/ -VOID -XhcPeiRingDoorBell ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ) -{ - if (SlotId == 0) { - XhcPeiWriteDoorBellReg (Xhc, 0, 0); - } else { - XhcPeiWriteDoorBellReg (Xhc, SlotId * sizeof (UINT32), Dci); - } -} - -/** - Assign and initialize the device slot for a new device. - - @param Xhc The XHCI device. - @param ParentRouteChart The route string pointed to the parent device. - @param ParentPort The port at which the device is located. - @param RouteChart The route string pointed to the device. - @param DeviceSpeed The device speed. - - @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it. - @retval Others Fail to initialize device slot. - -**/ -EFI_STATUS -XhcPeiInitializeDeviceSlot ( - IN PEI_XHC_DEV *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT16 ParentPort, - IN USB_DEV_ROUTE RouteChart, - IN UINT8 DeviceSpeed - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputContext; - TRANSFER_RING *EndpointTransferRing; - CMD_TRB_ADDRESS_DEVICE CmdTrbAddr; - UINT8 DeviceAddress; - CMD_TRB_ENABLE_SLOT CmdTrb; - UINT8 SlotId; - UINT8 ParentSlotId; - DEVICE_CONTEXT *ParentDeviceContext; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT)); - CmdTrb.CycleBit = 1; - CmdTrb.Type = TRB_TYPE_EN_SLOT; - - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrb, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiInitializeDeviceSlot: Enable Slot Failed, Status = %r\n", Status)); - return Status; - } - ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn); - DEBUG ((EFI_D_INFO, "XhcPeiInitializeDeviceSlot: Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId)); - SlotId = (UINT8) EvtTrb->SlotId; - ASSERT (SlotId != 0); - - ZeroMem (&Xhc->UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT)); - Xhc->UsbDevContext[SlotId].Enabled = TRUE; - Xhc->UsbDevContext[SlotId].SlotId = SlotId; - Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword; - Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword; - - // - // 4.3.3 Device Slot Initialization - // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'. - // - InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT)); - ASSERT (InputContext != NULL); - ASSERT (((UINTN) InputContext & 0x3F) == 0); - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - - Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext; - - // - // 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1 - // flags to '1'. These flags indicate that the Slot Context and the Endpoint 0 Context of the Input - // Context are affected by the command. - // - InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1); - - // - // 3) Initialize the Input Slot Context data structure - // - InputContext->Slot.RouteString = RouteChart.Route.RouteString; - InputContext->Slot.Speed = DeviceSpeed + 1; - InputContext->Slot.ContextEntries = 1; - InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum; - - if (RouteChart.Route.RouteString != 0) { - // - // The device is behind of hub device. - // - ParentSlotId = XhcPeiRouteStringToSlotId (Xhc, ParentRouteChart); - ASSERT (ParentSlotId != 0); - // - // If the Full/Low device attached to a High Speed Hub, init the TTPortNum and TTHubSlotId field of slot context - // - ParentDeviceContext = (DEVICE_CONTEXT *) Xhc->UsbDevContext[ParentSlotId].OutputContext; - if ((ParentDeviceContext->Slot.TTPortNum == 0) && - (ParentDeviceContext->Slot.TTHubSlotId == 0)) { - if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) { - // - // Full/Low device attached to High speed hub port that isolates the high speed signaling - // environment from Full/Low speed signaling environment for a device - // - InputContext->Slot.TTPortNum = ParentPort; - InputContext->Slot.TTHubSlotId = ParentSlotId; - } - } else { - // - // Inherit the TT parameters from parent device. - // - InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum; - InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId; - // - // If the device is a High speed device then down the speed to be the same as its parent Hub - // - if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed; - } - } - } - - // - // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint. - // - EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing; - XhcPeiCreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *) Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]); - // - // 5) Initialize the Input default control Endpoint 0 Context (6.2.3). - // - InputContext->EP[0].EPType = ED_CONTROL_BIDIR; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - InputContext->EP[0].MaxPacketSize = 512; - } else if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - InputContext->EP[0].MaxPacketSize = 64; - } else { - InputContext->EP[0].MaxPacketSize = 8; - } - // - // Initial value of Average TRB Length for Control endpoints would be 8B, Interrupt endpoints - // 1KB, and Bulk and Isoch endpoints 3KB. - // - InputContext->EP[0].AverageTRBLength = 8; - InputContext->EP[0].MaxBurstSize = 0; - InputContext->EP[0].Interval = 0; - InputContext->EP[0].MaxPStreams = 0; - InputContext->EP[0].Mult = 0; - InputContext->EP[0].CErr = 3; - - // - // Init the DCS(dequeue cycle state) as the transfer ring's CCS - // - PhyAddr = UsbHcGetPciAddrForHostAddr ( - Xhc->MemPool, - ((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0, - sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER - ); - InputContext->EP[0].PtrLo = XHC_LOW_32BIT (PhyAddr) | BIT0; - InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (PhyAddr); - - // - // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'. - // - OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT)); - ASSERT (OutputContext != NULL); - ASSERT (((UINTN) OutputContext & 0x3F) == 0); - ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT)); - - Xhc->UsbDevContext[SlotId].OutputContext = OutputContext; - // - // 7) Load the appropriate (Device Slot ID) entry in the Device Context Base Address Array (5.4.6) with - // a pointer to the Output Device Context data structure (6.2.1). - // - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, OutputContext, sizeof (DEVICE_CONTEXT)); - // - // Fill DCBAA with PCI device address - // - Xhc->DCBAA[SlotId] = (UINT64) (UINTN) PhyAddr; - - // - // 8) Issue an Address Device Command for the Device Slot, where the command points to the Input - // Context data structure described above. - // - ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbAddr.CycleBit = 1; - CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV; - CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (!EFI_ERROR (Status)) { - DeviceAddress = (UINT8) OutputContext->Slot.DeviceAddress; - DEBUG ((EFI_D_INFO, "XhcPeiInitializeDeviceSlot: Address %d assigned successfully\n", DeviceAddress)); - Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress; - } - - DEBUG ((EFI_D_INFO, "XhcPeiInitializeDeviceSlot: Enable Slot, Status = %r\n", Status)); - return Status; -} - -/** - Assign and initialize the device slot for a new device. - - @param Xhc The XHCI device. - @param ParentRouteChart The route string pointed to the parent device. - @param ParentPort The port at which the device is located. - @param RouteChart The route string pointed to the device. - @param DeviceSpeed The device speed. - - @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it. - @retval Others Fail to initialize device slot. - -**/ -EFI_STATUS -XhcPeiInitializeDeviceSlot64 ( - IN PEI_XHC_DEV *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT16 ParentPort, - IN USB_DEV_ROUTE RouteChart, - IN UINT8 DeviceSpeed - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT_64 *InputContext; - DEVICE_CONTEXT_64 *OutputContext; - TRANSFER_RING *EndpointTransferRing; - CMD_TRB_ADDRESS_DEVICE CmdTrbAddr; - UINT8 DeviceAddress; - CMD_TRB_ENABLE_SLOT CmdTrb; - UINT8 SlotId; - UINT8 ParentSlotId; - DEVICE_CONTEXT_64 *ParentDeviceContext; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ZeroMem (&CmdTrb, sizeof (CMD_TRB_ENABLE_SLOT)); - CmdTrb.CycleBit = 1; - CmdTrb.Type = TRB_TYPE_EN_SLOT; - - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrb, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiInitializeDeviceSlot64: Enable Slot Failed, Status = %r\n", Status)); - return Status; - } - ASSERT (EvtTrb->SlotId <= Xhc->MaxSlotsEn); - DEBUG ((EFI_D_INFO, "XhcPeiInitializeDeviceSlot64: Enable Slot Successfully, The Slot ID = 0x%x\n", EvtTrb->SlotId)); - SlotId = (UINT8)EvtTrb->SlotId; - ASSERT (SlotId != 0); - - ZeroMem (&Xhc->UsbDevContext[SlotId], sizeof (USB_DEV_CONTEXT)); - Xhc->UsbDevContext[SlotId].Enabled = TRUE; - Xhc->UsbDevContext[SlotId].SlotId = SlotId; - Xhc->UsbDevContext[SlotId].RouteString.Dword = RouteChart.Dword; - Xhc->UsbDevContext[SlotId].ParentRouteString.Dword = ParentRouteChart.Dword; - - // - // 4.3.3 Device Slot Initialization - // 1) Allocate an Input Context data structure (6.2.5) and initialize all fields to '0'. - // - InputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (INPUT_CONTEXT_64)); - ASSERT (InputContext != NULL); - ASSERT (((UINTN) InputContext & 0x3F) == 0); - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - - Xhc->UsbDevContext[SlotId].InputContext = (VOID *) InputContext; - - // - // 2) Initialize the Input Control Context (6.2.5.1) of the Input Context by setting the A0 and A1 - // flags to '1'. These flags indicate that the Slot Context and the Endpoint 0 Context of the Input - // Context are affected by the command. - // - InputContext->InputControlContext.Dword2 |= (BIT0 | BIT1); - - // - // 3) Initialize the Input Slot Context data structure - // - InputContext->Slot.RouteString = RouteChart.Route.RouteString; - InputContext->Slot.Speed = DeviceSpeed + 1; - InputContext->Slot.ContextEntries = 1; - InputContext->Slot.RootHubPortNum = RouteChart.Route.RootPortNum; - - if (RouteChart.Route.RouteString != 0) { - // - // The device is behind of hub device. - // - ParentSlotId = XhcPeiRouteStringToSlotId (Xhc, ParentRouteChart); - ASSERT (ParentSlotId != 0); - // - //if the Full/Low device attached to a High Speed Hub, Init the TTPortNum and TTHubSlotId field of slot context - // - ParentDeviceContext = (DEVICE_CONTEXT_64 *) Xhc->UsbDevContext[ParentSlotId].OutputContext; - if ((ParentDeviceContext->Slot.TTPortNum == 0) && - (ParentDeviceContext->Slot.TTHubSlotId == 0)) { - if ((ParentDeviceContext->Slot.Speed == (EFI_USB_SPEED_HIGH + 1)) && (DeviceSpeed < EFI_USB_SPEED_HIGH)) { - // - // Full/Low device attached to High speed hub port that isolates the high speed signaling - // environment from Full/Low speed signaling environment for a device - // - InputContext->Slot.TTPortNum = ParentPort; - InputContext->Slot.TTHubSlotId = ParentSlotId; - } - } else { - // - // Inherit the TT parameters from parent device. - // - InputContext->Slot.TTPortNum = ParentDeviceContext->Slot.TTPortNum; - InputContext->Slot.TTHubSlotId = ParentDeviceContext->Slot.TTHubSlotId; - // - // If the device is a High speed device then down the speed to be the same as its parent Hub - // - if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - InputContext->Slot.Speed = ParentDeviceContext->Slot.Speed; - } - } - } - - // - // 4) Allocate and initialize the Transfer Ring for the Default Control Endpoint. - // - EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[0] = EndpointTransferRing; - XhcPeiCreateTransferRing(Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *) Xhc->UsbDevContext[SlotId].EndpointTransferRing[0]); - // - // 5) Initialize the Input default control Endpoint 0 Context (6.2.3). - // - InputContext->EP[0].EPType = ED_CONTROL_BIDIR; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - InputContext->EP[0].MaxPacketSize = 512; - } else if (DeviceSpeed == EFI_USB_SPEED_HIGH) { - InputContext->EP[0].MaxPacketSize = 64; - } else { - InputContext->EP[0].MaxPacketSize = 8; - } - // - // Initial value of Average TRB Length for Control endpoints would be 8B, Interrupt endpoints - // 1KB, and Bulk and Isoch endpoints 3KB. - // - InputContext->EP[0].AverageTRBLength = 8; - InputContext->EP[0].MaxBurstSize = 0; - InputContext->EP[0].Interval = 0; - InputContext->EP[0].MaxPStreams = 0; - InputContext->EP[0].Mult = 0; - InputContext->EP[0].CErr = 3; - - // - // Init the DCS(dequeue cycle state) as the transfer ring's CCS - // - PhyAddr = UsbHcGetPciAddrForHostAddr ( - Xhc->MemPool, - ((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[0])->RingSeg0, - sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER - ); - InputContext->EP[0].PtrLo = XHC_LOW_32BIT (PhyAddr) | BIT0; - InputContext->EP[0].PtrHi = XHC_HIGH_32BIT (PhyAddr); - - // - // 6) Allocate the Output Device Context data structure (6.2.1) and initialize it to '0'. - // - OutputContext = UsbHcAllocateMem (Xhc->MemPool, sizeof (DEVICE_CONTEXT_64)); - ASSERT (OutputContext != NULL); - ASSERT (((UINTN) OutputContext & 0x3F) == 0); - ZeroMem (OutputContext, sizeof (DEVICE_CONTEXT_64)); - - Xhc->UsbDevContext[SlotId].OutputContext = OutputContext; - // - // 7) Load the appropriate (Device Slot ID) entry in the Device Context Base Address Array (5.4.6) with - // a pointer to the Output Device Context data structure (6.2.1). - // - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, OutputContext, sizeof (DEVICE_CONTEXT_64)); - // - // Fill DCBAA with PCI device address - // - Xhc->DCBAA[SlotId] = (UINT64) (UINTN) PhyAddr; - - // - // 8) Issue an Address Device Command for the Device Slot, where the command points to the Input - // Context data structure described above. - // - ZeroMem (&CmdTrbAddr, sizeof (CmdTrbAddr)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbAddr.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbAddr.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbAddr.CycleBit = 1; - CmdTrbAddr.Type = TRB_TYPE_ADDRESS_DEV; - CmdTrbAddr.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbAddr, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (!EFI_ERROR (Status)) { - DeviceAddress = (UINT8) OutputContext->Slot.DeviceAddress; - DEBUG ((EFI_D_INFO, "XhcPeiInitializeDeviceSlot64: Address %d assigned successfully\n", DeviceAddress)); - Xhc->UsbDevContext[SlotId].XhciDevAddr = DeviceAddress; - } - - DEBUG ((EFI_D_INFO, "XhcPeiInitializeDeviceSlot64: Enable Slot, Status = %r\n", Status)); - return Status; -} - - -/** - Disable the specified device slot. - - @param Xhc The XHCI device. - @param SlotId The slot id to be disabled. - - @retval EFI_SUCCESS Successfully disable the device slot. - -**/ -EFI_STATUS -XhcPeiDisableSlotCmd ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId - ) -{ - EFI_STATUS Status; - TRB_TEMPLATE *EvtTrb; - CMD_TRB_DISABLE_SLOT CmdTrbDisSlot; - UINT8 Index; - VOID *RingSeg; - - // - // Disable the device slots occupied by these devices on its downstream ports. - // Entry 0 is reserved. - // - for (Index = 0; Index < 255; Index++) { - if (!Xhc->UsbDevContext[Index + 1].Enabled || - (Xhc->UsbDevContext[Index + 1].SlotId == 0) || - (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) { - continue; - } - - Status = XhcPeiDisableSlotCmd (Xhc, Xhc->UsbDevContext[Index + 1].SlotId); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiDisableSlotCmd: failed to disable child, ignore error\n")); - Xhc->UsbDevContext[Index + 1].SlotId = 0; - } - } - - // - // Construct the disable slot command - // - DEBUG ((EFI_D_INFO, "XhcPeiDisableSlotCmd: Disable device slot %d!\n", SlotId)); - - ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot)); - CmdTrbDisSlot.CycleBit = 1; - CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT; - CmdTrbDisSlot.SlotId = SlotId; - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiDisableSlotCmd: Disable Slot Command Failed, Status = %r\n", Status)); - return Status; - } - // - // Free the slot's device context entry - // - Xhc->DCBAA[SlotId] = 0; - - // - // Free the slot related data structure - // - for (Index = 0; Index < 31; Index++) { - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) { - RingSeg = ((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0; - if (RingSeg != NULL) { - UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER); - } - FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] = NULL; - } - } - - for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) { - if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) { - FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]); - } - } - - if (Xhc->UsbDevContext[SlotId].InputContext != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT)); - } - - if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].OutputContext, sizeof (DEVICE_CONTEXT)); - } - // - // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established - // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to - // remove urb from XHCI's asynchronous transfer list. - // - Xhc->UsbDevContext[SlotId].Enabled = FALSE; - Xhc->UsbDevContext[SlotId].SlotId = 0; - - DEBUG ((EFI_D_INFO, "XhcPeiDisableSlotCmd: Disable Slot Command, Status = %r\n", Status)); - return Status; -} - -/** - Disable the specified device slot. - - @param Xhc The XHCI device. - @param SlotId The slot id to be disabled. - - @retval EFI_SUCCESS Successfully disable the device slot. - -**/ -EFI_STATUS -XhcPeiDisableSlotCmd64 ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId - ) -{ - EFI_STATUS Status; - TRB_TEMPLATE *EvtTrb; - CMD_TRB_DISABLE_SLOT CmdTrbDisSlot; - UINT8 Index; - VOID *RingSeg; - - // - // Disable the device slots occupied by these devices on its downstream ports. - // Entry 0 is reserved. - // - for (Index = 0; Index < 255; Index++) { - if (!Xhc->UsbDevContext[Index + 1].Enabled || - (Xhc->UsbDevContext[Index + 1].SlotId == 0) || - (Xhc->UsbDevContext[Index + 1].ParentRouteString.Dword != Xhc->UsbDevContext[SlotId].RouteString.Dword)) { - continue; - } - - Status = XhcPeiDisableSlotCmd64 (Xhc, Xhc->UsbDevContext[Index + 1].SlotId); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiDisableSlotCmd64: failed to disable child, ignore error\n")); - Xhc->UsbDevContext[Index + 1].SlotId = 0; - } - } - - // - // Construct the disable slot command - // - DEBUG ((EFI_D_INFO, "XhcPeiDisableSlotCmd64: Disable device slot %d!\n", SlotId)); - - ZeroMem (&CmdTrbDisSlot, sizeof (CmdTrbDisSlot)); - CmdTrbDisSlot.CycleBit = 1; - CmdTrbDisSlot.Type = TRB_TYPE_DIS_SLOT; - CmdTrbDisSlot.SlotId = SlotId; - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbDisSlot, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiDisableSlotCmd64: Disable Slot Command Failed, Status = %r\n", Status)); - return Status; - } - // - // Free the slot's device context entry - // - Xhc->DCBAA[SlotId] = 0; - - // - // Free the slot related data structure - // - for (Index = 0; Index < 31; Index++) { - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] != NULL) { - RingSeg = ((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index])->RingSeg0; - if (RingSeg != NULL) { - UsbHcFreeMem (Xhc->MemPool, RingSeg, sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER); - } - FreePool (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index]); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Index] = NULL; - } - } - - for (Index = 0; Index < Xhc->UsbDevContext[SlotId].DevDesc.NumConfigurations; Index++) { - if (Xhc->UsbDevContext[SlotId].ConfDesc[Index] != NULL) { - FreePool (Xhc->UsbDevContext[SlotId].ConfDesc[Index]); - } - } - - if (Xhc->UsbDevContext[SlotId].InputContext != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].InputContext, sizeof (INPUT_CONTEXT_64)); - } - - if (Xhc->UsbDevContext[SlotId].OutputContext != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->UsbDevContext[SlotId].OutputContext, sizeof (DEVICE_CONTEXT_64)); - } - // - // Doesn't zero the entry because XhcAsyncInterruptTransfer() may be invoked to remove the established - // asynchronous interrupt pipe after the device is disabled. It needs the device address mapping info to - // remove urb from XHCI's asynchronous transfer list. - // - Xhc->UsbDevContext[SlotId].Enabled = FALSE; - Xhc->UsbDevContext[SlotId].SlotId = 0; - - DEBUG ((EFI_D_INFO, "XhcPeiDisableSlotCmd64: Disable Slot Command, Status = %r\n", Status)); - return Status; -} - -/** - Configure all the device endpoints through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - - @retval EFI_SUCCESS Successfully configure all the device endpoints. - -**/ -EFI_STATUS -XhcPeiSetConfigCmd ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc - ) -{ - EFI_STATUS Status; - USB_INTERFACE_DESCRIPTOR *IfDesc; - USB_ENDPOINT_DESCRIPTOR *EpDesc; - UINT8 Index; - UINTN NumEp; - UINTN EpIndex; - UINT8 EpAddr; - EFI_USB_DATA_DIRECTION Direction; - UINT8 Dci; - UINT8 MaxDci; - EFI_PHYSICAL_ADDRESS PhyAddr; - UINT8 Interval; - - TRANSFER_RING *EndpointTransferRing; - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputContext; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - // - // 4.6.6 Configure Endpoint - // - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT)); - - ASSERT (ConfigDesc != NULL); - - MaxDci = 0; - - IfDesc = (USB_INTERFACE_DESCRIPTOR *) (ConfigDesc + 1); - for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) { - while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) { - IfDesc = (USB_INTERFACE_DESCRIPTOR *) ((UINTN) IfDesc + IfDesc->Length); - } - - NumEp = IfDesc->NumEndpoints; - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *) (IfDesc + 1); - for (EpIndex = 0; EpIndex < NumEp; EpIndex++) { - while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) { - EpDesc = (USB_ENDPOINT_DESCRIPTOR *) ((UINTN) EpDesc + EpDesc->Length); - } - - EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F); - Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut); - - Dci = XhcPeiEndpointToDci (EpAddr, Direction); - if (Dci > MaxDci) { - MaxDci = Dci; - } - - InputContext->InputControlContext.Dword2 |= (BIT0 << Dci); - InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - // - // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor. - // - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - } else { - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - } - - switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) { - case USB_ENDPOINT_BULK: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_BULK_IN; - } else { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_BULK_OUT; - } - - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - XhcPeiCreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); - } - - break; - case USB_ENDPOINT_ISO: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 0; - InputContext->EP[Dci-1].EPType = ED_ISOCH_IN; - } else { - InputContext->EP[Dci-1].CErr = 0; - InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT; - } - // - // Do not support isochronous transfer now. - // - DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd: Unsupport ISO EP found, Transfer ring is not allocated.\n")); - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - continue; - case USB_ENDPOINT_INTERRUPT: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN; - } else { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT; - } - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize; - // - // Get the bInterval from descriptor and init the interval field of endpoint context - // - if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) { - Interval = EpDesc->Interval; - // - // Calculate through the bInterval field of Endpoint descriptor. - // - ASSERT (Interval != 0); - InputContext->EP[Dci-1].Interval = (UINT32) HighBitSet32 ((UINT32) Interval) + 3; - } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) { - Interval = EpDesc->Interval; - ASSERT (Interval >= 1 && Interval <= 16); - // - // Refer to XHCI 1.0 spec section 6.2.3.6, table 61 - // - InputContext->EP[Dci-1].Interval = Interval - 1; - } - - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - XhcPeiCreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); - } - break; - - case USB_ENDPOINT_CONTROL: - // - // Do not support control transfer now. - // - DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd: Unsupport Control EP found, Transfer ring is not allocated.\n")); - default: - DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd: Unknown EP found, Transfer ring is not allocated.\n")); - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - continue; - } - - PhyAddr = UsbHcGetPciAddrForHostAddr ( - Xhc->MemPool, - ((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0, - sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER - ); - PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F); - PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS; - InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr); - InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr); - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *) ((UINTN) EpDesc + EpDesc->Length); - } - IfDesc = (USB_INTERFACE_DESCRIPTOR *) ((UINTN) IfDesc + IfDesc->Length); - } - - InputContext->InputControlContext.Dword2 |= BIT0; - InputContext->Slot.ContextEntries = MaxDci; - // - // configure endpoint - // - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "XhcSetConfigCmd: Configure Endpoint\n")); - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd: Config Endpoint Failed, Status = %r\n", Status)); - } - return Status; -} - -/** - Configure all the device endpoints through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - - @retval EFI_SUCCESS Successfully configure all the device endpoints. - -**/ -EFI_STATUS -XhcPeiSetConfigCmd64 ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc - ) -{ - EFI_STATUS Status; - USB_INTERFACE_DESCRIPTOR *IfDesc; - USB_ENDPOINT_DESCRIPTOR *EpDesc; - UINT8 Index; - UINTN NumEp; - UINTN EpIndex; - UINT8 EpAddr; - EFI_USB_DATA_DIRECTION Direction; - UINT8 Dci; - UINT8 MaxDci; - EFI_PHYSICAL_ADDRESS PhyAddr; - UINT8 Interval; - - TRANSFER_RING *EndpointTransferRing; - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - INPUT_CONTEXT_64 *InputContext; - DEVICE_CONTEXT_64 *OutputContext; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - // - // 4.6.6 Configure Endpoint - // - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - CopyMem (&InputContext->Slot, &OutputContext->Slot, sizeof (SLOT_CONTEXT_64)); - - ASSERT (ConfigDesc != NULL); - - MaxDci = 0; - - IfDesc = (USB_INTERFACE_DESCRIPTOR *) (ConfigDesc + 1); - for (Index = 0; Index < ConfigDesc->NumInterfaces; Index++) { - while ((IfDesc->DescriptorType != USB_DESC_TYPE_INTERFACE) || (IfDesc->AlternateSetting != 0)) { - IfDesc = (USB_INTERFACE_DESCRIPTOR *) ((UINTN) IfDesc + IfDesc->Length); - } - - NumEp = IfDesc->NumEndpoints; - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *) (IfDesc + 1); - for (EpIndex = 0; EpIndex < NumEp; EpIndex++) { - while (EpDesc->DescriptorType != USB_DESC_TYPE_ENDPOINT) { - EpDesc = (USB_ENDPOINT_DESCRIPTOR *) ((UINTN) EpDesc + EpDesc->Length); - } - - EpAddr = (UINT8) (EpDesc->EndpointAddress & 0x0F); - Direction = (UINT8) ((EpDesc->EndpointAddress & 0x80) ? EfiUsbDataIn : EfiUsbDataOut); - - Dci = XhcPeiEndpointToDci (EpAddr, Direction); - ASSERT (Dci < 32); - if (Dci > MaxDci) { - MaxDci = Dci; - } - - InputContext->InputControlContext.Dword2 |= (BIT0 << Dci); - InputContext->EP[Dci-1].MaxPacketSize = EpDesc->MaxPacketSize; - - if (DeviceSpeed == EFI_USB_SPEED_SUPER) { - // - // 6.2.3.4, shall be set to the value defined in the bMaxBurst field of the SuperSpeed Endpoint Companion Descriptor. - // - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - } else { - InputContext->EP[Dci-1].MaxBurstSize = 0x0; - } - - switch (EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK) { - case USB_ENDPOINT_BULK: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_BULK_IN; - } else { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_BULK_OUT; - } - - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - XhcPeiCreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); - } - - break; - case USB_ENDPOINT_ISO: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 0; - InputContext->EP[Dci-1].EPType = ED_ISOCH_IN; - } else { - InputContext->EP[Dci-1].CErr = 0; - InputContext->EP[Dci-1].EPType = ED_ISOCH_OUT; - } - // - // Do not support isochronous transfer now. - // - DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd64: Unsupport ISO EP found, Transfer ring is not allocated.\n")); - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - continue; - case USB_ENDPOINT_INTERRUPT: - if (Direction == EfiUsbDataIn) { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_INTERRUPT_IN; - } else { - InputContext->EP[Dci-1].CErr = 3; - InputContext->EP[Dci-1].EPType = ED_INTERRUPT_OUT; - } - InputContext->EP[Dci-1].AverageTRBLength = 0x1000; - InputContext->EP[Dci-1].MaxESITPayload = EpDesc->MaxPacketSize; - // - // Get the bInterval from descriptor and init the the interval field of endpoint context - // - if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) { - Interval = EpDesc->Interval; - // - // Calculate through the bInterval field of Endpoint descriptor. - // - ASSERT (Interval != 0); - InputContext->EP[Dci-1].Interval = (UINT32) HighBitSet32( (UINT32) Interval) + 3; - } else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) { - Interval = EpDesc->Interval; - ASSERT (Interval >= 1 && Interval <= 16); - // - // Refer to XHCI 1.0 spec section 6.2.3.6, table 61 - // - InputContext->EP[Dci-1].Interval = Interval - 1; - } - - if (Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] == NULL) { - EndpointTransferRing = AllocateZeroPool (sizeof (TRANSFER_RING)); - Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1] = (VOID *) EndpointTransferRing; - XhcPeiCreateTransferRing (Xhc, TR_RING_TRB_NUMBER, (TRANSFER_RING *) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1]); - } - break; - - case USB_ENDPOINT_CONTROL: - // - // Do not support control transfer now. - // - DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd64: Unsupport Control EP found, Transfer ring is not allocated.\n")); - default: - DEBUG ((EFI_D_INFO, "XhcPeiSetConfigCmd64: Unknown EP found, Transfer ring is not allocated.\n")); - EpDesc = (USB_ENDPOINT_DESCRIPTOR *)((UINTN)EpDesc + EpDesc->Length); - continue; - } - - PhyAddr = UsbHcGetPciAddrForHostAddr ( - Xhc->MemPool, - ((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingSeg0, - sizeof (TRB_TEMPLATE) * TR_RING_TRB_NUMBER - ); - - PhyAddr &= ~((EFI_PHYSICAL_ADDRESS)0x0F); - PhyAddr |= (EFI_PHYSICAL_ADDRESS)((TRANSFER_RING *) (UINTN) Xhc->UsbDevContext[SlotId].EndpointTransferRing[Dci-1])->RingPCS; - - InputContext->EP[Dci-1].PtrLo = XHC_LOW_32BIT (PhyAddr); - InputContext->EP[Dci-1].PtrHi = XHC_HIGH_32BIT (PhyAddr); - - EpDesc = (USB_ENDPOINT_DESCRIPTOR *) ((UINTN)EpDesc + EpDesc->Length); - } - IfDesc = (USB_INTERFACE_DESCRIPTOR *) ((UINTN)IfDesc + IfDesc->Length); - } - - InputContext->InputControlContext.Dword2 |= BIT0; - InputContext->Slot.ContextEntries = MaxDci; - // - // configure endpoint - // - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "XhcSetConfigCmd64: Configure Endpoint\n")); - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcSetConfigCmd64: Config Endpoint Failed, Status = %r\n", Status)); - } - - return Status; -} - - -/** - Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be evaluated. - @param MaxPacketSize The max packet size supported by the device control transfer. - - @retval EFI_SUCCESS Successfully evaluate the device endpoint 0. - -**/ -EFI_STATUS -XhcPeiEvaluateContext ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT32 MaxPacketSize - ) -{ - EFI_STATUS Status; - CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT *InputContext; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); - - // - // 4.6.7 Evaluate Context - // - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - - InputContext->InputControlContext.Dword2 |= BIT1; - InputContext->EP[0].MaxPacketSize = MaxPacketSize; - - ZeroMem (&CmdTrbEvalu, sizeof (CmdTrbEvalu)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbEvalu.CycleBit = 1; - CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT; - CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "XhcEvaluateContext: Evaluate context\n")); - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcEvaluateContext: Evaluate Context Failed, Status = %r\n", Status)); - } - return Status; -} - -/** - Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be evaluated. - @param MaxPacketSize The max packet size supported by the device control transfer. - - @retval EFI_SUCCESS Successfully evaluate the device endpoint 0. - -**/ -EFI_STATUS -XhcPeiEvaluateContext64 ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT32 MaxPacketSize - ) -{ - EFI_STATUS Status; - CMD_TRB_EVALUATE_CONTEXT CmdTrbEvalu; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT_64 *InputContext; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); - - // - // 4.6.7 Evaluate Context - // - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - - InputContext->InputControlContext.Dword2 |= BIT1; - InputContext->EP[0].MaxPacketSize = MaxPacketSize; - - ZeroMem (&CmdTrbEvalu, sizeof (CmdTrbEvalu)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbEvalu.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbEvalu.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbEvalu.CycleBit = 1; - CmdTrbEvalu.Type = TRB_TYPE_EVALU_CONTXT; - CmdTrbEvalu.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "XhcEvaluateContext64: Evaluate context 64\n")); - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbEvalu, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcEvaluateContext64: Evaluate Context Failed, Status = %r\n", Status)); - } - return Status; -} - -/** - Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be configured. - @param PortNum The total number of downstream port supported by the hub. - @param TTT The TT think time of the hub device. - @param MTT The multi-TT of the hub device. - - @retval EFI_SUCCESS Successfully configure the hub device's slot context. - -**/ -EFI_STATUS -XhcPeiConfigHubContext ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 PortNum, - IN UINT8 TTT, - IN UINT8 MTT - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT *InputContext; - DEVICE_CONTEXT *OutputContext; - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - - // - // 4.6.7 Evaluate Context - // - ZeroMem (InputContext, sizeof (INPUT_CONTEXT)); - - InputContext->InputControlContext.Dword2 |= BIT0; - - // - // Copy the slot context from OutputContext to Input context - // - CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT)); - InputContext->Slot.Hub = 1; - InputContext->Slot.PortNum = PortNum; - InputContext->Slot.TTT = TTT; - InputContext->Slot.MTT = MTT; - - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "Configure Hub Slot Context\n")); - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcConfigHubContext: Config Endpoint Failed, Status = %r\n", Status)); - } - return Status; -} - -/** - Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be configured. - @param PortNum The total number of downstream port supported by the hub. - @param TTT The TT think time of the hub device. - @param MTT The multi-TT of the hub device. - - @retval EFI_SUCCESS Successfully configure the hub device's slot context. - -**/ -EFI_STATUS -XhcPeiConfigHubContext64 ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 PortNum, - IN UINT8 TTT, - IN UINT8 MTT - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - INPUT_CONTEXT_64 *InputContext; - DEVICE_CONTEXT_64 *OutputContext; - CMD_TRB_CONFIG_ENDPOINT CmdTrbCfgEP; - EFI_PHYSICAL_ADDRESS PhyAddr; - - ASSERT (Xhc->UsbDevContext[SlotId].SlotId != 0); - InputContext = Xhc->UsbDevContext[SlotId].InputContext; - OutputContext = Xhc->UsbDevContext[SlotId].OutputContext; - - // - // 4.6.7 Evaluate Context - // - ZeroMem (InputContext, sizeof (INPUT_CONTEXT_64)); - - InputContext->InputControlContext.Dword2 |= BIT0; - - // - // Copy the slot context from OutputContext to Input context - // - CopyMem(&(InputContext->Slot), &(OutputContext->Slot), sizeof (SLOT_CONTEXT_64)); - InputContext->Slot.Hub = 1; - InputContext->Slot.PortNum = PortNum; - InputContext->Slot.TTT = TTT; - InputContext->Slot.MTT = MTT; - - ZeroMem (&CmdTrbCfgEP, sizeof (CmdTrbCfgEP)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, InputContext, sizeof (INPUT_CONTEXT_64)); - CmdTrbCfgEP.PtrLo = XHC_LOW_32BIT (PhyAddr); - CmdTrbCfgEP.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdTrbCfgEP.CycleBit = 1; - CmdTrbCfgEP.Type = TRB_TYPE_CON_ENDPOINT; - CmdTrbCfgEP.SlotId = Xhc->UsbDevContext[SlotId].SlotId; - DEBUG ((EFI_D_INFO, "Configure Hub Slot Context 64\n")); - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbCfgEP, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "XhcConfigHubContext64: Config Endpoint Failed, Status = %r\n", Status)); - } - return Status; -} - -/** - Stop endpoint through XHCI's Stop_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - - @retval EFI_SUCCESS Stop endpoint successfully. - @retval Others Failed to stop endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcPeiStopEndpoint ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - CMD_TRB_STOP_ENDPOINT CmdTrbStopED; - - DEBUG ((EFI_D_INFO, "XhcPeiStopEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci)); - - // - // Send stop endpoint command to transit Endpoint from running to stop state - // - ZeroMem (&CmdTrbStopED, sizeof (CmdTrbStopED)); - CmdTrbStopED.CycleBit = 1; - CmdTrbStopED.Type = TRB_TYPE_STOP_ENDPOINT; - CmdTrbStopED.EDID = Dci; - CmdTrbStopED.SlotId = SlotId; - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbStopED, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiStopEndpoint: Stop Endpoint Failed, Status = %r\n", Status)); - } - - return Status; -} - -/** - Reset endpoint through XHCI's Reset_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - - @retval EFI_SUCCESS Reset endpoint successfully. - @retval Others Failed to reset endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcPeiResetEndpoint ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - CMD_TRB_RESET_ENDPOINT CmdTrbResetED; - - DEBUG ((EFI_D_INFO, "XhcPeiResetEndpoint: Slot = 0x%x, Dci = 0x%x\n", SlotId, Dci)); - - // - // Send stop endpoint command to transit Endpoint from running to stop state - // - ZeroMem (&CmdTrbResetED, sizeof (CmdTrbResetED)); - CmdTrbResetED.CycleBit = 1; - CmdTrbResetED.Type = TRB_TYPE_RESET_ENDPOINT; - CmdTrbResetED.EDID = Dci; - CmdTrbResetED.SlotId = SlotId; - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdTrbResetED, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiResetEndpoint: Reset Endpoint Failed, Status = %r\n", Status)); - } - - return Status; -} - -/** - Set transfer ring dequeue pointer through XHCI's Set_Tr_Dequeue_Pointer cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - @param Urb The dequeue pointer of the transfer ring specified - by the urb to be updated. - - @retval EFI_SUCCESS Set transfer ring dequeue pointer succeeds. - @retval Others Failed to set transfer ring dequeue pointer. - -**/ -EFI_STATUS -EFIAPI -XhcPeiSetTrDequeuePointer ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci, - IN URB *Urb - ) -{ - EFI_STATUS Status; - EVT_TRB_COMMAND_COMPLETION *EvtTrb; - CMD_SET_TR_DEQ_POINTER CmdSetTRDeq; - EFI_PHYSICAL_ADDRESS PhyAddr; - - DEBUG ((EFI_D_INFO, "XhcPeiSetTrDequeuePointer: Slot = 0x%x, Dci = 0x%x, Urb = 0x%x\n", SlotId, Dci, Urb)); - - // - // Send stop endpoint command to transit Endpoint from running to stop state - // - ZeroMem (&CmdSetTRDeq, sizeof (CmdSetTRDeq)); - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Urb->Ring->RingEnqueue, sizeof (CMD_SET_TR_DEQ_POINTER)); - CmdSetTRDeq.PtrLo = XHC_LOW_32BIT (PhyAddr) | Urb->Ring->RingPCS; - CmdSetTRDeq.PtrHi = XHC_HIGH_32BIT (PhyAddr); - CmdSetTRDeq.CycleBit = 1; - CmdSetTRDeq.Type = TRB_TYPE_SET_TR_DEQUE; - CmdSetTRDeq.Endpoint = Dci; - CmdSetTRDeq.SlotId = SlotId; - Status = XhcPeiCmdTransfer ( - Xhc, - (TRB_TEMPLATE *) (UINTN) &CmdSetTRDeq, - XHC_GENERIC_TIMEOUT, - (TRB_TEMPLATE **) (UINTN) &EvtTrb - ); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "XhcPeiSetTrDequeuePointer: Set TR Dequeue Pointer Failed, Status = %r\n", Status)); - } - - return Status; -} - -/** - Check if there is a new generated event. - - @param Xhc The XHCI device. - @param EvtRing The event ring to check. - @param NewEvtTrb The new event TRB found. - - @retval EFI_SUCCESS Found a new event TRB at the event ring. - @retval EFI_NOT_READY The event ring has no new event. - -**/ -EFI_STATUS -XhcPeiCheckNewEvent ( - IN PEI_XHC_DEV *Xhc, - IN EVENT_RING *EvtRing, - OUT TRB_TEMPLATE **NewEvtTrb - ) -{ - ASSERT (EvtRing != NULL); - - *NewEvtTrb = EvtRing->EventRingDequeue; - - if (EvtRing->EventRingDequeue == EvtRing->EventRingEnqueue) { - return EFI_NOT_READY; - } - - EvtRing->EventRingDequeue++; - // - // If the dequeue pointer is beyond the ring, then roll-back it to the begining of the ring. - // - if ((UINTN) EvtRing->EventRingDequeue >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) { - EvtRing->EventRingDequeue = EvtRing->EventRingSeg0; - } - - return EFI_SUCCESS; -} - -/** - Synchronize the specified event ring to update the enqueue and dequeue pointer. - - @param Xhc The XHCI device. - @param EvtRing The event ring to sync. - - @retval EFI_SUCCESS The event ring is synchronized successfully. - -**/ -EFI_STATUS -XhcPeiSyncEventRing ( - IN PEI_XHC_DEV *Xhc, - IN EVENT_RING *EvtRing - ) -{ - UINTN Index; - TRB_TEMPLATE *EvtTrb; - - ASSERT (EvtRing != NULL); - - // - // Calculate the EventRingEnqueue and EventRingCCS. - // Note: only support single Segment - // - EvtTrb = EvtRing->EventRingDequeue; - - for (Index = 0; Index < EvtRing->TrbNumber; Index++) { - if (EvtTrb->CycleBit != EvtRing->EventRingCCS) { - break; - } - - EvtTrb++; - - if ((UINTN) EvtTrb >= ((UINTN) EvtRing->EventRingSeg0 + sizeof (TRB_TEMPLATE) * EvtRing->TrbNumber)) { - EvtTrb = EvtRing->EventRingSeg0; - EvtRing->EventRingCCS = (EvtRing->EventRingCCS) ? 0 : 1; - } - } - - if (Index < EvtRing->TrbNumber) { - EvtRing->EventRingEnqueue = EvtTrb; - } else { - ASSERT (FALSE); - } - - return EFI_SUCCESS; -} - -/** - Free XHCI event ring. - - @param Xhc The XHCI device. - @param EventRing The event ring to be freed. - -**/ -VOID -XhcPeiFreeEventRing ( - IN PEI_XHC_DEV *Xhc, - IN EVENT_RING *EventRing - ) -{ - if(EventRing->EventRingSeg0 == NULL) { - return; - } - - // - // Free EventRing Segment 0 - // - UsbHcFreeMem (Xhc->MemPool, EventRing->EventRingSeg0, sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER); - - // - // Free ERST table - // - UsbHcFreeMem (Xhc->MemPool, EventRing->ERSTBase, sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER); -} - -/** - Create XHCI event ring. - - @param Xhc The XHCI device. - @param EventRing The created event ring. - -**/ -VOID -XhcPeiCreateEventRing ( - IN PEI_XHC_DEV *Xhc, - OUT EVENT_RING *EventRing - ) -{ - VOID *Buf; - EVENT_RING_SEG_TABLE_ENTRY *ERSTBase; - UINTN Size; - EFI_PHYSICAL_ADDRESS ERSTPhy; - EFI_PHYSICAL_ADDRESS DequeuePhy; - - ASSERT (EventRing != NULL); - - Size = sizeof (TRB_TEMPLATE) * EVENT_RING_TRB_NUMBER; - Buf = UsbHcAllocateMem (Xhc->MemPool, Size); - ASSERT (Buf != NULL); - ASSERT (((UINTN) Buf & 0x3F) == 0); - ZeroMem (Buf, Size); - - DequeuePhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, Size); - - EventRing->EventRingSeg0 = Buf; - EventRing->TrbNumber = EVENT_RING_TRB_NUMBER; - EventRing->EventRingDequeue = (TRB_TEMPLATE *) EventRing->EventRingSeg0; - EventRing->EventRingEnqueue = (TRB_TEMPLATE *) EventRing->EventRingSeg0; - - // - // Software maintains an Event Ring Consumer Cycle State (CCS) bit, initializing it to '1' - // and toggling it every time the Event Ring Dequeue Pointer wraps back to the beginning of the Event Ring. - // - EventRing->EventRingCCS = 1; - - Size = sizeof (EVENT_RING_SEG_TABLE_ENTRY) * ERST_NUMBER; - Buf = UsbHcAllocateMem (Xhc->MemPool, Size); - ASSERT (Buf != NULL); - ASSERT (((UINTN) Buf & 0x3F) == 0); - ZeroMem (Buf, Size); - - ERSTBase = (EVENT_RING_SEG_TABLE_ENTRY *) Buf; - EventRing->ERSTBase = ERSTBase; - ERSTBase->PtrLo = XHC_LOW_32BIT (DequeuePhy); - ERSTBase->PtrHi = XHC_HIGH_32BIT (DequeuePhy); - ERSTBase->RingTrbSize = EVENT_RING_TRB_NUMBER; - - ERSTPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, Size); - - // - // Program the Interrupter Event Ring Segment Table Size (ERSTSZ) register (5.5.2.3.1) - // - XhcPeiWriteRuntimeReg ( - Xhc, - XHC_ERSTSZ_OFFSET, - ERST_NUMBER - ); - // - // Program the Interrupter Event Ring Dequeue Pointer (ERDP) register (5.5.2.3.3) - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - XhcPeiWriteRuntimeReg ( - Xhc, - XHC_ERDP_OFFSET, - XHC_LOW_32BIT ((UINT64) (UINTN) DequeuePhy) - ); - XhcPeiWriteRuntimeReg ( - Xhc, - XHC_ERDP_OFFSET + 4, - XHC_HIGH_32BIT ((UINT64) (UINTN) DequeuePhy) - ); - // - // Program the Interrupter Event Ring Segment Table Base Address (ERSTBA) register (5.5.2.3.2) - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - XhcPeiWriteRuntimeReg ( - Xhc, - XHC_ERSTBA_OFFSET, - XHC_LOW_32BIT ((UINT64) (UINTN) ERSTPhy) - ); - XhcPeiWriteRuntimeReg ( - Xhc, - XHC_ERSTBA_OFFSET + 4, - XHC_HIGH_32BIT ((UINT64) (UINTN) ERSTPhy) - ); - // - // Need set IMAN IE bit to enable the ring interrupt - // - XhcPeiSetRuntimeRegBit (Xhc, XHC_IMAN_OFFSET, XHC_IMAN_IE); -} - -/** - Synchronize the specified transfer ring to update the enqueue and dequeue pointer. - - @param Xhc The XHCI device. - @param TrsRing The transfer ring to sync. - - @retval EFI_SUCCESS The transfer ring is synchronized successfully. - -**/ -EFI_STATUS -XhcPeiSyncTrsRing ( - IN PEI_XHC_DEV *Xhc, - IN TRANSFER_RING *TrsRing - ) -{ - UINTN Index; - TRB_TEMPLATE *TrsTrb; - - ASSERT (TrsRing != NULL); - // - // Calculate the latest RingEnqueue and RingPCS - // - TrsTrb = TrsRing->RingEnqueue; - ASSERT (TrsTrb != NULL); - - for (Index = 0; Index < TrsRing->TrbNumber; Index++) { - if (TrsTrb->CycleBit != (TrsRing->RingPCS & BIT0)) { - break; - } - TrsTrb++; - if ((UINT8) TrsTrb->Type == TRB_TYPE_LINK) { - ASSERT (((LINK_TRB *) TrsTrb)->TC != 0); - // - // set cycle bit in Link TRB as normal - // - ((LINK_TRB*)TrsTrb)->CycleBit = TrsRing->RingPCS & BIT0; - // - // Toggle PCS maintained by software - // - TrsRing->RingPCS = (TrsRing->RingPCS & BIT0) ? 0 : 1; - TrsTrb = (TRB_TEMPLATE *) TrsRing->RingSeg0; // Use host address - } - } - - ASSERT (Index != TrsRing->TrbNumber); - - if (TrsTrb != TrsRing->RingEnqueue) { - TrsRing->RingEnqueue = TrsTrb; - } - - // - // Clear the Trb context for enqueue, but reserve the PCS bit - // - TrsTrb->Parameter1 = 0; - TrsTrb->Parameter2 = 0; - TrsTrb->Status = 0; - TrsTrb->RsvdZ1 = 0; - TrsTrb->Type = 0; - TrsTrb->Control = 0; - - return EFI_SUCCESS; -} - -/** - Create XHCI transfer ring. - - @param Xhc The XHCI Device. - @param TrbNum The number of TRB in the ring. - @param TransferRing The created transfer ring. - -**/ -VOID -XhcPeiCreateTransferRing ( - IN PEI_XHC_DEV *Xhc, - IN UINTN TrbNum, - OUT TRANSFER_RING *TransferRing - ) -{ - VOID *Buf; - LINK_TRB *EndTrb; - EFI_PHYSICAL_ADDRESS PhyAddr; - - Buf = UsbHcAllocateMem (Xhc->MemPool, sizeof (TRB_TEMPLATE) * TrbNum); - ASSERT (Buf != NULL); - ASSERT (((UINTN) Buf & 0x3F) == 0); - ZeroMem (Buf, sizeof (TRB_TEMPLATE) * TrbNum); - - TransferRing->RingSeg0 = Buf; - TransferRing->TrbNumber = TrbNum; - TransferRing->RingEnqueue = (TRB_TEMPLATE *) TransferRing->RingSeg0; - TransferRing->RingDequeue = (TRB_TEMPLATE *) TransferRing->RingSeg0; - TransferRing->RingPCS = 1; - // - // 4.9.2 Transfer Ring Management - // To form a ring (or circular queue) a Link TRB may be inserted at the end of a ring to - // point to the first TRB in the ring. - // - EndTrb = (LINK_TRB *) ((UINTN) Buf + sizeof (TRB_TEMPLATE) * (TrbNum - 1)); - EndTrb->Type = TRB_TYPE_LINK; - PhyAddr = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Buf, sizeof (TRB_TEMPLATE) * TrbNum); - EndTrb->PtrLo = XHC_LOW_32BIT (PhyAddr); - EndTrb->PtrHi = XHC_HIGH_32BIT (PhyAddr); - // - // Toggle Cycle (TC). When set to '1', the xHC shall toggle its interpretation of the Cycle bit. - // - EndTrb->TC = 1; - // - // Set Cycle bit as other TRB PCS init value - // - EndTrb->CycleBit = 0; -} - -/** - Initialize the XHCI host controller for schedule. - - @param Xhc The XHCI device to be initialized. - -**/ -VOID -XhcPeiInitSched ( - IN PEI_XHC_DEV *Xhc - ) -{ - VOID *Dcbaa; - EFI_PHYSICAL_ADDRESS DcbaaPhy; - UINTN Size; - EFI_PHYSICAL_ADDRESS CmdRingPhy; - UINT32 MaxScratchpadBufs; - UINT64 *ScratchBuf; - EFI_PHYSICAL_ADDRESS ScratchPhy; - UINT64 *ScratchEntry; - EFI_PHYSICAL_ADDRESS ScratchEntryPhy; - UINT32 Index; - EFI_STATUS Status; - - // - // Initialize memory management. - // - Xhc->MemPool = UsbHcInitMemPool (); - ASSERT (Xhc->MemPool != NULL); - - // - // Program the Max Device Slots Enabled (MaxSlotsEn) field in the CONFIG register (5.4.7) - // to enable the device slots that system software is going to use. - // - Xhc->MaxSlotsEn = Xhc->HcSParams1.Data.MaxSlots; - ASSERT (Xhc->MaxSlotsEn >= 1 && Xhc->MaxSlotsEn <= 255); - XhcPeiWriteOpReg (Xhc, XHC_CONFIG_OFFSET, (XhcPeiReadOpReg (Xhc, XHC_CONFIG_OFFSET) & ~XHC_CONFIG_MASK) | Xhc->MaxSlotsEn); - - // - // The Device Context Base Address Array entry associated with each allocated Device Slot - // shall contain a 64-bit pointer to the base of the associated Device Context. - // The Device Context Base Address Array shall contain MaxSlotsEn + 1 entries. - // Software shall set Device Context Base Address Array entries for unallocated Device Slots to '0'. - // - Size = (Xhc->MaxSlotsEn + 1) * sizeof (UINT64); - Dcbaa = UsbHcAllocateMem (Xhc->MemPool, Size); - ASSERT (Dcbaa != NULL); - - // - // A Scratchpad Buffer is a PAGESIZE block of system memory located on a PAGESIZE boundary. - // System software shall allocate the Scratchpad Buffer(s) before placing the xHC in to Run - // mode (Run/Stop(R/S) ='1'). - // - MaxScratchpadBufs = ((Xhc->HcSParams2.Data.ScratchBufHi) << 5) | (Xhc->HcSParams2.Data.ScratchBufLo); - Xhc->MaxScratchpadBufs = MaxScratchpadBufs; - ASSERT (MaxScratchpadBufs <= 1023); - if (MaxScratchpadBufs != 0) { - // - // Allocate the buffer to record the host address for each entry - // - ScratchEntry = AllocateZeroPool (sizeof (UINT64) * MaxScratchpadBufs); - ASSERT (ScratchEntry != NULL); - Xhc->ScratchEntry = ScratchEntry; - - ScratchPhy = 0; - Status = UsbHcAllocateAlignedPages ( - EFI_SIZE_TO_PAGES (MaxScratchpadBufs * sizeof (UINT64)), - Xhc->PageSize, - (VOID **) &ScratchBuf, - &ScratchPhy - ); - ASSERT_EFI_ERROR (Status); - - ZeroMem (ScratchBuf, MaxScratchpadBufs * sizeof (UINT64)); - Xhc->ScratchBuf = ScratchBuf; - - // - // Allocate each scratch buffer - // - for (Index = 0; Index < MaxScratchpadBufs; Index++) { - ScratchEntryPhy = 0; - Status = UsbHcAllocateAlignedPages ( - EFI_SIZE_TO_PAGES (Xhc->PageSize), - Xhc->PageSize, - (VOID **) &ScratchEntry[Index], - &ScratchEntryPhy - ); - ASSERT_EFI_ERROR (Status); - ZeroMem ((VOID *) (UINTN) ScratchEntry[Index], Xhc->PageSize); - // - // Fill with the PCI device address - // - *ScratchBuf++ = ScratchEntryPhy; - } - // - // The Scratchpad Buffer Array contains pointers to the Scratchpad Buffers. Entry 0 of the - // Device Context Base Address Array points to the Scratchpad Buffer Array. - // - *(UINT64 *) Dcbaa = (UINT64) (UINTN) ScratchPhy; - } - - // - // Program the Device Context Base Address Array Pointer (DCBAAP) register (5.4.6) with - // a 64-bit address pointing to where the Device Context Base Address Array is located. - // - Xhc->DCBAA = (UINT64 *) (UINTN) Dcbaa; - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - DcbaaPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Dcbaa, Size); - XhcPeiWriteOpReg (Xhc, XHC_DCBAAP_OFFSET, XHC_LOW_32BIT (DcbaaPhy)); - XhcPeiWriteOpReg (Xhc, XHC_DCBAAP_OFFSET + 4, XHC_HIGH_32BIT (DcbaaPhy)); - - DEBUG ((EFI_D_INFO, "XhcPeiInitSched:DCBAA=0x%x\n", Xhc->DCBAA)); - - // - // Define the Command Ring Dequeue Pointer by programming the Command Ring Control Register - // (5.4.5) with a 64-bit address pointing to the starting address of the first TRB of the Command Ring. - // Note: The Command Ring is 64 byte aligned, so the low order 6 bits of the Command Ring Pointer shall - // always be '0'. - // - XhcPeiCreateTransferRing (Xhc, CMD_RING_TRB_NUMBER, &Xhc->CmdRing); - // - // The xHC uses the Enqueue Pointer to determine when a Transfer Ring is empty. As it fetches TRBs from a - // Transfer Ring it checks for a Cycle bit transition. If a transition detected, the ring is empty. - // So we set RCS as inverted PCS init value to let Command Ring empty - // - CmdRingPhy = UsbHcGetPciAddrForHostAddr (Xhc->MemPool, Xhc->CmdRing.RingSeg0, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER); - ASSERT ((CmdRingPhy & 0x3F) == 0); - CmdRingPhy |= XHC_CRCR_RCS; - // - // Some 3rd party XHCI external cards don't support single 64-bytes width register access, - // So divide it to two 32-bytes width register access. - // - XhcPeiWriteOpReg (Xhc, XHC_CRCR_OFFSET, XHC_LOW_32BIT (CmdRingPhy)); - XhcPeiWriteOpReg (Xhc, XHC_CRCR_OFFSET + 4, XHC_HIGH_32BIT (CmdRingPhy)); - - DEBUG ((EFI_D_INFO, "XhcPeiInitSched:XHC_CRCR=0x%x\n", Xhc->CmdRing.RingSeg0)); - - // - // Disable the 'interrupter enable' bit in USB_CMD - // and clear IE & IP bit in all Interrupter X Management Registers. - // - XhcPeiClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_INTE); - for (Index = 0; Index < (UINT16)(Xhc->HcSParams1.Data.MaxIntrs); Index++) { - XhcPeiClearRuntimeRegBit (Xhc, XHC_IMAN_OFFSET + (Index * 32), XHC_IMAN_IE); - XhcPeiSetRuntimeRegBit (Xhc, XHC_IMAN_OFFSET + (Index * 32), XHC_IMAN_IP); - } - - // - // Allocate EventRing for Cmd, Ctrl, Bulk, Interrupt, AsynInterrupt transfer - // - XhcPeiCreateEventRing (Xhc, &Xhc->EventRing); - DEBUG ((EFI_D_INFO, "XhcPeiInitSched:XHC_EVENTRING=0x%x\n", Xhc->EventRing.EventRingSeg0)); -} - -/** - Free the resouce allocated at initializing schedule. - - @param Xhc The XHCI device. - -**/ -VOID -XhcPeiFreeSched ( - IN PEI_XHC_DEV *Xhc - ) -{ - UINT32 Index; - UINT64 *ScratchEntry; - - if (Xhc->ScratchBuf != NULL) { - ScratchEntry = Xhc->ScratchEntry; - for (Index = 0; Index < Xhc->MaxScratchpadBufs; Index++) { - // - // Free Scratchpad Buffers - // - UsbHcFreeAlignedPages ((VOID*) (UINTN) ScratchEntry[Index], EFI_SIZE_TO_PAGES (Xhc->PageSize)); - } - // - // Free Scratchpad Buffer Array - // - UsbHcFreeAlignedPages (Xhc->ScratchBuf, EFI_SIZE_TO_PAGES (Xhc->MaxScratchpadBufs * sizeof (UINT64))); - FreePool (Xhc->ScratchEntry); - } - - if (Xhc->CmdRing.RingSeg0 != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->CmdRing.RingSeg0, sizeof (TRB_TEMPLATE) * CMD_RING_TRB_NUMBER); - Xhc->CmdRing.RingSeg0 = NULL; - } - - XhcPeiFreeEventRing (Xhc,&Xhc->EventRing); - - if (Xhc->DCBAA != NULL) { - UsbHcFreeMem (Xhc->MemPool, Xhc->DCBAA, (Xhc->MaxSlotsEn + 1) * sizeof (UINT64)); - Xhc->DCBAA = NULL; - } - - // - // Free memory pool at last - // - if (Xhc->MemPool != NULL) { - UsbHcFreeMemPool (Xhc->MemPool); - Xhc->MemPool = NULL; - } -} - diff --git a/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h b/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h deleted file mode 100644 index b3d4c45614..0000000000 --- a/MdeModulePkg/Bus/Pci/XhciPei/XhciSched.h +++ /dev/null @@ -1,1307 +0,0 @@ -/** @file -Private Header file for Usb Host Controller PEIM - -Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
- -This program and the accompanying materials -are licensed and made available under the terms and conditions -of the BSD License which accompanies this distribution. The -full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _EFI_PEI_XHCI_SCHED_H_ -#define _EFI_PEI_XHCI_SCHED_H_ - -// -// Transfer types, used in URB to identify the transfer type -// -#define XHC_CTRL_TRANSFER 0x01 -#define XHC_BULK_TRANSFER 0x02 - -// -// 6.4.6 TRB Types -// -#define TRB_TYPE_NORMAL 1 -#define TRB_TYPE_SETUP_STAGE 2 -#define TRB_TYPE_DATA_STAGE 3 -#define TRB_TYPE_STATUS_STAGE 4 -#define TRB_TYPE_ISOCH 5 -#define TRB_TYPE_LINK 6 -#define TRB_TYPE_EVENT_DATA 7 -#define TRB_TYPE_NO_OP 8 -#define TRB_TYPE_EN_SLOT 9 -#define TRB_TYPE_DIS_SLOT 10 -#define TRB_TYPE_ADDRESS_DEV 11 -#define TRB_TYPE_CON_ENDPOINT 12 -#define TRB_TYPE_EVALU_CONTXT 13 -#define TRB_TYPE_RESET_ENDPOINT 14 -#define TRB_TYPE_STOP_ENDPOINT 15 -#define TRB_TYPE_SET_TR_DEQUE 16 -#define TRB_TYPE_RESET_DEV 17 -#define TRB_TYPE_GET_PORT_BANW 21 -#define TRB_TYPE_FORCE_HEADER 22 -#define TRB_TYPE_NO_OP_COMMAND 23 -#define TRB_TYPE_TRANS_EVENT 32 -#define TRB_TYPE_COMMAND_COMPLT_EVENT 33 -#define TRB_TYPE_PORT_STATUS_CHANGE_EVENT 34 -#define TRB_TYPE_HOST_CONTROLLER_EVENT 37 -#define TRB_TYPE_DEVICE_NOTIFI_EVENT 38 -#define TRB_TYPE_MFINDEX_WRAP_EVENT 39 - -// -// Endpoint Type (EP Type). -// -#define ED_NOT_VALID 0 -#define ED_ISOCH_OUT 1 -#define ED_BULK_OUT 2 -#define ED_INTERRUPT_OUT 3 -#define ED_CONTROL_BIDIR 4 -#define ED_ISOCH_IN 5 -#define ED_BULK_IN 6 -#define ED_INTERRUPT_IN 7 - -// -// 6.4.5 TRB Completion Codes -// -#define TRB_COMPLETION_INVALID 0 -#define TRB_COMPLETION_SUCCESS 1 -#define TRB_COMPLETION_DATA_BUFFER_ERROR 2 -#define TRB_COMPLETION_BABBLE_ERROR 3 -#define TRB_COMPLETION_USB_TRANSACTION_ERROR 4 -#define TRB_COMPLETION_TRB_ERROR 5 -#define TRB_COMPLETION_STALL_ERROR 6 -#define TRB_COMPLETION_SHORT_PACKET 13 - -// -// The topology string used to present usb device location -// -typedef struct _USB_DEV_TOPOLOGY { - // - // The tier concatenation of down stream port. - // - UINT32 RouteString:20; - // - // The root port number of the chain. - // - UINT32 RootPortNum:8; - // - // The Tier the device reside. - // - UINT32 TierNum:4; -} USB_DEV_TOPOLOGY; - -// -// USB Device's RouteChart -// -typedef union _USB_DEV_ROUTE { - UINT32 Dword; - USB_DEV_TOPOLOGY Route; -} USB_DEV_ROUTE; - -// -// Endpoint address and its capabilities -// -typedef struct _USB_ENDPOINT { - // - // Store logical device address assigned by UsbBus - // It's because some XHCI host controllers may assign the same physcial device - // address for those devices inserted at different root port. - // - UINT8 BusAddr; - UINT8 DevAddr; - UINT8 EpAddr; - EFI_USB_DATA_DIRECTION Direction; - UINT8 DevSpeed; - UINTN MaxPacket; - UINTN Type; -} USB_ENDPOINT; - -// -// TRB Template -// -typedef struct _TRB_TEMPLATE { - UINT32 Parameter1; - - UINT32 Parameter2; - - UINT32 Status; - - UINT32 CycleBit:1; - UINT32 RsvdZ1:9; - UINT32 Type:6; - UINT32 Control:16; -} TRB_TEMPLATE; - -typedef struct _TRANSFER_RING { - VOID *RingSeg0; - UINTN TrbNumber; - TRB_TEMPLATE *RingEnqueue; - TRB_TEMPLATE *RingDequeue; - UINT32 RingPCS; -} TRANSFER_RING; - -typedef struct _EVENT_RING { - VOID *ERSTBase; - VOID *EventRingSeg0; - UINTN TrbNumber; - TRB_TEMPLATE *EventRingEnqueue; - TRB_TEMPLATE *EventRingDequeue; - UINT32 EventRingCCS; -} EVENT_RING; - -#define XHC_URB_SIG SIGNATURE_32 ('U', 'S', 'B', 'R') - -// -// URB (Usb Request Block) contains information for all kinds of -// usb requests. -// -typedef struct _URB { - UINT32 Signature; - // - // Usb Device URB related information - // - USB_ENDPOINT Ep; - EFI_USB_DEVICE_REQUEST *Request; - VOID *Data; - UINTN DataLen; - VOID *DataPhy; - EFI_ASYNC_USB_TRANSFER_CALLBACK Callback; - VOID *Context; - // - // Execute result - // - UINT32 Result; - // - // completed data length - // - UINTN Completed; - // - // Command/Tranfer Ring info - // - TRANSFER_RING *Ring; - TRB_TEMPLATE *TrbStart; - TRB_TEMPLATE *TrbEnd; - UINTN TrbNum; - BOOLEAN StartDone; - BOOLEAN EndDone; - BOOLEAN Finished; - - TRB_TEMPLATE *EvtTrb; -} URB; - -// -// 6.5 Event Ring Segment Table -// The Event Ring Segment Table is used to define multi-segment Event Rings and to enable runtime -// expansion and shrinking of the Event Ring. The location of the Event Ring Segment Table is defined by the -// Event Ring Segment Table Base Address Register (5.5.2.3.2). The size of the Event Ring Segment Table -// is defined by the Event Ring Segment Table Base Size Register (5.5.2.3.1). -// -typedef struct _EVENT_RING_SEG_TABLE_ENTRY { - UINT32 PtrLo; - UINT32 PtrHi; - UINT32 RingTrbSize:16; - UINT32 RsvdZ1:16; - UINT32 RsvdZ2; -} EVENT_RING_SEG_TABLE_ENTRY; - -// -// 6.4.1.1 Normal TRB -// A Normal TRB is used in several ways; exclusively on Bulk and Interrupt Transfer Rings for normal and -// Scatter/Gather operations, to define additional data buffers for Scatter/Gather operations on Isoch Transfer -// Rings, and to define the Data stage information for Control Transfer Rings. -// -typedef struct _TRANSFER_TRB_NORMAL { - UINT32 TRBPtrLo; - - UINT32 TRBPtrHi; - - UINT32 Length:17; - UINT32 TDSize:5; - UINT32 IntTarget:10; - - UINT32 CycleBit:1; - UINT32 ENT:1; - UINT32 ISP:1; - UINT32 NS:1; - UINT32 CH:1; - UINT32 IOC:1; - UINT32 IDT:1; - UINT32 RsvdZ1:2; - UINT32 BEI:1; - UINT32 Type:6; - UINT32 RsvdZ2:16; -} TRANSFER_TRB_NORMAL; - -// -// 6.4.1.2.1 Setup Stage TRB -// A Setup Stage TRB is created by system software to initiate a USB Setup packet on a control endpoint. -// -typedef struct _TRANSFER_TRB_CONTROL_SETUP { - UINT32 bmRequestType:8; - UINT32 bRequest:8; - UINT32 wValue:16; - - UINT32 wIndex:16; - UINT32 wLength:16; - - UINT32 Length:17; - UINT32 RsvdZ1:5; - UINT32 IntTarget:10; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:4; - UINT32 IOC:1; - UINT32 IDT:1; - UINT32 RsvdZ3:3; - UINT32 Type:6; - UINT32 TRT:2; - UINT32 RsvdZ4:14; -} TRANSFER_TRB_CONTROL_SETUP; - -// -// 6.4.1.2.2 Data Stage TRB -// A Data Stage TRB is used generate the Data stage transaction of a USB Control transfer. -// -typedef struct _TRANSFER_TRB_CONTROL_DATA { - UINT32 TRBPtrLo; - - UINT32 TRBPtrHi; - - UINT32 Length:17; - UINT32 TDSize:5; - UINT32 IntTarget:10; - - UINT32 CycleBit:1; - UINT32 ENT:1; - UINT32 ISP:1; - UINT32 NS:1; - UINT32 CH:1; - UINT32 IOC:1; - UINT32 IDT:1; - UINT32 RsvdZ1:3; - UINT32 Type:6; - UINT32 DIR:1; - UINT32 RsvdZ2:15; -} TRANSFER_TRB_CONTROL_DATA; - -// -// 6.4.1.2.2 Data Stage TRB -// A Data Stage TRB is used generate the Data stage transaction of a USB Control transfer. -// -typedef struct _TRANSFER_TRB_CONTROL_STATUS { - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 RsvdZ3:22; - UINT32 IntTarget:10; - - UINT32 CycleBit:1; - UINT32 ENT:1; - UINT32 RsvdZ4:2; - UINT32 CH:1; - UINT32 IOC:1; - UINT32 RsvdZ5:4; - UINT32 Type:6; - UINT32 DIR:1; - UINT32 RsvdZ6:15; -} TRANSFER_TRB_CONTROL_STATUS; - -// -// 6.4.2.1 Transfer Event TRB -// A Transfer Event provides the completion status associated with a Transfer TRB. Refer to section 4.11.3.1 -// for more information on the use and operation of Transfer Events. -// -typedef struct _EVT_TRB_TRANSFER { - UINT32 TRBPtrLo; - - UINT32 TRBPtrHi; - - UINT32 Length:24; - UINT32 Completecode:8; - - UINT32 CycleBit:1; - UINT32 RsvdZ1:1; - UINT32 ED:1; - UINT32 RsvdZ2:7; - UINT32 Type:6; - UINT32 EndpointId:5; - UINT32 RsvdZ3:3; - UINT32 SlotId:8; -} EVT_TRB_TRANSFER; - -// -// 6.4.2.2 Command Completion Event TRB -// A Command Completion Event TRB shall be generated by the xHC when a command completes on the -// Command Ring. Refer to section 4.11.4 for more information on the use of Command Completion Events. -// -typedef struct _EVT_TRB_COMMAND_COMPLETION { - UINT32 TRBPtrLo; - - UINT32 TRBPtrHi; - - UINT32 RsvdZ2:24; - UINT32 Completecode:8; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 VFID:8; - UINT32 SlotId:8; -} EVT_TRB_COMMAND_COMPLETION; - -typedef union _TRB { - TRB_TEMPLATE TrbTemplate; - TRANSFER_TRB_NORMAL TrbNormal; - TRANSFER_TRB_CONTROL_SETUP TrbCtrSetup; - TRANSFER_TRB_CONTROL_DATA TrbCtrData; - TRANSFER_TRB_CONTROL_STATUS TrbCtrStatus; -} TRB; - -// -// 6.4.3.1 No Op Command TRB -// The No Op Command TRB provides a simple means for verifying the operation of the Command Ring -// mechanisms offered by the xHCI. -// -typedef struct _CMD_TRB_NO_OP { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 RsvdZ4:16; -} CMD_TRB_NO_OP; - -// -// 6.4.3.2 Enable Slot Command TRB -// The Enable Slot Command TRB causes the xHC to select an available Device Slot and return the ID of the -// selected slot to the host in a Command Completion Event. -// -typedef struct _CMD_TRB_ENABLE_SLOT { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 RsvdZ4:16; -} CMD_TRB_ENABLE_SLOT; - -// -// 6.4.3.3 Disable Slot Command TRB -// The Disable Slot Command TRB releases any bandwidth assigned to the disabled slot and frees any -// internal xHC resources assigned to the slot. -// -typedef struct _CMD_TRB_DISABLE_SLOT { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 RsvdZ4:8; - UINT32 SlotId:8; -} CMD_TRB_DISABLE_SLOT; - -// -// 6.4.3.4 Address Device Command TRB -// The Address Device Command TRB transitions the selected Device Context from the Default to the -// Addressed state and causes the xHC to select an address for the USB device in the Default State and -// issue a SET_ADDRESS request to the USB device. -// -typedef struct _CMD_TRB_ADDRESS_DEVICE { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:8; - UINT32 BSR:1; - UINT32 Type:6; - UINT32 RsvdZ3:8; - UINT32 SlotId:8; -} CMD_TRB_ADDRESS_DEVICE; - -// -// 6.4.3.5 Configure Endpoint Command TRB -// The Configure Endpoint Command TRB evaluates the bandwidth and resource requirements of the -// endpoints selected by the command. -// -typedef struct _CMD_TRB_CONFIG_ENDPOINT { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:8; - UINT32 DC:1; - UINT32 Type:6; - UINT32 RsvdZ3:8; - UINT32 SlotId:8; -} CMD_TRB_CONFIG_ENDPOINT; - -// -// 6.4.3.6 Evaluate Context Command TRB -// The Evaluate Context Command TRB is used by system software to inform the xHC that the selected -// Context data structures in the Device Context have been modified by system software and that the xHC -// shall evaluate any changes -// -typedef struct _CMD_TRB_EVALUATE_CONTEXT { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:9; - UINT32 Type:6; - UINT32 RsvdZ3:8; - UINT32 SlotId:8; -} CMD_TRB_EVALUATE_CONTEXT; - -// -// 6.4.3.7 Reset Endpoint Command TRB -// The Reset Endpoint Command TRB is used by system software to reset a specified Transfer Ring -// -typedef struct _CMD_TRB_RESET_ENDPOINT { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:8; - UINT32 TSP:1; - UINT32 Type:6; - UINT32 EDID:5; - UINT32 RsvdZ4:3; - UINT32 SlotId:8; -} CMD_TRB_RESET_ENDPOINT; - -// -// 6.4.3.8 Stop Endpoint Command TRB -// The Stop Endpoint Command TRB command allows software to stop the xHC execution of the TDs on a -// Transfer Ring and temporarily take ownership of TDs that had previously been passed to the xHC. -// -typedef struct _CMD_TRB_STOP_ENDPOINT { - UINT32 RsvdZ0; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - - UINT32 CycleBit:1; - UINT32 RsvdZ3:9; - UINT32 Type:6; - UINT32 EDID:5; - UINT32 RsvdZ4:2; - UINT32 SP:1; - UINT32 SlotId:8; -} CMD_TRB_STOP_ENDPOINT; - -// -// 6.4.3.9 Set TR Dequeue Pointer Command TRB -// The Set TR Dequeue Pointer Command TRB is used by system software to modify the TR Dequeue -// Pointer and DCS fields of an Endpoint or Stream Context. -// -typedef struct _CMD_SET_TR_DEQ_POINTER { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1:16; - UINT32 StreamID:16; - - UINT32 CycleBit:1; - UINT32 RsvdZ2:9; - UINT32 Type:6; - UINT32 Endpoint:5; - UINT32 RsvdZ3:3; - UINT32 SlotId:8; -} CMD_SET_TR_DEQ_POINTER; - -// -// 6.4.4.1 Link TRB -// A Link TRB provides support for non-contiguous TRB Rings. -// -typedef struct _LINK_TRB { - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 RsvdZ1:22; - UINT32 InterTarget:10; - - UINT32 CycleBit:1; - UINT32 TC:1; - UINT32 RsvdZ2:2; - UINT32 CH:1; - UINT32 IOC:1; - UINT32 RsvdZ3:4; - UINT32 Type:6; - UINT32 RsvdZ4:16; -} LINK_TRB; - -// -// 6.2.2 Slot Context -// -typedef struct _SLOT_CONTEXT { - UINT32 RouteString:20; - UINT32 Speed:4; - UINT32 RsvdZ1:1; - UINT32 MTT:1; - UINT32 Hub:1; - UINT32 ContextEntries:5; - - UINT32 MaxExitLatency:16; - UINT32 RootHubPortNum:8; - UINT32 PortNum:8; - - UINT32 TTHubSlotId:8; - UINT32 TTPortNum:8; - UINT32 TTT:2; - UINT32 RsvdZ2:4; - UINT32 InterTarget:10; - - UINT32 DeviceAddress:8; - UINT32 RsvdZ3:19; - UINT32 SlotState:5; - - UINT32 RsvdZ4; - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; -} SLOT_CONTEXT; - -typedef struct _SLOT_CONTEXT_64 { - UINT32 RouteString:20; - UINT32 Speed:4; - UINT32 RsvdZ1:1; - UINT32 MTT:1; - UINT32 Hub:1; - UINT32 ContextEntries:5; - - UINT32 MaxExitLatency:16; - UINT32 RootHubPortNum:8; - UINT32 PortNum:8; - - UINT32 TTHubSlotId:8; - UINT32 TTPortNum:8; - UINT32 TTT:2; - UINT32 RsvdZ2:4; - UINT32 InterTarget:10; - - UINT32 DeviceAddress:8; - UINT32 RsvdZ3:19; - UINT32 SlotState:5; - - UINT32 RsvdZ4; - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; - - UINT32 RsvdZ8; - UINT32 RsvdZ9; - UINT32 RsvdZ10; - UINT32 RsvdZ11; - - UINT32 RsvdZ12; - UINT32 RsvdZ13; - UINT32 RsvdZ14; - UINT32 RsvdZ15; - -} SLOT_CONTEXT_64; - - -// -// 6.2.3 Endpoint Context -// -typedef struct _ENDPOINT_CONTEXT { - UINT32 EPState:3; - UINT32 RsvdZ1:5; - UINT32 Mult:2; - UINT32 MaxPStreams:5; - UINT32 LSA:1; - UINT32 Interval:8; - UINT32 RsvdZ2:8; - - UINT32 RsvdZ3:1; - UINT32 CErr:2; - UINT32 EPType:3; - UINT32 RsvdZ4:1; - UINT32 HID:1; - UINT32 MaxBurstSize:8; - UINT32 MaxPacketSize:16; - - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 AverageTRBLength:16; - UINT32 MaxESITPayload:16; - - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; -} ENDPOINT_CONTEXT; - -typedef struct _ENDPOINT_CONTEXT_64 { - UINT32 EPState:3; - UINT32 RsvdZ1:5; - UINT32 Mult:2; - UINT32 MaxPStreams:5; - UINT32 LSA:1; - UINT32 Interval:8; - UINT32 RsvdZ2:8; - - UINT32 RsvdZ3:1; - UINT32 CErr:2; - UINT32 EPType:3; - UINT32 RsvdZ4:1; - UINT32 HID:1; - UINT32 MaxBurstSize:8; - UINT32 MaxPacketSize:16; - - UINT32 PtrLo; - - UINT32 PtrHi; - - UINT32 AverageTRBLength:16; - UINT32 MaxESITPayload:16; - - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; - - UINT32 RsvdZ8; - UINT32 RsvdZ9; - UINT32 RsvdZ10; - UINT32 RsvdZ11; - - UINT32 RsvdZ12; - UINT32 RsvdZ13; - UINT32 RsvdZ14; - UINT32 RsvdZ15; - -} ENDPOINT_CONTEXT_64; - - -// -// 6.2.5.1 Input Control Context -// -typedef struct _INPUT_CONTRL_CONTEXT { - UINT32 Dword1; - UINT32 Dword2; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - UINT32 RsvdZ3; - UINT32 RsvdZ4; - UINT32 RsvdZ5; - UINT32 RsvdZ6; -} INPUT_CONTRL_CONTEXT; - -typedef struct _INPUT_CONTRL_CONTEXT_64 { - UINT32 Dword1; - UINT32 Dword2; - UINT32 RsvdZ1; - UINT32 RsvdZ2; - UINT32 RsvdZ3; - UINT32 RsvdZ4; - UINT32 RsvdZ5; - UINT32 RsvdZ6; - UINT32 RsvdZ7; - UINT32 RsvdZ8; - UINT32 RsvdZ9; - UINT32 RsvdZ10; - UINT32 RsvdZ11; - UINT32 RsvdZ12; - UINT32 RsvdZ13; - UINT32 RsvdZ14; -} INPUT_CONTRL_CONTEXT_64; - -// -// 6.2.1 Device Context -// -typedef struct _DEVICE_CONTEXT { - SLOT_CONTEXT Slot; - ENDPOINT_CONTEXT EP[31]; -} DEVICE_CONTEXT; - -typedef struct _DEVICE_CONTEXT_64 { - SLOT_CONTEXT_64 Slot; - ENDPOINT_CONTEXT_64 EP[31]; -} DEVICE_CONTEXT_64; - -// -// 6.2.5 Input Context -// -typedef struct _INPUT_CONTEXT { - INPUT_CONTRL_CONTEXT InputControlContext; - SLOT_CONTEXT Slot; - ENDPOINT_CONTEXT EP[31]; -} INPUT_CONTEXT; - -typedef struct _INPUT_CONTEXT_64 { - INPUT_CONTRL_CONTEXT_64 InputControlContext; - SLOT_CONTEXT_64 Slot; - ENDPOINT_CONTEXT_64 EP[31]; -} INPUT_CONTEXT_64; - -/** - Execute the transfer by polling the URB. This is a synchronous operation. - - @param Xhc The XHCI device. - @param CmdTransfer The executed URB is for cmd transfer or not. - @param Urb The URB to execute. - @param Timeout The time to wait before abort, in millisecond. - - @return EFI_DEVICE_ERROR The transfer failed due to transfer error. - @return EFI_TIMEOUT The transfer failed due to time out. - @return EFI_SUCCESS The transfer finished OK. - -**/ -EFI_STATUS -XhcPeiExecTransfer ( - IN PEI_XHC_DEV *Xhc, - IN BOOLEAN CmdTransfer, - IN URB *Urb, - IN UINTN Timeout - ); - -/** - Find out the actual device address according to the requested device address from UsbBus. - - @param Xhc The XHCI device. - @param BusDevAddr The requested device address by UsbBus upper driver. - - @return The actual device address assigned to the device. - -**/ -UINT8 -XhcPeiBusDevAddrToSlotId ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 BusDevAddr - ); - -/** - Find out the slot id according to the device's route string. - - @param Xhc The XHCI device. - @param RouteString The route string described the device location. - - @return The slot id used by the device. - -**/ -UINT8 -XhcPeiRouteStringToSlotId ( - IN PEI_XHC_DEV *Xhc, - IN USB_DEV_ROUTE RouteString - ); - -/** - Calculate the device context index by endpoint address and direction. - - @param EpAddr The target endpoint number. - @param Direction The direction of the target endpoint. - - @return The device context index of endpoint. - -**/ -UINT8 -XhcPeiEndpointToDci ( - IN UINT8 EpAddr, - IN EFI_USB_DATA_DIRECTION Direction - ); - -/** - Ring the door bell to notify XHCI there is a transaction to be executed. - - @param Xhc The XHCI device. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - -**/ -VOID -XhcPeiRingDoorBell ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ); - -/** - Monitor the port status change. Enable/Disable device slot if there is a device attached/detached. - - @param Xhc The XHCI device. - @param ParentRouteChart The route string pointed to the parent device if it exists. - @param Port The port to be polled. - @param PortState The port state. - - @retval EFI_SUCCESS Successfully enable/disable device slot according to port state. - @retval Others Should not appear. - -**/ -EFI_STATUS -XhcPeiPollPortStatusChange ( - IN PEI_XHC_DEV *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT8 Port, - IN EFI_USB_PORT_STATUS *PortState - ); - -/** - Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be configured. - @param PortNum The total number of downstream port supported by the hub. - @param TTT The TT think time of the hub device. - @param MTT The multi-TT of the hub device. - - @retval EFI_SUCCESS Successfully configure the hub device's slot context. - -**/ -EFI_STATUS -XhcPeiConfigHubContext ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 PortNum, - IN UINT8 TTT, - IN UINT8 MTT - ); - -/** - Evaluate the slot context for hub device through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be configured. - @param PortNum The total number of downstream port supported by the hub. - @param TTT The TT think time of the hub device. - @param MTT The multi-TT of the hub device. - - @retval EFI_SUCCESS Successfully configure the hub device's slot context. - -**/ -EFI_STATUS -XhcPeiConfigHubContext64 ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 PortNum, - IN UINT8 TTT, - IN UINT8 MTT - ); - -/** - Configure all the device endpoints through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - - @retval EFI_SUCCESS Successfully configure all the device endpoints. - -**/ -EFI_STATUS -XhcPeiSetConfigCmd ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc - ); - -/** - Configure all the device endpoints through XHCI's Configure_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be configured. - @param DeviceSpeed The device's speed. - @param ConfigDesc The pointer to the usb device configuration descriptor. - - @retval EFI_SUCCESS Successfully configure all the device endpoints. - -**/ -EFI_STATUS -XhcPeiSetConfigCmd64 ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 DeviceSpeed, - IN USB_CONFIG_DESCRIPTOR *ConfigDesc - ); - -/** - Stop endpoint through XHCI's Stop_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - - @retval EFI_SUCCESS Stop endpoint successfully. - @retval Others Failed to stop endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcPeiStopEndpoint ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ); - -/** - Reset endpoint through XHCI's Reset_Endpoint cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - - @retval EFI_SUCCESS Reset endpoint successfully. - @retval Others Failed to reset endpoint. - -**/ -EFI_STATUS -EFIAPI -XhcPeiResetEndpoint ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci - ); - -/** - Set transfer ring dequeue pointer through XHCI's Set_Tr_Dequeue_Pointer cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id of the target device. - @param Dci The device context index of the target slot or endpoint. - @param Urb The dequeue pointer of the transfer ring specified - by the urb to be updated. - - @retval EFI_SUCCESS Set transfer ring dequeue pointer succeeds. - @retval Others Failed to set transfer ring dequeue pointer. - -**/ -EFI_STATUS -EFIAPI -XhcPeiSetTrDequeuePointer ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT8 Dci, - IN URB *Urb - ); - -/** - Assign and initialize the device slot for a new device. - - @param Xhc The XHCI device. - @param ParentRouteChart The route string pointed to the parent device. - @param ParentPort The port at which the device is located. - @param RouteChart The route string pointed to the device. - @param DeviceSpeed The device speed. - - @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it. - @retval Others Fail to initialize device slot. - -**/ -EFI_STATUS -XhcPeiInitializeDeviceSlot ( - IN PEI_XHC_DEV *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT16 ParentPort, - IN USB_DEV_ROUTE RouteChart, - IN UINT8 DeviceSpeed - ); - -/** - Assign and initialize the device slot for a new device. - - @param Xhc The XHCI device. - @param ParentRouteChart The route string pointed to the parent device. - @param ParentPort The port at which the device is located. - @param RouteChart The route string pointed to the device. - @param DeviceSpeed The device speed. - - @retval EFI_SUCCESS Successfully assign a slot to the device and assign an address to it. - @retval Others Fail to initialize device slot. - -**/ -EFI_STATUS -XhcPeiInitializeDeviceSlot64 ( - IN PEI_XHC_DEV *Xhc, - IN USB_DEV_ROUTE ParentRouteChart, - IN UINT16 ParentPort, - IN USB_DEV_ROUTE RouteChart, - IN UINT8 DeviceSpeed - ); - -/** - Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be evaluated. - @param MaxPacketSize The max packet size supported by the device control transfer. - - @retval EFI_SUCCESS Successfully evaluate the device endpoint 0. - -**/ -EFI_STATUS -XhcPeiEvaluateContext ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT32 MaxPacketSize - ); - -/** - Evaluate the endpoint 0 context through XHCI's Evaluate_Context cmd. - - @param Xhc The XHCI device. - @param SlotId The slot id to be evaluated. - @param MaxPacketSize The max packet size supported by the device control transfer. - - @retval EFI_SUCCESS Successfully evaluate the device endpoint 0. - -**/ -EFI_STATUS -XhcPeiEvaluateContext64 ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId, - IN UINT32 MaxPacketSize - ); - -/** - Disable the specified device slot. - - @param Xhc The XHCI device. - @param SlotId The slot id to be disabled. - - @retval EFI_SUCCESS Successfully disable the device slot. - -**/ -EFI_STATUS -XhcPeiDisableSlotCmd ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId - ); - -/** - Disable the specified device slot. - - @param Xhc The XHCI device. - @param SlotId The slot id to be disabled. - - @retval EFI_SUCCESS Successfully disable the device slot. - -**/ -EFI_STATUS -XhcPeiDisableSlotCmd64 ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 SlotId - ); - -/** - System software shall use a Reset Endpoint Command (section 4.11.4.7) to remove the Halted - condition in the xHC. After the successful completion of the Reset Endpoint Command, the Endpoint - Context is transitioned from the Halted to the Stopped state and the Transfer Ring of the endpoint is - reenabled. The next write to the Doorbell of the Endpoint will transition the Endpoint Context from the - Stopped to the Running state. - - @param Xhc The XHCI device. - @param Urb The urb which makes the endpoint halted. - - @retval EFI_SUCCESS The recovery is successful. - @retval Others Failed to recovery halted endpoint. - -**/ -EFI_STATUS -XhcPeiRecoverHaltedEndpoint ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ); - -/** - System software shall use a Stop Endpoint Command (section 4.6.9) and the Set TR Dequeue Pointer - Command (section 4.6.10) to remove the timed-out TDs from the xHC transfer ring. The next write to - the Doorbell of the Endpoint will transition the Endpoint Context from the Stopped to the Running - state. - - @param Xhc The XHCI device. - @param Urb The urb which doesn't get completed in a specified timeout range. - - @retval EFI_SUCCESS The dequeuing of the TDs is successful. - @retval Others Failed to stop the endpoint and dequeue the TDs. - -**/ -EFI_STATUS -XhcPeiDequeueTrbFromEndpoint ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ); - -/** - Create a new URB for a new transaction. - - @param Xhc The XHCI device - @param DevAddr The device address - @param EpAddr Endpoint addrress - @param DevSpeed The device speed - @param MaxPacket The max packet length of the endpoint - @param Type The transaction type - @param Request The standard USB request for control transfer - @param Data The user data to transfer - @param DataLen The length of data buffer - @param Callback The function to call when data is transferred - @param Context The context to the callback - - @return Created URB or NULL - -**/ -URB* -XhcPeiCreateUrb ( - IN PEI_XHC_DEV *Xhc, - IN UINT8 DevAddr, - IN UINT8 EpAddr, - IN UINT8 DevSpeed, - IN UINTN MaxPacket, - IN UINTN Type, - IN EFI_USB_DEVICE_REQUEST *Request, - IN VOID *Data, - IN UINTN DataLen, - IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, - IN VOID *Context - ); - -/** - Free an allocated URB. - - @param Xhc The XHCI device. - @param Urb The URB to free. - -**/ -VOID -XhcPeiFreeUrb ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ); - -/** - Create a transfer TRB. - - @param Xhc The XHCI device - @param Urb The urb used to construct the transfer TRB. - - @return Created TRB or NULL - -**/ -EFI_STATUS -XhcPeiCreateTransferTrb ( - IN PEI_XHC_DEV *Xhc, - IN URB *Urb - ); - -/** - Synchronize the specified transfer ring to update the enqueue and dequeue pointer. - - @param Xhc The XHCI device. - @param TrsRing The transfer ring to sync. - - @retval EFI_SUCCESS The transfer ring is synchronized successfully. - -**/ -EFI_STATUS -XhcPeiSyncTrsRing ( - IN PEI_XHC_DEV *Xhc, - IN TRANSFER_RING *TrsRing - ); - -/** - Create XHCI transfer ring. - - @param Xhc The XHCI Device. - @param TrbNum The number of TRB in the ring. - @param TransferRing The created transfer ring. - -**/ -VOID -XhcPeiCreateTransferRing ( - IN PEI_XHC_DEV *Xhc, - IN UINTN TrbNum, - OUT TRANSFER_RING *TransferRing - ); - -/** - Check if there is a new generated event. - - @param Xhc The XHCI device. - @param EvtRing The event ring to check. - @param NewEvtTrb The new event TRB found. - - @retval EFI_SUCCESS Found a new event TRB at the event ring. - @retval EFI_NOT_READY The event ring has no new event. - -**/ -EFI_STATUS -XhcPeiCheckNewEvent ( - IN PEI_XHC_DEV *Xhc, - IN EVENT_RING *EvtRing, - OUT TRB_TEMPLATE **NewEvtTrb - ); - -/** - Synchronize the specified event ring to update the enqueue and dequeue pointer. - - @param Xhc The XHCI device. - @param EvtRing The event ring to sync. - - @retval EFI_SUCCESS The event ring is synchronized successfully. - -**/ -EFI_STATUS -XhcPeiSyncEventRing ( - IN PEI_XHC_DEV *Xhc, - IN EVENT_RING *EvtRing - ); - -/** - Create XHCI event ring. - - @param Xhc The XHCI device. - @param EventRing The created event ring. - -**/ -VOID -XhcPeiCreateEventRing ( - IN PEI_XHC_DEV *Xhc, - OUT EVENT_RING *EventRing - ); - -/** - Initialize the XHCI host controller for schedule. - - @param Xhc The XHCI device to be initialized. - -**/ -VOID -XhcPeiInitSched ( - IN PEI_XHC_DEV *Xhc - ); - -/** - Free the resouce allocated at initializing schedule. - - @param Xhc The XHCI device. - -**/ -VOID -XhcPeiFreeSched ( - IN PEI_XHC_DEV *Xhc - ); - -#endif -- cgit v1.2.3