Updating ArmLib.h to add functions needed to turn on paging in CpuDxe. Also added...
[mirror_edk2.git] / ArmPkg / Drivers / CpuDxe / DebugSupport.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 /** @file
15 DXE Cpu Driver.
16
17 May need some porting work for platform specifics.
18
19 Copyright (c) 2008, Apple Inc
20 All rights reserved. This program and the accompanying materials
21 are licensed and made available under the terms and conditions of the BSD License
22 which accompanies this distribution. The full text of the license may be found at
23 http://opensource.org/licenses/bsd-license.php
24
25 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
26 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27
28 **/
29
30 #include "CpuDxe.h"
31
32 EFI_PERIODIC_CALLBACK gPeriodicCallBack = (EFI_PERIODIC_CALLBACK)NULL;
33
34 EFI_DEBUG_SUPPORT_PERIODIC_CALLBACK_PROTOCOL *gDebugSupportCallback = NULL;
35
36
37 EFI_STATUS
38 EFIAPI
39 DebugSupportGetMaximumProcessorIndex (
40 IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
41 OUT UINTN *MaxProcessorIndex
42 )
43 /*++
44
45 Routine Description: This is a DebugSupport protocol member function.
46
47 Arguments:
48 This - The DebugSupport instance
49 MaxProcessorIndex - The maximuim supported processor index
50
51 Returns:
52 Always returns EFI_SUCCESS with *MaxProcessorIndex set to 0
53
54 --*/
55 {
56 *MaxProcessorIndex = 0;
57 return EFI_SUCCESS;
58 }
59
60 EFI_STATUS
61 EFIAPI
62 DebugSupportRegisterPeriodicCallback (
63 IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
64 IN UINTN ProcessorIndex,
65 IN EFI_PERIODIC_CALLBACK PeriodicCallback
66 )
67 /*++
68
69 Routine Description: This is a DebugSupport protocol member function.
70
71 Arguments:
72 This - The DebugSupport instance
73 ProcessorIndex - Which processor the callback applies to.
74 PeriodicCallback - Callback function
75
76 Returns:
77
78 EFI_SUCCESS
79 EFI_INVALID_PARAMETER - requested uninstalling a handler from a vector that has
80 no handler registered for it
81 EFI_ALREADY_STARTED - requested install to a vector that already has a handler registered.
82
83 Other possible return values are passed through from UnHookEntry and HookEntry.
84
85 --*/
86 {
87 if (ProcessorIndex != 0) {
88 return EFI_INVALID_PARAMETER;
89 }
90
91 if ((gPeriodicCallBack != (EFI_PERIODIC_CALLBACK)NULL) && (PeriodicCallback != (EFI_PERIODIC_CALLBACK)NULL)) {
92 return EFI_ALREADY_STARTED;
93 }
94
95 gPeriodicCallBack = PeriodicCallback;
96
97 if (gDebugSupportCallback != NULL) {
98 //
99 // We can only update this protocol if the Register Protocol Notify has fired. If it fires
100 // after this call it will update with gPeriodicCallBack value.
101 //
102 gDebugSupportCallback->PeriodicCallback = gPeriodicCallBack;
103 }
104
105 return EFI_SUCCESS;
106 }
107
108
109 EFI_STATUS
110 EFIAPI
111 DebugSupportRegisterExceptionCallback (
112 IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
113 IN UINTN ProcessorIndex,
114 IN EFI_EXCEPTION_CALLBACK NewCallback,
115 IN EFI_EXCEPTION_TYPE ExceptionType
116 )
117 /*++
118
119 Routine Description:
120 This is a DebugSupport protocol member function.
121
122 This code executes in boot services context.
123
124 Arguments:
125 This - The DebugSupport instance
126 ProcessorIndex - Which processor the callback applies to.
127 NewCallback - Callback function
128 ExceptionType - Which exception to hook
129
130 Returns:
131
132 EFI_SUCCESS
133 EFI_INVALID_PARAMETER - requested uninstalling a handler from a vector that has
134 no handler registered for it
135 EFI_ALREADY_STARTED - requested install to a vector that already has a handler registered.
136
137 Other possible return values are passed through from UnHookEntry and HookEntry.
138
139 --*/
140 {
141 if (ProcessorIndex != 0) {
142 return EFI_INVALID_PARAMETER;
143 }
144
145 return RegisterDebuggerInterruptHandler (ExceptionType, NewCallback);
146 }
147
148
149 EFI_STATUS
150 EFIAPI
151 DebugSupportInvalidateInstructionCache (
152 IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
153 IN UINTN ProcessorIndex,
154 IN VOID *Start,
155 IN UINT64 Length
156 )
157 /*++
158
159 Routine Description:
160 This is a DebugSupport protocol member function.
161 Calls assembly routine to flush cache.
162
163 Arguments:
164 This - The DebugSupport instance
165 ProcessorIndex - Which processor the callback applies to.
166 Start - Physical base of the memory range to be invalidated
167 Length - mininum number of bytes in instruction cache to invalidate
168
169 Returns:
170
171 EFI_SUCCESS - always return success
172
173 --*/
174 {
175 if (ProcessorIndex != 0) {
176 return EFI_INVALID_PARAMETER;
177 }
178
179 InvalidateInstructionCache();
180
181 return EFI_SUCCESS;
182 }
183
184 //
185 // This is a global that is the actual interface
186 //
187 EFI_DEBUG_SUPPORT_PROTOCOL gDebugSupportProtocolInterface = {
188 IsaArm, // Fixme to be more generic
189 DebugSupportGetMaximumProcessorIndex,
190 DebugSupportRegisterPeriodicCallback,
191 DebugSupportRegisterExceptionCallback,
192 DebugSupportInvalidateInstructionCache
193 };
194
195
196 VOID
197 EFIAPI
198 DebugSupportPeriodicCallbackEventProtocolNotify (
199 IN EFI_EVENT Event,
200 IN VOID *Context
201 )
202 {
203 EFI_STATUS Status;
204
205 Status = gBS->LocateProtocol (&gEfiDebugSupportPeriodicCallbackProtocolGuid, NULL, (VOID **)&gDebugSupportCallback);
206 if (!EFI_ERROR (Status)) {
207 gDebugSupportCallback->PeriodicCallback = gPeriodicCallBack;
208 }
209 }
210
211 VOID *gRegistration = NULL;
212
213
214 EFI_DEBUG_SUPPORT_PROTOCOL *
215 InitilaizeDebugSupport (
216 VOID
217 )
218 {
219 // RPN gEfiDebugSupportPeriodicCallbackProtocolGuid
220 EFI_STATUS Status;
221 EFI_EVENT Event;
222
223 if (!FeaturePcdGet (PcdCpuDxeProduceDebugSupport)) {
224 // Don't include this code unless Feature Flag is set
225 return NULL;
226 }
227
228
229 Status = gBS->CreateEvent (
230 EVT_NOTIFY_SIGNAL,
231 TPL_CALLBACK,
232 DebugSupportPeriodicCallbackEventProtocolNotify,
233 NULL,
234 &Event
235 );
236 ASSERT_EFI_ERROR (Status);
237
238 Status = gBS->RegisterProtocolNotify (&gEfiDebugSupportPeriodicCallbackProtocolGuid, Event, &gRegistration);
239 ASSERT_EFI_ERROR (Status);
240
241 //
242 // We assume the Timer must depend on our driver to register interrupts so we don't need to do
243 // a gBS->SignalEvent (Event) here to check to see if the protocol allready exists
244 //
245
246 return &gDebugSupportProtocolInterface;
247 }