From e77fc9b44649d88b0a7bdd257ca9756f4916c3e1 Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 09:14:40 -0500 Subject: [PATCH 1/7] acpi: move acpi structure defs to lib/acpi.h --- common/lib/acpi.h | 60 +++++++++++++++++++++++++++++++++++++++++++++++ common/sys/smp.c | 57 -------------------------------------------- 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/common/lib/acpi.h b/common/lib/acpi.h index f9d69b4a2..2d60ea405 100644 --- a/common/lib/acpi.h +++ b/common/lib/acpi.h @@ -103,6 +103,66 @@ struct smbios_entry_point_64 { uint64_t table_address; } __attribute__((packed)); +struct madt { + struct sdt header; + uint32_t local_controller_addr; + uint32_t flags; + char madt_entries_begin[]; +} __attribute__((packed)); + +struct madt_header { + uint8_t type; + uint8_t length; +} __attribute__((packed)); + +struct madt_lapic { + struct madt_header header; + uint8_t acpi_processor_uid; + uint8_t lapic_id; + uint32_t flags; +} __attribute__((packed)); + +struct madt_x2apic { + struct madt_header header; + uint8_t reserved[2]; + uint32_t x2apic_id; + uint32_t flags; + uint32_t acpi_processor_uid; +} __attribute__((packed)); + +struct madt_gicc { + struct madt_header header; + uint8_t reserved1[2]; + uint32_t iface_no; + uint32_t acpi_uid; + uint32_t flags; + uint32_t parking_ver; + uint32_t perf_gsiv; + uint64_t parking_addr; + uint64_t gicc_base_addr; + uint64_t gicv_base_addr; + uint64_t gich_base_addr; + uint32_t vgic_maint_gsiv; + uint64_t gicr_base_addr; + uint64_t mpidr; + uint8_t power_eff_class; + uint8_t reserved2; + uint16_t spe_overflow_gsiv; +} __attribute__((packed)); + +// Reference: https://github.com/riscv-non-isa/riscv-acpi/issues/15 +struct madt_riscv_intc { + struct madt_header header; + uint8_t version; + uint8_t reserved; + uint32_t flags; + uint64_t hartid; + uint32_t acpi_processor_uid; +} __attribute__((packed)); + +#define MADT_RISCV_INTC_ENABLED ((uint32_t)1 << 0) +#define MADT_RISCV_INTC_ONLINE_CAPABLE ((uint32_t)1 << 1) + uint8_t acpi_checksum(void *ptr, size_t size); void *acpi_get_rsdp(void); diff --git a/common/sys/smp.c b/common/sys/smp.c index a0e617237..0fc5313f6 100644 --- a/common/sys/smp.c +++ b/common/sys/smp.c @@ -17,66 +17,9 @@ #include #endif -struct madt { - struct sdt header; - uint32_t local_controller_addr; - uint32_t flags; - char madt_entries_begin[]; -} __attribute__((packed)); - -struct madt_header { - uint8_t type; - uint8_t length; -} __attribute__((packed)); - -struct madt_lapic { - struct madt_header header; - uint8_t acpi_processor_uid; - uint8_t lapic_id; - uint32_t flags; -} __attribute__((packed)); - -struct madt_x2apic { - struct madt_header header; - uint8_t reserved[2]; - uint32_t x2apic_id; - uint32_t flags; - uint32_t acpi_processor_uid; -} __attribute__((packed)); - extern symbol smp_trampoline_start; extern size_t smp_trampoline_size; -struct madt_gicc { - struct madt_header header; - uint8_t reserved1[2]; - uint32_t iface_no; - uint32_t acpi_uid; - uint32_t flags; - uint32_t parking_ver; - uint32_t perf_gsiv; - uint64_t parking_addr; - uint64_t gicc_base_addr; - uint64_t gicv_base_addr; - uint64_t gich_base_addr; - uint32_t vgic_maint_gsiv; - uint64_t gicr_base_addr; - uint64_t mpidr; - uint8_t power_eff_class; - uint8_t reserved2; - uint16_t spe_overflow_gsiv; -} __attribute__((packed)); - -// Reference: https://github.com/riscv-non-isa/riscv-acpi/issues/15 -struct madt_riscv_intc { - struct madt_header header; - uint8_t version; - uint8_t reserved; - uint32_t flags; - uint64_t hartid; - uint32_t acpi_processor_uid; -} __attribute__((packed)); - #if defined (__x86_64__) || defined (__i386__) struct trampoline_passed_info { From 3d67b2278620de20cf4714672866a38e6f5a2dda Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 09:22:50 -0500 Subject: [PATCH 2/7] lib/libc: add misc utilities --- common/lib/libc.h | 3 +++ common/lib/libc.s2.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/common/lib/libc.h b/common/lib/libc.h index 19b50fc92..551d91a15 100644 --- a/common/lib/libc.h +++ b/common/lib/libc.h @@ -6,6 +6,8 @@ bool isprint(int c); bool isspace(int c); +bool isalpha(int c); +bool isdigit(int c); int toupper(int c); int tolower(int c); @@ -23,6 +25,7 @@ size_t strlen(const char *); int strcmp(const char *, const char *); int strcasecmp(const char *, const char *); int strncmp(const char *, const char *, size_t); +int strncasecmp(const char *, const char *, size_t); int inet_pton(const char *src, void *dst); #endif diff --git a/common/lib/libc.s2.c b/common/lib/libc.s2.c index c3eda16d0..11bd4461e 100644 --- a/common/lib/libc.s2.c +++ b/common/lib/libc.s2.c @@ -12,6 +12,14 @@ bool isspace(int c) { return (c >= '\t' && c <= 0xD) || c == ' '; } +bool isalpha(int c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +bool isdigit(int c) { + return c >= '0' && c <= '9'; +} + int toupper(int c) { if (c >= 'a' && c <= 'z') { return c - 0x20; @@ -84,6 +92,18 @@ int strncmp(const char *s1, const char *s2, size_t n) { return 0; } +int strncasecmp(const char *s1, const char *s2, size_t n) { + for (size_t i = 0; i < n; i++) { + char c1 = s1[i], c2 = s2[i]; + if (tolower(c1) != tolower(c2)) + return c1 < c2 ? -1 : 1; + if (!c1) + return 0; + } + + return 0; +} + size_t strlen(const char *str) { size_t len; From e847d6091044c6d972faf448e1bf2be178e5d77f Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 09:35:30 -0500 Subject: [PATCH 3/7] riscv: implement feature dectection --- common/entry.s3.c | 13 +++ common/sys/cpu.h | 24 ++++ common/sys/cpu_riscv.c | 255 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 292 insertions(+) create mode 100644 common/sys/cpu_riscv.c diff --git a/common/entry.s3.c b/common/entry.s3.c index da91b4cc0..56559a281 100644 --- a/common/entry.s3.c +++ b/common/entry.s3.c @@ -22,6 +22,7 @@ #include #include #include +#include void stage3_common(void); @@ -130,6 +131,18 @@ noreturn void stage3_common(void) { init_io_apics(); #endif +#if defined (__riscv) +#if defined (UEFI) + RISCV_EFI_BOOT_PROTOCOL *rv_proto = get_riscv_boot_protocol(); + if (rv_proto == NULL || rv_proto->GetBootHartId(rv_proto, &bsp_hartid) != EFI_SUCCESS) { + panic(false, "failed to get BSP's hartid"); + } +#else +#error riscv: only UEFI is supported +#endif + init_riscv(); +#endif + term_notready(); menu(true); diff --git a/common/sys/cpu.h b/common/sys/cpu.h index 12d48137e..bd8609ddd 100644 --- a/common/sys/cpu.h +++ b/common/sys/cpu.h @@ -320,6 +320,30 @@ inline uint64_t rdtsc(void) { locked_read__ret; \ }) +extern size_t bsp_hartid; + +struct riscv_hart { + struct riscv_hart *next; + const char *isa_string; + size_t hartid; + uint32_t acpi_uid; + uint8_t mmu_type; + uint8_t flags; +}; + +#define RISCV_HART_COPROC ((uint8_t)1 << 0) // is a coprocessor +#define RISCV_HART_HAS_MMU ((uint8_t)1 << 1) // `mmu_type` field is valid + +extern struct riscv_hart *hart_list; + +bool riscv_check_isa_extension_for(size_t hartid, const char *ext, size_t *maj, size_t *min); + +static inline bool riscv_check_isa_extension(const char *ext, size_t *maj, size_t *min) { + return riscv_check_isa_extension_for(bsp_hartid, ext, maj, min); +} + +void init_riscv(void); + #else #error Unknown architecture #endif diff --git a/common/sys/cpu_riscv.c b/common/sys/cpu_riscv.c new file mode 100644 index 000000000..37dcff901 --- /dev/null +++ b/common/sys/cpu_riscv.c @@ -0,0 +1,255 @@ + +#if defined(__riscv) + +#include +#include +#include +#include +#include +#include + +// ACPI RISC-V Hart Capabilities Table +struct rhct { + struct sdt header; + uint32_t flags; + uint64_t time_base_frequency; + uint32_t nodes_len; + uint32_t nodes_offset; + uint8_t nodes[]; +} __attribute__((packed)); + +#define RHCT_ISA_STRING 0 +#define RHCT_CMO 1 +#define RHCT_MMU 2 +#define RHCT_HART_INFO 65535 + +struct rhct_header { + uint16_t type; // node type + uint16_t size; // node size (bytes) + uint16_t revision; // node revision +} __attribute__((packed)); + +// One `struct rhct_hart_info` structure exists per hart in the system. +// The `offsets` array points to other entries in the RHCT associated with the +// hart. +struct rhct_hart_info { + struct rhct_header header; + uint16_t offsets_len; + uint32_t acpi_processor_uid; + uint32_t offsets[]; +} __attribute__((packed)); + +struct rhct_isa_string { + struct rhct_header header; + uint16_t isa_string_len; + const char isa_string[]; +} __attribute__((packed)); + +#define RISCV_MMU_TYPE_SV39 0 +#define RISCV_MMU_TYPE_SV48 1 +#define RISCV_MMU_TYPE_SV57 2 + +struct rhct_mmu { + struct rhct_header header; + uint8_t reserved0; + uint8_t mmu_type; +} __attribute__((packed)); + +size_t bsp_hartid; +struct riscv_hart *hart_list; +static struct riscv_hart *bsp_hart; + +static struct riscv_hart *riscv_get_hart(size_t hartid) { + for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) { + if (hart->hartid == hartid) { + return hart; + } + } + panic(false, "no `struct riscv_hart` for hartid %u", hartid); +} + +static inline struct rhct_hart_info *rhct_get_hart_info(struct rhct *rhct, uint32_t acpi_uid) { + uint32_t offset = rhct->nodes_offset; + for (uint32_t i = 0; i < rhct->nodes_len; i++) { + struct rhct_hart_info *node = (void *)((uintptr_t)rhct + offset); + if (node->header.type == RHCT_HART_INFO && node->acpi_processor_uid == acpi_uid) { + return node; + } + offset += node->header.size; + } + return NULL; +} + +void riscv_init(void) { + struct madt *madt = acpi_get_table("APIC", 0); + struct rhct *rhct = acpi_get_table("RHCT", 0); + if (madt == NULL || rhct == NULL) { + panic(false, "riscv: requires acpi"); + } + + for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin; + (uintptr_t)madt_ptr < (uintptr_t)madt + madt->header.length; madt_ptr += *(madt_ptr + 1)) { + if (*madt_ptr != 0x18) { + continue; + } + struct madt_riscv_intc *intc = (struct madt_riscv_intc *)madt_ptr; + + // Ignore harts we can't do anything with. + if (!(intc->flags & MADT_RISCV_INTC_ENABLED || + intc->flags & MADT_RISCV_INTC_ONLINE_CAPABLE)) { + continue; + } + + uint32_t acpi_uid = intc->acpi_processor_uid; + size_t hartid = intc->hartid; + + struct rhct_hart_info *hart_info = rhct_get_hart_info(rhct, acpi_uid); + if (hart_info == NULL) { + panic(false, "riscv: missing rhct node for hartid %u", hartid); + } + + const char *isa_string = NULL; + uint8_t mmu_type = 0; + uint8_t flags = 0; + + for (uint32_t i = 0; i < hart_info->offsets_len; i++) { + const struct rhct_header *node = (void *)((uintptr_t)rhct + hart_info->offsets[i]); + switch (node->type) { + case RHCT_ISA_STRING: + isa_string = ((struct rhct_isa_string *)node)->isa_string; + break; + case RHCT_MMU: + mmu_type = ((struct rhct_mmu *)node)->mmu_type; + flags |= RISCV_HART_HAS_MMU; + break; + } + } + + if (isa_string == NULL) { + print("riscv: missing isa string for hartid %u, skipping.\n", hartid); + continue; + } + + struct riscv_hart *hart = ext_mem_alloc(sizeof(struct riscv_hart)); + if (hart == NULL) { + panic(false, "out of memory"); + } + + hart->hartid = hartid; + hart->acpi_uid = acpi_uid; + hart->isa_string = isa_string; + hart->mmu_type = mmu_type; + hart->flags = flags; + + hart->next = hart_list; + hart_list = hart; + + if (hart->hartid == bsp_hartid) { + bsp_hart = hart; + } + } + + if (bsp_hart == NULL) { + panic(false, "riscv: missing `struct riscv_hart` for BSP"); + } + + if (strncasecmp(bsp_hart->isa_string, "rv64i", 5)) { + panic(false, "unsupported cpu: %s", bsp_hart->isa_string); + } + + for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) { + if (hart != bsp_hart && strcmp(bsp_hart->isa_string, hart->isa_string)) { + hart->flags |= RISCV_HART_COPROC; + } + } +} + +struct isa_extension { + const char *name; + size_t name_len; + uint32_t ver_maj; + uint32_t ver_min; +}; + +// Parse the next sequence of digit characters into an integer. +static bool parse_number(const char **s, size_t *_n) { + size_t n = 0; + bool parsed = false; + while (isdigit(**s)) { + n *= 10; + n += *(*s)++ - '0'; + parsed = true; + } + *_n = n; + return parsed; +} + +// Parse the next extension from an ISA string. +static bool parse_extension(const char **s, struct isa_extension *ext) { + if (**s == '\0') { + return false; + } + + const char *name = *s; + size_t name_len = 1; + if (**s == 's' || **s == 'S' || **s == 'x' || **s == 'X' || **s == 'z' || **s == 'Z') { + while (isalpha((*s)[name_len])) { + name_len++; + } + } + *s += name_len; + + size_t maj = 0, min = 0; + if (parse_number(s, &maj)) { + if (**s == 'p') { + *s += 1; + parse_number(s, &min); + } + } + + while (**s == '_') { + *s += 1; + } + + if (ext) { + ext->name = name; + ext->name_len = name_len; + ext->ver_maj = maj; + ext->ver_min = min; + } + return true; +} + +static bool extension_matches(const struct isa_extension *ext, const char *name) { + for (size_t i = ext->name_len; i > 0; i--) { + const char c1 = tolower(ext->name[i]); + const char c2 = tolower(*name++); + if (c2 == '\0' || c1 != c2) { + return false; + } + } + // Make sure `name` is not longer. + return *name == '\0'; +} + +bool riscv_check_isa_extension_for(size_t hartid, const char *name, size_t *maj, size_t *min) { + const char *isa_string = riscv_get_hart(hartid)->isa_string; + + struct isa_extension ext; + while (parse_extension(&isa_string, &ext)) { + if (!extension_matches(&ext, name)) { + continue; + } + if (maj) { + *maj = ext.ver_maj; + } + if (min) { + *min = ext.ver_min; + } + return true; + } + + return false; +} + +#endif \ No newline at end of file From 3c2a0f5717b16dfe9773b0f459190b8f8d6780e1 Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 09:37:43 -0500 Subject: [PATCH 4/7] riscv: refactor smp init --- common/protos/limine.c | 20 +--------- common/sys/smp.c | 91 ++++++++++++++---------------------------- common/sys/smp.h | 1 - 3 files changed, 31 insertions(+), 81 deletions(-) diff --git a/common/protos/limine.c b/common/protos/limine.c index e119214f9..ec8a30e8b 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -923,19 +923,6 @@ FEAT_END pagemap = build_pagemap(paging_mode, nx_available, ranges, ranges_count, physical_base, virtual_base, direct_map_offset); -#if defined (__riscv64) - // Fetch the BSP's Hart ID before exiting boot services. - size_t bsp_hartid; - bool have_bsp_hartid = false; - - RISCV_EFI_BOOT_PROTOCOL *riscv_boot_proto = get_riscv_boot_protocol(); - if (riscv_boot_proto != NULL) { - if (riscv_boot_proto->GetBootHartId(riscv_boot_proto, &bsp_hartid) == EFI_SUCCESS) { - have_bsp_hartid = true; - } - } -#endif - #if defined (UEFI) efi_exit_boot_services(); #endif @@ -962,12 +949,7 @@ FEAT_START pagemap, LIMINE_MAIR(fb_attr), LIMINE_TCR(tsz, pa), LIMINE_SCTLR, direct_map_offset); #elif defined (__riscv64) - if (!have_bsp_hartid) { - printv("smp: failed to get bsp's hart id\n"); - break; - } - - smp_info = init_smp(&cpu_count, bsp_hartid, pagemap, direct_map_offset); + smp_info = init_smp(&cpu_count, pagemap, direct_map_offset); #else #error Unknown architecture #endif diff --git a/common/sys/smp.c b/common/sys/smp.c index 0fc5313f6..77dfbd8d0 100644 --- a/common/sys/smp.c +++ b/common/sys/smp.c @@ -551,77 +551,46 @@ static bool smp_start_ap(size_t hartid, size_t satp, struct limine_smp_info *inf return false; } -struct limine_smp_info *init_smp(size_t *cpu_count, - size_t bsp_hartid, - pagemap_t pagemap, - uint64_t hhdm_offset) { - // No RSDP means no ACPI. - // Parsing the Device Tree is the only other method for detecting APs. - if (acpi_get_rsdp() == NULL) { - printv("smp: ACPI is required to detect APs.\n"); - return NULL; +struct limine_smp_info *init_smp(size_t *cpu_count, pagemap_t pagemap, uint64_t hhdm_offset) { + size_t num_cpus = 0; + for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) { + if (!(hart->flags & RISCV_HART_COPROC)) { + num_cpus += 1; + } } - struct madt *madt = acpi_get_table("APIC", 0); - if (madt == NULL) - return NULL; - - size_t max_cpus = 0; - for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin; - (uintptr_t)madt_ptr < (uintptr_t)madt + madt->header.length; - madt_ptr += *(madt_ptr + 1)) { - switch (*madt_ptr) { - case 0x18: { - struct madt_riscv_intc *intc = (void *)madt_ptr; - - // Check if we can actually try to start the AP - if ((intc->flags & 1) ^ ((intc->flags >> 1) & 1)) - max_cpus++; - - continue; - } - } + struct limine_smp_info *ret = ext_mem_alloc(num_cpus * sizeof(struct limine_smp_info)); + if (ret == NULL) { + panic(false, "out of memory"); } - struct limine_smp_info *ret = ext_mem_alloc(max_cpus * sizeof(struct limine_smp_info)); *cpu_count = 0; + for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) { + if (hart->flags & RISCV_HART_COPROC) { + continue; + } + struct limine_smp_info *info_struct = &ret[*cpu_count]; - // Try to start all APs - for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin; - (uintptr_t)madt_ptr < (uintptr_t)madt + madt->header.length; - madt_ptr += *(madt_ptr + 1)) { - switch (*madt_ptr) { - case 0x18: { - struct madt_riscv_intc *intc = (void *)madt_ptr; - - // Check if we can actually try to start the AP - if (!((intc->flags & 1) ^ ((intc->flags >> 1) & 1))) - continue; - - struct limine_smp_info *info_struct = &ret[*cpu_count]; - - info_struct->processor_id = intc->acpi_processor_uid; - info_struct->hartid = intc->hartid; + info_struct->hartid = hart->hartid; + info_struct->processor_id = hart->acpi_uid; - // Do not try to restart the BSP - if (intc->hartid == bsp_hartid) { - (*cpu_count)++; - continue; - } + // Don't try to start the BSP. + if (hart->hartid == bsp_hartid) { + *cpu_count += 1; + continue; + } - printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", intc->hartid); + printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", hart->hartid); - // Try to start the AP. - size_t satp = make_satp(pagemap.paging_mode, pagemap.top_level); - if (!smp_start_ap(intc->hartid, satp, info_struct, hhdm_offset)) { - print("smp: FAILED to bring-up AP\n"); - continue; - } - - (*cpu_count)++; - continue; - } + // Try to start the AP. + size_t satp = make_satp(pagemap.paging_mode, pagemap.top_level); + if (!smp_start_ap(hart->hartid, satp, info_struct, hhdm_offset)) { + print("smp: FAILED to bring-up AP\n"); + continue; } + + (*cpu_count)++; + continue; } return ret; diff --git a/common/sys/smp.h b/common/sys/smp.h index bc82d6cd3..6919b871a 100644 --- a/common/sys/smp.h +++ b/common/sys/smp.h @@ -33,7 +33,6 @@ struct limine_smp_info *init_smp(size_t *cpu_count, #elif defined (__riscv64) struct limine_smp_info *init_smp(size_t *cpu_count, - uint64_t bsp_hartid, pagemap_t pagemap, uint64_t hhdm_offset); From f5c79b3cf6885eb052273dfcebbc28e8c160c5a0 Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 09:38:47 -0500 Subject: [PATCH 5/7] riscv/vmm: use Svpbmt extension when available --- common/mm/vmm.c | 13 +++++++++++++ common/sys/cpu_riscv.c | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/common/mm/vmm.c b/common/mm/vmm.c index b4db155d7..2a7355f0b 100644 --- a/common/mm/vmm.c +++ b/common/mm/vmm.c @@ -252,6 +252,7 @@ void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_ #define PT_FLAG_USER ((uint64_t)1 << 4) #define PT_FLAG_ACCESSED ((uint64_t)1 << 6) #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_FLAG_RWX (PT_FLAG_READ | PT_FLAG_WRITE | PT_FLAG_EXEC) @@ -271,6 +272,8 @@ static uint64_t pt_to_vmm_flags_internal(pt_entry_t entry) { flags |= VMM_FLAG_WRITE; if (!(entry & PT_FLAG_EXEC)) flags |= VMM_FLAG_NOEXEC; + if (entry & PT_FLAG_PBMT_NC) + flags |= VMM_FLAG_FB; return flags; } @@ -337,11 +340,19 @@ int vmm_max_paging_mode(void) return 6 + max_level; } +static pt_entry_t pbmt_nc = 0; + pagemap_t new_pagemap(int paging_mode) { pagemap_t pagemap; pagemap.paging_mode = paging_mode; pagemap.max_page_size = paging_mode - 6; 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; } @@ -357,6 +368,8 @@ void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_ ptflags |= PT_FLAG_WRITE; if (!(flags & VMM_FLAG_NOEXEC)) ptflags |= PT_FLAG_EXEC; + if (flags & VMM_FLAG_FB) + ptflags |= pbmt_nc; // Start at the highest level. // The values of `enum page_size` map to the level index at which that size is mapped. diff --git a/common/sys/cpu_riscv.c b/common/sys/cpu_riscv.c index 37dcff901..41203b500 100644 --- a/common/sys/cpu_riscv.c +++ b/common/sys/cpu_riscv.c @@ -80,7 +80,7 @@ static inline struct rhct_hart_info *rhct_get_hart_info(struct rhct *rhct, uint3 return NULL; } -void riscv_init(void) { +void init_riscv(void) { struct madt *madt = acpi_get_table("APIC", 0); struct rhct *rhct = acpi_get_table("RHCT", 0); 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) { - 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 c2 = tolower(*name++); if (c2 == '\0' || c1 != c2) { From c1a67396bc974d25de64a13d3d656f269bdc78f3 Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 10:18:09 -0500 Subject: [PATCH 6/7] acpi: remove duplicate definition in sys/lapic.c --- common/lib/acpi.h | 9 +++++++++ common/sys/lapic.c | 16 ---------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/common/lib/acpi.h b/common/lib/acpi.h index 2d60ea405..8d29a7df5 100644 --- a/common/lib/acpi.h +++ b/common/lib/acpi.h @@ -130,6 +130,15 @@ struct madt_x2apic { uint32_t acpi_processor_uid; } __attribute__((packed)); +struct madt_io_apic { + uint8_t type; + uint8_t length; + uint8_t apic_id; + uint8_t reserved; + uint32_t address; + uint32_t gsib; +} __attribute__((packed)); + struct madt_gicc { struct madt_header header; uint8_t reserved1[2]; diff --git a/common/sys/lapic.c b/common/sys/lapic.c index cb348968a..13e2d3fdb 100644 --- a/common/sys/lapic.c +++ b/common/sys/lapic.c @@ -9,22 +9,6 @@ #include #include -struct madt { - struct sdt header; - uint32_t local_controller_addr; - uint32_t flags; - char madt_entries_begin[]; -} __attribute__((packed)); - -struct madt_io_apic { - uint8_t type; - uint8_t length; - uint8_t apic_id; - uint8_t reserved; - uint32_t address; - uint32_t gsib; -} __attribute__((packed)); - struct dmar { struct sdt header; uint8_t host_address_width; From 1352a6384be31ac16ec5284cd16e0be6e882e16b Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 18:57:46 -0500 Subject: [PATCH 7/7] riscv: skip `rv{32,64}` prefix when parsing extensions from isa strings --- common/sys/cpu_riscv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/common/sys/cpu_riscv.c b/common/sys/cpu_riscv.c index 41203b500..40f288449 100644 --- a/common/sys/cpu_riscv.c +++ b/common/sys/cpu_riscv.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -130,6 +131,10 @@ void init_riscv(void) { continue; } + if (strncmp("rv64", isa_string, 4) && strncmp("rv32", isa_string, 4)) { + print("riscv: skipping hartid %u with invalid isa string: %s", hartid, isa_string); + } + struct riscv_hart *hart = ext_mem_alloc(sizeof(struct riscv_hart)); if (hart == NULL) { panic(false, "out of memory"); @@ -233,7 +238,8 @@ static bool extension_matches(const struct isa_extension *ext, const char *name) } bool riscv_check_isa_extension_for(size_t hartid, const char *name, size_t *maj, size_t *min) { - const char *isa_string = riscv_get_hart(hartid)->isa_string; + // Skip the `rv{32,64}` prefix so it's not parsed as extensions. + const char *isa_string = riscv_get_hart(hartid)->isa_string + 4; struct isa_extension ext; while (parse_extension(&isa_string, &ext)) {