summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-31 14:15:18 +0100
committerMarcin Koƛcielnicki <koriakin@0x04.net>2016-12-31 14:15:18 +0100
commit66cdbc3951e5b5d73142219b4451022c9193dcb5 (patch)
treee37cef861d9a8046988e15c74263fefa213cf070
parent6afdfe6ffb8f2394a212b4937abc238ce7407d22 (diff)
hwtest/pgraph: Enter Rankine.
-rw-r--r--hwtest/pgraph.h6
-rw-r--r--hwtest/pgraph_scan.cc24
-rw-r--r--hwtest/pgraph_state.cc140
-rw-r--r--hwtest/pgraph_state_tests.cc42
-rw-r--r--include/nvhw/pgraph.h6
-rw-r--r--nvhw/pgraph.c4
6 files changed, 175 insertions, 47 deletions
diff --git a/hwtest/pgraph.h b/hwtest/pgraph.h
index 9ec3e19d..2995697c 100644
--- a/hwtest/pgraph.h
+++ b/hwtest/pgraph.h
@@ -53,6 +53,12 @@ public:
virtual void sim_write(struct pgraph_state *state, uint32_t val) { ref(state) = (val & mask) | fixed; }
virtual uint32_t read(int cnum) = 0;
virtual void write(int cnum, uint32_t val) = 0;
+ virtual void gen(struct pgraph_state *state, int cnum, std::mt19937 &rnd) {
+ sim_write(state, rnd());
+ }
+ virtual bool diff(struct pgraph_state *exp, struct pgraph_state *real) {
+ return ref(exp) != ref(real);
+ }
virtual bool scan_test(int cnum, std::mt19937 &rnd) {
uint32_t tmp = read(cnum);
write(cnum, 0xffffffff);
diff --git a/hwtest/pgraph_scan.cc b/hwtest/pgraph_scan.cc
index 77dcabbb..7e575dc1 100644
--- a/hwtest/pgraph_scan.cc
+++ b/hwtest/pgraph_scan.cc
@@ -85,7 +85,7 @@ class ScanDebugTest : public ScanTest {
bitscan(0x400088, 0xffffffff, 0);
bitscan(0x40008c, is_nv15p ? 0xffffff78 : 0xfffffc70, is_nv17p ? 0x400 : 0);
bitscan(0x400090, is_nv17p ? 0x1fffffff : 0x00ffffff, 0);
- } else {
+ } else if (chipset.card_type < 0x30) {
bool is_nv25p = nv04_pgraph_is_nv25p(&chipset);
bitscan(0x400080, is_nv25p ? 0x07ffefff : 0x03ffefff, 0);
bitscan(0x400084, 0x0011f7c1, 0);
@@ -97,6 +97,16 @@ class ScanDebugTest : public ScanTest {
bitscan(0x40009c, 0xfff, 0);
if (is_nv25p)
bitscan(0x4000c0, 3, 0);
+ } else {
+ bitscan(0x400080, chipset.chipset == 0x34 ? 0x7fffffff : 0x3fffffff, 0);
+ bitscan(0x400084, 0x7012f7c1, 0);
+ bitscan(0x40008c, 0xfffedf7d, 0);
+ bitscan(0x400090, 0x3fffffff, 0);
+ bitscan(0x400098, 0xffffffff, 0);
+ bitscan(0x40009c, 0xffffffff, 0);
+ bitscan(0x4000a0, 0xffffffff, 0);
+ bitscan(0x4000a4, 0xf, 0);
+ bitscan(0x4000c0, 0x1e, 0);
}
return res;
}
@@ -218,8 +228,16 @@ class ScanControlTest : public ScanTest {
bitscan(0x400f50, 0x00001fff, 0);
} else if (chipset.card_type < 0x20) {
bitscan(0x400f50, 0x00007ffc, 0);
- } else {
+ } else if (chipset.card_type < 0x30) {
bitscan(0x400f50, 0x0001fffc, 0);
+ if (!nv04_pgraph_is_nv25p(&chipset))
+ bitscan(0x400750, 0x01ff1ffc, 0);
+ else
+ bitscan(0x400750, 0x03ff1ffc, 0);
+ } else {
+ bitscan(0x400f50, 0x0003fffc, 0);
+ bitscan(0x400750, 0x03ff7ffc, 0);
+ bitscan(0x40075c, 1, 0);
}
}
}
@@ -474,7 +492,7 @@ public:
}
bool PGraphScanTests::supported() {
- return chipset.card_type < 0x30;
+ return chipset.card_type < 0x40;
}
Test::Subtests PGraphScanTests::subtests() {
diff --git a/hwtest/pgraph_state.cc b/hwtest/pgraph_state.cc
index 055ad018..ddb7e0f6 100644
--- a/hwtest/pgraph_state.cc
+++ b/hwtest/pgraph_state.cc
@@ -180,6 +180,17 @@ public:
}
};
+class SurfUnk800Nv34Register : public SimpleMmioRegister {
+public:
+ SurfUnk800Nv34Register(uint32_t addr, uint32_t mask) :
+ SimpleMmioRegister(addr, mask, "SURF_UNK800", &pgraph_state::surf_unk800) {}
+ void sim_write(struct pgraph_state *state, uint32_t val) override {
+ ref(state) = val & mask;
+ insrt(state->surf_unk800, 8, 1, extr(state->surf_unk800, 0, 1));
+ insrt(state->surf_unk800, 12, 1, extr(state->surf_unk800, 4, 1));
+ }
+};
+
std::vector<std::unique_ptr<Register>> pgraph_canvas_regs(const chipset_info &chipset) {
std::vector<std::unique_ptr<Register>> res;
if (chipset.card_type < 4) {
@@ -241,11 +252,17 @@ std::vector<std::unique_ptr<Register>> pgraph_canvas_regs(const chipset_info &ch
REG(0x400614, 0xc0000000 | offset_mask, "SURF_UNK614", surf_unk614);
} else {
uint32_t offset_mask = pgraph_offset_mask(&chipset);
+ uint32_t base_mask = offset_mask;
+ uint32_t limit_fixed = 0x3f;
+ if (chipset.chipset == 0x34) {
+ base_mask |= 0xc0000000;
+ limit_fixed = 0xf;
+ }
uint32_t pitch_mask = pgraph_pitch_mask(&chipset);
for (int i = 0; i < 6; i++) {
res.push_back(std::unique_ptr<Register>(new SurfOffsetRegister(0x400820 + i * 4, i, offset_mask)));
- res.push_back(std::unique_ptr<Register>(new SurfBaseRegister(0x400838 + i * 4, i, offset_mask)));
- IREGF(0x400864 + i * 4, 1 << 31 | offset_mask, "SURF_LIMIT", surf_limit, i, 7, 0x3f);
+ res.push_back(std::unique_ptr<Register>(new SurfBaseRegister(0x400838 + i * 4, i, base_mask)));
+ IREGF(0x400864 + i * 4, 1 << 31 | offset_mask, "SURF_LIMIT", surf_limit, i, 7, limit_fixed);
}
for (int i = 0; i < 5; i++) {
res.push_back(std::unique_ptr<Register>(new SurfPitchRegister(0x400850 + i * 4, i, pitch_mask)));
@@ -255,9 +272,9 @@ std::vector<std::unique_ptr<Register>> pgraph_canvas_regs(const chipset_info &ch
}
if (nv04_pgraph_is_nv25p(&chipset)) {
res.push_back(std::unique_ptr<Register>(new SurfOffsetRegister(0x400880, 6, offset_mask)));
- res.push_back(std::unique_ptr<Register>(new SurfBaseRegister(0x400884, 6, offset_mask)));
+ res.push_back(std::unique_ptr<Register>(new SurfBaseRegister(0x400884, 6, base_mask)));
res.push_back(std::unique_ptr<Register>(new SurfPitchRegister(0x400888, 5, pitch_mask)));
- IREGF(0x40088c, 1 << 31 | offset_mask, "SURF_LIMIT", surf_limit, 6, 7, 0x3f);
+ IREGF(0x40088c, 1 << 31 | offset_mask, "SURF_LIMIT", surf_limit, 6, 7, limit_fixed);
}
uint32_t st_mask;
if (!nv04_pgraph_is_nv25p(&chipset))
@@ -267,14 +284,20 @@ std::vector<std::unique_ptr<Register>> pgraph_canvas_regs(const chipset_info &ch
res.push_back(std::unique_ptr<Register>(new SurfTypeRegister(
chipset.card_type >= 0x10 ? 0x400710 : 0x40070c,
st_mask)));
- REG(0x400724, 0xffffff, "SURF_FORMAT", surf_format);
+ if (chipset.card_type < 0x30)
+ REG(0x400724, 0xffffff, "SURF_FORMAT", surf_format);
+ else
+ REG(0x400724, 0x3fffffff, "SURF_FORMAT", surf_format);
REG(chipset.card_type >= 0x10 ? 0x400714 : 0x400710,
nv04_pgraph_is_nv25p(&chipset) ? 0x0f733f7f : nv04_pgraph_is_nv17p(&chipset) ? 0x3f731f3f : 0x0f731f3f,
"CTX_VALID", ctx_valid);
- REG(0x400800, 0xfff31f1f, "SURF_UNK800", surf_unk800);
- REG(0x40080c, 0xfffffffc, "SURF_UNK80C", surf_unk80c);
- REG(0x400810, 0xfffffffc, "SURF_UNK810", surf_unk810);
- if (chipset.card_type >= 0x20) {
+ if (chipset.chipset != 0x34) {
+ if (chipset.card_type < 0x30)
+ REG(0x400800, 0xfff31f1f, "SURF_UNK800", surf_unk800);
+ else
+ REG(0x400800, 0xf1ffdf1f, "SURF_UNK800", surf_unk800);
+ REG(0x40080c, 0xfffffffc, "SURF_UNK80C", surf_unk80c);
+ REG(0x400810, 0xfffffffc, "SURF_UNK810", surf_unk810);
if (!nv04_pgraph_is_nv25p(&chipset)) {
REG(0x400880, 0xffffffff, "SURF_UNK880", surf_unk880);
REG(0x400888, 0x0000003f, "SURF_UNK888", surf_unk888);
@@ -283,6 +306,13 @@ std::vector<std::unique_ptr<Register>> pgraph_canvas_regs(const chipset_info &ch
REG(0x400898, 0x0000007f, "SURF_UNK888", surf_unk888);
REG(0x40089c, 0x0fffffff, "SURF_UNK89C", surf_unk89c);
}
+ } else {
+ res.push_back(std::unique_ptr<Register>(new SurfUnk800Nv34Register(0x400800, 0x00001f17)));
+ REG(0x40080c, 0xfffffff0, "SURF_UNK80C", surf_unk80c);
+ REG(0x400810, 0xfffffff0, "SURF_UNK810", surf_unk810);
+ REG(0x400890, 0xffffffff, "SURF_UNK880", surf_unk880);
+ REG(0x4008a4, 0xffffffff, "SURF_UNK8A4", surf_unk8a4);
+ REG(0x4008a8, 0xffffffff, "SURF_UNK8A8", surf_unk8a8);
}
}
return res;
@@ -310,6 +340,20 @@ public:
}
};
+class XyARegister : public SimpleMmioRegister {
+public:
+ XyARegister(uint32_t addr, uint32_t mask, uint32_t fixed) :
+ SimpleMmioRegister(addr, mask, "XY_A", &pgraph_state::xy_a, fixed) {}
+ void gen(struct pgraph_state *state, int cnum, std::mt19937 &rnd) override {
+ sim_write(state, rnd());
+ }
+ void sim_write(struct pgraph_state *state, uint32_t val) override {
+ if (!extr(val, 1, 17))
+ insrt(val, 18, 1, 1);
+ ref(state) = val & (mask | fixed);
+ }
+};
+
std::vector<std::unique_ptr<Register>> pgraph_vstate_regs(const chipset_info &chipset) {
std::vector<std::unique_ptr<Register>> res;
if (chipset.card_type < 3) {
@@ -325,8 +369,9 @@ std::vector<std::unique_ptr<Register>> pgraph_vstate_regs(const chipset_info &ch
uint32_t xy_a_mask = 0xf013ffff;
if (chipset.card_type >= 0x10)
xy_a_mask |= 0x01000000;
+ uint32_t xy_a_fixed = chipset.chipset == 0x34 ? 0x40000 : 0;
uint32_t xy_b_mask = chipset.card_type >= 4 ? 0x00111031 : 0x0f177331;
- REG(0x400514, xy_a_mask, "XY_A", xy_a);
+ res.push_back(std::unique_ptr<Register>(new XyARegister(0x400514, xy_a_mask, xy_a_fixed)));
IREG(0x400518, xy_b_mask, "XY_B", xy_misc_1, 0, 2);
IREG(0x40051c, xy_b_mask, "XY_B", xy_misc_1, 1, 2);
REG(0x400520, 0x7f7f1111, "XY_C", xy_misc_3);
@@ -721,7 +766,7 @@ void pgraph_gen_state_debug(int cnum, std::mt19937 &rnd, struct pgraph_state *st
state->debug[4] = rnd() & (is_nv17p ? 0x1fffffff : 0x00ffffff);
if (is_nv17p)
state->debug[3] |= 0x400;
- } else {
+ } else if (state->chipset.card_type < 0x30) {
// debug[0] holds only resets?
state->debug[0] = 0;
state->debug[1] = rnd() & 0x0011f7c1;
@@ -731,6 +776,19 @@ void pgraph_gen_state_debug(int cnum, std::mt19937 &rnd, struct pgraph_state *st
state->debug[6] = rnd();
state->debug[7] = rnd() & 0xfff;
state->debug[16] = rnd() & 3;
+ } else {
+ // debug[0] holds only resets?
+ state->debug[0] = 0;
+ state->debug[1] = rnd() & 0x7012f7c1;
+ state->debug[3] = rnd() & 0xfffedf7d;
+ state->debug[4] = rnd() & 0x3fffffff;
+ state->debug[6] = rnd();
+ state->debug[7] = rnd();
+ state->debug[8] = rnd();
+ state->debug[9] = rnd() & 0xf;
+ state->debug[16] = rnd() & 0x1e;
+ // XXX: figure this out
+ state->debug[1] &= 0xbfffffff;
}
}
@@ -904,44 +962,44 @@ using namespace hwtest::pgraph;
void pgraph_gen_state_canvas(int cnum, std::mt19937 &rnd, struct pgraph_state *state) {
for (auto &reg : pgraph_canvas_regs(state->chipset)) {
- reg->ref(state) = (rnd() & reg->mask) | reg->fixed;
+ reg->gen(state, cnum, rnd);
}
}
void pgraph_gen_state_rop(int cnum, std::mt19937 &rnd, struct pgraph_state *state) {
for (auto &reg : pgraph_rop_regs(state->chipset)) {
- reg->ref(state) = (rnd() & reg->mask) | reg->fixed;
+ reg->gen(state, cnum, rnd);
}
}
void pgraph_gen_state_vstate(int cnum, std::mt19937 &rnd, struct pgraph_state *state) {
for (auto &reg : pgraph_vstate_regs(state->chipset)) {
- reg->ref(state) = (rnd() & reg->mask) | reg->fixed;
+ reg->gen(state, cnum, rnd);
}
}
void pgraph_gen_state_dma_nv3(int cnum, std::mt19937 &rnd, struct pgraph_state *state) {
state->dma_intr = 0;
for (auto &reg : pgraph_dma_nv3_regs(state->chipset)) {
- reg->ref(state) = (rnd() & reg->mask) | reg->fixed;
+ reg->gen(state, cnum, rnd);
}
}
void pgraph_gen_state_dma_nv4(int cnum, std::mt19937 &rnd, struct pgraph_state *state) {
for (auto &reg : pgraph_dma_nv4_regs(state->chipset)) {
- reg->ref(state) = (rnd() & reg->mask) | reg->fixed;
+ reg->gen(state, cnum, rnd);
}
}
void pgraph_gen_state_d3d0(int cnum, std::mt19937 &rnd, struct pgraph_state *state) {
for (auto &reg : pgraph_d3d0_regs(state->chipset)) {
- reg->ref(state) = (rnd() & reg->mask) | reg->fixed;
+ reg->gen(state, cnum, rnd);
}
}
void pgraph_gen_state_d3d56(int cnum, std::mt19937 &rnd, struct pgraph_state *state) {
for (auto &reg : pgraph_d3d56_regs(state->chipset)) {
- reg->ref(state) = (rnd() & reg->mask) | reg->fixed;
+ reg->gen(state, cnum, rnd);
}
}
@@ -964,7 +1022,7 @@ static uint32_t canonical_ovtx_fog(uint32_t v) {
void pgraph_gen_state_celsius(int cnum, std::mt19937 &rnd, struct pgraph_state *state) {
for (auto &reg : pgraph_celsius_regs(state->chipset)) {
- reg->ref(state) = (rnd() & reg->mask) | reg->fixed;
+ reg->gen(state, cnum, rnd);
state->celsius_pipe_begin_end = rnd() & 0xf;
state->celsius_pipe_edge_flag = rnd() & 0x1;
state->celsius_pipe_unk48 = 0;
@@ -1184,6 +1242,10 @@ void pgraph_load_debug(int cnum, struct pgraph_state *state) {
nva_wr32(cnum, 0x4000c0, state->debug[16]);
}
}
+ if (state->chipset.card_type >= 0x30) {
+ nva_wr32(cnum, 0x4000a0, state->debug[8]);
+ nva_wr32(cnum, 0x4000a4, state->debug[9]);
+ }
}
void pgraph_load_vstate(int cnum, struct pgraph_state *state) {
@@ -1624,6 +1686,10 @@ void pgraph_dump_debug(int cnum, struct pgraph_state *state) {
state->debug[16] = nva_rd32(cnum, 0x4000c0);
}
}
+ if (state->chipset.card_type >= 0x30) {
+ state->debug[8] = nva_rd32(cnum, 0x4000a0);
+ state->debug[9] = nva_rd32(cnum, 0x4000a4);
+ }
}
void pgraph_dump_dma_nv3(int cnum, struct pgraph_state *state) {
@@ -1735,6 +1801,10 @@ restart:
CMP(debug[16], "DEBUG[16]")
}
}
+ if (orig->chipset.card_type >= 0x30) {
+ CMP(debug[8], "DEBUG[8]")
+ CMP(debug[9], "DEBUG[9]")
+ }
CMP(intr, "INTR")
CMP(intr_en, "INTR_EN")
@@ -1847,8 +1917,8 @@ restart:
if (print)
printf("%08x %08x %08x %s %s\n",
reg->ref(orig), reg->ref(exp), reg->ref(real), name.c_str(),
- (reg->ref(exp) == reg->ref(real) ? "" : "*"));
- else if (reg->ref(exp) != reg->ref(real)) {
+ (!reg->diff(exp, real) ? "" : "*"));
+ else if (reg->diff(exp, real)) {
printf("Difference in reg %s: expected %08x real %08x\n",
name.c_str(), reg->ref(exp), reg->ref(real));
broke = true;
@@ -1861,8 +1931,8 @@ restart:
if (print)
printf("%08x %08x %08x %s %s\n",
reg->ref(orig), reg->ref(exp), reg->ref(real), name.c_str(),
- (reg->ref(exp) == reg->ref(real) ? "" : "*"));
- else if (reg->ref(exp) != reg->ref(real)) {
+ (!reg->diff(exp, real) ? "" : "*"));
+ else if (reg->diff(exp, real)) {
printf("Difference in reg %s: expected %08x real %08x\n",
name.c_str(), reg->ref(exp), reg->ref(real));
broke = true;
@@ -1875,8 +1945,8 @@ restart:
if (print)
printf("%08x %08x %08x %s %s\n",
reg->ref(orig), reg->ref(exp), reg->ref(real), name.c_str(),
- (reg->ref(exp) == reg->ref(real) ? "" : "*"));
- else if (reg->ref(exp) != reg->ref(real)) {
+ (!reg->diff(exp, real) ? "" : "*"));
+ else if (reg->diff(exp, real)) {
printf("Difference in reg %s: expected %08x real %08x\n",
name.c_str(), reg->ref(exp), reg->ref(real));
broke = true;
@@ -1890,8 +1960,8 @@ restart:
if (print)
printf("%08x %08x %08x %s %s\n",
reg->ref(orig), reg->ref(exp), reg->ref(real), name.c_str(),
- (reg->ref(exp) == reg->ref(real) ? "" : "*"));
- else if (reg->ref(exp) != reg->ref(real)) {
+ (!reg->diff(exp, real) ? "" : "*"));
+ else if (reg->diff(exp, real)) {
printf("Difference in reg %s: expected %08x real %08x\n",
name.c_str(), reg->ref(exp), reg->ref(real));
broke = true;
@@ -1904,8 +1974,8 @@ restart:
if (print)
printf("%08x %08x %08x %s %s\n",
reg->ref(orig), reg->ref(exp), reg->ref(real), name.c_str(),
- (reg->ref(exp) == reg->ref(real) ? "" : "*"));
- else if (reg->ref(exp) != reg->ref(real)) {
+ (!reg->diff(exp, real) ? "" : "*"));
+ else if (reg->diff(exp, real)) {
printf("Difference in reg %s: expected %08x real %08x\n",
name.c_str(), reg->ref(exp), reg->ref(real));
broke = true;
@@ -1918,8 +1988,8 @@ restart:
if (print)
printf("%08x %08x %08x %s %s\n",
reg->ref(orig), reg->ref(exp), reg->ref(real), name.c_str(),
- (reg->ref(exp) == reg->ref(real) ? "" : "*"));
- else if (reg->ref(exp) != reg->ref(real)) {
+ (!reg->diff(exp, real) ? "" : "*"));
+ else if (reg->diff(exp, real)) {
printf("Difference in reg %s: expected %08x real %08x\n",
name.c_str(), reg->ref(exp), reg->ref(real));
broke = true;
@@ -1990,8 +2060,8 @@ restart:
if (print)
printf("%08x %08x %08x %s %s\n",
reg->ref(orig), reg->ref(exp), reg->ref(real), name.c_str(),
- (reg->ref(exp) == reg->ref(real) ? "" : "*"));
- else if (reg->ref(exp) != reg->ref(real)) {
+ (!reg->diff(exp, real) ? "" : "*"));
+ else if (reg->diff(exp, real)) {
printf("Difference in reg %s: expected %08x real %08x\n",
name.c_str(), reg->ref(exp), reg->ref(real));
broke = true;
@@ -2003,8 +2073,8 @@ restart:
if (print)
printf("%08x %08x %08x %s %s\n",
reg->ref(orig), reg->ref(exp), reg->ref(real), name.c_str(),
- (reg->ref(exp) == reg->ref(real) ? "" : "*"));
- else if (reg->ref(exp) != reg->ref(real)) {
+ (!reg->diff(exp, real) ? "" : "*"));
+ else if (reg->diff(exp, real)) {
printf("Difference in reg %s: expected %08x real %08x\n",
name.c_str(), reg->ref(exp), reg->ref(real));
broke = true;
diff --git a/hwtest/pgraph_state_tests.cc b/hwtest/pgraph_state_tests.cc
index 2b1eac81..4f4ea04b 100644
--- a/hwtest/pgraph_state_tests.cc
+++ b/hwtest/pgraph_state_tests.cc
@@ -142,7 +142,9 @@ protected:
return;
if ((reg & 0xffffff00) == 0x400200 && chipset.chipset == 0x20)
return;
- if ((reg & 0xffffff00) == 0x400300 && chipset.card_type == 0x20)
+ if ((reg & 0xffffff00) == 0x400300 && chipset.card_type >= 0x20)
+ return;
+ if (reg == 0x400754 && chipset.card_type >= 0x20)
return;
}
nva_rd32(cnum, reg);
@@ -406,8 +408,10 @@ protected:
if (val & 1 << 31)
mangled |= 1 << 30;
exp.debug[1] = mangled & (is_nv11p ? 0xfe71f701 : 0xfe11f701);
- } else {
+ } else if (chipset.card_type < 0x30) {
exp.debug[1] = val & 0x0011f7c1;
+ } else {
+ exp.debug[1] = val & 0x7012f7c1;
}
if (val & 0x10)
exp.xy_misc_1[0] &= ~1;
@@ -416,7 +420,7 @@ protected:
if (chipset.card_type >= 0x20)
return;
reg = 0x400088;
- if (chipset.card_type <0x10)
+ if (chipset.card_type < 0x10)
exp.debug[2] = val & 0x11d7fff1;
else
exp.debug[2] = val;
@@ -429,8 +433,10 @@ protected:
exp.debug[3] = val & (is_nv15p ? 0xffffff78 : 0xfffffc70);
if (is_nv17p)
exp.debug[3] |= 0x400;
- } else {
+ } else if (chipset.card_type < 0x30) {
exp.debug[3] = val & (is_nv25p ? 0xffffdf7d : 0xffffd77d);
+ } else {
+ exp.debug[3] = val & 0xfffedf7d;
}
break;
case 6:
@@ -440,8 +446,10 @@ protected:
if (chipset.card_type < 0x20) {
exp.debug[4] = val & (is_nv17p ? 0x1fffffff : 0x00ffffff);
insrt(exp.unka10, 29, 1, extr(exp.debug[4], 2, 1) && !!extr(exp.surf_type, 2, 2));
- } else {
+ } else if (chipset.card_type < 0x30) {
exp.debug[4] = val & (is_nv25p ? 0xffffffff : 0xfffff3ff);
+ } else {
+ exp.debug[4] = val & 0x3fffffff;
}
break;
case 7:
@@ -590,13 +598,31 @@ protected:
if (chipset.card_type < 0x20)
return;
reg = 0x40009c;
- exp.debug[7] = val & 0xfff;
+ if (chipset.card_type < 0x30)
+ exp.debug[7] = val & 0xfff;
+ else
+ exp.debug[7] = val;
break;
case 32:
+ if (chipset.card_type < 0x30)
+ return;
+ reg = 0x4000a0;
+ exp.debug[8] = val;
+ break;
+ case 33:
+ if (chipset.card_type < 0x30)
+ return;
+ reg = 0x4000a4;
+ exp.debug[9] = val & 0xf;
+ break;
+ case 34:
if (!is_nv25p)
return;
reg = 0x4000c0;
- exp.debug[16] = val & 3;
+ if (chipset.card_type < 0x30)
+ exp.debug[16] = val & 3;
+ else
+ exp.debug[16] = val & 0x1e;
break;
}
nva_wr32(cnum, reg, val);
@@ -1086,7 +1112,7 @@ public:
}
bool PGraphStateTests::supported() {
- return chipset.card_type < 0x30;
+ return chipset.card_type < 0x40;
}
Test::Subtests PGraphStateTests::subtests() {
diff --git a/include/nvhw/pgraph.h b/include/nvhw/pgraph.h
index 77344836..0838c4ef 100644
--- a/include/nvhw/pgraph.h
+++ b/include/nvhw/pgraph.h
@@ -130,6 +130,8 @@ struct pgraph_state {
uint32_t surf_unk880;
uint32_t surf_unk888;
uint32_t surf_unk89c;
+ uint32_t surf_unk8a4;
+ uint32_t surf_unk8a8;
uint32_t ctx_valid;
uint32_t ctx_format;
uint32_t notify;
@@ -420,6 +422,8 @@ static inline uint32_t pgraph_offset_mask(const struct chipset_info *chipset) {
return 0x01fffff0;
else if (chipset->card_type < 0x20)
return 0x07fffff0;
+ else if (chipset->chipset == 0x34)
+ return 0x3ffffff0;
else
return 0x3fffffc0;
}
@@ -427,7 +431,7 @@ static inline uint32_t pgraph_offset_mask(const struct chipset_info *chipset) {
static inline uint32_t pgraph_pitch_mask(const struct chipset_info *chipset) {
if (chipset->card_type < 0x10)
return 0x1ff0;
- else if (chipset->card_type < 0x20)
+ else if (chipset->card_type < 0x20 || chipset->chipset == 0x34)
return 0xfff0;
else
return 0xffc0;
diff --git a/nvhw/pgraph.c b/nvhw/pgraph.c
index c025b5d5..f52df9e8 100644
--- a/nvhw/pgraph.c
+++ b/nvhw/pgraph.c
@@ -75,11 +75,15 @@ void pgraph_reset(struct pgraph_state *state) {
state->xy_clip[0][1] = 0x55555555;
state->xy_clip[1][0] = 0x55555555;
state->xy_clip[1][1] = 0x55555555;
+ if (state->chipset.chipset == 0x34)
+ state->xy_a |= 0x40000;
}
}
void pgraph_volatile_reset(struct pgraph_state *state) {
state->xy_a = 0;
+ if (state->chipset.chipset == 0x34)
+ state->xy_a |= 0x40000;
if (state->chipset.card_type < 3) {
state->bitmap_color[0] &= 0x3fffffff;
state->bitmap_color[1] &= 0x3fffffff;