]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Debugger/Debugport/Dxe/DebugPort.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[mirror_edk2.git] / EdkModulePkg / Universal / Debugger / Debugport / Dxe / DebugPort.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 DebugPort.c\r
15\r
16Abstract:\r
17\r
18 Top level C file for debugport driver. Contains initialization function.\r
19 This driver layers on top of SerialIo.\r
20 \r
21 ALL CODE IN THE SERIALIO STACK MUST BE RE-ENTRANT AND CALLABLE FROM\r
22 INTERRUPT CONTEXT.\r
23\r
24Revision History\r
25\r
26--*/\r
27\r
28\r
29#include "DebugPort.h"\r
30\r
31//\r
1cc8ee78 32// Misc. functions local to this module..\r
878ddf1f 33//\r
34STATIC\r
35VOID\r
36GetDebugPortVariable (\r
1cc8ee78 37 DEBUGPORT_DEVICE *DebugPortDevice\r
38 )\r
39/*++\r
878ddf1f 40\r
1cc8ee78 41Routine Description:\r
42 Local worker function to obtain device path information from DebugPort variable.\r
43 Records requested settings in DebugPort device structure.\r
44 \r
45Arguments:\r
46 DEBUGPORT_DEVICE *DebugPortDevice,\r
47\r
48Returns:\r
49\r
50 Nothing\r
51\r
52--*/\r
53{\r
54 UINTN DataSize;\r
55 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
56 EFI_STATUS Status;\r
57\r
58 DataSize = 0;\r
59\r
60 Status = gRT->GetVariable (\r
61 (CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,\r
62 &gEfiDebugPortVariableGuid,\r
63 NULL,\r
64 &DataSize,\r
65 DebugPortDevice->DebugPortVariable\r
66 );\r
67\r
68 if (Status == EFI_BUFFER_TOO_SMALL) {\r
69 if (gDebugPortDevice->DebugPortVariable != NULL) {\r
70 gBS->FreePool (gDebugPortDevice->DebugPortVariable);\r
71 }\r
72\r
73 DebugPortDevice->DebugPortVariable = AllocatePool (DataSize);\r
74 if (DebugPortDevice->DebugPortVariable != NULL) {\r
75 gRT->GetVariable (\r
76 (CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,\r
77 &gEfiDebugPortVariableGuid,\r
78 NULL,\r
79 &DataSize,\r
80 DebugPortDevice->DebugPortVariable\r
81 );\r
82 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DebugPortDevice->DebugPortVariable;\r
83 while (!EfiIsDevicePathEnd (DevicePath) && !EfiIsUartDevicePath (DevicePath)) {\r
84 DevicePath = EfiNextDevicePathNode (DevicePath);\r
85 }\r
86\r
87 if (EfiIsDevicePathEnd (DevicePath)) {\r
88 gBS->FreePool (gDebugPortDevice->DebugPortVariable);\r
89 DebugPortDevice->DebugPortVariable = NULL;\r
90 } else {\r
91 gBS->CopyMem (\r
92 &DebugPortDevice->BaudRate,\r
93 &((UART_DEVICE_PATH *) DevicePath)->BaudRate,\r
94 sizeof (((UART_DEVICE_PATH *) DevicePath)->BaudRate)\r
95 );\r
96 DebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;\r
97 DebugPortDevice->Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;\r
98 gBS->CopyMem (\r
99 &DebugPortDevice->Parity,\r
100 &((UART_DEVICE_PATH *) DevicePath)->Parity,\r
101 sizeof (((UART_DEVICE_PATH *) DevicePath)->Parity)\r
102 );\r
103 gBS->CopyMem (\r
104 &DebugPortDevice->DataBits,\r
105 &((UART_DEVICE_PATH *) DevicePath)->DataBits,\r
106 sizeof (((UART_DEVICE_PATH *) DevicePath)->DataBits)\r
107 );\r
108 gBS->CopyMem (\r
109 &DebugPortDevice->StopBits,\r
110 &((UART_DEVICE_PATH *) DevicePath)->StopBits,\r
111 sizeof (((UART_DEVICE_PATH *) DevicePath)->StopBits)\r
112 );\r
113 }\r
114 }\r
115 }\r
116}\r
878ddf1f 117\r
118//\r
119// Globals\r
120//\r
121\r
122EFI_DRIVER_BINDING_PROTOCOL gDebugPortDriverBinding = {\r
123 DebugPortSupported,\r
124 DebugPortStart,\r
125 DebugPortStop,\r
126 DEBUGPORT_DRIVER_VERSION,\r
127 NULL,\r
128 NULL\r
129};\r
130\r
131DEBUGPORT_DEVICE *gDebugPortDevice;\r
878ddf1f 132\r
133//\r
134// implementation code\r
135//\r
136\r
137EFI_STATUS\r
138EFIAPI\r
139InitializeDebugPortDriver (\r
140 IN EFI_HANDLE ImageHandle,\r
141 IN EFI_SYSTEM_TABLE *SystemTable\r
142 )\r
143/*++\r
144\r
145Routine Description:\r
146 Driver entry point. Reads DebugPort variable to determine what device and settings\r
147 to use as the debug port. Binds exclusively to SerialIo. Reverts to defaults \\r
148 if no variable is found. \r
149 \r
150 Creates debugport and devicepath protocols on new handle.\r
151\r
152Arguments:\r
153 ImageHandle,\r
154 SystemTable\r
155\r
156Returns:\r
157\r
158 EFI_UNSUPPORTED\r
159 EFI_OUT_OF_RESOURCES\r
160\r
161--*/\r
162{\r
878ddf1f 163 //\r
164 // Allocate and Initialize dev structure\r
165 //\r
166 gDebugPortDevice = AllocateZeroPool (sizeof (DEBUGPORT_DEVICE));\r
167 if (gDebugPortDevice == NULL) {\r
168 return EFI_OUT_OF_RESOURCES;\r
169 }\r
170 //\r
171 // Fill in static and default pieces of device structure first.\r
172 //\r
173 gDebugPortDevice->Signature = DEBUGPORT_DEVICE_SIGNATURE;\r
174\r
175 gDebugPortDevice->DebugPortInterface.Reset = DebugPortReset;\r
176 gDebugPortDevice->DebugPortInterface.Read = DebugPortRead;\r
177 gDebugPortDevice->DebugPortInterface.Write = DebugPortWrite;\r
178 gDebugPortDevice->DebugPortInterface.Poll = DebugPortPoll;\r
179\r
180 gDebugPortDevice->BaudRate = DEBUGPORT_UART_DEFAULT_BAUDRATE;\r
181 gDebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;\r
182 gDebugPortDevice->Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;\r
1cc8ee78 183 gDebugPortDevice->Parity = (EFI_PARITY_TYPE) DEBUGPORT_UART_DEFAULT_PARITY;\r
878ddf1f 184 gDebugPortDevice->DataBits = DEBUGPORT_UART_DEFAULT_DATA_BITS;\r
1cc8ee78 185 gDebugPortDevice->StopBits = (EFI_STOP_BITS_TYPE) DEBUGPORT_UART_DEFAULT_STOP_BITS;\r
878ddf1f 186\r
187 return EFI_SUCCESS;\r
188}\r
189//\r
190// DebugPort driver binding member functions...\r
191//\r
192EFI_STATUS\r
193EFIAPI\r
194DebugPortSupported (\r
195 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
196 IN EFI_HANDLE ControllerHandle,\r
197 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
198 )\r
199/*++\r
200\r
201Routine Description:\r
202 Checks to see that there's not already a DebugPort interface somewhere. If so,\r
203 fail.\r
204 \r
205 If there's a DEBUGPORT variable, the device path must match exactly. If there's\r
206 no DEBUGPORT variable, then device path is not checked and does not matter.\r
207 \r
208 Checks to see that there's a serial io interface on the controller handle\r
209 that can be bound BY_DRIVER | EXCLUSIVE.\r
210 \r
211 If all these tests succeed, then we return EFI_SUCCESS, else, EFI_UNSUPPORTED\r
212 or other error returned by OpenProtocol.\r
213\r
214Arguments:\r
215 This\r
216 ControllerHandle\r
217 RemainingDevicePath\r
218 \r
219Returns:\r
220 EFI_UNSUPPORTED\r
221 EFI_OUT_OF_RESOURCES\r
222 EFI_SUCCESS\r
223 \r
224--*/\r
225{\r
226 EFI_STATUS Status;\r
227 EFI_DEVICE_PATH_PROTOCOL *Dp1;\r
228 EFI_DEVICE_PATH_PROTOCOL *Dp2;\r
229 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
230 EFI_DEBUGPORT_PROTOCOL *DebugPortInterface;\r
231 EFI_HANDLE TempHandle;\r
232\r
233 //\r
234 // Check to see that there's not a debugport protocol already published\r
235 //\r
236 if (gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **) &DebugPortInterface) != EFI_NOT_FOUND) {\r
237 return EFI_UNSUPPORTED;\r
238 }\r
239 //\r
240 // Read DebugPort variable to determine debug port selection and parameters\r
241 //\r
242 GetDebugPortVariable (gDebugPortDevice);\r
243\r
244 if (gDebugPortDevice->DebugPortVariable != NULL) {\r
245 //\r
246 // There's a DEBUGPORT variable, so do LocateDevicePath and check to see if\r
247 // the closest matching handle matches the controller handle, and if it does,\r
248 // check to see that the remaining device path has the DebugPort GUIDed messaging\r
249 // device path only. Otherwise, it's a mismatch and EFI_UNSUPPORTED is returned.\r
250 //\r
251 Dp1 = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) gDebugPortDevice->DebugPortVariable);\r
252 if (Dp1 == NULL) {\r
253 return EFI_OUT_OF_RESOURCES;\r
254 }\r
255\r
256 Dp2 = Dp1;\r
257\r
258 Status = gBS->LocateDevicePath (\r
259 &gEfiSerialIoProtocolGuid,\r
260 &Dp2,\r
261 &TempHandle\r
262 );\r
263\r
264 if (Status == EFI_SUCCESS && TempHandle != ControllerHandle) {\r
265 Status = EFI_UNSUPPORTED;\r
266 }\r
267\r
268 if (Status == EFI_SUCCESS && (Dp2->Type != 3 || Dp2->SubType != 10 || *((UINT16 *) Dp2->Length) != 20)) {\r
269 Status = EFI_UNSUPPORTED;\r
270 }\r
271\r
272 if (Status == EFI_SUCCESS && CompareMem (&gEfiDebugPortDevicePathGuid, Dp2 + 1, sizeof (EFI_GUID))) {\r
273 Status = EFI_UNSUPPORTED;\r
274 }\r
275\r
276 gBS->FreePool (Dp1);\r
277 if (EFI_ERROR (Status)) {\r
278 return Status;\r
279 }\r
280 }\r
281\r
282 Status = gBS->OpenProtocol (\r
283 ControllerHandle,\r
284 &gEfiSerialIoProtocolGuid,\r
285 (VOID **) &SerialIo,\r
286 This->DriverBindingHandle,\r
287 ControllerHandle,\r
288 EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE\r
289 );\r
290 if (EFI_ERROR (Status)) {\r
291 return Status;\r
292 }\r
293\r
294 gBS->CloseProtocol (\r
295 ControllerHandle,\r
296 &gEfiSerialIoProtocolGuid,\r
297 This->DriverBindingHandle,\r
298 ControllerHandle\r
299 );\r
300\r
301 return EFI_SUCCESS;\r
302}\r
303\r
304EFI_STATUS\r
305EFIAPI\r
306DebugPortStart (\r
307 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
308 IN EFI_HANDLE ControllerHandle,\r
309 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
310 )\r
311/*++\r
312\r
313Routine Description:\r
314 Binds exclusively to serial io on the controller handle. Produces DebugPort\r
315 protocol and DevicePath on new handle.\r
316\r
317Arguments:\r
318 This\r
319 ControllerHandle\r
320 RemainingDevicePath\r
321 \r
322Returns:\r
323 EFI_OUT_OF_RESOURCES\r
324 EFI_SUCCESS\r
325--*/\r
326{\r
327 EFI_STATUS Status;\r
328 DEBUGPORT_DEVICE_PATH DebugPortDP;\r
329 EFI_DEVICE_PATH_PROTOCOL EndDP;\r
330 EFI_DEVICE_PATH_PROTOCOL *Dp1;\r
331\r
332 Status = gBS->OpenProtocol (\r
333 ControllerHandle,\r
334 &gEfiSerialIoProtocolGuid,\r
335 (VOID **) &gDebugPortDevice->SerialIoBinding,\r
336 This->DriverBindingHandle,\r
337 ControllerHandle,\r
338 EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE\r
339 );\r
340 if (EFI_ERROR (Status)) {\r
341 return Status;\r
342 }\r
343\r
344 gDebugPortDevice->SerialIoDeviceHandle = ControllerHandle;\r
345\r
346 //\r
347 // Initialize the Serial Io interface...\r
348 //\r
349 Status = gDebugPortDevice->SerialIoBinding->SetAttributes (\r
350 gDebugPortDevice->SerialIoBinding,\r
351 gDebugPortDevice->BaudRate,\r
352 gDebugPortDevice->ReceiveFifoDepth,\r
353 gDebugPortDevice->Timeout,\r
354 gDebugPortDevice->Parity,\r
355 gDebugPortDevice->DataBits,\r
356 gDebugPortDevice->StopBits\r
357 );\r
358 if (EFI_ERROR (Status)) {\r
359 gDebugPortDevice->BaudRate = 0;\r
360 gDebugPortDevice->Parity = DefaultParity;\r
361 gDebugPortDevice->DataBits = 0;\r
362 gDebugPortDevice->StopBits = DefaultStopBits;\r
363 gDebugPortDevice->ReceiveFifoDepth = 0;\r
364 Status = gDebugPortDevice->SerialIoBinding->SetAttributes (\r
365 gDebugPortDevice->SerialIoBinding,\r
366 gDebugPortDevice->BaudRate,\r
367 gDebugPortDevice->ReceiveFifoDepth,\r
368 gDebugPortDevice->Timeout,\r
369 gDebugPortDevice->Parity,\r
370 gDebugPortDevice->DataBits,\r
371 gDebugPortDevice->StopBits\r
372 );\r
373 if (EFI_ERROR (Status)) {\r
374 gBS->CloseProtocol (\r
375 ControllerHandle,\r
376 &gEfiSerialIoProtocolGuid,\r
377 This->DriverBindingHandle,\r
378 ControllerHandle\r
379 );\r
380 return Status;\r
381 }\r
382 }\r
383\r
384 gDebugPortDevice->SerialIoBinding->Reset (gDebugPortDevice->SerialIoBinding);\r
385\r
386 //\r
387 // Create device path instance for DebugPort\r
388 //\r
389 DebugPortDP.Header.Type = MESSAGING_DEVICE_PATH;\r
390 DebugPortDP.Header.SubType = MSG_VENDOR_DP;\r
391 SetDevicePathNodeLength (&(DebugPortDP.Header), sizeof (DebugPortDP));\r
392 gBS->CopyMem (&DebugPortDP.Guid, &gEfiDebugPortDevicePathGuid, sizeof (EFI_GUID));\r
393\r
394 Dp1 = DevicePathFromHandle (ControllerHandle);\r
395 if (Dp1 == NULL) {\r
396 Dp1 = &EndDP;\r
397 SetDevicePathEndNode (Dp1);\r
398 }\r
399\r
400 gDebugPortDevice->DebugPortDevicePath = AppendDevicePathNode (Dp1, (EFI_DEVICE_PATH_PROTOCOL *) &DebugPortDP);\r
401 if (gDebugPortDevice->DebugPortDevicePath == NULL) {\r
402 return EFI_OUT_OF_RESOURCES;\r
403 }\r
404 //\r
405 // Publish DebugPort and Device Path protocols\r
406 //\r
407 Status = gBS->InstallMultipleProtocolInterfaces (\r
408 &gDebugPortDevice->DebugPortDeviceHandle,\r
409 &gEfiDevicePathProtocolGuid,\r
410 gDebugPortDevice->DebugPortDevicePath,\r
411 &gEfiDebugPortProtocolGuid,\r
412 &gDebugPortDevice->DebugPortInterface,\r
413 NULL\r
414 );\r
415\r
416 if (EFI_ERROR (Status)) {\r
417 gBS->CloseProtocol (\r
418 ControllerHandle,\r
419 &gEfiSerialIoProtocolGuid,\r
420 This->DriverBindingHandle,\r
421 ControllerHandle\r
422 );\r
423 return Status;\r
424 }\r
425 //\r
426 // Connect debugport child to serial io\r
427 //\r
428 Status = gBS->OpenProtocol (\r
429 ControllerHandle,\r
430 &gEfiSerialIoProtocolGuid,\r
431 (VOID **) &gDebugPortDevice->SerialIoBinding,\r
432 This->DriverBindingHandle,\r
433 gDebugPortDevice->DebugPortDeviceHandle,\r
434 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
435 );\r
436\r
437 if (EFI_ERROR (Status)) {\r
2ce31132 438 DEBUG_CODE_BEGIN ();\r
878ddf1f 439 UINTN BufferSize;\r
440\r
441 BufferSize = 48;\r
442 DebugPortWrite (\r
443 &gDebugPortDevice->DebugPortInterface,\r
444 0,\r
445 &BufferSize,\r
446 "DebugPort driver failed to open child controller\n\n"\r
447 );\r
2ce31132 448 DEBUG_CODE_END ();\r
878ddf1f 449\r
450 gBS->CloseProtocol (\r
451 ControllerHandle,\r
452 &gEfiSerialIoProtocolGuid,\r
453 This->DriverBindingHandle,\r
454 ControllerHandle\r
455 );\r
456 return Status;\r
457 }\r
458\r
2ce31132 459 DEBUG_CODE_BEGIN ();\r
878ddf1f 460 UINTN BufferSize;\r
461\r
462 BufferSize = 38;\r
463 DebugPortWrite (\r
464 &gDebugPortDevice->DebugPortInterface,\r
465 0,\r
466 &BufferSize,\r
467 "Hello World from the DebugPort driver\n\n"\r
468 );\r
2ce31132 469 DEBUG_CODE_END ();\r
878ddf1f 470\r
471 return EFI_SUCCESS;\r
472}\r
473\r
474EFI_STATUS\r
475EFIAPI\r
476DebugPortStop (\r
477 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
478 IN EFI_HANDLE ControllerHandle,\r
479 IN UINTN NumberOfChildren,\r
480 IN EFI_HANDLE *ChildHandleBuffer\r
481 )\r
482/*++\r
483\r
484Routine Description:\r
485 We're never intending to be stopped via the driver model so this just returns\r
486 EFI_UNSUPPORTED\r
487\r
488Arguments:\r
489 Per EFI 1.10 driver model\r
490 \r
491Returns:\r
492 EFI_UNSUPPORTED\r
493 EFI_SUCCESS\r
494 \r
495--*/\r
496{\r
497 EFI_STATUS Status;\r
498\r
499 if (NumberOfChildren == 0) {\r
500 //\r
501 // Close the bus driver\r
502 //\r
503 gBS->CloseProtocol (\r
504 ControllerHandle,\r
505 &gEfiSerialIoProtocolGuid,\r
506 This->DriverBindingHandle,\r
507 ControllerHandle\r
508 );\r
509\r
510 gDebugPortDevice->SerialIoBinding = NULL;\r
511\r
512 gBS->CloseProtocol (\r
513 ControllerHandle,\r
514 &gEfiDevicePathProtocolGuid,\r
515 This->DriverBindingHandle,\r
516 ControllerHandle\r
517 );\r
518\r
519 gBS->FreePool (gDebugPortDevice->DebugPortDevicePath);\r
520\r
521 return EFI_SUCCESS;\r
522 } else {\r
523 //\r
524 // Disconnect SerialIo child handle\r
525 //\r
526 Status = gBS->CloseProtocol (\r
527 gDebugPortDevice->SerialIoDeviceHandle,\r
528 &gEfiSerialIoProtocolGuid,\r
529 This->DriverBindingHandle,\r
530 gDebugPortDevice->DebugPortDeviceHandle\r
531 );\r
532\r
533 if (EFI_ERROR (Status)) {\r
534 return Status;\r
535 }\r
536 //\r
537 // Unpublish our protocols (DevicePath, DebugPort)\r
538 //\r
539 Status = gBS->UninstallMultipleProtocolInterfaces (\r
540 gDebugPortDevice->DebugPortDeviceHandle,\r
541 &gEfiDevicePathProtocolGuid,\r
542 gDebugPortDevice->DebugPortDevicePath,\r
543 &gEfiDebugPortProtocolGuid,\r
544 &gDebugPortDevice->DebugPortInterface,\r
545 NULL\r
546 );\r
547\r
548 if (EFI_ERROR (Status)) {\r
549 gBS->OpenProtocol (\r
550 ControllerHandle,\r
551 &gEfiSerialIoProtocolGuid,\r
552 (VOID **) &gDebugPortDevice->SerialIoBinding,\r
553 This->DriverBindingHandle,\r
554 gDebugPortDevice->DebugPortDeviceHandle,\r
555 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
556 );\r
557 } else {\r
558 gDebugPortDevice->DebugPortDeviceHandle = NULL;\r
559 }\r
560 }\r
561\r
562 return Status;\r
563}\r
564//\r
565// Debugport protocol member functions\r
566//\r
567EFI_STATUS\r
568EFIAPI\r
569DebugPortReset (\r
570 IN EFI_DEBUGPORT_PROTOCOL *This\r
571 )\r
572/*++\r
573\r
574Routine Description:\r
575 DebugPort protocol member function. Calls SerialIo:GetControl to flush buffer.\r
576 We cannot call SerialIo:SetAttributes because it uses pool services, which use\r
577 locks, which affect TPL, so it's not interrupt context safe or re-entrant.\r
578 SerialIo:Reset() calls SetAttributes, so it can't be used either.\r
579 \r
580 The port itself should be fine since it was set up during initialization. \r
581 \r
582Arguments:\r
583 This\r
584\r
585Returns:\r
586\r
587 EFI_SUCCESS\r
588\r
589--*/\r
590{\r
878ddf1f 591 UINTN BufferSize;\r
592 UINTN BitBucket;\r
593\r
878ddf1f 594 while (This->Poll (This) == EFI_SUCCESS) {\r
595 BufferSize = 1;\r
596 This->Read (This, 0, &BufferSize, &BitBucket);\r
597 }\r
598\r
599 return EFI_SUCCESS;\r
600}\r
601\r
602EFI_STATUS\r
603EFIAPI\r
604DebugPortRead (\r
605 IN EFI_DEBUGPORT_PROTOCOL *This,\r
606 IN UINT32 Timeout,\r
607 IN OUT UINTN *BufferSize,\r
608 IN VOID *Buffer\r
609 )\r
610/*++\r
611\r
612Routine Description:\r
613 DebugPort protocol member function. Calls SerialIo:Read() after setting\r
614 if it's different than the last SerialIo access.\r
615 \r
616Arguments:\r
617 IN EFI_DEBUGPORT_PROTOCOL *This\r
618 IN UINT32 Timeout,\r
619 IN OUT UINTN *BufferSize,\r
620 IN VOID *Buffer\r
621\r
622Returns:\r
623\r
624 EFI_STATUS\r
625\r
626--*/\r
627{\r
628 DEBUGPORT_DEVICE *DebugPortDevice;\r
629 UINTN LocalBufferSize;\r
630 EFI_STATUS Status;\r
631 UINT8 *BufferPtr;\r
632\r
633 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);\r
634 BufferPtr = Buffer;\r
635 LocalBufferSize = *BufferSize;\r
636 do {\r
637 Status = DebugPortDevice->SerialIoBinding->Read (\r
638 DebugPortDevice->SerialIoBinding,\r
639 &LocalBufferSize,\r
640 BufferPtr\r
641 );\r
642 if (Status == EFI_TIMEOUT) {\r
643 if (Timeout > DEBUGPORT_UART_DEFAULT_TIMEOUT) {\r
644 Timeout -= DEBUGPORT_UART_DEFAULT_TIMEOUT;\r
645 } else {\r
646 Timeout = 0;\r
647 }\r
648 } else if (EFI_ERROR (Status)) {\r
649 break;\r
650 }\r
651\r
652 BufferPtr += LocalBufferSize;\r
653 LocalBufferSize = *BufferSize - (BufferPtr - (UINT8 *) Buffer);\r
654 } while (LocalBufferSize != 0 && Timeout > 0);\r
655\r
656 *BufferSize = (UINTN) (BufferPtr - (UINT8 *) Buffer);\r
657\r
658 return Status;\r
659}\r
660\r
661EFI_STATUS\r
662EFIAPI\r
663DebugPortWrite (\r
664 IN EFI_DEBUGPORT_PROTOCOL *This,\r
665 IN UINT32 Timeout,\r
666 IN OUT UINTN *BufferSize,\r
667 OUT VOID *Buffer\r
668 )\r
669/*++\r
670\r
671Routine Description:\r
672 DebugPort protocol member function. Calls SerialIo:Write() Writes 8 bytes at\r
673 a time and does a GetControl between 8 byte writes to help insure reads are\r
674 interspersed This is poor-man's flow control..\r
675 \r
676Arguments:\r
677 This - Pointer to DebugPort protocol\r
678 Timeout - Timeout value\r
679 BufferSize - On input, the size of Buffer. \r
680 On output, the amount of data actually written.\r
681 Buffer - Pointer to buffer to write\r
682\r
683Returns:\r
684 EFI_SUCCESS - The data was written.\r
685 EFI_DEVICE_ERROR - The device reported an error.\r
686 EFI_TIMEOUT - The data write was stopped due to a timeout.\r
687\r
688--*/\r
689{\r
690 DEBUGPORT_DEVICE *DebugPortDevice;\r
691 UINTN Position;\r
692 UINTN WriteSize;\r
693 EFI_STATUS Status;\r
694 UINT32 SerialControl;\r
695\r
696 Status = EFI_SUCCESS;\r
697 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);\r
698\r
699 WriteSize = 8;\r
700 for (Position = 0; Position < *BufferSize && !EFI_ERROR (Status); Position += WriteSize) {\r
701 DebugPortDevice->SerialIoBinding->GetControl (\r
702 DebugPortDevice->SerialIoBinding,\r
703 &SerialControl\r
704 );\r
705 if (*BufferSize - Position < 8) {\r
706 WriteSize = *BufferSize - Position;\r
707 }\r
708\r
709 Status = DebugPortDevice->SerialIoBinding->Write (\r
710 DebugPortDevice->SerialIoBinding,\r
711 &WriteSize,\r
712 &((UINT8 *) Buffer)[Position]\r
713 );\r
714 }\r
715\r
716 *BufferSize = Position;\r
717 return Status;\r
718}\r
719\r
720EFI_STATUS\r
721EFIAPI\r
722DebugPortPoll (\r
723 IN EFI_DEBUGPORT_PROTOCOL *This\r
724 )\r
725/*++\r
726\r
727Routine Description:\r
728 DebugPort protocol member function. Calls SerialIo:Write() after setting\r
729 if it's different than the last SerialIo access.\r
730 \r
731Arguments:\r
732 IN EFI_DEBUGPORT_PROTOCOL *This\r
733\r
734Returns:\r
735 EFI_SUCCESS - At least 1 character is ready to be read from the DebugPort interface\r
736 EFI_NOT_READY - There are no characters ready to read from the DebugPort interface\r
737 EFI_DEVICE_ERROR - A hardware failure occured... (from SerialIo)\r
738\r
739--*/\r
740{\r
741 EFI_STATUS Status;\r
742 UINT32 SerialControl;\r
743 DEBUGPORT_DEVICE *DebugPortDevice;\r
744\r
745 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);\r
746\r
747 Status = DebugPortDevice->SerialIoBinding->GetControl (\r
748 DebugPortDevice->SerialIoBinding,\r
749 &SerialControl\r
750 );\r
751\r
752 if (!EFI_ERROR (Status)) {\r
753 if (SerialControl & EFI_SERIAL_INPUT_BUFFER_EMPTY) {\r
754 Status = EFI_NOT_READY;\r
755 } else {\r
756 Status = EFI_SUCCESS;\r
757 }\r
758 }\r
759\r
760 return Status;\r
761}\r
878ddf1f 762\r
763EFI_STATUS\r
764EFIAPI\r
765ImageUnloadHandler (\r
766 EFI_HANDLE ImageHandle\r
767 )\r
768/*++\r
769\r
770Routine Description:\r
771 Unload function that is registered in the LoadImage protocol. It un-installs\r
772 protocols produced and deallocates pool used by the driver. Called by the core\r
773 when unloading the driver.\r
774 \r
775Arguments:\r
776 EFI_HANDLE ImageHandle\r
777\r
778Returns:\r
779\r
780 EFI_SUCCESS\r
781\r
782--*/\r
783{\r
784 EFI_STATUS Status;\r
785\r
786 if (gDebugPortDevice->SerialIoBinding != NULL) {\r
787 return EFI_ABORTED;\r
788 }\r
789\r
790 Status = gBS->UninstallMultipleProtocolInterfaces (\r
791 ImageHandle,\r
792 &gEfiDriverBindingProtocolGuid,\r
793 &gDebugPortDevice->DriverBindingInterface,\r
794 &gEfiComponentNameProtocolGuid,\r
795 &gDebugPortDevice->ComponentNameInterface,\r
796 NULL\r
797 );\r
798\r
799 if (EFI_ERROR (Status)) {\r
800 return Status;\r
801 }\r
802 //\r
803 // Clean up allocations\r
804 //\r
805 if (gDebugPortDevice->DebugPortVariable != NULL) {\r
806 gBS->FreePool (gDebugPortDevice->DebugPortVariable);\r
807 }\r
808\r
809 gBS->FreePool (gDebugPortDevice);\r
810\r
811 return EFI_SUCCESS;\r
812}\r