HyperDbg Debugger
Loading...
Searching...
No Matches
omap.c File Reference
#include "common.h"
#include "kdcom.h"

Macros

#define CLOCK_RATE   2995200ul
 
#define COM_EFR   0x2
 
#define COM_MDR1   0x8
 
#define LC_DATA_SIZE   0x03
 

Functions

UART_STATUS Uart16550GetByte (_Inout_ PCPPORT Port, _Out_ PUCHAR Byte)
 
UART_STATUS Uart16550PutByte (_Inout_ PCPPORT Port, UCHAR Byte, BOOLEAN BusyWait)
 
BOOLEAN Uart16550RxReady (_Inout_ PCPPORT Port)
 
BOOLEAN OmapSetBaud (_Inout_ PCPPORT Port, ULONG Rate)
 
BOOLEAN OmapInitializePort (_In_opt_ _Null_terminated_ PCHAR LoadOptions, _Inout_ PCPPORT Port, BOOLEAN MemoryMapped, UCHAR AccessSize, UCHAR BitWidth)
 

Variables

UART_HARDWARE_DRIVER OmapHardwareDriver
 

Macro Definition Documentation

◆ CLOCK_RATE

#define CLOCK_RATE   2995200ul

◆ COM_EFR

#define COM_EFR   0x2

◆ COM_MDR1

#define COM_MDR1   0x8

◆ LC_DATA_SIZE

#define LC_DATA_SIZE   0x03

Function Documentation

◆ OmapInitializePort()

BOOLEAN OmapInitializePort ( _In_opt_ _Null_terminated_ PCHAR LoadOptions,
_Inout_ PCPPORT Port,
BOOLEAN MemoryMapped,
UCHAR AccessSize,
UCHAR BitWidth )
89{
90 UNREFERENCED_PARAMETER(LoadOptions);
91 UNREFERENCED_PARAMETER(AccessSize);
92 UNREFERENCED_PARAMETER(BitWidth);
93
94 Port->Flags = 0;
95
96 //
97 // Set the Read / Write function pointers for this serial port.
98 //
99
100 UartpSetAccess(Port, MemoryMapped, AcpiGenericAccessSizeByte, 32);
101
102 //
103 // Set baud Rate.
104 //
105
106 OmapSetBaud(Port, Port->BaudRate);
107
108 //
109 // Put in operational mode.
110 //
111
112 Port->Write(Port, COM_LCR, Port->Read(Port, COM_LCR) & ~LC_DLAB);
113
114 //
115 // Disable device interrupts.
116 //
117
118 Port->Write(Port, COM_IEN, 0);
119
120 //
121 // Reset and disable the FIFO queue.
122 //
123
124 Port->Write(Port, COM_FCR, (FC_CLEAR_TRANSMIT | FC_CLEAR_RECEIVE));
125
126 //
127 // Configure the Modem Control Register. Disable device interrupts and
128 // turn off loopback.
129 //
130
131 Port->Write(Port, COM_MCR, Port->Read(Port, COM_MCR) & MC_DTRRTS);
132
133 //
134 // Initialize the Modem Control Register. Indicate to the device that
135 // we are able to send and receive data.
136 //
137
138 Port->Write(Port, COM_MCR, MC_DTRRTS);
139
140 //
141 // Enable the FIFO queues.
142 //
143
144 Port->Write(Port, COM_FCR, FC_ENABLE);
145 return TRUE;
146}
#define TRUE
Definition BasicTypes.h:55
#define FC_CLEAR_TRANSMIT
Definition kdcom.h:57
#define LC_DLAB
Definition kdcom.h:47
#define FC_CLEAR_RECEIVE
Definition kdcom.h:56
#define COM_IEN
Definition kdcom.h:32
#define FC_ENABLE
Definition kdcom.h:55
#define MC_DTRRTS
Definition kdcom.h:51
#define COM_MCR
Definition kdcom.h:35
#define COM_FCR
Definition kdcom.h:33
#define COM_LCR
Definition kdcom.h:34
BOOLEAN OmapSetBaud(_Inout_ PCPPORT Port, ULONG Rate)
Definition omap.c:149
BOOLEAN UartpSetAccess(_Inout_ PCPPORT Port, const BOOLEAN MemoryMapped, const UCHAR AccessSize, const UCHAR BitWidth)
Definition uartio.c:225
@ AcpiGenericAccessSizeByte
Definition uartp.h:51

◆ OmapSetBaud()

BOOLEAN OmapSetBaud ( _Inout_ PCPPORT Port,
ULONG Rate )
171{
172 ULONG DivisorLatch;
173 UCHAR Enhanced;
174
175 UNREFERENCED_PARAMETER(Rate);
176
177 if ((Port == NULL) || (Port->Address == NULL))
178 {
179 return FALSE;
180 }
181
182 //
183 // Disable UART.
184 //
185
186 Port->Write(Port, COM_MDR1, 0x7);
187
188 //
189 // Set register configuration mode B.
190 //
191
192 Port->Write(Port, COM_LCR, 0xBF);
193
194 //
195 // Set enhanced mode.
196 //
197
198 Enhanced = Port->Read(Port, COM_EFR);
199 Port->Write(Port, COM_EFR, (Enhanced | (1 << 4)));
200
201 //
202 // Switch to operational mode.
203 //
204
205 Port->Write(Port, COM_LCR, 0);
206
207 //
208 // Clear sleep mode.
209 //
210
211 Port->Write(Port, COM_IEN, 0);
212
213 //
214 // Set register configuration mode B.
215 //
216
217 Port->Write(Port, COM_LCR, 0xBF);
218
219 //
220 // Compute the divsor.
221 //
222
223 DivisorLatch = CLOCK_RATE / 115200;
224
225 //
226 // Write the divisor latch value to DLL and DLM.
227 //
228
229 Port->Write(Port, COM_DLM, (UCHAR)((DivisorLatch >> 8) & 0xFF));
230 Port->Write(Port, COM_DLL, (UCHAR)(DivisorLatch & 0xFF));
231
232 //
233 // Restore enhanced mode.
234 //
235
236 Port->Write(Port, COM_EFR, Enhanced);
237
238 //
239 // Reset the Line Control Register.
240 //
241
242 Port->Write(Port, COM_LCR, LC_DATA_SIZE);
243
244 //
245 // Enable UART.
246 //
247
248 Port->Write(Port, COM_MDR1, 0);
249 return TRUE;
250}
unsigned char UCHAR
Definition BasicTypes.h:35
#define FALSE
Definition BasicTypes.h:54
unsigned long ULONG
Definition BasicTypes.h:37
#define COM_DLL
Definition kdcom.h:39
#define COM_DLM
Definition kdcom.h:40
#define LC_DATA_SIZE
Definition omap.c:26
#define CLOCK_RATE
Definition omap.c:23
#define COM_MDR1
Definition omap.c:25
#define COM_EFR
Definition omap.c:24

◆ Uart16550GetByte()

UART_STATUS Uart16550GetByte ( _Inout_ PCPPORT Port,
_Out_ PUCHAR Byte )
568{
569 UCHAR Data;
570 UCHAR Lsr;
571 UCHAR Msr;
572
573 *Byte = 0;
574
575 if ((Port == NULL) || (Port->Address == NULL))
576 {
577 return UartNotReady;
578 }
579
580 //
581 // Check to see if all bits are set in LSR. If this is the case, it means
582 // the port I/O address is invalid as 0xFF is nonsense for LSR.
583 //
584
585 Lsr = Port->Read(Port, COM_LSR);
586 if (Lsr == SERIAL_LSR_NOT_PRESENT)
587 {
588 return UartNotReady;
589 }
590
591 if (CHECK_FLAG(Lsr, COM_DATRDY))
592 {
593 //
594 // Return unsuccessfully if any errors are indicated by the
595 // LSR.
596 //
597
598 if (CHECK_FLAG(Lsr, COM_PE) ||
599 CHECK_FLAG(Lsr, COM_FE) ||
600 CHECK_FLAG(Lsr, COM_OE))
601 {
602 return UartError;
603 }
604
605 Data = Port->Read(Port, COM_DAT);
606
607 //
608 // When using modem control, ignore any bytes that don't have
609 // the carrier detect flag set.
610 //
611
612 if (CHECK_FLAG(Port->Flags, PORT_MODEM_CONTROL))
613 {
614 Msr = Port->Read(Port, COM_MSR);
615 if (CHECK_FLAG(Msr, MS_CD) == FALSE)
616 {
617 return UartNoData;
618 }
619 }
620
621 *Byte = Data;
622 return UartSuccess;
623 }
624 else
625 {
626 //
627 // Data is not available. Determine if the ring indicator has toggled.
628 // If so, enable modem control.
629 //
630
631 Msr = Port->Read(Port, COM_MSR);
632 if ((CHECK_FLAG(Port->Flags, PORT_RING_INDICATOR) &&
633 !CHECK_FLAG(Msr, SERIAL_MSR_RI)) ||
634 (!CHECK_FLAG(Port->Flags, PORT_RING_INDICATOR) &&
636 {
637 Port->Flags |= PORT_MODEM_CONTROL;
638 }
639
640 return UartNoData;
641 }
642}
#define COM_LSR
Definition kdcom.h:36
#define COM_PE
Definition kdcom.h:44
#define COM_FE
Definition kdcom.h:43
#define COM_OE
Definition kdcom.h:45
#define COM_MSR
Definition kdcom.h:37
#define SERIAL_MSR_RI
Definition kdcom.h:107
#define COM_DATRDY
Definition kdcom.h:60
#define COM_DAT
Definition kdcom.h:31
#define MS_CD
Definition kdcom.h:53
#define SERIAL_LSR_NOT_PRESENT
Definition kdcom.h:116
Start of Optional Data
Definition script_buffer.hex.txt:8
#define CHECK_FLAG(_x, _f)
Definition uartp.h:27

◆ Uart16550PutByte()

UART_STATUS Uart16550PutByte ( _Inout_ PCPPORT Port,
UCHAR Byte,
BOOLEAN BusyWait )
667{
668 UCHAR Lsr;
669 UCHAR Msr;
670
671 if ((Port == NULL) || (Port->Address == NULL))
672 {
673 return UartNotReady;
674 }
675
676 //
677 // When using modem control, DSR, CTS, and CD flags must all be set before
678 // sending any data.
679 //
680
681 if (CHECK_FLAG(Port->Flags, PORT_MODEM_CONTROL))
682 {
683 Msr = Port->Read(Port, COM_MSR);
684 while ((Msr & MS_DSRCTSCD) != MS_DSRCTSCD)
685 {
686 //
687 // If there's a byte ready, discard it from the input queue.
688 //
689
690 if (!CHECK_FLAG(Msr, MS_CD))
691 {
692 Lsr = Port->Read(Port, COM_LSR);
693 if (CHECK_FLAG(Port->Flags, COM_DATRDY))
694 {
695 Port->Read(Port, COM_DAT);
696 }
697 }
698
699 Msr = Port->Read(Port, COM_MSR);
700 }
701 }
702
703 //
704 // Check to see if all bits are set in LSR. If this is the case, it means
705 // the port I/O address is invalid as 0xFF is nonsense for LSR. This
706 // prevents writing a byte to non-existent hardware.
707 //
708
709 Lsr = Port->Read(Port, COM_LSR);
710 if (Lsr == SERIAL_LSR_NOT_PRESENT)
711 {
712 return UartNotReady;
713 }
714
715 //
716 // The port must be ready to accept a byte for output before continuing.
717 //
718
719 while (!CHECK_FLAG(Lsr, COM_OUTRDY))
720 {
721 //
722 // Determine if the ring indicator has toggled.
723 // If so, enable modem control.
724 //
725
726 Msr = Port->Read(Port, COM_MSR);
727 if ((CHECK_FLAG(Port->Flags, PORT_RING_INDICATOR) &&
728 !CHECK_FLAG(Msr, SERIAL_MSR_RI)) ||
729 (!CHECK_FLAG(Port->Flags, PORT_RING_INDICATOR) &&
731 {
732 Port->Flags |= PORT_MODEM_CONTROL;
733 }
734
735 if (BusyWait == FALSE)
736 {
737 return UartNotReady;
738 }
739
740 Lsr = Port->Read(Port, COM_LSR);
741 }
742
743 //
744 // Transmitter holding register is empty. Send the byte.
745 //
746
747 Port->Write(Port, COM_DAT, Byte);
748 return UartSuccess;
749}
#define MS_DSRCTSCD
Definition kdcom.h:52
#define COM_OUTRDY
Definition kdcom.h:59

◆ Uart16550RxReady()

BOOLEAN Uart16550RxReady ( _Inout_ PCPPORT Port)
771{
772 UCHAR Lsr;
773
774 if ((Port == NULL) || (Port->Address == NULL))
775 {
776 return FALSE;
777 }
778
779 //
780 // Check to see if all bits are set in LSR. If this is the case, it means
781 // the port I/O address is invalid as 0xFF is nonsense for LSR. This
782 // prevents the DATRDY check below from returning TRUE, which could cause
783 // a caller to think that data is pending when in actuality there is no
784 // UART present.
785 //
786
787 Lsr = Port->Read(Port, COM_LSR);
788 if (Lsr == SERIAL_LSR_NOT_PRESENT)
789 {
790 return FALSE;
791 }
792
793 //
794 // Look at the Line Status Register to determine if there is pending data.
795 //
796
797 if (CHECK_FLAG(Lsr, COM_DATRDY))
798 {
799 return TRUE;
800 }
801
802 return FALSE;
803}

Variable Documentation

◆ OmapHardwareDriver

UART_HARDWARE_DRIVER OmapHardwareDriver
Initial value:
= {
BOOLEAN Uart16550RxReady(_Inout_ PCPPORT Port)
Definition uart16550.c:752
BOOLEAN OmapInitializePort(_In_opt_ _Null_terminated_ PCHAR LoadOptions, _Inout_ PCPPORT Port, BOOLEAN MemoryMapped, UCHAR AccessSize, UCHAR BitWidth)
Definition omap.c:55
UART_STATUS Uart16550GetByte(_Inout_ PCPPORT Port, _Out_ PUCHAR Byte)
Definition uart16550.c:546
UART_STATUS Uart16550PutByte(_Inout_ PCPPORT Port, UCHAR Byte, BOOLEAN BusyWait)
Definition uart16550.c:645