diff --git a/src/dart.c b/src/dart.c index eab2c890..f16a2720 100644 --- a/src/dart.c +++ b/src/dart.c @@ -116,6 +116,7 @@ struct dart_dev { u8 device; enum dart_type_t type; const struct dart_params *params; + u64 vm_base; u64 *l1[DART_MAX_TTBR_COUNT]; }; @@ -320,6 +321,8 @@ dart_dev_t *dart_init_adt(const char *path, int instance, int device, bool keep_ dart->l1[i]); } } + if (ADT_GETPROP(adt, node, "vm-base", &dart->vm_base) < 0) + dart->vm_base = 0; return dart; } @@ -391,7 +394,7 @@ dart_dev_t *dart_init_fdt(void *dt, u32 phandle, int device, bool keep_pts) return dart; } -int dart_setup_pt_region(dart_dev_t *dart, const char *path, int device) +int dart_setup_pt_region(dart_dev_t *dart, const char *path, int device, u64 vm_base) { /* only device 0 of dart-dcp and dart-disp0 are of interest */ if (device != 0) @@ -415,9 +418,10 @@ int dart_setup_pt_region(dart_dev_t *dart, const char *path, int device) /* first index is the l1 table, cap at 2 or else macOS hates it */ tbl_count = min(2, tbl_count - 1); u64 l2_start = region[0] + SZ_16K; + u64 vmstart = vm_base >> (14 + 11); for (u64 index = 0; index < tbl_count; index++) { - int ttbr = index >> 11; - int idx = index & 0x7ff; + int ttbr = (vmstart + index) >> 11; + int idx = (vmstart + index) & 0x7ff; u64 l2tbl = l2_start + index * SZ_16K; if (dart->l1[ttbr][idx] & DART_PTE_VALID) { @@ -692,3 +696,8 @@ void dart_shutdown(dart_dev_t *dart) free(dart->l1[i]); free(dart); } + +u64 dart_vm_base(dart_dev_t *dart) +{ + return dart->vm_base; +} diff --git a/src/dart.h b/src/dart.h index 66d2b265..7d8474b4 100644 --- a/src/dart.h +++ b/src/dart.h @@ -20,7 +20,7 @@ dart_dev_t *dart_init(uintptr_t base, u8 device, bool keep_pts, enum dart_type_t dart_dev_t *dart_init_adt(const char *path, int instance, int device, bool keep_pts); void dart_lock_adt(const char *path, int instance); dart_dev_t *dart_init_fdt(void *dt, u32 phandle, int device, bool keep_pts); -int dart_setup_pt_region(dart_dev_t *dart, const char *path, int device); +int dart_setup_pt_region(dart_dev_t *dart, const char *path, int device, u64 vm_base); int dart_map(dart_dev_t *dart, uintptr_t iova, void *bfr, size_t len); void dart_unmap(dart_dev_t *dart, uintptr_t iova, size_t len); void dart_free_l2(dart_dev_t *dart, uintptr_t iova); @@ -28,5 +28,6 @@ void *dart_translate(dart_dev_t *dart, uintptr_t iova); u64 dart_search(dart_dev_t *dart, void *paddr); u64 dart_find_iova(dart_dev_t *dart, s64 start, size_t len); void dart_shutdown(dart_dev_t *dart); +u64 dart_vm_base(dart_dev_t *dart); #endif diff --git a/src/dcp.c b/src/dcp.c index efa862d9..56aec4e5 100644 --- a/src/dcp.c +++ b/src/dcp.c @@ -18,14 +18,16 @@ dcp_dev_t *dcp_init(const char *dcp_path, const char *dcp_dart_path, const char printf("dcp: failed to initialize DCP DART\n"); goto out_free; } - dart_setup_pt_region(dcp->dart_dcp, dcp_dart_path, 0); + u64 vm_base = dart_vm_base(dcp->dart_dcp); + dart_setup_pt_region(dcp->dart_dcp, dcp_dart_path, 0, vm_base); dcp->dart_disp = dart_init_adt(disp_dart_path, 0, 0, true); if (!dcp->dart_disp) { printf("dcp: failed to initialize DISP DART\n"); goto out_dart_dcp; } - dart_setup_pt_region(dcp->dart_disp, disp_dart_path, 0); + // set disp0's page tables at dart-dcp's vm-base + dart_setup_pt_region(dcp->dart_disp, disp_dart_path, 0, vm_base); dcp->iovad_dcp = iovad_init(0x10000000, 0x20000000);