1 /** @file
2 *
3 *  Copyright (c) 2011 - 2014, 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/ArmV7.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 "ArmV7Lib.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     switch (Reg) {
36     case CntFrq:
37       *((UINTN *)DstBuf) = ArmReadCntFrq ();
38       return;
39 
40     case CntPct:
41       *((UINT64 *)DstBuf) = ArmReadCntPct ();
42       return;
43 
44     case CntkCtl:
45       *((UINTN *)DstBuf) = ArmReadCntkCtl();
46       return;
47 
48     case CntpTval:
49       *((UINTN *)DstBuf) = ArmReadCntpTval ();
50       return;
51 
52     case CntpCtl:
53       *((UINTN *)DstBuf) = ArmReadCntpCtl ();
54       return;
55 
56     case CntvTval:
57       *((UINTN *)DstBuf) = ArmReadCntvTval ();
58       return;
59 
60     case CntvCtl:
61       *((UINTN *)DstBuf) = ArmReadCntvCtl ();
62       return;
63 
64     case CntvCt:
65       *((UINT64 *)DstBuf) = ArmReadCntvCt ();
66       return;
67 
68     case CntpCval:
69       *((UINT64 *)DstBuf) = ArmReadCntpCval ();
70       return;
71 
72     case CntvCval:
73       *((UINT64 *)DstBuf) = ArmReadCntvCval ();
74       return;
75 
76     case CntvOff:
77       *((UINT64 *)DstBuf) = ArmReadCntvOff ();
78       return;
79 
80     case CnthCtl:
81     case CnthpTval:
82     case CnthpCtl:
83     case CnthpCval:
84       DEBUG ((EFI_D_ERROR, "The register is related to Hypervisor Mode. Can't perform requested operation\n "));
85       break;
86 
87     default:
88       DEBUG ((EFI_D_ERROR, "Unknown ARM Generic Timer register %x. \n ", Reg));
89     }
90   } else {
91     DEBUG ((EFI_D_ERROR, "Attempt to read ARM Generic Timer registers. But ARM Generic Timer extension is not implemented \n "));
92     ASSERT (0);
93   }
94 
95   *((UINT64 *)DstBuf) = 0;
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