]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SerialDxe/SerialIo.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / SerialDxe / SerialIo.c
CommitLineData
bf6b810f
SZ
1/** @file\r
2 Serial driver that layers on top of a Serial Port Library instance.\r
3\r
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
5 Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
6 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
7\r
9d510e61 8 SPDX-License-Identifier: BSD-2-Clause-Patent\r
bf6b810f
SZ
9\r
10**/\r
11\r
12#include <Library/UefiBootServicesTableLib.h>\r
13#include <Library/SerialPortLib.h>\r
14#include <Library/DebugLib.h>\r
15#include <Library/PcdLib.h>\r
16\r
17#include <Protocol/SerialIo.h>\r
18#include <Protocol/DevicePath.h>\r
cf78c9d1 19#include <Guid/SerialPortLibVendor.h>\r
bf6b810f
SZ
20\r
21typedef struct {\r
1436aea4
MK
22 VENDOR_DEVICE_PATH Guid;\r
23 UART_DEVICE_PATH Uart;\r
24 EFI_DEVICE_PATH_PROTOCOL End;\r
bf6b810f
SZ
25} SERIAL_DEVICE_PATH;\r
26\r
27/**\r
28 Reset the serial device.\r
29\r
30 @param This Protocol instance pointer.\r
31\r
32 @retval EFI_SUCCESS The device was reset.\r
33 @retval EFI_DEVICE_ERROR The serial device could not be reset.\r
34\r
35**/\r
36EFI_STATUS\r
37EFIAPI\r
38SerialReset (\r
1436aea4 39 IN EFI_SERIAL_IO_PROTOCOL *This\r
bf6b810f
SZ
40 );\r
41\r
42/**\r
43 Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,\r
44 data bits, and stop bits on a serial device.\r
45\r
46 @param This Protocol instance pointer.\r
47 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the\r
48 device's default interface speed.\r
49 @param ReceiveFifoDepth The requested depth of the FIFO on the receive side of the\r
50 serial interface. A ReceiveFifoDepth value of 0 will use\r
51 the device's default FIFO depth.\r
52 @param Timeout The requested time out for a single character in microseconds.\r
53 This timeout applies to both the transmit and receive side of the\r
54 interface. A Timeout value of 0 will use the device's default time\r
55 out value.\r
56 @param Parity The type of parity to use on this serial device. A Parity value of\r
57 DefaultParity will use the device's default parity value.\r
58 @param DataBits The number of data bits to use on the serial device. A DataBits\r
59 value of 0 will use the device's default data bit setting.\r
60 @param StopBits The number of stop bits to use on this serial device. A StopBits\r
61 value of DefaultStopBits will use the device's default number of\r
62 stop bits.\r
63\r
13d378fc
JG
64 @retval EFI_SUCCESS The device was reset.\r
65 @retval EFI_INVALID_PARAMETER One or more attributes has an unsupported value.\r
66 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
bf6b810f
SZ
67\r
68**/\r
69EFI_STATUS\r
70EFIAPI\r
71SerialSetAttributes (\r
1436aea4
MK
72 IN EFI_SERIAL_IO_PROTOCOL *This,\r
73 IN UINT64 BaudRate,\r
74 IN UINT32 ReceiveFifoDepth,\r
75 IN UINT32 Timeout,\r
76 IN EFI_PARITY_TYPE Parity,\r
77 IN UINT8 DataBits,\r
78 IN EFI_STOP_BITS_TYPE StopBits\r
bf6b810f
SZ
79 );\r
80\r
81/**\r
82 Set the control bits on a serial device\r
83\r
84 @param This Protocol instance pointer.\r
85 @param Control Set the bits of Control that are settable.\r
86\r
87 @retval EFI_SUCCESS The new control bits were set on the serial device.\r
88 @retval EFI_UNSUPPORTED The serial device does not support this operation.\r
89 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
90\r
91**/\r
92EFI_STATUS\r
93EFIAPI\r
94SerialSetControl (\r
1436aea4
MK
95 IN EFI_SERIAL_IO_PROTOCOL *This,\r
96 IN UINT32 Control\r
bf6b810f
SZ
97 );\r
98\r
99/**\r
100 Retrieves the status of the control bits on a serial device\r
101\r
102 @param This Protocol instance pointer.\r
103 @param Control A pointer to return the current Control signals from the serial device.\r
104\r
105 @retval EFI_SUCCESS The control bits were read from the serial device.\r
106 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
107\r
108**/\r
109EFI_STATUS\r
110EFIAPI\r
111SerialGetControl (\r
1436aea4
MK
112 IN EFI_SERIAL_IO_PROTOCOL *This,\r
113 OUT UINT32 *Control\r
bf6b810f
SZ
114 );\r
115\r
116/**\r
117 Writes data to a serial device.\r
118\r
119 @param This Protocol instance pointer.\r
120 @param BufferSize On input, the size of the Buffer. On output, the amount of\r
121 data actually written.\r
122 @param Buffer The buffer of data to write\r
123\r
124 @retval EFI_SUCCESS The data was written.\r
125 @retval EFI_DEVICE_ERROR The device reported an error.\r
126 @retval EFI_TIMEOUT The data write was stopped due to a timeout.\r
127\r
128**/\r
129EFI_STATUS\r
130EFIAPI\r
131SerialWrite (\r
1436aea4
MK
132 IN EFI_SERIAL_IO_PROTOCOL *This,\r
133 IN OUT UINTN *BufferSize,\r
134 IN VOID *Buffer\r
bf6b810f
SZ
135 );\r
136\r
137/**\r
138 Reads data from a serial device.\r
139\r
140 @param This Protocol instance pointer.\r
141 @param BufferSize On input, the size of the Buffer. On output, the amount of\r
142 data returned in Buffer.\r
143 @param Buffer The buffer to return the data into.\r
144\r
145 @retval EFI_SUCCESS The data was read.\r
146 @retval EFI_DEVICE_ERROR The device reported an error.\r
147 @retval EFI_TIMEOUT The data write was stopped due to a timeout.\r
148\r
149**/\r
150EFI_STATUS\r
151EFIAPI\r
152SerialRead (\r
1436aea4
MK
153 IN EFI_SERIAL_IO_PROTOCOL *This,\r
154 IN OUT UINTN *BufferSize,\r
155 OUT VOID *Buffer\r
bf6b810f
SZ
156 );\r
157\r
1436aea4 158EFI_HANDLE mSerialHandle = NULL;\r
bf6b810f 159\r
1436aea4 160SERIAL_DEVICE_PATH mSerialDevicePath = {\r
bf6b810f 161 {\r
1436aea4
MK
162 { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 }\r
163 },\r
cf78c9d1 164 EDKII_SERIAL_PORT_LIB_VENDOR_GUID\r
bf6b810f
SZ
165 },\r
166 {\r
1436aea4
MK
167 { MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof (UART_DEVICE_PATH), 0 }\r
168 },\r
bf6b810f
SZ
169 0, // Reserved\r
170 0, // BaudRate\r
171 0, // DataBits\r
172 0, // Parity\r
173 0 // StopBits\r
174 },\r
1436aea4
MK
175 { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }\r
176 }\r
bf6b810f
SZ
177};\r
178\r
179//\r
180// Template used to initialize the Serial IO protocols.\r
181//\r
1436aea4 182EFI_SERIAL_IO_MODE mSerialIoMode = {\r
c0beed6d
LE
183 //\r
184 // value field set in SerialDxeInitialize()?\r
1436aea4
MK
185 // --------- ------------------- -----------------------------\r
186 0, // ControlMask\r
ea012619 187 1000 * 1000, // Timeout\r
1436aea4
MK
188 0, // BaudRate yes\r
189 1, // ReceiveFifoDepth\r
190 0, // DataBits yes\r
191 0, // Parity yes\r
192 0 // StopBits yes\r
bf6b810f
SZ
193};\r
194\r
1436aea4 195EFI_SERIAL_IO_PROTOCOL mSerialIoTemplate = {\r
bf6b810f
SZ
196 SERIAL_IO_INTERFACE_REVISION,\r
197 SerialReset,\r
198 SerialSetAttributes,\r
199 SerialSetControl,\r
200 SerialGetControl,\r
201 SerialWrite,\r
202 SerialRead,\r
203 &mSerialIoMode\r
204};\r
205\r
206/**\r
207 Reset the serial device.\r
208\r
209 @param This Protocol instance pointer.\r
210\r
211 @retval EFI_SUCCESS The device was reset.\r
212 @retval EFI_DEVICE_ERROR The serial device could not be reset.\r
213\r
214**/\r
215EFI_STATUS\r
216EFIAPI\r
217SerialReset (\r
1436aea4 218 IN EFI_SERIAL_IO_PROTOCOL *This\r
bf6b810f
SZ
219 )\r
220{\r
1436aea4 221 EFI_STATUS Status;\r
bf6b810f
SZ
222\r
223 Status = SerialPortInitialize ();\r
224 if (EFI_ERROR (Status)) {\r
225 return Status;\r
226 }\r
227\r
228 //\r
91cc526b 229 // Go set the current attributes\r
bf6b810f 230 //\r
91cc526b
PB
231 Status = This->SetAttributes (\r
232 This,\r
233 This->Mode->BaudRate,\r
234 This->Mode->ReceiveFifoDepth,\r
235 This->Mode->Timeout,\r
1436aea4
MK
236 (EFI_PARITY_TYPE)This->Mode->Parity,\r
237 (UINT8)This->Mode->DataBits,\r
238 (EFI_STOP_BITS_TYPE)This->Mode->StopBits\r
91cc526b 239 );\r
7ce5af40
JG
240\r
241 //\r
242 // The serial device may not support some of the attributes. To prevent\r
243 // later failure, always return EFI_SUCCESS when SetAttributes is returning\r
244 // EFI_INVALID_PARAMETER.\r
245 //\r
246 if (Status == EFI_INVALID_PARAMETER) {\r
247 return EFI_SUCCESS;\r
248 }\r
bf6b810f
SZ
249\r
250 return Status;\r
251}\r
252\r
253/**\r
254 Sets the baud rate, receive FIFO depth, transmit/receive time out, parity,\r
255 data bits, and stop bits on a serial device.\r
256\r
257 @param This Protocol instance pointer.\r
258 @param BaudRate The requested baud rate. A BaudRate value of 0 will use the the\r
259 device's default interface speed.\r
260 @param ReceiveFifoDepth The requested depth of the FIFO on the receive side of the\r
261 serial interface. A ReceiveFifoDepth value of 0 will use\r
262 the device's default FIFO depth.\r
263 @param Timeout The requested time out for a single character in microseconds.\r
264 This timeout applies to both the transmit and receive side of the\r
265 interface. A Timeout value of 0 will use the device's default time\r
266 out value.\r
267 @param Parity The type of parity to use on this serial device. A Parity value of\r
268 DefaultParity will use the device's default parity value.\r
269 @param DataBits The number of data bits to use on the serial device. A DataBits\r
270 value of 0 will use the device's default data bit setting.\r
271 @param StopBits The number of stop bits to use on this serial device. A StopBits\r
272 value of DefaultStopBits will use the device's default number of\r
273 stop bits.\r
274\r
13d378fc
JG
275 @retval EFI_SUCCESS The device was reset.\r
276 @retval EFI_INVALID_PARAMETER One or more attributes has an unsupported value.\r
277 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
bf6b810f
SZ
278\r
279**/\r
280EFI_STATUS\r
281EFIAPI\r
282SerialSetAttributes (\r
1436aea4
MK
283 IN EFI_SERIAL_IO_PROTOCOL *This,\r
284 IN UINT64 BaudRate,\r
285 IN UINT32 ReceiveFifoDepth,\r
286 IN UINT32 Timeout,\r
287 IN EFI_PARITY_TYPE Parity,\r
288 IN UINT8 DataBits,\r
289 IN EFI_STOP_BITS_TYPE StopBits\r
bf6b810f
SZ
290 )\r
291{\r
1436aea4
MK
292 EFI_STATUS Status;\r
293 EFI_TPL Tpl;\r
294 UINT64 OriginalBaudRate;\r
295 UINT32 OriginalReceiveFifoDepth;\r
296 UINT32 OriginalTimeout;\r
297 EFI_PARITY_TYPE OriginalParity;\r
298 UINT8 OriginalDataBits;\r
299 EFI_STOP_BITS_TYPE OriginalStopBits;\r
bf6b810f 300\r
a7fd8452
SZ
301 //\r
302 // Preserve the original input values in case\r
303 // SerialPortSetAttributes() updates the input/output\r
304 // parameters even on error.\r
305 //\r
1436aea4 306 OriginalBaudRate = BaudRate;\r
a7fd8452 307 OriginalReceiveFifoDepth = ReceiveFifoDepth;\r
1436aea4
MK
308 OriginalTimeout = Timeout;\r
309 OriginalParity = Parity;\r
310 OriginalDataBits = DataBits;\r
311 OriginalStopBits = StopBits;\r
312 Status = SerialPortSetAttributes (&BaudRate, &ReceiveFifoDepth, &Timeout, &Parity, &DataBits, &StopBits);\r
bf6b810f 313 if (EFI_ERROR (Status)) {\r
a7fd8452
SZ
314 //\r
315 // If it is just to set Timeout value and unsupported is returned,\r
316 // do not return error.\r
317 //\r
318 if ((Status == EFI_UNSUPPORTED) &&\r
319 (This->Mode->Timeout != OriginalTimeout) &&\r
320 (This->Mode->ReceiveFifoDepth == OriginalReceiveFifoDepth) &&\r
321 (This->Mode->BaudRate == OriginalBaudRate) &&\r
1436aea4
MK
322 (This->Mode->DataBits == (UINT32)OriginalDataBits) &&\r
323 (This->Mode->Parity == (UINT32)OriginalParity) &&\r
324 (This->Mode->StopBits == (UINT32)OriginalStopBits))\r
325 {\r
a7fd8452
SZ
326 //\r
327 // Restore to the original input values.\r
328 //\r
1436aea4 329 BaudRate = OriginalBaudRate;\r
a7fd8452 330 ReceiveFifoDepth = OriginalReceiveFifoDepth;\r
1436aea4
MK
331 Timeout = OriginalTimeout;\r
332 Parity = OriginalParity;\r
333 DataBits = OriginalDataBits;\r
334 StopBits = OriginalStopBits;\r
335 Status = EFI_SUCCESS;\r
336 } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {\r
13d378fc 337 return EFI_INVALID_PARAMETER;\r
a7fd8452 338 } else {\r
13d378fc 339 return EFI_DEVICE_ERROR;\r
a7fd8452 340 }\r
bf6b810f
SZ
341 }\r
342\r
343 //\r
344 // Set the Serial I/O mode and update the device path\r
345 //\r
346\r
347 Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
348\r
349 //\r
350 // Set the Serial I/O mode\r
351 //\r
1436aea4
MK
352 This->Mode->ReceiveFifoDepth = ReceiveFifoDepth;\r
353 This->Mode->Timeout = Timeout;\r
354 This->Mode->BaudRate = BaudRate;\r
355 This->Mode->DataBits = (UINT32)DataBits;\r
356 This->Mode->Parity = (UINT32)Parity;\r
357 This->Mode->StopBits = (UINT32)StopBits;\r
bf6b810f
SZ
358\r
359 //\r
360 // Check if the device path has actually changed\r
361 //\r
1436aea4
MK
362 if ((mSerialDevicePath.Uart.BaudRate == BaudRate) &&\r
363 (mSerialDevicePath.Uart.DataBits == DataBits) &&\r
364 (mSerialDevicePath.Uart.Parity == (UINT8)Parity) &&\r
365 (mSerialDevicePath.Uart.StopBits == (UINT8)StopBits)\r
366 )\r
367 {\r
bf6b810f
SZ
368 gBS->RestoreTPL (Tpl);\r
369 return EFI_SUCCESS;\r
370 }\r
371\r
372 //\r
373 // Update the device path\r
374 //\r
375 mSerialDevicePath.Uart.BaudRate = BaudRate;\r
376 mSerialDevicePath.Uart.DataBits = DataBits;\r
1436aea4
MK
377 mSerialDevicePath.Uart.Parity = (UINT8)Parity;\r
378 mSerialDevicePath.Uart.StopBits = (UINT8)StopBits;\r
bf6b810f
SZ
379\r
380 Status = gBS->ReinstallProtocolInterface (\r
381 mSerialHandle,\r
382 &gEfiDevicePathProtocolGuid,\r
383 &mSerialDevicePath,\r
384 &mSerialDevicePath\r
385 );\r
386\r
387 gBS->RestoreTPL (Tpl);\r
388\r
389 return Status;\r
390}\r
391\r
392/**\r
393 Set the control bits on a serial device\r
394\r
395 @param This Protocol instance pointer.\r
396 @param Control Set the bits of Control that are settable.\r
397\r
398 @retval EFI_SUCCESS The new control bits were set on the serial device.\r
399 @retval EFI_UNSUPPORTED The serial device does not support this operation.\r
400 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
401\r
402**/\r
403EFI_STATUS\r
404EFIAPI\r
405SerialSetControl (\r
1436aea4
MK
406 IN EFI_SERIAL_IO_PROTOCOL *This,\r
407 IN UINT32 Control\r
bf6b810f
SZ
408 )\r
409{\r
410 return SerialPortSetControl (Control);\r
411}\r
412\r
413/**\r
414 Retrieves the status of the control bits on a serial device\r
415\r
416 @param This Protocol instance pointer.\r
417 @param Control A pointer to return the current Control signals from the serial device.\r
418\r
419 @retval EFI_SUCCESS The control bits were read from the serial device.\r
420 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.\r
421\r
422**/\r
423EFI_STATUS\r
424EFIAPI\r
425SerialGetControl (\r
1436aea4
MK
426 IN EFI_SERIAL_IO_PROTOCOL *This,\r
427 OUT UINT32 *Control\r
bf6b810f
SZ
428 )\r
429{\r
430 return SerialPortGetControl (Control);\r
431}\r
432\r
433/**\r
434 Writes data to a serial device.\r
435\r
436 @param This Protocol instance pointer.\r
437 @param BufferSize On input, the size of the Buffer. On output, the amount of\r
438 data actually written.\r
439 @param Buffer The buffer of data to write\r
440\r
441 @retval EFI_SUCCESS The data was written.\r
442 @retval EFI_DEVICE_ERROR The device reported an error.\r
443 @retval EFI_TIMEOUT The data write was stopped due to a timeout.\r
444\r
445**/\r
446EFI_STATUS\r
447EFIAPI\r
448SerialWrite (\r
1436aea4
MK
449 IN EFI_SERIAL_IO_PROTOCOL *This,\r
450 IN OUT UINTN *BufferSize,\r
451 IN VOID *Buffer\r
bf6b810f
SZ
452 )\r
453{\r
1436aea4 454 UINTN Count;\r
bf6b810f
SZ
455\r
456 Count = SerialPortWrite (Buffer, *BufferSize);\r
457\r
458 if (Count != *BufferSize) {\r
459 *BufferSize = Count;\r
460 return EFI_TIMEOUT;\r
461 }\r
462\r
463 return EFI_SUCCESS;\r
464}\r
465\r
466/**\r
467 Reads data from a serial device.\r
468\r
469 @param This Protocol instance pointer.\r
470 @param BufferSize On input, the size of the Buffer. On output, the amount of\r
471 data returned in Buffer.\r
472 @param Buffer The buffer to return the data into.\r
473\r
474 @retval EFI_SUCCESS The data was read.\r
475 @retval EFI_DEVICE_ERROR The device reported an error.\r
476 @retval EFI_TIMEOUT The data write was stopped due to a timeout.\r
477\r
478**/\r
479EFI_STATUS\r
480EFIAPI\r
481SerialRead (\r
1436aea4
MK
482 IN EFI_SERIAL_IO_PROTOCOL *This,\r
483 IN OUT UINTN *BufferSize,\r
484 OUT VOID *Buffer\r
bf6b810f
SZ
485 )\r
486{\r
1436aea4
MK
487 UINTN Count;\r
488 UINTN TimeOut;\r
bf6b810f
SZ
489\r
490 Count = 0;\r
491\r
4cf3f37c
SZ
492 while (Count < *BufferSize) {\r
493 TimeOut = 0;\r
494 while (TimeOut < mSerialIoMode.Timeout) {\r
495 if (SerialPortPoll ()) {\r
496 break;\r
497 }\r
1436aea4 498\r
4cf3f37c
SZ
499 gBS->Stall (10);\r
500 TimeOut += 10;\r
501 }\r
1436aea4 502\r
4cf3f37c
SZ
503 if (TimeOut >= mSerialIoMode.Timeout) {\r
504 break;\r
505 }\r
1436aea4 506\r
4cf3f37c
SZ
507 SerialPortRead (Buffer, 1);\r
508 Count++;\r
1436aea4 509 Buffer = (VOID *)((UINT8 *)Buffer + 1);\r
bf6b810f
SZ
510 }\r
511\r
512 if (Count != *BufferSize) {\r
513 *BufferSize = Count;\r
514 return EFI_TIMEOUT;\r
515 }\r
516\r
517 return EFI_SUCCESS;\r
518}\r
519\r
520/**\r
521 Initialization for the Serial Io Protocol.\r
522\r
523 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
524 @param[in] SystemTable A pointer to the EFI System Table.\r
525\r
526 @retval EFI_SUCCESS The entry point is executed successfully.\r
527 @retval other Some error occurs when executing this entry point.\r
528\r
529**/\r
530EFI_STATUS\r
531EFIAPI\r
532SerialDxeInitialize (\r
1436aea4
MK
533 IN EFI_HANDLE ImageHandle,\r
534 IN EFI_SYSTEM_TABLE *SystemTable\r
bf6b810f
SZ
535 )\r
536{\r
1436aea4 537 EFI_STATUS Status;\r
bf6b810f 538\r
1436aea4
MK
539 mSerialIoMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
540 mSerialIoMode.DataBits = (UINT32)PcdGet8 (PcdUartDefaultDataBits);\r
541 mSerialIoMode.Parity = (UINT32)PcdGet8 (PcdUartDefaultParity);\r
542 mSerialIoMode.StopBits = (UINT32)PcdGet8 (PcdUartDefaultStopBits);\r
543 mSerialIoMode.ReceiveFifoDepth = PcdGet16 (PcdUartDefaultReceiveFifoDepth);\r
bf6b810f
SZ
544 mSerialDevicePath.Uart.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
545 mSerialDevicePath.Uart.DataBits = PcdGet8 (PcdUartDefaultDataBits);\r
546 mSerialDevicePath.Uart.Parity = PcdGet8 (PcdUartDefaultParity);\r
547 mSerialDevicePath.Uart.StopBits = PcdGet8 (PcdUartDefaultStopBits);\r
548\r
91cc526b
PB
549 //\r
550 // Issue a reset to initialize the Serial Port\r
551 //\r
552 Status = mSerialIoTemplate.Reset (&mSerialIoTemplate);\r
553 if (EFI_ERROR (Status)) {\r
554 return Status;\r
555 }\r
556\r
bf6b810f
SZ
557 //\r
558 // Make a new handle with Serial IO protocol and its device path on it.\r
559 //\r
560 Status = gBS->InstallMultipleProtocolInterfaces (\r
561 &mSerialHandle,\r
1436aea4
MK
562 &gEfiSerialIoProtocolGuid,\r
563 &mSerialIoTemplate,\r
564 &gEfiDevicePathProtocolGuid,\r
565 &mSerialDevicePath,\r
bf6b810f
SZ
566 NULL\r
567 );\r
568 ASSERT_EFI_ERROR (Status);\r
569\r
570 return Status;\r
571}\r