diff --git a/src/riscv/api.h b/src/riscv/api.h index 1f2600e3..f5b9594d 100644 --- a/src/riscv/api.h +++ b/src/riscv/api.h @@ -42,11 +42,28 @@ CPUINFO_INTERNAL void cpuinfo_riscv_decode_vendor_uarch( enum cpuinfo_vendor vendor[restrict static 1], enum cpuinfo_uarch uarch[restrict static 1]); +/** + * Decodes the cache hierarchy based on the provided inpu parameters, + * regardless of underlying operating system. + * + * @param[uarch]: The processor micro-architecture code. + * @param[l1i] - Reference to the l1i cpuinfo_cache to populate. + * @param[l1d]: - Reference to the l1d cpuinfo_cache to populate. + * @param[l2]: - Reference to the l2 cpuinfo_cache to populate. + */ + CPUINFO_INTERNAL void cpuinfo_riscv_decode_cache( enum cpuinfo_uarch uarch, struct cpuinfo_cache l1i[restrict static 1], struct cpuinfo_cache l1d[restrict static 1], struct cpuinfo_cache l2[restrict static 1]); +/** + * Extracts the maximum cache size from a RISC-V processor, independently + * of underlying operating system. + * + * @param[processor]: The RISC-V processor. + * @preturn: The maximum cache size. + */ CPUINFO_INTERNAL uint32_t cpuinfo_riscv_compute_max_cache_size( const struct cpuinfo_processor processor[restrict static 1]); diff --git a/src/riscv/cache.c b/src/riscv/cache.c index 83d50bdf..d4dc1ca5 100644 --- a/src/riscv/cache.c +++ b/src/riscv/cache.c @@ -8,9 +8,9 @@ void cpuinfo_riscv_decode_cache( enum cpuinfo_uarch uarch, struct cpuinfo_cache l1i[restrict static 1], struct cpuinfo_cache l1d[restrict static 1], - struct cpuinfo_cache l2[restrict static 1]) -{ + struct cpuinfo_cache l2[restrict static 1]) { switch(uarch) { + // According to https://starfivetech.com/uploads/u74mc_core_complex_manual_21G1.pdf case cpuinfo_uarch_u74_mc: *l1i = (struct cpuinfo_cache) { .size = 32 * 1024, @@ -43,10 +43,11 @@ void cpuinfo_riscv_decode_cache( uint32_t cpuinfo_riscv_compute_max_cache_size(const struct cpuinfo_processor* processor) { switch(processor->core->uarch) { + // According to https://starfivetech.com/uploads/u74mc_core_complex_manual_21G1.pdf case cpuinfo_uarch_u74_mc: return 2 * 1024 * 1024; default: - cpuinfo_log_warning("target uarch not recognized; mas cache size is not populated"); + cpuinfo_log_warning("target uarch not recognized; max cache size is not populated"); return 0; } } \ No newline at end of file diff --git a/src/riscv/linux/api.h b/src/riscv/linux/api.h index fa6ef740..0f621e02 100644 --- a/src/riscv/linux/api.h +++ b/src/riscv/linux/api.h @@ -86,13 +86,24 @@ CPUINFO_INTERNAL void cpuinfo_riscv_linux_decode_vendor_uarch_from_hwprobe( enum cpuinfo_vendor vendor[restrict static 1], enum cpuinfo_uarch uarch[restrict static 1]); -CPUINFO_INTERNAL void cpuinfo_riscv_linux_count_cluster_processors( - uint32_t max_processors, - struct cpuinfo_riscv_linux_processor processors[restrict static max_processors]); +/** + * Reads the value of hwcap from the `getauxval` function, or + * mocks a fake value for testing purposes + * + * @param[hwcap] - The hwcap flags to be populated + */ CPUINFO_INTERNAL void cpuinfo_riscv_linux_hwcap_from_getauxval( uint32_t hwcap[restrict static 1]); +/** + * Parses the output of the `/proc/cpuinfo` command to extract + * info about the RISC-V processors. + * + * @param[max_processors_count] - The maximum number of processors. + * @param processors - Reference to the processor list to populate. + * @return false if any error occurred, true otherwise. + */ CPUINFO_INTERNAL bool cpuinfo_riscv_linux_parse_proc_cpuinfo( uint32_t max_processors_count, struct cpuinfo_riscv_linux_processor processors[restrict static max_processors_count]); diff --git a/src/riscv/linux/cpuinfo.c b/src/riscv/linux/cpuinfo.c index 09df8518..3d12fd52 100644 --- a/src/riscv/linux/cpuinfo.c +++ b/src/riscv/linux/cpuinfo.c @@ -21,7 +21,7 @@ static uint32_t parse_processor_number( if (processor_length == 0) { cpuinfo_log_warning("Processor number in /proc/cpuinfo is ignored: string is empty"); - return 0; + return -1; } uint32_t processor_number = 0; @@ -45,7 +45,7 @@ static void parse_isa( struct cpuinfo_riscv_linux_processor processor[restrict static 1]) { const size_t isa_length = (size_t) (isa_end - isa_start); - if (!(memcmp(isa_start, "rv32", 4) == 0 || memcmp(isa_start, "rv64", 4) == 0)) { + if (isa_length < 4 || !(memcmp(isa_start, "rv32", 4) == 0 || memcmp(isa_start, "rv64", 4) == 0)) { cpuinfo_log_error("Invalid isa format in /proc/cpuinfo: %.*s. It should start with either `rv32` or `rv64`", (int) (isa_length), isa_start); return; @@ -178,8 +178,8 @@ static bool parse_line( } /* Skip line if no ':' separator was found. */ if (separator == line_end) { - cpuinfo_log_info("Line %.*s in /proc/cpuinfo is ignored: key/value separator ':' not found", - (int) (line_end - line_start), line_start); + cpuinfo_log_warning("Line %.*s in /proc/cpuinfo is ignored: key/value separator ':' not found", + (int) (line_end - line_start), line_start); return true; } @@ -238,13 +238,6 @@ static bool parse_line( goto unknown; } break; - case 4: - if (memcmp(line_start, "hart", key_length) == 0) { - // Do nothing - } else { - goto unknown; - } - break; case 5: if (memcmp(line_start, "uarch", key_length) == 0) { parse_uarch(value_start, value_end, processor); @@ -255,7 +248,10 @@ static bool parse_line( case 9: if (memcmp(line_start, "processor", key_length) == 0) { const uint32_t new_processor_index = parse_processor_number(value_start, value_end); - if (new_processor_index < processor_index) { + if (new_processor_index < 0) { + /* Strange: empty string */ + break; + } else if (new_processor_index < processor_index) { /* Strange: decreasing processor number */ cpuinfo_log_warning( "unexpectedly low processor number %"PRIu32" following processor %"PRIu32" in /proc/cpuinfo", @@ -280,6 +276,8 @@ static bool parse_line( } break; default: + // Do nothing + break; unknown: cpuinfo_log_debug("unknown /proc/cpuinfo key: %.*s", (int) key_length, line_start); } diff --git a/src/riscv/linux/hwcap.c b/src/riscv/linux/hwcap.c index 90ad2c51..e9321f7f 100644 --- a/src/riscv/linux/hwcap.c +++ b/src/riscv/linux/hwcap.c @@ -2,28 +2,16 @@ #if CPUINFO_MOCK #include -#endif - -#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 - #include -#else - #define AT_HWCAP 16 - #define AT_HWCAP2 26 -#endif -#if CPUINFO_MOCK static uint32_t mock_hwcap = 0; void cpuinfo_set_hwcap(uint32_t hwcap) { mock_hwcap = hwcap; } - - static uint32_t mock_hwcap2 = 0; - void cpuinfo_set_hwcap2(uint32_t hwcap2) { - mock_hwcap2 = hwcap2; - } #endif #if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64 + #include + void cpuinfo_riscv_linux_hwcap_from_getauxval( uint32_t hwcap[restrict static 1]) { diff --git a/src/riscv/linux/init.c b/src/riscv/linux/init.c index cdc32fbd..e2990965 100644 --- a/src/riscv/linux/init.c +++ b/src/riscv/linux/init.c @@ -634,7 +634,7 @@ void cpuinfo_riscv_linux_init(void) { l1i[processor].processor_count = l1d[processor].processor_count = 1; if (temp_l2.size != 0) { /* Assume L2 is shared by cores in the same cluster */ - if (riscv_linux_processors[processor].package_leader_id == linux_id) { + if (riscv_linux_processors[processor].cluster_leader_id == linux_id) { l2_count += 1; } } diff --git a/src/riscv/linux/riscv-isa.c b/src/riscv/linux/riscv-isa.c index 6270279b..cad76e52 100644 --- a/src/riscv/linux/riscv-isa.c +++ b/src/riscv/linux/riscv-isa.c @@ -6,7 +6,7 @@ void cpuinfo_riscv_linux_decode_isa_from_hwcap( struct cpuinfo_riscv_isa isa[restrict static 1]) { - unsigned long hwcap = 0; + uint32_t hwcap = 0; cpuinfo_riscv_linux_hwcap_from_getauxval(&hwcap); if (hwcap & CPUINFO_RISCV_LINUX_FEATURE_I) {