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