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

Macros

#define UART_DR   0x00
 
#define UART_RSR   0x04
 
#define UART_ECR   0x04
 
#define UART_FR   0x18
 
#define UART_ILPR   0x20
 
#define UART_IBRD   0x24
 
#define UART_FBRD   0x28
 
#define UART_LCRH   0x2C
 
#define UART_CR   0x30
 
#define UART_IFLS   0x34
 
#define UART_IMSC   0x38
 
#define UART_RIS   0x3C
 
#define UART_MIS   0x40
 
#define UART_ICR   0x44
 
#define UART_DMACR   0x48
 
#define TOTAL_UART_REGISTER_SIZE   0x4C
 
#define UART_FR_TXFE   0x80
 
#define UART_FR_RXFF   0x40
 
#define UART_FR_TXFF   0x20
 
#define UART_FR_RXFE   0x10
 
#define UART_FR_BUSY   0x08
 
#define UART_LCRH_SPS   0x80
 
#define UART_LCRH_WLEN_8   0x60
 
#define UART_LCRH_WLEN_7   0x40
 
#define UART_LCRH_WLEN_6   0x20
 
#define UART_LCRH_WLEN_5   0x00
 
#define UART_LCRH_FEN   0x10
 
#define UART_LCRH_STP2   0x08
 
#define UART_LCRH_EPS   0x04
 
#define UART_LCRH_PEN   0x02
 
#define UART_LCRH_BRK   0x01
 
#define UART_CR_CTSEn   0x8000
 
#define UART_CR_RTSEn   0x4000
 
#define UART_CR_OUT2   0x2000
 
#define UART_CR_OUT1   0x1000
 
#define UART_CR_RTS   0x0800
 
#define UART_CR_DTR   0x0400
 
#define UART_CR_RXE   0x0200
 
#define UART_CR_TXE   0x0100
 
#define UART_CR_LBE   0x0080
 
#define UART_CR_SIRLP   0x0004
 
#define UART_CR_SIREN   0x0002
 
#define UART_CR_UARTEN   0x0001
 
#define UART_DR_OE   0x800
 
#define UART_DR_BE   0x400
 
#define UART_DR_PE   0x200
 
#define UART_DR_FE   0x100
 
#define PL011_READ_REGISTER_UCHAR(a, f)    (UCHAR)((f) ? READ_REGISTER_ULONG((PULONG)(a)) : READ_REGISTER_UCHAR(a))
 
#define PL011_READ_REGISTER_USHORT(a, f)    (USHORT)((f) ? READ_REGISTER_ULONG((PULONG)(a)) : READ_REGISTER_USHORT(a))
 
#define PL011_WRITE_REGISTER_UCHAR(a, d, f)    ((f) ? WRITE_REGISTER_ULONG((PULONG)(a), d) : WRITE_REGISTER_UCHAR(a, d))
 
#define PL011_WRITE_REGISTER_USHORT(a, d, f)    ((f) ? WRITE_REGISTER_ULONG((PULONG)(a), d) : WRITE_REGISTER_USHORT(a, d))
 

Functions

BOOLEAN PL011InitializePort (_In_opt_ _Null_terminated_ PCHAR LoadOptions, _Inout_ PCPPORT Port, BOOLEAN MemoryMapped, UCHAR AccessSize, UCHAR BitWidth)
 
BOOLEAN SBSAInitializePort (_In_opt_ _Null_terminated_ PCHAR LoadOptions, _Inout_ PCPPORT Port, BOOLEAN MemoryMapped, UCHAR AccessSize, UCHAR BitWidth)
 
BOOLEAN SBSA32InitializePort (_In_opt_ _Null_terminated_ PCHAR LoadOptions, _Inout_ PCPPORT Port, BOOLEAN MemoryMapped, UCHAR AccessSize, UCHAR BitWidth)
 
BOOLEAN PL011SetBaud (_Inout_ PCPPORT Port, ULONG Rate)
 
UART_STATUS PL011GetByte (_Inout_ PCPPORT Port, _Out_ PUCHAR Byte)
 
UART_STATUS PL011PutByte (_Inout_ PCPPORT Port, UCHAR Byte, BOOLEAN BusyWait)
 
BOOLEAN PL011RxReady (_Inout_ PCPPORT Port)
 

Variables

UART_HARDWARE_DRIVER PL011HardwareDriver
 
UART_HARDWARE_DRIVER SBSAHardwareDriver
 
UART_HARDWARE_DRIVER SBSA32HardwareDriver
 

Macro Definition Documentation

◆ PL011_READ_REGISTER_UCHAR

#define PL011_READ_REGISTER_UCHAR ( a,
f )    (UCHAR)((f) ? READ_REGISTER_ULONG((PULONG)(a)) : READ_REGISTER_UCHAR(a))
80#define PL011_READ_REGISTER_UCHAR(a, f) \
81 (UCHAR)((f) ? READ_REGISTER_ULONG((PULONG)(a)) : READ_REGISTER_UCHAR(a))

◆ PL011_READ_REGISTER_USHORT

#define PL011_READ_REGISTER_USHORT ( a,
f )    (USHORT)((f) ? READ_REGISTER_ULONG((PULONG)(a)) : READ_REGISTER_USHORT(a))
83#define PL011_READ_REGISTER_USHORT(a, f) \
84 (USHORT)((f) ? READ_REGISTER_ULONG((PULONG)(a)) : READ_REGISTER_USHORT(a))

◆ PL011_WRITE_REGISTER_UCHAR

#define PL011_WRITE_REGISTER_UCHAR ( a,
d,
f )    ((f) ? WRITE_REGISTER_ULONG((PULONG)(a), d) : WRITE_REGISTER_UCHAR(a, d))
86#define PL011_WRITE_REGISTER_UCHAR(a, d, f) \
87 ((f) ? WRITE_REGISTER_ULONG((PULONG)(a), d) : WRITE_REGISTER_UCHAR(a, d))

◆ PL011_WRITE_REGISTER_USHORT

#define PL011_WRITE_REGISTER_USHORT ( a,
d,
f )    ((f) ? WRITE_REGISTER_ULONG((PULONG)(a), d) : WRITE_REGISTER_USHORT(a, d))
89#define PL011_WRITE_REGISTER_USHORT(a, d, f) \
90 ((f) ? WRITE_REGISTER_ULONG((PULONG)(a), d) : WRITE_REGISTER_USHORT(a, d))

◆ TOTAL_UART_REGISTER_SIZE

#define TOTAL_UART_REGISTER_SIZE   0x4C

◆ UART_CR

#define UART_CR   0x30

◆ UART_CR_CTSEn

#define UART_CR_CTSEn   0x8000

◆ UART_CR_DTR

#define UART_CR_DTR   0x0400

◆ UART_CR_LBE

#define UART_CR_LBE   0x0080

◆ UART_CR_OUT1

#define UART_CR_OUT1   0x1000

◆ UART_CR_OUT2

#define UART_CR_OUT2   0x2000

◆ UART_CR_RTS

#define UART_CR_RTS   0x0800

◆ UART_CR_RTSEn

#define UART_CR_RTSEn   0x4000

◆ UART_CR_RXE

#define UART_CR_RXE   0x0200

◆ UART_CR_SIREN

#define UART_CR_SIREN   0x0002

◆ UART_CR_SIRLP

#define UART_CR_SIRLP   0x0004

◆ UART_CR_TXE

#define UART_CR_TXE   0x0100

◆ UART_CR_UARTEN

#define UART_CR_UARTEN   0x0001

◆ UART_DMACR

#define UART_DMACR   0x48

◆ UART_DR

#define UART_DR   0x00

◆ UART_DR_BE

#define UART_DR_BE   0x400

◆ UART_DR_FE

#define UART_DR_FE   0x100

◆ UART_DR_OE

#define UART_DR_OE   0x800

◆ UART_DR_PE

#define UART_DR_PE   0x200

◆ UART_ECR

#define UART_ECR   0x04

◆ UART_FBRD

#define UART_FBRD   0x28

◆ UART_FR

#define UART_FR   0x18

◆ UART_FR_BUSY

#define UART_FR_BUSY   0x08

◆ UART_FR_RXFE

#define UART_FR_RXFE   0x10

◆ UART_FR_RXFF

#define UART_FR_RXFF   0x40

◆ UART_FR_TXFE

#define UART_FR_TXFE   0x80

◆ UART_FR_TXFF

#define UART_FR_TXFF   0x20

◆ UART_IBRD

#define UART_IBRD   0x24

◆ UART_ICR

#define UART_ICR   0x44

◆ UART_IFLS

#define UART_IFLS   0x34

◆ UART_ILPR

#define UART_ILPR   0x20

◆ UART_IMSC

#define UART_IMSC   0x38

◆ UART_LCRH

#define UART_LCRH   0x2C

◆ UART_LCRH_BRK

#define UART_LCRH_BRK   0x01

◆ UART_LCRH_EPS

#define UART_LCRH_EPS   0x04

◆ UART_LCRH_FEN

#define UART_LCRH_FEN   0x10

◆ UART_LCRH_PEN

#define UART_LCRH_PEN   0x02

◆ UART_LCRH_SPS

#define UART_LCRH_SPS   0x80

◆ UART_LCRH_STP2

#define UART_LCRH_STP2   0x08

◆ UART_LCRH_WLEN_5

#define UART_LCRH_WLEN_5   0x00

◆ UART_LCRH_WLEN_6

#define UART_LCRH_WLEN_6   0x20

◆ UART_LCRH_WLEN_7

#define UART_LCRH_WLEN_7   0x40

◆ UART_LCRH_WLEN_8

#define UART_LCRH_WLEN_8   0x60

◆ UART_MIS

#define UART_MIS   0x40

◆ UART_RIS

#define UART_RIS   0x3C

◆ UART_RSR

#define UART_RSR   0x04

Function Documentation

◆ PL011GetByte()

UART_STATUS PL011GetByte ( _Inout_ PCPPORT Port,
_Out_ PUCHAR Byte )
422{
423 BOOLEAN Force32Bit;
424 USHORT Fsr;
426
427 if ((Port == NULL) || (Port->Address == NULL))
428 {
429 return UartNotReady;
430 }
431
432 Force32Bit = ((Port->Flags & PORT_FORCE_32BIT_IO) != 0);
433
434 //
435 // Get FIFO status.
436 //
437
438 Fsr = PL011_READ_REGISTER_USHORT((PUSHORT)(Port->Address + UART_FR),
439 Force32Bit);
440
441 //
442 // Is at least one character available?
443 //
444
445 if ((Fsr & UART_FR_RXFE) == 0)
446 {
447 //
448 // Fetch the data byte and associated error information.
449 //
450
451 Value =
452 PL011_READ_REGISTER_USHORT((PUSHORT)(Port->Address + UART_DR),
453 Force32Bit);
454
455 //
456 // Check for errors. Deliberately don't treat overrun as an error.
457 //
458
459 if ((Value & (UART_DR_PE | UART_DR_FE | UART_DR_BE)) != 0)
460 {
461 *Byte = 0;
462 return UartError;
463 }
464
465 *Byte = Value & (UCHAR)0xFF;
466 return UartSuccess;
467 }
468
469 return UartNoData;
470}
UCHAR BOOLEAN
Definition BasicTypes.h:39
unsigned char UCHAR
Definition BasicTypes.h:35
unsigned short USHORT
Definition BasicTypes.h:36
RequestedActionOfThePacket Value(0x1) 00000000
#define UART_DR_PE
Definition pl011.c:75
#define UART_FR
Definition pl011.c:24
#define UART_DR_FE
Definition pl011.c:76
#define UART_DR_BE
Definition pl011.c:74
#define UART_FR_RXFE
Definition pl011.c:46
#define PL011_READ_REGISTER_USHORT(a, f)
Definition pl011.c:83
#define UART_DR
Definition pl011.c:21

◆ PL011InitializePort()

BOOLEAN PL011InitializePort ( _In_opt_ _Null_terminated_ PCHAR LoadOptions,
_Inout_ PCPPORT Port,
BOOLEAN MemoryMapped,
UCHAR AccessSize,
UCHAR BitWidth )
129{
130 UINT16 Cr;
131 BOOLEAN Force32Bit;
132 UINT16 Fsr;
133
134 UNREFERENCED_PARAMETER(LoadOptions);
135 UNREFERENCED_PARAMETER(AccessSize);
136
137 if (MemoryMapped == FALSE)
138 {
139 return FALSE;
140 }
141
142 if (BitWidth == 32)
143 {
144 Port->Flags = PORT_FORCE_32BIT_IO;
145 Force32Bit = TRUE;
146 }
147 else
148 {
149 Port->Flags = 0;
150 Force32Bit = FALSE;
151 }
152
153 //
154 // Disable UART.
155 //
156
157 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_CR),
158 0,
159 Force32Bit);
160
161 //
162 // Flush the FIFO by disabling the FIFO.
163 // FIFO need to be flushed before re-enabling the UART.
164 //
165
166 do
167 {
168 PL011_WRITE_REGISTER_UCHAR((PUCHAR)(Port->Address + UART_LCRH), 0, FALSE);
169 Fsr = PL011_READ_REGISTER_USHORT((PUSHORT)(Port->Address + UART_FR), FALSE);
170
171 } while ((Fsr & (UART_FR_RXFE | UART_FR_TXFE)) != (UART_FR_RXFE | UART_FR_TXFE));
172
173 //
174 // Set word length to 8 bits, enable the FIFO, disable parity.
175 //
176
179 Force32Bit);
180
181 //
182 // Clear all interrupts
183 //
184
185 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_IMSC),
186 0x0000,
187 Force32Bit);
188
189 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_ICR),
190 0x07FF,
191 Force32Bit);
192
193 //
194 // Enable UART, Enable Transmit and Receive, Enable RTS.
195 //
196 // The RTS hardware flow control is required to ensure RX FIFO won't be
197 // overflowed on simulator.
198 //
199
200 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_CR),
202 Force32Bit);
203
204 Cr = PL011_READ_REGISTER_USHORT((PUSHORT)(Port->Address + UART_CR),
205 Force32Bit);
206
207 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_CR),
208 (Cr | UART_CR_UARTEN),
209 Force32Bit);
210
211 return TRUE;
212}
unsigned short UINT16
Definition BasicTypes.h:47
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
#define UART_FR_TXFE
Definition pl011.c:43
#define UART_ICR
Definition pl011.c:34
#define UART_LCRH
Definition pl011.c:28
#define UART_CR_UARTEN
Definition pl011.c:71
#define UART_CR
Definition pl011.c:29
#define UART_IMSC
Definition pl011.c:31
#define UART_CR_TXE
Definition pl011.c:67
#define UART_CR_RTSEn
Definition pl011.c:61
#define UART_LCRH_FEN
Definition pl011.c:54
#define UART_LCRH_WLEN_8
Definition pl011.c:50
#define PL011_WRITE_REGISTER_UCHAR(a, d, f)
Definition pl011.c:86
#define UART_CR_RXE
Definition pl011.c:66
#define PL011_WRITE_REGISTER_USHORT(a, d, f)
Definition pl011.c:89

◆ PL011PutByte()

UART_STATUS PL011PutByte ( _Inout_ PCPPORT Port,
UCHAR Byte,
BOOLEAN BusyWait )
499{
500 BOOLEAN Force32Bit;
501
502 if ((Port == NULL) || (Port->Address == NULL))
503 {
504 return UartNotReady;
505 }
506
507 Force32Bit = ((Port->Flags & PORT_FORCE_32BIT_IO) != 0);
508
509 //
510 // Wait for port to be free and FIFO not full.
511 //
512 // _ARM_WORKAROUND_ modem control is not supported
513 //
514
515 if (BusyWait != FALSE)
516 {
518 (PUSHORT)(Port->Address + UART_FR),
519 Force32Bit) &
520 (UART_FR_TXFF))
521 ;
522 }
523 else
524 {
526 (PUSHORT)(Port->Address + UART_FR),
527 Force32Bit) &
528 (UART_FR_TXFF))
529 {
530 return UartNotReady;
531 }
532 }
533
534 //
535 // Send the byte.
536 //
537
538 PL011_WRITE_REGISTER_UCHAR(Port->Address + UART_DR, Byte, Force32Bit);
539 return UartSuccess;
540}
#define UART_FR_TXFF
Definition pl011.c:45

◆ PL011RxReady()

BOOLEAN PL011RxReady ( _Inout_ PCPPORT Port)
562{
563 PUCHAR BaseAddress;
564 USHORT Flags;
565 BOOLEAN Force32Bit;
566
567 if ((Port == NULL) || (Port->Address == NULL))
568 {
569 return FALSE;
570 }
571
572 //
573 // Read the Flag Register to determine if there is any pending
574 // data to read.
575 //
576
577 BaseAddress = Port->Address;
578 Force32Bit = ((Port->Flags & PORT_FORCE_32BIT_IO) != 0);
579 Flags = PL011_READ_REGISTER_USHORT((PUSHORT)(BaseAddress + UART_FR),
580 Force32Bit);
581
582 //
583 // Check the "receive FIFO empty" flag. If it is clear, then at least one
584 // byte is available.
585 //
586
587 if (CHECK_FLAG(Flags, UART_FR_RXFE) == 0)
588 {
589 return TRUE;
590 }
591
592 return FALSE;
593}
#define CHECK_FLAG(_x, _f)
Definition uartp.h:27

◆ PL011SetBaud()

BOOLEAN PL011SetBaud ( _Inout_ PCPPORT Port,
ULONG Rate )
385{
386 if ((Port == NULL) || (Port->Address == NULL))
387 {
388 return FALSE;
389 }
390
391 //
392 // Remember the baud rate.
393 //
394
395 Port->BaudRate = Rate;
396 return TRUE;
397}

◆ SBSA32InitializePort()

BOOLEAN SBSA32InitializePort ( _In_opt_ _Null_terminated_ PCHAR LoadOptions,
_Inout_ PCPPORT Port,
BOOLEAN MemoryMapped,
UCHAR AccessSize,
UCHAR BitWidth )
356{
357 UNREFERENCED_PARAMETER(BitWidth);
358
359 return SBSAInitializePort(LoadOptions, Port, MemoryMapped, AccessSize, 32);
360}
BOOLEAN SBSAInitializePort(_In_opt_ _Null_terminated_ PCHAR LoadOptions, _Inout_ PCPPORT Port, BOOLEAN MemoryMapped, UCHAR AccessSize, UCHAR BitWidth)
Definition pl011.c:215

◆ SBSAInitializePort()

BOOLEAN SBSAInitializePort ( _In_opt_ _Null_terminated_ PCHAR LoadOptions,
_Inout_ PCPPORT Port,
BOOLEAN MemoryMapped,
UCHAR AccessSize,
UCHAR BitWidth )
249{
250 UINT16 Cr;
251 BOOLEAN Force32Bit;
252
253 UNREFERENCED_PARAMETER(LoadOptions);
254 UNREFERENCED_PARAMETER(AccessSize);
255
256 if (MemoryMapped == FALSE)
257 {
258 return FALSE;
259 }
260
261 if (BitWidth == 32)
262 {
263 Port->Flags = PORT_FORCE_32BIT_IO;
264 Force32Bit = TRUE;
265 }
266 else
267 {
268 Port->Flags = 0;
269 Force32Bit = FALSE;
270 }
271
272 //
273 // Disable UART.
274 //
275
276 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_CR),
277 0,
278 Force32Bit);
279
280 //
281 // Set word length to 8 bits, enable the FIFO, disable parity.
282 //
283
286 Force32Bit);
287
288 //
289 // Clear all interrupts
290 //
291
292 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_IMSC),
293 0x0000,
294 Force32Bit);
295
296 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_ICR),
297 0x07FF,
298 Force32Bit);
299
300 //
301 // Enable UART, Enable Transmit and Receive, Enable RTS.
302 //
303 // The RTS hardware flow control is required to ensure RX FIFO won't be
304 // overflowed on simulator.
305 //
306
307 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_CR),
309 Force32Bit);
310
311 Cr = PL011_READ_REGISTER_USHORT((PUSHORT)(Port->Address + UART_CR),
312 Force32Bit);
313
314 PL011_WRITE_REGISTER_USHORT((PUSHORT)(Port->Address + UART_CR),
315 (Cr | UART_CR_UARTEN),
316 Force32Bit);
317
318 return TRUE;
319}

Variable Documentation

◆ PL011HardwareDriver

UART_HARDWARE_DRIVER PL011HardwareDriver
Initial value:
= {
UART_STATUS PL011GetByte(_Inout_ PCPPORT Port, _Out_ PUCHAR Byte)
Definition pl011.c:400
UART_STATUS PL011PutByte(_Inout_ PCPPORT Port, UCHAR Byte, BOOLEAN BusyWait)
Definition pl011.c:473
BOOLEAN PL011RxReady(_Inout_ PCPPORT Port)
Definition pl011.c:543
BOOLEAN PL011SetBaud(_Inout_ PCPPORT Port, ULONG Rate)
Definition pl011.c:363
BOOLEAN PL011InitializePort(_In_opt_ _Null_terminated_ PCHAR LoadOptions, _Inout_ PCPPORT Port, BOOLEAN MemoryMapped, UCHAR AccessSize, UCHAR BitWidth)
Definition pl011.c:95

◆ SBSA32HardwareDriver

UART_HARDWARE_DRIVER SBSA32HardwareDriver
Initial value:
= {
BOOLEAN SBSA32InitializePort(_In_opt_ _Null_terminated_ PCHAR LoadOptions, _Inout_ PCPPORT Port, BOOLEAN MemoryMapped, UCHAR AccessSize, UCHAR BitWidth)
Definition pl011.c:322

◆ SBSAHardwareDriver

UART_HARDWARE_DRIVER SBSAHardwareDriver