Skip to content

Commit 18ecdc1

Browse files
lifeixacrnsi
authored andcommitted
hv: uart: make uart base address more readable
Now if the uart is mapped to a PIO address space, the uart base address is a physical PIO address; if it's mapped to a MMIO address space, the uart base address is a virtual MMIO address. Add union uart_addr structure to imply this. And define a console_uart structure to add all uart related fields into this structure. Tracked-On: #2987 Signed-off-by: Li, Fei1 <fei1.li@intel.com>
1 parent 49e60ae commit 18ecdc1

File tree

1 file changed

+63
-54
lines changed

1 file changed

+63
-54
lines changed

hypervisor/debug/uart16550.c

Lines changed: 63 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,35 @@
1414

1515
#define MAX_BDF_LEN 8
1616

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+
1728
#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+
};
2134
static char pci_bdf_info[MAX_BDF_LEN + 1U];
2235
#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+
};
2639
static char pci_bdf_info[MAX_BDF_LEN + 1U] = CONFIG_SERIAL_PCI_BDF;
2740
#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;
3142
static char pci_bdf_info[MAX_BDF_LEN + 1U];
3243
#endif
3344

3445
typedef uint32_t uart_reg_t;
35-
36-
static spinlock_t uart_rx_lock;
37-
static spinlock_t uart_tx_lock;
3846
static union pci_bdf serial_pci_bdf;
3947

4048
/* 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)
6472
}
6573

6674
/**
67-
* @pre uart_enabled == true
75+
* @pre uart->enabled == true
6876
*/
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)
7078
{
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);
7381
} else {
74-
return mmio_read32((void *)((uint32_t *)hpa2hva(base) + reg_idx));
82+
return mmio_read32((uint32_t *)uart.mmio_base_vaddr + reg_idx);
7583
}
7684
}
7785

7886
/**
79-
* @pre uart_enabled == true
87+
* @pre uart->enabled == true
8088
*/
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)
8290
{
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);
8593
} else {
86-
mmio_write32(val, (void *)((uint32_t *)hpa2hva(base) + reg_idx));
94+
mmio_write32(val, (uint32_t *)uart.mmio_base_vaddr + reg_idx);
8795
}
8896
}
8997

@@ -99,7 +107,7 @@ static void uart16550_calc_baud_div(uint32_t ref_freq, uint32_t *baud_div_ptr, u
99107
}
100108

101109
/**
102-
* @pre uart_enabled == true
110+
* @pre uart->enabled == true
103111
*/
104112
static void uart16550_set_baud_rate(uint32_t baud_rate)
105113
{
@@ -110,75 +118,76 @@ static void uart16550_set_baud_rate(uint32_t baud_rate)
110118
uart16550_calc_baud_div(duart_clock, &baud_div, baud_rate);
111119

112120
/* 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);
114122
temp_reg |= LCR_DLAB;
115-
uart16550_write_reg(uart_base_address, temp_reg, UART16550_LCR);
123+
uart16550_write_reg(uart, temp_reg, UART16550_LCR);
116124

117125
/* 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);
120128

121129
/* Disable DLL and DLM registers */
122130
temp_reg &= ~LCR_DLAB;
123-
uart16550_write_reg(uart_base_address, temp_reg, UART16550_LCR);
131+
uart16550_write_reg(uart, temp_reg, UART16550_LCR);
124132
}
125133

126134
void uart16550_init(void)
127135
{
128-
if (!uart_enabled) {
136+
if (!uart.enabled) {
129137
return;
130138
}
131139

132140
/* if configure serial PCI BDF, get its base MMIO address */
133-
if (!serial_port_mapped) {
141+
if (!uart.serial_port_mapped) {
134142
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);
136145
}
137146

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);
140149
}
141150

142-
spinlock_init(&uart_rx_lock);
143-
spinlock_init(&uart_tx_lock);
151+
spinlock_init(&uart.rx_lock);
152+
spinlock_init(&uart.tx_lock);
144153
/* 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);
146155

147156
/* 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);
149158

150159
/* 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);
152161

153162
/* Set baud rate */
154163
uart16550_set_baud_rate(BAUD_115200);
155164

156165
/* 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);
158167
}
159168

160169
char uart16550_getc(void)
161170
{
162171
char ret = -1;
163172

164-
if (!uart_enabled) {
173+
if (!uart.enabled) {
165174
return ret;
166175
}
167176

168-
spinlock_obtain(&uart_rx_lock);
177+
spinlock_obtain(&uart.rx_lock);
169178

170179
/* 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) {
172181
/* Read a character */
173-
ret = uart16550_read_reg(uart_base_address, UART16550_RBR);
182+
ret = uart16550_read_reg(uart, UART16550_RBR);
174183

175184
}
176-
spinlock_release(&uart_rx_lock);
185+
spinlock_release(&uart.rx_lock);
177186
return ret;
178187
}
179188

180189
/**
181-
* @pre uart_enabled == true
190+
* @pre uart->enabled == true
182191
*/
183192
static void uart16550_putc(char c)
184193
{
@@ -187,21 +196,21 @@ static void uart16550_putc(char c)
187196

188197
/* Ensure there are no further Transmit buffer write requests */
189198
do {
190-
reg = uart16550_read_reg(uart_base_address, UART16550_LSR);
199+
reg = uart16550_read_reg(uart, UART16550_LSR);
191200
} while ((reg & LSR_THRE) == 0U || (reg & LSR_TEMT) == 0U);
192201

193202
temp = (uint8_t)c;
194203
/* 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);
196205
}
197206

198207
size_t uart16550_puts(const char *buf, uint32_t len)
199208
{
200209
uint32_t i;
201-
if (!uart_enabled) {
210+
if (!uart.enabled) {
202211
return len;
203212
}
204-
spinlock_obtain(&uart_tx_lock);
213+
spinlock_obtain(&uart.tx_lock);
205214
for (i = 0U; i < len; i++) {
206215
/* Transmit character */
207216
uart16550_putc(*buf);
@@ -211,17 +220,17 @@ size_t uart16550_puts(const char *buf, uint32_t len)
211220
}
212221
buf++;
213222
}
214-
spinlock_release(&uart_tx_lock);
223+
spinlock_release(&uart.tx_lock);
215224
return len;
216225
}
217226

218227
void uart16550_set_property(bool enabled, bool port_mapped, uint64_t base_addr)
219228
{
220-
uart_enabled = enabled;
221-
serial_port_mapped = port_mapped;
229+
uart.enabled = enabled;
230+
uart.serial_port_mapped = port_mapped;
222231

223232
if (port_mapped) {
224-
uart_base_address = base_addr;
233+
uart.port_address = base_addr;
225234
} else {
226235
const char *bdf = (const char *)base_addr;
227236
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)
232241
{
233242
bool ret = false;
234243

235-
if (uart_enabled && !serial_port_mapped) {
244+
if (uart.enabled && !uart.serial_port_mapped) {
236245
if (bdf_value.value == serial_pci_bdf.value) {
237246
ret = true;
238247
}

0 commit comments

Comments
 (0)