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