Naresh Solanki (naresh.solanki@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17113
-gerrit
commit 05f09417017823a0f85ceaba5ac98ec4d95c9ba5 Author: Naresh G Solanki naresh.solanki@intel.com Date: Tue Oct 25 00:51:24 2016 +0530
[WIP]arch/x86/acpigen: Add OperationRegion & Field method.
OperationRegion : This requires region name, region space, region length & region size packed as input.
Field : This requires Operation region name & field list as input.
Change-Id: I578834217d39aa3b0d409eb8ba4b5f7a31969fa8 Signed-off-by: Naresh G Solanki naresh.solanki@intel.com --- src/arch/x86/acpigen.c | 72 +++++++++++++++++++++++++++++++++++++ src/arch/x86/include/arch/acpigen.h | 44 ++++++++++++++++++++++- 2 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c index 0a57263..7c06ba6 100644 --- a/src/arch/x86/acpigen.c +++ b/src/arch/x86/acpigen.c @@ -351,6 +351,78 @@ void acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len) acpigen_emit_byte(pblock_len); }
+ +void acpigen_write_opregion(struct opregion *opreg) +{ + /* OpregionOp */ + acpigen_emit_byte(0x5b); + acpigen_emit_byte(0x80); + /* NameString 4 chars only */ + acpigen_emit_simple_namestring(opreg->name); + /* RegionSpace */ + acpigen_emit_byte(opreg->RegionSpace); + /* RegionOffset & RegionLen, it can be byte word or double word */ + acpigen_write_integer(opreg->RegionOffset); + acpigen_write_integer(opreg->RegionLen); +} + +static void acpigen_write_field_offset(u32 offset, u32 current_bit_pos) +{ + + int diff; + diff = offset - (current_bit_pos/8); + if (current_bit_pos % 8 != 0) + diff++; + + if (diff < 0) + return; + + /* Offset */ + acpigen_emit_byte(0); + if (diff < 0x10) { + diff = diff << 3; + acpigen_emit_byte(diff & 0xf); + } + else if (diff < 0x100) { + diff = diff << 3; + acpigen_emit_byte(0x40 | (diff & 0xf)); + acpigen_emit_byte((diff & 0xff0) >> 4); + } + else if (diff < 0x1000) { + diff = diff << 3; + acpigen_emit_byte(0x80 | (diff & 0xf)); + acpigen_emit_byte((diff & 0xff0) >> 4); + acpigen_emit_byte((diff & 0xff000) >> 12); + } +} + +void acpigen_write_field(char *name, struct fieldlist *l, u16 n_field) +{ + u16 i; + u32 current_bit_pos = 0; + + /* FieldOp */ + acpigen_emit_byte(0x5b); + acpigen_emit_byte(0x81); + /* Package Length */ + acpigen_write_len_f(); + /* NameString 4 chars only */ + acpigen_emit_simple_namestring(name); + /* Field Flag */ + acpigen_emit_byte(0x00); // AnyAcc temp + + for (i = 0; i < n_field; i++) { + if (l[i].type == Offset) + acpigen_write_field_offset(l[i].bits, current_bit_pos); + else if (l[i].type == NameString) { + acpigen_emit_simple_namestring(l[i].name); + acpigen_emit_byte(l[i].bits); + current_bit_pos += l[i].bits; + } + } + acpigen_pop_len(); +} + void acpigen_write_empty_PCT(void) { /* diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h index 0c515da..1156117 100644 --- a/src/arch/x86/include/arch/acpigen.h +++ b/src/arch/x86/include/arch/acpigen.h @@ -81,6 +81,47 @@ enum { ONES_OP = 0xFF, };
+#define FIELDLIST_OFFSET(X) { .type = Offset, \ + .name = "",\ + .bits = X,\ + } +#define FIELDLIST_NAMESTR(X, Y) { .type = NameString, \ + .name = X, \ + .bits = Y, \ + } + +enum field_type { + Offset, + NameString, + FieldTypeMax, +}; + +struct fieldlist { + enum field_type type; + char name[4]; + u16 bits; +}; + +enum Region_Space { + SystemMemory, + SystemIO, + PCI_Config, + EmbeddedControl, + SMBus, + CMOS, + PciBarTarget, + IPMI, + RegionSpaceMax, + +}; + +struct opregion { + char name[4]; + enum Region_Space RegionSpace; + unsigned long RegionOffset; + unsigned long RegionLen; +}; + void acpigen_write_len_f(void); void acpigen_pop_len(void); void acpigen_set_current(char *curr); @@ -157,7 +198,8 @@ void acpigen_write_debug_op(uint8_t op); void acpigen_write_if(void); void acpigen_write_if_and(uint8_t arg1, uint8_t arg2); void acpigen_write_else(void); - +void acpigen_write_opregion(struct opregion *opreg); +void acpigen_write_field(char *name, struct fieldlist *l, u16 n_field); int get_cst_entries(acpi_cstate_t **);
/*