29 [VIRTIO_SERIAL_DEVICE_READY] =
"device-ready",
30 [VIRTIO_SERIAL_DEVICE_ADD] =
"device-add",
31 [VIRTIO_SERIAL_DEVICE_REMOVE] =
"device-remove",
32 [VIRTIO_SERIAL_PORT_READY] =
"port-ready",
33 [VIRTIO_SERIAL_CONSOLE_PORT] =
"console-port",
34 [VIRTIO_SERIAL_RESIZE] =
"resize",
35 [VIRTIO_SERIAL_PORT_OPEN] =
"port-open",
36 [VIRTIO_SERIAL_PORT_NAME] =
"port-name",
52 DEBUG ((DEBUG_INFO,
"ConvertDevicePathToText failed\n"));
56 DEBUG ((Level,
"%a: %s%s%s\n", Func, Note ? Note : L
"", Note ? L
": " : L
"", Str));
62VirtioSerialTxControl (
72 Control.Event = Event;
73 Control.Value = Value;
77 "%a:%d: >>> event %a, port-id %d, value %d\n",
80 EventNames[Control.Event],
85 VirtioSerialRingClearTx (Dev, VIRTIO_SERIAL_Q_TX_CTRL);
86 return VirtioSerialRingSendBuffer (Dev, VIRTIO_SERIAL_Q_TX_CTRL, &Control,
sizeof (Control),
TRUE);
92VirtioSerialRxControl (
96 UINT8 Data[CTRL_RX_BUFSIZE+1];
104 HasData = VirtioSerialRingGetBuffer (Dev, VIRTIO_SERIAL_Q_RX_CTRL, Data, &DataSize);
109 if (DataSize <
sizeof (Control)) {
112 "%a:%d: length mismatch: %d != %d\n",
121 CopyMem (&Control, Data,
sizeof (Control));
123 if (Control.Event <
ARRAY_SIZE (EventNames)) {
126 "%a:%d: <<< event %a, port-id %d, value %d\n",
129 EventNames[Control.Event],
136 "%a:%d: unknown event: %d\n",
143 switch (Control.Event) {
144 case VIRTIO_SERIAL_DEVICE_ADD:
145 if (Control.Id < MAX_PORTS) {
146 Status = VirtioSerialPortAdd (Dev, Control.Id);
152 VirtioSerialTxControl (Dev, Control.Id, VIRTIO_SERIAL_PORT_READY, Ready);
158 case VIRTIO_SERIAL_DEVICE_REMOVE:
159 if (Control.Id < MAX_PORTS) {
160 VirtioSerialPortRemove (Dev, Control.Id);
164 case VIRTIO_SERIAL_CONSOLE_PORT:
165 if (Control.Id < MAX_PORTS) {
166 VirtioSerialPortSetConsole (Dev, Control.Id);
171 case VIRTIO_SERIAL_PORT_NAME:
172 if (Control.Id < MAX_PORTS) {
174 VirtioSerialPortSetName (Dev, Control.Id, Data + sizeof (Control));
175 Dev->NumNamedPorts++;
179 case VIRTIO_SERIAL_PORT_OPEN:
180 if (Control.Id < MAX_PORTS) {
181 VirtioSerialPortSetDeviceOpen (Dev, Control.Id, Control.Value);
201 VirtioSerialRxControl (Dev);
207VirtioSerialUninitAllRings (
213 for (Index = 0; Index < MAX_RINGS; Index++) {
214 VirtioSerialUninitRing (Dev, Index);
234 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
235 if (EFI_ERROR (Status)) {
239 NextDevStat |= VSTAT_ACK;
240 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
241 if (EFI_ERROR (Status)) {
245 NextDevStat |= VSTAT_DRIVER;
246 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
247 if (EFI_ERROR (Status)) {
254 Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
255 if (EFI_ERROR (Status)) {
262 Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
263 if (EFI_ERROR (Status)) {
267 Features &= (VIRTIO_F_VERSION_1 |
268 VIRTIO_F_IOMMU_PLATFORM |
269 VIRTIO_SERIAL_F_MULTIPORT);
275 if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) {
277 if (EFI_ERROR (Status)) {
284 "%a:%d: features ok:%a%a%a\n",
287 (Features & VIRTIO_F_VERSION_1) ?
" v1.0" :
"",
288 (Features & VIRTIO_F_IOMMU_PLATFORM) ?
" iommu" :
"",
289 (Features & VIRTIO_SERIAL_F_MULTIPORT) ?
" multiport" :
""
292 if (Features & VIRTIO_SERIAL_F_MULTIPORT) {
293 Dev->VirtIo->ReadDevice (
296 sizeof (Dev->Config.MaxPorts),
297 sizeof (Dev->Config.MaxPorts),
298 &Dev->Config.MaxPorts
302 "%a:%d: max device ports: %d\n",
309 Status = VirtioSerialInitRing (Dev, VIRTIO_SERIAL_Q_RX_CTRL, CTRL_RX_BUFSIZE);
310 if (EFI_ERROR (Status)) {
314 Status = VirtioSerialInitRing (Dev, VIRTIO_SERIAL_Q_TX_CTRL, CTRL_TX_BUFSIZE);
315 if (EFI_ERROR (Status)) {
322 if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
323 Features &= ~(UINT64)(VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM);
324 Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
325 if (EFI_ERROR (Status)) {
333 NextDevStat |= VSTAT_DRIVER_OK;
334 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
335 if (EFI_ERROR (Status)) {
339 VirtioSerialRingFillRx (Dev, VIRTIO_SERIAL_Q_RX_CTRL);
340 VirtioSerialTxControl (Dev, 0, VIRTIO_SERIAL_DEVICE_READY, 1);
341 for (Retries = 0; Retries < 100; Retries++) {
343 VirtioSerialRxControl (Dev);
344 if (Dev->NumPorts && (Dev->NumConsoles + Dev->NumNamedPorts == Dev->NumPorts)) {
350 Status =
gBS->CreateEvent (
351 EVT_TIMER | EVT_NOTIFY_SIGNAL,
357 if (EFI_ERROR (Status)) {
361 Status =
gBS->SetTimer (
366 if (EFI_ERROR (Status)) {
372 "%a:%d: OK, %d consoles, %d named ports\n",
381 VirtioSerialUninitAllRings (Dev);
387 NextDevStat |= VSTAT_FAILED;
388 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
390 DEBUG ((DEBUG_INFO,
"%a:%d: ERROR: %r\n", __func__, __LINE__, Status));
403 gBS->CloseEvent (Dev->Timer);
410 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
412 for (PortId = 0; PortId < MAX_PORTS; PortId++) {
413 VirtioSerialPortRemove (Dev, PortId);
416 VirtioSerialUninitAllRings (Dev);
426VirtioSerialExitBoot (
433 DEBUG ((DEBUG_INFO,
"%a: Context=0x%p\n", __func__, Context));
442 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
456 if (DeviceHandle == Dev->DeviceHandle) {
481VirtioSerialDriverBindingSupported (
495 Status =
gBS->OpenProtocol (
497 &gVirtioDeviceProtocolGuid,
499 This->DriverBindingHandle,
502 EFI_OPEN_PROTOCOL_BY_DRIVER
505 if (EFI_ERROR (Status)) {
509 if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_CONSOLE) {
510 Status = EFI_UNSUPPORTED;
519 &gVirtioDeviceProtocolGuid,
520 This->DriverBindingHandle,
529VirtioSerialDriverBindingStart (
540 return EFI_OUT_OF_RESOURCES;
543 Status =
gBS->OpenProtocol (
545 &gEfiDevicePathProtocolGuid,
546 (VOID **)&Dev->DevicePath,
547 This->DriverBindingHandle,
549 EFI_OPEN_PROTOCOL_GET_PROTOCOL
551 if (EFI_ERROR (Status)) {
552 goto FreeVirtioSerial;
555 Status =
gBS->OpenProtocol (
557 &gVirtioDeviceProtocolGuid,
558 (VOID **)&Dev->VirtIo,
559 This->DriverBindingHandle,
561 EFI_OPEN_PROTOCOL_BY_DRIVER
563 if (EFI_ERROR (Status)) {
564 goto FreeVirtioSerial;
567 LogDevicePath (DEBUG_INFO, __func__, L
"Dev", Dev->DevicePath);
572 Dev->Signature = VIRTIO_SERIAL_SIG;
573 Dev->DriverBindingHandle = This->DriverBindingHandle;
574 Dev->DeviceHandle = DeviceHandle;
575 Status = VirtioSerialInit (Dev);
576 if (EFI_ERROR (Status)) {
580 Status =
gBS->CreateEvent (
581 EVT_SIGNAL_EXIT_BOOT_SERVICES,
583 &VirtioSerialExitBoot,
587 if (EFI_ERROR (Status)) {
595 VirtioSerialUninit (Dev);
600 &gVirtioDeviceProtocolGuid,
601 This->DriverBindingHandle,
614VirtioSerialDriverBindingStop (
625 Dev = VirtioSerialFind (DeviceHandle);
630 if (NumberOfChildren) {
632 DEBUG ((DEBUG_INFO,
"%a:%d: child handle 0x%x\n", __func__, __LINE__, ChildHandleBuffer[
Child]));
633 for (PortId = 0; PortId < MAX_PORTS; PortId++) {
634 if (Dev->Ports[PortId].Ready &&
635 Dev->Ports[PortId].SerialIo &&
636 (Dev->Ports[PortId].SerialIo->DeviceHandle == ChildHandleBuffer[
Child]))
638 VirtioSerialPortRemove (Dev, PortId);
646 DEBUG ((DEBUG_INFO,
"%a:%d: controller handle 0x%x\n", __func__, __LINE__, DeviceHandle));
648 gBS->CloseEvent (Dev->ExitBoot);
650 VirtioSerialUninit (Dev);
654 &gVirtioDeviceProtocolGuid,
655 This->DriverBindingHandle,
672 &VirtioSerialDriverBindingSupported,
673 &VirtioSerialDriverBindingStart,
674 &VirtioSerialDriverBindingStop,
691 {
"eng;en", L
"Virtio Serial Driver" },
697 {
"eng;en", L
"Virtio Serial Device" },
703 {
"eng;en", L
"Virtio Serial Port" },
713VirtioSerialGetDriverName (
716 OUT CHAR16 **DriverName
721 This->SupportedLanguages,
724 (BOOLEAN)(This == &gComponentName)
731VirtioSerialGetDeviceName (
736 OUT CHAR16 **ControllerName
743 Dev = VirtioSerialFind (DeviceHandle);
745 return EFI_UNSUPPORTED;
749 for (PortId = 0; PortId < MAX_PORTS; PortId++) {
750 if (Dev->Ports[PortId].Ready &&
751 Dev->Ports[PortId].SerialIo &&
752 (Dev->Ports[PortId].SerialIo->DeviceHandle == ChildHandle))
754 *ControllerName = Dev->Ports[PortId].Name;
759 Table = mPortNameTable;
761 Table = mDeviceNameTable;
766 This->SupportedLanguages,
769 (BOOLEAN)(This == &gComponentName)
775 &VirtioSerialGetDriverName,
776 &VirtioSerialGetDeviceName,
792VirtioSerialEntryPoint (
#define BASE_LIST_FOR_EACH(Entry, ListHead)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME2_GET_DRIVER_NAME)(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName)
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName)
NODE Child(IN NODE LoopVar6, IN UINT8 LoopVar5)
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ARRAY_SIZE(Array)
#define OFFSET_OF(TYPE, Field)
#define DEBUG(Expression)
#define CR(Record, TYPE, Field, TestSignature)
#define EFI_TIMER_PERIOD_MILLISECONDS(Milliseconds)
EFI_STATUS EFIAPI LookupUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable, OUT CHAR16 **UnicodeString, IN BOOLEAN Iso639Language)
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI Virtio10WriteFeatures(IN VIRTIO_DEVICE_PROTOCOL *VirtIo, IN UINT64 Features, IN OUT UINT8 *DeviceStatus)