Stefan Reinauer (stefan.reinauer@coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/944
-gerrit
commit 32eb84d2ff1caca403f0d33ac8f94b432f1287ca Author: Stefan Reinauer stefan.reinauer@coreboot.org Date: Fri Apr 27 21:49:28 2012 +0200
acpigen: Add support for generating T state tables
Change-Id: I58050591198bb06de5f0ca58ca3a02f1cfa95069 Signed-off-by: Duncan Laurie dlaurie@google.com Signed-off-by: Stefan Reinauer reinauer@google.com --- src/arch/x86/boot/acpigen.c | 125 +++++++++++++++++++++++++++++++++++ src/arch/x86/include/arch/acpi.h | 8 ++ src/arch/x86/include/arch/acpigen.h | 4 + 3 files changed, 137 insertions(+), 0 deletions(-)
diff --git a/src/arch/x86/boot/acpigen.c b/src/arch/x86/boot/acpigen.c index b44f9b9..ac1dec2 100644 --- a/src/arch/x86/boot/acpigen.c +++ b/src/arch/x86/boot/acpigen.c @@ -315,6 +315,59 @@ int acpigen_write_empty_PCT(void) return acpigen_emit_stream(stream, ARRAY_SIZE(stream)); }
+int acpigen_write_empty_PTC(void) +{ +/* + Name (_PTC, Package (0x02) + { + ResourceTemplate () + { + Register (FFixedHW, + 0x00, // Bit Width + 0x00, // Bit Offset + 0x0000000000000000, // Address + ,) + }, + + ResourceTemplate () + { + Register (FFixedHW, + 0x00, // Bit Width + 0x00, // Bit Offset + 0x0000000000000000, // Address + ,) + } + }) +*/ + int len, nlen, rlen; + acpi_addr_t addr = { + .space_id = ACPI_ADDRESS_SPACE_FIXED, + .bit_width = 0, + .bit_offset = 0, + .resv = 0, + .addrl = 0, + .addrh = 0, + }; + + nlen = acpigen_write_name("_PTC"); + len = acpigen_write_package(2); + + /* ControlRegister */ + rlen = acpigen_write_resourcetemplate_header(); + rlen += acpigen_write_register(&addr); + len += acpigen_write_resourcetemplate_footer(rlen); + len += rlen; + + /* StatusRegister */ + rlen = acpigen_write_resourcetemplate_header(); + rlen += acpigen_write_register(&addr); + len += acpigen_write_resourcetemplate_footer(rlen); + len += rlen; + + acpigen_patch_len(len - 1); + return len + nlen; +} + /* generates a func with max supported P states */ int acpigen_write_PPC(u8 nr) { @@ -341,6 +394,27 @@ int acpigen_write_PPC(u8 nr) return len; }
+int acpigen_write_TPC(const char *gnvs_tpc_limit) +{ +/* + // Sample _TPC method + Method (_TPC, 0, NotSerialized) + { + Return (\TLVL) + } + */ + int len; + + len = acpigen_emit_byte(0x14); /* MethodOp */ + len += acpigen_write_len_f(); /* PkgLength */ + len += acpigen_emit_namestring("_TPC"); + len += acpigen_emit_byte(0x00); /* No Arguments */ + len += acpigen_emit_byte(0xa4); /* ReturnOp */ + len += acpigen_emit_namestring(gnvs_tpc_limit); + acpigen_patch_len(len - 1); + return len; +} + int acpigen_write_PSS_package(u32 coreFreq, u32 power, u32 transLat, u32 busmLat, u32 control, u32 status) { @@ -409,6 +483,57 @@ int acpigen_write_CST_package(acpi_cstate_t *cstate, int nentries) return len + lenh; }
+int acpigen_write_TSS_package(int entries, acpi_tstate_t *tstate_list) +{ +/* + Sample _TSS package with 100% and 50% duty cycles + Name (_TSS, Package (0x02) + { + Package(){100, 1000, 0, 0x00, 0) + Package(){50, 520, 0, 0x18, 0) + }) + */ + int i, len, plen, nlen; + acpi_tstate_t *tstate = tstate_list; + + nlen = acpigen_write_name("_TSS"); + plen = acpigen_write_package(entries); + + for (i = 0; i < entries; i++) { + len = acpigen_write_package(5); + len += acpigen_write_dword(tstate->percent); + len += acpigen_write_dword(tstate->power); + len += acpigen_write_dword(tstate->latency); + len += acpigen_write_dword(tstate->control); + len += acpigen_write_dword(tstate->status); + acpigen_patch_len(len - 1); + tstate++; + plen += len; + } + + acpigen_patch_len(plen - 1); + return plen + nlen; +} + +int acpigen_write_TSD_package(u32 domain, u32 numprocs, PSD_coord coordtype) +{ + int len, lenh, lenp; + lenh = acpigen_write_name("_TSD"); + lenp = acpigen_write_package(1); + len = acpigen_write_package(5); + len += acpigen_write_byte(5); // 5 values + len += acpigen_write_byte(0); // revision 0 + len += acpigen_write_dword(domain); + len += acpigen_write_dword(coordtype); + len += acpigen_write_dword(numprocs); + acpigen_patch_len(len - 1); + len += lenp; + acpigen_patch_len(len - 1); + return len + lenh; +} + + + int acpigen_write_mem32fixed(int readwrite, u32 base, u32 size) { /* diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index ea85d9f..587c484 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -418,6 +418,14 @@ typedef struct acpi_cstate { acpi_addr_t resource; } __attribute__ ((packed)) acpi_cstate_t;
+typedef struct acpi_tstate { + u32 percent; + u32 power; + u32 latency; + u32 control; + u32 status; +} __attribute__ ((packed)) acpi_tstate_t; + /* These are implemented by the target port or north/southbridge. */ unsigned long write_acpi_tables(unsigned long addr); unsigned long acpi_fill_madt(unsigned long current); diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h index 4d16040..335d1bc 100644 --- a/src/arch/x86/include/arch/acpigen.h +++ b/src/arch/x86/include/arch/acpigen.h @@ -42,12 +42,16 @@ int acpigen_write_name_byte(const char *name, uint8_t val); int acpigen_write_scope(const char *name); int acpigen_write_PPC(u8 nr); int acpigen_write_empty_PCT(void); +int acpigen_write_empty_PTC(void); +int acpigen_write_TPC(const char *gnvs_tpc_limit); int acpigen_write_PSS_package(u32 coreFreq, u32 power, u32 transLat, u32 busmLat, u32 control, u32 status); typedef enum { SW_ALL=0xfc, SW_ANY=0xfd, HW_ALL=0xfe } PSD_coord; int acpigen_write_PSD_package(u32 domain, u32 numprocs, PSD_coord coordtype); int acpigen_write_CST_package(acpi_cstate_t *entry, int nentries); int acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len); +int acpigen_write_TSS_package(int entries, acpi_tstate_t *tstate_list); +int acpigen_write_TSD_package(u32 domain, u32 numprocs, PSD_coord coordtype); int acpigen_write_mem32fixed(int readwrite, u32 base, u32 size); int acpigen_write_io16(u16 min, u16 max, u8 align, u8 len, u8 decode16); int acpigen_write_register(acpi_addr_t *addr);