diff --git a/sys/riscv/riscv/locore.S b/sys/riscv/riscv/locore.S --- a/sys/riscv/riscv/locore.S +++ b/sys/riscv/riscv/locore.S @@ -148,12 +148,17 @@ /* Get the kernel's load address (kernstart) in s9 */ jal get_physmem + /* Get PTE attribute bits in s8. */ + call _C_LABEL(thead_get_pte_fixup_bits) + mv s8, a0 + /* Construct 1GB Identity Map (1:1 PA->VA) */ lla s1, bootstrap_pt_l1 srli s2, s9, L1_SHIFT /* kernstart >> L1_SHIFT */ andi a5, s2, Ln_ADDR_MASK /* & Ln_ADDR_MASK */ li t4, (PTE_KERN) + or t4, t4, s8 /* t4 |= pte bits */ slli s2, s2, PTE_PPN2_S /* (s2 << PTE_PPN2_S) */ or t6, t4, s2 @@ -189,6 +194,7 @@ li t2, Ln_ENTRIES /* Build 512 entries */ add t3, t4, t2 li t0, (PTE_KERN | PTE_X) + or t0, t0, s8 /* t0 |= pte bits */ 1: slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */ or t5, t0, t2 diff --git a/sys/riscv/thead/thead.c b/sys/riscv/thead/thead.c --- a/sys/riscv/thead/thead.c +++ b/sys/riscv/thead/thead.c @@ -30,10 +30,30 @@ #include #include +#include +#include #include bool has_errata_thead_pbmt = false; +pt_entry_t thead_get_pte_fixup_bits(void); + +/* + * This function is called extremely early from locore assembly. Unfortunately, + * the PTE memory attribute bits for 'normal' memory are non-zero, therefore + * they must be set correctly in the initial set of page tables. + */ +pt_entry_t +thead_get_pte_fixup_bits(void) +{ + register_t mvendorid = sbi_get_mvendorid(); + + if (mvendorid == MVENDORID_THEAD) + return (PTE_THEAD_MA_NONE); + + return (0ul); +} + /* ----------------- dcache ops --------------------- */ /* MHTODO: we could parse this information from the device tree. */