| 1 | /*++\r |
| 2 | \r |
| 3 | Copyright (c) 2006, Intel Corporation \r |
| 4 | All rights reserved. This program and the accompanying materials \r |
| 5 | are licensed and made available under the terms and conditions of the BSD License \r |
| 6 | which accompanies this distribution. The full text of the license may be found at \r |
| 7 | http://opensource.org/licenses/bsd-license.php \r |
| 8 | \r |
| 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r |
| 10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r |
| 11 | \r |
| 12 | Module Name:\r |
| 13 | \r |
| 14 | CirrusLogic5430.c\r |
| 15 | \r |
| 16 | Abstract:\r |
| 17 | \r |
| 18 | Cirrus Logic 5430 Controller Driver.\r |
| 19 | This driver is a sample implementation of the UGA Draw Protocol for the\r |
| 20 | Cirrus Logic 5430 family of PCI video controllers. This driver is only\r |
| 21 | usable in the EFI pre-boot environment. This sample is intended to show\r |
| 22 | how the UGA Draw Protocol is able to function. The UGA I/O Protocol is not\r |
| 23 | implemented in this sample. A fully compliant EFI UGA driver requires both\r |
| 24 | the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's\r |
| 25 | documentation on UGA for details on how to write a UGA driver that is able\r |
| 26 | to function both in the EFI pre-boot environment and from the OS runtime.\r |
| 27 | \r |
| 28 | Revision History:\r |
| 29 | \r |
| 30 | --*/\r |
| 31 | \r |
| 32 | //\r |
| 33 | // Cirrus Logic 5430 Controller Driver\r |
| 34 | //\r |
| 35 | \r |
| 36 | #include "CirrusLogic5430.h"\r |
| 37 | \r |
| 38 | EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = {\r |
| 39 | CirrusLogic5430ControllerDriverSupported,\r |
| 40 | CirrusLogic5430ControllerDriverStart,\r |
| 41 | CirrusLogic5430ControllerDriverStop,\r |
| 42 | 0x10,\r |
| 43 | NULL,\r |
| 44 | NULL\r |
| 45 | };\r |
| 46 | \r |
| 47 | EFI_STATUS\r |
| 48 | EFIAPI\r |
| 49 | CirrusLogic5430ControllerDriverSupported (\r |
| 50 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r |
| 51 | IN EFI_HANDLE Controller,\r |
| 52 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r |
| 53 | )\r |
| 54 | /*++\r |
| 55 | \r |
| 56 | Routine Description:\r |
| 57 | \r |
| 58 | Arguments:\r |
| 59 | \r |
| 60 | Returns:\r |
| 61 | \r |
| 62 | None\r |
| 63 | \r |
| 64 | --*/\r |
| 65 | // TODO: This - add argument and description to function comment\r |
| 66 | // TODO: Controller - add argument and description to function comment\r |
| 67 | // TODO: RemainingDevicePath - add argument and description to function comment\r |
| 68 | {\r |
| 69 | EFI_STATUS Status;\r |
| 70 | EFI_PCI_IO_PROTOCOL *PciIo;\r |
| 71 | PCI_TYPE00 Pci;\r |
| 72 | \r |
| 73 | //\r |
| 74 | // Open the PCI I/O Protocol\r |
| 75 | //\r |
| 76 | Status = gBS->OpenProtocol (\r |
| 77 | Controller,\r |
| 78 | &gEfiPciIoProtocolGuid,\r |
| 79 | (VOID **) &PciIo,\r |
| 80 | This->DriverBindingHandle,\r |
| 81 | Controller,\r |
| 82 | EFI_OPEN_PROTOCOL_BY_DRIVER\r |
| 83 | );\r |
| 84 | if (EFI_ERROR (Status)) {\r |
| 85 | return Status;\r |
| 86 | }\r |
| 87 | \r |
| 88 | //\r |
| 89 | // Read the PCI Configuration Header from the PCI Device\r |
| 90 | //\r |
| 91 | Status = PciIo->Pci.Read (\r |
| 92 | PciIo,\r |
| 93 | EfiPciIoWidthUint32,\r |
| 94 | 0,\r |
| 95 | sizeof (Pci) / sizeof (UINT32),\r |
| 96 | &Pci\r |
| 97 | );\r |
| 98 | if (EFI_ERROR (Status)) {\r |
| 99 | goto Done;\r |
| 100 | }\r |
| 101 | \r |
| 102 | Status = EFI_UNSUPPORTED;\r |
| 103 | //\r |
| 104 | // See if the I/O enable is on. Most systems only allow one VGA device to be turned on\r |
| 105 | // at a time, so see if this is one that is turned on.\r |
| 106 | //\r |
| 107 | // if (((Pci.Hdr.Command & 0x01) == 0x01)) {\r |
| 108 | //\r |
| 109 | // See if this is a Cirrus Logic PCI controller\r |
| 110 | //\r |
| 111 | if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {\r |
| 112 | //\r |
| 113 | // See if this is a 5430 or a 5446 PCI controller\r |
| 114 | //\r |
| 115 | if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID) {\r |
| 116 | Status = EFI_SUCCESS;\r |
| 117 | }\r |
| 118 | \r |
| 119 | if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID) {\r |
| 120 | Status = EFI_SUCCESS;\r |
| 121 | }\r |
| 122 | \r |
| 123 | if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {\r |
| 124 | Status = EFI_SUCCESS;\r |
| 125 | }\r |
| 126 | }\r |
| 127 | \r |
| 128 | Done:\r |
| 129 | //\r |
| 130 | // Close the PCI I/O Protocol\r |
| 131 | //\r |
| 132 | gBS->CloseProtocol (\r |
| 133 | Controller,\r |
| 134 | &gEfiPciIoProtocolGuid,\r |
| 135 | This->DriverBindingHandle,\r |
| 136 | Controller\r |
| 137 | );\r |
| 138 | \r |
| 139 | return Status;\r |
| 140 | }\r |
| 141 | \r |
| 142 | EFI_STATUS\r |
| 143 | EFIAPI\r |
| 144 | CirrusLogic5430ControllerDriverStart (\r |
| 145 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r |
| 146 | IN EFI_HANDLE Controller,\r |
| 147 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r |
| 148 | )\r |
| 149 | /*++\r |
| 150 | \r |
| 151 | Routine Description:\r |
| 152 | \r |
| 153 | Arguments:\r |
| 154 | \r |
| 155 | Returns:\r |
| 156 | \r |
| 157 | None\r |
| 158 | \r |
| 159 | --*/\r |
| 160 | // TODO: This - add argument and description to function comment\r |
| 161 | // TODO: Controller - add argument and description to function comment\r |
| 162 | // TODO: RemainingDevicePath - add argument and description to function comment\r |
| 163 | {\r |
| 164 | EFI_STATUS Status;\r |
| 165 | CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;\r |
| 166 | \r |
| 167 | //\r |
| 168 | // Allocate Private context data for UGA Draw inteface.\r |
| 169 | //\r |
| 170 | Private = NULL;\r |
| 171 | Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA));\r |
| 172 | if (Private == NULL) {\r |
| 173 | Status = EFI_OUT_OF_RESOURCES;\r |
| 174 | goto Error;\r |
| 175 | }\r |
| 176 | \r |
| 177 | //\r |
| 178 | // Set up context record\r |
| 179 | //\r |
| 180 | Private->Signature = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;\r |
| 181 | Private->Handle = Controller;\r |
| 182 | \r |
| 183 | //\r |
| 184 | // Open PCI I/O Protocol\r |
| 185 | //\r |
| 186 | Status = gBS->OpenProtocol (\r |
| 187 | Private->Handle,\r |
| 188 | &gEfiPciIoProtocolGuid,\r |
| 189 | (VOID **) &Private->PciIo,\r |
| 190 | This->DriverBindingHandle,\r |
| 191 | Private->Handle,\r |
| 192 | EFI_OPEN_PROTOCOL_BY_DRIVER\r |
| 193 | );\r |
| 194 | if (EFI_ERROR (Status)) {\r |
| 195 | goto Error;\r |
| 196 | }\r |
| 197 | \r |
| 198 | Status = Private->PciIo->Attributes (\r |
| 199 | Private->PciIo,\r |
| 200 | EfiPciIoAttributeOperationEnable,\r |
| 201 | EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r |
| 202 | NULL\r |
| 203 | );\r |
| 204 | if (EFI_ERROR (Status)) {\r |
| 205 | goto Error;\r |
| 206 | }\r |
| 207 | \r |
| 208 | //\r |
| 209 | // Start the UGA Draw software stack.\r |
| 210 | //\r |
| 211 | Status = CirrusLogic5430UgaDrawConstructor (Private);\r |
| 212 | if (EFI_ERROR (Status)) {\r |
| 213 | goto Error;\r |
| 214 | }\r |
| 215 | \r |
| 216 | //\r |
| 217 | // Publish the UGA Draw interface to the world\r |
| 218 | //\r |
| 219 | Status = gBS->InstallMultipleProtocolInterfaces (\r |
| 220 | &Private->Handle,\r |
| 221 | &gEfiUgaDrawProtocolGuid,\r |
| 222 | &Private->UgaDraw,\r |
| 223 | NULL\r |
| 224 | );\r |
| 225 | \r |
| 226 | Error:\r |
| 227 | if (EFI_ERROR (Status)) {\r |
| 228 | if (Private) {\r |
| 229 | if (Private->PciIo) {\r |
| 230 | Private->PciIo->Attributes (\r |
| 231 | Private->PciIo,\r |
| 232 | EfiPciIoAttributeOperationDisable,\r |
| 233 | EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r |
| 234 | NULL\r |
| 235 | );\r |
| 236 | }\r |
| 237 | }\r |
| 238 | \r |
| 239 | //\r |
| 240 | // Close the PCI I/O Protocol\r |
| 241 | //\r |
| 242 | gBS->CloseProtocol (\r |
| 243 | Private->Handle,\r |
| 244 | &gEfiPciIoProtocolGuid,\r |
| 245 | This->DriverBindingHandle,\r |
| 246 | Private->Handle\r |
| 247 | );\r |
| 248 | if (Private) {\r |
| 249 | gBS->FreePool (Private);\r |
| 250 | }\r |
| 251 | }\r |
| 252 | \r |
| 253 | return Status;\r |
| 254 | }\r |
| 255 | \r |
| 256 | EFI_STATUS\r |
| 257 | EFIAPI\r |
| 258 | CirrusLogic5430ControllerDriverStop (\r |
| 259 | IN EFI_DRIVER_BINDING_PROTOCOL *This,\r |
| 260 | IN EFI_HANDLE Controller,\r |
| 261 | IN UINTN NumberOfChildren,\r |
| 262 | IN EFI_HANDLE *ChildHandleBuffer\r |
| 263 | )\r |
| 264 | /*++\r |
| 265 | \r |
| 266 | Routine Description:\r |
| 267 | \r |
| 268 | Arguments:\r |
| 269 | \r |
| 270 | Returns:\r |
| 271 | \r |
| 272 | None\r |
| 273 | \r |
| 274 | --*/\r |
| 275 | // TODO: This - add argument and description to function comment\r |
| 276 | // TODO: Controller - add argument and description to function comment\r |
| 277 | // TODO: NumberOfChildren - add argument and description to function comment\r |
| 278 | // TODO: ChildHandleBuffer - add argument and description to function comment\r |
| 279 | // TODO: EFI_SUCCESS - add return value to function comment\r |
| 280 | {\r |
| 281 | EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r |
| 282 | EFI_STATUS Status;\r |
| 283 | CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;\r |
| 284 | \r |
| 285 | Status = gBS->OpenProtocol (\r |
| 286 | Controller,\r |
| 287 | &gEfiUgaDrawProtocolGuid,\r |
| 288 | (VOID **) &UgaDraw,\r |
| 289 | This->DriverBindingHandle,\r |
| 290 | Controller,\r |
| 291 | EFI_OPEN_PROTOCOL_GET_PROTOCOL\r |
| 292 | );\r |
| 293 | if (EFI_ERROR (Status)) {\r |
| 294 | //\r |
| 295 | // If the UGA Draw interface does not exist the driver is not started\r |
| 296 | //\r |
| 297 | return Status;\r |
| 298 | }\r |
| 299 | \r |
| 300 | //\r |
| 301 | // Get our private context information\r |
| 302 | //\r |
| 303 | Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw);\r |
| 304 | \r |
| 305 | //\r |
| 306 | // Remove the UGA Draw interface from the system\r |
| 307 | //\r |
| 308 | Status = gBS->UninstallMultipleProtocolInterfaces (\r |
| 309 | Private->Handle,\r |
| 310 | &gEfiUgaDrawProtocolGuid,\r |
| 311 | &Private->UgaDraw,\r |
| 312 | NULL\r |
| 313 | );\r |
| 314 | if (EFI_ERROR (Status)) {\r |
| 315 | return Status;\r |
| 316 | }\r |
| 317 | \r |
| 318 | //\r |
| 319 | // Shutdown the hardware\r |
| 320 | //\r |
| 321 | CirrusLogic5430UgaDrawDestructor (Private);\r |
| 322 | \r |
| 323 | Private->PciIo->Attributes (\r |
| 324 | Private->PciIo,\r |
| 325 | EfiPciIoAttributeOperationDisable,\r |
| 326 | EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,\r |
| 327 | NULL\r |
| 328 | );\r |
| 329 | \r |
| 330 | //\r |
| 331 | // Close the PCI I/O Protocol\r |
| 332 | //\r |
| 333 | gBS->CloseProtocol (\r |
| 334 | Controller,\r |
| 335 | &gEfiPciIoProtocolGuid,\r |
| 336 | This->DriverBindingHandle,\r |
| 337 | Controller\r |
| 338 | );\r |
| 339 | \r |
| 340 | //\r |
| 341 | // Free our instance data\r |
| 342 | //\r |
| 343 | gBS->FreePool (Private);\r |
| 344 | \r |
| 345 | return EFI_SUCCESS;\r |
| 346 | }\r |