diff --git a/sys/riscv/include/pte.h b/sys/riscv/include/pte.h --- a/sys/riscv/include/pte.h +++ b/sys/riscv/include/pte.h @@ -102,6 +102,32 @@ #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 --- 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 --- a/sys/riscv/riscv/identcpu.c +++ b/sys/riscv/riscv/identcpu.c @@ -470,6 +470,7 @@ 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 --- 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 @@ 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 --- 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 --------------------- */ /* MHTODO: we could parse this information from the device tree. */