@@ -10,6 +10,8 @@
#include <xen/efi.h>
#include <xen/pci.h>
#include <xen/pci_regs.h>
+#include <xen/unaligned.h>
+#include <acpi/cpufreq/cpufreq.h>
#define memcpy_fromio memcpy
#define alloc_bootmem(l) xmalloc_bytes(l)
@@ -680,6 +682,23 @@ static void __init cf_check dmi_decode(const struct dmi_header *dm)
dmi_string(dm, data[6])));
dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
break;
+ case DMI_ENTRY_PROCESSOR:
+ dmi_max_speed_mhz = 0;
+ if ( dm->length >= DMI_ENTRY_PROCESSOR_MIN_LENGTH )
+ {
+ dmi_max_speed_mhz = (uint16_t)get_unaligned((const uint16_t *)
+ (dm + DMI_PROCESSOR_MAX_SPEED_OFFSET));
+ if ( !dmi_max_speed_mhz )
+ dmi_printk(("Warnning: read zero value for Processor Max Speed\n"));
+ }
+ /*
+ * Real stupid fallback value, just in case there is no
+ * actual value set.
+ */
+ dmi_max_speed_mhz = dmi_max_speed_mhz ? : 1;
+
+ dmi_printk(("Processor Max Speed: %u\n", dmi_max_speed));
+ break;
}
}
@@ -271,4 +271,6 @@ int acpi_cpufreq_register(void);
int amd_pstate_cmdline_parse(const char *s, const char *e);
int amd_pstate_register_driver(void);
+extern uint16_t dmi_max_speed_mhz;
+
#endif /* __XEN_CPUFREQ_PM_H__ */
@@ -1,6 +1,11 @@
#ifndef __DMI_H__
#define __DMI_H__
+/* Minimum struct length needed for the DMI processor entry we want */
+#define DMI_ENTRY_PROCESSOR_MIN_LENGTH 48
+/* Offset in the DMI processor entry for the max frequency */
+#define DMI_PROCESSOR_MAX_SPEED_OFFSET 0x14
+
enum dmi_field {
DMI_NONE,
DMI_BIOS_VENDOR,
When _CPC table could not provide processor frequency range values for OS governor, we need to read processor max frequency as anchor point. For AMD processors, we rely on parsing DMI table to get processor max speed. Signed-off-by: Penny Zheng <Penny.Zheng@amd.com> --- xen/arch/x86/dmi_scan.c | 19 +++++++++++++++++++ xen/include/acpi/cpufreq/cpufreq.h | 2 ++ xen/include/xen/dmi.h | 5 +++++ 3 files changed, 26 insertions(+)