• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   FDT client library for ARM's TimerDxe
3 
4   Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
5 
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this distribution.  The full text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include <Uefi.h>
17 
18 #include <Library/BaseLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 
23 #include <Protocol/FdtClient.h>
24 
25 #pragma pack (1)
26 typedef struct {
27   UINT32  Type;
28   UINT32  Number;
29   UINT32  Flags;
30 } INTERRUPT_PROPERTY;
31 #pragma pack ()
32 
33 RETURN_STATUS
34 EFIAPI
ArmVirtTimerFdtClientLibConstructor(VOID)35 ArmVirtTimerFdtClientLibConstructor (
36   VOID
37   )
38 {
39   EFI_STATUS                    Status;
40   FDT_CLIENT_PROTOCOL           *FdtClient;
41   CONST INTERRUPT_PROPERTY      *InterruptProp;
42   UINT32                        PropSize;
43   INT32                         SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum;
44   RETURN_STATUS                 PcdStatus;
45 
46   Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
47                   (VOID **)&FdtClient);
48   ASSERT_EFI_ERROR (Status);
49 
50   Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,armv7-timer",
51                         "interrupts", (CONST VOID **)&InterruptProp,
52                         &PropSize);
53   if (Status == EFI_NOT_FOUND) {
54     Status = FdtClient->FindCompatibleNodeProperty (FdtClient,
55                           "arm,armv8-timer", "interrupts",
56                           (CONST VOID **)&InterruptProp,
57                           &PropSize);
58   }
59 
60   if (EFI_ERROR (Status)) {
61     return Status;
62   }
63 
64   //
65   // - interrupts : Interrupt list for secure, non-secure, virtual and
66   //  hypervisor timers, in that order.
67   //
68   ASSERT (PropSize == 36 || PropSize == 48);
69 
70   SecIntrNum = SwapBytes32 (InterruptProp[0].Number)
71                + (InterruptProp[0].Type ? 16 : 0);
72   IntrNum = SwapBytes32 (InterruptProp[1].Number)
73             + (InterruptProp[1].Type ? 16 : 0);
74   VirtIntrNum = SwapBytes32 (InterruptProp[2].Number)
75                 + (InterruptProp[2].Type ? 16 : 0);
76   HypIntrNum = PropSize < 48 ? 0 : SwapBytes32 (InterruptProp[3].Number)
77                                    + (InterruptProp[3].Type ? 16 : 0);
78 
79   DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n",
80     SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum));
81 
82   PcdStatus = PcdSet32S (PcdArmArchTimerSecIntrNum, SecIntrNum);
83   ASSERT_RETURN_ERROR (PcdStatus);
84   PcdStatus = PcdSet32S (PcdArmArchTimerIntrNum, IntrNum);
85   ASSERT_RETURN_ERROR (PcdStatus);
86   PcdStatus = PcdSet32S (PcdArmArchTimerVirtIntrNum, VirtIntrNum);
87   ASSERT_RETURN_ERROR (PcdStatus);
88   PcdStatus = PcdSet32S (PcdArmArchTimerHypIntrNum, HypIntrNum);
89   ASSERT_RETURN_ERROR (PcdStatus);
90 
91   return EFI_SUCCESS;
92 }
93