dart: Add DART_PTR_ERR to indicate failures for IOVA returning functions

0 is a valid and used device virtual address. Daart functions returning
device address can not use 0 to indicate errors.

Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
Janne Grunau 2022-06-04 11:09:48 +02:00 committed by Hector Martin
parent 2e1ed1d457
commit f1664ccef4
3 changed files with 24 additions and 19 deletions

View file

@ -559,10 +559,10 @@ u64 dart_search(dart_dev_t *dart, void *paddr)
} }
} }
return 0; return DART_PTR_ERR;
} }
s64 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)
{ {
if (len % SZ_16K) if (len % SZ_16K)
return -1; return -1;
@ -588,7 +588,7 @@ s64 dart_find_iova(dart_dev_t *dart, s64 start, size_t len)
iova += SZ_16K; iova += SZ_16K;
} }
return -1; return DART_PTR_ERR;
} }
void dart_shutdown(dart_dev_t *dart) void dart_shutdown(dart_dev_t *dart)

View file

@ -5,6 +5,9 @@
#include "types.h" #include "types.h"
#define DART_PTR_ERR BIT(63)
#define DART_IS_ERR(val) FIELD_GET(DART_PTR_ERR, val)
typedef struct dart_dev dart_dev_t; typedef struct dart_dev dart_dev_t;
enum dart_type_t { enum dart_type_t {
@ -21,7 +24,7 @@ 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);
void *dart_translate(dart_dev_t *dart, uintptr_t iova); 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);
s64 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);
#endif #endif

View file

@ -115,20 +115,20 @@ int display_get_vram(u64 *paddr, u64 *size)
static uintptr_t display_map_fb(uintptr_t iova, u64 paddr, u64 size) static uintptr_t display_map_fb(uintptr_t iova, u64 paddr, u64 size)
{ {
if (iova == 0) { if (iova == 0) {
s64 iova_disp0 = 0; u64 iova_disp0 = 0;
s64 iova_dcp = 0; u64 iova_dcp = 0;
iova_dcp = dart_find_iova(dcp->dart_dcp, iova_dcp, size); iova_dcp = dart_find_iova(dcp->dart_dcp, iova_dcp, size);
if (iova_dcp < 0) { if (DART_IS_ERR(iova_dcp)) {
printf("display: failed to find IOVA for fb of %06zx bytes (dcp)\n", size); printf("display: failed to find IOVA for fb of %06zx bytes (dcp)\n", size);
return 0; return iova_dcp;
} }
// try to map the fb to the same IOVA on disp0 // try to map the fb to the same IOVA on disp0
iova_disp0 = dart_find_iova(dcp->dart_dcp, iova_dcp, size); iova_disp0 = dart_find_iova(dcp->dart_dcp, iova_dcp, size);
if (iova_disp0 < 0) { if (DART_IS_ERR(iova_disp0)) {
printf("display: failed to find IOVA for fb of %06zx bytes (disp0)\n", size); printf("display: failed to find IOVA for fb of %06zx bytes (disp0)\n", size);
return 0; return iova_disp0;
} }
// assume this results in the same IOVA, not sure if this is required but matches what iboot // assume this results in the same IOVA, not sure if this is required but matches what iboot
@ -136,7 +136,7 @@ static uintptr_t display_map_fb(uintptr_t iova, u64 paddr, u64 size)
if (iova_disp0 != iova_dcp) { if (iova_disp0 != iova_dcp) {
printf("display: IOVA mismatch for fb between dcp (%08lx) and disp0 (%08lx)\n", printf("display: IOVA mismatch for fb between dcp (%08lx) and disp0 (%08lx)\n",
(u64)iova_dcp, (u64)iova_disp0); (u64)iova_dcp, (u64)iova_disp0);
return 0; return DART_PTR_ERR;
} }
iova = iova_dcp; iova = iova_dcp;
@ -145,14 +145,14 @@ static uintptr_t display_map_fb(uintptr_t iova, u64 paddr, u64 size)
int ret = dart_map(dcp->dart_disp, iova, (void *)paddr, size); int ret = dart_map(dcp->dart_disp, iova, (void *)paddr, size);
if (ret < 0) { if (ret < 0) {
printf("display: failed to map fb to dart-disp0\n"); printf("display: failed to map fb to dart-disp0\n");
return 0; return DART_PTR_ERR;
} }
ret = dart_map(dcp->dart_dcp, iova, (void *)paddr, size); ret = dart_map(dcp->dart_dcp, iova, (void *)paddr, size);
if (ret < 0) { if (ret < 0) {
printf("display: failed to map fb to dart-dcp\n"); printf("display: failed to map fb to dart-dcp\n");
dart_unmap(dcp->dart_disp, iova, size); dart_unmap(dcp->dart_disp, iova, size);
return 0; return DART_PTR_ERR;
} }
return iova; return iova;
@ -182,10 +182,11 @@ int display_start_dcp(void)
// Find the framebuffer DVA // Find the framebuffer DVA
fb_dva = dart_search(dcp->dart_disp, (void *)cur_boot_args.video.base); fb_dva = dart_search(dcp->dart_disp, (void *)cur_boot_args.video.base);
// framebuffer is not mapped on the M1 Ultra Mac Studio // framebuffer is not mapped on the M1 Ultra Mac Studio
if (!fb_dva) if (DART_IS_ERR(fb_dva))
fb_dva = display_map_fb(0, pa, size); fb_dva = display_map_fb(0, pa, size);
if (!fb_dva) { if (DART_IS_ERR(fb_dva)) {
printf("display: failed to find display DVA\n"); printf("display: failed to find display DVA\n");
fb_dva = 0;
dcp_shutdown(dcp, false); dcp_shutdown(dcp, false);
return -1; return -1;
} }
@ -377,8 +378,8 @@ int display_configure(const char *config)
tmp_dva = iova_alloc(dcp->iovad_dcp, size); tmp_dva = iova_alloc(dcp->iovad_dcp, size);
ret = display_map_fb(tmp_dva, fb_pa, size); tmp_dva = display_map_fb(tmp_dva, fb_pa, size);
if (ret < 0) { if (DART_IS_ERR(tmp_dva)) {
printf("display: failed to map new fb\n"); printf("display: failed to map new fb\n");
return -1; return -1;
} }
@ -395,9 +396,10 @@ int display_configure(const char *config)
dart_unmap(dcp->dart_disp, fb_dva, fb_size); dart_unmap(dcp->dart_disp, fb_dva, fb_size);
dart_unmap(dcp->dart_dcp, fb_dva, fb_size); dart_unmap(dcp->dart_dcp, fb_dva, fb_size);
ret = display_map_fb(fb_dva, fb_pa, size); fb_dva = display_map_fb(fb_dva, fb_pa, size);
if (ret < 0) { if (DART_IS_ERR(fb_dva)) {
printf("display: failed to map new fb\n"); printf("display: failed to map new fb\n");
fb_dva = 0;
return -1; return -1;
} }