On Tue, 2015-08-18 at 11:43 +0200, Ard Biesheuvel wrote: > On 18 August 2015 at 11:31, Haojian Zhuang <haojian.zhu...@linaro.org> wrote: > > On Tue, 2015-08-18 at 11:22 +0200, Ard Biesheuvel wrote: > >> On 18 August 2015 at 11:04, Haojian Zhuang <haojian.zhu...@linaro.org> > >> wrote: > >> > Support multiple PL061 controllers. > >> > > >> > Contributed-under: TianoCore Contribution Agreement 1.0 > >> > Signed-off-by: Haojian Zhuang <haojian.zhu...@linaro.org> > >> > --- > >> > ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c | 107 > >> > ++++++++++++++------- > >> > .../Drivers/PL061GpioDxe/PL061GpioDxe.inf | 3 +- > >> > ArmPlatformPkg/Include/Drivers/PL061Gpio.h | 40 ++++---- > >> > 3 files changed, 96 insertions(+), 54 deletions(-) > >> > > >> > diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c > >> > b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c > >> > index e8a2094..3027656 100644 > >> > --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c > >> > +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c > >> > @@ -28,6 +28,7 @@ > >> > #include <Drivers/PL061Gpio.h> > >> > > >> > BOOLEAN mPL061Initialized = FALSE; > >> > +PLATFORM_GPIO_CONTROLLER *mPL061PlatformGpio; > >> > > >> > /** > >> > Function implementations > >> > @@ -38,20 +39,31 @@ PL061Identify ( > >> > VOID > >> > ) > >> > { > >> > - // Check if this is a PrimeCell Peripheral > >> > - if ( (MmioRead8 (PL061_GPIO_PCELL_ID0) != 0x0D) > >> > - || (MmioRead8 (PL061_GPIO_PCELL_ID1) != 0xF0) > >> > - || (MmioRead8 (PL061_GPIO_PCELL_ID2) != 0x05) > >> > - || (MmioRead8 (PL061_GPIO_PCELL_ID3) != 0xB1)) { > >> > - return EFI_NOT_FOUND; > >> > + UINTN Index; > >> > + UINT32 RegisterBase; > >> > >> Why is this a 32-bit value? > > > > All registers in PL061 are 32-bit. So we don't need to define UINTN at > > here. > > > > So what happens if the GPIO controller is mapped above 4 GB in physical > memory? >
OK. I'll use 64-bit register base at here. But the original PL061 driver is also using 32-bit register base. We could get the definition from PL061Gpio.h #define PL061_GPIO_DATA_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x000) > >> > @@ -329,6 +367,9 @@ PL061InstallProtocol ( > >> > // > >> > ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid); > >> > > >> > + Status = gBS->LocateProtocol (&gPlatformGpioProtocolGuid, NULL, (VOID > >> > **)&mPL061PlatformGpio); > >> > + ASSERT_EFI_ERROR (Status); > >> > + > >> > >> We should fall back to using the PCD if the protocol cannot be found. > >> This way, we won't break existing users. > >> > > > > I was intended to use fallback. But I think it's not good enough. > > > > 1. If anyone defines the PCD register base in dec file. The fallback > > mechanism will be broken. > > > > Well, you would only look at the PCD if the protocol is not installed, > so I don't see how that would change anything compared to the current > situation. > > > 2. Since every driver is built as module, we must create the driver > > dependency. > > > > Please try and use a BEFORE ... depex instead, you can put it in your > platform GPIO DXE with the file GUID of the PL061 DXE driver. > I tried to use BEFORE in inf. Here's the content in platform gpio inf. [Defines] INF_VERSION = 0x00010005 BASE_NAME = HiKeyGpio FILE_GUID = b51a851c-7bf7-463f-b261-cfb158b7f699 MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 ENTRY_POINT = HiKeyGpioEntryPoint [Protocols] gPlatformGpioProtocolGuid [Depex] BEFORE gEmbeddedGpioProtocolGuid And here's updated PL061 driver. PL061InstallProtocol ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE Handle; GPIO_CONTROLLER *GpioController; // // Make sure the Gpio protocol has not been installed in the system yet. // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid); Status = gBS->LocateProtocol (&gPlatformGpioProtocolGuid, NULL, (VOID **)&mPL061PlatformGpio); DEBUG ((EFI_D_ERROR, "#%a, %d, Status:%r\n", __func__, __LINE__, Status)); if (EFI_ERROR (Status) && (Status == EFI_NOT_FOUND)) { // Create the mPL061PlatformGpio mPL061PlatformGpio = (PLATFORM_GPIO_CONTROLLER *)AllocateZeroPool (sizeof (PLATFORM_GPIO_CONTROLLER) + sizeof (GPIO_CONTROLLER)); if (mPL061PlatformGpio == NULL) { DEBUG ((EFI_D_ERROR, "%a: failed to allocate PLATFORM_GPIO_CONTROLLER\n", __func__)); return EFI_BAD_BUFFER_SIZE; } mPL061PlatformGpio->GpioCount = PL061_GPIO_PINS; mPL061PlatformGpio->GpioControllerCount = 1; mPL061PlatformGpio->GpioControllerSize = sizeof (GPIO_CONTROLLER); mPL061PlatformGpio->GpioController = (GPIO_CONTROLLER *)((UINTN) mPL061PlatformGpio + sizeof (PLATFORM_GPIO_CONTROLLER)); GpioController = mPL061PlatformGpio->GpioController; GpioController->RegisterBase = (UINTN) PcdGet32 (PcdPL061GpioBase); GpioController->GpioIndex = 0; GpioController->InternalGpioCount = PL061_GPIO_PINS; } ... } The log of uefi is in below. add-symbol-file /opt/workspace/boot/uefi/linaro-edk2/Build/HiKey/DEBUG_GCC49/AAR CH64/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe/DEBUG/PL061GpioDxe.dll 0x3D9B3260 Loading driver at 0x0003D9B3000 EntryPoint=0x0003D9B32A8 PL061GpioDxe.efi #PL061InstallProtocol, 377, Status:Not Found add-symbol-file /opt/workspace/boot/uefi/linaro-edk2/Build/HiKey/DEBUG_GCC49/AAR CH64/MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe/DEBUG/En glishDxe.dll 0x3D89E260 Loading driver at 0x0003D89E000 EntryPoint=0x0003D89E2A8 EnglishDxe.efi Driver B51A851C-7BF7-463F-B261-CFB158B7F699 was discovered but not loaded!! HiKeyDetectJumper: failed to set jumper as gpio input It seems that "BEFORE" can't make platform gpio driver loaded just before PL061. It's not loaded at all. > >> > // Install the Embedded GPIO Protocol onto a new handle > >> > Handle = NULL; > >> > Status = gBS->InstallMultipleProtocolInterfaces( > >> > diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf > >> > b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf > >> > index 9d9e4cd..971452c 100644 > >> > --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf > >> > +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf > >> > @@ -45,6 +45,7 @@ > >> > > >> > [Protocols] > >> > gEmbeddedGpioProtocolGuid > >> > + gPlatformGpioProtocolGuid > >> > > >> > [Depex] > >> > - TRUE > >> > + gPlatformGpioProtocolGuid > >> > >> Likewise, this breaks existing users > > > > Withouth this dependency, LocateProtocol() will be invoked before > > InstallMultipleProtocols(). So I have to add the dependency at here. > > > > Where is the InstallMultipleProtocols() call? Are you going to post it as > well? > I didn't post it since it's in the platform gpio driver. And the platform isn't created in edk2 code repository yet. ------------------------------------------------------------------------------ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel