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