Skip to content

Commit 5b3ebf8

Browse files
committed
[riscv] Support T-Head CPUs using non-standard Memory Attribute Extension
Xuantie/T-Head processors such as the C910 (as used in the Sipeed Lichee Pi 4A) use the high bits of the PTE in a very non-standard way that is incompatible with the RISC-V specification. As per the "Memory Attribute Extension (XTheadMae)", bits 62 and 61 represent cacheability and "bufferability" (write-back cacheability) respectively. If we do not enable these bits, then the processor gets incredibly confused at the point that paging is enabled. The symptom is that cache lines will occasionally fail to fill, and so reads from any address may return unrelated data from a previously read cache line for a different address. Work around these hardware flaws by detecting T-Head CPUs (via the "get machine vendor ID" SBI call), then reading the vendor-specific SXSTATUS register to determine whether or not the vendor-specific Memory Attribute Extension has been enabled by the M-mode firmware. If it has, then set bits 61 and 62 in each page table entry that is used to access normal memory. Signed-off-by: Michael Brown <mcb30@ipxe.org>
1 parent 817145f commit 5b3ebf8

File tree

1 file changed

+59
-7
lines changed

1 file changed

+59
-7
lines changed

src/arch/riscv/prefix/libprefix.S

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,33 @@ page_table:
793793
* use only a single physical 4kB page table.
794794
*/
795795

796+
/** SBI base extension */
797+
#define SBI_BASE 0x10
798+
#define SBI_BASE_MVENDORID 0x04
799+
800+
/** Non-standard T-Head page table entry additional flags
801+
*
802+
* T-Head processors such as the C910 use the high bits of the PTE in
803+
* a very non-standard way that is incompatible with the RISC-V
804+
* specification.
805+
*
806+
* As per the "Memory Attribute Extension (XTheadMae)", bits 62 and 61
807+
* represent cacheability and "bufferability" (i.e. write-back
808+
* cacheability) respectively. If we do not enable these bits, then
809+
* the processor gets incredibly confused at the point that paging is
810+
* enabled. The symptom is that cache lines will occasionally fail to
811+
* fill, and so reads from any address may return unrelated data from
812+
* a previously read cache line for a different address.
813+
*/
814+
#define THEAD_PTE_MAEE ( 0x60 << ( __riscv_xlen - 8 ) )
815+
816+
/** T-Head vendor ID */
817+
#define THEAD_MVENDORID 0x5b7
818+
819+
/** T-Head "sxstatus" CSR */
820+
#define THEAD_CSR_SXSTATUS 0x5c0
821+
#define THEAD_CSR_SXSTATUS_MAEE 0x00200000 /**< XTheadMae enabled */
822+
796823
.section ".prefix.enable_paging_64", "ax", @progbits
797824
enable_paging_64:
798825
/* Register usage:
@@ -805,15 +832,39 @@ enable_paging_64:
805832
* a4 - PTE stride
806833
* a5 - size of accessible physical address space
807834
*/
808-
809835
progress " paging:"
810-
li a1, SATP_MODE_SV57
811836

812837
/* Calculate virtual address offset */
813838
LOADN t0, prefix_link
814839
la t1, _prefix
815840
sub tp, t1, t0
816841

842+
/* Construct base page table entry for address zero */
843+
li t0, PTE_LEAF
844+
STOREN t0, (a0)
845+
846+
/* Check for broken T-Head paging extensions */
847+
mv a3, a0
848+
li a7, SBI_BASE
849+
li a6, SBI_BASE_MVENDORID
850+
ecall
851+
bnez a0, 1f
852+
li t0, THEAD_MVENDORID
853+
bne a1, t0, 1f
854+
progress "thead-"
855+
csrr t0, THEAD_CSR_SXSTATUS
856+
li t1, THEAD_CSR_SXSTATUS_MAEE
857+
and t0, t0, t1
858+
beqz t0, 1f
859+
progress "mae-"
860+
LOADN t0, (a3)
861+
li t1, THEAD_PTE_MAEE
862+
or t0, t0, t1
863+
STOREN t0, (a3)
864+
1: mv a0, a3
865+
866+
/* Find highest supported paging level */
867+
li a1, SATP_MODE_SV57
817868
enable_paging_64_loop:
818869

819870
/* Calculate PTE stride for identity map at this paging level
@@ -841,7 +892,7 @@ enable_paging_64_loop:
841892
/* Construct PTE[0-255] for identity map */
842893
mv a3, a0
843894
li t0, ( PTE_COUNT / 2 )
844-
li t1, PTE_LEAF
895+
LOADN t1, (a0)
845896
1: STOREN t1, (a3)
846897
addi a3, a3, PTE_SIZE
847898
add t1, t1, a4
@@ -886,13 +937,14 @@ enable_paging_64_loop:
886937
/* Construct PTE[x-y] for iPXE virtual address map */
887938
la t0, _prefix
888939
srli t0, t0, PTE_PPN_SHIFT
889-
ori t0, t0, PTE_LEAF
890-
la t1, _ebss
891-
srli t1, t1, PTE_PPN_SHIFT
940+
LOADN t1, (a0)
941+
or t0, t0, t1
942+
la t2, _ebss
943+
srli t2, t2, PTE_PPN_SHIFT
892944
1: STOREN t0, (a3)
893945
addi a3, a3, PTE_SIZE
894946
add t0, t0, a4
895-
ble t0, t1, 1b
947+
ble t0, t2, 1b
896948

897949
/* Attempt to enable paging, and read back active paging level */
898950
slli t0, a1, SATP_MODE_SHIFT

0 commit comments

Comments
 (0)