90bf8a9af8764d0cc63cd669f924fbae11e75262
[mirror_edk2.git] / EmbeddedPkg / TemplateCpuDxe / CpuDxe.c
1 /** @file
2
3 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
4
5 All rights reserved. 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 "CpuDxe.h"
16
17
18
19 /**
20 This function flushes the range of addresses from Start to Start+Length
21 from the processor's data cache. If Start is not aligned to a cache line
22 boundary, then the bytes before Start to the preceding cache line boundary
23 are also flushed. If Start+Length is not aligned to a cache line boundary,
24 then the bytes past Start+Length to the end of the next cache line boundary
25 are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be
26 supported. If the data cache is fully coherent with all DMA operations, then
27 this function can just return EFI_SUCCESS. If the processor does not support
28 flushing a range of the data cache, then the entire data cache can be flushed.
29
30 @param This The EFI_CPU_ARCH_PROTOCOL instance.
31 @param Start The beginning physical address to flush from the processor's data
32 cache.
33 @param Length The number of bytes to flush from the processor's data cache. This
34 function may flush more bytes than Length specifies depending upon
35 the granularity of the flush operation that the processor supports.
36 @param FlushType Specifies the type of flush operation to perform.
37
38 @retval EFI_SUCCESS The address range from Start to Start+Length was flushed from
39 the processor's data cache.
40 @retval EFI_UNSUPPORTED The processor does not support the cache flush type specified
41 by FlushType.
42 @retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed
43 from the processor's data cache.
44
45 **/
46 EFI_STATUS
47 EFIAPI
48 CpuFlushCpuDataCache (
49 IN EFI_CPU_ARCH_PROTOCOL *This,
50 IN EFI_PHYSICAL_ADDRESS Start,
51 IN UINT64 Length,
52 IN EFI_CPU_FLUSH_TYPE FlushType
53 )
54 {
55 return FlushCpuDataCache (Start, Length, FlushType);
56 }
57
58
59 /**
60 This function enables interrupt processing by the processor.
61
62 @param This The EFI_CPU_ARCH_PROTOCOL instance.
63
64 @retval EFI_SUCCESS Interrupts are enabled on the processor.
65 @retval EFI_DEVICE_ERROR Interrupts could not be enabled on the processor.
66
67 **/
68 EFI_STATUS
69 EFIAPI
70 CpuEnableInterrupt (
71 IN EFI_CPU_ARCH_PROTOCOL *This
72 )
73 {
74 EnableInterrupts ();
75 return EFI_SUCCESS;
76 }
77
78
79 /**
80 This function disables interrupt processing by the processor.
81
82 @param This The EFI_CPU_ARCH_PROTOCOL instance.
83
84 @retval EFI_SUCCESS Interrupts are disabled on the processor.
85 @retval EFI_DEVICE_ERROR Interrupts could not be disabled on the processor.
86
87 **/
88 EFI_STATUS
89 EFIAPI
90 CpuDisableInterrupt (
91 IN EFI_CPU_ARCH_PROTOCOL *This
92 )
93 /*++
94
95 Routine Description:
96 Disables CPU interrupts.
97
98 Arguments:
99 This - Protocol instance structure
100
101 Returns:
102 EFI_SUCCESS - If interrupts were disabled in the CPU.
103 EFI_DEVICE_ERROR - If interrupts could not be disabled on the CPU.
104
105 --*/
106 {
107 DisableInterrupts ();
108 return EFI_SUCCESS;
109 }
110
111
112 /**
113 This function retrieves the processor's current interrupt state a returns it in
114 State. If interrupts are currently enabled, then TRUE is returned. If interrupts
115 are currently disabled, then FALSE is returned.
116
117 @param This The EFI_CPU_ARCH_PROTOCOL instance.
118 @param State A pointer to the processor's current interrupt state. Set to TRUE if
119 interrupts are enabled and FALSE if interrupts are disabled.
120
121 @retval EFI_SUCCESS The processor's current interrupt state was returned in State.
122 @retval EFI_INVALID_PARAMETER State is NULL.
123
124 **/
125 EFI_STATUS
126 EFIAPI
127 CpuGetInterruptState (
128 IN EFI_CPU_ARCH_PROTOCOL *This,
129 OUT BOOLEAN *State
130 )
131 {
132 if (State == NULL) {
133 return EFI_INVALID_PARAMETER;
134 }
135
136 *State = GetInterruptState ();
137 return EFI_SUCCESS;
138 }
139
140
141 /**
142 This function generates an INIT on the processor. If this function succeeds, then the
143 processor will be reset, and control will not be returned to the caller. If InitType is
144 not supported by this processor, or the processor cannot programmatically generate an
145 INIT without help from external hardware, then EFI_UNSUPPORTED is returned. If an error
146 occurs attempting to generate an INIT, then EFI_DEVICE_ERROR is returned.
147
148 @param This The EFI_CPU_ARCH_PROTOCOL instance.
149 @param InitType The type of processor INIT to perform.
150
151 @retval EFI_SUCCESS The processor INIT was performed. This return code should never be seen.
152 @retval EFI_UNSUPPORTED The processor INIT operation specified by InitType is not supported
153 by this processor.
154 @retval EFI_DEVICE_ERROR The processor INIT failed.
155
156 **/
157 EFI_STATUS
158 EFIAPI
159 CpuInit (
160 IN EFI_CPU_ARCH_PROTOCOL *This,
161 IN EFI_CPU_INIT_TYPE InitType
162 )
163 {
164 return EFI_UNSUPPORTED;
165 }
166
167
168 /**
169 This function registers and enables the handler specified by InterruptHandler for a processor
170 interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
171 handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
172 The installed handler is called once for each processor interrupt or exception.
173
174 @param This The EFI_CPU_ARCH_PROTOCOL instance.
175 @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
176 are enabled and FALSE if interrupts are disabled.
177 @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
178 when a processor interrupt occurs. If this parameter is NULL, then the handler
179 will be uninstalled.
180
181 @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
182 @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
183 previously installed.
184 @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
185 previously installed.
186 @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
187
188 **/
189 EFI_STATUS
190 EFIAPI
191 CpuRegisterInterruptHandler (
192 IN EFI_CPU_ARCH_PROTOCOL *This,
193 IN EFI_EXCEPTION_TYPE InterruptType,
194 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
195 )
196 {
197 return RegisterInterruptHandler (InterruptType, InterruptHandler);
198 }
199
200
201 /**
202 This function reads the processor timer specified by TimerIndex and returns it in TimerValue.
203
204 @param This The EFI_CPU_ARCH_PROTOCOL instance.
205 @param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter
206 must be between 0 and NumberOfTimers-1.
207 @param TimerValue Pointer to the returned timer value.
208 @param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment
209 of TimerValue.
210
211 @retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue.
212 @retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers.
213 @retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.
214 @retval EFI_UNSUPPORTED The processor does not have any readable timers.
215
216 **/
217 EFI_STATUS
218 EFIAPI
219 CpuGetTimerValue (
220 IN EFI_CPU_ARCH_PROTOCOL *This,
221 IN UINT32 TimerIndex,
222 OUT UINT64 *TimerValue,
223 OUT UINT64 *TimerPeriod OPTIONAL
224 )
225 {
226 return GetTimerValue (TimerIndex, TimerValue, TimerPeriod);
227 }
228
229
230 /**
231 This function modifies the attributes for the memory region specified by BaseAddress and
232 Length from their current attributes to the attributes specified by Attributes.
233
234 @param This The EFI_CPU_ARCH_PROTOCOL instance.
235 @param BaseAddress The physical address that is the start address of a memory region.
236 @param Length The size in bytes of the memory region.
237 @param Attributes The bit mask of attributes to set for the memory region.
238
239 @retval EFI_SUCCESS The attributes were set for the memory region.
240 @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by
241 BaseAddress and Length cannot be modified.
242 @retval EFI_INVALID_PARAMETER Length is zero.
243 @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
244 the memory resource range.
245 @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory
246 resource range specified by BaseAddress and Length.
247 The bit mask of attributes is not support for the memory resource
248 range specified by BaseAddress and Length.
249
250 **/
251 EFI_STATUS
252 EFIAPI
253 CpuSetMemoryAttributes (
254 IN EFI_CPU_ARCH_PROTOCOL *This,
255 IN EFI_PHYSICAL_ADDRESS BaseAddress,
256 IN UINT64 Length,
257 IN UINT64 Attributes
258 )
259 {
260 //
261 // This is used to set cachability via the MMU on ARM
262 //
263 // This more about optimization and we can usually run fine if the default
264 // settings for cachability are good.
265 //
266 return EFI_UNSUPPORTED;
267 }
268
269
270
271
272 //
273 // Globals used to initialize the protocol
274 //
275 EFI_HANDLE mCpuHandle = NULL;
276 EFI_CPU_ARCH_PROTOCOL mCpu = {
277 CpuFlushCpuDataCache,
278 CpuEnableInterrupt,
279 CpuDisableInterrupt,
280 CpuGetInterruptState,
281 CpuInit,
282 CpuRegisterInterruptHandler,
283 CpuGetTimerValue,
284 CpuSetMemoryAttributes,
285 0, // NumberOfTimers
286 4, // DmaBufferAlignment
287 };
288
289
290 /**
291 Initialize the state information for the CPU Architectural Protocol
292
293 @param ImageHandle of the loaded driver
294 @param SystemTable Pointer to the System Table
295
296 @retval EFI_SUCCESS Protocol registered
297 @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
298 @retval EFI_DEVICE_ERROR Hardware problems
299
300 **/
301 EFI_STATUS
302 CpuDxeInitialize (
303 IN EFI_HANDLE ImageHandle,
304 IN EFI_SYSTEM_TABLE *SystemTable
305 )
306 {
307 EFI_STATUS Status;
308
309 InitializeExceptions (&mCpu);
310
311 //
312 // Install CPU Architectural Protocol and the thunk protocol
313 //
314 Status = gBS->InstallMultipleProtocolInterfaces (
315 &mCpuHandle,
316 &gEfiCpuArchProtocolGuid, &mCpu,
317 NULL
318 );
319 ASSERT_EFI_ERROR (Status);
320
321 return Status;
322 }
323