dart: Use "vm-base" as start when installing L2 tables

Additional L2 tables for dart-dcp/disp0 need to be from carveout memory
so they can kept after m1n1 exist. iboot has "pt-region-X" and "l2-tt-X"
in the ADT. For DCP on M2 we have to start installing them at "vm-base"
which is 0x8_0000_0000.
This probably causes problems on M2 Pro which uses 1 << 40 as vm-base
for dart-dcp0.

Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
Janne Grunau 2023-01-25 17:07:21 +01:00 committed by Hector Martin
parent d110da1e75
commit 72cdec0e31
3 changed files with 18 additions and 6 deletions

View file

@ -116,6 +116,7 @@ struct dart_dev {
u8 device; u8 device;
enum dart_type_t type; enum dart_type_t type;
const struct dart_params *params; const struct dart_params *params;
u64 vm_base;
u64 *l1[DART_MAX_TTBR_COUNT]; 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]); dart->l1[i]);
} }
} }
if (ADT_GETPROP(adt, node, "vm-base", &dart->vm_base) < 0)
dart->vm_base = 0;
return dart; return dart;
} }
@ -391,7 +394,7 @@ dart_dev_t *dart_init_fdt(void *dt, u32 phandle, int device, bool keep_pts)
return dart; 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 */ /* only device 0 of dart-dcp and dart-disp0 are of interest */
if (device != 0) 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 */ /* first index is the l1 table, cap at 2 or else macOS hates it */
tbl_count = min(2, tbl_count - 1); tbl_count = min(2, tbl_count - 1);
u64 l2_start = region[0] + SZ_16K; u64 l2_start = region[0] + SZ_16K;
u64 vmstart = vm_base >> (14 + 11);
for (u64 index = 0; index < tbl_count; index++) { for (u64 index = 0; index < tbl_count; index++) {
int ttbr = index >> 11; int ttbr = (vmstart + index) >> 11;
int idx = index & 0x7ff; int idx = (vmstart + index) & 0x7ff;
u64 l2tbl = l2_start + index * SZ_16K; u64 l2tbl = l2_start + index * SZ_16K;
if (dart->l1[ttbr][idx] & DART_PTE_VALID) { 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->l1[i]);
free(dart); free(dart);
} }
u64 dart_vm_base(dart_dev_t *dart)
{
return dart->vm_base;
}

View file

@ -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); 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); void dart_lock_adt(const char *path, int instance);
dart_dev_t *dart_init_fdt(void *dt, u32 phandle, int device, bool keep_pts); 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); 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_unmap(dart_dev_t *dart, uintptr_t iova, size_t len);
void dart_free_l2(dart_dev_t *dart, uintptr_t iova); 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_search(dart_dev_t *dart, void *paddr);
u64 dart_find_iova(dart_dev_t *dart, s64 start, size_t len); u64 dart_find_iova(dart_dev_t *dart, s64 start, size_t len);
void dart_shutdown(dart_dev_t *dart); void dart_shutdown(dart_dev_t *dart);
u64 dart_vm_base(dart_dev_t *dart);
#endif #endif

View file

@ -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"); printf("dcp: failed to initialize DCP DART\n");
goto out_free; 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); dcp->dart_disp = dart_init_adt(disp_dart_path, 0, 0, true);
if (!dcp->dart_disp) { if (!dcp->dart_disp) {
printf("dcp: failed to initialize DISP DART\n"); printf("dcp: failed to initialize DISP DART\n");
goto out_dart_dcp; 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); dcp->iovad_dcp = iovad_init(0x10000000, 0x20000000);