mirror of
https://github.com/ipxe/ipxe
synced 2026-01-22 20:19:08 +03:00
[riscv] Support mapping early UARTs outside of the identity map
Some platforms (such as the Sipeed Lichee Pi 4A) choose to make early debugging entertainingly cumbersome for the programmer. These platforms not only fail to provide a functional SBI debug console, but also choose to place the UART at a physical address that cannot be identity-mapped under the only paging model supported by the CPU. Support such platforms by creating a virtual address mapping for the early UART (in the 2MB megapage immediately below iPXE itself), and using this as the UART base address whenever paging is enabled. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -149,10 +149,33 @@ prefix_virt:
|
||||
|
||||
#define print_char_uart _C2 ( print_char_uart_, EARLY_UART_MODEL )
|
||||
|
||||
#define early_uart_reg_base _C2 ( early_uart_reg_base_, __riscv_xlen )
|
||||
|
||||
/* Print character via nonexistent UART */
|
||||
.macro print_char_uart_none
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Get UART base address (64-bit addressing)
|
||||
*/
|
||||
.macro early_uart_reg_base_64 reg
|
||||
csrr \reg, satp
|
||||
beqz \reg, early_uart_reg_base_64_nonpaged_\@
|
||||
LOADN \reg, early_uart_reg_base_64_virt
|
||||
j early_uart_reg_base_64_done_\@
|
||||
early_uart_reg_base_64_nonpaged_\@:
|
||||
li \reg, EARLY_UART_REG_BASE
|
||||
early_uart_reg_base_64_done_\@:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Get UART base address (32-bit addressing)
|
||||
*/
|
||||
.macro early_uart_reg_base_32 reg
|
||||
li \reg, EARLY_UART_REG_BASE
|
||||
sub \reg, \reg, tp
|
||||
.endm
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Print character via 8250-compatible early UART
|
||||
@@ -179,7 +202,7 @@ prefix_virt:
|
||||
#define EARLY_UART_8250_LSR_THRE 0x20
|
||||
|
||||
.macro print_char_uart_8250
|
||||
li a7, EARLY_UART_REG_BASE
|
||||
early_uart_reg_base a7
|
||||
sb a0, EARLY_UART_8250_TX(a7)
|
||||
uart_wait_\@:
|
||||
lbu a1, EARLY_UART_8250_LSR(a7)
|
||||
@@ -749,6 +772,7 @@ enable_paging_64:
|
||||
* a4 - PTE stride
|
||||
* a5 - size of accessible physical address space
|
||||
*/
|
||||
|
||||
progress " paging:"
|
||||
li a1, SATP_MODE_SV57
|
||||
|
||||
@@ -818,6 +842,14 @@ enable_paging_64_loop:
|
||||
li a4, 1
|
||||
slli a4, a4, PTE_PPN1_LSB
|
||||
|
||||
/* Construct PTE[x-1] for early UART, if applicable */
|
||||
#ifdef EARLY_UART_REG_BASE
|
||||
li t0, ( EARLY_UART_REG_BASE & ~( ( 1 << VPN1_LSB ) - 1 ) )
|
||||
srli t0, t0, PTE_PPN_SHIFT
|
||||
ori t0, t0, PTE_LEAF
|
||||
STOREN t0, -PTE_SIZE(a3)
|
||||
#endif
|
||||
|
||||
/* Construct PTE[x-y] for iPXE virtual address map */
|
||||
la t0, _prefix
|
||||
srli t0, t0, PTE_PPN_SHIFT
|
||||
@@ -862,6 +894,20 @@ enable_paging_64_loop:
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/* Early UART base address when 64-bit paging is enabled
|
||||
*
|
||||
* When an early UART is in use, we choose to use the 2MB
|
||||
* "megapage" immediately below iPXE itself to map the UART.
|
||||
*/
|
||||
#ifdef EARLY_UART_REG_BASE
|
||||
.section ".rodata.early_uart_reg_base_64_virt", "a", @progbits
|
||||
.balign 8
|
||||
early_uart_reg_base_64_virt:
|
||||
.dword ( _base - ( 1 << VPN1_LSB ) + \
|
||||
( EARLY_UART_REG_BASE & ( ( 1 << VPN1_LSB ) - 1 ) ) )
|
||||
.size early_uart_reg_base_64_virt, . - early_uart_reg_base_64_virt
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Disable 64-bit paging
|
||||
@@ -1152,6 +1198,7 @@ install:
|
||||
* s6 - relocation offset
|
||||
* tp - virtual address offset
|
||||
*/
|
||||
mv tp, zero
|
||||
progress "\r\nSBI->iPXE hart:"
|
||||
print_hex_reg a0
|
||||
progress " temp:"
|
||||
@@ -1167,9 +1214,6 @@ install:
|
||||
mv s2, ra
|
||||
la s3, _edata
|
||||
|
||||
/* Initialise virtual address offset */
|
||||
mv tp, zero
|
||||
|
||||
/* Attempt to enable paging, if we have temporary page table space */
|
||||
mv a0, a2
|
||||
beqz a2, 1f
|
||||
|
||||
Reference in New Issue
Block a user