diff options
author | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-12-30 15:58:37 +0000 |
---|---|---|
committer | Marcin KoĆcielnicki <koriakin@0x04.net> | 2016-12-30 15:58:37 +0000 |
commit | ec493bb6f07fa89d6ea2d58552c99252d5322b4f (patch) | |
tree | f791d58e467a5e3c8ecdba89ce853dcc5b8d4b65 | |
parent | aecd4221f2e493a6cb5c76a383ec84f68f6383b7 (diff) |
hwtest/pgraph: Initial Kelvin support.
-rw-r--r-- | hwtest/pgraph_scan.cc | 48 | ||||
-rw-r--r-- | hwtest/pgraph_state.cc | 182 | ||||
-rw-r--r-- | hwtest/pgraph_state_tests.cc | 99 | ||||
-rw-r--r-- | include/nvhw/pgraph.h | 24 | ||||
-rw-r--r-- | nvhw/pgraph_xy4.c | 2 |
5 files changed, 266 insertions, 89 deletions
diff --git a/hwtest/pgraph_scan.cc b/hwtest/pgraph_scan.cc index 657231eb..77dcabbb 100644 --- a/hwtest/pgraph_scan.cc +++ b/hwtest/pgraph_scan.cc @@ -76,7 +76,7 @@ class ScanDebugTest : public ScanTest { bitscan(0x400084, is_nv5 ? 0xf2ffb701 : 0x72113101, 0); bitscan(0x400088, 0x11d7fff1, 0); bitscan(0x40008c, is_nv5 ? 0xfbffff73 : 0x11ffff33, 0); - } else { + } else if (chipset.card_type < 0x20) { bool is_nv11p = nv04_pgraph_is_nv11p(&chipset); bool is_nv15p = nv04_pgraph_is_nv15p(&chipset); bool is_nv17p = nv04_pgraph_is_nv17p(&chipset); @@ -85,6 +85,18 @@ 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 { + bool is_nv25p = nv04_pgraph_is_nv25p(&chipset); + bitscan(0x400080, is_nv25p ? 0x07ffefff : 0x03ffefff, 0); + bitscan(0x400084, 0x0011f7c1, 0); + bitscan(0x40008c, is_nv25p ? 0xffffdf7d : 0xffffd77d, 0); + bitscan(0x400090, is_nv25p ? 0xffffffff : 0xfffff3ff, 0); + if (!is_nv25p) + bitscan(0x400094, 0xff, 0); + bitscan(0x400098, 0xffffffff, 0); + bitscan(0x40009c, 0xfff, 0); + if (is_nv25p) + bitscan(0x4000c0, 3, 0); } return res; } @@ -116,8 +128,8 @@ class ScanControlTest : public ScanTest { bool is_nv11p = nv04_pgraph_is_nv11p(&chipset); bool is_nv15p = nv04_pgraph_is_nv15p(&chipset); bool is_nv17p = nv04_pgraph_is_nv17p(&chipset); + bool is_nv1720p = is_nv17p || chipset.card_type >= 0x20; uint32_t ctxs_mask, ctxc_mask; - uint32_t offset_mask = pgraph_offset_mask(&chipset); nva_wr32(cnum, 0x400720, 0); if (chipset.card_type < 0x10) { ctxs_mask = ctxc_mask = is_nv5 ? 0x7f73f0ff : 0x0303f0ff; @@ -129,8 +141,6 @@ class ScanControlTest : public ScanTest { bitscan(0x400164, 0xffff3f03, 0); bitscan(0x400168, 0xffffffff, 0); bitscan(0x40016c, 0x0000ffff, 0); - bitscan(0x400610, 0xe0000000 | offset_mask, 0); - bitscan(0x400614, 0xc0000000 | offset_mask, 0); nva_wr32(cnum, 0x400750, 0); nva_wr32(cnum, 0x400754, 0); bitscan(0x400750, 0x00000077, 0); @@ -150,18 +160,24 @@ class ScanControlTest : public ScanTest { } else { ctxs_mask = is_nv11p ? 0x7ffff0ff : 0x7fb3f0ff; ctxc_mask = is_nv11p ? 0x7ffff0ff : is_nv15p ? 0x7fb3f0ff : 0x7f33f0ff; + if (nv04_pgraph_is_nv25p(&chipset)) + ctxs_mask = ctxc_mask = 0x7fffffff; bitscan(0x400104, 0x07800000, 0); - bitscan(0x400140, 0x01113711, 0); + if (chipset.card_type < 0x20) + bitscan(0x400140, 0x01113711, 0); + else + bitscan(0x400140, 0x011137d1, 0); bitscan(0x400144, 0x11010103, 0); - bitscan(0x400148, is_nv15p ? 0x9f00e000 : 0x1f00e000, 0); + if (chipset.card_type < 0x20) + bitscan(0x400148, is_nv15p ? 0x9f00e000 : 0x1f00e000, 0); + else + bitscan(0x400148, 0x9f00ff11, 0); bitscan(0x40014c, ctxs_mask, 0); bitscan(0x400150, 0xffff3f03, 0); bitscan(0x400154, 0xffffffff, 0); bitscan(0x400158, 0x0000ffff, 0); bitscan(0x40015c, 0xffffffff, 0); - bitscan(0x400610, 0xf8000000 | offset_mask, 0); - bitscan(0x400614, 0xc0000000 | offset_mask, 0); - bitscan(0x40077c, is_nv15p ? 0x631fffff : 0x7100ffff, 0); + bitscan(0x40077c, chipset.card_type >= 0x20 ? 0x0100ffff : is_nv15p ? 0x631fffff : 0x7100ffff, 0); if (is_nv17p) { nva_wr32(cnum, 0x400090, 0); bitscan(0x4006b0, 0xffffffff, 0); @@ -173,8 +189,8 @@ class ScanControlTest : public ScanTest { } nva_wr32(cnum, 0x400760, 0); nva_wr32(cnum, 0x400764, 0); - bitscan(0x400760, is_nv17p ? 0x000000ff : 0x00000077, 0); - bitscan(0x400764, is_nv17p ? 0x7ff71ffc : 0x3ff71ffc, 0); + bitscan(0x400760, is_nv1720p ? 0x000000ff : 0x00000077, 0); + bitscan(0x400764, is_nv1720p ? 0x7ff71ffc : 0x3ff71ffc, 0); bitscan(0x400768, 0xffffffff, 0); bitscan(0x40076c, 0xffffffff, 0); bitscan(0x400720, 0x1, 0); @@ -185,7 +201,7 @@ class ScanControlTest : public ScanTest { bitscan(0x4001c0 + i * 4, 0x0000ffff, 0); bitscan(0x4001e0 + i * 4, 0xffffffff, 0); } - if (!is_nv17p) { + if (!is_nv1720p) { for (int i = 0 ; i < 4; i++) { bitscan(0x400730 + i * 4, 0x01171ffc, 0); bitscan(0x400740 + i * 4, 0xffffffff, 0); @@ -198,10 +214,12 @@ class ScanControlTest : public ScanTest { bitscan(0x4007e0 + i * 4, 0xffffffff, 0); } } - if (is_nv15p) { + if (!is_nv15p) { + bitscan(0x400f50, 0x00001fff, 0); + } else if (chipset.card_type < 0x20) { bitscan(0x400f50, 0x00007ffc, 0); } else { - bitscan(0x400f50, 0x00001fff, 0); + bitscan(0x400f50, 0x0001fffc, 0); } } } @@ -456,7 +474,7 @@ public: } bool PGraphScanTests::supported() { - return chipset.card_type < 0x20; + return chipset.card_type < 0x30; } Test::Subtests PGraphScanTests::subtests() { diff --git a/hwtest/pgraph_state.cc b/hwtest/pgraph_state.cc index 60de3e7a..c03331dd 100644 --- a/hwtest/pgraph_state.cc +++ b/hwtest/pgraph_state.cc @@ -59,8 +59,8 @@ public: class BitmapColor0Register : public IndexedMmioRegister<2> { public: - BitmapColor0Register() : - IndexedMmioRegister<2>(0x400600, 0xffffffff, "BITMAP_COLOR", &pgraph_state::bitmap_color, 0) {} + BitmapColor0Register(uint32_t addr) : + IndexedMmioRegister<2>(addr, 0xffffffff, "BITMAP_COLOR", &pgraph_state::bitmap_color, 0) {} void sim_write(struct pgraph_state *state, uint32_t val) override { ref(state) = val; insrt(state->valid[0], 17, 1, 1); @@ -91,7 +91,7 @@ std::vector<std::unique_ptr<Register>> pgraph_rop_regs(const chipset_info &chips res.push_back(std::unique_ptr<Register>(new BetaRegister(0x400630))); else res.push_back(std::unique_ptr<Register>(new BetaRegister(0x400640))); - } else { + } else if (chipset.card_type < 0x20) { for (int i = 0; i < 2; i++) { IREG(0x400800 + i * 4, 0xffffffff, "PATTERN_MONO_COLOR", pattern_mono_color, i, 2); IREG(0x400808 + i * 4, 0xffffffff, "PATTERN_MONO_BITMAP", pattern_mono_bitmap, i, 2); @@ -100,20 +100,35 @@ std::vector<std::unique_ptr<Register>> pgraph_rop_regs(const chipset_info &chips for (int i = 0; i < 64; i++) { IREG(0x400900 + i * 4, 0x00ffffff, "PATTERN_COLOR", pattern_color, i, 64); } - res.push_back(std::unique_ptr<Register>(new BitmapColor0Register())); + res.push_back(std::unique_ptr<Register>(new BitmapColor0Register(0x400600))); REG(0x400604, 0xff, "ROP", rop); REG(0x400608, 0x7f800000, "BETA", beta); REG(0x40060c, 0xffffffff, "BETA4", beta4); REG(0x400814, 0xffffffff, "CHROMA", chroma); REG(0x400830, 0x3f3f3f3f, "CTX_FORMAT", ctx_format); + } else { + for (int i = 0; i < 2; i++) { + IREG(0x400b10 + i * 4, 0xffffffff, "PATTERN_MONO_COLOR", pattern_mono_color, i, 2); + IREG(0x400b18 + i * 4, 0xffffffff, "PATTERN_MONO_BITMAP", pattern_mono_bitmap, i, 2); + } + REG(0x400b20, 0x13, "PATTERN_CONFIG", pattern_config); + for (int i = 0; i < 64; i++) { + IREG(0x400a00 + i * 4, 0x00ffffff, "PATTERN_COLOR", pattern_color, i, 64); + } + res.push_back(std::unique_ptr<Register>(new BitmapColor0Register(0x400814))); + REG(0x400b00, 0xff, "ROP", rop); + REG(0x400b04, 0x7f800000, "BETA", beta); + REG(0x400b08, 0xffffffff, "BETA4", beta4); + REG(0x40087c, 0xffffffff, "CHROMA", chroma); + REG(0x400b0c, 0x3f3f3f3f, "CTX_FORMAT", ctx_format); } return res; } class SurfOffsetRegister : public IndexedMmioRegister<6> { public: - SurfOffsetRegister(int idx, uint32_t mask) : - IndexedMmioRegister<6>(0x400640 + idx * 4, mask, "SURF_OFFSET", &pgraph_state::surf_offset, idx) {} + SurfOffsetRegister(uint32_t addr, int idx, uint32_t mask) : + IndexedMmioRegister<6>(addr, mask, "SURF_OFFSET", &pgraph_state::surf_offset, idx) {} void sim_write(struct pgraph_state *state, uint32_t val) override { ref(state) = val & mask; insrt(state->valid[0], 3, 1, 1); @@ -122,8 +137,8 @@ public: class SurfPitchRegister : public IndexedMmioRegister<5> { public: - SurfPitchRegister(int idx, uint32_t mask) : - IndexedMmioRegister<5>(0x400670 + idx * 4, mask, "SURF_PITCH", &pgraph_state::surf_pitch, idx) {} + SurfPitchRegister(uint32_t addr, int idx, uint32_t mask) : + IndexedMmioRegister<5>(addr, mask, "SURF_PITCH", &pgraph_state::surf_pitch, idx) {} void sim_write(struct pgraph_state *state, uint32_t val) override { ref(state) = val & mask; insrt(state->valid[0], 2, 1, 1); @@ -167,16 +182,16 @@ std::vector<std::unique_ptr<Register>> pgraph_canvas_regs(const chipset_info &ch IREG(0x400694 + i * 8, canvas_mask, "CLIPRECT_MAX", cliprect_max, i, 2); } REG(0x4006a0, 0x113, "CLIPRECT_CTRL", cliprect_ctrl); - } else { + } else if (chipset.card_type < 0x20) { uint32_t offset_mask = pgraph_offset_mask(&chipset); uint32_t pitch_mask = pgraph_pitch_mask(&chipset); for (int i = 0; i < 6; i++) { - res.push_back(std::unique_ptr<Register>(new SurfOffsetRegister(i, offset_mask))); + res.push_back(std::unique_ptr<Register>(new SurfOffsetRegister(0x400640 + i * 4, i, offset_mask))); IREG(0x400658 + i * 4, offset_mask, "SURF_BASE", surf_base, i, 6); IREGF(0x400684 + i * 4, 1 << 31 | offset_mask, "SURF_LIMIT", surf_limit, i, 6, 0xf); } for (int i = 0; i < 5; i++) { - res.push_back(std::unique_ptr<Register>(new SurfPitchRegister(i, pitch_mask))); + res.push_back(std::unique_ptr<Register>(new SurfPitchRegister(0x400670 + i * 4, i, pitch_mask))); } for (int i = 0; i < 2; i++) { IREG(0x40069c + i * 4, 0x0f0f0000, "SURF_SWIZZLE", surf_swizzle, i, 2); @@ -197,6 +212,46 @@ std::vector<std::unique_ptr<Register>> pgraph_canvas_regs(const chipset_info &ch REG(chipset.card_type >= 0x10 ? 0x400714 : 0x400710, nv04_pgraph_is_nv17p(&chipset) ? 0x3f731f3f : 0x0f731f3f, "CTX_VALID", ctx_valid); + REG(0x400610, (chipset.card_type < 4 ? 0xe0000000 : 0xf8000000) | offset_mask, "SURF_UNK610", surf_unk610); + REG(0x400614, 0xc0000000 | offset_mask, "SURF_UNK614", surf_unk614); + } else { + uint32_t offset_mask = pgraph_offset_mask(&chipset); + 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))); + IREG(0x400838 + i * 4, offset_mask, "SURF_BASE", surf_base, i, 6); + IREGF(0x400864 + i * 4, 1 << 31 | offset_mask, "SURF_LIMIT", surf_limit, i, 6, 0x3f); + } + for (int i = 0; i < 5; i++) { + res.push_back(std::unique_ptr<Register>(new SurfPitchRegister(0x400850 + i * 4, i, pitch_mask))); + } + for (int i = 0; i < 2; i++) { + IREG(0x400818 + i * 4, 0x0f0f0000, "SURF_SWIZZLE", surf_swizzle, i, 2); + } + uint32_t st_mask; + if (chipset.card_type < 0x20) { + if (!nv04_pgraph_is_nv15p(&chipset)) + st_mask = 3; + else if (!nv04_pgraph_is_nv11p(&chipset)) + st_mask = 0x77777703; + else if (!nv04_pgraph_is_nv17p(&chipset)) + st_mask = 0x77777713; + else + st_mask = 0xf77777ff; + } else if (!nv04_pgraph_is_nv25p(&chipset)) + st_mask = 0x77777733; + else + st_mask = 0x77777773; + res.push_back(std::unique_ptr<Register>(new SurfTypeRegister( + chipset.card_type >= 0x10 ? 0x400710 : 0x40070c, + st_mask))); + REG(0x400724, 0xffffff, "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); } return res; } @@ -277,7 +332,8 @@ std::vector<std::unique_ptr<Register>> pgraph_vstate_regs(const chipset_info &ch } else { uint32_t v1_mask = chipset.card_type < 0x10 ? 0x1fffffff : 0xdfffffff; IREG(0x400508, 0xf07fffff, "VALID", valid, 0, 2); - IREG(0x400578, v1_mask, "VALID", valid, 1, 2); + if (chipset.card_type < 0x20) + IREG(0x400578, v1_mask, "VALID", valid, 1, 2); } } return res; @@ -567,7 +623,7 @@ std::vector<std::unique_ptr<Register>> pgraph_dma_nv3_regs(const chipset_info &c std::vector<std::unique_ptr<Register>> pgraph_dma_nv4_regs(const chipset_info &chipset) { std::vector<std::unique_ptr<Register>> res; - bool is_nv17p = nv04_pgraph_is_nv17p(&chipset); + bool is_nv17p = nv04_pgraph_is_nv17p(&chipset) && chipset.card_type < 0x20; IREG(0x401000, 0xffffffff, "DMA_OFFSET", dma_offset, 0, 3); IREG(0x401004, 0xffffffff, "DMA_OFFSET", dma_offset, 1, 3); REG(0x401008, 0x3fffff, "DMA_LENGTH", dma_length); @@ -576,6 +632,8 @@ std::vector<std::unique_ptr<Register>> pgraph_dma_nv4_regs(const chipset_info &c IREG(0x401024, 0xffffffff, "DMA_UNK20", dma_unk20, 1, 2); if (is_nv17p) REG(0x40103c, 0x1f, "DMA_UNK3C", dma_unk3c); + if (chipset.card_type >= 0x20) + REG(0x401038, 0xffffffff, "DMA_UNK38", dma_unk38); for (int i = 0; i < 2; i++) { IREG(0x401040 + i * 0x40, 0xffff, "DMA_ENG_INST", dma_eng_inst, i, 2); IREG(0x401044 + i * 0x40, 0xfff33000, "DMA_ENG_FLAGS", dma_eng_flags, i, 2); @@ -607,6 +665,7 @@ void pgraph_gen_state_debug(int cnum, std::mt19937 &rnd, struct pgraph_state *st bool is_nv11p = nv04_pgraph_is_nv11p(&state->chipset); bool is_nv15p = nv04_pgraph_is_nv15p(&state->chipset); bool is_nv17p = nv04_pgraph_is_nv17p(&state->chipset); + bool is_nv25p = nv04_pgraph_is_nv25p(&state->chipset); if (state->chipset.card_type < 3) { state->debug[0] = rnd() & 0x11111110; state->debug[1] = rnd() & 0x31111101; @@ -630,6 +689,16 @@ 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 { + // debug[0] holds only resets? + state->debug[0] = 0; + state->debug[1] = rnd() & 0x0011f7c1; + state->debug[3] = rnd() & (is_nv25p ? 0xffffdf7d : 0xffffd77d); + state->debug[4] = rnd() & (is_nv25p ? 0xffffffff : 0xfffff3ff); + state->debug[5] = rnd() & 0xff; + state->debug[6] = rnd(); + state->debug[7] = rnd() & 0xfff; + state->debug[16] = rnd() & 3; } } @@ -638,6 +707,7 @@ void pgraph_gen_state_control(int cnum, std::mt19937 &rnd, struct pgraph_state * bool is_nv11p = nv04_pgraph_is_nv11p(&state->chipset); bool is_nv15p = nv04_pgraph_is_nv15p(&state->chipset); bool is_nv17p = nv04_pgraph_is_nv17p(&state->chipset); + bool is_nv1720p = is_nv17p || state->chipset.card_type >= 0x20; state->intr = 0; state->invalid = 0; if (state->chipset.card_type < 4) { @@ -647,7 +717,10 @@ void pgraph_gen_state_control(int cnum, std::mt19937 &rnd, struct pgraph_state * state->intr_en = rnd() & 0x11311; state->nstatus = rnd() & 0x7800; } else { - state->intr_en = rnd() & 0x1113711; + if (state->chipset.card_type < 0x20) + state->intr_en = rnd() & 0x1113711; + else + state->intr_en = rnd() & 0x11137d1; state->nstatus = rnd() & 0x7800000; } state->nsource = 0; @@ -675,20 +748,21 @@ void pgraph_gen_state_control(int cnum, std::mt19937 &rnd, struct pgraph_state * if (state->chipset.card_type < 0x10) { ctxs_mask = ctxc_mask = is_nv5 ? 0x7f73f0ff : 0x0303f0ff; state->ctx_user = rnd() & 0x0f00e000; - state->unk610 = rnd() & (is_nv5 ? 0xe1fffff0 : 0xe0fffff0); - state->unk614 = rnd() & (is_nv5 ? 0xc1fffff0 : 0xc0fffff0); } else { ctxs_mask = is_nv11p ? 0x7ffff0ff : 0x7fb3f0ff; ctxc_mask = is_nv11p ? 0x7ffff0ff : is_nv15p ? 0x7fb3f0ff : 0x7f33f0ff; - state->ctx_user = rnd() & (is_nv15p ? 0x9f00e000 : 0x1f00e000); - state->unk610 = rnd() & 0xfffffff0; - state->unk614 = rnd() & 0xc7fffff0; + if (state->chipset.card_type < 0x20) + state->ctx_user = rnd() & (is_nv15p ? 0x9f00e000 : 0x1f00e000); + else + state->ctx_user = rnd() & 0x9f00ff11; if (!is_nv15p) { state->unk77c = rnd() & 0x1100ffff; if (state->unk77c & 0x10000000) state->unk77c |= 0x70000000; - } else { + } else if (state->chipset.card_type < 0x20) { state->unk77c = rnd() & 0x631fffff; + } else { + state->unk77c = rnd() & 0x0100ffff; } state->unk6b0 = rnd(); state->unk838 = rnd(); @@ -713,7 +787,7 @@ void pgraph_gen_state_control(int cnum, std::mt19937 &rnd, struct pgraph_state * for (int i = 0; i < 8; i++) { if (state->chipset.card_type < 0x10) { state->fifo_mthd[i] = rnd() & 0x00007fff; - } else if (!is_nv17p) { + } else if (!is_nv1720p) { state->fifo_mthd[i] = rnd() & 0x01171ffc; } else { state->fifo_mthd[i] = rnd() & 0x00371ffc; @@ -722,18 +796,18 @@ void pgraph_gen_state_control(int cnum, std::mt19937 &rnd, struct pgraph_state * state->fifo_data[i][1] = rnd() & 0xffffffff; } if (state->fifo_enable) { - state->fifo_ptr = (rnd() & (is_nv17p ? 0xf : 7)) * 0x11; + state->fifo_ptr = (rnd() & (is_nv1720p ? 0xf : 7)) * 0x11; if (state->chipset.card_type < 0x10) { state->fifo_mthd_st2 = rnd() & 0x000ffffe; } else { - state->fifo_mthd_st2 = rnd() & (is_nv17p ? 0x7bf71ffc : 0x3bf71ffc); + state->fifo_mthd_st2 = rnd() & (is_nv1720p ? 0x7bf71ffc : 0x3bf71ffc); } } else { - state->fifo_ptr = rnd() & (is_nv17p ? 0xff : 0x77); + state->fifo_ptr = rnd() & (is_nv1720p ? 0xff : 0x77); if (state->chipset.card_type < 0x10) { state->fifo_mthd_st2 = rnd() & 0x000fffff; } else { - state->fifo_mthd_st2 = rnd() & (is_nv17p ? 0x7ff71ffc : 0x3ff71ffc); + state->fifo_mthd_st2 = rnd() & (is_nv1720p ? 0x7ff71ffc : 0x3ff71ffc); } } state->fifo_data_st2[0] = rnd() & 0xffffffff; @@ -998,8 +1072,6 @@ void pgraph_load_control(int cnum, struct pgraph_state *state) { nva_wr32(cnum, 0x400100, 0xffffffff); nva_wr32(cnum, 0x400140, state->intr_en); nva_wr32(cnum, 0x400104, state->nstatus); - nva_wr32(cnum, 0x400610, state->unk610); - nva_wr32(cnum, 0x400614, state->unk614); if (state->chipset.card_type < 0x10) { for (int j = 0; j < 4; j++) { nva_wr32(cnum, 0x400160 + j * 4, state->ctx_switch[j]); @@ -1047,11 +1119,21 @@ void pgraph_load_debug(int cnum, struct pgraph_state *state) { mangled |= 1 << 30; nva_wr32(cnum, 0x400084, mangled); } - nva_wr32(cnum, 0x400088, state->debug[2]); + if (state->chipset.card_type < 0x20) + nva_wr32(cnum, 0x400088, state->debug[2]); if (state->chipset.card_type >= 3) nva_wr32(cnum, 0x40008c, state->debug[3]); if (state->chipset.card_type >= 0x10) nva_wr32(cnum, 0x400090, state->debug[4]); + if (state->chipset.card_type >= 0x20) { + nva_wr32(cnum, 0x400098, state->debug[6]); + nva_wr32(cnum, 0x40009c, state->debug[7]); + if (!nv04_pgraph_is_nv25p(&state->chipset)) { + nva_wr32(cnum, 0x400094, state->debug[5]); + } else { + nva_wr32(cnum, 0x4000c0, state->debug[16]); + } + } } void pgraph_load_vstate(int cnum, struct pgraph_state *state) { @@ -1180,7 +1262,8 @@ void pgraph_load_fifo(int cnum, struct pgraph_state *state) { nva_wr32(cnum, 0x400758, state->fifo_data_st2[0]); } else { bool is_nv17p = nv04_pgraph_is_nv17p(&state->chipset); - if (!is_nv17p) { + bool is_nv1720p = is_nv17p || state->chipset.card_type >= 0x20; + if (!is_nv1720p) { for (int i = 0; i < 4; i++) { nva_wr32(cnum, 0x400730 + i * 4, state->fifo_mthd[i]); nva_wr32(cnum, 0x400740 + i * 4, state->fifo_data[i][0]); @@ -1275,7 +1358,8 @@ void pgraph_dump_fifo(int cnum, struct pgraph_state *state) { state->fifo_data_st2[0] = nva_rd32(cnum, 0x400758); } else { bool is_nv17p = nv04_pgraph_is_nv17p(&state->chipset); - if (!is_nv17p) { + bool is_nv1720p = is_nv17p || state->chipset.card_type >= 0x20; + if (!is_nv1720p) { for (int i = 0; i < 4; i++) { state->fifo_mthd[i] = nva_rd32(cnum, 0x400730 + i * 4); state->fifo_data[i][0] = nva_rd32(cnum, 0x400740 + i * 4); @@ -1344,8 +1428,6 @@ void pgraph_dump_control(int cnum, struct pgraph_state *state) { } else { state->notify = nva_rd32(cnum, 0x400718); } - state->unk610 = nva_rd32(cnum, 0x400610); - state->unk614 = nva_rd32(cnum, 0x400614); if (state->chipset.card_type >= 0x10) state->unk77c = nva_rd32(cnum, 0x40077c); bool is_nv17p = nv04_pgraph_is_nv17p(&state->chipset); @@ -1390,7 +1472,7 @@ void pgraph_dump_vtx(int cnum, struct pgraph_state *state) { state->uclip_max[0][i] = nva_rd32(cnum, 0x400544 + i * 4); state->uclip_min[1][i] = nva_rd32(cnum, 0x400560 + i * 4); state->uclip_max[1][i] = nva_rd32(cnum, 0x400568 + i * 4); - if (state->chipset.card_type >= 0x10) { + if (state->chipset.card_type == 0x10) { state->uclip_min[2][i] = nva_rd32(cnum, 0x400550 + i * 4); state->uclip_max[2][i] = nva_rd32(cnum, 0x400558 + i * 4); } @@ -1475,13 +1557,23 @@ void pgraph_dump_celsius_pipe(int cnum, struct pgraph_state *state) { void pgraph_dump_debug(int cnum, struct pgraph_state *state) { state->debug[0] = nva_rd32(cnum, 0x400080); state->debug[1] = nva_rd32(cnum, 0x400084); - state->debug[2] = nva_rd32(cnum, 0x400088); + if (state->chipset.card_type < 0x20) + state->debug[2] = nva_rd32(cnum, 0x400088); if (state->chipset.card_type >= 3) state->debug[3] = nva_rd32(cnum, 0x40008c); if (state->chipset.card_type >= 0x10) state->debug[4] = nva_rd32(cnum, 0x400090); if (state->chipset.card_type >= 0x10) nva_wr32(cnum, 0x400080, 0); + if (state->chipset.card_type >= 0x20) { + state->debug[6] = nva_rd32(cnum, 0x400098); + state->debug[7] = nva_rd32(cnum, 0x40009c); + if (!nv04_pgraph_is_nv25p(&state->chipset)) { + state->debug[5] = nva_rd32(cnum, 0x400094); + } else { + state->debug[16] = nva_rd32(cnum, 0x4000c0); + } + } } void pgraph_dump_dma_nv3(int cnum, struct pgraph_state *state) { @@ -1541,6 +1633,8 @@ void pgraph_dump_state(int cnum, struct pgraph_state *state) { int pgraph_cmp_state(struct pgraph_state *orig, struct pgraph_state *exp, struct pgraph_state *real, bool broke) { bool is_nv17p = nv04_pgraph_is_nv17p(&orig->chipset); + bool is_nv1720p = is_nv17p || orig->chipset.card_type >= 0x20; + bool is_nv25p = nv04_pgraph_is_nv25p(&orig->chipset); bool print = false; #define CMP(reg, name, ...) \ if (print) \ @@ -1572,13 +1666,25 @@ restart: } CMP(debug[0], "DEBUG[0]") CMP(debug[1], "DEBUG[1]") - CMP(debug[2], "DEBUG[2]") + if (orig->chipset.card_type < 0x20) { + CMP(debug[2], "DEBUG[2]") + } if (orig->chipset.card_type >= 3) { CMP(debug[3], "DEBUG[3]") } if (orig->chipset.card_type >= 0x10) { CMP(debug[4], "DEBUG[4]") } + if (orig->chipset.card_type >= 0x20) { + if (!is_nv25p) { + CMP(debug[5], "DEBUG[5]") + } + CMP(debug[6], "DEBUG[6]") + CMP(debug[7], "DEBUG[7]") + if (is_nv25p) { + CMP(debug[16], "DEBUG[16]") + } + } CMP(intr, "INTR") CMP(intr_en, "INTR_EN") @@ -1628,8 +1734,6 @@ restart: CMP(ctx_control, "CTX_CONTROL") } CMP(ctx_user, "CTX_USER") - CMP(unk610, "UNK610") - CMP(unk614, "UNK614") if (orig->chipset.card_type >= 0x10) { CMP(unk77c, "UNK77C") } @@ -1641,7 +1745,7 @@ restart: CMP(zcull_unka00[1], "ZCULL_UNKA00[1]") CMP(unka10, "UNKA10") } - for (int i = 0; i < 4; i++) { + for (int i = 0; i < (is_nv1720p ? 8 : 4); i++) { CMP(fifo_mthd[i], "FIFO_MTHD[%d]", i) CMP(fifo_data[i][0], "FIFO_DATA[%d][0]", i) if (orig->chipset.card_type >= 0x10) { @@ -1671,7 +1775,7 @@ restart: CMP(uclip_max[1][i], "OCLIP_MAX[%d]", i) } } - if (orig->chipset.card_type >= 0x10) { + if (orig->chipset.card_type == 0x10) { for (int i = 0; i < 2; i++) { CMP(uclip_min[2][i], "CLIP3D_MIN[%d]", i) CMP(uclip_max[2][i], "CLIP3D_MAX[%d]", i) diff --git a/hwtest/pgraph_state_tests.cc b/hwtest/pgraph_state_tests.cc index 5f9906f3..56a05f51 100644 --- a/hwtest/pgraph_state_tests.cc +++ b/hwtest/pgraph_state_tests.cc @@ -140,6 +140,10 @@ protected: // No idea. if ((reg & 0xffffff00) == 0x400800 && chipset.chipset == 0x10) return; + if ((reg & 0xffffff00) == 0x400200 && chipset.chipset == 0x20) + return; + if ((reg & 0xffffff00) == 0x400300 && chipset.card_type == 0x20) + return; } nva_rd32(cnum, reg); } @@ -319,21 +323,26 @@ protected: bool is_nv11p = nv04_pgraph_is_nv11p(&chipset); bool is_nv15p = nv04_pgraph_is_nv15p(&chipset); bool is_nv17p = nv04_pgraph_is_nv17p(&chipset); + bool is_nv25p = nv04_pgraph_is_nv25p(&chipset); uint32_t ctxs_mask, ctxc_mask; uint32_t offset_mask = pgraph_offset_mask(&chipset); if (chipset.card_type < 0x10) { ctxs_mask = ctxc_mask = is_nv5 ? 0x7f73f0ff : 0x0303f0ff; - } else { + } else if (chipset.card_type < 0x20) { ctxs_mask = is_nv11p ? 0x7ffff0ff : 0x7fb3f0ff; ctxc_mask = is_nv11p ? 0x7ffff0ff : is_nv15p ? 0x7fb3f0ff : 0x7f33f0ff; + } else { + ctxs_mask = ctxc_mask = is_nv25p ? 0x7fffffff : 0x7ffff0ff; } - switch (rnd() % 29) { + switch (rnd() % 33) { default: reg = 0x400140; if (chipset.card_type < 0x10) { exp.intr_en = val & 0x11311; - } else { + } else if (chipset.card_type < 0x20) { exp.intr_en = val & 0x1113711; + } else { + exp.intr_en = val & 0x11137d1; } break; case 1: @@ -378,8 +387,8 @@ protected: exp.surf_pitch[i] = 0; for (int i = 0; i < 2; i++) exp.surf_swizzle[i] = 0; - exp.unk610 = 0; - exp.unk614 = 0; + exp.surf_unk610 = 0; + exp.surf_unk614 = 0; } if (val & 0x101) { exp.dma_eng_flags[0] &= ~0x1000; @@ -390,20 +399,22 @@ protected: reg = 0x400084; if (chipset.card_type < 0x10) { exp.debug[1] = val & (is_nv5 ? 0xf2ffb701 : 0x72113101); - if (val & 0x10) - exp.xy_misc_1[0] &= ~1; - } else { + } else if (chipset.card_type < 0x20) { uint32_t mangled = val & 0x3fffffff; if (val & 1 << 30) mangled |= 1 << 31; if (val & 1 << 31) mangled |= 1 << 30; exp.debug[1] = mangled & (is_nv11p ? 0xfe71f701 : 0xfe11f701); - if (val & 0x10) - exp.xy_misc_1[0] &= ~1; + } else { + exp.debug[1] = val & 0x0011f7c1; } + if (val & 0x10) + exp.xy_misc_1[0] &= ~1; break; case 4: + if (chipset.card_type >= 0x20) + return; reg = 0x400088; if (chipset.card_type <0x10) exp.debug[2] = val & 0x11d7fff1; @@ -414,18 +425,24 @@ protected: reg = 0x40008c; if (chipset.card_type < 0x10) { exp.debug[3] = val & (is_nv5 ? 0xfbffff73 : 0x11ffff33); - } else { + } else if (chipset.card_type < 0x20) { exp.debug[3] = val & (is_nv15p ? 0xffffff78 : 0xfffffc70); if (is_nv17p) exp.debug[3] |= 0x400; + } else { + exp.debug[3] = val & (is_nv25p ? 0xffffdf7d : 0xffffd77d); } break; case 6: reg = 0x400090; if (chipset.card_type < 0x10) return; - 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)); + 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 { + exp.debug[4] = val & (is_nv25p ? 0xffffffff : 0xfffff3ff); + } break; case 7: { @@ -496,22 +513,12 @@ protected: reg = chipset.card_type >= 0x10 ? 0x400148 : 0x400174; if (chipset.card_type < 0x10) { exp.ctx_user = val & 0x0f00e000; - } else { + } else if (chipset.card_type < 0x20) { exp.ctx_user = val & (is_nv15p ? 0x9f00e000 : 0x1f00e000); - } - break; - case 19: - reg = 0x400610; - if (chipset.card_type < 0x10) { - exp.unk610 = val & (0xe0000000 | offset_mask); } else { - exp.unk610 = val & 0xfffffff0; + exp.ctx_user = val & 0x9f00ff11; } break; - case 20: - reg = 0x400614; - exp.unk614 = val & (0xc0000000 | offset_mask); - break; case 21: if (chipset.card_type < 0x10) return; @@ -520,8 +527,10 @@ protected: exp.unk77c = val & 0x0100ffff; if (val & 1 << 28) exp.unk77c |= 7 << 28; - } else { + } else if (chipset.card_type < 0x20) { exp.unk77c = val & 0x631fffff; + } else { + exp.unk77c = val & 0x0100ffff; } break; case 22: @@ -565,6 +574,30 @@ protected: exp.unka10 = val & 0xdfff3fff; insrt(exp.unka10, 29, 1, extr(exp.debug[4], 2, 1) && !!extr(exp.surf_type, 2, 2)); break; + case 29: + if (chipset.card_type < 0x20 || is_nv25p) + return; + reg = 0x400094; + exp.debug[5] = val & 0xff; + break; + case 30: + if (chipset.card_type < 0x20) + return; + reg = 0x400098; + exp.debug[6] = val; + break; + case 31: + if (chipset.card_type < 0x20) + return; + reg = 0x40009c; + exp.debug[7] = val & 0xfff; + break; + case 32: + if (!is_nv25p) + return; + reg = 0x4000c0; + exp.debug[16] = val & 3; + break; } nva_wr32(cnum, reg, val); } @@ -986,7 +1019,12 @@ public: class FormatsTest : public StateTest { uint32_t val; protected: - bool supported() override { return chipset.card_type >= 4; } + bool supported() override { + // XXX fix me + if (chipset.card_type >= 0x20) + return false; + return chipset.card_type >= 4; + } void adjust_orig() override { if (!(rnd() & 3)) { uint32_t classes[] = { @@ -1028,7 +1066,10 @@ protected: } } void mutate() override { - val = nva_rd32(cnum, 0x400618); + if (chipset.card_type < 0x20) + val = nva_rd32(cnum, 0x400618); + else + val = nva_rd32(cnum, 0x400804); } bool other_fail() override { uint32_t ev = nv04_pgraph_formats(&orig); @@ -1045,7 +1086,7 @@ public: } bool PGraphStateTests::supported() { - return chipset.card_type < 0x20; + return chipset.card_type < 0x30; } Test::Subtests PGraphStateTests::subtests() { diff --git a/include/nvhw/pgraph.h b/include/nvhw/pgraph.h index 913f52b5..a167848e 100644 --- a/include/nvhw/pgraph.h +++ b/include/nvhw/pgraph.h @@ -49,7 +49,7 @@ int pgraph_type(int chipset); struct pgraph_state { struct chipset_info chipset; - uint32_t debug[5]; + uint32_t debug[17]; uint32_t intr; uint32_t intr_en; uint32_t invalid; @@ -62,12 +62,13 @@ struct pgraph_state { uint32_t ctx_cache[8][5]; uint32_t ctx_control; uint32_t ctx_user; - uint32_t unk610; - uint32_t unk614; uint32_t unk77c; uint32_t unk6b0; uint32_t unk838; uint32_t unk83c; + uint32_t surf_unk800; + uint32_t surf_unk80c; + uint32_t surf_unk810; uint32_t zcull_unka00[2]; uint32_t unka10; uint32_t access; @@ -117,6 +118,8 @@ struct pgraph_state { uint32_t pattern_mono_bitmap[2]; uint32_t pattern_config; uint32_t pattern_color[64]; + uint32_t surf_unk610; + uint32_t surf_unk614; uint32_t surf_base[6]; uint32_t surf_offset[6]; uint32_t surf_limit[6]; @@ -163,6 +166,7 @@ struct pgraph_state { uint32_t dma_length; uint32_t dma_misc; uint32_t dma_unk20[2]; + uint32_t dma_unk38; uint32_t dma_unk3c; uint32_t dma_eng_inst[2]; uint32_t dma_eng_flags[2]; @@ -396,7 +400,11 @@ static inline bool nv04_pgraph_is_nv15p(const struct chipset_info *chipset) { } static inline bool nv04_pgraph_is_nv17p(const struct chipset_info *chipset) { - return chipset->chipset >= 0x17 && chipset->chipset != 0x1a; + return chipset->chipset >= 0x17 && chipset->chipset != 0x1a && chipset->card_type < 0x20; +} + +static inline bool nv04_pgraph_is_nv25p(const struct chipset_info *chipset) { + return chipset->chipset >= 0x25 && chipset->chipset != 0x2a; } static inline uint32_t pgraph_offset_mask(const struct chipset_info *chipset) { @@ -406,15 +414,19 @@ static inline uint32_t pgraph_offset_mask(const struct chipset_info *chipset) { return 0x00fffff0; else if (chipset->card_type < 0x10) return 0x01fffff0; - else + else if (chipset->card_type < 0x20) return 0x07fffff0; + else + return 0x3fffffc0; } static inline uint32_t pgraph_pitch_mask(const struct chipset_info *chipset) { if (chipset->card_type < 0x10) return 0x1ff0; - else + else if (chipset->card_type < 0x20) return 0xfff0; + else + return 0xffc0; } static inline bool pgraph_is_class_line(struct pgraph_state *state) { diff --git a/nvhw/pgraph_xy4.c b/nvhw/pgraph_xy4.c index d6d8f803..7373a469 100644 --- a/nvhw/pgraph_xy4.c +++ b/nvhw/pgraph_xy4.c @@ -165,6 +165,8 @@ bool nv04_pgraph_is_sync(struct pgraph_state *state) { bool nv04_pgraph_is_3d_class(struct pgraph_state *state) { int cls = extr(state->ctx_switch[0], 0, 8); bool alt = extr(state->debug[3], 16, 1) && state->chipset.card_type >= 0x10; + if (state->chipset.card_type >= 0x20) + return false; switch (cls) { case 0x48: return state->chipset.chipset <= 0x10; |