From f997b5554acd2c3ddcc9080b78a834853e59c783 Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Sat, 14 Feb 2009 15:40:23 +0000 Subject: [PATCH] Following patch adds dynamically generated P-States infrastructure as well as M2V-MX SE as example how to do that. It is based on AMD code and mine code for ACPI generation. Signed-off-by: Rudolf Marek Acked-by: Peter Stuge git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3946 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/arch/i386/boot/acpigen.c | 100 +++++++++++++++++++++ src/arch/i386/include/arch/acpigen.h | 5 ++ src/cpu/amd/model_fxx/Config.lb | 1 + src/mainboard/asus/m2v-mx_se/acpi_tables.c | 3 +- src/mainboard/asus/m2v-mx_se/dsdt.asl | 8 -- 5 files changed, 108 insertions(+), 9 deletions(-) diff --git a/src/arch/i386/boot/acpigen.c b/src/arch/i386/boot/acpigen.c index 203f5a0f3..6342a6957 100644 --- a/src/arch/i386/boot/acpigen.c +++ b/src/arch/i386/boot/acpigen.c @@ -136,3 +136,103 @@ int acpigen_write_scope(char *name) len = acpigen_write_len_f(); return len + acpigen_emit_stream(name, strlen(name)) + 1; } + +int acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len) +{ +/* + Processor (\_PR.CPUcpuindex, cpuindex, pblock_addr, pblock_len) + { +*/ + char pscope[16]; + int len; + /* processor op */ + acpigen_emit_byte(0x5b); + acpigen_emit_byte(0x83); + len = acpigen_write_len_f(); + + sprintf(pscope, "\\._PR_CPU%x", (unsigned int) cpuindex); + len += acpigen_emit_stream(pscope, strlen(pscope)); + acpigen_emit_byte(cpuindex); + acpigen_emit_byte(pblock_addr & 0xff); + acpigen_emit_byte((pblock_addr >> 8) & 0xff); + acpigen_emit_byte((pblock_addr >> 16) & 0xff); + acpigen_emit_byte((pblock_addr >> 24) & 0xff); + acpigen_emit_byte(pblock_len); + return 6 + 2 + len; +} + +int acpigen_write_empty_PCT(void) +{ +/* + Name (_PCT, Package (0x02) + { + ResourceTemplate () + { + Register (FFixedHW, + 0x00, // Bit Width + 0x00, // Bit Offset + 0x0000000000000000, // Address + ,) + }, + + ResourceTemplate () + { + Register (FFixedHW, + 0x00, // Bit Width + 0x00, // Bit Offset + 0x0000000000000000, // Address + ,) + } + }) +*/ + static char stream[] = { + 0x08, 0x5F, 0x50, 0x43, 0x54, 0x12, 0x2C, /* 00000030 "0._PCT.," */ + 0x02, 0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, /* 00000038 "........" */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00000040 "........" */ + 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x11, 0x14, /* 00000048 "....y..." */ + 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, 0x00, 0x00, /* 00000050 "........" */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00000058 "........" */ + 0x00, 0x79, 0x00 + }; + return acpigen_emit_stream(stream, ARRAY_SIZE(stream)); +} + +/* generates a func with max supported P states */ +int acpigen_write_PPC(u8 nr) +{ +/* + Method (_PPC, 0, NotSerialized) + { + Return (nr) + } +*/ + int len; + /* method op */ + acpigen_emit_byte(0x14); + len = acpigen_write_len_f(); + len += acpigen_emit_stream("_PPC", 4); + /* no fnarg */ + acpigen_emit_byte(0x00); + /* return */ + acpigen_emit_byte(0xa4); + /* arg */ + len += acpigen_write_byte(nr); + acpigen_patch_len(len - 1); + return len + 3; +} + +int acpigen_write_PSS_package(u32 coreFreq, u32 power, u32 transLat, u32 busmLat, + u32 control, u32 status) +{ + int len; + len = acpigen_write_package(6); + len += acpigen_write_dword(coreFreq); + len += acpigen_write_dword(power); + len += acpigen_write_dword(transLat); + len += acpigen_write_dword(busmLat); + len += acpigen_write_dword(control); + len += acpigen_write_dword(status); + //pkglen without the len opcode + acpigen_patch_len(len - 1); + return len; +} diff --git a/src/arch/i386/include/arch/acpigen.h b/src/arch/i386/include/arch/acpigen.h index 710593c00..e024f67d6 100644 --- a/src/arch/i386/include/arch/acpigen.h +++ b/src/arch/i386/include/arch/acpigen.h @@ -34,4 +34,9 @@ int acpigen_write_name(char *name); int acpigen_write_name_dword(char *name, uint32_t val); int acpigen_write_name_byte(char *name, uint8_t val); int acpigen_write_scope(char *name); +int acpigen_write_PPC(u8 nr); +int acpigen_write_empty_PCT(void); +int acpigen_write_PSS_package(u32 coreFreq, u32 power, u32 transLat, u32 busmLat, + u32 control, u32 status); +int acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len); #endif diff --git a/src/cpu/amd/model_fxx/Config.lb b/src/cpu/amd/model_fxx/Config.lb index 60463e3e6..550716bc3 100644 --- a/src/cpu/amd/model_fxx/Config.lb +++ b/src/cpu/amd/model_fxx/Config.lb @@ -20,3 +20,4 @@ driver model_fxx_init.o object apic_timer.o object model_fxx_update_microcode.o object processor_name.o +object powernow_acpi.o diff --git a/src/mainboard/asus/m2v-mx_se/acpi_tables.c b/src/mainboard/asus/m2v-mx_se/acpi_tables.c index 33540e09b..7dc2c823b 100644 --- a/src/mainboard/asus/m2v-mx_se/acpi_tables.c +++ b/src/mainboard/asus/m2v-mx_se/acpi_tables.c @@ -31,6 +31,7 @@ #include <../../../southbridge/via/vt8237r/vt8237r.h> #include <../../../southbridge/via/k8t890/k8t890.h> #include <../../../northbridge/amd/amdk8/amdk8_acpi.h> +#include extern unsigned char AmlCode[]; @@ -83,7 +84,7 @@ unsigned long acpi_fill_madt(unsigned long current) unsigned long acpi_fill_ssdt_generator(unsigned long current, char *oem_table_id) { k8acpi_write_vars(); - /* put PSTATES generator call here */ + amd_model_fxx_generate_powernow(0, 0, 0); return (unsigned long) (acpigen_get_current()); } diff --git a/src/mainboard/asus/m2v-mx_se/dsdt.asl b/src/mainboard/asus/m2v-mx_se/dsdt.asl index d75f9c058..a339747a8 100644 --- a/src/mainboard/asus/m2v-mx_se/dsdt.asl +++ b/src/mainboard/asus/m2v-mx_se/dsdt.asl @@ -24,14 +24,6 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "LXBIOS", "LXB-DSDT", 1) { Include ("amdk8_util.asl") - - /* Define the main processor.*/ - Scope (\_PR) - { - Processor (\_PR.CPU0, 0x00, 0x000000, 0x00) {} - Processor (\_PR.CPU1, 0x01, 0x000000, 0x00) {} - } - /* For now only define 2 power states: * - S0 which is fully on * - S5 which is soft off -- 2.25.1