diff --git a/sys/riscv/include/pte.h b/sys/riscv/include/pte.h index 34cd2a674627..77a7817fd27e 100644 --- a/sys/riscv/include/pte.h +++ b/sys/riscv/include/pte.h @@ -102,6 +102,32 @@ typedef uint64_t pn_t; /* page number */ #define PTE_MA_NC (1ul << PTE_MA_SHIFT) #define PTE_MA_IO (2ul << PTE_MA_SHIFT) +/* + * T-HEAD Custom Memory Attribute (MA) bits [63:59]. + * + * bit 59: Trustable (relating to TEE) + * bit 60: Shareable (among CPUs, not configurable) + * bit 61: Bufferable (writes to device memory) + * bit 62: Cacheable + * bit 63: Memory Ordering (1 = strongly ordered (device), 0 = default) + * + * +------+-------+------------------------------------------------------------+ + * | Mode | Value | Requested Memory Attributes | + * +------+-------+------------------------------------------------------------+ + * | NC | 00110 | Weakly-ordered, non-cacheable, bufferable, shareable, | + * | | | non-trustable | + * | PMA | 01110 | Weakly-ordered, cacheable, bufferable, shareable, | + * | | | non-trustable | + * | IO | 10010 | Strongly-ordered, non-cacheable, non-bufferable, | + * | | | shareable, non-trustable | + * +------+-------+------------------------------------------------------------+ + */ +#define PTE_THEAD_MA_SHIFT 59 +#define PTE_THEAD_MA_MASK (0x1ful << PTE_THEAD_MA_SHIFT) +#define PTE_THEAD_MA_NC (0x6ul << PTE_THEAD_MA_SHIFT) +#define PTE_THEAD_MA_NONE (0xeul << PTE_THEAD_MA_SHIFT) +#define PTE_THEAD_MA_IO (0x12ul << PTE_THEAD_MA_SHIFT) + /* Bits 63 - 54 are reserved for future use. */ #define PTE_HI_MASK 0xFFC0000000000000ULL diff --git a/sys/riscv/include/thead.h b/sys/riscv/include/thead.h index e11d5c37374c..7d845f6660e8 100644 --- a/sys/riscv/include/thead.h +++ b/sys/riscv/include/thead.h @@ -30,6 +30,8 @@ #ifndef _RISCV_THEAD_H_ #define _RISCV_THEAD_H_ +extern bool has_errata_thead_pbmt; + void thead_setup_cache(void); #endif /* _RISCV_THEAD_H_ */ diff --git a/sys/riscv/riscv/identcpu.c b/sys/riscv/riscv/identcpu.c index f85aed88d3b9..e02907092b56 100644 --- a/sys/riscv/riscv/identcpu.c +++ b/sys/riscv/riscv/identcpu.c @@ -470,6 +470,7 @@ handle_thead_quirks(u_int cpu, struct cpu_desc *desc) if (cpu != 0) return; + has_errata_thead_pbmt = true; thead_setup_cache(); } diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index e11adba0d832..c8a69f9674e9 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -156,6 +156,7 @@ #include #include #include +#include /* * Boundary values for the page table page index space: @@ -867,6 +868,11 @@ pmap_bootstrap(vm_paddr_t kernstart, vm_size_t kernlen) memattr_bits[VM_MEMATTR_UNCACHEABLE] = PTE_MA_NC; memattr_bits[VM_MEMATTR_DEVICE] = PTE_MA_IO; memattr_mask = PTE_MA_MASK; + } else if (has_errata_thead_pbmt) { + memattr_bits[VM_MEMATTR_PMA] = PTE_THEAD_MA_NONE; + memattr_bits[VM_MEMATTR_UNCACHEABLE] = PTE_THEAD_MA_NC; + memattr_bits[VM_MEMATTR_DEVICE] = PTE_THEAD_MA_IO; + memattr_mask = PTE_THEAD_MA_MASK; } /* Create a new set of pagetables to run the kernel in. */ diff --git a/sys/riscv/thead/thead.c b/sys/riscv/thead/thead.c index f959d32cfed8..c72f4f1312e0 100644 --- a/sys/riscv/thead/thead.c +++ b/sys/riscv/thead/thead.c @@ -32,6 +32,8 @@ #include +bool has_errata_thead_pbmt = false; + /* ----------------- dcache ops --------------------- */