riscv/vmm: use Svpbmt extension when available
This commit is contained in:
parent
e3d65aa628
commit
90b82dc43f
|
@ -246,6 +246,7 @@ level4:
|
||||||
#define PT_FLAG_USER ((uint64_t)1 << 4)
|
#define PT_FLAG_USER ((uint64_t)1 << 4)
|
||||||
#define PT_FLAG_ACCESSED ((uint64_t)1 << 6)
|
#define PT_FLAG_ACCESSED ((uint64_t)1 << 6)
|
||||||
#define PT_FLAG_DIRTY ((uint64_t)1 << 7)
|
#define PT_FLAG_DIRTY ((uint64_t)1 << 7)
|
||||||
|
#define PT_FLAG_PBMT_NC ((uint64_t)1 << 62)
|
||||||
#define PT_PADDR_MASK ((uint64_t)0x003ffffffffffc00)
|
#define PT_PADDR_MASK ((uint64_t)0x003ffffffffffc00)
|
||||||
|
|
||||||
#define PT_FLAG_RWX (PT_FLAG_READ | PT_FLAG_WRITE | PT_FLAG_EXEC)
|
#define PT_FLAG_RWX (PT_FLAG_READ | PT_FLAG_WRITE | PT_FLAG_EXEC)
|
||||||
|
@ -265,6 +266,8 @@ static uint64_t pt_to_vmm_flags_internal(pt_entry_t entry) {
|
||||||
flags |= VMM_FLAG_WRITE;
|
flags |= VMM_FLAG_WRITE;
|
||||||
if (!(entry & PT_FLAG_EXEC))
|
if (!(entry & PT_FLAG_EXEC))
|
||||||
flags |= VMM_FLAG_NOEXEC;
|
flags |= VMM_FLAG_NOEXEC;
|
||||||
|
if (entry & PT_FLAG_PBMT_NC)
|
||||||
|
flags |= VMM_FLAG_FB;
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
@ -331,11 +334,19 @@ done:
|
||||||
return 6 + max_level;
|
return 6 + max_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pt_entry_t pbmt_nc = 0;
|
||||||
|
|
||||||
pagemap_t new_pagemap(int paging_mode) {
|
pagemap_t new_pagemap(int paging_mode) {
|
||||||
pagemap_t pagemap;
|
pagemap_t pagemap;
|
||||||
pagemap.paging_mode = paging_mode;
|
pagemap.paging_mode = paging_mode;
|
||||||
pagemap.max_page_size = paging_mode - 6;
|
pagemap.max_page_size = paging_mode - 6;
|
||||||
pagemap.top_level = ext_mem_alloc(PT_SIZE);
|
pagemap.top_level = ext_mem_alloc(PT_SIZE);
|
||||||
|
|
||||||
|
if (riscv_check_isa_extension("svpbmt", NULL, NULL)) {
|
||||||
|
printv("riscv: Svpbmt extension is supported.\n");
|
||||||
|
pbmt_nc = PT_FLAG_PBMT_NC;
|
||||||
|
}
|
||||||
|
|
||||||
return pagemap;
|
return pagemap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +362,8 @@ void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_
|
||||||
ptflags |= PT_FLAG_WRITE;
|
ptflags |= PT_FLAG_WRITE;
|
||||||
if (!(flags & VMM_FLAG_NOEXEC))
|
if (!(flags & VMM_FLAG_NOEXEC))
|
||||||
ptflags |= PT_FLAG_EXEC;
|
ptflags |= PT_FLAG_EXEC;
|
||||||
|
if (flags & VMM_FLAG_FB)
|
||||||
|
ptflags |= pbmt_nc;
|
||||||
|
|
||||||
// Start at the highest level.
|
// Start at the highest level.
|
||||||
// The values of `enum page_size` map to the level index at which that size is mapped.
|
// The values of `enum page_size` map to the level index at which that size is mapped.
|
||||||
|
|
|
@ -80,7 +80,7 @@ static inline struct rhct_hart_info *rhct_get_hart_info(struct rhct *rhct, uint3
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void riscv_init(void) {
|
void init_riscv(void) {
|
||||||
struct madt *madt = acpi_get_table("APIC", 0);
|
struct madt *madt = acpi_get_table("APIC", 0);
|
||||||
struct rhct *rhct = acpi_get_table("RHCT", 0);
|
struct rhct *rhct = acpi_get_table("RHCT", 0);
|
||||||
if (madt == NULL || rhct == NULL) {
|
if (madt == NULL || rhct == NULL) {
|
||||||
|
@ -221,7 +221,7 @@ static bool parse_extension(const char **s, struct isa_extension *ext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool extension_matches(const struct isa_extension *ext, const char *name) {
|
static bool extension_matches(const struct isa_extension *ext, const char *name) {
|
||||||
for (size_t i = ext->name_len; i > 0; i--) {
|
for (size_t i = 0; i < ext->name_len; i++) {
|
||||||
const char c1 = tolower(ext->name[i]);
|
const char c1 = tolower(ext->name[i]);
|
||||||
const char c2 = tolower(*name++);
|
const char c2 = tolower(*name++);
|
||||||
if (c2 == '\0' || c1 != c2) {
|
if (c2 == '\0' || c1 != c2) {
|
||||||
|
|
Loading…
Reference in New Issue