[coreboot-gerrit] New patch to review for coreboot: [WIP]arch/x86/acpigen: Add OperationRegion & Field method.

Naresh Solanki (naresh.solanki@intel.com) gerrit at coreboot.org
Tue Oct 25 12:38:51 CEST 2016


Naresh Solanki (naresh.solanki at 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 at 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 at 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 **);
 
 /*



More information about the coreboot-gerrit mailing list