1 /** @file
2 *
3 *  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
4 *
5 *  This program and the accompanying materials
6 *  are licensed and made available under the terms and conditions of the BSD License
7 *  which accompanies this distribution.  The full text of the license may be found at
8 *  http://opensource.org/licenses/bsd-license.php
9 *
10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14 
15 #include <Uefi.h>
16 #include <Chipset/AArch64.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/ArmLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/DebugLib.h>
22 #include "AArch64Lib.h"
23 #include "ArmLibPrivate.h"
24 #include <Library/ArmArchTimer.h>
25 
26 VOID
27 EFIAPI
ArmArchTimerReadReg(IN ARM_ARCH_TIMER_REGS Reg,OUT VOID * DstBuf)28 ArmArchTimerReadReg (
29     IN   ARM_ARCH_TIMER_REGS   Reg,
30     OUT  VOID                  *DstBuf
31     )
32 {
33   // Check if the Generic/Architecture timer is implemented
34   if (ArmIsArchTimerImplemented ()) {
35 
36     switch (Reg) {
37 
38     case CntFrq:
39       *((UINTN *)DstBuf) = ArmReadCntFrq ();
40       break;
41 
42     case CntPct:
43       *((UINT64 *)DstBuf) = ArmReadCntPct ();
44       break;
45 
46     case CntkCtl:
47       *((UINTN *)DstBuf) = ArmReadCntkCtl();
48       break;
49 
50     case CntpTval:
51       *((UINTN *)DstBuf) = ArmReadCntpTval ();
52       break;
53 
54     case CntpCtl:
55       *((UINTN *)DstBuf) = ArmReadCntpCtl ();
56       break;
57 
58     case CntvTval:
59       *((UINTN *)DstBuf) = ArmReadCntvTval ();
60       break;
61 
62     case CntvCtl:
63       *((UINTN *)DstBuf) = ArmReadCntvCtl ();
64       break;
65 
66     case CntvCt:
67       *((UINT64 *)DstBuf) = ArmReadCntvCt ();
68       break;
69 
70     case CntpCval:
71       *((UINT64 *)DstBuf) = ArmReadCntpCval ();
72       break;
73 
74     case CntvCval:
75       *((UINT64 *)DstBuf) = ArmReadCntvCval ();
76       break;
77 
78     case CntvOff:
79       *((UINT64 *)DstBuf) = ArmReadCntvOff ();
80       break;
81 
82     case CnthCtl:
83     case CnthpTval:
84     case CnthpCtl:
85     case CnthpCval:
86     DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));
87       break;
88 
89     default:
90       DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));
91     }
92   } else {
93     DEBUG ((EFI_D_ERROR, "Attempt to read ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));
94     ASSERT (0);
95   }
96 }
97 
98 VOID
99 EFIAPI
ArmArchTimerWriteReg(IN ARM_ARCH_TIMER_REGS Reg,IN VOID * SrcBuf)100 ArmArchTimerWriteReg (
101     IN   ARM_ARCH_TIMER_REGS   Reg,
102     IN   VOID                  *SrcBuf
103     )
104 {
105   // Check if the Generic/Architecture timer is implemented
106   if (ArmIsArchTimerImplemented ()) {
107 
108     switch (Reg) {
109 
110     case CntFrq:
111       ArmWriteCntFrq (*((UINTN *)SrcBuf));
112       break;
113 
114     case CntPct:
115       DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTPCT \n"));
116       break;
117 
118     case CntkCtl:
119       ArmWriteCntkCtl (*((UINTN *)SrcBuf));
120       break;
121 
122     case CntpTval:
123       ArmWriteCntpTval (*((UINTN *)SrcBuf));
124       break;
125 
126     case CntpCtl:
127       ArmWriteCntpCtl (*((UINTN *)SrcBuf));
128       break;
129 
130     case CntvTval:
131       ArmWriteCntvTval (*((UINTN *)SrcBuf));
132       break;
133 
134     case CntvCtl:
135       ArmWriteCntvCtl (*((UINTN *)SrcBuf));
136       break;
137 
138     case CntvCt:
139       DEBUG ((EFI_D_ERROR, "Can't write to Read Only Register: CNTVCT \n"));
140       break;
141 
142     case CntpCval:
143       ArmWriteCntpCval (*((UINT64 *)SrcBuf) );
144       break;
145 
146     case CntvCval:
147       ArmWriteCntvCval (*((UINT64 *)SrcBuf) );
148       break;
149 
150     case CntvOff:
151       ArmWriteCntvOff (*((UINT64 *)SrcBuf));
152       break;
153 
154     case CnthCtl:
155     case CnthpTval:
156     case CnthpCtl:
157     case CnthpCval:
158       DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));
159       break;
160 
161     default:
162       DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));
163     }
164   } else {
165     DEBUG ((EFI_D_ERROR, "Attempt to write to ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));
166     ASSERT (0);
167   }
168 }
169