[coreboot-gerrit] Patch set updated for coreboot: arch/x86/acpigen: Add OperationRegion & Field method.

Naresh Solanki (naresh.solanki@intel.com) gerrit at coreboot.org
Thu Oct 27 06:21:10 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 7671fbbc09e710907635859acd7bae65913750fb
Author: Naresh G Solanki <naresh.solanki at intel.com>
Date:   Tue Oct 25 00:51:24 2016 +0530

    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              | 78 +++++++++++++++++++++++++++++++++++++
 src/arch/x86/include/arch/acpigen.h | 67 +++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+)

diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c
index 42d4204..db387c2 100644
--- a/src/arch/x86/acpigen.c
+++ b/src/arch/x86/acpigen.c
@@ -351,6 +351,84 @@ 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_ext_op(OPREGION_OP);
+	/* 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)
+{
+	u32 diff_bits;
+	u32 i, j;
+	u8 emit[4];
+	diff_bits = offset - current_bit_pos;
+
+	if (offset < current_bit_pos)
+		return;
+
+	/* Upper limit */
+	if (diff_bits > 0xFFFFFFF)
+		return;
+
+	emit[0] = diff_bits & 0xF;
+	diff_bits >>= 4;
+	i = 1;
+
+	while (diff_bits) {
+		emit[i] = diff_bits & 0xFF;
+		i++;
+		diff_bits >>= 8;
+	}
+
+	/* Update bit 7:6 : Number of byte followed byt this */
+	emit[0] |= (i-1) << 6;
+
+	acpigen_emit_byte(0);
+	for (j = 0; j < i; j++)
+		acpigen_emit_byte(emit[j]);
+}
+
+void acpigen_write_field(const char *name, struct fieldlist *l, u8 flags)
+{
+	u16 i = 0;
+	u32 current_bit_pos = 0;
+
+	/* FieldOp */
+	acpigen_emit_ext_op(FIELD_OP);
+	/* Package Length */
+	acpigen_write_len_f();
+	/* NameString 4 chars only */
+	acpigen_emit_simple_namestring(name);
+	/* Field Flag */
+	acpigen_emit_byte(flags);
+
+	while (1) {
+		if (l[i].type ==  NAME_STRING) {
+			acpigen_emit_simple_namestring(l[i].name);
+			acpigen_emit_byte(l[i].bits);
+			current_bit_pos += l[i].bits;
+		} else if (l[i].type == OFFSET) {
+			acpigen_write_field_offset(l[i].bits, current_bit_pos);
+			current_bit_pos = l[i].bits;
+		} else  if (l[i].type == FIELD_TYPE_MAX) {
+			printk(BIOS_ERR, "%s: Invalid field type 0x%X\n",
+				__func__, l[i].type);
+			break;
+		}
+		i++;
+	}
+	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 7c15a31..db2c1a2 100644
--- a/src/arch/x86/include/arch/acpigen.h
+++ b/src/arch/x86/include/arch/acpigen.h
@@ -53,6 +53,8 @@ enum {
 	EXT_OP_PREFIX		= 0x5B,
 	 SLEEP_OP		= 0x22,
 	 DEBUG_OP		= 0x31,
+	 OPREGION_OP		= 0x80,
+	 FIELD_OP		= 0x81,
 	 DEVICE_OP		= 0x82,
 	 PROCESSOR_OP		= 0x83,
 	 POWER_RES_OP		= 0x84,
@@ -84,6 +86,69 @@ enum {
 	ONES_OP		= 0xFF,
 };
 
+#define FIELDLIST_OFFSET(X)		{ .type = OFFSET, \
+					  .name = "",\
+					  .bits = X * 8, \
+					}
+#define FIELDLIST_NAMESTR(X, Y)		{ .type = NAME_STRING, \
+					  .name = X, \
+					  .bits = Y, \
+					}
+
+#define FIELDLIST_END			{ .type = FIELD_TYPE_MAX,\
+					  .name = "", \
+					  .bits = 0, \
+					}
+
+#define FIELD_ANYACC			0
+#define FIELD_BYTEACC			1
+#define FIELD_WORDACC			2
+#define FIELD_DWORDACC			3
+#define FIELD_QWORDACC			4
+#define FIELD_BUFFERACC			5
+#define FIELD_NOLOCK			(0<<4)
+#define FIELD_LOCK			(1<<4)
+#define FIELD_PRESERVE			(0<<5)
+#define FIELD_WRITEASONES		(1<<5)
+#define FIELD_WRITEASZEROS		(2<<5)
+
+enum field_type {
+	OFFSET,
+	NAME_STRING,
+	FIELD_TYPE_MAX,
+};
+
+struct fieldlist {
+	enum field_type type;
+	const char *name;
+	u32 bits;
+};
+
+#define OPREGION(rname, space, offset, len)	{.name = rname, \
+						 .regionspace = space, \
+						 .regionoffset = offset, \
+						 .regionlen = len, \
+						}
+
+enum region_space {
+	SYSTEMMEMORY,
+	SYSTEMIO,
+	PCI_CONFIG,
+	EMBEDDEDCONTROL,
+	SMBUS,
+	CMOS,
+	PCIBARTARGET,
+	IPMI,
+	REGION_SPACE_MAX,
+};
+
+struct opregion {
+	const char *name;
+	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);
@@ -176,6 +241,8 @@ void acpigen_write_return_byte(uint8_t arg);
 void acpigen_write_dsm(const char *uuid, void (*callbacks[])(void *),
 		       size_t count, void *arg);
 
+void acpigen_write_opregion(struct opregion *opreg);
+void acpigen_write_field(const char *name, struct fieldlist *l, u8 field);
 int get_cst_entries(acpi_cstate_t **);
 
 /*



More information about the coreboot-gerrit mailing list