PcatIsaAcpi.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /** @file
  2. EFI PCAT ISA ACPI Driver for a Generic PC Platform
  3. Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "PcatIsaAcpi.h"
  7. //
  8. // PcatIsaAcpi Driver Binding Protocol
  9. //
  10. EFI_DRIVER_BINDING_PROTOCOL gPcatIsaAcpiDriverBinding = {
  11. PcatIsaAcpiDriverBindingSupported,
  12. PcatIsaAcpiDriverBindingStart,
  13. PcatIsaAcpiDriverBindingStop,
  14. 0xa,
  15. NULL,
  16. NULL
  17. };
  18. /**
  19. the entry point of the PcatIsaAcpi driver.
  20. @param ImageHandle Handle for driver image
  21. @param SystemTable Point to EFI_SYSTEM_TABLE
  22. @return Success or not for installing driver binding protocol
  23. **/
  24. EFI_STATUS
  25. EFIAPI
  26. PcatIsaAcpiDriverEntryPoint (
  27. IN EFI_HANDLE ImageHandle,
  28. IN EFI_SYSTEM_TABLE *SystemTable
  29. )
  30. {
  31. return EfiLibInstallDriverBindingComponentName2 (
  32. ImageHandle,
  33. SystemTable,
  34. &gPcatIsaAcpiDriverBinding,
  35. ImageHandle,
  36. &gPcatIsaAcpiComponentName,
  37. &gPcatIsaAcpiComponentName2
  38. );
  39. }
  40. /**
  41. ControllerDriver Protocol Method
  42. @param This Driver Binding protocol instance pointer.
  43. @param Controller Handle of device to test.
  44. @param RemainingDevicePath Optional parameter use to pick a specific child
  45. device to start.
  46. @retval EFI_SUCCESS This driver supports this device.
  47. @retval other This driver does not support this device.
  48. **/
  49. EFI_STATUS
  50. EFIAPI
  51. PcatIsaAcpiDriverBindingSupported (
  52. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  53. IN EFI_HANDLE Controller,
  54. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  55. )
  56. {
  57. EFI_STATUS Status;
  58. EFI_PCI_IO_PROTOCOL *PciIo;
  59. PCI_TYPE00 Pci;
  60. UINTN SegmentNumber;
  61. UINTN BusNumber;
  62. UINTN DeviceNumber;
  63. UINTN FunctionNumber;
  64. //
  65. // Get PciIo protocol instance
  66. //
  67. Status = gBS->OpenProtocol (
  68. Controller,
  69. &gEfiPciIoProtocolGuid,
  70. (VOID**)&PciIo,
  71. This->DriverBindingHandle,
  72. Controller,
  73. EFI_OPEN_PROTOCOL_BY_DRIVER
  74. );
  75. if (EFI_ERROR(Status)) {
  76. return Status;
  77. }
  78. Status = PciIo->Pci.Read (
  79. PciIo,
  80. EfiPciIoWidthUint32,
  81. 0,
  82. sizeof(Pci) / sizeof(UINT32),
  83. &Pci);
  84. if (!EFI_ERROR (Status)) {
  85. Status = EFI_UNSUPPORTED;
  86. if ((Pci.Hdr.Command & 0x03) == 0x03) {
  87. if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
  88. //
  89. // See if this is a standard PCI to ISA Bridge from the Base Code and Class Code
  90. //
  91. if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
  92. Status = EFI_SUCCESS;
  93. }
  94. //
  95. // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
  96. //
  97. if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE &&
  98. Pci.Hdr.VendorId == 0x8086 ) {
  99. //
  100. // See if this is on Function #0 to avoid false positives on
  101. // PCI_CLASS_BRIDGE_OTHER that has the same value as
  102. // PCI_CLASS_BRIDGE_ISA_PDECODE
  103. //
  104. Status = PciIo->GetLocation (
  105. PciIo,
  106. &SegmentNumber,
  107. &BusNumber,
  108. &DeviceNumber,
  109. &FunctionNumber
  110. );
  111. if (!EFI_ERROR (Status) && FunctionNumber == 0) {
  112. Status = EFI_SUCCESS;
  113. } else {
  114. Status = EFI_UNSUPPORTED;
  115. }
  116. }
  117. }
  118. }
  119. }
  120. gBS->CloseProtocol (
  121. Controller,
  122. &gEfiPciIoProtocolGuid,
  123. This->DriverBindingHandle,
  124. Controller
  125. );
  126. return Status;
  127. }
  128. /**
  129. Install EFI_ISA_ACPI_PROTOCOL.
  130. @param This Driver Binding protocol instance pointer.
  131. @param ControllerHandle Handle of device to bind driver to.
  132. @param RemainingDevicePath Optional parameter use to pick a specific child
  133. device to start.
  134. @retval EFI_SUCCESS This driver is added to ControllerHandle
  135. @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
  136. @retval other This driver does not support this device
  137. **/
  138. EFI_STATUS
  139. EFIAPI
  140. PcatIsaAcpiDriverBindingStart (
  141. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  142. IN EFI_HANDLE Controller,
  143. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  144. )
  145. {
  146. EFI_STATUS Status;
  147. EFI_PCI_IO_PROTOCOL *PciIo;
  148. PCAT_ISA_ACPI_DEV *PcatIsaAcpiDev;
  149. UINT64 Supports;
  150. UINT64 OriginalAttributes;
  151. BOOLEAN Enabled;
  152. Enabled = FALSE;
  153. Supports = 0;
  154. PcatIsaAcpiDev = NULL;
  155. OriginalAttributes = 0;
  156. //
  157. // Open the PCI I/O Protocol Interface
  158. //
  159. PciIo = NULL;
  160. Status = gBS->OpenProtocol (
  161. Controller,
  162. &gEfiPciIoProtocolGuid,
  163. (VOID**)&PciIo,
  164. This->DriverBindingHandle,
  165. Controller,
  166. EFI_OPEN_PROTOCOL_BY_DRIVER
  167. );
  168. if (EFI_ERROR (Status)) {
  169. goto Done;
  170. }
  171. //
  172. // Get supported PCI attributes
  173. //
  174. Status = PciIo->Attributes (
  175. PciIo,
  176. EfiPciIoAttributeOperationSupported,
  177. 0,
  178. &Supports
  179. );
  180. if (EFI_ERROR (Status)) {
  181. goto Done;
  182. }
  183. Supports &= (UINT64) (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);
  184. if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_ISA_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO_16)) {
  185. Status = EFI_UNSUPPORTED;
  186. goto Done;
  187. }
  188. Status = PciIo->Attributes (
  189. PciIo,
  190. EfiPciIoAttributeOperationGet,
  191. 0,
  192. &OriginalAttributes
  193. );
  194. if (EFI_ERROR (Status)) {
  195. goto Done;
  196. }
  197. Status = PciIo->Attributes (
  198. PciIo,
  199. EfiPciIoAttributeOperationEnable,
  200. EFI_PCI_DEVICE_ENABLE | Supports | EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO,
  201. NULL
  202. );
  203. if (EFI_ERROR (Status)) {
  204. goto Done;
  205. }
  206. Enabled = TRUE;
  207. //
  208. // Allocate memory for the PCAT ISA ACPI Device structure
  209. //
  210. PcatIsaAcpiDev = NULL;
  211. Status = gBS->AllocatePool (
  212. EfiBootServicesData,
  213. sizeof(PCAT_ISA_ACPI_DEV),
  214. (VOID**)&PcatIsaAcpiDev
  215. );
  216. if (EFI_ERROR (Status)) {
  217. goto Done;
  218. }
  219. //
  220. // Initialize the PCAT ISA ACPI Device structure
  221. //
  222. PcatIsaAcpiDev->Signature = PCAT_ISA_ACPI_DEV_SIGNATURE;
  223. PcatIsaAcpiDev->Handle = Controller;
  224. PcatIsaAcpiDev->PciIo = PciIo;
  225. PcatIsaAcpiDev->OriginalAttributes = OriginalAttributes;
  226. //
  227. // Initialize PcatIsaAcpiDeviceList
  228. //
  229. InitializePcatIsaAcpiDeviceList ();
  230. //
  231. // IsaAcpi interface
  232. //
  233. (PcatIsaAcpiDev->IsaAcpi).DeviceEnumerate = IsaDeviceEnumerate;
  234. (PcatIsaAcpiDev->IsaAcpi).SetPower = IsaDeviceSetPower;
  235. (PcatIsaAcpiDev->IsaAcpi).GetCurResource = IsaGetCurrentResource;
  236. (PcatIsaAcpiDev->IsaAcpi).GetPosResource = IsaGetPossibleResource;
  237. (PcatIsaAcpiDev->IsaAcpi).SetResource = IsaSetResource;
  238. (PcatIsaAcpiDev->IsaAcpi).EnableDevice = IsaEnableDevice;
  239. (PcatIsaAcpiDev->IsaAcpi).InitDevice = IsaInitDevice;
  240. (PcatIsaAcpiDev->IsaAcpi).InterfaceInit = IsaInterfaceInit;
  241. //
  242. // Install the ISA ACPI Protocol interface
  243. //
  244. Status = gBS->InstallMultipleProtocolInterfaces (
  245. &Controller,
  246. &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi,
  247. NULL
  248. );
  249. Done:
  250. if (EFI_ERROR (Status)) {
  251. if (PciIo != NULL && Enabled) {
  252. PciIo->Attributes (
  253. PciIo,
  254. EfiPciIoAttributeOperationSet,
  255. OriginalAttributes,
  256. NULL
  257. );
  258. }
  259. gBS->CloseProtocol (
  260. Controller,
  261. &gEfiPciIoProtocolGuid,
  262. This->DriverBindingHandle,
  263. Controller
  264. );
  265. if (PcatIsaAcpiDev != NULL) {
  266. gBS->FreePool (PcatIsaAcpiDev);
  267. }
  268. return Status;
  269. }
  270. return EFI_SUCCESS;
  271. }
  272. /**
  273. Stop this driver on ControllerHandle. Support stopping any child handles
  274. created by this driver.
  275. @param This Protocol instance pointer.
  276. @param ControllerHandle Handle of device to stop driver on
  277. @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
  278. children is zero stop the entire bus driver.
  279. @param ChildHandleBuffer List of Child Handles to Stop.
  280. @retval EFI_SUCCESS This driver is removed ControllerHandle
  281. @retval other This driver was not removed from this device
  282. **/
  283. EFI_STATUS
  284. EFIAPI
  285. PcatIsaAcpiDriverBindingStop (
  286. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  287. IN EFI_HANDLE Controller,
  288. IN UINTN NumberOfChildren,
  289. IN EFI_HANDLE *ChildHandleBuffer
  290. )
  291. {
  292. EFI_STATUS Status;
  293. EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
  294. PCAT_ISA_ACPI_DEV *PcatIsaAcpiDev;
  295. //
  296. // Get the ISA ACPI Protocol Interface
  297. //
  298. Status = gBS->OpenProtocol (
  299. Controller,
  300. &gEfiIsaAcpiProtocolGuid,
  301. (VOID**)&IsaAcpi,
  302. This->DriverBindingHandle,
  303. Controller,
  304. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  305. );
  306. if (EFI_ERROR (Status)) {
  307. return Status;
  308. }
  309. //
  310. // Get the PCAT ISA ACPI Device structure from the ISA ACPI Protocol
  311. //
  312. PcatIsaAcpiDev = PCAT_ISA_ACPI_DEV_FROM_THIS (IsaAcpi);
  313. //
  314. // Restore PCI attributes
  315. //
  316. Status = PcatIsaAcpiDev->PciIo->Attributes (
  317. PcatIsaAcpiDev->PciIo,
  318. EfiPciIoAttributeOperationSet,
  319. PcatIsaAcpiDev->OriginalAttributes,
  320. NULL
  321. );
  322. if (EFI_ERROR (Status)) {
  323. return Status;
  324. }
  325. //
  326. // Uninstall protocol interface: EFI_ISA_ACPI_PROTOCOL
  327. //
  328. Status = gBS->UninstallProtocolInterface (
  329. Controller,
  330. &gEfiIsaAcpiProtocolGuid, &PcatIsaAcpiDev->IsaAcpi
  331. );
  332. if (EFI_ERROR (Status)) {
  333. return Status;
  334. }
  335. gBS->CloseProtocol (
  336. Controller,
  337. &gEfiPciIoProtocolGuid,
  338. This->DriverBindingHandle,
  339. Controller
  340. );
  341. gBS->FreePool (PcatIsaAcpiDev);
  342. return EFI_SUCCESS;
  343. }