Date
1 - 4 of 4
[PATCH] hv: support for pci uart with high mmio
hangliu1
to enable early print output by pci uart, which has mmio address
above 4G, add the early pagetable map for the MMIO range. we make an assumption that only map it with 2MB page, since platform with 39bit memory width have no 1G huge page feature and we cannot get the capacity at runtime, since it is a very early code stage. Signed-off-by: hangliu1 <hang1.liu@...> --- hypervisor/debug/uart16550.c | 45 +++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/hypervisor/debug/uart16550.c b/hypervisor/debug/uart16550.c index 1d56ec190..9dad8152f 100644 --- a/hypervisor/debug/uart16550.c +++ b/hypervisor/debug/uart16550.c @@ -121,6 +121,30 @@ static void uart16550_set_baud_rate(uint32_t baud_rate) uart16550_write_reg(uart, temp_reg, UART16550_LCR); } +static uint8_t uart_pde_page[PAGE_SIZE]__aligned(PAGE_SIZE); +static uint8_t uart_pdpte_page[PAGE_SIZE]__aligned(PAGE_SIZE); + +static void early_pgtable_map_uart(uint64_t addr) +{ + uint64_t *pml4e, *pdpte, *pde; + uint64_t value; + + CPU_CR_READ(cr3, &value); + /*assumpiton for map high mmio in early pagetable is that it is only used for + 2MB page since 1G page may not available when memory width is 39bit */ + pml4e = pml4e_offset((uint64_t *)value, addr); + if(!(*pml4e & PAGE_PRESENT)) { + *pml4e = (uint64_t)uart_pdpte_page + (PAGE_PRESENT|PAGE_RW); + } + pdpte = pdpte_offset(pml4e, addr); + /*make assumption here that *pdpte is not present since not setup + in assemble code except adress below 4G, which must be ensured not to + passed to this function*/ + *(pdpte) = (uint64_t)uart_pde_page+ (PAGE_PRESENT|PAGE_RW); + pde = pde_offset(pdpte, addr); + *pde = (addr & PDE_MASK) + (PAGE_PRESENT|PAGE_RW|PAGE_PSE); +} + void uart16550_init(bool early_boot) { void *mmio_base_va = NULL; @@ -154,19 +178,18 @@ void uart16550_init(bool early_boot) uart.port_address = (uint16_t)(bar0 & PCI_BASE_ADDRESS_IO_MASK); uart.reg_width = 1; pci_pdev_write_cfg(uart.bdf, PCIR_COMMAND, 2U, cmd | PCIM_CMD_PORTEN); - } else { - uint32_t bar_hi = pci_pdev_read_cfg(uart.bdf, pci_bar_offset(1), 4U); - - /* Enable the PCI UART if the BAR is 32bit, or 64bit with 4GB- mmio space. */ - if (((bar0 & 0x7U) == 0U) || (((bar0 & 0x7U) == 4U) && (bar_hi == 0U))) { + } else if (((bar0 & 0x7U) == 0U) || ((bar0 & 0x7U) == 4U)) { uart.type = MMIO; - uart.mmio_base_vaddr = hpa2hva_early((bar0 & PCI_BASE_ADDRESS_MEM_MASK)); + uint32_t bar_hi = pci_pdev_read_cfg(uart.bdf, pci_bar_offset(1), 4U); + uint64_t addr = (bar0 & PCI_BASE_ADDRESS_MEM_MASK)|(((uint64_t)bar_hi) << 32U); + if (bar_hi != 0U) { + early_pgtable_map_uart(addr); + } + uart.mmio_base_vaddr = hpa2hva_early(addr); pci_pdev_write_cfg(uart.bdf, PCIR_COMMAND, 2U, cmd | PCIM_CMD_MEMEN); - } else { - /* TODO: enable 64bit BAR with 4GB+ mmio space */ - uart.enabled = false; - return; - } + } else { + uart.enabled = false; + return; } } } -- 2.25.1 |
|
Li, Fei1
+static uint8_t uart_pde_page[PAGE_SIZE]__aligned(PAGE_SIZE);align + 2MB page since 1G page may not available when memory width is 39bit *//* address is above 512G */ + if(!(*pml4e & PAGE_PRESENT)) {hva2hpa_early(uart_pdpte_page) + (PAGE_PRESENT | PAGE_RW); + }align + /*make assumption here that *pdpte is not present since not setupAdd ASSERT here or add check whether pdpte is present here. + *(pdpte) = (uint64_t)uart_pde_page+ (PAGE_PRESENT|PAGE_RW);hva2hpa_early(uart_pde_page) + pde = pde_offset(pdpte, addr); |
|
toggle quoted message
Show quoted text
-----Original Message-----We only do this for 64 bit MMIO BAR. Not for 32 bit MMIO BAR though bar_hi is likely 0 for this case. + if (bar_hi != 0U) { |
|
hangliu1
On Mon, Nov 21, 2022 at 06:18:39PM +0000, Eddie Dong wrote:
yes, but this patch is merged, it will be soon be modified by later patches regarding other uart-----Original Message-----We only do this for 64 bit MMIO BAR. Not for 32 bit MMIO BAR though bar_hi is likely 0 for this case. changes. + if (bar_hi != 0U) { |
|