[coreboot-gerrit] Patch set updated for coreboot: arch/x86/acpigen: Add OperationRegion & Field method.
Naresh Solanki (naresh.solanki@intel.com)
gerrit at coreboot.org
Tue Oct 25 17:00:47 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 265e8cedef117901c7555486c26f74f8c2c2c061
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 | 71 +++++++++++++++++++++++++++++++++++++
src/arch/x86/include/arch/acpigen.h | 61 +++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+)
diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c
index 42d4204..fe793d6 100644
--- a/src/arch/x86/acpigen.c
+++ b/src/arch/x86/acpigen.c
@@ -351,6 +351,77 @@ 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)
+{
+ 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, u8 field)
+{
+ 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(field); // AnyAcc temp
+
+ 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);
+ else
+ 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..f89759a 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,63 @@ enum {
ONES_OP = 0xFF,
};
+#define FIELDLIST_OFFSET(X) { .type = OFFSET, \
+ .name = "",\
+ .bits = X,\
+ }
+#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
+#define FIELD_LOCK (1<<4)
+#define FIELD_PRESERVE 0
+#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;
+ char name[4];
+ u16 bits;
+};
+
+enum region_space {
+ SYSTEMMEMORY,
+ SYSTEMIO,
+ PCI_CONFIG,
+ EMBEDDEDCONTROL,
+ SMBUS,
+ CMOS,
+ PCIBARTARGET,
+ IPMI,
+ REGION_SPACE_MAX,
+};
+
+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);
@@ -176,6 +235,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(char *name, struct fieldlist *l, u8 field);
int get_cst_entries(acpi_cstate_t **);
/*
More information about the coreboot-gerrit
mailing list