summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 018e28c..04716a2 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -678,11 +678,14 @@ static int svc_map_lookup(u64 gpu_va, u64 *pa);
* big half -> PT_BIG [20:16]
* small half -> PT_4K [20:12]
*
- * A directory entry carries the aperture in bits 2:1 (1 = video memory,
- * 2 = system coherent, 3 = system non-coherent) and the child address in bits
- * 53:8 at 4 KB granularity (bits 53:4 at 256 B granularity in the big half of
- * a dual entry). Bit 0 of a leaf entry is VALID; bit 0 of a directory entry is
- * IS_PTE, so a set bit means the level terminates in a page here.
+ * A directory entry carries the aperture in bits 2:1 (0 = invalid, 1 = video
+ * memory, 2 = system coherent, 3 = system non-coherent) and the child address
+ * (>> 12) in bits 32:8 for video memory and bits 53:8 for system memory. The
+ * PD0 dual entry is 16 bytes: the big half (offset 0) is either a 2 MB leaf
+ * PTE (bit 0 = IS_PTE = 1, regular PTE encoding) or, with bit 0 clear, a
+ * pointer for 64 KB pages; the small half (offset 8) points to a 4 KB page
+ * table (bit 0 clear). Bit 0 of a leaf entry is VALID; on a single directory
+ * entry it is IS_PDE (0 = points to the next level).
*/
#define SVC_MMU_VA_BITS 49
#define SVC_MMU_AP_VID 1 /* in directory entries */
@@ -693,11 +696,21 @@ static int svc_map_lookup(u64 gpu_va, u64 *pa);
#define SVC_MMU_PTE_AP_SYS_COH 2
#define SVC_MMU_PTE_AP_SYS_NC 3
+/*
+ * Address field decode for NV_MMU_VER2 (Turing+) PDEs and PTEs: the encoder
+ * stores `address >> 12` in bits 32:8 for video memory and bits 53:8 for
+ * system memory. The previous mask-and-keep decode omitted the *left* shift
+ * by 12, so every child pointer and leaf came out 16x too small (0x20200
+ * instead of 0x202000) and no walk ever found a mapping (walks_ok=0 on every
+ * boot). Verified against live page tables: a directory entry 0x2020a
+ * resolves to table 0x202000 and the leaf 0x0600000000760001 (aperture VID,
+ * KIND=6 GENERIC_MEMORY) resolves to PA 0x7600000.
+ */
static u64 svc_pte_addr(u64 e, bool vidmem)
{
if (vidmem)
- return (e & 0x00000001FFFFFFFF00ULL);
- return (e & 0x003FFFFFFFFF00ULL);
+ return ((e >> 8) & 0x0000000001FFFFFFULL) << 12;
+ return ((e >> 8) & 0x00003FFFFFFFFFFFULL) << 12;
}
/* Return the file/buffer selector (SVC_APERTURE_*) for an entry bit-field. */