]> git.proxmox.com Git - mirror_edk2.git/blob - 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
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 gBS->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 gBS->FreePool (gDebugPortDevice->DebugPortVariable);
89 DebugPortDevice->DebugPortVariable = NULL;
90 } else {
91 gBS->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 gBS->CopyMem (
99 &DebugPortDevice->Parity,
100 &((UART_DEVICE_PATH *) DevicePath)->Parity,
101 sizeof (((UART_DEVICE_PATH *) DevicePath)->Parity)
102 );
103 gBS->CopyMem (
104 &DebugPortDevice->DataBits,
105 &((UART_DEVICE_PATH *) DevicePath)->DataBits,
106 sizeof (((UART_DEVICE_PATH *) DevicePath)->DataBits)
107 );
108 gBS->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 //
164 // Allocate and Initialize dev structure
165 //
166 gDebugPortDevice = AllocateZeroPool (sizeof (DEBUGPORT_DEVICE));
167 if (gDebugPortDevice == NULL) {
168 return EFI_OUT_OF_RESOURCES;
169 }
170 //
171 // Fill in static and default pieces of device structure first.
172 //
173 gDebugPortDevice->Signature = DEBUGPORT_DEVICE_SIGNATURE;
174
175 gDebugPortDevice->DebugPortInterface.Reset = DebugPortReset;
176 gDebugPortDevice->DebugPortInterface.Read = DebugPortRead;
177 gDebugPortDevice->DebugPortInterface.Write = DebugPortWrite;
178 gDebugPortDevice->DebugPortInterface.Poll = DebugPortPoll;
179
180 gDebugPortDevice->BaudRate = DEBUGPORT_UART_DEFAULT_BAUDRATE;
181 gDebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
182 gDebugPortDevice->Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;
183 gDebugPortDevice->Parity = (EFI_PARITY_TYPE) DEBUGPORT_UART_DEFAULT_PARITY;
184 gDebugPortDevice->DataBits = DEBUGPORT_UART_DEFAULT_DATA_BITS;
185 gDebugPortDevice->StopBits = (EFI_STOP_BITS_TYPE) DEBUGPORT_UART_DEFAULT_STOP_BITS;
186
187 return EFI_SUCCESS;
188 }
189 //
190 // DebugPort driver binding member functions...
191 //
192 EFI_STATUS
193 EFIAPI
194 DebugPortSupported (
195 IN EFI_DRIVER_BINDING_PROTOCOL *This,
196 IN EFI_HANDLE ControllerHandle,
197 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
198 )
199 /*++
200
201 Routine Description:
202 Checks to see that there's not already a DebugPort interface somewhere. If so,
203 fail.
204
205 If there's a DEBUGPORT variable, the device path must match exactly. If there's
206 no DEBUGPORT variable, then device path is not checked and does not matter.
207
208 Checks to see that there's a serial io interface on the controller handle
209 that can be bound BY_DRIVER | EXCLUSIVE.
210
211 If all these tests succeed, then we return EFI_SUCCESS, else, EFI_UNSUPPORTED
212 or other error returned by OpenProtocol.
213
214 Arguments:
215 This
216 ControllerHandle
217 RemainingDevicePath
218
219 Returns:
220 EFI_UNSUPPORTED
221 EFI_OUT_OF_RESOURCES
222 EFI_SUCCESS
223
224 --*/
225 {
226 EFI_STATUS Status;
227 EFI_DEVICE_PATH_PROTOCOL *Dp1;
228 EFI_DEVICE_PATH_PROTOCOL *Dp2;
229 EFI_SERIAL_IO_PROTOCOL *SerialIo;
230 EFI_DEBUGPORT_PROTOCOL *DebugPortInterface;
231 EFI_HANDLE TempHandle;
232
233 //
234 // Check to see that there's not a debugport protocol already published
235 //
236 if (gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **) &DebugPortInterface) != EFI_NOT_FOUND) {
237 return EFI_UNSUPPORTED;
238 }
239 //
240 // Read DebugPort variable to determine debug port selection and parameters
241 //
242 GetDebugPortVariable (gDebugPortDevice);
243
244 if (gDebugPortDevice->DebugPortVariable != NULL) {
245 //
246 // There's a DEBUGPORT variable, so do LocateDevicePath and check to see if
247 // the closest matching handle matches the controller handle, and if it does,
248 // check to see that the remaining device path has the DebugPort GUIDed messaging
249 // device path only. Otherwise, it's a mismatch and EFI_UNSUPPORTED is returned.
250 //
251 Dp1 = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) gDebugPortDevice->DebugPortVariable);
252 if (Dp1 == NULL) {
253 return EFI_OUT_OF_RESOURCES;
254 }
255
256 Dp2 = Dp1;
257
258 Status = gBS->LocateDevicePath (
259 &gEfiSerialIoProtocolGuid,
260 &Dp2,
261 &TempHandle
262 );
263
264 if (Status == EFI_SUCCESS && TempHandle != ControllerHandle) {
265 Status = EFI_UNSUPPORTED;
266 }
267
268 if (Status == EFI_SUCCESS && (Dp2->Type != 3 || Dp2->SubType != 10 || *((UINT16 *) Dp2->Length) != 20)) {
269 Status = EFI_UNSUPPORTED;
270 }
271
272 if (Status == EFI_SUCCESS && CompareMem (&gEfiDebugPortDevicePathGuid, Dp2 + 1, sizeof (EFI_GUID))) {
273 Status = EFI_UNSUPPORTED;
274 }
275
276 gBS->FreePool (Dp1);
277 if (EFI_ERROR (Status)) {
278 return Status;
279 }
280 }
281
282 Status = gBS->OpenProtocol (
283 ControllerHandle,
284 &gEfiSerialIoProtocolGuid,
285 (VOID **) &SerialIo,
286 This->DriverBindingHandle,
287 ControllerHandle,
288 EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
289 );
290 if (EFI_ERROR (Status)) {
291 return Status;
292 }
293
294 gBS->CloseProtocol (
295 ControllerHandle,
296 &gEfiSerialIoProtocolGuid,
297 This->DriverBindingHandle,
298 ControllerHandle
299 );
300
301 return EFI_SUCCESS;
302 }
303
304 EFI_STATUS
305 EFIAPI
306 DebugPortStart (
307 IN EFI_DRIVER_BINDING_PROTOCOL *This,
308 IN EFI_HANDLE ControllerHandle,
309 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
310 )
311 /*++
312
313 Routine Description:
314 Binds exclusively to serial io on the controller handle. Produces DebugPort
315 protocol and DevicePath on new handle.
316
317 Arguments:
318 This
319 ControllerHandle
320 RemainingDevicePath
321
322 Returns:
323 EFI_OUT_OF_RESOURCES
324 EFI_SUCCESS
325 --*/
326 {
327 EFI_STATUS Status;
328 DEBUGPORT_DEVICE_PATH DebugPortDP;
329 EFI_DEVICE_PATH_PROTOCOL EndDP;
330 EFI_DEVICE_PATH_PROTOCOL *Dp1;
331
332 Status = gBS->OpenProtocol (
333 ControllerHandle,
334 &gEfiSerialIoProtocolGuid,
335 (VOID **) &gDebugPortDevice->SerialIoBinding,
336 This->DriverBindingHandle,
337 ControllerHandle,
338 EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
339 );
340 if (EFI_ERROR (Status)) {
341 return Status;
342 }
343
344 gDebugPortDevice->SerialIoDeviceHandle = ControllerHandle;
345
346 //
347 // Initialize the Serial Io interface...
348 //
349 Status = gDebugPortDevice->SerialIoBinding->SetAttributes (
350 gDebugPortDevice->SerialIoBinding,
351 gDebugPortDevice->BaudRate,
352 gDebugPortDevice->ReceiveFifoDepth,
353 gDebugPortDevice->Timeout,
354 gDebugPortDevice->Parity,
355 gDebugPortDevice->DataBits,
356 gDebugPortDevice->StopBits
357 );
358 if (EFI_ERROR (Status)) {
359 gDebugPortDevice->BaudRate = 0;
360 gDebugPortDevice->Parity = DefaultParity;
361 gDebugPortDevice->DataBits = 0;
362 gDebugPortDevice->StopBits = DefaultStopBits;
363 gDebugPortDevice->ReceiveFifoDepth = 0;
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 gBS->CloseProtocol (
375 ControllerHandle,
376 &gEfiSerialIoProtocolGuid,
377 This->DriverBindingHandle,
378 ControllerHandle
379 );
380 return Status;
381 }
382 }
383
384 gDebugPortDevice->SerialIoBinding->Reset (gDebugPortDevice->SerialIoBinding);
385
386 //
387 // Create device path instance for DebugPort
388 //
389 DebugPortDP.Header.Type = MESSAGING_DEVICE_PATH;
390 DebugPortDP.Header.SubType = MSG_VENDOR_DP;
391 SetDevicePathNodeLength (&(DebugPortDP.Header), sizeof (DebugPortDP));
392 gBS->CopyMem (&DebugPortDP.Guid, &gEfiDebugPortDevicePathGuid, sizeof (EFI_GUID));
393
394 Dp1 = DevicePathFromHandle (ControllerHandle);
395 if (Dp1 == NULL) {
396 Dp1 = &EndDP;
397 SetDevicePathEndNode (Dp1);
398 }
399
400 gDebugPortDevice->DebugPortDevicePath = AppendDevicePathNode (Dp1, (EFI_DEVICE_PATH_PROTOCOL *) &DebugPortDP);
401 if (gDebugPortDevice->DebugPortDevicePath == NULL) {
402 return EFI_OUT_OF_RESOURCES;
403 }
404 //
405 // Publish DebugPort and Device Path protocols
406 //
407 Status = gBS->InstallMultipleProtocolInterfaces (
408 &gDebugPortDevice->DebugPortDeviceHandle,
409 &gEfiDevicePathProtocolGuid,
410 gDebugPortDevice->DebugPortDevicePath,
411 &gEfiDebugPortProtocolGuid,
412 &gDebugPortDevice->DebugPortInterface,
413 NULL
414 );
415
416 if (EFI_ERROR (Status)) {
417 gBS->CloseProtocol (
418 ControllerHandle,
419 &gEfiSerialIoProtocolGuid,
420 This->DriverBindingHandle,
421 ControllerHandle
422 );
423 return Status;
424 }
425 //
426 // Connect debugport child to serial io
427 //
428 Status = gBS->OpenProtocol (
429 ControllerHandle,
430 &gEfiSerialIoProtocolGuid,
431 (VOID **) &gDebugPortDevice->SerialIoBinding,
432 This->DriverBindingHandle,
433 gDebugPortDevice->DebugPortDeviceHandle,
434 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
435 );
436
437 if (EFI_ERROR (Status)) {
438 DEBUG_CODE_BEGIN ();
439 UINTN BufferSize;
440
441 BufferSize = 48;
442 DebugPortWrite (
443 &gDebugPortDevice->DebugPortInterface,
444 0,
445 &BufferSize,
446 "DebugPort driver failed to open child controller\n\n"
447 );
448 DEBUG_CODE_END ();
449
450 gBS->CloseProtocol (
451 ControllerHandle,
452 &gEfiSerialIoProtocolGuid,
453 This->DriverBindingHandle,
454 ControllerHandle
455 );
456 return Status;
457 }
458
459 DEBUG_CODE_BEGIN ();
460 UINTN BufferSize;
461
462 BufferSize = 38;
463 DebugPortWrite (
464 &gDebugPortDevice->DebugPortInterface,
465 0,
466 &BufferSize,
467 "Hello World from the DebugPort driver\n\n"
468 );
469 DEBUG_CODE_END ();
470
471 return EFI_SUCCESS;
472 }
473
474 EFI_STATUS
475 EFIAPI
476 DebugPortStop (
477 IN EFI_DRIVER_BINDING_PROTOCOL *This,
478 IN EFI_HANDLE ControllerHandle,
479 IN UINTN NumberOfChildren,
480 IN EFI_HANDLE *ChildHandleBuffer
481 )
482 /*++
483
484 Routine Description:
485 We're never intending to be stopped via the driver model so this just returns
486 EFI_UNSUPPORTED
487
488 Arguments:
489 Per EFI 1.10 driver model
490
491 Returns:
492 EFI_UNSUPPORTED
493 EFI_SUCCESS
494
495 --*/
496 {
497 EFI_STATUS Status;
498
499 if (NumberOfChildren == 0) {
500 //
501 // Close the bus driver
502 //
503 gBS->CloseProtocol (
504 ControllerHandle,
505 &gEfiSerialIoProtocolGuid,
506 This->DriverBindingHandle,
507 ControllerHandle
508 );
509
510 gDebugPortDevice->SerialIoBinding = NULL;
511
512 gBS->CloseProtocol (
513 ControllerHandle,
514 &gEfiDevicePathProtocolGuid,
515 This->DriverBindingHandle,
516 ControllerHandle
517 );
518
519 gBS->FreePool (gDebugPortDevice->DebugPortDevicePath);
520
521 return EFI_SUCCESS;
522 } else {
523 //
524 // Disconnect SerialIo child handle
525 //
526 Status = gBS->CloseProtocol (
527 gDebugPortDevice->SerialIoDeviceHandle,
528 &gEfiSerialIoProtocolGuid,
529 This->DriverBindingHandle,
530 gDebugPortDevice->DebugPortDeviceHandle
531 );
532
533 if (EFI_ERROR (Status)) {
534 return Status;
535 }
536 //
537 // Unpublish our protocols (DevicePath, DebugPort)
538 //
539 Status = gBS->UninstallMultipleProtocolInterfaces (
540 gDebugPortDevice->DebugPortDeviceHandle,
541 &gEfiDevicePathProtocolGuid,
542 gDebugPortDevice->DebugPortDevicePath,
543 &gEfiDebugPortProtocolGuid,
544 &gDebugPortDevice->DebugPortInterface,
545 NULL
546 );
547
548 if (EFI_ERROR (Status)) {
549 gBS->OpenProtocol (
550 ControllerHandle,
551 &gEfiSerialIoProtocolGuid,
552 (VOID **) &gDebugPortDevice->SerialIoBinding,
553 This->DriverBindingHandle,
554 gDebugPortDevice->DebugPortDeviceHandle,
555 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
556 );
557 } else {
558 gDebugPortDevice->DebugPortDeviceHandle = NULL;
559 }
560 }
561
562 return Status;
563 }
564 //
565 // Debugport protocol member functions
566 //
567 EFI_STATUS
568 EFIAPI
569 DebugPortReset (
570 IN EFI_DEBUGPORT_PROTOCOL *This
571 )
572 /*++
573
574 Routine Description:
575 DebugPort protocol member function. Calls SerialIo:GetControl to flush buffer.
576 We cannot call SerialIo:SetAttributes because it uses pool services, which use
577 locks, which affect TPL, so it's not interrupt context safe or re-entrant.
578 SerialIo:Reset() calls SetAttributes, so it can't be used either.
579
580 The port itself should be fine since it was set up during initialization.
581
582 Arguments:
583 This
584
585 Returns:
586
587 EFI_SUCCESS
588
589 --*/
590 {
591 UINTN BufferSize;
592 UINTN BitBucket;
593
594 while (This->Poll (This) == EFI_SUCCESS) {
595 BufferSize = 1;
596 This->Read (This, 0, &BufferSize, &BitBucket);
597 }
598
599 return EFI_SUCCESS;
600 }
601
602 EFI_STATUS
603 EFIAPI
604 DebugPortRead (
605 IN EFI_DEBUGPORT_PROTOCOL *This,
606 IN UINT32 Timeout,
607 IN OUT UINTN *BufferSize,
608 IN VOID *Buffer
609 )
610 /*++
611
612 Routine Description:
613 DebugPort protocol member function. Calls SerialIo:Read() after setting
614 if it's different than the last SerialIo access.
615
616 Arguments:
617 IN EFI_DEBUGPORT_PROTOCOL *This
618 IN UINT32 Timeout,
619 IN OUT UINTN *BufferSize,
620 IN VOID *Buffer
621
622 Returns:
623
624 EFI_STATUS
625
626 --*/
627 {
628 DEBUGPORT_DEVICE *DebugPortDevice;
629 UINTN LocalBufferSize;
630 EFI_STATUS Status;
631 UINT8 *BufferPtr;
632
633 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
634 BufferPtr = Buffer;
635 LocalBufferSize = *BufferSize;
636 do {
637 Status = DebugPortDevice->SerialIoBinding->Read (
638 DebugPortDevice->SerialIoBinding,
639 &LocalBufferSize,
640 BufferPtr
641 );
642 if (Status == EFI_TIMEOUT) {
643 if (Timeout > DEBUGPORT_UART_DEFAULT_TIMEOUT) {
644 Timeout -= DEBUGPORT_UART_DEFAULT_TIMEOUT;
645 } else {
646 Timeout = 0;
647 }
648 } else if (EFI_ERROR (Status)) {
649 break;
650 }
651
652 BufferPtr += LocalBufferSize;
653 LocalBufferSize = *BufferSize - (BufferPtr - (UINT8 *) Buffer);
654 } while (LocalBufferSize != 0 && Timeout > 0);
655
656 *BufferSize = (UINTN) (BufferPtr - (UINT8 *) Buffer);
657
658 return Status;
659 }
660
661 EFI_STATUS
662 EFIAPI
663 DebugPortWrite (
664 IN EFI_DEBUGPORT_PROTOCOL *This,
665 IN UINT32 Timeout,
666 IN OUT UINTN *BufferSize,
667 OUT VOID *Buffer
668 )
669 /*++
670
671 Routine Description:
672 DebugPort protocol member function. Calls SerialIo:Write() Writes 8 bytes at
673 a time and does a GetControl between 8 byte writes to help insure reads are
674 interspersed This is poor-man's flow control..
675
676 Arguments:
677 This - Pointer to DebugPort protocol
678 Timeout - Timeout value
679 BufferSize - On input, the size of Buffer.
680 On output, the amount of data actually written.
681 Buffer - Pointer to buffer to write
682
683 Returns:
684 EFI_SUCCESS - The data was written.
685 EFI_DEVICE_ERROR - The device reported an error.
686 EFI_TIMEOUT - The data write was stopped due to a timeout.
687
688 --*/
689 {
690 DEBUGPORT_DEVICE *DebugPortDevice;
691 UINTN Position;
692 UINTN WriteSize;
693 EFI_STATUS Status;
694 UINT32 SerialControl;
695
696 Status = EFI_SUCCESS;
697 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
698
699 WriteSize = 8;
700 for (Position = 0; Position < *BufferSize && !EFI_ERROR (Status); Position += WriteSize) {
701 DebugPortDevice->SerialIoBinding->GetControl (
702 DebugPortDevice->SerialIoBinding,
703 &SerialControl
704 );
705 if (*BufferSize - Position < 8) {
706 WriteSize = *BufferSize - Position;
707 }
708
709 Status = DebugPortDevice->SerialIoBinding->Write (
710 DebugPortDevice->SerialIoBinding,
711 &WriteSize,
712 &((UINT8 *) Buffer)[Position]
713 );
714 }
715
716 *BufferSize = Position;
717 return Status;
718 }
719
720 EFI_STATUS
721 EFIAPI
722 DebugPortPoll (
723 IN EFI_DEBUGPORT_PROTOCOL *This
724 )
725 /*++
726
727 Routine Description:
728 DebugPort protocol member function. Calls SerialIo:Write() after setting
729 if it's different than the last SerialIo access.
730
731 Arguments:
732 IN EFI_DEBUGPORT_PROTOCOL *This
733
734 Returns:
735 EFI_SUCCESS - At least 1 character is ready to be read from the DebugPort interface
736 EFI_NOT_READY - There are no characters ready to read from the DebugPort interface
737 EFI_DEVICE_ERROR - A hardware failure occured... (from SerialIo)
738
739 --*/
740 {
741 EFI_STATUS Status;
742 UINT32 SerialControl;
743 DEBUGPORT_DEVICE *DebugPortDevice;
744
745 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
746
747 Status = DebugPortDevice->SerialIoBinding->GetControl (
748 DebugPortDevice->SerialIoBinding,
749 &SerialControl
750 );
751
752 if (!EFI_ERROR (Status)) {
753 if (SerialControl & EFI_SERIAL_INPUT_BUFFER_EMPTY) {
754 Status = EFI_NOT_READY;
755 } else {
756 Status = EFI_SUCCESS;
757 }
758 }
759
760 return Status;
761 }
762
763 EFI_STATUS
764 EFIAPI
765 ImageUnloadHandler (
766 EFI_HANDLE ImageHandle
767 )
768 /*++
769
770 Routine Description:
771 Unload function that is registered in the LoadImage protocol. It un-installs
772 protocols produced and deallocates pool used by the driver. Called by the core
773 when unloading the driver.
774
775 Arguments:
776 EFI_HANDLE ImageHandle
777
778 Returns:
779
780 EFI_SUCCESS
781
782 --*/
783 {
784 EFI_STATUS Status;
785
786 if (gDebugPortDevice->SerialIoBinding != NULL) {
787 return EFI_ABORTED;
788 }
789
790 Status = gBS->UninstallMultipleProtocolInterfaces (
791 ImageHandle,
792 &gEfiDriverBindingProtocolGuid,
793 &gDebugPortDevice->DriverBindingInterface,
794 &gEfiComponentNameProtocolGuid,
795 &gDebugPortDevice->ComponentNameInterface,
796 NULL
797 );
798
799 if (EFI_ERROR (Status)) {
800 return Status;
801 }
802 //
803 // Clean up allocations
804 //
805 if (gDebugPortDevice->DebugPortVariable != NULL) {
806 gBS->FreePool (gDebugPortDevice->DebugPortVariable);
807 }
808
809 gBS->FreePool (gDebugPortDevice);
810
811 return EFI_SUCCESS;
812 }