| Address | Name | Description | |||
|---|---|---|---|---|---|
| SerialIoDriverBindingSupported | |||||
| SerialIoDriverBindingStart | |||||
| SerialIoDriverBindingStop | |||||
| SerialIoComponentNameGetDriverName | |||||
| SerialIoComponentNameGetControllerName | |||||
| SerialIoReset | |||||
| SerialIoSetAttributes | |||||
| SerialIoSetControlBits | |||||
| SerialIoGetControlBits | |||||
| SerialIoWrite | |||||
| SerialIoRead | |||||
| UartReadRegister | |||||
| UartWriteRegister | |||||
| UartSetFifoMode | |||||
| SerialIoCreateDevicePathNode | |||||
| SerialIoTransmitReadyTimer | |||||
| SerialIoDetectUart | |||||
| SerialIoDetectUartEnhanced | |||||
| SerialIoDriverEntryPoint | |||||
| HobGetAcpiDevicePathEnd | |||||
| COM | port name strings (off_3560 at 0x3560) | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED | const CHAR16 *mComPortNames[10] = { | ||||
| Baud | rate table (dword_35D0 at 0x35D0) | ||||
| Supported | rates in ascending order, used to clamp requested baud rates | ||||
| to | the nearest valid value. | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED | const UINT32 mBaudRateTable[19] = { | ||||
| PCI | UART Device Table (at 0x3AC8) | ||||
| Terminated | by DeviceId = 0xFFFF. | ||||
| The | SerialIoDriverBindingStart code iterates this table to match PCI UART | ||||
| Data | at 0x3AC8: first entry = {0xFFFF, 0x00FF, ...} (table may be empty/terminator) | ||||
| Default | serial attributes for initial Setup | ||||
| xmmword_35B0 | at 0x35B0 = 0x0000130E03 | ||||
| Hardware | magic constant: | ||||
| Max | consecutive write timeouts before blocking | ||||
| Software | flow control timeout (in 100ns units, 10 seconds) | ||||
| Transmit | timeout loop limit | ||||
| EFI_GUID | gEfiSerialIoProtocolGuid = EFI_SERIAL_IO_PROTOCOL_GUID; | ||||
| Device | path GUID for UART serial device node | ||||
| EFI_GUID | gEfiSerialIoDevicePathGuid = EFI_SERIAL_IO_DEVICE_PATH_GUID; | ||||
| EFI_STATUS | EFIAPI | ||||
| Component | Name 2 Protocol | ||||
| Serial | I/O Protocol Functions | ||||
| UART | Hardware Access | ||||
| UINT8 | UartReadRegister ( | ||||
| Backend | functions (not protocol interface, internal) | ||||
| EFI_STATUS | SerialIoCreateDevicePathNode ( | ||||
| caller | frees | ||||
| if | (Private->AccessMethod) { | ||||
| MMIO | access (direct memory read of register) | ||||
| switch | (Private->RegisterWidth) { | ||||
| Legacy | I/O port access | ||||
| return | __inbyte(Offset + (UINT16)Private->BaseAddress); | ||||
| PCI | I/O protocol backed access | ||||
| EFI_PCI_IO_PROTOCOL | *PciIo; | ||||
| Use | PCI MMIO read via PCI I/O protocol | ||||
| Use | PCI I/O port read | ||||
| MMIO | access | ||||
| Only | run detection for '$SIO' magic UARTs | ||||
| if | (Private->Magic != SERIAL_IO_MAGIC) { | ||||
| Enable | FIFO, clear RCVR/XMIT FIFOs | ||||
| UartWriteRegister | **(Private, R_UART_FCR, FCR_FIFO_ENABLE | ** | |||
| Read | IIR to check FIFO enable status | ||||
| if | (UartReadRegister (Private, R_UART_IIR) == 0xFF) { | ||||
| No | UART at this address (bus pulls data high) | ||||
| UartWriteRegister | (Private, R_UART_FCR, SavedFcr); | ||||
| Flush | any pending data | ||||
| Perform | 8250/16550 detection by writing 0x80 then checking loopback | ||||
| UartWriteRegister | (Private, R_UART_THR, 0x80); | ||||
| Check | if 0x80 can be read back correctly | ||||
| if | ((UartReadRegister (Private, R_UART_LSR) & LSR_DR) != 0 && | ||||
| No | FIFO: standard 8250/16450 | ||||
| Restore | FCR to enabled+cleared state for further probing | ||||
| This | is controlled by byte_3FA1 (a global flag, possibly setup-dependent) | ||||
| if | (mSomeLoopbackEnableFlag) { | ||||
| Flush | remaining data | ||||
| while | ((UartReadRegister (Private, R_UART_LSR) & LSR_DR) != 0) { | ||||
| Perform | DTR/RTS loopback test: | ||||
| Toggle | DTR bit | ||||
| if | ((NextMcr & MCR_DTR) != 0) { | ||||
| Restore | MCR | ||||
| return | UartWriteRegister (Private, R_UART_FCR, 0xFE); | ||||
| 16750 | with 64-byte FIFO: enable FIFO with trigger level 14 | ||||
| 16550A | / standard: 16-byte FIFO with trigger level 1 | ||||
| Reset | UART: clear DLAB, disable break, set LCR to default | ||||
| Lcr | = UartReadRegister (Private, R_UART_LCR); | ||||
| Reset | FIFOs | ||||
| Reconfigure | FIFO with default depth (64 if 16750, else 16) | ||||
| UartSetFifoMode | (Private, 0x40, 0); | ||||
| Clear | MCR loopback bits | ||||
| Mcr | = UartReadRegister (Private, R_UART_MCR); | ||||
| Reset | scratch register | ||||
| UartWriteRegister | (Private, R_UART_SCR, 0); | ||||
| Restore | serial attributes | ||||
| UartCfg | = Private->UartConfig; | ||||
| Reset | SW FIFO and state | ||||
| Flush | RBR (read to clear) | ||||
| UartReadRegister | (Private, R_UART_RBR); | ||||
| Apply | defaults for zero-valued parameters | ||||
| if | (BaudRate == 0) { | ||||
| DefaultNoParity | } | ||||
| DefaultStopBits | = 1 | ||||
| if | (Private->HardwareType == HW_TYPE_16750 && DataBits < 7) { | ||||
| Clamp | baud rate to nearest valid table entry | ||||
| for | (BaudIndex = 0; BaudIndex < 19 - 1; BaudIndex++) { | ||||
| Validate | all parameters against range limits | ||||
| if | **(ReceiveFifoDepth - 1 > 63 | ** | |||
| Check | if already configured at these settings | ||||
| if | (Private->BaudRate == BaudRate && | ||||
| Update | FIFO depth in hardware if changed | ||||
| if | (Private->UartConfig->ReceiveFifoDepth != ReceiveFifoDepth) { | ||||
| Calculate | baud rate divisor | ||||
| Divisor | = Clock / (16 * BaudRate); | ||||
| Set | DLAB (Divisor Latch Access Bit) and wait for THRE+TSRE | ||||
| Lcr | **= UartReadRegister (Private, R_UART_LCR) | LCR_DLAB;** | |||
| Write | divisor | ||||
| UartWriteRegister | (Private, R_UART_LCR, Lcr); | ||||
| Set | line control (parity, stop bits, data bits) | ||||
| switch | (Parity) { | ||||
| NoParity | **NewLcr &= ~(LCR_PEN | LCR_EPS | LCR_SP);** | ||
| EvenParity | **NewLcr = (NewLcr & ~(LCR_PEN | LCR_EPS | LCR_SP)) | (LCR_PEN | LCR_EPS);** |
| OddParity | **NewLcr = (NewLcr & ~(LCR_EPS | LCR_SP)) | LCR_PEN;** | ||
| MarkParity | / SpaceParity | ||||
| SpaceParity | (Mark=4, Space=5 in EFI) | ||||
| Set | word length (5, 6, 7, 8 -> 0, 1, 2, 3) | ||||
| NewLcr | **= (NewLcr & ~(LCR_WLS0 | LCR_WLS1)) | (DataBits - 5);** | ||
| Update | stored configuration | ||||
| Notify | parent via re-propagated device path if attributes changed | ||||
| if | **(Private->BaudRate != BaudRate | ** | |||
| Duplicate | device path with new attributes and re-install | ||||
| VOID | *OldDevPath; | ||||
| Free | old if present | ||||
| if | (Private->ParentDevicePath != NULL) { | ||||
| if | ((Control & 0xFFFF8FFC) != 0) { | ||||
| Set | DTR (MCR bit 0) | ||||
| Mcr | **= (Mcr & ~MCR_DTR) | ((Control & SERIAL_CTRL_DTR) ? MCR_DTR : 0);** | |||
| Set | RTS (MCR bit 1) | ||||
| Mcr | **= (Mcr & ~MCR_RTS) | ((Control & SERIAL_CTRL_RTS) ? MCR_RTS : 0);** | |||
| Set | Loopback (MCR bit 4) -> mapped to SERIAL_CTRL_REQUEST_TO_SEND bit 12 (0x1000) | ||||
| Mcr | **= (Mcr & ~MCR_LOOP) | ((Control & 0x1000) ? MCR_LOOP : 0);** | |||
| Update | software control bits | ||||
| Read | Modem Status Register | ||||
| Msr | = UartReadRegister (Private, R_UART_MSR); | ||||
| Read | Modem Control Register | ||||
| Add | software-controlled hardware reset bit | ||||
| if | ((Private->ControlBits & SERIAL_CTRL_HARDWARE_RESET) != 0) { | ||||
| Read | Line Status Register for error conditions | ||||
| Lsr | = UartReadRegister (Private, R_UART_LSR); | ||||
| Not | exactly - indicates TX in progress | ||||
| Too | many retries or CTS lost | arm timer and return error | |||
| When | RTS/CTS is active, limit writes to 16 bytes per call | ||||
| No | flow control: use SW FIFO or direct write | ||||
| if | (*BufferSize > 0) { | ||||
| Fill | SW FIFO if space available | ||||
| while | (Private->FifoCount < *FifoDepth) { | ||||
| Hardware | flow control: poll for CTS before sending | ||||
| do | { | ||||
| XOFF | character received | ||||
| Standard | write (no flow control or RTS) | ||||
| if | ((Private->ControlBits & SERIAL_CTRL_HARDWARE_RESET) != 0 && | ||||
| Assert | RTS | ||||
| SoftwareLoop | = TRUE; | ||||
| Wait | for CTS (MSR bit 4) | ||||
| while | ((UartReadRegister (Private, R_UART_MSR) & MSR_CTS) == 0) { | ||||
| Write | loop | ||||
| Wait | for THR empty (LSR bit 5) | ||||
| Write | byte | ||||
| UartWriteRegister | (Private, R_UART_THR | ||||
| Update | status from partial transfer | ||||
| if | (AutoRts && Status == EFI_TIMEOUT) { | ||||
| preserve | EFI_TIMEOUT but with data written | ||||
| SW | FIFO mode: read from SW FIFO buffer | ||||
| Flush | the FIFO after an overrun | ||||
| Direct | read from UART: poll for data | ||||
| Drain | FIFO on overrun | ||||
| for | ( ; Index < *BufferSize; Index++) { | ||||
| No | more data available now | ||||
| Check | for CTS recovery | ||||
| if | ((UartReadRegister (Private, R_UART_MSR) & MSR_CTS) != 0) { | ||||
| Check | for THRE recovery | ||||
| if | ((UartReadRegister (Private, R_UART_LSR) & LSR_THRE) != 0) { | ||||
| Global | flag controlling extended UART detection (at 0x3FA1) | ||||
| extern | UINT8 mExtendedUartDetection; | ||||
| Perform | UART presence and loopback detection. | ||||
| Returns | TRUE if UART appears absent/removed, FALSE if it seems present. | ||||
| UINT8 | SerialIoDetectUartEnhanced ( | ||||
| Enable | FIFOs, clear them | ||||
| No | UART: return TRUE = removed | ||||
| Flush | RBR | ||||
| 8250 | detection: write 0x80, then 0x08, 0x20, 0x08 | ||||
| 8250 | without FIFO | ||||
| goto | DeviceRemoved; | ||||
| Extended | test: toggle DTR and check MSR CTS change | ||||
| if | (mExtendedUartDetection) { | ||||
| Toggle | DTR in MCR | ||||
| if | ((Msr2 & MCR_DTR) != 0) { | ||||
| Restore | // | ||||
| EFI | Driver Binding Protocol instance (installed on image handle) | ||||
| EFI_DRIVER_BINDING_PROTOCOL | gSerialIoDriverBinding = { | ||||
| EFI | Component Name 2 Protocol instance | ||||
| EFI_COMPONENT_NAME2_PROTOCOL | gSerialIoComponentName2 = { | ||||
| Supported | languages for component name | ||||
| GLOBAL_REMOVE_IF_UNREFERENCED | CHAR8 *mSupportedLanguages[] = { | ||||
| Add | more languages as needed | ||||
| Install | Driver Binding Protocol and Component Name 2 Protocol | ||||
| Status | = EfiLibInstallDriverBindingComponentName2 ( | ||||
| Case | 1: Controller has ISA I/O protocol (legacy ISA/ACPI UART) | ||||
| Status | = gBS->OpenProtocol ( | ||||
| Check | ACPI device path for UART | ||||
| Case | 2: UART IO protocol or ACPI device path | ||||
| if | (HobGetAcpiDevicePathEnd (This, ControllerHandle, &AcpiEnd, 16) >= 0 && | ||||
| ACPI | device path end found: this is an ACPI UART | ||||
| Check | that it has type=3, subtype=14 (Serial I/O device path) | ||||
| if | (RemainingDevicePath != NULL && | ||||
| Case | 3: PCI UART - check for PCI I/O protocol | ||||
| if | (mSomeLoopbackEnableFlag == 1) { | ||||
| Close | protocol since we only need it for Supported() | ||||
| Case | 4: UART IO protocol on child UART device | ||||
| Check | for UART mode | ||||
| Probe | for 512 or 256 byte FIFO via UART IO protocol | ||||
| This | is used for MMIO UART controllers | ||||
| Found | 512-byte UART | ||||
| goto | Found512; | ||||
| Walk | device path looking for ACPI UART node | ||||
| ParentPath | = DevicePath; | ||||
| not | END | ||||
| ACPI | device path: check HID/UID | ||||
| return | EFI_SUCCESS; | ||||
| No | supported controller found | ||||
| if | (Status == EFI_ALREADY_STARTED) { | ||||
| GUID | for serial I/O device path (0x00180A03-...) | ||||
| EFI_GUID | SerialDevicePathGuid = EFI_SERIAL_IO_DEVICE_PATH_GUID; | ||||
| GUID | for ACPI UART HID | ||||
| EFI_GUID | AcpiUartHid = { 0x01031804, 0x9A9D, 0x3749 | ||||
| Probe | for ISA I/O protocol first (legacy COM ports) | ||||
| ISA | UART: get resources (I/O base, IRQ) | ||||
| Probe | for device path + ACPI table (legacy UART enumeration) | ||||
| Get | the UART IO protocol | ||||
| Query | UART capabilities | ||||
| MMIO | UART with ISA I/O | ||||
| ACPI | enumerated UART | ||||
| Enumerate | PCI UARTs | ||||
| if | (UartIo->GetChildHandle != NULL) { | ||||
| Channel | found with FIFO type 0 (512 byte) | ||||
| MMIO | Private->InsideIo = FALSE; | ||||
| Open | parent channel | ||||
| 256 | or 512 byte FIFO | ||||
| Walk | device path to compute device path for child | ||||
| Probe | for ACPI device path (UART IO protocol from HOB) | ||||
| if | (HobGetAcpiDevicePathEnd ( | ||||
| This | may be an ACPI enumerated UART | ||||
| Open | protocols | ||||
| No | UART IO mode: try PCI I/O protocol | ||||
| actually | DeviceId high | ||||
| Look | up clock frequency and register width in PCI UART table | ||||
| if | (gPciUartTableStart != (UINT16)-1) { | ||||
| UART | IO protocol available | ||||
| If | no protocols found, fail | ||||
| if | (Private->PciIo == NULL && Private->BaseAddress == 0) { | ||||
| Initialize | UART hardware | ||||
| UartWriteRegister | (Private, R_UART_SCR, 0xAA); | ||||
| UART | not present or not responding | ||||
| goto | CleanupAll; | ||||
| Probe | for FIFO type | ||||
| 16750 | (64-byte FIFO) | ||||
| 16550A | (16-byte FIFO, rev A) | ||||
| 16550A | (16-byte FIFO, rev B) | ||||
| Set | defaults for clock and register width if not yet configured | ||||
| if | (Private->ClockFrequency == 0) { | ||||
| Standard | PC UART clock | ||||
| Initialize | state | ||||
| Set | up Serial I/O Protocol function table | ||||
| Actually | points to self | ||||
| Initialize | default serial attributes | ||||
| Set | default attributes on hardware | ||||
| Status | = Private->SetAttributes (Private, 0, 0, 0, 0, 0, 0); | ||||
| Copy | device path attributes if present | ||||
| if | (RemainingDevicePath != NULL) { | ||||
| Build | device path for child | ||||
| ChildDevicePath | = HobDuplicateDevicePath ( | ||||
| Install | Serial I/O Protocol on new child handle | ||||
| Status | = gBS->InstallMultipleProtocolInterfaces ( | ||||
| Open | protocols (child handle) | ||||
| if | (Private->IsaAccess) { | ||||
| Create | timer for transmit ready monitoring | ||||
| Status | = gBS->CreateEvent ( | ||||
| Close | protocols opened by Supported() | ||||
| Status | = gBS->CloseProtocol ( | ||||
| Stop | the child: get private context from child handle | ||||
| Determine | which protocol was opened on the controller | ||||
| Close | the child protocol | ||||
| Uninstall | protocols from child handle | ||||
| Free | the private context | ||||
| Get | the private context from the child handle | ||||
| Private | = NULL; | ||||
| Walk | to the end of the device path | ||||
| while | (PathWalk->Type != 0x7F) { // END | ||||
| Not | an ACPI device path | ||||
| Status | = EFI_UNSUPPORTED; |
Generated by HR650X BIOS Decompilation Project