]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.c
ArmPkg: add ArmGenericTimerCounterLib implementation using virtual timer
[mirror_edk2.git] / ArmPkg / Library / ArmGenericTimerVirtCounterLib / ArmGenericTimerVirtCounterLib.c
1 /** @file
2
3 Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
4 Copyright (c) 2014, 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 <Library/ArmGenericTimerCounterLib.h>
17 #include <Library/ArmArchTimer.h>
18
19 VOID
20 EFIAPI
21 ArmGenericTimerEnableTimer (
22 VOID
23 )
24 {
25 UINTN TimerCtrlReg;
26
27 ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg);
28 TimerCtrlReg |= ARM_ARCH_TIMER_ENABLE;
29
30 //
31 // When running under KVM, we need to unmask the interrupt on the timer side
32 // as KVM will mask it when servicing the interrupt at the hypervisor level
33 // and delivering the virtual timer interrupt to the guest. Otherwise, the
34 // interrupt will fire again, trapping into the hypervisor again, etc. etc.
35 // This is scheduled to be fixed on the KVM side, but there is no harm in
36 // leaving this in once KVM gets fixed.
37 //
38 TimerCtrlReg &= ~ARM_ARCH_TIMER_IMASK;
39 ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg);
40 }
41
42 VOID
43 EFIAPI
44 ArmGenericTimerDisableTimer (
45 VOID
46 )
47 {
48 UINTN TimerCtrlReg;
49
50 ArmArchTimerReadReg (CntvCtl, (VOID *)&TimerCtrlReg);
51 TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE;
52 ArmArchTimerWriteReg (CntvCtl, (VOID *)&TimerCtrlReg);
53 }
54
55 VOID
56 EFIAPI
57 ArmGenericTimerSetTimerFreq (
58 IN UINTN FreqInHz
59 )
60 {
61 ArmArchTimerWriteReg (CntFrq, (VOID *)&FreqInHz);
62 }
63
64 UINTN
65 EFIAPI
66 ArmGenericTimerGetTimerFreq (
67 VOID
68 )
69 {
70 UINTN ArchTimerFreq = 0;
71 ArmArchTimerReadReg (CntFrq, (VOID *)&ArchTimerFreq);
72 return ArchTimerFreq;
73 }
74
75 UINTN
76 EFIAPI
77 ArmGenericTimerGetTimerVal (
78 VOID
79 )
80 {
81 UINTN ArchTimerValue;
82 ArmArchTimerReadReg (CntvTval, (VOID *)&ArchTimerValue);
83
84 return ArchTimerValue;
85 }
86
87
88 VOID
89 EFIAPI
90 ArmGenericTimerSetTimerVal (
91 IN UINTN Value
92 )
93 {
94 ArmArchTimerWriteReg (CntvTval, (VOID *)&Value);
95 }
96
97 UINT64
98 EFIAPI
99 ArmGenericTimerGetSystemCount (
100 VOID
101 )
102 {
103 UINT64 SystemCount;
104 ArmArchTimerReadReg (CntvCt, (VOID *)&SystemCount);
105
106 return SystemCount;
107 }
108
109 UINTN
110 EFIAPI
111 ArmGenericTimerGetTimerCtrlReg (
112 VOID
113 )
114 {
115 UINTN Value;
116 ArmArchTimerReadReg (CntvCtl, (VOID *)&Value);
117
118 return Value;
119 }
120
121 VOID
122 EFIAPI
123 ArmGenericTimerSetTimerCtrlReg (
124 UINTN Value
125 )
126 {
127 ArmArchTimerWriteReg (CntvCtl, (VOID *)&Value);
128 }
129
130 UINT64
131 EFIAPI
132 ArmGenericTimerGetCompareVal (
133 VOID
134 )
135 {
136 UINT64 Value;
137 ArmArchTimerReadReg (CntvCval, (VOID *)&Value);
138
139 return Value;
140 }
141
142 VOID
143 EFIAPI
144 ArmGenericTimerSetCompareVal (
145 IN UINT64 Value
146 )
147 {
148 ArmArchTimerWriteReg (CntvCval, (VOID *)&Value);
149 }