[freeldr] Rework the ramdisk driver to let it be a full device, instead of a deprecat...
[reactos.git] / reactos / boot / freeldr / freeldr / arch / arm / versuart.c
1 /*
2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/freeldr/arch/arm/versuart.c
5 * PURPOSE: Implements code for Versatile boards using the PL011 UART
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <freeldr.h>
12
13 /* GLOBALS ********************************************************************/
14
15 //
16 // UART Registers
17 //
18 #define UART_PL01x_DR (ArmBoardBlock->UartRegisterBase + 0x00)
19 #define UART_PL01x_RSR (ArmBoardBlock->UartRegisterBase + 0x04)
20 #define UART_PL01x_ECR (ArmBoardBlock->UartRegisterBase + 0x04)
21 #define UART_PL01x_FR (ArmBoardBlock->UartRegisterBase + 0x18)
22 #define UART_PL011_IBRD (ArmBoardBlock->UartRegisterBase + 0x24)
23 #define UART_PL011_FBRD (ArmBoardBlock->UartRegisterBase + 0x28)
24 #define UART_PL011_LCRH (ArmBoardBlock->UartRegisterBase + 0x2C)
25 #define UART_PL011_CR (ArmBoardBlock->UartRegisterBase + 0x30)
26 #define UART_PL011_IMSC (ArmBoardBlock->UartRegisterBase + 0x38)
27
28 //
29 // LCR Values
30 //
31 #define UART_PL011_LCRH_WLEN_8 0x60
32 #define UART_PL011_LCRH_FEN 0x10
33
34 //
35 // FCR Values
36 //
37 #define UART_PL011_CR_UARTEN 0x01
38 #define UART_PL011_CR_TXE 0x100
39 #define UART_PL011_CR_RXE 0x200
40
41 //
42 // LSR Values
43 //
44 #define UART_PL01x_FR_RXFE 0x10
45 #define UART_PL01x_FR_TXFF 0x20
46
47 /* FUNCTIONS ******************************************************************/
48
49 VOID
50 ArmVersaSerialInit(IN ULONG Baudrate)
51 {
52 ULONG Divider, Remainder, Fraction;
53
54 //
55 // Calculate baudrate clock divider and remainder
56 //
57 Divider = ArmBoardBlock->ClockRate / (16 * Baudrate);
58 Remainder = ArmBoardBlock->ClockRate % (16 * Baudrate);
59
60 //
61 // Calculate the fractional part
62 //
63 Fraction = (8 * Remainder / Baudrate) >> 1;
64 Fraction += (8 * Remainder / Baudrate) & 1;
65
66 //
67 // Disable interrupts
68 //
69 WRITE_REGISTER_ULONG(UART_PL011_CR, 0);
70
71 //
72 // Set the baud rate to 115200 bps
73 //
74 WRITE_REGISTER_ULONG(UART_PL011_IBRD, Divider);
75 WRITE_REGISTER_ULONG(UART_PL011_FBRD, Fraction);
76
77 //
78 // Set 8 bits for data, 1 stop bit, no parity, FIFO enabled
79 //
80 WRITE_REGISTER_ULONG(UART_PL011_LCRH,
81 UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN);
82
83 //
84 // Clear and enable FIFO
85 //
86 WRITE_REGISTER_ULONG(UART_PL011_CR,
87 UART_PL011_CR_UARTEN |
88 UART_PL011_CR_TXE |
89 UART_PL011_CR_RXE);
90 }
91
92 VOID
93 ArmVersaPutChar(IN INT Char)
94 {
95 //
96 // Properly support new-lines
97 //
98 if (Char == '\n') ArmVersaPutChar('\r');
99
100 //
101 // Wait for ready
102 //
103 while ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_TXFF) != 0);
104
105 //
106 // Send the character
107 //
108 WRITE_REGISTER_ULONG(UART_PL01x_DR, Char);
109 }
110
111 INT
112 ArmVersaGetCh(VOID)
113 {
114 //
115 // Wait for ready
116 //
117 while ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_RXFE) != 0);
118
119 //
120 // Read the character
121 //
122 return READ_REGISTER_ULONG(UART_PL01x_DR);
123 }
124
125 BOOLEAN
126 ArmVersaKbHit(VOID)
127 {
128 //
129 // Return if something is ready
130 //
131 return ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_RXFE) == 0);
132 }