summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peres <martin.peres@free.fr>2016-11-24 02:42:35 +0200
committerMartin Peres <martin.peres@free.fr>2016-11-24 02:42:35 +0200
commit46e800236559c33727e0791b9872beacf9b1f8af (patch)
tree37b5d16fe4024e5812cdd11e03271a4eb6f88d15
parent729d9c2052138765f1a4e79bc063db79c0d785bb (diff)
nvbios/power: partially decode P.unk18
-rw-r--r--nvbios/bios.h22
-rw-r--r--nvbios/power.c79
-rw-r--r--nvbios/print.c2
3 files changed, 70 insertions, 33 deletions
diff --git a/nvbios/bios.h b/nvbios/bios.h
index 002f064c..c46bd391 100644
--- a/nvbios/bios.h
+++ b/nvbios/bios.h
@@ -739,11 +739,23 @@ struct envy_bios_power_unk14 {
struct envy_bios_power_unk14_entry *entries;
};
-struct envy_bios_power_unk18_entry {
+struct envy_bios_power_fan_calib_entry {
uint32_t offset;
+ uint8_t enable;
+ uint8_t mode;
+
+ uint16_t unk02;
+ uint16_t unk04;
+ uint16_t unk06;
+ uint16_t pwm_freq;
+ uint16_t calib_full_pwr;
+ uint16_t calib_no_pwr;
+ uint16_t unk0e;
+ uint16_t unk10;
+ uint16_t unk12;
};
-struct envy_bios_power_unk18 {
+struct envy_bios_power_fan_calib {
uint32_t offset;
uint8_t valid;
uint8_t version;
@@ -751,7 +763,7 @@ struct envy_bios_power_unk18 {
uint8_t entriesnum;
uint8_t rlen;
- struct envy_bios_power_unk18_entry *entries;
+ struct envy_bios_power_fan_calib_entry *entries;
};
struct envy_bios_power_unk1c_entry {
@@ -1332,7 +1344,7 @@ struct envy_bios_power {
struct envy_bios_power_therm therm;
struct envy_bios_power_volt volt;
struct envy_bios_power_unk14 unk14;
- struct envy_bios_power_unk18 unk18;
+ struct envy_bios_power_fan_calib fan_calib;
struct envy_bios_power_unk1c unk1c;
struct envy_bios_power_volt_map volt_map;
@@ -1648,7 +1660,7 @@ void envy_bios_print_i2cscript (struct envy_bios *bios, FILE *out, unsigned mask
int envy_bios_parse_bit_P (struct envy_bios *bios, struct envy_bios_bit_entry *bit);
void envy_bios_print_bit_P (struct envy_bios *bios, FILE *out, unsigned mask);
void envy_bios_print_power_unk14(struct envy_bios *bios, FILE *out, unsigned mask);
-void envy_bios_print_power_unk18(struct envy_bios *bios, FILE *out, unsigned mask);
+void envy_bios_print_power_fan_calib(struct envy_bios *bios, FILE *out, unsigned mask);
void envy_bios_print_power_unk1c(struct envy_bios *bios, FILE *out, unsigned mask);
void envy_bios_print_power_unk24(struct envy_bios *bios, FILE *out, unsigned mask);
void envy_bios_print_power_sense(struct envy_bios *bios, FILE *out, unsigned mask);
diff --git a/nvbios/power.c b/nvbios/power.c
index 6ccddd1d..c34c453d 100644
--- a/nvbios/power.c
+++ b/nvbios/power.c
@@ -30,7 +30,7 @@
void printscript (uint16_t soff);
int envy_bios_parse_power_unk14(struct envy_bios *bios);
-int envy_bios_parse_power_unk18(struct envy_bios *bios);
+int envy_bios_parse_power_fan_calib(struct envy_bios *bios);
int envy_bios_parse_power_unk1c(struct envy_bios *bios);
int envy_bios_parse_power_budget(struct envy_bios *bios);
int envy_bios_parse_power_boost(struct envy_bios *bios);
@@ -77,7 +77,7 @@ static int parse_at(struct envy_bios *bios, struct envy_bios_power *power,
{ 0x04, &power->timing.offset, "MEMORY TIMINGS" },
{ 0x0c, &power->therm.offset, "THERMAL" },
{ 0x10, &power->volt.offset, "VOLTAGE" },
- { 0x15, &power->unk18.offset, "POWER UNK18" }
+ { 0x15, &power->fan_calib.offset, "POWER UNK18" }
};
struct P_known_tables p2_tbls[] = {
{ 0x00, &power->perf.offset, "PERFORMANCE" },
@@ -86,7 +86,7 @@ static int parse_at(struct envy_bios *bios, struct envy_bios_power *power,
{ 0x0c, &power->volt.offset, "VOLTAGE" },
{ 0x10, &power->therm.offset, "THERMAL" },
{ 0x14, &power->unk14.offset, "UNK14" },
- { 0x18, &power->unk18.offset, "POWER UNK18" },
+ { 0x18, &power->fan_calib.offset, "FAN CALIBRATION" },
{ 0x1c, &power->unk1c.offset, "POWER UNK1C" },
{ 0x20, &power->volt_map.offset, "VOLT MAPPING" },
{ 0x24, &power->unk24.offset, "POWER UNK24" },
@@ -170,7 +170,7 @@ int envy_bios_parse_bit_P (struct envy_bios *bios, struct envy_bios_bit_entry *b
idx++;
envy_bios_parse_power_unk14(bios);
- envy_bios_parse_power_unk18(bios);
+ envy_bios_parse_power_fan_calib(bios);
envy_bios_parse_power_unk1c(bios);
envy_bios_parse_power_unk24(bios);
envy_bios_parse_power_sense(bios);
@@ -284,54 +284,79 @@ void envy_bios_print_power_unk14(struct envy_bios *bios, FILE *out, unsigned mas
fprintf(out, "\n");
}
-int envy_bios_parse_power_unk18(struct envy_bios *bios) {
- struct envy_bios_power_unk18 *unk18 = &bios->power.unk18;
+int envy_bios_parse_power_fan_calib(struct envy_bios *bios) {
+ struct envy_bios_power_fan_calib *fan_calib = &bios->power.fan_calib;
int i, err = 0;
- if (!unk18->offset)
+ if (!fan_calib->offset)
return -EINVAL;
- bios_u8(bios, unk18->offset + 0x0, &unk18->version);
- switch(unk18->version) {
+ bios_u8(bios, fan_calib->offset + 0x0, &fan_calib->version);
+ switch(fan_calib->version) {
case 0x10:
- err |= bios_u8(bios, unk18->offset + 0x1, &unk18->hlen);
- err |= bios_u8(bios, unk18->offset + 0x2, &unk18->rlen);
- err |= bios_u8(bios, unk18->offset + 0x3, &unk18->entriesnum);
- unk18->valid = !err;
+ err |= bios_u8(bios, fan_calib->offset + 0x1, &fan_calib->hlen);
+ err |= bios_u8(bios, fan_calib->offset + 0x2, &fan_calib->rlen);
+ err |= bios_u8(bios, fan_calib->offset + 0x3, &fan_calib->entriesnum);
+ fan_calib->valid = !err;
break;
default:
- ENVY_BIOS_ERR("Unknown UNK18 table version 0x%x\n", unk18->version);
+ ENVY_BIOS_ERR("Unknown FAN CALIBRATION table version 0x%x\n", fan_calib->version);
return -EINVAL;
};
err = 0;
- unk18->entries = malloc(unk18->entriesnum * sizeof(struct envy_bios_power_unk18_entry));
- for (i = 0; i < unk18->entriesnum; i++) {
- uint16_t data = unk18->offset + unk18->hlen + i * unk18->rlen;
+ fan_calib->entries = calloc(fan_calib->entriesnum, sizeof(struct envy_bios_power_fan_calib_entry));
+ for (i = 0; i < fan_calib->entriesnum; i++) {
+ uint16_t data = fan_calib->offset + fan_calib->hlen + i * fan_calib->rlen;
- unk18->entries[i].offset = data;
+ fan_calib->entries[i].offset = data;
+ bios_u8(bios, data + 0x00, &fan_calib->entries[i].enable);
+ bios_u8(bios, data + 0x01, &fan_calib->entries[i].mode);
+ bios_u16(bios, data + 0x02, &fan_calib->entries[i].unk02);
+ bios_u16(bios, data + 0x04, &fan_calib->entries[i].unk04);
+ bios_u16(bios, data + 0x06, &fan_calib->entries[i].unk06);
+ bios_u16(bios, data + 0x08, &fan_calib->entries[i].pwm_freq); /* not used by the blob */
+ bios_u16(bios, data + 0x0a, &fan_calib->entries[i].calib_full_pwr);
+ bios_u16(bios, data + 0x0c, &fan_calib->entries[i].calib_no_pwr);
+ bios_u16(bios, data + 0x0e, &fan_calib->entries[i].unk0e);
+
+ if (fan_calib->rlen >= 0x12)
+ bios_u16(bios, data + 0x10, &fan_calib->entries[i].unk10);
+
+ if (fan_calib->rlen >= 0x14)
+ bios_u16(bios, data + 0x12, &fan_calib->entries[i].unk12);
}
return 0;
}
-void envy_bios_print_power_unk18(struct envy_bios *bios, FILE *out, unsigned mask) {
- struct envy_bios_power_unk18 *unk18 = &bios->power.unk18;
+void envy_bios_print_power_fan_calib(struct envy_bios *bios, FILE *out, unsigned mask) {
+ struct envy_bios_power_fan_calib *fan_calib = &bios->power.fan_calib;
int i;
- if (!unk18->offset || !(mask & ENVY_BIOS_PRINT_PERF))
+ if (!fan_calib->offset || !(mask & ENVY_BIOS_PRINT_PERF))
return;
- if (!unk18->valid) {
- fprintf(out, "Failed to parse UNK18 table at 0x%x, version %x\n", unk18->offset, unk18->version);
+ if (!fan_calib->valid) {
+ fprintf(out, "Failed to parse FAN CALIBRATION table at 0x%x, version %x\n", fan_calib->offset, fan_calib->version);
return;
}
- fprintf(out, "UNK18 table at 0x%x, version %x\n", unk18->offset, unk18->version);
- envy_bios_dump_hex(bios, out, unk18->offset, unk18->hlen, mask);
+ fprintf(out, "FAN CALIBRATION table at 0x%x, version %x\n", fan_calib->offset, fan_calib->version);
+ envy_bios_dump_hex(bios, out, fan_calib->offset, fan_calib->hlen, mask);
if (mask & ENVY_BIOS_PRINT_VERBOSE) fprintf(out, "\n");
- for (i = 0; i < unk18->entriesnum; i++) {
- envy_bios_dump_hex(bios, out, unk18->entries[i].offset, unk18->rlen, mask);
+ for (i = 0; i < fan_calib->entriesnum; i++) {
+ struct envy_bios_power_fan_calib_entry *e = &fan_calib->entries[i];
+ if (e->enable == 1 && (e->mode & 0x7) == 1) {
+ fprintf(out, "-- %i: mode_high %u mode_low %u unk02 %u unk04 %u "
+ "unk06 %u PWM freq %d Hz full_power %d no_pwr %d "
+ "unk0e %u unk10 %u unk12 %u --\n",
+ i, e->mode >> 4, e->mode & 0x7, e->unk02, e->unk04, e->unk06,
+ e->pwm_freq, e->calib_full_pwr, e->calib_no_pwr,
+ e->unk0e, e->unk10, e->unk12);
+ }
+
+ envy_bios_dump_hex(bios, out, fan_calib->entries[i].offset, fan_calib->rlen, mask);
if (mask & ENVY_BIOS_PRINT_VERBOSE) fprintf(out, "\n");
}
diff --git a/nvbios/print.c b/nvbios/print.c
index 9d69a3e3..e214d365 100644
--- a/nvbios/print.c
+++ b/nvbios/print.c
@@ -424,7 +424,7 @@ void envy_bios_print (struct envy_bios *bios, FILE *out, unsigned mask) {
envy_bios_print_mem_unk0d(bios, stdout, mask);
envy_bios_print_power_unk14(bios, stdout, mask);
- envy_bios_print_power_unk18(bios, stdout, mask);
+ envy_bios_print_power_fan_calib(bios, stdout, mask);
envy_bios_print_power_unk1c(bios, stdout, mask);
envy_bios_print_power_unk24(bios, stdout, mask);
envy_bios_print_power_sense(bios, stdout, mask);