因為在 EFI Driver Model 這篇文章中有提到了一些概念
但是基於自己還有些模糊的情況下
就找了些Sample Code來強化自己的觀念
使用上會有四個Step
但是基於自己還有些模糊的情況下
就找了些Sample Code來強化自己的觀念
使用上會有四個Step
- Initialize:安裝Driver Binding Protocol
- Support():詢問可不可以支援傳入的Handle
- Start():連結Device 及 Handle
- Stop():斷開Device 及 Handle
在設計上要注意到以下幾點
- 符合EFU Model的規範
- 保持Support函式的輕巧,複雜的I/O工作在Start()的時後再做
EDK的Sample 中有個VgaMainPort.c
Initialize:安裝Driver Binding Protocol
EFI_DRIVER_BINDING_PROTOCOL gPciVgaMiniPortDriverBinding = { PciVgaMiniPortDriverBindingSupported, PciVgaMiniPortDriverBindingStart, PciVgaMiniPortDriverBindingStop, 0x00000000, NULL, NULL }; /** Entrypoint of VGA Mini Port Driver. This function is the entrypoint of UVGA Mini Port Driver. It installs Driver Binding Protocols together with Component Name Protocols. @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. **/ FI_STATUS EFIAPI PciVgaMiniPortDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; Status = EfiLibInstallDriverBindingComponentName2 ( ImageHandle, SystemTable, &gPciVgaMiniPortDriverBinding, ImageHandle, &gPciVgaMiniPortComponentName, &gPciVgaMiniPortComponentName2 ); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
Support():詢問可不可以支援傳入的Handle
/** Check whether VGA Mini Port driver supports this device. @param This The driver binding protocol. @param Controller The controller handle to check. @param RemainingDevicePath The remaining device path. @retval EFI_SUCCESS The driver supports this controller. @retval EFI_UNSUPPORTED This device isn't supported. **/ EFI_STATUS EFIAPI PciVgaMiniPortDriverBindingSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_PCI_IO_PROTOCOL *PciIo; PCI_TYPE00 Pci; // // Open the IO Abstraction(s) needed to perform the supported test // Status = gBS->OpenProtocol ( Controller, &gEfiPciIoProtocolGuid, (VOID **) &PciIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { return Status; } // // See if this is a PCI VGA Controller by looking at the Command register and // Class Code Register // Status = PciIo->Pci.Read ( PciIo, EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci ); if (EFI_ERROR (Status)) { goto Done; } Status = EFI_UNSUPPORTED; // // See if the device is an enabled VGA device. // Most systems can only have on VGA device on at a time. // if (((Pci.Hdr.Command & 0x03) == 0x03) && IS_PCI_VGA (&Pci)) { Status = EFI_SUCCESS; } Done: gBS->CloseProtocol ( Controller, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, Controller ); return Status; }
Start():連結Device 及 Handle
/** Starts the VGA device with this driver. This function consumes PCI I/O Protocol, and installs VGA Mini Port Protocol onto the VGA device handle. @param This The driver binding instance. @param Controller The controller to check. @param RemainingDevicePath The remaining device patch. @retval EFI_SUCCESS The controller is controlled by the driver. @retval EFI_ALREADY_STARTED The controller is already controlled by the driver. @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. **/ EFI_STATUS EFIAPI PciVgaMiniPortDriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; EFI_PCI_IO_PROTOCOL *PciIo; PCI_VGA_MINI_PORT_DEV *PciVgaMiniPortPrivate; PciVgaMiniPortPrivate = NULL; PciIo = NULL; // // Open the IO Abstraction(s) needed // Status = gBS->OpenProtocol ( Controller, &gEfiPciIoProtocolGuid, (VOID **) &PciIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER ); if (EFI_ERROR (Status)) { goto Done; } // // Allocate the private device structure // PciVgaMiniPortPrivate = AllocateZeroPool (sizeof (PCI_VGA_MINI_PORT_DEV)); ASSERT (PciVgaMiniPortPrivate != NULL); // // Initialize the private device structure // PciVgaMiniPortPrivate->Signature = PCI_VGA_MINI_PORT_DEV_SIGNATURE; PciVgaMiniPortPrivate->Handle = Controller; PciVgaMiniPortPrivate->PciIo = PciIo; PciVgaMiniPortPrivate->VgaMiniPort.SetMode = PciVgaMiniPortSetMode; PciVgaMiniPortPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000; PciVgaMiniPortPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4; PciVgaMiniPortPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5; PciVgaMiniPortPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR; PciVgaMiniPortPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; PciVgaMiniPortPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; PciVgaMiniPortPrivate->VgaMiniPort.MaxMode = 1; // // Install VGA Mini Port Protocol // Status = gBS->InstallMultipleProtocolInterfaces ( &Controller, &gEfiVgaMiniPortProtocolGuid, &PciVgaMiniPortPrivate->VgaMiniPort, NULL ); Done: if (EFI_ERROR (Status)) { gBS->CloseProtocol ( Controller, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, Controller ); if (PciVgaMiniPortPrivate != NULL) { FreePool (PciVgaMiniPortPrivate); } } return Status; }
Stop():斷開Device 及 Handle
/** Stop the VGA device with this driver. This function uninstalls VGA Mini Port Protocol from the VGA device handle, and closes PCI I/O Protocol. @param This The driver binding protocol. @param Controller The controller to release. @param NumberOfChildren The child number that opened controller BY_CHILD. @param ChildHandleBuffer The array of child handle. @retval EFI_SUCCESS The controller or children are stopped. @retval EFI_DEVICE_ERROR Failed to stop the driver. **/ EFI_STATUS EFIAPI PciVgaMiniPortDriverBindingStop ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer ) { EFI_STATUS Status; EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort; PCI_VGA_MINI_PORT_DEV *PciVgaMiniPortPrivate; Status = gBS->OpenProtocol ( Controller, &gEfiVgaMiniPortProtocolGuid, (VOID **) &VgaMiniPort, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } PciVgaMiniPortPrivate = PCI_VGA_MINI_PORT_DEV_FROM_THIS (VgaMiniPort); Status = gBS->UninstallProtocolInterface ( Controller, &gEfiVgaMiniPortProtocolGuid, &PciVgaMiniPortPrivate->VgaMiniPort ); if (EFI_ERROR (Status)) { return Status; } gBS->CloseProtocol ( Controller, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, Controller ); FreePool (PciVgaMiniPortPrivate); return EFI_SUCCESS; }
留言
張貼留言