Add CPU frequency detection from CPUID vendor string#121
Conversation
| #define MHZ_MULTIPLIER 1000000 | ||
| #define GHZ_MULTIPLIER 1000000000 | ||
|
|
||
| static inline uint64_t get_cpu_freq(const char *cpu_str) { |
There was a problem hiding this comment.
I would make it regular function (no inline).
There was a problem hiding this comment.
Did that, had to use it somewhere afterwards :)
| #define MHZ_MULTIPLIER 1000000 | ||
| #define GHZ_MULTIPLIER 1000000000 |
There was a problem hiding this comment.
it might make sense to add common defines for HZ() KHZ() MHZ() and GHZ(), similar to the ones for KB(), MB(), and GB()
|
|
||
| /* we need to reverse the vendor string for parsing the freq */ | ||
| while (len--) { | ||
| if (isspace(*(cpu_str + len))) { |
| *(reverse) = '\0'; | ||
| break; | ||
| } | ||
| *(reverse++) = *(cpu_str + len); |
There was a problem hiding this comment.
nit: *reverse++ = cpu_str[len]
| uint64_t frequency = 0; | ||
| char buf[16]; | ||
| char buf2[16]; | ||
| char *reverse = &buf[0]; |
There was a problem hiding this comment.
nit: reverse can be declared in the while() {} loop scope using it
| } | ||
|
|
||
| if (!strstr(buf, "zHM") && !strstr(buf, "zHG")) { | ||
| // if we have nothing to calculate, just return |
There was a problem hiding this comment.
also this if seems redundant. We call the same strstr() in the below if-else if-else. We can make return 0 the statement of the final else
| size_t len = strlen(cpu_str); | ||
| uint64_t multiplier = 0; | ||
| uint64_t frequency = 0; | ||
| char buf[16]; |
There was a problem hiding this comment.
nit: I would call it reverse and the buf2 result
| if (strlen(buf2) == 2) | ||
| frequency += strtoul(buf2, NULL, 0) * 10 * multiplier; | ||
| else if (strlen(buf2) == 1) | ||
| frequency += strtoul(buf2, NULL, 0) * 100 * multiplier; |
There was a problem hiding this comment.
this could be: frequency += strtoul(buf2, NULL, 0) * (1000 / (10 * strlen(buf2))) * multiplier
65b6dd4 to
695e61d
Compare
| if (cpu_vendor_string(&cpu_identifier[0])) | ||
| if (cpu_vendor_string(&cpu_identifier[0])) { | ||
| printk("CPU: %.48s\n", cpu_identifier); | ||
| printk("Frequency: %llu Hz\n", get_cpu_freq(&cpu_identifier[0])); |
There was a problem hiding this comment.
nit: I would prefer MHz and %lu formatter should be ok
| #define CPUID_BRAND_INFO_MIN 0x80000002U | ||
| #define CPUID_BRAND_INFO_MAX 0x80000004U | ||
|
|
||
| #define KHZ(x) (_U64(x) * ipow(10, 3)) |
There was a problem hiding this comment.
nit: this and below I would move to compiler.h
| } | ||
| } | ||
| } | ||
| else { |
There was a problem hiding this comment.
nit: since frequency is set to 0 by default, this is redundant
| } | ||
|
|
||
| static inline unsigned int ipow(int base, int exp) { | ||
| int result = 1; |
There was a problem hiding this comment.
This should be unsigned long
| return n; | ||
| } | ||
|
|
||
| static inline unsigned int ipow(int base, int exp) { |
There was a problem hiding this comment.
The function should return unsigned long
|
|
||
| static inline unsigned int ipow(int base, int exp) { | ||
| int result = 1; | ||
| for (;;) { |
Signed-off-by: Martin Mazein <amazein@amazon.de>
|
|
||
| /* Print cpu vendor info */ | ||
| if (cpu_vendor_string(&cpu_identifier[0])) | ||
| if (cpu_vendor_string(&cpu_identifier[0])) { |
There was a problem hiding this comment.
nit: here and below: s/&cpu_identifier[0]/cpu_identifier/
| #define GB(x) (_U64(x) << 30) | ||
|
|
||
| #define KHZ(x) (_U64(x) * 1000) | ||
| #define MHZ(x) (_U64(x) * 1000000) |
There was a problem hiding this comment.
nit: MHZ(x) (KHZ(x) * 1000)
| return n; | ||
| } | ||
|
|
||
| static inline unsigned long ipow(int base, int exp) { |
There was a problem hiding this comment.
s/int exp/unsigned int exp/
Signed-off-by: Martin Mazein <amazein@amazon.de>
… string Signed-off-by: Martin Mazein <amazein@amazon.de>
Signed-off-by: Martin Mazein <amazein@amazon.de>
Issue #, if available: #80
Description of changes:
This commit series is adding a cpu frequency detection by parsing the specific bits out of the CPUID vendor string.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Testing done:
UNITTEST=1 make clean booton the branch results in executing unit tests