14
14
15
15
#define MAX_BDF_LEN 8
16
16
17
+ struct console_uart {
18
+ bool enabled ;
19
+ bool serial_port_mapped ;
20
+ union {
21
+ uint16_t port_address ;
22
+ void * mmio_base_vaddr ;
23
+ };
24
+ spinlock_t rx_lock ;
25
+ spinlock_t tx_lock ;
26
+ };
27
+
17
28
#if defined(CONFIG_SERIAL_PIO_BASE )
18
- static bool serial_port_mapped = true;
19
- static bool uart_enabled = true;
20
- static uint64_t uart_base_address = CONFIG_SERIAL_PIO_BASE ;
29
+ static struct console_uart uart = {
30
+ .enabled = true,
31
+ .serial_port_mapped = true,
32
+ .port_address = CONFIG_SERIAL_PIO_BASE ,
33
+ };
21
34
static char pci_bdf_info [MAX_BDF_LEN + 1U ];
22
35
#elif defined(CONFIG_SERIAL_PCI_BDF )
23
- static bool serial_port_mapped ;
24
- static bool uart_enabled = true;
25
- static uint64_t uart_base_address ;
36
+ static struct console_uart uart = {
37
+ . enabled = true,
38
+ } ;
26
39
static char pci_bdf_info [MAX_BDF_LEN + 1U ] = CONFIG_SERIAL_PCI_BDF ;
27
40
#else
28
- static bool serial_port_mapped ;
29
- static bool uart_enabled ;
30
- static uint64_t uart_base_address ;
41
+ static struct console_uart uart ;
31
42
static char pci_bdf_info [MAX_BDF_LEN + 1U ];
32
43
#endif
33
44
34
45
typedef uint32_t uart_reg_t ;
35
-
36
- static spinlock_t uart_rx_lock ;
37
- static spinlock_t uart_tx_lock ;
38
46
static union pci_bdf serial_pci_bdf ;
39
47
40
48
/* PCI BDF must follow format: bus:dev.func, for example 0:18.2 */
@@ -64,26 +72,26 @@ static uint16_t get_pci_bdf_value(char *bdf)
64
72
}
65
73
66
74
/**
67
- * @pre uart_enabled == true
75
+ * @pre uart->enabled == true
68
76
*/
69
- static inline uint32_t uart16550_read_reg (uint64_t base , uint16_t reg_idx )
77
+ static inline uint32_t uart16550_read_reg (struct console_uart uart , uint16_t reg_idx )
70
78
{
71
- if (serial_port_mapped ) {
72
- return pio_read8 (( uint16_t ) base + reg_idx );
79
+ if (uart . serial_port_mapped ) {
80
+ return pio_read8 (uart . port_address + reg_idx );
73
81
} else {
74
- return mmio_read32 ((void * )(( uint32_t * )hpa2hva ( base ) + reg_idx ) );
82
+ return mmio_read32 ((uint32_t * )uart . mmio_base_vaddr + reg_idx );
75
83
}
76
84
}
77
85
78
86
/**
79
- * @pre uart_enabled == true
87
+ * @pre uart->enabled == true
80
88
*/
81
- static inline void uart16550_write_reg (uint64_t base , uint32_t val , uint16_t reg_idx )
89
+ static inline void uart16550_write_reg (struct console_uart uart , uint32_t val , uint16_t reg_idx )
82
90
{
83
- if (serial_port_mapped ) {
84
- pio_write8 (( uint8_t ) val , ( uint16_t ) base + reg_idx );
91
+ if (uart . serial_port_mapped ) {
92
+ pio_write8 (val , uart . port_address + reg_idx );
85
93
} else {
86
- mmio_write32 (val , (void * )(( uint32_t * )hpa2hva ( base ) + reg_idx ) );
94
+ mmio_write32 (val , (uint32_t * )uart . mmio_base_vaddr + reg_idx );
87
95
}
88
96
}
89
97
@@ -99,7 +107,7 @@ static void uart16550_calc_baud_div(uint32_t ref_freq, uint32_t *baud_div_ptr, u
99
107
}
100
108
101
109
/**
102
- * @pre uart_enabled == true
110
+ * @pre uart->enabled == true
103
111
*/
104
112
static void uart16550_set_baud_rate (uint32_t baud_rate )
105
113
{
@@ -110,75 +118,76 @@ static void uart16550_set_baud_rate(uint32_t baud_rate)
110
118
uart16550_calc_baud_div (duart_clock , & baud_div , baud_rate );
111
119
112
120
/* Enable DLL and DLM registers for setting the Divisor */
113
- temp_reg = uart16550_read_reg (uart_base_address , UART16550_LCR );
121
+ temp_reg = uart16550_read_reg (uart , UART16550_LCR );
114
122
temp_reg |= LCR_DLAB ;
115
- uart16550_write_reg (uart_base_address , temp_reg , UART16550_LCR );
123
+ uart16550_write_reg (uart , temp_reg , UART16550_LCR );
116
124
117
125
/* Write the appropriate divisor value */
118
- uart16550_write_reg (uart_base_address , ((baud_div >> 8U ) & 0xFFU ), UART16550_DLM );
119
- uart16550_write_reg (uart_base_address , (baud_div & 0xFFU ), UART16550_DLL );
126
+ uart16550_write_reg (uart , ((baud_div >> 8U ) & 0xFFU ), UART16550_DLM );
127
+ uart16550_write_reg (uart , (baud_div & 0xFFU ), UART16550_DLL );
120
128
121
129
/* Disable DLL and DLM registers */
122
130
temp_reg &= ~LCR_DLAB ;
123
- uart16550_write_reg (uart_base_address , temp_reg , UART16550_LCR );
131
+ uart16550_write_reg (uart , temp_reg , UART16550_LCR );
124
132
}
125
133
126
134
void uart16550_init (void )
127
135
{
128
- if (!uart_enabled ) {
136
+ if (!uart . enabled ) {
129
137
return ;
130
138
}
131
139
132
140
/* if configure serial PCI BDF, get its base MMIO address */
133
- if (!serial_port_mapped ) {
141
+ if (!uart . serial_port_mapped ) {
134
142
serial_pci_bdf .value = get_pci_bdf_value (pci_bdf_info );
135
- uart_base_address = pci_pdev_read_cfg (serial_pci_bdf , pci_bar_offset (0 ), 4U ) & PCIM_BAR_MEM_BASE ;
143
+ uart .mmio_base_vaddr =
144
+ hpa2hva (pci_pdev_read_cfg (serial_pci_bdf , pci_bar_offset (0 ), 4U ) & PCIM_BAR_MEM_BASE );
136
145
}
137
146
138
- if (!serial_port_mapped ) {
139
- hv_access_memory_region_update (uart_base_address , PDE_SIZE );
147
+ if (!uart . serial_port_mapped ) {
148
+ hv_access_memory_region_update (( uint64_t ) uart . mmio_base_vaddr , PDE_SIZE );
140
149
}
141
150
142
- spinlock_init (& uart_rx_lock );
143
- spinlock_init (& uart_tx_lock );
151
+ spinlock_init (& uart . rx_lock );
152
+ spinlock_init (& uart . tx_lock );
144
153
/* Enable TX and RX FIFOs */
145
- uart16550_write_reg (uart_base_address , FCR_FIFOE | FCR_RFR | FCR_TFR , UART16550_FCR );
154
+ uart16550_write_reg (uart , FCR_FIFOE | FCR_RFR | FCR_TFR , UART16550_FCR );
146
155
147
156
/* Set-up data bits / parity / stop bits. */
148
- uart16550_write_reg (uart_base_address , (LCR_WL8 | LCR_NB_STOP_BITS_1 | LCR_PARITY_NONE ), UART16550_LCR );
157
+ uart16550_write_reg (uart , (LCR_WL8 | LCR_NB_STOP_BITS_1 | LCR_PARITY_NONE ), UART16550_LCR );
149
158
150
159
/* Disable interrupts (we use polling) */
151
- uart16550_write_reg (uart_base_address , UART_IER_DISABLE_ALL , UART16550_IER );
160
+ uart16550_write_reg (uart , UART_IER_DISABLE_ALL , UART16550_IER );
152
161
153
162
/* Set baud rate */
154
163
uart16550_set_baud_rate (BAUD_115200 );
155
164
156
165
/* Data terminal ready + Request to send */
157
- uart16550_write_reg (uart_base_address , MCR_RTS | MCR_DTR , UART16550_MCR );
166
+ uart16550_write_reg (uart , MCR_RTS | MCR_DTR , UART16550_MCR );
158
167
}
159
168
160
169
char uart16550_getc (void )
161
170
{
162
171
char ret = -1 ;
163
172
164
- if (!uart_enabled ) {
173
+ if (!uart . enabled ) {
165
174
return ret ;
166
175
}
167
176
168
- spinlock_obtain (& uart_rx_lock );
177
+ spinlock_obtain (& uart . rx_lock );
169
178
170
179
/* If a character has been received, read it */
171
- if ((uart16550_read_reg (uart_base_address , UART16550_LSR ) & LSR_DR ) == LSR_DR ) {
180
+ if ((uart16550_read_reg (uart , UART16550_LSR ) & LSR_DR ) == LSR_DR ) {
172
181
/* Read a character */
173
- ret = uart16550_read_reg (uart_base_address , UART16550_RBR );
182
+ ret = uart16550_read_reg (uart , UART16550_RBR );
174
183
175
184
}
176
- spinlock_release (& uart_rx_lock );
185
+ spinlock_release (& uart . rx_lock );
177
186
return ret ;
178
187
}
179
188
180
189
/**
181
- * @pre uart_enabled == true
190
+ * @pre uart->enabled == true
182
191
*/
183
192
static void uart16550_putc (char c )
184
193
{
@@ -187,21 +196,21 @@ static void uart16550_putc(char c)
187
196
188
197
/* Ensure there are no further Transmit buffer write requests */
189
198
do {
190
- reg = uart16550_read_reg (uart_base_address , UART16550_LSR );
199
+ reg = uart16550_read_reg (uart , UART16550_LSR );
191
200
} while ((reg & LSR_THRE ) == 0U || (reg & LSR_TEMT ) == 0U );
192
201
193
202
temp = (uint8_t )c ;
194
203
/* Transmit the character. */
195
- uart16550_write_reg (uart_base_address , (uint32_t )temp , UART16550_THR );
204
+ uart16550_write_reg (uart , (uint32_t )temp , UART16550_THR );
196
205
}
197
206
198
207
size_t uart16550_puts (const char * buf , uint32_t len )
199
208
{
200
209
uint32_t i ;
201
- if (!uart_enabled ) {
210
+ if (!uart . enabled ) {
202
211
return len ;
203
212
}
204
- spinlock_obtain (& uart_tx_lock );
213
+ spinlock_obtain (& uart . tx_lock );
205
214
for (i = 0U ; i < len ; i ++ ) {
206
215
/* Transmit character */
207
216
uart16550_putc (* buf );
@@ -211,17 +220,17 @@ size_t uart16550_puts(const char *buf, uint32_t len)
211
220
}
212
221
buf ++ ;
213
222
}
214
- spinlock_release (& uart_tx_lock );
223
+ spinlock_release (& uart . tx_lock );
215
224
return len ;
216
225
}
217
226
218
227
void uart16550_set_property (bool enabled , bool port_mapped , uint64_t base_addr )
219
228
{
220
- uart_enabled = enabled ;
221
- serial_port_mapped = port_mapped ;
229
+ uart . enabled = enabled ;
230
+ uart . serial_port_mapped = port_mapped ;
222
231
223
232
if (port_mapped ) {
224
- uart_base_address = base_addr ;
233
+ uart . port_address = base_addr ;
225
234
} else {
226
235
const char * bdf = (const char * )base_addr ;
227
236
strncpy_s (pci_bdf_info , MAX_BDF_LEN + 1U , bdf , MAX_BDF_LEN );
@@ -232,7 +241,7 @@ bool is_pci_dbg_uart(union pci_bdf bdf_value)
232
241
{
233
242
bool ret = false;
234
243
235
- if (uart_enabled && !serial_port_mapped ) {
244
+ if (uart . enabled && !uart . serial_port_mapped ) {
236
245
if (bdf_value .value == serial_pci_bdf .value ) {
237
246
ret = true;
238
247
}
0 commit comments